blob: 9e60791ae60e347a9482c5dc7eea9c68af813cdc [file] [log] [blame]
Andrey Andreevc5536aa2012-11-01 17:33:58 +02001<?php
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
Andrey Andreev80500af2013-01-01 08:16:53 +020021 * @copyright Copyright (c) 2008 - 2013, 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 */
Andrey Andreevc5536aa2012-11-01 17:33:58 +020027defined('BASEPATH') OR exit('No direct script access allowed');
Derek Allard2067d1a2008-11-13 22:59:24 +000028
Andrey Andreevf5ccd122012-11-02 00:17:39 +020029if ( ! function_exists('xml_parser_create'))
30{
31 show_error('Your PHP installation does not support XML');
32}
33
34// ------------------------------------------------------------------------
35
Derek Allard2067d1a2008-11-13 22:59:24 +000036/**
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 Andreevf5ccd122012-11-02 00:17:39 +020047 /**
48 * Debug flag
49 *
50 * @var bool
51 */
52 public $debug = FALSE;
53
54 /**
55 * I4 data type
56 *
57 * @var string
58 */
Andrey Andreeva30faf92011-12-25 18:15:34 +020059 public $xmlrpcI4 = 'i4';
Andrey Andreevf5ccd122012-11-02 00:17:39 +020060
61 /**
62 * Integer data type
63 *
64 * @var string
65 */
Andrey Andreeva30faf92011-12-25 18:15:34 +020066 public $xmlrpcInt = 'int';
Andrey Andreevf5ccd122012-11-02 00:17:39 +020067
68 /**
69 * Boolean data type
70 *
71 * @var string
72 */
Andrey Andreeva30faf92011-12-25 18:15:34 +020073 public $xmlrpcBoolean = 'boolean';
Andrey Andreevf5ccd122012-11-02 00:17:39 +020074
75 /**
76 * Double data type
77 *
78 * @var string
79 */
Andrey Andreeva30faf92011-12-25 18:15:34 +020080 public $xmlrpcDouble = 'double';
Andrey Andreevf5ccd122012-11-02 00:17:39 +020081
82 /**
83 * String data type
84 *
85 * @var string
86 */
Andrey Andreeva30faf92011-12-25 18:15:34 +020087 public $xmlrpcString = 'string';
Andrey Andreevf5ccd122012-11-02 00:17:39 +020088
89 /**
90 * DateTime format
91 *
92 * @var string
93 */
Andrey Andreeva30faf92011-12-25 18:15:34 +020094 public $xmlrpcDateTime = 'dateTime.iso8601';
Andrey Andreevf5ccd122012-11-02 00:17:39 +020095
96 /**
97 * Base64 data type
98 *
99 * @var string
100 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200101 public $xmlrpcBase64 = 'base64';
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200102
103 /**
104 * Array data type
105 *
106 * @var string
107 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200108 public $xmlrpcArray = 'array';
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200109
110 /**
111 * Struct data type
112 *
113 * @var string
114 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200115 public $xmlrpcStruct = 'struct';
Barry Mienydd671972010-10-04 16:33:58 +0200116
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200117 /**
118 * Data types list
119 *
120 * @var array
121 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200122 public $xmlrpcTypes = array();
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200123
124 /**
125 * Valid parents list
126 *
127 * @var array
128 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200129 public $valid_parents = array();
Barry Mienydd671972010-10-04 16:33:58 +0200130
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200131 /**
132 * Response error numbers list
133 *
134 * @var array
135 */
136 public $xmlrpcerr = array();
137
138 /**
139 * Response error messages list
140 *
141 * @var string[]
142 */
143 public $xmlrpcstr = array();
144
145 /**
146 * Encoding charset
147 *
148 * @var string
149 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200150 public $xmlrpc_defencoding = 'UTF-8';
Barry Mienydd671972010-10-04 16:33:58 +0200151
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200152 /**
153 * XML-RPC client name
154 *
155 * @var string
156 */
157 public $xmlrpcName = 'XML-RPC for CodeIgniter';
158
159 /**
160 * XML-RPC version
161 *
162 * @var string
163 */
164 public $xmlrpcVersion = '1.1';
165
166 /**
167 * Start of user errors
168 *
169 * @var int
170 */
171 public $xmlrpcerruser = 800;
172
173 /**
174 * Start of XML parse errors
175 *
176 * @var int
177 */
178 public $xmlrpcerrxml = 100;
179
180 /**
181 * Backslash replacement value
182 *
183 * @var string
184 */
185 public $xmlrpc_backslash = '';
186
187 /**
188 * XML-RPC Client object
189 *
190 * @var object
191 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200192 public $client;
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200193
194 /**
195 * XML-RPC Method name
196 *
197 * @var string
198 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200199 public $method;
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200200
201 /**
202 * XML-RPC Data
203 *
204 * @var array
205 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200206 public $data;
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200207
208 /**
209 * XML-RPC Message
210 *
211 * @var string
212 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200213 public $message = '';
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200214
215 /**
216 * Request error message
217 *
218 * @var string
219 */
220 public $error = '';
221
222 /**
223 * XML-RPC result object
224 *
225 * @var object
226 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200227 public $result;
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200228
229 /**
230 * XML-RPC Reponse
231 *
232 * @var array
233 */
vkeranovb497d2b2012-11-23 23:27:33 +0200234 public $response = array(); // Response from remote server
Derek Allard2067d1a2008-11-13 22:59:24 +0000235
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200236 /**
237 * XSS Filter flag
238 *
239 * @var bool
240 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200241 public $xss_clean = TRUE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000242
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200243 // --------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +0000244
Andrey Andreevc8709832012-04-04 13:43:53 +0300245 /**
246 * Constructor
247 *
248 * Initializes property default values
249 *
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200250 * @param array $config
Andrey Andreevc8709832012-04-04 13:43:53 +0300251 * @return void
252 */
Greg Akera9263282010-11-10 15:26:43 -0600253 public function __construct($config = array())
Derek Allard2067d1a2008-11-13 22:59:24 +0000254 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000255 $this->xmlrpc_backslash = chr(92).chr(92);
Barry Mienydd671972010-10-04 16:33:58 +0200256
Derek Allard2067d1a2008-11-13 22:59:24 +0000257 // Types for info sent back and forth
258 $this->xmlrpcTypes = array(
Barry Mienydd671972010-10-04 16:33:58 +0200259 $this->xmlrpcI4 => '1',
260 $this->xmlrpcInt => '1',
261 $this->xmlrpcBoolean => '1',
262 $this->xmlrpcString => '1',
263 $this->xmlrpcDouble => '1',
264 $this->xmlrpcDateTime => '1',
265 $this->xmlrpcBase64 => '1',
266 $this->xmlrpcArray => '2',
267 $this->xmlrpcStruct => '3'
vkeranovb497d2b2012-11-23 23:27:33 +0200268 );
Barry Mienydd671972010-10-04 16:33:58 +0200269
Derek Allard2067d1a2008-11-13 22:59:24 +0000270 // Array of Valid Parents for Various XML-RPC elements
Timothy Warren0688ac92012-04-20 10:25:04 -0400271 $this->valid_parents = array('BOOLEAN' => array('VALUE'),
272 'I4' => array('VALUE'),
273 'INT' => array('VALUE'),
274 'STRING' => array('VALUE'),
275 'DOUBLE' => array('VALUE'),
276 'DATETIME.ISO8601' => array('VALUE'),
277 'BASE64' => array('VALUE'),
278 'ARRAY' => array('VALUE'),
279 'STRUCT' => array('VALUE'),
280 'PARAM' => array('PARAMS'),
281 'METHODNAME' => array('METHODCALL'),
282 'PARAMS' => array('METHODCALL', 'METHODRESPONSE'),
283 'MEMBER' => array('STRUCT'),
284 'NAME' => array('MEMBER'),
285 'DATA' => array('ARRAY'),
286 'FAULT' => array('METHODRESPONSE'),
287 'VALUE' => array('MEMBER', 'DATA', 'PARAM', 'FAULT')
vkeranovb497d2b2012-11-23 23:27:33 +0200288 );
Barry Mienydd671972010-10-04 16:33:58 +0200289
Derek Allard2067d1a2008-11-13 22:59:24 +0000290 // XML-RPC Responses
291 $this->xmlrpcerr['unknown_method'] = '1';
292 $this->xmlrpcstr['unknown_method'] = 'This is not a known method for this XML-RPC Server';
293 $this->xmlrpcerr['invalid_return'] = '2';
vkeranovb497d2b2012-11-23 23:27:33 +0200294 $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 +0000295 $this->xmlrpcerr['incorrect_params'] = '3';
296 $this->xmlrpcstr['incorrect_params'] = 'Incorrect parameters were passed to method';
297 $this->xmlrpcerr['introspect_unknown'] = '4';
Andrey Andreeva30faf92011-12-25 18:15:34 +0200298 $this->xmlrpcstr['introspect_unknown'] = 'Cannot inspect signature for request: method unknown';
Derek Allard2067d1a2008-11-13 22:59:24 +0000299 $this->xmlrpcerr['http_error'] = '5';
300 $this->xmlrpcstr['http_error'] = "Did not receive a '200 OK' response from remote server.";
301 $this->xmlrpcerr['no_data'] = '6';
vkeranovb497d2b2012-11-23 23:27:33 +0200302 $this->xmlrpcstr['no_data'] = 'No data received from server.';
Barry Mienydd671972010-10-04 16:33:58 +0200303
Derek Allard2067d1a2008-11-13 22:59:24 +0000304 $this->initialize($config);
Barry Mienydd671972010-10-04 16:33:58 +0200305
Andrey Andreev8f50b6b2012-03-28 14:12:09 +0300306 log_message('debug', 'XML-RPC Class Initialized');
Derek Allard2067d1a2008-11-13 22:59:24 +0000307 }
Barry Mienydd671972010-10-04 16:33:58 +0200308
Andrey Andreevc8709832012-04-04 13:43:53 +0300309 // --------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +0000310
Andrey Andreevc8709832012-04-04 13:43:53 +0300311 /**
312 * Initialize
313 *
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200314 * @param array $config
Andrey Andreevc8709832012-04-04 13:43:53 +0300315 * @return void
316 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200317 public function initialize($config = array())
Derek Allard2067d1a2008-11-13 22:59:24 +0000318 {
Derek Jones33559102009-02-02 18:50:38 +0000319 if (count($config) > 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000320 {
321 foreach ($config as $key => $val)
322 {
323 if (isset($this->$key))
324 {
Barry Mienydd671972010-10-04 16:33:58 +0200325 $this->$key = $val;
Derek Allard2067d1a2008-11-13 22:59:24 +0000326 }
327 }
328 }
329 }
Barry Mienydd671972010-10-04 16:33:58 +0200330
Andrey Andreevc8709832012-04-04 13:43:53 +0300331 // --------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +0000332
Andrey Andreevc8709832012-04-04 13:43:53 +0300333 /**
334 * Parse server URL
335 *
Andrey Andreev5fd3ae82012-10-24 14:55:35 +0300336 * @param string $url
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200337 * @param int $port
338 * @param string $proxy
339 * @param int $proxy_port
Andrey Andreevc8709832012-04-04 13:43:53 +0300340 * @return void
341 */
Valentin Sheyretskicfcf34e2012-07-02 12:04:36 +0300342 public function server($url, $port = 80, $proxy = FALSE, $proxy_port = 8080)
Derek Allard2067d1a2008-11-13 22:59:24 +0000343 {
Andrey Andreeva30faf92011-12-25 18:15:34 +0200344 if (strpos($url, 'http') !== 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000345 {
Andrey Andreevc8709832012-04-04 13:43:53 +0300346 $url = 'http://'.$url;
Derek Allard2067d1a2008-11-13 22:59:24 +0000347 }
Barry Mienydd671972010-10-04 16:33:58 +0200348
Derek Allard2067d1a2008-11-13 22:59:24 +0000349 $parts = parse_url($url);
Barry Mienydd671972010-10-04 16:33:58 +0200350
Andrey Andreev8f50b6b2012-03-28 14:12:09 +0300351 $path = isset($parts['path']) ? $parts['path'] : '/';
Barry Mienydd671972010-10-04 16:33:58 +0200352
Andrey Andreev8f50b6b2012-03-28 14:12:09 +0300353 if ( ! empty($parts['query']))
Derek Allard2067d1a2008-11-13 22:59:24 +0000354 {
355 $path .= '?'.$parts['query'];
Barry Mienydd671972010-10-04 16:33:58 +0200356 }
357
Valio9dee5352012-07-02 10:42:28 +0300358 $this->client = new XML_RPC_Client($path, $parts['host'], $port, $proxy, $proxy_port);
Derek Allard2067d1a2008-11-13 22:59:24 +0000359 }
Barry Mienydd671972010-10-04 16:33:58 +0200360
Andrey Andreevc8709832012-04-04 13:43:53 +0300361 // --------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +0000362
Andrey Andreevc8709832012-04-04 13:43:53 +0300363 /**
364 * Set Timeout
365 *
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200366 * @param int $seconds
Andrey Andreevc8709832012-04-04 13:43:53 +0300367 * @return void
368 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200369 public function timeout($seconds = 5)
Derek Allard2067d1a2008-11-13 22:59:24 +0000370 {
vlakoff1228fe22013-01-14 01:30:09 +0100371 if ($this->client !== NULL && is_int($seconds))
Derek Allard2067d1a2008-11-13 22:59:24 +0000372 {
373 $this->client->timeout = $seconds;
374 }
375 }
Barry Mienydd671972010-10-04 16:33:58 +0200376
Andrey Andreevc8709832012-04-04 13:43:53 +0300377 // --------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +0000378
Andrey Andreevc8709832012-04-04 13:43:53 +0300379 /**
380 * Set Methods
381 *
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200382 * @param string $function Method name
Andrey Andreevc8709832012-04-04 13:43:53 +0300383 * @return void
384 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200385 public function method($function)
Derek Allard2067d1a2008-11-13 22:59:24 +0000386 {
387 $this->method = $function;
388 }
Barry Mienydd671972010-10-04 16:33:58 +0200389
Andrey Andreevc8709832012-04-04 13:43:53 +0300390 // --------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +0000391
Andrey Andreevc8709832012-04-04 13:43:53 +0300392 /**
393 * Take Array of Data and Create Objects
394 *
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200395 * @param array $incoming
Andrey Andreevc8709832012-04-04 13:43:53 +0300396 * @return void
397 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200398 public function request($incoming)
Derek Allard2067d1a2008-11-13 22:59:24 +0000399 {
400 if ( ! is_array($incoming))
401 {
402 // Send Error
Andrey Andreevc8709832012-04-04 13:43:53 +0300403 return;
Derek Allard2067d1a2008-11-13 22:59:24 +0000404 }
Barry Mienydd671972010-10-04 16:33:58 +0200405
Derek Allard2067d1a2008-11-13 22:59:24 +0000406 $this->data = array();
Barry Mienydd671972010-10-04 16:33:58 +0200407
Pascal Kriete14287f32011-02-14 13:39:34 -0500408 foreach ($incoming as $key => $value)
Derek Allard2067d1a2008-11-13 22:59:24 +0000409 {
410 $this->data[$key] = $this->values_parsing($value);
411 }
412 }
Barry Mienydd671972010-10-04 16:33:58 +0200413
Andrey Andreevc8709832012-04-04 13:43:53 +0300414 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200415
Andrey Andreevc8709832012-04-04 13:43:53 +0300416 /**
417 * Set Debug
418 *
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200419 * @param bool $flag
Andrey Andreevc8709832012-04-04 13:43:53 +0300420 * @return void
421 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200422 public function set_debug($flag = TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000423 {
Alex Bilbied261b1e2012-06-02 11:12:16 +0100424 $this->debug = ($flag === TRUE);
Derek Allard2067d1a2008-11-13 22:59:24 +0000425 }
Barry Mienydd671972010-10-04 16:33:58 +0200426
Andrey Andreevc8709832012-04-04 13:43:53 +0300427 // --------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +0000428
Andrey Andreevc8709832012-04-04 13:43:53 +0300429 /**
430 * Values Parsing
431 *
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200432 * @param mixed $value
Andrey Andreevc8709832012-04-04 13:43:53 +0300433 * @return object
434 */
435 public function values_parsing($value)
Derek Allard2067d1a2008-11-13 22:59:24 +0000436 {
Derek Jones8c4b5e72010-01-06 22:21:41 +0000437 if (is_array($value) && array_key_exists(0, $value))
Derek Allard2067d1a2008-11-13 22:59:24 +0000438 {
Andrey Andreev8f50b6b2012-03-28 14:12:09 +0300439 if ( ! isset($value[1], $this->xmlrpcTypes[$value[1]]))
Derek Allard2067d1a2008-11-13 22:59:24 +0000440 {
Andrey Andreeva30faf92011-12-25 18:15:34 +0200441 $temp = new XML_RPC_Values($value[0], (is_array($value[0]) ? 'array' : 'string'));
Derek Allard2067d1a2008-11-13 22:59:24 +0000442 }
443 else
444 {
Alex Bilbied261b1e2012-06-02 11:12:16 +0100445 if (is_array($value[0]) && ($value[1] === 'struct' OR $value[1] === 'array'))
Andrey Andreeva30faf92011-12-25 18:15:34 +0200446 {
447 while (list($k) = each($value[0]))
448 {
449 $value[0][$k] = $this->values_parsing($value[0][$k], TRUE);
450 }
451 }
452
453 $temp = new XML_RPC_Values($value[0], $value[1]);
Derek Allard2067d1a2008-11-13 22:59:24 +0000454 }
455 }
456 else
457 {
458 $temp = new XML_RPC_Values($value, 'string');
459 }
460
461 return $temp;
462 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000463
Andrey Andreevc8709832012-04-04 13:43:53 +0300464 // --------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +0000465
Andrey Andreevc8709832012-04-04 13:43:53 +0300466 /**
467 * Sends XML-RPC Request
468 *
469 * @return bool
470 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200471 public function send_request()
Derek Allard2067d1a2008-11-13 22:59:24 +0000472 {
Andrey Andreevc8709832012-04-04 13:43:53 +0300473 $this->message = new XML_RPC_Message($this->method, $this->data);
Derek Allard2067d1a2008-11-13 22:59:24 +0000474 $this->message->debug = $this->debug;
Barry Mienydd671972010-10-04 16:33:58 +0200475
Andrey Andreeva30faf92011-12-25 18:15:34 +0200476 if ( ! $this->result = $this->client->send($this->message) OR ! is_object($this->result->val))
Derek Allard2067d1a2008-11-13 22:59:24 +0000477 {
478 $this->error = $this->result->errstr;
479 return FALSE;
480 }
Barry Mienydd671972010-10-04 16:33:58 +0200481
Derek Allard2067d1a2008-11-13 22:59:24 +0000482 $this->response = $this->result->decode();
Derek Allard2067d1a2008-11-13 22:59:24 +0000483 return TRUE;
484 }
Barry Mienydd671972010-10-04 16:33:58 +0200485
Andrey Andreevc8709832012-04-04 13:43:53 +0300486 // --------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +0000487
Andrey Andreevc8709832012-04-04 13:43:53 +0300488 /**
489 * Returns Error
490 *
491 * @return string
492 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200493 public function display_error()
Derek Allard2067d1a2008-11-13 22:59:24 +0000494 {
495 return $this->error;
496 }
Barry Mienydd671972010-10-04 16:33:58 +0200497
Andrey Andreevc8709832012-04-04 13:43:53 +0300498 // --------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +0000499
Andrey Andreevc8709832012-04-04 13:43:53 +0300500 /**
501 * Returns Remote Server Response
502 *
503 * @return string
504 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200505 public function display_response()
Derek Allard2067d1a2008-11-13 22:59:24 +0000506 {
507 return $this->response;
508 }
Barry Mienydd671972010-10-04 16:33:58 +0200509
Andrey Andreevc8709832012-04-04 13:43:53 +0300510 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200511
Andrey Andreevc8709832012-04-04 13:43:53 +0300512 /**
513 * Sends an Error Message for Server Request
514 *
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200515 * @param int $number
516 * @param string $message
Andrey Andreevc8709832012-04-04 13:43:53 +0300517 * @return object
518 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200519 public function send_error_message($number, $message)
Derek Allard2067d1a2008-11-13 22:59:24 +0000520 {
Andrey Andreeva30faf92011-12-25 18:15:34 +0200521 return new XML_RPC_Response(0, $number, $message);
Derek Allard2067d1a2008-11-13 22:59:24 +0000522 }
Barry Mienydd671972010-10-04 16:33:58 +0200523
Andrey Andreevc8709832012-04-04 13:43:53 +0300524 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200525
Andrey Andreevc8709832012-04-04 13:43:53 +0300526 /**
527 * Send Response for Server Request
528 *
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200529 * @param array $response
Andrey Andreevc8709832012-04-04 13:43:53 +0300530 * @return object
531 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200532 public function send_response($response)
Derek Allard2067d1a2008-11-13 22:59:24 +0000533 {
534 // $response should be array of values, which will be parsed
535 // based on their data and type into a valid group of XML-RPC values
Andrey Andreeva30faf92011-12-25 18:15:34 +0200536 return new XML_RPC_Response($this->values_parsing($response));
Derek Allard2067d1a2008-11-13 22:59:24 +0000537 }
Barry Mienydd671972010-10-04 16:33:58 +0200538
Derek Allard2067d1a2008-11-13 22:59:24 +0000539} // END XML_RPC Class
540
Derek Allard2067d1a2008-11-13 22:59:24 +0000541/**
542 * XML-RPC Client class
543 *
544 * @category XML-RPC
Derek Jonesf4a4bd82011-10-20 12:18:42 -0500545 * @author EllisLab Dev Team
Derek Allard2067d1a2008-11-13 22:59:24 +0000546 * @link http://codeigniter.com/user_guide/libraries/xmlrpc.html
547 */
548class XML_RPC_Client extends CI_Xmlrpc
549{
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200550 /**
551 * Path
552 *
553 * @var string
554 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200555 public $path = '';
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200556
557 /**
558 * Server hostname
559 *
560 * @var string
561 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200562 public $server = '';
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200563
564 /**
565 * Server port
566 *
567 * @var int
568 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200569 public $port = 80;
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200570
571 /**
572 * Proxy hostname
573 *
574 * @var string
575 */
Valio9dee5352012-07-02 10:42:28 +0300576 public $proxy = FALSE;
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200577
578 /**
579 * Proxy port
580 *
581 * @var int
582 */
Valio9dee5352012-07-02 10:42:28 +0300583 public $proxy_port = 8080;
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200584
585 /**
586 * Error number
587 *
588 * @var string
589 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200590 public $errno = '';
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200591
592 /**
593 * Error message
594 *
595 * @var string
596 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200597 public $errstring = '';
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200598
599 /**
600 * Timeout in seconds
601 *
602 * @var int
603 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200604 public $timeout = 5;
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200605
606 /**
607 * No Multicall flag
608 *
609 * @var bool
610 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200611 public $no_multicall = FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000612
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200613 // --------------------------------------------------------------------
614
Andrey Andreevc8709832012-04-04 13:43:53 +0300615 /**
616 * Constructor
617 *
Andrey Andreev5fd3ae82012-10-24 14:55:35 +0300618 * @param string $path
619 * @param object $server
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200620 * @param int $port
621 * @param string $proxy
622 * @param int $proxy_port
Andrey Andreevc8709832012-04-04 13:43:53 +0300623 * @return void
624 */
Valio9dee5352012-07-02 10:42:28 +0300625 public function __construct($path, $server, $port = 80, $proxy = FALSE, $proxy_port = 8080)
Derek Allard2067d1a2008-11-13 22:59:24 +0000626 {
Greg Akera9263282010-11-10 15:26:43 -0600627 parent::__construct();
Barry Mienydd671972010-10-04 16:33:58 +0200628
Derek Allard2067d1a2008-11-13 22:59:24 +0000629 $this->port = $port;
630 $this->server = $server;
631 $this->path = $path;
Valio9dee5352012-07-02 10:42:28 +0300632 $this->proxy = $proxy;
633 $this->proxy_port = $proxy_port;
Derek Allard2067d1a2008-11-13 22:59:24 +0000634 }
Barry Mienydd671972010-10-04 16:33:58 +0200635
Andrey Andreevc8709832012-04-04 13:43:53 +0300636 // --------------------------------------------------------------------
637
638 /**
639 * Send message
640 *
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200641 * @param mixed $msg
Andrey Andreevc8709832012-04-04 13:43:53 +0300642 * @return object
643 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200644 public function send($msg)
Derek Allard2067d1a2008-11-13 22:59:24 +0000645 {
646 if (is_array($msg))
647 {
648 // Multi-call disabled
Andrey Andreevc8709832012-04-04 13:43:53 +0300649 return new XML_RPC_Response(0, $this->xmlrpcerr['multicall_recursion'], $this->xmlrpcstr['multicall_recursion']);
Derek Allard2067d1a2008-11-13 22:59:24 +0000650 }
651
652 return $this->sendPayload($msg);
653 }
654
Andrey Andreevc8709832012-04-04 13:43:53 +0300655 // --------------------------------------------------------------------
656
657 /**
658 * Send payload
659 *
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200660 * @param object $msg
Andrey Andreevc8709832012-04-04 13:43:53 +0300661 * @return object
662 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200663 public function sendPayload($msg)
Barry Mienydd671972010-10-04 16:33:58 +0200664 {
Andrey Andreevc02e7c52012-07-02 16:43:43 +0300665 if ($this->proxy === FALSE)
Valentin Sheyretskicfcf34e2012-07-02 12:04:36 +0300666 {
667 $server = $this->server;
668 $port = $this->port;
Valentin Sheyretski09217ce2012-07-02 16:27:01 +0300669 }
670 else
671 {
Valio9dee5352012-07-02 10:42:28 +0300672 $server = $this->proxy;
673 $port = $this->proxy_port;
674 }
Valentin Sheyretskicfcf34e2012-07-02 12:04:36 +0300675
Valio9dee5352012-07-02 10:42:28 +0300676 $fp = @fsockopen($server, $port, $this->errno, $this->errstring, $this->timeout);
Barry Mienydd671972010-10-04 16:33:58 +0200677
Derek Allard2067d1a2008-11-13 22:59:24 +0000678 if ( ! is_resource($fp))
679 {
680 error_log($this->xmlrpcstr['http_error']);
Andrey Andreevc8709832012-04-04 13:43:53 +0300681 return new XML_RPC_Response(0, $this->xmlrpcerr['http_error'], $this->xmlrpcstr['http_error']);
Derek Allard2067d1a2008-11-13 22:59:24 +0000682 }
Barry Mienydd671972010-10-04 16:33:58 +0200683
Pascal Kriete14287f32011-02-14 13:39:34 -0500684 if (empty($msg->payload))
Derek Allard2067d1a2008-11-13 22:59:24 +0000685 {
686 // $msg = XML_RPC_Messages
687 $msg->createPayload();
688 }
Barry Mienydd671972010-10-04 16:33:58 +0200689
Derek Allard2067d1a2008-11-13 22:59:24 +0000690 $r = "\r\n";
Andrey Andreev8f50b6b2012-03-28 14:12:09 +0300691 $op = 'POST '.$this->path.' HTTP/1.0'.$r
692 .'Host: '.$this->server.$r
693 .'Content-Type: text/xml'.$r
694 .'User-Agent: '.$this->xmlrpcName.$r
695 .'Content-Length: '.strlen($msg->payload).$r.$r
696 .$msg->payload;
Barry Mienydd671972010-10-04 16:33:58 +0200697
George Petsagourakis306b3782012-05-02 20:31:08 +0300698 if ( ! fwrite($fp, $op, strlen($op)))
Derek Allard2067d1a2008-11-13 22:59:24 +0000699 {
700 error_log($this->xmlrpcstr['http_error']);
Andrey Andreevc8709832012-04-04 13:43:53 +0300701 return new XML_RPC_Response(0, $this->xmlrpcerr['http_error'], $this->xmlrpcstr['http_error']);
Derek Allard2067d1a2008-11-13 22:59:24 +0000702 }
Andrey Andreevc8709832012-04-04 13:43:53 +0300703
Derek Allard2067d1a2008-11-13 22:59:24 +0000704 $resp = $msg->parseResponse($fp);
705 fclose($fp);
706 return $resp;
707 }
708
Andrey Andreevc8709832012-04-04 13:43:53 +0300709} // END XML_RPC_Client Class
Derek Allard2067d1a2008-11-13 22:59:24 +0000710
711/**
712 * XML-RPC Response class
713 *
714 * @category XML-RPC
Derek Jonesf4a4bd82011-10-20 12:18:42 -0500715 * @author EllisLab Dev Team
Derek Allard2067d1a2008-11-13 22:59:24 +0000716 * @link http://codeigniter.com/user_guide/libraries/xmlrpc.html
717 */
718class XML_RPC_Response
719{
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200720
721 /**
722 * Value
723 *
724 * @var mixed
725 */
Andrey Andreevc8709832012-04-04 13:43:53 +0300726 public $val = 0;
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200727
728 /**
729 * Error number
730 *
731 * @var int
732 */
Andrey Andreevc8709832012-04-04 13:43:53 +0300733 public $errno = 0;
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200734
735 /**
736 * Error message
737 *
738 * @var string
739 */
Andrey Andreevc8709832012-04-04 13:43:53 +0300740 public $errstr = '';
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200741
742 /**
743 * Headers list
744 *
745 * @var array
746 */
Andrey Andreevc8709832012-04-04 13:43:53 +0300747 public $headers = array();
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200748
749 /**
750 * XSS Filter flag
751 *
752 * @var bool
753 */
Andrey Andreevc8709832012-04-04 13:43:53 +0300754 public $xss_clean = TRUE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000755
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200756 // --------------------------------------------------------------------
757
Andrey Andreevc8709832012-04-04 13:43:53 +0300758 /**
759 * Constructor
760 *
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200761 * @param mixed $val
762 * @param int $code
763 * @param string $fstr
Andrey Andreevc8709832012-04-04 13:43:53 +0300764 * @return void
765 */
Greg Akera9263282010-11-10 15:26:43 -0600766 public function __construct($val, $code = 0, $fstr = '')
Barry Mienydd671972010-10-04 16:33:58 +0200767 {
Alex Bilbied261b1e2012-06-02 11:12:16 +0100768 if ($code !== 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000769 {
770 // error
771 $this->errno = $code;
Andrey Andreevc8709832012-04-04 13:43:53 +0300772 $this->errstr = htmlspecialchars($fstr,
773 (is_php('5.4') ? ENT_XML1 | ENT_NOQUOTES : ENT_NOQUOTES),
774 'UTF-8');
Derek Allard2067d1a2008-11-13 22:59:24 +0000775 }
Andrey Andreev8f50b6b2012-03-28 14:12:09 +0300776 elseif ( ! is_object($val))
Derek Allard2067d1a2008-11-13 22:59:24 +0000777 {
778 // programmer error, not an object
Andrey Andreev8f50b6b2012-03-28 14:12:09 +0300779 error_log("Invalid type '".gettype($val)."' (value: ".$val.') passed to XML_RPC_Response. Defaulting to empty value.');
Derek Allard2067d1a2008-11-13 22:59:24 +0000780 $this->val = new XML_RPC_Values();
781 }
782 else
783 {
784 $this->val = $val;
785 }
786 }
787
Andrey Andreevc8709832012-04-04 13:43:53 +0300788 // --------------------------------------------------------------------
789
790 /**
791 * Fault code
792 *
793 * @return int
794 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200795 public function faultCode()
Derek Allard2067d1a2008-11-13 22:59:24 +0000796 {
797 return $this->errno;
798 }
799
Andrey Andreevc8709832012-04-04 13:43:53 +0300800 // --------------------------------------------------------------------
801
802 /**
803 * Fault string
804 *
805 * @return string
806 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200807 public function faultString()
Derek Allard2067d1a2008-11-13 22:59:24 +0000808 {
809 return $this->errstr;
810 }
811
Andrey Andreevc8709832012-04-04 13:43:53 +0300812 // --------------------------------------------------------------------
813
814 /**
815 * Value
816 *
817 * @return mixed
818 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200819 public function value()
Derek Allard2067d1a2008-11-13 22:59:24 +0000820 {
821 return $this->val;
822 }
Barry Mienydd671972010-10-04 16:33:58 +0200823
Andrey Andreevc8709832012-04-04 13:43:53 +0300824 // --------------------------------------------------------------------
825
826 /**
827 * Prepare response
828 *
829 * @return string xml
830 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200831 public function prepare_response()
Derek Allard2067d1a2008-11-13 22:59:24 +0000832 {
Andrey Andreeva30faf92011-12-25 18:15:34 +0200833 return "<methodResponse>\n"
Andrey Andreevc8709832012-04-04 13:43:53 +0300834 .($this->errno
835 ? '<fault>
Derek Allard2067d1a2008-11-13 22:59:24 +0000836 <value>
837 <struct>
838 <member>
839 <name>faultCode</name>
Andrey Andreevc8709832012-04-04 13:43:53 +0300840 <value><int>'.$this->errno.'</int></value>
Derek Allard2067d1a2008-11-13 22:59:24 +0000841 </member>
842 <member>
843 <name>faultString</name>
Andrey Andreevc8709832012-04-04 13:43:53 +0300844 <value><string>'.$this->errstr.'</string></value>
Derek Allard2067d1a2008-11-13 22:59:24 +0000845 </member>
846 </struct>
847 </value>
Andrey Andreeva30faf92011-12-25 18:15:34 +0200848</fault>'
Andrey Andreevc8709832012-04-04 13:43:53 +0300849 : "<params>\n<param>\n".$this->val->serialize_class()."</param>\n</params>")
850 ."\n</methodResponse>";
Derek Allard2067d1a2008-11-13 22:59:24 +0000851 }
Barry Mienydd671972010-10-04 16:33:58 +0200852
Andrey Andreevc8709832012-04-04 13:43:53 +0300853 // --------------------------------------------------------------------
854
855 /**
856 * Decode
857 *
858 * @param mixed
859 * @return array
860 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200861 public function decode($array = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000862 {
863 $CI =& get_instance();
Andrey Andreeva30faf92011-12-25 18:15:34 +0200864
865 if (is_array($array))
Derek Allard2067d1a2008-11-13 22:59:24 +0000866 {
867 while (list($key) = each($array))
868 {
869 if (is_array($array[$key]))
870 {
871 $array[$key] = $this->decode($array[$key]);
872 }
873 else
874 {
Robin Sowell66a3fc02010-03-18 09:44:55 -0400875 $array[$key] = ($this->xss_clean) ? $CI->security->xss_clean($array[$key]) : $array[$key];
Derek Allard2067d1a2008-11-13 22:59:24 +0000876 }
877 }
Barry Mienydd671972010-10-04 16:33:58 +0200878
Andrey Andreevc8709832012-04-04 13:43:53 +0300879 return $array;
880 }
881
882 $result = $this->xmlrpc_decoder($this->val);
883
884 if (is_array($result))
885 {
886 $result = $this->decode($result);
Derek Allard2067d1a2008-11-13 22:59:24 +0000887 }
888 else
889 {
Andrey Andreevc8709832012-04-04 13:43:53 +0300890 $result = ($this->xss_clean) ? $CI->security->xss_clean($result) : $result;
Derek Allard2067d1a2008-11-13 22:59:24 +0000891 }
Barry Mienydd671972010-10-04 16:33:58 +0200892
Derek Allard2067d1a2008-11-13 22:59:24 +0000893 return $result;
894 }
895
Andrey Andreevc8709832012-04-04 13:43:53 +0300896 // --------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +0000897
Andrey Andreevc8709832012-04-04 13:43:53 +0300898 /**
899 * XML-RPC Object to PHP Types
900 *
901 * @param object
902 * @return array
903 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200904 public function xmlrpc_decoder($xmlrpc_val)
Derek Allard2067d1a2008-11-13 22:59:24 +0000905 {
906 $kind = $xmlrpc_val->kindOf();
907
Alex Bilbied261b1e2012-06-02 11:12:16 +0100908 if ($kind === 'scalar')
Derek Allard2067d1a2008-11-13 22:59:24 +0000909 {
910 return $xmlrpc_val->scalarval();
911 }
Alex Bilbied261b1e2012-06-02 11:12:16 +0100912 elseif ($kind === 'array')
Derek Allard2067d1a2008-11-13 22:59:24 +0000913 {
914 reset($xmlrpc_val->me);
Andrey Andreevadc11752011-12-30 14:46:08 +0200915 $b = current($xmlrpc_val->me);
Derek Allard2067d1a2008-11-13 22:59:24 +0000916 $arr = array();
917
Andrey Andreeva30faf92011-12-25 18:15:34 +0200918 for ($i = 0, $size = count($b); $i < $size; $i++)
Derek Allard2067d1a2008-11-13 22:59:24 +0000919 {
920 $arr[] = $this->xmlrpc_decoder($xmlrpc_val->me['array'][$i]);
921 }
922 return $arr;
923 }
Alex Bilbied261b1e2012-06-02 11:12:16 +0100924 elseif ($kind === 'struct')
Derek Allard2067d1a2008-11-13 22:59:24 +0000925 {
926 reset($xmlrpc_val->me['struct']);
927 $arr = array();
928
Pascal Kriete14287f32011-02-14 13:39:34 -0500929 while (list($key,$value) = each($xmlrpc_val->me['struct']))
Derek Allard2067d1a2008-11-13 22:59:24 +0000930 {
931 $arr[$key] = $this->xmlrpc_decoder($value);
932 }
933 return $arr;
934 }
935 }
Barry Mienydd671972010-10-04 16:33:58 +0200936
Andrey Andreevc8709832012-04-04 13:43:53 +0300937 // --------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +0000938
Andrey Andreevc8709832012-04-04 13:43:53 +0300939 /**
940 * ISO-8601 time to server or UTC time
941 *
942 * @param string
943 * @param bool
944 * @return int unix timestamp
945 */
946 public function iso8601_decode($time, $utc = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000947 {
vkeranovb497d2b2012-11-23 23:27:33 +0200948 // Return a time in the localtime, or UTC
Derek Allard2067d1a2008-11-13 22:59:24 +0000949 $t = 0;
950 if (preg_match('/([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})/', $time, $regs))
951 {
Alex Bilbied261b1e2012-06-02 11:12:16 +0100952 $fnc = ($utc === TRUE) ? 'gmmktime' : 'mktime';
Pascal Kriete14287f32011-02-14 13:39:34 -0500953 $t = $fnc($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
Derek Allard2067d1a2008-11-13 22:59:24 +0000954 }
955 return $t;
956 }
Barry Mienydd671972010-10-04 16:33:58 +0200957
Andrey Andreevc8709832012-04-04 13:43:53 +0300958} // END XML_RPC_Response Class
Derek Allard2067d1a2008-11-13 22:59:24 +0000959
960/**
961 * XML-RPC Message class
962 *
963 * @category XML-RPC
Derek Jonesf4a4bd82011-10-20 12:18:42 -0500964 * @author EllisLab Dev Team
Derek Allard2067d1a2008-11-13 22:59:24 +0000965 * @link http://codeigniter.com/user_guide/libraries/xmlrpc.html
966 */
967class XML_RPC_Message extends CI_Xmlrpc
968{
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200969
970 /**
971 * Payload
972 *
973 * @var string
974 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200975 public $payload;
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200976
977 /**
978 * Method name
979 *
980 * @var string
981 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200982 public $method_name;
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200983
984 /**
985 * Parameter list
986 *
987 * @var array
988 */
Andrey Andreevc8709832012-04-04 13:43:53 +0300989 public $params = array();
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200990
991 /**
992 * XH?
993 *
994 * @var array
995 */
Andrey Andreevc8709832012-04-04 13:43:53 +0300996 public $xh = array();
Derek Allard2067d1a2008-11-13 22:59:24 +0000997
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200998 // --------------------------------------------------------------------
999
Andrey Andreevc8709832012-04-04 13:43:53 +03001000 /**
1001 * Constructor
1002 *
Andrey Andreevf5ccd122012-11-02 00:17:39 +02001003 * @param string $method
1004 * @param array $pars
Andrey Andreevc8709832012-04-04 13:43:53 +03001005 * @return void
1006 */
1007 public function __construct($method, $pars = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +00001008 {
Greg Akera9263282010-11-10 15:26:43 -06001009 parent::__construct();
Barry Mienydd671972010-10-04 16:33:58 +02001010
Derek Allard2067d1a2008-11-13 22:59:24 +00001011 $this->method_name = $method;
Derek Jones33559102009-02-02 18:50:38 +00001012 if (is_array($pars) && count($pars) > 0)
Derek Allard2067d1a2008-11-13 22:59:24 +00001013 {
Andrey Andreeva30faf92011-12-25 18:15:34 +02001014 for ($i = 0, $c = count($pars); $i < $c; $i++)
Derek Allard2067d1a2008-11-13 22:59:24 +00001015 {
1016 // $pars[$i] = XML_RPC_Values
1017 $this->params[] = $pars[$i];
1018 }
1019 }
1020 }
Barry Mienydd671972010-10-04 16:33:58 +02001021
Andrey Andreevc8709832012-04-04 13:43:53 +03001022 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +02001023
Andrey Andreevc8709832012-04-04 13:43:53 +03001024 /**
1025 * Create Payload to Send
1026 *
1027 * @return void
1028 */
Andrey Andreeva30faf92011-12-25 18:15:34 +02001029 public function createPayload()
Derek Allard2067d1a2008-11-13 22:59:24 +00001030 {
Andrey Andreevc8709832012-04-04 13:43:53 +03001031 $this->payload = '<?xml version="1.0"?'.">\r\n<methodCall>\r\n"
1032 .'<methodName>'.$this->method_name."</methodName>\r\n"
1033 ."<params>\r\n";
Barry Mienydd671972010-10-04 16:33:58 +02001034
Andrey Andreeva30faf92011-12-25 18:15:34 +02001035 for ($i = 0, $c = count($this->params); $i < $c; $i++)
Derek Allard2067d1a2008-11-13 22:59:24 +00001036 {
1037 // $p = XML_RPC_Values
1038 $p = $this->params[$i];
1039 $this->payload .= "<param>\r\n".$p->serialize_class()."</param>\r\n";
1040 }
Barry Mienydd671972010-10-04 16:33:58 +02001041
Derek Allard2067d1a2008-11-13 22:59:24 +00001042 $this->payload .= "</params>\r\n</methodCall>\r\n";
1043 }
Barry Mienydd671972010-10-04 16:33:58 +02001044
Andrey Andreevc8709832012-04-04 13:43:53 +03001045 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +02001046
Andrey Andreevc8709832012-04-04 13:43:53 +03001047 /**
1048 * Parse External XML-RPC Server's Response
1049 *
1050 * @param resource
1051 * @return object
1052 */
Andrey Andreeva30faf92011-12-25 18:15:34 +02001053 public function parseResponse($fp)
Derek Allard2067d1a2008-11-13 22:59:24 +00001054 {
1055 $data = '';
Barry Mienydd671972010-10-04 16:33:58 +02001056
Pascal Kriete14287f32011-02-14 13:39:34 -05001057 while ($datum = fread($fp, 4096))
Derek Allard2067d1a2008-11-13 22:59:24 +00001058 {
1059 $data .= $datum;
1060 }
Barry Mienydd671972010-10-04 16:33:58 +02001061
Andrey Andreevc8709832012-04-04 13:43:53 +03001062 // Display HTTP content for debugging
Derek Allard2067d1a2008-11-13 22:59:24 +00001063 if ($this->debug === TRUE)
1064 {
Andrey Andreeva30faf92011-12-25 18:15:34 +02001065 echo "<pre>---DATA---\n".htmlspecialchars($data)."\n---END DATA---\n\n</pre>";
Derek Allard2067d1a2008-11-13 22:59:24 +00001066 }
Barry Mienydd671972010-10-04 16:33:58 +02001067
Andrey Andreevc8709832012-04-04 13:43:53 +03001068 // Check for data
Andrey Andreeva30faf92011-12-25 18:15:34 +02001069 if ($data === '')
Derek Allard2067d1a2008-11-13 22:59:24 +00001070 {
1071 error_log($this->xmlrpcstr['no_data']);
Andrey Andreevc8709832012-04-04 13:43:53 +03001072 return new XML_RPC_Response(0, $this->xmlrpcerr['no_data'], $this->xmlrpcstr['no_data']);
Derek Allard2067d1a2008-11-13 22:59:24 +00001073 }
Barry Mienydd671972010-10-04 16:33:58 +02001074
Andrey Andreevc8709832012-04-04 13:43:53 +03001075 // Check for HTTP 200 Response
Andrey Andreev3dad2e72012-06-14 15:10:56 +03001076 if (strpos($data, 'HTTP') === 0 && ! preg_match('/^HTTP\/[0-9\.]+ 200 /', $data))
Derek Allard2067d1a2008-11-13 22:59:24 +00001077 {
Andrey Andreevc8709832012-04-04 13:43:53 +03001078 $errstr = substr($data, 0, strpos($data, "\n")-1);
1079 return new XML_RPC_Response(0, $this->xmlrpcerr['http_error'], $this->xmlrpcstr['http_error'].' ('.$errstr.')');
Derek Allard2067d1a2008-11-13 22:59:24 +00001080 }
Barry Mienydd671972010-10-04 16:33:58 +02001081
Derek Allard2067d1a2008-11-13 22:59:24 +00001082 //-------------------------------------
vkeranovb497d2b2012-11-23 23:27:33 +02001083 // Create and Set Up XML Parser
Derek Allard2067d1a2008-11-13 22:59:24 +00001084 //-------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +02001085
Derek Allard2067d1a2008-11-13 22:59:24 +00001086 $parser = xml_parser_create($this->xmlrpc_defencoding);
1087
Andrey Andreeva30faf92011-12-25 18:15:34 +02001088 $this->xh[$parser] = array(
Andrey Andreevc8709832012-04-04 13:43:53 +03001089 'isf' => 0,
1090 'ac' => '',
1091 'headers' => array(),
1092 'stack' => array(),
1093 'valuestack' => array(),
1094 'isf_reason' => 0
Andrey Andreeva30faf92011-12-25 18:15:34 +02001095 );
Derek Allard2067d1a2008-11-13 22:59:24 +00001096
1097 xml_set_object($parser, $this);
Andrey Andreevc8709832012-04-04 13:43:53 +03001098 xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, TRUE);
Derek Allard2067d1a2008-11-13 22:59:24 +00001099 xml_set_element_handler($parser, 'open_tag', 'closing_tag');
1100 xml_set_character_data_handler($parser, 'character_data');
1101 //xml_set_default_handler($parser, 'default_handler');
1102
Andrey Andreevc8709832012-04-04 13:43:53 +03001103 // Get headers
Derek Allard2067d1a2008-11-13 22:59:24 +00001104 $lines = explode("\r\n", $data);
1105 while (($line = array_shift($lines)))
1106 {
1107 if (strlen($line) < 1)
1108 {
1109 break;
1110 }
1111 $this->xh[$parser]['headers'][] = $line;
1112 }
1113 $data = implode("\r\n", $lines);
Barry Mienydd671972010-10-04 16:33:58 +02001114
Andrey Andreevc8709832012-04-04 13:43:53 +03001115 // Parse XML data
Derek Jones33559102009-02-02 18:50:38 +00001116 if ( ! xml_parse($parser, $data, count($data)))
Derek Allard2067d1a2008-11-13 22:59:24 +00001117 {
1118 $errstr = sprintf('XML error: %s at line %d',
Andrey Andreevc8709832012-04-04 13:43:53 +03001119 xml_error_string(xml_get_error_code($parser)),
1120 xml_get_current_line_number($parser));
vkeranovb497d2b2012-11-23 23:27:33 +02001121
Derek Allard2067d1a2008-11-13 22:59:24 +00001122 $r = new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'], $this->xmlrpcstr['invalid_return']);
1123 xml_parser_free($parser);
1124 return $r;
1125 }
1126 xml_parser_free($parser);
Barry Mienydd671972010-10-04 16:33:58 +02001127
Andrey Andreevc8709832012-04-04 13:43:53 +03001128 // Got ourselves some badness, it seems
Derek Allard2067d1a2008-11-13 22:59:24 +00001129 if ($this->xh[$parser]['isf'] > 1)
1130 {
1131 if ($this->debug === TRUE)
1132 {
Andrey Andreeva30faf92011-12-25 18:15:34 +02001133 echo "---Invalid Return---\n".$this->xh[$parser]['isf_reason']."---Invalid Return---\n\n";
Derek Allard2067d1a2008-11-13 22:59:24 +00001134 }
Barry Mienydd671972010-10-04 16:33:58 +02001135
Andrey Andreevc8709832012-04-04 13:43:53 +03001136 return new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'], $this->xmlrpcstr['invalid_return'].' '.$this->xh[$parser]['isf_reason']);
Derek Allard2067d1a2008-11-13 22:59:24 +00001137 }
1138 elseif ( ! is_object($this->xh[$parser]['value']))
1139 {
Andrey Andreevc8709832012-04-04 13:43:53 +03001140 return new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'], $this->xmlrpcstr['invalid_return'].' '.$this->xh[$parser]['isf_reason']);
Derek Allard2067d1a2008-11-13 22:59:24 +00001141 }
Barry Mienydd671972010-10-04 16:33:58 +02001142
Andrey Andreevc8709832012-04-04 13:43:53 +03001143 // Display XML content for debugging
Derek Allard2067d1a2008-11-13 22:59:24 +00001144 if ($this->debug === TRUE)
1145 {
Andrey Andreev8f50b6b2012-03-28 14:12:09 +03001146 echo '<pre>';
Barry Mienydd671972010-10-04 16:33:58 +02001147
Derek Allard2067d1a2008-11-13 22:59:24 +00001148 if (count($this->xh[$parser]['headers'] > 0))
1149 {
1150 echo "---HEADERS---\n";
1151 foreach ($this->xh[$parser]['headers'] as $header)
1152 {
Andrey Andreev8f50b6b2012-03-28 14:12:09 +03001153 echo $header."\n";
Derek Allard2067d1a2008-11-13 22:59:24 +00001154 }
1155 echo "---END HEADERS---\n\n";
1156 }
Barry Mienydd671972010-10-04 16:33:58 +02001157
Andrey Andreeva30faf92011-12-25 18:15:34 +02001158 echo "---DATA---\n".htmlspecialchars($data)."\n---END DATA---\n\n---PARSED---\n";
Derek Allard2067d1a2008-11-13 22:59:24 +00001159 var_dump($this->xh[$parser]['value']);
1160 echo "\n---END PARSED---</pre>";
1161 }
Barry Mienydd671972010-10-04 16:33:58 +02001162
Andrey Andreevc8709832012-04-04 13:43:53 +03001163 // Send response
Derek Allard2067d1a2008-11-13 22:59:24 +00001164 $v = $this->xh[$parser]['value'];
Derek Allard2067d1a2008-11-13 22:59:24 +00001165 if ($this->xh[$parser]['isf'])
1166 {
1167 $errno_v = $v->me['struct']['faultCode'];
1168 $errstr_v = $v->me['struct']['faultString'];
1169 $errno = $errno_v->scalarval();
1170
Alex Bilbied261b1e2012-06-02 11:12:16 +01001171 if ($errno === 0)
Derek Allard2067d1a2008-11-13 22:59:24 +00001172 {
1173 // FAULT returned, errno needs to reflect that
1174 $errno = -1;
1175 }
1176
1177 $r = new XML_RPC_Response($v, $errno, $errstr_v->scalarval());
1178 }
1179 else
1180 {
1181 $r = new XML_RPC_Response($v);
1182 }
1183
1184 $r->headers = $this->xh[$parser]['headers'];
1185 return $r;
1186 }
Barry Mienydd671972010-10-04 16:33:58 +02001187
Andrey Andreevc8709832012-04-04 13:43:53 +03001188 // --------------------------------------------------------------------
1189
Derek Allard2067d1a2008-11-13 22:59:24 +00001190 // ------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -05001191 // Begin Return Message Parsing section
Derek Allard2067d1a2008-11-13 22:59:24 +00001192 // ------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +02001193
Derek Allard2067d1a2008-11-13 22:59:24 +00001194 // quick explanation of components:
Derek Jones37f4b9c2011-07-01 17:56:50 -05001195 // ac - used to accumulate values
1196 // isf - used to indicate a fault
1197 // lv - used to indicate "looking for a value": implements
Derek Allard2067d1a2008-11-13 22:59:24 +00001198 // the logic to allow values with no types to be strings
Derek Jones37f4b9c2011-07-01 17:56:50 -05001199 // params - used to store parameters in method calls
1200 // method - used to store method name
Derek Allard2067d1a2008-11-13 22:59:24 +00001201 // stack - array with parent tree of the xml element,
1202 // used to validate the nesting of elements
1203
Andrey Andreevc8709832012-04-04 13:43:53 +03001204 // --------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +00001205
Andrey Andreevc8709832012-04-04 13:43:53 +03001206 /**
1207 * Start Element Handler
1208 *
1209 * @param string
1210 * @param string
1211 * @return void
1212 */
1213 public function open_tag($the_parser, $name)
Derek Allard2067d1a2008-11-13 22:59:24 +00001214 {
1215 // If invalid nesting, then return
1216 if ($this->xh[$the_parser]['isf'] > 1) return;
Barry Mienydd671972010-10-04 16:33:58 +02001217
Derek Allard2067d1a2008-11-13 22:59:24 +00001218 // Evaluate and check for correct nesting of XML elements
Alex Bilbied261b1e2012-06-02 11:12:16 +01001219 if (count($this->xh[$the_parser]['stack']) === 0)
Derek Allard2067d1a2008-11-13 22:59:24 +00001220 {
Alex Bilbied261b1e2012-06-02 11:12:16 +01001221 if ($name !== 'METHODRESPONSE' && $name !== 'METHODCALL')
Derek Allard2067d1a2008-11-13 22:59:24 +00001222 {
1223 $this->xh[$the_parser]['isf'] = 2;
1224 $this->xh[$the_parser]['isf_reason'] = 'Top level XML-RPC element is missing';
1225 return;
1226 }
1227 }
Andrey Andreevc8709832012-04-04 13:43:53 +03001228 // not top level element: see if parent is OK
1229 elseif ( ! in_array($this->xh[$the_parser]['stack'][0], $this->valid_parents[$name], TRUE))
Derek Allard2067d1a2008-11-13 22:59:24 +00001230 {
Andrey Andreevc8709832012-04-04 13:43:53 +03001231 $this->xh[$the_parser]['isf'] = 2;
vkeranovb497d2b2012-11-23 23:27:33 +02001232 $this->xh[$the_parser]['isf_reason'] = 'XML-RPC element '.$name.' cannot be child of '.$this->xh[$the_parser]['stack'][0];
Andrey Andreevc8709832012-04-04 13:43:53 +03001233 return;
Derek Allard2067d1a2008-11-13 22:59:24 +00001234 }
Barry Mienydd671972010-10-04 16:33:58 +02001235
Andrey Andreevc8709832012-04-04 13:43:53 +03001236 switch ($name)
Derek Allard2067d1a2008-11-13 22:59:24 +00001237 {
1238 case 'STRUCT':
1239 case 'ARRAY':
1240 // Creates array for child elements
Andrey Andreev8f50b6b2012-03-28 14:12:09 +03001241 $cur_val = array('value' => array(), 'type' => $name);
Derek Allard2067d1a2008-11-13 22:59:24 +00001242 array_unshift($this->xh[$the_parser]['valuestack'], $cur_val);
Andrey Andreevc8709832012-04-04 13:43:53 +03001243 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001244 case 'METHODNAME':
1245 case 'NAME':
1246 $this->xh[$the_parser]['ac'] = '';
Andrey Andreevc8709832012-04-04 13:43:53 +03001247 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001248 case 'FAULT':
1249 $this->xh[$the_parser]['isf'] = 1;
Andrey Andreevc8709832012-04-04 13:43:53 +03001250 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001251 case 'PARAM':
Pascal Kriete8761ef52011-02-14 13:13:52 -05001252 $this->xh[$the_parser]['value'] = NULL;
Andrey Andreevc8709832012-04-04 13:43:53 +03001253 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001254 case 'VALUE':
1255 $this->xh[$the_parser]['vt'] = 'value';
1256 $this->xh[$the_parser]['ac'] = '';
1257 $this->xh[$the_parser]['lv'] = 1;
Andrey Andreevc8709832012-04-04 13:43:53 +03001258 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001259 case 'I4':
1260 case 'INT':
1261 case 'STRING':
1262 case 'BOOLEAN':
1263 case 'DOUBLE':
1264 case 'DATETIME.ISO8601':
1265 case 'BASE64':
Alex Bilbied261b1e2012-06-02 11:12:16 +01001266 if ($this->xh[$the_parser]['vt'] !== 'value')
Derek Allard2067d1a2008-11-13 22:59:24 +00001267 {
1268 //two data elements inside a value: an error occurred!
1269 $this->xh[$the_parser]['isf'] = 2;
vkeranovb497d2b2012-11-23 23:27:33 +02001270 $this->xh[$the_parser]['isf_reason'] = 'There is a '.$name.' element following a '
Andrey Andreevc8709832012-04-04 13:43:53 +03001271 .$this->xh[$the_parser]['vt'].' element inside a single value';
Derek Allard2067d1a2008-11-13 22:59:24 +00001272 return;
1273 }
Barry Mienydd671972010-10-04 16:33:58 +02001274
Derek Allard2067d1a2008-11-13 22:59:24 +00001275 $this->xh[$the_parser]['ac'] = '';
Andrey Andreevc8709832012-04-04 13:43:53 +03001276 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001277 case 'MEMBER':
1278 // Set name of <member> to nothing to prevent errors later if no <name> is found
1279 $this->xh[$the_parser]['valuestack'][0]['name'] = '';
Barry Mienydd671972010-10-04 16:33:58 +02001280
Derek Allard2067d1a2008-11-13 22:59:24 +00001281 // Set NULL value to check to see if value passed for this param/member
Pascal Kriete8761ef52011-02-14 13:13:52 -05001282 $this->xh[$the_parser]['value'] = NULL;
Andrey Andreevc8709832012-04-04 13:43:53 +03001283 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001284 case 'DATA':
1285 case 'METHODCALL':
1286 case 'METHODRESPONSE':
1287 case 'PARAMS':
1288 // valid elements that add little to processing
Andrey Andreevc8709832012-04-04 13:43:53 +03001289 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001290 default:
1291 /// An Invalid Element is Found, so we have trouble
1292 $this->xh[$the_parser]['isf'] = 2;
Andrey Andreevc8709832012-04-04 13:43:53 +03001293 $this->xh[$the_parser]['isf_reason'] = 'Invalid XML-RPC element found: '.$name;
1294 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001295 }
Barry Mienydd671972010-10-04 16:33:58 +02001296
Derek Allard2067d1a2008-11-13 22:59:24 +00001297 // Add current element name to stack, to allow validation of nesting
1298 array_unshift($this->xh[$the_parser]['stack'], $name);
1299
Alex Bilbied261b1e2012-06-02 11:12:16 +01001300 $name === 'VALUE' OR $this->xh[$the_parser]['lv'] = 0;
Derek Allard2067d1a2008-11-13 22:59:24 +00001301 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001302
Andrey Andreevc8709832012-04-04 13:43:53 +03001303 // --------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +00001304
Andrey Andreevc8709832012-04-04 13:43:53 +03001305 /**
1306 * End Element Handler
1307 *
1308 * @param string
1309 * @param string
1310 * @return void
1311 */
Andrey Andreeva30faf92011-12-25 18:15:34 +02001312 public function closing_tag($the_parser, $name)
Derek Allard2067d1a2008-11-13 22:59:24 +00001313 {
1314 if ($this->xh[$the_parser]['isf'] > 1) return;
Barry Mienydd671972010-10-04 16:33:58 +02001315
Derek Allard2067d1a2008-11-13 22:59:24 +00001316 // Remove current element from stack and set variable
1317 // NOTE: If the XML validates, then we do not have to worry about
Andrey Andreevc8709832012-04-04 13:43:53 +03001318 // the opening and closing of elements. Nesting is checked on the opening
Derek Allard2067d1a2008-11-13 22:59:24 +00001319 // tag so we be safe there as well.
Barry Mienydd671972010-10-04 16:33:58 +02001320
Derek Allard2067d1a2008-11-13 22:59:24 +00001321 $curr_elem = array_shift($this->xh[$the_parser]['stack']);
Barry Mienydd671972010-10-04 16:33:58 +02001322
Andrey Andreevc8709832012-04-04 13:43:53 +03001323 switch ($name)
Derek Allard2067d1a2008-11-13 22:59:24 +00001324 {
1325 case 'STRUCT':
1326 case 'ARRAY':
1327 $cur_val = array_shift($this->xh[$the_parser]['valuestack']);
Andrey Andreevc8709832012-04-04 13:43:53 +03001328 $this->xh[$the_parser]['value'] = isset($cur_val['values']) ? $cur_val['values'] : array();
Derek Allard2067d1a2008-11-13 22:59:24 +00001329 $this->xh[$the_parser]['vt'] = strtolower($name);
Andrey Andreevc8709832012-04-04 13:43:53 +03001330 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001331 case 'NAME':
1332 $this->xh[$the_parser]['valuestack'][0]['name'] = $this->xh[$the_parser]['ac'];
Andrey Andreevc8709832012-04-04 13:43:53 +03001333 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001334 case 'BOOLEAN':
1335 case 'I4':
1336 case 'INT':
1337 case 'STRING':
1338 case 'DOUBLE':
1339 case 'DATETIME.ISO8601':
1340 case 'BASE64':
1341 $this->xh[$the_parser]['vt'] = strtolower($name);
Barry Mienydd671972010-10-04 16:33:58 +02001342
Alex Bilbied261b1e2012-06-02 11:12:16 +01001343 if ($name === 'STRING')
Derek Allard2067d1a2008-11-13 22:59:24 +00001344 {
1345 $this->xh[$the_parser]['value'] = $this->xh[$the_parser]['ac'];
1346 }
Alex Bilbied261b1e2012-06-02 11:12:16 +01001347 elseif ($name === 'DATETIME.ISO8601')
Derek Allard2067d1a2008-11-13 22:59:24 +00001348 {
1349 $this->xh[$the_parser]['vt'] = $this->xmlrpcDateTime;
1350 $this->xh[$the_parser]['value'] = $this->xh[$the_parser]['ac'];
1351 }
Alex Bilbied261b1e2012-06-02 11:12:16 +01001352 elseif ($name === 'BASE64')
Derek Allard2067d1a2008-11-13 22:59:24 +00001353 {
1354 $this->xh[$the_parser]['value'] = base64_decode($this->xh[$the_parser]['ac']);
1355 }
Alex Bilbied261b1e2012-06-02 11:12:16 +01001356 elseif ($name === 'BOOLEAN')
Derek Allard2067d1a2008-11-13 22:59:24 +00001357 {
1358 // Translated BOOLEAN values to TRUE AND FALSE
Andrey Andreevc8709832012-04-04 13:43:53 +03001359 $this->xh[$the_parser]['value'] = (bool) $this->xh[$the_parser]['ac'];
Derek Allard2067d1a2008-11-13 22:59:24 +00001360 }
1361 elseif ($name=='DOUBLE')
1362 {
1363 // we have a DOUBLE
1364 // we must check that only 0123456789-.<space> are characters here
Andrey Andreevc8709832012-04-04 13:43:53 +03001365 $this->xh[$the_parser]['value'] = preg_match('/^[+-]?[eE0-9\t \.]+$/', $this->xh[$the_parser]['ac'])
1366 ? (float) $this->xh[$the_parser]['ac']
1367 : 'ERROR_NON_NUMERIC_FOUND';
Derek Allard2067d1a2008-11-13 22:59:24 +00001368 }
1369 else
1370 {
1371 // we have an I4/INT
1372 // we must check that only 0123456789-<space> are characters here
Andrey Andreevc8709832012-04-04 13:43:53 +03001373 $this->xh[$the_parser]['value'] = preg_match('/^[+-]?[0-9\t ]+$/', $this->xh[$the_parser]['ac'])
George Petsagourakis306b3782012-05-02 20:31:08 +03001374 ? (int) $this->xh[$the_parser]['ac']
Andrey Andreevc8709832012-04-04 13:43:53 +03001375 : 'ERROR_NON_NUMERIC_FOUND';
Derek Allard2067d1a2008-11-13 22:59:24 +00001376 }
1377 $this->xh[$the_parser]['ac'] = '';
1378 $this->xh[$the_parser]['lv'] = 3; // indicate we've found a value
Andrey Andreevc8709832012-04-04 13:43:53 +03001379 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001380 case 'VALUE':
1381 // This if() detects if no scalar was inside <VALUE></VALUE>
vkeranovb497d2b2012-11-23 23:27:33 +02001382 if ($this->xh[$the_parser]['vt'] == 'value')
Derek Allard2067d1a2008-11-13 22:59:24 +00001383 {
1384 $this->xh[$the_parser]['value'] = $this->xh[$the_parser]['ac'];
1385 $this->xh[$the_parser]['vt'] = $this->xmlrpcString;
1386 }
Barry Mienydd671972010-10-04 16:33:58 +02001387
Derek Allard2067d1a2008-11-13 22:59:24 +00001388 // build the XML-RPC value out of the data received, and substitute it
1389 $temp = new XML_RPC_Values($this->xh[$the_parser]['value'], $this->xh[$the_parser]['vt']);
Barry Mienydd671972010-10-04 16:33:58 +02001390
Alex Bilbied261b1e2012-06-02 11:12:16 +01001391 if (count($this->xh[$the_parser]['valuestack']) && $this->xh[$the_parser]['valuestack'][0]['type'] === 'ARRAY')
Derek Allard2067d1a2008-11-13 22:59:24 +00001392 {
1393 // Array
1394 $this->xh[$the_parser]['valuestack'][0]['values'][] = $temp;
1395 }
1396 else
1397 {
1398 // Struct
1399 $this->xh[$the_parser]['value'] = $temp;
1400 }
Andrey Andreevc8709832012-04-04 13:43:53 +03001401 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001402 case 'MEMBER':
Andrey Andreevc8709832012-04-04 13:43:53 +03001403 $this->xh[$the_parser]['ac'] = '';
Barry Mienydd671972010-10-04 16:33:58 +02001404
Derek Allard2067d1a2008-11-13 22:59:24 +00001405 // If value add to array in the stack for the last element built
1406 if ($this->xh[$the_parser]['value'])
1407 {
1408 $this->xh[$the_parser]['valuestack'][0]['values'][$this->xh[$the_parser]['valuestack'][0]['name']] = $this->xh[$the_parser]['value'];
1409 }
Andrey Andreevc8709832012-04-04 13:43:53 +03001410 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001411 case 'DATA':
Andrey Andreevc8709832012-04-04 13:43:53 +03001412 $this->xh[$the_parser]['ac'] = '';
1413 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001414 case 'PARAM':
1415 if ($this->xh[$the_parser]['value'])
1416 {
1417 $this->xh[$the_parser]['params'][] = $this->xh[$the_parser]['value'];
1418 }
Andrey Andreevc8709832012-04-04 13:43:53 +03001419 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001420 case 'METHODNAME':
1421 $this->xh[$the_parser]['method'] = ltrim($this->xh[$the_parser]['ac']);
Andrey Andreevc8709832012-04-04 13:43:53 +03001422 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001423 case 'PARAMS':
1424 case 'FAULT':
1425 case 'METHODCALL':
1426 case 'METHORESPONSE':
1427 // We're all good kids with nuthin' to do
Andrey Andreevc8709832012-04-04 13:43:53 +03001428 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001429 default:
Andrey Andreevc8709832012-04-04 13:43:53 +03001430 // End of an Invalid Element. Taken care of during the opening tag though
1431 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001432 }
1433 }
1434
Andrey Andreevc8709832012-04-04 13:43:53 +03001435 // --------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +00001436
Andrey Andreevc8709832012-04-04 13:43:53 +03001437 /**
1438 * Parse character data
1439 *
1440 * @param string
1441 * @param string
1442 * @return void
1443 */
Andrey Andreeva30faf92011-12-25 18:15:34 +02001444 public function character_data($the_parser, $data)
Derek Allard2067d1a2008-11-13 22:59:24 +00001445 {
1446 if ($this->xh[$the_parser]['isf'] > 1) return; // XML Fault found already
Barry Mienydd671972010-10-04 16:33:58 +02001447
Derek Allard2067d1a2008-11-13 22:59:24 +00001448 // If a value has not been found
Alex Bilbied261b1e2012-06-02 11:12:16 +01001449 if ($this->xh[$the_parser]['lv'] !== 3)
Derek Allard2067d1a2008-11-13 22:59:24 +00001450 {
Alex Bilbied261b1e2012-06-02 11:12:16 +01001451 if ($this->xh[$the_parser]['lv'] === 1)
Derek Allard2067d1a2008-11-13 22:59:24 +00001452 {
1453 $this->xh[$the_parser]['lv'] = 2; // Found a value
1454 }
Barry Mienydd671972010-10-04 16:33:58 +02001455
Andrey Andreevc8709832012-04-04 13:43:53 +03001456 if ( ! isset($this->xh[$the_parser]['ac']))
Derek Allard2067d1a2008-11-13 22:59:24 +00001457 {
1458 $this->xh[$the_parser]['ac'] = '';
1459 }
Barry Mienydd671972010-10-04 16:33:58 +02001460
Derek Allard2067d1a2008-11-13 22:59:24 +00001461 $this->xh[$the_parser]['ac'] .= $data;
1462 }
1463 }
Barry Mienydd671972010-10-04 16:33:58 +02001464
Andrey Andreevc8709832012-04-04 13:43:53 +03001465 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +02001466
Andrey Andreevc8709832012-04-04 13:43:53 +03001467 /**
1468 * Add parameter
1469 *
1470 * @param mixed
1471 * @return void
1472 */
Andrey Andreeva30faf92011-12-25 18:15:34 +02001473 public function addParam($par)
1474 {
1475 $this->params[] = $par;
1476 }
Barry Mienydd671972010-10-04 16:33:58 +02001477
Andrey Andreevc8709832012-04-04 13:43:53 +03001478 // --------------------------------------------------------------------
1479
1480 /**
1481 * Output parameters
1482 *
1483 * @param array
1484 * @return array
1485 */
Andrey Andreeva30faf92011-12-25 18:15:34 +02001486 public function output_parameters($array = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +00001487 {
Barry Mienydd671972010-10-04 16:33:58 +02001488 $CI =& get_instance();
Andrey Andreeva30faf92011-12-25 18:15:34 +02001489
1490 if (is_array($array))
Derek Allard2067d1a2008-11-13 22:59:24 +00001491 {
1492 while (list($key) = each($array))
1493 {
1494 if (is_array($array[$key]))
1495 {
1496 $array[$key] = $this->output_parameters($array[$key]);
1497 }
1498 else
1499 {
Derek Jonesa9647e82010-03-02 22:59:07 -06001500 // 'bits' is for the MetaWeblog API image bits
1501 // @todo - this needs to be made more general purpose
Alex Bilbied261b1e2012-06-02 11:12:16 +01001502 $array[$key] = ($key === 'bits' OR $this->xss_clean === FALSE) ? $array[$key] : $CI->security->xss_clean($array[$key]);
Derek Allard2067d1a2008-11-13 22:59:24 +00001503 }
1504 }
Barry Mienydd671972010-10-04 16:33:58 +02001505
Andrey Andreevc8709832012-04-04 13:43:53 +03001506 return $array;
Derek Allard2067d1a2008-11-13 22:59:24 +00001507 }
Andrey Andreevc8709832012-04-04 13:43:53 +03001508
1509 $parameters = array();
1510
1511 for ($i = 0, $c = count($this->params); $i < $c; $i++)
Derek Allard2067d1a2008-11-13 22:59:24 +00001512 {
Andrey Andreevc8709832012-04-04 13:43:53 +03001513 $a_param = $this->decode_message($this->params[$i]);
Barry Mienydd671972010-10-04 16:33:58 +02001514
Andrey Andreevc8709832012-04-04 13:43:53 +03001515 if (is_array($a_param))
Derek Allard2067d1a2008-11-13 22:59:24 +00001516 {
Andrey Andreevc8709832012-04-04 13:43:53 +03001517 $parameters[] = $this->output_parameters($a_param);
1518 }
1519 else
1520 {
1521 $parameters[] = ($this->xss_clean) ? $CI->security->xss_clean($a_param) : $a_param;
Barry Mienydd671972010-10-04 16:33:58 +02001522 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001523 }
Barry Mienydd671972010-10-04 16:33:58 +02001524
Derek Allard2067d1a2008-11-13 22:59:24 +00001525 return $parameters;
1526 }
Barry Mienydd671972010-10-04 16:33:58 +02001527
Andrey Andreevc8709832012-04-04 13:43:53 +03001528 // --------------------------------------------------------------------
1529
1530 /**
1531 * Decode message
1532 *
1533 * @param object
1534 * @return mixed
1535 */
Andrey Andreeva30faf92011-12-25 18:15:34 +02001536 public function decode_message($param)
Derek Allard2067d1a2008-11-13 22:59:24 +00001537 {
1538 $kind = $param->kindOf();
1539
Alex Bilbied261b1e2012-06-02 11:12:16 +01001540 if ($kind === 'scalar')
Derek Allard2067d1a2008-11-13 22:59:24 +00001541 {
1542 return $param->scalarval();
1543 }
Alex Bilbied261b1e2012-06-02 11:12:16 +01001544 elseif ($kind === 'array')
Derek Allard2067d1a2008-11-13 22:59:24 +00001545 {
1546 reset($param->me);
Andrey Andreevadc11752011-12-30 14:46:08 +02001547 $b = current($param->me);
Derek Allard2067d1a2008-11-13 22:59:24 +00001548 $arr = array();
1549
Andrey Andreevc8709832012-04-04 13:43:53 +03001550 for ($i = 0, $c = count($b); $i < $c; $i++)
Derek Allard2067d1a2008-11-13 22:59:24 +00001551 {
1552 $arr[] = $this->decode_message($param->me['array'][$i]);
1553 }
Barry Mienydd671972010-10-04 16:33:58 +02001554
Derek Allard2067d1a2008-11-13 22:59:24 +00001555 return $arr;
1556 }
Alex Bilbied261b1e2012-06-02 11:12:16 +01001557 elseif ($kind === 'struct')
Derek Allard2067d1a2008-11-13 22:59:24 +00001558 {
1559 reset($param->me['struct']);
Derek Allard2067d1a2008-11-13 22:59:24 +00001560 $arr = array();
1561
Pascal Kriete14287f32011-02-14 13:39:34 -05001562 while (list($key,$value) = each($param->me['struct']))
Derek Allard2067d1a2008-11-13 22:59:24 +00001563 {
1564 $arr[$key] = $this->decode_message($value);
1565 }
Barry Mienydd671972010-10-04 16:33:58 +02001566
Derek Allard2067d1a2008-11-13 22:59:24 +00001567 return $arr;
1568 }
1569 }
Barry Mienydd671972010-10-04 16:33:58 +02001570
Andrey Andreevc8709832012-04-04 13:43:53 +03001571} // END XML_RPC_Message Class
Derek Allard2067d1a2008-11-13 22:59:24 +00001572
1573/**
1574 * XML-RPC Values class
1575 *
1576 * @category XML-RPC
Derek Jonesf4a4bd82011-10-20 12:18:42 -05001577 * @author EllisLab Dev Team
Derek Allard2067d1a2008-11-13 22:59:24 +00001578 * @link http://codeigniter.com/user_guide/libraries/xmlrpc.html
1579 */
1580class XML_RPC_Values extends CI_Xmlrpc
1581{
Andrey Andreevf5ccd122012-11-02 00:17:39 +02001582 /**
1583 * Value data
1584 *
1585 * @var array
1586 */
Andrey Andreeva30faf92011-12-25 18:15:34 +02001587 public $me = array();
Andrey Andreevf5ccd122012-11-02 00:17:39 +02001588
1589 /**
1590 * Value type
1591 *
1592 * @var int
1593 */
Andrey Andreeva30faf92011-12-25 18:15:34 +02001594 public $mytype = 0;
Derek Allard2067d1a2008-11-13 22:59:24 +00001595
Andrey Andreevf5ccd122012-11-02 00:17:39 +02001596 // --------------------------------------------------------------------
1597
Andrey Andreevc8709832012-04-04 13:43:53 +03001598 /**
1599 * Constructor
1600 *
Andrey Andreevf5ccd122012-11-02 00:17:39 +02001601 * @param mixed $val
1602 * @param string $type
Andrey Andreevc8709832012-04-04 13:43:53 +03001603 * @return void
1604 */
Andrey Andreeva30faf92011-12-25 18:15:34 +02001605 public function __construct($val = -1, $type = '')
Barry Mienydd671972010-10-04 16:33:58 +02001606 {
Greg Akera9263282010-11-10 15:26:43 -06001607 parent::__construct();
Barry Mienydd671972010-10-04 16:33:58 +02001608
Alex Bilbied261b1e2012-06-02 11:12:16 +01001609 if ($val !== -1 OR $type !== '')
Derek Allard2067d1a2008-11-13 22:59:24 +00001610 {
Alex Bilbied261b1e2012-06-02 11:12:16 +01001611 $type = $type === '' ? 'string' : $type;
Barry Mienydd671972010-10-04 16:33:58 +02001612
Dimitar740480a2012-10-05 13:24:59 +03001613 if ($this->xmlrpcTypes[$type] == 1)
Derek Allard2067d1a2008-11-13 22:59:24 +00001614 {
vkeranovb497d2b2012-11-23 23:27:33 +02001615 $this->addScalar($val, $type);
Derek Allard2067d1a2008-11-13 22:59:24 +00001616 }
Dimitar740480a2012-10-05 13:24:59 +03001617 elseif ($this->xmlrpcTypes[$type] == 2)
Derek Allard2067d1a2008-11-13 22:59:24 +00001618 {
1619 $this->addArray($val);
1620 }
Dimitar740480a2012-10-05 13:24:59 +03001621 elseif ($this->xmlrpcTypes[$type] == 3)
Derek Allard2067d1a2008-11-13 22:59:24 +00001622 {
1623 $this->addStruct($val);
1624 }
1625 }
1626 }
1627
Andrey Andreevc8709832012-04-04 13:43:53 +03001628 // --------------------------------------------------------------------
1629
1630 /**
1631 * Add scalar value
1632 *
1633 * @param scalar
1634 * @param string
1635 * @return int
1636 */
Andrey Andreeva30faf92011-12-25 18:15:34 +02001637 public function addScalar($val, $type = 'string')
Derek Allard2067d1a2008-11-13 22:59:24 +00001638 {
1639 $typeof = $this->xmlrpcTypes[$type];
Barry Mienydd671972010-10-04 16:33:58 +02001640
Alex Bilbied261b1e2012-06-02 11:12:16 +01001641 if ($this->mytype === 1)
Derek Allard2067d1a2008-11-13 22:59:24 +00001642 {
1643 echo '<strong>XML_RPC_Values</strong>: scalar can have only one value<br />';
1644 return 0;
1645 }
Barry Mienydd671972010-10-04 16:33:58 +02001646
Dimitar740480a2012-10-05 13:24:59 +03001647 if ($typeof != 1)
Derek Allard2067d1a2008-11-13 22:59:24 +00001648 {
1649 echo '<strong>XML_RPC_Values</strong>: not a scalar type (${typeof})<br />';
1650 return 0;
1651 }
1652
Alex Bilbied261b1e2012-06-02 11:12:16 +01001653 if ($type === $this->xmlrpcBoolean)
Derek Allard2067d1a2008-11-13 22:59:24 +00001654 {
Andrey Andreev3f3f1352012-09-05 16:39:28 +03001655 $val = (int) (strcasecmp($val, 'true') === 0 OR $val === 1 OR ($val === TRUE && strcasecmp($val, 'false')));
Derek Allard2067d1a2008-11-13 22:59:24 +00001656 }
1657
Alex Bilbied261b1e2012-06-02 11:12:16 +01001658 if ($this->mytype === 2)
Derek Allard2067d1a2008-11-13 22:59:24 +00001659 {
1660 // adding to an array here
1661 $ar = $this->me['array'];
1662 $ar[] = new XML_RPC_Values($val, $type);
1663 $this->me['array'] = $ar;
1664 }
1665 else
1666 {
1667 // a scalar, so set the value and remember we're scalar
1668 $this->me[$type] = $val;
1669 $this->mytype = $typeof;
1670 }
Andrey Andreevc8709832012-04-04 13:43:53 +03001671
Derek Allard2067d1a2008-11-13 22:59:24 +00001672 return 1;
1673 }
1674
Andrey Andreevc8709832012-04-04 13:43:53 +03001675 // --------------------------------------------------------------------
1676
1677 /**
1678 * Add array value
1679 *
1680 * @param array
1681 * @return int
1682 */
Andrey Andreeva30faf92011-12-25 18:15:34 +02001683 public function addArray($vals)
Derek Allard2067d1a2008-11-13 22:59:24 +00001684 {
Alex Bilbied261b1e2012-06-02 11:12:16 +01001685 if ($this->mytype !== 0)
Derek Allard2067d1a2008-11-13 22:59:24 +00001686 {
1687 echo '<strong>XML_RPC_Values</strong>: already initialized as a [' . $this->kindOf() . ']<br />';
1688 return 0;
1689 }
1690
1691 $this->mytype = $this->xmlrpcTypes['array'];
1692 $this->me['array'] = $vals;
1693 return 1;
1694 }
1695
Andrey Andreevc8709832012-04-04 13:43:53 +03001696 // --------------------------------------------------------------------
1697
1698 /**
1699 * Add struct value
1700 *
1701 * @param object
1702 * @return int
1703 */
Andrey Andreeva30faf92011-12-25 18:15:34 +02001704 public function addStruct($vals)
Derek Allard2067d1a2008-11-13 22:59:24 +00001705 {
Alex Bilbied261b1e2012-06-02 11:12:16 +01001706 if ($this->mytype !== 0)
Derek Allard2067d1a2008-11-13 22:59:24 +00001707 {
1708 echo '<strong>XML_RPC_Values</strong>: already initialized as a [' . $this->kindOf() . ']<br />';
1709 return 0;
1710 }
1711 $this->mytype = $this->xmlrpcTypes['struct'];
1712 $this->me['struct'] = $vals;
1713 return 1;
1714 }
1715
Andrey Andreevc8709832012-04-04 13:43:53 +03001716 // --------------------------------------------------------------------
1717
1718 /**
1719 * Get value type
1720 *
1721 * @return string
1722 */
Andrey Andreeva30faf92011-12-25 18:15:34 +02001723 public function kindOf()
Derek Allard2067d1a2008-11-13 22:59:24 +00001724 {
Andrey Andreevc8709832012-04-04 13:43:53 +03001725 switch ($this->mytype)
Derek Allard2067d1a2008-11-13 22:59:24 +00001726 {
Andrey Andreevc8709832012-04-04 13:43:53 +03001727 case 3: return 'struct';
1728 case 2: return 'array';
1729 case 1: return 'scalar';
1730 default: return 'undef';
Derek Allard2067d1a2008-11-13 22:59:24 +00001731 }
1732 }
1733
Andrey Andreevc8709832012-04-04 13:43:53 +03001734 // --------------------------------------------------------------------
1735
1736 /**
1737 * Serialize data
1738 *
1739 * @param string
1740 * @param mixed
1741 */
Andrey Andreeva30faf92011-12-25 18:15:34 +02001742 public function serializedata($typ, $val)
Derek Allard2067d1a2008-11-13 22:59:24 +00001743 {
1744 $rs = '';
Derek Jonesa9647e82010-03-02 22:59:07 -06001745
Andrey Andreevc8709832012-04-04 13:43:53 +03001746 switch ($this->xmlrpcTypes[$typ])
Derek Allard2067d1a2008-11-13 22:59:24 +00001747 {
1748 case 3:
1749 // struct
1750 $rs .= "<struct>\n";
1751 reset($val);
Pascal Kriete14287f32011-02-14 13:39:34 -05001752 while (list($key2, $val2) = each($val))
Derek Allard2067d1a2008-11-13 22:59:24 +00001753 {
Andrey Andreeva30faf92011-12-25 18:15:34 +02001754 $rs .= "<member>\n<name>{$key2}</name>\n".$this->serializeval($val2)."</member>\n";
Derek Allard2067d1a2008-11-13 22:59:24 +00001755 }
1756 $rs .= '</struct>';
Andrey Andreevc8709832012-04-04 13:43:53 +03001757 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001758 case 2:
1759 // array
1760 $rs .= "<array>\n<data>\n";
Andrey Andreevc8709832012-04-04 13:43:53 +03001761 for ($i = 0, $c = count($val); $i < $c; $i++)
Derek Allard2067d1a2008-11-13 22:59:24 +00001762 {
1763 $rs .= $this->serializeval($val[$i]);
1764 }
Andrey Andreeva30faf92011-12-25 18:15:34 +02001765 $rs .= "</data>\n</array>\n";
Derek Allard2067d1a2008-11-13 22:59:24 +00001766 break;
1767 case 1:
1768 // others
1769 switch ($typ)
1770 {
1771 case $this->xmlrpcBase64:
Andrey Andreevc8709832012-04-04 13:43:53 +03001772 $rs .= '<'.$typ.'>'.base64_encode( (string) $val).'</'.$typ.">\n";
1773 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001774 case $this->xmlrpcBoolean:
Andrey Andreevc8709832012-04-04 13:43:53 +03001775 $rs .= '<'.$typ.'>'.( (bool) $val ? '1' : '0').'</'.$typ.">\n";
1776 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001777 case $this->xmlrpcString:
Andrey Andreevc8709832012-04-04 13:43:53 +03001778 $rs .= '<'.$typ.'>'.htmlspecialchars( (string) $val).'</'.$typ.">\n";
1779 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001780 default:
Andrey Andreevc8709832012-04-04 13:43:53 +03001781 $rs .= '<'.$typ.'>'.$val.'</'.$typ.">\n";
1782 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001783 }
1784 default:
Andrey Andreevc8709832012-04-04 13:43:53 +03001785 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001786 }
Andrey Andreevc8709832012-04-04 13:43:53 +03001787
Derek Allard2067d1a2008-11-13 22:59:24 +00001788 return $rs;
1789 }
1790
Andrey Andreevc8709832012-04-04 13:43:53 +03001791 // --------------------------------------------------------------------
1792
1793 /**
1794 * Serialize class
1795 *
1796 * @return string
1797 */
Andrey Andreeva30faf92011-12-25 18:15:34 +02001798 public function serialize_class()
Derek Allard2067d1a2008-11-13 22:59:24 +00001799 {
1800 return $this->serializeval($this);
1801 }
1802
Andrey Andreevc8709832012-04-04 13:43:53 +03001803 // --------------------------------------------------------------------
1804
1805 /**
1806 * Serialize value
1807 *
1808 * @param object
1809 * @return string
1810 */
Andrey Andreeva30faf92011-12-25 18:15:34 +02001811 public function serializeval($o)
Derek Allard2067d1a2008-11-13 22:59:24 +00001812 {
1813 $ar = $o->me;
1814 reset($ar);
Barry Mienydd671972010-10-04 16:33:58 +02001815
Derek Allard2067d1a2008-11-13 22:59:24 +00001816 list($typ, $val) = each($ar);
Andrey Andreeva30faf92011-12-25 18:15:34 +02001817 return "<value>\n".$this->serializedata($typ, $val)."</value>\n";
Derek Allard2067d1a2008-11-13 22:59:24 +00001818 }
Barry Mienydd671972010-10-04 16:33:58 +02001819
Andrey Andreevc8709832012-04-04 13:43:53 +03001820 // --------------------------------------------------------------------
1821
1822 /**
1823 * Scalar value
1824 *
1825 * @return mixed
1826 */
Andrey Andreeva30faf92011-12-25 18:15:34 +02001827 public function scalarval()
Derek Allard2067d1a2008-11-13 22:59:24 +00001828 {
1829 reset($this->me);
Andrey Andreevadc11752011-12-30 14:46:08 +02001830 return current($this->me);
Derek Allard2067d1a2008-11-13 22:59:24 +00001831 }
1832
Andrey Andreevc8709832012-04-04 13:43:53 +03001833 // --------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +00001834
Andrey Andreevc8709832012-04-04 13:43:53 +03001835 /**
1836 * Encode time in ISO-8601 form.
1837 * Useful for sending time in XML-RPC
1838 *
1839 * @param int unix timestamp
1840 * @param bool
1841 * @return string
1842 */
1843 public function iso8601_encode($time, $utc = FALSE)
Barry Mienydd671972010-10-04 16:33:58 +02001844 {
Andrey Andreev62090152011-12-30 12:49:27 +02001845 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 +00001846 }
Barry Mienydd671972010-10-04 16:33:58 +02001847
Andrey Andreevc8709832012-04-04 13:43:53 +03001848} // END XML_RPC_Values Class
Derek Allard2067d1a2008-11-13 22:59:24 +00001849
1850/* End of file Xmlrpc.php */
Andrey Andreev8f50b6b2012-03-28 14:12:09 +03001851/* Location: ./system/libraries/Xmlrpc.php */