/lenasys/trunk

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/lenasys/trunk
20.1.1 by galaxyAbstractor
* Added an simple admin panel to the codeviewer-cmssy stuff
1
<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
2
/**
3
 * CodeIgniter
4
 *
5
 * An open source application development framework for PHP 5.1.6 or newer
6
 *
7
 * @package		CodeIgniter
8
 * @author		ExpressionEngine Dev Team
9
 * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc.
10
 * @license		http://codeigniter.com/user_guide/license.html
11
 * @link		http://codeigniter.com
12
 * @since		Version 1.0
13
 * @filesource
14
 */
15
16
if ( ! function_exists('xml_parser_create'))
17
{
18
	show_error('Your PHP installation does not support XML');
19
}
20
21
if ( ! class_exists('CI_Xmlrpc'))
22
{
23
	show_error('You must load the Xmlrpc class before loading the Xmlrpcs class in order to create a server.');
24
}
25
26
// ------------------------------------------------------------------------
27
28
/**
29
 * XML-RPC server class
30
 *
31
 * @package		CodeIgniter
32
 * @subpackage	Libraries
33
 * @category	XML-RPC
34
 * @author		ExpressionEngine Dev Team
35
 * @link		http://codeigniter.com/user_guide/libraries/xmlrpc.html
36
 */
