your scripts. */ function quoteInput($s) { if ($this->SCRIPT_DECODE_MODE == 'entities') return str_replace(array('"', '<', '>'), array('"', '<', '>'), $s); else return htmlspecialchars($s); } /** * Convert a PHP scalar, array or hash to JS scalar/array/hash. This function is * an analog of json_encode(), but it can work with a non-UTF8 input and does not * analyze the passed data. Output format must be fully JSON compatible. * * @param mixed $a Any structure to convert to JS. * @return string JavaScript equivalent structure. */ function php2js($a=false) { if (is_null($a)) return 'null'; if ($a === false) return 'false'; if ($a === true) return 'true'; if (is_scalar($a)) { if (is_float($a)) { // Always use "." for floats. $a = str_replace(",", ".", strval($a)); } // All scalars are converted to strings to avoid indeterminism. // PHP's "1" and 1 are equal for all PHP operators, but // JS's "1" and 1 are not. So if we pass "1" or 1 from the PHP backend, // we should get the same result in the JS frontend (string). // Character replacements for JSON. static $jsonReplaces = array( array("\\", "/", "\n", "\t", "\r", "\b", "\f", '"'), array('\\\\', '\\/', '\\n', '\\t', '\\r', '\\b', '\\f', '\"') ); return '"' . str_replace($jsonReplaces[0], $jsonReplaces[1], $a) . '"'; } $isList = true; for ($i = 0, reset($a); $i < count($a); $i++, next($a)) { if (key($a) !== $i) { $isList = false; break; } } $result = array(); if ($isList) { foreach ($a as $v) { $result[] = JsHttpRequest::php2js($v); } return '[ ' . join(', ', $result) . ' ]'; } else { foreach ($a as $k => $v) { $result[] = JsHttpRequest::php2js($k) . ': ' . JsHttpRequest::php2js($v); } return '{ ' . join(', ', $result) . ' }'; } } /** * Internal methods. */ /** * Parse & decode QUERY_STRING. */ function _correctSuperglobals() { // In case of FORM loader we may go to nirvana, everything is already parsed by PHP. if ($this->LOADER == 'form') return; // ATTENTION!!! // HTTP_RAW_POST_DATA is only accessible when Content-Type of POST request // is NOT default "application/x-www-form-urlencoded"!!! // Library frontend sets "application/octet-stream" for that purpose, // see JavaScript code. In PHP 5.2.2.HTTP_RAW_POST_DATA is not set sometimes; // in such cases - read the POST data manually from the STDIN stream. $rawPost = strcasecmp($_SERVER['REQUEST_METHOD'], 'POST') == 0? (isset($GLOBALS['HTTP_RAW_POST_DATA'])? $GLOBALS['HTTP_RAW_POST_DATA'] : @file_get_contents("php://input")) : null; $source = array( '_GET' => !empty($_SERVER['QUERY_STRING'])? $_SERVER['QUERY_STRING'] : null, '_POST'=> $rawPost, ); foreach ($source as $dst=>$src) { // First correct all 2-byte entities. $s = preg_replace('/%(?!5B)(?!5D)([0-9a-f]{2})/si', '%u00\\1', $src); // Now we can use standard parse_str() with no worry! $data = null; parse_str($s, $data); $GLOBALS[$dst] = $this->_ucs2EntitiesDecode($data); } $GLOBALS['HTTP_GET_VARS'] = $_GET; // deprecated vars $GLOBALS['HTTP_POST_VARS'] = $_POST; $_REQUEST = (isset($_COOKIE)? $_COOKIE : array()) + (isset($_POST)? $_POST : array()) + (isset($_GET)? $_GET : array()); if (ini_get('register_globals')) { // TODO? } } /** * Called in case of error too! */ function _obHandler($text) { unset($this->_emergBuffer); // free a piece of memory for memory_limit error unset($GLOBALS['JsHttpRequest_Active']); // Check for error & fetch a resulting data. if (preg_match("/{$this->_uniqHash}(.*?){$this->_uniqHash}/sx", $text, $m)) { if (!ini_get('display_errors') || (!$this->_prevDisplayErrors && ini_get('display_errors') == $this->_magic)) { // Display_errors: // 1. disabled manually after the library initialization, or // 2. was initially disabled and is not changed $text = str_replace($m[0], '', $text); // strip whole error message } else { $text = str_replace($this->_uniqHash, '', $text); } } if ($m && preg_match('/\bFatal error(<.*?>)?:/i', $m[1])) { // On fatal errors - force null result (generate 500 error). $this->RESULT = null; } else { // Make a resulting hash. if (!isset($this->RESULT)) { $this->RESULT = isset($GLOBALS['_RESULT'])? $GLOBALS['_RESULT'] : null; } } $encoding = $this->SCRIPT_ENCODING; $result = array( 'id' => $this->ID, 'js' => $this->RESULT, 'text' => $text, ); if (function_exists('array_walk_recursive') && function_exists('json_encode') && $this->_unicodeConvMethod) { $encoding = "UTF-8"; $this->_nonAsciiChars = join("", array_map('chr', range(128, 255))); $this->_toUtfFailed = false; array_walk_recursive($result, array(&$this, '_toUtf8_callback'), $this->SCRIPT_ENCODING); if (!$this->_toUtfFailed) { // If some key contains non-ASCII character, convert everything manually. $text = json_encode($result); } else { $text = $this->php2js($result); } } else { $text = $this->php2js($result); } // Content-type header. // In XMLHttpRequest mode we must return text/plain - damned stupid Opera 8.0. :( $ctype = !empty($this->_contentTypes[$this->LOADER])? $this->_contentTypes[$this->LOADER] : $this->_contentTypes['']; header("Content-type: $ctype; charset=$encoding"); if ($this->LOADER != "xml") { // In non-XML mode we cannot use plain JSON. So - wrap with JS function call. // If top.JsHttpRequestGlobal is not defined, loading is aborted and // iframe is removed, so - do not call dataReady(). $text = "" . ($this->LOADER == "form"? 'top && top.JsHttpRequestGlobal && top.JsHttpRequestGlobal' : 'JsHttpRequest') . ".dataReady(" . $text . ")\n" . ""; if ($this->LOADER == "form") { $text = ''; } } return $text; } /** * Internal function, used in array_walk_recursive() before json_encode() call. * If a key contains non-ASCII characters, this function sets $this->_toUtfFailed = true, * becaues array_walk_recursive() cannot modify array keys. */ function _toUtf8_callback(&$v, $k, $fromEnc) { if ($v === null || is_bool($v)) return; if ($this->_toUtfFailed || !is_scalar($v) || strpbrk($k, $this->_nonAsciiChars) !== false) { $this->_toUtfFailed = true; } else { $v = $this->_unicodeConv($fromEnc, 'UTF-8', $v); } } /** * Decode all %uXXXX entities in string or array (recurrent). * String must not contain %XX entities - they are ignored! */ function _ucs2EntitiesDecode($data) { if (is_array($data)) { $d = array(); foreach ($data as $k=>$v) { $d[$this->_ucs2EntitiesDecode($k)] = $this->_ucs2EntitiesDecode($v); } return $d; }