[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

/vendor/kissifrot/php-ixr/src/Server/ -> IntrospectionServer.php (source)

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