home *** CD-ROM | disk | FTP | other *** search
/ HTML Examples / WP.iso / wordpress / wp-includes / IXR / class-IXR-server.php < prev    next >
Encoding:
PHP Script  |  2016-08-26  |  6.8 KB  |  226 lines

  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: '.date('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. }
  226.