37
class CI_Xmlrpcs extends CI_Xmlrpc
38
{
39
	var $methods		= array();	//array of methods mapped to function names and signatures
40
	var $debug_msg		= '';		// Debug Message
41
	var $system_methods = array();	// XML RPC Server methods
42
	var $controller_obj;
43
44
	var $object			= FALSE;
45
46
	/**
47
	 * Constructor
48
	 */
49
	public function __construct($config=array())
50
	{
51
		parent::__construct();
52
		$this->set_system_methods();
53
54
		if (isset($config['functions']) && is_array($config['functions']))
55
		{
56
			$this->methods = array_merge($this->methods, $config['functions']);
57
		}
58
59
		log_message('debug', "XML-RPC Server Class Initialized");
60
	}
61
62
	// --------------------------------------------------------------------
63
64
	/**
65
	 * Initialize Prefs and Serve
66
	 *
67
	 * @access	public
68
	 * @param	mixed
69
	 * @return	void
70
	 */
71
	function initialize($config=array())
72
	{
73
		if (isset($config['functions']) && is_array($config['functions']))
74
		{
75
			$this->methods = array_merge($this->methods, $config['functions']);
76
		}
77
78
		if (isset($config['debug']))
79
		{
80
			$this->debug = $config['debug'];
81
		}
82
83
		if (isset($config['object']) && is_object($config['object']))
84
		{
85
			$this->object = $config['object'];
86
		}
87
88
		if (isset($config['xss_clean']))
89
		{
90
			$this->xss_clean = $config['xss_clean'];
91
		}
92
	}
93
94
	// --------------------------------------------------------------------
95
96
	/**
97
	 * Setting of System Methods
98
	 *
99
	 * @access	public
100
	 * @return	void
101
	 */
102
	function set_system_methods()
103
	{
104
		$this->methods = array(
105
					'system.listMethods'	 => array(
106
													'function' => 'this.listMethods',
107
													'signature' => array(array($this->xmlrpcArray, $this->xmlrpcString), array($this->xmlrpcArray)),
108
													'docstring' => 'Returns an array of available methods on this server'),
109
					'system.methodHelp'		 => array(
110
													'function' => 'this.methodHelp',
111
													'signature' => array(array($this->xmlrpcString, $this->xmlrpcString)),
112
													'docstring' => 'Returns a documentation string for the specified method'),
113
					'system.methodSignature' => array(
114
													'function' => 'this.methodSignature',
115
													'signature' => array(array($this->xmlrpcArray, $this->xmlrpcString)),
116
													'docstring' => 'Returns an array describing the return type and required parameters of a method'),
117
					'system.multicall'		 => array(
118
												'function' => 'this.multicall',
119
												'signature' => array(array($this->xmlrpcArray, $this->xmlrpcArray)),
120
												'docstring' => 'Combine multiple RPC calls in one request. See http://www.xmlrpc.com/discuss/msgReader$1208 for details')
121
					);
122
	}
123
124
	// --------------------------------------------------------------------
125
126
	/**
127
	 * Main Server Function
128
	 *
129
	 * @access	public
130
	 * @return	void
131
	 */
132
	function serve()
133
	{
134
		$r = $this->parseRequest();
135
		$payload  = '<?xml version="1.0" encoding="'.$this->xmlrpc_defencoding.'"?'.'>'."\n";
136
		$payload .= $this->debug_msg;
137
		$payload .= $r->prepare_response();
138
139
		header("Content-Type: text/xml");
140
		header("Content-Length: ".strlen($payload));
141
		exit($payload);
142
	}
143
144
	// --------------------------------------------------------------------
145
146
	/**
147
	 * Add Method to Class
148
	 *
149
	 * @access	public
150
	 * @param	string	method name
151
	 * @param	string	function
152
	 * @param	string	signature
153
	 * @param	string	docstring
154
	 * @return	void
155
	 */
156
	function add_to_map($methodname, $function, $sig, $doc)
157
	{
158
		$this->methods[$methodname] = array(
159
			'function'  => $function,
160
			'signature' => $sig,
161
			'docstring' => $doc
162
		);
163
	}
164
165
	// --------------------------------------------------------------------
166
167
	/**
168
	 * Parse Server Request
169
	 *
170
	 * @access	public
171
	 * @param	string	data
172
	 * @return	object	xmlrpc response
173
	 */
174
	function parseRequest($data='')
175
	{
176
		global $HTTP_RAW_POST_DATA;
177
178
		//-------------------------------------
179
		//  Get Data
180
		//-------------------------------------
181
182
		if ($data == '')
183
		{
184
			$data = $HTTP_RAW_POST_DATA;
185
		}
186
187
		//-------------------------------------
188
		//  Set up XML Parser
189
		//-------------------------------------
190
191
		$parser = xml_parser_create($this->xmlrpc_defencoding);
192
		$parser_object = new XML_RPC_Message("filler");
193
194
		$parser_object->xh[$parser]					= array();
195
		$parser_object->xh[$parser]['isf']			= 0;
196
		$parser_object->xh[$parser]['isf_reason']	= '';
197
		$parser_object->xh[$parser]['params']		= array();
198
		$parser_object->xh[$parser]['stack']		= array();
199
		$parser_object->xh[$parser]['valuestack']	= array();
200
		$parser_object->xh[$parser]['method']		= '';
201
202
		xml_set_object($parser, $parser_object);
203
		xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true);
204
		xml_set_element_handler($parser, 'open_tag', 'closing_tag');
205
		xml_set_character_data_handler($parser, 'character_data');
206
		//xml_set_default_handler($parser, 'default_handler');
207
208
209
		//-------------------------------------
210
		//  PARSE + PROCESS XML DATA
211
		//-------------------------------------
212
213
		if ( ! xml_parse($parser, $data, 1))
214
		{
215
			// return XML error as a faultCode
216
			$r = new XML_RPC_Response(0,
217
			$this->xmlrpcerrxml + xml_get_error_code($parser),
218
			sprintf('XML error: %s at line %d',
219
				xml_error_string(xml_get_error_code($parser)),
220
				xml_get_current_line_number($parser)));
221
			xml_parser_free($parser);
222
		}
223
		elseif ($parser_object->xh[$parser]['isf'])
224
		{
225
			return new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'], $this->xmlrpcstr['invalid_return']);
226
		}
227
		else
228
		{
229
			xml_parser_free($parser);
230
231
			$m = new XML_RPC_Message($parser_object->xh[$parser]['method']);
232
			$plist='';
233
234
			for ($i=0; $i < count($parser_object->xh[$parser]['params']); $i++)
235
			{
236
				if ($this->debug === TRUE)
237
				{
238
					$plist .= "$i - " .  print_r(get_object_vars($parser_object->xh[$parser]['params'][$i]), TRUE). ";\n";
239
				}
240
241
				$m->addParam($parser_object->xh[$parser]['params'][$i]);
242
			}
243
244
			if ($this->debug === TRUE)
245
			{
246
				echo "<pre>";
247
				echo "---PLIST---\n" . $plist . "\n---PLIST END---\n\n";
248
				echo "</pre>";
249
			}
250
251
			$r = $this->_execute($m);
252
		}
253
254
		//-------------------------------------
255
		//  SET DEBUGGING MESSAGE
256
		//-------------------------------------
257
258
		if ($this->debug === TRUE)
259
		{
260
			$this->debug_msg = "<!-- DEBUG INFO:\n\n".$plist."\n END DEBUG-->\n";
261
		}
262
263
		return $r;
264
	}
265
266
	// --------------------------------------------------------------------
267
268
	/**
269
	 * Executes the Method
270
	 *
271
	 * @access	protected
272
	 * @param	object
273
	 * @return	mixed
274
	 */
275
	function _execute($m)
276
	{
277
		$methName = $m->method_name;
278
279
		// Check to see if it is a system call
280
		$system_call = (strncmp($methName, 'system', 5) == 0) ? TRUE : FALSE;
281
282
		if ($this->xss_clean == FALSE)
283
		{
284
			$m->xss_clean = FALSE;
285
		}
286
287
		//-------------------------------------
288
		//  Valid Method
289
		//-------------------------------------
290
291
		if ( ! isset($this->methods[$methName]['function']))
292
		{
293
			return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']);
294
		}
295
296
		//-------------------------------------
297
		//  Check for Method (and Object)
298
		//-------------------------------------
299
300
		$method_parts = explode(".", $this->methods[$methName]['function']);
301
		$objectCall = (isset($method_parts['1']) && $method_parts['1'] != "") ? TRUE : FALSE;
302
303
		if ($system_call === TRUE)
304
		{
305
			if ( ! is_callable(array($this,$method_parts['1'])))
306
			{
307
				return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']);
308
			}
309
		}
310
		else
311
		{
312
			if ($objectCall && ! is_callable(array($method_parts['0'],$method_parts['1'])))
313
			{
314
				return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']);
315
			}
316
			elseif ( ! $objectCall && ! is_callable($this->methods[$methName]['function']))
317
			{
318
				return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']);
319
			}
320
		}
321
322
		//-------------------------------------
323
		//  Checking Methods Signature
324
		//-------------------------------------
325
326
		if (isset($this->methods[$methName]['signature']))
327
		{
328
			$sig = $this->methods[$methName]['signature'];
329
			for ($i=0; $i<count($sig); $i++)
330
			{
331
				$current_sig = $sig[$i];
332
333
				if (count($current_sig) == count($m->params)+1)
334
				{
335
					for ($n=0; $n < count($m->params); $n++)
336
					{
337
						$p = $m->params[$n];
338
						$pt = ($p->kindOf() == 'scalar') ? $p->scalarval() : $p->kindOf();
339
340
						if ($pt != $current_sig[$n+1])
341
						{
342
							$pno = $n+1;
343
							$wanted = $current_sig[$n+1];
344
345
							return new XML_RPC_Response(0,
346
								$this->xmlrpcerr['incorrect_params'],
347
								$this->xmlrpcstr['incorrect_params'] .
348
								": Wanted {$wanted}, got {$pt} at param {$pno})");
349
						}
350
					}
351
				}
352
			}
353
		}
354
355
		//-------------------------------------
356
		//  Calls the Function
357
		//-------------------------------------
358
359
		if ($objectCall === TRUE)
360
		{
361
			if ($method_parts[0] == "this" && $system_call == TRUE)
362
			{
363
				return call_user_func(array($this, $method_parts[1]), $m);
364
			}
365
			else
366
			{
367
				if ($this->object === FALSE)
368
				{
369
					$CI =& get_instance();
370
					return $CI->$method_parts['1']($m);
371
				}
372
				else
373
				{
374
					return $this->object->$method_parts['1']($m);
375
					//return call_user_func(array(&$method_parts['0'],$method_parts['1']), $m);
376
				}
377
			}
378
		}
379
		else
380
		{
381
			return call_user_func($this->methods[$methName]['function'], $m);
382
		}
383
	}
