mirror of
https://github.com/moodle/moodle.git
synced 2025-08-02 23:59:41 +02:00
MDL-16780 Merging from MOODLE_19_STABLE
This commit is contained in:
parent
18a9406799
commit
1e074660da
14 changed files with 1970 additions and 76 deletions
|
@ -10,7 +10,7 @@
|
||||||
*/
|
*/
|
||||||
require_once('../config.php');
|
require_once('../config.php');
|
||||||
require_once('lib.php');
|
require_once('lib.php');
|
||||||
require_once($CFG->libdir.'/json/JSON.php');
|
require_once($CFG->libdir.'/pear/HTML/AJAX/JSON.php');
|
||||||
|
|
||||||
require_js(array('yui_yahoo', 'yui_dom', 'yui_utilities', 'yui_connection'));
|
require_js(array('yui_yahoo', 'yui_dom', 'yui_utilities', 'yui_connection'));
|
||||||
require_js('group/clientlib.js');
|
require_js('group/clientlib.js');
|
||||||
|
@ -58,8 +58,7 @@ switch ($action) {
|
||||||
$roles[]=$shortroledata;
|
$roles[]=$shortroledata;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$json = new Services_JSON();
|
echo json_encode($roles);
|
||||||
echo $json->encode($roles);
|
|
||||||
die; // Client side JavaScript takes it from here.
|
die; // Client side JavaScript takes it from here.
|
||||||
|
|
||||||
case 'deletegroup':
|
case 'deletegroup':
|
||||||
|
@ -205,11 +204,11 @@ if ($sel_groupid) {
|
||||||
echo '<option value="'.$member->id.'">'.fullname($member, true).'</option>';
|
echo '<option value="'.$member->id.'">'.fullname($member, true).'</option>';
|
||||||
$atleastonemember = true;
|
$atleastonemember = true;
|
||||||
}
|
}
|
||||||
echo '</optgroup>';
|
echo '</optgroup>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$atleastonemember) {
|
if (!$atleastonemember) {
|
||||||
// Print an empty option to avoid the XHTML error of having an empty select element
|
// Print an empty option to avoid the XHTML error of having an empty select element
|
||||||
echo '<option> </option>';
|
echo '<option> </option>';
|
||||||
|
|
357
lib/pear/HTML/AJAX/Action.php
Executable file
357
lib/pear/HTML/AJAX/Action.php
Executable file
|
@ -0,0 +1,357 @@
|
||||||
|
<?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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
144
lib/pear/HTML/AJAX/Debug.php
Executable file
144
lib/pear/HTML/AJAX/Debug.php
Executable file
|
@ -0,0 +1,144 @@
|
||||||
|
<?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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
?>
|
186
lib/pear/HTML/AJAX/Helper.php
Executable file
186
lib/pear/HTML/AJAX/Helper.php
Executable file
|
@ -0,0 +1,186 @@
|
||||||
|
<?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: */
|
||||||
|
?>
|
111
lib/json/JSON.php → lib/pear/HTML/AJAX/JSON.php
Normal file → Executable file
111
lib/json/JSON.php → lib/pear/HTML/AJAX/JSON.php
Normal file → Executable file
|
@ -1,5 +1,17 @@
|
||||||
<?php
|
<?php
|
||||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
/**
|
||||||
|
* 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.
|
* Converts to and from JSON format.
|
||||||
|
@ -46,48 +58,47 @@
|
||||||
* DAMAGE.
|
* DAMAGE.
|
||||||
*
|
*
|
||||||
* @category
|
* @category
|
||||||
* @package Services_JSON
|
* @package HTML_AJAX_JSON
|
||||||
* @author Michal Migurski <mike-json@teczno.com>
|
* @author Michal Migurski <mike-json@teczno.com>
|
||||||
* @author Matt Knapp <mdknapp[at]gmail[dot]com>
|
* @author Matt Knapp <mdknapp[at]gmail[dot]com>
|
||||||
* @author Brett Stimmerman <brettstimmerman[at]gmail[dot]com>
|
* @author Brett Stimmerman <brettstimmerman[at]gmail[dot]com>
|
||||||
* @copyright 2005 Michal Migurski
|
* @copyright 2005 Michal Migurski
|
||||||
* @version CVS: $Id$
|
|
||||||
* @license http://www.opensource.org/licenses/bsd-license.php
|
* @license http://www.opensource.org/licenses/bsd-license.php
|
||||||
* @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198
|
* @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Marker constant for Services_JSON::decode(), used to flag stack state
|
* Marker constant for HTML_AJAX_JSON::decode(), used to flag stack state
|
||||||
*/
|
*/
|
||||||
define('SERVICES_JSON_SLICE', 1);
|
define('SERVICES_JSON_SLICE', 1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Marker constant for Services_JSON::decode(), used to flag stack state
|
* Marker constant for HTML_AJAX_JSON::decode(), used to flag stack state
|
||||||
*/
|
*/
|
||||||
define('SERVICES_JSON_IN_STR', 2);
|
define('SERVICES_JSON_IN_STR', 2);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Marker constant for Services_JSON::decode(), used to flag stack state
|
* Marker constant for HTML_AJAX_JSON::decode(), used to flag stack state
|
||||||
*/
|
*/
|
||||||
define('SERVICES_JSON_IN_ARR', 3);
|
define('SERVICES_JSON_IN_ARR', 3);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Marker constant for Services_JSON::decode(), used to flag stack state
|
* Marker constant for HTML_AJAX_JSON::decode(), used to flag stack state
|
||||||
*/
|
*/
|
||||||
define('SERVICES_JSON_IN_OBJ', 4);
|
define('SERVICES_JSON_IN_OBJ', 4);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Marker constant for Services_JSON::decode(), used to flag stack state
|
* Marker constant for HTML_AJAX_JSON::decode(), used to flag stack state
|
||||||
*/
|
*/
|
||||||
define('SERVICES_JSON_IN_CMT', 5);
|
define('SERVICES_JSON_IN_CMT', 5);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Behavior switch for Services_JSON::decode()
|
* Behavior switch for HTML_AJAX_JSON::decode()
|
||||||
*/
|
*/
|
||||||
define('SERVICES_JSON_LOOSE_TYPE', 16);
|
define('SERVICES_JSON_LOOSE_TYPE', 16);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Behavior switch for Services_JSON::decode()
|
* Behavior switch for HTML_AJAX_JSON::decode()
|
||||||
*/
|
*/
|
||||||
define('SERVICES_JSON_SUPPRESS_ERRORS', 32);
|
define('SERVICES_JSON_SUPPRESS_ERRORS', 32);
|
||||||
|
|
||||||
|
@ -97,8 +108,8 @@ define('SERVICES_JSON_SUPPRESS_ERRORS', 32);
|
||||||
* Brief example of use:
|
* Brief example of use:
|
||||||
*
|
*
|
||||||
* <code>
|
* <code>
|
||||||
* // create a new instance of Services_JSON
|
* // create a new instance of HTML_AJAX_JSON
|
||||||
* $json = new Services_JSON();
|
* $json = new HTML_AJAX_JSON();
|
||||||
*
|
*
|
||||||
* // convert a complexe value to JSON notation, and send it to the browser
|
* // 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)));
|
* $value = array('foo', 'bar', array(1, 2, 'baz'), array(3, array(4)));
|
||||||
|
@ -112,7 +123,7 @@ define('SERVICES_JSON_SUPPRESS_ERRORS', 32);
|
||||||
* $value = $json->decode($input);
|
* $value = $json->decode($input);
|
||||||
* </code>
|
* </code>
|
||||||
*/
|
*/
|
||||||
class Services_JSON
|
class HTML_AJAX_JSON
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* constructs a new JSON instance
|
* constructs a new JSON instance
|
||||||
|
@ -130,7 +141,7 @@ class Services_JSON
|
||||||
* bubble up with an error, so all return values
|
* bubble up with an error, so all return values
|
||||||
* from encode() should be checked with isError()
|
* from encode() should be checked with isError()
|
||||||
*/
|
*/
|
||||||
function Services_JSON($use = 0)
|
function HTML_AJAX_JSON($use = 0)
|
||||||
{
|
{
|
||||||
$this->use = $use;
|
$this->use = $use;
|
||||||
}
|
}
|
||||||
|
@ -149,9 +160,8 @@ class Services_JSON
|
||||||
function utf162utf8($utf16)
|
function utf162utf8($utf16)
|
||||||
{
|
{
|
||||||
// oh please oh please oh please oh please oh please
|
// oh please oh please oh please oh please oh please
|
||||||
if(function_exists('mb_convert_encoding')) {
|
if(function_exists('mb_convert_encoding'))
|
||||||
return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16');
|
return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16');
|
||||||
}
|
|
||||||
|
|
||||||
$bytes = (ord($utf16{0}) << 8) | ord($utf16{1});
|
$bytes = (ord($utf16{0}) << 8) | ord($utf16{1});
|
||||||
|
|
||||||
|
@ -193,9 +203,8 @@ class Services_JSON
|
||||||
function utf82utf16($utf8)
|
function utf82utf16($utf8)
|
||||||
{
|
{
|
||||||
// oh please oh please oh please oh please oh please
|
// oh please oh please oh please oh please oh please
|
||||||
if(function_exists('mb_convert_encoding')) {
|
if(function_exists('mb_convert_encoding'))
|
||||||
return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
|
return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
|
||||||
}
|
|
||||||
|
|
||||||
switch(strlen($utf8)) {
|
switch(strlen($utf8)) {
|
||||||
case 1:
|
case 1:
|
||||||
|
@ -227,7 +236,7 @@ class Services_JSON
|
||||||
* encodes an arbitrary variable into JSON format
|
* encodes an arbitrary variable into JSON format
|
||||||
*
|
*
|
||||||
* @param mixed $var any number, boolean, string, array, or object to be encoded.
|
* @param mixed $var any number, boolean, string, array, or object to be encoded.
|
||||||
* see argument 1 to Services_JSON() above for array-parsing behavior.
|
* see argument 1 to HTML_AJAX_JSON() above for array-parsing behavior.
|
||||||
* if var is a strng, note that encode() always expects it
|
* if var is a strng, note that encode() always expects it
|
||||||
* to be in ASCII or UTF-8 format!
|
* to be in ASCII or UTF-8 format!
|
||||||
*
|
*
|
||||||
|
@ -380,11 +389,9 @@ class Services_JSON
|
||||||
array_keys($var),
|
array_keys($var),
|
||||||
array_values($var));
|
array_values($var));
|
||||||
|
|
||||||
foreach($properties as $property) {
|
foreach($properties as $property)
|
||||||
if(Services_JSON::isError($property)) {
|
if(HTML_AJAX_JSON::isError($property))
|
||||||
return $property;
|
return $property;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return '{' . join(',', $properties) . '}';
|
return '{' . join(',', $properties) . '}';
|
||||||
}
|
}
|
||||||
|
@ -392,11 +399,9 @@ class Services_JSON
|
||||||
// treat it like a regular array
|
// treat it like a regular array
|
||||||
$elements = array_map(array($this, 'encode'), $var);
|
$elements = array_map(array($this, 'encode'), $var);
|
||||||
|
|
||||||
foreach($elements as $element) {
|
foreach($elements as $element)
|
||||||
if(Services_JSON::isError($element)) {
|
if(HTML_AJAX_JSON::isError($element))
|
||||||
return $element;
|
return $element;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return '[' . join(',', $elements) . ']';
|
return '[' . join(',', $elements) . ']';
|
||||||
|
|
||||||
|
@ -407,18 +412,16 @@ class Services_JSON
|
||||||
array_keys($vars),
|
array_keys($vars),
|
||||||
array_values($vars));
|
array_values($vars));
|
||||||
|
|
||||||
foreach($properties as $property) {
|
foreach($properties as $property)
|
||||||
if(Services_JSON::isError($property)) {
|
if(HTML_AJAX_JSON::isError($property))
|
||||||
return $property;
|
return $property;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return '{' . join(',', $properties) . '}';
|
return '{' . join(',', $properties) . '}';
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return ($this->use & SERVICES_JSON_SUPPRESS_ERRORS)
|
return ($this->use & SERVICES_JSON_SUPPRESS_ERRORS)
|
||||||
? 'null'
|
? 'null'
|
||||||
: new Services_JSON_Error(gettype($var)." can not be encoded as JSON string");
|
: new HTML_AJAX_JSON_Error(gettype($var)." can not be encoded as JSON string");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -435,9 +438,8 @@ class Services_JSON
|
||||||
{
|
{
|
||||||
$encoded_value = $this->encode($value);
|
$encoded_value = $this->encode($value);
|
||||||
|
|
||||||
if(Services_JSON::isError($encoded_value)) {
|
if(HTML_AJAX_JSON::isError($encoded_value))
|
||||||
return $encoded_value;
|
return $encoded_value;
|
||||||
}
|
|
||||||
|
|
||||||
return $this->encode(strval($name)) . ':' . $encoded_value;
|
return $this->encode(strval($name)) . ':' . $encoded_value;
|
||||||
}
|
}
|
||||||
|
@ -476,7 +478,7 @@ class Services_JSON
|
||||||
*
|
*
|
||||||
* @return mixed number, boolean, string, array, or object
|
* @return mixed number, boolean, string, array, or object
|
||||||
* corresponding to given JSON input string.
|
* corresponding to given JSON input string.
|
||||||
* See argument 1 to Services_JSON() above for object-output behavior.
|
* See argument 1 to HTML_AJAX_JSON() above for object-output behavior.
|
||||||
* Note that decode() always returns strings
|
* Note that decode() always returns strings
|
||||||
* in ASCII or UTF-8 format!
|
* in ASCII or UTF-8 format!
|
||||||
* @access public
|
* @access public
|
||||||
|
@ -496,8 +498,6 @@ class Services_JSON
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
$m = array();
|
|
||||||
|
|
||||||
if (is_numeric($str)) {
|
if (is_numeric($str)) {
|
||||||
// Lookie-loo, it's a number
|
// Lookie-loo, it's a number
|
||||||
|
|
||||||
|
@ -665,8 +665,6 @@ class Services_JSON
|
||||||
// out the property name and set an
|
// out the property name and set an
|
||||||
// element in an associative array,
|
// element in an associative array,
|
||||||
// for now
|
// for now
|
||||||
$parts = array();
|
|
||||||
|
|
||||||
if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
|
if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
|
||||||
// "name":value pair
|
// "name":value pair
|
||||||
$key = $this->decode($parts[1]);
|
$key = $this->decode($parts[1]);
|
||||||
|
@ -698,10 +696,9 @@ class Services_JSON
|
||||||
|
|
||||||
} elseif (($chrs{$c} == $top['delim']) &&
|
} elseif (($chrs{$c} == $top['delim']) &&
|
||||||
($top['what'] == SERVICES_JSON_IN_STR) &&
|
($top['what'] == SERVICES_JSON_IN_STR) &&
|
||||||
((strlen(substr($chrs, 0, $c)) - strlen(rtrim(substr($chrs, 0, $c), '\\'))) % 2 != 1)) {
|
(($chrs{$c - 1} != '\\') ||
|
||||||
|
($chrs{$c - 1} == '\\' && $chrs{$c - 2} == '\\'))) {
|
||||||
// found a quote, we're in a string, and it's not escaped
|
// found a quote, we're in a string, and it's not escaped
|
||||||
// we know that it's not escaped becase there is _not_ an
|
|
||||||
// odd number of backslashes at the end of the string so far
|
|
||||||
array_pop($stk);
|
array_pop($stk);
|
||||||
//print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n");
|
//print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n");
|
||||||
|
|
||||||
|
@ -765,7 +762,7 @@ class Services_JSON
|
||||||
*/
|
*/
|
||||||
function isError($data, $code = null)
|
function isError($data, $code = null)
|
||||||
{
|
{
|
||||||
if (class_exists('pear')) {
|
if (HTML_AJAX_class_exists('pear', false)) {
|
||||||
return PEAR::isError($data, $code);
|
return PEAR::isError($data, $code);
|
||||||
} elseif (is_object($data) && (get_class($data) == 'services_json_error' ||
|
} elseif (is_object($data) && (get_class($data) == 'services_json_error' ||
|
||||||
is_subclass_of($data, 'services_json_error'))) {
|
is_subclass_of($data, 'services_json_error'))) {
|
||||||
|
@ -776,11 +773,11 @@ class Services_JSON
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (class_exists('PEAR_Error')) {
|
if (HTML_AJAX_class_exists('pear_error', false)) {
|
||||||
|
|
||||||
class Services_JSON_Error extends PEAR_Error
|
class HTML_AJAX_JSON_Error extends PEAR_Error
|
||||||
{
|
{
|
||||||
function Services_JSON_Error($message = 'unknown error', $code = null,
|
function HTML_AJAX_JSON_Error($message = 'unknown error', $code = null,
|
||||||
$mode = null, $options = null, $userinfo = null)
|
$mode = null, $options = null, $userinfo = null)
|
||||||
{
|
{
|
||||||
parent::PEAR_Error($message, $code, $mode, $options, $userinfo);
|
parent::PEAR_Error($message, $code, $mode, $options, $userinfo);
|
||||||
|
@ -792,9 +789,9 @@ if (class_exists('PEAR_Error')) {
|
||||||
/**
|
/**
|
||||||
* @todo Ultimately, this class shall be descended from PEAR_Error
|
* @todo Ultimately, this class shall be descended from PEAR_Error
|
||||||
*/
|
*/
|
||||||
class Services_JSON_Error
|
class HTML_AJAX_JSON_Error
|
||||||
{
|
{
|
||||||
function Services_JSON_Error($message = 'unknown error', $code = null,
|
function HTML_AJAX_JSON_Error($message = 'unknown error', $code = null,
|
||||||
$mode = null, $options = null, $userinfo = null)
|
$mode = null, $options = null, $userinfo = null)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -802,5 +799,21 @@ if (class_exists('PEAR_Error')) {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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: */
|
||||||
?>
|
?>
|
78
lib/pear/HTML/AJAX/Response.php
Executable file
78
lib/pear/HTML/AJAX/Response.php
Executable file
|
@ -0,0 +1,78 @@
|
||||||
|
<?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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
20
lib/pear/HTML/AJAX/Serializer/Error.php
Executable file
20
lib/pear/HTML/AJAX/Serializer/Error.php
Executable file
|
@ -0,0 +1,20 @@
|
||||||
|
<?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: */
|
||||||
|
?>
|
96
lib/pear/HTML/AJAX/Serializer/JSON.php
Executable file
96
lib/pear/HTML/AJAX/Serializer/JSON.php
Executable file
|
@ -0,0 +1,96 @@
|
||||||
|
<?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: */
|
||||||
|
?>
|
28
lib/pear/HTML/AJAX/Serializer/Null.php
Executable file
28
lib/pear/HTML/AJAX/Serializer/Null.php
Executable file
|
@ -0,0 +1,28 @@
|
||||||
|
<?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: */
|
||||||
|
?>
|
88
lib/pear/HTML/AJAX/Serializer/PHP.php
Executable file
88
lib/pear/HTML/AJAX/Serializer/PHP.php
Executable file
|
@ -0,0 +1,88 @@
|
||||||
|
<?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: */
|
||||||
|
?>
|
67
lib/pear/HTML/AJAX/Serializer/Urlencoded.php
Executable file
67
lib/pear/HTML/AJAX/Serializer/Urlencoded.php
Executable file
|
@ -0,0 +1,67 @@
|
||||||
|
<?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: */
|
||||||
|
?>
|
88
lib/pear/HTML/AJAX/Serializer/XML.php
Executable file
88
lib/pear/HTML/AJAX/Serializer/XML.php
Executable file
|
@ -0,0 +1,88 @@
|
||||||
|
<?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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
725
lib/pear/HTML/AJAX/Server.php
Executable file
725
lib/pear/HTML/AJAX/Server.php
Executable file
|
@ -0,0 +1,725 @@
|
||||||
|
<?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: */
|
||||||
|
?>
|
|
@ -2,13 +2,13 @@ PEAR Libraries
|
||||||
====================================================================
|
====================================================================
|
||||||
|
|
||||||
|
|
||||||
This directory (lib/pear) contains unmodified copies of some
|
This directory (lib/pear) contains unmodified copies of some
|
||||||
libraries from the standard PEAR distribution (http://pear.php.net).
|
libraries from the standard PEAR distribution (http://pear.php.net).
|
||||||
|
|
||||||
We include these in Moodle solely for the convenience of sites that
|
We include these in Moodle solely for the convenience of sites that
|
||||||
may not have PEAR installed.
|
may not have PEAR installed.
|
||||||
|
|
||||||
If this directory is DELETED from Moodle then Moodle will search
|
If this directory is DELETED from Moodle then Moodle will search
|
||||||
the standard PHP directories and use the PEAR libraries there instead.
|
the standard PHP directories and use the PEAR libraries there instead.
|
||||||
|
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ In detail, the libraries added here are:
|
||||||
- http://pear.php.net/package/HTML
|
- http://pear.php.net/package/HTML
|
||||||
- PEAR main class:
|
- PEAR main class:
|
||||||
- Current version: 1.4.5
|
- Current version: 1.4.5
|
||||||
- by Stig Bakken, Thomas V.V.Cox, Pierre-Alain Joye,
|
- by Stig Bakken, Thomas V.V.Cox, Pierre-Alain Joye,
|
||||||
Greg Beaver and Martin Jansen
|
Greg Beaver and Martin Jansen
|
||||||
- License: PHP
|
- License: PHP
|
||||||
- http://pear.php.net/package/PEAR
|
- http://pear.php.net/package/PEAR
|
||||||
|
@ -60,23 +60,28 @@ In detail, the libraries added here are:
|
||||||
- by Hartmut Holzgraefe and Christian Stocker
|
- by Hartmut Holzgraefe and Christian Stocker
|
||||||
- License: BSD
|
- License: BSD
|
||||||
- http://pear.php.net/package/HTTP_WebDAV_Server
|
- http://pear.php.net/package/HTTP_WebDAV_Server
|
||||||
|
- PEAR HTML_AJAX:
|
||||||
|
- Current version: 0.5.6
|
||||||
|
- by Elizabeth Smith, Arpad Ray, Joshua Eichorn, David Coallier and Laurent Yaish
|
||||||
|
- License: LGPL
|
||||||
|
- http://pear.php.net/package/HTML_AJAX/
|
||||||
|
|
||||||
|
|
||||||
----------------------------------------------------------------
|
----------------------------------------------------------------
|
||||||
A NOTE TO DEVELOPERS
|
A NOTE TO DEVELOPERS
|
||||||
================================================================
|
================================================================
|
||||||
|
|
||||||
We must not use these classes directly ever. Instead we must build
|
We must not use these classes directly ever. Instead we must build
|
||||||
and use wrapper classes to isolate Moodle code from internal PEAR
|
and use wrapper classes to isolate Moodle code from internal PEAR
|
||||||
implementations, allowing us to migrate if needed to other
|
implementations, allowing us to migrate if needed to other
|
||||||
libraries in the future. For an example of wrapped classes,
|
libraries in the future. For an example of wrapped classes,
|
||||||
see the excel.class.lib file, that includes code to build
|
see the excel.class.lib file, that includes code to build
|
||||||
Excel files using the cool library inside PEAR, but using
|
Excel files using the cool library inside PEAR, but using
|
||||||
the old calls used before Moodle 1.6 to maintain compatibility.
|
the old calls used before Moodle 1.6 to maintain compatibility.
|
||||||
|
|
||||||
Please, don't forget it! Always use wrapper classes/functions!
|
Please, don't forget it! Always use wrapper classes/functions!
|
||||||
|
|
||||||
Ciao,
|
Ciao,
|
||||||
Eloy Lafuente, 2005-12-17 :-)
|
Eloy Lafuente, 2005-12-17 :-)
|
||||||
|
|
||||||
|
|
||||||
|
@ -88,28 +93,28 @@ A NOTE ON THE PHP LICENSE AND MOODLE
|
||||||
Everything in Moodle in pure GPL. This pear directory is the only
|
Everything in Moodle in pure GPL. This pear directory is the only
|
||||||
part of the distribution that is not.
|
part of the distribution that is not.
|
||||||
|
|
||||||
There is some question about how PHP-licensed software can be
|
There is some question about how PHP-licensed software can be
|
||||||
included within a GPL-licensed distribution like Moodle, specifically
|
included within a GPL-licensed distribution like Moodle, specifically
|
||||||
the clause that annoyingly says no derivative of the software can
|
the clause that annoyingly says no derivative of the software can
|
||||||
include the name PHP.
|
include the name PHP.
|
||||||
|
|
||||||
We don't intend to rename Moodle to anything of the sort, obviously,
|
We don't intend to rename Moodle to anything of the sort, obviously,
|
||||||
but to help people downstream who could possibly want to do so,
|
but to help people downstream who could possibly want to do so,
|
||||||
we have sought special permission from the authors of these classes
|
we have sought special permission from the authors of these classes
|
||||||
to allow us an exemption on this point so that we don't need to
|
to allow us an exemption on this point so that we don't need to
|
||||||
change our nice clean GPL license.
|
change our nice clean GPL license.
|
||||||
|
|
||||||
Several authors have given Moodle explicit permission to distribute
|
Several authors have given Moodle explicit permission to distribute
|
||||||
their PHP-licensed PEAR classes in the Moodle distribution, allowing
|
their PHP-licensed PEAR classes in the Moodle distribution, allowing
|
||||||
anybody using these classes ONLY as part of the Moodle distribution
|
anybody using these classes ONLY as part of the Moodle distribution
|
||||||
exemption from clauses of the PHP license that could cause
|
exemption from clauses of the PHP license that could cause
|
||||||
conflict with the main GNU Public License that Moodle uses.
|
conflict with the main GNU Public License that Moodle uses.
|
||||||
|
|
||||||
We are still waiting to hear back from the others but we assume
|
We are still waiting to hear back from the others but we assume
|
||||||
for now that it will likewise be OK.
|
for now that it will likewise be OK.
|
||||||
|
|
||||||
If you are at all worried about this situation you can simply delete
|
If you are at all worried about this situation you can simply delete
|
||||||
this directory from Moodle and it will use your installed PEAR
|
this directory from Moodle and it will use your installed PEAR
|
||||||
libraries instead.
|
libraries instead.
|
||||||
|
|
||||||
Cheers,
|
Cheers,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue