You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

175 lines
5.2 KiB

  1. <?php
  2. /**
  3. * IXR_IntrospectionServer
  4. *
  5. * @package IXR
  6. * @since 1.5.0
  7. */
  8. class IXR_IntrospectionServer extends IXR_Server
  9. {
  10. var $signatures;
  11. var $help;
  12. /**
  13. * PHP5 constructor.
  14. */
  15. function __construct()
  16. {
  17. $this->setCallbacks();
  18. $this->setCapabilities();
  19. $this->capabilities['introspection'] = array(
  20. 'specUrl' => 'http://xmlrpc.usefulinc.com/doc/reserved.html',
  21. 'specVersion' => 1
  22. );
  23. $this->addCallback(
  24. 'system.methodSignature',
  25. 'this:methodSignature',
  26. array('array', 'string'),
  27. 'Returns an array describing the return type and required parameters of a method'
  28. );
  29. $this->addCallback(
  30. 'system.getCapabilities',
  31. 'this:getCapabilities',
  32. array('struct'),
  33. 'Returns a struct describing the XML-RPC specifications supported by this server'
  34. );
  35. $this->addCallback(
  36. 'system.listMethods',
  37. 'this:listMethods',
  38. array('array'),
  39. 'Returns an array of available methods on this server'
  40. );
  41. $this->addCallback(
  42. 'system.methodHelp',
  43. 'this:methodHelp',
  44. array('string', 'string'),
  45. 'Returns a documentation string for the specified method'
  46. );
  47. }
  48. /**
  49. * PHP4 constructor.
  50. */
  51. public function IXR_IntrospectionServer() {
  52. self::__construct();
  53. }
  54. function addCallback($method, $callback, $args, $help)
  55. {
  56. $this->callbacks[$method] = $callback;
  57. $this->signatures[$method] = $args;
  58. $this->help[$method] = $help;
  59. }
  60. function call($methodname, $args)
  61. {
  62. // Make sure it's in an array
  63. if ($args && !is_array($args)) {
  64. $args = array($args);
  65. }
  66. // Over-rides default call method, adds signature check
  67. if (!$this->hasMethod($methodname)) {
  68. return new IXR_Error(-32601, 'server error. requested method "'.$this->message->methodName.'" not specified.');
  69. }
  70. $method = $this->callbacks[$methodname];
  71. $signature = $this->signatures[$methodname];
  72. $returnType = array_shift($signature);
  73. // Check the number of arguments
  74. if (count($args) != count($signature)) {
  75. return new IXR_Error(-32602, 'server error. wrong number of method parameters');
  76. }
  77. // Check the argument types
  78. $ok = true;
  79. $argsbackup = $args;
  80. for ($i = 0, $j = count($args); $i < $j; $i++) {
  81. $arg = array_shift($args);
  82. $type = array_shift($signature);
  83. switch ($type) {
  84. case 'int':
  85. case 'i4':
  86. if (is_array($arg) || !is_int($arg)) {
  87. $ok = false;
  88. }
  89. break;
  90. case 'base64':
  91. case 'string':
  92. if (!is_string($arg)) {
  93. $ok = false;
  94. }
  95. break;
  96. case 'boolean':
  97. if ($arg !== false && $arg !== true) {
  98. $ok = false;
  99. }
  100. break;
  101. case 'float':
  102. case 'double':
  103. if (!is_float($arg)) {
  104. $ok = false;
  105. }
  106. break;
  107. case 'date':
  108. case 'dateTime.iso8601':
  109. if (!is_a($arg, 'IXR_Date')) {
  110. $ok = false;
  111. }
  112. break;
  113. }
  114. if (!$ok) {
  115. return new IXR_Error(-32602, 'server error. invalid method parameters');
  116. }
  117. }
  118. // It passed the test - run the "real" method call
  119. return parent::call($methodname, $argsbackup);
  120. }
  121. function methodSignature($method)
  122. {
  123. if (!$this->hasMethod($method)) {
  124. return new IXR_Error(-32601, 'server error. requested method "'.$method.'" not specified.');
  125. }
  126. // We should be returning an array of types
  127. $types = $this->signatures[$method];
  128. $return = array();
  129. foreach ($types as $type) {
  130. switch ($type) {
  131. case 'string':
  132. $return[] = 'string';
  133. break;
  134. case 'int':
  135. case 'i4':
  136. $return[] = 42;
  137. break;
  138. case 'double':
  139. $return[] = 3.1415;
  140. break;
  141. case 'dateTime.iso8601':
  142. $return[] = new IXR_Date(time());
  143. break;
  144. case 'boolean':
  145. $return[] = true;
  146. break;
  147. case 'base64':
  148. $return[] = new IXR_Base64('base64');
  149. break;
  150. case 'array':
  151. $return[] = array('array');
  152. break;
  153. case 'struct':
  154. $return[] = array('struct' => 'struct');
  155. break;
  156. }
  157. }
  158. return $return;
  159. }
  160. function methodHelp($method)
  161. {
  162. return $this->help[$method];
  163. }
  164. }