cvs: pear /HTML_AJAX AJAX.php DeveloperNotes.txt package.php /HTML_AJAX/AJAX Action.php Debug.php Helper.php Response.php Server.php
/HTML_AJAX/AJAX/Serializer Error.php JSON.php Null.php PHP.php Urlencoded.php /HTML_AJAX/examples README action_usage.php auto_server.php
error_usage.php form.php grab.php haa_usage.php helper_usage.php index.php php_callback.php proxy_usage_inline_javascript.php proxy_usage_server.php
proxyless_usage.php queue_usage.php server.php shoutbox.php slow_livesearch.php slow_server.php xml_usage.php xmlserver.php

From: Date: Fri, 13 Oct 2006 15:31:23 +0000
Subject: cvs: pear /HTML_AJAX AJAX.php DeveloperNotes.txt package.php /HTML_AJAX/AJAX Action.php Debug.php Helper.php Response.php Server.php
/HTML_AJAX/AJAX/Serializer Error.php JSON.php Null.php PHP.php Urlencoded.php /HTML_AJAX/examples README action_usage.php auto_server.php
error_usage.php form.php grab.php haa_usage.php helper_usage.php index.php php_callback.php proxy_usage_inline_javascript.php proxy_usage_server.php
proxyless_usage.php queue_usage.php server.php shoutbox.php slow_livesearch.php slow_server.php xml_usage.php xmlserver.php
Groups: php.pear.cvs 
Request: Send a blank email to pear-cvs+get-42527@lists.php.net to get a copy of this message
davidc Fri Oct 13 15:31:23 2006 UTC Added files: /pear/HTML_AJAX DeveloperNotes.txt /pear/HTML_AJAX/examples action_usage.php form.php grab.php haa_usage.php php_callback.php shoutbox.php slow_livesearch.php slow_server.php xml_usage.php xmlserver.php Modified files: /pear/HTML_AJAX AJAX.php package.php /pear/HTML_AJAX/AJAX Action.php Debug.php Helper.php Response.php Server.php /pear/HTML_AJAX/AJAX/Serializer Error.php JSON.php Null.php PHP.php Urlencoded.php /pear/HTML_AJAX/examples README auto_server.php error_usage.php helper_usage.php index.php proxy_usage_inline_javascript.php proxy_usage_server.php proxyless_usage.php queue_usage.php server.php Log: - Latest files from SVN, latest update

