[ Index ]
 

Code source de Drupal 5.3

Accédez au Source d'autres logiciels libres

Classes | Fonctions | Variables | Constantes | Tables

title

Body

[fermer]

/includes/ -> xmlrpcs.inc (source)

   1  <?php
   2  // $Id: xmlrpcs.inc,v 1.21 2006/07/05 11:45:51 dries Exp $
   3  
   4  /**
   5   * The main entry point for XML-RPC requests.
   6   *
   7   * @param $callbacks
   8   *   Array of external XML-RPC method names with the callbacks they map to.
   9   */
  10  function xmlrpc_server($callbacks) {
  11    $xmlrpc_server = new stdClass();
  12    // Define built-in XML-RPC method names
  13    $defaults = array(
  14        'system.multicall' => 'xmlrpc_server_multicall',
  15      array(
  16        'system.methodSignature',
  17        'xmlrpc_server_method_signature',
  18        array('array', 'string'),
  19        'Returns an array describing the return type and required parameters of a method.'
  20      ),
  21      array(
  22        'system.getCapabilities',
  23        'xmlrpc_server_get_capabilities',
  24        array('struct'),
  25        'Returns a struct describing the XML-RPC specifications supported by this server.'
  26      ),
  27      array(
  28        'system.listMethods',
  29        'xmlrpc_server_list_methods',
  30        array('array'),
  31        'Returns an array of available methods on this server.'),
  32      array(
  33        'system.methodHelp',
  34        'xmlrpc_server_method_help',
  35        array('string', 'string'),
  36        'Returns a documentation string for the specified method.')
  37    );
  38    // We build an array of all method names by combining the built-ins
  39    // with those defined by modules implementing the _xmlrpc hook.
  40    // Built-in methods are overridable.
  41    foreach (array_merge($defaults, (array)$callbacks) as $key => $callback) {
  42      // we could check for is_array($callback)
  43      if (is_int($key)) {
  44        $method = $callback[0];
  45        $xmlrpc_server->callbacks[$method] = $callback[1];
  46        $xmlrpc_server->signatures[$method] = $callback[2];
  47        $xmlrpc_server->help[$method] = $callback[3];
  48      }
  49      else {
  50        $xmlrpc_server->callbacks[$key] = $callback;
  51        $xmlrpc_server->signatures[$key] = '';
  52        $xmlrpc_server->help[$key] = '';
  53      }
  54    }
  55  
  56    $data = file_get_contents('php://input');
  57    if (!$data) {
  58       die('XML-RPC server accepts POST requests only.');
  59    }
  60    $xmlrpc_server->message = xmlrpc_message($data);
  61    if (!xmlrpc_message_parse($xmlrpc_server->message)) {
  62      xmlrpc_server_error(-32700, t('Parse error. Request not well formed.'));
  63    }
  64    if ($xmlrpc_server->message->messagetype != 'methodCall') {
  65      xmlrpc_server_error(-32600, t('Server error. Invalid XML-RPC. Request must be a methodCall.'));
  66    }
  67    xmlrpc_server_set($xmlrpc_server);
  68    $result = xmlrpc_server_call($xmlrpc_server, $xmlrpc_server->message->methodname, $xmlrpc_server->message->params);
  69  
  70    if ($result->is_error) {
  71      xmlrpc_server_error($result);
  72    }
  73    // Encode the result
  74    $r = xmlrpc_value($result);
  75    // Create the XML
  76    $xml = '
  77  <methodResponse>
  78    <params>
  79    <param>
  80      <value>'.
  81      xmlrpc_value_get_xml($r)
  82      .'</value>
  83    </param>
  84    </params>
  85  </methodResponse>
  86  
  87  ';
  88    // Send it
  89    xmlrpc_server_output($xml);
  90  }
  91  
  92  /**
  93   * Throw an XML-RPC error.
  94   *
  95   * @param $error
  96   *   an error object OR integer error code
  97   * @param $message
  98   *   description of error, used only if integer error code was passed
  99   */
 100  function xmlrpc_server_error($error, $message = FALSE) {
 101    if ($message && !is_object($error)) {
 102      $error = xmlrpc_error($error, $message);
 103    }
 104    xmlrpc_server_output(xmlrpc_error_get_xml($error));
 105  }
 106  
 107  function xmlrpc_server_output($xml) {
 108    $xml = '<?xml version="1.0"?>'."\n". $xml;
 109    header('Connection: close');
 110    header('Content-Length: '. strlen($xml));
 111    header('Content-Type: text/xml');
 112    header('Date: '.date('r'));
 113    echo $xml;
 114    exit;
 115  }
 116  
 117  /**
 118   * Store a copy of the request temporarily.
 119   *
 120   * @param $xmlrpc_server
 121   *   Request object created by xmlrpc_server().
 122   */
 123  function xmlrpc_server_set($xmlrpc_server = NULL) {
 124    static $server;
 125    if (!isset($server)) {
 126      $server = $xmlrpc_server;
 127    }
 128    return $server;
 129  }
 130  
 131  // Retrieve the stored request.
 132  function xmlrpc_server_get() {
 133    return xmlrpc_server_set();
 134  }
 135  
 136  /**
 137   * Dispatch the request and any parameters to the appropriate handler.
 138   *
 139   * @param $xmlrpc_server
 140   * @param $methodname
 141   *   The external XML-RPC method name, e.g. 'system.methodHelp'
 142   * @param $args
 143   *   Array containing any parameters that were sent along with the request.
 144   */
 145  function xmlrpc_server_call($xmlrpc_server, $methodname, $args) {
 146    // Make sure parameters are in an array
 147    if ($args && !is_array($args)) {
 148      $args = array($args);
 149    }
 150    // Has this method been mapped to a Drupal function by us or by modules?
 151    if (!isset($xmlrpc_server->callbacks[$methodname])) {
 152      return xmlrpc_error(-32601, t('Server error. Requested method %methodname not specified.', array("%methodname" => $xmlrpc_server->message->methodname)));
 153    }
 154    $method = $xmlrpc_server->callbacks[$methodname];
 155    $signature = $xmlrpc_server->signatures[$methodname];
 156  
 157    // If the method has a signature, validate the request against the signature
 158    if (is_array($signature)) {
 159      $ok = TRUE;
 160      $return_type = array_shift($signature);
 161      // Check the number of arguments
 162      if (count($args) != count($signature)) {
 163        return xmlrpc_error(-32602, t('Server error. Wrong number of method parameters.'));
 164      }
 165      // Check the argument types
 166      foreach ($signature as $key => $type) {
 167        $arg = $args[$key];
 168        switch ($type) {
 169          case 'int':
 170          case 'i4':
 171            if (is_array($arg) || !is_int($arg)) {
 172              $ok = FALSE;
 173            }
 174            break;
 175          case 'base64':
 176          case 'string':
 177            if (!is_string($arg)) {
 178              $ok = FALSE;
 179            }
 180            break;
 181          case 'boolean':
 182            if ($arg !== FALSE && $arg !== TRUE) {
 183              $ok = FALSE;
 184            }
 185            break;
 186          case 'float':
 187          case 'double':
 188            if (!is_float($arg)) {
 189              $ok = FALSE;
 190            }
 191            break;
 192          case 'date':
 193          case 'dateTime.iso8601':
 194            if (!$arg->is_date) {
 195              $ok = FALSE;
 196            }
 197            break;
 198        }
 199        if (!$ok) {
 200          return xmlrpc_error(-32602, t('Server error. Invalid method parameters.'));
 201        }
 202      }
 203    }
 204    /*
 205    if (count($args) == 1) {
 206      // If only one parameter just send that instead of the whole array
 207      $args = $args[0];
 208    }
 209    */
 210    if (!function_exists($method)) {
 211      return xmlrpc_error(-32601, t('Server error. Requested function %method does not exist.', array("%method" => $method)));
 212    }
 213    // Call the mapped function
 214    return call_user_func_array($method, $args);
 215  }
 216  
 217  function xmlrpc_server_multicall($methodcalls) {
 218    // See http://www.xmlrpc.com/discuss/msgReader$1208
 219    $return = array();
 220    $xmlrpc_server = xmlrpc_server_get();
 221    foreach ($methodcalls as $call) {
 222      $ok = TRUE;
 223      if (!isset($call['methodName']) || !isset($call['params'])) {
 224        $result = xmlrpc_error(3, t('Invalid syntax for system.multicall.'));
 225        $ok = FALSE;
 226      }
 227      $method = $call['methodName'];
 228      $params = $call['params'];
 229      if ($method == 'system.multicall') {
 230        $result = xmlrpc_error(-32600, t('Recursive calls to system.multicall are forbidden.'));
 231      }
 232      elseif ($ok) {
 233        $result = xmlrpc_server_call($xmlrpc_server, $method, $params);
 234      }
 235      if ($result->is_error) {
 236        $return[] = array(
 237          'faultCode' => $result->code,
 238          'faultString' => $result->message
 239        );
 240      }
 241      else {
 242        $return[] = $result;
 243      }
 244    }
 245    return $return;
 246  }
 247  
 248  
 249  /**
 250   * XML-RPC method system.listMethods maps to this function.
 251   */
 252  function xmlrpc_server_list_methods() {
 253    $xmlrpc_server = xmlrpc_server_get();
 254    return array_keys($xmlrpc_server->callbacks);
 255  }
 256  
 257  /**
 258   * XML-RPC method system.getCapabilities maps to this function.
 259   * See http://groups.yahoo.com/group/xml-rpc/message/2897
 260   */
 261  function xmlrpc_server_get_capabilities() {
 262    return array(
 263      'xmlrpc' => array(
 264        'specUrl' => 'http://www.xmlrpc.com/spec',
 265        'specVersion' => 1
 266      ),
 267      'faults_interop' => array(
 268        'specUrl' => 'http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php',
 269        'specVersion' => 20010516
 270      ),
 271      'system.multicall' => array(
 272        'specUrl' => 'http://www.xmlrpc.com/discuss/msgReader$1208',
 273        'specVersion' => 1
 274      ),
 275      'introspection' => array(
 276      'specUrl' => 'http://scripts.incutio.com/xmlrpc/introspection.html',
 277      'specVersion' => 1
 278      )
 279    );
 280  }
 281  
 282  /**
 283   * XML-RPC method system.methodSignature maps to this function.
 284   *
 285   * @param $methodname
 286   *   Name of method for which we return a method signature.
 287   * @return array
 288   *   An array of types representing the method signature of the
 289   *   function that the methodname maps to. The methodSignature of
 290   *   this function is 'array', 'string' because it takes an array
 291   *   and returns a string.
 292   */
 293  function xmlrpc_server_method_signature($methodname) {
 294    $xmlrpc_server = xmlrpc_server_get();
 295    if (!isset($xmlrpc_server->callbacks[$methodname])) {
 296      return xmlrpc_error(-32601, t('Server error. Requested method %methodname not specified.', array("%methodname" => $methodname)));
 297    }
 298    if (!is_array($xmlrpc_server->signatures[$methodname])) {
 299      return xmlrpc_error(-32601, t('Server error. Requested method %methodname signature not specified.', array("%methodname" => $methodname)));
 300    }
 301    // We array of types
 302    $return = array();
 303    foreach ($xmlrpc_server->signatures[$methodname] as $type) {
 304      $return[] = $type;
 305    }
 306    return $return;
 307  }
 308  
 309  /**
 310   * XML-RPC method system.methodHelp maps to this function.
 311   *
 312   * @param $method
 313   *   Name of method for which we return a help string.
 314   */
 315  function xmlrpc_server_method_help($method) {
 316    $xmlrpc_server = xmlrpc_server_get();
 317    return $xmlrpc_server->help[$method];
 318  }


Généré le : Fri Nov 30 16:20:15 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics