blob: 587b750403decf894a2cf161bd721185231484f3 [file] [log] [blame]
Derek Jones37f4b9c2011-07-01 17:56:50 -05001<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
Derek Allard2067d1a2008-11-13 22:59:24 +00002/**
3 * CodeIgniter
4 *
Greg Aker741de1c2010-11-10 14:52:57 -06005 * An open source application development framework for PHP 5.1.6 or newer
Derek Allard2067d1a2008-11-13 22:59:24 +00006 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05007 * NOTICE OF LICENSE
8 *
9 * Licensed under the Open Software License version 3.0
10 *
11 * 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
21 * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
22 * @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{
Barry Mienydd671972010-10-04 16:33:58 +020051 var $methods = array(); //array of methods mapped to function names and signatures
Derek Allard2067d1a2008-11-13 22:59:24 +000052 var $debug_msg = ''; // Debug Message
Barry Mienydd671972010-10-04 16:33:58 +020053 var $system_methods = array(); // XML RPC Server methods
Derek Allard2067d1a2008-11-13 22:59:24 +000054 var $controller_obj;
Barry Mienydd671972010-10-04 16:33:58 +020055
Derek Allard2067d1a2008-11-13 22:59:24 +000056 var $object = FALSE;
Derek Jonesc4c34ee2010-03-02 23:00:28 -060057
Greg Akera9263282010-11-10 15:26:43 -060058 /**
59 * Constructor
60 */
61 public function __construct($config=array())
Barry Mienydd671972010-10-04 16:33:58 +020062 {
Greg Akera9263282010-11-10 15:26:43 -060063 parent::__construct();
Derek Allard2067d1a2008-11-13 22:59:24 +000064 $this->set_system_methods();
Barry Mienydd671972010-10-04 16:33:58 +020065
Derek Allard2067d1a2008-11-13 22:59:24 +000066 if (isset($config['functions']) && is_array($config['functions']))
67 {
68 $this->methods = array_merge($this->methods, $config['functions']);
69 }
Barry Mienydd671972010-10-04 16:33:58 +020070
Derek Allard2067d1a2008-11-13 22:59:24 +000071 log_message('debug', "XML-RPC Server Class Initialized");
72 }
Barry Mienydd671972010-10-04 16:33:58 +020073
Pascal Kriete68d29872011-02-14 13:39:06 -050074 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +020075
Pascal Kriete68d29872011-02-14 13:39:06 -050076 /**
77 * Initialize Prefs and Serve
78 *
79 * @access public
80 * @param mixed
81 * @return void
82 */
Derek Allard2067d1a2008-11-13 22:59:24 +000083 function initialize($config=array())
Barry Mienydd671972010-10-04 16:33:58 +020084 {
Derek Allard2067d1a2008-11-13 22:59:24 +000085 if (isset($config['functions']) && is_array($config['functions']))
86 {
87 $this->methods = array_merge($this->methods, $config['functions']);
88 }
Barry Mienydd671972010-10-04 16:33:58 +020089
Derek Allard2067d1a2008-11-13 22:59:24 +000090 if (isset($config['debug']))
91 {
92 $this->debug = $config['debug'];
93 }
Barry Mienydd671972010-10-04 16:33:58 +020094
Derek Allard2067d1a2008-11-13 22:59:24 +000095 if (isset($config['object']) && is_object($config['object']))
96 {
97 $this->object = $config['object'];
98 }
Barry Mienydd671972010-10-04 16:33:58 +020099
Robin Sowell66a3fc02010-03-18 09:44:55 -0400100 if (isset($config['xss_clean']))
101 {
102 $this->xss_clean = $config['xss_clean'];
103 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000104 }
Barry Mienydd671972010-10-04 16:33:58 +0200105
Pascal Kriete68d29872011-02-14 13:39:06 -0500106 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200107
Pascal Kriete68d29872011-02-14 13:39:06 -0500108 /**
109 * Setting of System Methods
110 *
111 * @access public
112 * @return void
113 */
114 function set_system_methods()
Derek Allard2067d1a2008-11-13 22:59:24 +0000115 {
116 $this->methods = array(
117 'system.listMethods' => array(
118 'function' => 'this.listMethods',
119 'signature' => array(array($this->xmlrpcArray, $this->xmlrpcString), array($this->xmlrpcArray)),
120 'docstring' => 'Returns an array of available methods on this server'),
121 'system.methodHelp' => array(
122 'function' => 'this.methodHelp',
123 'signature' => array(array($this->xmlrpcString, $this->xmlrpcString)),
124 'docstring' => 'Returns a documentation string for the specified method'),
125 'system.methodSignature' => array(
126 'function' => 'this.methodSignature',
127 'signature' => array(array($this->xmlrpcArray, $this->xmlrpcString)),
128 'docstring' => 'Returns an array describing the return type and required parameters of a method'),
129 'system.multicall' => array(
130 'function' => 'this.multicall',
131 'signature' => array(array($this->xmlrpcArray, $this->xmlrpcArray)),
132 'docstring' => 'Combine multiple RPC calls in one request. See http://www.xmlrpc.com/discuss/msgReader$1208 for details')
133 );
134 }
135
Pascal Kriete68d29872011-02-14 13:39:06 -0500136 // --------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +0000137
Pascal Kriete68d29872011-02-14 13:39:06 -0500138 /**
139 * Main Server Function
140 *
141 * @access public
142 * @return void
143 */
Derek Allard2067d1a2008-11-13 22:59:24 +0000144 function serve()
145 {
146 $r = $this->parseRequest();
Derek Jones37f4b9c2011-07-01 17:56:50 -0500147 $payload = '<?xml version="1.0" encoding="'.$this->xmlrpc_defencoding.'"?'.'>'."\n";
Derek Allard2067d1a2008-11-13 22:59:24 +0000148 $payload .= $this->debug_msg;
149 $payload .= $r->prepare_response();
Barry Mienydd671972010-10-04 16:33:58 +0200150
Derek Allard2067d1a2008-11-13 22:59:24 +0000151 header("Content-Type: text/xml");
152 header("Content-Length: ".strlen($payload));
Derek Jonesb8d3c3d2009-06-24 15:27:01 +0000153 exit($payload);
Derek Allard2067d1a2008-11-13 22:59:24 +0000154 }
155
Pascal Kriete68d29872011-02-14 13:39:06 -0500156 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200157
Pascal Kriete68d29872011-02-14 13:39:06 -0500158 /**
159 * Add Method to Class
160 *
161 * @access public
162 * @param string method name
163 * @param string function
164 * @param string signature
165 * @param string docstring
166 * @return void
167 */
168 function add_to_map($methodname, $function, $sig, $doc)
Derek Allard2067d1a2008-11-13 22:59:24 +0000169 {
170 $this->methods[$methodname] = array(
Derek Jones37f4b9c2011-07-01 17:56:50 -0500171 'function' => $function,
Derek Allard2067d1a2008-11-13 22:59:24 +0000172 'signature' => $sig,
173 'docstring' => $doc
174 );
175 }
176
Pascal Kriete68d29872011-02-14 13:39:06 -0500177 // --------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +0000178
Pascal Kriete68d29872011-02-14 13:39:06 -0500179 /**
180 * Parse Server Request
181 *
182 * @access public
183 * @param string data
184 * @return object xmlrpc response
185 */
Derek Allard2067d1a2008-11-13 22:59:24 +0000186 function parseRequest($data='')
187 {
188 global $HTTP_RAW_POST_DATA;
Barry Mienydd671972010-10-04 16:33:58 +0200189
Derek Allard2067d1a2008-11-13 22:59:24 +0000190 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500191 // Get Data
Derek Allard2067d1a2008-11-13 22:59:24 +0000192 //-------------------------------------
193
194 if ($data == '')
195 {
196 $data = $HTTP_RAW_POST_DATA;
197 }
198
199 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500200 // Set up XML Parser
Derek Allard2067d1a2008-11-13 22:59:24 +0000201 //-------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200202
Derek Allard2067d1a2008-11-13 22:59:24 +0000203 $parser = xml_parser_create($this->xmlrpc_defencoding);
204 $parser_object = new XML_RPC_Message("filler");
Barry Mienydd671972010-10-04 16:33:58 +0200205
Derek Allard2067d1a2008-11-13 22:59:24 +0000206 $parser_object->xh[$parser] = array();
207 $parser_object->xh[$parser]['isf'] = 0;
208 $parser_object->xh[$parser]['isf_reason'] = '';
209 $parser_object->xh[$parser]['params'] = array();
210 $parser_object->xh[$parser]['stack'] = array();
211 $parser_object->xh[$parser]['valuestack'] = array();
212 $parser_object->xh[$parser]['method'] = '';
213
214 xml_set_object($parser, $parser_object);
215 xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true);
216 xml_set_element_handler($parser, 'open_tag', 'closing_tag');
217 xml_set_character_data_handler($parser, 'character_data');
218 //xml_set_default_handler($parser, 'default_handler');
Barry Mienydd671972010-10-04 16:33:58 +0200219
220
Derek Allard2067d1a2008-11-13 22:59:24 +0000221 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500222 // PARSE + PROCESS XML DATA
Barry Mienydd671972010-10-04 16:33:58 +0200223 //-------------------------------------
224
Derek Allard2067d1a2008-11-13 22:59:24 +0000225 if ( ! xml_parse($parser, $data, 1))
226 {
227 // return XML error as a faultCode
228 $r = new XML_RPC_Response(0,
229 $this->xmlrpcerrxml + xml_get_error_code($parser),
230 sprintf('XML error: %s at line %d',
231 xml_error_string(xml_get_error_code($parser)),
232 xml_get_current_line_number($parser)));
233 xml_parser_free($parser);
234 }
Pascal Kriete68d29872011-02-14 13:39:06 -0500235 elseif ($parser_object->xh[$parser]['isf'])
Derek Allard2067d1a2008-11-13 22:59:24 +0000236 {
237 return new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'], $this->xmlrpcstr['invalid_return']);
238 }
239 else
240 {
241 xml_parser_free($parser);
Barry Mienydd671972010-10-04 16:33:58 +0200242
Derek Allard2067d1a2008-11-13 22:59:24 +0000243 $m = new XML_RPC_Message($parser_object->xh[$parser]['method']);
244 $plist='';
Barry Mienydd671972010-10-04 16:33:58 +0200245
Pascal Kriete68d29872011-02-14 13:39:06 -0500246 for ($i=0; $i < count($parser_object->xh[$parser]['params']); $i++)
Derek Allard2067d1a2008-11-13 22:59:24 +0000247 {
248 if ($this->debug === TRUE)
249 {
Derek Jones37f4b9c2011-07-01 17:56:50 -0500250 $plist .= "$i - " . print_r(get_object_vars($parser_object->xh[$parser]['params'][$i]), TRUE). ";\n";
Derek Allard2067d1a2008-11-13 22:59:24 +0000251 }
Barry Mienydd671972010-10-04 16:33:58 +0200252
Derek Allard2067d1a2008-11-13 22:59:24 +0000253 $m->addParam($parser_object->xh[$parser]['params'][$i]);
254 }
Barry Mienydd671972010-10-04 16:33:58 +0200255
Derek Allard2067d1a2008-11-13 22:59:24 +0000256 if ($this->debug === TRUE)
257 {
258 echo "<pre>";
259 echo "---PLIST---\n" . $plist . "\n---PLIST END---\n\n";
260 echo "</pre>";
261 }
Barry Mienydd671972010-10-04 16:33:58 +0200262
Derek Allard2067d1a2008-11-13 22:59:24 +0000263 $r = $this->_execute($m);
264 }
Barry Mienydd671972010-10-04 16:33:58 +0200265
Derek Allard2067d1a2008-11-13 22:59:24 +0000266 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500267 // SET DEBUGGING MESSAGE
Barry Mienydd671972010-10-04 16:33:58 +0200268 //-------------------------------------
269
Derek Allard2067d1a2008-11-13 22:59:24 +0000270 if ($this->debug === TRUE)
271 {
272 $this->debug_msg = "<!-- DEBUG INFO:\n\n".$plist."\n END DEBUG-->\n";
273 }
Barry Mienydd671972010-10-04 16:33:58 +0200274
Derek Allard2067d1a2008-11-13 22:59:24 +0000275 return $r;
276 }
277
Pascal Kriete68d29872011-02-14 13:39:06 -0500278 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200279
Pascal Kriete68d29872011-02-14 13:39:06 -0500280 /**
281 * Executes the Method
282 *
283 * @access protected
284 * @param object
285 * @return mixed
286 */
Derek Allard2067d1a2008-11-13 22:59:24 +0000287 function _execute($m)
288 {
289 $methName = $m->method_name;
Barry Mienydd671972010-10-04 16:33:58 +0200290
Derek Allard2067d1a2008-11-13 22:59:24 +0000291 // Check to see if it is a system call
292 $system_call = (strncmp($methName, 'system', 5) == 0) ? TRUE : FALSE;
Barry Mienydd671972010-10-04 16:33:58 +0200293
Robin Sowell66a3fc02010-03-18 09:44:55 -0400294 if ($this->xss_clean == FALSE)
295 {
296 $m->xss_clean = FALSE;
297 }
298
Derek Allard2067d1a2008-11-13 22:59:24 +0000299 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500300 // Valid Method
Derek Allard2067d1a2008-11-13 22:59:24 +0000301 //-------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200302
Derek Allard2067d1a2008-11-13 22:59:24 +0000303 if ( ! isset($this->methods[$methName]['function']))
304 {
305 return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']);
306 }
Barry Mienydd671972010-10-04 16:33:58 +0200307
Derek Allard2067d1a2008-11-13 22:59:24 +0000308 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500309 // Check for Method (and Object)
Derek Allard2067d1a2008-11-13 22:59:24 +0000310 //-------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200311
Derek Allard2067d1a2008-11-13 22:59:24 +0000312 $method_parts = explode(".", $this->methods[$methName]['function']);
313 $objectCall = (isset($method_parts['1']) && $method_parts['1'] != "") ? TRUE : FALSE;
Barry Mienydd671972010-10-04 16:33:58 +0200314
Derek Allard2067d1a2008-11-13 22:59:24 +0000315 if ($system_call === TRUE)
316 {
317 if ( ! is_callable(array($this,$method_parts['1'])))
318 {
319 return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']);
320 }
321 }
322 else
323 {
324 if ($objectCall && ! is_callable(array($method_parts['0'],$method_parts['1'])))
325 {
326 return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']);
327 }
328 elseif ( ! $objectCall && ! is_callable($this->methods[$methName]['function']))
329 {
330 return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']);
331 }
332 }
Barry Mienydd671972010-10-04 16:33:58 +0200333
Derek Allard2067d1a2008-11-13 22:59:24 +0000334 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500335 // Checking Methods Signature
Derek Allard2067d1a2008-11-13 22:59:24 +0000336 //-------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200337
Derek Allard2067d1a2008-11-13 22:59:24 +0000338 if (isset($this->methods[$methName]['signature']))
339 {
340 $sig = $this->methods[$methName]['signature'];
Pascal Kriete68d29872011-02-14 13:39:06 -0500341 for ($i=0; $i<count($sig); $i++)
Derek Allard2067d1a2008-11-13 22:59:24 +0000342 {
343 $current_sig = $sig[$i];
Barry Mienydd671972010-10-04 16:33:58 +0200344
Derek Jones33559102009-02-02 18:50:38 +0000345 if (count($current_sig) == count($m->params)+1)
Derek Allard2067d1a2008-11-13 22:59:24 +0000346 {
Pascal Kriete68d29872011-02-14 13:39:06 -0500347 for ($n=0; $n < count($m->params); $n++)
Derek Allard2067d1a2008-11-13 22:59:24 +0000348 {
349 $p = $m->params[$n];
350 $pt = ($p->kindOf() == 'scalar') ? $p->scalarval() : $p->kindOf();
Barry Mienydd671972010-10-04 16:33:58 +0200351
Derek Allard2067d1a2008-11-13 22:59:24 +0000352 if ($pt != $current_sig[$n+1])
353 {
354 $pno = $n+1;
355 $wanted = $current_sig[$n+1];
Barry Mienydd671972010-10-04 16:33:58 +0200356
Derek Allard2067d1a2008-11-13 22:59:24 +0000357 return new XML_RPC_Response(0,
358 $this->xmlrpcerr['incorrect_params'],
359 $this->xmlrpcstr['incorrect_params'] .
360 ": Wanted {$wanted}, got {$pt} at param {$pno})");
361 }
362 }
363 }
364 }
365 }
366
367 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500368 // Calls the Function
Derek Allard2067d1a2008-11-13 22:59:24 +0000369 //-------------------------------------
370
371 if ($objectCall === TRUE)
372 {
373 if ($method_parts[0] == "this" && $system_call == TRUE)
374 {
375 return call_user_func(array($this, $method_parts[1]), $m);
376 }
377 else
378 {
379 if ($this->object === FALSE)
380 {
381 $CI =& get_instance();
382 return $CI->$method_parts['1']($m);
383 }
384 else
385 {
386 return $this->object->$method_parts['1']($m);
387 //return call_user_func(array(&$method_parts['0'],$method_parts['1']), $m);
388 }
389 }
390 }
391 else
392 {
393 return call_user_func($this->methods[$methName]['function'], $m);
394 }
395 }
Derek Jones37f4b9c2011-07-01 17:56:50 -0500396
Pascal Kriete68d29872011-02-14 13:39:06 -0500397 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200398
Pascal Kriete68d29872011-02-14 13:39:06 -0500399 /**
Derek Jones37f4b9c2011-07-01 17:56:50 -0500400 * Server Function: List Methods
Pascal Kriete68d29872011-02-14 13:39:06 -0500401 *
402 * @access public
403 * @param mixed
404 * @return object
405 */
Derek Allard2067d1a2008-11-13 22:59:24 +0000406 function listMethods($m)
407 {
408 $v = new XML_RPC_Values();
409 $output = array();
Barry Mienydd671972010-10-04 16:33:58 +0200410
Pascal Kriete68d29872011-02-14 13:39:06 -0500411 foreach ($this->methods as $key => $value)
Derek Allard2067d1a2008-11-13 22:59:24 +0000412 {
413 $output[] = new XML_RPC_Values($key, 'string');
414 }
Barry Mienydd671972010-10-04 16:33:58 +0200415
Pascal Kriete68d29872011-02-14 13:39:06 -0500416 foreach ($this->system_methods as $key => $value)
Derek Allard2067d1a2008-11-13 22:59:24 +0000417 {
418 $output[]= new XML_RPC_Values($key, 'string');
419 }
420
421 $v->addArray($output);
422 return new XML_RPC_Response($v);
423 }
Derek Jones37f4b9c2011-07-01 17:56:50 -0500424
Pascal Kriete68d29872011-02-14 13:39:06 -0500425 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200426
Pascal Kriete68d29872011-02-14 13:39:06 -0500427 /**
Derek Jones37f4b9c2011-07-01 17:56:50 -0500428 * Server Function: Return Signature for Method
Pascal Kriete68d29872011-02-14 13:39:06 -0500429 *
430 * @access public
431 * @param mixed
432 * @return object
433 */
Derek Allard2067d1a2008-11-13 22:59:24 +0000434 function methodSignature($m)
435 {
436 $parameters = $m->output_parameters();
437 $method_name = $parameters[0];
Barry Mienydd671972010-10-04 16:33:58 +0200438
Derek Allard2067d1a2008-11-13 22:59:24 +0000439 if (isset($this->methods[$method_name]))
440 {
441 if ($this->methods[$method_name]['signature'])
442 {
443 $sigs = array();
444 $signature = $this->methods[$method_name]['signature'];
Barry Mienydd671972010-10-04 16:33:58 +0200445
Pascal Kriete68d29872011-02-14 13:39:06 -0500446 for ($i=0; $i < count($signature); $i++)
Derek Allard2067d1a2008-11-13 22:59:24 +0000447 {
448 $cursig = array();
449 $inSig = $signature[$i];
Pascal Kriete68d29872011-02-14 13:39:06 -0500450 for ($j=0; $j<count($inSig); $j++)
Derek Allard2067d1a2008-11-13 22:59:24 +0000451 {
452 $cursig[]= new XML_RPC_Values($inSig[$j], 'string');
453 }
454 $sigs[]= new XML_RPC_Values($cursig, 'array');
455 }
456 $r = new XML_RPC_Response(new XML_RPC_Values($sigs, 'array'));
457 }
458 else
459 {
460 $r = new XML_RPC_Response(new XML_RPC_Values('undef', 'string'));
461 }
462 }
463 else
464 {
465 $r = new XML_RPC_Response(0,$this->xmlrpcerr['introspect_unknown'], $this->xmlrpcstr['introspect_unknown']);
466 }
467 return $r;
468 }
Barry Mienydd671972010-10-04 16:33:58 +0200469
Pascal Kriete68d29872011-02-14 13:39:06 -0500470 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200471
Pascal Kriete68d29872011-02-14 13:39:06 -0500472 /**
Derek Jones37f4b9c2011-07-01 17:56:50 -0500473 * Server Function: Doc String for Method
Pascal Kriete68d29872011-02-14 13:39:06 -0500474 *
475 * @access public
476 * @param mixed
477 * @return object
478 */
Derek Allard2067d1a2008-11-13 22:59:24 +0000479 function methodHelp($m)
480 {
481 $parameters = $m->output_parameters();
482 $method_name = $parameters[0];
Barry Mienydd671972010-10-04 16:33:58 +0200483
Derek Allard2067d1a2008-11-13 22:59:24 +0000484 if (isset($this->methods[$method_name]))
485 {
486 $docstring = isset($this->methods[$method_name]['docstring']) ? $this->methods[$method_name]['docstring'] : '';
Barry Mienydd671972010-10-04 16:33:58 +0200487
Derek Allard2067d1a2008-11-13 22:59:24 +0000488 return new XML_RPC_Response(new XML_RPC_Values($docstring, 'string'));
489 }
490 else
491 {
492 return new XML_RPC_Response(0, $this->xmlrpcerr['introspect_unknown'], $this->xmlrpcstr['introspect_unknown']);
493 }
494 }
Derek Jones37f4b9c2011-07-01 17:56:50 -0500495
Pascal Kriete68d29872011-02-14 13:39:06 -0500496 // --------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +0000497
Pascal Kriete68d29872011-02-14 13:39:06 -0500498 /**
Derek Jones37f4b9c2011-07-01 17:56:50 -0500499 * Server Function: Multi-call
Pascal Kriete68d29872011-02-14 13:39:06 -0500500 *
501 * @access public
502 * @param mixed
503 * @return object
504 */
Derek Allard2067d1a2008-11-13 22:59:24 +0000505 function multicall($m)
506 {
507 // Disabled
508 return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']);
Barry Mienydd671972010-10-04 16:33:58 +0200509
Derek Allard2067d1a2008-11-13 22:59:24 +0000510 $parameters = $m->output_parameters();
511 $calls = $parameters[0];
512
513 $result = array();
514
515 foreach ($calls as $value)
516 {
517 //$attempt = $this->_execute(new XML_RPC_Message($value[0], $value[1]));
Barry Mienydd671972010-10-04 16:33:58 +0200518
Derek Allard2067d1a2008-11-13 22:59:24 +0000519 $m = new XML_RPC_Message($value[0]);
520 $plist='';
Barry Mienydd671972010-10-04 16:33:58 +0200521
Pascal Kriete68d29872011-02-14 13:39:06 -0500522 for ($i=0; $i < count($value[1]); $i++)
Derek Allard2067d1a2008-11-13 22:59:24 +0000523 {
524 $m->addParam(new XML_RPC_Values($value[1][$i], 'string'));
525 }
Barry Mienydd671972010-10-04 16:33:58 +0200526
Derek Allard2067d1a2008-11-13 22:59:24 +0000527 $attempt = $this->_execute($m);
528
529 if ($attempt->faultCode() != 0)
530 {
531 return $attempt;
532 }
533
534 $result[] = new XML_RPC_Values(array($attempt->value()), 'array');
535 }
536
537 return new XML_RPC_Response(new XML_RPC_Values($result, 'array'));
538 }
Barry Mienydd671972010-10-04 16:33:58 +0200539
Pascal Kriete68d29872011-02-14 13:39:06 -0500540 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200541
Pascal Kriete68d29872011-02-14 13:39:06 -0500542 /**
Derek Jones37f4b9c2011-07-01 17:56:50 -0500543 * Multi-call Function: Error Handling
Pascal Kriete68d29872011-02-14 13:39:06 -0500544 *
545 * @access public
546 * @param mixed
547 * @return object
548 */
Derek Allard2067d1a2008-11-13 22:59:24 +0000549 function multicall_error($err)
550 {
Derek Jones37f4b9c2011-07-01 17:56:50 -0500551 $str = is_string($err) ? $this->xmlrpcstr["multicall_${err}"] : $err->faultString();
Derek Allard2067d1a2008-11-13 22:59:24 +0000552 $code = is_string($err) ? $this->xmlrpcerr["multicall_${err}"] : $err->faultCode();
Barry Mienydd671972010-10-04 16:33:58 +0200553
Derek Allard2067d1a2008-11-13 22:59:24 +0000554 $struct['faultCode'] = new XML_RPC_Values($code, 'int');
555 $struct['faultString'] = new XML_RPC_Values($str, 'string');
Barry Mienydd671972010-10-04 16:33:58 +0200556
Derek Allard2067d1a2008-11-13 22:59:24 +0000557 return new XML_RPC_Values($struct, 'struct');
558 }
Barry Mienydd671972010-10-04 16:33:58 +0200559
Pascal Kriete68d29872011-02-14 13:39:06 -0500560 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200561
Pascal Kriete68d29872011-02-14 13:39:06 -0500562 /**
Derek Jones37f4b9c2011-07-01 17:56:50 -0500563 * Multi-call Function: Processes method
Pascal Kriete68d29872011-02-14 13:39:06 -0500564 *
565 * @access public
566 * @param mixed
567 * @return object
568 */
Derek Allard2067d1a2008-11-13 22:59:24 +0000569 function do_multicall($call)
570 {
571 if ($call->kindOf() != 'struct')
Pascal Kriete68d29872011-02-14 13:39:06 -0500572 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000573 return $this->multicall_error('notstruct');
Pascal Kriete68d29872011-02-14 13:39:06 -0500574 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000575 elseif ( ! $methName = $call->me['struct']['methodName'])
Pascal Kriete68d29872011-02-14 13:39:06 -0500576 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000577 return $this->multicall_error('nomethod');
Pascal Kriete68d29872011-02-14 13:39:06 -0500578 }
Barry Mienydd671972010-10-04 16:33:58 +0200579
Derek Allard2067d1a2008-11-13 22:59:24 +0000580 list($scalar_type,$scalar_value)=each($methName->me);
581 $scalar_type = $scalar_type == $this->xmlrpcI4 ? $this->xmlrpcInt : $scalar_type;
Barry Mienydd671972010-10-04 16:33:58 +0200582
Derek Allard2067d1a2008-11-13 22:59:24 +0000583 if ($methName->kindOf() != 'scalar' OR $scalar_type != 'string')
Pascal Kriete68d29872011-02-14 13:39:06 -0500584 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000585 return $this->multicall_error('notstring');
Pascal Kriete68d29872011-02-14 13:39:06 -0500586 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000587 elseif ($scalar_value == 'system.multicall')
Pascal Kriete68d29872011-02-14 13:39:06 -0500588 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000589 return $this->multicall_error('recursion');
Pascal Kriete68d29872011-02-14 13:39:06 -0500590 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000591 elseif ( ! $params = $call->me['struct']['params'])
Pascal Kriete68d29872011-02-14 13:39:06 -0500592 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000593 return $this->multicall_error('noparams');
Pascal Kriete68d29872011-02-14 13:39:06 -0500594 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000595 elseif ($params->kindOf() != 'array')
Pascal Kriete68d29872011-02-14 13:39:06 -0500596 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000597 return $this->multicall_error('notarray');
Pascal Kriete68d29872011-02-14 13:39:06 -0500598 }
Barry Mienydd671972010-10-04 16:33:58 +0200599
Derek Allard2067d1a2008-11-13 22:59:24 +0000600 list($a,$b)=each($params->me);
Derek Jones33559102009-02-02 18:50:38 +0000601 $numParams = count($b);
Derek Allard2067d1a2008-11-13 22:59:24 +0000602
603 $msg = new XML_RPC_Message($scalar_value);
604 for ($i = 0; $i < $numParams; $i++)
605 {
606 $msg->params[] = $params->me['array'][$i];
607 }
608
609 $result = $this->_execute($msg);
610
611 if ($result->faultCode() != 0)
612 {
613 return $this->multicall_error($result);
614 }
615
616 return new XML_RPC_Values(array($result->value()), 'array');
Barry Mienydd671972010-10-04 16:33:58 +0200617 }
618
Derek Allard2067d1a2008-11-13 22:59:24 +0000619}
620// END XML_RPC_Server class
621
622
623/* End of file Xmlrpcs.php */
Derek Jonesa3ffbbb2008-05-11 18:18:29 +0000624/* Location: ./system/libraries/Xmlrpcs.php */