PageRenderTime 47ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/src/application/libraries/Zend/XmlRpc/Server.php

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