<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" /><style type="text/css"><!--
#msg dl { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fc0 solid; padding: 6px; }
#msg ul, pre { overflow: auto; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<title>[15612] trunk/wp-includes/class-IXR.php:
Update Incutio XML-RPC Library to latest version (1.7.4).</title>
</head>
<body>
<div id="msg">
<dl>
<dt>Revision</dt> <dd><a href="http://trac.wordpress.org/changeset/15612">15612</a></dd>
<dt>Author</dt> <dd>scribu</dd>
<dt>Date</dt> <dd>2010-09-13 16:36:08 +0000 (Mon, 13 Sep 2010)</dd>
</dl>
<h3>Log Message</h3>
<pre>Update Incutio XML-RPC Library to latest version (1.7.4). Props hakre. Fixes <a href="http://trac.wordpress.org/ticket/14703">#14703</a></pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkwpincludesclassIXRphp">trunk/wp-includes/class-IXR.php</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkwpincludesclassIXRphp"></a>
<div class="modfile"><h4>Modified: trunk/wp-includes/class-IXR.php (15611 => 15612)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-includes/class-IXR.php        2010-09-12 18:46:18 UTC (rev 15611)
+++ trunk/wp-includes/class-IXR.php        2010-09-13 16:36:08 UTC (rev 15612)
</span><span class="lines">@@ -1,16 +1,42 @@
</span><span class="cx"> <?php
</span><span class="cx"> /**
</span><del>- * IXR - The Inutio XML-RPC Library
</del><ins>+ * IXR - The Incutio XML-RPC Library
</ins><span class="cx"> *
</span><ins>+ * Copyright (c) 2010, Incutio Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * - Neither the name of Incutio Ltd. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
</ins><span class="cx"> * @package IXR
</span><span class="cx"> * @since 1.5
</span><span class="cx"> *
</span><del>- * @copyright Incutio Ltd 2002-2005
- * @version 1.7 (beta) 23rd May 2005
- * @author Simon Willison
- * @link http://scripts.incutio.com/xmlrpc/ Site
- * @link http://scripts.incutio.com/xmlrpc/manual.php Manual
- * @license BSD License http://www.opensource.org/licenses/bsd-license.php
</del><ins>+ * @copyright Incutio Ltd 2010 (http://www.incutio.com)
+ * @version 1.7.4 7th September 2010
+ * @author Simon Willison
+ * @link http://scripts.incutio.com/xmlrpc/ Site/manual
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD
</ins><span class="cx"> */
</span><span class="cx">
</span><span class="cx"> /**
</span><span class="lines">@@ -23,14 +49,15 @@
</span><span class="cx"> var $data;
</span><span class="cx"> var $type;
</span><span class="cx">
</span><del>- function IXR_Value ($data, $type = false) {
</del><ins>+ function IXR_Value($data, $type = false)
+ {
</ins><span class="cx"> $this->data = $data;
</span><span class="cx"> if (!$type) {
</span><span class="cx"> $type = $this->calculateType();
</span><span class="cx"> }
</span><span class="cx"> $this->type = $type;
</span><span class="cx"> if ($type == 'struct') {
</span><del>- /* Turn all the values in the array in to new IXR_Value objects */
</del><ins>+ // Turn all the values in the array in to new IXR_Value objects
</ins><span class="cx"> foreach ($this->data as $key => $value) {
</span><span class="cx"> $this->data[$key] = new IXR_Value($value);
</span><span class="cx"> }
</span><span class="lines">@@ -42,7 +69,8 @@
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><del>- function calculateType() {
</del><ins>+ function calculateType()
+ {
</ins><span class="cx"> if ($this->data === true || $this->data === false) {
</span><span class="cx"> return 'boolean';
</span><span class="cx"> }
</span><span class="lines">@@ -52,6 +80,7 @@
</span><span class="cx"> if (is_double($this->data)) {
</span><span class="cx"> return 'double';
</span><span class="cx"> }
</span><ins>+
</ins><span class="cx"> // Deal with IXR object types base64 and date
</span><span class="cx"> if (is_object($this->data) && is_a($this->data, 'IXR_Date')) {
</span><span class="cx"> return 'date';
</span><span class="lines">@@ -59,16 +88,17 @@
</span><span class="cx"> if (is_object($this->data) && is_a($this->data, 'IXR_Base64')) {
</span><span class="cx"> return 'base64';
</span><span class="cx"> }
</span><ins>+
</ins><span class="cx"> // If it is a normal PHP object convert it in to a struct
</span><span class="cx"> if (is_object($this->data)) {
</span><del>-
</del><span class="cx"> $this->data = get_object_vars($this->data);
</span><span class="cx"> return 'struct';
</span><span class="cx"> }
</span><span class="cx"> if (!is_array($this->data)) {
</span><span class="cx"> return 'string';
</span><span class="cx"> }
</span><del>- /* We have an array - is it an array or a struct ? */
</del><ins>+
+ // We have an array - is it an array or a struct?
</ins><span class="cx"> if ($this->isStruct($this->data)) {
</span><span class="cx"> return 'struct';
</span><span class="cx"> } else {
</span><span class="lines">@@ -76,8 +106,9 @@
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><del>- function getXml() {
- /* Return XML for this value */
</del><ins>+ function getXml()
+ {
+ // Return XML for this value
</ins><span class="cx"> switch ($this->type) {
</span><span class="cx"> case 'boolean':
</span><span class="cx"> return '<boolean>'.(($this->data) ? '1' : '0').'</boolean>';
</span><span class="lines">@@ -117,8 +148,14 @@
</span><span class="cx"> return false;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- function isStruct($array) {
- /* Nasty function to check if an array is a struct or not */
</del><ins>+ /**
+ * Checks whether or not the supplied array is a struct or not
+ *
+ * @param unknown_type $array
+ * @return boolean
+ */
+ function isStruct($array)
+ {
</ins><span class="cx"> $expected = 0;
</span><span class="cx"> foreach ($array as $key => $value) {
</span><span class="cx"> if ((string)$key != (string)$expected) {
</span><span class="lines">@@ -131,18 +168,21 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> /**
</span><del>- * IXR_Message
</del><ins>+ * IXR_MESSAGE
</ins><span class="cx"> *
</span><span class="cx"> * @package IXR
</span><span class="cx"> * @since 1.5
</span><ins>+ *
</ins><span class="cx"> */
</span><del>-class IXR_Message {
</del><ins>+class IXR_Message
+{
</ins><span class="cx"> var $message;
</span><span class="cx"> var $messageType; // methodCall / methodResponse / fault
</span><span class="cx"> var $faultCode;
</span><span class="cx"> var $faultString;
</span><span class="cx"> var $methodName;
</span><span class="cx"> var $params;
</span><ins>+
</ins><span class="cx"> // Current variable stacks
</span><span class="cx"> var $_arraystructs = array(); // The stack used to keep track of the current array/struct
</span><span class="cx"> var $_arraystructstypes = array(); // Stack keeping track of if things are structs or array
</span><span class="lines">@@ -153,44 +193,54 @@
</span><span class="cx"> var $_currentTagContents;
</span><span class="cx"> // The XML parser
</span><span class="cx"> var $_parser;
</span><del>- function IXR_Message (&$message) {
- $this->message = &$message;
</del><ins>+
+ function IXR_Message($message)
+ {
+ $this->message =& $message;
</ins><span class="cx"> }
</span><del>- function parse() {
-                // first remove the XML declaration
-                // this method avoids the RAM usage of preg_replace on very large messages
-                $header = preg_replace( '/<\?xml.*?\?'.'>/', '', substr( $this->message, 0, 100 ), 1 );
-                $this->message = substr_replace($this->message, $header, 0, 100);
</del><ins>+
+ function parse()
+ {
+ // first remove the XML declaration
+ // merged from WP #10698 - this method avoids the RAM usage of preg_replace on very large messages
+ $header = preg_replace( '/<\?xml.*?\?'.'>/', '', substr($this->message, 0, 100), 1);
+ $this->message = substr_replace($this->message, $header, 0, 100);
</ins><span class="cx"> if (trim($this->message) == '') {
</span><span class="cx"> return false;
</span><del>-                }
</del><ins>+ }
</ins><span class="cx"> $this->_parser = xml_parser_create();
</span><span class="cx"> // Set XML parser to take the case of tags in to account
</span><span class="cx"> xml_parser_set_option($this->_parser, XML_OPTION_CASE_FOLDING, false);
</span><span class="cx"> // Set XML parser callback functions
</span><span class="cx"> xml_set_object($this->_parser, $this);
</span><span class="cx"> xml_set_element_handler($this->_parser, 'tag_open', 'tag_close');
</span><del>-                xml_set_character_data_handler($this->_parser, 'cdata');
-                $chunk_size = 262144; // 256Kb, parse in chunks to avoid the RAM usage on very large messages
-                do {
-                        if ( strlen($this->message) <= $chunk_size )
-                                $final=true;
-                        $part = substr( $this->message, 0, $chunk_size );
-                        $this->message = substr( $this->message, $chunk_size );
-                        if ( !xml_parse( $this->_parser, $part, $final ) )
-                                return false;
-                        if ( $final )
-                                break;
-                } while ( true );
-                xml_parser_free($this->_parser);
</del><ins>+ xml_set_character_data_handler($this->_parser, 'cdata');
+ $chunk_size = 262144; // 256Kb, parse in chunks to avoid the RAM usage on very large messages
+ do {
+ if (strlen($this->message) <= $chunk_size) {
+ $final = true;
+ }
+ $part = substr($this->message, 0, $chunk_size);
+ $this->message = substr($this->message, $chunk_size);
+ if (!xml_parse($this->_parser, $part, $final)) {
+ return false;
+ }
+ if ($final) {
+ break;
+ }
+ } while (true);
+ xml_parser_free($this->_parser);
+
</ins><span class="cx"> // Grab the error messages, if any
</span><span class="cx"> if ($this->messageType == 'fault') {
</span><span class="cx"> $this->faultCode = $this->params[0]['faultCode'];
</span><span class="cx"> $this->faultString = $this->params[0]['faultString'];
</span><del>-                }
</del><ins>+ }
</ins><span class="cx"> return true;
</span><span class="cx"> }
</span><del>- function tag_open($parser, $tag, $attr) {
</del><ins>+
+ function tag_open($parser, $tag, $attr)
+ {
</ins><span class="cx"> $this->_currentTagContents = '';
</span><span class="cx"> $this->currentTag = $tag;
</span><span class="cx"> switch($tag) {
</span><span class="lines">@@ -199,7 +249,7 @@
</span><span class="cx"> case 'fault':
</span><span class="cx"> $this->messageType = $tag;
</span><span class="cx"> break;
</span><del>- /* Deal with stacks of arrays and structs */
</del><ins>+ /* Deal with stacks of arrays and structs */
</ins><span class="cx"> case 'data': // data is to all intents and puposes more interesting than array
</span><span class="cx"> $this->_arraystructstypes[] = 'array';
</span><span class="cx"> $this->_arraystructs[] = array();
</span><span class="lines">@@ -210,28 +260,31 @@
</span><span class="cx"> break;
</span><span class="cx"> }
</span><span class="cx"> }
</span><del>- function cdata($parser, $cdata) {
</del><ins>+
+ function cdata($parser, $cdata)
+ {
</ins><span class="cx"> $this->_currentTagContents .= $cdata;
</span><span class="cx"> }
</span><del>- function tag_close($parser, $tag) {
</del><ins>+
+ function tag_close($parser, $tag)
+ {
</ins><span class="cx"> $valueFlag = false;
</span><span class="cx"> switch($tag) {
</span><span class="cx"> case 'int':
</span><span class="cx"> case 'i4':
</span><del>- $value = (int) trim($this->_currentTagContents);
</del><ins>+ $value = (int)trim($this->_currentTagContents);
</ins><span class="cx"> $valueFlag = true;
</span><span class="cx"> break;
</span><span class="cx"> case 'double':
</span><del>- $value = (double) trim($this->_currentTagContents);
</del><ins>+ $value = (double)trim($this->_currentTagContents);
</ins><span class="cx"> $valueFlag = true;
</span><span class="cx"> break;
</span><span class="cx"> case 'string':
</span><del>- $value = $this->_currentTagContents;
</del><ins>+ $value = (string)trim($this->_currentTagContents);
</ins><span class="cx"> $valueFlag = true;
</span><span class="cx"> break;
</span><span class="cx"> case 'dateTime.iso8601':
</span><span class="cx"> $value = new IXR_Date(trim($this->_currentTagContents));
</span><del>- // $value = $iso->getTimestamp();
</del><span class="cx"> $valueFlag = true;
</span><span class="cx"> break;
</span><span class="cx"> case 'value':
</span><span class="lines">@@ -242,14 +295,14 @@
</span><span class="cx"> }
</span><span class="cx"> break;
</span><span class="cx"> case 'boolean':
</span><del>- $value = (boolean) trim($this->_currentTagContents);
</del><ins>+ $value = (boolean)trim($this->_currentTagContents);
</ins><span class="cx"> $valueFlag = true;
</span><span class="cx"> break;
</span><span class="cx"> case 'base64':
</span><del>- $value = base64_decode( trim( $this->_currentTagContents ) );
</del><ins>+ $value = base64_decode($this->_currentTagContents);
</ins><span class="cx"> $valueFlag = true;
</span><span class="cx"> break;
</span><del>- /* Deal with stacks of arrays and structs */
</del><ins>+ /* Deal with stacks of arrays and structs */
</ins><span class="cx"> case 'data':
</span><span class="cx"> case 'struct':
</span><span class="cx"> $value = array_pop($this->_arraystructs);
</span><span class="lines">@@ -266,6 +319,7 @@
</span><span class="cx"> $this->methodName = trim($this->_currentTagContents);
</span><span class="cx"> break;
</span><span class="cx"> }
</span><ins>+
</ins><span class="cx"> if ($valueFlag) {
</span><span class="cx"> if (count($this->_arraystructs) > 0) {
</span><span class="cx"> // Add value to struct or array
</span><span class="lines">@@ -291,27 +345,40 @@
</span><span class="cx"> * @package IXR
</span><span class="cx"> * @since 1.5
</span><span class="cx"> */
</span><del>-class IXR_Server {
</del><ins>+class IXR_Server
+{
</ins><span class="cx"> var $data;
</span><span class="cx"> var $callbacks = array();
</span><span class="cx"> var $message;
</span><span class="cx"> var $capabilities;
</span><del>- function IXR_Server($callbacks = false, $data = false) {
</del><ins>+
+ function IXR_Server($callbacks = false, $data = false, $wait = false)
+ {
</ins><span class="cx"> $this->setCapabilities();
</span><span class="cx"> if ($callbacks) {
</span><span class="cx"> $this->callbacks = $callbacks;
</span><span class="cx"> }
</span><span class="cx"> $this->setCallbacks();
</span><del>- $this->serve($data);
</del><ins>+ if (!$wait) {
+ $this->serve($data);
+ }
</ins><span class="cx"> }
</span><del>- function serve($data = false) {
</del><ins>+
+ function serve($data = false)
+ {
</ins><span class="cx"> if (!$data) {
</span><ins>+ if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] !== 'POST') {
+         header('Content-Type: text/plain'); // merged from WP #9093
+ die('XML-RPC server accepts POST requests only.');
+ }
+
</ins><span class="cx"> global $HTTP_RAW_POST_DATA;
</span><del>- if (!$HTTP_RAW_POST_DATA) {
- header( 'Content-Type: text/plain' );
- die('XML-RPC server accepts POST requests only.');
</del><ins>+ if (empty($HTTP_RAW_POST_DATA)) {
+ // workaround for a bug in PHP 5.2.2 - http://bugs.php.net/bug.php?id=41293
+ $data = file_get_contents('php://input');
+ } else {
+ $data =& $HTTP_RAW_POST_DATA;
</ins><span class="cx"> }
</span><del>- $data = &$HTTP_RAW_POST_DATA;
</del><span class="cx"> }
</span><span class="cx"> $this->message = new IXR_Message($data);
</span><span class="cx"> if (!$this->message->parse()) {
</span><span class="lines">@@ -321,75 +388,83 @@
</span><span class="cx"> $this->error(-32600, 'server error. invalid xml-rpc. not conforming to spec. Request must be a methodCall');
</span><span class="cx"> }
</span><span class="cx"> $result = $this->call($this->message->methodName, $this->message->params);
</span><ins>+
</ins><span class="cx"> // Is the result an error?
</span><span class="cx"> if (is_a($result, 'IXR_Error')) {
</span><span class="cx"> $this->error($result);
</span><span class="cx"> }
</span><ins>+
</ins><span class="cx"> // Encode the result
</span><span class="cx"> $r = new IXR_Value($result);
</span><span class="cx"> $resultxml = $r->getXml();
</span><ins>+
</ins><span class="cx"> // Create the XML
</span><span class="cx"> $xml = <<<EOD
</span><span class="cx"> <methodResponse>
</span><span class="cx"> <params>
</span><span class="cx"> <param>
</span><span class="cx"> <value>
</span><del>- $resultxml
</del><ins>+ $resultxml
</ins><span class="cx"> </value>
</span><span class="cx"> </param>
</span><span class="cx"> </params>
</span><span class="cx"> </methodResponse>
</span><span class="cx">
</span><span class="cx"> EOD;
</span><del>- // Send it
- $this->output($xml);
</del><ins>+ // Send it
+ $this->output($xml);
</ins><span class="cx"> }
</span><del>- function call($methodname, $args) {
</del><ins>+
+ function call($methodname, $args)
+ {
</ins><span class="cx"> if (!$this->hasMethod($methodname)) {
</span><del>- return new IXR_Error(-32601, 'server error. requested method '.
- $methodname.' does not exist.');
</del><ins>+ return new IXR_Error(-32601, 'server error. requested method '.$methodname.' does not exist.');
</ins><span class="cx"> }
</span><span class="cx"> $method = $this->callbacks[$methodname];
</span><ins>+
</ins><span class="cx"> // Perform the callback and send the response
</span><span class="cx"> if (count($args) == 1) {
</span><span class="cx"> // If only one paramater just send that instead of the whole array
</span><span class="cx"> $args = $args[0];
</span><span class="cx"> }
</span><ins>+
</ins><span class="cx"> // Are we dealing with a function or a method?
</span><del>- if ( is_string( $method ) && substr($method, 0, 5) == 'this:' ) {
</del><ins>+ if (is_string($method) && substr($method, 0, 5) == 'this:') {
</ins><span class="cx"> // It's a class method - check it exists
</span><span class="cx"> $method = substr($method, 5);
</span><span class="cx"> if (!method_exists($this, $method)) {
</span><del>- return new IXR_Error(-32601, 'server error. requested class method "'.
- $method.'" does not exist.');
</del><ins>+ return new IXR_Error(-32601, 'server error. requested class method "'.$method.'" does not exist.');
</ins><span class="cx"> }
</span><del>- // Call the method
</del><ins>+
+ //Call the method
</ins><span class="cx"> $result = $this->$method($args);
</span><span class="cx"> } else {
</span><span class="cx"> // It's a function - does it exist?
</span><span class="cx"> if (is_array($method)) {
</span><span class="cx"> if (!method_exists($method[0], $method[1])) {
</span><del>- return new IXR_Error(-32601, 'server error. requested object method "'.
- $method[1].'" does not exist.');
</del><ins>+ return new IXR_Error(-32601, 'server error. requested object method "'.$method[1].'" does not exist.');
</ins><span class="cx"> }
</span><span class="cx"> } else if (!function_exists($method)) {
</span><del>- return new IXR_Error(-32601, 'server error. requested function "'.
- $method.'" does not exist.');
</del><ins>+ return new IXR_Error(-32601, 'server error. requested function "'.$method.'" does not exist.');
</ins><span class="cx"> }
</span><ins>+
</ins><span class="cx"> // Call the function
</span><span class="cx"> $result = call_user_func($method, $args);
</span><span class="cx"> }
</span><span class="cx"> return $result;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- function error($error, $message = false) {
</del><ins>+ function error($error, $message = false)
+ {
</ins><span class="cx"> // Accepts either an error object or an error code and message
</span><span class="cx"> if ($message && !is_object($error)) {
</span><span class="cx"> $error = new IXR_Error($error, $message);
</span><span class="cx"> }
</span><span class="cx"> $this->output($error->getXml());
</span><span class="cx"> }
</span><del>- function output($xml) {
</del><ins>+
+ function output($xml)
+ {
</ins><span class="cx"> $xml = '<?xml version="1.0"?>'."\n".$xml;
</span><span class="cx"> $length = strlen($xml);
</span><span class="cx"> header('Connection: close');
</span><span class="lines">@@ -399,40 +474,52 @@
</span><span class="cx"> echo $xml;
</span><span class="cx"> exit;
</span><span class="cx"> }
</span><del>- function hasMethod($method) {
</del><ins>+
+ function hasMethod($method)
+ {
</ins><span class="cx"> return in_array($method, array_keys($this->callbacks));
</span><span class="cx"> }
</span><del>- function setCapabilities() {
</del><ins>+
+ function setCapabilities()
+ {
</ins><span class="cx"> // Initialises capabilities array
</span><span class="cx"> $this->capabilities = array(
</span><span class="cx"> 'xmlrpc' => array(
</span><span class="cx"> 'specUrl' => 'http://www.xmlrpc.com/spec',
</span><span class="cx"> 'specVersion' => 1
</span><del>- ),
</del><ins>+ ),
</ins><span class="cx"> 'faults_interop' => array(
</span><span class="cx"> 'specUrl' => 'http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php',
</span><span class="cx"> 'specVersion' => 20010516
</span><del>- ),
</del><ins>+ ),
</ins><span class="cx"> 'system.multicall' => array(
</span><span class="cx"> 'specUrl' => 'http://www.xmlrpc.com/discuss/msgReader$1208',
</span><span class="cx"> 'specVersion' => 1
</span><del>- ),
</del><ins>+ ),
</ins><span class="cx"> );
</span><span class="cx"> }
</span><del>- function getCapabilities($args) {
</del><ins>+
+ function getCapabilities($args)
+ {
</ins><span class="cx"> return $this->capabilities;
</span><span class="cx"> }
</span><del>- function setCallbacks() {
</del><ins>+
+ function setCallbacks()
+ {
</ins><span class="cx"> $this->callbacks['system.getCapabilities'] = 'this:getCapabilities';
</span><span class="cx"> $this->callbacks['system.listMethods'] = 'this:listMethods';
</span><span class="cx"> $this->callbacks['system.multicall'] = 'this:multiCall';
</span><span class="cx"> }
</span><del>- function listMethods($args) {
</del><ins>+
+ function listMethods($args)
+ {
</ins><span class="cx"> // Returns a list of methods - uses array_reverse to ensure user defined
</span><span class="cx"> // methods are listed before server defined methods
</span><span class="cx"> return array_reverse(array_keys($this->callbacks));
</span><span class="cx"> }
</span><del>- function multiCall($methodcalls) {
</del><ins>+
+ function multiCall($methodcalls)
+ {
</ins><span class="cx"> // See http://www.xmlrpc.com/discuss/msgReader$1208
</span><span class="cx"> $return = array();
</span><span class="cx"> foreach ($methodcalls as $call) {
</span><span class="lines">@@ -462,11 +549,14 @@
</span><span class="cx"> * @package IXR
</span><span class="cx"> * @since 1.5
</span><span class="cx"> */
</span><del>-class IXR_Request {
</del><ins>+class IXR_Request
+{
</ins><span class="cx"> var $method;
</span><span class="cx"> var $args;
</span><span class="cx"> var $xml;
</span><del>- function IXR_Request($method, $args) {
</del><ins>+
+ function IXR_Request($method, $args)
+ {
</ins><span class="cx"> $this->method = $method;
</span><span class="cx"> $this->args = $args;
</span><span class="cx"> $this->xml = <<<EOD
</span><span class="lines">@@ -484,10 +574,14 @@
</span><span class="cx"> }
</span><span class="cx"> $this->xml .= '</params></methodCall>';
</span><span class="cx"> }
</span><del>- function getLength() {
</del><ins>+
+ function getLength()
+ {
</ins><span class="cx"> return strlen($this->xml);
</span><span class="cx"> }
</span><del>- function getXml() {
</del><ins>+
+ function getXml()
+ {
</ins><span class="cx"> return $this->xml;
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="lines">@@ -497,26 +591,31 @@
</span><span class="cx"> *
</span><span class="cx"> * @package IXR
</span><span class="cx"> * @since 1.5
</span><ins>+ *
</ins><span class="cx"> */
</span><del>-class IXR_Client {
</del><ins>+class IXR_Client
+{
</ins><span class="cx"> var $server;
</span><span class="cx"> var $port;
</span><span class="cx"> var $path;
</span><span class="cx"> var $useragent;
</span><del>-        var $headers;
</del><span class="cx"> var $response;
</span><span class="cx"> var $message = false;
</span><span class="cx"> var $debug = false;
</span><span class="cx"> var $timeout;
</span><ins>+
</ins><span class="cx"> // Storage place for an error message
</span><span class="cx"> var $error = false;
</span><del>- function IXR_Client($server, $path = false, $port = 80, $timeout = false) {
</del><ins>+
+ function IXR_Client($server, $path = false, $port = 80, $timeout = 15)
+ {
</ins><span class="cx"> if (!$path) {
</span><span class="cx"> // Assume we have been given a URL instead
</span><span class="cx"> $bits = parse_url($server);
</span><span class="cx"> $this->server = $bits['host'];
</span><span class="cx"> $this->port = isset($bits['port']) ? $bits['port'] : 80;
</span><span class="cx"> $this->path = isset($bits['path']) ? $bits['path'] : '/';
</span><ins>+
</ins><span class="cx"> // Make absolutely sure we have a path
</span><span class="cx"> if (!$this->path) {
</span><span class="cx"> $this->path = '/';
</span><span class="lines">@@ -529,7 +628,9 @@
</span><span class="cx"> $this->useragent = 'The Incutio XML-RPC PHP Library';
</span><span class="cx"> $this->timeout = $timeout;
</span><span class="cx"> }
</span><del>- function query() {
</del><ins>+
+ function query()
+ {
</ins><span class="cx"> $args = func_get_args();
</span><span class="cx"> $method = array_shift($args);
</span><span class="cx"> $request = new IXR_Request($method, $args);
</span><span class="lines">@@ -538,33 +639,36 @@
</span><span class="cx"> $r = "\r\n";
</span><span class="cx"> $request = "POST {$this->path} HTTP/1.0$r";
</span><span class="cx">
</span><del>-                $this->headers['Host']                        = $this->server;
-                $this->headers['Content-Type']        = 'text/xml';
-                $this->headers['User-Agent']        = $this->useragent;
-                $this->headers['Content-Length']= $length;
</del><ins>+ // Merged from WP #8145 - allow custom headers
+ $this->headers['Host'] = $this->server;
+ $this->headers['Content-Type'] = 'text/xml';
+ $this->headers['User-Agent'] = $this->useragent;
+ $this->headers['Content-Length']= $length;
</ins><span class="cx">
</span><del>-                foreach( $this->headers as $header => $value ) {
-                        $request .= "{$header}: {$value}{$r}";
-                }
-                $request .= $r;
</del><ins>+ foreach( $this->headers as $header => $value ) {
+ $request .= "{$header}: {$value}{$r}";
+ }
+ $request .= $r;
</ins><span class="cx">
</span><span class="cx"> $request .= $xml;
</span><ins>+
</ins><span class="cx"> // Now send the request
</span><span class="cx"> if ($this->debug) {
</span><span class="cx"> echo '<pre class="ixr_request">'.htmlspecialchars($request)."\n</pre>\n\n";
</span><span class="cx"> }
</span><ins>+
</ins><span class="cx"> if ($this->timeout) {
</span><span class="cx"> $fp = @fsockopen($this->server, $this->port, $errno, $errstr, $this->timeout);
</span><span class="cx"> } else {
</span><span class="cx"> $fp = @fsockopen($this->server, $this->port, $errno, $errstr);
</span><span class="cx"> }
</span><span class="cx"> if (!$fp) {
</span><del>- $this->error = new IXR_Error(-32300, "transport error - could not open socket: $errno $errstr");
</del><ins>+ $this->error = new IXR_Error(-32300, 'transport error - could not open socket');
</ins><span class="cx"> return false;
</span><span class="cx"> }
</span><span class="cx"> fputs($fp, $request);
</span><span class="cx"> $contents = '';
</span><del>- $debug_contents = '';
</del><ins>+ $debugContents = '';
</ins><span class="cx"> $gotFirstLine = false;
</span><span class="cx"> $gettingHeaders = true;
</span><span class="cx"> while (!feof($fp)) {
</span><span class="lines">@@ -572,7 +676,7 @@
</span><span class="cx"> if (!$gotFirstLine) {
</span><span class="cx"> // Check line for '200'
</span><span class="cx"> if (strstr($line, '200') === false) {
</span><del>- $this->error = new IXR_Error(-32301, 'transport error - HTTP status code was not 200');
</del><ins>+ $this->error = new IXR_Error(-32300, 'transport error - HTTP status code was not 200');
</ins><span class="cx"> return false;
</span><span class="cx"> }
</span><span class="cx"> $gotFirstLine = true;
</span><span class="lines">@@ -581,16 +685,17 @@
</span><span class="cx"> $gettingHeaders = false;
</span><span class="cx"> }
</span><span class="cx"> if (!$gettingHeaders) {
</span><del>-         // WP#12559 remove trim so as to not strip newlines from received response.
</del><ins>+         // merged from WP #12559 - remove trim
</ins><span class="cx"> $contents .= $line;
</span><span class="cx"> }
</span><span class="cx"> if ($this->debug) {
</span><del>- $debug_contents .= $line;
</del><ins>+         $debugContents .= $line;
</ins><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx"> if ($this->debug) {
</span><del>- echo '<pre class="ixr_response">'.htmlspecialchars($debug_contents)."\n</pre>\n\n";
</del><ins>+ echo '<pre class="ixr_response">'.htmlspecialchars($debugContents)."\n</pre>\n\n";
</ins><span class="cx"> }
</span><ins>+
</ins><span class="cx"> // Now parse what we've got back
</span><span class="cx"> $this->message = new IXR_Message($contents);
</span><span class="cx"> if (!$this->message->parse()) {
</span><span class="lines">@@ -598,44 +703,59 @@
</span><span class="cx"> $this->error = new IXR_Error(-32700, 'parse error. not well formed');
</span><span class="cx"> return false;
</span><span class="cx"> }
</span><ins>+
</ins><span class="cx"> // Is the message a fault?
</span><span class="cx"> if ($this->message->messageType == 'fault') {
</span><span class="cx"> $this->error = new IXR_Error($this->message->faultCode, $this->message->faultString);
</span><span class="cx"> return false;
</span><span class="cx"> }
</span><ins>+
</ins><span class="cx"> // Message must be OK
</span><span class="cx"> return true;
</span><span class="cx"> }
</span><del>- function getResponse() {
</del><ins>+
+ function getResponse()
+ {
</ins><span class="cx"> // methodResponses can only have one param - return that
</span><span class="cx"> return $this->message->params[0];
</span><span class="cx"> }
</span><del>- function isError() {
</del><ins>+
+ function isError()
+ {
</ins><span class="cx"> return (is_object($this->error));
</span><span class="cx"> }
</span><del>- function getErrorCode() {
</del><ins>+
+ function getErrorCode()
+ {
</ins><span class="cx"> return $this->error->code;
</span><span class="cx"> }
</span><del>- function getErrorMessage() {
</del><ins>+
+ function getErrorMessage()
+ {
</ins><span class="cx"> return $this->error->message;
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+
</ins><span class="cx"> /**
</span><span class="cx"> * IXR_Error
</span><span class="cx"> *
</span><span class="cx"> * @package IXR
</span><span class="cx"> * @since 1.5
</span><span class="cx"> */
</span><del>-class IXR_Error {
</del><ins>+class IXR_Error
+{
</ins><span class="cx"> var $code;
</span><span class="cx"> var $message;
</span><del>- function IXR_Error($code, $message) {
</del><ins>+
+ function IXR_Error($code, $message)
+ {
</ins><span class="cx"> $this->code = $code;
</span><del>- // WP adds htmlspecialchars(). See #5666
</del><span class="cx"> $this->message = htmlspecialchars($message);
</span><span class="cx"> }
</span><del>- function getXml() {
</del><ins>+
+ function getXml()
+ {
</ins><span class="cx"> $xml = <<<EOD
</span><span class="cx"> <methodResponse>
</span><span class="cx"> <fault>
</span><span class="lines">@@ -673,7 +793,9 @@
</span><span class="cx"> var $minute;
</span><span class="cx"> var $second;
</span><span class="cx"> var $timezone;
</span><del>- function IXR_Date($time) {
</del><ins>+
+ function IXR_Date($time)
+ {
</ins><span class="cx"> // $time can be a PHP timestamp or an ISO one
</span><span class="cx"> if (is_numeric($time)) {
</span><span class="cx"> $this->parseTimestamp($time);
</span><span class="lines">@@ -681,34 +803,41 @@
</span><span class="cx"> $this->parseIso($time);
</span><span class="cx"> }
</span><span class="cx"> }
</span><del>- function parseTimestamp($timestamp) {
</del><ins>+
+ function parseTimestamp($timestamp)
+ {
</ins><span class="cx"> $this->year = date('Y', $timestamp);
</span><span class="cx"> $this->month = date('m', $timestamp);
</span><span class="cx"> $this->day = date('d', $timestamp);
</span><span class="cx"> $this->hour = date('H', $timestamp);
</span><span class="cx"> $this->minute = date('i', $timestamp);
</span><span class="cx"> $this->second = date('s', $timestamp);
</span><del>- // WP adds timezone. See #2036
</del><span class="cx"> $this->timezone = '';
</span><span class="cx"> }
</span><del>- function parseIso($iso) {
</del><ins>+
+ function parseIso($iso)
+ {
</ins><span class="cx"> $this->year = substr($iso, 0, 4);
</span><span class="cx"> $this->month = substr($iso, 4, 2);
</span><span class="cx"> $this->day = substr($iso, 6, 2);
</span><span class="cx"> $this->hour = substr($iso, 9, 2);
</span><span class="cx"> $this->minute = substr($iso, 12, 2);
</span><span class="cx"> $this->second = substr($iso, 15, 2);
</span><del>- // WP adds timezone. See #2036
</del><span class="cx"> $this->timezone = substr($iso, 17);
</span><span class="cx"> }
</span><del>- function getIso() {
-         // WP adds timezone. See #2036
</del><ins>+
+ function getIso()
+ {
</ins><span class="cx"> return $this->year.$this->month.$this->day.'T'.$this->hour.':'.$this->minute.':'.$this->second.$this->timezone;
</span><span class="cx"> }
</span><del>- function getXml() {
</del><ins>+
+ function getXml()
+ {
</ins><span class="cx"> return '<dateTime.iso8601>'.$this->getIso().'</dateTime.iso8601>';
</span><span class="cx"> }
</span><del>- function getTimestamp() {
</del><ins>+
+ function getTimestamp()
+ {
</ins><span class="cx"> return mktime($this->hour, $this->minute, $this->second, $this->month, $this->day, $this->year);
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="lines">@@ -719,12 +848,17 @@
</span><span class="cx"> * @package IXR
</span><span class="cx"> * @since 1.5
</span><span class="cx"> */
</span><del>-class IXR_Base64 {
</del><ins>+class IXR_Base64
+{
</ins><span class="cx"> var $data;
</span><del>- function IXR_Base64($data) {
</del><ins>+
+ function IXR_Base64($data)
+ {
</ins><span class="cx"> $this->data = $data;
</span><span class="cx"> }
</span><del>- function getXml() {
</del><ins>+
+ function getXml()
+ {
</ins><span class="cx"> return '<base64>'.base64_encode($this->data).'</base64>';
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="lines">@@ -735,10 +869,13 @@
</span><span class="cx"> * @package IXR
</span><span class="cx"> * @since 1.5
</span><span class="cx"> */
</span><del>-class IXR_IntrospectionServer extends IXR_Server {
</del><ins>+class IXR_IntrospectionServer extends IXR_Server
+{
</ins><span class="cx"> var $signatures;
</span><span class="cx"> var $help;
</span><del>- function IXR_IntrospectionServer() {
</del><ins>+
+ function IXR_IntrospectionServer()
+ {
</ins><span class="cx"> $this->setCallbacks();
</span><span class="cx"> $this->setCapabilities();
</span><span class="cx"> $this->capabilities['introspection'] = array(
</span><span class="lines">@@ -770,16 +907,21 @@
</span><span class="cx"> 'Returns a documentation string for the specified method'
</span><span class="cx"> );
</span><span class="cx"> }
</span><del>- function addCallback($method, $callback, $args, $help) {
</del><ins>+
+ function addCallback($method, $callback, $args, $help)
+ {
</ins><span class="cx"> $this->callbacks[$method] = $callback;
</span><span class="cx"> $this->signatures[$method] = $args;
</span><span class="cx"> $this->help[$method] = $help;
</span><span class="cx"> }
</span><del>- function call($methodname, $args) {
</del><ins>+
+ function call($methodname, $args)
+ {
</ins><span class="cx"> // Make sure it's in an array
</span><span class="cx"> if ($args && !is_array($args)) {
</span><span class="cx"> $args = array($args);
</span><span class="cx"> }
</span><ins>+
</ins><span class="cx"> // Over-rides default call method, adds signature check
</span><span class="cx"> if (!$this->hasMethod($methodname)) {
</span><span class="cx"> return new IXR_Error(-32601, 'server error. requested method "'.$this->message->methodName.'" not specified.');
</span><span class="lines">@@ -787,10 +929,12 @@
</span><span class="cx"> $method = $this->callbacks[$methodname];
</span><span class="cx"> $signature = $this->signatures[$methodname];
</span><span class="cx"> $returnType = array_shift($signature);
</span><ins>+
</ins><span class="cx"> // Check the number of arguments
</span><span class="cx"> if (count($args) != count($signature)) {
</span><span class="cx"> return new IXR_Error(-32602, 'server error. wrong number of method parameters');
</span><span class="cx"> }
</span><ins>+
</ins><span class="cx"> // Check the argument types
</span><span class="cx"> $ok = true;
</span><span class="cx"> $argsbackup = $args;
</span><span class="lines">@@ -835,7 +979,9 @@
</span><span class="cx"> // It passed the test - run the "real" method call
</span><span class="cx"> return parent::call($methodname, $argsbackup);
</span><span class="cx"> }
</span><del>- function methodSignature($method) {
</del><ins>+
+ function methodSignature($method)
+ {
</ins><span class="cx"> if (!$this->hasMethod($method)) {
</span><span class="cx"> return new IXR_Error(-32601, 'server error. requested method "'.$method.'" not specified.');
</span><span class="cx"> }
</span><span class="lines">@@ -873,7 +1019,9 @@
</span><span class="cx"> }
</span><span class="cx"> return $return;
</span><span class="cx"> }
</span><del>- function methodHelp($method) {
</del><ins>+
+ function methodHelp($method)
+ {
</ins><span class="cx"> return $this->help[$method];
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="lines">@@ -884,13 +1032,18 @@
</span><span class="cx"> * @package IXR
</span><span class="cx"> * @since 1.5
</span><span class="cx"> */
</span><del>-class IXR_ClientMulticall extends IXR_Client {
</del><ins>+class IXR_ClientMulticall extends IXR_Client
+{
</ins><span class="cx"> var $calls = array();
</span><del>- function IXR_ClientMulticall($server, $path = false, $port = 80) {
</del><ins>+
+ function IXR_ClientMulticall($server, $path = false, $port = 80)
+ {
</ins><span class="cx"> parent::IXR_Client($server, $path, $port);
</span><span class="cx"> $this->useragent = 'The Incutio XML-RPC PHP Library (multicall client)';
</span><span class="cx"> }
</span><del>- function addCall() {
</del><ins>+
+ function addCall()
+ {
</ins><span class="cx"> $args = func_get_args();
</span><span class="cx"> $methodName = array_shift($args);
</span><span class="cx"> $struct = array(
</span><span class="lines">@@ -899,7 +1052,9 @@
</span><span class="cx"> );
</span><span class="cx"> $this->calls[] = $struct;
</span><span class="cx"> }
</span><del>- function query() {
</del><ins>+
+ function query()
+ {
</ins><span class="cx"> // Prepare multicall, then call the parent::query() method
</span><span class="cx"> return parent::query('system.multicall', $this->calls);
</span><span class="cx"> }
</span></span></pre>
</div>
</div>
</body>
</html>