384
	
385
	// --------------------------------------------------------------------
386
387
	/**
388
	 * Server Function:  List Methods
389
	 *
390
	 * @access	public
391
	 * @param	mixed
392
	 * @return	object
393
	 */
394
	function listMethods($m)
395
	{
396
		$v = new XML_RPC_Values();
397
		$output = array();
398
399
		foreach ($this->methods as $key => $value)
400
		{
401
			$output[] = new XML_RPC_Values($key, 'string');
402
		}
403
404
		foreach ($this->system_methods as $key => $value)
405
		{
406
			$output[]= new XML_RPC_Values($key, 'string');
407
		}
408
409
		$v->addArray($output);
410
		return new XML_RPC_Response($v);
411
	}
412
	
413
	// --------------------------------------------------------------------
414
415
	/**
416
	 * Server Function:  Return Signature for Method
417
	 *
418
	 * @access	public
419
	 * @param	mixed
420
	 * @return	object
421
	 */
422
	function methodSignature($m)
423
	{
424
		$parameters = $m->output_parameters();
425
		$method_name = $parameters[0];
426
427
		if (isset($this->methods[$method_name]))
428
		{
429
			if ($this->methods[$method_name]['signature'])
430
			{
431
				$sigs = array();
432
				$signature = $this->methods[$method_name]['signature'];
433
434
				for ($i=0; $i < count($signature); $i++)
435
				{
436
					$cursig = array();
437
					$inSig = $signature[$i];
438
					for ($j=0; $j<count($inSig); $j++)
439
					{
440
						$cursig[]= new XML_RPC_Values($inSig[$j], 'string');
441
					}
442
					$sigs[]= new XML_RPC_Values($cursig, 'array');
443
				}
444
				$r = new XML_RPC_Response(new XML_RPC_Values($sigs, 'array'));
445
			}
446
			else
447
			{
448
				$r = new XML_RPC_Response(new XML_RPC_Values('undef', 'string'));
449
			}
450
		}
451
		else
452
		{
453
			$r = new XML_RPC_Response(0,$this->xmlrpcerr['introspect_unknown'], $this->xmlrpcstr['introspect_unknown']);
454
		}
455
		return $r;
456
	}
457
458
	// --------------------------------------------------------------------
459
460
	/**
461
	 * Server Function:  Doc String for Method
462
	 *
463
	 * @access	public
464
	 * @param	mixed
465
	 * @return	object
466
	 */
467
	function methodHelp($m)
468
	{
469
		$parameters = $m->output_parameters();
470
		$method_name = $parameters[0];
471
472
		if (isset($this->methods[$method_name]))
473
		{
474
			$docstring = isset($this->methods[$method_name]['docstring']) ? $this->methods[$method_name]['docstring'] : '';
475
476
			return new XML_RPC_Response(new XML_RPC_Values($docstring, 'string'));
477
		}
478
		else
479
		{
480
			return new XML_RPC_Response(0, $this->xmlrpcerr['introspect_unknown'], $this->xmlrpcstr['introspect_unknown']);
481
		}
482
	}
483
	
484
	// --------------------------------------------------------------------
