Documentation is available at Server.class.php
- <?php
- /**
- * XOAD Server file.
- *
- * <p>This file defines the {@link XOAD_Server} Class.</p>
- * <p>Example:</p>
- * <code>
- * <?php
- *
- * require_once('xoad.php');
- *
- * class Calculator
- * {
- * var $result;
- *
- * function Calculator()
- * {
- * $this->result = 0;
- * }
- *
- * function Add($arg)
- * {
- * $this->result += $arg;
- * }
- * }
- *
- * XOAD_Server::runServer();
- *
- * ?>
- * </code>
- *
- * @author Stanimir Angeloff
- *
- * @package XOAD
- *
- * @version 0.6.0.0
- *
- */
- /**
- * XOAD Server Class.
- *
- * <p>This class is used to handle client callbacks.</p>
- * <p>Example:</p>
- * <code>
- * <?php
- *
- * require_once('xoad.php');
- *
- * class Calculator
- * {
- * var $result;
- *
- * function Calculator()
- * {
- * $this->result = 0;
- * }
- *
- * function Add($arg)
- * {
- * $this->result += $arg;
- * }
- * }
- *
- * XOAD_Server::runServer();
- *
- * ?>
- * </code>
- *
- * @author Stanimir Angeloff
- *
- * @package XOAD
- *
- * @version 0.6.0.0
- *
- */
- class XOAD_Server extends XOAD_Observable
- {
- /**
- * Checks if the request is a client callback
- * to the server and handles it.
- *
- * @access public
- *
- * @return bool true if the request is a valid client callback,
- * false otherwise.
- *
- * @static
- *
- */
- function runServer()
- {
- if ( ! XOAD_Server::notifyObservers('runServerEnter')) {
- return false;
- }
- if (XOAD_Server::initializeCallback()) {
- XOAD_Server::dispatch();
- /**
- * Defines whether the request is a client callback.
- */
- define('XOAD_CALLBACK', true);
- }
- if ( ! defined('XOAD_CALLBACK')) {
- /**
- * Defines whether the request is a client callback.
- */
- define('XOAD_CALLBACK', false);
- }
- if (XOAD_Server::notifyObservers('runServerLeave', array('isCallback' => XOAD_CALLBACK))) {
- return XOAD_CALLBACK;
- } else {
- return false;
- }
- }
- /**
- * Checks if the request is a client callback to the
- * server and initializes callback parameters.
- *
- * @access public
- *
- * @return bool true if the request is a valid client callback,
- * false otherwise.
- *
- * @static
- *
- */
- function initializeCallback()
- {
- if ( ! XOAD_Server::notifyObservers('initializeCallbackEnter')) {
- return false;
- }
- if (isset($_GET['xoadCall'])) {
- if (strcasecmp($_GET['xoadCall'], 'true') == 0) {
- if ( ! isset($GLOBALS['HTTP_RAW_POST_DATA'])) {
- return false;
- }
- $requestBody = @unserialize($GLOBALS['HTTP_RAW_POST_DATA']);
- if ($requestBody == null) {
- return false;
- }
- if (
- isset($requestBody['eventPost']) &&
- isset($requestBody['className']) &&
- isset($requestBody['sender']) &&
- isset($requestBody['event']) &&
- array_key_exists('data', $requestBody) &&
- array_key_exists('filter', $requestBody)) {
- if (
- (XOAD_Utilities::getType($requestBody['eventPost']) != 'bool') ||
- (XOAD_Utilities::getType($requestBody['className']) != 'string') ||
- (XOAD_Utilities::getType($requestBody['sender']) != 'string') ||
- (XOAD_Utilities::getType($requestBody['event']) != 'string')) {
- return false;
- }
- if ( ! empty($requestBody['className'])) {
- XOAD_Server::loadClass($requestBody['className']);
- } else {
- return false;
- }
- if ( ! XOAD_Server::isClassAllowed($requestBody['className'])) {
- return false;
- }
- $requestBody['sender'] = @unserialize($requestBody['sender']);
- if ($requestBody['sender'] === null) {
- return false;
- }
- if (strcasecmp(get_class($requestBody['sender']), $requestBody['className']) != 0) {
- return false;
- }
- if ( ! XOAD_Server::notifyObservers('initializeCallbackSuccess', array('request' => &$requestBody))) {
- return false;
- }
- $GLOBALS['_XOAD_SERVER_REQUEST_BODY'] =& $requestBody;
- if (XOAD_Server::notifyObservers('initializeCallbackLeave', array('request' => &$requestBody))) {
- return true;
- }
- } else if (
- isset($requestBody['eventsCallback']) &&
- isset($requestBody['time']) &&
- isset($requestBody['data'])) {
- if (
- (XOAD_Utilities::getType($requestBody['eventsCallback']) != 'bool') ||
- (XOAD_Utilities::getType($requestBody['time']) != 'float') ||
- (XOAD_Utilities::getType($requestBody['data']) != 's_array')) {
- return false;
- }
- foreach ($requestBody['data'] as $eventData) {
- if ( ! empty($eventData['className'])) {
- XOAD_Server::loadClass($eventData['className']);
- } else {
- return false;
- }
- if ( ! XOAD_Server::isClassAllowed($eventData['className'])) {
- return false;
- }
- }
- if ( ! XOAD_Server::notifyObservers('initializeCallbackSuccess', array('request' => &$requestBody))) {
- return false;
- }
- $GLOBALS['_XOAD_SERVER_REQUEST_BODY'] =& $requestBody;
- if (XOAD_Server::notifyObservers('initializeCallbackLeave', array('request' => &$requestBody))) {
- return true;
- }
- } else {
- if (
- ( ! isset($requestBody['source'])) ||
- ( ! isset($requestBody['className'])) ||
- ( ! isset($requestBody['method'])) ||
- ( ! isset($requestBody['arguments']))) {
- return false;
- }
- if ( ! empty($requestBody['className'])) {
- XOAD_Server::loadClass($requestBody['className']);
- }
- $requestBody['source'] = @unserialize($requestBody['source']);
- $requestBody['arguments'] = @unserialize($requestBody['arguments']);
- if (
- ($requestBody['source'] === null) ||
- ($requestBody['className'] === null) ||
- ($requestBody['arguments'] === null)) {
- return false;
- }
- if (
- (XOAD_Utilities::getType($requestBody['source']) != 'object') ||
- (XOAD_Utilities::getType($requestBody['className']) != 'string') ||
- (XOAD_Utilities::getType($requestBody['method']) != 'string') ||
- (XOAD_Utilities::getType($requestBody['arguments']) != 's_array')) {
- return false;
- }
- if (strcasecmp($requestBody['className'], get_class($requestBody['source'])) != 0) {
- return false;
- }
- if ( ! XOAD_Server::isClassAllowed($requestBody['className'])) {
- return false;
- }
- if (method_exists($requestBody['source'], XOAD_CLIENT_METADATA_METHOD_NAME)) {
- call_user_func_array(array(&$requestBody['source'], XOAD_CLIENT_METADATA_METHOD_NAME), null);
- if (isset($requestBody['source']->xoadMeta)) {
- if (XOAD_Utilities::getType($requestBody['source']->xoadMeta) == 'object') {
- if (strcasecmp(get_class($requestBody['source']->xoadMeta), 'XOAD_Meta') == 0) {
- if ( ! $requestBody['source']->xoadMeta->isPublicMethod($requestBody['method'])) {
- return false;
- }
- }
- }
- }
- }
- if ( ! XOAD_Server::notifyObservers('initializeCallbackSuccess', array('request' => &$requestBody))) {
- return false;
- }
- $GLOBALS['_XOAD_SERVER_REQUEST_BODY'] =& $requestBody;
- if (XOAD_Server::notifyObservers('initializeCallbackLeave', array('request' => &$requestBody))) {
- return true;
- }
- }
- }
- }
- XOAD_Server::notifyObservers('initializeCallbackLeave');
- return false;
- }
- /**
- * Dispatches a client callback to the server.
- *
- * @access public
- *
- * @return string Outputs JavaString code that contains the result
- * and the output of the callback.
- *
- * @static
- *
- */
- function dispatch()
- {
- if (empty($GLOBALS['_XOAD_SERVER_REQUEST_BODY'])) {
- return false;
- }
- $requestBody =& $GLOBALS['_XOAD_SERVER_REQUEST_BODY'];
- if ( ! XOAD_Server::notifyObservers('dispatchEnter', array('request' => &$requestBody))) {
- return false;
- }
- if (isset($requestBody['eventPost'])) {
- $callbackResponse = array();
- $storage =& XOAD_Events_Storage::getStorage();
- $callbackResponse['status'] = $storage->postEvent($requestBody['event'], $requestBody['className'], $requestBody['sender'], $requestBody['data'], $requestBody['filter']);
- if (XOAD_Server::notifyObservers('dispatchLeave', array('request' => &$requestBody, 'response' => &$callbackResponse))) {
- if ( ! empty($callbackResponse['status'])) {
- print XOAD_Client::register($callbackResponse);
- }
- }
- } else if (isset($requestBody['eventsCallback'])) {
- $eventsQuery = array();
- foreach ($requestBody['data'] as $event) {
- $eventsQuery[] = array(
- 'event' => $event['event'],
- 'className' => $event['className'],
- 'filter' => $event['filter'],
- 'time' => $requestBody['time']
- );
- }
- $callbackResponse = array();
- $storage =& XOAD_Events_Storage::getStorage();
- $storage->cleanEvents();
- $callbackResponse['result'] = $storage->filterMultipleEvents($eventsQuery);
- if (XOAD_Server::notifyObservers('dispatchLeave', array('request' => &$requestBody, 'response' => &$callbackResponse))) {
- if ( ! empty($callbackResponse['result'])) {
- print XOAD_Client::register($callbackResponse);
- }
- }
- } else {
- $callbackResponse = array();
- $outputBuffering = @ob_start();
- set_error_handler(array('XOAD_Server', 'handleError'));
- $callbackResponse['returnValue'] = call_user_func_array(array(&$requestBody['source'], $requestBody['method']), $requestBody['arguments']);
- if (defined('XOAD_SERVER_EXCEPTION')) {
- if (XOAD_Server::notifyObservers('dispatchFailed', array('request' => &$requestBody, 'message' => XOAD_SERVER_EXCEPTION))) {
- XOAD_Server::throwException(XOAD_SERVER_EXCEPTION);
- return false;
- }
- }
- $callbackResponse['returnObject'] =& $requestBody['source'];
- if ($outputBuffering) {
- $output = @ob_get_contents();
- if ( ! empty($output)) {
- $callbackResponse['output'] = $output;
- }
- @ob_end_clean();
- }
- restore_error_handler();
- if (XOAD_Server::notifyObservers('dispatchLeave', array('request' => &$requestBody, 'response' => &$callbackResponse))) {
- print XOAD_Client::register($callbackResponse);
- }
- }
- }
- /**
- * Handles all errors that occur during the callback.
- *
- * <p>Only E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR and E_USER_ERROR
- * will halt the callback and throw an exception.</p>
- *
- * @access protected
- *
- * @param int $type Error type (compile, core, user...).
- *
- * @param string $message Error message.
- *
- * @return void
- *
- * @static
- *
- */
- function handleError($type, $message)
- {
- if (error_reporting()) {
- if ( ! XOAD_Server::notifyObservers('handleErrorEnter', array('type' => &$type, 'message' => &$message))) {
- return false;
- }
- $breakLevel = E_ERROR | E_PARSE | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR;
- if (($type & $breakLevel) > 0) {
- if ( ! defined('XOAD_SERVER_EXCEPTION')) {
- /**
- * Defines the error message that caused the callback to halt.
- */
- define('XOAD_SERVER_EXCEPTION', $message);
- }
- }
- }
- XOAD_Server::notifyObservers('handleErrorLeave', array('type' => &$type, 'message' => &$message));
- }
- /**
- * Throws a XOAD callback exception.
- *
- * @access protected
- *
- * @param string $message Exception message.
- *
- * @return string Outputs JavaString code that contains the
- * exception message.
- *
- * @static
- *
- */
- function throwException($message)
- {
- if ( ! XOAD_Server::notifyObservers('throwExceptionEnter', array('message' => &$message))) {
- return false;
- }
- restore_error_handler();
- $callbackException = array();
- $callbackException['exception'] = $message;
- if (XOAD_Server::notifyObservers('throwExceptionLeave', array('message' => &$message))) {
- print XOAD_Client::register($callbackException);
- }
- }
- /**
- * Adds a specified class to the classes map.
- *
- * <p>Example:</p>
- * <code>
- * <?php
- *
- * require_once('xoad.php');
- *
- * XOAD_Server::mapClass('Calculator', 'Calculator.class.php');
- *
- * XOAD_Server::mapClass('EnglishDictionary', array('BaseDictionary.class.php', 'EnglishDictionary.class.php'));
- *
- * XOAD_Server::runServer();
- *
- * ?>
- * </code>
- *
- * @access public
- *
- * @param string $className The class name to add.
- *
- * @param mixed $files The files that are required
- * to load the class.
- *
- * @return void
- *
- * @static
- *
- */
- function mapClass($className, $files)
- {
- if ( ! isset($GLOBALS['_XOAD_SERVER_CLASSES_MAP'])) {
- $GLOBALS['_XOAD_SERVER_CLASSES_MAP'] = array();
- }
- $GLOBALS['_XOAD_SERVER_CLASSES_MAP'][strtolower($className)] = $files;
- }
- /**
- * Loads a specified class from the classes map.
- *
- * @access public
- *
- * @param string $className The class name to load. Note that all files
- * that are included in the class map will be
- * loaded.
- *
- * @return void
- *
- * @static
- *
- */
- function loadClass($className)
- {
- $className = strtolower($className);
- if ( ! empty($GLOBALS['_XOAD_SERVER_CLASSES_MAP'])) {
- if (isset($GLOBALS['_XOAD_SERVER_CLASSES_MAP'][$className])) {
- $files = $GLOBALS['_XOAD_SERVER_CLASSES_MAP'][$className];
- $filesType = XOAD_Utilities::getType($files);
- if ($filesType == 'string') {
- require_once($files);
- } else if (
- ($filesType == 's_array') ||
- ($filesType == 'a_array')) {
- foreach ($files as $fileName) {
- require_once($fileName);
- }
- }
- }
- }
- }
- /**
- * Adds specified classes to the allowed classes map.
- *
- * <p>Example:</p>
- * <code>
- * <?php
- *
- * class AllowedClass
- * {
- * function call() { return 'AllowedClass->call()'; }
- * }
- *
- * class DeniedClass
- * {
- * function call() { return 'DeniedClass->call()'; }
- * }
- *
- * require_once('xoad.php');
- *
- * XOAD_Server::allowClasses('AllowedClass');
- *
- * if (XOAD_Server::runServer()) {
- *
- * exit;
- * }
- *
- * ?>
- * <?= XOAD_Utilities::header() ?>
- *
- * <script type="text/javascript">
- *
- * var allowedClass = <?= XOAD_Client::register(new AllowedClass()) ?>;
- *
- * var deniedClass = <?= XOAD_Client::register(new DeniedClass()) ?>;
- *
- * alert(allowedClass.call());
- *
- * // This line will throw an exception.
- * // DeniedClass is not in the allowed classes list.
- * alert(deniedClass.call());
- *
- * </script>
- * </code>
- *
- * @access public
- *
- * @param mixed $classes The classes that can be accessed within
- * a callback request.
- *
- * @return void
- *
- * @static
- *
- */
- function allowClasses($classes)
- {
- $classesType = XOAD_Utilities::getType($classes);
- if ( ! isset($GLOBALS['_XOAD_SERVER_ALLOWED_CLASSES'])) {
- $GLOBALS['_XOAD_SERVER_ALLOWED_CLASSES'] = array();
- }
- $allowedClasses =& $GLOBALS['_XOAD_SERVER_ALLOWED_CLASSES'];
- if ($classesType == 'string') {
- $allowedClasses[] = strtolower($classes);
- } else if (($classesType == 's_array') || ($classesType == 'a_array')) {
- foreach ($classes as $class) {
- $allowedClasses[] = strtolower($class);
- }
- }
- }
- /**
- * Adds specified classes to the denied classes map.
- *
- * <p>Example:</p>
- * <code>
- * <?php
- *
- * class AllowedClass
- * {
- * function call() { return 'AllowedClass->call()'; }
- * }
- *
- * class DeniedClass
- * {
- * function call() { return 'DeniedClass->call()'; }
- * }
- *
- * require_once('xoad.php');
- *
- * XOAD_Server::denyClasses('DeniedClass');
- *
- * if (XOAD_Server::runServer()) {
- *
- * exit;
- * }
- *
- * ?>
- * <?= XOAD_Utilities::header() ?>
- *
- * <script type="text/javascript">
- *
- * var allowedClass = <?= XOAD_Client::register(new AllowedClass()) ?>;
- *
- * var deniedClass = <?= XOAD_Client::register(new DeniedClass()) ?>;
- *
- * alert(allowedClass.call());
- *
- * // This line will throw an exception.
- * // DeniedClass is in the denied classes list.
- * alert(deniedClass.call());
- *
- * </script>
- * </code>
- *
- * @access public
- *
- * @param mixed $classes The classes that can NOT be accessed
- * within a callback request.
- *
- * @return void
- *
- * @static
- *
- */
- function denyClasses($classes)
- {
- $classesType = XOAD_Utilities::getType($classes);
- if ( ! isset($GLOBALS['_XOAD_SERVER_DENIED_CLASSES'])) {
- $GLOBALS['_XOAD_SERVER_DENIED_CLASSES'] = array();
- }
- $deniedClasses =& $GLOBALS['_XOAD_SERVER_DENIED_CLASSES'];
- if ($classesType == 'string') {
- $deniedClasses[] = strtolower($classes);
- } else if (($classesType == 's_array') || ($classesType == 'a_array')) {
- foreach ($classes as $class) {
- $deniedClasses[] = strtolower($class);
- }
- }
- }
- /**
- * Checks if a class can be accessed within a callback request.
- *
- * @access public
- *
- * @param string $class The class name to check.
- *
- * @return bool true if the class can be accessed, false if
- * the class is denied and can NOT be accessed.
- *
- * @static
- *
- */
- function isClassAllowed($class)
- {
- $allowedClasses = null;
- $deniedClasses = null;
- if (isset($GLOBALS['_XOAD_SERVER_ALLOWED_CLASSES'])) {
- $allowedClasses =& $GLOBALS['_XOAD_SERVER_ALLOWED_CLASSES'];
- }
- if (isset($GLOBALS['_XOAD_SERVER_DENIED_CLASSES'])) {
- $deniedClasses =& $GLOBALS['_XOAD_SERVER_DENIED_CLASSES'];
- }
- if ( ! empty($deniedClasses)) {
- if (in_array(strtolower($class), $deniedClasses)) {
- return false;
- }
- }
- if ( ! empty($allowedClasses)) {
- if ( ! in_array(strtolower($class), $allowedClasses)) {
- return false;
- }
- }
- return true;
- }
- /**
- * Adds a {@link XOAD_Server} events observer.
- *
- * @access public
- *
- * @param mixed $observer The observer object to add (must extend {@link XOAD_Observer}).
- *
- * @return string true on success, false otherwise.
- *
- * @static
- *
- */
- function addObserver(&$observer)
- {
- return parent::addObserver($observer, 'XOAD_Server');
- }
- /**
- *
- * @access public
- *
- * @return bool
- *
- */
- function notifyObservers($event = 'default', $arg = null)
- {
- return parent::notifyObservers($event, $arg, 'XOAD_Server');
- }
- }
- ?>
Documentation generated on Sat, 12 Nov 2005 20:24:42 +0200 by phpDocumentor 1.3.0RC3