[ 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          $this->output($error->getXml());
 133      }
 134  
 135      function output($xml)
 136      {
 137          $charset = function_exists('get_option') ? get_option('blog_charset') : '';
 138          if ($charset)
 139              $xml = '<?xml version="1.0" encoding="'.$charset.'"?>'."\n".$xml;
 140          else
 141              $xml = '<?xml version="1.0"?>'."\n".$xml;
 142          $length = strlen($xml);
 143          header('Connection: close');
 144          if ($charset)
 145              header('Content-Type: text/xml; charset='.$charset);
 146          else
 147              header('Content-Type: text/xml');
 148          header('Date: '.gmdate('r'));
 149          echo $xml;
 150          exit;
 151      }
 152  
 153      function hasMethod($method)
 154      {
 155          return in_array($method, array_keys($this->callbacks));
 156      }
 157  
 158      function setCapabilities()
 159      {
 160          // Initialises capabilities array
 161          $this->capabilities = array(
 162              'xmlrpc' => array(
 163                  'specUrl' => 'http://www.xmlrpc.com/spec',
 164                  'specVersion' => 1
 165          ),
 166              'faults_interop' => array(
 167                  'specUrl' => 'http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php',
 168                  'specVersion' => 20010516
 169          ),
 170              'system.multicall' => array(
 171                  'specUrl' => 'http://www.xmlrpc.com/discuss/msgReader$1208',
 172                  'specVersion' => 1
 173          ),
 174          );
 175      }
 176  
 177      function getCapabilities($args)
 178      {
 179          return $this->capabilities;
 180      }
 181  
 182      function setCallbacks()
 183      {
 184          $this->callbacks['system.getCapabilities'] = 'this:getCapabilities';
 185          $this->callbacks['system.listMethods'] = 'this:listMethods';
 186          $this->callbacks['system.multicall'] = 'this:multiCall';
 187      }
 188  
 189      function listMethods($args)
 190      {
 191          // Returns a list of methods - uses array_reverse to ensure user defined
 192          // methods are listed before server defined methods
 193          return array_reverse(array_keys($this->callbacks));
 194      }
 195  
 196      function multiCall($methodcalls)
 197      {
 198          // See http://www.xmlrpc.com/discuss/msgReader$1208
 199          $return = array();
 200          foreach ($methodcalls as $call) {
 201              $method = $call['methodName'];
 202              $params = $call['params'];
 203              if ($method == 'system.multicall') {
 204                  $result = new IXR_Error(-32600, 'Recursive calls to system.multicall are forbidden');
 205              } else {
 206                  $result = $this->call($method, $params);
 207              }
 208              if (is_a($result, 'IXR_Error')) {
 209                  $return[] = array(
 210                      'faultCode' => $result->code,
 211                      'faultString' => $result->message
 212                  );
 213              } else {
 214                  $return[] = array($result);
 215              }
 216          }
 217          return $return;
 218      }
 219  }


Generated: Thu Nov 26 01:00:03 2020 Cross-referenced by PHPXref 0.7.1