[ 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              global $HTTP_RAW_POST_DATA;
  51              if (empty($HTTP_RAW_POST_DATA)) {
  52                  // workaround for a bug in PHP 5.2.2 - http://bugs.php.net/bug.php?id=41293
  53                  $data = file_get_contents('php://input');
  54              } else {
  55                  $data =& $HTTP_RAW_POST_DATA;
  56              }
  57          }
  58          $this->message = new IXR_Message($data);
  59          if (!$this->message->parse()) {
  60              $this->error(-32700, 'parse error. not well formed');
  61          }
  62          if ($this->message->messageType != 'methodCall') {
  63              $this->error(-32600, 'server error. invalid xml-rpc. not conforming to spec. Request must be a methodCall');
  64          }
  65          $result = $this->call($this->message->methodName, $this->message->params);
  66  
  67          // Is the result an error?
  68          if (is_a($result, 'IXR_Error')) {
  69              $this->error($result);
  70          }
  71  
  72          // Encode the result
  73          $r = new IXR_Value($result);
  74          $resultxml = $r->getXml();
  75  
  76          // Create the XML
  77          $xml = <<<EOD
  78  <methodResponse>
  79    <params>
  80      <param>
  81        <value>
  82        $resultxml
  83        </value>
  84      </param>
  85    </params>
  86  </methodResponse>
  87  
  88  EOD;
  89        // Send it
  90        $this->output($xml);
  91      }
  92  
  93      function call($methodname, $args)
  94      {
  95          if (!$this->hasMethod($methodname)) {
  96              return new IXR_Error(-32601, 'server error. requested method '.$methodname.' does not exist.');
  97          }
  98          $method = $this->callbacks[$methodname];
  99  
 100          // Perform the callback and send the response
 101          if (count($args) == 1) {
 102              // If only one parameter just send that instead of the whole array
 103              $args = $args[0];
 104          }
 105  
 106          // Are we dealing with a function or a method?
 107          if (is_string($method) && substr($method, 0, 5) == 'this:') {
 108              // It's a class method - check it exists
 109              $method = substr($method, 5);
 110              if (!method_exists($this, $method)) {
 111                  return new IXR_Error(-32601, 'server error. requested class method "'.$method.'" does not exist.');
 112              }
 113  
 114              //Call the method
 115              $result = $this->$method($args);
 116          } else {
 117              // It's a function - does it exist?
 118              if (is_array($method)) {
 119                  if (!is_callable(array($method[0], $method[1]))) {
 120                      return new IXR_Error(-32601, 'server error. requested object method "'.$method[1].'" does not exist.');
 121                  }
 122              } else if (!function_exists($method)) {
 123                  return new IXR_Error(-32601, 'server error. requested function "'.$method.'" does not exist.');
 124              }
 125  
 126              // Call the function
 127              $result = call_user_func($method, $args);
 128          }
 129          return $result;
 130      }
 131  
 132      function error($error, $message = false)
 133      {
 134          // Accepts either an error object or an error code and message
 135          if ($message && !is_object($error)) {
 136              $error = new IXR_Error($error, $message);
 137          }
 138          $this->output($error->getXml());
 139      }
 140  
 141      function output($xml)
 142      {
 143          $charset = function_exists('get_option') ? get_option('blog_charset') : '';
 144          if ($charset)
 145              $xml = '<?xml version="1.0" encoding="'.$charset.'"?>'."\n".$xml;
 146          else
 147              $xml = '<?xml version="1.0"?>'."\n".$xml;
 148          $length = strlen($xml);
 149          header('Connection: close');
 150          if ($charset)
 151              header('Content-Type: text/xml; charset='.$charset);
 152          else
 153              header('Content-Type: text/xml');
 154          header('Date: '.gmdate('r'));
 155          echo $xml;
 156          exit;
 157      }
 158  
 159      function hasMethod($method)
 160      {
 161          return in_array($method, array_keys($this->callbacks));
 162      }
 163  
 164      function setCapabilities()
 165      {
 166          // Initialises capabilities array
 167          $this->capabilities = array(
 168              'xmlrpc' => array(
 169                  'specUrl' => 'http://www.xmlrpc.com/spec',
 170                  'specVersion' => 1
 171          ),
 172              'faults_interop' => array(
 173                  'specUrl' => 'http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php',
 174                  'specVersion' => 20010516
 175          ),
 176              'system.multicall' => array(
 177                  'specUrl' => 'http://www.xmlrpc.com/discuss/msgReader$1208',
 178                  'specVersion' => 1
 179          ),
 180          );
 181      }
 182  
 183      function getCapabilities($args)
 184      {
 185          return $this->capabilities;
 186      }
 187  
 188      function setCallbacks()
 189      {
 190          $this->callbacks['system.getCapabilities'] = 'this:getCapabilities';
 191          $this->callbacks['system.listMethods'] = 'this:listMethods';
 192          $this->callbacks['system.multicall'] = 'this:multiCall';
 193      }
 194  
 195      function listMethods($args)
 196      {
 197          // Returns a list of methods - uses array_reverse to ensure user defined
 198          // methods are listed before server defined methods
 199          return array_reverse(array_keys($this->callbacks));
 200      }
 201  
 202      function multiCall($methodcalls)
 203      {
 204          // See http://www.xmlrpc.com/discuss/msgReader$1208
 205          $return = array();
 206          foreach ($methodcalls as $call) {
 207              $method = $call['methodName'];
 208              $params = $call['params'];
 209              if ($method == 'system.multicall') {
 210                  $result = new IXR_Error(-32600, 'Recursive calls to system.multicall are forbidden');
 211              } else {
 212                  $result = $this->call($method, $params);
 213              }
 214              if (is_a($result, 'IXR_Error')) {
 215                  $return[] = array(
 216                      'faultCode' => $result->code,
 217                      'faultString' => $result->message
 218                  );
 219              } else {
 220                  $return[] = array($result);
 221              }
 222          }
 223          return $return;
 224      }
 225  }


Generated: Wed Jul 24 01:00:02 2019 Cross-referenced by PHPXref 0.7.1