blob: b6e6c810d18f66a16ea53429006c023bffb9ed66 [file] [log] [blame]
Andrey Andreeva30faf92011-12-25 18:15:34 +02001<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
Derek Allard2067d1a2008-11-13 22:59:24 +00002/**
3 * CodeIgniter
4 *
Phil Sturgeon07c1ac82012-03-09 17:03:37 +00005 * An open source application development framework for PHP 5.2.4 or newer
Derek Allard2067d1a2008-11-13 22:59:24 +00006 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05007 * NOTICE OF LICENSE
Andrey Andreeva30faf92011-12-25 18:15:34 +02008 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05009 * Licensed under the Open Software License version 3.0
Andrey Andreeva30faf92011-12-25 18:15:34 +020010 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -050011 * This source file is subject to the Open Software License (OSL 3.0) that is
12 * bundled with this package in the files license.txt / license.rst. It is
13 * also available through the world wide web at this URL:
14 * http://opensource.org/licenses/OSL-3.0
15 * If you did not receive a copy of the license and are unable to obtain it
16 * through the world wide web, please send an email to
17 * licensing@ellislab.com so we can send you a copy immediately.
18 *
Derek Allard2067d1a2008-11-13 22:59:24 +000019 * @package CodeIgniter
Derek Jonesf4a4bd82011-10-20 12:18:42 -050020 * @author EllisLab Dev Team
Greg Aker0defe5d2012-01-01 18:46:41 -060021 * @copyright Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
Derek Jonesf4a4bd82011-10-20 12:18:42 -050022 * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
Derek Allard2067d1a2008-11-13 22:59:24 +000023 * @link http://codeigniter.com
24 * @since Version 1.0
25 * @filesource
26 */
27
28if ( ! function_exists('xml_parser_create'))
Barry Mienydd671972010-10-04 16:33:58 +020029{
Derek Allard2067d1a2008-11-13 22:59:24 +000030 show_error('Your PHP installation does not support XML');
31}
32
33
34// ------------------------------------------------------------------------
35
36/**
37 * XML-RPC request handler class
38 *
39 * @package CodeIgniter
40 * @subpackage Libraries
41 * @category XML-RPC
Derek Jonesf4a4bd82011-10-20 12:18:42 -050042 * @author EllisLab Dev Team
Derek Allard2067d1a2008-11-13 22:59:24 +000043 * @link http://codeigniter.com/user_guide/libraries/xmlrpc.html
44 */
45class CI_Xmlrpc {
46
Andrey Andreeva30faf92011-12-25 18:15:34 +020047 public $debug = FALSE; // Debugging on or off
48 public $xmlrpcI4 = 'i4';
49 public $xmlrpcInt = 'int';
50 public $xmlrpcBoolean = 'boolean';
51 public $xmlrpcDouble = 'double';
52 public $xmlrpcString = 'string';
53 public $xmlrpcDateTime = 'dateTime.iso8601';
54 public $xmlrpcBase64 = 'base64';
55 public $xmlrpcArray = 'array';
56 public $xmlrpcStruct = 'struct';
Barry Mienydd671972010-10-04 16:33:58 +020057
Andrey Andreeva30faf92011-12-25 18:15:34 +020058 public $xmlrpcTypes = array();
59 public $valid_parents = array();
60 public $xmlrpcerr = array(); // Response numbers
61 public $xmlrpcstr = array(); // Response strings
Barry Mienydd671972010-10-04 16:33:58 +020062
Andrey Andreeva30faf92011-12-25 18:15:34 +020063 public $xmlrpc_defencoding = 'UTF-8';
64 public $xmlrpcName = 'XML-RPC for CodeIgniter';
65 public $xmlrpcVersion = '1.1';
66 public $xmlrpcerruser = 800; // Start of user errors
67 public $xmlrpcerrxml = 100; // Start of XML Parse errors
68 public $xmlrpc_backslash = ''; // formulate backslashes for escaping regexp
Barry Mienydd671972010-10-04 16:33:58 +020069
Andrey Andreeva30faf92011-12-25 18:15:34 +020070 public $client;
71 public $method;
72 public $data;
73 public $message = '';
74 public $error = ''; // Error string for request
75 public $result;
76 public $response = array(); // Response from remote server
Derek Allard2067d1a2008-11-13 22:59:24 +000077
Andrey Andreeva30faf92011-12-25 18:15:34 +020078 public $xss_clean = TRUE;
Derek Allard2067d1a2008-11-13 22:59:24 +000079
80 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -050081 // VALUES THAT MULTIPLE CLASSES NEED
Derek Allard2067d1a2008-11-13 22:59:24 +000082 //-------------------------------------
83
Greg Akera9263282010-11-10 15:26:43 -060084 public function __construct($config = array())
Derek Allard2067d1a2008-11-13 22:59:24 +000085 {
Andrey Andreeva30faf92011-12-25 18:15:34 +020086 $this->xmlrpcName = $this->xmlrpcName;
Derek Allard2067d1a2008-11-13 22:59:24 +000087 $this->xmlrpc_backslash = chr(92).chr(92);
Barry Mienydd671972010-10-04 16:33:58 +020088
Derek Allard2067d1a2008-11-13 22:59:24 +000089 // Types for info sent back and forth
90 $this->xmlrpcTypes = array(
Barry Mienydd671972010-10-04 16:33:58 +020091 $this->xmlrpcI4 => '1',
92 $this->xmlrpcInt => '1',
93 $this->xmlrpcBoolean => '1',
94 $this->xmlrpcString => '1',
95 $this->xmlrpcDouble => '1',
96 $this->xmlrpcDateTime => '1',
97 $this->xmlrpcBase64 => '1',
98 $this->xmlrpcArray => '2',
99 $this->xmlrpcStruct => '3'
Derek Allard2067d1a2008-11-13 22:59:24 +0000100 );
Barry Mienydd671972010-10-04 16:33:58 +0200101
Derek Allard2067d1a2008-11-13 22:59:24 +0000102 // Array of Valid Parents for Various XML-RPC elements
103 $this->valid_parents = array('BOOLEAN' => array('VALUE'),
Andrey Andreeva30faf92011-12-25 18:15:34 +0200104 'I4' => array('VALUE'),
105 'INT' => array('VALUE'),
106 'STRING' => array('VALUE'),
107 'DOUBLE' => array('VALUE'),
108 'DATETIME.ISO8601' => array('VALUE'),
109 'BASE64' => array('VALUE'),
110 'ARRAY' => array('VALUE'),
111 'STRUCT' => array('VALUE'),
112 'PARAM' => array('PARAMS'),
113 'METHODNAME' => array('METHODCALL'),
114 'PARAMS' => array('METHODCALL', 'METHODRESPONSE'),
115 'MEMBER' => array('STRUCT'),
116 'NAME' => array('MEMBER'),
117 'DATA' => array('ARRAY'),
118 'FAULT' => array('METHODRESPONSE'),
119 'VALUE' => array('MEMBER', 'DATA', 'PARAM', 'FAULT')
120 );
Barry Mienydd671972010-10-04 16:33:58 +0200121
122
Derek Allard2067d1a2008-11-13 22:59:24 +0000123 // XML-RPC Responses
124 $this->xmlrpcerr['unknown_method'] = '1';
125 $this->xmlrpcstr['unknown_method'] = 'This is not a known method for this XML-RPC Server';
126 $this->xmlrpcerr['invalid_return'] = '2';
Derek Jones37f4b9c2011-07-01 17:56:50 -0500127 $this->xmlrpcstr['invalid_return'] = 'The XML data received was either invalid or not in the correct form for XML-RPC. Turn on debugging to examine the XML data further.';
Derek Allard2067d1a2008-11-13 22:59:24 +0000128 $this->xmlrpcerr['incorrect_params'] = '3';
129 $this->xmlrpcstr['incorrect_params'] = 'Incorrect parameters were passed to method';
130 $this->xmlrpcerr['introspect_unknown'] = '4';
Andrey Andreeva30faf92011-12-25 18:15:34 +0200131 $this->xmlrpcstr['introspect_unknown'] = 'Cannot inspect signature for request: method unknown';
Derek Allard2067d1a2008-11-13 22:59:24 +0000132 $this->xmlrpcerr['http_error'] = '5';
133 $this->xmlrpcstr['http_error'] = "Did not receive a '200 OK' response from remote server.";
134 $this->xmlrpcerr['no_data'] = '6';
135 $this->xmlrpcstr['no_data'] ='No data received from server.';
Barry Mienydd671972010-10-04 16:33:58 +0200136
Derek Allard2067d1a2008-11-13 22:59:24 +0000137 $this->initialize($config);
Barry Mienydd671972010-10-04 16:33:58 +0200138
Andrey Andreev8f50b6b2012-03-28 14:12:09 +0300139 log_message('debug', 'XML-RPC Class Initialized');
Derek Allard2067d1a2008-11-13 22:59:24 +0000140 }
Barry Mienydd671972010-10-04 16:33:58 +0200141
Derek Allard2067d1a2008-11-13 22:59:24 +0000142 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500143 // Initialize Prefs
Derek Allard2067d1a2008-11-13 22:59:24 +0000144 //-------------------------------------
145
Andrey Andreeva30faf92011-12-25 18:15:34 +0200146 public function initialize($config = array())
Derek Allard2067d1a2008-11-13 22:59:24 +0000147 {
Derek Jones33559102009-02-02 18:50:38 +0000148 if (count($config) > 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000149 {
150 foreach ($config as $key => $val)
151 {
152 if (isset($this->$key))
153 {
Barry Mienydd671972010-10-04 16:33:58 +0200154 $this->$key = $val;
Derek Allard2067d1a2008-11-13 22:59:24 +0000155 }
156 }
157 }
158 }
159 // END
Barry Mienydd671972010-10-04 16:33:58 +0200160
Derek Allard2067d1a2008-11-13 22:59:24 +0000161 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500162 // Take URL and parse it
Derek Allard2067d1a2008-11-13 22:59:24 +0000163 //-------------------------------------
164
Andrey Andreev8f50b6b2012-03-28 14:12:09 +0300165 public function server($url, $port = 80)
Derek Allard2067d1a2008-11-13 22:59:24 +0000166 {
Andrey Andreeva30faf92011-12-25 18:15:34 +0200167 if (strpos($url, 'http') !== 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000168 {
169 $url = "http://".$url;
170 }
Barry Mienydd671972010-10-04 16:33:58 +0200171
Derek Allard2067d1a2008-11-13 22:59:24 +0000172 $parts = parse_url($url);
Barry Mienydd671972010-10-04 16:33:58 +0200173
Andrey Andreev8f50b6b2012-03-28 14:12:09 +0300174 $path = isset($parts['path']) ? $parts['path'] : '/';
Barry Mienydd671972010-10-04 16:33:58 +0200175
Andrey Andreev8f50b6b2012-03-28 14:12:09 +0300176 if ( ! empty($parts['query']))
Derek Allard2067d1a2008-11-13 22:59:24 +0000177 {
178 $path .= '?'.$parts['query'];
Barry Mienydd671972010-10-04 16:33:58 +0200179 }
180
Derek Allard2067d1a2008-11-13 22:59:24 +0000181 $this->client = new XML_RPC_Client($path, $parts['host'], $port);
182 }
183 // END
Barry Mienydd671972010-10-04 16:33:58 +0200184
Derek Allard2067d1a2008-11-13 22:59:24 +0000185 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500186 // Set Timeout
Derek Allard2067d1a2008-11-13 22:59:24 +0000187 //-------------------------------------
188
Andrey Andreeva30faf92011-12-25 18:15:34 +0200189 public function timeout($seconds = 5)
Derek Allard2067d1a2008-11-13 22:59:24 +0000190 {
191 if ( ! is_null($this->client) && is_int($seconds))
192 {
193 $this->client->timeout = $seconds;
194 }
195 }
196 // END
Barry Mienydd671972010-10-04 16:33:58 +0200197
Derek Allard2067d1a2008-11-13 22:59:24 +0000198 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500199 // Set Methods
Derek Allard2067d1a2008-11-13 22:59:24 +0000200 //-------------------------------------
201
Andrey Andreeva30faf92011-12-25 18:15:34 +0200202 public function method($function)
Derek Allard2067d1a2008-11-13 22:59:24 +0000203 {
204 $this->method = $function;
205 }
206 // END
Barry Mienydd671972010-10-04 16:33:58 +0200207
Derek Allard2067d1a2008-11-13 22:59:24 +0000208 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500209 // Take Array of Data and Create Objects
Derek Allard2067d1a2008-11-13 22:59:24 +0000210 //-------------------------------------
211
Andrey Andreeva30faf92011-12-25 18:15:34 +0200212 public function request($incoming)
Derek Allard2067d1a2008-11-13 22:59:24 +0000213 {
214 if ( ! is_array($incoming))
215 {
216 // Send Error
217 }
Barry Mienydd671972010-10-04 16:33:58 +0200218
Derek Allard2067d1a2008-11-13 22:59:24 +0000219 $this->data = array();
Barry Mienydd671972010-10-04 16:33:58 +0200220
Pascal Kriete14287f32011-02-14 13:39:34 -0500221 foreach ($incoming as $key => $value)
Derek Allard2067d1a2008-11-13 22:59:24 +0000222 {
223 $this->data[$key] = $this->values_parsing($value);
224 }
225 }
226 // END
Barry Mienydd671972010-10-04 16:33:58 +0200227
228
Derek Allard2067d1a2008-11-13 22:59:24 +0000229 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500230 // Set Debug
Derek Allard2067d1a2008-11-13 22:59:24 +0000231 //-------------------------------------
232
Andrey Andreeva30faf92011-12-25 18:15:34 +0200233 public function set_debug($flag = TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000234 {
Andrey Andreeva30faf92011-12-25 18:15:34 +0200235 $this->debug = ($flag == TRUE);
Derek Allard2067d1a2008-11-13 22:59:24 +0000236 }
Barry Mienydd671972010-10-04 16:33:58 +0200237
Derek Allard2067d1a2008-11-13 22:59:24 +0000238 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500239 // Values Parsing
Derek Allard2067d1a2008-11-13 22:59:24 +0000240 //-------------------------------------
241
Andrey Andreeva30faf92011-12-25 18:15:34 +0200242 public function values_parsing($value, $return = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000243 {
Derek Jones8c4b5e72010-01-06 22:21:41 +0000244 if (is_array($value) && array_key_exists(0, $value))
Derek Allard2067d1a2008-11-13 22:59:24 +0000245 {
Andrey Andreev8f50b6b2012-03-28 14:12:09 +0300246 if ( ! isset($value[1], $this->xmlrpcTypes[$value[1]]))
Derek Allard2067d1a2008-11-13 22:59:24 +0000247 {
Andrey Andreeva30faf92011-12-25 18:15:34 +0200248 $temp = new XML_RPC_Values($value[0], (is_array($value[0]) ? 'array' : 'string'));
Derek Allard2067d1a2008-11-13 22:59:24 +0000249 }
250 else
251 {
Andrey Andreeva30faf92011-12-25 18:15:34 +0200252 if (is_array($value[0]) && ($value[1] == 'struct' OR $value[1] == 'array'))
253 {
254 while (list($k) = each($value[0]))
255 {
256 $value[0][$k] = $this->values_parsing($value[0][$k], TRUE);
257 }
258 }
259
260 $temp = new XML_RPC_Values($value[0], $value[1]);
Derek Allard2067d1a2008-11-13 22:59:24 +0000261 }
262 }
263 else
264 {
265 $temp = new XML_RPC_Values($value, 'string');
266 }
267
268 return $temp;
269 }
270 // END
271
272
273 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500274 // Sends XML-RPC Request
Derek Allard2067d1a2008-11-13 22:59:24 +0000275 //-------------------------------------
276
Andrey Andreeva30faf92011-12-25 18:15:34 +0200277 public function send_request()
Derek Allard2067d1a2008-11-13 22:59:24 +0000278 {
279 $this->message = new XML_RPC_Message($this->method,$this->data);
280 $this->message->debug = $this->debug;
Barry Mienydd671972010-10-04 16:33:58 +0200281
Andrey Andreeva30faf92011-12-25 18:15:34 +0200282 if ( ! $this->result = $this->client->send($this->message) OR ! is_object($this->result->val))
Derek Allard2067d1a2008-11-13 22:59:24 +0000283 {
284 $this->error = $this->result->errstr;
285 return FALSE;
286 }
Barry Mienydd671972010-10-04 16:33:58 +0200287
Derek Allard2067d1a2008-11-13 22:59:24 +0000288 $this->response = $this->result->decode();
Derek Allard2067d1a2008-11-13 22:59:24 +0000289 return TRUE;
290 }
291 // END
Barry Mienydd671972010-10-04 16:33:58 +0200292
Derek Allard2067d1a2008-11-13 22:59:24 +0000293 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500294 // Returns Error
Derek Allard2067d1a2008-11-13 22:59:24 +0000295 //-------------------------------------
296
Andrey Andreeva30faf92011-12-25 18:15:34 +0200297 public function display_error()
Derek Allard2067d1a2008-11-13 22:59:24 +0000298 {
299 return $this->error;
300 }
301 // END
Barry Mienydd671972010-10-04 16:33:58 +0200302
Derek Allard2067d1a2008-11-13 22:59:24 +0000303 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500304 // Returns Remote Server Response
Derek Allard2067d1a2008-11-13 22:59:24 +0000305 //-------------------------------------
306
Andrey Andreeva30faf92011-12-25 18:15:34 +0200307 public function display_response()
Derek Allard2067d1a2008-11-13 22:59:24 +0000308 {
309 return $this->response;
310 }
311 // END
Barry Mienydd671972010-10-04 16:33:58 +0200312
Derek Allard2067d1a2008-11-13 22:59:24 +0000313 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500314 // Sends an Error Message for Server Request
Derek Allard2067d1a2008-11-13 22:59:24 +0000315 //-------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200316
Andrey Andreeva30faf92011-12-25 18:15:34 +0200317 public function send_error_message($number, $message)
Derek Allard2067d1a2008-11-13 22:59:24 +0000318 {
Andrey Andreeva30faf92011-12-25 18:15:34 +0200319 return new XML_RPC_Response(0, $number, $message);
Derek Allard2067d1a2008-11-13 22:59:24 +0000320 }
321 // END
Barry Mienydd671972010-10-04 16:33:58 +0200322
323
Derek Allard2067d1a2008-11-13 22:59:24 +0000324 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500325 // Send Response for Server Request
Derek Allard2067d1a2008-11-13 22:59:24 +0000326 //-------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200327
Andrey Andreeva30faf92011-12-25 18:15:34 +0200328 public function send_response($response)
Derek Allard2067d1a2008-11-13 22:59:24 +0000329 {
330 // $response should be array of values, which will be parsed
331 // based on their data and type into a valid group of XML-RPC values
Andrey Andreeva30faf92011-12-25 18:15:34 +0200332 return new XML_RPC_Response($this->values_parsing($response));
Derek Allard2067d1a2008-11-13 22:59:24 +0000333 }
334 // END
Barry Mienydd671972010-10-04 16:33:58 +0200335
Derek Allard2067d1a2008-11-13 22:59:24 +0000336} // END XML_RPC Class
337
Barry Mienydd671972010-10-04 16:33:58 +0200338
Derek Allard2067d1a2008-11-13 22:59:24 +0000339/**
340 * XML-RPC Client class
341 *
342 * @category XML-RPC
Derek Jonesf4a4bd82011-10-20 12:18:42 -0500343 * @author EllisLab Dev Team
Derek Allard2067d1a2008-11-13 22:59:24 +0000344 * @link http://codeigniter.com/user_guide/libraries/xmlrpc.html
345 */
346class XML_RPC_Client extends CI_Xmlrpc
347{
Andrey Andreeva30faf92011-12-25 18:15:34 +0200348 public $path = '';
349 public $server = '';
350 public $port = 80;
351 public $errno = '';
352 public $errstring = '';
353 public $timeout = 5;
354 public $no_multicall = FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000355
Andrey Andreev8f50b6b2012-03-28 14:12:09 +0300356 public function __construct($path, $server, $port = 80)
Derek Allard2067d1a2008-11-13 22:59:24 +0000357 {
Greg Akera9263282010-11-10 15:26:43 -0600358 parent::__construct();
Barry Mienydd671972010-10-04 16:33:58 +0200359
Derek Allard2067d1a2008-11-13 22:59:24 +0000360 $this->port = $port;
361 $this->server = $server;
362 $this->path = $path;
363 }
Barry Mienydd671972010-10-04 16:33:58 +0200364
Andrey Andreeva30faf92011-12-25 18:15:34 +0200365 public function send($msg)
Derek Allard2067d1a2008-11-13 22:59:24 +0000366 {
367 if (is_array($msg))
368 {
369 // Multi-call disabled
370 $r = new XML_RPC_Response(0, $this->xmlrpcerr['multicall_recursion'],$this->xmlrpcstr['multicall_recursion']);
371 return $r;
372 }
373
374 return $this->sendPayload($msg);
375 }
376
Andrey Andreeva30faf92011-12-25 18:15:34 +0200377 public function sendPayload($msg)
Barry Mienydd671972010-10-04 16:33:58 +0200378 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000379 $fp = @fsockopen($this->server, $this->port,$this->errno, $this->errstr, $this->timeout);
Barry Mienydd671972010-10-04 16:33:58 +0200380
Derek Allard2067d1a2008-11-13 22:59:24 +0000381 if ( ! is_resource($fp))
382 {
383 error_log($this->xmlrpcstr['http_error']);
Andrey Andreev8f50b6b2012-03-28 14:12:09 +0300384 $r = new XML_RPC_Response(0, $this->xmlrpcerr['http_error'], $this->xmlrpcstr['http_error']);
Derek Allard2067d1a2008-11-13 22:59:24 +0000385 return $r;
386 }
Barry Mienydd671972010-10-04 16:33:58 +0200387
Pascal Kriete14287f32011-02-14 13:39:34 -0500388 if (empty($msg->payload))
Derek Allard2067d1a2008-11-13 22:59:24 +0000389 {
390 // $msg = XML_RPC_Messages
391 $msg->createPayload();
392 }
Barry Mienydd671972010-10-04 16:33:58 +0200393
Derek Allard2067d1a2008-11-13 22:59:24 +0000394 $r = "\r\n";
Andrey Andreev8f50b6b2012-03-28 14:12:09 +0300395 $op = 'POST '.$this->path.' HTTP/1.0'.$r
396 .'Host: '.$this->server.$r
397 .'Content-Type: text/xml'.$r
398 .'User-Agent: '.$this->xmlrpcName.$r
399 .'Content-Length: '.strlen($msg->payload).$r.$r
400 .$msg->payload;
Barry Mienydd671972010-10-04 16:33:58 +0200401
Derek Allard2067d1a2008-11-13 22:59:24 +0000402
403 if ( ! fputs($fp, $op, strlen($op)))
404 {
405 error_log($this->xmlrpcstr['http_error']);
406 $r = new XML_RPC_Response(0, $this->xmlrpcerr['http_error'], $this->xmlrpcstr['http_error']);
407 return $r;
408 }
409 $resp = $msg->parseResponse($fp);
410 fclose($fp);
411 return $resp;
412 }
413
Andrey Andreeva30faf92011-12-25 18:15:34 +0200414}
415// end class XML_RPC_Client
Derek Allard2067d1a2008-11-13 22:59:24 +0000416
417/**
418 * XML-RPC Response class
419 *
420 * @category XML-RPC
Derek Jonesf4a4bd82011-10-20 12:18:42 -0500421 * @author EllisLab Dev Team
Derek Allard2067d1a2008-11-13 22:59:24 +0000422 * @link http://codeigniter.com/user_guide/libraries/xmlrpc.html
423 */
424class XML_RPC_Response
425{
Andrey Andreeva30faf92011-12-25 18:15:34 +0200426 public $val = 0;
427 public $errno = 0;
428 public $errstr = '';
429 public $headers = array();
430 public $xss_clean = TRUE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000431
Greg Akera9263282010-11-10 15:26:43 -0600432 public function __construct($val, $code = 0, $fstr = '')
Barry Mienydd671972010-10-04 16:33:58 +0200433 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000434 if ($code != 0)
435 {
436 // error
437 $this->errno = $code;
Andrey Andreevb1956372012-01-03 11:01:48 +0200438 if ( ! is_php('5.4'))
439 {
440 $this->errstr = htmlspecialchars($fstr, ENT_NOQUOTES, 'UTF-8');
441 }
442 else
443 {
444 $this->errstr = htmlspecialchars($fstr, ENT_XML1 | ENT_NOQUOTES, 'UTF-8');
445 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000446 }
Andrey Andreev8f50b6b2012-03-28 14:12:09 +0300447 elseif ( ! is_object($val))
Derek Allard2067d1a2008-11-13 22:59:24 +0000448 {
449 // programmer error, not an object
Andrey Andreev8f50b6b2012-03-28 14:12:09 +0300450 error_log("Invalid type '".gettype($val)."' (value: ".$val.') passed to XML_RPC_Response. Defaulting to empty value.');
Derek Allard2067d1a2008-11-13 22:59:24 +0000451 $this->val = new XML_RPC_Values();
452 }
453 else
454 {
455 $this->val = $val;
456 }
457 }
458
Andrey Andreeva30faf92011-12-25 18:15:34 +0200459 public function faultCode()
Derek Allard2067d1a2008-11-13 22:59:24 +0000460 {
461 return $this->errno;
462 }
463
Andrey Andreeva30faf92011-12-25 18:15:34 +0200464 public function faultString()
Derek Allard2067d1a2008-11-13 22:59:24 +0000465 {
466 return $this->errstr;
467 }
468
Andrey Andreeva30faf92011-12-25 18:15:34 +0200469 public function value()
Derek Allard2067d1a2008-11-13 22:59:24 +0000470 {
471 return $this->val;
472 }
Barry Mienydd671972010-10-04 16:33:58 +0200473
Andrey Andreeva30faf92011-12-25 18:15:34 +0200474 public function prepare_response()
Derek Allard2067d1a2008-11-13 22:59:24 +0000475 {
Andrey Andreeva30faf92011-12-25 18:15:34 +0200476 return "<methodResponse>\n"
477 . ($this->errno
478 ? '<fault>
Derek Allard2067d1a2008-11-13 22:59:24 +0000479 <value>
480 <struct>
481 <member>
482 <name>faultCode</name>
483 <value><int>' . $this->errno . '</int></value>
484 </member>
485 <member>
486 <name>faultString</name>
487 <value><string>' . $this->errstr . '</string></value>
488 </member>
489 </struct>
490 </value>
Andrey Andreeva30faf92011-12-25 18:15:34 +0200491</fault>'
492 : "<params>\n<param>\n".$this->val->serialize_class()."</param>\n</params>")
493 . "\n</methodResponse>";
Derek Allard2067d1a2008-11-13 22:59:24 +0000494 }
Barry Mienydd671972010-10-04 16:33:58 +0200495
Andrey Andreeva30faf92011-12-25 18:15:34 +0200496 public function decode($array = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000497 {
498 $CI =& get_instance();
Andrey Andreeva30faf92011-12-25 18:15:34 +0200499
500 if (is_array($array))
Derek Allard2067d1a2008-11-13 22:59:24 +0000501 {
502 while (list($key) = each($array))
503 {
504 if (is_array($array[$key]))
505 {
506 $array[$key] = $this->decode($array[$key]);
507 }
508 else
509 {
Robin Sowell66a3fc02010-03-18 09:44:55 -0400510 $array[$key] = ($this->xss_clean) ? $CI->security->xss_clean($array[$key]) : $array[$key];
Derek Allard2067d1a2008-11-13 22:59:24 +0000511 }
512 }
Barry Mienydd671972010-10-04 16:33:58 +0200513
Derek Allard2067d1a2008-11-13 22:59:24 +0000514 $result = $array;
515 }
516 else
517 {
518 $result = $this->xmlrpc_decoder($this->val);
Barry Mienydd671972010-10-04 16:33:58 +0200519
Derek Allard2067d1a2008-11-13 22:59:24 +0000520 if (is_array($result))
521 {
522 $result = $this->decode($result);
523 }
524 else
525 {
Robin Sowell66a3fc02010-03-18 09:44:55 -0400526 $result = ($this->xss_clean) ? $CI->security->xss_clean($result) : $result;
Derek Allard2067d1a2008-11-13 22:59:24 +0000527 }
528 }
Barry Mienydd671972010-10-04 16:33:58 +0200529
Derek Allard2067d1a2008-11-13 22:59:24 +0000530 return $result;
531 }
532
Derek Allard2067d1a2008-11-13 22:59:24 +0000533 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500534 // XML-RPC Object to PHP Types
Derek Allard2067d1a2008-11-13 22:59:24 +0000535 //-------------------------------------
536
Andrey Andreeva30faf92011-12-25 18:15:34 +0200537 public function xmlrpc_decoder($xmlrpc_val)
Derek Allard2067d1a2008-11-13 22:59:24 +0000538 {
539 $kind = $xmlrpc_val->kindOf();
540
Pascal Kriete14287f32011-02-14 13:39:34 -0500541 if ($kind == 'scalar')
Derek Allard2067d1a2008-11-13 22:59:24 +0000542 {
543 return $xmlrpc_val->scalarval();
544 }
Pascal Kriete14287f32011-02-14 13:39:34 -0500545 elseif ($kind == 'array')
Derek Allard2067d1a2008-11-13 22:59:24 +0000546 {
547 reset($xmlrpc_val->me);
Andrey Andreevadc11752011-12-30 14:46:08 +0200548 $b = current($xmlrpc_val->me);
Derek Allard2067d1a2008-11-13 22:59:24 +0000549 $arr = array();
550
Andrey Andreeva30faf92011-12-25 18:15:34 +0200551 for ($i = 0, $size = count($b); $i < $size; $i++)
Derek Allard2067d1a2008-11-13 22:59:24 +0000552 {
553 $arr[] = $this->xmlrpc_decoder($xmlrpc_val->me['array'][$i]);
554 }
555 return $arr;
556 }
Pascal Kriete14287f32011-02-14 13:39:34 -0500557 elseif ($kind == 'struct')
Derek Allard2067d1a2008-11-13 22:59:24 +0000558 {
559 reset($xmlrpc_val->me['struct']);
560 $arr = array();
561
Pascal Kriete14287f32011-02-14 13:39:34 -0500562 while (list($key,$value) = each($xmlrpc_val->me['struct']))
Derek Allard2067d1a2008-11-13 22:59:24 +0000563 {
564 $arr[$key] = $this->xmlrpc_decoder($value);
565 }
566 return $arr;
567 }
568 }
Barry Mienydd671972010-10-04 16:33:58 +0200569
Derek Allard2067d1a2008-11-13 22:59:24 +0000570 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500571 // ISO-8601 time to server or UTC time
Derek Allard2067d1a2008-11-13 22:59:24 +0000572 //-------------------------------------
573
Andrey Andreeva30faf92011-12-25 18:15:34 +0200574 public function iso8601_decode($time, $utc = 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000575 {
576 // return a timet in the localtime, or UTC
577 $t = 0;
578 if (preg_match('/([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})/', $time, $regs))
579 {
Pascal Kriete14287f32011-02-14 13:39:34 -0500580 $fnc = ($utc == 1) ? 'gmmktime' : 'mktime';
581 $t = $fnc($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
Derek Allard2067d1a2008-11-13 22:59:24 +0000582 }
583 return $t;
584 }
Barry Mienydd671972010-10-04 16:33:58 +0200585
Andrey Andreeva30faf92011-12-25 18:15:34 +0200586}
587// End Response Class
Derek Allard2067d1a2008-11-13 22:59:24 +0000588
589/**
590 * XML-RPC Message class
591 *
592 * @category XML-RPC
Derek Jonesf4a4bd82011-10-20 12:18:42 -0500593 * @author EllisLab Dev Team
Derek Allard2067d1a2008-11-13 22:59:24 +0000594 * @link http://codeigniter.com/user_guide/libraries/xmlrpc.html
595 */
596class XML_RPC_Message extends CI_Xmlrpc
597{
Andrey Andreeva30faf92011-12-25 18:15:34 +0200598 public $payload;
599 public $method_name;
600 public $params = array();
601 public $xh = array();
Derek Allard2067d1a2008-11-13 22:59:24 +0000602
Andrey Andreev8f50b6b2012-03-28 14:12:09 +0300603 public function __construct($method, $pars = 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000604 {
Greg Akera9263282010-11-10 15:26:43 -0600605 parent::__construct();
Barry Mienydd671972010-10-04 16:33:58 +0200606
Derek Allard2067d1a2008-11-13 22:59:24 +0000607 $this->method_name = $method;
Derek Jones33559102009-02-02 18:50:38 +0000608 if (is_array($pars) && count($pars) > 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000609 {
Andrey Andreeva30faf92011-12-25 18:15:34 +0200610 for ($i = 0, $c = count($pars); $i < $c; $i++)
Derek Allard2067d1a2008-11-13 22:59:24 +0000611 {
612 // $pars[$i] = XML_RPC_Values
613 $this->params[] = $pars[$i];
614 }
615 }
616 }
Barry Mienydd671972010-10-04 16:33:58 +0200617
Derek Allard2067d1a2008-11-13 22:59:24 +0000618 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500619 // Create Payload to Send
Derek Allard2067d1a2008-11-13 22:59:24 +0000620 //-------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200621
Andrey Andreeva30faf92011-12-25 18:15:34 +0200622 public function createPayload()
Derek Allard2067d1a2008-11-13 22:59:24 +0000623 {
Andrey Andreeva30faf92011-12-25 18:15:34 +0200624 $this->payload = "<?xml version=\"1.0\"?".">\r\n<methodCall>\r\n"
625 . '<methodName>'.$this->method_name."</methodName>\r\n"
626 . "<params>\r\n";
Barry Mienydd671972010-10-04 16:33:58 +0200627
Andrey Andreeva30faf92011-12-25 18:15:34 +0200628 for ($i = 0, $c = count($this->params); $i < $c; $i++)
Derek Allard2067d1a2008-11-13 22:59:24 +0000629 {
630 // $p = XML_RPC_Values
631 $p = $this->params[$i];
632 $this->payload .= "<param>\r\n".$p->serialize_class()."</param>\r\n";
633 }
Barry Mienydd671972010-10-04 16:33:58 +0200634
Derek Allard2067d1a2008-11-13 22:59:24 +0000635 $this->payload .= "</params>\r\n</methodCall>\r\n";
636 }
Barry Mienydd671972010-10-04 16:33:58 +0200637
Derek Allard2067d1a2008-11-13 22:59:24 +0000638 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500639 // Parse External XML-RPC Server's Response
Derek Allard2067d1a2008-11-13 22:59:24 +0000640 //-------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200641
Andrey Andreeva30faf92011-12-25 18:15:34 +0200642 public function parseResponse($fp)
Derek Allard2067d1a2008-11-13 22:59:24 +0000643 {
644 $data = '';
Barry Mienydd671972010-10-04 16:33:58 +0200645
Pascal Kriete14287f32011-02-14 13:39:34 -0500646 while ($datum = fread($fp, 4096))
Derek Allard2067d1a2008-11-13 22:59:24 +0000647 {
648 $data .= $datum;
649 }
Barry Mienydd671972010-10-04 16:33:58 +0200650
Derek Allard2067d1a2008-11-13 22:59:24 +0000651 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500652 // DISPLAY HTTP CONTENT for DEBUGGING
Derek Allard2067d1a2008-11-13 22:59:24 +0000653 //-------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200654
Derek Allard2067d1a2008-11-13 22:59:24 +0000655 if ($this->debug === TRUE)
656 {
Andrey Andreeva30faf92011-12-25 18:15:34 +0200657 echo "<pre>---DATA---\n".htmlspecialchars($data)."\n---END DATA---\n\n</pre>";
Derek Allard2067d1a2008-11-13 22:59:24 +0000658 }
Barry Mienydd671972010-10-04 16:33:58 +0200659
Derek Allard2067d1a2008-11-13 22:59:24 +0000660 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500661 // Check for data
Derek Allard2067d1a2008-11-13 22:59:24 +0000662 //-------------------------------------
663
Andrey Andreeva30faf92011-12-25 18:15:34 +0200664 if ($data === '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000665 {
666 error_log($this->xmlrpcstr['no_data']);
667 $r = new XML_RPC_Response(0, $this->xmlrpcerr['no_data'], $this->xmlrpcstr['no_data']);
668 return $r;
669 }
Barry Mienydd671972010-10-04 16:33:58 +0200670
671
Derek Allard2067d1a2008-11-13 22:59:24 +0000672 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500673 // Check for HTTP 200 Response
Derek Allard2067d1a2008-11-13 22:59:24 +0000674 //-------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200675
Andrey Andreeva30faf92011-12-25 18:15:34 +0200676 if (strncmp($data, 'HTTP', 4) === 0 && ! preg_match('/^HTTP\/[0-9\.]+ 200 /', $data))
Derek Allard2067d1a2008-11-13 22:59:24 +0000677 {
678 $errstr= substr($data, 0, strpos($data, "\n")-1);
Andrey Andreev8f50b6b2012-03-28 14:12:09 +0300679 $r = new XML_RPC_Response(0, $this->xmlrpcerr['http_error'], $this->xmlrpcstr['http_error'].' (' . $errstr . ')');
Derek Allard2067d1a2008-11-13 22:59:24 +0000680 return $r;
681 }
Barry Mienydd671972010-10-04 16:33:58 +0200682
Derek Allard2067d1a2008-11-13 22:59:24 +0000683 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500684 // Create and Set Up XML Parser
Derek Allard2067d1a2008-11-13 22:59:24 +0000685 //-------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200686
Derek Allard2067d1a2008-11-13 22:59:24 +0000687 $parser = xml_parser_create($this->xmlrpc_defencoding);
688
Andrey Andreeva30faf92011-12-25 18:15:34 +0200689 $this->xh[$parser] = array(
690 'isf' => 0,
691 'ac' => '',
692 'headers' => array(),
693 'stack' => array(),
694 'valuestack' => array(),
695 'isf_reason' => 0
696 );
Derek Allard2067d1a2008-11-13 22:59:24 +0000697
698 xml_set_object($parser, $this);
699 xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true);
700 xml_set_element_handler($parser, 'open_tag', 'closing_tag');
701 xml_set_character_data_handler($parser, 'character_data');
702 //xml_set_default_handler($parser, 'default_handler');
703
Derek Allard2067d1a2008-11-13 22:59:24 +0000704 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500705 // GET HEADERS
Derek Allard2067d1a2008-11-13 22:59:24 +0000706 //-------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200707
Derek Allard2067d1a2008-11-13 22:59:24 +0000708 $lines = explode("\r\n", $data);
709 while (($line = array_shift($lines)))
710 {
711 if (strlen($line) < 1)
712 {
713 break;
714 }
715 $this->xh[$parser]['headers'][] = $line;
716 }
717 $data = implode("\r\n", $lines);
Barry Mienydd671972010-10-04 16:33:58 +0200718
719
Derek Allard2067d1a2008-11-13 22:59:24 +0000720 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500721 // PARSE XML DATA
Barry Mienydd671972010-10-04 16:33:58 +0200722 //-------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +0000723
Derek Jones33559102009-02-02 18:50:38 +0000724 if ( ! xml_parse($parser, $data, count($data)))
Derek Allard2067d1a2008-11-13 22:59:24 +0000725 {
726 $errstr = sprintf('XML error: %s at line %d',
727 xml_error_string(xml_get_error_code($parser)),
728 xml_get_current_line_number($parser));
729 //error_log($errstr);
730 $r = new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'], $this->xmlrpcstr['invalid_return']);
731 xml_parser_free($parser);
732 return $r;
733 }
734 xml_parser_free($parser);
Barry Mienydd671972010-10-04 16:33:58 +0200735
Derek Allard2067d1a2008-11-13 22:59:24 +0000736 // ---------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500737 // Got Ourselves Some Badness, It Seems
Derek Allard2067d1a2008-11-13 22:59:24 +0000738 // ---------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200739
Derek Allard2067d1a2008-11-13 22:59:24 +0000740 if ($this->xh[$parser]['isf'] > 1)
741 {
742 if ($this->debug === TRUE)
743 {
Andrey Andreeva30faf92011-12-25 18:15:34 +0200744 echo "---Invalid Return---\n".$this->xh[$parser]['isf_reason']."---Invalid Return---\n\n";
Derek Allard2067d1a2008-11-13 22:59:24 +0000745 }
Barry Mienydd671972010-10-04 16:33:58 +0200746
Derek Allard2067d1a2008-11-13 22:59:24 +0000747 $r = new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'],$this->xmlrpcstr['invalid_return'].' '.$this->xh[$parser]['isf_reason']);
748 return $r;
749 }
750 elseif ( ! is_object($this->xh[$parser]['value']))
751 {
752 $r = new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'],$this->xmlrpcstr['invalid_return'].' '.$this->xh[$parser]['isf_reason']);
753 return $r;
754 }
Barry Mienydd671972010-10-04 16:33:58 +0200755
Derek Allard2067d1a2008-11-13 22:59:24 +0000756 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500757 // DISPLAY XML CONTENT for DEBUGGING
Barry Mienydd671972010-10-04 16:33:58 +0200758 //-------------------------------------
759
Derek Allard2067d1a2008-11-13 22:59:24 +0000760 if ($this->debug === TRUE)
761 {
Andrey Andreev8f50b6b2012-03-28 14:12:09 +0300762 echo '<pre>';
Barry Mienydd671972010-10-04 16:33:58 +0200763
Derek Allard2067d1a2008-11-13 22:59:24 +0000764 if (count($this->xh[$parser]['headers'] > 0))
765 {
766 echo "---HEADERS---\n";
767 foreach ($this->xh[$parser]['headers'] as $header)
768 {
Andrey Andreev8f50b6b2012-03-28 14:12:09 +0300769 echo $header."\n";
Derek Allard2067d1a2008-11-13 22:59:24 +0000770 }
771 echo "---END HEADERS---\n\n";
772 }
Barry Mienydd671972010-10-04 16:33:58 +0200773
Andrey Andreeva30faf92011-12-25 18:15:34 +0200774 echo "---DATA---\n".htmlspecialchars($data)."\n---END DATA---\n\n---PARSED---\n";
Derek Allard2067d1a2008-11-13 22:59:24 +0000775 var_dump($this->xh[$parser]['value']);
776 echo "\n---END PARSED---</pre>";
777 }
Barry Mienydd671972010-10-04 16:33:58 +0200778
Derek Allard2067d1a2008-11-13 22:59:24 +0000779 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500780 // SEND RESPONSE
Derek Allard2067d1a2008-11-13 22:59:24 +0000781 //-------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200782
Derek Allard2067d1a2008-11-13 22:59:24 +0000783 $v = $this->xh[$parser]['value'];
Derek Allard2067d1a2008-11-13 22:59:24 +0000784 if ($this->xh[$parser]['isf'])
785 {
786 $errno_v = $v->me['struct']['faultCode'];
787 $errstr_v = $v->me['struct']['faultString'];
788 $errno = $errno_v->scalarval();
789
790 if ($errno == 0)
791 {
792 // FAULT returned, errno needs to reflect that
793 $errno = -1;
794 }
795
796 $r = new XML_RPC_Response($v, $errno, $errstr_v->scalarval());
797 }
798 else
799 {
800 $r = new XML_RPC_Response($v);
801 }
802
803 $r->headers = $this->xh[$parser]['headers'];
804 return $r;
805 }
Barry Mienydd671972010-10-04 16:33:58 +0200806
Derek Allard2067d1a2008-11-13 22:59:24 +0000807 // ------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500808 // Begin Return Message Parsing section
Derek Allard2067d1a2008-11-13 22:59:24 +0000809 // ------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200810
Derek Allard2067d1a2008-11-13 22:59:24 +0000811 // quick explanation of components:
Derek Jones37f4b9c2011-07-01 17:56:50 -0500812 // ac - used to accumulate values
813 // isf - used to indicate a fault
814 // lv - used to indicate "looking for a value": implements
Derek Allard2067d1a2008-11-13 22:59:24 +0000815 // the logic to allow values with no types to be strings
Derek Jones37f4b9c2011-07-01 17:56:50 -0500816 // params - used to store parameters in method calls
817 // method - used to store method name
Derek Allard2067d1a2008-11-13 22:59:24 +0000818 // stack - array with parent tree of the xml element,
819 // used to validate the nesting of elements
820
821 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500822 // Start Element Handler
Derek Allard2067d1a2008-11-13 22:59:24 +0000823 //-------------------------------------
824
Andrey Andreeva30faf92011-12-25 18:15:34 +0200825 public function open_tag($the_parser, $name, $attrs)
Derek Allard2067d1a2008-11-13 22:59:24 +0000826 {
827 // If invalid nesting, then return
828 if ($this->xh[$the_parser]['isf'] > 1) return;
Barry Mienydd671972010-10-04 16:33:58 +0200829
Derek Allard2067d1a2008-11-13 22:59:24 +0000830 // Evaluate and check for correct nesting of XML elements
Barry Mienydd671972010-10-04 16:33:58 +0200831
Derek Allard2067d1a2008-11-13 22:59:24 +0000832 if (count($this->xh[$the_parser]['stack']) == 0)
833 {
834 if ($name != 'METHODRESPONSE' && $name != 'METHODCALL')
835 {
836 $this->xh[$the_parser]['isf'] = 2;
837 $this->xh[$the_parser]['isf_reason'] = 'Top level XML-RPC element is missing';
838 return;
839 }
840 }
841 else
842 {
843 // not top level element: see if parent is OK
844 if ( ! in_array($this->xh[$the_parser]['stack'][0], $this->valid_parents[$name], TRUE))
845 {
846 $this->xh[$the_parser]['isf'] = 2;
Andrey Andreev8f50b6b2012-03-28 14:12:09 +0300847 $this->xh[$the_parser]['isf_reason'] = 'XML-RPC element $name cannot be child of '.$this->xh[$the_parser]['stack'][0];
Derek Allard2067d1a2008-11-13 22:59:24 +0000848 return;
849 }
850 }
Barry Mienydd671972010-10-04 16:33:58 +0200851
Derek Allard2067d1a2008-11-13 22:59:24 +0000852 switch($name)
853 {
854 case 'STRUCT':
855 case 'ARRAY':
856 // Creates array for child elements
Barry Mienydd671972010-10-04 16:33:58 +0200857
Andrey Andreev8f50b6b2012-03-28 14:12:09 +0300858 $cur_val = array('value' => array(), 'type' => $name);
Barry Mienydd671972010-10-04 16:33:58 +0200859
Derek Allard2067d1a2008-11-13 22:59:24 +0000860 array_unshift($this->xh[$the_parser]['valuestack'], $cur_val);
861 break;
862 case 'METHODNAME':
863 case 'NAME':
864 $this->xh[$the_parser]['ac'] = '';
865 break;
866 case 'FAULT':
867 $this->xh[$the_parser]['isf'] = 1;
868 break;
869 case 'PARAM':
Pascal Kriete8761ef52011-02-14 13:13:52 -0500870 $this->xh[$the_parser]['value'] = NULL;
Derek Allard2067d1a2008-11-13 22:59:24 +0000871 break;
872 case 'VALUE':
873 $this->xh[$the_parser]['vt'] = 'value';
874 $this->xh[$the_parser]['ac'] = '';
875 $this->xh[$the_parser]['lv'] = 1;
876 break;
877 case 'I4':
878 case 'INT':
879 case 'STRING':
880 case 'BOOLEAN':
881 case 'DOUBLE':
882 case 'DATETIME.ISO8601':
883 case 'BASE64':
884 if ($this->xh[$the_parser]['vt'] != 'value')
885 {
886 //two data elements inside a value: an error occurred!
887 $this->xh[$the_parser]['isf'] = 2;
888 $this->xh[$the_parser]['isf_reason'] = "'Twas a $name element following a ".$this->xh[$the_parser]['vt']." element inside a single value";
889 return;
890 }
Barry Mienydd671972010-10-04 16:33:58 +0200891
Derek Allard2067d1a2008-11-13 22:59:24 +0000892 $this->xh[$the_parser]['ac'] = '';
893 break;
894 case 'MEMBER':
895 // Set name of <member> to nothing to prevent errors later if no <name> is found
896 $this->xh[$the_parser]['valuestack'][0]['name'] = '';
Barry Mienydd671972010-10-04 16:33:58 +0200897
Derek Allard2067d1a2008-11-13 22:59:24 +0000898 // Set NULL value to check to see if value passed for this param/member
Pascal Kriete8761ef52011-02-14 13:13:52 -0500899 $this->xh[$the_parser]['value'] = NULL;
Derek Allard2067d1a2008-11-13 22:59:24 +0000900 break;
901 case 'DATA':
902 case 'METHODCALL':
903 case 'METHODRESPONSE':
904 case 'PARAMS':
905 // valid elements that add little to processing
906 break;
907 default:
908 /// An Invalid Element is Found, so we have trouble
909 $this->xh[$the_parser]['isf'] = 2;
910 $this->xh[$the_parser]['isf_reason'] = "Invalid XML-RPC element found: $name";
911 break;
912 }
Barry Mienydd671972010-10-04 16:33:58 +0200913
Derek Allard2067d1a2008-11-13 22:59:24 +0000914 // Add current element name to stack, to allow validation of nesting
915 array_unshift($this->xh[$the_parser]['stack'], $name);
916
917 if ($name != 'VALUE') $this->xh[$the_parser]['lv'] = 0;
918 }
919 // END
920
Derek Allard2067d1a2008-11-13 22:59:24 +0000921 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500922 // End Element Handler
Derek Allard2067d1a2008-11-13 22:59:24 +0000923 //-------------------------------------
924
Andrey Andreeva30faf92011-12-25 18:15:34 +0200925 public function closing_tag($the_parser, $name)
Derek Allard2067d1a2008-11-13 22:59:24 +0000926 {
927 if ($this->xh[$the_parser]['isf'] > 1) return;
Barry Mienydd671972010-10-04 16:33:58 +0200928
Derek Allard2067d1a2008-11-13 22:59:24 +0000929 // Remove current element from stack and set variable
930 // NOTE: If the XML validates, then we do not have to worry about
Derek Jones37f4b9c2011-07-01 17:56:50 -0500931 // the opening and closing of elements. Nesting is checked on the opening
Derek Allard2067d1a2008-11-13 22:59:24 +0000932 // tag so we be safe there as well.
Barry Mienydd671972010-10-04 16:33:58 +0200933
Derek Allard2067d1a2008-11-13 22:59:24 +0000934 $curr_elem = array_shift($this->xh[$the_parser]['stack']);
Barry Mienydd671972010-10-04 16:33:58 +0200935
Derek Allard2067d1a2008-11-13 22:59:24 +0000936 switch($name)
937 {
938 case 'STRUCT':
939 case 'ARRAY':
940 $cur_val = array_shift($this->xh[$the_parser]['valuestack']);
941 $this->xh[$the_parser]['value'] = ( ! isset($cur_val['values'])) ? array() : $cur_val['values'];
942 $this->xh[$the_parser]['vt'] = strtolower($name);
943 break;
944 case 'NAME':
945 $this->xh[$the_parser]['valuestack'][0]['name'] = $this->xh[$the_parser]['ac'];
946 break;
947 case 'BOOLEAN':
948 case 'I4':
949 case 'INT':
950 case 'STRING':
951 case 'DOUBLE':
952 case 'DATETIME.ISO8601':
953 case 'BASE64':
954 $this->xh[$the_parser]['vt'] = strtolower($name);
Barry Mienydd671972010-10-04 16:33:58 +0200955
Derek Allard2067d1a2008-11-13 22:59:24 +0000956 if ($name == 'STRING')
957 {
958 $this->xh[$the_parser]['value'] = $this->xh[$the_parser]['ac'];
959 }
960 elseif ($name=='DATETIME.ISO8601')
961 {
962 $this->xh[$the_parser]['vt'] = $this->xmlrpcDateTime;
963 $this->xh[$the_parser]['value'] = $this->xh[$the_parser]['ac'];
964 }
965 elseif ($name=='BASE64')
966 {
967 $this->xh[$the_parser]['value'] = base64_decode($this->xh[$the_parser]['ac']);
968 }
969 elseif ($name=='BOOLEAN')
970 {
971 // Translated BOOLEAN values to TRUE AND FALSE
972 if ($this->xh[$the_parser]['ac'] == '1')
973 {
974 $this->xh[$the_parser]['value'] = TRUE;
975 }
976 else
977 {
978 $this->xh[$the_parser]['value'] = FALSE;
979 }
980 }
981 elseif ($name=='DOUBLE')
982 {
983 // we have a DOUBLE
984 // we must check that only 0123456789-.<space> are characters here
985 if ( ! preg_match('/^[+-]?[eE0-9\t \.]+$/', $this->xh[$the_parser]['ac']))
986 {
987 $this->xh[$the_parser]['value'] = 'ERROR_NON_NUMERIC_FOUND';
988 }
989 else
990 {
Andrey Andreev8f50b6b2012-03-28 14:12:09 +0300991 $this->xh[$the_parser]['value'] = (float) $this->xh[$the_parser]['ac'];
Derek Allard2067d1a2008-11-13 22:59:24 +0000992 }
993 }
994 else
995 {
996 // we have an I4/INT
997 // we must check that only 0123456789-<space> are characters here
998 if ( ! preg_match('/^[+-]?[0-9\t ]+$/', $this->xh[$the_parser]['ac']))
999 {
1000 $this->xh[$the_parser]['value'] = 'ERROR_NON_NUMERIC_FOUND';
1001 }
1002 else
1003 {
1004 $this->xh[$the_parser]['value'] = (int)$this->xh[$the_parser]['ac'];
1005 }
1006 }
1007 $this->xh[$the_parser]['ac'] = '';
1008 $this->xh[$the_parser]['lv'] = 3; // indicate we've found a value
1009 break;
1010 case 'VALUE':
1011 // This if() detects if no scalar was inside <VALUE></VALUE>
1012 if ($this->xh[$the_parser]['vt']=='value')
1013 {
1014 $this->xh[$the_parser]['value'] = $this->xh[$the_parser]['ac'];
1015 $this->xh[$the_parser]['vt'] = $this->xmlrpcString;
1016 }
Barry Mienydd671972010-10-04 16:33:58 +02001017
Derek Allard2067d1a2008-11-13 22:59:24 +00001018 // build the XML-RPC value out of the data received, and substitute it
1019 $temp = new XML_RPC_Values($this->xh[$the_parser]['value'], $this->xh[$the_parser]['vt']);
Barry Mienydd671972010-10-04 16:33:58 +02001020
Derek Allard2067d1a2008-11-13 22:59:24 +00001021 if (count($this->xh[$the_parser]['valuestack']) && $this->xh[$the_parser]['valuestack'][0]['type'] == 'ARRAY')
1022 {
1023 // Array
1024 $this->xh[$the_parser]['valuestack'][0]['values'][] = $temp;
1025 }
1026 else
1027 {
1028 // Struct
1029 $this->xh[$the_parser]['value'] = $temp;
1030 }
1031 break;
1032 case 'MEMBER':
1033 $this->xh[$the_parser]['ac']='';
Barry Mienydd671972010-10-04 16:33:58 +02001034
Derek Allard2067d1a2008-11-13 22:59:24 +00001035 // If value add to array in the stack for the last element built
1036 if ($this->xh[$the_parser]['value'])
1037 {
1038 $this->xh[$the_parser]['valuestack'][0]['values'][$this->xh[$the_parser]['valuestack'][0]['name']] = $this->xh[$the_parser]['value'];
1039 }
1040 break;
1041 case 'DATA':
1042 $this->xh[$the_parser]['ac']='';
1043 break;
1044 case 'PARAM':
1045 if ($this->xh[$the_parser]['value'])
1046 {
1047 $this->xh[$the_parser]['params'][] = $this->xh[$the_parser]['value'];
1048 }
1049 break;
1050 case 'METHODNAME':
1051 $this->xh[$the_parser]['method'] = ltrim($this->xh[$the_parser]['ac']);
1052 break;
1053 case 'PARAMS':
1054 case 'FAULT':
1055 case 'METHODCALL':
1056 case 'METHORESPONSE':
1057 // We're all good kids with nuthin' to do
1058 break;
1059 default:
Derek Jones37f4b9c2011-07-01 17:56:50 -05001060 // End of an Invalid Element. Taken care of during the opening tag though
Derek Allard2067d1a2008-11-13 22:59:24 +00001061 break;
1062 }
1063 }
1064
1065 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -05001066 // Parses Character Data
Derek Allard2067d1a2008-11-13 22:59:24 +00001067 //-------------------------------------
1068
Andrey Andreeva30faf92011-12-25 18:15:34 +02001069 public function character_data($the_parser, $data)
Derek Allard2067d1a2008-11-13 22:59:24 +00001070 {
1071 if ($this->xh[$the_parser]['isf'] > 1) return; // XML Fault found already
Barry Mienydd671972010-10-04 16:33:58 +02001072
Derek Allard2067d1a2008-11-13 22:59:24 +00001073 // If a value has not been found
1074 if ($this->xh[$the_parser]['lv'] != 3)
1075 {
1076 if ($this->xh[$the_parser]['lv'] == 1)
1077 {
1078 $this->xh[$the_parser]['lv'] = 2; // Found a value
1079 }
Barry Mienydd671972010-10-04 16:33:58 +02001080
Pascal Kriete14287f32011-02-14 13:39:34 -05001081 if ( ! @isset($this->xh[$the_parser]['ac']))
Derek Allard2067d1a2008-11-13 22:59:24 +00001082 {
1083 $this->xh[$the_parser]['ac'] = '';
1084 }
Barry Mienydd671972010-10-04 16:33:58 +02001085
Derek Allard2067d1a2008-11-13 22:59:24 +00001086 $this->xh[$the_parser]['ac'] .= $data;
1087 }
1088 }
Barry Mienydd671972010-10-04 16:33:58 +02001089
1090
Andrey Andreeva30faf92011-12-25 18:15:34 +02001091 public function addParam($par)
1092 {
1093 $this->params[] = $par;
1094 }
Barry Mienydd671972010-10-04 16:33:58 +02001095
Andrey Andreeva30faf92011-12-25 18:15:34 +02001096 public function output_parameters($array = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +00001097 {
Barry Mienydd671972010-10-04 16:33:58 +02001098 $CI =& get_instance();
Andrey Andreeva30faf92011-12-25 18:15:34 +02001099
1100 if (is_array($array))
Derek Allard2067d1a2008-11-13 22:59:24 +00001101 {
1102 while (list($key) = each($array))
1103 {
1104 if (is_array($array[$key]))
1105 {
1106 $array[$key] = $this->output_parameters($array[$key]);
1107 }
1108 else
1109 {
Derek Jonesa9647e82010-03-02 22:59:07 -06001110 // 'bits' is for the MetaWeblog API image bits
1111 // @todo - this needs to be made more general purpose
Robin Sowell66a3fc02010-03-18 09:44:55 -04001112 $array[$key] = ($key == 'bits' OR $this->xss_clean == FALSE) ? $array[$key] : $CI->security->xss_clean($array[$key]);
Derek Allard2067d1a2008-11-13 22:59:24 +00001113 }
1114 }
Barry Mienydd671972010-10-04 16:33:58 +02001115
Derek Allard2067d1a2008-11-13 22:59:24 +00001116 $parameters = $array;
1117 }
1118 else
1119 {
1120 $parameters = array();
Barry Mienydd671972010-10-04 16:33:58 +02001121
Andrey Andreeva30faf92011-12-25 18:15:34 +02001122 for ($i = 0, $c = count($this->params); $i < $c; $i++)
Derek Allard2067d1a2008-11-13 22:59:24 +00001123 {
1124 $a_param = $this->decode_message($this->params[$i]);
Barry Mienydd671972010-10-04 16:33:58 +02001125
Derek Allard2067d1a2008-11-13 22:59:24 +00001126 if (is_array($a_param))
1127 {
1128 $parameters[] = $this->output_parameters($a_param);
1129 }
1130 else
1131 {
Robin Sowell66a3fc02010-03-18 09:44:55 -04001132 $parameters[] = ($this->xss_clean) ? $CI->security->xss_clean($a_param) : $a_param;
Derek Allard2067d1a2008-11-13 22:59:24 +00001133 }
Barry Mienydd671972010-10-04 16:33:58 +02001134 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001135 }
Barry Mienydd671972010-10-04 16:33:58 +02001136
Derek Allard2067d1a2008-11-13 22:59:24 +00001137 return $parameters;
1138 }
Barry Mienydd671972010-10-04 16:33:58 +02001139
Andrey Andreeva30faf92011-12-25 18:15:34 +02001140 public function decode_message($param)
Derek Allard2067d1a2008-11-13 22:59:24 +00001141 {
1142 $kind = $param->kindOf();
1143
Pascal Kriete14287f32011-02-14 13:39:34 -05001144 if ($kind == 'scalar')
Derek Allard2067d1a2008-11-13 22:59:24 +00001145 {
1146 return $param->scalarval();
1147 }
Pascal Kriete14287f32011-02-14 13:39:34 -05001148 elseif ($kind == 'array')
Derek Allard2067d1a2008-11-13 22:59:24 +00001149 {
1150 reset($param->me);
Andrey Andreevadc11752011-12-30 14:46:08 +02001151 $b = current($param->me);
Derek Allard2067d1a2008-11-13 22:59:24 +00001152 $arr = array();
1153
Andrey Andreeva30faf92011-12-25 18:15:34 +02001154 for($i = 0, $c = count($b); $i < $c; $i++)
Derek Allard2067d1a2008-11-13 22:59:24 +00001155 {
1156 $arr[] = $this->decode_message($param->me['array'][$i]);
1157 }
Barry Mienydd671972010-10-04 16:33:58 +02001158
Derek Allard2067d1a2008-11-13 22:59:24 +00001159 return $arr;
1160 }
Pascal Kriete14287f32011-02-14 13:39:34 -05001161 elseif ($kind == 'struct')
Derek Allard2067d1a2008-11-13 22:59:24 +00001162 {
1163 reset($param->me['struct']);
Derek Allard2067d1a2008-11-13 22:59:24 +00001164 $arr = array();
1165
Pascal Kriete14287f32011-02-14 13:39:34 -05001166 while (list($key,$value) = each($param->me['struct']))
Derek Allard2067d1a2008-11-13 22:59:24 +00001167 {
1168 $arr[$key] = $this->decode_message($value);
1169 }
Barry Mienydd671972010-10-04 16:33:58 +02001170
Derek Allard2067d1a2008-11-13 22:59:24 +00001171 return $arr;
1172 }
1173 }
Barry Mienydd671972010-10-04 16:33:58 +02001174
Andrey Andreeva30faf92011-12-25 18:15:34 +02001175}
1176// End XML_RPC_Messages class
Derek Allard2067d1a2008-11-13 22:59:24 +00001177
1178/**
1179 * XML-RPC Values class
1180 *
1181 * @category XML-RPC
Derek Jonesf4a4bd82011-10-20 12:18:42 -05001182 * @author EllisLab Dev Team
Derek Allard2067d1a2008-11-13 22:59:24 +00001183 * @link http://codeigniter.com/user_guide/libraries/xmlrpc.html
1184 */
1185class XML_RPC_Values extends CI_Xmlrpc
1186{
Andrey Andreeva30faf92011-12-25 18:15:34 +02001187 public $me = array();
1188 public $mytype = 0;
Derek Allard2067d1a2008-11-13 22:59:24 +00001189
Andrey Andreeva30faf92011-12-25 18:15:34 +02001190 public function __construct($val = -1, $type = '')
Barry Mienydd671972010-10-04 16:33:58 +02001191 {
Greg Akera9263282010-11-10 15:26:43 -06001192 parent::__construct();
Barry Mienydd671972010-10-04 16:33:58 +02001193
Derek Allard2067d1a2008-11-13 22:59:24 +00001194 if ($val != -1 OR $type != '')
1195 {
1196 $type = $type == '' ? 'string' : $type;
Barry Mienydd671972010-10-04 16:33:58 +02001197
Derek Allard2067d1a2008-11-13 22:59:24 +00001198 if ($this->xmlrpcTypes[$type] == 1)
1199 {
1200 $this->addScalar($val,$type);
1201 }
1202 elseif ($this->xmlrpcTypes[$type] == 2)
1203 {
1204 $this->addArray($val);
1205 }
1206 elseif ($this->xmlrpcTypes[$type] == 3)
1207 {
1208 $this->addStruct($val);
1209 }
1210 }
1211 }
1212
Andrey Andreeva30faf92011-12-25 18:15:34 +02001213 public function addScalar($val, $type = 'string')
Derek Allard2067d1a2008-11-13 22:59:24 +00001214 {
1215 $typeof = $this->xmlrpcTypes[$type];
Barry Mienydd671972010-10-04 16:33:58 +02001216
Derek Allard2067d1a2008-11-13 22:59:24 +00001217 if ($this->mytype==1)
1218 {
1219 echo '<strong>XML_RPC_Values</strong>: scalar can have only one value<br />';
1220 return 0;
1221 }
Barry Mienydd671972010-10-04 16:33:58 +02001222
Derek Allard2067d1a2008-11-13 22:59:24 +00001223 if ($typeof != 1)
1224 {
1225 echo '<strong>XML_RPC_Values</strong>: not a scalar type (${typeof})<br />';
1226 return 0;
1227 }
1228
1229 if ($type == $this->xmlrpcBoolean)
1230 {
Andrey Andreev8f50b6b2012-03-28 14:12:09 +03001231 $val = (strcasecmp($val,'true') === 0 OR $val == 1 OR ($val == TRUE && strcasecmp($val, 'false'))) ? 1 : 0;
Derek Allard2067d1a2008-11-13 22:59:24 +00001232 }
1233
1234 if ($this->mytype == 2)
1235 {
1236 // adding to an array here
1237 $ar = $this->me['array'];
1238 $ar[] = new XML_RPC_Values($val, $type);
1239 $this->me['array'] = $ar;
1240 }
1241 else
1242 {
1243 // a scalar, so set the value and remember we're scalar
1244 $this->me[$type] = $val;
1245 $this->mytype = $typeof;
1246 }
1247 return 1;
1248 }
1249
Andrey Andreeva30faf92011-12-25 18:15:34 +02001250 public function addArray($vals)
Derek Allard2067d1a2008-11-13 22:59:24 +00001251 {
1252 if ($this->mytype != 0)
1253 {
1254 echo '<strong>XML_RPC_Values</strong>: already initialized as a [' . $this->kindOf() . ']<br />';
1255 return 0;
1256 }
1257
1258 $this->mytype = $this->xmlrpcTypes['array'];
1259 $this->me['array'] = $vals;
1260 return 1;
1261 }
1262
Andrey Andreeva30faf92011-12-25 18:15:34 +02001263 public function addStruct($vals)
Derek Allard2067d1a2008-11-13 22:59:24 +00001264 {
1265 if ($this->mytype != 0)
1266 {
1267 echo '<strong>XML_RPC_Values</strong>: already initialized as a [' . $this->kindOf() . ']<br />';
1268 return 0;
1269 }
1270 $this->mytype = $this->xmlrpcTypes['struct'];
1271 $this->me['struct'] = $vals;
1272 return 1;
1273 }
1274
Andrey Andreeva30faf92011-12-25 18:15:34 +02001275 public function kindOf()
Derek Allard2067d1a2008-11-13 22:59:24 +00001276 {
1277 switch($this->mytype)
1278 {
1279 case 3:
1280 return 'struct';
1281 break;
1282 case 2:
1283 return 'array';
1284 break;
1285 case 1:
1286 return 'scalar';
1287 break;
1288 default:
1289 return 'undef';
1290 }
1291 }
1292
Andrey Andreeva30faf92011-12-25 18:15:34 +02001293 public function serializedata($typ, $val)
Derek Allard2067d1a2008-11-13 22:59:24 +00001294 {
1295 $rs = '';
Derek Jonesa9647e82010-03-02 22:59:07 -06001296
Derek Allard2067d1a2008-11-13 22:59:24 +00001297 switch($this->xmlrpcTypes[$typ])
1298 {
1299 case 3:
1300 // struct
1301 $rs .= "<struct>\n";
1302 reset($val);
Pascal Kriete14287f32011-02-14 13:39:34 -05001303 while (list($key2, $val2) = each($val))
Derek Allard2067d1a2008-11-13 22:59:24 +00001304 {
Andrey Andreeva30faf92011-12-25 18:15:34 +02001305 $rs .= "<member>\n<name>{$key2}</name>\n".$this->serializeval($val2)."</member>\n";
Derek Allard2067d1a2008-11-13 22:59:24 +00001306 }
1307 $rs .= '</struct>';
1308 break;
1309 case 2:
1310 // array
1311 $rs .= "<array>\n<data>\n";
Andrey Andreeva30faf92011-12-25 18:15:34 +02001312 for($i = 0, $c = count($val); $i < $c; $i++)
Derek Allard2067d1a2008-11-13 22:59:24 +00001313 {
1314 $rs .= $this->serializeval($val[$i]);
1315 }
Andrey Andreeva30faf92011-12-25 18:15:34 +02001316 $rs .= "</data>\n</array>\n";
Derek Allard2067d1a2008-11-13 22:59:24 +00001317 break;
1318 case 1:
1319 // others
1320 switch ($typ)
1321 {
1322 case $this->xmlrpcBase64:
Derek Jonesb8d3c3d2009-06-24 15:27:01 +00001323 $rs .= "<{$typ}>" . base64_encode((string)$val) . "</{$typ}>\n";
Derek Allard2067d1a2008-11-13 22:59:24 +00001324 break;
1325 case $this->xmlrpcBoolean:
Derek Jonesb8d3c3d2009-06-24 15:27:01 +00001326 $rs .= "<{$typ}>" . ((bool)$val ? '1' : '0') . "</{$typ}>\n";
Derek Allard2067d1a2008-11-13 22:59:24 +00001327 break;
1328 case $this->xmlrpcString:
Derek Jonesb8d3c3d2009-06-24 15:27:01 +00001329 $rs .= "<{$typ}>" . htmlspecialchars((string)$val). "</{$typ}>\n";
Derek Allard2067d1a2008-11-13 22:59:24 +00001330 break;
1331 default:
1332 $rs .= "<{$typ}>{$val}</{$typ}>\n";
1333 break;
1334 }
1335 default:
1336 break;
1337 }
1338 return $rs;
1339 }
1340
Andrey Andreeva30faf92011-12-25 18:15:34 +02001341 public function serialize_class()
Derek Allard2067d1a2008-11-13 22:59:24 +00001342 {
1343 return $this->serializeval($this);
1344 }
1345
Andrey Andreeva30faf92011-12-25 18:15:34 +02001346 public function serializeval($o)
Derek Allard2067d1a2008-11-13 22:59:24 +00001347 {
1348 $ar = $o->me;
1349 reset($ar);
Barry Mienydd671972010-10-04 16:33:58 +02001350
Derek Allard2067d1a2008-11-13 22:59:24 +00001351 list($typ, $val) = each($ar);
Andrey Andreeva30faf92011-12-25 18:15:34 +02001352 return "<value>\n".$this->serializedata($typ, $val)."</value>\n";
Derek Allard2067d1a2008-11-13 22:59:24 +00001353 }
Barry Mienydd671972010-10-04 16:33:58 +02001354
Andrey Andreeva30faf92011-12-25 18:15:34 +02001355 public function scalarval()
Derek Allard2067d1a2008-11-13 22:59:24 +00001356 {
1357 reset($this->me);
Andrey Andreevadc11752011-12-30 14:46:08 +02001358 return current($this->me);
Derek Allard2067d1a2008-11-13 22:59:24 +00001359 }
1360
1361
1362 //-------------------------------------
1363 // Encode time in ISO-8601 form.
1364 //-------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +02001365
Derek Allard2067d1a2008-11-13 22:59:24 +00001366 // Useful for sending time in XML-RPC
1367
Andrey Andreev62090152011-12-30 12:49:27 +02001368 public function iso8601_encode($time, $utc = 0)
Barry Mienydd671972010-10-04 16:33:58 +02001369 {
Andrey Andreev62090152011-12-30 12:49:27 +02001370 return ($utc) ? strftime('%Y%m%dT%H:%i:%s', $time) : gmstrftime('%Y%m%dT%H:%i:%s', $time);
Derek Allard2067d1a2008-11-13 22:59:24 +00001371 }
Barry Mienydd671972010-10-04 16:33:58 +02001372
Derek Allard2067d1a2008-11-13 22:59:24 +00001373}
1374// END XML_RPC_Values Class
1375
1376/* End of file Xmlrpc.php */
Andrey Andreev8f50b6b2012-03-28 14:12:09 +03001377/* Location: ./system/libraries/Xmlrpc.php */