<!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"> &lt;?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 &quot;AS
+ * IS&quot; 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-&gt;data = $data;
</span><span class="cx">         if (!$type) {
</span><span class="cx">             $type = $this-&gt;calculateType();
</span><span class="cx">         }
</span><span class="cx">         $this-&gt;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-&gt;data as $key =&gt; $value) {
</span><span class="cx">                 $this-&gt;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-&gt;data === true || $this-&gt;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-&gt;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-&gt;data) &amp;&amp; is_a($this-&gt;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-&gt;data) &amp;&amp; is_a($this-&gt;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-&gt;data)) {
</span><del>-
</del><span class="cx">             $this-&gt;data = get_object_vars($this-&gt;data);
</span><span class="cx">             return 'struct';
</span><span class="cx">         }
</span><span class="cx">         if (!is_array($this-&gt;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-&gt;isStruct($this-&gt;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-&gt;type) {
</span><span class="cx">             case 'boolean':
</span><span class="cx">                 return '&lt;boolean&gt;'.(($this-&gt;data) ? '1' : '0').'&lt;/boolean&gt;';
</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 =&gt; $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 (&amp;$message) {
-        $this-&gt;message = &amp;$message;
</del><ins>+
+    function IXR_Message($message)
+    {
+        $this-&gt;message =&amp; $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( '/&lt;\?xml.*?\?'.'&gt;/', '', substr( $this-&gt;message, 0, 100 ), 1 );
-                $this-&gt;message = substr_replace($this-&gt;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( '/&lt;\?xml.*?\?'.'&gt;/', '', substr($this-&gt;message, 0, 100), 1);
+        $this-&gt;message = substr_replace($this-&gt;message, $header, 0, 100);
</ins><span class="cx">         if (trim($this-&gt;message) == '') {
</span><span class="cx">             return false;
</span><del>-                }
</del><ins>+        }
</ins><span class="cx">         $this-&gt;_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-&gt;_parser, XML_OPTION_CASE_FOLDING, false);
</span><span class="cx">         // Set XML parser callback functions
</span><span class="cx">         xml_set_object($this-&gt;_parser, $this);
</span><span class="cx">         xml_set_element_handler($this-&gt;_parser, 'tag_open', 'tag_close');
</span><del>-                xml_set_character_data_handler($this-&gt;_parser, 'cdata');
-                $chunk_size = 262144; // 256Kb, parse in chunks to avoid the RAM usage on very large messages
-                do {
-                        if ( strlen($this-&gt;message) &lt;= $chunk_size )
-                                $final=true;
-                        $part = substr( $this-&gt;message, 0, $chunk_size );
-                        $this-&gt;message = substr( $this-&gt;message, $chunk_size );
-                        if ( !xml_parse( $this-&gt;_parser, $part, $final ) )
-                                return false;
-                        if ( $final )
-                                break;
-                } while ( true );
-                xml_parser_free($this-&gt;_parser);
</del><ins>+        xml_set_character_data_handler($this-&gt;_parser, 'cdata');
+        $chunk_size = 262144; // 256Kb, parse in chunks to avoid the RAM usage on very large messages
+        do {
+            if (strlen($this-&gt;message) &lt;= $chunk_size) {
+                $final = true;
+            }
+            $part = substr($this-&gt;message, 0, $chunk_size);
+            $this-&gt;message = substr($this-&gt;message, $chunk_size);
+            if (!xml_parse($this-&gt;_parser, $part, $final)) {
+                return false;
+            }
+            if ($final) {
+                break;
+            }
+        } while (true);
+        xml_parser_free($this-&gt;_parser);
+
</ins><span class="cx">         // Grab the error messages, if any
</span><span class="cx">         if ($this-&gt;messageType == 'fault') {
</span><span class="cx">             $this-&gt;faultCode = $this-&gt;params[0]['faultCode'];
</span><span class="cx">             $this-&gt;faultString = $this-&gt;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-&gt;_currentTagContents = '';
</span><span class="cx">         $this-&gt;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-&gt;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-&gt;_arraystructstypes[] = 'array';
</span><span class="cx">                 $this-&gt;_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-&gt;_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-&gt;_currentTagContents);
</del><ins>+                $value = (int)trim($this-&gt;_currentTagContents);
</ins><span class="cx">                 $valueFlag = true;
</span><span class="cx">                 break;
</span><span class="cx">             case 'double':
</span><del>-                $value = (double) trim($this-&gt;_currentTagContents);
</del><ins>+                $value = (double)trim($this-&gt;_currentTagContents);
</ins><span class="cx">                 $valueFlag = true;
</span><span class="cx">                 break;
</span><span class="cx">             case 'string':
</span><del>-                $value = $this-&gt;_currentTagContents;
</del><ins>+                $value = (string)trim($this-&gt;_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-&gt;_currentTagContents));
</span><del>-                // $value = $iso-&gt;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-&gt;_currentTagContents);
</del><ins>+                $value = (boolean)trim($this-&gt;_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-&gt;_currentTagContents ) );
</del><ins>+                $value = base64_decode($this-&gt;_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-&gt;_arraystructs);
</span><span class="lines">@@ -266,6 +319,7 @@
</span><span class="cx">                 $this-&gt;methodName = trim($this-&gt;_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-&gt;_arraystructs) &gt; 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-&gt;setCapabilities();
</span><span class="cx">         if ($callbacks) {
</span><span class="cx">             $this-&gt;callbacks = $callbacks;
</span><span class="cx">         }
</span><span class="cx">         $this-&gt;setCallbacks();
</span><del>-        $this-&gt;serve($data);
</del><ins>+        if (!$wait) {
+            $this-&gt;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']) &amp;&amp; $_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 =&amp; $HTTP_RAW_POST_DATA;
</ins><span class="cx">             }
</span><del>-            $data = &amp;$HTTP_RAW_POST_DATA;
</del><span class="cx">         }
</span><span class="cx">         $this-&gt;message = new IXR_Message($data);
</span><span class="cx">         if (!$this-&gt;message-&gt;parse()) {
</span><span class="lines">@@ -321,75 +388,83 @@
</span><span class="cx">             $this-&gt;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-&gt;call($this-&gt;message-&gt;methodName, $this-&gt;message-&gt;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-&gt;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-&gt;getXml();
</span><ins>+
</ins><span class="cx">         // Create the XML
</span><span class="cx">         $xml = &lt;&lt;&lt;EOD
</span><span class="cx"> &lt;methodResponse&gt;
</span><span class="cx">   &lt;params&gt;
</span><span class="cx">     &lt;param&gt;
</span><span class="cx">       &lt;value&gt;
</span><del>-        $resultxml
</del><ins>+      $resultxml
</ins><span class="cx">       &lt;/value&gt;
</span><span class="cx">     &lt;/param&gt;
</span><span class="cx">   &lt;/params&gt;
</span><span class="cx"> &lt;/methodResponse&gt;
</span><span class="cx"> 
</span><span class="cx"> EOD;
</span><del>-        // Send it
-        $this-&gt;output($xml);
</del><ins>+      // Send it
+      $this-&gt;output($xml);
</ins><span class="cx">     }
</span><del>-    function call($methodname, $args) {
</del><ins>+
+    function call($methodname, $args)
+    {
</ins><span class="cx">         if (!$this-&gt;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-&gt;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 ) &amp;&amp; substr($method, 0, 5) == 'this:' ) {
</del><ins>+        if (is_string($method) &amp;&amp; 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 &quot;'.
-                    $method.'&quot; does not exist.');
</del><ins>+                return new IXR_Error(-32601, 'server error. requested class method &quot;'.$method.'&quot; does not exist.');
</ins><span class="cx">             }
</span><del>-            // Call the method
</del><ins>+
+            //Call the method
</ins><span class="cx">             $result = $this-&gt;$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 &quot;'.
-                        $method[1].'&quot; does not exist.');
</del><ins>+                    return new IXR_Error(-32601, 'server error. requested object method &quot;'.$method[1].'&quot; 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 &quot;'.
-                    $method.'&quot; does not exist.');
</del><ins>+                return new IXR_Error(-32601, 'server error. requested function &quot;'.$method.'&quot; 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 &amp;&amp; !is_object($error)) {
</span><span class="cx">             $error = new IXR_Error($error, $message);
</span><span class="cx">         }
</span><span class="cx">         $this-&gt;output($error-&gt;getXml());
</span><span class="cx">     }
</span><del>-    function output($xml) {
</del><ins>+
+    function output($xml)
+    {
</ins><span class="cx">         $xml = '&lt;?xml version=&quot;1.0&quot;?&gt;'.&quot;\n&quot;.$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-&gt;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-&gt;capabilities = array(
</span><span class="cx">             'xmlrpc' =&gt; array(
</span><span class="cx">                 'specUrl' =&gt; 'http://www.xmlrpc.com/spec',
</span><span class="cx">                 'specVersion' =&gt; 1
</span><del>-            ),
</del><ins>+        ),
</ins><span class="cx">             'faults_interop' =&gt; array(
</span><span class="cx">                 'specUrl' =&gt; 'http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php',
</span><span class="cx">                 'specVersion' =&gt; 20010516
</span><del>-            ),
</del><ins>+        ),
</ins><span class="cx">             'system.multicall' =&gt; array(
</span><span class="cx">                 'specUrl' =&gt; 'http://www.xmlrpc.com/discuss/msgReader$1208',
</span><span class="cx">                 'specVersion' =&gt; 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-&gt;capabilities;
</span><span class="cx">     }
</span><del>-    function setCallbacks() {
</del><ins>+
+    function setCallbacks()
+    {
</ins><span class="cx">         $this-&gt;callbacks['system.getCapabilities'] = 'this:getCapabilities';
</span><span class="cx">         $this-&gt;callbacks['system.listMethods'] = 'this:listMethods';
</span><span class="cx">         $this-&gt;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-&gt;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-&gt;method = $method;
</span><span class="cx">         $this-&gt;args = $args;
</span><span class="cx">         $this-&gt;xml = &lt;&lt;&lt;EOD
</span><span class="lines">@@ -484,10 +574,14 @@
</span><span class="cx">         }
</span><span class="cx">         $this-&gt;xml .= '&lt;/params&gt;&lt;/methodCall&gt;';
</span><span class="cx">     }
</span><del>-    function getLength() {
</del><ins>+
+    function getLength()
+    {
</ins><span class="cx">         return strlen($this-&gt;xml);
</span><span class="cx">     }
</span><del>-    function getXml() {
</del><ins>+
+    function getXml()
+    {
</ins><span class="cx">         return $this-&gt;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-&gt;server = $bits['host'];
</span><span class="cx">             $this-&gt;port = isset($bits['port']) ? $bits['port'] : 80;
</span><span class="cx">             $this-&gt;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-&gt;path) {
</span><span class="cx">                 $this-&gt;path = '/';
</span><span class="lines">@@ -529,7 +628,9 @@
</span><span class="cx">         $this-&gt;useragent = 'The Incutio XML-RPC PHP Library';
</span><span class="cx">         $this-&gt;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 = &quot;\r\n&quot;;
</span><span class="cx">         $request  = &quot;POST {$this-&gt;path} HTTP/1.0$r&quot;;
</span><span class="cx"> 
</span><del>-                $this-&gt;headers['Host']                        = $this-&gt;server;
-                $this-&gt;headers['Content-Type']        = 'text/xml';
-                $this-&gt;headers['User-Agent']        = $this-&gt;useragent;
-                $this-&gt;headers['Content-Length']= $length;
</del><ins>+        // Merged from WP #8145 - allow custom headers
+        $this-&gt;headers['Host']          = $this-&gt;server;
+        $this-&gt;headers['Content-Type']  = 'text/xml';
+        $this-&gt;headers['User-Agent']    = $this-&gt;useragent;
+        $this-&gt;headers['Content-Length']= $length;
</ins><span class="cx"> 
</span><del>-                foreach( $this-&gt;headers as $header =&gt; $value ) {
-                        $request .= &quot;{$header}: {$value}{$r}&quot;;
-                }
-                $request .= $r;
</del><ins>+        foreach( $this-&gt;headers as $header =&gt; $value ) {
+            $request .= &quot;{$header}: {$value}{$r}&quot;;
+        }
+        $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-&gt;debug) {
</span><span class="cx">             echo '&lt;pre class=&quot;ixr_request&quot;&gt;'.htmlspecialchars($request).&quot;\n&lt;/pre&gt;\n\n&quot;;
</span><span class="cx">         }
</span><ins>+
</ins><span class="cx">         if ($this-&gt;timeout) {
</span><span class="cx">             $fp = @fsockopen($this-&gt;server, $this-&gt;port, $errno, $errstr, $this-&gt;timeout);
</span><span class="cx">         } else {
</span><span class="cx">             $fp = @fsockopen($this-&gt;server, $this-&gt;port, $errno, $errstr);
</span><span class="cx">         }
</span><span class="cx">         if (!$fp) {
</span><del>-            $this-&gt;error = new IXR_Error(-32300, &quot;transport error - could not open socket: $errno $errstr&quot;);
</del><ins>+            $this-&gt;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-&gt;error = new IXR_Error(-32301, 'transport error - HTTP status code was not 200');
</del><ins>+                    $this-&gt;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-&gt;debug) {
</span><del>-                $debug_contents .= $line;
</del><ins>+                    $debugContents .= $line;
</ins><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx">         if ($this-&gt;debug) {
</span><del>-            echo '&lt;pre class=&quot;ixr_response&quot;&gt;'.htmlspecialchars($debug_contents).&quot;\n&lt;/pre&gt;\n\n&quot;;
</del><ins>+            echo '&lt;pre class=&quot;ixr_response&quot;&gt;'.htmlspecialchars($debugContents).&quot;\n&lt;/pre&gt;\n\n&quot;;
</ins><span class="cx">         }
</span><ins>+
</ins><span class="cx">         // Now parse what we've got back
</span><span class="cx">         $this-&gt;message = new IXR_Message($contents);
</span><span class="cx">         if (!$this-&gt;message-&gt;parse()) {
</span><span class="lines">@@ -598,44 +703,59 @@
</span><span class="cx">             $this-&gt;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-&gt;message-&gt;messageType == 'fault') {
</span><span class="cx">             $this-&gt;error = new IXR_Error($this-&gt;message-&gt;faultCode, $this-&gt;message-&gt;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-&gt;message-&gt;params[0];
</span><span class="cx">     }
</span><del>-    function isError() {
</del><ins>+
+    function isError()
+    {
</ins><span class="cx">         return (is_object($this-&gt;error));
</span><span class="cx">     }
</span><del>-    function getErrorCode() {
</del><ins>+
+    function getErrorCode()
+    {
</ins><span class="cx">         return $this-&gt;error-&gt;code;
</span><span class="cx">     }
</span><del>-    function getErrorMessage() {
</del><ins>+
+    function getErrorMessage()
+    {
</ins><span class="cx">         return $this-&gt;error-&gt;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-&gt;code = $code;
</span><del>-        // WP adds htmlspecialchars(). See #5666
</del><span class="cx">         $this-&gt;message = htmlspecialchars($message);
</span><span class="cx">     }
</span><del>-    function getXml() {
</del><ins>+
+    function getXml()
+    {
</ins><span class="cx">         $xml = &lt;&lt;&lt;EOD
</span><span class="cx"> &lt;methodResponse&gt;
</span><span class="cx">   &lt;fault&gt;
</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-&gt;parseTimestamp($time);
</span><span class="lines">@@ -681,34 +803,41 @@
</span><span class="cx">             $this-&gt;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-&gt;year = date('Y', $timestamp);
</span><span class="cx">         $this-&gt;month = date('m', $timestamp);
</span><span class="cx">         $this-&gt;day = date('d', $timestamp);
</span><span class="cx">         $this-&gt;hour = date('H', $timestamp);
</span><span class="cx">         $this-&gt;minute = date('i', $timestamp);
</span><span class="cx">         $this-&gt;second = date('s', $timestamp);
</span><del>-        // WP adds timezone. See #2036
</del><span class="cx">         $this-&gt;timezone = '';
</span><span class="cx">     }
</span><del>-    function parseIso($iso) {
</del><ins>+
+    function parseIso($iso)
+    {
</ins><span class="cx">         $this-&gt;year = substr($iso, 0, 4);
</span><span class="cx">         $this-&gt;month = substr($iso, 4, 2);
</span><span class="cx">         $this-&gt;day = substr($iso, 6, 2);
</span><span class="cx">         $this-&gt;hour = substr($iso, 9, 2);
</span><span class="cx">         $this-&gt;minute = substr($iso, 12, 2);
</span><span class="cx">         $this-&gt;second = substr($iso, 15, 2);
</span><del>-        // WP adds timezone. See #2036
</del><span class="cx">         $this-&gt;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-&gt;year.$this-&gt;month.$this-&gt;day.'T'.$this-&gt;hour.':'.$this-&gt;minute.':'.$this-&gt;second.$this-&gt;timezone;
</span><span class="cx">     }
</span><del>-    function getXml() {
</del><ins>+
+    function getXml()
+    {
</ins><span class="cx">         return '&lt;dateTime.iso8601&gt;'.$this-&gt;getIso().'&lt;/dateTime.iso8601&gt;';
</span><span class="cx">     }
</span><del>-    function getTimestamp() {
</del><ins>+
+    function getTimestamp()
+    {
</ins><span class="cx">         return mktime($this-&gt;hour, $this-&gt;minute, $this-&gt;second, $this-&gt;month, $this-&gt;day, $this-&gt;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-&gt;data = $data;
</span><span class="cx">     }
</span><del>-    function getXml() {
</del><ins>+
+    function getXml()
+    {
</ins><span class="cx">         return '&lt;base64&gt;'.base64_encode($this-&gt;data).'&lt;/base64&gt;';
</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-&gt;setCallbacks();
</span><span class="cx">         $this-&gt;setCapabilities();
</span><span class="cx">         $this-&gt;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-&gt;callbacks[$method] = $callback;
</span><span class="cx">         $this-&gt;signatures[$method] = $args;
</span><span class="cx">         $this-&gt;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 &amp;&amp; !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-&gt;hasMethod($methodname)) {
</span><span class="cx">             return new IXR_Error(-32601, 'server error. requested method &quot;'.$this-&gt;message-&gt;methodName.'&quot; not specified.');
</span><span class="lines">@@ -787,10 +929,12 @@
</span><span class="cx">         $method = $this-&gt;callbacks[$methodname];
</span><span class="cx">         $signature = $this-&gt;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 &quot;real&quot; 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-&gt;hasMethod($method)) {
</span><span class="cx">             return new IXR_Error(-32601, 'server error. requested method &quot;'.$method.'&quot; 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-&gt;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-&gt;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-&gt;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-&gt;calls);
</span><span class="cx">     }
</span></span></pre>
</div>
</div>

</body>
</html>