[ Index ]

PHP Cross Reference of WordPress

title

Body

[close]

/wp-includes/IXR/ -> class-IXR-server.php (source)

   1  <?php
   2  
   3  /**
   4   * IXR_Server
   5   *
   6   * @package IXR
   7   * @since 1.5.0
   8   */
   9  class IXR_Server
  10  {
  11      var $data;
  12      var $callbacks = array();
  13      var $message;
  14      var $capabilities;
  15  
  16      /**
  17       * PHP5 constructor.
  18       */
  19      function __construct( $callbacks = false, $data = false, $wait = false )
  20      {
  21          $this->setCapabilities();
  22          if ($callbacks) {
  23              $this->callbacks = $callbacks;
  24          }
  25          $this->setCallbacks();
  26          if (!$wait) {
  27              $this->serve($data);
  28          }
  29      }
  30  
  31      /**
  32       * PHP4 constructor.
  33       */
  34  	public function IXR_Server( $callbacks = false, $data = false, $wait = false ) {
  35          self::__construct( $callbacks, $data, $wait );
  36      }
  37  
  38      function serve($data = false)
  39      {
  40          if (!$data) {
  41              if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] !== 'POST') {
  42                  if ( function_exists( 'status_header' ) ) {
  43                      status_header( 405 ); // WP #20986
  44                      header( 'Allow: POST' );
  45                  }
  46                  header('Content-Type: text/plain'); // merged from WP #9093
  47                  die('XML-RPC server accepts POST requests only.');
  48              }
  49  
  50              $data = file_get_contents('php://input');
  51          }
  52          $this->message = new IXR_Message($data);
  53          if (!$this->message->parse()) {
  54              $this->error(-32700, 'parse error. not well formed');
  55          }
  56          if ($this->message->messageType != 'methodCall') {
  57              $this->error(-32600, 'server error. invalid xml-rpc. not conforming to spec. Request must be a methodCall');
  58          }
  59          $result = $this->call($this->message->methodName, $this->message->params);
  60  
  61          // Is the result an error?
  62          if (is_a($result, 'IXR_Error')) {
  63              $this->error($result);
  64          }
  65  
  66          // Encode the result
  67          $r = new IXR_Value($result);
  68          $resultxml = $r->getXml();
  69  
  70          // Create the XML
  71          $xml = <<<EOD
  72  <methodResponse>
  73    <params>
  74      <param>
  75        <value>
  76        $resultxml
  77        </value>
  78      </param>
  79    </params>
  80  </methodResponse>
  81  
  82  EOD;
  83        // Send it
  84        $this->output($xml);
  85      }
  86  
  87      function call($methodname, $args)
  88      {
  89          if (!$this->hasMethod($methodname)) {
  90              return new IXR_Error(-32601, 'server error. requested method '.$methodname.' does not exist.');
  91          }
  92          $method = $this->callbacks[$methodname];
  93  
  94          // Perform the callback and send the response
  95          if (count($args) == 1) {
  96              // If only one parameter just send that instead of the whole array
  97              $args = $args[0];
  98          }
  99  
 100          // Are we dealing with a function or a method?
 101          if (is_string($method) && substr($method, 0, 5) == 'this:') {
 102              // It's a class method - check it exists
 103              $method = substr($method, 5);
 104              if (!method_exists($this, $method)) {
 105                  return new IXR_Error(-32601, 'server error. requested class method "'.$method.'" does not exist.');
 106              }
 107  
 108              //Call the method
 109              $result = $this->$method($args);
 110          } else {
 111              // It's a function - does it exist?
 112              if (is_array($method)) {
 113                  if (!is_callable(array($method[0], $method[1]))) {
 114                      return new IXR_Error(-32601, 'server error. requested object method "'.$method[1].'" does not exist.');
 115                  }
 116              } else if (!function_exists($method)) {
 117                  return new IXR_Error(-32601, 'server error. requested function "'.$method.'" does not exist.');
 118              }
 119  
 120              // Call the function
 121              $result = call_user_func($method, $args);
 122          }
 123          return $result;
 124      }
 125  
 126      function error($error, $message = false)
 127      {
 128          // Accepts either an error object or an error code and message
 129          if ($message && !is_object($error)) {
 130              $error = new IXR_Error($error, $message);
 131          }
 132  
 133          $this->output($error->getXml());
 134      }
 135  
 136      function output($xml)
 137      {
 138          $charset = function_exists('get_option') ? get_option('blog_charset') : '';
 139          if ($charset)
 140              $xml = '<?xml version="1.0" encoding="'.$charset.'"?>'."\n".$xml;
 141          else
 142              $xml = '<?xml version="1.0"?>'."\n".$xml;
 143          $length = strlen($xml);
 144          header('Connection: close');
 145          if ($charset)
 146              header('Content-Type: text/xml; charset='.$charset);
 147          else
 148              header('Content-Type: text/xml');
 149          header('Date: '.gmdate('r'));
 150          echo $xml;
 151          exit;
 152      }
 153  
 154      function hasMethod($method)
 155      {
 156          return in_array($method, array_keys($this->callbacks));
 157      }
 158  
 159      function setCapabilities()
 160      {
 161          // Initialises capabilities array
 162          $this->capabilities = array(
 163              'xmlrpc' => array(
 164                  'specUrl' => 'http://www.xmlrpc.com/spec',
 165                  'specVersion' => 1
 166          ),
 167              'faults_interop' => array(
 168                  'specUrl' => 'http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php',
 169                  'specVersion' => 20010516
 170          ),
 171              'system.multicall' => array(
 172                  'specUrl' => 'http://www.xmlrpc.com/discuss/msgReader$1208',
 173                  'specVersion' => 1
 174          ),
 175          );
 176      }
 177  
 178      function getCapabilities($args)
 179      {
 180          return $this->capabilities;
 181      }
 182  
 183      function setCallbacks()
 184      {
 185          $this->callbacks['system.getCapabilities'] = 'this:getCapabilities';
 186          $this->callbacks['system.listMethods'] = 'this:listMethods';
 187          $this->callbacks['system.multicall'] = 'this:multiCall';
 188      }
 189  
 190      function listMethods($args)
 191      {
 192          // Returns a list of methods - uses array_reverse to ensure user defined
 193          // methods are listed before server defined methods
 194          return array_reverse(array_keys($this->callbacks));
 195      }
 196  
 197      function multiCall($methodcalls)
 198      {
 199          // See http://www.xmlrpc.com/discuss/msgReader$1208
 200          $return = array();
 201          foreach ($methodcalls as $call) {
 202              $method = $call['methodName'];
 203              $params = $call['params'];
 204              if ($method == 'system.multicall') {
 205                  $result = new IXR_Error(-32600, 'Recursive calls to system.multicall are forbidden');
 206              } else {
 207                  $result = $this->call($method, $params);
 208              }
 209              if (is_a($result, 'IXR_Error')) {
 210                  $return[] = array(
 211                      'faultCode' => $result->code,
 212                      'faultString' => $result->message
 213                  );
 214              } else {
 215                  $return[] = array($result);
 216              }
 217          }
 218          return $return;
 219      }
 220  }


Generated: Tue Dec 24 01:00:02 2024 Cross-referenced by PHPXref 0.7.1