blob: fc41444bc597664e0ee92b444799de1f30cbb389 [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
Greg Akera9263282010-11-10 15:26:43 -060057 /**
58 * Constructor
59 */
60 public function __construct($config=array())
Barry Mienydd671972010-10-04 16:33:58 +020061 {
Greg Akera9263282010-11-10 15:26:43 -060062 parent::__construct();
Derek Allard2067d1a2008-11-13 22:59:24 +000063 $this->set_system_methods();
Barry Mienydd671972010-10-04 16:33:58 +020064
Derek Allard2067d1a2008-11-13 22:59:24 +000065 if (isset($config['functions']) && is_array($config['functions']))
66 {
67 $this->methods = array_merge($this->methods, $config['functions']);
68 }
Barry Mienydd671972010-10-04 16:33:58 +020069
Derek Allard2067d1a2008-11-13 22:59:24 +000070 log_message('debug', "XML-RPC Server Class Initialized");
71 }
Barry Mienydd671972010-10-04 16:33:58 +020072
Pascal Kriete68d29872011-02-14 13:39:06 -050073 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +020074
Pascal Kriete68d29872011-02-14 13:39:06 -050075 /**
76 * Initialize Prefs and Serve
77 *
78 * @access public
79 * @param mixed
80 * @return void
81 */
Andrey Andreev56e32142011-12-25 18:36:31 +020082 public function initialize($config = array())
Barry Mienydd671972010-10-04 16:33:58 +020083 {
Derek Allard2067d1a2008-11-13 22:59:24 +000084 if (isset($config['functions']) && is_array($config['functions']))
85 {
86 $this->methods = array_merge($this->methods, $config['functions']);
87 }
Barry Mienydd671972010-10-04 16:33:58 +020088
Derek Allard2067d1a2008-11-13 22:59:24 +000089 if (isset($config['debug']))
90 {
91 $this->debug = $config['debug'];
92 }
Barry Mienydd671972010-10-04 16:33:58 +020093
Derek Allard2067d1a2008-11-13 22:59:24 +000094 if (isset($config['object']) && is_object($config['object']))
95 {
96 $this->object = $config['object'];
97 }
Barry Mienydd671972010-10-04 16:33:58 +020098
Robin Sowell66a3fc02010-03-18 09:44:55 -040099 if (isset($config['xss_clean']))
100 {
101 $this->xss_clean = $config['xss_clean'];
102 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000103 }
Barry Mienydd671972010-10-04 16:33:58 +0200104
Pascal Kriete68d29872011-02-14 13:39:06 -0500105 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200106
Pascal Kriete68d29872011-02-14 13:39:06 -0500107 /**
108 * Setting of System Methods
109 *
110 * @access public
111 * @return void
112 */
Andrey Andreev56e32142011-12-25 18:36:31 +0200113 public function set_system_methods()
Derek Allard2067d1a2008-11-13 22:59:24 +0000114 {
115 $this->methods = array(
116 'system.listMethods' => array(
Andrey Andreev56e32142011-12-25 18:36:31 +0200117 'function' => 'this.listMethods',
118 'signature' => array(array($this->xmlrpcArray, $this->xmlrpcString), array($this->xmlrpcArray)),
119 'docstring' => 'Returns an array of available methods on this server'),
120 'system.methodHelp' => array(
121 'function' => 'this.methodHelp',
122 'signature' => array(array($this->xmlrpcString, $this->xmlrpcString)),
123 'docstring' => 'Returns a documentation string for the specified method'),
Derek Allard2067d1a2008-11-13 22:59:24 +0000124 'system.methodSignature' => array(
Andrey Andreev56e32142011-12-25 18:36:31 +0200125 'function' => 'this.methodSignature',
126 'signature' => array(array($this->xmlrpcArray, $this->xmlrpcString)),
127 'docstring' => 'Returns an array describing the return type and required parameters of a method'),
128 'system.multicall' => array(
129 'function' => 'this.multicall',
130 'signature' => array(array($this->xmlrpcArray, $this->xmlrpcArray)),
131 'docstring' => 'Combine multiple RPC calls in one request. See http://www.xmlrpc.com/discuss/msgReader$1208 for details')
132 );
Derek Allard2067d1a2008-11-13 22:59:24 +0000133 }
134
Pascal Kriete68d29872011-02-14 13:39:06 -0500135 // --------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +0000136
Pascal Kriete68d29872011-02-14 13:39:06 -0500137 /**
138 * Main Server Function
139 *
140 * @access public
141 * @return void
142 */
Andrey Andreev56e32142011-12-25 18:36:31 +0200143 public function serve()
Derek Allard2067d1a2008-11-13 22:59:24 +0000144 {
145 $r = $this->parseRequest();
Andrey Andreev56e32142011-12-25 18:36:31 +0200146 $payload = '<?xml version="1.0" encoding="'.$this->xmlrpc_defencoding.'"?'.'>'."\n".$this->debug_msg.$r->prepare_response();
Barry Mienydd671972010-10-04 16:33:58 +0200147
Derek Allard2067d1a2008-11-13 22:59:24 +0000148 header("Content-Type: text/xml");
149 header("Content-Length: ".strlen($payload));
Derek Jonesb8d3c3d2009-06-24 15:27:01 +0000150 exit($payload);
Derek Allard2067d1a2008-11-13 22:59:24 +0000151 }
152
Pascal Kriete68d29872011-02-14 13:39:06 -0500153 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200154
Pascal Kriete68d29872011-02-14 13:39:06 -0500155 /**
156 * Add Method to Class
157 *
158 * @access public
159 * @param string method name
160 * @param string function
161 * @param string signature
162 * @param string docstring
163 * @return void
164 */
Andrey Andreev56e32142011-12-25 18:36:31 +0200165 public function add_to_map($methodname, $function, $sig, $doc)
Derek Allard2067d1a2008-11-13 22:59:24 +0000166 {
167 $this->methods[$methodname] = array(
Derek Jones37f4b9c2011-07-01 17:56:50 -0500168 'function' => $function,
Derek Allard2067d1a2008-11-13 22:59:24 +0000169 'signature' => $sig,
170 'docstring' => $doc
171 );
172 }
173
Pascal Kriete68d29872011-02-14 13:39:06 -0500174 // --------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +0000175
Pascal Kriete68d29872011-02-14 13:39:06 -0500176 /**
177 * Parse Server Request
178 *
179 * @access public
180 * @param string data
181 * @return object xmlrpc response
182 */
Andrey Andreev56e32142011-12-25 18:36:31 +0200183 public function parseRequest($data = '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000184 {
185 global $HTTP_RAW_POST_DATA;
Barry Mienydd671972010-10-04 16:33:58 +0200186
Derek Allard2067d1a2008-11-13 22:59:24 +0000187 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500188 // Get Data
Derek Allard2067d1a2008-11-13 22:59:24 +0000189 //-------------------------------------
190
191 if ($data == '')
192 {
193 $data = $HTTP_RAW_POST_DATA;
194 }
195
196 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500197 // Set up XML Parser
Derek Allard2067d1a2008-11-13 22:59:24 +0000198 //-------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200199
Derek Allard2067d1a2008-11-13 22:59:24 +0000200 $parser = xml_parser_create($this->xmlrpc_defencoding);
201 $parser_object = new XML_RPC_Message("filler");
Barry Mienydd671972010-10-04 16:33:58 +0200202
Andrey Andreev56e32142011-12-25 18:36:31 +0200203 $parser_object->xh[$parser] = array(
204 'isf' => 0,
205 'isf_reason' => '',
206 'params' => array(),
207 'stack' => array(),
208 'valuestack' => array(),
209 'method' => ''
210 );
Derek Allard2067d1a2008-11-13 22:59:24 +0000211
212 xml_set_object($parser, $parser_object);
213 xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true);
214 xml_set_element_handler($parser, 'open_tag', 'closing_tag');
215 xml_set_character_data_handler($parser, 'character_data');
216 //xml_set_default_handler($parser, 'default_handler');
Barry Mienydd671972010-10-04 16:33:58 +0200217
218
Derek Allard2067d1a2008-11-13 22:59:24 +0000219 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500220 // PARSE + PROCESS XML DATA
Barry Mienydd671972010-10-04 16:33:58 +0200221 //-------------------------------------
222
Derek Allard2067d1a2008-11-13 22:59:24 +0000223 if ( ! xml_parse($parser, $data, 1))
224 {
225 // return XML error as a faultCode
226 $r = new XML_RPC_Response(0,
227 $this->xmlrpcerrxml + xml_get_error_code($parser),
228 sprintf('XML error: %s at line %d',
229 xml_error_string(xml_get_error_code($parser)),
230 xml_get_current_line_number($parser)));
231 xml_parser_free($parser);
232 }
Pascal Kriete68d29872011-02-14 13:39:06 -0500233 elseif ($parser_object->xh[$parser]['isf'])
Derek Allard2067d1a2008-11-13 22:59:24 +0000234 {
235 return new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'], $this->xmlrpcstr['invalid_return']);
236 }
237 else
238 {
239 xml_parser_free($parser);
Barry Mienydd671972010-10-04 16:33:58 +0200240
Derek Allard2067d1a2008-11-13 22:59:24 +0000241 $m = new XML_RPC_Message($parser_object->xh[$parser]['method']);
242 $plist='';
Barry Mienydd671972010-10-04 16:33:58 +0200243
Andrey Andreev56e32142011-12-25 18:36:31 +0200244 for ($i = 0, $c = count($parser_object->xh[$parser]['params']); $i < $c; $i++)
Derek Allard2067d1a2008-11-13 22:59:24 +0000245 {
246 if ($this->debug === TRUE)
247 {
Derek Jones37f4b9c2011-07-01 17:56:50 -0500248 $plist .= "$i - " . print_r(get_object_vars($parser_object->xh[$parser]['params'][$i]), TRUE). ";\n";
Derek Allard2067d1a2008-11-13 22:59:24 +0000249 }
Barry Mienydd671972010-10-04 16:33:58 +0200250
Derek Allard2067d1a2008-11-13 22:59:24 +0000251 $m->addParam($parser_object->xh[$parser]['params'][$i]);
252 }
Barry Mienydd671972010-10-04 16:33:58 +0200253
Derek Allard2067d1a2008-11-13 22:59:24 +0000254 if ($this->debug === TRUE)
255 {
Andrey Andreev56e32142011-12-25 18:36:31 +0200256 echo "<pre>---PLIST---\n".$plist."\n---PLIST END---\n\n</pre>";
Derek Allard2067d1a2008-11-13 22:59:24 +0000257 }
Barry Mienydd671972010-10-04 16:33:58 +0200258
Derek Allard2067d1a2008-11-13 22:59:24 +0000259 $r = $this->_execute($m);
260 }
Barry Mienydd671972010-10-04 16:33:58 +0200261
Derek Allard2067d1a2008-11-13 22:59:24 +0000262 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500263 // SET DEBUGGING MESSAGE
Barry Mienydd671972010-10-04 16:33:58 +0200264 //-------------------------------------
265
Derek Allard2067d1a2008-11-13 22:59:24 +0000266 if ($this->debug === TRUE)
267 {
268 $this->debug_msg = "<!-- DEBUG INFO:\n\n".$plist."\n END DEBUG-->\n";
269 }
Barry Mienydd671972010-10-04 16:33:58 +0200270
Derek Allard2067d1a2008-11-13 22:59:24 +0000271 return $r;
272 }
273
Pascal Kriete68d29872011-02-14 13:39:06 -0500274 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200275
Pascal Kriete68d29872011-02-14 13:39:06 -0500276 /**
277 * Executes the Method
278 *
279 * @access protected
280 * @param object
281 * @return mixed
282 */
Andrey Andreev56e32142011-12-25 18:36:31 +0200283 protected function _execute($m)
Derek Allard2067d1a2008-11-13 22:59:24 +0000284 {
285 $methName = $m->method_name;
Barry Mienydd671972010-10-04 16:33:58 +0200286
Derek Allard2067d1a2008-11-13 22:59:24 +0000287 // Check to see if it is a system call
Andrey Andreev56e32142011-12-25 18:36:31 +0200288 $system_call = (strncmp($methName, 'system', 5) === 0);
Barry Mienydd671972010-10-04 16:33:58 +0200289
Robin Sowell66a3fc02010-03-18 09:44:55 -0400290 if ($this->xss_clean == FALSE)
291 {
292 $m->xss_clean = FALSE;
293 }
294
Derek Allard2067d1a2008-11-13 22:59:24 +0000295 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500296 // Valid Method
Derek Allard2067d1a2008-11-13 22:59:24 +0000297 //-------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200298
Derek Allard2067d1a2008-11-13 22:59:24 +0000299 if ( ! isset($this->methods[$methName]['function']))
300 {
301 return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']);
302 }
Barry Mienydd671972010-10-04 16:33:58 +0200303
Derek Allard2067d1a2008-11-13 22:59:24 +0000304 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500305 // Check for Method (and Object)
Derek Allard2067d1a2008-11-13 22:59:24 +0000306 //-------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200307
Derek Allard2067d1a2008-11-13 22:59:24 +0000308 $method_parts = explode(".", $this->methods[$methName]['function']);
Andrey Andreev56e32142011-12-25 18:36:31 +0200309 $objectCall = (isset($method_parts[1]) && $method_parts[1] != '');
Barry Mienydd671972010-10-04 16:33:58 +0200310
Derek Allard2067d1a2008-11-13 22:59:24 +0000311 if ($system_call === TRUE)
312 {
Andrey Andreev56e32142011-12-25 18:36:31 +0200313 if ( ! is_callable(array($this,$method_parts[1])))
Derek Allard2067d1a2008-11-13 22:59:24 +0000314 {
315 return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']);
316 }
317 }
318 else
319 {
Andrey Andreev56e32142011-12-25 18:36:31 +0200320 if (($objectCall AND ! is_callable(array($method_parts[0], $method_parts[1])))
321 OR ( ! $objectCall AND ! is_callable($this->methods[$methName]['function']))
322 )
Derek Allard2067d1a2008-11-13 22:59:24 +0000323 {
324 return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']);
325 }
326 }
Barry Mienydd671972010-10-04 16:33:58 +0200327
Derek Allard2067d1a2008-11-13 22:59:24 +0000328 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500329 // Checking Methods Signature
Derek Allard2067d1a2008-11-13 22:59:24 +0000330 //-------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200331
Derek Allard2067d1a2008-11-13 22:59:24 +0000332 if (isset($this->methods[$methName]['signature']))
333 {
334 $sig = $this->methods[$methName]['signature'];
Andrey Andreev56e32142011-12-25 18:36:31 +0200335 for ($i = 0, $c = count($sig); $i < $c; $i++)
Derek Allard2067d1a2008-11-13 22:59:24 +0000336 {
337 $current_sig = $sig[$i];
Barry Mienydd671972010-10-04 16:33:58 +0200338
Andrey Andreev56e32142011-12-25 18:36:31 +0200339 if (count($current_sig) === count($m->params)+1)
Derek Allard2067d1a2008-11-13 22:59:24 +0000340 {
Andrey Andreev56e32142011-12-25 18:36:31 +0200341 for ($n = 0, $mc = count($m->params); $n < $mc; $n++)
Derek Allard2067d1a2008-11-13 22:59:24 +0000342 {
343 $p = $m->params[$n];
344 $pt = ($p->kindOf() == 'scalar') ? $p->scalarval() : $p->kindOf();
Barry Mienydd671972010-10-04 16:33:58 +0200345
Derek Allard2067d1a2008-11-13 22:59:24 +0000346 if ($pt != $current_sig[$n+1])
347 {
348 $pno = $n+1;
349 $wanted = $current_sig[$n+1];
Barry Mienydd671972010-10-04 16:33:58 +0200350
Derek Allard2067d1a2008-11-13 22:59:24 +0000351 return new XML_RPC_Response(0,
352 $this->xmlrpcerr['incorrect_params'],
353 $this->xmlrpcstr['incorrect_params'] .
354 ": Wanted {$wanted}, got {$pt} at param {$pno})");
355 }
356 }
357 }
358 }
359 }
360
361 //-------------------------------------
Derek Jones37f4b9c2011-07-01 17:56:50 -0500362 // Calls the Function
Derek Allard2067d1a2008-11-13 22:59:24 +0000363 //-------------------------------------
364
365 if ($objectCall === TRUE)
366 {
Andrey Andreev56e32142011-12-25 18:36:31 +0200367 if ($method_parts[0] === 'this' && $system_call === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000368 {
369 return call_user_func(array($this, $method_parts[1]), $m);
370 }
371 else
372 {
373 if ($this->object === FALSE)
374 {
375 $CI =& get_instance();
Andrey Andreev56e32142011-12-25 18:36:31 +0200376 return $CI->$method_parts[1]($m);
Derek Allard2067d1a2008-11-13 22:59:24 +0000377 }
378 else
379 {
Andrey Andreev56e32142011-12-25 18:36:31 +0200380 return $this->object->$method_parts[1]($m);
Derek Allard2067d1a2008-11-13 22:59:24 +0000381 //return call_user_func(array(&$method_parts['0'],$method_parts['1']), $m);
382 }
383 }
384 }
385 else
386 {
387 return call_user_func($this->methods[$methName]['function'], $m);
388 }
389 }
Andrey Andreev56e32142011-12-25 18:36:31 +0200390
Pascal Kriete68d29872011-02-14 13:39:06 -0500391 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200392
Pascal Kriete68d29872011-02-14 13:39:06 -0500393 /**
Derek Jones37f4b9c2011-07-01 17:56:50 -0500394 * Server Function: List Methods
Pascal Kriete68d29872011-02-14 13:39:06 -0500395 *
396 * @access public
397 * @param mixed
398 * @return object
399 */
Andrey Andreev56e32142011-12-25 18:36:31 +0200400 public function listMethods($m)
Derek Allard2067d1a2008-11-13 22:59:24 +0000401 {
402 $v = new XML_RPC_Values();
403 $output = array();
Barry Mienydd671972010-10-04 16:33:58 +0200404
Pascal Kriete68d29872011-02-14 13:39:06 -0500405 foreach ($this->methods as $key => $value)
Derek Allard2067d1a2008-11-13 22:59:24 +0000406 {
407 $output[] = new XML_RPC_Values($key, 'string');
408 }
Barry Mienydd671972010-10-04 16:33:58 +0200409
Pascal Kriete68d29872011-02-14 13:39:06 -0500410 foreach ($this->system_methods as $key => $value)
Derek Allard2067d1a2008-11-13 22:59:24 +0000411 {
412 $output[]= new XML_RPC_Values($key, 'string');
413 }
414
415 $v->addArray($output);
416 return new XML_RPC_Response($v);
417 }
Andrey Andreev56e32142011-12-25 18:36:31 +0200418
Pascal Kriete68d29872011-02-14 13:39:06 -0500419 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200420
Pascal Kriete68d29872011-02-14 13:39:06 -0500421 /**
Derek Jones37f4b9c2011-07-01 17:56:50 -0500422 * Server Function: Return Signature for Method
Pascal Kriete68d29872011-02-14 13:39:06 -0500423 *
424 * @access public
425 * @param mixed
426 * @return object
427 */
Andrey Andreev56e32142011-12-25 18:36:31 +0200428 public function methodSignature($m)
Derek Allard2067d1a2008-11-13 22:59:24 +0000429 {
430 $parameters = $m->output_parameters();
431 $method_name = $parameters[0];
Barry Mienydd671972010-10-04 16:33:58 +0200432
Derek Allard2067d1a2008-11-13 22:59:24 +0000433 if (isset($this->methods[$method_name]))
434 {
435 if ($this->methods[$method_name]['signature'])
436 {
437 $sigs = array();
438 $signature = $this->methods[$method_name]['signature'];
Barry Mienydd671972010-10-04 16:33:58 +0200439
Andrey Andreev56e32142011-12-25 18:36:31 +0200440 for ($i = 0, $c = count($signature); $i < $c; $i++)
Derek Allard2067d1a2008-11-13 22:59:24 +0000441 {
442 $cursig = array();
443 $inSig = $signature[$i];
Andrey Andreev56e32142011-12-25 18:36:31 +0200444 for ($j = 0, $jc = count($inSig); $j < $jc; $j++)
Derek Allard2067d1a2008-11-13 22:59:24 +0000445 {
446 $cursig[]= new XML_RPC_Values($inSig[$j], 'string');
447 }
Andrey Andreev56e32142011-12-25 18:36:31 +0200448 $sigs[] = new XML_RPC_Values($cursig, 'array');
Derek Allard2067d1a2008-11-13 22:59:24 +0000449 }
450 $r = new XML_RPC_Response(new XML_RPC_Values($sigs, 'array'));
451 }
452 else
453 {
454 $r = new XML_RPC_Response(new XML_RPC_Values('undef', 'string'));
455 }
456 }
457 else
458 {
459 $r = new XML_RPC_Response(0,$this->xmlrpcerr['introspect_unknown'], $this->xmlrpcstr['introspect_unknown']);
460 }
461 return $r;
462 }
Barry Mienydd671972010-10-04 16:33:58 +0200463
Pascal Kriete68d29872011-02-14 13:39:06 -0500464 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200465
Pascal Kriete68d29872011-02-14 13:39:06 -0500466 /**
Derek Jones37f4b9c2011-07-01 17:56:50 -0500467 * Server Function: Doc String for Method
Pascal Kriete68d29872011-02-14 13:39:06 -0500468 *
469 * @access public
470 * @param mixed
471 * @return object
472 */
Andrey Andreev56e32142011-12-25 18:36:31 +0200473 public function methodHelp($m)
Derek Allard2067d1a2008-11-13 22:59:24 +0000474 {
475 $parameters = $m->output_parameters();
476 $method_name = $parameters[0];
Barry Mienydd671972010-10-04 16:33:58 +0200477
Derek Allard2067d1a2008-11-13 22:59:24 +0000478 if (isset($this->methods[$method_name]))
479 {
480 $docstring = isset($this->methods[$method_name]['docstring']) ? $this->methods[$method_name]['docstring'] : '';
Barry Mienydd671972010-10-04 16:33:58 +0200481
Derek Allard2067d1a2008-11-13 22:59:24 +0000482 return new XML_RPC_Response(new XML_RPC_Values($docstring, 'string'));
483 }
484 else
485 {
486 return new XML_RPC_Response(0, $this->xmlrpcerr['introspect_unknown'], $this->xmlrpcstr['introspect_unknown']);
487 }
488 }
Andrey Andreev56e32142011-12-25 18:36:31 +0200489
Pascal Kriete68d29872011-02-14 13:39:06 -0500490 // --------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +0000491
Pascal Kriete68d29872011-02-14 13:39:06 -0500492 /**
Derek Jones37f4b9c2011-07-01 17:56:50 -0500493 * Server Function: Multi-call
Pascal Kriete68d29872011-02-14 13:39:06 -0500494 *
495 * @access public
496 * @param mixed
497 * @return object
498 */
Andrey Andreev56e32142011-12-25 18:36:31 +0200499 public function multicall($m)
Derek Allard2067d1a2008-11-13 22:59:24 +0000500 {
501 // Disabled
502 return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']);
Barry Mienydd671972010-10-04 16:33:58 +0200503
Derek Allard2067d1a2008-11-13 22:59:24 +0000504 $parameters = $m->output_parameters();
505 $calls = $parameters[0];
506
507 $result = array();
508
509 foreach ($calls as $value)
510 {
511 //$attempt = $this->_execute(new XML_RPC_Message($value[0], $value[1]));
Barry Mienydd671972010-10-04 16:33:58 +0200512
Derek Allard2067d1a2008-11-13 22:59:24 +0000513 $m = new XML_RPC_Message($value[0]);
514 $plist='';
Barry Mienydd671972010-10-04 16:33:58 +0200515
Andrey Andreev56e32142011-12-25 18:36:31 +0200516 for ($i = 0, $c = count($value[1]); $i < $c; $i++)
Derek Allard2067d1a2008-11-13 22:59:24 +0000517 {
518 $m->addParam(new XML_RPC_Values($value[1][$i], 'string'));
519 }
Barry Mienydd671972010-10-04 16:33:58 +0200520
Derek Allard2067d1a2008-11-13 22:59:24 +0000521 $attempt = $this->_execute($m);
522
523 if ($attempt->faultCode() != 0)
524 {
525 return $attempt;
526 }
527
528 $result[] = new XML_RPC_Values(array($attempt->value()), 'array');
529 }
530
531 return new XML_RPC_Response(new XML_RPC_Values($result, 'array'));
532 }
Barry Mienydd671972010-10-04 16:33:58 +0200533
Pascal Kriete68d29872011-02-14 13:39:06 -0500534 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200535
Pascal Kriete68d29872011-02-14 13:39:06 -0500536 /**
Derek Jones37f4b9c2011-07-01 17:56:50 -0500537 * Multi-call Function: Error Handling
Pascal Kriete68d29872011-02-14 13:39:06 -0500538 *
539 * @access public
540 * @param mixed
541 * @return object
542 */
Andrey Andreev56e32142011-12-25 18:36:31 +0200543 public function multicall_error($err)
Derek Allard2067d1a2008-11-13 22:59:24 +0000544 {
Derek Jones37f4b9c2011-07-01 17:56:50 -0500545 $str = is_string($err) ? $this->xmlrpcstr["multicall_${err}"] : $err->faultString();
Derek Allard2067d1a2008-11-13 22:59:24 +0000546 $code = is_string($err) ? $this->xmlrpcerr["multicall_${err}"] : $err->faultCode();
Barry Mienydd671972010-10-04 16:33:58 +0200547
Derek Allard2067d1a2008-11-13 22:59:24 +0000548 $struct['faultCode'] = new XML_RPC_Values($code, 'int');
549 $struct['faultString'] = new XML_RPC_Values($str, 'string');
Barry Mienydd671972010-10-04 16:33:58 +0200550
Derek Allard2067d1a2008-11-13 22:59:24 +0000551 return new XML_RPC_Values($struct, 'struct');
552 }
Barry Mienydd671972010-10-04 16:33:58 +0200553
Pascal Kriete68d29872011-02-14 13:39:06 -0500554 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200555
Pascal Kriete68d29872011-02-14 13:39:06 -0500556 /**
Derek Jones37f4b9c2011-07-01 17:56:50 -0500557 * Multi-call Function: Processes method
Pascal Kriete68d29872011-02-14 13:39:06 -0500558 *
559 * @access public
560 * @param mixed
561 * @return object
562 */
Andrey Andreev56e32142011-12-25 18:36:31 +0200563 public function do_multicall($call)
Derek Allard2067d1a2008-11-13 22:59:24 +0000564 {
565 if ($call->kindOf() != 'struct')
Pascal Kriete68d29872011-02-14 13:39:06 -0500566 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000567 return $this->multicall_error('notstruct');
Pascal Kriete68d29872011-02-14 13:39:06 -0500568 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000569 elseif ( ! $methName = $call->me['struct']['methodName'])
Pascal Kriete68d29872011-02-14 13:39:06 -0500570 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000571 return $this->multicall_error('nomethod');
Pascal Kriete68d29872011-02-14 13:39:06 -0500572 }
Barry Mienydd671972010-10-04 16:33:58 +0200573
Derek Allard2067d1a2008-11-13 22:59:24 +0000574 list($scalar_type,$scalar_value)=each($methName->me);
575 $scalar_type = $scalar_type == $this->xmlrpcI4 ? $this->xmlrpcInt : $scalar_type;
Barry Mienydd671972010-10-04 16:33:58 +0200576
Derek Allard2067d1a2008-11-13 22:59:24 +0000577 if ($methName->kindOf() != 'scalar' OR $scalar_type != 'string')
Pascal Kriete68d29872011-02-14 13:39:06 -0500578 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000579 return $this->multicall_error('notstring');
Pascal Kriete68d29872011-02-14 13:39:06 -0500580 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000581 elseif ($scalar_value == 'system.multicall')
Pascal Kriete68d29872011-02-14 13:39:06 -0500582 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000583 return $this->multicall_error('recursion');
Pascal Kriete68d29872011-02-14 13:39:06 -0500584 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000585 elseif ( ! $params = $call->me['struct']['params'])
Pascal Kriete68d29872011-02-14 13:39:06 -0500586 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000587 return $this->multicall_error('noparams');
Pascal Kriete68d29872011-02-14 13:39:06 -0500588 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000589 elseif ($params->kindOf() != 'array')
Pascal Kriete68d29872011-02-14 13:39:06 -0500590 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000591 return $this->multicall_error('notarray');
Pascal Kriete68d29872011-02-14 13:39:06 -0500592 }
Barry Mienydd671972010-10-04 16:33:58 +0200593
Andrey Andreev56e32142011-12-25 18:36:31 +0200594 list($a,$b) = each($params->me);
Derek Allard2067d1a2008-11-13 22:59:24 +0000595
596 $msg = new XML_RPC_Message($scalar_value);
Andrey Andreev56e32142011-12-25 18:36:31 +0200597 for ($i = 0, $numParams = count($b); $i < $numParams; $i++)
Derek Allard2067d1a2008-11-13 22:59:24 +0000598 {
599 $msg->params[] = $params->me['array'][$i];
600 }
601
602 $result = $this->_execute($msg);
603
604 if ($result->faultCode() != 0)
605 {
606 return $this->multicall_error($result);
607 }
608
609 return new XML_RPC_Values(array($result->value()), 'array');
Barry Mienydd671972010-10-04 16:33:58 +0200610 }
611
Derek Allard2067d1a2008-11-13 22:59:24 +0000612}
613// END XML_RPC_Server class
614
Derek Allard2067d1a2008-11-13 22:59:24 +0000615/* End of file Xmlrpcs.php */
Andrey Andreev56e32142011-12-25 18:36:31 +0200616/* Location: ./system/libraries/Xmlrpcs.php */