[ Index ]

PHP Cross Reference of moodle-2.8

title

Body

[close]

/lib/zend/Zend/XmlRpc/ -> Server.php (source)

   1  <?php
   2  /**
   3   * Zend Framework
   4   *
   5   * LICENSE
   6   *
   7   * This source file is subject to the new BSD license that is bundled
   8   * with this package in the file LICENSE.txt.
   9   * It is also available through the world-wide-web at this URL:
  10   * http://framework.zend.com/license/new-bsd
  11   * If you did not receive a copy of the license and are unable to
  12   * obtain it through the world-wide-web, please send an email
  13   * to [email protected] so we can send you a copy immediately.
  14   *
  15   * @category   Zend
  16   * @package    Zend_XmlRpc
  17   * @subpackage Server
  18   * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
  19   * @license    http://framework.zend.com/license/new-bsd     New BSD License
  20   * @version    $Id$
  21   */
  22  
  23  /**
  24   * Extends Zend_Server_Abstract
  25   */
  26  require_once 'Zend/Server/Abstract.php';
  27  
  28  /**
  29   * XMLRPC Request
  30   */
  31  require_once 'Zend/XmlRpc/Request.php';
  32  
  33  /**
  34   * XMLRPC Response
  35   */
  36  require_once 'Zend/XmlRpc/Response.php';
  37  
  38  /**
  39   * XMLRPC HTTP Response
  40   */
  41  require_once 'Zend/XmlRpc/Response/Http.php';
  42  
  43  /**
  44   * XMLRPC server fault class
  45   */
  46  require_once 'Zend/XmlRpc/Server/Fault.php';
  47  
  48  /**
  49   * XMLRPC server system methods class
  50   */
  51  require_once 'Zend/XmlRpc/Server/System.php';
  52  
  53  /**
  54   * Convert PHP to and from xmlrpc native types
  55   */
  56  require_once 'Zend/XmlRpc/Value.php';
  57  
  58  /**
  59   * Reflection API for function/method introspection
  60   */
  61  require_once 'Zend/Server/Reflection.php';
  62  
  63  /**
  64   * Zend_Server_Reflection_Function_Abstract
  65   */
  66  require_once 'Zend/Server/Reflection/Function/Abstract.php';
  67  
  68  /**
  69   * Specifically grab the Zend_Server_Reflection_Method for manually setting up
  70   * system.* methods and handling callbacks in {@link loadFunctions()}.
  71   */
  72  require_once 'Zend/Server/Reflection/Method.php';
  73  
  74  /**
  75   * An XML-RPC server implementation
  76   *
  77   * Example:
  78   * <code>
  79   * require_once 'Zend/XmlRpc/Server.php';
  80   * require_once 'Zend/XmlRpc/Server/Cache.php';
  81   * require_once 'Zend/XmlRpc/Server/Fault.php';
  82   * require_once 'My/Exception.php';
  83   * require_once 'My/Fault/Observer.php';
  84   *
  85   * // Instantiate server
  86   * $server = new Zend_XmlRpc_Server();
  87   *
  88   * // Allow some exceptions to report as fault responses:
  89   * Zend_XmlRpc_Server_Fault::attachFaultException('My_Exception');
  90   * Zend_XmlRpc_Server_Fault::attachObserver('My_Fault_Observer');
  91   *
  92   * // Get or build dispatch table:
  93   * if (!Zend_XmlRpc_Server_Cache::get($filename, $server)) {
  94   *     require_once 'Some/Service/Class.php';
  95   *     require_once 'Another/Service/Class.php';
  96   *
  97   *     // Attach Some_Service_Class in 'some' namespace
  98   *     $server->setClass('Some_Service_Class', 'some');
  99   *
 100   *     // Attach Another_Service_Class in 'another' namespace
 101   *     $server->setClass('Another_Service_Class', 'another');
 102   *
 103   *     // Create dispatch table cache file
 104   *     Zend_XmlRpc_Server_Cache::save($filename, $server);
 105   * }
 106   *
 107   * $response = $server->handle();
 108   * echo $response;
 109   * </code>
 110   *
 111   * @category   Zend
 112   * @package    Zend_XmlRpc
 113   * @subpackage Server
 114   * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
 115   * @license    http://framework.zend.com/license/new-bsd     New BSD License
 116   */
 117  class Zend_XmlRpc_Server extends Zend_Server_Abstract
 118  {
 119      /**
 120       * Character encoding
 121       * @var string
 122       */
 123      protected $_encoding = 'UTF-8';
 124  
 125      /**
 126       * Request processed
 127       * @var null|Zend_XmlRpc_Request
 128       */
 129      protected $_request = null;
 130  
 131      /**
 132       * Class to use for responses; defaults to {@link Zend_XmlRpc_Response_Http}
 133       * @var string
 134       */
 135      protected $_responseClass = 'Zend_XmlRpc_Response_Http';
 136  
 137      /**
 138       * Dispatch table of name => method pairs
 139       * @var Zend_Server_Definition
 140       */
 141      protected $_table;
 142  
 143      /**
 144       * PHP types => XML-RPC types
 145       * @var array
 146       */
 147      protected $_typeMap = array(
 148          'i4'                         => 'i4',
 149          'int'                        => 'int',
 150          'integer'                    => 'int',
 151          'Zend_Crypt_Math_BigInteger' => 'i8',
 152          'i8'                         => 'i8',
 153          'ex:i8'                      => 'i8',
 154          'double'                     => 'double',
 155          'float'                      => 'double',
 156          'real'                       => 'double',
 157          'boolean'                    => 'boolean',
 158          'bool'                       => 'boolean',
 159          'true'                       => 'boolean',
 160          'false'                      => 'boolean',
 161          'string'                     => 'string',
 162          'str'                        => 'string',
 163          'base64'                     => 'base64',
 164          'dateTime.iso8601'           => 'dateTime.iso8601',
 165          'date'                       => 'dateTime.iso8601',
 166          'time'                       => 'dateTime.iso8601',
 167          'time'                       => 'dateTime.iso8601',
 168          'Zend_Date'                  => 'dateTime.iso8601',
 169          'DateTime'                   => 'dateTime.iso8601',
 170          'array'                      => 'array',
 171          'struct'                     => 'struct',
 172          'null'                       => 'nil',
 173          'nil'                        => 'nil',
 174          'ex:nil'                     => 'nil',
 175          'void'                       => 'void',
 176          'mixed'                      => 'struct',
 177      );
 178  
 179      /**
 180       * Send arguments to all methods or just constructor?
 181       *
 182       * @var bool
 183       */
 184      protected $_sendArgumentsToAllMethods = true;
 185  
 186      /**
 187       * Constructor
 188       *
 189       * Creates system.* methods.
 190       *
 191       * @return void
 192       */
 193      public function __construct()
 194      {
 195          $this->_table = new Zend_Server_Definition();
 196          $this->_registerSystemMethods();
 197      }
 198  
 199      /**
 200       * Proxy calls to system object
 201       *
 202       * @param  string $method
 203       * @param  array $params
 204       * @return mixed
 205       * @throws Zend_XmlRpc_Server_Exception
 206       */
 207      public function __call($method, $params)
 208      {
 209          $system = $this->getSystem();
 210          if (!method_exists($system, $method)) {
 211              require_once 'Zend/XmlRpc/Server/Exception.php';
 212              throw new Zend_XmlRpc_Server_Exception('Unknown instance method called on server: ' . $method);
 213          }
 214          return call_user_func_array(array($system, $method), $params);
 215      }
 216  
 217      /**
 218       * Attach a callback as an XMLRPC method
 219       *
 220       * Attaches a callback as an XMLRPC method, prefixing the XMLRPC method name
 221       * with $namespace, if provided. Reflection is done on the callback's
 222       * docblock to create the methodHelp for the XMLRPC method.
 223       *
 224       * Additional arguments to pass to the function at dispatch may be passed;
 225       * any arguments following the namespace will be aggregated and passed at
 226       * dispatch time.
 227       *
 228       * @param string|array $function Valid callback
 229       * @param string $namespace Optional namespace prefix
 230       * @return void
 231       * @throws Zend_XmlRpc_Server_Exception
 232       */
 233      public function addFunction($function, $namespace = '')
 234      {
 235          if (!is_string($function) && !is_array($function)) {
 236              require_once 'Zend/XmlRpc/Server/Exception.php';
 237              throw new Zend_XmlRpc_Server_Exception('Unable to attach function; invalid', 611);
 238          }
 239  
 240          $argv = null;
 241          if (2 < func_num_args()) {
 242              $argv = func_get_args();
 243              $argv = array_slice($argv, 2);
 244          }
 245  
 246          $function = (array) $function;
 247          foreach ($function as $func) {
 248              if (!is_string($func) || !function_exists($func)) {
 249                  require_once 'Zend/XmlRpc/Server/Exception.php';
 250                  throw new Zend_XmlRpc_Server_Exception('Unable to attach function; invalid', 611);
 251              }
 252              $reflection = Zend_Server_Reflection::reflectFunction($func, $argv, $namespace);
 253              $this->_buildSignature($reflection);
 254          }
 255      }
 256  
 257      /**
 258       * Attach class methods as XMLRPC method handlers
 259       *
 260       * $class may be either a class name or an object. Reflection is done on the
 261       * class or object to determine the available public methods, and each is
 262       * attached to the server as an available method; if a $namespace has been
 263       * provided, that namespace is used to prefix the XMLRPC method names.
 264       *
 265       * Any additional arguments beyond $namespace will be passed to a method at
 266       * invocation.
 267       *
 268       * @param string|object $class
 269       * @param string $namespace Optional
 270       * @param mixed $argv Optional arguments to pass to methods
 271       * @return void
 272       * @throws Zend_XmlRpc_Server_Exception on invalid input
 273       */
 274      public function setClass($class, $namespace = '', $argv = null)
 275      {
 276          if (is_string($class) && !class_exists($class)) {
 277              require_once 'Zend/XmlRpc/Server/Exception.php';
 278              throw new Zend_XmlRpc_Server_Exception('Invalid method class', 610);
 279          }
 280  
 281          $argv = null;
 282          if (2 < func_num_args()) {
 283              $argv = func_get_args();
 284              $argv = array_slice($argv, 2);
 285          }
 286  
 287          $dispatchable = Zend_Server_Reflection::reflectClass($class, $argv, $namespace);
 288          foreach ($dispatchable->getMethods() as $reflection) {
 289              $this->_buildSignature($reflection, $class);
 290          }
 291      }
 292  
 293      /**
 294       * Raise an xmlrpc server fault
 295       *
 296       * @param string|Exception $fault
 297       * @param int $code
 298       * @return Zend_XmlRpc_Server_Fault
 299       */
 300      public function fault($fault = null, $code = 404)
 301      {
 302          if (!$fault instanceof Exception) {
 303              $fault = (string) $fault;
 304              if (empty($fault)) {
 305                  $fault = 'Unknown Error';
 306              }
 307              require_once 'Zend/XmlRpc/Server/Exception.php';
 308              $fault = new Zend_XmlRpc_Server_Exception($fault, $code);
 309          }
 310  
 311          return Zend_XmlRpc_Server_Fault::getInstance($fault);
 312      }
 313  
 314      /**
 315       * Handle an xmlrpc call
 316       *
 317       * @param Zend_XmlRpc_Request $request Optional
 318       * @return Zend_XmlRpc_Response|Zend_XmlRpc_Fault
 319       */
 320      public function handle($request = false)
 321      {
 322          // Get request
 323          if ((!$request || !$request instanceof Zend_XmlRpc_Request)
 324              && (null === ($request = $this->getRequest()))
 325          ) {
 326              require_once 'Zend/XmlRpc/Request/Http.php';
 327              $request = new Zend_XmlRpc_Request_Http();
 328              $request->setEncoding($this->getEncoding());
 329          }
 330  
 331          $this->setRequest($request);
 332  
 333          if ($request->isFault()) {
 334              $response = $request->getFault();
 335          } else {
 336              try {
 337                  $response = $this->_handle($request);
 338              } catch (Exception $e) {
 339                  $response = $this->fault($e);
 340              }
 341          }
 342  
 343          // Set output encoding
 344          $response->setEncoding($this->getEncoding());
 345  
 346          return $response;
 347      }
 348  
 349      /**
 350       * Load methods as returned from {@link getFunctions}
 351       *
 352       * Typically, you will not use this method; it will be called using the
 353       * results pulled from {@link Zend_XmlRpc_Server_Cache::get()}.
 354       *
 355       * @param  array|Zend_Server_Definition $definition
 356       * @return void
 357       * @throws Zend_XmlRpc_Server_Exception on invalid input
 358       */
 359      public function loadFunctions($definition)
 360      {
 361          if (!is_array($definition) && (!$definition instanceof Zend_Server_Definition)) {
 362              if (is_object($definition)) {
 363                  $type = get_class($definition);
 364              } else {
 365                  $type = gettype($definition);
 366              }
 367              require_once 'Zend/XmlRpc/Server/Exception.php';
 368              throw new Zend_XmlRpc_Server_Exception('Unable to load server definition; must be an array or Zend_Server_Definition, received ' . $type, 612);
 369          }
 370  
 371          $this->_table->clearMethods();
 372          $this->_registerSystemMethods();
 373  
 374          if ($definition instanceof Zend_Server_Definition) {
 375              $definition = $definition->getMethods();
 376          }
 377  
 378          foreach ($definition as $key => $method) {
 379              if ('system.' == substr($key, 0, 7)) {
 380                  continue;
 381              }
 382              $this->_table->addMethod($method, $key);
 383          }
 384      }
 385  
 386      /**
 387       * Set encoding
 388       *
 389       * @param string $encoding
 390       * @return Zend_XmlRpc_Server
 391       */
 392      public function setEncoding($encoding)
 393      {
 394          $this->_encoding = $encoding;
 395          Zend_XmlRpc_Value::setEncoding($encoding);
 396          return $this;
 397      }
 398  
 399      /**
 400       * Retrieve current encoding
 401       *
 402       * @return string
 403       */
 404      public function getEncoding()
 405      {
 406          return $this->_encoding;
 407      }
 408  
 409      /**
 410       * Do nothing; persistence is handled via {@link Zend_XmlRpc_Server_Cache}
 411       *
 412       * @param  mixed $mode
 413       * @return void
 414       */
 415      public function setPersistence($mode)
 416      {
 417      }
 418  
 419      /**
 420       * Set the request object
 421       *
 422       * @param string|Zend_XmlRpc_Request $request
 423       * @return Zend_XmlRpc_Server
 424       * @throws Zend_XmlRpc_Server_Exception on invalid request class or object
 425       */
 426      public function setRequest($request)
 427      {
 428          if (is_string($request) && class_exists($request)) {
 429              $request = new $request();
 430              if (!$request instanceof Zend_XmlRpc_Request) {
 431                  require_once 'Zend/XmlRpc/Server/Exception.php';
 432                  throw new Zend_XmlRpc_Server_Exception('Invalid request class');
 433              }
 434              $request->setEncoding($this->getEncoding());
 435          } elseif (!$request instanceof Zend_XmlRpc_Request) {
 436              require_once 'Zend/XmlRpc/Server/Exception.php';
 437              throw new Zend_XmlRpc_Server_Exception('Invalid request object');
 438          }
 439  
 440          $this->_request = $request;
 441          return $this;
 442      }
 443  
 444      /**
 445       * Return currently registered request object
 446       *
 447       * @return null|Zend_XmlRpc_Request
 448       */
 449      public function getRequest()
 450      {
 451          return $this->_request;
 452      }
 453  
 454      /**
 455       * Set the class to use for the response
 456       *
 457       * @param string $class
 458       * @return boolean True if class was set, false if not
 459       */
 460      public function setResponseClass($class)
 461      {
 462          if (!class_exists($class) or
 463              ($c = new ReflectionClass($class) and !$c->isSubclassOf('Zend_XmlRpc_Response'))) {
 464  
 465              require_once 'Zend/XmlRpc/Server/Exception.php';
 466              throw new Zend_XmlRpc_Server_Exception('Invalid response class');
 467          }
 468          $this->_responseClass = $class;
 469          return true;
 470      }
 471  
 472      /**
 473       * Retrieve current response class
 474       *
 475       * @return string
 476       */
 477      public function getResponseClass()
 478      {
 479          return $this->_responseClass;
 480      }
 481  
 482      /**
 483       * Retrieve dispatch table
 484       *
 485       * @return array
 486       */
 487      public function getDispatchTable()
 488      {
 489          return $this->_table;
 490      }
 491  
 492      /**
 493       * Returns a list of registered methods
 494       *
 495       * Returns an array of dispatchables (Zend_Server_Reflection_Function,
 496       * _Method, and _Class items).
 497       *
 498       * @return array
 499       */
 500      public function getFunctions()
 501      {
 502          return $this->_table->toArray();
 503      }
 504  
 505      /**
 506       * Retrieve system object
 507       *
 508       * @return Zend_XmlRpc_Server_System
 509       */
 510      public function getSystem()
 511      {
 512          return $this->_system;
 513      }
 514  
 515      /**
 516       * Send arguments to all methods?
 517       *
 518       * If setClass() is used to add classes to the server, this flag defined
 519       * how to handle arguments. If set to true, all methods including constructor
 520       * will receive the arguments. If set to false, only constructor will receive the
 521       * arguments
 522       */
 523      public function sendArgumentsToAllMethods($flag = null)
 524      {
 525          if ($flag === null) {
 526              return $this->_sendArgumentsToAllMethods;
 527          }
 528  
 529          $this->_sendArgumentsToAllMethods = (bool)$flag;
 530          return $this;
 531      }
 532  
 533      /**
 534       * Map PHP type to XML-RPC type
 535       *
 536       * @param  string $type
 537       * @return string
 538       */
 539      protected function _fixType($type)
 540      {
 541          if (isset($this->_typeMap[$type])) {
 542              return $this->_typeMap[$type];
 543          }
 544          return 'void';
 545      }
 546  
 547      /**
 548       * Handle an xmlrpc call (actual work)
 549       *
 550       * @param Zend_XmlRpc_Request $request
 551       * @return Zend_XmlRpc_Response
 552       * @throws Zend_XmlRpcServer_Exception|Exception
 553       * Zend_XmlRpcServer_Exceptions are thrown for internal errors; otherwise,
 554       * any other exception may be thrown by the callback
 555       */
 556      protected function _handle(Zend_XmlRpc_Request $request)
 557      {
 558          $method = $request->getMethod();
 559  
 560          // Check for valid method
 561          if (!$this->_table->hasMethod($method)) {
 562              require_once 'Zend/XmlRpc/Server/Exception.php';
 563              throw new Zend_XmlRpc_Server_Exception('Method "' . $method . '" does not exist', 620);
 564          }
 565  
 566          $info     = $this->_table->getMethod($method);
 567          $params   = $request->getParams();
 568          $argv     = $info->getInvokeArguments();
 569          if (0 < count($argv) and $this->sendArgumentsToAllMethods()) {
 570              $params = array_merge($params, $argv);
 571          }
 572  
 573          // Check calling parameters against signatures
 574          $matched    = false;
 575          $sigCalled  = $request->getTypes();
 576  
 577          $sigLength  = count($sigCalled);
 578          $paramsLen  = count($params);
 579          if ($sigLength < $paramsLen) {
 580              for ($i = $sigLength; $i < $paramsLen; ++$i) {
 581                  $xmlRpcValue = Zend_XmlRpc_Value::getXmlRpcValue($params[$i]);
 582                  $sigCalled[] = $xmlRpcValue->getType();
 583              }
 584          }
 585  
 586          $signatures = $info->getPrototypes();
 587          foreach ($signatures as $signature) {
 588              $sigParams = $signature->getParameters();
 589              if ($sigCalled === $sigParams) {
 590                  $matched = true;
 591                  break;
 592              }
 593          }
 594          if (!$matched) {
 595              require_once 'Zend/XmlRpc/Server/Exception.php';
 596              throw new Zend_XmlRpc_Server_Exception('Calling parameters do not match signature', 623);
 597          }
 598  
 599          $return        = $this->_dispatch($info, $params);
 600          $responseClass = $this->getResponseClass();
 601          return new $responseClass($return);
 602      }
 603  
 604      /**
 605       * Register system methods with the server
 606       *
 607       * @return void
 608       */
 609      protected function _registerSystemMethods()
 610      {
 611          $system = new Zend_XmlRpc_Server_System($this);
 612          $this->_system = $system;
 613          $this->setClass($system, 'system');
 614      }
 615  }


Generated: Fri Nov 28 20:29:05 2014 Cross-referenced by PHPXref 0.7.1