http://cvs.php.net/viewvc.cgi/pear/HTML_AJAX/AJAX.php?r1=1.10&r2=1.11&diff_format=u Index: pear/HTML_AJAX/AJAX.php diff -u pear/HTML_AJAX/AJAX.php:1.10 pear/HTML_AJAX/AJAX.php:1.11 --- pear/HTML_AJAX/AJAX.php:1.10 Mon Nov 7 18:40:10 2005 +++ pear/HTML_AJAX/AJAX.php Fri Oct 13 15:31:22 2006 @@ -1,15 +1,5 @@ <?php -// $Id: AJAX.php,v 1.10 2005/11/07 18:40:10 davidc Exp $ -/** - * OO AJAX Implementation for PHP - * - * @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@ - */ +// $Id: AJAX.php,v 1.11 2006/10/13 15:31:22 davidc Exp $ /** * This is a quick hack, loading serializers as needed doesn't work in php5 @@ -17,20 +7,23 @@ require_once "HTML/AJAX/Serializer/JSON.php"; require_once "HTML/AJAX/Serializer/Null.php"; require_once "HTML/AJAX/Serializer/Error.php"; +require_once "HTML/AJAX/Serializer/XML.php"; +require_once "HTML/AJAX/Serializer/PHP.php"; require_once 'HTML/AJAX/Debug.php'; /** * OO AJAX Implementation for PHP * - * @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 - * @todo Decide if its good thing to support get - * @todo Add some sort of debugging console + * @category HTML + * @package AJAX + * @author Joshua Eichorn <josh@bluga.net> + * @author Arpad Ray <arpad@php.net> + * @author David Coallier <davidc@php.net> + * @author Elizabeth Smith <auroraeosrose@gmail.com> + * @copyright 2005 Joshua Eichorn, Arpad Ray, David Coallier, Elizabeth Smith + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @version Release: @package_version@ + * @link http://pear.php.net/package/HTML_AJAX */ class HTML_AJAX { /** @@ -43,18 +36,7 @@ * @var object * @access private */ - var $_exportedInstances; - - /** - * To make integration with applications easier, you can - * register callbacks to serve header calls, clean/retrive server vars - * and clean/retrieve get vars - */ - var $_callbacks = array( - 'headers' => array('HTML_AJAX', '_sendHeaders'), - 'get' => array('HTML_AJAX', '_getVar'), - 'server' => array('HTML_AJAX', '_getVar'), - ); + var $_exportedInstances = array(); /** * Set the server url in the generated stubs to this value @@ -65,29 +47,39 @@ /** * What encoding your going to use for serializing data from php being sent to javascript - * @var string JSON|null + * @var string JSON|PHP|Null */ var $serializer = 'JSON'; /** * What encoding your going to use for unserializing data sent from javascript - * @var string JSON|null + * @var string JSON|PHP|Null */ var $unserializer = 'JSON'; /** + * Option to use loose typing for JSON encoding + * @var bool + * @access public + */ + var $jsonLooseType = true; + + /** * Content-type map * * Used in to automatically choose serializers as needed */ var $contentTypeMap = array( 'JSON' => 'application/json', + 'XML' => 'application/xml', 'Null' => 'text/plain', 'Error' => 'application/error', + 'PHP' => 'application/php-serialized', + 'Urlencoded' => 'application/x-www-form-urlencoded' ); /** - * This is the debug variable that we will be passing the + * This is the debug variable that we will be passing the * HTML_AJAX_Debug instance to. * * @param object HTML_AJAX_Debug @@ -106,7 +98,7 @@ * * @access public */ - var $debugSession = false; + var $debugSession = false; /** * If the Content-Length header should be sent, if your using a gzip handler on an output buffer, or run into any compatability problems, try disabling this. @@ -115,21 +107,75 @@ * @var boolean */ var $sendContentLength = true; - + + /** + * Make Generated code compatible with php4 by lowercasing all class/method names before exporting to JavaScript + * If you have code that works on php4 but not on php5 then setting this flag can fix the problem. + * The recommended solution is too specify the class and method names when registering the class letting you have function case in php4 as well + * + * @access public + * @var boolean + */ + var $php4CompatCase = false; + + /** + * Automatically pack all generated JavaScript making it smaller + * + * If your using output compression this might not make sense + */ + var $packJavaScript = false; + + /** + * Holds current payload info + * + * @access private + * @var string + */ + var $_payload; + + /** + * Holds iframe id IF this is an iframe xmlhttprequest + * + * @access private + * @var string + */ + var $_iframe; + + /** + * Holds the list of classes permitted to be unserialized + * + * @access private + * @var array + */ + var $_allowedClasses = array(); + + /** + * Holds serializer instances + */ + var $_serializers = array(); + + /** + * PHP callbacks we're exporting + */ + var $_validCallbacks = array(); + /** * Set a class to handle requests * * @param object $instance - * @param string|bool $exportedName Name used for the javascript class, if false the name of the php class is used - * @param array|bool $exportedMethods If false all functions without a _ prefix are exported, if an array only the methods listed in the array are exported + * @param mixed $exportedName Name used for the javascript class, if false the name of the php class is used + * @param mixed $exportedMethods If false all functions without a _ prefix are exported, if an array only the methods listed in the array are exported * @return void */ - function registerClass(&$instance, $exportedName = false, $exportedMethods = false) + function registerClass(&$instance, $exportedName = false, $exportedMethods = false) { $className = strtolower(get_class($instance)); if ($exportedName === false) { - $exportedName = $className; + $exportedName = get_class($instance); + if ($this->php4CompatCase) { + $exportedName = strtolower($exportedName); + } } if ($exportedMethods === false) { @@ -148,15 +194,15 @@ /** * Get a list of methods in a class to export * - * This function uses get_class_methods to get a list of callable methods, so if your on PHP5 extending this class with a class you want to export should export its - * protected methods, while normally only its public methods would be exported. All methods starting with _ are removed from the export list. This covers - * PHP4 style private by naming as well as magic methods in either PHP4 or PHP5 + * This function uses get_class_methods to get a list of callable methods, so if you're on PHP5 extending this class with a class you want to export should export its + * protected methods, while normally only its public methods would be exported. All methods starting with _ are removed from the export list. + * This covers PHP4 style private by naming as well as magic methods in either PHP4 or PHP5 * - * @param string $className - * @return array all methods of the class that are public + * @param string $className + * @return array all methods of the class that are public * @access private */ - function _getMethodsToExport($className) + function _getMethodsToExport($className) { $funcs = get_class_methods($className); @@ -164,6 +210,9 @@ if (strtolower($func) === $className || substr($func,0,1) === '_') { unset($funcs[$key]); } + else if ($this->php4CompatCase) { + $funcs[$key] = strtolower($func); + } } return $funcs; } @@ -171,58 +220,36 @@ /** * Generate the client Javascript code * - * @return string generated javascript client code + * @return string generated javascript client code */ - function generateJavaScriptClient() + function generateJavaScriptClient() { $client = ''; $names = array_keys($this->_exportedInstances); - foreach($names as $name) { + foreach ($names as $name) { $client .= $this->generateClassStub($name); } return $client; } /** - * Registers callbacks for sending headers or retriving post/get vars - * for better application integration - */ - function registerCallback($callback, $type = 'headers') - { - if(is_callable($callback)) { - if($type == 'headers') { - $this->_callbacks['headers'] = $callback; - return true; - } elseif($type == 'get') { - $this->_callbacks['get'] = $callback; - return true; - } elseif($type == 'server') { - $this->_callbacks['server'] = $callback; - return true; - } else { - return false; - } - } - } - - /** * Return the stub for a class * - * @param string $name name of the class to generated the stub for, note that this is the exported name not the php class name - * @return string javascript proxy stub code for a single class + * @param string $name name of the class to generated the stub for, note that this is the exported name not the php class name + * @return string javascript proxy stub code for a single class */ - function generateClassStub($name) + function generateClassStub($name) { if (!isset($this->_exportedInstances[$name])) { return ''; } - $client = "// Client stub for the {$this->_exportedInstances[$name]['className']} PHP Class\n"; + $client = "// Client stub for the {$this->_exportedInstances[$name]['exportedName']} PHP Class\n"; $client .= "function {$this->_exportedInstances[$name]['exportedName']}(callback) {\n"; $client .= "\tmode = 'sync';\n"; $client .= "\tif (callback) { mode = 'async'; }\n"; - $client .= "\tthis.className = '{$name}';\n"; + $client .= "\tthis.className = '{$this->_exportedInstances[$name]['exportedName']}';\n"; if ($this->serverUrl) { $client .= "\tthis.dispatcher = new HTML_AJAX_Dispatcher(this.className,mode,callback,'{$this->serverUrl}','{$this->unserializer}');\n}\n"; } else { @@ -230,88 +257,166 @@ } $client .= "{$this->_exportedInstances[$name]['exportedName']}.prototype = {\n"; $client .= "\tSync: function() { this.dispatcher.Sync(); }, \n"; - $client .= "\tAsync: function(callback) { this.dispatcher.Async(callback); },\n"; + $client .= "\tAsync: function(callback) { this.dispatcher.Async(callback); },\n"; foreach($this->_exportedInstances[$name]['exportedMethods'] as $method) { $client .= $this->_generateMethodStub($method); } $client = substr($client,0,(strlen($client)-2))."\n"; $client .= "}\n\n"; + + if ($this->packJavaScript) { + $client = $this->packJavaScript($client); + } return $client; } /** * Returns a methods stub - * + * * * @param string the method name * @return string the js code * @access private */ - function _generateMethodStub($method) + function _generateMethodStub($method) { $stub = "\t{$method}: function() { return this.dispatcher.doCall('{$method}',arguments); },\n"; return $stub; } /** + * Populates the current payload + * + * + * @param string the method name + * @return string the js code + * @access private + */ + function populatePayload() + { + if(isset($_REQUEST['Iframe_XHR'])) { + $this->_iframe = $_REQUEST['Iframe_XHR_id']; + if (isset($_REQUEST['Iframe_XHR_headers']) && is_array($_REQUEST['Iframe_XHR_headers'])) { + foreach ($_REQUEST['Iframe_XHR_headers'] as $header) { + $array = explode(':', $header); + $array[0] = strip_tags(strtoupper(str_replace('-', '_', $array[0]))); + //only content-length and content-type can go in without an http_ prefix - security + if(strpos($array[0], 'HTTP_') !== 0 + && strcmp('CONTENT_TYPE', $array[0]) + && strcmp('CONTENT_LENGTH', $array[0])) { + $array[0] = 'HTTP_' . $array[0]; + } + $_SERVER[$array[0]] = strip_tags($array[1]); + } + } + $this->_payload = (isset($_REQUEST['Iframe_XHR_data']) ? $_REQUEST['Iframe_XHR_data'] : ''); + if (isset($_REQUEST['Iframe_XHR_method'])) { + $_GET['m'] = $_REQUEST['Iframe_XHR_method']; + } + if (isset($_REQUEST['Iframe_XHR_class'])) { + $_GET['c'] = $_REQUEST['Iframe_XHR_class']; + } + } + } + + /** * Handle a ajax request if needed * * The current check is if GET variables c (class) and m (method) are set, more options may be available in the future * * @todo is it worth it to figure out howto use just 1 instance if the type is the same for serialize and unserialize * - * @return boolean true if an ajax call was handled, false otherwise + * @return boolean true if an ajax call was handled, false otherwise */ - function handleRequest() + function handleRequest() { - $class = call_user_func((array)$this->_callbacks['get'], 'c'); - $method = call_user_func($this->_callbacks['get'], 'm'); - if (!empty($class) && !empty($method)) { - set_error_handler(array(&$this,'_errorHandler')); - if (function_exists('set_exception_handler')) { - set_exception_handler(array(&$this,'_exceptionHandler')); + set_error_handler(array(&$this,'_errorHandler')); + if (function_exists('set_exception_handler')) { + set_exception_handler(array(&$this,'_exceptionHandler')); + } + if (isset($_GET['px'])) { + if ($this->_iframeGrabProxy()) { + restore_error_handler(); + if (function_exists('restore_exception_handler')) { + restore_exception_handler(); + } + return true; } - + } + + $class = strtolower($this->_getVar('c')); + $method = $this->_getVar('m'); + $phpCallback = $this->_getVar('cb'); + + if (!empty($class) && !empty($method)) { if (!isset($this->_exportedInstances[$class])) { // handle error - trigger_error('Unknown class: '.$class); + trigger_error('Unknown class: '. $class); } if (!in_array($method,$this->_exportedInstances[$class]['exportedMethods'])) { // handle error - trigger_error('Unknown method: '.$method); - } - - // auto-detect serializer to use from content-type - $type = $this->unserializer; - $key = array_search($this->_getClientPayloadContentType(),$this->contentTypeMap); - if ($key) { - $type = $key; + trigger_error('Unknown method: ' . $method); } - $unserializer = $this->_getSerializer($type); - - $args = $unserializer->unserialize($this->_getClientPayload()); - if (!is_array($args)) { - $args = array($args); + } else if (!empty($phpCallback)) { + if (strpos($phpCallback, '.') !== false) { + $phpCallback = explode('.', $phpCallback); + } + if (!$this->_validatePhpCallback($phpCallback)) { + restore_error_handler(); + if (function_exists('restore_exception_handler')) { + restore_exception_handler(); + } + return false; } - $ret = call_user_func_array(array(&$this->_exportedInstances[$class]['instance'],$method),$args); - - + } else { restore_error_handler(); - $this->_sendResponse($ret); + if (function_exists('restore_exception_handler')) { + restore_exception_handler(); + } + return false; + } - return true; + // auto-detect serializer to use from content-type + $type = $this->unserializer; + $key = array_search($this->_getClientPayloadContentType(),$this->contentTypeMap); + if ($key) { + $type = $key; + } + $unserializer = $this->_getSerializer($type); + + $args = $unserializer->unserialize($this->_getClientPayload(), $this->_allowedClasses); + if (!is_array($args)) { + $args = array($args); + } + + if (empty($phpCallback)) { + $ret = call_user_func_array(array(&$this->_exportedInstances[$class]['instance'], $method), $args); + } else { + $ret = call_user_func_array($phpCallback, $args); } - return false; + + restore_error_handler(); + $this->_sendResponse($ret); + return true; } - function _getClientPayloadContentType() { - if (isset($_SERVER['CONTENT_TYPE'])) { - $type = $_SERVER['CONTENT_TYPE']; - if (strstr($type,';')) { - $types = explode(';',$type); - $type = array_shift($types); - } - return strtolower($type); + /** + * Determines the content type of the client payload + * + * @return string + * a MIME content type + */ + function _getClientPayloadContentType() + { + //OPERA IS STUPID FIX + if (isset($_SERVER['HTTP_X_CONTENT_TYPE'])) { + $type = $this->_getServer('HTTP_X_CONTENT_TYPE'); + $pos = strpos($type, ';'); + return strtolower($pos ? substr($type, 0, $pos) : $type); + } else if (isset($_SERVER['CONTENT_TYPE'])) { + $type = $this->_getServer('CONTENT_TYPE'); + $pos = strpos($type, ';'); + return strtolower($pos ? substr($type, 0, $pos) : $type); } return 'text/plain'; } @@ -320,45 +425,93 @@ * Send a reponse adding needed headers and serializing content * * Note: this method echo's output as well as setting headers to prevent caching + * Iframe Detection: if this has been detected as an iframe response, it has to + * be wrapped in different code and headers changed (quite a mess) * - * @param mixed content to serialize and send - * @access private + * @param mixed content to serialize and send + * @access private */ - function _sendResponse($response) + function _sendResponse($response) { + if(is_object($response) && is_a($response, 'HTML_AJAX_Response')) { + $output = $response->getPayload(); + $content = $response->getContentType(); + } else if(is_a($response, 'PEAR_Error')) { + $serializer = $this->_getSerializer('Error'); + $output = $serializer->serialize(array( + 'message' => $response->getMessage(), + 'userinfo' => $response->getUserInfo(), + 'code' => $response->getCode(), + 'mode' => $response->getMode() + ) + ); + $content = $this->contentTypeMap['Error']; + } else { $serializer = $this->_getSerializer($this->serializer); $output = $serializer->serialize($response); - - // headers to force things not to be cached: - $headers = array(); - if ($this->sendContentLength) { - $headers['Content-Length'] = strlen($output); - } - $headers['Expires'] = 'Mon, 26 Jul 1997 05:00:00 GMT'; - $headers['Last-Modified'] = gmdate( "D, d M Y H:i:s" ) . 'GMT'; - $headers['Cache-Control'] = 'no-cache, must-revalidate'; - $headers['Pragma'] = 'no-cache'; - if (isset($this->contentTypeMap[$this->serializer])) { //remember that IE is stupid and wants a capital T - $headers['Content-Type'] = $this->contentTypeMap[$this->serializer]; + $content = $this->contentTypeMap[$this->serializer]; } + } + // headers to force things not to be cached: + $headers = array(); + //OPERA IS STUPID FIX + if(isset($_SERVER['HTTP_X_CONTENT_TYPE'])) + { + $headers['X-Content-Type'] = $content; + $content = 'text/plain'; + } + if ($this->_sendContentLength()) { + $headers['Content-Length'] = strlen($output); + } + $headers['Expires'] = 'Mon, 26 Jul 1997 05:00:00 GMT'; + $headers['Last-Modified'] = gmdate( "D, d M Y H:i:s" ) . 'GMT'; + $headers['Cache-Control'] = 'no-cache, must-revalidate'; + $headers['Pragma'] = 'no-cache'; + $headers['Content-Type'] = $content.'; charset=utf-8'; + + //intercept to wrap iframe return data + if($this->_iframe) + { + $output = $this->_iframeWrapper($this->_iframe, $output, $headers); + $headers['Content-Type'] = 'text/html; charset=utf-8'; + } + $this->_sendHeaders($headers); + echo $output; + } - call_user_func($this->_callbacks['headers'],$headers); - echo $output; + /** + * Decide if we should send a Content-length header + * @return bool true if it's ok to send the header, false otherwise + * @access private + */ + function _sendContentLength() { + if (!$this->sendContentLength) { + return false; + } + $ini_tests = array( "output_handler", + "zlib.output_compression", + "zlib.output_handler"); + foreach($ini_tests as $test) { + if (ini_get($test)) { + return false; + } + } + return (ob_get_level() <= 0); } /** * Actually send a list of headers * - * @param array list of headers to send, default callback for headers + * @param array list of headers to send, default callback for headers * @access private */ - function _sendHeaders($array) + function _sendHeaders($array) { - foreach($array as $header => $value) { - header($header .': '.$value); - } + foreach($array as $header => $value) { + header($header . ': ' . $value); + } } /** @@ -366,36 +519,57 @@ * * @access private */ - function _getSerializer($type) + function _getSerializer($type) { + if (isset($this->_serializers[$type])) { + return $this->_serializers[$type]; + } + $class = 'HTML_AJAX_Serializer_'.$type; - if (!class_exists($class)) { + if ( (version_compare(phpversion(),5,'>') && !class_exists($class,false)) || (version_compare(phpversion(),5,'<') && !class_exists($class)) ) { // include the class only if it isn't defined require_once "HTML/AJAX/Serializer/{$type}.php"; } - $instance = new $class(); - return $instance; + //handle JSON loose typing option for associative arrays + if ($type == 'JSON') { + $this->_serializers[$type] = new $class($this->jsonLooseType); + } else { + $this->_serializers[$type] = new $class(); + } + return $this->_serializers[$type]; } /** * Get payload in its submitted form, currently only supports raw post * - * @access private - * @return string raw post data + * @access private + * @return string raw post data */ - function _getClientPayload() { - return $GLOBALS['HTTP_RAW_POST_DATA']; + function _getClientPayload() + { + if (empty($this->_payload)) { + if (isset($GLOBALS['HTTP_RAW_POST_DATA'])) { + $this->_payload = $GLOBALS['HTTP_RAW_POST_DATA']; + } else if (function_exists('file_get_contents')) { + // both file_get_contents() and php://input require PHP >= 4.3.0 + $this->_payload = file_get_contents('php://input'); + } else { + $this->_payload = ''; + } + } + return $this->_payload; } /** - * stub for getting get/server vars - applies strip_tags + * stub for getting get vars - applies strip_tags * - * @access private - * @return string filtered _GET value + * @access private + * @return string filtered _GET value */ - function _getVar($var) { + function _getVar($var) + { if (!isset($_GET[$var])) { return NULL; } else { @@ -404,21 +578,37 @@ } /** + * stub for getting server vars - applies strip_tags + * + * @access private + * @return string filtered _GET value + */ + function _getServer($var) + { + if (!isset($_SERVER[$var])) { + return NULL; + } else { + return strip_tags($_SERVER[$var]); + } + } + + /** * Exception handler, passes them to _errorHandler to do the actual work * * @access private */ - function _exceptionHandler($ex) { + function _exceptionHandler($ex) + { $this->_errorHandler($ex->getCode(),$ex->getMessage(),$ex->getFile(),$ex->getLine()); } - + /** * Error handler that sends it errors to the client side * * @access private */ - function _errorHandler($errno, $errstr, $errfile, $errline) + function _errorHandler($errno, $errstr, $errfile, $errline) { if ($errno & error_reporting()) { $e = new stdClass(); @@ -438,6 +628,252 @@ die(); } } + + /** + * Creates html to wrap serialized info for iframe xmlhttprequest fakeout + * + * @access private + */ + function _iframeWrapper($id, $data, $headers = array()) + { + $string = '<html><script type="text/javascript">'."\n".'var Iframe_XHR_headers = new Object();'; + foreach($headers as $label => $value) { + $string .= 'Iframe_XHR_headers["'.preg_replace("/\r?\n/", "\\n", addslashes($label)).'"] = "'.preg_replace("/\r?\n/", "\\n", addslashes($value))."\";\n"; + } + $string .= 'var Iframe_XHR_data = "' . preg_replace("/\r?\n/", "\\n", addslashes($data)) . '";</script>' + . '<body onload="parent.HTML_AJAX_IframeXHR_instances[\''.$id.'\']' + . '.isLoaded(Iframe_XHR_headers, Iframe_XHR_data);"></body></html>'; + return $string; + } + + /** + * Handles a proxied grab request + * + * @return bool true to end the response, false to continue trying to handle it + * @access private + */ + function _iframeGrabProxy() + { + if (!isset($_REQUEST['Iframe_XHR_id'])) { + trigger_error('Invalid iframe ID'); + return false; + } + $this->_iframe = $_REQUEST['Iframe_XHR_id']; + $this->_payload = (isset($_REQUEST['Iframe_XHR_data']) ? $_REQUEST['Iframe_XHR_data'] : ''); + $url = urldecode($_GET['px']); + $url_parts = parse_url($url); + $urlregex = '#^https?://#i'; + if (!preg_match($urlregex, $url) || $url_parts['host'] != $_SERVER['HTTP_HOST']) { + trigger_error('Invalid URL for grab proxy'); + return true; + } + $method = (isset($_REQUEST['Iframe_XHR_HTTP_method']) + ? strtoupper($_REQUEST['Iframe_XHR_HTTP_method']) + : 'GET'); + // validate method + if ($method != 'GET' && $method != 'POST') { + trigger_error('Invalid grab URL'); + return true; + } + // validate headers + $headers = ''; + if (isset($_REQUEST['Iframe_XHR_headers'])) { + foreach ($_REQUEST['Iframe_XHR_headers'] as $header) { + if (strpos($header, "\r") !== false + || strpos($header, "\n") !== false) { + trigger_error('Invalid grab header'); + return true; + } + $headers .= $header . "\r\n"; + } + } + // tries to make request with file_get_contents() + if (ini_get('allow_url_fopen') && version_compare(phpversion(), '5.0.0'. '>=')) { + $opts = array( + $url_parts['scheme'] => array( + 'method' => $method, + 'headers' => $headers, + 'content' => $this->_payload + ) + ); + $ret = @file_get_contents($url, false, stream_context_create($opts)); + if (!empty($ret)) { + $this->_sendResponse($ret); + return true; + } + } + // tries to make request using the curl extension + if (function_exists('curl_setopt')) { + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_HEADER, $headers); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + $ret = curl_exec($ch); + if ($ret !== false) { + curl_close($ch); + $this->_sendResponse($ret); + return true; + } + } + if (isset($url_parts['port'])) { + $port = $url_parts['port']; + } else { + $port = getservbyname(strtolower($url_parts['scheme']), 'tcp'); + if ($port === false) { + trigger_error('Grab proxy: Unknown port or service, defaulting to 80', E_USER_WARNING); + $port = 80; + } + } + if (!isset($url_parts['path'])) { + $url_parts['path'] = '/'; + } + if (!empty($url_parts['query'])) { + $url_parts['path'] .= '?' . $url_parts['query']; + } + $request = "$method {$url_parts['path']} HTTP/1.0\r\n" + . "Host: {$url['host']}\r\n" + . "Connection: close\r\n" + . "$headers\r\n"; + // tries to make request using the socket functions + $fp = fsockopen($_SERVER['HTTP_HOST'], $port, $errno, $errstr, 4); + if ($fp) { + fputs($fp, $request); + $ret = ''; + $done_headers = false; + while (!feof($fp)) { + $ret .= fgets($fp, 2048); + if ($done_headers || ($contentpos = strpos($ret, "\r\n\r\n")) === false) { + continue; + } + $done_headers = true; + $ret = substr($ret, $contentpos + 4); + } + fclose($fp); + $this->_sendResponse($ret); + return true; + } + // tries to make the request using the socket extension + $host = gethostbyname($url['host']); + if (($socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) < 0 + || ($connected = socket_connect($socket, $host, $port)) < 0 + || ($written = socket_write($socket, $request)) < strlen($request)) { + trigger_error('Grab proxy failed: ' . socket_strerror($socket)); + return true; + } + $ret = ''; + $done_headers = false; + while ($out = socket_read($socket, 2048)) { + $ret .= $out; + if ($done_headers || ($contentpos = strpos($ret, "\r\n\r\n")) === false) { + continue; + } + $done_headers = true; + $ret = substr($ret, $contentpos + 4); + } + socket_close($socket); + $this->_sendResponse($ret); + return true; + } + + /** + * Add a class or classes to those allowed to be unserialized + * + * @param mixed $classes + * the class or array of classes to add + * @access public + */ + function addAllowedClasses($classes) + { + if (!is_array($classes)) { + $this->_allowedClasses[] = $classes; + } else { + $this->_allowedClasses = array_merge($this->_allowedClasses, $classes); + } + $this->_allowedClasses = array_unique($this->_allowedClasses); + } + + /** + * Checks that the given callback is callable and allowed to be called + * + * @param callback $callback + * the callback to check + * @return bool + * true if the callback is valid, false otherwise + * @access private + */ + function _validatePhpCallback($callback) + { + if (!is_callable($callback)) { + return false; + } + $sig = md5(serialize($callback)); + return isset($this->_validCallbacks[$sig]); + } + + /** + * Register a callback so it may be called from JS + * + * @param callback $callback + * the callback to register + * @access public + */ + function registerPhpCallback($callback) + { + $this->_validCallbacks[md5(serialize($callback))] = 1; + } + + /** + * Make JavaScript code smaller + * + * Currently just strips whitespace and comments, needs to remain fast + */ + function packJavaScript($input) { + $stripPregs = array( + '/^\s+$/', + '/^\s*\/\/.*$/' + ); + $blockStart = '/\/\*/'; + $blockEnd = '/\*\//'; + + $out = ''; + + $lines = explode("\n",$input); + $inblock = false; + foreach($lines as $line) { + $keep = true; + if ($inblock) { + if (preg_match($blockEnd,$line)) { + $inblock = false; + $keep = false; + } + } + else if (preg_match($blockStart,$line)) { + $inblock = true; + $keep = false; + if (preg_match($blockEnd,$line)) { + $inblock = false; + } + } + + if (!$inblock) { + foreach($stripPregs as $preg) { + if (preg_match($preg,$line)) { + $keep = false; + break; + } + } + } + + if ($keep && !$inblock) { + $out .= trim($line)."\n"; + } + /* Enable to see what your striping out + else { + echo $line."<br>"; + }//*/ + } + return $out; + } } /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ ?> http://cvs.php.net/viewvc.cgi/pear/HTML_AJAX/package.php?r1=1.10&r2=1.11&diff_format=u Index: pear/HTML_AJAX/package.php diff -u pear/HTML_AJAX/package.php:1.10 pear/HTML_AJAX/package.php:1.11 --- pear/HTML_AJAX/package.php:1.10 Mon Nov 7 18:48:52 2005 +++ pear/HTML_AJAX/package.php Fri Oct 13 15:31:22 2006 @@ -13,18 +13,15 @@ * @author Greg Beaver <cellog@php.net> * @copyright 2005 The PHP Group * @license http://www.php.net/license/3_0.txt PHP License 3.0 - * @version CVS: $Id: package.php,v 1.10 2005/11/07 18:48:52 davidc Exp $ + * @version CVS: $Id: package.php,v 1.11 2006/10/13 15:31:22 davidc Exp $ * @link http://pear.php.net/package/PEAR_PackageFileManager * @since File available since Release 0.1.0 */ require_once 'PEAR/PackageFileManager.php'; -$version = '0.2.5'; +$version = '0.5.1'; $notes = <<<EOT - Small optimizations and cleanup of HTML_AJAX and HTML_AJAX_Server - Case fixes for specifing case while exporting a class - Fix url creation in javascript allowing server urls to contain parameters - Added a flag to turn off sending a Content-Length header + Map PEAR_Error objects so they can be caught on the JavaScript side EOT; $description =<<<EOT @@ -38,9 +35,9 @@ 'summary' => 'PHP and JavaScript AJAX library', 'description' => $description, 'version' => $version, - 'state' => 'alpha', + 'state' => 'beta', 'license' => 'lgpl', - 'ignore' => array('package.php', 'package.xml', '*.bak', '*src*', '*.tgz','test.bat','build.php','DeveloperNotes.txt'), + 'ignore' => array('package.php', 'package.xml', '*.bak', '*src*', '*.tgz','test.bat','build.php','DeveloperNotes.txt','*cssQuery-src*'), 'filelistgenerator' => 'file', // other option is 'file' 'notes' => $notes, 'changelogoldtonew' => false, @@ -59,6 +56,8 @@ $package->addMaintainer('jeichorn','lead','Joshua Eichorn','josh@bluga.net'); $package->addMaintainer('davidc','lead','David Coallier','davidc@php.net'); +$package->addMaintainer('arpad','developer','Arpad Ray','arpad@php.net'); +$package->addMaintainer('lyaish','developer','Laurent Yaish','laurenty@gmail.com'); // dependencies can be added at will here $package->addDependency('PEAR', '1.3.5', 'ge', 'pkg', false); http://cvs.php.net/viewvc.cgi/pear/HTML_AJAX/AJAX/Action.php?r1=1.1&r2=1.2&diff_format=u Index: pear/HTML_AJAX/AJAX/Action.php diff -u pear/HTML_AJAX/AJAX/Action.php:1.1 pear/HTML_AJAX/AJAX/Action.php:1.2 --- pear/HTML_AJAX/AJAX/Action.php:1.1 Thu Feb 9 14:48:08 2006 +++ pear/HTML_AJAX/AJAX/Action.php Fri Oct 13 15:31:22 2006 @@ -1,11 +1,11 @@ <?php /** - * OO AJAX Implementation for PHP + * OO AJAX Implementation for PHP, contains HTML_AJAX_Action * * @category HTML * @package AJAX * @author Elizabeth Smith <auroraeosrose@gmail.com> - * @copyright 2005 Elizabeth Smith + * @copyright 2005-2006 Elizabeth Smith * @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @version Release: @package_version@ */ @@ -17,199 +17,324 @@ require_once 'HTML/AJAX/Serializer/JSON.php'; /** - * Helper Class for creating information that can be properly serialized and used by - * the haaction serializer that eliminates the need for php users to write javascript + * 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 + * + * @version $Id: Action.php,v 1.2 2006/10/13 15:31:22 davidc Exp $ */ class HTML_AJAX_Action extends HTML_AJAX_Response { - /** - * about - * @var $contentType type - */ - var $contentType = 'application/html_ajax_action'; - - /** - * about - * @var $_actions type - */ - var $_actions; - - /** - * public function prependAttr() - * - * adds $data to the end of the attribute in the item identified by $id ($id can also be a class) - */ - 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; - } - - /** - * public function appendAttr() - * - * adds $data to the beginning of the attribute in the item identified by $id ($id can also be a class) - */ - function appendAttr($id, $attribute, $data = NULL) - { - if(!is_null($data)) - { - $attribute = array($attribute => $data); - } - $this->_actions[] = array( - 'action' => 'append', - 'id' => $id, - 'attributes' => $attribute, - ); - return; - } - - /** - * public function assignAttr() - * - * assigns $data to the value of the attribute in the item identified by $id ($id can also be a class) - * if attribute already exists, the entire value of the attribute will be replaced - */ - function assignAttr($id, $attribute, $data = NULL) - { - if(!is_null($data)) - { - $attribute = array($attribute => $data); - } - $this->_actions[] = array( - 'action' => 'assign', - 'id' => $id, - 'attributes' => $attribute, - ); - return; - } - - /** - * public function clearAttr() - * - * removes an attr from the item identified by $id ($id can also be a class) - */ - function clearAttr($id, $attribute) - { - if(!is_array($attribute)) - { - $attribute = array($attribute); - } - $this->_actions[] = array( - 'action' => 'clear', - 'id' => $id, - 'attributes' => $attribute, - ); - return; - } - - /** - * public function createNode() - * - * higher level dom manipulation - creates a new node to insert into the dom - * type can be append, prepend, or insert - for insert id should be the id of - * the element you're inserting before, for append or prepend should be the id - * of the element you're inserting into - */ - function createNode($id, $tag, $attribute, $type = 'append') - { - $types = array('append', 'prepend', 'insertBefore', 'insertAfter'); - if(!in_array($type, $types)) - { - $type = 'append'; - } - settype($attribute, 'array'); - $this->_actions[] = array( - 'action' => 'create', - 'id' => $id, - 'tag' => $tag, - 'attributes' => $attribute, - 'type' => $type, - ); - return; - } - - /** - * public function replaceNode() - * - * 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 - */ - function replaceNode($id, $tag, $attribute) - { - $this->_actions[] = array( - 'action' => 'replace', - 'id' => $id, - 'tag' => $tag, - 'attributes' => settype($attribute, 'array'), - ); - return; - } - - /** - * public function removeNode() - * - * higher level dom manipulation - deletes node from the dom - */ - function removeNode($id) - { - $this->_actions[] = array( - 'action' => 'remove', - 'id' => $id, - ); - return; - } - - /** - * public function insertScript() - * - * adds straight javascript - */ - function insertScript($data) - { - $this->_actions[] = array( - 'action' => 'script', - 'data' => $data, - ); - return; - } - - /** - * public function insertAlert() - * - * adds javascript alert - */ - function insertAlert($data) - { - $this->_actions[] = array( - 'action' => 'alert', - 'data' => $data, - ); - return; - } - - /** - * public function getPayload() - * - * something - */ - function getPayload() - { - $serializer = new HTML_AJAX_Serializer_JSON(); - return $serializer->serialize($this->_actions); - } + /** + * 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; + + /** + * 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. + * + * $response->createNode('myid', 'div'); + * $response->createNode('submit', 'input', + * array('id' => 'key', + * 'name' => 'key', + * 'type' => 'hidden', + * 'value' => $id), + * 'insertBefore'); + * + * @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 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; + } } -?> \ No newline at end of file +?> http://cvs.php.net/viewvc.cgi/pear/HTML_AJAX/AJAX/Debug.php?r1=1.2&r2=1.3&diff_format=u Index: pear/HTML_AJAX/AJAX/Debug.php diff -u pear/HTML_AJAX/AJAX/Debug.php:1.2 pear/HTML_AJAX/AJAX/Debug.php:1.3 --- pear/HTML_AJAX/AJAX/Debug.php:1.2 Thu Nov 3 13:54:37 2005 +++ pear/HTML_AJAX/AJAX/Debug.php Fri Oct 13 15:31:22 2006 @@ -1,140 +1,140 @@ -<?php -define ("NEWLINE", "\n"); -// {{{ class HTML_AJAX_Debug -/** - * AJAX Debugging implementation - * - * LICENSE: This source file is subject to version 3.0 of the PHP license - * that is available through the world-wide-web at the following URI: - * http://www.php.net/license/3_0.txt. If you did not receive a copy of - * the PHP License and are unable to obtain it through the web, please - * send a note to license@php.net so we can mail you a copy immediately. - * - * @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: @package_version@ - */ -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>" . NEWLINE; - $error .= " <msg>{$this->errorMsg}</msg>" . NEWLINE; - $error .= " <code>{$this->errorCode}</code>" . NEWLINE; - $error .= " <line>{$this->errorLine}</line>" . NEWLINE; - $error .= " <file>{$this->errorFile}</file>" . NEWLINE . 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); - } - } - // }}} -} -// }}} -?> +<?php +define ("NEWLINE", "\n"); +// {{{ class HTML_AJAX_Debug +/** + * AJAX Debugging implementation + * + * LICENSE: This source file is subject to version 3.0 of the PHP license + * that is available through the world-wide-web at the following URI: + * http://www.php.net/license/3_0.txt. If you did not receive a copy of + * the PHP License and are unable to obtain it through the web, please + * send a note to license@php.net so we can mail you a copy immediately. + * + * @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: @package_version@ + */ +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>" . NEWLINE; + $error .= " <msg>{$this->errorMsg}</msg>" . NEWLINE; + $error .= " <code>{$this->errorCode}</code>" . NEWLINE; + $error .= " <line>{$this->errorLine}</line>" . NEWLINE; + $error .= " <file>{$this->errorFile}</file>" . NEWLINE . 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); + } + } + // }}} +} +// }}} +?> http://cvs.php.net/viewvc.cgi/pear/HTML_AJAX/AJAX/Helper.php?r1=1.3&r2=1.4&diff_format=u Index: pear/HTML_AJAX/AJAX/Helper.php diff -u pear/HTML_AJAX/AJAX/Helper.php:1.3 pear/HTML_AJAX/AJAX/Helper.php:1.4 --- pear/HTML_AJAX/AJAX/Helper.php:1.3 Thu Feb 9 14:48:08 2006 +++ pear/HTML_AJAX/AJAX/Helper.php Fri Oct 13 15:31:22 2006 @@ -1,136 +1,149 @@ -<?php -/** - * 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: @package_version@ - */ - -/** - * 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: @package_version@ - * @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(); - - /** - * Include all needed libraries, stubs, and set defaultServer - * - * @return string - */ - function setupAJAX() - { - $libs = array(0=>array()); - foreach($this->jsLibraries as $library) { - if (is_array($library)) { - $libs[] = implode(',',$library); - } - else { - $libs[0][] = $library; - } - } - $libs[0] = implode(',',$libs[0]); - - $ret = ''; - foreach($libs as $list) { - $ret .= "<script type='text/javascript' src='{$this->serverUrl}?client={$list}'></script>\n"; - } - - if (count($this->stubs) > 0) { - $stubs = implode(',',$this->stubs); - $ret .= "<script type='text/javascript' src='{$this->serverUrl}?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"; - } -} -?> +<?php +/** + * 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: @package_version@ + */ + +/** + * 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: @package_version@ + * @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(); + + /** + * Include all needed libraries, stubs, and set defaultServer + * + * @return string + */ + function setupAJAX() + { + $libs = array(0=>array()); + foreach($this->jsLibraries as $library) { + if (is_array($library)) { + $libs[] = implode(',',$library); + } + else { + $libs[0][] = $library; + } + } + $libs[0] = implode(',',$libs[0]); + + $ret = ''; + foreach($libs as $list) { + $ret .= "<script type='text/javascript' src='{$this->serverUrl}?client={$list}'></script>\n"; + } + + if (count($this->stubs) > 0) { + $stubs = implode(',',$this->stubs); + $ret .= "<script type='text/javascript' src='{$this->serverUrl}?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); + } +} +?> http://cvs.php.net/viewvc.cgi/pear/HTML_AJAX/AJAX/Response.php?r1=1.1&r2=1.2&diff_format=u Index: pear/HTML_AJAX/AJAX/Response.php diff -u pear/HTML_AJAX/AJAX/Response.php:1.1 pear/HTML_AJAX/AJAX/Response.php:1.2 --- pear/HTML_AJAX/AJAX/Response.php:1.1 Thu Feb 9 14:48:08 2006 +++ pear/HTML_AJAX/AJAX/Response.php Fri Oct 13 15:31:22 2006 @@ -1,11 +1,11 @@ <?php /** - * OO AJAX Implementation for PHP + * OO AJAX Implementation for PHP, contains HTML_AJAX_Response * * @category HTML * @package AJAX * @author Elizabeth Smith <auroraeosrose@gmail.com> - * @copyright 2005 Elizabeth Smith + * @copyright 2005-2006 Elizabeth Smith * @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @version Release: @package_version@ */ @@ -16,41 +16,61 @@ require_once 'HTML/AJAX.php'; /** - * Josh says we need this, I don't know why yet + * 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: Response.php,v 1.2 2006/10/13 15:31:22 davidc Exp $ */ class HTML_AJAX_Response { - /** - * about - * @var $contentType type - */ - var $contentType = 'text/plain'; - - /** - * about - * @var $payload type - */ - var $payload = ''; - - /** - * public function getContentType() - * - * gets the right content type? - */ - function getContentType() - { - return $this->contentType; - } - - /** - * public function getPayload() - * - * something - */ - function getPayload() - { - return $this->payload; - } + /** + * 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; + } } ?> \ No newline at end of file http://cvs.php.net/viewvc.cgi/pear/HTML_AJAX/AJAX/Server.php?r1=1.10&r2=1.11&diff_format=u Index: pear/HTML_AJAX/AJAX/Server.php diff -u pear/HTML_AJAX/AJAX/Server.php:1.10 pear/HTML_AJAX/AJAX/Server.php:1.11 --- pear/HTML_AJAX/AJAX/Server.php:1.10 Thu Feb 9 14:48:08 2006 +++ pear/HTML_AJAX/AJAX/Server.php Fri Oct 13 15:31:22 2006 @@ -1,603 +1,659 @@ -<?php -/** - * OO AJAX Implementation for PHP - * - * @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', - ); - - /** - * 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('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', - 'priorityqueue' => 'priorityQueue.js', - 'clientpool' => 'clientPool.js', - 'iframe' => 'IframeXHR.js', - 'behavior' => array('behavior/behavior.js','behavior/cssQuery-p.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 - */ - function HTML_AJAX_Server() - { - $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 '&amp;' (to be sure) and is optional. '=something' is optional too. - $querystring = preg_replace('/(' . join('|', $parameters) . ')(?:=[^&]*(?:&(?:amp;)?|$))?/', '', $_SERVER['QUERY_STRING']); - - // call the server with this query string - $this->ajax->serverUrl = htmlentities($_SERVER['PHP_SELF']) .'?'. htmlentities($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 { - $this->_init($this->_cleanIdentifier($_GET['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); - } - - /** - * 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); - } - } - } - - /** - * 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 - $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; - } - else { - $fileList[] = $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 ($length > 0 && $this->ajax->_sendContentLength()) { - $headers['Content-Length'] = $length; - } - $headers['Content-Type'] = 'text/javascript; charset=utf-8'; - call_user_func($this->ajax->_callbacks['headers'], $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; - } - } - - /** - * Load options from _GET - * - * @access private - */ - function _loadOptions() - { - $this->options = array('client'=>array(),'stub'=>array()); - if (isset($_GET['client'])) { - $this->options['client'] = array(); - if (strstr($_GET['client'],',')) { - $clients = explode(',',$_GET['client']); - } else { - $clients = array($_GET['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'])) { - if (strstr($_GET['stub'],',')) { - $stubs = explode(',',$_GET['stub']); - } else { - $stubs = array($_GET['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) - { - 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($_SERVER['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: */ -?> +<?php +/** + * OO AJAX Implementation for PHP + * + * @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', + ); + + /** + * 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 '&amp;' (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 . htmlentities($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 ($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; + } + } + + /** + * 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: */ +?> http://cvs.php.net/viewvc.cgi/pear/HTML_AJAX/AJAX/Serializer/Error.php?r1=1.6&r2=1.7&diff_format=u Index: pear/HTML_AJAX/AJAX/Serializer/Error.php diff -u pear/HTML_AJAX/AJAX/Serializer/Error.php:1.6 pear/HTML_AJAX/AJAX/Serializer/Error.php:1.7 --- pear/HTML_AJAX/AJAX/Serializer/Error.php:1.6 Thu Nov 3 13:51:02 2005 +++ pear/HTML_AJAX/AJAX/Serializer/Error.php Fri Oct 13 15:31:22 2006 @@ -1,20 +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: @package_version@ - * @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: */ -?> +<?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: @package_version@ + * @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: */ +?> http://cvs.php.net/viewvc.cgi/pear/HTML_AJAX/AJAX/Serializer/JSON.php?r1=1.10&r2=1.11&diff_format=u Index: pear/HTML_AJAX/AJAX/Serializer/JSON.php diff -u pear/HTML_AJAX/AJAX/Serializer/JSON.php:1.10 pear/HTML_AJAX/AJAX/Serializer/JSON.php:1.11 --- pear/HTML_AJAX/AJAX/Serializer/JSON.php:1.10 Thu Feb 9 15:21:50 2006 +++ pear/HTML_AJAX/AJAX/Serializer/JSON.php Fri Oct 13 15:31:22 2006 @@ -1,87 +1,96 @@ -<?php -require_once 'HTML/AJAX/JSON.php'; -// $Id: JSON.php,v 1.10 2006/02/09 15:21:50 davidc Exp $ -/** - * 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: @package_version@ - * @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; - // }}} - // {{{ constructor - function HTML_AJAX_Serializer_JSON() - { - $this->_jsonext = $this->_detect(); - if(!$this->_jsonext) { - $this->_json =& new HTML_AJAX_JSON(); - } - } - // }}} - // {{{ 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); - } else { - return $this->_json->decode($input); - } - } - // }}} - // {{{ _detect - /** - * detcts the loaded extension - */ - function _detect() - { - return extension_loaded('json'); - } - // }}} -} -// }}} -/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ -?> +<?php +require_once 'HTML/AJAX/JSON.php'; +// $Id: JSON.php,v 1.11 2006/10/13 15:31:22 davidc Exp $ +/** + * 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: @package_version@ + * @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: */ +?> http://cvs.php.net/viewvc.cgi/pear/HTML_AJAX/AJAX/Serializer/Null.php?r1=1.9&r2=1.10&diff_format=u Index: pear/HTML_AJAX/AJAX/Serializer/Null.php diff -u pear/HTML_AJAX/AJAX/Serializer/Null.php:1.9 pear/HTML_AJAX/AJAX/Serializer/Null.php:1.10 --- pear/HTML_AJAX/AJAX/Serializer/Null.php:1.9 Thu Feb 9 15:21:50 2006 +++ pear/HTML_AJAX/AJAX/Serializer/Null.php Fri Oct 13 15:31:22 2006 @@ -1,28 +1,28 @@ -<?php -// $Id: Null.php,v 1.9 2006/02/09 15:21:50 davidc Exp $ -/** - * 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: @package_version@ - * @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: */ -?> +<?php +// $Id: Null.php,v 1.10 2006/10/13 15:31:22 davidc Exp $ +/** + * 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: @package_version@ + * @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: */ +?> http://cvs.php.net/viewvc.cgi/pear/HTML_AJAX/AJAX/Serializer/PHP.php?r1=1.1&r2=1.2&diff_format=u Index: pear/HTML_AJAX/AJAX/Serializer/PHP.php diff -u pear/HTML_AJAX/AJAX/Serializer/PHP.php:1.1 pear/HTML_AJAX/AJAX/Serializer/PHP.php:1.2 --- pear/HTML_AJAX/AJAX/Serializer/PHP.php:1.1 Thu Feb 9 15:21:50 2006 +++ pear/HTML_AJAX/AJAX/Serializer/PHP.php Fri Oct 13 15:31:22 2006 @@ -1,88 +1,88 @@ -<?php -// $Id: PHP.php,v 1.1 2006/02/09 15:21:50 davidc Exp $ -/** - * 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: @package_version@ - * @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: */ -?> +<?php +// $Id: PHP.php,v 1.2 2006/10/13 15:31:22 davidc Exp $ +/** + * 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: @package_version@ + * @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: */ +?> http://cvs.php.net/viewvc.cgi/pear/HTML_AJAX/AJAX/Serializer/Urlencoded.php?r1=1.1&r2=1.2&diff_format=u Index: pear/HTML_AJAX/AJAX/Serializer/Urlencoded.php diff -u pear/HTML_AJAX/AJAX/Serializer/Urlencoded.php:1.1 pear/HTML_AJAX/AJAX/Serializer/Urlencoded.php:1.2 --- pear/HTML_AJAX/AJAX/Serializer/Urlencoded.php:1.1 Thu Feb 9 15:21:50 2006 +++ pear/HTML_AJAX/AJAX/Serializer/Urlencoded.php Fri Oct 13 15:31:22 2006 @@ -1,67 +1,67 @@ -<?php -// $Id: Urlencoded.php,v 1.1 2006/02/09 15:21:50 davidc Exp $ - -// {{{ 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: @package_version@ - * @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: */ -?> +<?php +// $Id: Urlencoded.php,v 1.2 2006/10/13 15:31:22 davidc Exp $ + +// {{{ 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: @package_version@ + * @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: */ +?> http://cvs.php.net/viewvc.cgi/pear/HTML_AJAX/examples/README?r1=1.4&r2=1.5&diff_format=u Index: pear/HTML_AJAX/examples/README diff -u pear/HTML_AJAX/examples/README:1.4 pear/HTML_AJAX/examples/README:1.5 --- pear/HTML_AJAX/examples/README:1.4 Mon Nov 7 18:43:49 2005 +++ pear/HTML_AJAX/examples/README Fri Oct 13 15:31:22 2006 @@ -1 +1,3 @@ -See Index.php for details +This is the README file, its loaded in lots of examples + +See Index.php for details http://cvs.php.net/viewvc.cgi/pear/HTML_AJAX/examples/auto_server.php?r1=1.4&r2=1.5&diff_format=u Index: pear/HTML_AJAX/examples/auto_server.php diff -u pear/HTML_AJAX/examples/auto_server.php:1.4 pear/HTML_AJAX/examples/auto_server.php:1.5 --- pear/HTML_AJAX/examples/auto_server.php:1.4 Mon Nov 7 18:43:49 2005 +++ pear/HTML_AJAX/examples/auto_server.php Fri Oct 13 15:31:22 2006 @@ -1,65 +1,70 @@ -<?php -/** - * Advanced usage of HTML_AJAX_Server - * Allows for a single server to manage exporting a large number of classes without high overhead per call - * Also gives a single place to handle setup tasks especially useful if session setup is required - * - * The server responds to ajax calls and also serves the js client libraries, so they can be used directly from the PEAR data dir - * 304 not modified headers are used when server client libraries so they will be cached on the browser reducing overhead - * - * @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/HTML_AJAX - */ - - // include the server class -include 'HTML/AJAX/Server.php'; - - -// extend HTML_AJAX_Server creating our own custom one with init{ClassName} methods for each class it supports calls on -class TestServer extends HTML_AJAX_Server { - // this flag must be set to on init methods - var $initMethods = true; - - // init method for the test class, includes needed files an registers it for ajax - function initTest() { - include 'test.class.php'; - $this->registerClass(new test()); - } - - // init method for the livesearch class, includes needed files an registers it for ajax - function initLivesearch() { - include 'livesearch.class.php'; - $this->registerClass(new livesearch()); - } - - -} - -// create an instance of our test server -$server = new TestServer(); - -// init methods can also be added to the server by registering init objects, this is useful in cases where you want to dynamically add init methods -class initObject { - // init method for the test class, includes needed files an registers it for ajax - function initTest2() { - include 'test2.class.php'; - $this->server->registerClass(new test2()); - } -} -$init = new initObject(); -$init->server =& $server; -$server->registerInitObject($init); - -// you can use HTML_AJAX_Server to deliver your own custom javascript libs, when used with comma seperated client lists you can -// use just one javascript include for all your library files -// example url: auto_server.php?client=auto_server.php?client=Util,Main,Request,HttpClient,Dispatcher,Behavior,customLib -$server->registerJSLibrary('customLib','customLib.js','./'); - -// handle requests as needed -$server->handleRequest(); -?> +<?php +/** + * Advanced usage of HTML_AJAX_Server + * Allows for a single server to manage exporting a large number of classes without high overhead per call + * Also gives a single place to handle setup tasks especially useful if session setup is required + * + * The server responds to ajax calls and also serves the js client libraries, so they can be used directly from the PEAR data dir + * 304 not modified headers are used when server client libraries so they will be cached on the browser reducing overhead + * + * @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/HTML_AJAX + */ + + // include the server class +include 'HTML/AJAX/Server.php'; + + +// extend HTML_AJAX_Server creating our own custom one with init{ClassName} methods for each class it supports calls on +class TestServer extends HTML_AJAX_Server { + // this flag must be set to on init methods + var $initMethods = true; + + // init method for the test class, includes needed files an registers it for ajax + function initTest() { + include 'support/test.class.php'; + $this->registerClass(new test()); + } + + // init method for the livesearch class, includes needed files an registers it for ajax + function initLivesearch() { + include 'support/livesearch.class.php'; + $this->registerClass(new livesearch()); + } + + // init method for the testHaa class, includes needed files an registers it for ajax, directly passes in methods to register to specify case in php4 + function initTestHaa() { + include 'support/testHaa.class.php'; + $this->registerClass(new testHaa(),'testHaa',array('updateClassName','greenText','highlight','duplicate')); + } + + +} + +// create an instance of our test server +$server = new TestServer(); + +// init methods can also be added to the server by registering init objects, this is useful in cases where you want to dynamically add init methods +class initObject { + // init method for the test class, includes needed files an registers it for ajax + function initTest2() { + include 'support/test2.class.php'; + $this->server->registerClass(new test2()); + } +} +$init = new initObject(); +$server->registerInitObject($init); + +// you can use HTML_AJAX_Server to deliver your own custom javascript libs, when used with comma seperated client lists you can +// use just one javascript include for all your library files +// example url: auto_server.php?client=auto_server.php?client=Util,Main,Request,HttpClient,Dispatcher,Behavior,customLib +$server->registerJSLibrary('customLib','customLib.js','./support/'); + +// handle requests as needed +$server->handleRequest(); +?> http://cvs.php.net/viewvc.cgi/pear/HTML_AJAX/examples/error_usage.php?r1=1.2&r2=1.3&diff_format=u Index: pear/HTML_AJAX/examples/error_usage.php diff -u pear/HTML_AJAX/examples/error_usage.php:1.2 pear/HTML_AJAX/examples/error_usage.php:1.3 --- pear/HTML_AJAX/examples/error_usage.php:1.2 Mon Nov 7 18:43:49 2005 +++ pear/HTML_AJAX/examples/error_usage.php Fri Oct 13 15:31:22 2006 @@ -1,31 +1,31 @@ -<?php -/** - * Test class used in other examples - * Constructors and private methods marked with _ are never exported in proxies to JavaScript - * - * @category HTML - * @package AJAX - * @author David Coallier <davidc@agoraproduction.com> - * @copyright 2005 David Coallier - * @license LGPL http://www.gnu.org/copyleft/lesser.txt - * @version Release: @package_version@ - * @link http://pear.php.net/package/HTML_AJAX - */ -require_once 'HTML/AJAX.php'; - -class error_test -{ - function error_test() - { - $ajax =& new HTML_AJAX; - $ajax->debugEnabled = true; - $ajax->debugSession = true; - set_error_handler(array(&$ajax, '_errorHandler')); - trigger_error("I don't know"); - } -} - -$t =& new error_test; -print_r($t); - -?> +<?php +/** + * Test class used in other examples + * Constructors and private methods marked with _ are never exported in proxies to JavaScript + * + * @category HTML + * @package AJAX + * @author David Coallier <davidc@agoraproduction.com> + * @copyright 2005 David Coallier + * @license LGPL http://www.gnu.org/copyleft/lesser.txt + * @version Release: @package_version@ + * @link http://pear.php.net/package/HTML_AJAX + */ +require_once 'HTML/AJAX.php'; + +class error_test +{ + function error_test() + { + $ajax =& new HTML_AJAX; + $ajax->debugEnabled = true; + $ajax->debugSession = true; + set_error_handler(array(&$ajax, '_errorHandler')); + trigger_error("I don't know"); + } +} + +$t =& new error_test; +print_r($t); + +?> http://cvs.php.net/viewvc.cgi/pear/HTML_AJAX/examples/helper_usage.php?r1=1.2&r2=1.3&diff_format=u Index: pear/HTML_AJAX/examples/helper_usage.php diff -u pear/HTML_AJAX/examples/helper_usage.php:1.2 pear/HTML_AJAX/examples/helper_usage.php:1.3 --- pear/HTML_AJAX/examples/helper_usage.php:1.2 Mon Nov 7 18:43:49 2005 +++ pear/HTML_AJAX/examples/helper_usage.php Fri Oct 13 15:31:22 2006 @@ -1,49 +1,49 @@ -<?php -/** - * Example of Using HTML_AJAX_Helper - * - * HTML_AJAX_Helper takes care of basic JavaScript and HTML generation that is needed in many AJAX requests - * - * @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/HTML_AJAX - */ - -// include the helper class -require_once 'HTML/AJAX/Helper.php'; - -// create an instance and set the server url -$ajaxHelper = new HTML_AJAX_Helper(); -$ajaxHelper->serverUrl = 'auto_server.php'; -$ajaxHelper->jsLibraries[] = 'customLib'; -?> -<html> -<head> - -<?php - // output a javascript neded to setup HTML_AJAX - // by default this is all the libraries shipped with HTML_AJAX, take a look at $ajaxHelper->jsLibraries to edit the list - echo $ajaxHelper->setupAJAX(); -?> - -</head> -<body> -<?php - // output a custom loading message - echo $ajaxHelper->loadingMessage("Waiting on the Server ..."); -?> - -<div id="updateTarget">I'm an update Target</div> -<?php - // update the element using ajax - echo $ajaxHelper->updateElement('updateTarget',array('test','echo_string','Some text to echo'),'replace',true); -?> -</body> -</html> -<?php -/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ -?> +<?php +/** + * Example of Using HTML_AJAX_Helper + * + * HTML_AJAX_Helper takes care of basic JavaScript and HTML generation that is needed in many AJAX requests + * + * @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/HTML_AJAX + */ + +// include the helper class +require_once 'HTML/AJAX/Helper.php'; + +// create an instance and set the server url +$ajaxHelper = new HTML_AJAX_Helper(); +$ajaxHelper->serverUrl = 'auto_server.php'; +$ajaxHelper->jsLibraries[] = 'customLib'; +?> +<html> +<head> + +<?php + // output a javascript neded to setup HTML_AJAX + // by default this is all the libraries shipped with HTML_AJAX, take a look at $ajaxHelper->jsLibraries to edit the list + echo $ajaxHelper->setupAJAX(); +?> + +</head> +<body> +<?php + // output a custom loading message + echo $ajaxHelper->loadingMessage("Waiting on the Server ..."); +?> + +<div id="updateTarget">I'm an update Target</div> +<?php + // update the element using ajax + echo $ajaxHelper->updateElement('updateTarget',array('test','echo_string','Some text to echo'),'replace',true); +?> +</body> +</html> +<?php +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ +?> http://cvs.php.net/viewvc.cgi/pear/HTML_AJAX/examples/index.php?r1=1.3&r2=1.4&diff_format=u Index: pear/HTML_AJAX/examples/index.php diff -u pear/HTML_AJAX/examples/index.php:1.3 pear/HTML_AJAX/examples/index.php:1.4 --- pear/HTML_AJAX/examples/index.php:1.3 Mon Nov 7 18:43:49 2005 +++ pear/HTML_AJAX/examples/index.php Fri Oct 13 15:31:22 2006 @@ -1,51 +1,91 @@ -<html> -<head> -<title>HTML_AJAX Examples</title> -</head> -<body> -<p> -These examples cover basic AJAX usage -</p> - -<p> -All example files are fully commented, reading through them will give you a good overview on how things work. -</p> - -<p>The term proxy in these examples refers to a javascript class that is generated and has functions that map to the eqivalent php class. -These proxy classes work much in the same way as a SOAP proxy class that is generated from wsdl. -</p> - -<p> -Front end files for examples, you can actually run these and see some example output -</p> -<ul> -<li><a href='proxyless_usage.php'>proxyless_usage.php</a> - Using HTML_AJAX in standalone mode, possible doesn't require PHP or any backend HTML_AJAX classes</li> -<li><a href='proxy_usage_inline_javascript.php'>proxy_usage_inline_javascript.php</a> - Single file proxy style usage</li> -<li><a href='proxy_usage_server.php'>proxy_usage_server.php</a> - Multi-file proxy usage, either server file could be used with this example</li> -<li><a href='queue_usage.php'>queue_usage.php</a> - An example of using a queue to manage ajax calls, a simple live search example</li> -<li><a href='helper_usage.php'>helper_usage.php</a> - An example showing the basics of the helper api</li> -</ul> - -<p>Real Life Examples</p> -<ul> -<li><a href='login/index.php'>login/index.php</a> - An example creating an AJAX driven login</a></li> -</ul> - -<p> -2 server examples are provided -</p> -<ul> -<li>server.php - Basic server operation, serving ajax calls and client lib requests</li> -<li>auto_server.php - Advanced server operation, only create php classes as needed</li> -</ul> - -<p> -Other Example files: -</p> -<ul> -<li><a href='test_speed.php'>test_speed.php</a> - A basic setup for measuring the speed of calls</li> -<li><a href='serialize.examples.htm'>serialize.examples.htm/a> - Internal tests for the php serialize format serializer</li> -</ul> - -</body> -</html> +<html> +<head> +<title>HTML_AJAX 0.5.0 Examples</title> +</head> +<body> +<h1>HTML_AJAX 0.5.0 Examples</h1> +<p> +These are examples showing the basics of using HTML_AJAX +</p> + +<p> +These examples show off many of the features of HTML_AJAX, but you'll find them most useful as a learning tool. +Reading through the commented code as you view the examples in your browser. +</p> + +<p> +These examples are available online at: http://bluga.net/projects/HTML_AJAX or in your local PEAR install in the documentation dir. + +On most Linux systems the location is /usr/share/pear/docs/HTML_AJAX/examples/ + +You can find the location of your PEAR documentation dir running +<code>pear config-get doc_dir</code> +</p> + +<p>The term proxy in these examples refers to a javascript class that is generated and has functions that map to the eqivalent php class. +These proxy classes work much in the same way as a SOAP proxy class that is generated from wsdl. +</p> + +<p> +Front end files for examples, you can actually run these and see some example output +</p> +<ul> +<li><a href='proxyless_usage.php'>proxyless_usage.php</a> - Using HTML_AJAX in standalone mode, possible doesn't require PHP or any backend HTML_AJAX classes</li> +<li><a href='proxy_usage_inline_javascript.php'>proxy_usage_inline_javascript.php</a> - Single file proxy style usage</li> +<li><a href='proxy_usage_server.php'>proxy_usage_server.php</a> - Multi-file proxy usage, either server file could be used with this example</li> +<li><a href='queue_usage.php'>queue_usage.php</a> - An example of using a queue to manage ajax calls, a simple live search example</li> +<li><a href='slow_livesearch.php'>slow_livesearch.php</a> - An example showing how the ordered queue can be used to manage high latency</li> +<li><a href='helper_usage.php'>helper_usage.php</a> - An example showing the basics of the helper api</li> +<li><a href='form.php'>form.php</a> - Basic AJAX form submission example</a></li> +<li><a href='action_usage.php'>action_usage.php</a> - Basic HTML_AJAX_Action usage</a></li> +<li><a href='xml_usage.php'>xml_usage.php</a> - Basic XML serializer usage</a></li> +</ul> + +<p>Real Life Examples</p> +<ul> +<li><a href='login/index.php'>login/index.php</a> - An example creating an AJAX driven login</a></li> +<li><a href='review/index.php'>review/index.php</a> - A simple live review system, AJAX form submission and click to edit</a></li> +<li><a href='guestbook/index.php'>guestbook/index.php</a> - A simple guestbook system, uses action system so you never write a line of javascript</a></li> +<li><a href='shoutbox.php'>shoutbox.php</a> - How to use AJAX form submission</a></li> +</ul> + +<p> +2 server examples are provided, both provide the same output but the auto_server example has code to help you deal with managing multiple ajax classes +</p> +<ul> +<li>server.php - Basic server operation, serving ajax calls and client lib requests</li> +<li>auto_server.php - Advanced server operation, only create php classes as needed</li> +<li><a href='server.php?client=util,main'>server.php?client=util,main</a> - server.php generating a javascript file with the main and util libs in it</li> +<li><a href='auto_server.php?stub=test2'>server.php?stub=test2</a> - auto_server.php generating a javascript file a which contains a generated proxy class for the test2 php class</li> +<li><a href='auto_server.php?stub=all'>server.php?stub=all</a> - auto_server.php generating a javascript file which contains proxies for all the php classes registered with it</li> +</ul> + +<p> +Examples files showing howto use HTML_AJAX_Util javascript class +</p> +<ul> +<li><a href='tests/js_utils_vardump.php'>js_utils_vardump.php</a> - Shows the output of HTML_AJAX_Util.varDump() and compares its against PHP's var_dump +</ul> + + +<p> +Other Example files: +</p> +<ul> +<li><a href='tests/test_speed.php'>test_speed.php</a> - A basic setup for measuring the speed of calls</li> +<li><a href='tests/test_priority.php'>test_priority.php</a> - A basic test showing how Priority queue works</li> +<li><a href='tests/serialize.php.examples.php'>serialize.php.examples.php</a> - Internal tests for the php serialize format serializer</li> +<li><a href='tests/serialize.url.examples.php'>serialize.url.examples.php</a> - Internal tests for the urlencoded format serializer</li> +<li><a href='tests/setInnerHTML.php'>setInnerHTML.php</a> - Tests used to verify the operation of HTML_AJAX_Util.setInnerHTML</li> +<li><a href='tests/duplicateJSLib.php'>duplicateJSLib.php</a> - Tests used to verify that HTML_AJAX_Server is removing duplicate JS libraries from client generation correctly</li> +<li><a href='tests/behaviorSpeed.php'>behaviorSpeed.php</a> - Tests used to see how fast the JavaScript behavior code runs.</li> +</ul> + +<p> +Javascript and Html Examples: +</p> +<ul> +<li><a href="tests/test_behavior.html">test_behavior.html</a> - A short overview of how to use behavior.js. Behavior uses css selectors to apply javascript behaviors without throwing lots of javascript handlers into your html.</li> +</ul> +</body> +</html> http://cvs.php.net/viewvc.cgi/pear/HTML_AJAX/examples/proxy_usage_inline_javascript.php?r1=1.4&r2=1.5&diff_format=u Index: pear/HTML_AJAX/examples/proxy_usage_inline_javascript.php diff -u pear/HTML_AJAX/examples/proxy_usage_inline_javascript.php:1.4 pear/HTML_AJAX/examples/proxy_usage_inline_javascript.php:1.5 --- pear/HTML_AJAX/examples/proxy_usage_inline_javascript.php:1.4 Mon Nov 7 18:43:49 2005 +++ pear/HTML_AJAX/examples/proxy_usage_inline_javascript.php Fri Oct 13 15:31:22 2006 @@ -1,155 +1,166 @@ -<?php -/** - * Example of Using HTML_AJAX in proxy operation - * - * All AJAX calls are handled by this same file and the proxy js is outputed in a js block directly in this script - * This is a use case very similar to Sajax (Sajax registers functions not objects) - * - * The only needed interaction is creation of a new object from the proxy defintion, all AJAX calls happen transparently from - * - * If you want to perform async calls a callback object must be passed to the constructor of the object - * - * The client JavaScript library is provided by server.php, you could also copy HTML_AJAX.js (all js files combined) or the seperate js files into your webroot - * from the PEAR data dir and src them directly - * - * This example also registers a custom error handler, without this handler errors float out of the app as an Exception - * - * An example debugging event listener is also shown - * - * @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/HTML_AJAX - */ - -// include the main HTML_AJAX class -include 'HTML/AJAX.php'; - -// our simple test class -include 'test.class.php'; - - - -// create an instance of HTML_AJAX -$ajax = new HTML_AJAX(); -// register an instance of the test class -$ajax->registerClass(new test()); - -// handle and ajax call, if one is made die, else continue processing -if ($ajax->handleRequest()) { - die(); -} -?><html> -<head> - -<!-- the entire client library can be retreived in one call using the all keyword, or each piece can be requested like below --> -<script type='text/javascript' src="server.php?client=Main"></script> -<script type='text/javascript' src="server.php?client=Dispatcher"></script> -<script type='text/javascript' src="server.php?client=HttpClient"></script> -<script type='text/javascript' src="server.php?client=Request"></script> -<script type='text/javascript' src="server.php?client=JSON"></script> -<script type='text/javascript' src="server.php?client=loading"></script> - -<script type='text/javascript'> -<?php - // generate proxy definition javascript for all registered class - echo $ajax->generateJavascriptClient(); -?> - -// definition of the callback javascript class, used to handle async requests -function callback() {} -callback.prototype = { - echo_string: function(result) { - document.getElementById('target').innerHTML = result; - }, - slow_echo_string: function(result) { - document.getElementById('target').innerHTML = result; - }, - error_test: function(result) { - document.getElementById('target').innerHTML = result; - } -} - -// function used to clear out the target div -function clearTarget() { - document.getElementById('target').innerHTML = 'clear'; - document.getElementById('eventLog').innerHTML = 'clear'; - document.getElementById('error').innerHTML = 'clear'; -} - -// register a custom error handler -HTML_AJAX.onError = function(e) { - msg = "\n\n"; - for(var i in e) { - msg += i + ':' + e[i] +"\n"; - } - document.getElementById('error').innerHTML += msg; -} - -// register custom event handlers, but lets keep the old ones so we still have that automatic loading message -var onOpen = HTML_AJAX.onOpen; -var onLoad = HTML_AJAX.onLoad; - -HTML_AJAX.onOpen = function(request) { - onOpen(); - document.getElementById('eventLog').innerHTML += "Open: "+request.className+'::'+request.methodName+"\n"; -} -HTML_AJAX.onSend = function(request) { - document.getElementById('eventLog').innerHTML += "Send: "+request.className+'::'+request.methodName+"\n"; -} -HTML_AJAX.onProgress = function(request) { - document.getElementById('eventLog').innerHTML += "Progress: "+request.className+'::'+request.methodName+"\n"; -} -HTML_AJAX.onLoad = function(request) { - onLoad(); - document.getElementById('eventLog').innerHTML += "Load: "+request.className+'::'+request.methodName+"\n"; -} - -</script> -</head> -<body> -<script type="text/javascript"> -// create a proxy in sync mode -var syncProxy = new test(); -// create a proxy in async mode -var asyncProxy = new test(new callback()); - -// run a sync call and set its results to the target div -function syncCall() { - document.getElementById('target').innerHTML = syncProxy.echo_string("I'm a sync call"); -} - -// run a sync call, callback class will handle its results -function asyncCall() { - asyncProxy.echo_string("I'm a async call"); -} - -// run a sync call, callback class will handle its results -// the purpose of this slow call is to show off the built in loading messaging -function slowAsyncCall() { - asyncProxy.slow_echo_string("I'm a slow async call"); -} - -// run a sync call, callback class will handle its results -function serverErrorExample() { - asyncProxy.error_test("I'm an error generated by trigger error in test.class.php"); -} -</script> -<ul> - <li><a href="javascript:clearTarget()">Clear Target</a></li> - <li><a href="javascript:syncCall()">Run Sync Echo call</a></li> - <li><a href="javascript:asyncCall();">Run Async Echo call</a></li> - <li><a href="javascript:slowAsyncCall();">Run Slow Async Echo call (sleep on server to emulate slow processing)</a></li> - <li><a href="javascript:serverErrorExample();">Run a call where an error is generated on the server</a></li> -</ul> -<div style="white-space: pre; padding: 1em; margin: 1em; width: 300px; height: 400px; border: solid 2px black; overflow: auto; float: right;" id="error">Error Target</div> - -<div style="white-space: pre; padding: 1em; margin: 1em; width: 500px; height: 300px; border: solid 2px black; overflow: auto;" id="target">Target</div> - -<div style="white-space: pre; padding: 1em; margin: 1em; width: 500px; height: 400px; border: solid 2px black; overflow: auto;" id="eventLog">Event Log -</div> -</body> -</html> +<?php +/** + * Example of Using HTML_AJAX in proxy operation + * + * All AJAX calls are handled by this same file and the proxy js is outputed in a js block directly in this script + * This is a use case very similar to Sajax (Sajax registers functions not objects) + * + * The only needed interaction is creation of a new object from the proxy defintion, all AJAX calls happen transparently from + * + * If you want to perform async calls a callback object must be passed to the constructor of the object + * + * The client JavaScript library is provided by server.php, you could also copy HTML_AJAX.js (all js files combined) or the seperate js files into your webroot + * from the PEAR data dir and src them directly + * + * This example also registers a custom error handler, without this handler errors float out of the app as an Exception + * + * An example debugging event listener is also shown + * + * @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/HTML_AJAX + */ + +// include the main HTML_AJAX class +include 'HTML/AJAX.php'; + +// our simple test class +include 'support/test.class.php'; + + + +// create an instance of HTML_AJAX +$ajax = new HTML_AJAX(); +// register an instance of the test class +$ajax->registerClass(new test()); + +// handle and ajax call, if one is made die, else continue processing +if ($ajax->handleRequest()) { + die(); +} +?><html> +<head> + +<!-- the entire client library can be retreived in one call using the all keyword, or each piece can be requested like below --> +<script type='text/javascript' src="server.php?client=Main"></script> +<script type='text/javascript' src="server.php?client=Dispatcher"></script> +<script type='text/javascript' src="server.php?client=HttpClient"></script> +<script type='text/javascript' src="server.php?client=Request"></script> +<script type='text/javascript' src="server.php?client=JSON"></script> +<script type='text/javascript' src="server.php?client=iframe"></script> +<script type='text/javascript' src="server.php?client=loading"></script> + +<script type='text/javascript'> +<?php + // generate proxy definition javascript for all registered class + echo $ajax->generateJavascriptClient(); +?> + +// definition of the callback javascript class, used to handle async requests +function callback() {} +callback.prototype = { + echo_string: function(result) { + document.getElementById('target').innerHTML = result; + }, + slow_echo_string: function(result) { + document.getElementById('target').innerHTML = result; + }, + error_test: function(result) { + document.getElementById('target').innerHTML = result; + } +} + +// function used to clear out the target div +function clearTarget() { + document.getElementById('target').innerHTML = 'clear'; + document.getElementById('eventLog').innerHTML = 'clear'; + document.getElementById('error').innerHTML = 'clear'; +} + +// register a custom error handler +HTML_AJAX.onError = function(e) { + msg = "\n\n"; + for(var i in e) { + msg += i + ':' + e[i] +"\n"; + } + document.getElementById('error').innerHTML += msg; +} + +// register custom event handlers, but lets keep the old ones so we still have that automatic loading message +var Open = HTML_AJAX.Open; +var Load = HTML_AJAX.Load; + +HTML_AJAX.Open = function(request) { + Open(request); + document.getElementById('eventLog').innerHTML += "Open: "+request.className+'::'+request.methodName+"\n"; +} +HTML_AJAX.Send = function(request) { + document.getElementById('eventLog').innerHTML += "Send: "+request.className+'::'+request.methodName+"\n"; +} +HTML_AJAX.rogress = function(request) { + document.getElementById('eventLog').innerHTML += "Progress: "+request.className+'::'+request.methodName+"\n"; +} +HTML_AJAX.Load = function(request) { + Load(request); + document.getElementById('eventLog').innerHTML += "Load: "+request.className+'::'+request.methodName+"\n"; +} + +</script> +</head> +<body> +<script type="text/javascript"> +// create a proxy in sync mode +var syncProxy = new test(); +// create a proxy in async mode +var asyncProxy = new test(new callback()); + +// run a sync call and set its results to the target div +function syncCall() { + document.getElementById('target').innerHTML = syncProxy.echo_string("I'm a sync call"); +} + +// run a sync call, callback class will handle its results +function asyncCall() { + asyncProxy.echo_string("I'm a async call"); +} + +// run a sync call, callback class will handle its results +// the purpose of this slow call is to show off the built in loading messaging +function slowAsyncCall() { + asyncProxy.slow_echo_string("I'm a slow async call"); +} +// same thing, notice how it locks up your browser in Firefox you can't switch to another tab +function slowSyncCall() { + document.getElementById('target').innerHTML = syncProxy.slow_echo_string("I'm a slow sync call"); +} + +// run a sync call, callback class will handle its results +function serverErrorExample() { + asyncProxy.error_test("I'm an error generated by trigger error in test.class.php"); +} +// same as above, shown for completeness +function serverErrorSyncExample() { + document.getElementById('target').innerHTML = syncProxy.error_test("I'm an error generated by trigger error in test.class.php"); +} +</script> +<ul> + <li><a href="javascript:clearTarget()">Clear Target</a></li> + <li><a href="javascript:syncCall()">Run Sync Echo call</a></li> + <li><a href="javascript:asyncCall();">Run Async Echo call</a></li> + <li><a href="javascript:slowAsyncCall();">Run Slow Async Echo call (sleep on server to emulate slow processing)</a></li> + <li><a href="javascript:slowSyncCall();">Run Slow Sync Echo call (notice how it locks your browser)</a></li> + <li><a href="javascript:serverErrorExample();">Run a call where an error is generated on the server (Async)</a></li> + <li><a href="javascript:serverErrorSyncExample();">Run a call where an error is generated on the server (Sync)</a></li> +</ul> +<div style="white-space: pre; padding: 1em; margin: 1em; width: 300px; height: 400px; border: solid 2px black; overflow: auto; float: right;" id="error">Error Target</div> + +<div style="white-space: pre; padding: 1em; margin: 1em; width: 500px; height: 300px; border: solid 2px black; overflow: auto;" id="target">Target</div> + +<div style="white-space: pre; padding: 1em; margin: 1em; width: 500px; height: 400px; border: solid 2px black; overflow: auto;" id="eventLog">Event Log +</div> +</body> +</html> http://cvs.php.net/viewvc.cgi/pear/HTML_AJAX/examples/proxy_usage_server.php?r1=1.4&r2=1.5&diff_format=u Index: pear/HTML_AJAX/examples/proxy_usage_server.php diff -u pear/HTML_AJAX/examples/proxy_usage_server.php:1.4 pear/HTML_AJAX/examples/proxy_usage_server.php:1.5 --- pear/HTML_AJAX/examples/proxy_usage_server.php:1.4 Mon Nov 7 18:43:49 2005 +++ pear/HTML_AJAX/examples/proxy_usage_server.php Fri Oct 13 15:31:22 2006 @@ -1,95 +1,122 @@ -<?php -/** - * Example of Using HTML_AJAX in proxy operation - * - * All AJAX calls are handled by the auto_server.php file, server.php could also be used, the differences between the two are covered in those files - * This is a use case very similar to JPSpan (JPSpan only has a server.php equivalent) - * - * The only needed interaction is creation of a new object from the proxy defintion, all AJAX calls happen transparently from there - * - * If you want to perform async calls a callback object must be passed to the constructor of the object - * - * The client JavaScript library is provided by auto_server.php, you could also copy HTML_AJAX.js (all js files combined) or the seperate js files into your webroot - * from the PEAR data dir and src them directly. You can use multiple includes of the component files or use the all flag to get them all at once. - * - * @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/HTML_AJAX - */ - -?><html> -<head> - -<!-- These two calls can be combined into one call if wanted, but its not recomended since it will hurt caching as you might want stubs of multiple classes --> -<script type='text/javascript' src="auto_server.php?client=all"></script> -<!-- Stub is passed the class you want the proxy definition for, you can also use all to get every registered class but that create those auto server - has to instanciate every class where here only the class used on this page has to be instanciated --> -<script type='text/javascript' src="auto_server.php?stub=test"></script> - -<script type='text/javascript'> -// definition of the callback javascript class, used to handle async requests -function callback() {} -callback.prototype = { - echo_string: function(result) { - document.getElementById('target').innerHTML = result; - }, - cookies: function(result) { - var ret = ""; - for(var i in result) { - ret += i+':'+result[i]+"\n"; - } - document.getElementById('target').innerHTML = ret; - } -} - -// function used to clear out the target div -function clearTarget() { - document.getElementById('target').innerHTML = 'clear'; -} -</script> -</head> -<body> -<script type="text/javascript"> -// create a proxy in sync mode -var syncProxy = new test(); -// create a proxy in async mode -var asyncProxy = new test(new callback()); - -// run a sync call and set its results to the target div -function syncCall() { - document.getElementById('target').innerHTML = syncProxy.echo_string("I'm a sync call"); -} - -// run a sync call, callback class will handle its results -function asyncCall() { - asyncProxy.echo_string("I'm a async call"); -} - -function cookieTest() { - asyncProxy.cookies(); -} -</script> -<ul> - <li><a href="javascript:clearTarget()">Clear Target</a></li> - <li><a href="javascript:syncCall()">Run Sync Echo call</a></li> - <li><a href="javascript:asyncCall();">Run Async Echo call</a></li> - <li><a href="javascript:cookieTest();">View Cookies</a></li> -</ul> - -<div style="white-space: pre; padding: 1em; margin: 1em; width: 600px; height: 300px; border: solid 2px black; overflow: auto;" id="target">Target</div> - -<div> -Runing view Cookies should show you these same cookies being returned by the AJAX call -<pre> -<?php - var_dump($_COOKIE); -?> -</pre> -</div> - -</body> -</html> +<?php +/** + * Example of Using HTML_AJAX in proxy operation + * + * All AJAX calls are handled by the auto_server.php file, server.php could also be used, the differences between the two are covered in those files + * This is a use case very similar to JPSpan (JPSpan only has a server.php equivalent) + * + * The only needed interaction is creation of a new object from the proxy defintion, all AJAX calls happen transparently from there + * + * If you want to perform async calls a callback object must be passed to the constructor of the object + * + * The client JavaScript library is provided by auto_server.php, you could also copy HTML_AJAX.js (all js files combined) or the seperate js files into your webroot + * from the PEAR data dir and src them directly. You can use multiple includes of the component files or use the all flag to get them all at once. + * + * @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/HTML_AJAX + */ + +// set a cookie so we always have an example cookie for the test +setcookie('testcookie',"Doesn't taste as good as a peanut butter cookie"); + +?><html> +<head> + +<!-- These two calls can be combined into one call if wanted, but its not recomended since it will hurt caching as you might want stubs of multiple classes --> +<script type='text/javascript' src="auto_server.php?client=all"></script> +<!-- Stub is passed the class you want the proxy definition for, you can also use all to get every registered class but that create those auto server + has to instanciate every class where here only the class used on this page has to be instanciated --> +<script type='text/javascript' src="auto_server.php?stub=test"></script> + +<script type='text/javascript'> +// definition of the callback javascript class, used to handle async requests +function callback() {} +callback.prototype = { + echo_string: function(result) { + document.getElementById('target').innerHTML = result; + }, + cookies: function(result) { + var ret = ""; + for(var i in result) { + ret += i+':'+result[i]+"\n"; + } + document.getElementById('target').innerHTML = ret; + }, + echo_data: function(result) { + document.getElementById('target').innerHTML = HTML_AJAX_Util.varDump(result); + }, + unicode_data: function(result) { + document.getElementById('target').innerHTML = HTML_AJAX_Util.varDump(result); + }, + dump: function(result) { + document.getElementById('target').innerHTML = result; + } +} + +// function used to clear out the target div +function clearTarget() { + document.getElementById('target').innerHTML = 'clear'; +} +</script> +</head> +<body> +<script type="text/javascript"> +// create a proxy in sync mode +var syncProxy = new test(); +// create a proxy in async mode +var asyncProxy = new test(new callback()); + +// run a sync call and set its results to the target div +function syncCall() { + document.getElementById('target').innerHTML = syncProxy.echo_string("I'm a sync call"); +} + +// run a sync call, callback class will handle its results +function asyncCall() { + asyncProxy.echo_string("I'm a async call"); +} + +function unicodeTest() { + asyncProxy.echo_data({'suggestion': ['Français', 'caractères']}); +} + +function unicodeTest2() { + asyncProxy.unicode_data(); +} + +function cookieTest() { + asyncProxy.cookies(); +} +function assocTest() { + asyncProxy.dump({a: 'first var', b: 'second var'}); +} +</script> +<ul> + <li><a href="javascript:clearTarget()">Clear Target</a></li> + <li><a href="javascript:syncCall()">Run Sync Echo call</a></li> + <li><a href="javascript:asyncCall();">Run Async Echo call</a></li> + <li><a href="javascript:unicodeTest();">Check ability to round trip utf-8 JSON data</a></li> + <li><a href="javascript:unicodeTest2();">Check ability to recieve utf-8 JSON data</a></li> + <li><a href="javascript:assocTest();">Check ability to decode js hashes into PHP associative arrays using JSON</a></li> + <li><a href="javascript:cookieTest();">View Cookies</a></li> +</ul> + +<div style="white-space: pre; padding: 1em; margin: 1em; width: 600px; height: 300px; border: solid 2px black; overflow: auto;" id="target">Target</div> + +<div> +Runing view Cookies should show you these same cookies being returned by the AJAX call<br> +If the lists don't match, try reloading this page, it sets a test cookie, but we can't see it on the PHP side until the client returns it on a test. +<pre> +<?php + var_dump($_COOKIE); +?> +</pre> +</div> + +</body> +</html> http://cvs.php.net/viewvc.cgi/pear/HTML_AJAX/examples/proxyless_usage.php?r1=1.4&r2=1.5&diff_format=u Index: pear/HTML_AJAX/examples/proxyless_usage.php diff -u pear/HTML_AJAX/examples/proxyless_usage.php:1.4 pear/HTML_AJAX/examples/proxyless_usage.php:1.5 --- pear/HTML_AJAX/examples/proxyless_usage.php:1.4 Mon Nov 7 18:43:49 2005 +++ pear/HTML_AJAX/examples/proxyless_usage.php Fri Oct 13 15:31:22 2006 @@ -1,128 +1,149 @@ -<?php -/** - * Example of Using HTML_AJAX in proxyless operation - * - * This is the simplest way to use HTML_AJAX if your just using grab and replace functions you don't even need a server - * You need every javascript file except JSON which is optional and is only needed if your using that encoding - * - * The proxyless api is provided by Main.js - * - * There are 3 main methods and 2 properties to the proxyless api, they all exist as static methods on HTML_AJAX - * HTML_AJAX.grab(url) - * HTML_AJAX.replace(id,url) or HTML_AJAX.replace(id,class,method,arg1,arg2,etc) - * HTML_AJAX.call(class,method,callback,arg1,arg2,etc) - * - * HTML_AJAX.defaultServerUrl = 'serverurl'; - * HTML_AJAX.defaultEncoding = 'Null'; - * - * The api is demonstrated below, server.php is used for call examples and to load the needed js files - * - * @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/HTML_AJAX - */ -?> -<html> -<head> - -<script type='text/javascript' src="server.php?client=Util"></script> -<script type='text/javascript' src="server.php?client=main"></script> -<script type='text/javascript' src="server.php?client=dispatcher"></script> -<script type='text/javascript' src="server.php?client=HttpClient"></script> -<script type='text/javascript' src="server.php?client=Request"></script> -<script type='text/javascript' src="server.php?client=json"></script> -<script type='text/javascript' src="server.php?client=loading"></script> - -</head> -<body> -<script type="text/javascript"> -function clearTarget() { - document.getElementById('target').innerHTML = 'clear'; -} - -// Add an error handler so we get an alert if any errors happen while making an AJAX call -HTML_AJAX.onError = function(e) -{ - alert(HTML_AJAX_Util.varDump(e)); -} - - -// Grab is the simplest usage of HTML_AJAX you use it to perform a request to a page and get its results back -// It can be used in either Sync mode where it returns directory or with a call back, both methods are shown below -var url = 'README'; -function grabSync() { - document.getElementById('target').innerHTML = HTML_AJAX.grab(url); -} - -function grabAsync() { - HTML_AJAX.grab(url,grabCallback); -} - -function grabCallback(result) { - document.getElementById('target').innerHTML = result; -} - - -// replace can operate either against a url like grab or against a remote method -// if its going to be used against a remote method defaultServerUrl needs to be set to a url that is exporting the class its trying to call -// note that replace replace always works async - -HTML_AJAX.defaultServerUrl = 'server.php'; - -function replaceUrl() { - HTML_AJAX.replace('target',url); -} - -function replaceFromMethod() { - HTML_AJAX.replace('target','test','echo_string','Im a method call replacement'); -} -function replaceFromMethodMulti() { - // Null encoding does not support multiple arguments, you have to use JSON for that - HTML_AJAX.defaultEncoding = 'JSON'; // set encoding to JSON encoding method - HTML_AJAX.replace('target','test','multiarg','argument1','argument2','argument3'); - HTML_AJAX.defaultEncoding = 'Null'; // return it to default which is Null -} - - -// call is used to call a method on a remote server -// you need to set HTML_AJAX.defaultServerUrl to use it -// you might also want to set HTML_AJAX.defaultEncoding, options are Null and JSON, the server will autodetect this encoding from your content type -// but the return content type will be based on whatever the servers settings are -// You can use call in either Sync or Async mode depending on if you pass it a callback function - -function callSync() { - HTML_AJAX.defaultEncoding = 'JSON'; // set encoding to JSON encoding method - document.getElementById('target').innerHTML = HTML_AJAX.call('test','echo_string',false,'Im text that was echoed'); - HTML_AJAX.defaultEncoding = 'Null'; // return it to default which is Null -} - -function callAsync() { - HTML_AJAX.call('test','echo_string',callCallback,'Im text that was echoed Async'); -} - -function callCallback(result) { - document.getElementById('target').innerHTML = result; -} - -</script> -<ul> - <li><a href="javascript:clearTarget()">Clear Target</a></li> - <li><a href="javascript:grabSync()">Run Sync Grab Example</a></li> - <li><a href="javascript:grabAsync()">Run Async Grab Example</a></li> - <li><a href="javascript:replaceUrl()">Replace with content from a url</a></li> - <li><a href="javascript:replaceFromMethod()">Replace with content from a method call</a></li> - <li><a href="javascript:replaceFromMethodMulti()">Replace with content from a method call (multiple method arguments)</a></li> - <li><a href="javascript:callSync()">Sync Call</a></li> - <li><a href="javascript:callAsync()">ASync Call</a></li> -</ul> - -<div style="white-space: pre; padding: 1em; margin: 1em; width: 600px; height: 300px; border: solid 2px black; overflow: auto;" id="target">Target</div> -</body> -</html> -<?php -/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ -?> +<?php +/** + * Example of Using HTML_AJAX in proxyless operation + * + * This is the simplest way to use HTML_AJAX if your just using grab and replace functions you don't even need a server + * You need every javascript file except JSON which is optional and is only needed if your using that encoding + * + * The proxyless api is provided by Main.js + * + * There are 4 main methods and 2 properties to the proxyless api, they all exist as static methods on HTML_AJAX + * HTML_AJAX.grab(url) + * HTML_AJAX.post(url,payload) + * HTML_AJAX.replace(id,url) or HTML_AJAX.replace(id,class,method,arg1,arg2,etc) + * HTML_AJAX.call(class,method,callback,arg1,arg2,etc) + * + * HTML_AJAX.defaultServerUrl = 'serverurl'; + * HTML_AJAX.defaultEncoding = 'Null'; + * + * The api is demonstrated below, server.php is used for call examples and to load the needed js files + * + * @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/HTML_AJAX + */ +?> +<html> +<head> + +<script type='text/javascript' src="server.php?client=Util"></script> +<script type='text/javascript' src="server.php?client=main"></script> +<script type='text/javascript' src="server.php?client=dispatcher"></script> +<script type='text/javascript' src="server.php?client=HttpClient"></script> +<script type='text/javascript' src="server.php?client=Request"></script> +<script type='text/javascript' src="server.php?client=json"></script> +<script type='text/javascript' src="server.php?client=loading"></script> +<script type='text/javascript' src="server.php?client=iframe"></script> +<script type='text/javascript' src="server.php?client=urlserializer"></script> + +</head> +<body> +<script type="text/javascript"> +function clearTarget() { + document.getElementById('target').innerHTML = 'clear'; +} + +// Add an error handler so we get an alert if any errors happen while making an AJAX call +HTML_AJAX.onError = function(e) +{ + alert(HTML_AJAX_Util.varDump(e)); +} + + +// Grab is the simplest usage of HTML_AJAX you use it to perform a request to a page and get its results back +// It can be used in either Sync mode where it returns directory or with a call back, both methods are shown below +var url = 'README'; +function grabSync() { + document.getElementById('target').innerHTML = HTML_AJAX.grab(url); +} + +function grabAsync() { + HTML_AJAX.grab(url,grabCallback); +} + +function grabCallback(result) { + document.getElementById('target').innerHTML = result; +} + +// POST lets you make simple POST requests to a url, if you use a hash {key:value,key2:value,etc} as the payload then the +// data will be automatically be urlencoded, making it look like a form submission to the server +// if the data is a string it will be sent as is +var postUrl = 'support/post_tester.php'; +function postSync() { + document.getElementById('target').innerHTML = HTML_AJAX.post(postUrl,{dog:'bob',cat:'tigger'}); +} + +function postAsync() { + HTML_AJAX.post(postUrl,{dog:'bob',cat:'tigger'},grabCallback); +} + +function postCallback(result) { + document.getElementById('target').innerHTML = result; +} + + +// replace can operate either against a url like grab or against a remote method +// if its going to be used against a remote method defaultServerUrl needs to be set to a url that is exporting the class its trying to call +// note that replace replace always works async + +HTML_AJAX.defaultServerUrl = 'server.php'; + +function replaceUrl() { + HTML_AJAX.replace('target',url); +} + +function replaceFromMethod() { + HTML_AJAX.replace('target','test','echo_string','Im a method call replacement'); +} +function replaceFromMethodMulti() { + // Null encoding does not support multiple arguments, you have to use JSON for that + HTML_AJAX.defaultEncoding = 'JSON'; // set encoding to JSON encoding method + HTML_AJAX.replace('target','test','multiarg','argument1','argument2','argument3'); + HTML_AJAX.defaultEncoding = 'Null'; // return it to default which is Null +} + + +// call is used to call a method on a remote server +// you need to set HTML_AJAX.defaultServerUrl to use it +// you might also want to set HTML_AJAX.defaultEncoding, options are Null and JSON, the server will autodetect this encoding from your content type +// but the return content type will be based on whatever the servers settings are +// You can use call in either Sync or Async mode depending on if you pass it a callback function + +function callSync() { + HTML_AJAX.defaultEncoding = 'JSON'; // set encoding to JSON encoding method + document.getElementById('target').innerHTML = HTML_AJAX.call('test','echo_string',false,'Im text that was echoed'); + HTML_AJAX.defaultEncoding = 'Null'; // return it to default which is Null +} + +function callAsync() { + HTML_AJAX.call('test','echo_string',callCallback,'Im text that was echoed Async'); +} + +function callCallback(result) { + document.getElementById('target').innerHTML = result; +} + +</script> +<ul> + <li><a href="javascript:clearTarget()">Clear Target</a></li> + <li><a href="javascript:grabSync()">Run Sync Grab Example</a></li> + <li><a href="javascript:grabAsync()">Run Async Grab Example</a></li> + <li><a href="javascript:postSync()">Run Sync Post Example</a></li> + <li><a href="javascript:postAsync()">Run Async Post Example</a></li> + <li><a href="javascript:replaceUrl()">Replace with content from a url</a></li> + <li><a href="javascript:replaceFromMethod()">Replace with content from a method call</a></li> + <li><a href="javascript:replaceFromMethodMulti()">Replace with content from a method call (multiple method arguments)</a></li> + <li><a href="javascript:callSync()">Sync Call</a></li> + <li><a href="javascript:callAsync()">ASync Call</a></li> +</ul> + +<div style="white-space: pre; padding: 1em; margin: 1em; width: 600px; height: 300px; border: solid 2px black; overflow: auto;" id="target">Target</div> +</body> +</html> +<?php +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ +?> http://cvs.php.net/viewvc.cgi/pear/HTML_AJAX/examples/queue_usage.php?r1=1.2&r2=1.3&diff_format=u Index: pear/HTML_AJAX/examples/queue_usage.php diff -u pear/HTML_AJAX/examples/queue_usage.php:1.2 pear/HTML_AJAX/examples/queue_usage.php:1.3 --- pear/HTML_AJAX/examples/queue_usage.php:1.2 Mon Nov 7 18:43:49 2005 +++ pear/HTML_AJAX/examples/queue_usage.php Fri Oct 13 15:31:22 2006 @@ -1,76 +1,76 @@ -<?php -/** - * Example of Using HTML_AJAX with a queue - * - * When using HTML_AJAX your actually always using a queue, its just its a simple one that always performs whatever actions its given immediately - * HTML_AJAX however provides other queues offering different modes of operation - * - * Currently the Queues are (class names are prefixed with: HTML_AJAX_Queue_): - * Immediate - Default make the request immediately - * Interval_SingleBuffer - Make request on an interval with holding just the last request between calls - * - * Interval_SingleBuffer is generally used for Live Search/Google Suggest type operations - * - * @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/HTML_AJAX - */ -?> -<html> -<head> - -<script type='text/javascript' src="server.php?client=Util,main,dispatcher,httpclient,request,json,loading"></script> -<script type='text/javascript' src="auto_server.php?stub=livesearch"></script> - -</head> -<body> -<script type="text/javascript"> - -// callback hash, outputs the results of the search method -callback = { - search: function(result) { - var out = "<ul>"; - - // if we have object this works right, if we have an array we get a problem - // if we have sparse keys will get an array back otherwise will get an array - for(var i in result) { - if (i != '______array') { - out += "<li>"+i+" = "+result[i]+"</li>"; - } - } - out += "</ul>"; - document.getElementById('target').innerHTML = out; - } -} - -// setup our remote object from the generated proxy stub -var remoteLiveSearch = new livesearch(callback); - -// we could change the queue by overriding the default one, but generally you want to create a new one -// set our remote object to use the rls queue -remoteLiveSearch.dispatcher.queue = 'rls'; - -// create the rls queue, with a 350ms buffer, a larger interval such as 2000 is useful to see what is happening but not so useful in real life -HTML_AJAX.queues['rls'] = new HTML_AJAX_Queue_Interval_SingleBuffer(350); - - -// what to call on onkeyup, you might want some logic here to not search on empty strings or to do something else in those cases -function searchRequest(searchBox) { - remoteLiveSearch.search(searchBox.value); -} -</script> - -<p>This is a really basic LiveSearch example, type in the box below to find a fruit</p> - -Search <input id="search" autocomplete="off" onkeyup="searchRequest(this)"> - -<div style="white-space: pre; padding: 1em; margin: 1em; width: 600px; height: 300px; border: solid 2px black; overflow: auto;" id="target">Target</div> -</body> -</html> -<?php -/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ -?> +<?php +/** + * Example of Using HTML_AJAX with a queue + * + * When using HTML_AJAX your actually always using a queue, its just its a simple one that always performs whatever actions its given immediately + * HTML_AJAX however provides other queues offering different modes of operation + * + * Currently the Queues are (class names are prefixed with: HTML_AJAX_Queue_): + * Immediate - Default make the request immediately + * Interval_SingleBuffer - Make request on an interval with holding just the last request between calls + * + * Interval_SingleBuffer is generally used for Live Search/Google Suggest type operations + * + * @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/HTML_AJAX + */ +?> +<html> +<head> + +<script type='text/javascript' src="server.php?client=Util,main,dispatcher,httpclient,request,json,loading,iframe,queues"></script> +<script type='text/javascript' src="auto_server.php?stub=livesearch"></script> + +</head> +<body> +<script type="text/javascript"> + +// callback hash, outputs the results of the search method +callback = { + search: function(result) { + var out = "<ul>"; + + // if we have object this works right, if we have an array we get a problem + // if we have sparse keys will get an array back otherwise will get an array + for(var i in result) { + if (i != '______array') { + out += "<li>"+i+" = "+result[i]+"</li>"; + } + } + out += "</ul>"; + document.getElementById('target').innerHTML = out; + } +} + +// setup our remote object from the generated proxy stub +var remoteLiveSearch = new livesearch(callback); + +// we could change the queue by overriding the default one, but generally you want to create a new one +// set our remote object to use the rls queue +remoteLiveSearch.dispatcher.queue = 'rls'; + +// create the rls queue, with a 350ms buffer, a larger interval such as 2000 is useful to see what is happening but not so useful in real life +HTML_AJAX.queues['rls'] = new HTML_AJAX_Queue_Interval_SingleBuffer(350); + + +// what to call on onkeyup, you might want some logic here to not search on empty strings or to do something else in those cases +function searchRequest(searchBox) { + remoteLiveSearch.search(searchBox.value); +} +</script> + +<p>This is a really basic LiveSearch example, type in the box below to find a fruit</p> + +Search <input id="search" autocomplete="off" onkeyup="searchRequest(this)"> + +<div style="white-space: pre; padding: 1em; margin: 1em; width: 600px; height: 300px; border: solid 2px black; overflow: auto;" id="target">Target</div> +</body> +</html> +<?php +/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ +?> http://cvs.php.net/viewvc.cgi/pear/HTML_AJAX/examples/server.php?r1=1.4&r2=1.5&diff_format=u Index: pear/HTML_AJAX/examples/server.php diff -u pear/HTML_AJAX/examples/server.php:1.4 pear/HTML_AJAX/examples/server.php:1.5 --- pear/HTML_AJAX/examples/server.php:1.4 Mon Nov 7 18:43:49 2005 +++ pear/HTML_AJAX/examples/server.php Fri Oct 13 15:31:22 2006 @@ -1,35 +1,36 @@ -<?php -/** - * Simplest possible usage of HTML_AJAX_Server - * - * The server responds to ajax calls and also serves the js client libraries, so they can be used directly from the PEAR data dir - * 304 not modified headers are used when server client libraries so they will be cached on the browser reducing overhead - * - * @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/HTML_AJAX - */ - - // include the server class -include 'HTML/AJAX/Server.php'; - -// include the test class will be registering - include 'test.class.php'; - -// create our new server -$server = new HTML_AJAX_Server(); - -// register an instance of the class were registering -$test =& new test(); -$server->registerClass($test); - -// handle different types of requests possiblities are -// ?client=all - request for all javascript client files -// ?stub=classname - request for proxy stub for given class, can be combined with client but this may hurt caching unless stub=all is used -// ?c=classname&m=method - an ajax call, server handles serialization and handing things off to the proper method then returning the results -$server->handleRequest(); -?> +<?php +/** + * Simplest possible usage of HTML_AJAX_Server + * + * The server responds to ajax calls and also serves the js client libraries, so they can be used directly from the PEAR data dir + * 304 not modified headers are used when server client libraries so they will be cached on the browser reducing overhead + * + * @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/HTML_AJAX + */ + + // include the server class +include 'HTML/AJAX/Server.php'; + +// include the test class will be registering + include 'support/test.class.php'; + +// create our new server +$server = new HTML_AJAX_Server(); + +// register an instance of the class were registering +$test =& new test(); +$server->registerClass($test); +$server->ajax->packJavaScript = true; + +// handle different types of requests possiblities are +// ?client=all - request for all javascript client files +// ?stub=classname - request for proxy stub for given class, can be combined with client but this may hurt caching unless stub=all is used +// ?c=classname&m=method - an ajax call, server handles serialization and handing things off to the proper method then returning the results +$server->handleRequest(); +?> http://cvs.php.net/viewvc.cgi/pear/HTML_AJAX/DeveloperNotes.txt?view=markup&rev=1.1 Index: pear/HTML_AJAX/DeveloperNotes.txt +++ pear/HTML_AJAX/DeveloperNotes.txt Well if you've got this far you've at least found the development version of HTML_AJAX If you want to run a non released version you have to perform some of the magic the pear installer does on your own. The quickest solution to this is to run pear install -f package.xml. This will install HTML_AJAX overwriting whatever version is currently installed. If your on windows you'll want to take a look at test.bat. Or you can simply check out HTML_AJAX into a directory called HTML and set the parent directory in an .htacess file as the include path, also make sure you turn off E_STRICT or the examples will break php_value include_path "/path/to/HTML/parent" php_value error_reporting 2047 http://cvs.php.net/viewvc.cgi/pear/HTML_AJAX/examples/action_usage.php?view=markup&rev=1.1 Index: pear/HTML_AJAX/examples/action_usage.php +++ pear/HTML_AJAX/examples/action_usage.php <?php /** * Example of Using HTML_AJAX_Action * * All the work happens in support/testHaa.class.php * This class just attaches some acctions to calls to the server class * * This just shows basic functionality, what were doing isn't actually useful * For an example on how one would actually use HTML_AJAX_Action check out the guestbook example * * @category HTML * @package AJAX * @author Joshua Eichorn <josh@bluga.net> * @copyright 2006 Joshua Eichorn * @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @version Release: @package_version@ * @link http://pear.php.net/package/HTML_AJAX */ ?> <html> <head> <script type='text/javascript' src="auto_server.php?client=all"></script> <script type='text/javascript' src="auto_server.php?stub=testHaa"></script> <script type='text/javascript'> // create our remote object so we can use it elsewhere var remote = new testHaa({}); // pass in an empty hash so were in async mode </script> </head> <body> <h1>Basic HTML_AJAX_Action Usage</h1> <ul> <li><a href="#" onclick="remote.greenText('target')">Make Target Green</a></li> <li><a href="#" onclick="remote.highlight('target')">Highlight Target</a></li> <li><a href="#" onclick="remote.duplicate('target','dest')">Duplicate Target</a></li> </ul> <div id="target"> I'm some random text. Ain't I fun. </div> <div id="dest"> </div> </body> </html> http://cvs.php.net/viewvc.cgi/pear/HTML_AJAX/examples/form.php?view=markup&rev=1.1 Index: pear/HTML_AJAX/examples/form.php +++ pear/HTML_AJAX/examples/form.php <?php /** * AJAX form submission example * * @category HTML * @package AJAX * @author Arpad Ray <arpad@php.net> * @author Laurent Yaish <laurenty@gmail.com> * @copyright 2005 Arpad Ray * @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @version Release: @package_version@ * @link http://pear.php.net/package/HTML_AJAX */ ?> <html> <head> <script type="text/javascript" src="server.php?client=all&stub=test"></script> </head> <body> <pre id="target"> </pre> <form action="server.php" method="post" onsubmit="return !HTML_AJAX.formSubmit(this, 'target', {className: 'test', methodName:'multiarg'});"> <table> <tr> <td>Text</td> <td><input type="text" name="test_text" value="example" /></td> </tr> <tr> <td>Single Select</td> <td> <select name="test_select"> <option value="example1">Example 1</option> <option value="example2">Example 2</option> </select> </td> </tr> <tr> <td>Multi Select</td> <td> <select name="test_select_multiple[]" multiple="multiple"> <option value="examplea">Example A</option> <option value="exampleb">Example B</option> <option value="examplec">Example C</option> <option value="exampled">Example D</option> </select> </td> </tr> <tr> <td>Single Checkbox</td> <td><input type="checkbox" name="single_checkbox" value="single_check1" /></td> </tr> <tr> <td>Multi Checkboxes</td> <td> <input type="checkbox" name="multi_checkbox[]" value="multi_check1" />1 <input type="checkbox" name="multi_checkbox[]" value="multi_check2" />2 <input type="checkbox" name="multi_checkbox[]" value="multi_check3" />3 </td> </tr> <tr> <td>Radio Buttons</td> <td> <input type="radio" name="test_radio" value="radio_1" />1 <input type="radio" name="test_radio" value="radio_2" />2 <input type="radio" name="test_radio" value="radio_3" />3 </td> </tr> <tr> <td>Textarea</td> <td> <textarea name="long_text">type a long string in here....</textarea> </td> </tr> </table> <input type="submit" name="submit" value="Submit form" /> </form> </body> </html> http://cvs.php.net/viewvc.cgi/pear/HTML_AJAX/examples/grab.php?view=markup&rev=1.1 Index: pear/HTML_AJAX/examples/grab.php +++ pear/HTML_AJAX/examples/grab.php <?php /** * Simple grab example * * @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: @package_version@ * @link http://pear.php.net/package/HTML_AJAX */ include 'HTML/AJAX.php'; if (isset($_GET['grab'])) { die('Grabbed from php!'); } $ajax = new HTML_AJAX(); if ($ajax->handleRequest()) { exit; } ?><html> <head> <script type='text/javascript' src="../js/HTML_AJAX.js"></script> <script type="text/javascript"> function grab() { var callback = function(result) { document.getElementById('target').innerHTML = result; } HTML_AJAX.grab('grab.php?grab=1', callback); } </script> </head> <body> <a href="javascript:grab()">grab</a> <pre id="target"> </pre> </body> </html> http://cvs.php.net/viewvc.cgi/pear/HTML_AJAX/examples/haa_usage.php?view=markup&rev=1.1 Index: pear/HTML_AJAX/examples/haa_usage.php +++ pear/HTML_AJAX/examples/haa_usage.php <?php /** * Example of Using HTML_AJAX_Action see support/testHaa.class.php * * @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/HTML_AJAX */ // include the helper class require_once 'HTML/AJAX/Helper.php'; // create an instance and set the server url $ajaxHelper = new HTML_AJAX_Helper(); $ajaxHelper->serverUrl = 'auto_server.php'; $ajaxHelper->jsLibraries[] = array('haserializer'); $ajaxHelper->stubs[] = 'testHaa'; ?> <html> <head> <?php echo $ajaxHelper->setupAJAX(); ?> <script type="text/javascript"> var remote = new testHaa(); </script> <style type="text/css">..test { color: red; } </style> </head> <body> <div id="test"> I'm some test content </div> <ul> <li><a href="#" onclick="remote.updateClassName()">Update className</a></li> </ul> </body> </html> http://cvs.php.net/viewvc.cgi/pear/HTML_AJAX/examples/php_callback.php?view=markup&rev=1.1 Index: pear/HTML_AJAX/examples/php_callback.php +++ pear/HTML_AJAX/examples/php_callback.php <?php require_once 'HTML/AJAX/Server.php'; class Foo { function bar() { return 'hello'; } } function foobar() { return 'hello'; } // start server $server = new HTML_AJAX_Server(); // register normal function $callback = 'foobar'; $server->registerPhpCallback($callback); // register static method $callback = array('Foo', 'bar'); $server->registerPhpCallback($callback); // register object method $foo = new Foo; $callback = array($foo, 'bar'); $server->registerPhpCallback($callback); // handle the request if ($server->handleRequest()) { exit; } ?> <html> <head> <script type='text/javascript' src="?client=all&amp;stub=all"></script> <script type="text/javascript" language="Javascript"> <!-- HTML_AJAX.defaultServerUrl = 'php_callback.php'; function testCallPhpCallback(cb) { HTML_AJAX.callPhpCallback(cb, showResult); } function showResult(result) { alert(result); } var foo = new foo; //--> </script> </head> <body> using HTML_AJAX.callPhpCallback() <ul> <li><a href="javascript:testCallPhpCallback('foobar')">normal function</a></li> <li><a href="javascript:testCallPhpCallback(['Foo', 'bar'])">static method</a></li> <li><a href="javascript:testCallPhpCallback([foo, 'bar'])">object method</a></li> </ul> exported <ul> <li><a href="javascript:alert(foo.bar())">object method</a></li> </ul> </body> </html> http://cvs.php.net/viewvc.cgi/pear/HTML_AJAX/examples/shoutbox.php?view=markup&rev=1.1 Index: pear/HTML_AJAX/examples/shoutbox.php +++ pear/HTML_AJAX/examples/shoutbox.php <?php /** * AJAX form submission, practical example * * @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: @package_version@ * @link http://pear.php.net/package/HTML_AJAX */ define('MESSAGE_FILE', 'messages.txt'); $messages = (is_readable(MESSAGE_FILE) ? unserialize(file_get_contents(MESSAGE_FILE)) : array()); function show_messages() { foreach ($GLOBALS['messages'] as $m) { echo "<br>Name:{$m[0]}<br>Message:{$m[1]}<br><hr>"; } } function save_messages() { if ($h = @fopen(MESSAGE_FILE, 'wb')) { $GLOBALS['messages'] = array_slice($GLOBALS['messages'], -5); fwrite($h, serialize($GLOBALS['messages'])); fclose($h); } } if (!empty($_POST)) { if (!empty($_POST['name']) && !empty($_POST['message'])) { $messages[] = array( htmlspecialchars(strip_tags(substr($_POST['name'], 0, 10))), htmlspecialchars(strip_tags(substr($_POST['message'], 0, 30))) ); save_messages(); } show_messages(); exit; } ?><html> <head> <script type="text/javascript" src="server.php?client=all&amp;stub=all"></script> </head> <body> <h1>Messages:</h1> <div id="target"> <?php show_messages(); ?> </div> <form action="shoutbox.php" method="post" onsubmit="return !HTML_AJAX.formSubmit(this, 'target')"> <label> Name: <input type="text" name="name" id="name" /> </label> <label> Message: <input type="text" name="message" id="message" /> </label> <input type="submit" value="Submit" /> </form> </body> </html> http://cvs.php.net/viewvc.cgi/pear/HTML_AJAX/examples/slow_livesearch.php?view=markup&rev=1.1 Index: pear/HTML_AJAX/examples/slow_livesearch.php +++ pear/HTML_AJAX/examples/slow_livesearch.php <?php /** * Using the ordered queue to deal with high latency * * @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/HTML_AJAX */ session_start(); if (isset($_GET['latency'])) { $_SESSION['sleep'] = $_GET['latency']; } ?> <html> <head> <script type='text/javascript' src="server.php?client=Util,main,dispatcher,httpclient,request,json,loading,iframe,orderedqueue"></script> <script type='text/javascript' src="slow_server.php?stub=livesearch"></script> </head> <body> <script type="text/javascript"> // callback hash, outputs the results of the search method callback = { search: function(result) { var out = "<ul>"; // if we have object this works right, if we have an array we get a problem // if we have sparse keys will get an array back otherwise will get an array for(var i in result) { if (i != '______array') { out += "<li>"+i+" = "+result[i]+"</li>"; } } out += "</ul>"; document.getElementById('target').innerHTML = out; } } // setup our remote object from the generated proxy stub var remoteLiveSearch = new livesearch(callback); // we could change the queue by overriding the default one, but generally you want to create a new one // set our remote object to use the ordered queue remoteLiveSearch.dispatcher.queue = 'ordered'; HTML_AJAX.queues['ordered'] = new HTML_AJAX_Queue_Ordered(); // what to call on onkeyup, you might want some logic here to not search on empty strings or to do something else in those cases function searchRequest(searchBox) { remoteLiveSearch.search(searchBox.value); } </script> <p>This is a really basic LiveSearch example, type in the box below to find a fruit</p> <p>By deafult server add latency to the request, starting with 5 seconds and reducing 1 second per request</p> <p>An ordered queue has been used which should make results come back in the order they are sent not the order they are received</p> <form action="slow_livesearch.php"> <label>Set current latency too: <input name="latency" size=4><input type="submit"> </form> <hr><br> Search <input id="search" autocomplete="off" onkeyup="searchRequest(this)"> <div style="white-space: pre; padding: 1em; margin: 1em; width: 600px; height: 300px; border: solid 2px black; overflow: auto;" id="target">Target</div> </body> </html> <?php /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ ?> http://cvs.php.net/viewvc.cgi/pear/HTML_AJAX/examples/slow_server.php?view=markup&rev=1.1 Index: pear/HTML_AJAX/examples/slow_server.php +++ pear/HTML_AJAX/examples/slow_server.php <?php /** * A server that adds artificial latency to requests * * @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/HTML_AJAX */ session_start(); // include the server class include 'HTML/AJAX/Server.php'; // don't add delays to client library requests if (!isset($_GET['client']) && !isset($_GET['stub'])) { if (!isset($_SESSION['sleep']) || $_SESSION['sleep'] == 0) { $_SESSION['sleep'] = 5; } sleep($_SESSION['sleep']--); } // extend HTML_AJAX_Server creating our own custom one with init{ClassName} methods for each class it supports calls on class TestServer extends HTML_AJAX_Server { // this flag must be set to on init methods var $initMethods = true; // init method for the test class, includes needed files an registers it for ajax function initTest() { include 'support/test.class.php'; $this->registerClass(new test()); } // init method for the livesearch class, includes needed files an registers it for ajax function initLivesearch() { include 'support/livesearch.class.php'; $this->registerClass(new livesearch()); } // init method for the testHaa class, includes needed files an registers it for ajax, directly passes in methods to register to specify case in php4 function initTestHaa() { include 'support/testHaa.class.php'; $this->registerClass(new testHaa(),'testHaa',array('updateClassName')); } } $server = new TestServer(); // handle requests as needed $server->handleRequest(); ?> http://cvs.php.net/viewvc.cgi/pear/HTML_AJAX/examples/xml_usage.php?view=markup&rev=1.1 Index: pear/HTML_AJAX/examples/xml_usage.php +++ pear/HTML_AJAX/examples/xml_usage.php <?php /** * Example of Using HTML_AJAX in proxy operation * * All AJAX calls are handled by the xmlserver.php * * The only needed interaction is creation of a new object from the proxy defintion, all AJAX calls happen transparently from there * * If you want to perform async calls a callback object must be passed to the constructor of the object * * @category HTML * @package AJAX * @author Elizabeth Smith <auroraeosrose@gmail.com> * @copyright 2006 Elizabeth Smith * @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @version Release: @package_version@ * @link http://pear.php.net/package/HTML_AJAX */ ?><html> <head> <script type='text/javascript' src="xmlserver.php?client=all"></script> <script type='text/javascript' src="xmlserver.php?stub=testxml"></script> <script type='text/javascript'> // function to display xml received from server function showItems(xml) { var list=xml.getElementsByTagName('item'); document.getElementById('target').innerHTML = '<p>My Fridge</p>'; for (var i=0;i<list.length;i++) { var node = list[i]; document.getElementById('target').innerHTML += '<p>' + node.firstChild.nodeValue + ' is a ' + node.getAttribute('type') + '</p>'; } } // function to display xml created here function showMessage(xml) { var list=xml.getElementsByTagName('tag'); document.getElementById('target').innerHTML = ''; for (var i=0;i<list.length;i++) { var node = list[i]; document.getElementById('target').innerHTML += '<p>' + node.firstChild.nodeValue + '</p>'; } } // definition of the callback javascript class, used to handle async requests function callback() {} callback.prototype = { createJunk: function(result) { showItems(result); }, writeDoc: function(result) { dom = HTML_AJAX.grab('test.xml'); showMessage(dom); } } // function used to clear out the target div function clearTarget() { document.getElementById('target').innerHTML = 'clear'; } //create xml document to send back to server var xmlhello = '<?xml version="1.0"?><root><tag>Hello</tag></root>'; xmlhello = new DOMParser().parseFromString(xmlhello, 'text/xml'); var xmlgoodbye = '<?xml version="1.0"?><root><tag>Goodbye</tag></root>'; xmlgoodbye = new DOMParser().parseFromString(xmlgoodbye, 'text/xml'); </script> </head> <body> <script type="text/javascript"> // create a proxy in sync mode var syncProxy = new TestXml(); // create a proxy in async mode var asyncProxy = new TestXml(new callback()); // run a sync call and set its results to the target div function syncCall() { dom = syncProxy.createHealthy(); showItems(dom); } function syncSend(xml) { syncProxy.writeDoc(xml); dom = HTML_AJAX.grab('test.xml'); showMessage(dom); } // run a sync call, callback class will handle its results function asyncCall() { asyncProxy.createJunk(); } // run a sync call, callback class will handle its results function asyncSend(xml) { asyncProxy.writeDoc(xml); } </script> <ul> <li><a href="javascript:clearTarget()">Clear Target</a></li> <li><a href="javascript:syncCall()">Retrieve XmlDom Sync</a></li> <li><a href="javascript:asyncCall();">Retrieve XmlDom Async</a></li> <li><a href="javascript:syncSend(xmlhello);">Send XmlDom Sync</a></li> <li><a href="javascript:asyncSend(xmlgoodbye);">Send XmlDom Async</a></li> </ul> <div style="white-space: pre; padding: 1em; margin: 1em; width: 600px; height: 300px; border: solid 2px black; overflow: auto;" id="target">Target</div> </div> </body> </html> http://cvs.php.net/viewvc.cgi/pear/HTML_AJAX/examples/xmlserver.php?view=markup&rev=1.1 Index: pear/HTML_AJAX/examples/xmlserver.php +++ pear/HTML_AJAX/examples/xmlserver.php <?php include 'HTML/AJAX/Server.php'; include 'support/xml.class.php'; $server = new HTML_AJAX_Server(); // register an instance of the class were registering $xml =& new TestXml(); $server->registerClass($xml); $server->setSerializer('XML'); $server->handleRequest(); ?>
« previous php.pear.cvs (#42527) next »