public static function ajax($options = array(), $xhr = null)
{
$options = array_merge(self::$ajaxSettings, $options);
$documentID = isset($options['document']) ? self::getDocumentID($options['document']) : null;
if ($xhr) {
// reuse existing XHR object, but clean it up
$client = $xhr;
// $client->setParameterPost(null);
// $client->setParameterGet(null);
$client->setAuth(false);
$client->setHeaders('If-Modified-Since', null);
$client->setHeaders('Referer', null);
$client->resetParameters();
} else {
// create new XHR object
require_once 'Zend/Http/Client.php';
$client = new Zend_Http_Client();
$client->setCookieJar();
}
if (isset($options['timeout'])) {
$client->setConfig(array('timeout' => $options['timeout']));
}
// 'maxredirects' => 0,
foreach (self::$ajaxAllowedHosts as $k => $host) {
if ($host == '.' && isset($_SERVER['HTTP_HOST'])) {
self::$ajaxAllowedHosts[$k] = $_SERVER['HTTP_HOST'];
}
}
$host = parse_url($options['url'], PHP_URL_HOST);
if (!in_array($host, self::$ajaxAllowedHosts)) {
throw new Exception("Request not permitted, host '{$host}' not present in " . 'phpQuery::$ajaxAllowedHosts');
}
// JSONP
$jsre = '/=\\?(&|$)/';
if (isset($options['dataType']) && $options['dataType'] == 'jsonp') {
$jsonpCallbackParam = $options['jsonp'] ? $options['jsonp'] : 'callback';
if (strtolower($options['type']) == 'get') {
if (!preg_match($jsre, $options['url'])) {
$sep = strpos($options['url'], '?') ? '&' : '?';
$options['url'] .= "{$sep}{$jsonpCallbackParam}=?";
}
} elseif ($options['data']) {
$jsonp = false;
foreach ($options['data'] as $n => $v) {
if ($v == '?') {
$jsonp = true;
}
}
if (!$jsonp) {
$options['data'][$jsonpCallbackParam] = '?';
}
}
$options['dataType'] = 'json';
}
if (isset($options['dataType']) && $options['dataType'] == 'json') {
$jsonpCallback = 'json_' . md5(microtime());
$jsonpData = $jsonpUrl = false;
if ($options['data']) {
foreach ($options['data'] as $n => $v) {
if ($v == '?') {
$jsonpData = $n;
}
}
}
if (preg_match($jsre, $options['url'])) {
$jsonpUrl = true;
}
if ($jsonpData !== false || $jsonpUrl) {
// remember callback name for httpData()
$options['_jsonp'] = $jsonpCallback;
if ($jsonpData !== false) {
$options['data'][$jsonpData] = $jsonpCallback;
}
if ($jsonpUrl) {
$options['url'] = preg_replace($jsre, "={$jsonpCallback}\\1", $options['url']);
}
}
}
$client->setUri($options['url']);
$client->setMethod(strtoupper($options['type']));
if (isset($options['referer']) && $options['referer']) {
$client->setHeaders('Referer', $options['referer']);
}
$client->setHeaders(array('User-Agent' => 'Mozilla/5.0 (X11; U; Linux x86; en-US; rv:1.9.0.5) Gecko' . '/2008122010 Firefox/3.0.5', 'Accept-Charset' => 'ISO-8859-1,utf-8;q=0.7,*;q=0.7', 'Accept-Language' => 'en-us,en;q=0.5'));
if ($options['username']) {
$client->setAuth($options['username'], $options['password']);
}
if (isset($options['ifModified']) && $options['ifModified']) {
$client->setHeaders('If-Modified-Since', self::$lastModified ? self::$lastModified : 'Thu, 01 Jan 1970 00:00:00 GMT');
}
$client->setHeaders('Accept', isset($options['dataType']) && isset(self::$ajaxSettings['accepts'][$options['dataType']]) ? self::$ajaxSettings['accepts'][$options['dataType']] . ', */*' : self::$ajaxSettings['accepts']['_default']);
// TODO $options['processData']
if ($options['data'] instanceof phpQueryObject) {
$serialized = $options['data']->serializeArray($options['data']);
$options['data'] = array();
foreach ($serialized as $r) {
$options['data'][$r['name']] = $r['value'];
}
}
if (strtolower($options['type']) == 'get') {
$client->setParameterGet($options['data']);
} elseif (strtolower($options['type']) == 'post') {
$client->setEncType($options['contentType']);
$client->setParameterPost($options['data']);
}
if (self::$active == 0 && $options['global']) {
phpQueryEvents::trigger($documentID, 'ajaxStart');
}
++self::$active;
// beforeSend callback
if (isset($options['beforeSend']) && $options['beforeSend']) {
self::callbackRun($options['beforeSend'], array($client));
}
// ajaxSend event
if ($options['global']) {
phpQueryEvents::trigger($documentID, 'ajaxSend', array($client, $options));
}
if (self::$debug) {
self::debug("{$options['type']}: {$options['url']}\n");
self::debug('Options: <pre>' . var_export($options, true) . "</pre>\n");
// if ($client->getCookieJar())
// self::debug("Cookies: <pre>".var_export($client->getCookieJar()->getMatchingCookies($options['url']), true)."</pre>\n");
}
// request
$response = $client->request();
if (self::$debug) {
self::debug('Status: ' . $response->getStatus() . ' / ' . $response->getMessage());
self::debug($client->getLastRequest());
self::debug($response->getHeaders());
}
if ($response->isSuccessful()) {
// XXX tempolary
self::$lastModified = $response->getHeader('Last-Modified');
$data = self::httpData($response->getBody(), $options['dataType'], $options);
if (isset($options['success']) && $options['success']) {
self::callbackRun($options['success'], array($data, $response->getStatus(), $options));
}
if ($options['global']) {
phpQueryEvents::trigger($documentID, 'ajaxSuccess', array($client, $options));
}
} else {
if (isset($options['error']) && $options['error']) {
self::callbackRun($options['error'], array($client, $response->getStatus(), $response->getMessage()));
}
if ($options['global']) {
phpQueryEvents::trigger($documentID, 'ajaxError', array($client, $response->getMessage(), $options));
}
}
if (isset($options['complete']) && $options['complete']) {
self::callbackRun($options['complete'], array($client, $response->getStatus()));
}
if ($options['global']) {
phpQueryEvents::trigger($documentID, 'ajaxComplete', array($client, $options));
}
if ($options['global'] && !--self::$active) {
phpQueryEvents::trigger($documentID, 'ajaxStop');
}
return $client;
// if (is_null($domId))
// $domId = self::$defaultDocumentID ? self::$defaultDocumentID : false;
// return new phpQueryAjaxResponse($response, $domId);
}