upgrade to codeigniter 1.7.2 for f12
[www-register-wizard.git] / libraries / Xmlrpc.php
index c9e7972..5460842 100644 (file)
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');\r
-/**\r
- * CodeIgniter\r
- *\r
- * An open source application development framework for PHP 4.3.2 or newer\r
- *\r
- * @package            CodeIgniter\r
- * @author             ExpressionEngine Dev Team\r
- * @copyright  Copyright (c) 2008, EllisLab, Inc.\r
- * @license            http://codeigniter.com/user_guide/license.html\r
- * @link               http://codeigniter.com\r
- * @since              Version 1.0\r
- * @filesource\r
- */\r
-\r
-if ( ! function_exists('xml_parser_create'))\r
-{      \r
-       show_error('Your PHP installation does not support XML');\r
-}\r
-\r
-\r
-// ------------------------------------------------------------------------\r
-\r
-/**\r
- * XML-RPC request handler class\r
- *\r
- * @package            CodeIgniter\r
- * @subpackage Libraries\r
- * @category   XML-RPC\r
- * @author             ExpressionEngine Dev Team\r
- * @link               http://codeigniter.com/user_guide/libraries/xmlrpc.html\r
- */\r
-class CI_Xmlrpc {\r
-\r
-       var $debug                      = FALSE;        // Debugging on or off  \r
-       var $xmlrpcI4           = 'i4';\r
-       var $xmlrpcInt          = 'int';\r
-       var $xmlrpcBoolean      = 'boolean';\r
-       var $xmlrpcDouble       = 'double';     \r
-       var $xmlrpcString       = 'string';\r
-       var $xmlrpcDateTime     = 'datetime.iso8601';\r
-       var $xmlrpcBase64       = 'base64';\r
-       var $xmlrpcArray        = 'array';\r
-       var $xmlrpcStruct       = 'struct';\r
-       \r
-       var $xmlrpcTypes        = array();\r
-       var $valid_parents      = array();\r
-       var $xmlrpcerr          = array();      // Response numbers\r
-       var $xmlrpcstr          = array();  // Response strings\r
-       \r
-       var $xmlrpc_defencoding = 'UTF-8';\r
-       var $xmlrpcName                 = 'XML-RPC for CodeIgniter';\r
-       var $xmlrpcVersion              = '1.1';\r
-       var $xmlrpcerruser              = 800; // Start of user errors\r
-       var $xmlrpcerrxml               = 100; // Start of XML Parse errors\r
-       var $xmlrpc_backslash   = ''; // formulate backslashes for escaping regexp\r
-       \r
-       var $client;\r
-       var $method;\r
-       var $data;\r
-       var $message                    = '';\r
-       var $error                              = '';           // Error string for request\r
-       var $result;\r
-       var $response                   = array();  // Response from remote server\r
-\r
-\r
-       //-------------------------------------\r
-       //  VALUES THAT MULTIPLE CLASSES NEED\r
-       //-------------------------------------\r
-\r
-       function CI_Xmlrpc ($config = array())\r
-       {\r
-               $this->xmlrpcName               = $this->xmlrpcName;\r
-               $this->xmlrpc_backslash = chr(92).chr(92);\r
-               \r
-               // Types for info sent back and forth\r
-               $this->xmlrpcTypes = array(\r
-                       $this->xmlrpcI4    => '1',\r
-                       $this->xmlrpcInt          => '1',\r
-                       $this->xmlrpcBoolean  => '1',\r
-                       $this->xmlrpcString   => '1',\r
-                       $this->xmlrpcDouble   => '1',\r
-                       $this->xmlrpcDateTime => '1',\r
-                       $this->xmlrpcBase64   => '1',\r
-                       $this->xmlrpcArray      => '2',\r
-                       $this->xmlrpcStruct   => '3'\r
-                       );\r
-                       \r
-               // Array of Valid Parents for Various XML-RPC elements\r
-               $this->valid_parents = array('BOOLEAN'                  => array('VALUE'),\r
-                                                                        'I4'                           => array('VALUE'),\r
-                                                                        'INT'                          => array('VALUE'),\r
-                                                                        'STRING'                       => array('VALUE'),\r
-                                                                        'DOUBLE'                       => array('VALUE'),\r
-                                                                        'DATETIME.ISO8601'     => array('VALUE'),\r
-                                                                        'BASE64'                       => array('VALUE'),\r
-                                                                        'ARRAY'                        => array('VALUE'),\r
-                                                                        'STRUCT'                       => array('VALUE'),\r
-                                                                        'PARAM'                        => array('PARAMS'),\r
-                                                                        'METHODNAME'           => array('METHODCALL'),\r
-                                                                        'PARAMS'                       => array('METHODCALL', 'METHODRESPONSE'),\r
-                                                                        'MEMBER'                       => array('STRUCT'),\r
-                                                                        'NAME'                         => array('MEMBER'),\r
-                                                                        'DATA'                         => array('ARRAY'),\r
-                                                                        'FAULT'                        => array('METHODRESPONSE'),\r
-                                                                        'VALUE'                        => array('MEMBER', 'DATA', 'PARAM', 'FAULT')\r
-                                                                        );\r
-                       \r
-                       \r
-               // XML-RPC Responses\r
-               $this->xmlrpcerr['unknown_method'] = '1';\r
-               $this->xmlrpcstr['unknown_method'] = 'This is not a known method for this XML-RPC Server';\r
-               $this->xmlrpcerr['invalid_return'] = '2';\r
-               $this->xmlrpcstr['invalid_return'] = 'The XML data receieved was either invalid or not in the correct form for XML-RPC.  Turn on debugging to examine the XML data further.';\r
-               $this->xmlrpcerr['incorrect_params'] = '3';\r
-               $this->xmlrpcstr['incorrect_params'] = 'Incorrect parameters were passed to method';\r
-               $this->xmlrpcerr['introspect_unknown'] = '4';\r
-               $this->xmlrpcstr['introspect_unknown'] = "Cannot inspect signature for request: method unknown";\r
-               $this->xmlrpcerr['http_error'] = '5';\r
-               $this->xmlrpcstr['http_error'] = "Did not receive a '200 OK' response from remote server.";\r
-               $this->xmlrpcerr['no_data'] = '6';\r
-               $this->xmlrpcstr['no_data'] ='No data received from server.';\r
-               \r
-               $this->initialize($config);\r
-               \r
-               log_message('debug', "XML-RPC Class Initialized");\r
-       }\r
-       \r
-       \r
-       //-------------------------------------\r
-       //  Initialize Prefs\r
-       //-------------------------------------\r
-\r
-       function initialize($config = array())\r
-       {\r
-               if (sizeof($config) > 0)\r
-               {\r
-                       foreach ($config as $key => $val)\r
-                       {\r
-                               if (isset($this->$key))\r
-                               {\r
-                                       $this->$key = $val;                     \r
-                               }\r
-                       }\r
-               }\r
-       }\r
-       // END\r
-       \r
-       //-------------------------------------\r
-       //  Take URL and parse it\r
-       //-------------------------------------\r
-\r
-       function server($url, $port=80)\r
-       {\r
-               if (substr($url, 0, 4) != "http")\r
-               {\r
-                       $url = "http://".$url;\r
-               }\r
-               \r
-               $parts = parse_url($url);\r
-               \r
-               $path = ( ! isset($parts['path'])) ? '/' : $parts['path'];\r
-               \r
-               if (isset($parts['query']) && $parts['query'] != '')\r
-               {\r
-                       $path .= '?'.$parts['query'];\r
-               }       \r
-               \r
-               $this->client = new XML_RPC_Client($path, $parts['host'], $port);\r
-       }\r
-       // END\r
-       \r
-       //-------------------------------------\r
-       //  Set Timeout\r
-       //-------------------------------------\r
-\r
-       function timeout($seconds=5)\r
-       {\r
-               if ( ! is_null($this->client) && is_int($seconds))\r
-               {\r
-                       $this->client->timeout = $seconds;\r
-               }\r
-       }\r
-       // END\r
-       \r
-       //-------------------------------------\r
-       //  Set Methods\r
-       //-------------------------------------\r
-\r
-       function method($function)\r
-       {\r
-               $this->method = $function;\r
-       }\r
-       // END\r
-       \r
-       //-------------------------------------\r
-       //  Take Array of Data and Create Objects\r
-       //-------------------------------------\r
-\r
-       function request($incoming)\r
-       {\r
-               if ( ! is_array($incoming))\r
-               {\r
-                       // Send Error\r
-               }\r
-               \r
-               $this->data = array();\r
-               \r
-               foreach($incoming as $key => $value)\r
-               {\r
-                       $this->data[$key] = $this->values_parsing($value);\r
-               }\r
-       }\r
-       // END\r
-       \r
-       \r
-       //-------------------------------------\r
-       //  Set Debug\r
-       //-------------------------------------\r
-\r
-       function set_debug($flag = TRUE)\r
-       {\r
-               $this->debug = ($flag == TRUE) ? TRUE : FALSE;\r
-       }\r
-       \r
-       //-------------------------------------\r
-       //  Values Parsing\r
-       //-------------------------------------\r
-\r
-       function values_parsing($value, $return = FALSE)\r
-       {\r
-               if (is_array($value) && isset($value['0']))\r
-               {\r
-                       if ( ! isset($value['1']) OR ! isset($this->xmlrpcTypes[strtolower($value['1'])]))\r
-                       {\r
-                               if (is_array($value[0]))\r
-                               {\r
-                                       $temp = new XML_RPC_Values($value['0'], 'array');\r
-                               }\r
-                               else\r
-                               {\r
-                                       $temp = new XML_RPC_Values($value['0'], 'string');\r
-                               }\r
-                       }\r
-                       elseif(is_array($value['0']) && ($value['1'] == 'struct' OR $value['1'] == 'array'))\r
-                       {\r
-                               while (list($k) = each($value['0']))\r
-                               {\r
-                                       $value['0'][$k] = $this->values_parsing($value['0'][$k], TRUE);\r
-                               }\r
-                               \r
-                               $temp = new XML_RPC_Values($value['0'], $value['1']);\r
-                       }\r
-                       else\r
-                       {\r
-                               $temp = new XML_RPC_Values($value['0'], $value['1']);\r
-                       }\r
-               }\r
-               else\r
-               {\r
-                       $temp = new XML_RPC_Values($value, 'string');\r
-               }\r
-\r
-               return $temp;\r
-       }\r
-       // END\r
-\r
-\r
-       //-------------------------------------\r
-       //  Sends XML-RPC Request\r
-       //-------------------------------------\r
-\r
-       function send_request()\r
-       {\r
-               $this->message = new XML_RPC_Message($this->method,$this->data);\r
-               $this->message->debug = $this->debug;\r
-       \r
-               if ( ! $this->result = $this->client->send($this->message))\r
-               {\r
-                       $this->error = $this->result->errstr;\r
-                       return FALSE;\r
-               }\r
-               elseif( ! is_object($this->result->val))\r
-               {\r
-                       $this->error = $this->result->errstr;\r
-                       return FALSE;\r
-               }\r
-               \r
-               $this->response = $this->result->decode();\r
-               \r
-               return TRUE;\r
-       }\r
-       // END\r
-       \r
-       //-------------------------------------\r
-       //  Returns Error\r
-       //-------------------------------------\r
-\r
-       function display_error()\r
-       {\r
-               return $this->error;\r
-       }\r
-       // END\r
-       \r
-       //-------------------------------------\r
-       //  Returns Remote Server Response\r
-       //-------------------------------------\r
-\r
-       function display_response()\r
-       {\r
-               return $this->response;\r
-       }\r
-       // END\r
-       \r
-       //-------------------------------------\r
-       //  Sends an Error Message for Server Request\r
-       //-------------------------------------\r
-       \r
-       function send_error_message($number, $message)\r
-       {\r
-               return new XML_RPC_Response('0',$number, $message);\r
-       }\r
-       // END\r
-       \r
-       \r
-       //-------------------------------------\r
-       //  Send Response for Server Request\r
-       //-------------------------------------\r
-       \r
-       function send_response($response)\r
-       {\r
-               // $response should be array of values, which will be parsed\r
-               // based on their data and type into a valid group of XML-RPC values\r
-               \r
-               $response = $this->values_parsing($response);\r
-       \r
-               return new XML_RPC_Response($response);\r
-       }\r
-       // END\r
-       \r
-} // END XML_RPC Class\r
-\r
-       \r
-       \r
-/**\r
- * XML-RPC Client class\r
- *\r
- * @category   XML-RPC\r
- * @author             ExpressionEngine Dev Team\r
- * @link               http://codeigniter.com/user_guide/libraries/xmlrpc.html\r
- */\r
-class XML_RPC_Client extends CI_Xmlrpc\r
-{\r
-       var $path                       = '';\r
-       var $server                     = '';\r
-       var $port                       = 80;\r
-       var $errno                      = '';\r
-       var $errstring          = '';\r
-       var $timeout            = 5;\r
-       var $no_multicall       = false;\r
-\r
-       function XML_RPC_Client($path, $server, $port=80)\r
-       {\r
-               parent::CI_Xmlrpc();\r
-               \r
-               $this->port = $port;\r
-               $this->server = $server;\r
-               $this->path = $path;\r
-       }\r
-       \r
-       function send($msg)\r
-       {\r
-               if (is_array($msg))\r
-               {\r
-                       // Multi-call disabled\r
-                       $r = new XML_RPC_Response(0, $this->xmlrpcerr['multicall_recursion'],$this->xmlrpcstr['multicall_recursion']);\r
-                       return $r;\r
-               }\r
-\r
-               return $this->sendPayload($msg);\r
-       }\r
-\r
-       function sendPayload($msg)\r
-       {       \r
-               $fp = @fsockopen($this->server, $this->port,$this->errno, $this->errstr, $this->timeout);\r
-               \r
-               if ( ! is_resource($fp))\r
-               {\r
-                       error_log($this->xmlrpcstr['http_error']);\r
-                       $r = new XML_RPC_Response(0, $this->xmlrpcerr['http_error'],$this->xmlrpcstr['http_error']);\r
-                       return $r;\r
-               }\r
-               \r
-               if(empty($msg->payload))\r
-               {\r
-                       // $msg = XML_RPC_Messages\r
-                       $msg->createPayload();\r
-               }\r
-               \r
-               $r = "\r\n";\r
-               $op  = "POST {$this->path} HTTP/1.0$r";\r
-               $op .= "Host: {$this->server}$r";\r
-               $op .= "Content-Type: text/xml$r";\r
-               $op .= "User-Agent: {$this->xmlrpcName}$r";\r
-               $op .= "Content-Length: ".strlen($msg->payload). "$r$r";\r
-               $op .= $msg->payload;\r
-               \r
-\r
-               if ( ! fputs($fp, $op, strlen($op)))\r
-               {\r
-                       error_log($this->xmlrpcstr['http_error']);\r
-                       $r = new XML_RPC_Response(0, $this->xmlrpcerr['http_error'], $this->xmlrpcstr['http_error']);\r
-                       return $r;\r
-               }\r
-               $resp = $msg->parseResponse($fp);\r
-               fclose($fp);\r
-               return $resp;\r
-       }\r
-\r
-} // end class XML_RPC_Client\r
-\r
-\r
-/**\r
- * XML-RPC Response class\r
- *\r
- * @category   XML-RPC\r
- * @author             ExpressionEngine Dev Team\r
- * @link               http://codeigniter.com/user_guide/libraries/xmlrpc.html\r
- */\r
-class XML_RPC_Response\r
-{\r
-       var $val = 0;\r
-       var $errno = 0;\r
-       var $errstr = '';\r
-       var $headers = array();\r
-\r
-       function XML_RPC_Response($val, $code = 0, $fstr = '')\r
-       {       \r
-               if ($code != 0)\r
-               {\r
-                       // error\r
-                       $this->errno = $code;\r
-                       $this->errstr = htmlentities($fstr);\r
-               }\r
-               else if ( ! is_object($val))\r
-               {\r
-                       // programmer error, not an object\r
-                       error_log("Invalid type '" . gettype($val) . "' (value: $val) passed to XML_RPC_Response.  Defaulting to empty value.");\r
-                       $this->val = new XML_RPC_Values();\r
-               }\r
-               else\r
-               {\r
-                       $this->val = $val;\r
-               }\r
-       }\r
-\r
-       function faultCode()\r
-       {\r
-               return $this->errno;\r
-       }\r
-\r
-       function faultString()\r
-       {\r
-               return $this->errstr;\r
-       }\r
-\r
-       function value()\r
-       {\r
-               return $this->val;\r
-       }\r
-       \r
-       function prepare_response()\r
-       {\r
-               $result = "<methodResponse>\n";\r
-               if ($this->errno)\r
-               {\r
-                       $result .= '<fault>\r
-       <value>\r
-               <struct>\r
-                       <member>\r
-                               <name>faultCode</name>\r
-                               <value><int>' . $this->errno . '</int></value>\r
-                       </member>\r
-                       <member>\r
-                               <name>faultString</name>\r
-                               <value><string>' . $this->errstr . '</string></value>\r
-                       </member>\r
-               </struct>\r
-       </value>\r
-</fault>';\r
-               }\r
-               else\r
-               {\r
-                       $result .= "<params>\n<param>\n" .\r
-                                       $this->val->serialize_class() .\r
-                                       "</param>\n</params>";\r
-               }\r
-               $result .= "\n</methodResponse>";\r
-               return $result;\r
-       }\r
-       \r
-       function decode($array=FALSE)\r
-       {\r
-               $CI =& get_instance();\r
-\r
-               if ($array !== FALSE && is_array($array))\r
-               {\r
-                       while (list($key) = each($array))\r
-                       {\r
-                               if (is_array($array[$key]))\r
-                               {\r
-                                       $array[$key] = $this->decode($array[$key]);\r
-                               }\r
-                               else\r
-                               {\r
-                                       $array[$key] = $CI->input->xss_clean($array[$key]);\r
-                               }\r
-                       }\r
-                       \r
-                       $result = $array;\r
-               }\r
-               else\r
-               {\r
-                       $result = $this->xmlrpc_decoder($this->val);\r
-                       \r
-                       if (is_array($result))\r
-                       {\r
-                               $result = $this->decode($result);\r
-                       }\r
-                       else\r
-                       {\r
-                               $result = $CI->input->xss_clean($result);\r
-                       }\r
-               }\r
-               \r
-               return $result;\r
-       }\r
-\r
-       \r
-       \r
-       //-------------------------------------\r
-       //  XML-RPC Object to PHP Types\r
-       //-------------------------------------\r
-\r
-       function xmlrpc_decoder($xmlrpc_val)\r
-       {\r
-               $kind = $xmlrpc_val->kindOf();\r
-\r
-               if($kind == 'scalar')\r
-               {\r
-                       return $xmlrpc_val->scalarval();\r
-               }\r
-               elseif($kind == 'array')\r
-               {\r
-                       reset($xmlrpc_val->me);\r
-                       list($a,$b) = each($xmlrpc_val->me);\r
-                       $size = sizeof($b);\r
-                       \r
-                       $arr = array();\r
-\r
-                       for($i = 0; $i < $size; $i++)\r
-                       {\r
-                               $arr[] = $this->xmlrpc_decoder($xmlrpc_val->me['array'][$i]);\r
-                       }\r
-                       return $arr;\r
-               }\r
-               elseif($kind == 'struct')\r
-               {\r
-                       reset($xmlrpc_val->me['struct']);\r
-                       $arr = array();\r
-\r
-                       while(list($key,$value) = each($xmlrpc_val->me['struct']))\r
-                       {\r
-                               $arr[$key] = $this->xmlrpc_decoder($value);\r
-                       }\r
-                       return $arr;\r
-               }\r
-       }\r
-       \r
-       \r
-       //-------------------------------------\r
-       //  ISO-8601 time to server or UTC time\r
-       //-------------------------------------\r
-\r
-       function iso8601_decode($time, $utc=0)\r
-       {\r
-               // return a timet in the localtime, or UTC\r
-               $t = 0;\r
-               if (preg_match('/([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})/', $time, $regs))\r
-               {\r
-                       if ($utc == 1)\r
-                               $t = gmmktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);\r
-                       else\r
-                               $t = mktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);\r
-               }\r
-               return $t;\r
-       }\r
-       \r
-} // End Response Class\r
-\r
-\r
-\r
-/**\r
- * XML-RPC Message class\r
- *\r
- * @category   XML-RPC\r
- * @author             ExpressionEngine Dev Team\r
- * @link               http://codeigniter.com/user_guide/libraries/xmlrpc.html\r
- */\r
-class XML_RPC_Message extends CI_Xmlrpc\r
-{\r
-       var $payload;\r
-       var $method_name;\r
-       var $params                     = array();\r
-       var $xh                         = array();\r
-\r
-       function XML_RPC_Message($method, $pars=0)\r
-       {\r
-               parent::CI_Xmlrpc();\r
-               \r
-               $this->method_name = $method;\r
-               if (is_array($pars) && sizeof($pars) > 0)\r
-               {\r
-                       for($i=0; $i<sizeof($pars); $i++)\r
-                       {\r
-                               // $pars[$i] = XML_RPC_Values\r
-                               $this->params[] = $pars[$i];\r
-                       }\r
-               }\r
-       }\r
-       \r
-       //-------------------------------------\r
-       //  Create Payload to Send\r
-       //-------------------------------------\r
-       \r
-       function createPayload()\r
-       {\r
-               $this->payload = "<?xml version=\"1.0\"?".">\r\n<methodCall>\r\n";\r
-               $this->payload .= '<methodName>' . $this->method_name . "</methodName>\r\n";\r
-               $this->payload .= "<params>\r\n";\r
-               \r
-               for($i=0; $i<sizeof($this->params); $i++)\r
-               {\r
-                       // $p = XML_RPC_Values\r
-                       $p = $this->params[$i];\r
-                       $this->payload .= "<param>\r\n".$p->serialize_class()."</param>\r\n";\r
-               }\r
-               \r
-               $this->payload .= "</params>\r\n</methodCall>\r\n";\r
-       }\r
-       \r
-       //-------------------------------------\r
-       //  Parse External XML-RPC Server's Response\r
-       //-------------------------------------\r
-       \r
-       function parseResponse($fp)\r
-       {\r
-               $data = '';\r
-               \r
-               while($datum = fread($fp, 4096))\r
-               {\r
-                       $data .= $datum;\r
-               }\r
-               \r
-               //-------------------------------------\r
-               //  DISPLAY HTTP CONTENT for DEBUGGING\r
-               //-------------------------------------\r
-               \r
-               if ($this->debug === TRUE)\r
-               {\r
-                       echo "<pre>";\r
-                       echo "---DATA---\n" . htmlspecialchars($data) . "\n---END DATA---\n\n";\r
-                       echo "</pre>";\r
-               }\r
-               \r
-               //-------------------------------------\r
-               //  Check for data\r
-               //-------------------------------------\r
-\r
-               if($data == "")\r
-               {\r
-                       error_log($this->xmlrpcstr['no_data']);\r
-                       $r = new XML_RPC_Response(0, $this->xmlrpcerr['no_data'], $this->xmlrpcstr['no_data']);\r
-                       return $r;\r
-               }\r
-               \r
-               \r
-               //-------------------------------------\r
-               //  Check for HTTP 200 Response\r
-               //-------------------------------------\r
-               \r
-               if (strncmp($data, 'HTTP', 4) == 0 && ! preg_match('/^HTTP\/[0-9\.]+ 200 /', $data))\r
-               {\r
-                       $errstr= substr($data, 0, strpos($data, "\n")-1);\r
-                       $r = new XML_RPC_Response(0, $this->xmlrpcerr['http_error'], $this->xmlrpcstr['http_error']. ' (' . $errstr . ')');\r
-                       return $r;\r
-               }\r
-               \r
-               //-------------------------------------\r
-               //  Create and Set Up XML Parser\r
-               //-------------------------------------\r
-       \r
-               $parser = xml_parser_create($this->xmlrpc_defencoding);\r
-\r
-               $this->xh[$parser]                               = array();\r
-               $this->xh[$parser]['isf']                = 0;\r
-               $this->xh[$parser]['ac']                 = '';\r
-               $this->xh[$parser]['headers']    = array();\r
-               $this->xh[$parser]['stack']              = array();\r
-               $this->xh[$parser]['valuestack'] = array();\r
-               $this->xh[$parser]['isf_reason'] = 0;\r
-\r
-               xml_set_object($parser, $this);\r
-               xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true);\r
-               xml_set_element_handler($parser, 'open_tag', 'closing_tag');\r
-               xml_set_character_data_handler($parser, 'character_data');\r
-               //xml_set_default_handler($parser, 'default_handler');\r
-\r
-\r
-               //-------------------------------------\r
-               //  GET HEADERS\r
-               //-------------------------------------\r
-               \r
-               $lines = explode("\r\n", $data);\r
-               while (($line = array_shift($lines)))\r
-               {\r
-                       if (strlen($line) < 1)\r
-                       {\r
-                               break;\r
-                       }\r
-                       $this->xh[$parser]['headers'][] = $line;\r
-               }\r
-               $data = implode("\r\n", $lines);\r
-               \r
-               \r
-               //-------------------------------------\r
-               //  PARSE XML DATA\r
-               //-------------------------------------         \r
-\r
-               if ( ! xml_parse($parser, $data, sizeof($data)))\r
-               {\r
-                       $errstr = sprintf('XML error: %s at line %d',\r
-                                       xml_error_string(xml_get_error_code($parser)),\r
-                                       xml_get_current_line_number($parser));\r
-                       //error_log($errstr);\r
-                       $r = new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'], $this->xmlrpcstr['invalid_return']);\r
-                       xml_parser_free($parser);\r
-                       return $r;\r
-               }\r
-               xml_parser_free($parser);\r
-               \r
-               // ---------------------------------------\r
-               //  Got Ourselves Some Badness, It Seems\r
-               // ---------------------------------------\r
-               \r
-               if ($this->xh[$parser]['isf'] > 1)\r
-               {\r
-                       if ($this->debug === TRUE)\r
-                       {\r
-                               echo "---Invalid Return---\n";\r
-                               echo $this->xh[$parser]['isf_reason'];\r
-                               echo "---Invalid Return---\n\n";\r
-                       }\r
-                               \r
-                       $r = new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'],$this->xmlrpcstr['invalid_return'].' '.$this->xh[$parser]['isf_reason']);\r
-                       return $r;\r
-               }\r
-               elseif ( ! is_object($this->xh[$parser]['value']))\r
-               {\r
-                       $r = new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'],$this->xmlrpcstr['invalid_return'].' '.$this->xh[$parser]['isf_reason']);\r
-                       return $r;\r
-               }\r
-               \r
-               //-------------------------------------\r
-               //  DISPLAY XML CONTENT for DEBUGGING\r
-               //-------------------------------------         \r
-               \r
-               if ($this->debug === TRUE)\r
-               {\r
-                       echo "<pre>";\r
-                       \r
-                       if (count($this->xh[$parser]['headers'] > 0))\r
-                       {\r
-                               echo "---HEADERS---\n";\r
-                               foreach ($this->xh[$parser]['headers'] as $header)\r
-                               {\r
-                                       echo "$header\n";\r
-                               }\r
-                               echo "---END HEADERS---\n\n";\r
-                       }\r
-                       \r
-                       echo "---DATA---\n" . htmlspecialchars($data) . "\n---END DATA---\n\n";\r
-                       \r
-                       echo "---PARSED---\n" ;\r
-                       var_dump($this->xh[$parser]['value']);\r
-                       echo "\n---END PARSED---</pre>";\r
-               }\r
-               \r
-               //-------------------------------------\r
-               //  SEND RESPONSE\r
-               //-------------------------------------\r
-               \r
-               $v = $this->xh[$parser]['value'];\r
-                       \r
-               if ($this->xh[$parser]['isf'])\r
-               {\r
-                       $errno_v = $v->me['struct']['faultCode'];\r
-                       $errstr_v = $v->me['struct']['faultString'];\r
-                       $errno = $errno_v->scalarval();\r
-\r
-                       if ($errno == 0)\r
-                       {\r
-                               // FAULT returned, errno needs to reflect that\r
-                               $errno = -1;\r
-                       }\r
-\r
-                       $r = new XML_RPC_Response($v, $errno, $errstr_v->scalarval());\r
-               }\r
-               else\r
-               {\r
-                       $r = new XML_RPC_Response($v);\r
-               }\r
-\r
-               $r->headers = $this->xh[$parser]['headers'];\r
-               return $r;\r
-       }\r
-       \r
-       // ------------------------------------\r
-       //  Begin Return Message Parsing section\r
-       // ------------------------------------\r
-       \r
-       // quick explanation of components:\r
-       //   ac - used to accumulate values\r
-       //   isf - used to indicate a fault\r
-       //   lv - used to indicate "looking for a value": implements\r
-       //              the logic to allow values with no types to be strings\r
-       //   params - used to store parameters in method calls\r
-       //   method - used to store method name\r
-       //       stack - array with parent tree of the xml element,\r
-       //                       used to validate the nesting of elements\r
-\r
-       //-------------------------------------\r
-       //  Start Element Handler\r
-       //-------------------------------------\r
-\r
-       function open_tag($the_parser, $name, $attrs)\r
-       {\r
-               // If invalid nesting, then return\r
-               if ($this->xh[$the_parser]['isf'] > 1) return;\r
-               \r
-               // Evaluate and check for correct nesting of XML elements\r
-               \r
-               if (count($this->xh[$the_parser]['stack']) == 0)\r
-               {\r
-                       if ($name != 'METHODRESPONSE' && $name != 'METHODCALL')\r
-                       {\r
-                               $this->xh[$the_parser]['isf'] = 2;\r
-                               $this->xh[$the_parser]['isf_reason'] = 'Top level XML-RPC element is missing';\r
-                               return;\r
-                       }\r
-               }\r
-               else\r
-               {\r
-                       // not top level element: see if parent is OK\r
-                       if ( ! in_array($this->xh[$the_parser]['stack'][0], $this->valid_parents[$name], TRUE))\r
-                       {\r
-                               $this->xh[$the_parser]['isf'] = 2;\r
-                               $this->xh[$the_parser]['isf_reason'] = "XML-RPC element $name cannot be child of ".$this->xh[$the_parser]['stack'][0];\r
-                               return;\r
-                       }\r
-               }\r
-               \r
-               switch($name)\r
-               {\r
-                       case 'STRUCT':\r
-                       case 'ARRAY':\r
-                               // Creates array for child elements\r
-                               \r
-                               $cur_val = array('value' => array(),\r
-                                                                'type'  => $name);\r
-                                                               \r
-                               array_unshift($this->xh[$the_parser]['valuestack'], $cur_val);\r
-                       break;\r
-                       case 'METHODNAME':\r
-                       case 'NAME':\r
-                               $this->xh[$the_parser]['ac'] = '';\r
-                       break;\r
-                       case 'FAULT':\r
-                               $this->xh[$the_parser]['isf'] = 1;\r
-                       break;\r
-                       case 'PARAM':\r
-                               $this->xh[$the_parser]['value'] = null;\r
-                       break;\r
-                       case 'VALUE':\r
-                               $this->xh[$the_parser]['vt'] = 'value';\r
-                               $this->xh[$the_parser]['ac'] = '';\r
-                               $this->xh[$the_parser]['lv'] = 1;\r
-                       break;\r
-                       case 'I4':\r
-                       case 'INT':\r
-                       case 'STRING':\r
-                       case 'BOOLEAN':\r
-                       case 'DOUBLE':\r
-                       case 'DATETIME.ISO8601':\r
-                       case 'BASE64':\r
-                               if ($this->xh[$the_parser]['vt'] != 'value')\r
-                               {\r
-                                       //two data elements inside a value: an error occurred!\r
-                                       $this->xh[$the_parser]['isf'] = 2;\r
-                                       $this->xh[$the_parser]['isf_reason'] = "'Twas a $name element following a ".$this->xh[$the_parser]['vt']." element inside a single value";\r
-                                       return;\r
-                               }\r
-                               \r
-                               $this->xh[$the_parser]['ac'] = '';\r
-                       break;\r
-                       case 'MEMBER':\r
-                               // Set name of <member> to nothing to prevent errors later if no <name> is found\r
-                               $this->xh[$the_parser]['valuestack'][0]['name'] = '';\r
-                               \r
-                               // Set NULL value to check to see if value passed for this param/member\r
-                               $this->xh[$the_parser]['value'] = null;\r
-                       break;\r
-                       case 'DATA':\r
-                       case 'METHODCALL':\r
-                       case 'METHODRESPONSE':\r
-                       case 'PARAMS':\r
-                               // valid elements that add little to processing\r
-                       break;\r
-                       default:\r
-                               /// An Invalid Element is Found, so we have trouble\r
-                               $this->xh[$the_parser]['isf'] = 2;\r
-                               $this->xh[$the_parser]['isf_reason'] = "Invalid XML-RPC element found: $name";\r
-                       break;\r
-               }\r
-               \r
-               // Add current element name to stack, to allow validation of nesting\r
-               array_unshift($this->xh[$the_parser]['stack'], $name);\r
-\r
-               if ($name != 'VALUE') $this->xh[$the_parser]['lv'] = 0;\r
-       }\r
-       // END\r
-\r
-\r
-       //-------------------------------------\r
-       //  End Element Handler\r
-       //-------------------------------------\r
-\r
-       function closing_tag($the_parser, $name)\r
-       {\r
-               if ($this->xh[$the_parser]['isf'] > 1) return;\r
-               \r
-               // Remove current element from stack and set variable\r
-               // NOTE: If the XML validates, then we do not have to worry about\r
-               // the opening and closing of elements.  Nesting is checked on the opening\r
-               // tag so we be safe there as well.\r
-               \r
-               $curr_elem = array_shift($this->xh[$the_parser]['stack']);\r
-       \r
-               switch($name)\r
-               {\r
-                       case 'STRUCT':\r
-                       case 'ARRAY':\r
-                               $cur_val = array_shift($this->xh[$the_parser]['valuestack']);\r
-                               $this->xh[$the_parser]['value'] = ( ! isset($cur_val['values'])) ? array() : $cur_val['values'];\r
-                               $this->xh[$the_parser]['vt']    = strtolower($name);\r
-                       break;\r
-                       case 'NAME':\r
-                               $this->xh[$the_parser]['valuestack'][0]['name'] = $this->xh[$the_parser]['ac'];\r
-                       break;\r
-                       case 'BOOLEAN':\r
-                       case 'I4':\r
-                       case 'INT':\r
-                       case 'STRING':\r
-                       case 'DOUBLE':\r
-                       case 'DATETIME.ISO8601':\r
-                       case 'BASE64':\r
-                               $this->xh[$the_parser]['vt'] = strtolower($name);\r
-                               \r
-                               if ($name == 'STRING')\r
-                               {\r
-                                       $this->xh[$the_parser]['value'] = $this->xh[$the_parser]['ac'];\r
-                               }\r
-                               elseif ($name=='DATETIME.ISO8601')\r
-                               {\r
-                                       $this->xh[$the_parser]['vt']    = $this->xmlrpcDateTime;\r
-                                       $this->xh[$the_parser]['value'] = $this->xh[$the_parser]['ac'];\r
-                               }\r
-                               elseif ($name=='BASE64')\r
-                               {\r
-                                       $this->xh[$the_parser]['value'] = base64_decode($this->xh[$the_parser]['ac']);\r
-                               }\r
-                               elseif ($name=='BOOLEAN')\r
-                               {\r
-                                       // Translated BOOLEAN values to TRUE AND FALSE\r
-                                       if ($this->xh[$the_parser]['ac'] == '1')\r
-                                       {\r
-                                               $this->xh[$the_parser]['value'] = TRUE;\r
-                                       }\r
-                                       else\r
-                                       {\r
-                                               $this->xh[$the_parser]['value'] = FALSE;\r
-                                       }\r
-                               }\r
-                               elseif ($name=='DOUBLE')\r
-                               {\r
-                                       // we have a DOUBLE\r
-                                       // we must check that only 0123456789-.<space> are characters here\r
-                                       if ( ! preg_match('/^[+-]?[eE0-9\t \.]+$/', $this->xh[$the_parser]['ac']))\r
-                                       {\r
-                                               $this->xh[$the_parser]['value'] = 'ERROR_NON_NUMERIC_FOUND';\r
-                                       }\r
-                                       else\r
-                                       {\r
-                                               $this->xh[$the_parser]['value'] = (double)$this->xh[$the_parser]['ac'];\r
-                                       }\r
-                               }\r
-                               else\r
-                               {\r
-                                       // we have an I4/INT\r
-                                       // we must check that only 0123456789-<space> are characters here\r
-                                       if ( ! preg_match('/^[+-]?[0-9\t ]+$/', $this->xh[$the_parser]['ac']))\r
-                                       {\r
-                                               $this->xh[$the_parser]['value'] = 'ERROR_NON_NUMERIC_FOUND';\r
-                                       }\r
-                                       else\r
-                                       {\r
-                                               $this->xh[$the_parser]['value'] = (int)$this->xh[$the_parser]['ac'];\r
-                                       }\r
-                               }\r
-                               $this->xh[$the_parser]['ac'] = '';\r
-                               $this->xh[$the_parser]['lv'] = 3; // indicate we've found a value\r
-                       break;\r
-                       case 'VALUE':\r
-                               // This if() detects if no scalar was inside <VALUE></VALUE>\r
-                               if ($this->xh[$the_parser]['vt']=='value')\r
-                               {\r
-                                       $this->xh[$the_parser]['value'] = $this->xh[$the_parser]['ac'];\r
-                                       $this->xh[$the_parser]['vt']    = $this->xmlrpcString;\r
-                               }\r
-                               \r
-                               // build the XML-RPC value out of the data received, and substitute it\r
-                               $temp = new XML_RPC_Values($this->xh[$the_parser]['value'], $this->xh[$the_parser]['vt']);\r
-                               \r
-                               if (count($this->xh[$the_parser]['valuestack']) && $this->xh[$the_parser]['valuestack'][0]['type'] == 'ARRAY')\r
-                               {\r
-                                       // Array\r
-                                       $this->xh[$the_parser]['valuestack'][0]['values'][] = $temp;\r
-                               }\r
-                               else\r
-                               {\r
-                                       // Struct\r
-                                       $this->xh[$the_parser]['value'] = $temp;\r
-                               }\r
-                       break;\r
-                       case 'MEMBER':\r
-                               $this->xh[$the_parser]['ac']='';\r
-                               \r
-                               // If value add to array in the stack for the last element built\r
-                               if ($this->xh[$the_parser]['value'])\r
-                               {\r
-                                       $this->xh[$the_parser]['valuestack'][0]['values'][$this->xh[$the_parser]['valuestack'][0]['name']] = $this->xh[$the_parser]['value'];\r
-                               }\r
-                       break;\r
-                       case 'DATA':\r
-                               $this->xh[$the_parser]['ac']='';\r
-                       break;\r
-                       case 'PARAM':\r
-                               if ($this->xh[$the_parser]['value'])\r
-                               {\r
-                                       $this->xh[$the_parser]['params'][] = $this->xh[$the_parser]['value'];\r
-                               }\r
-                       break;\r
-                       case 'METHODNAME':\r
-                               $this->xh[$the_parser]['method'] = ltrim($this->xh[$the_parser]['ac']);\r
-                       break;\r
-                       case 'PARAMS':\r
-                       case 'FAULT':\r
-                       case 'METHODCALL':\r
-                       case 'METHORESPONSE':\r
-                               // We're all good kids with nuthin' to do\r
-                       break;\r
-                       default:\r
-                               // End of an Invalid Element.  Taken care of during the opening tag though\r
-                       break;\r
-               }\r
-       }\r
-\r
-       //-------------------------------------\r
-       //  Parses Character Data\r
-       //-------------------------------------\r
-\r
-       function character_data($the_parser, $data)\r
-       {\r
-               if ($this->xh[$the_parser]['isf'] > 1) return; // XML Fault found already\r
-               \r
-               // If a value has not been found\r
-               if ($this->xh[$the_parser]['lv'] != 3)\r
-               {\r
-                       if ($this->xh[$the_parser]['lv'] == 1)\r
-                       {\r
-                               $this->xh[$the_parser]['lv'] = 2; // Found a value\r
-                       }\r
-                               \r
-                       if( ! @isset($this->xh[$the_parser]['ac']))\r
-                       {\r
-                               $this->xh[$the_parser]['ac'] = '';\r
-                       }\r
-                               \r
-                       $this->xh[$the_parser]['ac'] .= $data;\r
-               }\r
-       }\r
-       \r
-       \r
-       function addParam($par) { $this->params[]=$par; }\r
-       \r
-       function output_parameters($array=FALSE)\r
-       {\r
-               $CI =& get_instance();  \r
-\r
-               if ($array !== FALSE && is_array($array))\r
-               {\r
-                       while (list($key) = each($array))\r
-                       {\r
-                               if (is_array($array[$key]))\r
-                               {\r
-                                       $array[$key] = $this->output_parameters($array[$key]);\r
-                               }\r
-                               else\r
-                               {\r
-                                       $array[$key] = $CI->input->xss_clean($array[$key]);\r
-                               }\r
-                       }\r
-                       \r
-                       $parameters = $array;\r
-               }\r
-               else\r
-               {\r
-                       $parameters = array();\r
-               \r
-                       for ($i = 0; $i < sizeof($this->params); $i++)\r
-                       {\r
-                               $a_param = $this->decode_message($this->params[$i]);\r
-                               \r
-                               if (is_array($a_param))\r
-                               {\r
-                                       $parameters[] = $this->output_parameters($a_param);\r
-                               }\r
-                               else\r
-                               {\r
-                                       $parameters[] = $CI->input->xss_clean($a_param);\r
-                               }\r
-                       }       \r
-               }\r
-               \r
-               return $parameters;\r
-       }\r
-       \r
-       \r
-       function decode_message($param)\r
-       {\r
-               $kind = $param->kindOf();\r
-\r
-               if($kind == 'scalar')\r
-               {\r
-                       return $param->scalarval();\r
-               }\r
-               elseif($kind == 'array')\r
-               {\r
-                       reset($param->me);\r
-                       list($a,$b) = each($param->me);\r
-                       \r
-                       $arr = array();\r
-\r
-                       for($i = 0; $i < sizeof($b); $i++)\r
-                       {\r
-                               $arr[] = $this->decode_message($param->me['array'][$i]);\r
-                       }\r
-                       \r
-                       return $arr;\r
-               }\r
-               elseif($kind == 'struct')\r
-               {\r
-                       reset($param->me['struct']);\r
-                       \r
-                       $arr = array();\r
-\r
-                       while(list($key,$value) = each($param->me['struct']))\r
-                       {\r
-                               $arr[$key] = $this->decode_message($value);\r
-                       }\r
-                       \r
-                       return $arr;\r
-               }\r
-       }\r
-       \r
-} // End XML_RPC_Messages class\r
-\r
-\r
-\r
-/**\r
- * XML-RPC Values class\r
- *\r
- * @category   XML-RPC\r
- * @author             ExpressionEngine Dev Team\r
- * @link               http://codeigniter.com/user_guide/libraries/xmlrpc.html\r
- */\r
-class XML_RPC_Values extends CI_Xmlrpc\r
-{\r
-       var $me         = array();\r
-       var $mytype     = 0;\r
-\r
-       function XML_RPC_Values($val=-1, $type='')\r
-       {       \r
-               parent::CI_Xmlrpc();\r
-               \r
-               if ($val != -1 OR $type != '')\r
-               {\r
-                       $type = $type == '' ? 'string' : $type;\r
-                       \r
-                       if ($this->xmlrpcTypes[$type] == 1)\r
-                       {\r
-                               $this->addScalar($val,$type);\r
-                       }\r
-                       elseif ($this->xmlrpcTypes[$type] == 2)\r
-                       {\r
-                               $this->addArray($val);\r
-                       }\r
-                       elseif ($this->xmlrpcTypes[$type] == 3)\r
-                       {\r
-                               $this->addStruct($val);\r
-                       }\r
-               }\r
-       }\r
-\r
-       function addScalar($val, $type='string')\r
-       {\r
-               $typeof = $this->xmlrpcTypes[$type];\r
-               \r
-               if ($this->mytype==1)\r
-               {\r
-                       echo '<strong>XML_RPC_Values</strong>: scalar can have only one value<br />';\r
-                       return 0;\r
-               }\r
-               \r
-               if ($typeof != 1)\r
-               {\r
-                       echo '<strong>XML_RPC_Values</strong>: not a scalar type (${typeof})<br />';\r
-                       return 0;\r
-               }\r
-\r
-               if ($type == $this->xmlrpcBoolean)\r
-               {\r
-                       if (strcasecmp($val,'true')==0 OR $val==1 OR ($val==true && strcasecmp($val,'false')))\r
-                       {\r
-                               $val = 1;\r
-                       }\r
-                       else\r
-                       {\r
-                               $val=0;\r
-                       }\r
-               }\r
-\r
-               if ($this->mytype == 2)\r
-               {\r
-                       // adding to an array here\r
-                       $ar = $this->me['array'];\r
-                       $ar[] = new XML_RPC_Values($val, $type);\r
-                       $this->me['array'] = $ar;\r
-               }\r
-               else\r
-               {\r
-                       // a scalar, so set the value and remember we're scalar\r
-                       $this->me[$type] = $val;\r
-                       $this->mytype = $typeof;\r
-               }\r
-               return 1;\r
-       }\r
-\r
-       function addArray($vals)\r
-       {\r
-               if ($this->mytype != 0)\r
-               {\r
-                       echo '<strong>XML_RPC_Values</strong>: already initialized as a [' . $this->kindOf() . ']<br />';\r
-                       return 0;\r
-               }\r
-\r
-               $this->mytype = $this->xmlrpcTypes['array'];\r
-               $this->me['array'] = $vals;\r
-               return 1;\r
-       }\r
-\r
-       function addStruct($vals)\r
-       {\r
-               if ($this->mytype != 0)\r
-               {\r
-                       echo '<strong>XML_RPC_Values</strong>: already initialized as a [' . $this->kindOf() . ']<br />';\r
-                       return 0;\r
-               }\r
-               $this->mytype = $this->xmlrpcTypes['struct'];\r
-               $this->me['struct'] = $vals;\r
-               return 1;\r
-       }\r
-\r
-       function kindOf()\r
-       {\r
-               switch($this->mytype)\r
-               {\r
-                       case 3:\r
-                               return 'struct';\r
-                               break;\r
-                       case 2:\r
-                               return 'array';\r
-                               break;\r
-                       case 1:\r
-                               return 'scalar';\r
-                               break;\r
-                       default:\r
-                               return 'undef';\r
-               }\r
-       }\r
-\r
-       function serializedata($typ, $val)\r
-       {\r
-               $rs = '';\r
-               \r
-               switch($this->xmlrpcTypes[$typ])\r
-               {\r
-                       case 3:\r
-                               // struct\r
-                               $rs .= "<struct>\n";\r
-                               reset($val);\r
-                               while(list($key2, $val2) = each($val))\r
-                               {\r
-                                       $rs .= "<member>\n<name>{$key2}</name>\n";\r
-                                       $rs .= $this->serializeval($val2);\r
-                                       $rs .= "</member>\n";\r
-                               }\r
-                               $rs .= '</struct>';\r
-                       break;\r
-                       case 2:\r
-                               // array\r
-                               $rs .= "<array>\n<data>\n";\r
-                               for($i=0; $i < sizeof($val); $i++)\r
-                               {\r
-                                       $rs .= $this->serializeval($val[$i]);\r
-                               }\r
-                               $rs.="</data>\n</array>\n";\r
-                               break;\r
-                       case 1:\r
-                               // others\r
-                               switch ($typ)\r
-                               {\r
-                                       case $this->xmlrpcBase64:\r
-                                               $rs .= "<{$typ}>" . base64_encode($val) . "</{$typ}>\n";\r
-                                       break;\r
-                                       case $this->xmlrpcBoolean:\r
-                                               $rs .= "<{$typ}>" . ($val ? '1' : '0') . "</{$typ}>\n";\r
-                                       break;\r
-                                       case $this->xmlrpcString:\r
-                                               $rs .= "<{$typ}>" . htmlspecialchars($val). "</{$typ}>\n";\r
-                                       break;\r
-                                       default:\r
-                                               $rs .= "<{$typ}>{$val}</{$typ}>\n";\r
-                                       break;\r
-                               }\r
-                       default:\r
-                       break;\r
-               }\r
-               return $rs;\r
-       }\r
-\r
-       function serialize_class()\r
-       {\r
-               return $this->serializeval($this);\r
-       }\r
-\r
-       function serializeval($o)\r
-       {\r
-               $ar = $o->me;\r
-               reset($ar);\r
-               \r
-               list($typ, $val) = each($ar);\r
-               $rs = "<value>\n".$this->serializedata($typ, $val)."</value>\n";\r
-               return $rs;\r
-       }\r
-       \r
-       function scalarval()\r
-       {\r
-               reset($this->me);\r
-               list($a,$b) = each($this->me);\r
-               return $b;\r
-       }\r
-\r
-\r
-       //-------------------------------------\r
-       // Encode time in ISO-8601 form.\r
-       //-------------------------------------\r
-       \r
-       // Useful for sending time in XML-RPC\r
-\r
-       function iso8601_encode($time, $utc=0)\r
-       {       \r
-               if ($utc == 1)\r
-               {\r
-                       $t = strftime("%Y%m%dT%H:%M:%S", $time);\r
-               }\r
-               else\r
-               {\r
-                       if (function_exists('gmstrftime'))\r
-                               $t = gmstrftime("%Y%m%dT%H:%M:%S", $time);\r
-                       else\r
-                               $t = strftime("%Y%m%dT%H:%M:%S", $time - date('Z'));\r
-               }\r
-               return $t;\r
-       }\r
-       \r
-}\r
-// END XML_RPC_Values Class\r
-\r
-/* End of file Xmlrpc.php */\r
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package            CodeIgniter
+ * @author             ExpressionEngine Dev Team
+ * @copyright  Copyright (c) 2008 - 2009, EllisLab, Inc.
+ * @license            http://codeigniter.com/user_guide/license.html
+ * @link               http://codeigniter.com
+ * @since              Version 1.0
+ * @filesource
+ */
+
+if ( ! function_exists('xml_parser_create'))
+{      
+       show_error('Your PHP installation does not support XML');
+}
+
+
+// ------------------------------------------------------------------------
+
+/**
+ * XML-RPC request handler class
+ *
+ * @package            CodeIgniter
+ * @subpackage Libraries
+ * @category   XML-RPC
+ * @author             ExpressionEngine Dev Team
+ * @link               http://codeigniter.com/user_guide/libraries/xmlrpc.html
+ */
+class CI_Xmlrpc {
+
+       var $debug                      = FALSE;        // Debugging on or off  
+       var $xmlrpcI4           = 'i4';
+       var $xmlrpcInt          = 'int';
+       var $xmlrpcBoolean      = 'boolean';
+       var $xmlrpcDouble       = 'double';     
+       var $xmlrpcString       = 'string';
+       var $xmlrpcDateTime     = 'dateTime.iso8601';
+       var $xmlrpcBase64       = 'base64';
+       var $xmlrpcArray        = 'array';
+       var $xmlrpcStruct       = 'struct';
+       
+       var $xmlrpcTypes        = array();
+       var $valid_parents      = array();
+       var $xmlrpcerr          = array();      // Response numbers
+       var $xmlrpcstr          = array();  // Response strings
+       
+       var $xmlrpc_defencoding = 'UTF-8';
+       var $xmlrpcName                 = 'XML-RPC for CodeIgniter';
+       var $xmlrpcVersion              = '1.1';
+       var $xmlrpcerruser              = 800; // Start of user errors
+       var $xmlrpcerrxml               = 100; // Start of XML Parse errors
+       var $xmlrpc_backslash   = ''; // formulate backslashes for escaping regexp
+       
+       var $client;
+       var $method;
+       var $data;
+       var $message                    = '';
+       var $error                              = '';           // Error string for request
+       var $result;
+       var $response                   = array();  // Response from remote server
+
+
+       //-------------------------------------
+       //  VALUES THAT MULTIPLE CLASSES NEED
+       //-------------------------------------
+
+       function CI_Xmlrpc ($config = array())
+       {
+               $this->xmlrpcName               = $this->xmlrpcName;
+               $this->xmlrpc_backslash = chr(92).chr(92);
+               
+               // Types for info sent back and forth
+               $this->xmlrpcTypes = array(
+                       $this->xmlrpcI4    => '1',
+                       $this->xmlrpcInt          => '1',
+                       $this->xmlrpcBoolean  => '1',
+                       $this->xmlrpcString   => '1',
+                       $this->xmlrpcDouble   => '1',
+                       $this->xmlrpcDateTime => '1',
+                       $this->xmlrpcBase64   => '1',
+                       $this->xmlrpcArray      => '2',
+                       $this->xmlrpcStruct   => '3'
+                       );
+                       
+               // Array of Valid Parents for Various XML-RPC elements
+               $this->valid_parents = array('BOOLEAN'                  => array('VALUE'),
+                                                                        'I4'                           => array('VALUE'),
+                                                                        'INT'                          => array('VALUE'),
+                                                                        'STRING'                       => array('VALUE'),
+                                                                        'DOUBLE'                       => array('VALUE'),
+                                                                        'DATETIME.ISO8601'     => array('VALUE'),
+                                                                        'BASE64'                       => array('VALUE'),
+                                                                        'ARRAY'                        => array('VALUE'),
+                                                                        'STRUCT'                       => array('VALUE'),
+                                                                        'PARAM'                        => array('PARAMS'),
+                                                                        'METHODNAME'           => array('METHODCALL'),
+                                                                        'PARAMS'                       => array('METHODCALL', 'METHODRESPONSE'),
+                                                                        'MEMBER'                       => array('STRUCT'),
+                                                                        'NAME'                         => array('MEMBER'),
+                                                                        'DATA'                         => array('ARRAY'),
+                                                                        'FAULT'                        => array('METHODRESPONSE'),
+                                                                        'VALUE'                        => array('MEMBER', 'DATA', 'PARAM', 'FAULT')
+                                                                        );
+                       
+                       
+               // XML-RPC Responses
+               $this->xmlrpcerr['unknown_method'] = '1';
+               $this->xmlrpcstr['unknown_method'] = 'This is not a known method for this XML-RPC Server';
+               $this->xmlrpcerr['invalid_return'] = '2';
+               $this->xmlrpcstr['invalid_return'] = 'The XML data receieved was either invalid or not in the correct form for XML-RPC.  Turn on debugging to examine the XML data further.';
+               $this->xmlrpcerr['incorrect_params'] = '3';
+               $this->xmlrpcstr['incorrect_params'] = 'Incorrect parameters were passed to method';
+               $this->xmlrpcerr['introspect_unknown'] = '4';
+               $this->xmlrpcstr['introspect_unknown'] = "Cannot inspect signature for request: method unknown";
+               $this->xmlrpcerr['http_error'] = '5';
+               $this->xmlrpcstr['http_error'] = "Did not receive a '200 OK' response from remote server.";
+               $this->xmlrpcerr['no_data'] = '6';
+               $this->xmlrpcstr['no_data'] ='No data received from server.';
+               
+               $this->initialize($config);
+               
+               log_message('debug', "XML-RPC Class Initialized");
+       }
+       
+       
+       //-------------------------------------
+       //  Initialize Prefs
+       //-------------------------------------
+
+       function initialize($config = array())
+       {
+               if (count($config) > 0)
+               {
+                       foreach ($config as $key => $val)
+                       {
+                               if (isset($this->$key))
+                               {
+                                       $this->$key = $val;                     
+                               }
+                       }
+               }
+       }
+       // END
+       
+       //-------------------------------------
+       //  Take URL and parse it
+       //-------------------------------------
+
+       function server($url, $port=80)
+       {
+               if (substr($url, 0, 4) != "http")
+               {
+                       $url = "http://".$url;
+               }
+               
+               $parts = parse_url($url);
+               
+               $path = ( ! isset($parts['path'])) ? '/' : $parts['path'];
+               
+               if (isset($parts['query']) && $parts['query'] != '')
+               {
+                       $path .= '?'.$parts['query'];
+               }       
+               
+               $this->client = new XML_RPC_Client($path, $parts['host'], $port);
+       }
+       // END
+       
+       //-------------------------------------
+       //  Set Timeout
+       //-------------------------------------
+
+       function timeout($seconds=5)
+       {
+               if ( ! is_null($this->client) && is_int($seconds))
+               {
+                       $this->client->timeout = $seconds;
+               }
+       }
+       // END
+       
+       //-------------------------------------
+       //  Set Methods
+       //-------------------------------------
+
+       function method($function)
+       {
+               $this->method = $function;
+       }
+       // END
+       
+       //-------------------------------------
+       //  Take Array of Data and Create Objects
+       //-------------------------------------
+
+       function request($incoming)
+       {
+               if ( ! is_array($incoming))
+               {
+                       // Send Error
+               }
+               
+               $this->data = array();
+               
+               foreach($incoming as $key => $value)
+               {
+                       $this->data[$key] = $this->values_parsing($value);
+               }
+       }
+       // END
+       
+       
+       //-------------------------------------
+       //  Set Debug
+       //-------------------------------------
+
+       function set_debug($flag = TRUE)
+       {
+               $this->debug = ($flag == TRUE) ? TRUE : FALSE;
+       }
+       
+       //-------------------------------------
+       //  Values Parsing
+       //-------------------------------------
+
+       function values_parsing($value, $return = FALSE)
+       {
+               if (is_array($value) && isset($value['0']))
+               {
+                       if ( ! isset($value['1']) OR (! isset($this->xmlrpcTypes[$value['1']])))
+                       {
+                               if (is_array($value[0]))
+                               {
+                                       $temp = new XML_RPC_Values($value['0'], 'array');
+                               }
+                               else
+                               {
+                                       $temp = new XML_RPC_Values($value['0'], 'string');
+                               }
+                       }
+                       elseif(is_array($value['0']) && ($value['1'] == 'struct' OR $value['1'] == 'array'))
+                       {
+                               while (list($k) = each($value['0']))
+                               {
+                                       $value['0'][$k] = $this->values_parsing($value['0'][$k], TRUE);
+                               }
+                               
+                               $temp = new XML_RPC_Values($value['0'], $value['1']);
+                       }
+                       else
+                       {
+                               $temp = new XML_RPC_Values($value['0'], $value['1']);
+                       }
+               }
+               else
+               {
+                       $temp = new XML_RPC_Values($value, 'string');
+               }
+
+               return $temp;
+       }
+       // END
+
+
+       //-------------------------------------
+       //  Sends XML-RPC Request
+       //-------------------------------------
+
+       function send_request()
+       {
+               $this->message = new XML_RPC_Message($this->method,$this->data);
+               $this->message->debug = $this->debug;
+       
+               if ( ! $this->result = $this->client->send($this->message))
+               {
+                       $this->error = $this->result->errstr;
+                       return FALSE;
+               }
+               elseif( ! is_object($this->result->val))
+               {
+                       $this->error = $this->result->errstr;
+                       return FALSE;
+               }
+               
+               $this->response = $this->result->decode();
+               
+               return TRUE;
+       }
+       // END
+       
+       //-------------------------------------
+       //  Returns Error
+       //-------------------------------------
+
+       function display_error()
+       {
+               return $this->error;
+       }
+       // END
+       
+       //-------------------------------------
+       //  Returns Remote Server Response
+       //-------------------------------------
+
+       function display_response()
+       {
+               return $this->response;
+       }
+       // END
+       
+       //-------------------------------------
+       //  Sends an Error Message for Server Request
+       //-------------------------------------
+       
+       function send_error_message($number, $message)
+       {
+               return new XML_RPC_Response('0',$number, $message);
+       }
+       // END
+       
+       
+       //-------------------------------------
+       //  Send Response for Server Request
+       //-------------------------------------
+       
+       function send_response($response)
+       {
+               // $response should be array of values, which will be parsed
+               // based on their data and type into a valid group of XML-RPC values
+               
+               $response = $this->values_parsing($response);
+       
+               return new XML_RPC_Response($response);
+       }
+       // END
+       
+} // END XML_RPC Class
+
+       
+       
+/**
+ * XML-RPC Client class
+ *
+ * @category   XML-RPC
+ * @author             ExpressionEngine Dev Team
+ * @link               http://codeigniter.com/user_guide/libraries/xmlrpc.html
+ */
+class XML_RPC_Client extends CI_Xmlrpc
+{
+       var $path                       = '';
+       var $server                     = '';
+       var $port                       = 80;
+       var $errno                      = '';
+       var $errstring          = '';
+       var $timeout            = 5;
+       var $no_multicall       = false;
+
+       function XML_RPC_Client($path, $server, $port=80)
+       {
+               parent::CI_Xmlrpc();
+               
+               $this->port = $port;
+               $this->server = $server;
+               $this->path = $path;
+       }
+       
+       function send($msg)
+       {
+               if (is_array($msg))
+               {
+                       // Multi-call disabled
+                       $r = new XML_RPC_Response(0, $this->xmlrpcerr['multicall_recursion'],$this->xmlrpcstr['multicall_recursion']);
+                       return $r;
+               }
+
+               return $this->sendPayload($msg);
+       }
+
+       function sendPayload($msg)
+       {       
+               $fp = @fsockopen($this->server, $this->port,$this->errno, $this->errstr, $this->timeout);
+               
+               if ( ! is_resource($fp))
+               {
+                       error_log($this->xmlrpcstr['http_error']);
+                       $r = new XML_RPC_Response(0, $this->xmlrpcerr['http_error'],$this->xmlrpcstr['http_error']);
+                       return $r;
+               }
+               
+               if(empty($msg->payload))
+               {
+                       // $msg = XML_RPC_Messages
+                       $msg->createPayload();
+               }
+               
+               $r = "\r\n";
+               $op  = "POST {$this->path} HTTP/1.0$r";
+               $op .= "Host: {$this->server}$r";
+               $op .= "Content-Type: text/xml$r";
+               $op .= "User-Agent: {$this->xmlrpcName}$r";
+               $op .= "Content-Length: ".strlen($msg->payload). "$r$r";
+               $op .= $msg->payload;
+               
+
+               if ( ! fputs($fp, $op, strlen($op)))
+               {
+                       error_log($this->xmlrpcstr['http_error']);
+                       $r = new XML_RPC_Response(0, $this->xmlrpcerr['http_error'], $this->xmlrpcstr['http_error']);
+                       return $r;
+               }
+               $resp = $msg->parseResponse($fp);
+               fclose($fp);
+               return $resp;
+       }
+
+} // end class XML_RPC_Client
+
+
+/**
+ * XML-RPC Response class
+ *
+ * @category   XML-RPC
+ * @author             ExpressionEngine Dev Team
+ * @link               http://codeigniter.com/user_guide/libraries/xmlrpc.html
+ */
+class XML_RPC_Response
+{
+       var $val = 0;
+       var $errno = 0;
+       var $errstr = '';
+       var $headers = array();
+
+       function XML_RPC_Response($val, $code = 0, $fstr = '')
+       {       
+               if ($code != 0)
+               {
+                       // error
+                       $this->errno = $code;
+                       $this->errstr = htmlentities($fstr);
+               }
+               else if ( ! is_object($val))
+               {
+                       // programmer error, not an object
+                       error_log("Invalid type '" . gettype($val) . "' (value: $val) passed to XML_RPC_Response.  Defaulting to empty value.");
+                       $this->val = new XML_RPC_Values();
+               }
+               else
+               {
+                       $this->val = $val;
+               }
+       }
+
+       function faultCode()
+       {
+               return $this->errno;
+       }
+
+       function faultString()
+       {
+               return $this->errstr;
+       }
+
+       function value()
+       {
+               return $this->val;
+       }
+       
+       function prepare_response()
+       {
+               $result = "<methodResponse>\n";
+               if ($this->errno)
+               {
+                       $result .= '<fault>
+       <value>
+               <struct>
+                       <member>
+                               <name>faultCode</name>
+                               <value><int>' . $this->errno . '</int></value>
+                       </member>
+                       <member>
+                               <name>faultString</name>
+                               <value><string>' . $this->errstr . '</string></value>
+                       </member>
+               </struct>
+       </value>
+</fault>';
+               }
+               else
+               {
+                       $result .= "<params>\n<param>\n" .
+                                       $this->val->serialize_class() .
+                                       "</param>\n</params>";
+               }
+               $result .= "\n</methodResponse>";
+               return $result;
+       }
+       
+       function decode($array=FALSE)
+       {
+               $CI =& get_instance();
+
+               if ($array !== FALSE && is_array($array))
+               {
+                       while (list($key) = each($array))
+                       {
+                               if (is_array($array[$key]))
+                               {
+                                       $array[$key] = $this->decode($array[$key]);
+                               }
+                               else
+                               {
+                                       $array[$key] = $CI->input->xss_clean($array[$key]);
+                               }
+                       }
+                       
+                       $result = $array;
+               }
+               else
+               {
+                       $result = $this->xmlrpc_decoder($this->val);
+                       
+                       if (is_array($result))
+                       {
+                               $result = $this->decode($result);
+                       }
+                       else
+                       {
+                               $result = $CI->input->xss_clean($result);
+                       }
+               }
+               
+               return $result;
+       }
+
+       
+       
+       //-------------------------------------
+       //  XML-RPC Object to PHP Types
+       //-------------------------------------
+
+       function xmlrpc_decoder($xmlrpc_val)
+       {
+               $kind = $xmlrpc_val->kindOf();
+
+               if($kind == 'scalar')
+               {
+                       return $xmlrpc_val->scalarval();
+               }
+               elseif($kind == 'array')
+               {
+                       reset($xmlrpc_val->me);
+                       list($a,$b) = each($xmlrpc_val->me);
+                       $size = count($b);
+                       
+                       $arr = array();
+
+                       for($i = 0; $i < $size; $i++)
+                       {
+                               $arr[] = $this->xmlrpc_decoder($xmlrpc_val->me['array'][$i]);
+                       }
+                       return $arr;
+               }
+               elseif($kind == 'struct')
+               {
+                       reset($xmlrpc_val->me['struct']);
+                       $arr = array();
+
+                       while(list($key,$value) = each($xmlrpc_val->me['struct']))
+                       {
+                               $arr[$key] = $this->xmlrpc_decoder($value);
+                       }
+                       return $arr;
+               }
+       }
+       
+       
+       //-------------------------------------
+       //  ISO-8601 time to server or UTC time
+       //-------------------------------------
+
+       function iso8601_decode($time, $utc=0)
+       {
+               // return a timet in the localtime, or UTC
+               $t = 0;
+               if (preg_match('/([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})/', $time, $regs))
+               {
+                       if ($utc == 1)
+                               $t = gmmktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
+                       else
+                               $t = mktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
+               }
+               return $t;
+       }
+       
+} // End Response Class
+
+
+
+/**
+ * XML-RPC Message class
+ *
+ * @category   XML-RPC
+ * @author             ExpressionEngine Dev Team
+ * @link               http://codeigniter.com/user_guide/libraries/xmlrpc.html
+ */
+class XML_RPC_Message extends CI_Xmlrpc
+{
+       var $payload;
+       var $method_name;
+       var $params                     = array();
+       var $xh                         = array();
+
+       function XML_RPC_Message($method, $pars=0)
+       {
+               parent::CI_Xmlrpc();
+               
+               $this->method_name = $method;
+               if (is_array($pars) && count($pars) > 0)
+               {
+                       for($i=0; $i<count($pars); $i++)
+                       {
+                               // $pars[$i] = XML_RPC_Values
+                               $this->params[] = $pars[$i];
+                       }
+               }
+       }
+       
+       //-------------------------------------
+       //  Create Payload to Send
+       //-------------------------------------
+       
+       function createPayload()
+       {
+               $this->payload = "<?xml version=\"1.0\"?".">\r\n<methodCall>\r\n";
+               $this->payload .= '<methodName>' . $this->method_name . "</methodName>\r\n";
+               $this->payload .= "<params>\r\n";
+               
+               for($i=0; $i<count($this->params); $i++)
+               {
+                       // $p = XML_RPC_Values
+                       $p = $this->params[$i];
+                       $this->payload .= "<param>\r\n".$p->serialize_class()."</param>\r\n";
+               }
+               
+               $this->payload .= "</params>\r\n</methodCall>\r\n";
+       }
+       
+       //-------------------------------------
+       //  Parse External XML-RPC Server's Response
+       //-------------------------------------
+       
+       function parseResponse($fp)
+       {
+               $data = '';
+               
+               while($datum = fread($fp, 4096))
+               {
+                       $data .= $datum;
+               }
+               
+               //-------------------------------------
+               //  DISPLAY HTTP CONTENT for DEBUGGING
+               //-------------------------------------
+               
+               if ($this->debug === TRUE)
+               {
+                       echo "<pre>";
+                       echo "---DATA---\n" . htmlspecialchars($data) . "\n---END DATA---\n\n";
+                       echo "</pre>";
+               }
+               
+               //-------------------------------------
+               //  Check for data
+               //-------------------------------------
+
+               if($data == "")
+               {
+                       error_log($this->xmlrpcstr['no_data']);
+                       $r = new XML_RPC_Response(0, $this->xmlrpcerr['no_data'], $this->xmlrpcstr['no_data']);
+                       return $r;
+               }
+               
+               
+               //-------------------------------------
+               //  Check for HTTP 200 Response
+               //-------------------------------------
+               
+               if (strncmp($data, 'HTTP', 4) == 0 && ! preg_match('/^HTTP\/[0-9\.]+ 200 /', $data))
+               {
+                       $errstr= substr($data, 0, strpos($data, "\n")-1);
+                       $r = new XML_RPC_Response(0, $this->xmlrpcerr['http_error'], $this->xmlrpcstr['http_error']. ' (' . $errstr . ')');
+                       return $r;
+               }
+               
+               //-------------------------------------
+               //  Create and Set Up XML Parser
+               //-------------------------------------
+       
+               $parser = xml_parser_create($this->xmlrpc_defencoding);
+
+               $this->xh[$parser]                               = array();
+               $this->xh[$parser]['isf']                = 0;
+               $this->xh[$parser]['ac']                 = '';
+               $this->xh[$parser]['headers']    = array();
+               $this->xh[$parser]['stack']              = array();
+               $this->xh[$parser]['valuestack'] = array();
+               $this->xh[$parser]['isf_reason'] = 0;
+
+               xml_set_object($parser, $this);
+               xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true);
+               xml_set_element_handler($parser, 'open_tag', 'closing_tag');
+               xml_set_character_data_handler($parser, 'character_data');
+               //xml_set_default_handler($parser, 'default_handler');
+
+
+               //-------------------------------------
+               //  GET HEADERS
+               //-------------------------------------
+               
+               $lines = explode("\r\n", $data);
+               while (($line = array_shift($lines)))
+               {
+                       if (strlen($line) < 1)
+                       {
+                               break;
+                       }
+                       $this->xh[$parser]['headers'][] = $line;
+               }
+               $data = implode("\r\n", $lines);
+               
+               
+               //-------------------------------------
+               //  PARSE XML DATA
+               //-------------------------------------         
+
+               if ( ! xml_parse($parser, $data, count($data)))
+               {
+                       $errstr = sprintf('XML error: %s at line %d',
+                                       xml_error_string(xml_get_error_code($parser)),
+                                       xml_get_current_line_number($parser));
+                       //error_log($errstr);
+                       $r = new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'], $this->xmlrpcstr['invalid_return']);
+                       xml_parser_free($parser);
+                       return $r;
+               }
+               xml_parser_free($parser);
+               
+               // ---------------------------------------
+               //  Got Ourselves Some Badness, It Seems
+               // ---------------------------------------
+               
+               if ($this->xh[$parser]['isf'] > 1)
+               {
+                       if ($this->debug === TRUE)
+                       {
+                               echo "---Invalid Return---\n";
+                               echo $this->xh[$parser]['isf_reason'];
+                               echo "---Invalid Return---\n\n";
+                       }
+                               
+                       $r = new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'],$this->xmlrpcstr['invalid_return'].' '.$this->xh[$parser]['isf_reason']);
+                       return $r;
+               }
+               elseif ( ! is_object($this->xh[$parser]['value']))
+               {
+                       $r = new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'],$this->xmlrpcstr['invalid_return'].' '.$this->xh[$parser]['isf_reason']);
+                       return $r;
+               }
+               
+               //-------------------------------------
+               //  DISPLAY XML CONTENT for DEBUGGING
+               //-------------------------------------         
+               
+               if ($this->debug === TRUE)
+               {
+                       echo "<pre>";
+                       
+                       if (count($this->xh[$parser]['headers'] > 0))
+                       {
+                               echo "---HEADERS---\n";
+                               foreach ($this->xh[$parser]['headers'] as $header)
+                               {
+                                       echo "$header\n";
+                               }
+                               echo "---END HEADERS---\n\n";
+                       }
+                       
+                       echo "---DATA---\n" . htmlspecialchars($data) . "\n---END DATA---\n\n";
+                       
+                       echo "---PARSED---\n" ;
+                       var_dump($this->xh[$parser]['value']);
+                       echo "\n---END PARSED---</pre>";
+               }
+               
+               //-------------------------------------
+               //  SEND RESPONSE
+               //-------------------------------------
+               
+               $v = $this->xh[$parser]['value'];
+                       
+               if ($this->xh[$parser]['isf'])
+               {
+                       $errno_v = $v->me['struct']['faultCode'];
+                       $errstr_v = $v->me['struct']['faultString'];
+                       $errno = $errno_v->scalarval();
+
+                       if ($errno == 0)
+                       {
+                               // FAULT returned, errno needs to reflect that
+                               $errno = -1;
+                       }
+
+                       $r = new XML_RPC_Response($v, $errno, $errstr_v->scalarval());
+               }
+               else
+               {
+                       $r = new XML_RPC_Response($v);
+               }
+
+               $r->headers = $this->xh[$parser]['headers'];
+               return $r;
+       }
+       
+       // ------------------------------------
+       //  Begin Return Message Parsing section
+       // ------------------------------------
+       
+       // quick explanation of components:
+       //   ac - used to accumulate values
+       //   isf - used to indicate a fault
+       //   lv - used to indicate "looking for a value": implements
+       //              the logic to allow values with no types to be strings
+       //   params - used to store parameters in method calls
+       //   method - used to store method name
+       //       stack - array with parent tree of the xml element,
+       //                       used to validate the nesting of elements
+
+       //-------------------------------------
+       //  Start Element Handler
+       //-------------------------------------
+
+       function open_tag($the_parser, $name, $attrs)
+       {
+               // If invalid nesting, then return
+               if ($this->xh[$the_parser]['isf'] > 1) return;
+               
+               // Evaluate and check for correct nesting of XML elements
+               
+               if (count($this->xh[$the_parser]['stack']) == 0)
+               {
+                       if ($name != 'METHODRESPONSE' && $name != 'METHODCALL')
+                       {
+                               $this->xh[$the_parser]['isf'] = 2;
+                               $this->xh[$the_parser]['isf_reason'] = 'Top level XML-RPC element is missing';
+                               return;
+                       }
+               }
+               else
+               {
+                       // not top level element: see if parent is OK
+                       if ( ! in_array($this->xh[$the_parser]['stack'][0], $this->valid_parents[$name], TRUE))
+                       {
+                               $this->xh[$the_parser]['isf'] = 2;
+                               $this->xh[$the_parser]['isf_reason'] = "XML-RPC element $name cannot be child of ".$this->xh[$the_parser]['stack'][0];
+                               return;
+                       }
+               }
+               
+               switch($name)
+               {
+                       case 'STRUCT':
+                       case 'ARRAY':
+                               // Creates array for child elements
+                               
+                               $cur_val = array('value' => array(),
+                                                                'type'  => $name);
+                                                               
+                               array_unshift($this->xh[$the_parser]['valuestack'], $cur_val);
+                       break;
+                       case 'METHODNAME':
+                       case 'NAME':
+                               $this->xh[$the_parser]['ac'] = '';
+                       break;
+                       case 'FAULT':
+                               $this->xh[$the_parser]['isf'] = 1;
+                       break;
+                       case 'PARAM':
+                               $this->xh[$the_parser]['value'] = null;
+                       break;
+                       case 'VALUE':
+                               $this->xh[$the_parser]['vt'] = 'value';
+                               $this->xh[$the_parser]['ac'] = '';
+                               $this->xh[$the_parser]['lv'] = 1;
+                       break;
+                       case 'I4':
+                       case 'INT':
+                       case 'STRING':
+                       case 'BOOLEAN':
+                       case 'DOUBLE':
+                       case 'DATETIME.ISO8601':
+                       case 'BASE64':
+                               if ($this->xh[$the_parser]['vt'] != 'value')
+                               {
+                                       //two data elements inside a value: an error occurred!
+                                       $this->xh[$the_parser]['isf'] = 2;
+                                       $this->xh[$the_parser]['isf_reason'] = "'Twas a $name element following a ".$this->xh[$the_parser]['vt']." element inside a single value";
+                                       return;
+                               }
+                               
+                               $this->xh[$the_parser]['ac'] = '';
+                       break;
+                       case 'MEMBER':
+                               // Set name of <member> to nothing to prevent errors later if no <name> is found
+                               $this->xh[$the_parser]['valuestack'][0]['name'] = '';
+                               
+                               // Set NULL value to check to see if value passed for this param/member
+                               $this->xh[$the_parser]['value'] = null;
+                       break;
+                       case 'DATA':
+                       case 'METHODCALL':
+                       case 'METHODRESPONSE':
+                       case 'PARAMS':
+                               // valid elements that add little to processing
+                       break;
+                       default:
+                               /// An Invalid Element is Found, so we have trouble
+                               $this->xh[$the_parser]['isf'] = 2;
+                               $this->xh[$the_parser]['isf_reason'] = "Invalid XML-RPC element found: $name";
+                       break;
+               }
+               
+               // Add current element name to stack, to allow validation of nesting
+               array_unshift($this->xh[$the_parser]['stack'], $name);
+
+               if ($name != 'VALUE') $this->xh[$the_parser]['lv'] = 0;
+       }
+       // END
+
+
+       //-------------------------------------
+       //  End Element Handler
+       //-------------------------------------
+
+       function closing_tag($the_parser, $name)
+       {
+               if ($this->xh[$the_parser]['isf'] > 1) return;
+               
+               // Remove current element from stack and set variable
+               // NOTE: If the XML validates, then we do not have to worry about
+               // the opening and closing of elements.  Nesting is checked on the opening
+               // tag so we be safe there as well.
+               
+               $curr_elem = array_shift($this->xh[$the_parser]['stack']);
+       
+               switch($name)
+               {
+                       case 'STRUCT':
+                       case 'ARRAY':
+                               $cur_val = array_shift($this->xh[$the_parser]['valuestack']);
+                               $this->xh[$the_parser]['value'] = ( ! isset($cur_val['values'])) ? array() : $cur_val['values'];
+                               $this->xh[$the_parser]['vt']    = strtolower($name);
+                       break;
+                       case 'NAME':
+                               $this->xh[$the_parser]['valuestack'][0]['name'] = $this->xh[$the_parser]['ac'];
+                       break;
+                       case 'BOOLEAN':
+                       case 'I4':
+                       case 'INT':
+                       case 'STRING':
+                       case 'DOUBLE':
+                       case 'DATETIME.ISO8601':
+                       case 'BASE64':
+                               $this->xh[$the_parser]['vt'] = strtolower($name);
+                               
+                               if ($name == 'STRING')
+                               {
+                                       $this->xh[$the_parser]['value'] = $this->xh[$the_parser]['ac'];
+                               }
+                               elseif ($name=='DATETIME.ISO8601')
+                               {
+                                       $this->xh[$the_parser]['vt']    = $this->xmlrpcDateTime;
+                                       $this->xh[$the_parser]['value'] = $this->xh[$the_parser]['ac'];
+                               }
+                               elseif ($name=='BASE64')
+                               {
+                                       $this->xh[$the_parser]['value'] = base64_decode($this->xh[$the_parser]['ac']);
+                               }
+                               elseif ($name=='BOOLEAN')
+                               {
+                                       // Translated BOOLEAN values to TRUE AND FALSE
+                                       if ($this->xh[$the_parser]['ac'] == '1')
+                                       {
+                                               $this->xh[$the_parser]['value'] = TRUE;
+                                       }
+                                       else
+                                       {
+                                               $this->xh[$the_parser]['value'] = FALSE;
+                                       }
+                               }
+                               elseif ($name=='DOUBLE')
+                               {
+                                       // we have a DOUBLE
+                                       // we must check that only 0123456789-.<space> are characters here
+                                       if ( ! preg_match('/^[+-]?[eE0-9\t \.]+$/', $this->xh[$the_parser]['ac']))
+                                       {
+                                               $this->xh[$the_parser]['value'] = 'ERROR_NON_NUMERIC_FOUND';
+                                       }
+                                       else
+                                       {
+                                               $this->xh[$the_parser]['value'] = (double)$this->xh[$the_parser]['ac'];
+                                       }
+                               }
+                               else
+                               {
+                                       // we have an I4/INT
+                                       // we must check that only 0123456789-<space> are characters here
+                                       if ( ! preg_match('/^[+-]?[0-9\t ]+$/', $this->xh[$the_parser]['ac']))
+                                       {
+                                               $this->xh[$the_parser]['value'] = 'ERROR_NON_NUMERIC_FOUND';
+                                       }
+                                       else
+                                       {
+                                               $this->xh[$the_parser]['value'] = (int)$this->xh[$the_parser]['ac'];
+                                       }
+                               }
+                               $this->xh[$the_parser]['ac'] = '';
+                               $this->xh[$the_parser]['lv'] = 3; // indicate we've found a value
+                       break;
+                       case 'VALUE':
+                               // This if() detects if no scalar was inside <VALUE></VALUE>
+                               if ($this->xh[$the_parser]['vt']=='value')
+                               {
+                                       $this->xh[$the_parser]['value'] = $this->xh[$the_parser]['ac'];
+                                       $this->xh[$the_parser]['vt']    = $this->xmlrpcString;
+                               }
+                               
+                               // build the XML-RPC value out of the data received, and substitute it
+                               $temp = new XML_RPC_Values($this->xh[$the_parser]['value'], $this->xh[$the_parser]['vt']);
+                               
+                               if (count($this->xh[$the_parser]['valuestack']) && $this->xh[$the_parser]['valuestack'][0]['type'] == 'ARRAY')
+                               {
+                                       // Array
+                                       $this->xh[$the_parser]['valuestack'][0]['values'][] = $temp;
+                               }
+                               else
+                               {
+                                       // Struct
+                                       $this->xh[$the_parser]['value'] = $temp;
+                               }
+                       break;
+                       case 'MEMBER':
+                               $this->xh[$the_parser]['ac']='';
+                               
+                               // If value add to array in the stack for the last element built
+                               if ($this->xh[$the_parser]['value'])
+                               {
+                                       $this->xh[$the_parser]['valuestack'][0]['values'][$this->xh[$the_parser]['valuestack'][0]['name']] = $this->xh[$the_parser]['value'];
+                               }
+                       break;
+                       case 'DATA':
+                               $this->xh[$the_parser]['ac']='';
+                       break;
+                       case 'PARAM':
+                               if ($this->xh[$the_parser]['value'])
+                               {
+                                       $this->xh[$the_parser]['params'][] = $this->xh[$the_parser]['value'];
+                               }
+                       break;
+                       case 'METHODNAME':
+                               $this->xh[$the_parser]['method'] = ltrim($this->xh[$the_parser]['ac']);
+                       break;
+                       case 'PARAMS':
+                       case 'FAULT':
+                       case 'METHODCALL':
+                       case 'METHORESPONSE':
+                               // We're all good kids with nuthin' to do
+                       break;
+                       default:
+                               // End of an Invalid Element.  Taken care of during the opening tag though
+                       break;
+               }
+       }
+
+       //-------------------------------------
+       //  Parses Character Data
+       //-------------------------------------
+
+       function character_data($the_parser, $data)
+       {
+               if ($this->xh[$the_parser]['isf'] > 1) return; // XML Fault found already
+               
+               // If a value has not been found
+               if ($this->xh[$the_parser]['lv'] != 3)
+               {
+                       if ($this->xh[$the_parser]['lv'] == 1)
+                       {
+                               $this->xh[$the_parser]['lv'] = 2; // Found a value
+                       }
+                               
+                       if( ! @isset($this->xh[$the_parser]['ac']))
+                       {
+                               $this->xh[$the_parser]['ac'] = '';
+                       }
+                               
+                       $this->xh[$the_parser]['ac'] .= $data;
+               }
+       }
+       
+       
+       function addParam($par) { $this->params[]=$par; }
+       
+       function output_parameters($array=FALSE)
+       {
+               $CI =& get_instance();  
+
+               if ($array !== FALSE && is_array($array))
+               {
+                       while (list($key) = each($array))
+                       {
+                               if (is_array($array[$key]))
+                               {
+                                       $array[$key] = $this->output_parameters($array[$key]);
+                               }
+                               else
+                               {
+                                       $array[$key] = $CI->input->xss_clean($array[$key]);
+                               }
+                       }
+                       
+                       $parameters = $array;
+               }
+               else
+               {
+                       $parameters = array();
+               
+                       for ($i = 0; $i < count($this->params); $i++)
+                       {
+                               $a_param = $this->decode_message($this->params[$i]);
+                               
+                               if (is_array($a_param))
+                               {
+                                       $parameters[] = $this->output_parameters($a_param);
+                               }
+                               else
+                               {
+                                       $parameters[] = $CI->input->xss_clean($a_param);
+                               }
+                       }       
+               }
+               
+               return $parameters;
+       }
+       
+       
+       function decode_message($param)
+       {
+               $kind = $param->kindOf();
+
+               if($kind == 'scalar')
+               {
+                       return $param->scalarval();
+               }
+               elseif($kind == 'array')
+               {
+                       reset($param->me);
+                       list($a,$b) = each($param->me);
+                       
+                       $arr = array();
+
+                       for($i = 0; $i < count($b); $i++)
+                       {
+                               $arr[] = $this->decode_message($param->me['array'][$i]);
+                       }
+                       
+                       return $arr;
+               }
+               elseif($kind == 'struct')
+               {
+                       reset($param->me['struct']);
+                       
+                       $arr = array();
+
+                       while(list($key,$value) = each($param->me['struct']))
+                       {
+                               $arr[$key] = $this->decode_message($value);
+                       }
+                       
+                       return $arr;
+               }
+       }
+       
+} // End XML_RPC_Messages class
+
+
+
+/**
+ * XML-RPC Values class
+ *
+ * @category   XML-RPC
+ * @author             ExpressionEngine Dev Team
+ * @link               http://codeigniter.com/user_guide/libraries/xmlrpc.html
+ */
+class XML_RPC_Values extends CI_Xmlrpc
+{
+       var $me         = array();
+       var $mytype     = 0;
+
+       function XML_RPC_Values($val=-1, $type='')
+       {       
+               parent::CI_Xmlrpc();
+               
+               if ($val != -1 OR $type != '')
+               {
+                       $type = $type == '' ? 'string' : $type;
+                       
+                       if ($this->xmlrpcTypes[$type] == 1)
+                       {
+                               $this->addScalar($val,$type);
+                       }
+                       elseif ($this->xmlrpcTypes[$type] == 2)
+                       {
+                               $this->addArray($val);
+                       }
+                       elseif ($this->xmlrpcTypes[$type] == 3)
+                       {
+                               $this->addStruct($val);
+                       }
+               }
+       }
+
+       function addScalar($val, $type='string')
+       {
+               $typeof = $this->xmlrpcTypes[$type];
+               
+               if ($this->mytype==1)
+               {
+                       echo '<strong>XML_RPC_Values</strong>: scalar can have only one value<br />';
+                       return 0;
+               }
+               
+               if ($typeof != 1)
+               {
+                       echo '<strong>XML_RPC_Values</strong>: not a scalar type (${typeof})<br />';
+                       return 0;
+               }
+
+               if ($type == $this->xmlrpcBoolean)
+               {
+                       if (strcasecmp($val,'true')==0 OR $val==1 OR ($val==true && strcasecmp($val,'false')))
+                       {
+                               $val = 1;
+                       }
+                       else
+                       {
+                               $val=0;
+                       }
+               }
+
+               if ($this->mytype == 2)
+               {
+                       // adding to an array here
+                       $ar = $this->me['array'];
+                       $ar[] = new XML_RPC_Values($val, $type);
+                       $this->me['array'] = $ar;
+               }
+               else
+               {
+                       // a scalar, so set the value and remember we're scalar
+                       $this->me[$type] = $val;
+                       $this->mytype = $typeof;
+               }
+               return 1;
+       }
+
+       function addArray($vals)
+       {
+               if ($this->mytype != 0)
+               {
+                       echo '<strong>XML_RPC_Values</strong>: already initialized as a [' . $this->kindOf() . ']<br />';
+                       return 0;
+               }
+
+               $this->mytype = $this->xmlrpcTypes['array'];
+               $this->me['array'] = $vals;
+               return 1;
+       }
+
+       function addStruct($vals)
+       {
+               if ($this->mytype != 0)
+               {
+                       echo '<strong>XML_RPC_Values</strong>: already initialized as a [' . $this->kindOf() . ']<br />';
+                       return 0;
+               }
+               $this->mytype = $this->xmlrpcTypes['struct'];
+               $this->me['struct'] = $vals;
+               return 1;
+       }
+
+       function kindOf()
+       {
+               switch($this->mytype)
+               {
+                       case 3:
+                               return 'struct';
+                               break;
+                       case 2:
+                               return 'array';
+                               break;
+                       case 1:
+                               return 'scalar';
+                               break;
+                       default:
+                               return 'undef';
+               }
+       }
+
+       function serializedata($typ, $val)
+       {
+               $rs = '';
+               
+               switch($this->xmlrpcTypes[$typ])
+               {
+                       case 3:
+                               // struct
+                               $rs .= "<struct>\n";
+                               reset($val);
+                               while(list($key2, $val2) = each($val))
+                               {
+                                       $rs .= "<member>\n<name>{$key2}</name>\n";
+                                       $rs .= $this->serializeval($val2);
+                                       $rs .= "</member>\n";
+                               }
+                               $rs .= '</struct>';
+                       break;
+                       case 2:
+                               // array
+                               $rs .= "<array>\n<data>\n";
+                               for($i=0; $i < count($val); $i++)
+                               {
+                                       $rs .= $this->serializeval($val[$i]);
+                               }
+                               $rs.="</data>\n</array>\n";
+                               break;
+                       case 1:
+                               // others
+                               switch ($typ)
+                               {
+                                       case $this->xmlrpcBase64:
+                                               $rs .= "<{$typ}>" . base64_encode((string)$val) . "</{$typ}>\n";
+                                       break;
+                                       case $this->xmlrpcBoolean:
+                                               $rs .= "<{$typ}>" . ((bool)$val ? '1' : '0') . "</{$typ}>\n";
+                                       break;
+                                       case $this->xmlrpcString:
+                                               $rs .= "<{$typ}>" . htmlspecialchars((string)$val). "</{$typ}>\n";
+                                       break;
+                                       default:
+                                               $rs .= "<{$typ}>{$val}</{$typ}>\n";
+                                       break;
+                               }
+                       default:
+                       break;
+               }
+               return $rs;
+       }
+
+       function serialize_class()
+       {
+               return $this->serializeval($this);
+       }
+
+       function serializeval($o)
+       {
+               $ar = $o->me;
+               reset($ar);
+               
+               list($typ, $val) = each($ar);
+               $rs = "<value>\n".$this->serializedata($typ, $val)."</value>\n";
+               return $rs;
+       }
+       
+       function scalarval()
+       {
+               reset($this->me);
+               list($a,$b) = each($this->me);
+               return $b;
+       }
+
+
+       //-------------------------------------
+       // Encode time in ISO-8601 form.
+       //-------------------------------------
+       
+       // Useful for sending time in XML-RPC
+
+       function iso8601_encode($time, $utc=0)
+       {       
+               if ($utc == 1)
+               {
+                       $t = strftime("%Y%m%dT%H:%M:%S", $time);
+               }
+               else
+               {
+                       if (function_exists('gmstrftime'))
+                               $t = gmstrftime("%Y%m%dT%H:%M:%S", $time);
+                       else
+                               $t = strftime("%Y%m%dT%H:%M:%S", $time - date('Z'));
+               }
+               return $t;
+       }
+       
+}
+// END XML_RPC_Values Class
+
+/* End of file Xmlrpc.php */
 /* Location: ./system/libraries/Xmlrpc.php */
\ No newline at end of file