[ Index ] |
PHP Cross Reference of moodle-2.8 |
[Summary view] [Print] [Text view]
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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:29:05 2014 | Cross-referenced by PHPXref 0.7.1 |