485
486
	/**
487
	 * Server Function:  Multi-call
488
	 *
489
	 * @access	public
490
	 * @param	mixed
491
	 * @return	object
492
	 */
493
	function multicall($m)
494
	{
495
		// Disabled
496
		return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']);
497
498
		$parameters = $m->output_parameters();
499
		$calls = $parameters[0];
500
501
		$result = array();
502
503
		foreach ($calls as $value)
504
		{
505
			//$attempt = $this->_execute(new XML_RPC_Message($value[0], $value[1]));
506
507
			$m = new XML_RPC_Message($value[0]);
508
			$plist='';
509
510
			for ($i=0; $i < count($value[1]); $i++)
511
			{
512
				$m->addParam(new XML_RPC_Values($value[1][$i], 'string'));
513
			}
514
515
			$attempt = $this->_execute($m);
516
517
			if ($attempt->faultCode() != 0)
518
			{
519
				return $attempt;
520
			}
521
522
			$result[] = new XML_RPC_Values(array($attempt->value()), 'array');
523
		}
524
525
		return new XML_RPC_Response(new XML_RPC_Values($result, 'array'));
526
	}
527
528
	// --------------------------------------------------------------------
529
530
	/**
531
	 *  Multi-call Function:  Error Handling
532
	 *
533
	 * @access	public
534
	 * @param	mixed
535
	 * @return	object
536
	 */
537
	function multicall_error($err)
538
	{
539
		$str  = is_string($err) ? $this->xmlrpcstr["multicall_${err}"] : $err->faultString();
540
		$code = is_string($err) ? $this->xmlrpcerr["multicall_${err}"] : $err->faultCode();
541
542
		$struct['faultCode'] = new XML_RPC_Values($code, 'int');
543
		$struct['faultString'] = new XML_RPC_Values($str, 'string');
544
545
		return new XML_RPC_Values($struct, 'struct');
546
	}
547
548
	// --------------------------------------------------------------------
549
550
	/**
551
	 *  Multi-call Function:  Processes method
552
	 *
553
	 * @access	public
554
	 * @param	mixed
555
	 * @return	object
556
	 */
557
	function do_multicall($call)
558
	{
559
		if ($call->kindOf() != 'struct')
560
		{
561
			return $this->multicall_error('notstruct');
562
		}
563
		elseif ( ! $methName = $call->me['struct']['methodName'])
564
		{
565
			return $this->multicall_error('nomethod');
566
		}
567
568
		list($scalar_type,$scalar_value)=each($methName->me);
569
		$scalar_type = $scalar_type == $this->xmlrpcI4 ? $this->xmlrpcInt : $scalar_type;
570
571
		if ($methName->kindOf() != 'scalar' OR $scalar_type != 'string')
572
		{
573
			return $this->multicall_error('notstring');
574
		}
575
		elseif ($scalar_value == 'system.multicall')
576
		{
577
			return $this->multicall_error('recursion');
578
		}
579
		elseif ( ! $params = $call->me['struct']['params'])
580
		{
581
			return $this->multicall_error('noparams');
582
		}
583
		elseif ($params->kindOf() != 'array')
584
		{
585
			return $this->multicall_error('notarray');
586
		}
587
588
		list($a,$b)=each($params->me);
589
		$numParams = count($b);
590
591
		$msg = new XML_RPC_Message($scalar_value);
592
		for ($i = 0; $i < $numParams; $i++)
593
		{
594
			$msg->params[] = $params->me['array'][$i];
595
		}
596
597
		$result = $this->_execute($msg);
598
599
		if ($result->faultCode() != 0)
600
		{
601
			return $this->multicall_error($result);
602
		}
603
604
		return new XML_RPC_Values(array($result->value()), 'array');
605
	}
606
607
}
608
// END XML_RPC_Server class
609
610
611
/* End of file Xmlrpcs.php */
612
/* Location: ./system/libraries/Xmlrpcs.php */