blob: 3ef823e297a6731abb198182b48fb173f0db851e [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
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 */
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 */
Andrey Andreeva30faf92011-12-25 18:15:34 +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'
Derek Allard2067d1a2008-11-13 22:59:24 +0000268 );
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')
288 );
Barry Mienydd671972010-10-04 16:33:58 +0200289
290
Derek Allard2067d1a2008-11-13 22:59:24 +0000291 // XML-RPC Responses
292 $this->xmlrpcerr['unknown_method'] = '1';
293 $this->xmlrpcstr['unknown_method'] = 'This is not a known method for this XML-RPC Server';
294 $this->xmlrpcerr['invalid_return'] = '2';
Derek Jones37f4b9c2011-07-01 17:56:50 -0500295 $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 +0000296 $this->xmlrpcerr['incorrect_params'] = '3';
297 $this->xmlrpcstr['incorrect_params'] = 'Incorrect parameters were passed to method';
298 $this->xmlrpcerr['introspect_unknown'] = '4';
Andrey Andreeva30faf92011-12-25 18:15:34 +0200299 $this->xmlrpcstr['introspect_unknown'] = 'Cannot inspect signature for request: method unknown';
Derek Allard2067d1a2008-11-13 22:59:24 +0000300 $this->xmlrpcerr['http_error'] = '5';
301 $this->xmlrpcstr['http_error'] = "Did not receive a '200 OK' response from remote server.";
302 $this->xmlrpcerr['no_data'] = '6';
303 $this->xmlrpcstr['no_data'] ='No data received from server.';
Barry Mienydd671972010-10-04 16:33:58 +0200304
Derek Allard2067d1a2008-11-13 22:59:24 +0000305 $this->initialize($config);
Barry Mienydd671972010-10-04 16:33:58 +0200306
Andrey Andreev8f50b6b2012-03-28 14:12:09 +0300307 log_message('debug', 'XML-RPC Class Initialized');
Derek Allard2067d1a2008-11-13 22:59:24 +0000308 }
Barry Mienydd671972010-10-04 16:33:58 +0200309
Andrey Andreevc8709832012-04-04 13:43:53 +0300310 // --------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +0000311
Andrey Andreevc8709832012-04-04 13:43:53 +0300312 /**
313 * Initialize
314 *
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200315 * @param array $config
Andrey Andreevc8709832012-04-04 13:43:53 +0300316 * @return void
317 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200318 public function initialize($config = array())
Derek Allard2067d1a2008-11-13 22:59:24 +0000319 {
Derek Jones33559102009-02-02 18:50:38 +0000320 if (count($config) > 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000321 {
322 foreach ($config as $key => $val)
323 {
324 if (isset($this->$key))
325 {
Barry Mienydd671972010-10-04 16:33:58 +0200326 $this->$key = $val;
Derek Allard2067d1a2008-11-13 22:59:24 +0000327 }
328 }
329 }
330 }
Barry Mienydd671972010-10-04 16:33:58 +0200331
Andrey Andreevc8709832012-04-04 13:43:53 +0300332 // --------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +0000333
Andrey Andreevc8709832012-04-04 13:43:53 +0300334 /**
335 * Parse server URL
336 *
Andrey Andreev5fd3ae82012-10-24 14:55:35 +0300337 * @param string $url
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200338 * @param int $port
339 * @param string $proxy
340 * @param int $proxy_port
Andrey Andreevc8709832012-04-04 13:43:53 +0300341 * @return void
342 */
Valentin Sheyretskicfcf34e2012-07-02 12:04:36 +0300343 public function server($url, $port = 80, $proxy = FALSE, $proxy_port = 8080)
Derek Allard2067d1a2008-11-13 22:59:24 +0000344 {
Andrey Andreeva30faf92011-12-25 18:15:34 +0200345 if (strpos($url, 'http') !== 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000346 {
Andrey Andreevc8709832012-04-04 13:43:53 +0300347 $url = 'http://'.$url;
Derek Allard2067d1a2008-11-13 22:59:24 +0000348 }
Barry Mienydd671972010-10-04 16:33:58 +0200349
Derek Allard2067d1a2008-11-13 22:59:24 +0000350 $parts = parse_url($url);
Barry Mienydd671972010-10-04 16:33:58 +0200351
Andrey Andreev8f50b6b2012-03-28 14:12:09 +0300352 $path = isset($parts['path']) ? $parts['path'] : '/';
Barry Mienydd671972010-10-04 16:33:58 +0200353
Andrey Andreev8f50b6b2012-03-28 14:12:09 +0300354 if ( ! empty($parts['query']))
Derek Allard2067d1a2008-11-13 22:59:24 +0000355 {
356 $path .= '?'.$parts['query'];
Barry Mienydd671972010-10-04 16:33:58 +0200357 }
358
Valio9dee5352012-07-02 10:42:28 +0300359 $this->client = new XML_RPC_Client($path, $parts['host'], $port, $proxy, $proxy_port);
Derek Allard2067d1a2008-11-13 22:59:24 +0000360 }
Barry Mienydd671972010-10-04 16:33:58 +0200361
Andrey Andreevc8709832012-04-04 13:43:53 +0300362 // --------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +0000363
Andrey Andreevc8709832012-04-04 13:43:53 +0300364 /**
365 * Set Timeout
366 *
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200367 * @param int $seconds
Andrey Andreevc8709832012-04-04 13:43:53 +0300368 * @return void
369 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200370 public function timeout($seconds = 5)
Derek Allard2067d1a2008-11-13 22:59:24 +0000371 {
372 if ( ! is_null($this->client) && is_int($seconds))
373 {
374 $this->client->timeout = $seconds;
375 }
376 }
Barry Mienydd671972010-10-04 16:33:58 +0200377
Andrey Andreevc8709832012-04-04 13:43:53 +0300378 // --------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +0000379
Andrey Andreevc8709832012-04-04 13:43:53 +0300380 /**
381 * Set Methods
382 *
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200383 * @param string $function Method name
Andrey Andreevc8709832012-04-04 13:43:53 +0300384 * @return void
385 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200386 public function method($function)
Derek Allard2067d1a2008-11-13 22:59:24 +0000387 {
388 $this->method = $function;
389 }
Barry Mienydd671972010-10-04 16:33:58 +0200390
Andrey Andreevc8709832012-04-04 13:43:53 +0300391 // --------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +0000392
Andrey Andreevc8709832012-04-04 13:43:53 +0300393 /**
394 * Take Array of Data and Create Objects
395 *
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200396 * @param array $incoming
Andrey Andreevc8709832012-04-04 13:43:53 +0300397 * @return void
398 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200399 public function request($incoming)
Derek Allard2067d1a2008-11-13 22:59:24 +0000400 {
401 if ( ! is_array($incoming))
402 {
403 // Send Error
Andrey Andreevc8709832012-04-04 13:43:53 +0300404 return;
Derek Allard2067d1a2008-11-13 22:59:24 +0000405 }
Barry Mienydd671972010-10-04 16:33:58 +0200406
Derek Allard2067d1a2008-11-13 22:59:24 +0000407 $this->data = array();
Barry Mienydd671972010-10-04 16:33:58 +0200408
Pascal Kriete14287f32011-02-14 13:39:34 -0500409 foreach ($incoming as $key => $value)
Derek Allard2067d1a2008-11-13 22:59:24 +0000410 {
411 $this->data[$key] = $this->values_parsing($value);
412 }
413 }
Barry Mienydd671972010-10-04 16:33:58 +0200414
Andrey Andreevc8709832012-04-04 13:43:53 +0300415 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200416
Andrey Andreevc8709832012-04-04 13:43:53 +0300417 /**
418 * Set Debug
419 *
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200420 * @param bool $flag
Andrey Andreevc8709832012-04-04 13:43:53 +0300421 * @return void
422 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200423 public function set_debug($flag = TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000424 {
Alex Bilbied261b1e2012-06-02 11:12:16 +0100425 $this->debug = ($flag === TRUE);
Derek Allard2067d1a2008-11-13 22:59:24 +0000426 }
Barry Mienydd671972010-10-04 16:33:58 +0200427
Andrey Andreevc8709832012-04-04 13:43:53 +0300428 // --------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +0000429
Andrey Andreevc8709832012-04-04 13:43:53 +0300430 /**
431 * Values Parsing
432 *
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200433 * @param mixed $value
Andrey Andreevc8709832012-04-04 13:43:53 +0300434 * @return object
435 */
436 public function values_parsing($value)
Derek Allard2067d1a2008-11-13 22:59:24 +0000437 {
Derek Jones8c4b5e72010-01-06 22:21:41 +0000438 if (is_array($value) && array_key_exists(0, $value))
Derek Allard2067d1a2008-11-13 22:59:24 +0000439 {
Andrey Andreev8f50b6b2012-03-28 14:12:09 +0300440 if ( ! isset($value[1], $this->xmlrpcTypes[$value[1]]))
Derek Allard2067d1a2008-11-13 22:59:24 +0000441 {
Andrey Andreeva30faf92011-12-25 18:15:34 +0200442 $temp = new XML_RPC_Values($value[0], (is_array($value[0]) ? 'array' : 'string'));
Derek Allard2067d1a2008-11-13 22:59:24 +0000443 }
444 else
445 {
Alex Bilbied261b1e2012-06-02 11:12:16 +0100446 if (is_array($value[0]) && ($value[1] === 'struct' OR $value[1] === 'array'))
Andrey Andreeva30faf92011-12-25 18:15:34 +0200447 {
448 while (list($k) = each($value[0]))
449 {
450 $value[0][$k] = $this->values_parsing($value[0][$k], TRUE);
451 }
452 }
453
454 $temp = new XML_RPC_Values($value[0], $value[1]);
Derek Allard2067d1a2008-11-13 22:59:24 +0000455 }
456 }
457 else
458 {
459 $temp = new XML_RPC_Values($value, 'string');
460 }
461
462 return $temp;
463 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000464
Andrey Andreevc8709832012-04-04 13:43:53 +0300465 // --------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +0000466
Andrey Andreevc8709832012-04-04 13:43:53 +0300467 /**
468 * Sends XML-RPC Request
469 *
470 * @return bool
471 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200472 public function send_request()
Derek Allard2067d1a2008-11-13 22:59:24 +0000473 {
Andrey Andreevc8709832012-04-04 13:43:53 +0300474 $this->message = new XML_RPC_Message($this->method, $this->data);
Derek Allard2067d1a2008-11-13 22:59:24 +0000475 $this->message->debug = $this->debug;
Barry Mienydd671972010-10-04 16:33:58 +0200476
Andrey Andreeva30faf92011-12-25 18:15:34 +0200477 if ( ! $this->result = $this->client->send($this->message) OR ! is_object($this->result->val))
Derek Allard2067d1a2008-11-13 22:59:24 +0000478 {
479 $this->error = $this->result->errstr;
480 return FALSE;
481 }
Barry Mienydd671972010-10-04 16:33:58 +0200482
Derek Allard2067d1a2008-11-13 22:59:24 +0000483 $this->response = $this->result->decode();
Derek Allard2067d1a2008-11-13 22:59:24 +0000484 return TRUE;
485 }
Barry Mienydd671972010-10-04 16:33:58 +0200486
Andrey Andreevc8709832012-04-04 13:43:53 +0300487 // --------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +0000488
Andrey Andreevc8709832012-04-04 13:43:53 +0300489 /**
490 * Returns Error
491 *
492 * @return string
493 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200494 public function display_error()
Derek Allard2067d1a2008-11-13 22:59:24 +0000495 {
496 return $this->error;
497 }
Barry Mienydd671972010-10-04 16:33:58 +0200498
Andrey Andreevc8709832012-04-04 13:43:53 +0300499 // --------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +0000500
Andrey Andreevc8709832012-04-04 13:43:53 +0300501 /**
502 * Returns Remote Server Response
503 *
504 * @return string
505 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200506 public function display_response()
Derek Allard2067d1a2008-11-13 22:59:24 +0000507 {
508 return $this->response;
509 }
Barry Mienydd671972010-10-04 16:33:58 +0200510
Andrey Andreevc8709832012-04-04 13:43:53 +0300511 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200512
Andrey Andreevc8709832012-04-04 13:43:53 +0300513 /**
514 * Sends an Error Message for Server Request
515 *
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200516 * @param int $number
517 * @param string $message
Andrey Andreevc8709832012-04-04 13:43:53 +0300518 * @return object
519 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200520 public function send_error_message($number, $message)
Derek Allard2067d1a2008-11-13 22:59:24 +0000521 {
Andrey Andreeva30faf92011-12-25 18:15:34 +0200522 return new XML_RPC_Response(0, $number, $message);
Derek Allard2067d1a2008-11-13 22:59:24 +0000523 }
Barry Mienydd671972010-10-04 16:33:58 +0200524
Andrey Andreevc8709832012-04-04 13:43:53 +0300525 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200526
Andrey Andreevc8709832012-04-04 13:43:53 +0300527 /**
528 * Send Response for Server Request
529 *
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200530 * @param array $response
Andrey Andreevc8709832012-04-04 13:43:53 +0300531 * @return object
532 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200533 public function send_response($response)
Derek Allard2067d1a2008-11-13 22:59:24 +0000534 {
535 // $response should be array of values, which will be parsed
536 // based on their data and type into a valid group of XML-RPC values
Andrey Andreeva30faf92011-12-25 18:15:34 +0200537 return new XML_RPC_Response($this->values_parsing($response));
Derek Allard2067d1a2008-11-13 22:59:24 +0000538 }
Barry Mienydd671972010-10-04 16:33:58 +0200539
Derek Allard2067d1a2008-11-13 22:59:24 +0000540} // END XML_RPC Class
541
Derek Allard2067d1a2008-11-13 22:59:24 +0000542/**
543 * XML-RPC Client class
544 *
545 * @category XML-RPC
Derek Jonesf4a4bd82011-10-20 12:18:42 -0500546 * @author EllisLab Dev Team
Derek Allard2067d1a2008-11-13 22:59:24 +0000547 * @link http://codeigniter.com/user_guide/libraries/xmlrpc.html
548 */
549class XML_RPC_Client extends CI_Xmlrpc
550{
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200551 /**
552 * Path
553 *
554 * @var string
555 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200556 public $path = '';
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200557
558 /**
559 * Server hostname
560 *
561 * @var string
562 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200563 public $server = '';
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200564
565 /**
566 * Server port
567 *
568 * @var int
569 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200570 public $port = 80;
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200571
572 /**
573 * Proxy hostname
574 *
575 * @var string
576 */
Valio9dee5352012-07-02 10:42:28 +0300577 public $proxy = FALSE;
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200578
579 /**
580 * Proxy port
581 *
582 * @var int
583 */
Valio9dee5352012-07-02 10:42:28 +0300584 public $proxy_port = 8080;
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200585
586 /**
587 * Error number
588 *
589 * @var string
590 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200591 public $errno = '';
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200592
593 /**
594 * Error message
595 *
596 * @var string
597 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200598 public $errstring = '';
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200599
600 /**
601 * Timeout in seconds
602 *
603 * @var int
604 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200605 public $timeout = 5;
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200606
607 /**
608 * No Multicall flag
609 *
610 * @var bool
611 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200612 public $no_multicall = FALSE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000613
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200614 // --------------------------------------------------------------------
615
Andrey Andreevc8709832012-04-04 13:43:53 +0300616 /**
617 * Constructor
618 *
Andrey Andreev5fd3ae82012-10-24 14:55:35 +0300619 * @param string $path
620 * @param object $server
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200621 * @param int $port
622 * @param string $proxy
623 * @param int $proxy_port
Andrey Andreevc8709832012-04-04 13:43:53 +0300624 * @return void
625 */
Valio9dee5352012-07-02 10:42:28 +0300626 public function __construct($path, $server, $port = 80, $proxy = FALSE, $proxy_port = 8080)
Derek Allard2067d1a2008-11-13 22:59:24 +0000627 {
Greg Akera9263282010-11-10 15:26:43 -0600628 parent::__construct();
Barry Mienydd671972010-10-04 16:33:58 +0200629
Derek Allard2067d1a2008-11-13 22:59:24 +0000630 $this->port = $port;
631 $this->server = $server;
632 $this->path = $path;
Valio9dee5352012-07-02 10:42:28 +0300633 $this->proxy = $proxy;
634 $this->proxy_port = $proxy_port;
Derek Allard2067d1a2008-11-13 22:59:24 +0000635 }
Barry Mienydd671972010-10-04 16:33:58 +0200636
Andrey Andreevc8709832012-04-04 13:43:53 +0300637 // --------------------------------------------------------------------
638
639 /**
640 * Send message
641 *
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200642 * @param mixed $msg
Andrey Andreevc8709832012-04-04 13:43:53 +0300643 * @return object
644 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200645 public function send($msg)
Derek Allard2067d1a2008-11-13 22:59:24 +0000646 {
647 if (is_array($msg))
648 {
649 // Multi-call disabled
Andrey Andreevc8709832012-04-04 13:43:53 +0300650 return new XML_RPC_Response(0, $this->xmlrpcerr['multicall_recursion'], $this->xmlrpcstr['multicall_recursion']);
Derek Allard2067d1a2008-11-13 22:59:24 +0000651 }
652
653 return $this->sendPayload($msg);
654 }
655
Andrey Andreevc8709832012-04-04 13:43:53 +0300656 // --------------------------------------------------------------------
657
658 /**
659 * Send payload
660 *
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200661 * @param object $msg
Andrey Andreevc8709832012-04-04 13:43:53 +0300662 * @return object
663 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200664 public function sendPayload($msg)
Barry Mienydd671972010-10-04 16:33:58 +0200665 {
Andrey Andreevc02e7c52012-07-02 16:43:43 +0300666 if ($this->proxy === FALSE)
Valentin Sheyretskicfcf34e2012-07-02 12:04:36 +0300667 {
668 $server = $this->server;
669 $port = $this->port;
Valentin Sheyretski09217ce2012-07-02 16:27:01 +0300670 }
671 else
672 {
Valio9dee5352012-07-02 10:42:28 +0300673 $server = $this->proxy;
674 $port = $this->proxy_port;
675 }
Valentin Sheyretskicfcf34e2012-07-02 12:04:36 +0300676
Valio9dee5352012-07-02 10:42:28 +0300677 $fp = @fsockopen($server, $port, $this->errno, $this->errstring, $this->timeout);
Barry Mienydd671972010-10-04 16:33:58 +0200678
Derek Allard2067d1a2008-11-13 22:59:24 +0000679 if ( ! is_resource($fp))
680 {
681 error_log($this->xmlrpcstr['http_error']);
Andrey Andreevc8709832012-04-04 13:43:53 +0300682 return new XML_RPC_Response(0, $this->xmlrpcerr['http_error'], $this->xmlrpcstr['http_error']);
Derek Allard2067d1a2008-11-13 22:59:24 +0000683 }
Barry Mienydd671972010-10-04 16:33:58 +0200684
Pascal Kriete14287f32011-02-14 13:39:34 -0500685 if (empty($msg->payload))
Derek Allard2067d1a2008-11-13 22:59:24 +0000686 {
687 // $msg = XML_RPC_Messages
688 $msg->createPayload();
689 }
Barry Mienydd671972010-10-04 16:33:58 +0200690
Derek Allard2067d1a2008-11-13 22:59:24 +0000691 $r = "\r\n";
Andrey Andreev8f50b6b2012-03-28 14:12:09 +0300692 $op = 'POST '.$this->path.' HTTP/1.0'.$r
693 .'Host: '.$this->server.$r
694 .'Content-Type: text/xml'.$r
695 .'User-Agent: '.$this->xmlrpcName.$r
696 .'Content-Length: '.strlen($msg->payload).$r.$r
697 .$msg->payload;
Barry Mienydd671972010-10-04 16:33:58 +0200698
George Petsagourakis306b3782012-05-02 20:31:08 +0300699 if ( ! fwrite($fp, $op, strlen($op)))
Derek Allard2067d1a2008-11-13 22:59:24 +0000700 {
701 error_log($this->xmlrpcstr['http_error']);
Andrey Andreevc8709832012-04-04 13:43:53 +0300702 return new XML_RPC_Response(0, $this->xmlrpcerr['http_error'], $this->xmlrpcstr['http_error']);
Derek Allard2067d1a2008-11-13 22:59:24 +0000703 }
Andrey Andreevc8709832012-04-04 13:43:53 +0300704
Derek Allard2067d1a2008-11-13 22:59:24 +0000705 $resp = $msg->parseResponse($fp);
706 fclose($fp);
707 return $resp;
708 }
709
Andrey Andreevc8709832012-04-04 13:43:53 +0300710} // END XML_RPC_Client Class
Derek Allard2067d1a2008-11-13 22:59:24 +0000711
712/**
713 * XML-RPC Response class
714 *
715 * @category XML-RPC
Derek Jonesf4a4bd82011-10-20 12:18:42 -0500716 * @author EllisLab Dev Team
Derek Allard2067d1a2008-11-13 22:59:24 +0000717 * @link http://codeigniter.com/user_guide/libraries/xmlrpc.html
718 */
719class XML_RPC_Response
720{
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200721
722 /**
723 * Value
724 *
725 * @var mixed
726 */
Andrey Andreevc8709832012-04-04 13:43:53 +0300727 public $val = 0;
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200728
729 /**
730 * Error number
731 *
732 * @var int
733 */
Andrey Andreevc8709832012-04-04 13:43:53 +0300734 public $errno = 0;
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200735
736 /**
737 * Error message
738 *
739 * @var string
740 */
Andrey Andreevc8709832012-04-04 13:43:53 +0300741 public $errstr = '';
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200742
743 /**
744 * Headers list
745 *
746 * @var array
747 */
Andrey Andreevc8709832012-04-04 13:43:53 +0300748 public $headers = array();
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200749
750 /**
751 * XSS Filter flag
752 *
753 * @var bool
754 */
Andrey Andreevc8709832012-04-04 13:43:53 +0300755 public $xss_clean = TRUE;
Derek Allard2067d1a2008-11-13 22:59:24 +0000756
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200757 // --------------------------------------------------------------------
758
Andrey Andreevc8709832012-04-04 13:43:53 +0300759 /**
760 * Constructor
761 *
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200762 * @param mixed $val
763 * @param int $code
764 * @param string $fstr
Andrey Andreevc8709832012-04-04 13:43:53 +0300765 * @return void
766 */
Greg Akera9263282010-11-10 15:26:43 -0600767 public function __construct($val, $code = 0, $fstr = '')
Barry Mienydd671972010-10-04 16:33:58 +0200768 {
Alex Bilbied261b1e2012-06-02 11:12:16 +0100769 if ($code !== 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000770 {
771 // error
772 $this->errno = $code;
Andrey Andreevc8709832012-04-04 13:43:53 +0300773 $this->errstr = htmlspecialchars($fstr,
774 (is_php('5.4') ? ENT_XML1 | ENT_NOQUOTES : ENT_NOQUOTES),
775 'UTF-8');
Derek Allard2067d1a2008-11-13 22:59:24 +0000776 }
Andrey Andreev8f50b6b2012-03-28 14:12:09 +0300777 elseif ( ! is_object($val))
Derek Allard2067d1a2008-11-13 22:59:24 +0000778 {
779 // programmer error, not an object
Andrey Andreev8f50b6b2012-03-28 14:12:09 +0300780 error_log("Invalid type '".gettype($val)."' (value: ".$val.') passed to XML_RPC_Response. Defaulting to empty value.');
Derek Allard2067d1a2008-11-13 22:59:24 +0000781 $this->val = new XML_RPC_Values();
782 }
783 else
784 {
785 $this->val = $val;
786 }
787 }
788
Andrey Andreevc8709832012-04-04 13:43:53 +0300789 // --------------------------------------------------------------------
790
791 /**
792 * Fault code
793 *
794 * @return int
795 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200796 public function faultCode()
Derek Allard2067d1a2008-11-13 22:59:24 +0000797 {
798 return $this->errno;
799 }
800
Andrey Andreevc8709832012-04-04 13:43:53 +0300801 // --------------------------------------------------------------------
802
803 /**
804 * Fault string
805 *
806 * @return string
807 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200808 public function faultString()
Derek Allard2067d1a2008-11-13 22:59:24 +0000809 {
810 return $this->errstr;
811 }
812
Andrey Andreevc8709832012-04-04 13:43:53 +0300813 // --------------------------------------------------------------------
814
815 /**
816 * Value
817 *
818 * @return mixed
819 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200820 public function value()
Derek Allard2067d1a2008-11-13 22:59:24 +0000821 {
822 return $this->val;
823 }
Barry Mienydd671972010-10-04 16:33:58 +0200824
Andrey Andreevc8709832012-04-04 13:43:53 +0300825 // --------------------------------------------------------------------
826
827 /**
828 * Prepare response
829 *
830 * @return string xml
831 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200832 public function prepare_response()
Derek Allard2067d1a2008-11-13 22:59:24 +0000833 {
Andrey Andreeva30faf92011-12-25 18:15:34 +0200834 return "<methodResponse>\n"
Andrey Andreevc8709832012-04-04 13:43:53 +0300835 .($this->errno
836 ? '<fault>
Derek Allard2067d1a2008-11-13 22:59:24 +0000837 <value>
838 <struct>
839 <member>
840 <name>faultCode</name>
Andrey Andreevc8709832012-04-04 13:43:53 +0300841 <value><int>'.$this->errno.'</int></value>
Derek Allard2067d1a2008-11-13 22:59:24 +0000842 </member>
843 <member>
844 <name>faultString</name>
Andrey Andreevc8709832012-04-04 13:43:53 +0300845 <value><string>'.$this->errstr.'</string></value>
Derek Allard2067d1a2008-11-13 22:59:24 +0000846 </member>
847 </struct>
848 </value>
Andrey Andreeva30faf92011-12-25 18:15:34 +0200849</fault>'
Andrey Andreevc8709832012-04-04 13:43:53 +0300850 : "<params>\n<param>\n".$this->val->serialize_class()."</param>\n</params>")
851 ."\n</methodResponse>";
Derek Allard2067d1a2008-11-13 22:59:24 +0000852 }
Barry Mienydd671972010-10-04 16:33:58 +0200853
Andrey Andreevc8709832012-04-04 13:43:53 +0300854 // --------------------------------------------------------------------
855
856 /**
857 * Decode
858 *
859 * @param mixed
860 * @return array
861 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200862 public function decode($array = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000863 {
864 $CI =& get_instance();
Andrey Andreeva30faf92011-12-25 18:15:34 +0200865
866 if (is_array($array))
Derek Allard2067d1a2008-11-13 22:59:24 +0000867 {
868 while (list($key) = each($array))
869 {
870 if (is_array($array[$key]))
871 {
872 $array[$key] = $this->decode($array[$key]);
873 }
874 else
875 {
Robin Sowell66a3fc02010-03-18 09:44:55 -0400876 $array[$key] = ($this->xss_clean) ? $CI->security->xss_clean($array[$key]) : $array[$key];
Derek Allard2067d1a2008-11-13 22:59:24 +0000877 }
878 }
Barry Mienydd671972010-10-04 16:33:58 +0200879
Andrey Andreevc8709832012-04-04 13:43:53 +0300880 return $array;
881 }
882
883 $result = $this->xmlrpc_decoder($this->val);
884
885 if (is_array($result))
886 {
887 $result = $this->decode($result);
Derek Allard2067d1a2008-11-13 22:59:24 +0000888 }
889 else
890 {
Andrey Andreevc8709832012-04-04 13:43:53 +0300891 $result = ($this->xss_clean) ? $CI->security->xss_clean($result) : $result;
Derek Allard2067d1a2008-11-13 22:59:24 +0000892 }
Barry Mienydd671972010-10-04 16:33:58 +0200893
Derek Allard2067d1a2008-11-13 22:59:24 +0000894 return $result;
895 }
896
Andrey Andreevc8709832012-04-04 13:43:53 +0300897 // --------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +0000898
Andrey Andreevc8709832012-04-04 13:43:53 +0300899 /**
900 * XML-RPC Object to PHP Types
901 *
902 * @param object
903 * @return array
904 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200905 public function xmlrpc_decoder($xmlrpc_val)
Derek Allard2067d1a2008-11-13 22:59:24 +0000906 {
907 $kind = $xmlrpc_val->kindOf();
908
Alex Bilbied261b1e2012-06-02 11:12:16 +0100909 if ($kind === 'scalar')
Derek Allard2067d1a2008-11-13 22:59:24 +0000910 {
911 return $xmlrpc_val->scalarval();
912 }
Alex Bilbied261b1e2012-06-02 11:12:16 +0100913 elseif ($kind === 'array')
Derek Allard2067d1a2008-11-13 22:59:24 +0000914 {
915 reset($xmlrpc_val->me);
Andrey Andreevadc11752011-12-30 14:46:08 +0200916 $b = current($xmlrpc_val->me);
Derek Allard2067d1a2008-11-13 22:59:24 +0000917 $arr = array();
918
Andrey Andreeva30faf92011-12-25 18:15:34 +0200919 for ($i = 0, $size = count($b); $i < $size; $i++)
Derek Allard2067d1a2008-11-13 22:59:24 +0000920 {
921 $arr[] = $this->xmlrpc_decoder($xmlrpc_val->me['array'][$i]);
922 }
923 return $arr;
924 }
Alex Bilbied261b1e2012-06-02 11:12:16 +0100925 elseif ($kind === 'struct')
Derek Allard2067d1a2008-11-13 22:59:24 +0000926 {
927 reset($xmlrpc_val->me['struct']);
928 $arr = array();
929
Pascal Kriete14287f32011-02-14 13:39:34 -0500930 while (list($key,$value) = each($xmlrpc_val->me['struct']))
Derek Allard2067d1a2008-11-13 22:59:24 +0000931 {
932 $arr[$key] = $this->xmlrpc_decoder($value);
933 }
934 return $arr;
935 }
936 }
Barry Mienydd671972010-10-04 16:33:58 +0200937
Andrey Andreevc8709832012-04-04 13:43:53 +0300938 // --------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +0000939
Andrey Andreevc8709832012-04-04 13:43:53 +0300940 /**
941 * ISO-8601 time to server or UTC time
942 *
943 * @param string
944 * @param bool
945 * @return int unix timestamp
946 */
947 public function iso8601_decode($time, $utc = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000948 {
Andrey Andreevc8709832012-04-04 13:43:53 +0300949 // return a time in the localtime, or UTC
Derek Allard2067d1a2008-11-13 22:59:24 +0000950 $t = 0;
951 if (preg_match('/([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})/', $time, $regs))
952 {
Alex Bilbied261b1e2012-06-02 11:12:16 +0100953 $fnc = ($utc === TRUE) ? 'gmmktime' : 'mktime';
Pascal Kriete14287f32011-02-14 13:39:34 -0500954 $t = $fnc($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
Derek Allard2067d1a2008-11-13 22:59:24 +0000955 }
956 return $t;
957 }
Barry Mienydd671972010-10-04 16:33:58 +0200958
Andrey Andreevc8709832012-04-04 13:43:53 +0300959} // END XML_RPC_Response Class
Derek Allard2067d1a2008-11-13 22:59:24 +0000960
961/**
962 * XML-RPC Message class
963 *
964 * @category XML-RPC
Derek Jonesf4a4bd82011-10-20 12:18:42 -0500965 * @author EllisLab Dev Team
Derek Allard2067d1a2008-11-13 22:59:24 +0000966 * @link http://codeigniter.com/user_guide/libraries/xmlrpc.html
967 */
968class XML_RPC_Message extends CI_Xmlrpc
969{
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200970
971 /**
972 * Payload
973 *
974 * @var string
975 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200976 public $payload;
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200977
978 /**
979 * Method name
980 *
981 * @var string
982 */
Andrey Andreeva30faf92011-12-25 18:15:34 +0200983 public $method_name;
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200984
985 /**
986 * Parameter list
987 *
988 * @var array
989 */
Andrey Andreevc8709832012-04-04 13:43:53 +0300990 public $params = array();
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200991
992 /**
993 * XH?
994 *
995 * @var array
996 */
Andrey Andreevc8709832012-04-04 13:43:53 +0300997 public $xh = array();
Derek Allard2067d1a2008-11-13 22:59:24 +0000998
Andrey Andreevf5ccd122012-11-02 00:17:39 +0200999 // --------------------------------------------------------------------
1000
Andrey Andreevc8709832012-04-04 13:43:53 +03001001 /**
1002 * Constructor
1003 *
Andrey Andreevf5ccd122012-11-02 00:17:39 +02001004 * @param string $method
1005 * @param array $pars
Andrey Andreevc8709832012-04-04 13:43:53 +03001006 * @return void
1007 */
1008 public function __construct($method, $pars = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +00001009 {
Greg Akera9263282010-11-10 15:26:43 -06001010 parent::__construct();
Barry Mienydd671972010-10-04 16:33:58 +02001011
Derek Allard2067d1a2008-11-13 22:59:24 +00001012 $this->method_name = $method;
Derek Jones33559102009-02-02 18:50:38 +00001013 if (is_array($pars) && count($pars) > 0)
Derek Allard2067d1a2008-11-13 22:59:24 +00001014 {
Andrey Andreeva30faf92011-12-25 18:15:34 +02001015 for ($i = 0, $c = count($pars); $i < $c; $i++)
Derek Allard2067d1a2008-11-13 22:59:24 +00001016 {
1017 // $pars[$i] = XML_RPC_Values
1018 $this->params[] = $pars[$i];
1019 }
1020 }
1021 }
Barry Mienydd671972010-10-04 16:33:58 +02001022
Andrey Andreevc8709832012-04-04 13:43:53 +03001023 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +02001024
Andrey Andreevc8709832012-04-04 13:43:53 +03001025 /**
1026 * Create Payload to Send
1027 *
1028 * @return void
1029 */
Andrey Andreeva30faf92011-12-25 18:15:34 +02001030 public function createPayload()
Derek Allard2067d1a2008-11-13 22:59:24 +00001031 {
Andrey Andreevc8709832012-04-04 13:43:53 +03001032 $this->payload = '<?xml version="1.0"?'.">\r\n<methodCall>\r\n"
1033 .'<methodName>'.$this->method_name."</methodName>\r\n"
1034 ."<params>\r\n";
Barry Mienydd671972010-10-04 16:33:58 +02001035
Andrey Andreeva30faf92011-12-25 18:15:34 +02001036 for ($i = 0, $c = count($this->params); $i < $c; $i++)
Derek Allard2067d1a2008-11-13 22:59:24 +00001037 {
1038 // $p = XML_RPC_Values
1039 $p = $this->params[$i];
1040 $this->payload .= "<param>\r\n".$p->serialize_class()."</param>\r\n";
1041 }
Barry Mienydd671972010-10-04 16:33:58 +02001042
Derek Allard2067d1a2008-11-13 22:59:24 +00001043 $this->payload .= "</params>\r\n</methodCall>\r\n";
1044 }
Barry Mienydd671972010-10-04 16:33:58 +02001045
Andrey Andreevc8709832012-04-04 13:43:53 +03001046 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +02001047
Andrey Andreevc8709832012-04-04 13:43:53 +03001048 /**
1049 * Parse External XML-RPC Server's Response
1050 *
1051 * @param resource
1052 * @return object
1053 */
Andrey Andreeva30faf92011-12-25 18:15:34 +02001054 public function parseResponse($fp)
Derek Allard2067d1a2008-11-13 22:59:24 +00001055 {
1056 $data = '';
Barry Mienydd671972010-10-04 16:33:58 +02001057
Pascal Kriete14287f32011-02-14 13:39:34 -05001058 while ($datum = fread($fp, 4096))
Derek Allard2067d1a2008-11-13 22:59:24 +00001059 {
1060 $data .= $datum;
1061 }
Barry Mienydd671972010-10-04 16:33:58 +02001062
Andrey Andreevc8709832012-04-04 13:43:53 +03001063 // Display HTTP content for debugging
Derek Allard2067d1a2008-11-13 22:59:24 +00001064 if ($this->debug === TRUE)
1065 {
Andrey Andreeva30faf92011-12-25 18:15:34 +02001066 echo "<pre>---DATA---\n".htmlspecialchars($data)."\n---END DATA---\n\n</pre>";
Derek Allard2067d1a2008-11-13 22:59:24 +00001067 }
Barry Mienydd671972010-10-04 16:33:58 +02001068
Andrey Andreevc8709832012-04-04 13:43:53 +03001069 // Check for data
Andrey Andreeva30faf92011-12-25 18:15:34 +02001070 if ($data === '')
Derek Allard2067d1a2008-11-13 22:59:24 +00001071 {
1072 error_log($this->xmlrpcstr['no_data']);
Andrey Andreevc8709832012-04-04 13:43:53 +03001073 return new XML_RPC_Response(0, $this->xmlrpcerr['no_data'], $this->xmlrpcstr['no_data']);
Derek Allard2067d1a2008-11-13 22:59:24 +00001074 }
Barry Mienydd671972010-10-04 16:33:58 +02001075
Andrey Andreevc8709832012-04-04 13:43:53 +03001076 // Check for HTTP 200 Response
Andrey Andreev3dad2e72012-06-14 15:10:56 +03001077 if (strpos($data, 'HTTP') === 0 && ! preg_match('/^HTTP\/[0-9\.]+ 200 /', $data))
Derek Allard2067d1a2008-11-13 22:59:24 +00001078 {
Andrey Andreevc8709832012-04-04 13:43:53 +03001079 $errstr = substr($data, 0, strpos($data, "\n")-1);
1080 return new XML_RPC_Response(0, $this->xmlrpcerr['http_error'], $this->xmlrpcstr['http_error'].' ('.$errstr.')');
Derek Allard2067d1a2008-11-13 22:59:24 +00001081 }
Barry Mienydd671972010-10-04 16:33:58 +02001082
Derek Allard2067d1a2008-11-13 22:59:24 +00001083 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -05001084 // Create and Set Up XML Parser
Derek Allard2067d1a2008-11-13 22:59:24 +00001085 //-------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +02001086
Derek Allard2067d1a2008-11-13 22:59:24 +00001087 $parser = xml_parser_create($this->xmlrpc_defencoding);
1088
Andrey Andreeva30faf92011-12-25 18:15:34 +02001089 $this->xh[$parser] = array(
Andrey Andreevc8709832012-04-04 13:43:53 +03001090 'isf' => 0,
1091 'ac' => '',
1092 'headers' => array(),
1093 'stack' => array(),
1094 'valuestack' => array(),
1095 'isf_reason' => 0
Andrey Andreeva30faf92011-12-25 18:15:34 +02001096 );
Derek Allard2067d1a2008-11-13 22:59:24 +00001097
1098 xml_set_object($parser, $this);
Andrey Andreevc8709832012-04-04 13:43:53 +03001099 xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, TRUE);
Derek Allard2067d1a2008-11-13 22:59:24 +00001100 xml_set_element_handler($parser, 'open_tag', 'closing_tag');
1101 xml_set_character_data_handler($parser, 'character_data');
1102 //xml_set_default_handler($parser, 'default_handler');
1103
Andrey Andreevc8709832012-04-04 13:43:53 +03001104 // Get headers
Derek Allard2067d1a2008-11-13 22:59:24 +00001105 $lines = explode("\r\n", $data);
1106 while (($line = array_shift($lines)))
1107 {
1108 if (strlen($line) < 1)
1109 {
1110 break;
1111 }
1112 $this->xh[$parser]['headers'][] = $line;
1113 }
1114 $data = implode("\r\n", $lines);
Barry Mienydd671972010-10-04 16:33:58 +02001115
Andrey Andreevc8709832012-04-04 13:43:53 +03001116 // Parse XML data
Derek Jones33559102009-02-02 18:50:38 +00001117 if ( ! xml_parse($parser, $data, count($data)))
Derek Allard2067d1a2008-11-13 22:59:24 +00001118 {
1119 $errstr = sprintf('XML error: %s at line %d',
Andrey Andreevc8709832012-04-04 13:43:53 +03001120 xml_error_string(xml_get_error_code($parser)),
1121 xml_get_current_line_number($parser));
Derek Allard2067d1a2008-11-13 22:59:24 +00001122 //error_log($errstr);
1123 $r = new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'], $this->xmlrpcstr['invalid_return']);
1124 xml_parser_free($parser);
1125 return $r;
1126 }
1127 xml_parser_free($parser);
Barry Mienydd671972010-10-04 16:33:58 +02001128
Andrey Andreevc8709832012-04-04 13:43:53 +03001129 // Got ourselves some badness, it seems
Derek Allard2067d1a2008-11-13 22:59:24 +00001130 if ($this->xh[$parser]['isf'] > 1)
1131 {
1132 if ($this->debug === TRUE)
1133 {
Andrey Andreeva30faf92011-12-25 18:15:34 +02001134 echo "---Invalid Return---\n".$this->xh[$parser]['isf_reason']."---Invalid Return---\n\n";
Derek Allard2067d1a2008-11-13 22:59:24 +00001135 }
Barry Mienydd671972010-10-04 16:33:58 +02001136
Andrey Andreevc8709832012-04-04 13:43:53 +03001137 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 +00001138 }
1139 elseif ( ! is_object($this->xh[$parser]['value']))
1140 {
Andrey Andreevc8709832012-04-04 13:43:53 +03001141 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 +00001142 }
Barry Mienydd671972010-10-04 16:33:58 +02001143
Andrey Andreevc8709832012-04-04 13:43:53 +03001144 // Display XML content for debugging
Derek Allard2067d1a2008-11-13 22:59:24 +00001145 if ($this->debug === TRUE)
1146 {
Andrey Andreev8f50b6b2012-03-28 14:12:09 +03001147 echo '<pre>';
Barry Mienydd671972010-10-04 16:33:58 +02001148
Derek Allard2067d1a2008-11-13 22:59:24 +00001149 if (count($this->xh[$parser]['headers'] > 0))
1150 {
1151 echo "---HEADERS---\n";
1152 foreach ($this->xh[$parser]['headers'] as $header)
1153 {
Andrey Andreev8f50b6b2012-03-28 14:12:09 +03001154 echo $header."\n";
Derek Allard2067d1a2008-11-13 22:59:24 +00001155 }
1156 echo "---END HEADERS---\n\n";
1157 }
Barry Mienydd671972010-10-04 16:33:58 +02001158
Andrey Andreeva30faf92011-12-25 18:15:34 +02001159 echo "---DATA---\n".htmlspecialchars($data)."\n---END DATA---\n\n---PARSED---\n";
Derek Allard2067d1a2008-11-13 22:59:24 +00001160 var_dump($this->xh[$parser]['value']);
1161 echo "\n---END PARSED---</pre>";
1162 }
Barry Mienydd671972010-10-04 16:33:58 +02001163
Andrey Andreevc8709832012-04-04 13:43:53 +03001164 // Send response
Derek Allard2067d1a2008-11-13 22:59:24 +00001165 $v = $this->xh[$parser]['value'];
Derek Allard2067d1a2008-11-13 22:59:24 +00001166 if ($this->xh[$parser]['isf'])
1167 {
1168 $errno_v = $v->me['struct']['faultCode'];
1169 $errstr_v = $v->me['struct']['faultString'];
1170 $errno = $errno_v->scalarval();
1171
Alex Bilbied261b1e2012-06-02 11:12:16 +01001172 if ($errno === 0)
Derek Allard2067d1a2008-11-13 22:59:24 +00001173 {
1174 // FAULT returned, errno needs to reflect that
1175 $errno = -1;
1176 }
1177
1178 $r = new XML_RPC_Response($v, $errno, $errstr_v->scalarval());
1179 }
1180 else
1181 {
1182 $r = new XML_RPC_Response($v);
1183 }
1184
1185 $r->headers = $this->xh[$parser]['headers'];
1186 return $r;
1187 }
Barry Mienydd671972010-10-04 16:33:58 +02001188
Andrey Andreevc8709832012-04-04 13:43:53 +03001189 // --------------------------------------------------------------------
1190
Derek Allard2067d1a2008-11-13 22:59:24 +00001191 // ------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -05001192 // Begin Return Message Parsing section
Derek Allard2067d1a2008-11-13 22:59:24 +00001193 // ------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +02001194
Derek Allard2067d1a2008-11-13 22:59:24 +00001195 // quick explanation of components:
Derek Jones37f4b9c2011-07-01 17:56:50 -05001196 // ac - used to accumulate values
1197 // isf - used to indicate a fault
1198 // lv - used to indicate "looking for a value": implements
Derek Allard2067d1a2008-11-13 22:59:24 +00001199 // the logic to allow values with no types to be strings
Derek Jones37f4b9c2011-07-01 17:56:50 -05001200 // params - used to store parameters in method calls
1201 // method - used to store method name
Derek Allard2067d1a2008-11-13 22:59:24 +00001202 // stack - array with parent tree of the xml element,
1203 // used to validate the nesting of elements
1204
Andrey Andreevc8709832012-04-04 13:43:53 +03001205 // --------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +00001206
Andrey Andreevc8709832012-04-04 13:43:53 +03001207 /**
1208 * Start Element Handler
1209 *
1210 * @param string
1211 * @param string
1212 * @return void
1213 */
1214 public function open_tag($the_parser, $name)
Derek Allard2067d1a2008-11-13 22:59:24 +00001215 {
1216 // If invalid nesting, then return
1217 if ($this->xh[$the_parser]['isf'] > 1) return;
Barry Mienydd671972010-10-04 16:33:58 +02001218
Derek Allard2067d1a2008-11-13 22:59:24 +00001219 // Evaluate and check for correct nesting of XML elements
Alex Bilbied261b1e2012-06-02 11:12:16 +01001220 if (count($this->xh[$the_parser]['stack']) === 0)
Derek Allard2067d1a2008-11-13 22:59:24 +00001221 {
Alex Bilbied261b1e2012-06-02 11:12:16 +01001222 if ($name !== 'METHODRESPONSE' && $name !== 'METHODCALL')
Derek Allard2067d1a2008-11-13 22:59:24 +00001223 {
1224 $this->xh[$the_parser]['isf'] = 2;
1225 $this->xh[$the_parser]['isf_reason'] = 'Top level XML-RPC element is missing';
1226 return;
1227 }
1228 }
Andrey Andreevc8709832012-04-04 13:43:53 +03001229 // not top level element: see if parent is OK
1230 elseif ( ! in_array($this->xh[$the_parser]['stack'][0], $this->valid_parents[$name], TRUE))
Derek Allard2067d1a2008-11-13 22:59:24 +00001231 {
Andrey Andreevc8709832012-04-04 13:43:53 +03001232 $this->xh[$the_parser]['isf'] = 2;
1233 $this->xh[$the_parser]['isf_reason'] = 'XML-RPC element $name cannot be child of '.$this->xh[$the_parser]['stack'][0];
1234 return;
Derek Allard2067d1a2008-11-13 22:59:24 +00001235 }
Barry Mienydd671972010-10-04 16:33:58 +02001236
Andrey Andreevc8709832012-04-04 13:43:53 +03001237 switch ($name)
Derek Allard2067d1a2008-11-13 22:59:24 +00001238 {
1239 case 'STRUCT':
1240 case 'ARRAY':
1241 // Creates array for child elements
Andrey Andreev8f50b6b2012-03-28 14:12:09 +03001242 $cur_val = array('value' => array(), 'type' => $name);
Derek Allard2067d1a2008-11-13 22:59:24 +00001243 array_unshift($this->xh[$the_parser]['valuestack'], $cur_val);
Andrey Andreevc8709832012-04-04 13:43:53 +03001244 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001245 case 'METHODNAME':
1246 case 'NAME':
1247 $this->xh[$the_parser]['ac'] = '';
Andrey Andreevc8709832012-04-04 13:43:53 +03001248 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001249 case 'FAULT':
1250 $this->xh[$the_parser]['isf'] = 1;
Andrey Andreevc8709832012-04-04 13:43:53 +03001251 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001252 case 'PARAM':
Pascal Kriete8761ef52011-02-14 13:13:52 -05001253 $this->xh[$the_parser]['value'] = NULL;
Andrey Andreevc8709832012-04-04 13:43:53 +03001254 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001255 case 'VALUE':
1256 $this->xh[$the_parser]['vt'] = 'value';
1257 $this->xh[$the_parser]['ac'] = '';
1258 $this->xh[$the_parser]['lv'] = 1;
Andrey Andreevc8709832012-04-04 13:43:53 +03001259 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001260 case 'I4':
1261 case 'INT':
1262 case 'STRING':
1263 case 'BOOLEAN':
1264 case 'DOUBLE':
1265 case 'DATETIME.ISO8601':
1266 case 'BASE64':
Alex Bilbied261b1e2012-06-02 11:12:16 +01001267 if ($this->xh[$the_parser]['vt'] !== 'value')
Derek Allard2067d1a2008-11-13 22:59:24 +00001268 {
1269 //two data elements inside a value: an error occurred!
1270 $this->xh[$the_parser]['isf'] = 2;
Andrey Andreevc8709832012-04-04 13:43:53 +03001271 $this->xh[$the_parser]['isf_reason'] = "'Twas a ".$name.' element following a '
1272 .$this->xh[$the_parser]['vt'].' element inside a single value';
Derek Allard2067d1a2008-11-13 22:59:24 +00001273 return;
1274 }
Barry Mienydd671972010-10-04 16:33:58 +02001275
Derek Allard2067d1a2008-11-13 22:59:24 +00001276 $this->xh[$the_parser]['ac'] = '';
Andrey Andreevc8709832012-04-04 13:43:53 +03001277 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001278 case 'MEMBER':
1279 // Set name of <member> to nothing to prevent errors later if no <name> is found
1280 $this->xh[$the_parser]['valuestack'][0]['name'] = '';
Barry Mienydd671972010-10-04 16:33:58 +02001281
Derek Allard2067d1a2008-11-13 22:59:24 +00001282 // Set NULL value to check to see if value passed for this param/member
Pascal Kriete8761ef52011-02-14 13:13:52 -05001283 $this->xh[$the_parser]['value'] = NULL;
Andrey Andreevc8709832012-04-04 13:43:53 +03001284 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001285 case 'DATA':
1286 case 'METHODCALL':
1287 case 'METHODRESPONSE':
1288 case 'PARAMS':
1289 // valid elements that add little to processing
Andrey Andreevc8709832012-04-04 13:43:53 +03001290 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001291 default:
1292 /// An Invalid Element is Found, so we have trouble
1293 $this->xh[$the_parser]['isf'] = 2;
Andrey Andreevc8709832012-04-04 13:43:53 +03001294 $this->xh[$the_parser]['isf_reason'] = 'Invalid XML-RPC element found: '.$name;
1295 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001296 }
Barry Mienydd671972010-10-04 16:33:58 +02001297
Derek Allard2067d1a2008-11-13 22:59:24 +00001298 // Add current element name to stack, to allow validation of nesting
1299 array_unshift($this->xh[$the_parser]['stack'], $name);
1300
Alex Bilbied261b1e2012-06-02 11:12:16 +01001301 $name === 'VALUE' OR $this->xh[$the_parser]['lv'] = 0;
Derek Allard2067d1a2008-11-13 22:59:24 +00001302 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001303
Andrey Andreevc8709832012-04-04 13:43:53 +03001304 // --------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +00001305
Andrey Andreevc8709832012-04-04 13:43:53 +03001306 /**
1307 * End Element Handler
1308 *
1309 * @param string
1310 * @param string
1311 * @return void
1312 */
Andrey Andreeva30faf92011-12-25 18:15:34 +02001313 public function closing_tag($the_parser, $name)
Derek Allard2067d1a2008-11-13 22:59:24 +00001314 {
1315 if ($this->xh[$the_parser]['isf'] > 1) return;
Barry Mienydd671972010-10-04 16:33:58 +02001316
Derek Allard2067d1a2008-11-13 22:59:24 +00001317 // Remove current element from stack and set variable
1318 // NOTE: If the XML validates, then we do not have to worry about
Andrey Andreevc8709832012-04-04 13:43:53 +03001319 // the opening and closing of elements. Nesting is checked on the opening
Derek Allard2067d1a2008-11-13 22:59:24 +00001320 // tag so we be safe there as well.
Barry Mienydd671972010-10-04 16:33:58 +02001321
Derek Allard2067d1a2008-11-13 22:59:24 +00001322 $curr_elem = array_shift($this->xh[$the_parser]['stack']);
Barry Mienydd671972010-10-04 16:33:58 +02001323
Andrey Andreevc8709832012-04-04 13:43:53 +03001324 switch ($name)
Derek Allard2067d1a2008-11-13 22:59:24 +00001325 {
1326 case 'STRUCT':
1327 case 'ARRAY':
1328 $cur_val = array_shift($this->xh[$the_parser]['valuestack']);
Andrey Andreevc8709832012-04-04 13:43:53 +03001329 $this->xh[$the_parser]['value'] = isset($cur_val['values']) ? $cur_val['values'] : array();
Derek Allard2067d1a2008-11-13 22:59:24 +00001330 $this->xh[$the_parser]['vt'] = strtolower($name);
Andrey Andreevc8709832012-04-04 13:43:53 +03001331 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001332 case 'NAME':
1333 $this->xh[$the_parser]['valuestack'][0]['name'] = $this->xh[$the_parser]['ac'];
Andrey Andreevc8709832012-04-04 13:43:53 +03001334 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001335 case 'BOOLEAN':
1336 case 'I4':
1337 case 'INT':
1338 case 'STRING':
1339 case 'DOUBLE':
1340 case 'DATETIME.ISO8601':
1341 case 'BASE64':
1342 $this->xh[$the_parser]['vt'] = strtolower($name);
Barry Mienydd671972010-10-04 16:33:58 +02001343
Alex Bilbied261b1e2012-06-02 11:12:16 +01001344 if ($name === 'STRING')
Derek Allard2067d1a2008-11-13 22:59:24 +00001345 {
1346 $this->xh[$the_parser]['value'] = $this->xh[$the_parser]['ac'];
1347 }
Alex Bilbied261b1e2012-06-02 11:12:16 +01001348 elseif ($name === 'DATETIME.ISO8601')
Derek Allard2067d1a2008-11-13 22:59:24 +00001349 {
1350 $this->xh[$the_parser]['vt'] = $this->xmlrpcDateTime;
1351 $this->xh[$the_parser]['value'] = $this->xh[$the_parser]['ac'];
1352 }
Alex Bilbied261b1e2012-06-02 11:12:16 +01001353 elseif ($name === 'BASE64')
Derek Allard2067d1a2008-11-13 22:59:24 +00001354 {
1355 $this->xh[$the_parser]['value'] = base64_decode($this->xh[$the_parser]['ac']);
1356 }
Alex Bilbied261b1e2012-06-02 11:12:16 +01001357 elseif ($name === 'BOOLEAN')
Derek Allard2067d1a2008-11-13 22:59:24 +00001358 {
1359 // Translated BOOLEAN values to TRUE AND FALSE
Andrey Andreevc8709832012-04-04 13:43:53 +03001360 $this->xh[$the_parser]['value'] = (bool) $this->xh[$the_parser]['ac'];
Derek Allard2067d1a2008-11-13 22:59:24 +00001361 }
1362 elseif ($name=='DOUBLE')
1363 {
1364 // we have a DOUBLE
1365 // we must check that only 0123456789-.<space> are characters here
Andrey Andreevc8709832012-04-04 13:43:53 +03001366 $this->xh[$the_parser]['value'] = preg_match('/^[+-]?[eE0-9\t \.]+$/', $this->xh[$the_parser]['ac'])
1367 ? (float) $this->xh[$the_parser]['ac']
1368 : 'ERROR_NON_NUMERIC_FOUND';
Derek Allard2067d1a2008-11-13 22:59:24 +00001369 }
1370 else
1371 {
1372 // we have an I4/INT
1373 // we must check that only 0123456789-<space> are characters here
Andrey Andreevc8709832012-04-04 13:43:53 +03001374 $this->xh[$the_parser]['value'] = preg_match('/^[+-]?[0-9\t ]+$/', $this->xh[$the_parser]['ac'])
George Petsagourakis306b3782012-05-02 20:31:08 +03001375 ? (int) $this->xh[$the_parser]['ac']
Andrey Andreevc8709832012-04-04 13:43:53 +03001376 : 'ERROR_NON_NUMERIC_FOUND';
Derek Allard2067d1a2008-11-13 22:59:24 +00001377 }
1378 $this->xh[$the_parser]['ac'] = '';
1379 $this->xh[$the_parser]['lv'] = 3; // indicate we've found a value
Andrey Andreevc8709832012-04-04 13:43:53 +03001380 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001381 case 'VALUE':
1382 // This if() detects if no scalar was inside <VALUE></VALUE>
1383 if ($this->xh[$the_parser]['vt']=='value')
1384 {
1385 $this->xh[$the_parser]['value'] = $this->xh[$the_parser]['ac'];
1386 $this->xh[$the_parser]['vt'] = $this->xmlrpcString;
1387 }
Barry Mienydd671972010-10-04 16:33:58 +02001388
Derek Allard2067d1a2008-11-13 22:59:24 +00001389 // build the XML-RPC value out of the data received, and substitute it
1390 $temp = new XML_RPC_Values($this->xh[$the_parser]['value'], $this->xh[$the_parser]['vt']);
Barry Mienydd671972010-10-04 16:33:58 +02001391
Alex Bilbied261b1e2012-06-02 11:12:16 +01001392 if (count($this->xh[$the_parser]['valuestack']) && $this->xh[$the_parser]['valuestack'][0]['type'] === 'ARRAY')
Derek Allard2067d1a2008-11-13 22:59:24 +00001393 {
1394 // Array
1395 $this->xh[$the_parser]['valuestack'][0]['values'][] = $temp;
1396 }
1397 else
1398 {
1399 // Struct
1400 $this->xh[$the_parser]['value'] = $temp;
1401 }
Andrey Andreevc8709832012-04-04 13:43:53 +03001402 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001403 case 'MEMBER':
Andrey Andreevc8709832012-04-04 13:43:53 +03001404 $this->xh[$the_parser]['ac'] = '';
Barry Mienydd671972010-10-04 16:33:58 +02001405
Derek Allard2067d1a2008-11-13 22:59:24 +00001406 // If value add to array in the stack for the last element built
1407 if ($this->xh[$the_parser]['value'])
1408 {
1409 $this->xh[$the_parser]['valuestack'][0]['values'][$this->xh[$the_parser]['valuestack'][0]['name']] = $this->xh[$the_parser]['value'];
1410 }
Andrey Andreevc8709832012-04-04 13:43:53 +03001411 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001412 case 'DATA':
Andrey Andreevc8709832012-04-04 13:43:53 +03001413 $this->xh[$the_parser]['ac'] = '';
1414 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001415 case 'PARAM':
1416 if ($this->xh[$the_parser]['value'])
1417 {
1418 $this->xh[$the_parser]['params'][] = $this->xh[$the_parser]['value'];
1419 }
Andrey Andreevc8709832012-04-04 13:43:53 +03001420 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001421 case 'METHODNAME':
1422 $this->xh[$the_parser]['method'] = ltrim($this->xh[$the_parser]['ac']);
Andrey Andreevc8709832012-04-04 13:43:53 +03001423 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001424 case 'PARAMS':
1425 case 'FAULT':
1426 case 'METHODCALL':
1427 case 'METHORESPONSE':
1428 // We're all good kids with nuthin' to do
Andrey Andreevc8709832012-04-04 13:43:53 +03001429 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001430 default:
Andrey Andreevc8709832012-04-04 13:43:53 +03001431 // End of an Invalid Element. Taken care of during the opening tag though
1432 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001433 }
1434 }
1435
Andrey Andreevc8709832012-04-04 13:43:53 +03001436 // --------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +00001437
Andrey Andreevc8709832012-04-04 13:43:53 +03001438 /**
1439 * Parse character data
1440 *
1441 * @param string
1442 * @param string
1443 * @return void
1444 */
Andrey Andreeva30faf92011-12-25 18:15:34 +02001445 public function character_data($the_parser, $data)
Derek Allard2067d1a2008-11-13 22:59:24 +00001446 {
1447 if ($this->xh[$the_parser]['isf'] > 1) return; // XML Fault found already
Barry Mienydd671972010-10-04 16:33:58 +02001448
Derek Allard2067d1a2008-11-13 22:59:24 +00001449 // If a value has not been found
Alex Bilbied261b1e2012-06-02 11:12:16 +01001450 if ($this->xh[$the_parser]['lv'] !== 3)
Derek Allard2067d1a2008-11-13 22:59:24 +00001451 {
Alex Bilbied261b1e2012-06-02 11:12:16 +01001452 if ($this->xh[$the_parser]['lv'] === 1)
Derek Allard2067d1a2008-11-13 22:59:24 +00001453 {
1454 $this->xh[$the_parser]['lv'] = 2; // Found a value
1455 }
Barry Mienydd671972010-10-04 16:33:58 +02001456
Andrey Andreevc8709832012-04-04 13:43:53 +03001457 if ( ! isset($this->xh[$the_parser]['ac']))
Derek Allard2067d1a2008-11-13 22:59:24 +00001458 {
1459 $this->xh[$the_parser]['ac'] = '';
1460 }
Barry Mienydd671972010-10-04 16:33:58 +02001461
Derek Allard2067d1a2008-11-13 22:59:24 +00001462 $this->xh[$the_parser]['ac'] .= $data;
1463 }
1464 }
Barry Mienydd671972010-10-04 16:33:58 +02001465
Andrey Andreevc8709832012-04-04 13:43:53 +03001466 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +02001467
Andrey Andreevc8709832012-04-04 13:43:53 +03001468 /**
1469 * Add parameter
1470 *
1471 * @param mixed
1472 * @return void
1473 */
Andrey Andreeva30faf92011-12-25 18:15:34 +02001474 public function addParam($par)
1475 {
1476 $this->params[] = $par;
1477 }
Barry Mienydd671972010-10-04 16:33:58 +02001478
Andrey Andreevc8709832012-04-04 13:43:53 +03001479 // --------------------------------------------------------------------
1480
1481 /**
1482 * Output parameters
1483 *
1484 * @param array
1485 * @return array
1486 */
Andrey Andreeva30faf92011-12-25 18:15:34 +02001487 public function output_parameters($array = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +00001488 {
Barry Mienydd671972010-10-04 16:33:58 +02001489 $CI =& get_instance();
Andrey Andreeva30faf92011-12-25 18:15:34 +02001490
1491 if (is_array($array))
Derek Allard2067d1a2008-11-13 22:59:24 +00001492 {
1493 while (list($key) = each($array))
1494 {
1495 if (is_array($array[$key]))
1496 {
1497 $array[$key] = $this->output_parameters($array[$key]);
1498 }
1499 else
1500 {
Derek Jonesa9647e82010-03-02 22:59:07 -06001501 // 'bits' is for the MetaWeblog API image bits
1502 // @todo - this needs to be made more general purpose
Alex Bilbied261b1e2012-06-02 11:12:16 +01001503 $array[$key] = ($key === 'bits' OR $this->xss_clean === FALSE) ? $array[$key] : $CI->security->xss_clean($array[$key]);
Derek Allard2067d1a2008-11-13 22:59:24 +00001504 }
1505 }
Barry Mienydd671972010-10-04 16:33:58 +02001506
Andrey Andreevc8709832012-04-04 13:43:53 +03001507 return $array;
Derek Allard2067d1a2008-11-13 22:59:24 +00001508 }
Andrey Andreevc8709832012-04-04 13:43:53 +03001509
1510 $parameters = array();
1511
1512 for ($i = 0, $c = count($this->params); $i < $c; $i++)
Derek Allard2067d1a2008-11-13 22:59:24 +00001513 {
Andrey Andreevc8709832012-04-04 13:43:53 +03001514 $a_param = $this->decode_message($this->params[$i]);
Barry Mienydd671972010-10-04 16:33:58 +02001515
Andrey Andreevc8709832012-04-04 13:43:53 +03001516 if (is_array($a_param))
Derek Allard2067d1a2008-11-13 22:59:24 +00001517 {
Andrey Andreevc8709832012-04-04 13:43:53 +03001518 $parameters[] = $this->output_parameters($a_param);
1519 }
1520 else
1521 {
1522 $parameters[] = ($this->xss_clean) ? $CI->security->xss_clean($a_param) : $a_param;
Barry Mienydd671972010-10-04 16:33:58 +02001523 }
Derek Allard2067d1a2008-11-13 22:59:24 +00001524 }
Barry Mienydd671972010-10-04 16:33:58 +02001525
Derek Allard2067d1a2008-11-13 22:59:24 +00001526 return $parameters;
1527 }
Barry Mienydd671972010-10-04 16:33:58 +02001528
Andrey Andreevc8709832012-04-04 13:43:53 +03001529 // --------------------------------------------------------------------
1530
1531 /**
1532 * Decode message
1533 *
1534 * @param object
1535 * @return mixed
1536 */
Andrey Andreeva30faf92011-12-25 18:15:34 +02001537 public function decode_message($param)
Derek Allard2067d1a2008-11-13 22:59:24 +00001538 {
1539 $kind = $param->kindOf();
1540
Alex Bilbied261b1e2012-06-02 11:12:16 +01001541 if ($kind === 'scalar')
Derek Allard2067d1a2008-11-13 22:59:24 +00001542 {
1543 return $param->scalarval();
1544 }
Alex Bilbied261b1e2012-06-02 11:12:16 +01001545 elseif ($kind === 'array')
Derek Allard2067d1a2008-11-13 22:59:24 +00001546 {
1547 reset($param->me);
Andrey Andreevadc11752011-12-30 14:46:08 +02001548 $b = current($param->me);
Derek Allard2067d1a2008-11-13 22:59:24 +00001549 $arr = array();
1550
Andrey Andreevc8709832012-04-04 13:43:53 +03001551 for ($i = 0, $c = count($b); $i < $c; $i++)
Derek Allard2067d1a2008-11-13 22:59:24 +00001552 {
1553 $arr[] = $this->decode_message($param->me['array'][$i]);
1554 }
Barry Mienydd671972010-10-04 16:33:58 +02001555
Derek Allard2067d1a2008-11-13 22:59:24 +00001556 return $arr;
1557 }
Alex Bilbied261b1e2012-06-02 11:12:16 +01001558 elseif ($kind === 'struct')
Derek Allard2067d1a2008-11-13 22:59:24 +00001559 {
1560 reset($param->me['struct']);
Derek Allard2067d1a2008-11-13 22:59:24 +00001561 $arr = array();
1562
Pascal Kriete14287f32011-02-14 13:39:34 -05001563 while (list($key,$value) = each($param->me['struct']))
Derek Allard2067d1a2008-11-13 22:59:24 +00001564 {
1565 $arr[$key] = $this->decode_message($value);
1566 }
Barry Mienydd671972010-10-04 16:33:58 +02001567
Derek Allard2067d1a2008-11-13 22:59:24 +00001568 return $arr;
1569 }
1570 }
Barry Mienydd671972010-10-04 16:33:58 +02001571
Andrey Andreevc8709832012-04-04 13:43:53 +03001572} // END XML_RPC_Message Class
Derek Allard2067d1a2008-11-13 22:59:24 +00001573
1574/**
1575 * XML-RPC Values class
1576 *
1577 * @category XML-RPC
Derek Jonesf4a4bd82011-10-20 12:18:42 -05001578 * @author EllisLab Dev Team
Derek Allard2067d1a2008-11-13 22:59:24 +00001579 * @link http://codeigniter.com/user_guide/libraries/xmlrpc.html
1580 */
1581class XML_RPC_Values extends CI_Xmlrpc
1582{
Andrey Andreevf5ccd122012-11-02 00:17:39 +02001583 /**
1584 * Value data
1585 *
1586 * @var array
1587 */
Andrey Andreeva30faf92011-12-25 18:15:34 +02001588 public $me = array();
Andrey Andreevf5ccd122012-11-02 00:17:39 +02001589
1590 /**
1591 * Value type
1592 *
1593 * @var int
1594 */
Andrey Andreeva30faf92011-12-25 18:15:34 +02001595 public $mytype = 0;
Derek Allard2067d1a2008-11-13 22:59:24 +00001596
Andrey Andreevf5ccd122012-11-02 00:17:39 +02001597 // --------------------------------------------------------------------
1598
Andrey Andreevc8709832012-04-04 13:43:53 +03001599 /**
1600 * Constructor
1601 *
Andrey Andreevf5ccd122012-11-02 00:17:39 +02001602 * @param mixed $val
1603 * @param string $type
Andrey Andreevc8709832012-04-04 13:43:53 +03001604 * @return void
1605 */
Andrey Andreeva30faf92011-12-25 18:15:34 +02001606 public function __construct($val = -1, $type = '')
Barry Mienydd671972010-10-04 16:33:58 +02001607 {
Greg Akera9263282010-11-10 15:26:43 -06001608 parent::__construct();
Barry Mienydd671972010-10-04 16:33:58 +02001609
Alex Bilbied261b1e2012-06-02 11:12:16 +01001610 if ($val !== -1 OR $type !== '')
Derek Allard2067d1a2008-11-13 22:59:24 +00001611 {
Alex Bilbied261b1e2012-06-02 11:12:16 +01001612 $type = $type === '' ? 'string' : $type;
Barry Mienydd671972010-10-04 16:33:58 +02001613
Dimitar740480a2012-10-05 13:24:59 +03001614 if ($this->xmlrpcTypes[$type] == 1)
Derek Allard2067d1a2008-11-13 22:59:24 +00001615 {
1616 $this->addScalar($val,$type);
1617 }
Dimitar740480a2012-10-05 13:24:59 +03001618 elseif ($this->xmlrpcTypes[$type] == 2)
Derek Allard2067d1a2008-11-13 22:59:24 +00001619 {
1620 $this->addArray($val);
1621 }
Dimitar740480a2012-10-05 13:24:59 +03001622 elseif ($this->xmlrpcTypes[$type] == 3)
Derek Allard2067d1a2008-11-13 22:59:24 +00001623 {
1624 $this->addStruct($val);
1625 }
1626 }
1627 }
1628
Andrey Andreevc8709832012-04-04 13:43:53 +03001629 // --------------------------------------------------------------------
1630
1631 /**
1632 * Add scalar value
1633 *
1634 * @param scalar
1635 * @param string
1636 * @return int
1637 */
Andrey Andreeva30faf92011-12-25 18:15:34 +02001638 public function addScalar($val, $type = 'string')
Derek Allard2067d1a2008-11-13 22:59:24 +00001639 {
1640 $typeof = $this->xmlrpcTypes[$type];
Barry Mienydd671972010-10-04 16:33:58 +02001641
Alex Bilbied261b1e2012-06-02 11:12:16 +01001642 if ($this->mytype === 1)
Derek Allard2067d1a2008-11-13 22:59:24 +00001643 {
1644 echo '<strong>XML_RPC_Values</strong>: scalar can have only one value<br />';
1645 return 0;
1646 }
Barry Mienydd671972010-10-04 16:33:58 +02001647
Dimitar740480a2012-10-05 13:24:59 +03001648 if ($typeof != 1)
Derek Allard2067d1a2008-11-13 22:59:24 +00001649 {
1650 echo '<strong>XML_RPC_Values</strong>: not a scalar type (${typeof})<br />';
1651 return 0;
1652 }
1653
Alex Bilbied261b1e2012-06-02 11:12:16 +01001654 if ($type === $this->xmlrpcBoolean)
Derek Allard2067d1a2008-11-13 22:59:24 +00001655 {
Andrey Andreev3f3f1352012-09-05 16:39:28 +03001656 $val = (int) (strcasecmp($val, 'true') === 0 OR $val === 1 OR ($val === TRUE && strcasecmp($val, 'false')));
Derek Allard2067d1a2008-11-13 22:59:24 +00001657 }
1658
Alex Bilbied261b1e2012-06-02 11:12:16 +01001659 if ($this->mytype === 2)
Derek Allard2067d1a2008-11-13 22:59:24 +00001660 {
1661 // adding to an array here
1662 $ar = $this->me['array'];
1663 $ar[] = new XML_RPC_Values($val, $type);
1664 $this->me['array'] = $ar;
1665 }
1666 else
1667 {
1668 // a scalar, so set the value and remember we're scalar
1669 $this->me[$type] = $val;
1670 $this->mytype = $typeof;
1671 }
Andrey Andreevc8709832012-04-04 13:43:53 +03001672
Derek Allard2067d1a2008-11-13 22:59:24 +00001673 return 1;
1674 }
1675
Andrey Andreevc8709832012-04-04 13:43:53 +03001676 // --------------------------------------------------------------------
1677
1678 /**
1679 * Add array value
1680 *
1681 * @param array
1682 * @return int
1683 */
Andrey Andreeva30faf92011-12-25 18:15:34 +02001684 public function addArray($vals)
Derek Allard2067d1a2008-11-13 22:59:24 +00001685 {
Alex Bilbied261b1e2012-06-02 11:12:16 +01001686 if ($this->mytype !== 0)
Derek Allard2067d1a2008-11-13 22:59:24 +00001687 {
1688 echo '<strong>XML_RPC_Values</strong>: already initialized as a [' . $this->kindOf() . ']<br />';
1689 return 0;
1690 }
1691
1692 $this->mytype = $this->xmlrpcTypes['array'];
1693 $this->me['array'] = $vals;
1694 return 1;
1695 }
1696
Andrey Andreevc8709832012-04-04 13:43:53 +03001697 // --------------------------------------------------------------------
1698
1699 /**
1700 * Add struct value
1701 *
1702 * @param object
1703 * @return int
1704 */
Andrey Andreeva30faf92011-12-25 18:15:34 +02001705 public function addStruct($vals)
Derek Allard2067d1a2008-11-13 22:59:24 +00001706 {
Alex Bilbied261b1e2012-06-02 11:12:16 +01001707 if ($this->mytype !== 0)
Derek Allard2067d1a2008-11-13 22:59:24 +00001708 {
1709 echo '<strong>XML_RPC_Values</strong>: already initialized as a [' . $this->kindOf() . ']<br />';
1710 return 0;
1711 }
1712 $this->mytype = $this->xmlrpcTypes['struct'];
1713 $this->me['struct'] = $vals;
1714 return 1;
1715 }
1716
Andrey Andreevc8709832012-04-04 13:43:53 +03001717 // --------------------------------------------------------------------
1718
1719 /**
1720 * Get value type
1721 *
1722 * @return string
1723 */
Andrey Andreeva30faf92011-12-25 18:15:34 +02001724 public function kindOf()
Derek Allard2067d1a2008-11-13 22:59:24 +00001725 {
Andrey Andreevc8709832012-04-04 13:43:53 +03001726 switch ($this->mytype)
Derek Allard2067d1a2008-11-13 22:59:24 +00001727 {
Andrey Andreevc8709832012-04-04 13:43:53 +03001728 case 3: return 'struct';
1729 case 2: return 'array';
1730 case 1: return 'scalar';
1731 default: return 'undef';
Derek Allard2067d1a2008-11-13 22:59:24 +00001732 }
1733 }
1734
Andrey Andreevc8709832012-04-04 13:43:53 +03001735 // --------------------------------------------------------------------
1736
1737 /**
1738 * Serialize data
1739 *
1740 * @param string
1741 * @param mixed
1742 */
Andrey Andreeva30faf92011-12-25 18:15:34 +02001743 public function serializedata($typ, $val)
Derek Allard2067d1a2008-11-13 22:59:24 +00001744 {
1745 $rs = '';
Derek Jonesa9647e82010-03-02 22:59:07 -06001746
Andrey Andreevc8709832012-04-04 13:43:53 +03001747 switch ($this->xmlrpcTypes[$typ])
Derek Allard2067d1a2008-11-13 22:59:24 +00001748 {
1749 case 3:
1750 // struct
1751 $rs .= "<struct>\n";
1752 reset($val);
Pascal Kriete14287f32011-02-14 13:39:34 -05001753 while (list($key2, $val2) = each($val))
Derek Allard2067d1a2008-11-13 22:59:24 +00001754 {
Andrey Andreeva30faf92011-12-25 18:15:34 +02001755 $rs .= "<member>\n<name>{$key2}</name>\n".$this->serializeval($val2)."</member>\n";
Derek Allard2067d1a2008-11-13 22:59:24 +00001756 }
1757 $rs .= '</struct>';
Andrey Andreevc8709832012-04-04 13:43:53 +03001758 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001759 case 2:
1760 // array
1761 $rs .= "<array>\n<data>\n";
Andrey Andreevc8709832012-04-04 13:43:53 +03001762 for ($i = 0, $c = count($val); $i < $c; $i++)
Derek Allard2067d1a2008-11-13 22:59:24 +00001763 {
1764 $rs .= $this->serializeval($val[$i]);
1765 }
Andrey Andreeva30faf92011-12-25 18:15:34 +02001766 $rs .= "</data>\n</array>\n";
Derek Allard2067d1a2008-11-13 22:59:24 +00001767 break;
1768 case 1:
1769 // others
1770 switch ($typ)
1771 {
1772 case $this->xmlrpcBase64:
Andrey Andreevc8709832012-04-04 13:43:53 +03001773 $rs .= '<'.$typ.'>'.base64_encode( (string) $val).'</'.$typ.">\n";
1774 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001775 case $this->xmlrpcBoolean:
Andrey Andreevc8709832012-04-04 13:43:53 +03001776 $rs .= '<'.$typ.'>'.( (bool) $val ? '1' : '0').'</'.$typ.">\n";
1777 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001778 case $this->xmlrpcString:
Andrey Andreevc8709832012-04-04 13:43:53 +03001779 $rs .= '<'.$typ.'>'.htmlspecialchars( (string) $val).'</'.$typ.">\n";
1780 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001781 default:
Andrey Andreevc8709832012-04-04 13:43:53 +03001782 $rs .= '<'.$typ.'>'.$val.'</'.$typ.">\n";
1783 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001784 }
1785 default:
Andrey Andreevc8709832012-04-04 13:43:53 +03001786 break;
Derek Allard2067d1a2008-11-13 22:59:24 +00001787 }
Andrey Andreevc8709832012-04-04 13:43:53 +03001788
Derek Allard2067d1a2008-11-13 22:59:24 +00001789 return $rs;
1790 }
1791
Andrey Andreevc8709832012-04-04 13:43:53 +03001792 // --------------------------------------------------------------------
1793
1794 /**
1795 * Serialize class
1796 *
1797 * @return string
1798 */
Andrey Andreeva30faf92011-12-25 18:15:34 +02001799 public function serialize_class()
Derek Allard2067d1a2008-11-13 22:59:24 +00001800 {
1801 return $this->serializeval($this);
1802 }
1803
Andrey Andreevc8709832012-04-04 13:43:53 +03001804 // --------------------------------------------------------------------
1805
1806 /**
1807 * Serialize value
1808 *
1809 * @param object
1810 * @return string
1811 */
Andrey Andreeva30faf92011-12-25 18:15:34 +02001812 public function serializeval($o)
Derek Allard2067d1a2008-11-13 22:59:24 +00001813 {
1814 $ar = $o->me;
1815 reset($ar);
Barry Mienydd671972010-10-04 16:33:58 +02001816
Derek Allard2067d1a2008-11-13 22:59:24 +00001817 list($typ, $val) = each($ar);
Andrey Andreeva30faf92011-12-25 18:15:34 +02001818 return "<value>\n".$this->serializedata($typ, $val)."</value>\n";
Derek Allard2067d1a2008-11-13 22:59:24 +00001819 }
Barry Mienydd671972010-10-04 16:33:58 +02001820
Andrey Andreevc8709832012-04-04 13:43:53 +03001821 // --------------------------------------------------------------------
1822
1823 /**
1824 * Scalar value
1825 *
1826 * @return mixed
1827 */
Andrey Andreeva30faf92011-12-25 18:15:34 +02001828 public function scalarval()
Derek Allard2067d1a2008-11-13 22:59:24 +00001829 {
1830 reset($this->me);
Andrey Andreevadc11752011-12-30 14:46:08 +02001831 return current($this->me);
Derek Allard2067d1a2008-11-13 22:59:24 +00001832 }
1833
Andrey Andreevc8709832012-04-04 13:43:53 +03001834 // --------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +00001835
Andrey Andreevc8709832012-04-04 13:43:53 +03001836 /**
1837 * Encode time in ISO-8601 form.
1838 * Useful for sending time in XML-RPC
1839 *
1840 * @param int unix timestamp
1841 * @param bool
1842 * @return string
1843 */
1844 public function iso8601_encode($time, $utc = FALSE)
Barry Mienydd671972010-10-04 16:33:58 +02001845 {
Andrey Andreev62090152011-12-30 12:49:27 +02001846 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 +00001847 }
Barry Mienydd671972010-10-04 16:33:58 +02001848
Andrey Andreevc8709832012-04-04 13:43:53 +03001849} // END XML_RPC_Values Class
Derek Allard2067d1a2008-11-13 22:59:24 +00001850
1851/* End of file Xmlrpc.php */
Andrey Andreev8f50b6b2012-03-28 14:12:09 +03001852/* Location: ./system/libraries/Xmlrpc.php */