mirror of
https://github.com/moodle/moodle.git
synced 2025-04-21 16:32:18 +02:00
MDL-16780, MDL-24058 removing PHP4 JSON implementation and related AJAX pear stuff that is not used any more - it is buggy, so we would have to either fix it (waste of time) or we have to remove it; no core code is using this and contrib can be easily updated to use standard json_encode()
This commit is contained in:
parent
8f46ae619c
commit
c1c89e3b21
@ -1,357 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* OO AJAX Implementation for PHP, contains HTML_AJAX_Action
|
||||
*
|
||||
* SVN Rev: $Id$
|
||||
*
|
||||
* @category HTML
|
||||
* @package AJAX
|
||||
* @author Elizabeth Smith <auroraeosrose@gmail.com>
|
||||
* @copyright 2005-2008 Elizabeth Smith
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @version Release: 0.5.6
|
||||
* @link http://htmlajax.org/HTML_AJAX/Using%20haSerializer
|
||||
*/
|
||||
|
||||
/**
|
||||
* Require the response class and json serializer
|
||||
*/
|
||||
require_once 'HTML/AJAX/Response.php';
|
||||
require_once 'HTML/AJAX/Serializer/JSON.php';
|
||||
|
||||
/**
|
||||
* Helper class to eliminate the need to write javascript functions to deal with data
|
||||
*
|
||||
* This class creates information that can be properly serialized and used by
|
||||
* the haaction serializer which eliminates the need for php users to write
|
||||
* javascript for dealing with the information returned by an ajax method -
|
||||
* instead the javascript is basically created for them
|
||||
*
|
||||
* @category HTML
|
||||
* @package AJAX
|
||||
* @author Elizabeth Smith <auroraeosrose@gmail.com>
|
||||
* @copyright 2005-2008 Elizabeth Smith
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @version Release: 0.5.6
|
||||
* @link http://htmlajax.org/HTML_AJAX/Using%20haSerializer
|
||||
*/
|
||||
class HTML_AJAX_Action extends HTML_AJAX_Response
|
||||
{
|
||||
|
||||
/**
|
||||
* Content type for the HAA response
|
||||
*
|
||||
* goofy but unique content type to tell the javascript which deserializer to use
|
||||
* overrides HTML_AJAX_Response
|
||||
*
|
||||
* @var string
|
||||
* @access public
|
||||
*/
|
||||
var $contentType = 'application/html_ajax_action';
|
||||
|
||||
/**
|
||||
* An array holding all the actions for the class
|
||||
*
|
||||
* these have numeric keys and each new action is added on the end, remember
|
||||
* these are executed in the order added
|
||||
*
|
||||
* @var array
|
||||
* @access private
|
||||
*/
|
||||
var $_actions = array();
|
||||
|
||||
/**
|
||||
* Prepends data to the attribute identified by id
|
||||
*
|
||||
* The data will be added to the beginning of the attribute identified by the id
|
||||
* sent, id must be unique
|
||||
*
|
||||
* $response->prependAttr('myid', 'class', 'red');
|
||||
* $response->prependAttr('myid', array('class' => 'red', 'innerHTML' => 'this is an error'));
|
||||
*
|
||||
* @param string $id id for a specific item on the page <div id="myid"></div>
|
||||
* @param string|array $attribute either an array of attribute/data pairs or a string attribute name
|
||||
* @param mixed $data should be NULL if attribute is an array, otherwise data you wish to set the attribute to
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
function prependAttr($id, $attribute, $data = null)
|
||||
{
|
||||
if (!is_null($data)) {
|
||||
$attribute = array($attribute => $data);
|
||||
}
|
||||
$this->_actions[] = array(
|
||||
'action' => 'prepend',
|
||||
'id' => $id,
|
||||
'attributes' => $attribute,
|
||||
'data' => $data,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends data to the attribute identified by id
|
||||
*
|
||||
* The data will be added to the end of the attribute identified by the id
|
||||
* sent, id must be unique
|
||||
*
|
||||
* $response->appendAttr('myid', 'class', 'red');
|
||||
* $response->appendAttr('myid', array('class' => 'red', 'innerHTML' => 'this is an error'));
|
||||
*
|
||||
* @param string $id id for a specific item on the page <div id="myid"></div>
|
||||
* @param string|array $attribute either an array of attribute/data pairs or a string attribute name
|
||||
* @param mixed $data should be NULL if attribute is an array, otherwise data you wish to set the attribute to
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
function appendAttr($id, $attribute, $data = null)
|
||||
{
|
||||
if (!is_null($data)) {
|
||||
$attribute = array($attribute => $data);
|
||||
}
|
||||
$this->_actions[] = array(
|
||||
'action' => 'append',
|
||||
'id' => $id,
|
||||
'attributes' => $attribute,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns data to the attribute identified by id overwriting any previous values
|
||||
*
|
||||
* The data will be assigned to the attribute identified by the id
|
||||
* sent, id must be unique
|
||||
*
|
||||
* $response->assignAttr('myid', 'class', 'red');
|
||||
* $response->assignAttr('myid', array('class' => 'red', 'innerHTML' => 'this is an error'));
|
||||
*
|
||||
* @param string $id id for a specific item on the page <div id="myid"></div>
|
||||
* @param string|array $attribute either an array of attribute/data pairs or a string attribute name
|
||||
* @param mixed $data should be NULL if attribute is an array, otherwise data you wish to set the attribute to
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
function assignAttr($id, $attribute, $data = null)
|
||||
{
|
||||
if (!is_null($data)) {
|
||||
$attribute = array($attribute => $data);
|
||||
}
|
||||
$this->_actions[] = array(
|
||||
'action' => 'assign',
|
||||
'id' => $id,
|
||||
'attributes' => $attribute,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes or assigns a value of an empty string to an attribute
|
||||
*
|
||||
* You may send either a single attribute or an array of attributes to clear
|
||||
*
|
||||
* $response->clearAttr('myid', 'class');
|
||||
* $response->clearAttr('myid', array('class', 'innerHTML'));
|
||||
*
|
||||
* @param string $id id for a specific item on the page <div id="myid"></div>
|
||||
* @param string|array $attribute either an array of attribute/data pairs or a string attribute name
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
function clearAttr($id, $attribute)
|
||||
{
|
||||
if (!is_array($attribute)) {
|
||||
$attribute = array($attribute);
|
||||
}
|
||||
$this->_actions[] = array(
|
||||
'action' => 'clear',
|
||||
'id' => $id,
|
||||
'attributes' => $attribute,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* create a dom node via javascript
|
||||
*
|
||||
* higher level dom manipulation - creates a new node to insert into the dom
|
||||
* You can control where the new node is inserted with two things, the insertion
|
||||
* type and the id/ The type should be append, prepend, insertBefore, or insertAfter
|
||||
*
|
||||
* The id is a sibling node - like a div in the same div you want to add more to
|
||||
* If you choose to append or prepend a node it will be placed at the beginning
|
||||
* or end of the node with the id you send. If you choose insertBefore or
|
||||
* InsertAfter it will be put right before or right after the node you specified.
|
||||
* You can send an array of attributes to apply to the new node as well,
|
||||
* so you don't have to create it and then assign Attributes.
|
||||
*
|
||||
* <code>
|
||||
* $response->createNode('myid', 'div');
|
||||
* $response->createNode('submit', 'input',
|
||||
* array('id' => 'key',
|
||||
* 'name' => 'key',
|
||||
* 'type' => 'hidden',
|
||||
* 'value' => $id),
|
||||
* 'insertBefore');
|
||||
* <code>
|
||||
*
|
||||
* @param string $id id for a specific item on the page <div id="myid"></div>
|
||||
* @param string $tag html node to create
|
||||
* @param array $attributes array of attribute -> data to fill the node with
|
||||
* @param string $type append|prepend|insertBefore|insertAfter default is append
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
function createNode($id, $tag, $attributes, $type = 'append')
|
||||
{
|
||||
$types = array('append', 'prepend', 'insertBefore', 'insertAfter');
|
||||
if (!in_array($type, $types)) {
|
||||
$type = 'append';
|
||||
}
|
||||
settype($attributes, 'array');
|
||||
$this->_actions[] = array(
|
||||
'action' => 'create',
|
||||
'id' => $id,
|
||||
'tag' => $tag,
|
||||
'attributes' => $attributes,
|
||||
'type' => $type,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace a dom node via javascript
|
||||
*
|
||||
* higher level dom manipulation - replaces one node with another
|
||||
* This can be used to replace a div with a form for inline editing
|
||||
* use innerHtml attribute to change inside text
|
||||
*
|
||||
* $response->replaceNode('myid', 'div', array('innerHTML' => 'loading complete'));
|
||||
* $response->replaceNode('mydiv', 'form', array('innerHTML' => $form));
|
||||
*
|
||||
* @param string $id id for a specific item on the page <div id="myid"></div>
|
||||
* @param string $tag html node to create
|
||||
* @param array $attributes array of attribute -> data to fill the node with
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
function replaceNode($id, $tag, $attributes)
|
||||
{
|
||||
settype($attributes, 'array');
|
||||
$this->_actions[] = array(
|
||||
'action' => 'replace',
|
||||
'id' => $id,
|
||||
'tag' => $tag,
|
||||
'attributes' => $attributes,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a dom node via javascript
|
||||
*
|
||||
* $response->removeNode('myid');
|
||||
* $response->removeNode(array('mydiv', 'myform'));
|
||||
*
|
||||
* @param string $id id for a specific item on the page <div id="myid"></div>
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
function removeNode($id)
|
||||
{
|
||||
$this->_actions[] = array(
|
||||
'action' => 'remove',
|
||||
'id' => $id,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a string to a javascript eval
|
||||
*
|
||||
* This will send the data right to the eval javascript function, it will NOT
|
||||
* allow you to dynamically add a javascript function for use later on because
|
||||
* it is constrined by the eval function
|
||||
*
|
||||
* @param string $data string to pass to the alert javascript function
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
function insertScript($data)
|
||||
{
|
||||
$this->_actions[] = array(
|
||||
'action' => 'script',
|
||||
'data' => $data,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a string to a javascript alert
|
||||
*
|
||||
* This will send the data right to the alert javascript function
|
||||
*
|
||||
* @param string $data string to pass to the alert javascript function
|
||||
*
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
function insertAlert($data)
|
||||
{
|
||||
$this->_actions[] = array(
|
||||
'action' => 'alert',
|
||||
'data' => $data,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the serialized content of the response class
|
||||
*
|
||||
* we actually use the json serializer underneath, so we send the actions array
|
||||
* to the json serializer and return the data
|
||||
*
|
||||
* @return string serialized response content
|
||||
* @access public
|
||||
*/
|
||||
function getPayload()
|
||||
{
|
||||
$serializer = new HTML_AJAX_Serializer_JSON();
|
||||
return $serializer->serialize($this->_actions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds all the actions from one response object to another, feature request
|
||||
* #6635 at pear.php.net
|
||||
*
|
||||
* @param object &$instance referenced HTML_AJAX_Action object
|
||||
*
|
||||
* @return array
|
||||
* @access public
|
||||
*/
|
||||
function combineActions(&$instance)
|
||||
{
|
||||
$this->_actions = array_merge($this->_actions, $instance->retrieveActions());
|
||||
}
|
||||
|
||||
/**
|
||||
* to follow proper property access we need a way to retrieve the private
|
||||
* actions array
|
||||
*
|
||||
* @return array
|
||||
* @access public
|
||||
*/
|
||||
function retrieveActions()
|
||||
{
|
||||
return $this->_actions;
|
||||
}
|
||||
}
|
||||
?>
|
@ -1,144 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* AJAX Debugging implementation
|
||||
*
|
||||
* SVN Rev: $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* Newline to use
|
||||
*/
|
||||
define ("HTML_AJAX_NEWLINE", "\n");
|
||||
|
||||
// {{{ class HTML_AJAX_Debug
|
||||
/**
|
||||
* AJAX Debugging implementation
|
||||
*
|
||||
* @category HTML
|
||||
* @package AJAX
|
||||
* @author David Coallier <davidc@php.net>
|
||||
* @copyright 2005 David Coallier
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @version Release: 0.5.6
|
||||
*/
|
||||
class HTML_AJAX_Debug {
|
||||
// {{{ properties
|
||||
/**
|
||||
* This is the error message.
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
var $errorMsg;
|
||||
|
||||
/**
|
||||
* The line where the error occured.
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
var $errorLine;
|
||||
|
||||
/**
|
||||
* The error code.
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
var $errorCode;
|
||||
|
||||
/**
|
||||
* The file where the error occured.
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
var $errorFile;
|
||||
|
||||
/**
|
||||
* Time the error occured
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
var $_timeOccured;
|
||||
|
||||
/**
|
||||
* The whole error itself
|
||||
*
|
||||
* @access private
|
||||
* @see errorMsg
|
||||
* @see errorLine
|
||||
* @see errorFile
|
||||
* @see errorCode
|
||||
*/
|
||||
var $error;
|
||||
|
||||
/**
|
||||
* The file to save the error to.
|
||||
*
|
||||
* @access private
|
||||
* @default ajaxErrLog.xml
|
||||
*/
|
||||
var $file = 'ajaxErrLog.xml';
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
/**
|
||||
* The constructor.
|
||||
*
|
||||
* @param string $errorMsg The error message.
|
||||
* @param string $errLine The line where error occured.
|
||||
* @param string $errCode The error Code.
|
||||
* @param string $errFile The file where error occured.
|
||||
*/
|
||||
function HTML_AJAX_Debug($errMsg, $errLine, $errCode, $errFile)
|
||||
{
|
||||
$this->errorMsg = $errMsg;
|
||||
$this->errorLine = $errLine;
|
||||
$this->errorCode = $errCode;
|
||||
$this->errorFile = $errFile;
|
||||
$this->_timeOccured = date("Y-m-d H:i:s", time());
|
||||
$this->xmlError();
|
||||
}
|
||||
// }}}
|
||||
// {{{ xmlError
|
||||
/**
|
||||
* This functions formats the error to xml format then we can save it.
|
||||
*
|
||||
* @access protected
|
||||
* @return $this->error the main error.
|
||||
*/
|
||||
function xmlError()
|
||||
{
|
||||
$error = " <when>{$this->_timeOccured}</when>" . HTML_AJAX_NEWLINE;
|
||||
$error .= " <msg>{$this->errorMsg}</msg>" . HTML_AJAX_NEWLINE;
|
||||
$error .= " <code>{$this->errorCode}</code>" . HTML_AJAX_NEWLINE;
|
||||
$error .= " <line>{$this->errorLine}</line>" . HTML_AJAX_NEWLINE;
|
||||
$error .= " <file>{$this->errorFile}</file>" . HTML_AJAX_NEWLINE . HTML_AJAX_NEWLINE;
|
||||
return $this->error = $error;
|
||||
}
|
||||
// }}}
|
||||
// {{{ sessionError
|
||||
/**
|
||||
* This function pushes the array $_SESSION['html_ajax_debug']['time'][]
|
||||
* with the values inside of $this->error
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function sessionError()
|
||||
{
|
||||
$_SESSION['html_ajax_debug']['time'][] = $this->error;
|
||||
}
|
||||
// }}}
|
||||
// {{{ _saveError
|
||||
/**
|
||||
* This function saves the error to a file
|
||||
* appending to this file.
|
||||
*
|
||||
* @access private.
|
||||
*/
|
||||
function _saveError()
|
||||
{
|
||||
if ($handle = fopen($this->file, 'a')) {
|
||||
fwrite($handle, $this->error);
|
||||
}
|
||||
}
|
||||
// }}}
|
||||
}
|
||||
// }}}
|
||||
?>
|
@ -1,186 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* HTML/JavaScript Generation Helper
|
||||
*
|
||||
* SVN Rev: $Id$
|
||||
*
|
||||
* @category HTML
|
||||
* @package AJAX
|
||||
* @author Joshua Eichorn <josh@bluga.net>
|
||||
* @copyright 2005 Joshua Eichorn
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @version Release: 0.5.6
|
||||
*/
|
||||
|
||||
/**
|
||||
* HTML/JavaScript Generation Helper
|
||||
*
|
||||
* @category HTML
|
||||
* @package AJAX
|
||||
* @author Joshua Eichorn <josh@bluga.net>
|
||||
* @copyright 2005 Joshua Eichorn
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @version Release: 0.5.6
|
||||
* @link http://pear.php.net/package/HTML_AJAX
|
||||
*/
|
||||
class HTML_AJAX_Helper
|
||||
{
|
||||
/**
|
||||
* URL where an HTML_AJAX_Server instance is serving up clients and taking ajax requests
|
||||
*/
|
||||
var $serverUrl = 'server.php';
|
||||
|
||||
/**
|
||||
* JS libraries to include
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
var $jsLibraries = array('Util','Main','Request','HttpClient','Dispatcher','Behavior','Loading','JSON','iframe');
|
||||
|
||||
/**
|
||||
* Remote class stubs to include
|
||||
*/
|
||||
var $stubs = array();
|
||||
|
||||
/**
|
||||
* Combine jsLibraries into a single require and remove duplicates
|
||||
*/
|
||||
var $combineJsIncludes = false;
|
||||
|
||||
/**
|
||||
* Include all needed libraries, stubs, and set defaultServer
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function setupAJAX()
|
||||
{
|
||||
$libs = array(0=>array());
|
||||
$combinedLibs = array();
|
||||
|
||||
$this->jsLibraries = array_unique($this->jsLibraries);
|
||||
foreach($this->jsLibraries as $library) {
|
||||
if (is_array($library)) {
|
||||
$library = array_unique($library);
|
||||
$combinedLibs = array_merge($combinedLibs,$library);
|
||||
$libs[] = implode(',',$library);
|
||||
}
|
||||
else {
|
||||
$libs[0][] = $library;
|
||||
$combinedLibs[] = $library;
|
||||
}
|
||||
}
|
||||
$libs[0] = implode(',',$libs[0]);
|
||||
|
||||
$sep = '?';
|
||||
if (strstr($this->serverUrl,'?')) {
|
||||
$sep = '&';
|
||||
}
|
||||
|
||||
$ret = '';
|
||||
if ($this->combineJsIncludes == true) {
|
||||
$list = implode(',',$combinedLibs);
|
||||
$ret .= "<script type='text/javascript' src='{$this->serverUrl}{$sep}client={$list}'></script>\n";
|
||||
}
|
||||
else {
|
||||
foreach($libs as $list) {
|
||||
$ret .= "<script type='text/javascript' src='{$this->serverUrl}{$sep}client={$list}'></script>\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (count($this->stubs) > 0) {
|
||||
$stubs = implode(',',$this->stubs);
|
||||
$ret .= "<script type='text/javascript' src='{$this->serverUrl}{$sep}stub={$stubs}'></script>\n";
|
||||
}
|
||||
$ret .= $this->encloseInScript('HTML_AJAX.defaultServerUrl = '.$this->escape($this->serverUrl));
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a custom Loading message
|
||||
*
|
||||
* @param string $body HTML body of the loading div
|
||||
* @param string $class CSS class of the div
|
||||
* @param string $style style tag of the loading div
|
||||
*/
|
||||
function loadingMessage($body, $class = 'HTML_AJAX_Loading',
|
||||
$style = 'position: absolute; top: 0; right: 0; background-color: red; width: 80px; padding: 4px; display: none')
|
||||
{
|
||||
return "<div id='HTML_AJAX_LOADING' class='{$class}' style=\"{$style}\">{$body}</div>\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the contents of an element using ajax
|
||||
*
|
||||
* @param string $id id of the element to update
|
||||
* @param string|array $update Either a url to update with or a array like array('class','method')
|
||||
* @param string $type replace or append
|
||||
* @param boolean $enclose
|
||||
*/
|
||||
function updateElement($id, $update, $type, $enclose = false) {
|
||||
if (is_array($update)) {
|
||||
$updateStr = "";
|
||||
$comma = '';
|
||||
foreach($update as $item) {
|
||||
$updateStr .= $comma.$this->escape($item);
|
||||
$comma = ',';
|
||||
}
|
||||
}
|
||||
else {
|
||||
$updateStr = $this->escape($update);
|
||||
}
|
||||
|
||||
$ret = "HTML_AJAX.{$type}(".$this->escape($id).",{$updateStr});\n";
|
||||
if ($enclose) {
|
||||
$ret = $this->encloseInScript($ret);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape a string and add quotes allowing it to be a javascript paramater
|
||||
*
|
||||
* @param string $input
|
||||
* @return string
|
||||
* @todo do something here besides a quick hack
|
||||
*/
|
||||
function escape($input) {
|
||||
return "'".addslashes($input)."'";
|
||||
}
|
||||
|
||||
/**
|
||||
* Enclose a string in a script block
|
||||
*
|
||||
* @param string $input
|
||||
* @return string
|
||||
*/
|
||||
function encloseInScript($input) {
|
||||
return '<script type="text/javascript">'.$input."</script>\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a JSON String
|
||||
*
|
||||
* @param string $input
|
||||
* @return string
|
||||
*/
|
||||
function jsonEncode($input) {
|
||||
require_once 'HTML/AJAX/Serializer/JSON.php';
|
||||
|
||||
$s = new HTML_AJAX_Serializer_JSON();
|
||||
return $s->serialize($input);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the request headers to see if this is an AJAX request
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
function isAJAX() {
|
||||
if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest') {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
?>
|
@ -1,819 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* This is an embedded version of HTML_AJAX_JSON since it has yet to have
|
||||
* a PEAR release it has been renamed to HTML_AJAX_JSON so no problems
|
||||
* will be caused by an eventual release
|
||||
* Feel free to report bugs against it to HTML_AJAX
|
||||
*
|
||||
* SVN Rev: $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* Needed for compat functions
|
||||
*/
|
||||
require_once 'HTML/AJAX.php';
|
||||
|
||||
/**
|
||||
* Converts to and from JSON format.
|
||||
*
|
||||
* JSON (JavaScript Object Notation) is a lightweight data-interchange
|
||||
* format. It is easy for humans to read and write. It is easy for machines
|
||||
* to parse and generate. It is based on a subset of the JavaScript
|
||||
* Programming Language, Standard ECMA-262 3rd Edition - December 1999.
|
||||
* This feature can also be found in Python. JSON is a text format that is
|
||||
* completely language independent but uses conventions that are familiar
|
||||
* to programmers of the C-family of languages, including C, C++, C#, Java,
|
||||
* JavaScript, Perl, TCL, and many others. These properties make JSON an
|
||||
* ideal data-interchange language.
|
||||
*
|
||||
* This package provides a simple encoder and decoder for JSON notation. It
|
||||
* is intended for use with client-side Javascript applications that make
|
||||
* use of HTTPRequest to perform server communication functions - data can
|
||||
* be encoded into JSON notation for use in a client-side javascript, or
|
||||
* decoded from incoming Javascript requests. JSON format is native to
|
||||
* Javascript, and can be directly eval()'ed with no further parsing
|
||||
* overhead
|
||||
*
|
||||
* All strings should be in ASCII or UTF-8 format!
|
||||
*
|
||||
* LICENSE: Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met: Redistributions of source code must retain the
|
||||
* above copyright notice, this list of conditions and the following
|
||||
* disclaimer. Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
* NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
* @category
|
||||
* @package HTML_AJAX_JSON
|
||||
* @author Michal Migurski <mike-json@teczno.com>
|
||||
* @author Matt Knapp <mdknapp[at]gmail[dot]com>
|
||||
* @author Brett Stimmerman <brettstimmerman[at]gmail[dot]com>
|
||||
* @copyright 2005 Michal Migurski
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php
|
||||
* @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198
|
||||
*/
|
||||
|
||||
/**
|
||||
* Marker constant for HTML_AJAX_JSON::decode(), used to flag stack state
|
||||
*/
|
||||
define('SERVICES_JSON_SLICE', 1);
|
||||
|
||||
/**
|
||||
* Marker constant for HTML_AJAX_JSON::decode(), used to flag stack state
|
||||
*/
|
||||
define('SERVICES_JSON_IN_STR', 2);
|
||||
|
||||
/**
|
||||
* Marker constant for HTML_AJAX_JSON::decode(), used to flag stack state
|
||||
*/
|
||||
define('SERVICES_JSON_IN_ARR', 3);
|
||||
|
||||
/**
|
||||
* Marker constant for HTML_AJAX_JSON::decode(), used to flag stack state
|
||||
*/
|
||||
define('SERVICES_JSON_IN_OBJ', 4);
|
||||
|
||||
/**
|
||||
* Marker constant for HTML_AJAX_JSON::decode(), used to flag stack state
|
||||
*/
|
||||
define('SERVICES_JSON_IN_CMT', 5);
|
||||
|
||||
/**
|
||||
* Behavior switch for HTML_AJAX_JSON::decode()
|
||||
*/
|
||||
define('SERVICES_JSON_LOOSE_TYPE', 16);
|
||||
|
||||
/**
|
||||
* Behavior switch for HTML_AJAX_JSON::decode()
|
||||
*/
|
||||
define('SERVICES_JSON_SUPPRESS_ERRORS', 32);
|
||||
|
||||
/**
|
||||
* Converts to and from JSON format.
|
||||
*
|
||||
* Brief example of use:
|
||||
*
|
||||
* <code>
|
||||
* // create a new instance of HTML_AJAX_JSON
|
||||
* $json = new HTML_AJAX_JSON();
|
||||
*
|
||||
* // convert a complexe value to JSON notation, and send it to the browser
|
||||
* $value = array('foo', 'bar', array(1, 2, 'baz'), array(3, array(4)));
|
||||
* $output = $json->encode($value);
|
||||
*
|
||||
* print($output);
|
||||
* // prints: ["foo","bar",[1,2,"baz"],[3,[4]]]
|
||||
*
|
||||
* // accept incoming POST data, assumed to be in JSON notation
|
||||
* $input = file_get_contents('php://input', 1000000);
|
||||
* $value = $json->decode($input);
|
||||
* </code>
|
||||
*/
|
||||
class HTML_AJAX_JSON
|
||||
{
|
||||
/**
|
||||
* constructs a new JSON instance
|
||||
*
|
||||
* @param int $use object behavior flags; combine with boolean-OR
|
||||
*
|
||||
* possible values:
|
||||
* - SERVICES_JSON_LOOSE_TYPE: loose typing.
|
||||
* "{...}" syntax creates associative arrays
|
||||
* instead of objects in decode().
|
||||
* - SERVICES_JSON_SUPPRESS_ERRORS: error suppression.
|
||||
* Values which can't be encoded (e.g. resources)
|
||||
* appear as NULL instead of throwing errors.
|
||||
* By default, a deeply-nested resource will
|
||||
* bubble up with an error, so all return values
|
||||
* from encode() should be checked with isError()
|
||||
*/
|
||||
function HTML_AJAX_JSON($use = 0)
|
||||
{
|
||||
$this->use = $use;
|
||||
}
|
||||
|
||||
/**
|
||||
* convert a string from one UTF-16 char to one UTF-8 char
|
||||
*
|
||||
* Normally should be handled by mb_convert_encoding, but
|
||||
* provides a slower PHP-only method for installations
|
||||
* that lack the multibye string extension.
|
||||
*
|
||||
* @param string $utf16 UTF-16 character
|
||||
* @return string UTF-8 character
|
||||
* @access private
|
||||
*/
|
||||
function utf162utf8($utf16)
|
||||
{
|
||||
// oh please oh please oh please oh please oh please
|
||||
if(function_exists('mb_convert_encoding'))
|
||||
return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16');
|
||||
|
||||
$bytes = (ord($utf16{0}) << 8) | ord($utf16{1});
|
||||
|
||||
switch(true) {
|
||||
case ((0x7F & $bytes) == $bytes):
|
||||
// this case should never be reached, because we are in ASCII range
|
||||
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
return chr(0x7F & $bytes);
|
||||
|
||||
case (0x07FF & $bytes) == $bytes:
|
||||
// return a 2-byte UTF-8 character
|
||||
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
return chr(0xC0 | (($bytes >> 6) & 0x1F))
|
||||
. chr(0x80 | ($bytes & 0x3F));
|
||||
|
||||
case (0xFFFF & $bytes) == $bytes:
|
||||
// return a 3-byte UTF-8 character
|
||||
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
return chr(0xE0 | (($bytes >> 12) & 0x0F))
|
||||
. chr(0x80 | (($bytes >> 6) & 0x3F))
|
||||
. chr(0x80 | ($bytes & 0x3F));
|
||||
}
|
||||
|
||||
// ignoring UTF-32 for now, sorry
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* convert a string from one UTF-8 char to one UTF-16 char
|
||||
*
|
||||
* Normally should be handled by mb_convert_encoding, but
|
||||
* provides a slower PHP-only method for installations
|
||||
* that lack the multibye string extension.
|
||||
*
|
||||
* @param string $utf8 UTF-8 character
|
||||
* @return string UTF-16 character
|
||||
* @access private
|
||||
*/
|
||||
function utf82utf16($utf8)
|
||||
{
|
||||
// oh please oh please oh please oh please oh please
|
||||
if(function_exists('mb_convert_encoding'))
|
||||
return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
|
||||
|
||||
switch(strlen($utf8)) {
|
||||
case 1:
|
||||
// this case should never be reached, because we are in ASCII range
|
||||
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
return $utf8;
|
||||
|
||||
case 2:
|
||||
// return a UTF-16 character from a 2-byte UTF-8 char
|
||||
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
return chr(0x07 & (ord($utf8{0}) >> 2))
|
||||
. chr((0xC0 & (ord($utf8{0}) << 6))
|
||||
| (0x3F & ord($utf8{1})));
|
||||
|
||||
case 3:
|
||||
// return a UTF-16 character from a 3-byte UTF-8 char
|
||||
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
return chr((0xF0 & (ord($utf8{0}) << 4))
|
||||
| (0x0F & (ord($utf8{1}) >> 2)))
|
||||
. chr((0xC0 & (ord($utf8{1}) << 6))
|
||||
| (0x7F & ord($utf8{2})));
|
||||
}
|
||||
|
||||
// ignoring UTF-32 for now, sorry
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* encodes an arbitrary variable into JSON format
|
||||
*
|
||||
* @param mixed $var any number, boolean, string, array, or object to be encoded.
|
||||
* see argument 1 to HTML_AJAX_JSON() above for array-parsing behavior.
|
||||
* if var is a strng, note that encode() always expects it
|
||||
* to be in ASCII or UTF-8 format!
|
||||
*
|
||||
* @return mixed JSON string representation of input var or an error if a problem occurs
|
||||
* @access public
|
||||
*/
|
||||
function encode($var)
|
||||
{
|
||||
switch (gettype($var)) {
|
||||
case 'boolean':
|
||||
return $var ? 'true' : 'false';
|
||||
|
||||
case 'NULL':
|
||||
return 'null';
|
||||
|
||||
case 'integer':
|
||||
return (int) $var;
|
||||
|
||||
case 'double':
|
||||
case 'float':
|
||||
return (float) $var;
|
||||
|
||||
case 'string':
|
||||
// STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT
|
||||
$ascii = '';
|
||||
$strlen_var = strlen($var);
|
||||
|
||||
/*
|
||||
* Iterate over every character in the string,
|
||||
* escaping with a slash or encoding to UTF-8 where necessary
|
||||
*/
|
||||
for ($c = 0; $c < $strlen_var; ++$c) {
|
||||
|
||||
$ord_var_c = ord($var{$c});
|
||||
|
||||
switch (true) {
|
||||
case $ord_var_c == 0x08:
|
||||
$ascii .= '\b';
|
||||
break;
|
||||
case $ord_var_c == 0x09:
|
||||
$ascii .= '\t';
|
||||
break;
|
||||
case $ord_var_c == 0x0A:
|
||||
$ascii .= '\n';
|
||||
break;
|
||||
case $ord_var_c == 0x0C:
|
||||
$ascii .= '\f';
|
||||
break;
|
||||
case $ord_var_c == 0x0D:
|
||||
$ascii .= '\r';
|
||||
break;
|
||||
|
||||
case $ord_var_c == 0x22:
|
||||
case $ord_var_c == 0x2F:
|
||||
case $ord_var_c == 0x5C:
|
||||
// double quote, slash, slosh
|
||||
$ascii .= '\\'.$var{$c};
|
||||
break;
|
||||
|
||||
case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)):
|
||||
// characters U-00000000 - U-0000007F (same as ASCII)
|
||||
$ascii .= $var{$c};
|
||||
break;
|
||||
|
||||
case (($ord_var_c & 0xE0) == 0xC0):
|
||||
// characters U-00000080 - U-000007FF, mask 110XXXXX
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$char = pack('C*', $ord_var_c, ord($var{$c + 1}));
|
||||
$c += 1;
|
||||
$utf16 = $this->utf82utf16($char);
|
||||
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
||||
break;
|
||||
|
||||
case (($ord_var_c & 0xF0) == 0xE0):
|
||||
// characters U-00000800 - U-0000FFFF, mask 1110XXXX
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$char = pack('C*', $ord_var_c,
|
||||
ord($var{$c + 1}),
|
||||
ord($var{$c + 2}));
|
||||
$c += 2;
|
||||
$utf16 = $this->utf82utf16($char);
|
||||
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
||||
break;
|
||||
|
||||
case (($ord_var_c & 0xF8) == 0xF0):
|
||||
// characters U-00010000 - U-001FFFFF, mask 11110XXX
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$char = pack('C*', $ord_var_c,
|
||||
ord($var{$c + 1}),
|
||||
ord($var{$c + 2}),
|
||||
ord($var{$c + 3}));
|
||||
$c += 3;
|
||||
$utf16 = $this->utf82utf16($char);
|
||||
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
||||
break;
|
||||
|
||||
case (($ord_var_c & 0xFC) == 0xF8):
|
||||
// characters U-00200000 - U-03FFFFFF, mask 111110XX
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$char = pack('C*', $ord_var_c,
|
||||
ord($var{$c + 1}),
|
||||
ord($var{$c + 2}),
|
||||
ord($var{$c + 3}),
|
||||
ord($var{$c + 4}));
|
||||
$c += 4;
|
||||
$utf16 = $this->utf82utf16($char);
|
||||
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
||||
break;
|
||||
|
||||
case (($ord_var_c & 0xFE) == 0xFC):
|
||||
// characters U-04000000 - U-7FFFFFFF, mask 1111110X
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$char = pack('C*', $ord_var_c,
|
||||
ord($var{$c + 1}),
|
||||
ord($var{$c + 2}),
|
||||
ord($var{$c + 3}),
|
||||
ord($var{$c + 4}),
|
||||
ord($var{$c + 5}));
|
||||
$c += 5;
|
||||
$utf16 = $this->utf82utf16($char);
|
||||
$ascii .= sprintf('\u%04s', bin2hex($utf16));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return '"'.$ascii.'"';
|
||||
|
||||
case 'array':
|
||||
/*
|
||||
* As per JSON spec if any array key is not an integer
|
||||
* we must treat the the whole array as an object. We
|
||||
* also try to catch a sparsely populated associative
|
||||
* array with numeric keys here because some JS engines
|
||||
* will create an array with empty indexes up to
|
||||
* max_index which can cause memory issues and because
|
||||
* the keys, which may be relevant, will be remapped
|
||||
* otherwise.
|
||||
*
|
||||
* As per the ECMA and JSON specification an object may
|
||||
* have any string as a property. Unfortunately due to
|
||||
* a hole in the ECMA specification if the key is a
|
||||
* ECMA reserved word or starts with a digit the
|
||||
* parameter is only accessible using ECMAScript's
|
||||
* bracket notation.
|
||||
*/
|
||||
|
||||
// treat as a JSON object
|
||||
if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) {
|
||||
$properties = array_map(array($this, 'name_value'),
|
||||
array_keys($var),
|
||||
array_values($var));
|
||||
|
||||
foreach($properties as $property)
|
||||
if(HTML_AJAX_JSON::isError($property))
|
||||
return $property;
|
||||
|
||||
return '{' . join(',', $properties) . '}';
|
||||
}
|
||||
|
||||
// treat it like a regular array
|
||||
$elements = array_map(array($this, 'encode'), $var);
|
||||
|
||||
foreach($elements as $element)
|
||||
if(HTML_AJAX_JSON::isError($element))
|
||||
return $element;
|
||||
|
||||
return '[' . join(',', $elements) . ']';
|
||||
|
||||
case 'object':
|
||||
$vars = get_object_vars($var);
|
||||
|
||||
$properties = array_map(array($this, 'name_value'),
|
||||
array_keys($vars),
|
||||
array_values($vars));
|
||||
|
||||
foreach($properties as $property)
|
||||
if(HTML_AJAX_JSON::isError($property))
|
||||
return $property;
|
||||
|
||||
return '{' . join(',', $properties) . '}';
|
||||
|
||||
default:
|
||||
return ($this->use & SERVICES_JSON_SUPPRESS_ERRORS)
|
||||
? 'null'
|
||||
: new HTML_AJAX_JSON_Error(gettype($var)." can not be encoded as JSON string");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* array-walking function for use in generating JSON-formatted name-value pairs
|
||||
*
|
||||
* @param string $name name of key to use
|
||||
* @param mixed $value reference to an array element to be encoded
|
||||
*
|
||||
* @return string JSON-formatted name-value pair, like '"name":value'
|
||||
* @access private
|
||||
*/
|
||||
function name_value($name, $value)
|
||||
{
|
||||
$encoded_value = $this->encode($value);
|
||||
|
||||
if(HTML_AJAX_JSON::isError($encoded_value))
|
||||
return $encoded_value;
|
||||
|
||||
return $this->encode(strval($name)) . ':' . $encoded_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* reduce a string by removing leading and trailing comments and whitespace
|
||||
*
|
||||
* @param $str string string value to strip of comments and whitespace
|
||||
*
|
||||
* @return string string value stripped of comments and whitespace
|
||||
* @access private
|
||||
*/
|
||||
function reduce_string($str)
|
||||
{
|
||||
$str = preg_replace(array(
|
||||
|
||||
// eliminate single line comments in '// ...' form
|
||||
'#^\s*//(.+)$#m',
|
||||
|
||||
// eliminate multi-line comments in '/* ... */' form, at start of string
|
||||
'#^\s*/\*(.+)\*/#Us',
|
||||
|
||||
// eliminate multi-line comments in '/* ... */' form, at end of string
|
||||
'#/\*(.+)\*/\s*$#Us'
|
||||
|
||||
), '', $str);
|
||||
|
||||
// eliminate extraneous space
|
||||
return trim($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* decodes a JSON string into appropriate variable
|
||||
*
|
||||
* @param string $str JSON-formatted string
|
||||
*
|
||||
* @return mixed number, boolean, string, array, or object
|
||||
* corresponding to given JSON input string.
|
||||
* See argument 1 to HTML_AJAX_JSON() above for object-output behavior.
|
||||
* Note that decode() always returns strings
|
||||
* in ASCII or UTF-8 format!
|
||||
* @access public
|
||||
*/
|
||||
function decode($str)
|
||||
{
|
||||
$str = $this->reduce_string($str);
|
||||
|
||||
switch (strtolower($str)) {
|
||||
case 'true':
|
||||
return true;
|
||||
|
||||
case 'false':
|
||||
return false;
|
||||
|
||||
case 'null':
|
||||
return null;
|
||||
|
||||
default:
|
||||
if (is_numeric($str)) {
|
||||
// Lookie-loo, it's a number
|
||||
|
||||
// This would work on its own, but I'm trying to be
|
||||
// good about returning integers where appropriate:
|
||||
// return (float)$str;
|
||||
|
||||
// Return float or int, as appropriate
|
||||
return ((float)$str == (integer)$str)
|
||||
? (integer)$str
|
||||
: (float)$str;
|
||||
|
||||
} elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) {
|
||||
// STRINGS RETURNED IN UTF-8 FORMAT
|
||||
$delim = substr($str, 0, 1);
|
||||
$chrs = substr($str, 1, -1);
|
||||
$utf8 = '';
|
||||
$strlen_chrs = strlen($chrs);
|
||||
|
||||
for ($c = 0; $c < $strlen_chrs; ++$c) {
|
||||
|
||||
$substr_chrs_c_2 = substr($chrs, $c, 2);
|
||||
$ord_chrs_c = ord($chrs{$c});
|
||||
|
||||
switch (true) {
|
||||
case $substr_chrs_c_2 == '\b':
|
||||
$utf8 .= chr(0x08);
|
||||
++$c;
|
||||
break;
|
||||
case $substr_chrs_c_2 == '\t':
|
||||
$utf8 .= chr(0x09);
|
||||
++$c;
|
||||
break;
|
||||
case $substr_chrs_c_2 == '\n':
|
||||
$utf8 .= chr(0x0A);
|
||||
++$c;
|
||||
break;
|
||||
case $substr_chrs_c_2 == '\f':
|
||||
$utf8 .= chr(0x0C);
|
||||
++$c;
|
||||
break;
|
||||
case $substr_chrs_c_2 == '\r':
|
||||
$utf8 .= chr(0x0D);
|
||||
++$c;
|
||||
break;
|
||||
|
||||
case $substr_chrs_c_2 == '\\"':
|
||||
case $substr_chrs_c_2 == '\\\'':
|
||||
case $substr_chrs_c_2 == '\\\\':
|
||||
case $substr_chrs_c_2 == '\\/':
|
||||
if (($delim == '"' && $substr_chrs_c_2 != '\\\'') ||
|
||||
($delim == "'" && $substr_chrs_c_2 != '\\"')) {
|
||||
$utf8 .= $chrs{++$c};
|
||||
}
|
||||
break;
|
||||
|
||||
case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)):
|
||||
// single, escaped unicode character
|
||||
$utf16 = chr(hexdec(substr($chrs, ($c + 2), 2)))
|
||||
. chr(hexdec(substr($chrs, ($c + 4), 2)));
|
||||
$utf8 .= $this->utf162utf8($utf16);
|
||||
$c += 5;
|
||||
break;
|
||||
|
||||
case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F):
|
||||
$utf8 .= $chrs{$c};
|
||||
break;
|
||||
|
||||
case ($ord_chrs_c & 0xE0) == 0xC0:
|
||||
// characters U-00000080 - U-000007FF, mask 110XXXXX
|
||||
//see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$utf8 .= substr($chrs, $c, 2);
|
||||
++$c;
|
||||
break;
|
||||
|
||||
case ($ord_chrs_c & 0xF0) == 0xE0:
|
||||
// characters U-00000800 - U-0000FFFF, mask 1110XXXX
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$utf8 .= substr($chrs, $c, 3);
|
||||
$c += 2;
|
||||
break;
|
||||
|
||||
case ($ord_chrs_c & 0xF8) == 0xF0:
|
||||
// characters U-00010000 - U-001FFFFF, mask 11110XXX
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$utf8 .= substr($chrs, $c, 4);
|
||||
$c += 3;
|
||||
break;
|
||||
|
||||
case ($ord_chrs_c & 0xFC) == 0xF8:
|
||||
// characters U-00200000 - U-03FFFFFF, mask 111110XX
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$utf8 .= substr($chrs, $c, 5);
|
||||
$c += 4;
|
||||
break;
|
||||
|
||||
case ($ord_chrs_c & 0xFE) == 0xFC:
|
||||
// characters U-04000000 - U-7FFFFFFF, mask 1111110X
|
||||
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
||||
$utf8 .= substr($chrs, $c, 6);
|
||||
$c += 5;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $utf8;
|
||||
|
||||
} elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) {
|
||||
// array, or object notation
|
||||
|
||||
if ($str{0} == '[') {
|
||||
$stk = array(SERVICES_JSON_IN_ARR);
|
||||
$arr = array();
|
||||
} else {
|
||||
if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
|
||||
$stk = array(SERVICES_JSON_IN_OBJ);
|
||||
$obj = array();
|
||||
} else {
|
||||
$stk = array(SERVICES_JSON_IN_OBJ);
|
||||
$obj = new stdClass();
|
||||
}
|
||||
}
|
||||
|
||||
array_push($stk, array('what' => SERVICES_JSON_SLICE,
|
||||
'where' => 0,
|
||||
'delim' => false));
|
||||
|
||||
$chrs = substr($str, 1, -1);
|
||||
$chrs = $this->reduce_string($chrs);
|
||||
|
||||
if ($chrs == '') {
|
||||
if (reset($stk) == SERVICES_JSON_IN_ARR) {
|
||||
return $arr;
|
||||
|
||||
} else {
|
||||
return $obj;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//print("\nparsing {$chrs}\n");
|
||||
|
||||
$strlen_chrs = strlen($chrs);
|
||||
|
||||
for ($c = 0; $c <= $strlen_chrs; ++$c) {
|
||||
|
||||
$top = end($stk);
|
||||
$substr_chrs_c_2 = substr($chrs, $c, 2);
|
||||
|
||||
if (($c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == SERVICES_JSON_SLICE))) {
|
||||
// found a comma that is not inside a string, array, etc.,
|
||||
// OR we've reached the end of the character list
|
||||
$slice = substr($chrs, $top['where'], ($c - $top['where']));
|
||||
array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false));
|
||||
//print("Found split at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
|
||||
|
||||
if (reset($stk) == SERVICES_JSON_IN_ARR) {
|
||||
// we are in an array, so just push an element onto the stack
|
||||
array_push($arr, $this->decode($slice));
|
||||
|
||||
} elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
|
||||
// we are in an object, so figure
|
||||
// out the property name and set an
|
||||
// element in an associative array,
|
||||
// for now
|
||||
if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
|
||||
// "name":value pair
|
||||
$key = $this->decode($parts[1]);
|
||||
$val = $this->decode($parts[2]);
|
||||
|
||||
if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
|
||||
$obj[$key] = $val;
|
||||
} else {
|
||||
$obj->$key = $val;
|
||||
}
|
||||
} elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
|
||||
// name:value pair, where name is unquoted
|
||||
$key = $parts[1];
|
||||
$val = $this->decode($parts[2]);
|
||||
|
||||
if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
|
||||
$obj[$key] = $val;
|
||||
} else {
|
||||
$obj->$key = $val;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != SERVICES_JSON_IN_STR)) {
|
||||
// found a quote, and we are not inside a string
|
||||
array_push($stk, array('what' => SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c}));
|
||||
//print("Found start of string at {$c}\n");
|
||||
|
||||
} elseif (($chrs{$c} == $top['delim']) &&
|
||||
($top['what'] == SERVICES_JSON_IN_STR) &&
|
||||
(($chrs{$c - 1} != '\\') ||
|
||||
($chrs{$c - 1} == '\\' && $chrs{$c - 2} == '\\'))) {
|
||||
// found a quote, we're in a string, and it's not escaped
|
||||
array_pop($stk);
|
||||
//print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n");
|
||||
|
||||
} elseif (($chrs{$c} == '[') &&
|
||||
in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
|
||||
// found a left-bracket, and we are in an array, object, or slice
|
||||
array_push($stk, array('what' => SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false));
|
||||
//print("Found start of array at {$c}\n");
|
||||
|
||||
} elseif (($chrs{$c} == ']') && ($top['what'] == SERVICES_JSON_IN_ARR)) {
|
||||
// found a right-bracket, and we're in an array
|
||||
array_pop($stk);
|
||||
//print("Found end of array at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
|
||||
|
||||
} elseif (($chrs{$c} == '{') &&
|
||||
in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
|
||||
// found a left-brace, and we are in an array, object, or slice
|
||||
array_push($stk, array('what' => SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false));
|
||||
//print("Found start of object at {$c}\n");
|
||||
|
||||
} elseif (($chrs{$c} == '}') && ($top['what'] == SERVICES_JSON_IN_OBJ)) {
|
||||
// found a right-brace, and we're in an object
|
||||
array_pop($stk);
|
||||
//print("Found end of object at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
|
||||
|
||||
} elseif (($substr_chrs_c_2 == '/*') &&
|
||||
in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
|
||||
// found a comment start, and we are in an array, object, or slice
|
||||
array_push($stk, array('what' => SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false));
|
||||
$c++;
|
||||
//print("Found start of comment at {$c}\n");
|
||||
|
||||
} elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == SERVICES_JSON_IN_CMT)) {
|
||||
// found a comment end, and we're in one now
|
||||
array_pop($stk);
|
||||
$c++;
|
||||
|
||||
for ($i = $top['where']; $i <= $c; ++$i)
|
||||
$chrs = substr_replace($chrs, ' ', $i, 1);
|
||||
|
||||
//print("Found end of comment at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (reset($stk) == SERVICES_JSON_IN_ARR) {
|
||||
return $arr;
|
||||
|
||||
} elseif (reset($stk) == SERVICES_JSON_IN_OBJ) {
|
||||
return $obj;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Ultimately, this should just call PEAR::isError()
|
||||
*/
|
||||
function isError($data, $code = null)
|
||||
{
|
||||
if (HTML_AJAX_class_exists('pear', false)) {
|
||||
return PEAR::isError($data, $code);
|
||||
} elseif (is_object($data) && (get_class($data) == 'services_json_error' ||
|
||||
is_subclass_of($data, 'services_json_error'))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (HTML_AJAX_class_exists('pear_error', false)) {
|
||||
|
||||
class HTML_AJAX_JSON_Error extends PEAR_Error
|
||||
{
|
||||
function HTML_AJAX_JSON_Error($message = 'unknown error', $code = null,
|
||||
$mode = null, $options = null, $userinfo = null)
|
||||
{
|
||||
parent::PEAR_Error($message, $code, $mode, $options, $userinfo);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/**
|
||||
* @todo Ultimately, this class shall be descended from PEAR_Error
|
||||
*/
|
||||
class HTML_AJAX_JSON_Error
|
||||
{
|
||||
function HTML_AJAX_JSON_Error($message = 'unknown error', $code = null,
|
||||
$mode = null, $options = null, $userinfo = null)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Future-friendly json_encode
|
||||
if( !function_exists('json_encode') ) {
|
||||
function json_encode($data) {
|
||||
$json = new HTML_AJAX_JSON();
|
||||
return( $json->encode($data) );
|
||||
}
|
||||
}
|
||||
|
||||
// Future-friendly json_decode
|
||||
if( !function_exists('json_decode') ) {
|
||||
function json_decode($data) {
|
||||
$json = new HTML_AJAX_JSON();
|
||||
return( $json->decode($data) );
|
||||
}
|
||||
}
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
?>
|
@ -1,78 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* OO AJAX Implementation for PHP, contains HTML_AJAX_Response
|
||||
*
|
||||
* SVN Rev: $Id$
|
||||
*
|
||||
* @category HTML
|
||||
* @package AJAX
|
||||
* @author Elizabeth Smith <auroraeosrose@gmail.com>
|
||||
* @copyright 2005-2006 Elizabeth Smith
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @version Release: 0.5.6
|
||||
*/
|
||||
|
||||
/**
|
||||
* Require the main AJAX library
|
||||
*/
|
||||
require_once 'HTML/AJAX.php';
|
||||
|
||||
/**
|
||||
* Simple base class for a response object to use as an ajax callback
|
||||
*
|
||||
* This is the base response class, more interesting response classes can be
|
||||
* built off of this, simply give it a unique content type and override the
|
||||
* getPayload method or fill the payload property with your extended classes's
|
||||
* serialized content
|
||||
*
|
||||
* @version $Id$
|
||||
*/
|
||||
class HTML_AJAX_Response
|
||||
{
|
||||
|
||||
/**
|
||||
* The base response class uses plain text so use that content type
|
||||
*
|
||||
* @var string
|
||||
* @access public
|
||||
*/
|
||||
var $contentType = 'text/plain';
|
||||
|
||||
/**
|
||||
* Assign a string to this variable to use the bare response class
|
||||
*
|
||||
* @var string
|
||||
* @access public
|
||||
*/
|
||||
var $payload = '';
|
||||
|
||||
/**
|
||||
* Returns the appropriate content type
|
||||
*
|
||||
* This normally simply returns the contentType property but can be overridden
|
||||
* by an extending class if the content-type is variable
|
||||
*
|
||||
* @return string appropriate content type
|
||||
* @access public
|
||||
*/
|
||||
function getContentType()
|
||||
{
|
||||
return $this->contentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the serialized content of the response class
|
||||
*
|
||||
* You can either fill the payload elsewhere in an extending class and leave
|
||||
* this method alone, or you can override it if you have a different type
|
||||
* of payload that needs special treatment
|
||||
*
|
||||
* @return string serialized response content
|
||||
* @access public
|
||||
*/
|
||||
function getPayload()
|
||||
{
|
||||
return $this->payload;
|
||||
}
|
||||
}
|
||||
?>
|
@ -1,20 +0,0 @@
|
||||
<?php
|
||||
require_once 'HTML/AJAX/Serializer/JSON.php';
|
||||
// $Id
|
||||
/**
|
||||
* Error Serializer, for now just uses JSON
|
||||
*
|
||||
* @category HTML
|
||||
* @package AJAX
|
||||
* @author Joshua Eichorn <josh@bluga.net>
|
||||
* @copyright 2005 Joshua Eichorn
|
||||
* @license http://www.php.net/license/3_0.txt PHP License 3.0
|
||||
* @version Release: 0.5.6
|
||||
* @link http://pear.php.net/package/HTML_AJAX
|
||||
*/
|
||||
class HTML_AJAX_Serializer_Error extends HTML_AJAX_Serializer_JSON
|
||||
{
|
||||
|
||||
}
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
?>
|
@ -1,96 +0,0 @@
|
||||
<?php
|
||||
require_once 'HTML/AJAX/JSON.php';
|
||||
// $Id$
|
||||
/**
|
||||
* JSON Serializer
|
||||
*
|
||||
* @category HTML
|
||||
* @package AJAX
|
||||
* @author Joshua Eichorn <josh@bluga.net>
|
||||
* @copyright 2005 Joshua Eichorn
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @version Release: 0.5.6
|
||||
* @link http://pear.php.net/package/PackageName
|
||||
*/
|
||||
// {{{ class HTMLA_AJAX_Serialize_JSON
|
||||
class HTML_AJAX_Serializer_JSON
|
||||
{
|
||||
// {{{ variables-properties
|
||||
/**
|
||||
* JSON instance
|
||||
* @var HTML_AJAX_JSON
|
||||
* @access private
|
||||
*/
|
||||
var $_json;
|
||||
|
||||
/**
|
||||
* use json php extension http://www.aurore.net/projects/php-json/
|
||||
* @access private
|
||||
*/
|
||||
var $_jsonext;
|
||||
|
||||
/**
|
||||
* use loose typing to decode js objects into php associative arrays
|
||||
* @access public
|
||||
*/
|
||||
var $loose_type;
|
||||
|
||||
// }}}
|
||||
// {{{ constructor
|
||||
function HTML_AJAX_Serializer_JSON($use_loose_type = true)
|
||||
{
|
||||
$this->loose_type = (bool) $use_loose_type;
|
||||
$this->_jsonext = $this->_detect();
|
||||
if(!$this->_jsonext) {
|
||||
$use_loose_type = ($this->loose_type) ? SERVICES_JSON_LOOSE_TYPE : 0;
|
||||
$this->_json = new HTML_AJAX_JSON($use_loose_type);
|
||||
}
|
||||
}
|
||||
// }}}
|
||||
// {{{ serialize
|
||||
/**
|
||||
* This function serializes and input passed to it.
|
||||
*
|
||||
* @access public
|
||||
* @param string $input The input to serialize.
|
||||
* @return string $input The serialized input.
|
||||
*/
|
||||
function serialize($input)
|
||||
{
|
||||
if($this->_jsonext) {
|
||||
return json_encode($input);
|
||||
} else {
|
||||
return $this->_json->encode($input);
|
||||
}
|
||||
}
|
||||
// }}}
|
||||
// {{{ unserialize
|
||||
/**
|
||||
* this function unserializes the input passed to it.
|
||||
*
|
||||
* @access public
|
||||
* @param string $input The input to unserialize
|
||||
* @return string $input The unserialized input.
|
||||
*/
|
||||
function unserialize($input)
|
||||
{
|
||||
if($this->_jsonext) {
|
||||
return json_decode($input, $this->loose_type);
|
||||
} else {
|
||||
return $this->_json->decode($input);
|
||||
}
|
||||
}
|
||||
// }}}
|
||||
// {{{ _detect
|
||||
/**
|
||||
* detects the loaded extension
|
||||
*/
|
||||
function _detect()
|
||||
{
|
||||
return extension_loaded('json');
|
||||
}
|
||||
// }}}
|
||||
}
|
||||
// }}}
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
?>
|
@ -1,28 +0,0 @@
|
||||
<?php
|
||||
// $Id$
|
||||
/**
|
||||
* Null Serializer
|
||||
*
|
||||
* @category HTML
|
||||
* @package AJAX
|
||||
* @author Joshua Eichorn <josh@bluga.net>
|
||||
* @copyright 2005 Joshua Eichorn
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @version Release: 0.5.6
|
||||
* @link http://pear.php.net/package/PackageName
|
||||
*/
|
||||
class HTML_AJAX_Serializer_Null
|
||||
{
|
||||
|
||||
function serialize($input)
|
||||
{
|
||||
return $input;
|
||||
}
|
||||
|
||||
function unserialize($input)
|
||||
{
|
||||
return $input;
|
||||
}
|
||||
}
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
?>
|
@ -1,88 +0,0 @@
|
||||
<?php
|
||||
// $Id$
|
||||
/**
|
||||
* PHP Serializer
|
||||
*
|
||||
* @category HTML
|
||||
* @package AJAX
|
||||
* @author Arpad Ray <arpad@php.net>
|
||||
* @copyright 2005 Arpad Ray
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @version Release: 0.5.6
|
||||
* @link http://pear.php.net/package/HTML_AJAX
|
||||
*/
|
||||
class HTML_AJAX_Serializer_PHP
|
||||
{
|
||||
function serialize($input)
|
||||
{
|
||||
return serialize($input);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unserializes the given string
|
||||
*
|
||||
* Triggers an error if a class is found which is not
|
||||
* in the provided array of allowed class names.
|
||||
*
|
||||
* @param string $input
|
||||
* the serialized string to process
|
||||
* @param array $allowedClasses
|
||||
* an array of class names to check objects against
|
||||
* before instantion
|
||||
* @return mixed
|
||||
* the unserialized variable on success, or false on
|
||||
* failure. If this method fails it will also trigger
|
||||
* a warning.
|
||||
*/
|
||||
function unserialize($input, $allowedClasses)
|
||||
{
|
||||
if (version_compare(PHP_VERSION, '4.3.10', '<')
|
||||
|| (substr(PHP_VERSION, 0, 1) == '5' && version_compare(PHP_VERSION, '5.0.3', '<'))) {
|
||||
trigger_error('Unsafe version of PHP for native unserialization');
|
||||
return false;
|
||||
}
|
||||
$classes = $this->_getSerializedClassNames($input);
|
||||
if ($classes === false) {
|
||||
trigger_error('Invalidly serialized string');
|
||||
return false;
|
||||
}
|
||||
$diff = array_diff($classes, $allowedClasses);
|
||||
if (!empty($diff)) {
|
||||
trigger_error('Class(es) not allowed to be serialized');
|
||||
return false;
|
||||
}
|
||||
return unserialize($input);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract class names from serialized string
|
||||
*
|
||||
* Adapted from code by Harry Fuecks
|
||||
*
|
||||
* @param string $string
|
||||
* the serialized string to process
|
||||
* @return mixed
|
||||
* an array of class names found, or false if the input
|
||||
* is invalidly formed
|
||||
*/
|
||||
function _getSerializedClassNames($string) {
|
||||
// Strip any string representations (which might contain object syntax)
|
||||
while (($pos = strpos($string, 's:')) !== false) {
|
||||
$pos2 = strpos($string, ':', $pos + 2);
|
||||
if ($pos2 === false) {
|
||||
// invalidly serialized string
|
||||
return false;
|
||||
}
|
||||
$end = $pos + 2 + substr($string, $pos + 2, $pos2) + 1;
|
||||
$string = substr($string, 0, $pos) . substr($string, $end);
|
||||
}
|
||||
|
||||
// Pull out the class names
|
||||
preg_match_all('/O:[0-9]+:"(.*)"/U', $string, $matches);
|
||||
|
||||
// Make sure names are unique (same object serialized twice)
|
||||
return array_unique($matches[1]);
|
||||
}
|
||||
}
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
?>
|
@ -1,67 +0,0 @@
|
||||
<?php
|
||||
// $Id$
|
||||
|
||||
// {{{ http_build_query
|
||||
/**
|
||||
* Replacement for http_build_query()
|
||||
*
|
||||
* @link http://php.net/function.http-build-query
|
||||
* @author vlad_mustafin@ukr.net
|
||||
* @author Arpad Ray <arpad@php.net>
|
||||
*/
|
||||
if (!function_exists('http_build_query')) {
|
||||
function http_build_query($formdata, $numeric_prefix = null, $key = null)
|
||||
{
|
||||
$res = array();
|
||||
foreach ((array)$formdata as $k => $v) {
|
||||
if (is_resource($v)) {
|
||||
return null;
|
||||
}
|
||||
$tmp_key = urlencode(is_int($k) ? $numeric_prefix . $k : $k);
|
||||
if (!is_null($key)) {
|
||||
$tmp_key = $key . '[' . $tmp_key . ']';
|
||||
}
|
||||
$res[] = (is_scalar($v))
|
||||
? $tmp_key . '=' . urlencode($v)
|
||||
: http_build_query($v, null , $tmp_key);
|
||||
}
|
||||
$separator = ini_get('arg_separator.output');
|
||||
if (strlen($separator) == 0) {
|
||||
$separator = '&';
|
||||
}
|
||||
return implode($separator, $res);
|
||||
}
|
||||
}
|
||||
// }}}
|
||||
// {{{ class HTML_AJAX_Serialize_Urlencoded
|
||||
/**
|
||||
* URL Encoding Serializer
|
||||
*
|
||||
* @category HTML
|
||||
* @package AJAX
|
||||
* @author Arpad Ray <arpad@php.net>
|
||||
* @author David Coallier <davidc@php.net>
|
||||
* @copyright 2005 Arpad Ray
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @version Release: 0.5.6
|
||||
* @link http://pear.php.net/package/HTML_AJAX
|
||||
*/
|
||||
class HTML_AJAX_Serializer_Urlencoded
|
||||
{
|
||||
// {{{ serialize
|
||||
function serialize($input)
|
||||
{
|
||||
return http_build_query(array('_HTML_AJAX' => $input));
|
||||
}
|
||||
// }}}
|
||||
// {{{ unserialize
|
||||
function unserialize($input)
|
||||
{
|
||||
parse_str($input, $ret);
|
||||
return (isset($ret['_HTML_AJAX']) ? $ret['_HTML_AJAX'] : $ret);
|
||||
}
|
||||
// }}}
|
||||
}
|
||||
// }}}
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
?>
|
@ -1,88 +0,0 @@
|
||||
<?php
|
||||
// $Id$
|
||||
/**
|
||||
* XML Serializer - does NOT need a js serializer, use responseXML property in XmlHttpRequest
|
||||
*
|
||||
* @category HTML
|
||||
* @package AJAX
|
||||
* @author Elizabeth Smith <auroraeosrose@gmail.com>
|
||||
* @copyright 2005-2006 Elizabeth Smith
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @version Release: 0.5.6
|
||||
* @link http://pear.php.net/package/PackageName
|
||||
*/
|
||||
class HTML_AJAX_Serializer_XML
|
||||
{
|
||||
|
||||
/**
|
||||
* Serializes a domdocument into an xml string
|
||||
*
|
||||
* Uses dom or domxml to dump a string from a DomDocument instance
|
||||
* remember dom is always the default and this will die horribly without
|
||||
* a domdocument instance
|
||||
*
|
||||
* @access public
|
||||
* @param object $input instanceof DomDocument
|
||||
* @return string xml string of DomDocument
|
||||
*/
|
||||
function serialize($input)
|
||||
{
|
||||
if(empty($input))
|
||||
{
|
||||
return $input;
|
||||
}
|
||||
// we check for the dom extension
|
||||
elseif (extension_loaded('Dom'))
|
||||
{
|
||||
return $input->saveXml();
|
||||
}
|
||||
// then will check for domxml
|
||||
elseif (extension_loaded('Domxml'))
|
||||
{
|
||||
return $input->dump_mem();
|
||||
}
|
||||
// will throw an error
|
||||
else {
|
||||
$error = new HTML_AJAX_Serializer_Error();
|
||||
$this->serializerNewType = 'Error';
|
||||
return $error->serialize(array('errStr'=>"Missing PHP Dom extension direct XML won't work"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unserializes the xml string sent from the document
|
||||
*
|
||||
* Uses dom or domxml to pump a string into a DomDocument instance
|
||||
* remember dom is always the default and this will die horribly without
|
||||
* one or the other, and will throw warnings if you have bad xml
|
||||
*
|
||||
* @access public
|
||||
* @param string $input The input to serialize.
|
||||
* @return object instanceofDomDocument
|
||||
*/
|
||||
function unserialize($input)
|
||||
{
|
||||
if(empty($input))
|
||||
{
|
||||
return $input;
|
||||
}
|
||||
// we check for the dom extension
|
||||
elseif (extension_loaded('Dom'))
|
||||
{
|
||||
$doc = new DOMDocument();
|
||||
$doc->loadXML($input);
|
||||
return $doc;
|
||||
}
|
||||
// then we check for the domxml extensions
|
||||
elseif (extension_loaded('Domxml'))
|
||||
{
|
||||
return domxml_open_mem($input);
|
||||
}
|
||||
// we give up and just return the xml directly
|
||||
else
|
||||
{
|
||||
return $input;
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
@ -1,725 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* OO AJAX Implementation for PHP
|
||||
*
|
||||
* SVN Rev: $Id$
|
||||
*
|
||||
* @category HTML
|
||||
* @package AJAX
|
||||
* @author Joshua Eichorn <josh@bluga.net>
|
||||
* @copyright 2005 Joshua Eichorn
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @version Release: @package_version@
|
||||
*/
|
||||
|
||||
/**
|
||||
* Require the main AJAX library
|
||||
*/
|
||||
require_once 'HTML/AJAX.php';
|
||||
|
||||
/**
|
||||
* Class for creating an external AJAX server
|
||||
*
|
||||
* Can be used in 2 different modes, registerClass mode where you create an instance of the server and add the classes that will be registered
|
||||
* and then run handle request
|
||||
*
|
||||
* Or you can extend it and add init{className} methods for each class you want to export
|
||||
*
|
||||
* Client js generation is exposed through 2 _GET params client and stub
|
||||
* Setting the _GET param client to `all` will give you all the js classes needed
|
||||
* Setting the _GET param stub to `all` will give you stubs of all registered classes, you can also set it too just 1 class
|
||||
*
|
||||
* @category HTML
|
||||
* @package AJAX
|
||||
* @author Joshua Eichorn <josh@bluga.net>
|
||||
* @copyright 2005 Joshua Eichorn
|
||||
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
|
||||
* @version Release: @package_version@
|
||||
* @link http://pear.php.net/package/PackageName
|
||||
*/
|
||||
class HTML_AJAX_Server
|
||||
{
|
||||
|
||||
/**
|
||||
* Client options array if set to true the code looks at _GET
|
||||
* @var bool|array
|
||||
*/
|
||||
var $options = true;
|
||||
|
||||
/**
|
||||
* HTML_AJAX instance
|
||||
* @var HTML_AJAX
|
||||
*/
|
||||
var $ajax;
|
||||
|
||||
/**
|
||||
* Set to true if your extending the server to add init{className methods}
|
||||
* @var boolean
|
||||
* @access public
|
||||
*/
|
||||
var $initMethods = false;
|
||||
|
||||
/**
|
||||
* Location on filesystem of client javascript library
|
||||
* @var false|string if false the default pear data dir location is used
|
||||
*/
|
||||
var $clientJsLocation = false;
|
||||
|
||||
/**
|
||||
* An array of options that tell the server howto Cache output
|
||||
*
|
||||
* The rules are functions that make etag hash used to see if the client needs to download updated content
|
||||
* If you extend this class you can make your own rule function the naming convention is _cacheRule{RuleName}
|
||||
*
|
||||
* <code>
|
||||
* array(
|
||||
* 'httpCacheClient' => true, // send 304 headers for responses to ?client=* requests
|
||||
* 'ClientCacheRule' => 'File', // create a hash from file names and modified times, options: file|content
|
||||
* 'ClientCacheExpects'=> 'files', // what type of content to send to the hash function, options: files|classes|content
|
||||
* 'httpCacheStub' => true, // send 304 headers for responses to ?stub=* requests
|
||||
* 'StubCacheRule' => 'Api', // create a hash from the exposed api, options: api|content
|
||||
* 'StubCacheExpects'=> 'classes', // what type of content to send to the hash function, options: files|classes|content
|
||||
* )
|
||||
* </code>
|
||||
*
|
||||
* @var array
|
||||
* @access public
|
||||
*/
|
||||
var $cacheOptions = array(
|
||||
'httpCacheClient' => true,
|
||||
'ClientCacheRule' => 'file',
|
||||
'ClientCacheExpects' => 'files',
|
||||
'httpCacheStub' => true,
|
||||
'StubCacheRule' => 'api',
|
||||
'StubCacheExpects' => 'classes',
|
||||
);
|
||||
|
||||
/**
|
||||
* Compression Options
|
||||
*
|
||||
* <code>
|
||||
* array(
|
||||
* 'enabled' => false, // enable compression
|
||||
* 'type' => 'gzip' // the type of compression to do, options: gzip
|
||||
* )
|
||||
* </code>
|
||||
*
|
||||
* @var array
|
||||
* @access public
|
||||
*/
|
||||
var $compression = array(
|
||||
'enabled' => false,
|
||||
'type' => 'gzip'
|
||||
);
|
||||
|
||||
/**
|
||||
* Javascript library names and there path
|
||||
*
|
||||
* the return of $this->clientJsLocation(), is prepended before running readfile on them
|
||||
*
|
||||
* @access public
|
||||
* @var array
|
||||
*/
|
||||
var $javascriptLibraries = array(
|
||||
'all' => 'HTML_AJAX.js',
|
||||
'html_ajax' => 'HTML_AJAX.js',
|
||||
'html_ajax_lite'=> 'HTML_AJAX_lite.js',
|
||||
'json' => 'serializer/JSON.js',
|
||||
'request' => 'Request.js',
|
||||
'main' => array('Compat.js','Main.js','clientPool.js'),
|
||||
'httpclient' => 'HttpClient.js',
|
||||
'dispatcher' => 'Dispatcher.js',
|
||||
'util' => 'util.js',
|
||||
'loading' => 'Loading.js',
|
||||
'phpserializer' => 'serializer/phpSerializer.js',
|
||||
'urlserializer' => 'serializer/UrlSerializer.js',
|
||||
'haserializer' => 'serializer/haSerializer.js',
|
||||
'clientpool' => 'clientPool.js',
|
||||
'iframe' => 'IframeXHR.js',
|
||||
'alias' => 'Alias.js',
|
||||
'queues' => 'Queue.js',
|
||||
'behavior' => array('behavior/behavior.js','behavior/cssQuery-p.js'),
|
||||
|
||||
// rules to help you use a minimal library set
|
||||
'standard' => array('Compat.js','clientPool.js','util.js','Main.js','HttpClient.js','Request.js','serializer/JSON.js',
|
||||
'Loading.js','serializer/UrlSerializer.js','Alias.js','behavior/behavior.js','behavior/cssQuery-p.js'),
|
||||
'jsonrpc' => array('Compat.js','util.js','Main.js','clientPool.js','HttpClient.js','Request.js','serializer/JSON.js'),
|
||||
'proxyobjects' => array('Compat.js','util.js','Main.js','clientPool.js','Request.js','serializer/JSON.js','Dispatcher.js'),
|
||||
|
||||
// BC rules
|
||||
'priorityqueue' => 'Queue.js',
|
||||
'orderedqueue' => 'Queue.js',
|
||||
);
|
||||
|
||||
/**
|
||||
* Custom paths to use for javascript libraries, if not set {@link clientJsLocation} is used to find the system path
|
||||
*
|
||||
* @access public
|
||||
* @var array
|
||||
* @see registerJsLibrary
|
||||
*/
|
||||
var $javascriptLibraryPaths = array();
|
||||
|
||||
/**
|
||||
* Array of className => init methods to call, generated from constructor from initClassName methods
|
||||
*
|
||||
* @access protected
|
||||
*/
|
||||
var $_initLookup = array();
|
||||
|
||||
|
||||
/**
|
||||
* Constructor creates the HTML_AJAX instance
|
||||
*
|
||||
* @param string $serverUrl (Optional) the url the client should be making a request too
|
||||
*/
|
||||
function HTML_AJAX_Server($serverUrl = false)
|
||||
{
|
||||
$this->ajax = new HTML_AJAX();
|
||||
|
||||
// parameters for HTML::AJAX
|
||||
$parameters = array('stub', 'client');
|
||||
|
||||
// keep in the query string all the parameters that don't belong to AJAX
|
||||
// we remove all string like "parameter=something&". Final '&' can also
|
||||
// be '&' (to be sure) and is optional. '=something' is optional too.
|
||||
$querystring = '';
|
||||
if (isset($_SERVER['QUERY_STRING'])) {
|
||||
$querystring = preg_replace('/(' . join('|', $parameters) . ')(?:=[^&]*(?:&(?:amp;)?|$))?/', '', $this->ajax->_getServer('QUERY_STRING'));
|
||||
}
|
||||
|
||||
// call the server with this query string
|
||||
if ($serverUrl === false) {
|
||||
$serverUrl = htmlentities($this->ajax->_getServer('PHP_SELF'));
|
||||
}
|
||||
|
||||
if (substr($serverUrl,-1) != '?') {
|
||||
$serverUrl .= '?';
|
||||
}
|
||||
$this->ajax->serverUrl = $serverUrl . $querystring;
|
||||
|
||||
$methods = get_class_methods($this);
|
||||
foreach($methods as $method) {
|
||||
if (preg_match('/^init([a-zA-Z0-9_]+)$/',$method,$match)) {
|
||||
$this->_initLookup[strtolower($match[1])] = $method;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a client request, either generating a client or having HTML_AJAX handle the request
|
||||
*
|
||||
* @return boolean true if request was handled, false otherwise
|
||||
*/
|
||||
function handleRequest()
|
||||
{
|
||||
if ($this->options == true) {
|
||||
$this->_loadOptions();
|
||||
}
|
||||
//basically a hook for iframe but allows processing of data earlier
|
||||
$this->ajax->populatePayload();
|
||||
if (!isset($_GET['c']) && (count($this->options['client']) > 0 || count($this->options['stub']) > 0) ) {
|
||||
$this->generateClient();
|
||||
return true;
|
||||
} else {
|
||||
if (!empty($_GET['c'])) {
|
||||
$this->_init($this->_cleanIdentifier($this->ajax->_getVar('c')));
|
||||
}
|
||||
return $this->ajax->handleRequest();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register method passthrough to HTML_AJAX
|
||||
*
|
||||
* @see HTML_AJAX::registerClass for docs
|
||||
*/
|
||||
function registerClass(&$instance, $exportedName = false, $exportedMethods = false)
|
||||
{
|
||||
$this->ajax->registerClass($instance,$exportedName,$exportedMethods);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change default serialization - important for exporting classes
|
||||
*
|
||||
* I wanted this for the xml serializer :)
|
||||
*/
|
||||
function setSerializer($type)
|
||||
{
|
||||
$this->ajax->serializer = $type;
|
||||
$this->ajax->unserializer = $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new js client library
|
||||
*
|
||||
* @param string $libraryName name you'll reference the library as
|
||||
* @param string|array $fileName actual filename with no path, for example customLib.js
|
||||
* @param string|false $path Optional, if not set the result from jsClientLocation is used
|
||||
*/
|
||||
function registerJSLibrary($libraryName,$fileName,$path = false) {
|
||||
$libraryName = strtolower($libraryName);
|
||||
$this->javascriptLibraries[$libraryName] = $fileName;
|
||||
|
||||
if ($path !== false) {
|
||||
$this->javascriptLibraryPaths[$libraryName] = $path;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register init methods from an external class
|
||||
*
|
||||
* @param object $instance an external class with initClassName methods
|
||||
*/
|
||||
function registerInitObject(&$instance) {
|
||||
$instance->server =& $this;
|
||||
$methods = get_class_methods($instance);
|
||||
foreach($methods as $method) {
|
||||
if (preg_match('/^init([a-zA-Z0-9_]+)$/',$method,$match)) {
|
||||
$this->_initLookup[strtolower($match[1])] = array(&$instance,$method);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback to be exported to the client
|
||||
*
|
||||
* This function uses the PHP callback pseudo-type
|
||||
*
|
||||
*/
|
||||
function registerPhpCallback($callback)
|
||||
{
|
||||
if (!is_callable($callback)) {
|
||||
// invalid callback
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_array($callback) && is_object($callback[0])) {
|
||||
// object method
|
||||
$this->registerClass($callback[0], strtolower(get_class($callback[0])), array($callback[1]));
|
||||
return true;
|
||||
}
|
||||
|
||||
// static callback
|
||||
$this->ajax->registerPhpCallback($callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate client js
|
||||
*
|
||||
* @todo this is going to need tests to cover all the options
|
||||
*/
|
||||
function generateClient()
|
||||
{
|
||||
$headers = array();
|
||||
|
||||
ob_start();
|
||||
|
||||
// create a list list of js files were going to need to output
|
||||
// index is the full file and so is the value, this keeps duplicates out of $fileList
|
||||
$fileList = array();
|
||||
|
||||
if(!is_array($this->options['client'])) {
|
||||
$this->options['client'] = array();
|
||||
}
|
||||
foreach($this->options['client'] as $library) {
|
||||
if (isset($this->javascriptLibraries[$library])) {
|
||||
$lib = (array)$this->javascriptLibraries[$library];
|
||||
foreach($lib as $file) {
|
||||
if (isset($this->javascriptLibraryPaths[$library])) {
|
||||
$fileList[$this->javascriptLibraryPaths[$library].$file] = $this->javascriptLibraryPaths[$library].$file;
|
||||
}
|
||||
else {
|
||||
$fileList[$this->clientJsLocation().$file] = $this->clientJsLocation().$file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// do needed class init if were running an init server
|
||||
if(!is_array($this->options['stub'])) {
|
||||
$this->options['stub'] = array();
|
||||
}
|
||||
$classList = $this->options['stub'];
|
||||
if ($this->initMethods) {
|
||||
if (isset($this->options['stub'][0]) && $this->options['stub'][0] === 'all') {
|
||||
$this->_initAll();
|
||||
} else {
|
||||
foreach($this->options['stub'] as $stub) {
|
||||
$this->_init($stub);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isset($this->options['stub'][0]) && $this->options['stub'][0] === 'all') {
|
||||
$classList = array_keys($this->ajax->_exportedInstances);
|
||||
}
|
||||
|
||||
// if were doing stub and client we have to wait for both ETags before we can compare with the client
|
||||
$combinedOutput = false;
|
||||
if ($classList != false && count($classList) > 0 && count($fileList) > 0) {
|
||||
$combinedOutput = true;
|
||||
}
|
||||
|
||||
|
||||
if ($classList != false && count($classList) > 0) {
|
||||
|
||||
// were setup enough to make a stubETag if the input it wants is a class list
|
||||
if ($this->cacheOptions['httpCacheStub'] &&
|
||||
$this->cacheOptions['StubCacheExpects'] == 'classes')
|
||||
{
|
||||
$stubETag = $this->_callCacheRule('Stub',$classList);
|
||||
}
|
||||
|
||||
// if were not in combined output compare etags, if method returns true were done
|
||||
if (!$combinedOutput && isset($stubETag)) {
|
||||
if ($this->_compareEtags($stubETag)) {
|
||||
ob_end_clean();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// output the stubs for all the classes in our list
|
||||
foreach($classList as $class) {
|
||||
echo $this->ajax->generateClassStub($class);
|
||||
}
|
||||
|
||||
// if were cacheing and the rule expects content make a tag and check it, if the check is true were done
|
||||
if ($this->cacheOptions['httpCacheStub'] &&
|
||||
$this->cacheOptions['StubCacheExpects'] == 'content')
|
||||
{
|
||||
$stubETag = $this->_callCacheRule('Stub',ob_get_contents());
|
||||
}
|
||||
|
||||
// if were not in combined output compare etags, if method returns true were done
|
||||
if (!$combinedOutput && isset($stubETag)) {
|
||||
if ($this->_compareEtags($stubETag)) {
|
||||
ob_end_clean();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (count($fileList) > 0) {
|
||||
// if were caching and need a file list build our jsETag
|
||||
if ($this->cacheOptions['httpCacheClient'] &&
|
||||
$this->cacheOptions['ClientCacheExpects'] === 'files')
|
||||
{
|
||||
$jsETag = $this->_callCacheRule('Client',$fileList);
|
||||
|
||||
}
|
||||
|
||||
// if were not in combined output compare etags, if method returns true were done
|
||||
if (!$combinedOutput && isset($jsETag)) {
|
||||
if ($this->_compareEtags($jsETag)) {
|
||||
ob_end_clean();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// output the needed client js files
|
||||
foreach($fileList as $file) {
|
||||
$this->_readFile($file);
|
||||
}
|
||||
|
||||
// if were caching and need content build the etag
|
||||
if ($this->cacheOptions['httpCacheClient'] &&
|
||||
$this->cacheOptions['ClientCacheExpects'] === 'content')
|
||||
{
|
||||
$jsETag = $this->_callCacheRule('Client',ob_get_contents());
|
||||
}
|
||||
|
||||
// if were not in combined output compare etags, if method returns true were done
|
||||
if (!$combinedOutput && isset($jsETag)) {
|
||||
if ($this->_compareEtags($jsETag)) {
|
||||
ob_end_clean();
|
||||
return;
|
||||
}
|
||||
}
|
||||
// were in combined output, merge the 2 ETags and compare
|
||||
else if (isset($jsETag) && isset($stubETag)) {
|
||||
if ($this->_compareEtags(md5($stubETag.$jsETag))) {
|
||||
ob_end_clean();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// were outputting content, add our length header and send the output
|
||||
$length = ob_get_length();
|
||||
$output = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
if ($this->ajax->packJavaScript) {
|
||||
$output = $this->ajax->packJavaScript($output);
|
||||
$length = strlen($output);
|
||||
}
|
||||
|
||||
if ($this->compression['enabled'] && $this->compression['type'] == 'gzip' && strpos($_SERVER["HTTP_ACCEPT_ENCODING"], "gzip") !== false) {
|
||||
$output = gzencode($output,9);
|
||||
$length = strlen($output);
|
||||
$headers['Content-Encoding'] = 'gzip';
|
||||
}
|
||||
|
||||
if ($length > 0 && $this->ajax->_sendContentLength()) {
|
||||
$headers['Content-Length'] = $length;
|
||||
}
|
||||
$headers['Content-Type'] = 'text/javascript; charset=utf-8';
|
||||
$this->ajax->_sendHeaders($headers);
|
||||
echo($output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run readfile on input with basic error checking
|
||||
*
|
||||
* @param string $file file to read
|
||||
* @access private
|
||||
* @todo is addslashes enough encoding for js?
|
||||
*/
|
||||
function _readFile($file)
|
||||
{
|
||||
if (file_exists($file)) {
|
||||
readfile($file);
|
||||
} else {
|
||||
$file = addslashes($file);
|
||||
echo "alert('Unable to find javascript file: $file');";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the location of the client js
|
||||
* To override the default pear datadir location set $this->clientJsLocation
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function clientJsLocation()
|
||||
{
|
||||
if (!$this->clientJsLocation) {
|
||||
$path = '@data-dir@'.DIRECTORY_SEPARATOR.'HTML_AJAX'.DIRECTORY_SEPARATOR.'js'.DIRECTORY_SEPARATOR;
|
||||
if(strpos($path, '@'.'data-dir@') === 0)
|
||||
{
|
||||
$path = realpath(dirname(__FILE__).DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'js').DIRECTORY_SEPARATOR;
|
||||
}
|
||||
return $path;
|
||||
} else {
|
||||
return $this->clientJsLocation;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the location of the client js
|
||||
*
|
||||
* @access public
|
||||
* @param string $location Location
|
||||
* @return void
|
||||
*/
|
||||
function setClientJsLocation($location)
|
||||
{
|
||||
$this->clientJsLocation = $location;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the path to a Javascript libraries
|
||||
*
|
||||
* @access public
|
||||
* @param string $library Library name
|
||||
* @param string $path Path
|
||||
* @return void
|
||||
*/
|
||||
function setJavascriptLibraryPath($library, $path)
|
||||
{
|
||||
$this->javascriptLibraryPaths[$library] = $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the path to more than one Javascript libraries at once
|
||||
*
|
||||
* @access public
|
||||
* @param array $paths Paths
|
||||
* @return void
|
||||
*/
|
||||
function setJavascriptLibraryPaths($paths)
|
||||
{
|
||||
if (is_array($paths)) {
|
||||
$this->javascriptLibraryPaths = array_merge($this->javascriptLibraryPaths, $paths);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load options from _GET
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function _loadOptions()
|
||||
{
|
||||
$this->options = array('client'=>array(),'stub'=>array());
|
||||
if (isset($_GET['client'])) {
|
||||
$clients = explode(',',$this->ajax->_getVar('client'));
|
||||
$client = array();
|
||||
foreach($clients as $val) {
|
||||
$cleanVal = $this->_cleanIdentifier($val);
|
||||
if (!empty($cleanVal)) {
|
||||
$client[] = strtolower($cleanVal);
|
||||
}
|
||||
}
|
||||
|
||||
if (count($client) > 0) {
|
||||
$this->options['client'] = $client;
|
||||
}
|
||||
}
|
||||
if (isset($_GET['stub'])) {
|
||||
$stubs = explode(',',$this->ajax->_getVar('stub'));
|
||||
$stub = array();
|
||||
foreach($stubs as $val) {
|
||||
$cleanVal = $this->_cleanIdentifier($val);
|
||||
if (!empty($cleanVal)) {
|
||||
$stub[] = strtolower($cleanVal);
|
||||
}
|
||||
}
|
||||
|
||||
if (count($stub) > 0) {
|
||||
$this->options['stub'] = $stub;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean an identifier like a class name making it safe to use
|
||||
*
|
||||
* @param string $input
|
||||
* @return string
|
||||
* @access private
|
||||
*/
|
||||
function _cleanIdentifier($input) {
|
||||
return trim(preg_replace('/[^A-Za-z_0-9]/','',$input));
|
||||
}
|
||||
|
||||
/**
|
||||
* Run every init method on the class
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function _initAll()
|
||||
{
|
||||
if ($this->initMethods) {
|
||||
foreach($this->_initLookup as $class => $method) {
|
||||
$this->_init($class);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Init one class
|
||||
*
|
||||
* @param string $className
|
||||
* @access private
|
||||
*/
|
||||
function _init($className)
|
||||
{
|
||||
$className = strtolower($className);
|
||||
if ($this->initMethods) {
|
||||
if (isset($this->_initLookup[$className])) {
|
||||
$method =& $this->_initLookup[$className];
|
||||
if (is_array($method)) {
|
||||
call_user_func($method);
|
||||
}
|
||||
else {
|
||||
$this->$method();
|
||||
}
|
||||
} else {
|
||||
trigger_error("Could find an init method for class: " . $className);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a hash from a list of files
|
||||
*
|
||||
* @param array $files file list
|
||||
* @return string a hash that can be used as an etag
|
||||
* @access private
|
||||
*/
|
||||
function _cacheRuleFile($files) {
|
||||
$signature = "";
|
||||
foreach($files as $file) {
|
||||
if (file_exists($file)) {
|
||||
$signature .= $file.filemtime($file);
|
||||
}
|
||||
}
|
||||
return md5($signature);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a hash from the api of registered classes
|
||||
*
|
||||
* @param array $classes class list
|
||||
* @return string a hash that can be used as an etag
|
||||
* @access private
|
||||
*/
|
||||
function _cacheRuleApi($classes) {
|
||||
$signature = "";
|
||||
foreach($classes as $class) {
|
||||
if (isset($this->ajax->_exportedInstances[$class])) {
|
||||
$signature .= $class.implode(',',$this->ajax->_exportedInstances[$class]['exportedMethods']);
|
||||
}
|
||||
}
|
||||
return md5($signature);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a hash from the raw content
|
||||
*
|
||||
* @param array $content
|
||||
* @return string a hash that can be used as an etag
|
||||
* @access private
|
||||
*/
|
||||
function _cacheRuleContent($content) {
|
||||
return md5($content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send cache control headers
|
||||
* @access private
|
||||
*/
|
||||
function _sendCacheHeaders($etag,$notModified) {
|
||||
header('Cache-Control: must-revalidate');
|
||||
header('ETag: '.$etag);
|
||||
if ($notModified) {
|
||||
header('HTTP/1.0 304 Not Modified',false,304);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare eTags
|
||||
*
|
||||
* @param string $serverETag server eTag
|
||||
* @return boolean
|
||||
* @access private
|
||||
*/
|
||||
function _compareEtags($serverETag) {
|
||||
if (isset($_SERVER['HTTP_IF_NONE_MATCH'])) {
|
||||
if (strcmp($this->ajax->_getServer('HTTP_IF_NONE_MATCH'),$serverETag) == 0) {
|
||||
$this->_sendCacheHeaders($serverETag,true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
$this->_sendCacheHeaders($serverETag,false);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call a cache rule and return its retusn
|
||||
*
|
||||
* @param string $rule Stub|Client
|
||||
* @param mixed $payload
|
||||
* @return boolean
|
||||
* @access private
|
||||
* @todo decide if error checking is needed
|
||||
*/
|
||||
function _callCacheRule($rule,$payload) {
|
||||
$method = '_cacheRule'.$this->cacheOptions[$rule.'CacheRule'];
|
||||
return call_user_func(array(&$this,$method),$payload);
|
||||
}
|
||||
}
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
?>
|
Loading…
x
Reference in New Issue
Block a user