blob: 6d270c2ea3d2a066a60bbae99c8007f1d2334a22 [file] [log] [blame]
Andrey Andreev56e32142011-12-25 18:36:31 +02001<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
Derek Allard2067d1a2008-11-13 22:59:24 +00002/**
3 * CodeIgniter
4 *
Phil Sturgeon07c1ac82012-03-09 17:03:37 +00005 * An open source application development framework for PHP 5.2.4 or newer
Derek Allard2067d1a2008-11-13 22:59:24 +00006 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05007 * NOTICE OF LICENSE
Andrey Andreev56e32142011-12-25 18:36:31 +02008 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05009 * Licensed under the Open Software License version 3.0
Andrey Andreev56e32142011-12-25 18:36:31 +020010 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -050011 * This source file is subject to the Open Software License (OSL 3.0) that is
12 * bundled with this package in the files license.txt / license.rst. It is
13 * also available through the world wide web at this URL:
14 * http://opensource.org/licenses/OSL-3.0
15 * If you did not receive a copy of the license and are unable to obtain it
16 * through the world wide web, please send an email to
17 * licensing@ellislab.com so we can send you a copy immediately.
18 *
Derek Allard2067d1a2008-11-13 22:59:24 +000019 * @package CodeIgniter
Derek Jonesf4a4bd82011-10-20 12:18:42 -050020 * @author EllisLab Dev Team
Greg Aker0defe5d2012-01-01 18:46:41 -060021 * @copyright Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
Derek Jonesf4a4bd82011-10-20 12:18:42 -050022 * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
Derek Allard2067d1a2008-11-13 22:59:24 +000023 * @link http://codeigniter.com
24 * @since Version 1.0
25 * @filesource
26 */
27
28if ( ! function_exists('xml_parser_create'))
Barry Mienydd671972010-10-04 16:33:58 +020029{
Derek Allard2067d1a2008-11-13 22:59:24 +000030 show_error('Your PHP installation does not support XML');
31}
32
33if ( ! class_exists('CI_Xmlrpc'))
34{
35 show_error('You must load the Xmlrpc class before loading the Xmlrpcs class in order to create a server.');
36}
37
38// ------------------------------------------------------------------------
39
40/**
41 * XML-RPC server class
42 *
43 * @package CodeIgniter
44 * @subpackage Libraries
45 * @category XML-RPC
Derek Jonesf4a4bd82011-10-20 12:18:42 -050046 * @author EllisLab Dev Team
Derek Allard2067d1a2008-11-13 22:59:24 +000047 * @link http://codeigniter.com/user_guide/libraries/xmlrpc.html
48 */
49class CI_Xmlrpcs extends CI_Xmlrpc
50{
Andrey Andreev56e32142011-12-25 18:36:31 +020051 public $methods = array(); //array of methods mapped to function names and signatures
52 public $debug_msg = ''; // Debug Message
53 public $system_methods = array(); // XML RPC Server methods
54 public $controller_obj;
55 public $object = FALSE;
Derek Jonesc4c34ee2010-03-02 23:00:28 -060056
Andrey Andreev52278372012-03-26 16:02:30 +030057 public function __construct($config = array())
Barry Mienydd671972010-10-04 16:33:58 +020058 {
Greg Akera9263282010-11-10 15:26:43 -060059 parent::__construct();
Derek Allard2067d1a2008-11-13 22:59:24 +000060 $this->set_system_methods();
Barry Mienydd671972010-10-04 16:33:58 +020061
Derek Allard2067d1a2008-11-13 22:59:24 +000062 if (isset($config['functions']) && is_array($config['functions']))
63 {
64 $this->methods = array_merge($this->methods, $config['functions']);
65 }
Barry Mienydd671972010-10-04 16:33:58 +020066
Andrey Andreev52278372012-03-26 16:02:30 +030067 log_message('debug', 'XML-RPC Server Class Initialized');
Derek Allard2067d1a2008-11-13 22:59:24 +000068 }
Barry Mienydd671972010-10-04 16:33:58 +020069
Pascal Kriete68d29872011-02-14 13:39:06 -050070 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +020071
Pascal Kriete68d29872011-02-14 13:39:06 -050072 /**
73 * Initialize Prefs and Serve
74 *
Pascal Kriete68d29872011-02-14 13:39:06 -050075 * @param mixed
76 * @return void
77 */
Andrey Andreev56e32142011-12-25 18:36:31 +020078 public function initialize($config = array())
Barry Mienydd671972010-10-04 16:33:58 +020079 {
Derek Allard2067d1a2008-11-13 22:59:24 +000080 if (isset($config['functions']) && is_array($config['functions']))
81 {
82 $this->methods = array_merge($this->methods, $config['functions']);
83 }
Barry Mienydd671972010-10-04 16:33:58 +020084
Derek Allard2067d1a2008-11-13 22:59:24 +000085 if (isset($config['debug']))
86 {
87 $this->debug = $config['debug'];
88 }
Barry Mienydd671972010-10-04 16:33:58 +020089
Derek Allard2067d1a2008-11-13 22:59:24 +000090 if (isset($config['object']) && is_object($config['object']))
91 {
92 $this->object = $config['object'];
93 }
Barry Mienydd671972010-10-04 16:33:58 +020094
Robin Sowell66a3fc02010-03-18 09:44:55 -040095 if (isset($config['xss_clean']))
96 {
97 $this->xss_clean = $config['xss_clean'];
98 }
Derek Allard2067d1a2008-11-13 22:59:24 +000099 }
Barry Mienydd671972010-10-04 16:33:58 +0200100
Pascal Kriete68d29872011-02-14 13:39:06 -0500101 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200102
Pascal Kriete68d29872011-02-14 13:39:06 -0500103 /**
104 * Setting of System Methods
105 *
Pascal Kriete68d29872011-02-14 13:39:06 -0500106 * @return void
107 */
Andrey Andreev56e32142011-12-25 18:36:31 +0200108 public function set_system_methods()
Derek Allard2067d1a2008-11-13 22:59:24 +0000109 {
110 $this->methods = array(
111 'system.listMethods' => array(
Andrey Andreev56e32142011-12-25 18:36:31 +0200112 'function' => 'this.listMethods',
113 'signature' => array(array($this->xmlrpcArray, $this->xmlrpcString), array($this->xmlrpcArray)),
114 'docstring' => 'Returns an array of available methods on this server'),
115 'system.methodHelp' => array(
116 'function' => 'this.methodHelp',
117 'signature' => array(array($this->xmlrpcString, $this->xmlrpcString)),
118 'docstring' => 'Returns a documentation string for the specified method'),
Derek Allard2067d1a2008-11-13 22:59:24 +0000119 'system.methodSignature' => array(
Andrey Andreev56e32142011-12-25 18:36:31 +0200120 'function' => 'this.methodSignature',
121 'signature' => array(array($this->xmlrpcArray, $this->xmlrpcString)),
122 'docstring' => 'Returns an array describing the return type and required parameters of a method'),
123 'system.multicall' => array(
124 'function' => 'this.multicall',
125 'signature' => array(array($this->xmlrpcArray, $this->xmlrpcArray)),
126 'docstring' => 'Combine multiple RPC calls in one request. See http://www.xmlrpc.com/discuss/msgReader$1208 for details')
127 );
Derek Allard2067d1a2008-11-13 22:59:24 +0000128 }
129
Pascal Kriete68d29872011-02-14 13:39:06 -0500130 // --------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +0000131
Pascal Kriete68d29872011-02-14 13:39:06 -0500132 /**
133 * Main Server Function
134 *
Pascal Kriete68d29872011-02-14 13:39:06 -0500135 * @return void
136 */
Andrey Andreev56e32142011-12-25 18:36:31 +0200137 public function serve()
Derek Allard2067d1a2008-11-13 22:59:24 +0000138 {
139 $r = $this->parseRequest();
Andrey Andreev56e32142011-12-25 18:36:31 +0200140 $payload = '<?xml version="1.0" encoding="'.$this->xmlrpc_defencoding.'"?'.'>'."\n".$this->debug_msg.$r->prepare_response();
Barry Mienydd671972010-10-04 16:33:58 +0200141
Andrey Andreev52278372012-03-26 16:02:30 +0300142 header('Content-Type: text/xml');
143 header('Content-Length: '.strlen($payload));
Derek Jonesb8d3c3d2009-06-24 15:27:01 +0000144 exit($payload);
Derek Allard2067d1a2008-11-13 22:59:24 +0000145 }
146
Pascal Kriete68d29872011-02-14 13:39:06 -0500147 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200148
Pascal Kriete68d29872011-02-14 13:39:06 -0500149 /**
150 * Add Method to Class
151 *
Pascal Kriete68d29872011-02-14 13:39:06 -0500152 * @param string method name
153 * @param string function
154 * @param string signature
155 * @param string docstring
156 * @return void
157 */
Andrey Andreev56e32142011-12-25 18:36:31 +0200158 public function add_to_map($methodname, $function, $sig, $doc)
Derek Allard2067d1a2008-11-13 22:59:24 +0000159 {
160 $this->methods[$methodname] = array(
Derek Jones37f4b9c2011-07-01 17:56:50 -0500161 'function' => $function,
Derek Allard2067d1a2008-11-13 22:59:24 +0000162 'signature' => $sig,
163 'docstring' => $doc
164 );
165 }
166
Pascal Kriete68d29872011-02-14 13:39:06 -0500167 // --------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +0000168
Pascal Kriete68d29872011-02-14 13:39:06 -0500169 /**
170 * Parse Server Request
171 *
Pascal Kriete68d29872011-02-14 13:39:06 -0500172 * @param string data
173 * @return object xmlrpc response
174 */
Andrey Andreev56e32142011-12-25 18:36:31 +0200175 public function parseRequest($data = '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000176 {
177 global $HTTP_RAW_POST_DATA;
Barry Mienydd671972010-10-04 16:33:58 +0200178
Derek Allard2067d1a2008-11-13 22:59:24 +0000179 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500180 // Get Data
Derek Allard2067d1a2008-11-13 22:59:24 +0000181 //-------------------------------------
182
183 if ($data == '')
184 {
185 $data = $HTTP_RAW_POST_DATA;
186 }
187
188 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500189 // Set up XML Parser
Derek Allard2067d1a2008-11-13 22:59:24 +0000190 //-------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200191
Derek Allard2067d1a2008-11-13 22:59:24 +0000192 $parser = xml_parser_create($this->xmlrpc_defencoding);
Andrey Andreev52278372012-03-26 16:02:30 +0300193 $parser_object = new XML_RPC_Message('filler');
Barry Mienydd671972010-10-04 16:33:58 +0200194
Andrey Andreev56e32142011-12-25 18:36:31 +0200195 $parser_object->xh[$parser] = array(
196 'isf' => 0,
197 'isf_reason' => '',
198 'params' => array(),
199 'stack' => array(),
200 'valuestack' => array(),
201 'method' => ''
202 );
Derek Allard2067d1a2008-11-13 22:59:24 +0000203
204 xml_set_object($parser, $parser_object);
205 xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true);
206 xml_set_element_handler($parser, 'open_tag', 'closing_tag');
207 xml_set_character_data_handler($parser, 'character_data');
208 //xml_set_default_handler($parser, 'default_handler');
Barry Mienydd671972010-10-04 16:33:58 +0200209
Derek Allard2067d1a2008-11-13 22:59:24 +0000210 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500211 // PARSE + PROCESS XML DATA
Barry Mienydd671972010-10-04 16:33:58 +0200212 //-------------------------------------
213
Derek Allard2067d1a2008-11-13 22:59:24 +0000214 if ( ! xml_parse($parser, $data, 1))
215 {
216 // return XML error as a faultCode
217 $r = new XML_RPC_Response(0,
218 $this->xmlrpcerrxml + xml_get_error_code($parser),
219 sprintf('XML error: %s at line %d',
220 xml_error_string(xml_get_error_code($parser)),
221 xml_get_current_line_number($parser)));
222 xml_parser_free($parser);
223 }
Pascal Kriete68d29872011-02-14 13:39:06 -0500224 elseif ($parser_object->xh[$parser]['isf'])
Derek Allard2067d1a2008-11-13 22:59:24 +0000225 {
226 return new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'], $this->xmlrpcstr['invalid_return']);
227 }
228 else
229 {
230 xml_parser_free($parser);
Barry Mienydd671972010-10-04 16:33:58 +0200231
Derek Allard2067d1a2008-11-13 22:59:24 +0000232 $m = new XML_RPC_Message($parser_object->xh[$parser]['method']);
233 $plist='';
Barry Mienydd671972010-10-04 16:33:58 +0200234
Andrey Andreev56e32142011-12-25 18:36:31 +0200235 for ($i = 0, $c = count($parser_object->xh[$parser]['params']); $i < $c; $i++)
Derek Allard2067d1a2008-11-13 22:59:24 +0000236 {
237 if ($this->debug === TRUE)
238 {
Andrey Andreev52278372012-03-26 16:02:30 +0300239 $plist .= $i.' - '.print_r(get_object_vars($parser_object->xh[$parser]['params'][$i]), TRUE).";\n";
Derek Allard2067d1a2008-11-13 22:59:24 +0000240 }
Barry Mienydd671972010-10-04 16:33:58 +0200241
Derek Allard2067d1a2008-11-13 22:59:24 +0000242 $m->addParam($parser_object->xh[$parser]['params'][$i]);
243 }
Barry Mienydd671972010-10-04 16:33:58 +0200244
Derek Allard2067d1a2008-11-13 22:59:24 +0000245 if ($this->debug === TRUE)
246 {
Andrey Andreev56e32142011-12-25 18:36:31 +0200247 echo "<pre>---PLIST---\n".$plist."\n---PLIST END---\n\n</pre>";
Derek Allard2067d1a2008-11-13 22:59:24 +0000248 }
Barry Mienydd671972010-10-04 16:33:58 +0200249
Derek Allard2067d1a2008-11-13 22:59:24 +0000250 $r = $this->_execute($m);
251 }
Barry Mienydd671972010-10-04 16:33:58 +0200252
Derek Allard2067d1a2008-11-13 22:59:24 +0000253 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500254 // SET DEBUGGING MESSAGE
Barry Mienydd671972010-10-04 16:33:58 +0200255 //-------------------------------------
256
Derek Allard2067d1a2008-11-13 22:59:24 +0000257 if ($this->debug === TRUE)
258 {
259 $this->debug_msg = "<!-- DEBUG INFO:\n\n".$plist."\n END DEBUG-->\n";
260 }
Barry Mienydd671972010-10-04 16:33:58 +0200261
Derek Allard2067d1a2008-11-13 22:59:24 +0000262 return $r;
263 }
264
Pascal Kriete68d29872011-02-14 13:39:06 -0500265 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200266
Pascal Kriete68d29872011-02-14 13:39:06 -0500267 /**
268 * Executes the Method
269 *
Pascal Kriete68d29872011-02-14 13:39:06 -0500270 * @param object
271 * @return mixed
272 */
Andrey Andreev56e32142011-12-25 18:36:31 +0200273 protected function _execute($m)
Derek Allard2067d1a2008-11-13 22:59:24 +0000274 {
275 $methName = $m->method_name;
Barry Mienydd671972010-10-04 16:33:58 +0200276
Derek Allard2067d1a2008-11-13 22:59:24 +0000277 // Check to see if it is a system call
Andrey Andreev56e32142011-12-25 18:36:31 +0200278 $system_call = (strncmp($methName, 'system', 5) === 0);
Barry Mienydd671972010-10-04 16:33:58 +0200279
Robin Sowell66a3fc02010-03-18 09:44:55 -0400280 if ($this->xss_clean == FALSE)
281 {
282 $m->xss_clean = FALSE;
283 }
284
Derek Allard2067d1a2008-11-13 22:59:24 +0000285 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500286 // Valid Method
Derek Allard2067d1a2008-11-13 22:59:24 +0000287 //-------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200288
Derek Allard2067d1a2008-11-13 22:59:24 +0000289 if ( ! isset($this->methods[$methName]['function']))
290 {
291 return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']);
292 }
Barry Mienydd671972010-10-04 16:33:58 +0200293
Derek Allard2067d1a2008-11-13 22:59:24 +0000294 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500295 // Check for Method (and Object)
Derek Allard2067d1a2008-11-13 22:59:24 +0000296 //-------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200297
Andrey Andreev52278372012-03-26 16:02:30 +0300298 $method_parts = explode('.', $this->methods[$methName]['function']);
Andrey Andreev56e32142011-12-25 18:36:31 +0200299 $objectCall = (isset($method_parts[1]) && $method_parts[1] != '');
Barry Mienydd671972010-10-04 16:33:58 +0200300
Derek Allard2067d1a2008-11-13 22:59:24 +0000301 if ($system_call === TRUE)
302 {
Andrey Andreev56e32142011-12-25 18:36:31 +0200303 if ( ! is_callable(array($this,$method_parts[1])))
Derek Allard2067d1a2008-11-13 22:59:24 +0000304 {
305 return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']);
306 }
307 }
Andrey Andreev52278372012-03-26 16:02:30 +0300308 elseif (($objectCall && ! is_callable(array($method_parts[0], $method_parts[1])))
309 OR ( ! $objectCall && ! is_callable($this->methods[$methName]['function']))
310 )
Derek Allard2067d1a2008-11-13 22:59:24 +0000311 {
Andrey Andreev52278372012-03-26 16:02:30 +0300312 return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']);
Derek Allard2067d1a2008-11-13 22:59:24 +0000313 }
Barry Mienydd671972010-10-04 16:33:58 +0200314
Derek Allard2067d1a2008-11-13 22:59:24 +0000315 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500316 // Checking Methods Signature
Derek Allard2067d1a2008-11-13 22:59:24 +0000317 //-------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200318
Derek Allard2067d1a2008-11-13 22:59:24 +0000319 if (isset($this->methods[$methName]['signature']))
320 {
321 $sig = $this->methods[$methName]['signature'];
Andrey Andreev56e32142011-12-25 18:36:31 +0200322 for ($i = 0, $c = count($sig); $i < $c; $i++)
Derek Allard2067d1a2008-11-13 22:59:24 +0000323 {
324 $current_sig = $sig[$i];
Barry Mienydd671972010-10-04 16:33:58 +0200325
Andrey Andreev56e32142011-12-25 18:36:31 +0200326 if (count($current_sig) === count($m->params)+1)
Derek Allard2067d1a2008-11-13 22:59:24 +0000327 {
Andrey Andreev56e32142011-12-25 18:36:31 +0200328 for ($n = 0, $mc = count($m->params); $n < $mc; $n++)
Derek Allard2067d1a2008-11-13 22:59:24 +0000329 {
330 $p = $m->params[$n];
331 $pt = ($p->kindOf() == 'scalar') ? $p->scalarval() : $p->kindOf();
Barry Mienydd671972010-10-04 16:33:58 +0200332
Derek Allard2067d1a2008-11-13 22:59:24 +0000333 if ($pt != $current_sig[$n+1])
334 {
335 $pno = $n+1;
336 $wanted = $current_sig[$n+1];
Barry Mienydd671972010-10-04 16:33:58 +0200337
Derek Allard2067d1a2008-11-13 22:59:24 +0000338 return new XML_RPC_Response(0,
339 $this->xmlrpcerr['incorrect_params'],
340 $this->xmlrpcstr['incorrect_params'] .
Andrey Andreev52278372012-03-26 16:02:30 +0300341 ': Wanted '.$wanted.', got '.$pt.' at param '.$pno.')');
Derek Allard2067d1a2008-11-13 22:59:24 +0000342 }
343 }
344 }
345 }
346 }
347
348 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500349 // Calls the Function
Derek Allard2067d1a2008-11-13 22:59:24 +0000350 //-------------------------------------
351
352 if ($objectCall === TRUE)
353 {
Andrey Andreev56e32142011-12-25 18:36:31 +0200354 if ($method_parts[0] === 'this' && $system_call === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000355 {
356 return call_user_func(array($this, $method_parts[1]), $m);
357 }
358 else
359 {
360 if ($this->object === FALSE)
361 {
362 $CI =& get_instance();
Andrey Andreev56e32142011-12-25 18:36:31 +0200363 return $CI->$method_parts[1]($m);
Derek Allard2067d1a2008-11-13 22:59:24 +0000364 }
365 else
366 {
Andrey Andreev56e32142011-12-25 18:36:31 +0200367 return $this->object->$method_parts[1]($m);
Derek Allard2067d1a2008-11-13 22:59:24 +0000368 //return call_user_func(array(&$method_parts['0'],$method_parts['1']), $m);
369 }
370 }
371 }
372 else
373 {
374 return call_user_func($this->methods[$methName]['function'], $m);
375 }
376 }
Andrey Andreev56e32142011-12-25 18:36:31 +0200377
Pascal Kriete68d29872011-02-14 13:39:06 -0500378 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200379
Pascal Kriete68d29872011-02-14 13:39:06 -0500380 /**
Derek Jones37f4b9c2011-07-01 17:56:50 -0500381 * Server Function: List Methods
Pascal Kriete68d29872011-02-14 13:39:06 -0500382 *
Pascal Kriete68d29872011-02-14 13:39:06 -0500383 * @param mixed
384 * @return object
385 */
Andrey Andreev56e32142011-12-25 18:36:31 +0200386 public function listMethods($m)
Derek Allard2067d1a2008-11-13 22:59:24 +0000387 {
388 $v = new XML_RPC_Values();
389 $output = array();
Barry Mienydd671972010-10-04 16:33:58 +0200390
Pascal Kriete68d29872011-02-14 13:39:06 -0500391 foreach ($this->methods as $key => $value)
Derek Allard2067d1a2008-11-13 22:59:24 +0000392 {
393 $output[] = new XML_RPC_Values($key, 'string');
394 }
Barry Mienydd671972010-10-04 16:33:58 +0200395
Pascal Kriete68d29872011-02-14 13:39:06 -0500396 foreach ($this->system_methods as $key => $value)
Derek Allard2067d1a2008-11-13 22:59:24 +0000397 {
Andrey Andreev52278372012-03-26 16:02:30 +0300398 $output[] = new XML_RPC_Values($key, 'string');
Derek Allard2067d1a2008-11-13 22:59:24 +0000399 }
400
401 $v->addArray($output);
402 return new XML_RPC_Response($v);
403 }
Andrey Andreev56e32142011-12-25 18:36:31 +0200404
Pascal Kriete68d29872011-02-14 13:39:06 -0500405 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200406
Pascal Kriete68d29872011-02-14 13:39:06 -0500407 /**
Derek Jones37f4b9c2011-07-01 17:56:50 -0500408 * Server Function: Return Signature for Method
Pascal Kriete68d29872011-02-14 13:39:06 -0500409 *
Pascal Kriete68d29872011-02-14 13:39:06 -0500410 * @param mixed
411 * @return object
412 */
Andrey Andreev56e32142011-12-25 18:36:31 +0200413 public function methodSignature($m)
Derek Allard2067d1a2008-11-13 22:59:24 +0000414 {
415 $parameters = $m->output_parameters();
416 $method_name = $parameters[0];
Barry Mienydd671972010-10-04 16:33:58 +0200417
Derek Allard2067d1a2008-11-13 22:59:24 +0000418 if (isset($this->methods[$method_name]))
419 {
420 if ($this->methods[$method_name]['signature'])
421 {
422 $sigs = array();
423 $signature = $this->methods[$method_name]['signature'];
Barry Mienydd671972010-10-04 16:33:58 +0200424
Andrey Andreev56e32142011-12-25 18:36:31 +0200425 for ($i = 0, $c = count($signature); $i < $c; $i++)
Derek Allard2067d1a2008-11-13 22:59:24 +0000426 {
427 $cursig = array();
428 $inSig = $signature[$i];
Andrey Andreev56e32142011-12-25 18:36:31 +0200429 for ($j = 0, $jc = count($inSig); $j < $jc; $j++)
Derek Allard2067d1a2008-11-13 22:59:24 +0000430 {
431 $cursig[]= new XML_RPC_Values($inSig[$j], 'string');
432 }
Andrey Andreev56e32142011-12-25 18:36:31 +0200433 $sigs[] = new XML_RPC_Values($cursig, 'array');
Derek Allard2067d1a2008-11-13 22:59:24 +0000434 }
Andrey Andreev52278372012-03-26 16:02:30 +0300435
436 return new XML_RPC_Response(new XML_RPC_Values($sigs, 'array'));
Derek Allard2067d1a2008-11-13 22:59:24 +0000437 }
Andrey Andreev52278372012-03-26 16:02:30 +0300438
439 return new XML_RPC_Response(new XML_RPC_Values('undef', 'string'));
Derek Allard2067d1a2008-11-13 22:59:24 +0000440 }
Andrey Andreev52278372012-03-26 16:02:30 +0300441
442 return new XML_RPC_Response(0,$this->xmlrpcerr['introspect_unknown'], $this->xmlrpcstr['introspect_unknown']);
Derek Allard2067d1a2008-11-13 22:59:24 +0000443 }
Barry Mienydd671972010-10-04 16:33:58 +0200444
Pascal Kriete68d29872011-02-14 13:39:06 -0500445 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200446
Pascal Kriete68d29872011-02-14 13:39:06 -0500447 /**
Derek Jones37f4b9c2011-07-01 17:56:50 -0500448 * Server Function: Doc String for Method
Pascal Kriete68d29872011-02-14 13:39:06 -0500449 *
Pascal Kriete68d29872011-02-14 13:39:06 -0500450 * @param mixed
451 * @return object
452 */
Andrey Andreev56e32142011-12-25 18:36:31 +0200453 public function methodHelp($m)
Derek Allard2067d1a2008-11-13 22:59:24 +0000454 {
455 $parameters = $m->output_parameters();
456 $method_name = $parameters[0];
Barry Mienydd671972010-10-04 16:33:58 +0200457
Derek Allard2067d1a2008-11-13 22:59:24 +0000458 if (isset($this->methods[$method_name]))
459 {
460 $docstring = isset($this->methods[$method_name]['docstring']) ? $this->methods[$method_name]['docstring'] : '';
Barry Mienydd671972010-10-04 16:33:58 +0200461
Derek Allard2067d1a2008-11-13 22:59:24 +0000462 return new XML_RPC_Response(new XML_RPC_Values($docstring, 'string'));
463 }
464 else
465 {
466 return new XML_RPC_Response(0, $this->xmlrpcerr['introspect_unknown'], $this->xmlrpcstr['introspect_unknown']);
467 }
468 }
Andrey Andreev56e32142011-12-25 18:36:31 +0200469
Pascal Kriete68d29872011-02-14 13:39:06 -0500470 // --------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +0000471
Pascal Kriete68d29872011-02-14 13:39:06 -0500472 /**
Derek Jones37f4b9c2011-07-01 17:56:50 -0500473 * Server Function: Multi-call
Pascal Kriete68d29872011-02-14 13:39:06 -0500474 *
Pascal Kriete68d29872011-02-14 13:39:06 -0500475 * @param mixed
476 * @return object
477 */
Andrey Andreev56e32142011-12-25 18:36:31 +0200478 public function multicall($m)
Derek Allard2067d1a2008-11-13 22:59:24 +0000479 {
480 // Disabled
481 return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']);
Barry Mienydd671972010-10-04 16:33:58 +0200482
Derek Allard2067d1a2008-11-13 22:59:24 +0000483 $parameters = $m->output_parameters();
484 $calls = $parameters[0];
485
486 $result = array();
487
488 foreach ($calls as $value)
489 {
490 //$attempt = $this->_execute(new XML_RPC_Message($value[0], $value[1]));
Barry Mienydd671972010-10-04 16:33:58 +0200491
Derek Allard2067d1a2008-11-13 22:59:24 +0000492 $m = new XML_RPC_Message($value[0]);
493 $plist='';
Barry Mienydd671972010-10-04 16:33:58 +0200494
Andrey Andreev56e32142011-12-25 18:36:31 +0200495 for ($i = 0, $c = count($value[1]); $i < $c; $i++)
Derek Allard2067d1a2008-11-13 22:59:24 +0000496 {
497 $m->addParam(new XML_RPC_Values($value[1][$i], 'string'));
498 }
Barry Mienydd671972010-10-04 16:33:58 +0200499
Derek Allard2067d1a2008-11-13 22:59:24 +0000500 $attempt = $this->_execute($m);
501
502 if ($attempt->faultCode() != 0)
503 {
504 return $attempt;
505 }
506
507 $result[] = new XML_RPC_Values(array($attempt->value()), 'array');
508 }
509
510 return new XML_RPC_Response(new XML_RPC_Values($result, 'array'));
511 }
Barry Mienydd671972010-10-04 16:33:58 +0200512
Pascal Kriete68d29872011-02-14 13:39:06 -0500513 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200514
Pascal Kriete68d29872011-02-14 13:39:06 -0500515 /**
Derek Jones37f4b9c2011-07-01 17:56:50 -0500516 * Multi-call Function: Error Handling
Pascal Kriete68d29872011-02-14 13:39:06 -0500517 *
Pascal Kriete68d29872011-02-14 13:39:06 -0500518 * @param mixed
519 * @return object
520 */
Andrey Andreev56e32142011-12-25 18:36:31 +0200521 public function multicall_error($err)
Derek Allard2067d1a2008-11-13 22:59:24 +0000522 {
Derek Jones37f4b9c2011-07-01 17:56:50 -0500523 $str = is_string($err) ? $this->xmlrpcstr["multicall_${err}"] : $err->faultString();
Derek Allard2067d1a2008-11-13 22:59:24 +0000524 $code = is_string($err) ? $this->xmlrpcerr["multicall_${err}"] : $err->faultCode();
Barry Mienydd671972010-10-04 16:33:58 +0200525
Derek Allard2067d1a2008-11-13 22:59:24 +0000526 $struct['faultCode'] = new XML_RPC_Values($code, 'int');
527 $struct['faultString'] = new XML_RPC_Values($str, 'string');
Barry Mienydd671972010-10-04 16:33:58 +0200528
Derek Allard2067d1a2008-11-13 22:59:24 +0000529 return new XML_RPC_Values($struct, 'struct');
530 }
Barry Mienydd671972010-10-04 16:33:58 +0200531
Pascal Kriete68d29872011-02-14 13:39:06 -0500532 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200533
Pascal Kriete68d29872011-02-14 13:39:06 -0500534 /**
Derek Jones37f4b9c2011-07-01 17:56:50 -0500535 * Multi-call Function: Processes method
Pascal Kriete68d29872011-02-14 13:39:06 -0500536 *
Pascal Kriete68d29872011-02-14 13:39:06 -0500537 * @param mixed
538 * @return object
539 */
Andrey Andreev56e32142011-12-25 18:36:31 +0200540 public function do_multicall($call)
Derek Allard2067d1a2008-11-13 22:59:24 +0000541 {
542 if ($call->kindOf() != 'struct')
Pascal Kriete68d29872011-02-14 13:39:06 -0500543 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000544 return $this->multicall_error('notstruct');
Pascal Kriete68d29872011-02-14 13:39:06 -0500545 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000546 elseif ( ! $methName = $call->me['struct']['methodName'])
Pascal Kriete68d29872011-02-14 13:39:06 -0500547 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000548 return $this->multicall_error('nomethod');
Pascal Kriete68d29872011-02-14 13:39:06 -0500549 }
Barry Mienydd671972010-10-04 16:33:58 +0200550
Derek Allard2067d1a2008-11-13 22:59:24 +0000551 list($scalar_type,$scalar_value)=each($methName->me);
552 $scalar_type = $scalar_type == $this->xmlrpcI4 ? $this->xmlrpcInt : $scalar_type;
Barry Mienydd671972010-10-04 16:33:58 +0200553
Derek Allard2067d1a2008-11-13 22:59:24 +0000554 if ($methName->kindOf() != 'scalar' OR $scalar_type != 'string')
Pascal Kriete68d29872011-02-14 13:39:06 -0500555 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000556 return $this->multicall_error('notstring');
Pascal Kriete68d29872011-02-14 13:39:06 -0500557 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000558 elseif ($scalar_value == 'system.multicall')
Pascal Kriete68d29872011-02-14 13:39:06 -0500559 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000560 return $this->multicall_error('recursion');
Pascal Kriete68d29872011-02-14 13:39:06 -0500561 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000562 elseif ( ! $params = $call->me['struct']['params'])
Pascal Kriete68d29872011-02-14 13:39:06 -0500563 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000564 return $this->multicall_error('noparams');
Pascal Kriete68d29872011-02-14 13:39:06 -0500565 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000566 elseif ($params->kindOf() != 'array')
Pascal Kriete68d29872011-02-14 13:39:06 -0500567 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000568 return $this->multicall_error('notarray');
Pascal Kriete68d29872011-02-14 13:39:06 -0500569 }
Barry Mienydd671972010-10-04 16:33:58 +0200570
Andrey Andreev56e32142011-12-25 18:36:31 +0200571 list($a,$b) = each($params->me);
Derek Allard2067d1a2008-11-13 22:59:24 +0000572
573 $msg = new XML_RPC_Message($scalar_value);
Andrey Andreev56e32142011-12-25 18:36:31 +0200574 for ($i = 0, $numParams = count($b); $i < $numParams; $i++)
Derek Allard2067d1a2008-11-13 22:59:24 +0000575 {
576 $msg->params[] = $params->me['array'][$i];
577 }
578
579 $result = $this->_execute($msg);
580
581 if ($result->faultCode() != 0)
582 {
583 return $this->multicall_error($result);
584 }
585
586 return new XML_RPC_Values(array($result->value()), 'array');
Barry Mienydd671972010-10-04 16:33:58 +0200587 }
588
Derek Allard2067d1a2008-11-13 22:59:24 +0000589}
Derek Allard2067d1a2008-11-13 22:59:24 +0000590
Derek Allard2067d1a2008-11-13 22:59:24 +0000591/* End of file Xmlrpcs.php */
Andrey Andreev52278372012-03-26 16:02:30 +0300592/* Location: ./system/libraries/Xmlrpcs.php */