Completed
Push — php51 ( 3c9909...bb9991 )
by Gaetano
10:12
created
lib/xmlrpc_wrappers.inc 3 patches
Indentation   +916 added lines, -916 removed lines patch added patch discarded remove patch
@@ -14,920 +14,920 @@
 block discarded – undo
14 14
  * @todo implement self-parsing of php code for PHP <= 4
15 15
  */
16 16
 
17
-	// requires: xmlrpc.inc
18
-
19
-	/**
20
-	* Given a string defining a php type or phpxmlrpc type (loosely defined: strings
21
-	* accepted come from javadoc blocks), return corresponding phpxmlrpc type.
22
-	* NB: for php 'resource' types returns empty string, since resources cannot be serialized;
23
-	* for php class names returns 'struct', since php objects can be serialized as xmlrpc structs
24
-	* for php arrays always return array, even though arrays sometiles serialize as json structs
25
-	* @param string $phptype
26
-	* @return string
27
-	*/
28
-	function php_2_xmlrpc_type($phptype)
29
-	{
30
-		switch(strtolower($phptype))
31
-		{
32
-			case 'string':
33
-				return $GLOBALS['xmlrpcString'];
34
-			case 'integer':
35
-			case $GLOBALS['xmlrpcInt']: // 'int'
36
-			case $GLOBALS['xmlrpcI4']:
37
-				return $GLOBALS['xmlrpcInt'];
38
-			case 'double':
39
-				return $GLOBALS['xmlrpcDouble'];
40
-			case 'boolean':
41
-				return $GLOBALS['xmlrpcBoolean'];
42
-			case 'array':
43
-				return $GLOBALS['xmlrpcArray'];
44
-			case 'object':
45
-				return $GLOBALS['xmlrpcStruct'];
46
-			case $GLOBALS['xmlrpcBase64']:
47
-			case $GLOBALS['xmlrpcStruct']:
48
-				return strtolower($phptype);
49
-			case 'resource':
50
-				return '';
51
-			default:
52
-				if(class_exists($phptype))
53
-				{
54
-					return $GLOBALS['xmlrpcStruct'];
55
-				}
56
-				else
57
-				{
58
-					// unknown: might be any 'extended' xmlrpc type
59
-					return $GLOBALS['xmlrpcValue'];
60
-				}
61
-		}
62
-	}
63
-
64
-	/**
65
-	* Given a string defining a phpxmlrpc type return corresponding php type.
66
-	* @param string $xmlrpctype
67
-	* @return string
68
-	*/
69
-	function xmlrpc_2_php_type($xmlrpctype)
70
-	{
71
-		switch(strtolower($xmlrpctype))
72
-		{
73
-			case 'base64':
74
-			case 'datetime.iso8601':
75
-			case 'string':
76
-				return $GLOBALS['xmlrpcString'];
77
-			case 'int':
78
-			case 'i4':
79
-				return 'integer';
80
-			case 'struct':
81
-			case 'array':
82
-				return 'array';
83
-			case 'double':
84
-				return 'float';
85
-			case 'undefined':
86
-				return 'mixed';
87
-			case 'boolean':
88
-			case 'null':
89
-			default:
90
-				// unknown: might be any xmlrpc type
91
-				return strtolower($xmlrpctype);
92
-		}
93
-	}
94
-
95
-	/**
96
-	* Given a user-defined PHP function, create a PHP 'wrapper' function that can
97
-	* be exposed as xmlrpc method from an xmlrpc_server object and called from remote
98
-	* clients (as well as its corresponding signature info).
99
-	*
100
-	* Since php is a typeless language, to infer types of input and output parameters,
101
-	* it relies on parsing the javadoc-style comment block associated with the given
102
-	* function. Usage of xmlrpc native types (such as datetime.dateTime.iso8601 and base64)
103
-	* in the @param tag is also allowed, if you need the php function to receive/send
104
-	* data in that particular format (note that base64 encoding/decoding is transparently
105
-	* carried out by the lib, while datetime vals are passed around as strings)
106
-	*
107
-	* Known limitations:
108
-	* - only works for user-defined functions, not for PHP internal functions
109
-	*   (reflection does not support retrieving number/type of params for those)
110
-	* - functions returning php objects will generate special xmlrpc responses:
111
-	*   when the xmlrpc decoding of those responses is carried out by this same lib, using
112
-	*   the appropriate param in php_xmlrpc_decode, the php objects will be rebuilt.
113
-	*   In short: php objects can be serialized, too (except for their resource members),
114
-	*   using this function.
115
-	*   Other libs might choke on the very same xml that will be generated in this case
116
-	*   (i.e. it has a nonstandard attribute on struct element tags)
117
-	* - usage of javadoc @param tags using param names in a different order from the
118
-	*   function prototype is not considered valid (to be fixed?)
119
-	*
120
-	* Note that since rel. 2.0RC3 the preferred method to have the server call 'standard'
121
-	* php functions (ie. functions not expecting a single xmlrpcmsg obj as parameter)
122
-	* is by making use of the functions_parameters_type class member.
123
-	*
124
-	* @param string $funcname the name of the PHP user function to be exposed as xmlrpc method; array($obj, 'methodname') and array('class', 'methodname') are ok too
125
-	* @param string $newfuncname (optional) name for function to be created
126
-	* @param array $extra_options (optional) array of options for conversion. valid values include:
127
-	*        bool  return_source when true, php code w. function definition will be returned, not evaluated
128
-	*        bool  encode_php_objs let php objects be sent to server using the 'improved' xmlrpc notation, so server can deserialize them as php objects
129
-	*        bool  decode_php_objs --- WARNING !!! possible security hazard. only use it with trusted servers ---
130
-	*        bool  suppress_warnings  remove from produced xml any runtime warnings due to the php function being invoked
131
-	* @return false on error, or an array containing the name of the new php function,
132
-	*         its signature and docs, to be used in the server dispatch map
133
-	*
134
-	* @todo decide how to deal with params passed by ref: bomb out or allow?
135
-	* @todo finish using javadoc info to build method sig if all params are named but out of order
136
-	* @todo add a check for params of 'resource' type
137
-	* @todo add some trigger_errors / error_log when returning false?
138
-	* @todo what to do when the PHP function returns NULL? we are currently returning an empty string value...
139
-	* @todo add an option to suppress php warnings in invocation of user function, similar to server debug level 3?
140
-	* @todo if $newfuncname is empty, we could use create_user_func instead of eval, as it is possibly faster
141
-	* @todo add a verbatim_object_copy parameter to allow avoiding the same obj instance?
142
-	*/
143
-	function wrap_php_function($funcname, $newfuncname='', $extra_options=array())
144
-	{
145
-		$buildit = isset($extra_options['return_source']) ? !($extra_options['return_source']) : true;
146
-		$prefix = isset($extra_options['prefix']) ? $extra_options['prefix'] : 'xmlrpc';
147
-		$encode_php_objects = isset($extra_options['encode_php_objs']) ? (bool)$extra_options['encode_php_objs'] : false;
148
-		$decode_php_objects = isset($extra_options['decode_php_objs']) ? (bool)$extra_options['decode_php_objs'] : false;
149
-		$catch_warnings = isset($extra_options['suppress_warnings']) && $extra_options['suppress_warnings'] ? '@' : '';
150
-
151
-		$exists = false;
152
-		if (is_string($funcname) && strpos($funcname, '::') !== false)
153
-		{
154
-			$funcname = explode('::', $funcname);
155
-		}
156
-		if(is_array($funcname))
157
-		{
158
-			if(count($funcname) < 2 || (!is_string($funcname[0]) && !is_object($funcname[0])))
159
-			{
160
-				error_log('XML-RPC: syntax for function to be wrapped is wrong');
161
-				return false;
162
-			}
163
-			if(is_string($funcname[0]))
164
-			{
165
-				$plainfuncname = implode('::', $funcname);
166
-			}
167
-			elseif(is_object($funcname[0]))
168
-			{
169
-				$plainfuncname = get_class($funcname[0]) . '->' . $funcname[1];
170
-			}
171
-			$exists = method_exists($funcname[0], $funcname[1]);
172
-		}
173
-		else
174
-		{
175
-			$plainfuncname = $funcname;
176
-			$exists = function_exists($funcname);
177
-		}
178
-
179
-		if(!$exists)
180
-		{
181
-			error_log('XML-RPC: function to be wrapped is not defined: '.$plainfuncname);
182
-			return false;
183
-		}
184
-		else
185
-		{
186
-			// determine name of new php function
187
-			if($newfuncname == '')
188
-			{
189
-				if(is_array($funcname))
190
-				{
191
-					if(is_string($funcname[0]))
192
-						$xmlrpcfuncname = "{$prefix}_".implode('_', $funcname);
193
-					else
194
-						$xmlrpcfuncname = "{$prefix}_".get_class($funcname[0]) . '_' . $funcname[1];
195
-				}
196
-				else
197
-				{
198
-					$xmlrpcfuncname = "{$prefix}_$funcname";
199
-				}
200
-			}
201
-			else
202
-			{
203
-				$xmlrpcfuncname = $newfuncname;
204
-			}
205
-			while($buildit && function_exists($xmlrpcfuncname))
206
-			{
207
-				$xmlrpcfuncname .= 'x';
208
-			}
209
-
210
-			// start to introspect PHP code
211
-			if(is_array($funcname))
212
-			{
213
-				$func = new ReflectionMethod($funcname[0], $funcname[1]);
214
-				if($func->isPrivate())
215
-				{
216
-					error_log('XML-RPC: method to be wrapped is private: '.$plainfuncname);
217
-					return false;
218
-				}
219
-				if($func->isProtected())
220
-				{
221
-					error_log('XML-RPC: method to be wrapped is protected: '.$plainfuncname);
222
-					return false;
223
-				}
224
-	 			if($func->isConstructor())
225
-				{
226
-					error_log('XML-RPC: method to be wrapped is the constructor: '.$plainfuncname);
227
-					return false;
228
-				}
229
-				if($func->isDestructor())
230
-				{
231
-					error_log('XML-RPC: method to be wrapped is the destructor: '.$plainfuncname);
232
-					return false;
233
-				}
234
-				if($func->isAbstract())
235
-				{
236
-					error_log('XML-RPC: method to be wrapped is abstract: '.$plainfuncname);
237
-					return false;
238
-				}
239
-				/// @todo add more checks for static vs. nonstatic?
240
-			}
241
-			else
242
-			{
243
-				$func = new ReflectionFunction($funcname);
244
-			}
245
-			if($func->isInternal())
246
-			{
247
-				// Note: from PHP 5.1.0 onward, we will possibly be able to use invokeargs
248
-				// instead of getparameters to fully reflect internal php functions ?
249
-				error_log('XML-RPC: function to be wrapped is internal: '.$plainfuncname);
250
-				return false;
251
-			}
252
-
253
-			// retrieve parameter names, types and description from javadoc comments
254
-
255
-			// function description
256
-			$desc = '';
257
-			// type of return val: by default 'any'
258
-			$returns = $GLOBALS['xmlrpcValue'];
259
-			// desc of return val
260
-			$returnsDocs = '';
261
-			// type + name of function parameters
262
-			$paramDocs = array();
263
-
264
-			$docs = $func->getDocComment();
265
-			if($docs != '')
266
-			{
267
-				$docs = explode("\n", $docs);
268
-				$i = 0;
269
-				foreach($docs as $doc)
270
-				{
271
-					$doc = trim($doc, " \r\t/*");
272
-					if(strlen($doc) && strpos($doc, '@') !== 0 && !$i)
273
-					{
274
-						if($desc)
275
-						{
276
-							$desc .= "\n";
277
-						}
278
-						$desc .= $doc;
279
-					}
280
-					elseif(strpos($doc, '@param') === 0)
281
-					{
282
-						// syntax: @param type [$name] desc
283
-						if(preg_match('/@param\s+(\S+)(\s+\$\S+)?\s+(.+)/', $doc, $matches))
284
-						{
285
-							if(strpos($matches[1], '|'))
286
-							{
287
-								//$paramDocs[$i]['type'] = explode('|', $matches[1]);
288
-								$paramDocs[$i]['type'] = 'mixed';
289
-							}
290
-							else
291
-							{
292
-								$paramDocs[$i]['type'] = $matches[1];
293
-							}
294
-							$paramDocs[$i]['name'] = trim($matches[2]);
295
-							$paramDocs[$i]['doc'] = $matches[3];
296
-						}
297
-						$i++;
298
-					}
299
-					elseif(strpos($doc, '@return') === 0)
300
-					{
301
-						// syntax: @return type desc
302
-						//$returns = preg_split('/\s+/', $doc);
303
-						if(preg_match('/@return\s+(\S+)\s+(.+)/', $doc, $matches))
304
-						{
305
-							$returns = php_2_xmlrpc_type($matches[1]);
306
-							if(isset($matches[2]))
307
-							{
308
-								$returnsDocs = $matches[2];
309
-							}
310
-						}
311
-					}
312
-				}
313
-			}
314
-
315
-			// execute introspection of actual function prototype
316
-			$params = array();
317
-			$i = 0;
318
-			foreach($func->getParameters() as $paramobj)
319
-			{
320
-				$params[$i] = array();
321
-				$params[$i]['name'] = '$'.$paramobj->getName();
322
-				$params[$i]['isoptional'] = $paramobj->isOptional();
323
-				$i++;
324
-			}
325
-
326
-			// start  building of PHP code to be eval'd
327
-			$innercode = '';
328
-			$i = 0;
329
-			$parsvariations = array();
330
-			$pars = array();
331
-			$pnum = count($params);
332
-			foreach($params as $param)
333
-			{
334
-				if (isset($paramDocs[$i]['name']) && $paramDocs[$i]['name'] && strtolower($paramDocs[$i]['name']) != strtolower($param['name']))
335
-				{
336
-					// param name from phpdoc info does not match param definition!
337
-					$paramDocs[$i]['type'] = 'mixed';
338
-				}
339
-
340
-				if($param['isoptional'])
341
-				{
342
-					// this particular parameter is optional. save as valid previous list of parameters
343
-					$innercode .= "if (\$paramcount > $i) {\n";
344
-					$parsvariations[] = $pars;
345
-				}
346
-				$innercode .= "\$p$i = \$msg->getParam($i);\n";
347
-				if ($decode_php_objects)
348
-				{
349
-					$innercode .= "if (\$p{$i}->kindOf() == 'scalar') \$p$i = \$p{$i}->scalarval(); else \$p$i = php_{$prefix}_decode(\$p$i, array('decode_php_objs'));\n";
350
-				}
351
-				else
352
-				{
353
-					$innercode .= "if (\$p{$i}->kindOf() == 'scalar') \$p$i = \$p{$i}->scalarval(); else \$p$i = php_{$prefix}_decode(\$p$i);\n";
354
-				}
355
-
356
-				$pars[] = "\$p$i";
357
-				$i++;
358
-				if($param['isoptional'])
359
-				{
360
-					$innercode .= "}\n";
361
-				}
362
-				if($i == $pnum)
363
-				{
364
-					// last allowed parameters combination
365
-					$parsvariations[] = $pars;
366
-				}
367
-			}
368
-
369
-			$sigs = array();
370
-			$psigs = array();
371
-			if(count($parsvariations) == 0)
372
-			{
373
-				// only known good synopsis = no parameters
374
-				$parsvariations[] = array();
375
-				$minpars = 0;
376
-			}
377
-			else
378
-			{
379
-				$minpars = count($parsvariations[0]);
380
-			}
381
-
382
-			if($minpars)
383
-			{
384
-				// add to code the check for min params number
385
-				// NB: this check needs to be done BEFORE decoding param values
386
-				$innercode = "\$paramcount = \$msg->getNumParams();\n" .
387
-				"if (\$paramcount < $minpars) return new {$prefix}resp(0, {$GLOBALS['xmlrpcerr']['incorrect_params']}, '{$GLOBALS['xmlrpcstr']['incorrect_params']}');\n" . $innercode;
388
-			}
389
-			else
390
-			{
391
-				$innercode = "\$paramcount = \$msg->getNumParams();\n" . $innercode;
392
-			}
393
-
394
-			$innercode .= "\$np = false;\n";
395
-			// since there are no closures in php, if we are given an object instance,
396
-			// we store a pointer to it in a global var...
397
-			if ( is_array($funcname) && is_object($funcname[0]) )
398
-			{
399
-				$GLOBALS['xmlrpcWPFObjHolder'][$xmlrpcfuncname] =& $funcname[0];
400
-				$innercode .= "\$obj =& \$GLOBALS['xmlrpcWPFObjHolder']['$xmlrpcfuncname'];\n";
401
-				$realfuncname = '$obj->'.$funcname[1];
402
-			}
403
-			else
404
-			{
405
-				$realfuncname = $plainfuncname;
406
-			}
407
-			foreach($parsvariations as $pars)
408
-			{
409
-				$innercode .= "if (\$paramcount == " . count($pars) . ") \$retval = {$catch_warnings}$realfuncname(" . implode(',', $pars) . "); else\n";
410
-				// build a 'generic' signature (only use an appropriate return type)
411
-				$sig = array($returns);
412
-				$psig = array($returnsDocs);
413
-				for($i=0; $i < count($pars); $i++)
414
-				{
415
-					if (isset($paramDocs[$i]['type']))
416
-					{
417
-						$sig[] = php_2_xmlrpc_type($paramDocs[$i]['type']);
418
-					}
419
-					else
420
-					{
421
-						$sig[] = $GLOBALS['xmlrpcValue'];
422
-					}
423
-					$psig[] = isset($paramDocs[$i]['doc']) ? $paramDocs[$i]['doc'] : '';
424
-				}
425
-				$sigs[] = $sig;
426
-				$psigs[] = $psig;
427
-			}
428
-			$innercode .= "\$np = true;\n";
429
-			$innercode .= "if (\$np) return new {$prefix}resp(0, {$GLOBALS['xmlrpcerr']['incorrect_params']}, '{$GLOBALS['xmlrpcstr']['incorrect_params']}'); else {\n";
430
-			//$innercode .= "if (\$_xmlrpcs_error_occurred) return new xmlrpcresp(0, $GLOBALS['xmlrpcerr']user, \$_xmlrpcs_error_occurred); else\n";
431
-			$innercode .= "if (is_a(\$retval, '{$prefix}resp')) return \$retval; else\n";
432
-			if($returns == $GLOBALS['xmlrpcDateTime'] || $returns == $GLOBALS['xmlrpcBase64'])
433
-			{
434
-				$innercode .= "return new {$prefix}resp(new {$prefix}val(\$retval, '$returns'));";
435
-			}
436
-			else
437
-			{
438
-				if ($encode_php_objects)
439
-					$innercode .= "return new {$prefix}resp(php_{$prefix}_encode(\$retval, array('encode_php_objs')));\n";
440
-				else
441
-					$innercode .= "return new {$prefix}resp(php_{$prefix}_encode(\$retval));\n";
442
-			}
443
-			// shall we exclude functions returning by ref?
444
-			// if($func->returnsReference())
445
-			// 	return false;
446
-			$code = "function $xmlrpcfuncname(\$msg) {\n" . $innercode . "}\n}";
447
-			//print_r($code);
448
-			if ($buildit)
449
-			{
450
-				$allOK = 0;
451
-				eval($code.'$allOK=1;');
452
-				// alternative
453
-				//$xmlrpcfuncname = create_function('$m', $innercode);
454
-
455
-				if(!$allOK)
456
-				{
457
-					error_log('XML-RPC: could not create function '.$xmlrpcfuncname.' to wrap php function '.$plainfuncname);
458
-					return false;
459
-				}
460
-			}
461
-
462
-			/// @todo examine if $paramDocs matches $parsvariations and build array for
463
-			/// usage as method signature, plus put together a nice string for docs
464
-
465
-			$ret = array('function' => $xmlrpcfuncname, 'signature' => $sigs, 'docstring' => $desc, 'signature_docs' => $psigs, 'source' => $code);
466
-			return $ret;
467
-		}
468
-	}
469
-
470
-	/**
471
-	* Given a user-defined PHP class or php object, map its methods onto a list of
472
-	* PHP 'wrapper' functions that can be exposed as xmlrpc methods from an xmlrpc_server
473
-	* object and called from remote clients (as well as their corresponding signature info).
474
-	*
475
-	* @param mixed $classname the name of the class whose methods are to be exposed as xmlrpc methods, or an object instance of that class
476
-	* @param array $extra_options see the docs for wrap_php_method for more options
477
-	*        string method_type 'static', 'nonstatic', 'all' and 'auto' (default); the latter will switch between static and non-static depending on wheter $classname is a class name or object instance
478
-	* @return array or false on failure
479
-	*
480
-	* @todo get_class_methods will return both static and non-static methods.
481
-	*       we have to differentiate the action, depending on whether we received a class name or object
482
-	*/
483
-	function wrap_php_class($classname, $extra_options=array())
484
-	{
485
-		$methodfilter = isset($extra_options['method_filter']) ? $extra_options['method_filter'] : '';
486
-		$methodtype = isset($extra_options['method_type']) ? $extra_options['method_type'] : 'auto';
487
-
488
-		$result = array();
489
-		$mlist = get_class_methods($classname);
490
-		foreach($mlist as $mname)
491
-		{
492
-			if ($methodfilter == '' || preg_match($methodfilter, $mname))
493
-			{
494
-				// echo $mlist."\n";
495
-				$func = new ReflectionMethod($classname, $mname);
496
-				if(!$func->isPrivate() && !$func->isProtected() && !$func->isConstructor() && !$func->isDestructor() && !$func->isAbstract())
497
-				{
498
-					if(($func->isStatic && ($methodtype == 'all' || $methodtype == 'static' || ($methodtype == 'auto' && is_string($classname)))) ||
499
-						(!$func->isStatic && ($methodtype == 'all' || $methodtype == 'nonstatic' || ($methodtype == 'auto' && is_object($classname)))))
500
-					{
501
-						$methodwrap = wrap_php_function(array($classname, $mname), '', $extra_options);
502
-						if ( $methodwrap )
503
-						{
504
-							$result[$methodwrap['function']] = $methodwrap['function'];
505
-						}
506
-					}
507
-				}
508
-			}
509
-		}
510
-		return $result;
511
-	}
512
-
513
-	/**
514
-	* Given an xmlrpc client and a method name, register a php wrapper function
515
-	* that will call it and return results using native php types for both
516
-	* params and results. The generated php function will return an xmlrpcresp
517
-	* object for failed xmlrpc calls
518
-	*
519
-	* Known limitations:
520
-	* - server must support system.methodsignature for the wanted xmlrpc method
521
-	* - for methods that expose many signatures, only one can be picked (we
522
-	*   could in principle check if signatures differ only by number of params
523
-	*   and not by type, but it would be more complication than we can spare time)
524
-	* - nested xmlrpc params: the caller of the generated php function has to
525
-	*   encode on its own the params passed to the php function if these are structs
526
-	*   or arrays whose (sub)members include values of type datetime or base64
527
-	*
528
-	* Notes: the connection properties of the given client will be copied
529
-	* and reused for the connection used during the call to the generated
530
-	* php function.
531
-	* Calling the generated php function 'might' be slow: a new xmlrpc client
532
-	* is created on every invocation and an xmlrpc-connection opened+closed.
533
-	* An extra 'debug' param is appended to param list of xmlrpc method, useful
534
-	* for debugging purposes.
535
-	*
536
-	* @param xmlrpc_client $client     an xmlrpc client set up correctly to communicate with target server
537
-	* @param string        $methodname the xmlrpc method to be mapped to a php function
538
-	* @param array         $extra_options array of options that specify conversion details. valid options include
539
-	*        integer       signum      the index of the method signature to use in mapping (if method exposes many sigs)
540
-	*        integer       timeout     timeout (in secs) to be used when executing function/calling remote method
541
-	*        string        protocol    'http' (default), 'http11' or 'https'
542
-	*        string        new_function_name the name of php function to create. If unspecified, lib will pick an appropriate name
543
-	*        string        return_source if true return php code w. function definition instead fo function name
544
-	*        bool          encode_php_objs let php objects be sent to server using the 'improved' xmlrpc notation, so server can deserialize them as php objects
545
-	*        bool          decode_php_objs --- WARNING !!! possible security hazard. only use it with trusted servers ---
546
-	*        mixed         return_on_fault a php value to be returned when the xmlrpc call fails/returns a fault response (by default the xmlrpcresp object is returned in this case). If a string is used, '%faultCode%' and '%faultString%' tokens will be substituted with actual error values
547
-	*        bool          debug        set it to 1 or 2 to see debug results of querying server for method synopsis
548
-	* @return string                   the name of the generated php function (or false) - OR AN ARRAY...
549
-	*/
550
-	function wrap_xmlrpc_method($client, $methodname, $extra_options=0, $timeout=0, $protocol='', $newfuncname='')
551
-	{
552
-		// mind numbing: let caller use sane calling convention (as per javadoc, 3 params),
553
-		// OR the 2.0 calling convention (no options) - we really love backward compat, don't we?
554
-		if (!is_array($extra_options))
555
-		{
556
-			$signum = $extra_options;
557
-			$extra_options = array();
558
-		}
559
-		else
560
-		{
561
-			$signum = isset($extra_options['signum']) ? (int)$extra_options['signum'] : 0;
562
-			$timeout = isset($extra_options['timeout']) ? (int)$extra_options['timeout'] : 0;
563
-			$protocol = isset($extra_options['protocol']) ? $extra_options['protocol'] : '';
564
-			$newfuncname = isset($extra_options['new_function_name']) ? $extra_options['new_function_name'] : '';
565
-		}
566
-		//$encode_php_objects = in_array('encode_php_objects', $extra_options);
567
-		//$verbatim_client_copy = in_array('simple_client_copy', $extra_options) ? 1 :
568
-		//	in_array('build_class_code', $extra_options) ? 2 : 0;
569
-
570
-		$encode_php_objects = isset($extra_options['encode_php_objs']) ? (bool)$extra_options['encode_php_objs'] : false;
571
-		$decode_php_objects = isset($extra_options['decode_php_objs']) ? (bool)$extra_options['decode_php_objs'] : false;
572
-		// it seems like the meaning of 'simple_client_copy' here is swapped wrt client_copy_mode later on...
573
-		$simple_client_copy = isset($extra_options['simple_client_copy']) ? (int)($extra_options['simple_client_copy']) : 0;
574
-		$buildit = isset($extra_options['return_source']) ? !($extra_options['return_source']) : true;
575
-		$prefix = isset($extra_options['prefix']) ? $extra_options['prefix'] : 'xmlrpc';
576
-		if (isset($extra_options['return_on_fault']))
577
-		{
578
-			$decode_fault = true;
579
-			$fault_response = $extra_options['return_on_fault'];
580
-		}
581
-		else
582
-		{
583
-			$decode_fault = false;
584
-			$fault_response = '';
585
-		}
586
-		$debug = isset($extra_options['debug']) ? ($extra_options['debug']) : 0;
587
-
588
-		$msgclass = $prefix.'msg';
589
-		$valclass = $prefix.'val';
590
-		$decodefunc = 'php_'.$prefix.'_decode';
591
-
592
-		$msg = new $msgclass('system.methodSignature');
593
-		$msg->addparam(new $valclass($methodname));
594
-		$client->setDebug($debug);
595
-		$response =& $client->send($msg, $timeout, $protocol);
596
-		if($response->faultCode())
597
-		{
598
-			error_log('XML-RPC: could not retrieve method signature from remote server for method '.$methodname);
599
-			return false;
600
-		}
601
-		else
602
-		{
603
-			$msig = $response->value();
604
-			if ($client->return_type != 'phpvals')
605
-			{
606
-				$msig = $decodefunc($msig);
607
-			}
608
-			if(!is_array($msig) || count($msig) <= $signum)
609
-			{
610
-				error_log('XML-RPC: could not retrieve method signature nr.'.$signum.' from remote server for method '.$methodname);
611
-				return false;
612
-			}
613
-			else
614
-			{
615
-				// pick a suitable name for the new function, avoiding collisions
616
-				if($newfuncname != '')
617
-				{
618
-					$xmlrpcfuncname = $newfuncname;
619
-				}
620
-				else
621
-				{
622
-					// take care to insure that methodname is translated to valid
623
-					// php function name
624
-					$xmlrpcfuncname = $prefix.'_'.preg_replace(array('/\./', '/[^a-zA-Z0-9_\x7f-\xff]/'),
625
-						array('_', ''), $methodname);
626
-				}
627
-				while($buildit && function_exists($xmlrpcfuncname))
628
-				{
629
-					$xmlrpcfuncname .= 'x';
630
-				}
631
-
632
-				$msig = $msig[$signum];
633
-				$mdesc = '';
634
-				// if in 'offline' mode, get method description too.
635
-				// in online mode, favour speed of operation
636
-				if(!$buildit)
637
-				{
638
-					$msg = new $msgclass('system.methodHelp');
639
-					$msg->addparam(new $valclass($methodname));
640
-					$response =& $client->send($msg, $timeout, $protocol);
641
-					if (!$response->faultCode())
642
-					{
643
-						$mdesc = $response->value();
644
-						if ($client->return_type != 'phpvals')
645
-						{
646
-							$mdesc = $mdesc->scalarval();
647
-						}
648
-					}
649
-				}
650
-
651
-				$results = build_remote_method_wrapper_code($client, $methodname,
652
-					$xmlrpcfuncname, $msig, $mdesc, $timeout, $protocol, $simple_client_copy,
653
-					$prefix, $decode_php_objects, $encode_php_objects, $decode_fault,
654
-					$fault_response);
655
-
656
-				//print_r($code);
657
-				if ($buildit)
658
-				{
659
-					$allOK = 0;
660
-					eval($results['source'].'$allOK=1;');
661
-					// alternative
662
-					//$xmlrpcfuncname = create_function('$m', $innercode);
663
-					if($allOK)
664
-					{
665
-						return $xmlrpcfuncname;
666
-					}
667
-					else
668
-					{
669
-						error_log('XML-RPC: could not create function '.$xmlrpcfuncname.' to wrap remote method '.$methodname);
670
-						return false;
671
-					}
672
-				}
673
-				else
674
-				{
675
-					$results['function'] = $xmlrpcfuncname;
676
-					return $results;
677
-				}
678
-			}
679
-		}
680
-	}
681
-
682
-	/**
683
-	* Similar to wrap_xmlrpc_method, but will generate a php class that wraps
684
-	* all xmlrpc methods exposed by the remote server as own methods.
685
-	* For more details see wrap_xmlrpc_method.
686
-	* @param xmlrpc_client $client the client obj all set to query the desired server
687
-	* @param array $extra_options list of options for wrapped code
688
-	* @return mixed false on error, the name of the created class if all ok or an array with code, class name and comments (if the appropriatevoption is set in extra_options)
689
-	*/
690
-	function wrap_xmlrpc_server($client, $extra_options=array())
691
-	{
692
-		$methodfilter = isset($extra_options['method_filter']) ? $extra_options['method_filter'] : '';
693
-		//$signum = isset($extra_options['signum']) ? (int)$extra_options['signum'] : 0;
694
-		$timeout = isset($extra_options['timeout']) ? (int)$extra_options['timeout'] : 0;
695
-		$protocol = isset($extra_options['protocol']) ? $extra_options['protocol'] : '';
696
-		$newclassname = isset($extra_options['new_class_name']) ? $extra_options['new_class_name'] : '';
697
-		$encode_php_objects = isset($extra_options['encode_php_objs']) ? (bool)$extra_options['encode_php_objs'] : false;
698
-		$decode_php_objects = isset($extra_options['decode_php_objs']) ? (bool)$extra_options['decode_php_objs'] : false;
699
-		$verbatim_client_copy = isset($extra_options['simple_client_copy']) ? !($extra_options['simple_client_copy']) : true;
700
-		$buildit = isset($extra_options['return_source']) ? !($extra_options['return_source']) : true;
701
-		$prefix = isset($extra_options['prefix']) ? $extra_options['prefix'] : 'xmlrpc';
702
-
703
-		$msgclass = $prefix.'msg';
704
-		//$valclass = $prefix.'val';
705
-		$decodefunc = 'php_'.$prefix.'_decode';
706
-
707
-		$msg = new $msgclass('system.listMethods');
708
-		$response =& $client->send($msg, $timeout, $protocol);
709
-		if($response->faultCode())
710
-		{
711
-			error_log('XML-RPC: could not retrieve method list from remote server');
712
-			return false;
713
-		}
714
-		else
715
-		{
716
-			$mlist = $response->value();
717
-			if ($client->return_type != 'phpvals')
718
-			{
719
-				$mlist = $decodefunc($mlist);
720
-			}
721
-			if(!is_array($mlist) || !count($mlist))
722
-			{
723
-				error_log('XML-RPC: could not retrieve meaningful method list from remote server');
724
-				return false;
725
-			}
726
-			else
727
-			{
728
-				// pick a suitable name for the new function, avoiding collisions
729
-				if($newclassname != '')
730
-				{
731
-					$xmlrpcclassname = $newclassname;
732
-				}
733
-				else
734
-				{
735
-					$xmlrpcclassname = $prefix.'_'.preg_replace(array('/\./', '/[^a-zA-Z0-9_\x7f-\xff]/'),
736
-						array('_', ''), $client->server).'_client';
737
-				}
738
-				while($buildit && class_exists($xmlrpcclassname))
739
-				{
740
-					$xmlrpcclassname .= 'x';
741
-				}
742
-
743
-				/// @todo add function setdebug() to new class, to enable/disable debugging
744
-				$source = "class $xmlrpcclassname\n{\nvar \$client;\n\n";
745
-				$source .= "function $xmlrpcclassname()\n{\n";
746
-				$source .= build_client_wrapper_code($client, $verbatim_client_copy, $prefix);
747
-				$source .= "\$this->client =& \$client;\n}\n\n";
748
-				$opts = array('simple_client_copy' => 2, 'return_source' => true,
749
-					'timeout' => $timeout, 'protocol' => $protocol,
750
-					'encode_php_objs' => $encode_php_objects, 'prefix' => $prefix,
751
-					'decode_php_objs' => $decode_php_objects
752
-					);
753
-				/// @todo build javadoc for class definition, too
754
-				foreach($mlist as $mname)
755
-				{
756
-					if ($methodfilter == '' || preg_match($methodfilter, $mname))
757
-					{
758
-						$opts['new_function_name'] = preg_replace(array('/\./', '/[^a-zA-Z0-9_\x7f-\xff]/'),
759
-							array('_', ''), $mname);
760
-						$methodwrap = wrap_xmlrpc_method($client, $mname, $opts);
761
-						if ($methodwrap)
762
-						{
763
-							if (!$buildit)
764
-							{
765
-								$source .= $methodwrap['docstring'];
766
-							}
767
-							$source .= $methodwrap['source']."\n";
768
-						}
769
-						else
770
-						{
771
-							error_log('XML-RPC: will not create class method to wrap remote method '.$mname);
772
-						}
773
-					}
774
-				}
775
-				$source .= "}\n";
776
-				if ($buildit)
777
-				{
778
-					$allOK = 0;
779
-					eval($source.'$allOK=1;');
780
-					// alternative
781
-					//$xmlrpcfuncname = create_function('$m', $innercode);
782
-					if($allOK)
783
-					{
784
-						return $xmlrpcclassname;
785
-					}
786
-					else
787
-					{
788
-						error_log('XML-RPC: could not create class '.$xmlrpcclassname.' to wrap remote server '.$client->server);
789
-						return false;
790
-					}
791
-				}
792
-				else
793
-				{
794
-					return array('class' => $xmlrpcclassname, 'code' => $source, 'docstring' => '');
795
-				}
796
-			}
797
-		}
798
-	}
799
-
800
-	/**
801
-	* Given the necessary info, build php code that creates a new function to
802
-	* invoke a remote xmlrpc method.
803
-	* Take care that no full checking of input parameters is done to ensure that
804
-	* valid php code is emitted.
805
-	* Note: real spaghetti code follows...
806
-	* @access private
807
-	*/
808
-	function build_remote_method_wrapper_code($client, $methodname, $xmlrpcfuncname,
809
-		$msig, $mdesc='', $timeout=0, $protocol='', $client_copy_mode=0, $prefix='xmlrpc',
810
-		$decode_php_objects=false, $encode_php_objects=false, $decode_fault=false,
811
-		$fault_response='')
812
-	{
813
-		$code = "function $xmlrpcfuncname (";
814
-		if ($client_copy_mode < 2)
815
-		{
816
-			// client copy mode 0 or 1 == partial / full client copy in emitted code
817
-			$innercode = build_client_wrapper_code($client, $client_copy_mode, $prefix);
818
-			$innercode .= "\$client->setDebug(\$debug);\n";
819
-			$this_ = '';
820
-		}
821
-		else
822
-		{
823
-			// client copy mode 2 == no client copy in emitted code
824
-			$innercode = '';
825
-			$this_ = 'this->';
826
-		}
827
-		$innercode .= "\$msg = new {$prefix}msg('$methodname');\n";
828
-
829
-		if ($mdesc != '')
830
-		{
831
-			// take care that PHP comment is not terminated unwillingly by method description
832
-			$mdesc = "/**\n* ".str_replace('*/', '* /', $mdesc)."\n";
833
-		}
834
-		else
835
-		{
836
-			$mdesc = "/**\nFunction $xmlrpcfuncname\n";
837
-		}
838
-
839
-		// param parsing
840
-		$plist = array();
841
-		$pcount = count($msig);
842
-		for($i = 1; $i < $pcount; $i++)
843
-		{
844
-			$plist[] = "\$p$i";
845
-			$ptype = $msig[$i];
846
-			if($ptype == 'i4' || $ptype == 'int' || $ptype == 'boolean' || $ptype == 'double' ||
847
-				$ptype == 'string' || $ptype == 'dateTime.iso8601' || $ptype == 'base64' || $ptype == 'null')
848
-			{
849
-				// only build directly xmlrpcvals when type is known and scalar
850
-				$innercode .= "\$p$i = new {$prefix}val(\$p$i, '$ptype');\n";
851
-			}
852
-			else
853
-			{
854
-				if ($encode_php_objects)
855
-				{
856
-					$innercode .= "\$p$i =& php_{$prefix}_encode(\$p$i, array('encode_php_objs'));\n";
857
-				}
858
-				else
859
-				{
860
-					$innercode .= "\$p$i =& php_{$prefix}_encode(\$p$i);\n";
861
-				}
862
-			}
863
-			$innercode .= "\$msg->addparam(\$p$i);\n";
864
-			$mdesc .= '* @param '.xmlrpc_2_php_type($ptype)." \$p$i\n";
865
-		}
866
-		if ($client_copy_mode < 2)
867
-		{
868
-			$plist[] = '$debug=0';
869
-			$mdesc .= "* @param int \$debug when 1 (or 2) will enable debugging of the underlying {$prefix} call (defaults to 0)\n";
870
-		}
871
-		$plist = implode(', ', $plist);
872
-		$mdesc .= '* @return '.xmlrpc_2_php_type($msig[0])." (or an {$prefix}resp obj instance if call fails)\n*/\n";
873
-
874
-		$innercode .= "\$res =& \${$this_}client->send(\$msg, $timeout, '$protocol');\n";
875
-		if ($decode_fault)
876
-		{
877
-			if (is_string($fault_response) && ((strpos($fault_response, '%faultCode%') !== false) || (strpos($fault_response, '%faultString%') !== false)))
878
-			{
879
-				$respcode = "str_replace(array('%faultCode%', '%faultString%'), array(\$res->faultCode(), \$res->faultString()), '".str_replace("'", "''", $fault_response)."')";
880
-			}
881
-			else
882
-			{
883
-				$respcode = var_export($fault_response, true);
884
-			}
885
-		}
886
-		else
887
-		{
888
-			$respcode = '$res';
889
-		}
890
-		if ($decode_php_objects)
891
-		{
892
-			$innercode .= "if (\$res->faultcode()) return $respcode; else return php_{$prefix}_decode(\$res->value(), array('decode_php_objs'));";
893
-		}
894
-		else
895
-		{
896
-			$innercode .= "if (\$res->faultcode()) return $respcode; else return php_{$prefix}_decode(\$res->value());";
897
-		}
898
-
899
-		$code = $code . $plist. ") {\n" . $innercode . "\n}\n";
900
-
901
-		return array('source' => $code, 'docstring' => $mdesc);
902
-	}
903
-
904
-	/**
905
-	* Given necessary info, generate php code that will rebuild a client object
906
-	* Take care that no full checking of input parameters is done to ensure that
907
-	* valid php code is emitted.
908
-	* @access private
909
-	*/
910
-	function build_client_wrapper_code($client, $verbatim_client_copy, $prefix='xmlrpc')
911
-	{
912
-		$code = "\$client = new {$prefix}_client('".str_replace("'", "\'", $client->path).
913
-			"', '" . str_replace("'", "\'", $client->server) . "', $client->port);\n";
914
-
915
-		// copy all client fields to the client that will be generated runtime
916
-		// (this provides for future expansion or subclassing of client obj)
917
-		if ($verbatim_client_copy)
918
-		{
919
-			foreach($client as $fld => $val)
920
-			{
921
-				if($fld != 'debug' && $fld != 'return_type')
922
-				{
923
-					$val = var_export($val, true);
924
-					$code .= "\$client->$fld = $val;\n";
925
-				}
926
-			}
927
-		}
928
-		// only make sure that client always returns the correct data type
929
-		$code .= "\$client->return_type = '{$prefix}vals';\n";
930
-		//$code .= "\$client->setDebug(\$debug);\n";
931
-		return $code;
932
-	}
17
+    // requires: xmlrpc.inc
18
+
19
+    /**
20
+     * Given a string defining a php type or phpxmlrpc type (loosely defined: strings
21
+     * accepted come from javadoc blocks), return corresponding phpxmlrpc type.
22
+     * NB: for php 'resource' types returns empty string, since resources cannot be serialized;
23
+     * for php class names returns 'struct', since php objects can be serialized as xmlrpc structs
24
+     * for php arrays always return array, even though arrays sometiles serialize as json structs
25
+     * @param string $phptype
26
+     * @return string
27
+     */
28
+    function php_2_xmlrpc_type($phptype)
29
+    {
30
+        switch(strtolower($phptype))
31
+        {
32
+            case 'string':
33
+                return $GLOBALS['xmlrpcString'];
34
+            case 'integer':
35
+            case $GLOBALS['xmlrpcInt']: // 'int'
36
+            case $GLOBALS['xmlrpcI4']:
37
+                return $GLOBALS['xmlrpcInt'];
38
+            case 'double':
39
+                return $GLOBALS['xmlrpcDouble'];
40
+            case 'boolean':
41
+                return $GLOBALS['xmlrpcBoolean'];
42
+            case 'array':
43
+                return $GLOBALS['xmlrpcArray'];
44
+            case 'object':
45
+                return $GLOBALS['xmlrpcStruct'];
46
+            case $GLOBALS['xmlrpcBase64']:
47
+            case $GLOBALS['xmlrpcStruct']:
48
+                return strtolower($phptype);
49
+            case 'resource':
50
+                return '';
51
+            default:
52
+                if(class_exists($phptype))
53
+                {
54
+                    return $GLOBALS['xmlrpcStruct'];
55
+                }
56
+                else
57
+                {
58
+                    // unknown: might be any 'extended' xmlrpc type
59
+                    return $GLOBALS['xmlrpcValue'];
60
+                }
61
+        }
62
+    }
63
+
64
+    /**
65
+     * Given a string defining a phpxmlrpc type return corresponding php type.
66
+     * @param string $xmlrpctype
67
+     * @return string
68
+     */
69
+    function xmlrpc_2_php_type($xmlrpctype)
70
+    {
71
+        switch(strtolower($xmlrpctype))
72
+        {
73
+            case 'base64':
74
+            case 'datetime.iso8601':
75
+            case 'string':
76
+                return $GLOBALS['xmlrpcString'];
77
+            case 'int':
78
+            case 'i4':
79
+                return 'integer';
80
+            case 'struct':
81
+            case 'array':
82
+                return 'array';
83
+            case 'double':
84
+                return 'float';
85
+            case 'undefined':
86
+                return 'mixed';
87
+            case 'boolean':
88
+            case 'null':
89
+            default:
90
+                // unknown: might be any xmlrpc type
91
+                return strtolower($xmlrpctype);
92
+        }
93
+    }
94
+
95
+    /**
96
+     * Given a user-defined PHP function, create a PHP 'wrapper' function that can
97
+     * be exposed as xmlrpc method from an xmlrpc_server object and called from remote
98
+     * clients (as well as its corresponding signature info).
99
+     *
100
+     * Since php is a typeless language, to infer types of input and output parameters,
101
+     * it relies on parsing the javadoc-style comment block associated with the given
102
+     * function. Usage of xmlrpc native types (such as datetime.dateTime.iso8601 and base64)
103
+     * in the @param tag is also allowed, if you need the php function to receive/send
104
+     * data in that particular format (note that base64 encoding/decoding is transparently
105
+     * carried out by the lib, while datetime vals are passed around as strings)
106
+     *
107
+     * Known limitations:
108
+     * - only works for user-defined functions, not for PHP internal functions
109
+     *   (reflection does not support retrieving number/type of params for those)
110
+     * - functions returning php objects will generate special xmlrpc responses:
111
+     *   when the xmlrpc decoding of those responses is carried out by this same lib, using
112
+     *   the appropriate param in php_xmlrpc_decode, the php objects will be rebuilt.
113
+     *   In short: php objects can be serialized, too (except for their resource members),
114
+     *   using this function.
115
+     *   Other libs might choke on the very same xml that will be generated in this case
116
+     *   (i.e. it has a nonstandard attribute on struct element tags)
117
+     * - usage of javadoc @param tags using param names in a different order from the
118
+     *   function prototype is not considered valid (to be fixed?)
119
+     *
120
+     * Note that since rel. 2.0RC3 the preferred method to have the server call 'standard'
121
+     * php functions (ie. functions not expecting a single xmlrpcmsg obj as parameter)
122
+     * is by making use of the functions_parameters_type class member.
123
+     *
124
+     * @param string $funcname the name of the PHP user function to be exposed as xmlrpc method; array($obj, 'methodname') and array('class', 'methodname') are ok too
125
+     * @param string $newfuncname (optional) name for function to be created
126
+     * @param array $extra_options (optional) array of options for conversion. valid values include:
127
+     *        bool  return_source when true, php code w. function definition will be returned, not evaluated
128
+     *        bool  encode_php_objs let php objects be sent to server using the 'improved' xmlrpc notation, so server can deserialize them as php objects
129
+     *        bool  decode_php_objs --- WARNING !!! possible security hazard. only use it with trusted servers ---
130
+     *        bool  suppress_warnings  remove from produced xml any runtime warnings due to the php function being invoked
131
+     * @return false on error, or an array containing the name of the new php function,
132
+     *         its signature and docs, to be used in the server dispatch map
133
+     *
134
+     * @todo decide how to deal with params passed by ref: bomb out or allow?
135
+     * @todo finish using javadoc info to build method sig if all params are named but out of order
136
+     * @todo add a check for params of 'resource' type
137
+     * @todo add some trigger_errors / error_log when returning false?
138
+     * @todo what to do when the PHP function returns NULL? we are currently returning an empty string value...
139
+     * @todo add an option to suppress php warnings in invocation of user function, similar to server debug level 3?
140
+     * @todo if $newfuncname is empty, we could use create_user_func instead of eval, as it is possibly faster
141
+     * @todo add a verbatim_object_copy parameter to allow avoiding the same obj instance?
142
+     */
143
+    function wrap_php_function($funcname, $newfuncname='', $extra_options=array())
144
+    {
145
+        $buildit = isset($extra_options['return_source']) ? !($extra_options['return_source']) : true;
146
+        $prefix = isset($extra_options['prefix']) ? $extra_options['prefix'] : 'xmlrpc';
147
+        $encode_php_objects = isset($extra_options['encode_php_objs']) ? (bool)$extra_options['encode_php_objs'] : false;
148
+        $decode_php_objects = isset($extra_options['decode_php_objs']) ? (bool)$extra_options['decode_php_objs'] : false;
149
+        $catch_warnings = isset($extra_options['suppress_warnings']) && $extra_options['suppress_warnings'] ? '@' : '';
150
+
151
+        $exists = false;
152
+        if (is_string($funcname) && strpos($funcname, '::') !== false)
153
+        {
154
+            $funcname = explode('::', $funcname);
155
+        }
156
+        if(is_array($funcname))
157
+        {
158
+            if(count($funcname) < 2 || (!is_string($funcname[0]) && !is_object($funcname[0])))
159
+            {
160
+                error_log('XML-RPC: syntax for function to be wrapped is wrong');
161
+                return false;
162
+            }
163
+            if(is_string($funcname[0]))
164
+            {
165
+                $plainfuncname = implode('::', $funcname);
166
+            }
167
+            elseif(is_object($funcname[0]))
168
+            {
169
+                $plainfuncname = get_class($funcname[0]) . '->' . $funcname[1];
170
+            }
171
+            $exists = method_exists($funcname[0], $funcname[1]);
172
+        }
173
+        else
174
+        {
175
+            $plainfuncname = $funcname;
176
+            $exists = function_exists($funcname);
177
+        }
178
+
179
+        if(!$exists)
180
+        {
181
+            error_log('XML-RPC: function to be wrapped is not defined: '.$plainfuncname);
182
+            return false;
183
+        }
184
+        else
185
+        {
186
+            // determine name of new php function
187
+            if($newfuncname == '')
188
+            {
189
+                if(is_array($funcname))
190
+                {
191
+                    if(is_string($funcname[0]))
192
+                        $xmlrpcfuncname = "{$prefix}_".implode('_', $funcname);
193
+                    else
194
+                        $xmlrpcfuncname = "{$prefix}_".get_class($funcname[0]) . '_' . $funcname[1];
195
+                }
196
+                else
197
+                {
198
+                    $xmlrpcfuncname = "{$prefix}_$funcname";
199
+                }
200
+            }
201
+            else
202
+            {
203
+                $xmlrpcfuncname = $newfuncname;
204
+            }
205
+            while($buildit && function_exists($xmlrpcfuncname))
206
+            {
207
+                $xmlrpcfuncname .= 'x';
208
+            }
209
+
210
+            // start to introspect PHP code
211
+            if(is_array($funcname))
212
+            {
213
+                $func = new ReflectionMethod($funcname[0], $funcname[1]);
214
+                if($func->isPrivate())
215
+                {
216
+                    error_log('XML-RPC: method to be wrapped is private: '.$plainfuncname);
217
+                    return false;
218
+                }
219
+                if($func->isProtected())
220
+                {
221
+                    error_log('XML-RPC: method to be wrapped is protected: '.$plainfuncname);
222
+                    return false;
223
+                }
224
+                    if($func->isConstructor())
225
+                {
226
+                    error_log('XML-RPC: method to be wrapped is the constructor: '.$plainfuncname);
227
+                    return false;
228
+                }
229
+                if($func->isDestructor())
230
+                {
231
+                    error_log('XML-RPC: method to be wrapped is the destructor: '.$plainfuncname);
232
+                    return false;
233
+                }
234
+                if($func->isAbstract())
235
+                {
236
+                    error_log('XML-RPC: method to be wrapped is abstract: '.$plainfuncname);
237
+                    return false;
238
+                }
239
+                /// @todo add more checks for static vs. nonstatic?
240
+            }
241
+            else
242
+            {
243
+                $func = new ReflectionFunction($funcname);
244
+            }
245
+            if($func->isInternal())
246
+            {
247
+                // Note: from PHP 5.1.0 onward, we will possibly be able to use invokeargs
248
+                // instead of getparameters to fully reflect internal php functions ?
249
+                error_log('XML-RPC: function to be wrapped is internal: '.$plainfuncname);
250
+                return false;
251
+            }
252
+
253
+            // retrieve parameter names, types and description from javadoc comments
254
+
255
+            // function description
256
+            $desc = '';
257
+            // type of return val: by default 'any'
258
+            $returns = $GLOBALS['xmlrpcValue'];
259
+            // desc of return val
260
+            $returnsDocs = '';
261
+            // type + name of function parameters
262
+            $paramDocs = array();
263
+
264
+            $docs = $func->getDocComment();
265
+            if($docs != '')
266
+            {
267
+                $docs = explode("\n", $docs);
268
+                $i = 0;
269
+                foreach($docs as $doc)
270
+                {
271
+                    $doc = trim($doc, " \r\t/*");
272
+                    if(strlen($doc) && strpos($doc, '@') !== 0 && !$i)
273
+                    {
274
+                        if($desc)
275
+                        {
276
+                            $desc .= "\n";
277
+                        }
278
+                        $desc .= $doc;
279
+                    }
280
+                    elseif(strpos($doc, '@param') === 0)
281
+                    {
282
+                        // syntax: @param type [$name] desc
283
+                        if(preg_match('/@param\s+(\S+)(\s+\$\S+)?\s+(.+)/', $doc, $matches))
284
+                        {
285
+                            if(strpos($matches[1], '|'))
286
+                            {
287
+                                //$paramDocs[$i]['type'] = explode('|', $matches[1]);
288
+                                $paramDocs[$i]['type'] = 'mixed';
289
+                            }
290
+                            else
291
+                            {
292
+                                $paramDocs[$i]['type'] = $matches[1];
293
+                            }
294
+                            $paramDocs[$i]['name'] = trim($matches[2]);
295
+                            $paramDocs[$i]['doc'] = $matches[3];
296
+                        }
297
+                        $i++;
298
+                    }
299
+                    elseif(strpos($doc, '@return') === 0)
300
+                    {
301
+                        // syntax: @return type desc
302
+                        //$returns = preg_split('/\s+/', $doc);
303
+                        if(preg_match('/@return\s+(\S+)\s+(.+)/', $doc, $matches))
304
+                        {
305
+                            $returns = php_2_xmlrpc_type($matches[1]);
306
+                            if(isset($matches[2]))
307
+                            {
308
+                                $returnsDocs = $matches[2];
309
+                            }
310
+                        }
311
+                    }
312
+                }
313
+            }
314
+
315
+            // execute introspection of actual function prototype
316
+            $params = array();
317
+            $i = 0;
318
+            foreach($func->getParameters() as $paramobj)
319
+            {
320
+                $params[$i] = array();
321
+                $params[$i]['name'] = '$'.$paramobj->getName();
322
+                $params[$i]['isoptional'] = $paramobj->isOptional();
323
+                $i++;
324
+            }
325
+
326
+            // start  building of PHP code to be eval'd
327
+            $innercode = '';
328
+            $i = 0;
329
+            $parsvariations = array();
330
+            $pars = array();
331
+            $pnum = count($params);
332
+            foreach($params as $param)
333
+            {
334
+                if (isset($paramDocs[$i]['name']) && $paramDocs[$i]['name'] && strtolower($paramDocs[$i]['name']) != strtolower($param['name']))
335
+                {
336
+                    // param name from phpdoc info does not match param definition!
337
+                    $paramDocs[$i]['type'] = 'mixed';
338
+                }
339
+
340
+                if($param['isoptional'])
341
+                {
342
+                    // this particular parameter is optional. save as valid previous list of parameters
343
+                    $innercode .= "if (\$paramcount > $i) {\n";
344
+                    $parsvariations[] = $pars;
345
+                }
346
+                $innercode .= "\$p$i = \$msg->getParam($i);\n";
347
+                if ($decode_php_objects)
348
+                {
349
+                    $innercode .= "if (\$p{$i}->kindOf() == 'scalar') \$p$i = \$p{$i}->scalarval(); else \$p$i = php_{$prefix}_decode(\$p$i, array('decode_php_objs'));\n";
350
+                }
351
+                else
352
+                {
353
+                    $innercode .= "if (\$p{$i}->kindOf() == 'scalar') \$p$i = \$p{$i}->scalarval(); else \$p$i = php_{$prefix}_decode(\$p$i);\n";
354
+                }
355
+
356
+                $pars[] = "\$p$i";
357
+                $i++;
358
+                if($param['isoptional'])
359
+                {
360
+                    $innercode .= "}\n";
361
+                }
362
+                if($i == $pnum)
363
+                {
364
+                    // last allowed parameters combination
365
+                    $parsvariations[] = $pars;
366
+                }
367
+            }
368
+
369
+            $sigs = array();
370
+            $psigs = array();
371
+            if(count($parsvariations) == 0)
372
+            {
373
+                // only known good synopsis = no parameters
374
+                $parsvariations[] = array();
375
+                $minpars = 0;
376
+            }
377
+            else
378
+            {
379
+                $minpars = count($parsvariations[0]);
380
+            }
381
+
382
+            if($minpars)
383
+            {
384
+                // add to code the check for min params number
385
+                // NB: this check needs to be done BEFORE decoding param values
386
+                $innercode = "\$paramcount = \$msg->getNumParams();\n" .
387
+                "if (\$paramcount < $minpars) return new {$prefix}resp(0, {$GLOBALS['xmlrpcerr']['incorrect_params']}, '{$GLOBALS['xmlrpcstr']['incorrect_params']}');\n" . $innercode;
388
+            }
389
+            else
390
+            {
391
+                $innercode = "\$paramcount = \$msg->getNumParams();\n" . $innercode;
392
+            }
393
+
394
+            $innercode .= "\$np = false;\n";
395
+            // since there are no closures in php, if we are given an object instance,
396
+            // we store a pointer to it in a global var...
397
+            if ( is_array($funcname) && is_object($funcname[0]) )
398
+            {
399
+                $GLOBALS['xmlrpcWPFObjHolder'][$xmlrpcfuncname] =& $funcname[0];
400
+                $innercode .= "\$obj =& \$GLOBALS['xmlrpcWPFObjHolder']['$xmlrpcfuncname'];\n";
401
+                $realfuncname = '$obj->'.$funcname[1];
402
+            }
403
+            else
404
+            {
405
+                $realfuncname = $plainfuncname;
406
+            }
407
+            foreach($parsvariations as $pars)
408
+            {
409
+                $innercode .= "if (\$paramcount == " . count($pars) . ") \$retval = {$catch_warnings}$realfuncname(" . implode(',', $pars) . "); else\n";
410
+                // build a 'generic' signature (only use an appropriate return type)
411
+                $sig = array($returns);
412
+                $psig = array($returnsDocs);
413
+                for($i=0; $i < count($pars); $i++)
414
+                {
415
+                    if (isset($paramDocs[$i]['type']))
416
+                    {
417
+                        $sig[] = php_2_xmlrpc_type($paramDocs[$i]['type']);
418
+                    }
419
+                    else
420
+                    {
421
+                        $sig[] = $GLOBALS['xmlrpcValue'];
422
+                    }
423
+                    $psig[] = isset($paramDocs[$i]['doc']) ? $paramDocs[$i]['doc'] : '';
424
+                }
425
+                $sigs[] = $sig;
426
+                $psigs[] = $psig;
427
+            }
428
+            $innercode .= "\$np = true;\n";
429
+            $innercode .= "if (\$np) return new {$prefix}resp(0, {$GLOBALS['xmlrpcerr']['incorrect_params']}, '{$GLOBALS['xmlrpcstr']['incorrect_params']}'); else {\n";
430
+            //$innercode .= "if (\$_xmlrpcs_error_occurred) return new xmlrpcresp(0, $GLOBALS['xmlrpcerr']user, \$_xmlrpcs_error_occurred); else\n";
431
+            $innercode .= "if (is_a(\$retval, '{$prefix}resp')) return \$retval; else\n";
432
+            if($returns == $GLOBALS['xmlrpcDateTime'] || $returns == $GLOBALS['xmlrpcBase64'])
433
+            {
434
+                $innercode .= "return new {$prefix}resp(new {$prefix}val(\$retval, '$returns'));";
435
+            }
436
+            else
437
+            {
438
+                if ($encode_php_objects)
439
+                    $innercode .= "return new {$prefix}resp(php_{$prefix}_encode(\$retval, array('encode_php_objs')));\n";
440
+                else
441
+                    $innercode .= "return new {$prefix}resp(php_{$prefix}_encode(\$retval));\n";
442
+            }
443
+            // shall we exclude functions returning by ref?
444
+            // if($func->returnsReference())
445
+            // 	return false;
446
+            $code = "function $xmlrpcfuncname(\$msg) {\n" . $innercode . "}\n}";
447
+            //print_r($code);
448
+            if ($buildit)
449
+            {
450
+                $allOK = 0;
451
+                eval($code.'$allOK=1;');
452
+                // alternative
453
+                //$xmlrpcfuncname = create_function('$m', $innercode);
454
+
455
+                if(!$allOK)
456
+                {
457
+                    error_log('XML-RPC: could not create function '.$xmlrpcfuncname.' to wrap php function '.$plainfuncname);
458
+                    return false;
459
+                }
460
+            }
461
+
462
+            /// @todo examine if $paramDocs matches $parsvariations and build array for
463
+            /// usage as method signature, plus put together a nice string for docs
464
+
465
+            $ret = array('function' => $xmlrpcfuncname, 'signature' => $sigs, 'docstring' => $desc, 'signature_docs' => $psigs, 'source' => $code);
466
+            return $ret;
467
+        }
468
+    }
469
+
470
+    /**
471
+     * Given a user-defined PHP class or php object, map its methods onto a list of
472
+     * PHP 'wrapper' functions that can be exposed as xmlrpc methods from an xmlrpc_server
473
+     * object and called from remote clients (as well as their corresponding signature info).
474
+     *
475
+     * @param mixed $classname the name of the class whose methods are to be exposed as xmlrpc methods, or an object instance of that class
476
+     * @param array $extra_options see the docs for wrap_php_method for more options
477
+     *        string method_type 'static', 'nonstatic', 'all' and 'auto' (default); the latter will switch between static and non-static depending on wheter $classname is a class name or object instance
478
+     * @return array or false on failure
479
+     *
480
+     * @todo get_class_methods will return both static and non-static methods.
481
+     *       we have to differentiate the action, depending on whether we received a class name or object
482
+     */
483
+    function wrap_php_class($classname, $extra_options=array())
484
+    {
485
+        $methodfilter = isset($extra_options['method_filter']) ? $extra_options['method_filter'] : '';
486
+        $methodtype = isset($extra_options['method_type']) ? $extra_options['method_type'] : 'auto';
487
+
488
+        $result = array();
489
+        $mlist = get_class_methods($classname);
490
+        foreach($mlist as $mname)
491
+        {
492
+            if ($methodfilter == '' || preg_match($methodfilter, $mname))
493
+            {
494
+                // echo $mlist."\n";
495
+                $func = new ReflectionMethod($classname, $mname);
496
+                if(!$func->isPrivate() && !$func->isProtected() && !$func->isConstructor() && !$func->isDestructor() && !$func->isAbstract())
497
+                {
498
+                    if(($func->isStatic && ($methodtype == 'all' || $methodtype == 'static' || ($methodtype == 'auto' && is_string($classname)))) ||
499
+                        (!$func->isStatic && ($methodtype == 'all' || $methodtype == 'nonstatic' || ($methodtype == 'auto' && is_object($classname)))))
500
+                    {
501
+                        $methodwrap = wrap_php_function(array($classname, $mname), '', $extra_options);
502
+                        if ( $methodwrap )
503
+                        {
504
+                            $result[$methodwrap['function']] = $methodwrap['function'];
505
+                        }
506
+                    }
507
+                }
508
+            }
509
+        }
510
+        return $result;
511
+    }
512
+
513
+    /**
514
+     * Given an xmlrpc client and a method name, register a php wrapper function
515
+     * that will call it and return results using native php types for both
516
+     * params and results. The generated php function will return an xmlrpcresp
517
+     * object for failed xmlrpc calls
518
+     *
519
+     * Known limitations:
520
+     * - server must support system.methodsignature for the wanted xmlrpc method
521
+     * - for methods that expose many signatures, only one can be picked (we
522
+     *   could in principle check if signatures differ only by number of params
523
+     *   and not by type, but it would be more complication than we can spare time)
524
+     * - nested xmlrpc params: the caller of the generated php function has to
525
+     *   encode on its own the params passed to the php function if these are structs
526
+     *   or arrays whose (sub)members include values of type datetime or base64
527
+     *
528
+     * Notes: the connection properties of the given client will be copied
529
+     * and reused for the connection used during the call to the generated
530
+     * php function.
531
+     * Calling the generated php function 'might' be slow: a new xmlrpc client
532
+     * is created on every invocation and an xmlrpc-connection opened+closed.
533
+     * An extra 'debug' param is appended to param list of xmlrpc method, useful
534
+     * for debugging purposes.
535
+     *
536
+     * @param xmlrpc_client $client     an xmlrpc client set up correctly to communicate with target server
537
+     * @param string        $methodname the xmlrpc method to be mapped to a php function
538
+     * @param array         $extra_options array of options that specify conversion details. valid options include
539
+     *        integer       signum      the index of the method signature to use in mapping (if method exposes many sigs)
540
+     *        integer       timeout     timeout (in secs) to be used when executing function/calling remote method
541
+     *        string        protocol    'http' (default), 'http11' or 'https'
542
+     *        string        new_function_name the name of php function to create. If unspecified, lib will pick an appropriate name
543
+     *        string        return_source if true return php code w. function definition instead fo function name
544
+     *        bool          encode_php_objs let php objects be sent to server using the 'improved' xmlrpc notation, so server can deserialize them as php objects
545
+     *        bool          decode_php_objs --- WARNING !!! possible security hazard. only use it with trusted servers ---
546
+     *        mixed         return_on_fault a php value to be returned when the xmlrpc call fails/returns a fault response (by default the xmlrpcresp object is returned in this case). If a string is used, '%faultCode%' and '%faultString%' tokens will be substituted with actual error values
547
+     *        bool          debug        set it to 1 or 2 to see debug results of querying server for method synopsis
548
+     * @return string                   the name of the generated php function (or false) - OR AN ARRAY...
549
+     */
550
+    function wrap_xmlrpc_method($client, $methodname, $extra_options=0, $timeout=0, $protocol='', $newfuncname='')
551
+    {
552
+        // mind numbing: let caller use sane calling convention (as per javadoc, 3 params),
553
+        // OR the 2.0 calling convention (no options) - we really love backward compat, don't we?
554
+        if (!is_array($extra_options))
555
+        {
556
+            $signum = $extra_options;
557
+            $extra_options = array();
558
+        }
559
+        else
560
+        {
561
+            $signum = isset($extra_options['signum']) ? (int)$extra_options['signum'] : 0;
562
+            $timeout = isset($extra_options['timeout']) ? (int)$extra_options['timeout'] : 0;
563
+            $protocol = isset($extra_options['protocol']) ? $extra_options['protocol'] : '';
564
+            $newfuncname = isset($extra_options['new_function_name']) ? $extra_options['new_function_name'] : '';
565
+        }
566
+        //$encode_php_objects = in_array('encode_php_objects', $extra_options);
567
+        //$verbatim_client_copy = in_array('simple_client_copy', $extra_options) ? 1 :
568
+        //	in_array('build_class_code', $extra_options) ? 2 : 0;
569
+
570
+        $encode_php_objects = isset($extra_options['encode_php_objs']) ? (bool)$extra_options['encode_php_objs'] : false;
571
+        $decode_php_objects = isset($extra_options['decode_php_objs']) ? (bool)$extra_options['decode_php_objs'] : false;
572
+        // it seems like the meaning of 'simple_client_copy' here is swapped wrt client_copy_mode later on...
573
+        $simple_client_copy = isset($extra_options['simple_client_copy']) ? (int)($extra_options['simple_client_copy']) : 0;
574
+        $buildit = isset($extra_options['return_source']) ? !($extra_options['return_source']) : true;
575
+        $prefix = isset($extra_options['prefix']) ? $extra_options['prefix'] : 'xmlrpc';
576
+        if (isset($extra_options['return_on_fault']))
577
+        {
578
+            $decode_fault = true;
579
+            $fault_response = $extra_options['return_on_fault'];
580
+        }
581
+        else
582
+        {
583
+            $decode_fault = false;
584
+            $fault_response = '';
585
+        }
586
+        $debug = isset($extra_options['debug']) ? ($extra_options['debug']) : 0;
587
+
588
+        $msgclass = $prefix.'msg';
589
+        $valclass = $prefix.'val';
590
+        $decodefunc = 'php_'.$prefix.'_decode';
591
+
592
+        $msg = new $msgclass('system.methodSignature');
593
+        $msg->addparam(new $valclass($methodname));
594
+        $client->setDebug($debug);
595
+        $response =& $client->send($msg, $timeout, $protocol);
596
+        if($response->faultCode())
597
+        {
598
+            error_log('XML-RPC: could not retrieve method signature from remote server for method '.$methodname);
599
+            return false;
600
+        }
601
+        else
602
+        {
603
+            $msig = $response->value();
604
+            if ($client->return_type != 'phpvals')
605
+            {
606
+                $msig = $decodefunc($msig);
607
+            }
608
+            if(!is_array($msig) || count($msig) <= $signum)
609
+            {
610
+                error_log('XML-RPC: could not retrieve method signature nr.'.$signum.' from remote server for method '.$methodname);
611
+                return false;
612
+            }
613
+            else
614
+            {
615
+                // pick a suitable name for the new function, avoiding collisions
616
+                if($newfuncname != '')
617
+                {
618
+                    $xmlrpcfuncname = $newfuncname;
619
+                }
620
+                else
621
+                {
622
+                    // take care to insure that methodname is translated to valid
623
+                    // php function name
624
+                    $xmlrpcfuncname = $prefix.'_'.preg_replace(array('/\./', '/[^a-zA-Z0-9_\x7f-\xff]/'),
625
+                        array('_', ''), $methodname);
626
+                }
627
+                while($buildit && function_exists($xmlrpcfuncname))
628
+                {
629
+                    $xmlrpcfuncname .= 'x';
630
+                }
631
+
632
+                $msig = $msig[$signum];
633
+                $mdesc = '';
634
+                // if in 'offline' mode, get method description too.
635
+                // in online mode, favour speed of operation
636
+                if(!$buildit)
637
+                {
638
+                    $msg = new $msgclass('system.methodHelp');
639
+                    $msg->addparam(new $valclass($methodname));
640
+                    $response =& $client->send($msg, $timeout, $protocol);
641
+                    if (!$response->faultCode())
642
+                    {
643
+                        $mdesc = $response->value();
644
+                        if ($client->return_type != 'phpvals')
645
+                        {
646
+                            $mdesc = $mdesc->scalarval();
647
+                        }
648
+                    }
649
+                }
650
+
651
+                $results = build_remote_method_wrapper_code($client, $methodname,
652
+                    $xmlrpcfuncname, $msig, $mdesc, $timeout, $protocol, $simple_client_copy,
653
+                    $prefix, $decode_php_objects, $encode_php_objects, $decode_fault,
654
+                    $fault_response);
655
+
656
+                //print_r($code);
657
+                if ($buildit)
658
+                {
659
+                    $allOK = 0;
660
+                    eval($results['source'].'$allOK=1;');
661
+                    // alternative
662
+                    //$xmlrpcfuncname = create_function('$m', $innercode);
663
+                    if($allOK)
664
+                    {
665
+                        return $xmlrpcfuncname;
666
+                    }
667
+                    else
668
+                    {
669
+                        error_log('XML-RPC: could not create function '.$xmlrpcfuncname.' to wrap remote method '.$methodname);
670
+                        return false;
671
+                    }
672
+                }
673
+                else
674
+                {
675
+                    $results['function'] = $xmlrpcfuncname;
676
+                    return $results;
677
+                }
678
+            }
679
+        }
680
+    }
681
+
682
+    /**
683
+     * Similar to wrap_xmlrpc_method, but will generate a php class that wraps
684
+     * all xmlrpc methods exposed by the remote server as own methods.
685
+     * For more details see wrap_xmlrpc_method.
686
+     * @param xmlrpc_client $client the client obj all set to query the desired server
687
+     * @param array $extra_options list of options for wrapped code
688
+     * @return mixed false on error, the name of the created class if all ok or an array with code, class name and comments (if the appropriatevoption is set in extra_options)
689
+     */
690
+    function wrap_xmlrpc_server($client, $extra_options=array())
691
+    {
692
+        $methodfilter = isset($extra_options['method_filter']) ? $extra_options['method_filter'] : '';
693
+        //$signum = isset($extra_options['signum']) ? (int)$extra_options['signum'] : 0;
694
+        $timeout = isset($extra_options['timeout']) ? (int)$extra_options['timeout'] : 0;
695
+        $protocol = isset($extra_options['protocol']) ? $extra_options['protocol'] : '';
696
+        $newclassname = isset($extra_options['new_class_name']) ? $extra_options['new_class_name'] : '';
697
+        $encode_php_objects = isset($extra_options['encode_php_objs']) ? (bool)$extra_options['encode_php_objs'] : false;
698
+        $decode_php_objects = isset($extra_options['decode_php_objs']) ? (bool)$extra_options['decode_php_objs'] : false;
699
+        $verbatim_client_copy = isset($extra_options['simple_client_copy']) ? !($extra_options['simple_client_copy']) : true;
700
+        $buildit = isset($extra_options['return_source']) ? !($extra_options['return_source']) : true;
701
+        $prefix = isset($extra_options['prefix']) ? $extra_options['prefix'] : 'xmlrpc';
702
+
703
+        $msgclass = $prefix.'msg';
704
+        //$valclass = $prefix.'val';
705
+        $decodefunc = 'php_'.$prefix.'_decode';
706
+
707
+        $msg = new $msgclass('system.listMethods');
708
+        $response =& $client->send($msg, $timeout, $protocol);
709
+        if($response->faultCode())
710
+        {
711
+            error_log('XML-RPC: could not retrieve method list from remote server');
712
+            return false;
713
+        }
714
+        else
715
+        {
716
+            $mlist = $response->value();
717
+            if ($client->return_type != 'phpvals')
718
+            {
719
+                $mlist = $decodefunc($mlist);
720
+            }
721
+            if(!is_array($mlist) || !count($mlist))
722
+            {
723
+                error_log('XML-RPC: could not retrieve meaningful method list from remote server');
724
+                return false;
725
+            }
726
+            else
727
+            {
728
+                // pick a suitable name for the new function, avoiding collisions
729
+                if($newclassname != '')
730
+                {
731
+                    $xmlrpcclassname = $newclassname;
732
+                }
733
+                else
734
+                {
735
+                    $xmlrpcclassname = $prefix.'_'.preg_replace(array('/\./', '/[^a-zA-Z0-9_\x7f-\xff]/'),
736
+                        array('_', ''), $client->server).'_client';
737
+                }
738
+                while($buildit && class_exists($xmlrpcclassname))
739
+                {
740
+                    $xmlrpcclassname .= 'x';
741
+                }
742
+
743
+                /// @todo add function setdebug() to new class, to enable/disable debugging
744
+                $source = "class $xmlrpcclassname\n{\nvar \$client;\n\n";
745
+                $source .= "function $xmlrpcclassname()\n{\n";
746
+                $source .= build_client_wrapper_code($client, $verbatim_client_copy, $prefix);
747
+                $source .= "\$this->client =& \$client;\n}\n\n";
748
+                $opts = array('simple_client_copy' => 2, 'return_source' => true,
749
+                    'timeout' => $timeout, 'protocol' => $protocol,
750
+                    'encode_php_objs' => $encode_php_objects, 'prefix' => $prefix,
751
+                    'decode_php_objs' => $decode_php_objects
752
+                    );
753
+                /// @todo build javadoc for class definition, too
754
+                foreach($mlist as $mname)
755
+                {
756
+                    if ($methodfilter == '' || preg_match($methodfilter, $mname))
757
+                    {
758
+                        $opts['new_function_name'] = preg_replace(array('/\./', '/[^a-zA-Z0-9_\x7f-\xff]/'),
759
+                            array('_', ''), $mname);
760
+                        $methodwrap = wrap_xmlrpc_method($client, $mname, $opts);
761
+                        if ($methodwrap)
762
+                        {
763
+                            if (!$buildit)
764
+                            {
765
+                                $source .= $methodwrap['docstring'];
766
+                            }
767
+                            $source .= $methodwrap['source']."\n";
768
+                        }
769
+                        else
770
+                        {
771
+                            error_log('XML-RPC: will not create class method to wrap remote method '.$mname);
772
+                        }
773
+                    }
774
+                }
775
+                $source .= "}\n";
776
+                if ($buildit)
777
+                {
778
+                    $allOK = 0;
779
+                    eval($source.'$allOK=1;');
780
+                    // alternative
781
+                    //$xmlrpcfuncname = create_function('$m', $innercode);
782
+                    if($allOK)
783
+                    {
784
+                        return $xmlrpcclassname;
785
+                    }
786
+                    else
787
+                    {
788
+                        error_log('XML-RPC: could not create class '.$xmlrpcclassname.' to wrap remote server '.$client->server);
789
+                        return false;
790
+                    }
791
+                }
792
+                else
793
+                {
794
+                    return array('class' => $xmlrpcclassname, 'code' => $source, 'docstring' => '');
795
+                }
796
+            }
797
+        }
798
+    }
799
+
800
+    /**
801
+     * Given the necessary info, build php code that creates a new function to
802
+     * invoke a remote xmlrpc method.
803
+     * Take care that no full checking of input parameters is done to ensure that
804
+     * valid php code is emitted.
805
+     * Note: real spaghetti code follows...
806
+     * @access private
807
+     */
808
+    function build_remote_method_wrapper_code($client, $methodname, $xmlrpcfuncname,
809
+        $msig, $mdesc='', $timeout=0, $protocol='', $client_copy_mode=0, $prefix='xmlrpc',
810
+        $decode_php_objects=false, $encode_php_objects=false, $decode_fault=false,
811
+        $fault_response='')
812
+    {
813
+        $code = "function $xmlrpcfuncname (";
814
+        if ($client_copy_mode < 2)
815
+        {
816
+            // client copy mode 0 or 1 == partial / full client copy in emitted code
817
+            $innercode = build_client_wrapper_code($client, $client_copy_mode, $prefix);
818
+            $innercode .= "\$client->setDebug(\$debug);\n";
819
+            $this_ = '';
820
+        }
821
+        else
822
+        {
823
+            // client copy mode 2 == no client copy in emitted code
824
+            $innercode = '';
825
+            $this_ = 'this->';
826
+        }
827
+        $innercode .= "\$msg = new {$prefix}msg('$methodname');\n";
828
+
829
+        if ($mdesc != '')
830
+        {
831
+            // take care that PHP comment is not terminated unwillingly by method description
832
+            $mdesc = "/**\n* ".str_replace('*/', '* /', $mdesc)."\n";
833
+        }
834
+        else
835
+        {
836
+            $mdesc = "/**\nFunction $xmlrpcfuncname\n";
837
+        }
838
+
839
+        // param parsing
840
+        $plist = array();
841
+        $pcount = count($msig);
842
+        for($i = 1; $i < $pcount; $i++)
843
+        {
844
+            $plist[] = "\$p$i";
845
+            $ptype = $msig[$i];
846
+            if($ptype == 'i4' || $ptype == 'int' || $ptype == 'boolean' || $ptype == 'double' ||
847
+                $ptype == 'string' || $ptype == 'dateTime.iso8601' || $ptype == 'base64' || $ptype == 'null')
848
+            {
849
+                // only build directly xmlrpcvals when type is known and scalar
850
+                $innercode .= "\$p$i = new {$prefix}val(\$p$i, '$ptype');\n";
851
+            }
852
+            else
853
+            {
854
+                if ($encode_php_objects)
855
+                {
856
+                    $innercode .= "\$p$i =& php_{$prefix}_encode(\$p$i, array('encode_php_objs'));\n";
857
+                }
858
+                else
859
+                {
860
+                    $innercode .= "\$p$i =& php_{$prefix}_encode(\$p$i);\n";
861
+                }
862
+            }
863
+            $innercode .= "\$msg->addparam(\$p$i);\n";
864
+            $mdesc .= '* @param '.xmlrpc_2_php_type($ptype)." \$p$i\n";
865
+        }
866
+        if ($client_copy_mode < 2)
867
+        {
868
+            $plist[] = '$debug=0';
869
+            $mdesc .= "* @param int \$debug when 1 (or 2) will enable debugging of the underlying {$prefix} call (defaults to 0)\n";
870
+        }
871
+        $plist = implode(', ', $plist);
872
+        $mdesc .= '* @return '.xmlrpc_2_php_type($msig[0])." (or an {$prefix}resp obj instance if call fails)\n*/\n";
873
+
874
+        $innercode .= "\$res =& \${$this_}client->send(\$msg, $timeout, '$protocol');\n";
875
+        if ($decode_fault)
876
+        {
877
+            if (is_string($fault_response) && ((strpos($fault_response, '%faultCode%') !== false) || (strpos($fault_response, '%faultString%') !== false)))
878
+            {
879
+                $respcode = "str_replace(array('%faultCode%', '%faultString%'), array(\$res->faultCode(), \$res->faultString()), '".str_replace("'", "''", $fault_response)."')";
880
+            }
881
+            else
882
+            {
883
+                $respcode = var_export($fault_response, true);
884
+            }
885
+        }
886
+        else
887
+        {
888
+            $respcode = '$res';
889
+        }
890
+        if ($decode_php_objects)
891
+        {
892
+            $innercode .= "if (\$res->faultcode()) return $respcode; else return php_{$prefix}_decode(\$res->value(), array('decode_php_objs'));";
893
+        }
894
+        else
895
+        {
896
+            $innercode .= "if (\$res->faultcode()) return $respcode; else return php_{$prefix}_decode(\$res->value());";
897
+        }
898
+
899
+        $code = $code . $plist. ") {\n" . $innercode . "\n}\n";
900
+
901
+        return array('source' => $code, 'docstring' => $mdesc);
902
+    }
903
+
904
+    /**
905
+     * Given necessary info, generate php code that will rebuild a client object
906
+     * Take care that no full checking of input parameters is done to ensure that
907
+     * valid php code is emitted.
908
+     * @access private
909
+     */
910
+    function build_client_wrapper_code($client, $verbatim_client_copy, $prefix='xmlrpc')
911
+    {
912
+        $code = "\$client = new {$prefix}_client('".str_replace("'", "\'", $client->path).
913
+            "', '" . str_replace("'", "\'", $client->server) . "', $client->port);\n";
914
+
915
+        // copy all client fields to the client that will be generated runtime
916
+        // (this provides for future expansion or subclassing of client obj)
917
+        if ($verbatim_client_copy)
918
+        {
919
+            foreach($client as $fld => $val)
920
+            {
921
+                if($fld != 'debug' && $fld != 'return_type')
922
+                {
923
+                    $val = var_export($val, true);
924
+                    $code .= "\$client->$fld = $val;\n";
925
+                }
926
+            }
927
+        }
928
+        // only make sure that client always returns the correct data type
929
+        $code .= "\$client->return_type = '{$prefix}vals';\n";
930
+        //$code .= "\$client->setDebug(\$debug);\n";
931
+        return $code;
932
+    }
933 933
 ?>
Please login to merge, or discard this patch.
Spacing   +94 added lines, -94 removed lines patch added patch discarded remove patch
@@ -27,7 +27,7 @@  discard block
 block discarded – undo
27 27
 	*/
28 28
 	function php_2_xmlrpc_type($phptype)
29 29
 	{
30
-		switch(strtolower($phptype))
30
+		switch (strtolower($phptype))
31 31
 		{
32 32
 			case 'string':
33 33
 				return $GLOBALS['xmlrpcString'];
@@ -49,7 +49,7 @@  discard block
 block discarded – undo
49 49
 			case 'resource':
50 50
 				return '';
51 51
 			default:
52
-				if(class_exists($phptype))
52
+				if (class_exists($phptype))
53 53
 				{
54 54
 					return $GLOBALS['xmlrpcStruct'];
55 55
 				}
@@ -68,7 +68,7 @@  discard block
 block discarded – undo
68 68
 	*/
69 69
 	function xmlrpc_2_php_type($xmlrpctype)
70 70
 	{
71
-		switch(strtolower($xmlrpctype))
71
+		switch (strtolower($xmlrpctype))
72 72
 		{
73 73
 			case 'base64':
74 74
 			case 'datetime.iso8601':
@@ -140,12 +140,12 @@  discard block
 block discarded – undo
140 140
 	* @todo if $newfuncname is empty, we could use create_user_func instead of eval, as it is possibly faster
141 141
 	* @todo add a verbatim_object_copy parameter to allow avoiding the same obj instance?
142 142
 	*/
143
-	function wrap_php_function($funcname, $newfuncname='', $extra_options=array())
143
+	function wrap_php_function($funcname, $newfuncname = '', $extra_options = array())
144 144
 	{
145 145
 		$buildit = isset($extra_options['return_source']) ? !($extra_options['return_source']) : true;
146 146
 		$prefix = isset($extra_options['prefix']) ? $extra_options['prefix'] : 'xmlrpc';
147
-		$encode_php_objects = isset($extra_options['encode_php_objs']) ? (bool)$extra_options['encode_php_objs'] : false;
148
-		$decode_php_objects = isset($extra_options['decode_php_objs']) ? (bool)$extra_options['decode_php_objs'] : false;
147
+		$encode_php_objects = isset($extra_options['encode_php_objs']) ? (bool) $extra_options['encode_php_objs'] : false;
148
+		$decode_php_objects = isset($extra_options['decode_php_objs']) ? (bool) $extra_options['decode_php_objs'] : false;
149 149
 		$catch_warnings = isset($extra_options['suppress_warnings']) && $extra_options['suppress_warnings'] ? '@' : '';
150 150
 
151 151
 		$exists = false;
@@ -153,20 +153,20 @@  discard block
 block discarded – undo
153 153
 		{
154 154
 			$funcname = explode('::', $funcname);
155 155
 		}
156
-		if(is_array($funcname))
156
+		if (is_array($funcname))
157 157
 		{
158
-			if(count($funcname) < 2 || (!is_string($funcname[0]) && !is_object($funcname[0])))
158
+			if (count($funcname)<2 || (!is_string($funcname[0]) && !is_object($funcname[0])))
159 159
 			{
160 160
 				error_log('XML-RPC: syntax for function to be wrapped is wrong');
161 161
 				return false;
162 162
 			}
163
-			if(is_string($funcname[0]))
163
+			if (is_string($funcname[0]))
164 164
 			{
165 165
 				$plainfuncname = implode('::', $funcname);
166 166
 			}
167
-			elseif(is_object($funcname[0]))
167
+			elseif (is_object($funcname[0]))
168 168
 			{
169
-				$plainfuncname = get_class($funcname[0]) . '->' . $funcname[1];
169
+				$plainfuncname = get_class($funcname[0]).'->'.$funcname[1];
170 170
 			}
171 171
 			$exists = method_exists($funcname[0], $funcname[1]);
172 172
 		}
@@ -176,7 +176,7 @@  discard block
 block discarded – undo
176 176
 			$exists = function_exists($funcname);
177 177
 		}
178 178
 
179
-		if(!$exists)
179
+		if (!$exists)
180 180
 		{
181 181
 			error_log('XML-RPC: function to be wrapped is not defined: '.$plainfuncname);
182 182
 			return false;
@@ -184,14 +184,14 @@  discard block
 block discarded – undo
184 184
 		else
185 185
 		{
186 186
 			// determine name of new php function
187
-			if($newfuncname == '')
187
+			if ($newfuncname == '')
188 188
 			{
189
-				if(is_array($funcname))
189
+				if (is_array($funcname))
190 190
 				{
191
-					if(is_string($funcname[0]))
191
+					if (is_string($funcname[0]))
192 192
 						$xmlrpcfuncname = "{$prefix}_".implode('_', $funcname);
193 193
 					else
194
-						$xmlrpcfuncname = "{$prefix}_".get_class($funcname[0]) . '_' . $funcname[1];
194
+						$xmlrpcfuncname = "{$prefix}_".get_class($funcname[0]).'_'.$funcname[1];
195 195
 				}
196 196
 				else
197 197
 				{
@@ -202,36 +202,36 @@  discard block
 block discarded – undo
202 202
 			{
203 203
 				$xmlrpcfuncname = $newfuncname;
204 204
 			}
205
-			while($buildit && function_exists($xmlrpcfuncname))
205
+			while ($buildit && function_exists($xmlrpcfuncname))
206 206
 			{
207 207
 				$xmlrpcfuncname .= 'x';
208 208
 			}
209 209
 
210 210
 			// start to introspect PHP code
211
-			if(is_array($funcname))
211
+			if (is_array($funcname))
212 212
 			{
213 213
 				$func = new ReflectionMethod($funcname[0], $funcname[1]);
214
-				if($func->isPrivate())
214
+				if ($func->isPrivate())
215 215
 				{
216 216
 					error_log('XML-RPC: method to be wrapped is private: '.$plainfuncname);
217 217
 					return false;
218 218
 				}
219
-				if($func->isProtected())
219
+				if ($func->isProtected())
220 220
 				{
221 221
 					error_log('XML-RPC: method to be wrapped is protected: '.$plainfuncname);
222 222
 					return false;
223 223
 				}
224
-	 			if($func->isConstructor())
224
+	 			if ($func->isConstructor())
225 225
 				{
226 226
 					error_log('XML-RPC: method to be wrapped is the constructor: '.$plainfuncname);
227 227
 					return false;
228 228
 				}
229
-				if($func->isDestructor())
229
+				if ($func->isDestructor())
230 230
 				{
231 231
 					error_log('XML-RPC: method to be wrapped is the destructor: '.$plainfuncname);
232 232
 					return false;
233 233
 				}
234
-				if($func->isAbstract())
234
+				if ($func->isAbstract())
235 235
 				{
236 236
 					error_log('XML-RPC: method to be wrapped is abstract: '.$plainfuncname);
237 237
 					return false;
@@ -242,7 +242,7 @@  discard block
 block discarded – undo
242 242
 			{
243 243
 				$func = new ReflectionFunction($funcname);
244 244
 			}
245
-			if($func->isInternal())
245
+			if ($func->isInternal())
246 246
 			{
247 247
 				// Note: from PHP 5.1.0 onward, we will possibly be able to use invokeargs
248 248
 				// instead of getparameters to fully reflect internal php functions ?
@@ -262,27 +262,27 @@  discard block
 block discarded – undo
262 262
 			$paramDocs = array();
263 263
 
264 264
 			$docs = $func->getDocComment();
265
-			if($docs != '')
265
+			if ($docs != '')
266 266
 			{
267 267
 				$docs = explode("\n", $docs);
268 268
 				$i = 0;
269
-				foreach($docs as $doc)
269
+				foreach ($docs as $doc)
270 270
 				{
271 271
 					$doc = trim($doc, " \r\t/*");
272
-					if(strlen($doc) && strpos($doc, '@') !== 0 && !$i)
272
+					if (strlen($doc) && strpos($doc, '@') !== 0 && !$i)
273 273
 					{
274
-						if($desc)
274
+						if ($desc)
275 275
 						{
276 276
 							$desc .= "\n";
277 277
 						}
278 278
 						$desc .= $doc;
279 279
 					}
280
-					elseif(strpos($doc, '@param') === 0)
280
+					elseif (strpos($doc, '@param') === 0)
281 281
 					{
282 282
 						// syntax: @param type [$name] desc
283
-						if(preg_match('/@param\s+(\S+)(\s+\$\S+)?\s+(.+)/', $doc, $matches))
283
+						if (preg_match('/@param\s+(\S+)(\s+\$\S+)?\s+(.+)/', $doc, $matches))
284 284
 						{
285
-							if(strpos($matches[1], '|'))
285
+							if (strpos($matches[1], '|'))
286 286
 							{
287 287
 								//$paramDocs[$i]['type'] = explode('|', $matches[1]);
288 288
 								$paramDocs[$i]['type'] = 'mixed';
@@ -296,14 +296,14 @@  discard block
 block discarded – undo
296 296
 						}
297 297
 						$i++;
298 298
 					}
299
-					elseif(strpos($doc, '@return') === 0)
299
+					elseif (strpos($doc, '@return') === 0)
300 300
 					{
301 301
 						// syntax: @return type desc
302 302
 						//$returns = preg_split('/\s+/', $doc);
303
-						if(preg_match('/@return\s+(\S+)\s+(.+)/', $doc, $matches))
303
+						if (preg_match('/@return\s+(\S+)\s+(.+)/', $doc, $matches))
304 304
 						{
305 305
 							$returns = php_2_xmlrpc_type($matches[1]);
306
-							if(isset($matches[2]))
306
+							if (isset($matches[2]))
307 307
 							{
308 308
 								$returnsDocs = $matches[2];
309 309
 							}
@@ -315,7 +315,7 @@  discard block
 block discarded – undo
315 315
 			// execute introspection of actual function prototype
316 316
 			$params = array();
317 317
 			$i = 0;
318
-			foreach($func->getParameters() as $paramobj)
318
+			foreach ($func->getParameters() as $paramobj)
319 319
 			{
320 320
 				$params[$i] = array();
321 321
 				$params[$i]['name'] = '$'.$paramobj->getName();
@@ -329,7 +329,7 @@  discard block
 block discarded – undo
329 329
 			$parsvariations = array();
330 330
 			$pars = array();
331 331
 			$pnum = count($params);
332
-			foreach($params as $param)
332
+			foreach ($params as $param)
333 333
 			{
334 334
 				if (isset($paramDocs[$i]['name']) && $paramDocs[$i]['name'] && strtolower($paramDocs[$i]['name']) != strtolower($param['name']))
335 335
 				{
@@ -337,7 +337,7 @@  discard block
 block discarded – undo
337 337
 					$paramDocs[$i]['type'] = 'mixed';
338 338
 				}
339 339
 
340
-				if($param['isoptional'])
340
+				if ($param['isoptional'])
341 341
 				{
342 342
 					// this particular parameter is optional. save as valid previous list of parameters
343 343
 					$innercode .= "if (\$paramcount > $i) {\n";
@@ -355,11 +355,11 @@  discard block
 block discarded – undo
355 355
 
356 356
 				$pars[] = "\$p$i";
357 357
 				$i++;
358
-				if($param['isoptional'])
358
+				if ($param['isoptional'])
359 359
 				{
360 360
 					$innercode .= "}\n";
361 361
 				}
362
-				if($i == $pnum)
362
+				if ($i == $pnum)
363 363
 				{
364 364
 					// last allowed parameters combination
365 365
 					$parsvariations[] = $pars;
@@ -368,7 +368,7 @@  discard block
 block discarded – undo
368 368
 
369 369
 			$sigs = array();
370 370
 			$psigs = array();
371
-			if(count($parsvariations) == 0)
371
+			if (count($parsvariations) == 0)
372 372
 			{
373 373
 				// only known good synopsis = no parameters
374 374
 				$parsvariations[] = array();
@@ -379,24 +379,24 @@  discard block
 block discarded – undo
379 379
 				$minpars = count($parsvariations[0]);
380 380
 			}
381 381
 
382
-			if($minpars)
382
+			if ($minpars)
383 383
 			{
384 384
 				// add to code the check for min params number
385 385
 				// NB: this check needs to be done BEFORE decoding param values
386
-				$innercode = "\$paramcount = \$msg->getNumParams();\n" .
387
-				"if (\$paramcount < $minpars) return new {$prefix}resp(0, {$GLOBALS['xmlrpcerr']['incorrect_params']}, '{$GLOBALS['xmlrpcstr']['incorrect_params']}');\n" . $innercode;
386
+				$innercode = "\$paramcount = \$msg->getNumParams();\n".
387
+				"if (\$paramcount < $minpars) return new {$prefix}resp(0, {$GLOBALS['xmlrpcerr']['incorrect_params']}, '{$GLOBALS['xmlrpcstr']['incorrect_params']}');\n".$innercode;
388 388
 			}
389 389
 			else
390 390
 			{
391
-				$innercode = "\$paramcount = \$msg->getNumParams();\n" . $innercode;
391
+				$innercode = "\$paramcount = \$msg->getNumParams();\n".$innercode;
392 392
 			}
393 393
 
394 394
 			$innercode .= "\$np = false;\n";
395 395
 			// since there are no closures in php, if we are given an object instance,
396 396
 			// we store a pointer to it in a global var...
397
-			if ( is_array($funcname) && is_object($funcname[0]) )
397
+			if (is_array($funcname) && is_object($funcname[0]))
398 398
 			{
399
-				$GLOBALS['xmlrpcWPFObjHolder'][$xmlrpcfuncname] =& $funcname[0];
399
+				$GLOBALS['xmlrpcWPFObjHolder'][$xmlrpcfuncname] = & $funcname[0];
400 400
 				$innercode .= "\$obj =& \$GLOBALS['xmlrpcWPFObjHolder']['$xmlrpcfuncname'];\n";
401 401
 				$realfuncname = '$obj->'.$funcname[1];
402 402
 			}
@@ -404,13 +404,13 @@  discard block
 block discarded – undo
404 404
 			{
405 405
 				$realfuncname = $plainfuncname;
406 406
 			}
407
-			foreach($parsvariations as $pars)
407
+			foreach ($parsvariations as $pars)
408 408
 			{
409
-				$innercode .= "if (\$paramcount == " . count($pars) . ") \$retval = {$catch_warnings}$realfuncname(" . implode(',', $pars) . "); else\n";
409
+				$innercode .= "if (\$paramcount == ".count($pars).") \$retval = {$catch_warnings}$realfuncname(".implode(',', $pars)."); else\n";
410 410
 				// build a 'generic' signature (only use an appropriate return type)
411 411
 				$sig = array($returns);
412 412
 				$psig = array($returnsDocs);
413
-				for($i=0; $i < count($pars); $i++)
413
+				for ($i = 0; $i<count($pars); $i++)
414 414
 				{
415 415
 					if (isset($paramDocs[$i]['type']))
416 416
 					{
@@ -429,7 +429,7 @@  discard block
 block discarded – undo
429 429
 			$innercode .= "if (\$np) return new {$prefix}resp(0, {$GLOBALS['xmlrpcerr']['incorrect_params']}, '{$GLOBALS['xmlrpcstr']['incorrect_params']}'); else {\n";
430 430
 			//$innercode .= "if (\$_xmlrpcs_error_occurred) return new xmlrpcresp(0, $GLOBALS['xmlrpcerr']user, \$_xmlrpcs_error_occurred); else\n";
431 431
 			$innercode .= "if (is_a(\$retval, '{$prefix}resp')) return \$retval; else\n";
432
-			if($returns == $GLOBALS['xmlrpcDateTime'] || $returns == $GLOBALS['xmlrpcBase64'])
432
+			if ($returns == $GLOBALS['xmlrpcDateTime'] || $returns == $GLOBALS['xmlrpcBase64'])
433 433
 			{
434 434
 				$innercode .= "return new {$prefix}resp(new {$prefix}val(\$retval, '$returns'));";
435 435
 			}
@@ -443,7 +443,7 @@  discard block
 block discarded – undo
443 443
 			// shall we exclude functions returning by ref?
444 444
 			// if($func->returnsReference())
445 445
 			// 	return false;
446
-			$code = "function $xmlrpcfuncname(\$msg) {\n" . $innercode . "}\n}";
446
+			$code = "function $xmlrpcfuncname(\$msg) {\n".$innercode."}\n}";
447 447
 			//print_r($code);
448 448
 			if ($buildit)
449 449
 			{
@@ -452,7 +452,7 @@  discard block
 block discarded – undo
452 452
 				// alternative
453 453
 				//$xmlrpcfuncname = create_function('$m', $innercode);
454 454
 
455
-				if(!$allOK)
455
+				if (!$allOK)
456 456
 				{
457 457
 					error_log('XML-RPC: could not create function '.$xmlrpcfuncname.' to wrap php function '.$plainfuncname);
458 458
 					return false;
@@ -480,26 +480,26 @@  discard block
 block discarded – undo
480 480
 	* @todo get_class_methods will return both static and non-static methods.
481 481
 	*       we have to differentiate the action, depending on whether we received a class name or object
482 482
 	*/
483
-	function wrap_php_class($classname, $extra_options=array())
483
+	function wrap_php_class($classname, $extra_options = array())
484 484
 	{
485 485
 		$methodfilter = isset($extra_options['method_filter']) ? $extra_options['method_filter'] : '';
486 486
 		$methodtype = isset($extra_options['method_type']) ? $extra_options['method_type'] : 'auto';
487 487
 
488 488
 		$result = array();
489 489
 		$mlist = get_class_methods($classname);
490
-		foreach($mlist as $mname)
490
+		foreach ($mlist as $mname)
491 491
 		{
492 492
 			if ($methodfilter == '' || preg_match($methodfilter, $mname))
493 493
 			{
494 494
 				// echo $mlist."\n";
495 495
 				$func = new ReflectionMethod($classname, $mname);
496
-				if(!$func->isPrivate() && !$func->isProtected() && !$func->isConstructor() && !$func->isDestructor() && !$func->isAbstract())
496
+				if (!$func->isPrivate() && !$func->isProtected() && !$func->isConstructor() && !$func->isDestructor() && !$func->isAbstract())
497 497
 				{
498
-					if(($func->isStatic && ($methodtype == 'all' || $methodtype == 'static' || ($methodtype == 'auto' && is_string($classname)))) ||
498
+					if (($func->isStatic && ($methodtype == 'all' || $methodtype == 'static' || ($methodtype == 'auto' && is_string($classname)))) ||
499 499
 						(!$func->isStatic && ($methodtype == 'all' || $methodtype == 'nonstatic' || ($methodtype == 'auto' && is_object($classname)))))
500 500
 					{
501 501
 						$methodwrap = wrap_php_function(array($classname, $mname), '', $extra_options);
502
-						if ( $methodwrap )
502
+						if ($methodwrap)
503 503
 						{
504 504
 							$result[$methodwrap['function']] = $methodwrap['function'];
505 505
 						}
@@ -547,7 +547,7 @@  discard block
 block discarded – undo
547 547
 	*        bool          debug        set it to 1 or 2 to see debug results of querying server for method synopsis
548 548
 	* @return string                   the name of the generated php function (or false) - OR AN ARRAY...
549 549
 	*/
550
-	function wrap_xmlrpc_method($client, $methodname, $extra_options=0, $timeout=0, $protocol='', $newfuncname='')
550
+	function wrap_xmlrpc_method($client, $methodname, $extra_options = 0, $timeout = 0, $protocol = '', $newfuncname = '')
551 551
 	{
552 552
 		// mind numbing: let caller use sane calling convention (as per javadoc, 3 params),
553 553
 		// OR the 2.0 calling convention (no options) - we really love backward compat, don't we?
@@ -558,8 +558,8 @@  discard block
 block discarded – undo
558 558
 		}
559 559
 		else
560 560
 		{
561
-			$signum = isset($extra_options['signum']) ? (int)$extra_options['signum'] : 0;
562
-			$timeout = isset($extra_options['timeout']) ? (int)$extra_options['timeout'] : 0;
561
+			$signum = isset($extra_options['signum']) ? (int) $extra_options['signum'] : 0;
562
+			$timeout = isset($extra_options['timeout']) ? (int) $extra_options['timeout'] : 0;
563 563
 			$protocol = isset($extra_options['protocol']) ? $extra_options['protocol'] : '';
564 564
 			$newfuncname = isset($extra_options['new_function_name']) ? $extra_options['new_function_name'] : '';
565 565
 		}
@@ -567,10 +567,10 @@  discard block
 block discarded – undo
567 567
 		//$verbatim_client_copy = in_array('simple_client_copy', $extra_options) ? 1 :
568 568
 		//	in_array('build_class_code', $extra_options) ? 2 : 0;
569 569
 
570
-		$encode_php_objects = isset($extra_options['encode_php_objs']) ? (bool)$extra_options['encode_php_objs'] : false;
571
-		$decode_php_objects = isset($extra_options['decode_php_objs']) ? (bool)$extra_options['decode_php_objs'] : false;
570
+		$encode_php_objects = isset($extra_options['encode_php_objs']) ? (bool) $extra_options['encode_php_objs'] : false;
571
+		$decode_php_objects = isset($extra_options['decode_php_objs']) ? (bool) $extra_options['decode_php_objs'] : false;
572 572
 		// it seems like the meaning of 'simple_client_copy' here is swapped wrt client_copy_mode later on...
573
-		$simple_client_copy = isset($extra_options['simple_client_copy']) ? (int)($extra_options['simple_client_copy']) : 0;
573
+		$simple_client_copy = isset($extra_options['simple_client_copy']) ? (int) ($extra_options['simple_client_copy']) : 0;
574 574
 		$buildit = isset($extra_options['return_source']) ? !($extra_options['return_source']) : true;
575 575
 		$prefix = isset($extra_options['prefix']) ? $extra_options['prefix'] : 'xmlrpc';
576 576
 		if (isset($extra_options['return_on_fault']))
@@ -592,8 +592,8 @@  discard block
 block discarded – undo
592 592
 		$msg = new $msgclass('system.methodSignature');
593 593
 		$msg->addparam(new $valclass($methodname));
594 594
 		$client->setDebug($debug);
595
-		$response =& $client->send($msg, $timeout, $protocol);
596
-		if($response->faultCode())
595
+		$response = & $client->send($msg, $timeout, $protocol);
596
+		if ($response->faultCode())
597 597
 		{
598 598
 			error_log('XML-RPC: could not retrieve method signature from remote server for method '.$methodname);
599 599
 			return false;
@@ -605,7 +605,7 @@  discard block
 block discarded – undo
605 605
 			{
606 606
 				$msig = $decodefunc($msig);
607 607
 			}
608
-			if(!is_array($msig) || count($msig) <= $signum)
608
+			if (!is_array($msig) || count($msig)<=$signum)
609 609
 			{
610 610
 				error_log('XML-RPC: could not retrieve method signature nr.'.$signum.' from remote server for method '.$methodname);
611 611
 				return false;
@@ -613,7 +613,7 @@  discard block
 block discarded – undo
613 613
 			else
614 614
 			{
615 615
 				// pick a suitable name for the new function, avoiding collisions
616
-				if($newfuncname != '')
616
+				if ($newfuncname != '')
617 617
 				{
618 618
 					$xmlrpcfuncname = $newfuncname;
619 619
 				}
@@ -624,7 +624,7 @@  discard block
 block discarded – undo
624 624
 					$xmlrpcfuncname = $prefix.'_'.preg_replace(array('/\./', '/[^a-zA-Z0-9_\x7f-\xff]/'),
625 625
 						array('_', ''), $methodname);
626 626
 				}
627
-				while($buildit && function_exists($xmlrpcfuncname))
627
+				while ($buildit && function_exists($xmlrpcfuncname))
628 628
 				{
629 629
 					$xmlrpcfuncname .= 'x';
630 630
 				}
@@ -633,11 +633,11 @@  discard block
 block discarded – undo
633 633
 				$mdesc = '';
634 634
 				// if in 'offline' mode, get method description too.
635 635
 				// in online mode, favour speed of operation
636
-				if(!$buildit)
636
+				if (!$buildit)
637 637
 				{
638 638
 					$msg = new $msgclass('system.methodHelp');
639 639
 					$msg->addparam(new $valclass($methodname));
640
-					$response =& $client->send($msg, $timeout, $protocol);
640
+					$response = & $client->send($msg, $timeout, $protocol);
641 641
 					if (!$response->faultCode())
642 642
 					{
643 643
 						$mdesc = $response->value();
@@ -660,7 +660,7 @@  discard block
 block discarded – undo
660 660
 					eval($results['source'].'$allOK=1;');
661 661
 					// alternative
662 662
 					//$xmlrpcfuncname = create_function('$m', $innercode);
663
-					if($allOK)
663
+					if ($allOK)
664 664
 					{
665 665
 						return $xmlrpcfuncname;
666 666
 					}
@@ -687,15 +687,15 @@  discard block
 block discarded – undo
687 687
 	* @param array $extra_options list of options for wrapped code
688 688
 	* @return mixed false on error, the name of the created class if all ok or an array with code, class name and comments (if the appropriatevoption is set in extra_options)
689 689
 	*/
690
-	function wrap_xmlrpc_server($client, $extra_options=array())
690
+	function wrap_xmlrpc_server($client, $extra_options = array())
691 691
 	{
692 692
 		$methodfilter = isset($extra_options['method_filter']) ? $extra_options['method_filter'] : '';
693 693
 		//$signum = isset($extra_options['signum']) ? (int)$extra_options['signum'] : 0;
694
-		$timeout = isset($extra_options['timeout']) ? (int)$extra_options['timeout'] : 0;
694
+		$timeout = isset($extra_options['timeout']) ? (int) $extra_options['timeout'] : 0;
695 695
 		$protocol = isset($extra_options['protocol']) ? $extra_options['protocol'] : '';
696 696
 		$newclassname = isset($extra_options['new_class_name']) ? $extra_options['new_class_name'] : '';
697
-		$encode_php_objects = isset($extra_options['encode_php_objs']) ? (bool)$extra_options['encode_php_objs'] : false;
698
-		$decode_php_objects = isset($extra_options['decode_php_objs']) ? (bool)$extra_options['decode_php_objs'] : false;
697
+		$encode_php_objects = isset($extra_options['encode_php_objs']) ? (bool) $extra_options['encode_php_objs'] : false;
698
+		$decode_php_objects = isset($extra_options['decode_php_objs']) ? (bool) $extra_options['decode_php_objs'] : false;
699 699
 		$verbatim_client_copy = isset($extra_options['simple_client_copy']) ? !($extra_options['simple_client_copy']) : true;
700 700
 		$buildit = isset($extra_options['return_source']) ? !($extra_options['return_source']) : true;
701 701
 		$prefix = isset($extra_options['prefix']) ? $extra_options['prefix'] : 'xmlrpc';
@@ -705,8 +705,8 @@  discard block
 block discarded – undo
705 705
 		$decodefunc = 'php_'.$prefix.'_decode';
706 706
 
707 707
 		$msg = new $msgclass('system.listMethods');
708
-		$response =& $client->send($msg, $timeout, $protocol);
709
-		if($response->faultCode())
708
+		$response = & $client->send($msg, $timeout, $protocol);
709
+		if ($response->faultCode())
710 710
 		{
711 711
 			error_log('XML-RPC: could not retrieve method list from remote server');
712 712
 			return false;
@@ -718,7 +718,7 @@  discard block
 block discarded – undo
718 718
 			{
719 719
 				$mlist = $decodefunc($mlist);
720 720
 			}
721
-			if(!is_array($mlist) || !count($mlist))
721
+			if (!is_array($mlist) || !count($mlist))
722 722
 			{
723 723
 				error_log('XML-RPC: could not retrieve meaningful method list from remote server');
724 724
 				return false;
@@ -726,7 +726,7 @@  discard block
 block discarded – undo
726 726
 			else
727 727
 			{
728 728
 				// pick a suitable name for the new function, avoiding collisions
729
-				if($newclassname != '')
729
+				if ($newclassname != '')
730 730
 				{
731 731
 					$xmlrpcclassname = $newclassname;
732 732
 				}
@@ -735,7 +735,7 @@  discard block
 block discarded – undo
735 735
 					$xmlrpcclassname = $prefix.'_'.preg_replace(array('/\./', '/[^a-zA-Z0-9_\x7f-\xff]/'),
736 736
 						array('_', ''), $client->server).'_client';
737 737
 				}
738
-				while($buildit && class_exists($xmlrpcclassname))
738
+				while ($buildit && class_exists($xmlrpcclassname))
739 739
 				{
740 740
 					$xmlrpcclassname .= 'x';
741 741
 				}
@@ -751,7 +751,7 @@  discard block
 block discarded – undo
751 751
 					'decode_php_objs' => $decode_php_objects
752 752
 					);
753 753
 				/// @todo build javadoc for class definition, too
754
-				foreach($mlist as $mname)
754
+				foreach ($mlist as $mname)
755 755
 				{
756 756
 					if ($methodfilter == '' || preg_match($methodfilter, $mname))
757 757
 					{
@@ -779,7 +779,7 @@  discard block
 block discarded – undo
779 779
 					eval($source.'$allOK=1;');
780 780
 					// alternative
781 781
 					//$xmlrpcfuncname = create_function('$m', $innercode);
782
-					if($allOK)
782
+					if ($allOK)
783 783
 					{
784 784
 						return $xmlrpcclassname;
785 785
 					}
@@ -806,12 +806,12 @@  discard block
 block discarded – undo
806 806
 	* @access private
807 807
 	*/
808 808
 	function build_remote_method_wrapper_code($client, $methodname, $xmlrpcfuncname,
809
-		$msig, $mdesc='', $timeout=0, $protocol='', $client_copy_mode=0, $prefix='xmlrpc',
810
-		$decode_php_objects=false, $encode_php_objects=false, $decode_fault=false,
811
-		$fault_response='')
809
+		$msig, $mdesc = '', $timeout = 0, $protocol = '', $client_copy_mode = 0, $prefix = 'xmlrpc',
810
+		$decode_php_objects = false, $encode_php_objects = false, $decode_fault = false,
811
+		$fault_response = '')
812 812
 	{
813 813
 		$code = "function $xmlrpcfuncname (";
814
-		if ($client_copy_mode < 2)
814
+		if ($client_copy_mode<2)
815 815
 		{
816 816
 			// client copy mode 0 or 1 == partial / full client copy in emitted code
817 817
 			$innercode = build_client_wrapper_code($client, $client_copy_mode, $prefix);
@@ -839,11 +839,11 @@  discard block
 block discarded – undo
839 839
 		// param parsing
840 840
 		$plist = array();
841 841
 		$pcount = count($msig);
842
-		for($i = 1; $i < $pcount; $i++)
842
+		for ($i = 1; $i<$pcount; $i++)
843 843
 		{
844 844
 			$plist[] = "\$p$i";
845 845
 			$ptype = $msig[$i];
846
-			if($ptype == 'i4' || $ptype == 'int' || $ptype == 'boolean' || $ptype == 'double' ||
846
+			if ($ptype == 'i4' || $ptype == 'int' || $ptype == 'boolean' || $ptype == 'double' ||
847 847
 				$ptype == 'string' || $ptype == 'dateTime.iso8601' || $ptype == 'base64' || $ptype == 'null')
848 848
 			{
849 849
 				// only build directly xmlrpcvals when type is known and scalar
@@ -863,7 +863,7 @@  discard block
 block discarded – undo
863 863
 			$innercode .= "\$msg->addparam(\$p$i);\n";
864 864
 			$mdesc .= '* @param '.xmlrpc_2_php_type($ptype)." \$p$i\n";
865 865
 		}
866
-		if ($client_copy_mode < 2)
866
+		if ($client_copy_mode<2)
867 867
 		{
868 868
 			$plist[] = '$debug=0';
869 869
 			$mdesc .= "* @param int \$debug when 1 (or 2) will enable debugging of the underlying {$prefix} call (defaults to 0)\n";
@@ -896,7 +896,7 @@  discard block
 block discarded – undo
896 896
 			$innercode .= "if (\$res->faultcode()) return $respcode; else return php_{$prefix}_decode(\$res->value());";
897 897
 		}
898 898
 
899
-		$code = $code . $plist. ") {\n" . $innercode . "\n}\n";
899
+		$code = $code.$plist.") {\n".$innercode."\n}\n";
900 900
 
901 901
 		return array('source' => $code, 'docstring' => $mdesc);
902 902
 	}
@@ -907,18 +907,18 @@  discard block
 block discarded – undo
907 907
 	* valid php code is emitted.
908 908
 	* @access private
909 909
 	*/
910
-	function build_client_wrapper_code($client, $verbatim_client_copy, $prefix='xmlrpc')
910
+	function build_client_wrapper_code($client, $verbatim_client_copy, $prefix = 'xmlrpc')
911 911
 	{
912 912
 		$code = "\$client = new {$prefix}_client('".str_replace("'", "\'", $client->path).
913
-			"', '" . str_replace("'", "\'", $client->server) . "', $client->port);\n";
913
+			"', '".str_replace("'", "\'", $client->server)."', $client->port);\n";
914 914
 
915 915
 		// copy all client fields to the client that will be generated runtime
916 916
 		// (this provides for future expansion or subclassing of client obj)
917 917
 		if ($verbatim_client_copy)
918 918
 		{
919
-			foreach($client as $fld => $val)
919
+			foreach ($client as $fld => $val)
920 920
 			{
921
-				if($fld != 'debug' && $fld != 'return_type')
921
+				if ($fld != 'debug' && $fld != 'return_type')
922 922
 				{
923 923
 					$val = var_export($val, true);
924 924
 					$code .= "\$client->$fld = $val;\n";
Please login to merge, or discard this patch.
Braces   +46 added lines, -80 removed lines patch added patch discarded remove patch
@@ -52,8 +52,7 @@  discard block
 block discarded – undo
52 52
 				if(class_exists($phptype))
53 53
 				{
54 54
 					return $GLOBALS['xmlrpcStruct'];
55
-				}
56
-				else
55
+				} else
57 56
 				{
58 57
 					// unknown: might be any 'extended' xmlrpc type
59 58
 					return $GLOBALS['xmlrpcValue'];
@@ -163,14 +162,12 @@  discard block
 block discarded – undo
163 162
 			if(is_string($funcname[0]))
164 163
 			{
165 164
 				$plainfuncname = implode('::', $funcname);
166
-			}
167
-			elseif(is_object($funcname[0]))
165
+			} elseif(is_object($funcname[0]))
168 166
 			{
169 167
 				$plainfuncname = get_class($funcname[0]) . '->' . $funcname[1];
170 168
 			}
171 169
 			$exists = method_exists($funcname[0], $funcname[1]);
172
-		}
173
-		else
170
+		} else
174 171
 		{
175 172
 			$plainfuncname = $funcname;
176 173
 			$exists = function_exists($funcname);
@@ -180,25 +177,23 @@  discard block
 block discarded – undo
180 177
 		{
181 178
 			error_log('XML-RPC: function to be wrapped is not defined: '.$plainfuncname);
182 179
 			return false;
183
-		}
184
-		else
180
+		} else
185 181
 		{
186 182
 			// determine name of new php function
187 183
 			if($newfuncname == '')
188 184
 			{
189 185
 				if(is_array($funcname))
190 186
 				{
191
-					if(is_string($funcname[0]))
192
-						$xmlrpcfuncname = "{$prefix}_".implode('_', $funcname);
193
-					else
194
-						$xmlrpcfuncname = "{$prefix}_".get_class($funcname[0]) . '_' . $funcname[1];
195
-				}
196
-				else
187
+					if(is_string($funcname[0])) {
188
+											$xmlrpcfuncname = "{$prefix}_".implode('_', $funcname);
189
+					} else {
190
+											$xmlrpcfuncname = "{$prefix}_".get_class($funcname[0]) . '_' . $funcname[1];
191
+					}
192
+				} else
197 193
 				{
198 194
 					$xmlrpcfuncname = "{$prefix}_$funcname";
199 195
 				}
200
-			}
201
-			else
196
+			} else
202 197
 			{
203 198
 				$xmlrpcfuncname = $newfuncname;
204 199
 			}
@@ -237,8 +232,7 @@  discard block
 block discarded – undo
237 232
 					return false;
238 233
 				}
239 234
 				/// @todo add more checks for static vs. nonstatic?
240
-			}
241
-			else
235
+			} else
242 236
 			{
243 237
 				$func = new ReflectionFunction($funcname);
244 238
 			}
@@ -276,8 +270,7 @@  discard block
 block discarded – undo
276 270
 							$desc .= "\n";
277 271
 						}
278 272
 						$desc .= $doc;
279
-					}
280
-					elseif(strpos($doc, '@param') === 0)
273
+					} elseif(strpos($doc, '@param') === 0)
281 274
 					{
282 275
 						// syntax: @param type [$name] desc
283 276
 						if(preg_match('/@param\s+(\S+)(\s+\$\S+)?\s+(.+)/', $doc, $matches))
@@ -286,8 +279,7 @@  discard block
 block discarded – undo
286 279
 							{
287 280
 								//$paramDocs[$i]['type'] = explode('|', $matches[1]);
288 281
 								$paramDocs[$i]['type'] = 'mixed';
289
-							}
290
-							else
282
+							} else
291 283
 							{
292 284
 								$paramDocs[$i]['type'] = $matches[1];
293 285
 							}
@@ -295,8 +287,7 @@  discard block
 block discarded – undo
295 287
 							$paramDocs[$i]['doc'] = $matches[3];
296 288
 						}
297 289
 						$i++;
298
-					}
299
-					elseif(strpos($doc, '@return') === 0)
290
+					} elseif(strpos($doc, '@return') === 0)
300 291
 					{
301 292
 						// syntax: @return type desc
302 293
 						//$returns = preg_split('/\s+/', $doc);
@@ -347,8 +338,7 @@  discard block
 block discarded – undo
347 338
 				if ($decode_php_objects)
348 339
 				{
349 340
 					$innercode .= "if (\$p{$i}->kindOf() == 'scalar') \$p$i = \$p{$i}->scalarval(); else \$p$i = php_{$prefix}_decode(\$p$i, array('decode_php_objs'));\n";
350
-				}
351
-				else
341
+				} else
352 342
 				{
353 343
 					$innercode .= "if (\$p{$i}->kindOf() == 'scalar') \$p$i = \$p{$i}->scalarval(); else \$p$i = php_{$prefix}_decode(\$p$i);\n";
354 344
 				}
@@ -373,8 +363,7 @@  discard block
 block discarded – undo
373 363
 				// only known good synopsis = no parameters
374 364
 				$parsvariations[] = array();
375 365
 				$minpars = 0;
376
-			}
377
-			else
366
+			} else
378 367
 			{
379 368
 				$minpars = count($parsvariations[0]);
380 369
 			}
@@ -385,8 +374,7 @@  discard block
 block discarded – undo
385 374
 				// NB: this check needs to be done BEFORE decoding param values
386 375
 				$innercode = "\$paramcount = \$msg->getNumParams();\n" .
387 376
 				"if (\$paramcount < $minpars) return new {$prefix}resp(0, {$GLOBALS['xmlrpcerr']['incorrect_params']}, '{$GLOBALS['xmlrpcstr']['incorrect_params']}');\n" . $innercode;
388
-			}
389
-			else
377
+			} else
390 378
 			{
391 379
 				$innercode = "\$paramcount = \$msg->getNumParams();\n" . $innercode;
392 380
 			}
@@ -399,8 +387,7 @@  discard block
 block discarded – undo
399 387
 				$GLOBALS['xmlrpcWPFObjHolder'][$xmlrpcfuncname] =& $funcname[0];
400 388
 				$innercode .= "\$obj =& \$GLOBALS['xmlrpcWPFObjHolder']['$xmlrpcfuncname'];\n";
401 389
 				$realfuncname = '$obj->'.$funcname[1];
402
-			}
403
-			else
390
+			} else
404 391
 			{
405 392
 				$realfuncname = $plainfuncname;
406 393
 			}
@@ -415,8 +402,7 @@  discard block
 block discarded – undo
415 402
 					if (isset($paramDocs[$i]['type']))
416 403
 					{
417 404
 						$sig[] = php_2_xmlrpc_type($paramDocs[$i]['type']);
418
-					}
419
-					else
405
+					} else
420 406
 					{
421 407
 						$sig[] = $GLOBALS['xmlrpcValue'];
422 408
 					}
@@ -432,13 +418,13 @@  discard block
 block discarded – undo
432 418
 			if($returns == $GLOBALS['xmlrpcDateTime'] || $returns == $GLOBALS['xmlrpcBase64'])
433 419
 			{
434 420
 				$innercode .= "return new {$prefix}resp(new {$prefix}val(\$retval, '$returns'));";
435
-			}
436
-			else
421
+			} else
437 422
 			{
438
-				if ($encode_php_objects)
439
-					$innercode .= "return new {$prefix}resp(php_{$prefix}_encode(\$retval, array('encode_php_objs')));\n";
440
-				else
441
-					$innercode .= "return new {$prefix}resp(php_{$prefix}_encode(\$retval));\n";
423
+				if ($encode_php_objects) {
424
+									$innercode .= "return new {$prefix}resp(php_{$prefix}_encode(\$retval, array('encode_php_objs')));\n";
425
+				} else {
426
+									$innercode .= "return new {$prefix}resp(php_{$prefix}_encode(\$retval));\n";
427
+				}
442 428
 			}
443 429
 			// shall we exclude functions returning by ref?
444 430
 			// if($func->returnsReference())
@@ -555,8 +541,7 @@  discard block
 block discarded – undo
555 541
 		{
556 542
 			$signum = $extra_options;
557 543
 			$extra_options = array();
558
-		}
559
-		else
544
+		} else
560 545
 		{
561 546
 			$signum = isset($extra_options['signum']) ? (int)$extra_options['signum'] : 0;
562 547
 			$timeout = isset($extra_options['timeout']) ? (int)$extra_options['timeout'] : 0;
@@ -577,8 +562,7 @@  discard block
 block discarded – undo
577 562
 		{
578 563
 			$decode_fault = true;
579 564
 			$fault_response = $extra_options['return_on_fault'];
580
-		}
581
-		else
565
+		} else
582 566
 		{
583 567
 			$decode_fault = false;
584 568
 			$fault_response = '';
@@ -597,8 +581,7 @@  discard block
 block discarded – undo
597 581
 		{
598 582
 			error_log('XML-RPC: could not retrieve method signature from remote server for method '.$methodname);
599 583
 			return false;
600
-		}
601
-		else
584
+		} else
602 585
 		{
603 586
 			$msig = $response->value();
604 587
 			if ($client->return_type != 'phpvals')
@@ -609,15 +592,13 @@  discard block
 block discarded – undo
609 592
 			{
610 593
 				error_log('XML-RPC: could not retrieve method signature nr.'.$signum.' from remote server for method '.$methodname);
611 594
 				return false;
612
-			}
613
-			else
595
+			} else
614 596
 			{
615 597
 				// pick a suitable name for the new function, avoiding collisions
616 598
 				if($newfuncname != '')
617 599
 				{
618 600
 					$xmlrpcfuncname = $newfuncname;
619
-				}
620
-				else
601
+				} else
621 602
 				{
622 603
 					// take care to insure that methodname is translated to valid
623 604
 					// php function name
@@ -663,14 +644,12 @@  discard block
 block discarded – undo
663 644
 					if($allOK)
664 645
 					{
665 646
 						return $xmlrpcfuncname;
666
-					}
667
-					else
647
+					} else
668 648
 					{
669 649
 						error_log('XML-RPC: could not create function '.$xmlrpcfuncname.' to wrap remote method '.$methodname);
670 650
 						return false;
671 651
 					}
672
-				}
673
-				else
652
+				} else
674 653
 				{
675 654
 					$results['function'] = $xmlrpcfuncname;
676 655
 					return $results;
@@ -710,8 +689,7 @@  discard block
 block discarded – undo
710 689
 		{
711 690
 			error_log('XML-RPC: could not retrieve method list from remote server');
712 691
 			return false;
713
-		}
714
-		else
692
+		} else
715 693
 		{
716 694
 			$mlist = $response->value();
717 695
 			if ($client->return_type != 'phpvals')
@@ -722,15 +700,13 @@  discard block
 block discarded – undo
722 700
 			{
723 701
 				error_log('XML-RPC: could not retrieve meaningful method list from remote server');
724 702
 				return false;
725
-			}
726
-			else
703
+			} else
727 704
 			{
728 705
 				// pick a suitable name for the new function, avoiding collisions
729 706
 				if($newclassname != '')
730 707
 				{
731 708
 					$xmlrpcclassname = $newclassname;
732
-				}
733
-				else
709
+				} else
734 710
 				{
735 711
 					$xmlrpcclassname = $prefix.'_'.preg_replace(array('/\./', '/[^a-zA-Z0-9_\x7f-\xff]/'),
736 712
 						array('_', ''), $client->server).'_client';
@@ -765,8 +741,7 @@  discard block
 block discarded – undo
765 741
 								$source .= $methodwrap['docstring'];
766 742
 							}
767 743
 							$source .= $methodwrap['source']."\n";
768
-						}
769
-						else
744
+						} else
770 745
 						{
771 746
 							error_log('XML-RPC: will not create class method to wrap remote method '.$mname);
772 747
 						}
@@ -782,14 +757,12 @@  discard block
 block discarded – undo
782 757
 					if($allOK)
783 758
 					{
784 759
 						return $xmlrpcclassname;
785
-					}
786
-					else
760
+					} else
787 761
 					{
788 762
 						error_log('XML-RPC: could not create class '.$xmlrpcclassname.' to wrap remote server '.$client->server);
789 763
 						return false;
790 764
 					}
791
-				}
792
-				else
765
+				} else
793 766
 				{
794 767
 					return array('class' => $xmlrpcclassname, 'code' => $source, 'docstring' => '');
795 768
 				}
@@ -817,8 +790,7 @@  discard block
 block discarded – undo
817 790
 			$innercode = build_client_wrapper_code($client, $client_copy_mode, $prefix);
818 791
 			$innercode .= "\$client->setDebug(\$debug);\n";
819 792
 			$this_ = '';
820
-		}
821
-		else
793
+		} else
822 794
 		{
823 795
 			// client copy mode 2 == no client copy in emitted code
824 796
 			$innercode = '';
@@ -830,8 +802,7 @@  discard block
 block discarded – undo
830 802
 		{
831 803
 			// take care that PHP comment is not terminated unwillingly by method description
832 804
 			$mdesc = "/**\n* ".str_replace('*/', '* /', $mdesc)."\n";
833
-		}
834
-		else
805
+		} else
835 806
 		{
836 807
 			$mdesc = "/**\nFunction $xmlrpcfuncname\n";
837 808
 		}
@@ -848,14 +819,12 @@  discard block
 block discarded – undo
848 819
 			{
849 820
 				// only build directly xmlrpcvals when type is known and scalar
850 821
 				$innercode .= "\$p$i = new {$prefix}val(\$p$i, '$ptype');\n";
851
-			}
852
-			else
822
+			} else
853 823
 			{
854 824
 				if ($encode_php_objects)
855 825
 				{
856 826
 					$innercode .= "\$p$i =& php_{$prefix}_encode(\$p$i, array('encode_php_objs'));\n";
857
-				}
858
-				else
827
+				} else
859 828
 				{
860 829
 					$innercode .= "\$p$i =& php_{$prefix}_encode(\$p$i);\n";
861 830
 				}
@@ -877,21 +846,18 @@  discard block
 block discarded – undo
877 846
 			if (is_string($fault_response) && ((strpos($fault_response, '%faultCode%') !== false) || (strpos($fault_response, '%faultString%') !== false)))
878 847
 			{
879 848
 				$respcode = "str_replace(array('%faultCode%', '%faultString%'), array(\$res->faultCode(), \$res->faultString()), '".str_replace("'", "''", $fault_response)."')";
880
-			}
881
-			else
849
+			} else
882 850
 			{
883 851
 				$respcode = var_export($fault_response, true);
884 852
 			}
885
-		}
886
-		else
853
+		} else
887 854
 		{
888 855
 			$respcode = '$res';
889 856
 		}
890 857
 		if ($decode_php_objects)
891 858
 		{
892 859
 			$innercode .= "if (\$res->faultcode()) return $respcode; else return php_{$prefix}_decode(\$res->value(), array('decode_php_objs'));";
893
-		}
894
-		else
860
+		} else
895 861
 		{
896 862
 			$innercode .= "if (\$res->faultcode()) return $respcode; else return php_{$prefix}_decode(\$res->value());";
897 863
 		}
Please login to merge, or discard this patch.
lib/xmlrpcs.inc 3 patches
Indentation   +1208 added lines, -1208 removed lines patch added patch discarded remove patch
@@ -34,1215 +34,1215 @@
 block discarded – undo
34 34
 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
35 35
 // OF THE POSSIBILITY OF SUCH DAMAGE.
36 36
 
37
-	// XML RPC Server class
38
-	// requires: xmlrpc.inc
39
-
40
-	$GLOBALS['xmlrpcs_capabilities'] = array(
41
-		// xmlrpc spec: always supported
42
-		'xmlrpc' => new xmlrpcval(array(
43
-			'specUrl' => new xmlrpcval('http://www.xmlrpc.com/spec', 'string'),
44
-			'specVersion' => new xmlrpcval(1, 'int')
45
-		), 'struct'),
46
-		// if we support system.xxx functions, we always support multicall, too...
47
-		// Note that, as of 2006/09/17, the following URL does not respond anymore
48
-		'system.multicall' => new xmlrpcval(array(
49
-			'specUrl' => new xmlrpcval('http://www.xmlrpc.com/discuss/msgReader$1208', 'string'),
50
-			'specVersion' => new xmlrpcval(1, 'int')
51
-		), 'struct'),
52
-		// introspection: version 2! we support 'mixed', too
53
-		'introspection' => new xmlrpcval(array(
54
-			'specUrl' => new xmlrpcval('http://phpxmlrpc.sourceforge.net/doc-2/ch10.html', 'string'),
55
-			'specVersion' => new xmlrpcval(2, 'int')
56
-		), 'struct')
57
-	);
58
-
59
-	/* Functions that implement system.XXX methods of xmlrpc servers */
60
-	$_xmlrpcs_getCapabilities_sig=array(array($GLOBALS['xmlrpcStruct']));
61
-	$_xmlrpcs_getCapabilities_doc='This method lists all the capabilites that the XML-RPC server has: the (more or less standard) extensions to the xmlrpc spec that it adheres to';
62
-	$_xmlrpcs_getCapabilities_sdoc=array(array('list of capabilities, described as structs with a version number and url for the spec'));
63
-	function _xmlrpcs_getCapabilities($server, $m=null)
64
-	{
65
-		$outAr = $GLOBALS['xmlrpcs_capabilities'];
66
-		// NIL extension
67
-		if ($GLOBALS['xmlrpc_null_extension']) {
68
-			$outAr['nil'] = new xmlrpcval(array(
69
-				'specUrl' => new xmlrpcval('http://www.ontosys.com/xml-rpc/extensions.php', 'string'),
70
-				'specVersion' => new xmlrpcval(1, 'int')
71
-			), 'struct');
72
-		}
73
-		return new xmlrpcresp(new xmlrpcval($outAr, 'struct'));
74
-	}
75
-
76
-	// listMethods: signature was either a string, or nothing.
77
-	// The useless string variant has been removed
78
-	$_xmlrpcs_listMethods_sig=array(array($GLOBALS['xmlrpcArray']));
79
-	$_xmlrpcs_listMethods_doc='This method lists all the methods that the XML-RPC server knows how to dispatch';
80
-	$_xmlrpcs_listMethods_sdoc=array(array('list of method names'));
81
-	function _xmlrpcs_listMethods($server, $m=null) // if called in plain php values mode, second param is missing
82
-	{
83
-
84
-		$outAr=array();
85
-		foreach($server->dmap as $key => $val)
86
-		{
87
-			$outAr[]=new xmlrpcval($key, 'string');
88
-		}
89
-		if($server->allow_system_funcs)
90
-		{
91
-			foreach($GLOBALS['_xmlrpcs_dmap'] as $key => $val)
92
-			{
93
-				$outAr[]=new xmlrpcval($key, 'string');
94
-			}
95
-		}
96
-		return new xmlrpcresp(new xmlrpcval($outAr, 'array'));
97
-	}
98
-
99
-	$_xmlrpcs_methodSignature_sig=array(array($GLOBALS['xmlrpcArray'], $GLOBALS['xmlrpcString']));
100
-	$_xmlrpcs_methodSignature_doc='Returns an array of known signatures (an array of arrays) for the method name passed. If no signatures are known, returns a none-array (test for type != array to detect missing signature)';
101
-	$_xmlrpcs_methodSignature_sdoc=array(array('list of known signatures, each sig being an array of xmlrpc type names', 'name of method to be described'));
102
-	function _xmlrpcs_methodSignature($server, $m)
103
-	{
104
-		// let accept as parameter both an xmlrpcval or string
105
-		if (is_object($m))
106
-		{
107
-			$methName=$m->getParam(0);
108
-			$methName=$methName->scalarval();
109
-		}
110
-		else
111
-		{
112
-			$methName=$m;
113
-		}
114
-		if(strpos($methName, "system.") === 0)
115
-		{
116
-			$dmap=$GLOBALS['_xmlrpcs_dmap']; //$sysCall=1;
117
-		}
118
-		else
119
-		{
120
-			$dmap=$server->dmap; //$sysCall=0;
121
-		}
122
-		if(isset($dmap[$methName]))
123
-		{
124
-			if(isset($dmap[$methName]['signature']))
125
-			{
126
-				$sigs=array();
127
-				foreach($dmap[$methName]['signature'] as $inSig)
128
-				{
129
-					$cursig=array();
130
-					foreach($inSig as $sig)
131
-					{
132
-						$cursig[]=new xmlrpcval($sig, 'string');
133
-					}
134
-					$sigs[]=new xmlrpcval($cursig, 'array');
135
-				}
136
-				$r=new xmlrpcresp(new xmlrpcval($sigs, 'array'));
137
-			}
138
-			else
139
-			{
140
-				// NB: according to the official docs, we should be returning a
141
-				// "none-array" here, which means not-an-array
142
-				$r=new xmlrpcresp(new xmlrpcval('undef', 'string'));
143
-			}
144
-		}
145
-		else
146
-		{
147
-			$r=new xmlrpcresp(0,$GLOBALS['xmlrpcerr']['introspect_unknown'], $GLOBALS['xmlrpcstr']['introspect_unknown']);
148
-		}
149
-		return $r;
150
-	}
151
-
152
-	$_xmlrpcs_methodHelp_sig=array(array($GLOBALS['xmlrpcString'], $GLOBALS['xmlrpcString']));
153
-	$_xmlrpcs_methodHelp_doc='Returns help text if defined for the method passed, otherwise returns an empty string';
154
-	$_xmlrpcs_methodHelp_sdoc=array(array('method description', 'name of the method to be described'));
155
-	function _xmlrpcs_methodHelp($server, $m)
156
-	{
157
-		// let accept as parameter both an xmlrpcval or string
158
-		if (is_object($m))
159
-		{
160
-			$methName=$m->getParam(0);
161
-			$methName=$methName->scalarval();
162
-		}
163
-		else
164
-		{
165
-			$methName=$m;
166
-		}
167
-		if(strpos($methName, "system.") === 0)
168
-		{
169
-			$dmap=$GLOBALS['_xmlrpcs_dmap']; //$sysCall=1;
170
-		}
171
-		else
172
-		{
173
-			$dmap=$server->dmap; //$sysCall=0;
174
-		}
175
-		if(isset($dmap[$methName]))
176
-		{
177
-			if(isset($dmap[$methName]['docstring']))
178
-			{
179
-				$r=new xmlrpcresp(new xmlrpcval($dmap[$methName]['docstring']), 'string');
180
-			}
181
-			else
182
-			{
183
-				$r=new xmlrpcresp(new xmlrpcval('', 'string'));
184
-			}
185
-		}
186
-		else
187
-		{
188
-			$r=new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['introspect_unknown'], $GLOBALS['xmlrpcstr']['introspect_unknown']);
189
-		}
190
-		return $r;
191
-	}
192
-
193
-	$_xmlrpcs_multicall_sig = array(array($GLOBALS['xmlrpcArray'], $GLOBALS['xmlrpcArray']));
194
-	$_xmlrpcs_multicall_doc = 'Boxcar multiple RPC calls in one request. See http://www.xmlrpc.com/discuss/msgReader$1208 for details';
195
-	$_xmlrpcs_multicall_sdoc = array(array('list of response structs, where each struct has the usual members', 'list of calls, with each call being represented as a struct, with members "methodname" and "params"'));
196
-	function _xmlrpcs_multicall_error($err)
197
-	{
198
-		if(is_string($err))
199
-		{
200
-			$str = $GLOBALS['xmlrpcstr']["multicall_${err}"];
201
-			$code = $GLOBALS['xmlrpcerr']["multicall_${err}"];
202
-		}
203
-		else
204
-		{
205
-			$code = $err->faultCode();
206
-			$str = $err->faultString();
207
-		}
208
-		$struct = array();
209
-		$struct['faultCode'] = new xmlrpcval($code, 'int');
210
-		$struct['faultString'] = new xmlrpcval($str, 'string');
211
-		return new xmlrpcval($struct, 'struct');
212
-	}
213
-
214
-	function _xmlrpcs_multicall_do_call($server, $call)
215
-	{
216
-		if($call->kindOf() != 'struct')
217
-		{
218
-			return _xmlrpcs_multicall_error('notstruct');
219
-		}
220
-		$methName = @$call->structmem('methodName');
221
-		if(!$methName)
222
-		{
223
-			return _xmlrpcs_multicall_error('nomethod');
224
-		}
225
-		if($methName->kindOf() != 'scalar' || $methName->scalartyp() != 'string')
226
-		{
227
-			return _xmlrpcs_multicall_error('notstring');
228
-		}
229
-		if($methName->scalarval() == 'system.multicall')
230
-		{
231
-			return _xmlrpcs_multicall_error('recursion');
232
-		}
233
-
234
-		$params = @$call->structmem('params');
235
-		if(!$params)
236
-		{
237
-			return _xmlrpcs_multicall_error('noparams');
238
-		}
239
-		if($params->kindOf() != 'array')
240
-		{
241
-			return _xmlrpcs_multicall_error('notarray');
242
-		}
243
-		$numParams = $params->arraysize();
244
-
245
-		$msg = new xmlrpcmsg($methName->scalarval());
246
-		for($i = 0; $i < $numParams; $i++)
247
-		{
248
-			if(!$msg->addParam($params->arraymem($i)))
249
-			{
250
-				$i++;
251
-				return _xmlrpcs_multicall_error(new xmlrpcresp(0,
252
-					$GLOBALS['xmlrpcerr']['incorrect_params'],
253
-					$GLOBALS['xmlrpcstr']['incorrect_params'] . ": probable xml error in param " . $i));
254
-			}
255
-		}
256
-
257
-		$result = $server->execute($msg);
258
-
259
-		if($result->faultCode() != 0)
260
-		{
261
-			return _xmlrpcs_multicall_error($result);		// Method returned fault.
262
-		}
263
-
264
-		return new xmlrpcval(array($result->value()), 'array');
265
-	}
266
-
267
-	function _xmlrpcs_multicall_do_call_phpvals($server, $call)
268
-	{
269
-		if(!is_array($call))
270
-		{
271
-			return _xmlrpcs_multicall_error('notstruct');
272
-		}
273
-		if(!array_key_exists('methodName', $call))
274
-		{
275
-			return _xmlrpcs_multicall_error('nomethod');
276
-		}
277
-		if (!is_string($call['methodName']))
278
-		{
279
-			return _xmlrpcs_multicall_error('notstring');
280
-		}
281
-		if($call['methodName'] == 'system.multicall')
282
-		{
283
-			return _xmlrpcs_multicall_error('recursion');
284
-		}
285
-		if(!array_key_exists('params', $call))
286
-		{
287
-			return _xmlrpcs_multicall_error('noparams');
288
-		}
289
-		if(!is_array($call['params']))
290
-		{
291
-			return _xmlrpcs_multicall_error('notarray');
292
-		}
293
-
294
-		// this is a real dirty and simplistic hack, since we might have received a
295
-		// base64 or datetime values, but they will be listed as strings here...
296
-		//$numParams = count($call['params']);
297
-		$pt = array();
298
-		foreach($call['params'] as $val)
299
-			$pt[] = php_2_xmlrpc_type(gettype($val));
300
-
301
-		$result = $server->execute($call['methodName'], $call['params'], $pt);
302
-
303
-		if($result->faultCode() != 0)
304
-		{
305
-			return _xmlrpcs_multicall_error($result);		// Method returned fault.
306
-		}
307
-
308
-		return new xmlrpcval(array($result->value()), 'array');
309
-	}
310
-
311
-	function _xmlrpcs_multicall($server, $m)
312
-	{
313
-		$result = array();
314
-		// let accept a plain list of php parameters, beside a single xmlrpc msg object
315
-		if (is_object($m))
316
-		{
317
-			$calls = $m->getParam(0);
318
-			$numCalls = $calls->arraysize();
319
-			for($i = 0; $i < $numCalls; $i++)
320
-			{
321
-				$call = $calls->arraymem($i);
322
-				$result[$i] = _xmlrpcs_multicall_do_call($server, $call);
323
-			}
324
-		}
325
-		else
326
-		{
327
-			$numCalls=count($m);
328
-			for($i = 0; $i < $numCalls; $i++)
329
-			{
330
-				$result[$i] = _xmlrpcs_multicall_do_call_phpvals($server, $m[$i]);
331
-			}
332
-		}
333
-
334
-		return new xmlrpcresp(new xmlrpcval($result, 'array'));
335
-	}
336
-
337
-	$GLOBALS['_xmlrpcs_dmap']=array(
338
-		'system.listMethods' => array(
339
-			'function' => '_xmlrpcs_listMethods',
340
-			'signature' => $_xmlrpcs_listMethods_sig,
341
-			'docstring' => $_xmlrpcs_listMethods_doc,
342
-			'signature_docs' => $_xmlrpcs_listMethods_sdoc),
343
-		'system.methodHelp' => array(
344
-			'function' => '_xmlrpcs_methodHelp',
345
-			'signature' => $_xmlrpcs_methodHelp_sig,
346
-			'docstring' => $_xmlrpcs_methodHelp_doc,
347
-			'signature_docs' => $_xmlrpcs_methodHelp_sdoc),
348
-		'system.methodSignature' => array(
349
-			'function' => '_xmlrpcs_methodSignature',
350
-			'signature' => $_xmlrpcs_methodSignature_sig,
351
-			'docstring' => $_xmlrpcs_methodSignature_doc,
352
-			'signature_docs' => $_xmlrpcs_methodSignature_sdoc),
353
-		'system.multicall' => array(
354
-			'function' => '_xmlrpcs_multicall',
355
-			'signature' => $_xmlrpcs_multicall_sig,
356
-			'docstring' => $_xmlrpcs_multicall_doc,
357
-			'signature_docs' => $_xmlrpcs_multicall_sdoc),
358
-		'system.getCapabilities' => array(
359
-			'function' => '_xmlrpcs_getCapabilities',
360
-			'signature' => $_xmlrpcs_getCapabilities_sig,
361
-			'docstring' => $_xmlrpcs_getCapabilities_doc,
362
-			'signature_docs' => $_xmlrpcs_getCapabilities_sdoc)
363
-	);
364
-
365
-	$GLOBALS['_xmlrpcs_occurred_errors'] = '';
366
-	$GLOBALS['_xmlrpcs_prev_ehandler'] = '';
367
-
368
-	/**
369
-	* Error handler used to track errors that occur during server-side execution of PHP code.
370
-	* This allows to report back to the client whether an internal error has occurred or not
371
-	* using an xmlrpc response object, instead of letting the client deal with the html junk
372
-	* that a PHP execution error on the server generally entails.
373
-	*
374
-	* NB: in fact a user defined error handler can only handle WARNING, NOTICE and USER_* errors.
375
-	*
376
-	*/
377
-	function _xmlrpcs_errorHandler($errcode, $errstring, $filename=null, $lineno=null, $context=null)
378
-	{
379
-		// obey the @ protocol
380
-		if (error_reporting() == 0)
381
-			return;
382
-
383
-		//if($errcode != E_NOTICE && $errcode != E_WARNING && $errcode != E_USER_NOTICE && $errcode != E_USER_WARNING)
384
-		if($errcode != E_STRICT)
385
-		{
386
-			$GLOBALS['_xmlrpcs_occurred_errors'] = $GLOBALS['_xmlrpcs_occurred_errors'] . $errstring . "\n";
387
-		}
388
-		// Try to avoid as much as possible disruption to the previous error handling
389
-		// mechanism in place
390
-		if($GLOBALS['_xmlrpcs_prev_ehandler'] == '')
391
-		{
392
-			// The previous error handler was the default: all we should do is log error
393
-			// to the default error log (if level high enough)
394
-			if(ini_get('log_errors') && (intval(ini_get('error_reporting')) & $errcode))
395
-			{
396
-				error_log($errstring);
397
-			}
398
-		}
399
-		else
400
-		{
401
-			// Pass control on to previous error handler, trying to avoid loops...
402
-			if($GLOBALS['_xmlrpcs_prev_ehandler'] != '_xmlrpcs_errorHandler')
403
-			{
404
-				// NB: this code will NOT work on php < 4.0.2: only 2 params were used for error handlers
405
-				if(is_array($GLOBALS['_xmlrpcs_prev_ehandler']))
406
-				{
407
-					// the following works both with static class methods and plain object methods as error handler
408
-					call_user_func_array($GLOBALS['_xmlrpcs_prev_ehandler'], array($errcode, $errstring, $filename, $lineno, $context));
409
-				}
410
-				else
411
-				{
412
-					$GLOBALS['_xmlrpcs_prev_ehandler']($errcode, $errstring, $filename, $lineno, $context);
413
-				}
414
-			}
415
-		}
416
-	}
417
-
418
-	$GLOBALS['_xmlrpc_debuginfo']='';
419
-
420
-	/**
421
-	* Add a string to the debug info that can be later seralized by the server
422
-	* as part of the response message.
423
-	* Note that for best compatibility, the debug string should be encoded using
424
-	* the $GLOBALS['xmlrpc_internalencoding'] character set.
425
-	* @param string $m
426
-	* @access public
427
-	*/
428
-	function xmlrpc_debugmsg($m)
429
-	{
430
-		$GLOBALS['_xmlrpc_debuginfo'] .= $m . "\n";
431
-	}
432
-
433
-	class xmlrpc_server
434
-	{
435
-		/**
436
-		* Array defining php functions exposed as xmlrpc methods by this server
437
-		* @access private
438
-		*/
439
-		var $dmap=array();
440
-		/**
441
-		* Defines how functions in dmap will be invoked: either using an xmlrpc msg object
442
-		* or plain php values.
443
-		* valid strings are 'xmlrpcvals', 'phpvals' or 'epivals'
444
-		*/
445
-		var $functions_parameters_type='xmlrpcvals';
446
-		/**
447
-		* Option used for fine-tuning the encoding the php values returned from
448
-		* functions registered in the dispatch map when the functions_parameters_types
449
-		* member is set to 'phpvals'
450
-		* @see php_xmlrpc_encode for a list of values
451
-		*/
452
-		var $phpvals_encoding_options = array( 'auto_dates' );
453
-		/// controls whether the server is going to echo debugging messages back to the client as comments in response body. valid values: 0,1,2,3
454
-		var $debug = 1;
455
-		/**
456
-		* Controls behaviour of server when invoked user function throws an exception:
457
-		* 0 = catch it and return an 'internal error' xmlrpc response (default)
458
-		* 1 = catch it and return an xmlrpc response with the error corresponding to the exception
459
-		* 2 = allow the exception to float to the upper layers
460
-		*/
461
-		var $exception_handling = 0;
462
-		/**
463
-		* When set to true, it will enable HTTP compression of the response, in case
464
-		* the client has declared its support for compression in the request.
465
-		*/
466
-		var $compress_response = false;
467
-		/**
468
-		* List of http compression methods accepted by the server for requests.
469
-		* NB: PHP supports deflate, gzip compressions out of the box if compiled w. zlib
470
-		*/
471
-		var $accepted_compression = array();
472
-		/// shall we serve calls to system.* methods?
473
-		var $allow_system_funcs = true;
474
-		/// list of charset encodings natively accepted for requests
475
-		var $accepted_charset_encodings = array();
476
-		/**
477
-		* charset encoding to be used for response.
478
-		* NB: if we can, we will convert the generated response from internal_encoding to the intended one.
479
-		* can be: a supported xml encoding (only UTF-8 and ISO-8859-1 at present, unless mbstring is enabled),
480
-		* null (leave unspecified in response, convert output stream to US_ASCII),
481
-		* 'default' (use xmlrpc library default as specified in xmlrpc.inc, convert output stream if needed),
482
-		* or 'auto' (use client-specified charset encoding or same as request if request headers do not specify it (unless request is US-ASCII: then use library default anyway).
483
-		* NB: pretty dangerous if you accept every charset and do not have mbstring enabled)
484
-		*/
485
-		var $response_charset_encoding = '';
486
-		/**
487
-		* Storage for internal debug info
488
-		* @access private
489
-		*/
490
-		var $debug_info = '';
491
-		/**
492
-		* Extra data passed at runtime to method handling functions. Used only by EPI layer
493
-		*/
494
-		var $user_data = null;
495
-
496
-		/**
497
-		* @param array $dispmap the dispatch map with definition of exposed services
498
-		* @param boolean $servicenow set to false to prevent the server from running upon construction
499
-		*/
500
-		function __construct($dispMap=null, $serviceNow=true)
501
-		{
502
-			// if ZLIB is enabled, let the server by default accept compressed requests,
503
-			// and compress responses sent to clients that support them
504
-			if(function_exists('gzinflate'))
505
-			{
506
-				$this->accepted_compression = array('gzip', 'deflate');
507
-				$this->compress_response = true;
508
-			}
509
-
510
-			// by default the xml parser can support these 3 charset encodings
511
-			$this->accepted_charset_encodings = array('UTF-8', 'ISO-8859-1', 'US-ASCII');
512
-
513
-			// dispMap is a dispatch array of methods
514
-			// mapped to function names and signatures
515
-			// if a method
516
-			// doesn't appear in the map then an unknown
517
-			// method error is generated
518
-			/* milosch - changed to make passing dispMap optional.
37
+    // XML RPC Server class
38
+    // requires: xmlrpc.inc
39
+
40
+    $GLOBALS['xmlrpcs_capabilities'] = array(
41
+        // xmlrpc spec: always supported
42
+        'xmlrpc' => new xmlrpcval(array(
43
+            'specUrl' => new xmlrpcval('http://www.xmlrpc.com/spec', 'string'),
44
+            'specVersion' => new xmlrpcval(1, 'int')
45
+        ), 'struct'),
46
+        // if we support system.xxx functions, we always support multicall, too...
47
+        // Note that, as of 2006/09/17, the following URL does not respond anymore
48
+        'system.multicall' => new xmlrpcval(array(
49
+            'specUrl' => new xmlrpcval('http://www.xmlrpc.com/discuss/msgReader$1208', 'string'),
50
+            'specVersion' => new xmlrpcval(1, 'int')
51
+        ), 'struct'),
52
+        // introspection: version 2! we support 'mixed', too
53
+        'introspection' => new xmlrpcval(array(
54
+            'specUrl' => new xmlrpcval('http://phpxmlrpc.sourceforge.net/doc-2/ch10.html', 'string'),
55
+            'specVersion' => new xmlrpcval(2, 'int')
56
+        ), 'struct')
57
+    );
58
+
59
+    /* Functions that implement system.XXX methods of xmlrpc servers */
60
+    $_xmlrpcs_getCapabilities_sig=array(array($GLOBALS['xmlrpcStruct']));
61
+    $_xmlrpcs_getCapabilities_doc='This method lists all the capabilites that the XML-RPC server has: the (more or less standard) extensions to the xmlrpc spec that it adheres to';
62
+    $_xmlrpcs_getCapabilities_sdoc=array(array('list of capabilities, described as structs with a version number and url for the spec'));
63
+    function _xmlrpcs_getCapabilities($server, $m=null)
64
+    {
65
+        $outAr = $GLOBALS['xmlrpcs_capabilities'];
66
+        // NIL extension
67
+        if ($GLOBALS['xmlrpc_null_extension']) {
68
+            $outAr['nil'] = new xmlrpcval(array(
69
+                'specUrl' => new xmlrpcval('http://www.ontosys.com/xml-rpc/extensions.php', 'string'),
70
+                'specVersion' => new xmlrpcval(1, 'int')
71
+            ), 'struct');
72
+        }
73
+        return new xmlrpcresp(new xmlrpcval($outAr, 'struct'));
74
+    }
75
+
76
+    // listMethods: signature was either a string, or nothing.
77
+    // The useless string variant has been removed
78
+    $_xmlrpcs_listMethods_sig=array(array($GLOBALS['xmlrpcArray']));
79
+    $_xmlrpcs_listMethods_doc='This method lists all the methods that the XML-RPC server knows how to dispatch';
80
+    $_xmlrpcs_listMethods_sdoc=array(array('list of method names'));
81
+    function _xmlrpcs_listMethods($server, $m=null) // if called in plain php values mode, second param is missing
82
+    {
83
+
84
+        $outAr=array();
85
+        foreach($server->dmap as $key => $val)
86
+        {
87
+            $outAr[]=new xmlrpcval($key, 'string');
88
+        }
89
+        if($server->allow_system_funcs)
90
+        {
91
+            foreach($GLOBALS['_xmlrpcs_dmap'] as $key => $val)
92
+            {
93
+                $outAr[]=new xmlrpcval($key, 'string');
94
+            }
95
+        }
96
+        return new xmlrpcresp(new xmlrpcval($outAr, 'array'));
97
+    }
98
+
99
+    $_xmlrpcs_methodSignature_sig=array(array($GLOBALS['xmlrpcArray'], $GLOBALS['xmlrpcString']));
100
+    $_xmlrpcs_methodSignature_doc='Returns an array of known signatures (an array of arrays) for the method name passed. If no signatures are known, returns a none-array (test for type != array to detect missing signature)';
101
+    $_xmlrpcs_methodSignature_sdoc=array(array('list of known signatures, each sig being an array of xmlrpc type names', 'name of method to be described'));
102
+    function _xmlrpcs_methodSignature($server, $m)
103
+    {
104
+        // let accept as parameter both an xmlrpcval or string
105
+        if (is_object($m))
106
+        {
107
+            $methName=$m->getParam(0);
108
+            $methName=$methName->scalarval();
109
+        }
110
+        else
111
+        {
112
+            $methName=$m;
113
+        }
114
+        if(strpos($methName, "system.") === 0)
115
+        {
116
+            $dmap=$GLOBALS['_xmlrpcs_dmap']; //$sysCall=1;
117
+        }
118
+        else
119
+        {
120
+            $dmap=$server->dmap; //$sysCall=0;
121
+        }
122
+        if(isset($dmap[$methName]))
123
+        {
124
+            if(isset($dmap[$methName]['signature']))
125
+            {
126
+                $sigs=array();
127
+                foreach($dmap[$methName]['signature'] as $inSig)
128
+                {
129
+                    $cursig=array();
130
+                    foreach($inSig as $sig)
131
+                    {
132
+                        $cursig[]=new xmlrpcval($sig, 'string');
133
+                    }
134
+                    $sigs[]=new xmlrpcval($cursig, 'array');
135
+                }
136
+                $r=new xmlrpcresp(new xmlrpcval($sigs, 'array'));
137
+            }
138
+            else
139
+            {
140
+                // NB: according to the official docs, we should be returning a
141
+                // "none-array" here, which means not-an-array
142
+                $r=new xmlrpcresp(new xmlrpcval('undef', 'string'));
143
+            }
144
+        }
145
+        else
146
+        {
147
+            $r=new xmlrpcresp(0,$GLOBALS['xmlrpcerr']['introspect_unknown'], $GLOBALS['xmlrpcstr']['introspect_unknown']);
148
+        }
149
+        return $r;
150
+    }
151
+
152
+    $_xmlrpcs_methodHelp_sig=array(array($GLOBALS['xmlrpcString'], $GLOBALS['xmlrpcString']));
153
+    $_xmlrpcs_methodHelp_doc='Returns help text if defined for the method passed, otherwise returns an empty string';
154
+    $_xmlrpcs_methodHelp_sdoc=array(array('method description', 'name of the method to be described'));
155
+    function _xmlrpcs_methodHelp($server, $m)
156
+    {
157
+        // let accept as parameter both an xmlrpcval or string
158
+        if (is_object($m))
159
+        {
160
+            $methName=$m->getParam(0);
161
+            $methName=$methName->scalarval();
162
+        }
163
+        else
164
+        {
165
+            $methName=$m;
166
+        }
167
+        if(strpos($methName, "system.") === 0)
168
+        {
169
+            $dmap=$GLOBALS['_xmlrpcs_dmap']; //$sysCall=1;
170
+        }
171
+        else
172
+        {
173
+            $dmap=$server->dmap; //$sysCall=0;
174
+        }
175
+        if(isset($dmap[$methName]))
176
+        {
177
+            if(isset($dmap[$methName]['docstring']))
178
+            {
179
+                $r=new xmlrpcresp(new xmlrpcval($dmap[$methName]['docstring']), 'string');
180
+            }
181
+            else
182
+            {
183
+                $r=new xmlrpcresp(new xmlrpcval('', 'string'));
184
+            }
185
+        }
186
+        else
187
+        {
188
+            $r=new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['introspect_unknown'], $GLOBALS['xmlrpcstr']['introspect_unknown']);
189
+        }
190
+        return $r;
191
+    }
192
+
193
+    $_xmlrpcs_multicall_sig = array(array($GLOBALS['xmlrpcArray'], $GLOBALS['xmlrpcArray']));
194
+    $_xmlrpcs_multicall_doc = 'Boxcar multiple RPC calls in one request. See http://www.xmlrpc.com/discuss/msgReader$1208 for details';
195
+    $_xmlrpcs_multicall_sdoc = array(array('list of response structs, where each struct has the usual members', 'list of calls, with each call being represented as a struct, with members "methodname" and "params"'));
196
+    function _xmlrpcs_multicall_error($err)
197
+    {
198
+        if(is_string($err))
199
+        {
200
+            $str = $GLOBALS['xmlrpcstr']["multicall_${err}"];
201
+            $code = $GLOBALS['xmlrpcerr']["multicall_${err}"];
202
+        }
203
+        else
204
+        {
205
+            $code = $err->faultCode();
206
+            $str = $err->faultString();
207
+        }
208
+        $struct = array();
209
+        $struct['faultCode'] = new xmlrpcval($code, 'int');
210
+        $struct['faultString'] = new xmlrpcval($str, 'string');
211
+        return new xmlrpcval($struct, 'struct');
212
+    }
213
+
214
+    function _xmlrpcs_multicall_do_call($server, $call)
215
+    {
216
+        if($call->kindOf() != 'struct')
217
+        {
218
+            return _xmlrpcs_multicall_error('notstruct');
219
+        }
220
+        $methName = @$call->structmem('methodName');
221
+        if(!$methName)
222
+        {
223
+            return _xmlrpcs_multicall_error('nomethod');
224
+        }
225
+        if($methName->kindOf() != 'scalar' || $methName->scalartyp() != 'string')
226
+        {
227
+            return _xmlrpcs_multicall_error('notstring');
228
+        }
229
+        if($methName->scalarval() == 'system.multicall')
230
+        {
231
+            return _xmlrpcs_multicall_error('recursion');
232
+        }
233
+
234
+        $params = @$call->structmem('params');
235
+        if(!$params)
236
+        {
237
+            return _xmlrpcs_multicall_error('noparams');
238
+        }
239
+        if($params->kindOf() != 'array')
240
+        {
241
+            return _xmlrpcs_multicall_error('notarray');
242
+        }
243
+        $numParams = $params->arraysize();
244
+
245
+        $msg = new xmlrpcmsg($methName->scalarval());
246
+        for($i = 0; $i < $numParams; $i++)
247
+        {
248
+            if(!$msg->addParam($params->arraymem($i)))
249
+            {
250
+                $i++;
251
+                return _xmlrpcs_multicall_error(new xmlrpcresp(0,
252
+                    $GLOBALS['xmlrpcerr']['incorrect_params'],
253
+                    $GLOBALS['xmlrpcstr']['incorrect_params'] . ": probable xml error in param " . $i));
254
+            }
255
+        }
256
+
257
+        $result = $server->execute($msg);
258
+
259
+        if($result->faultCode() != 0)
260
+        {
261
+            return _xmlrpcs_multicall_error($result);		// Method returned fault.
262
+        }
263
+
264
+        return new xmlrpcval(array($result->value()), 'array');
265
+    }
266
+
267
+    function _xmlrpcs_multicall_do_call_phpvals($server, $call)
268
+    {
269
+        if(!is_array($call))
270
+        {
271
+            return _xmlrpcs_multicall_error('notstruct');
272
+        }
273
+        if(!array_key_exists('methodName', $call))
274
+        {
275
+            return _xmlrpcs_multicall_error('nomethod');
276
+        }
277
+        if (!is_string($call['methodName']))
278
+        {
279
+            return _xmlrpcs_multicall_error('notstring');
280
+        }
281
+        if($call['methodName'] == 'system.multicall')
282
+        {
283
+            return _xmlrpcs_multicall_error('recursion');
284
+        }
285
+        if(!array_key_exists('params', $call))
286
+        {
287
+            return _xmlrpcs_multicall_error('noparams');
288
+        }
289
+        if(!is_array($call['params']))
290
+        {
291
+            return _xmlrpcs_multicall_error('notarray');
292
+        }
293
+
294
+        // this is a real dirty and simplistic hack, since we might have received a
295
+        // base64 or datetime values, but they will be listed as strings here...
296
+        //$numParams = count($call['params']);
297
+        $pt = array();
298
+        foreach($call['params'] as $val)
299
+            $pt[] = php_2_xmlrpc_type(gettype($val));
300
+
301
+        $result = $server->execute($call['methodName'], $call['params'], $pt);
302
+
303
+        if($result->faultCode() != 0)
304
+        {
305
+            return _xmlrpcs_multicall_error($result);		// Method returned fault.
306
+        }
307
+
308
+        return new xmlrpcval(array($result->value()), 'array');
309
+    }
310
+
311
+    function _xmlrpcs_multicall($server, $m)
312
+    {
313
+        $result = array();
314
+        // let accept a plain list of php parameters, beside a single xmlrpc msg object
315
+        if (is_object($m))
316
+        {
317
+            $calls = $m->getParam(0);
318
+            $numCalls = $calls->arraysize();
319
+            for($i = 0; $i < $numCalls; $i++)
320
+            {
321
+                $call = $calls->arraymem($i);
322
+                $result[$i] = _xmlrpcs_multicall_do_call($server, $call);
323
+            }
324
+        }
325
+        else
326
+        {
327
+            $numCalls=count($m);
328
+            for($i = 0; $i < $numCalls; $i++)
329
+            {
330
+                $result[$i] = _xmlrpcs_multicall_do_call_phpvals($server, $m[$i]);
331
+            }
332
+        }
333
+
334
+        return new xmlrpcresp(new xmlrpcval($result, 'array'));
335
+    }
336
+
337
+    $GLOBALS['_xmlrpcs_dmap']=array(
338
+        'system.listMethods' => array(
339
+            'function' => '_xmlrpcs_listMethods',
340
+            'signature' => $_xmlrpcs_listMethods_sig,
341
+            'docstring' => $_xmlrpcs_listMethods_doc,
342
+            'signature_docs' => $_xmlrpcs_listMethods_sdoc),
343
+        'system.methodHelp' => array(
344
+            'function' => '_xmlrpcs_methodHelp',
345
+            'signature' => $_xmlrpcs_methodHelp_sig,
346
+            'docstring' => $_xmlrpcs_methodHelp_doc,
347
+            'signature_docs' => $_xmlrpcs_methodHelp_sdoc),
348
+        'system.methodSignature' => array(
349
+            'function' => '_xmlrpcs_methodSignature',
350
+            'signature' => $_xmlrpcs_methodSignature_sig,
351
+            'docstring' => $_xmlrpcs_methodSignature_doc,
352
+            'signature_docs' => $_xmlrpcs_methodSignature_sdoc),
353
+        'system.multicall' => array(
354
+            'function' => '_xmlrpcs_multicall',
355
+            'signature' => $_xmlrpcs_multicall_sig,
356
+            'docstring' => $_xmlrpcs_multicall_doc,
357
+            'signature_docs' => $_xmlrpcs_multicall_sdoc),
358
+        'system.getCapabilities' => array(
359
+            'function' => '_xmlrpcs_getCapabilities',
360
+            'signature' => $_xmlrpcs_getCapabilities_sig,
361
+            'docstring' => $_xmlrpcs_getCapabilities_doc,
362
+            'signature_docs' => $_xmlrpcs_getCapabilities_sdoc)
363
+    );
364
+
365
+    $GLOBALS['_xmlrpcs_occurred_errors'] = '';
366
+    $GLOBALS['_xmlrpcs_prev_ehandler'] = '';
367
+
368
+    /**
369
+     * Error handler used to track errors that occur during server-side execution of PHP code.
370
+     * This allows to report back to the client whether an internal error has occurred or not
371
+     * using an xmlrpc response object, instead of letting the client deal with the html junk
372
+     * that a PHP execution error on the server generally entails.
373
+     *
374
+     * NB: in fact a user defined error handler can only handle WARNING, NOTICE and USER_* errors.
375
+     *
376
+     */
377
+    function _xmlrpcs_errorHandler($errcode, $errstring, $filename=null, $lineno=null, $context=null)
378
+    {
379
+        // obey the @ protocol
380
+        if (error_reporting() == 0)
381
+            return;
382
+
383
+        //if($errcode != E_NOTICE && $errcode != E_WARNING && $errcode != E_USER_NOTICE && $errcode != E_USER_WARNING)
384
+        if($errcode != E_STRICT)
385
+        {
386
+            $GLOBALS['_xmlrpcs_occurred_errors'] = $GLOBALS['_xmlrpcs_occurred_errors'] . $errstring . "\n";
387
+        }
388
+        // Try to avoid as much as possible disruption to the previous error handling
389
+        // mechanism in place
390
+        if($GLOBALS['_xmlrpcs_prev_ehandler'] == '')
391
+        {
392
+            // The previous error handler was the default: all we should do is log error
393
+            // to the default error log (if level high enough)
394
+            if(ini_get('log_errors') && (intval(ini_get('error_reporting')) & $errcode))
395
+            {
396
+                error_log($errstring);
397
+            }
398
+        }
399
+        else
400
+        {
401
+            // Pass control on to previous error handler, trying to avoid loops...
402
+            if($GLOBALS['_xmlrpcs_prev_ehandler'] != '_xmlrpcs_errorHandler')
403
+            {
404
+                // NB: this code will NOT work on php < 4.0.2: only 2 params were used for error handlers
405
+                if(is_array($GLOBALS['_xmlrpcs_prev_ehandler']))
406
+                {
407
+                    // the following works both with static class methods and plain object methods as error handler
408
+                    call_user_func_array($GLOBALS['_xmlrpcs_prev_ehandler'], array($errcode, $errstring, $filename, $lineno, $context));
409
+                }
410
+                else
411
+                {
412
+                    $GLOBALS['_xmlrpcs_prev_ehandler']($errcode, $errstring, $filename, $lineno, $context);
413
+                }
414
+            }
415
+        }
416
+    }
417
+
418
+    $GLOBALS['_xmlrpc_debuginfo']='';
419
+
420
+    /**
421
+     * Add a string to the debug info that can be later seralized by the server
422
+     * as part of the response message.
423
+     * Note that for best compatibility, the debug string should be encoded using
424
+     * the $GLOBALS['xmlrpc_internalencoding'] character set.
425
+     * @param string $m
426
+     * @access public
427
+     */
428
+    function xmlrpc_debugmsg($m)
429
+    {
430
+        $GLOBALS['_xmlrpc_debuginfo'] .= $m . "\n";
431
+    }
432
+
433
+    class xmlrpc_server
434
+    {
435
+        /**
436
+         * Array defining php functions exposed as xmlrpc methods by this server
437
+         * @access private
438
+         */
439
+        var $dmap=array();
440
+        /**
441
+         * Defines how functions in dmap will be invoked: either using an xmlrpc msg object
442
+         * or plain php values.
443
+         * valid strings are 'xmlrpcvals', 'phpvals' or 'epivals'
444
+         */
445
+        var $functions_parameters_type='xmlrpcvals';
446
+        /**
447
+         * Option used for fine-tuning the encoding the php values returned from
448
+         * functions registered in the dispatch map when the functions_parameters_types
449
+         * member is set to 'phpvals'
450
+         * @see php_xmlrpc_encode for a list of values
451
+         */
452
+        var $phpvals_encoding_options = array( 'auto_dates' );
453
+        /// controls whether the server is going to echo debugging messages back to the client as comments in response body. valid values: 0,1,2,3
454
+        var $debug = 1;
455
+        /**
456
+         * Controls behaviour of server when invoked user function throws an exception:
457
+         * 0 = catch it and return an 'internal error' xmlrpc response (default)
458
+         * 1 = catch it and return an xmlrpc response with the error corresponding to the exception
459
+         * 2 = allow the exception to float to the upper layers
460
+         */
461
+        var $exception_handling = 0;
462
+        /**
463
+         * When set to true, it will enable HTTP compression of the response, in case
464
+         * the client has declared its support for compression in the request.
465
+         */
466
+        var $compress_response = false;
467
+        /**
468
+         * List of http compression methods accepted by the server for requests.
469
+         * NB: PHP supports deflate, gzip compressions out of the box if compiled w. zlib
470
+         */
471
+        var $accepted_compression = array();
472
+        /// shall we serve calls to system.* methods?
473
+        var $allow_system_funcs = true;
474
+        /// list of charset encodings natively accepted for requests
475
+        var $accepted_charset_encodings = array();
476
+        /**
477
+         * charset encoding to be used for response.
478
+         * NB: if we can, we will convert the generated response from internal_encoding to the intended one.
479
+         * can be: a supported xml encoding (only UTF-8 and ISO-8859-1 at present, unless mbstring is enabled),
480
+         * null (leave unspecified in response, convert output stream to US_ASCII),
481
+         * 'default' (use xmlrpc library default as specified in xmlrpc.inc, convert output stream if needed),
482
+         * or 'auto' (use client-specified charset encoding or same as request if request headers do not specify it (unless request is US-ASCII: then use library default anyway).
483
+         * NB: pretty dangerous if you accept every charset and do not have mbstring enabled)
484
+         */
485
+        var $response_charset_encoding = '';
486
+        /**
487
+         * Storage for internal debug info
488
+         * @access private
489
+         */
490
+        var $debug_info = '';
491
+        /**
492
+         * Extra data passed at runtime to method handling functions. Used only by EPI layer
493
+         */
494
+        var $user_data = null;
495
+
496
+        /**
497
+         * @param array $dispmap the dispatch map with definition of exposed services
498
+         * @param boolean $servicenow set to false to prevent the server from running upon construction
499
+         */
500
+        function __construct($dispMap=null, $serviceNow=true)
501
+        {
502
+            // if ZLIB is enabled, let the server by default accept compressed requests,
503
+            // and compress responses sent to clients that support them
504
+            if(function_exists('gzinflate'))
505
+            {
506
+                $this->accepted_compression = array('gzip', 'deflate');
507
+                $this->compress_response = true;
508
+            }
509
+
510
+            // by default the xml parser can support these 3 charset encodings
511
+            $this->accepted_charset_encodings = array('UTF-8', 'ISO-8859-1', 'US-ASCII');
512
+
513
+            // dispMap is a dispatch array of methods
514
+            // mapped to function names and signatures
515
+            // if a method
516
+            // doesn't appear in the map then an unknown
517
+            // method error is generated
518
+            /* milosch - changed to make passing dispMap optional.
519 519
 			 * instead, you can use the class add_to_map() function
520 520
 			 * to add functions manually (borrowed from SOAPX4)
521 521
 			 */
522
-			if($dispMap)
523
-			{
524
-				$this->dmap = $dispMap;
525
-				if($serviceNow)
526
-				{
527
-					$this->service();
528
-				}
529
-			}
530
-		}
531
-
532
-		/**
533
-		* @deprecated
534
-		*/
535
-		function xmlrpc_client($dispMap=null, $serviceNow=true)
536
-		{
537
-			self::__construct($dispMap, $serviceNow);
538
-		}
539
-
540
-		/**
541
-		* Set debug level of server.
542
-		* @param integer $in debug lvl: determines info added to xmlrpc responses (as xml comments)
543
-		* 0 = no debug info,
544
-		* 1 = msgs set from user with debugmsg(),
545
-		* 2 = add complete xmlrpc request (headers and body),
546
-		* 3 = add also all processing warnings happened during method processing
547
-		* (NB: this involves setting a custom error handler, and might interfere
548
-		* with the standard processing of the php function exposed as method. In
549
-		* particular, triggering an USER_ERROR level error will not halt script
550
-		* execution anymore, but just end up logged in the xmlrpc response)
551
-		* Note that info added at level 2 and 3 will be base64 encoded
552
-		* @access public
553
-		*/
554
-		function setDebug($in)
555
-		{
556
-			$this->debug=$in;
557
-		}
558
-
559
-		/**
560
-		* Return a string with the serialized representation of all debug info
561
-		* @param string $charset_encoding the target charset encoding for the serialization
562
-		* @return string an XML comment (or two)
563
-		*/
564
-		function serializeDebug($charset_encoding='')
565
-		{
566
-			// Tough encoding problem: which internal charset should we assume for debug info?
567
-			// It might contain a copy of raw data received from client, ie with unknown encoding,
568
-			// intermixed with php generated data and user generated data...
569
-			// so we split it: system debug is base 64 encoded,
570
-			// user debug info should be encoded by the end user using the INTERNAL_ENCODING
571
-			$out = '';
572
-			if ($this->debug_info != '')
573
-			{
574
-				$out .= "<!-- SERVER DEBUG INFO (BASE64 ENCODED):\n".base64_encode($this->debug_info)."\n-->\n";
575
-			}
576
-			if($GLOBALS['_xmlrpc_debuginfo']!='')
577
-			{
578
-
579
-				$out .= "<!-- DEBUG INFO:\n" . xmlrpc_encode_entitites(str_replace('--', '_-', $GLOBALS['_xmlrpc_debuginfo']), $GLOBALS['xmlrpc_internalencoding'], $charset_encoding) . "\n-->\n";
580
-				// NB: a better solution MIGHT be to use CDATA, but we need to insert it
581
-				// into return payload AFTER the beginning tag
582
-				//$out .= "<![CDATA[ DEBUG INFO:\n\n" . str_replace(']]>', ']_]_>', $GLOBALS['_xmlrpc_debuginfo']) . "\n]]>\n";
583
-			}
584
-			return $out;
585
-		}
586
-
587
-		/**
588
-		* Execute the xmlrpc request, printing the response
589
-		* @param string $data the request body. If null, the http POST request will be examined
590
-		* @return xmlrpcresp the response object (usually not used by caller...)
591
-		* @access public
592
-		*/
593
-		function service($data=null, $return_payload=false)
594
-		{
595
-			if ($data === null)
596
-			{
597
-				// workaround for a known bug in php ver. 5.2.2 that broke $HTTP_RAW_POST_DATA
598
-				$data = file_get_contents('php://input');
599
-			}
600
-			$raw_data = $data;
601
-
602
-			// reset internal debug info
603
-			$this->debug_info = '';
604
-
605
-			// Echo back what we received, before parsing it
606
-			if($this->debug > 1)
607
-			{
608
-				$this->debugmsg("+++GOT+++\n" . $data . "\n+++END+++");
609
-			}
610
-
611
-			$r = $this->parseRequestHeaders($data, $req_charset, $resp_charset, $resp_encoding);
612
-			if (!$r)
613
-			{
614
-				$r=$this->parseRequest($data, $req_charset);
615
-			}
616
-
617
-			// save full body of request into response, for more debugging usages
618
-			$r->raw_data = $raw_data;
619
-
620
-			if($this->debug > 2 && $GLOBALS['_xmlrpcs_occurred_errors'])
621
-			{
622
-				$this->debugmsg("+++PROCESSING ERRORS AND WARNINGS+++\n" .
623
-					$GLOBALS['_xmlrpcs_occurred_errors'] . "+++END+++");
624
-			}
625
-
626
-			$payload=$this->xml_header($resp_charset);
627
-			if($this->debug > 0)
628
-			{
629
-				$payload = $payload . $this->serializeDebug($resp_charset);
630
-			}
631
-
632
-			// G. Giunta 2006-01-27: do not create response serialization if it has
633
-			// already happened. Helps building json magic
634
-			if (empty($r->payload))
635
-			{
636
-				$r->serialize($resp_charset);
637
-			}
638
-			$payload = $payload . $r->payload;
639
-
640
-			if ($return_payload)
641
-			{
642
-				return $payload;
643
-			}
644
-
645
-			// if we get a warning/error that has output some text before here, then we cannot
646
-			// add a new header. We cannot say we are sending xml, either...
647
-			if(!headers_sent())
648
-			{
649
-				header('Content-Type: '.$r->content_type);
650
-				// we do not know if client actually told us an accepted charset, but if he did
651
-				// we have to tell him what we did
652
-				header("Vary: Accept-Charset");
653
-
654
-				// http compression of output: only
655
-				// if we can do it, and we want to do it, and client asked us to,
656
-				// and php ini settings do not force it already
657
-				$php_no_self_compress = !ini_get('zlib.output_compression') && (ini_get('output_handler') != 'ob_gzhandler');
658
-				if($this->compress_response && function_exists('gzencode') && $resp_encoding != ''
659
-					&& $php_no_self_compress)
660
-				{
661
-					if(strpos($resp_encoding, 'gzip') !== false)
662
-					{
663
-						$payload = gzencode($payload);
664
-						header("Content-Encoding: gzip");
665
-						header("Vary: Accept-Encoding");
666
-					}
667
-					elseif (strpos($resp_encoding, 'deflate') !== false)
668
-					{
669
-						$payload = gzcompress($payload);
670
-						header("Content-Encoding: deflate");
671
-						header("Vary: Accept-Encoding");
672
-					}
673
-				}
674
-
675
-				// do not ouput content-length header if php is compressing output for us:
676
-				// it will mess up measurements
677
-				if($php_no_self_compress)
678
-				{
679
-					header('Content-Length: ' . (int)strlen($payload));
680
-				}
681
-			}
682
-			else
683
-			{
684
-				error_log('XML-RPC: '.__METHOD__.': http headers already sent before response is fully generated. Check for php warning or error messages');
685
-			}
686
-
687
-			print $payload;
688
-
689
-			// return request, in case subclasses want it
690
-			return $r;
691
-		}
692
-
693
-		/**
694
-		* Add a method to the dispatch map
695
-		* @param string $methodname the name with which the method will be made available
696
-		* @param string $function the php function that will get invoked
697
-		* @param array $sig the array of valid method signatures
698
-		* @param string $doc method documentation
699
-		* @param array $sigdoc the array of valid method signatures docs (one string per param, one for return type)
700
-		* @access public
701
-		*/
702
-		function add_to_map($methodname,$function,$sig=null,$doc=false,$sigdoc=false)
703
-		{
704
-			$this->dmap[$methodname] = array(
705
-				'function'	=> $function,
706
-				'docstring' => $doc
707
-			);
708
-			if ($sig)
709
-			{
710
-				$this->dmap[$methodname]['signature'] = $sig;
711
-			}
712
-			if ($sigdoc)
713
-			{
714
-				$this->dmap[$methodname]['signature_docs'] = $sigdoc;
715
-			}
716
-		}
717
-
718
-		/**
719
-		* Verify type and number of parameters received against a list of known signatures
720
-		* @param array $in array of either xmlrpcval objects or xmlrpc type definitions
721
-		* @param array $sig array of known signatures to match against
722
-		* @return array
723
-		* @access private
724
-		*/
725
-		function verifySignature($in, $sig)
726
-		{
727
-			// check each possible signature in turn
728
-			if (is_object($in))
729
-			{
730
-				$numParams = $in->getNumParams();
731
-			}
732
-			else
733
-			{
734
-				$numParams = count($in);
735
-			}
736
-			foreach($sig as $cursig)
737
-			{
738
-				if(count($cursig)==$numParams+1)
739
-				{
740
-					$itsOK=1;
741
-					for($n=0; $n<$numParams; $n++)
742
-					{
743
-						if (is_object($in))
744
-						{
745
-							$p=$in->getParam($n);
746
-							if($p->kindOf() == 'scalar')
747
-							{
748
-								$pt=$p->scalartyp();
749
-							}
750
-							else
751
-							{
752
-								$pt=$p->kindOf();
753
-							}
754
-						}
755
-						else
756
-						{
757
-							$pt= $in[$n] == 'i4' ? 'int' : strtolower($in[$n]); // dispatch maps never use i4...
758
-						}
759
-
760
-						// param index is $n+1, as first member of sig is return type
761
-						if($pt != $cursig[$n+1] && $cursig[$n+1] != $GLOBALS['xmlrpcValue'])
762
-						{
763
-							$itsOK=0;
764
-							$pno=$n+1;
765
-							$wanted=$cursig[$n+1];
766
-							$got=$pt;
767
-							break;
768
-						}
769
-					}
770
-					if($itsOK)
771
-					{
772
-						return array(1,'');
773
-					}
774
-				}
775
-			}
776
-			if(isset($wanted))
777
-			{
778
-				return array(0, "Wanted ${wanted}, got ${got} at param ${pno}");
779
-			}
780
-			else
781
-			{
782
-				return array(0, "No method signature matches number of parameters");
783
-			}
784
-		}
785
-
786
-		/**
787
-		* Parse http headers received along with xmlrpc request. If needed, inflate request
788
-		* @return mixed null on success or an xmlrpcresp
789
-		* @access private
790
-		*/
791
-		function parseRequestHeaders(&$data, &$req_encoding, &$resp_encoding, &$resp_compression)
792
-		{
793
-			// check if $_SERVER is populated: it might have been disabled via ini file
794
-			// (this is true even when in CLI mode)
795
-			if (count($_SERVER) == 0)
796
-			{
797
-				error_log('XML-RPC: '.__METHOD__.': cannot parse request headers as $_SERVER is not populated');
798
-			}
799
-
800
-			if($this->debug > 1)
801
-			{
802
-				if(function_exists('getallheaders'))
803
-				{
804
-					$this->debugmsg(''); // empty line
805
-					foreach(getallheaders() as $name => $val)
806
-					{
807
-						$this->debugmsg("HEADER: $name: $val");
808
-					}
809
-				}
810
-
811
-			}
812
-
813
-			if(isset($_SERVER['HTTP_CONTENT_ENCODING']))
814
-			{
815
-				$content_encoding = str_replace('x-', '', $_SERVER['HTTP_CONTENT_ENCODING']);
816
-			}
817
-			else
818
-			{
819
-				$content_encoding = '';
820
-			}
821
-
822
-			// check if request body has been compressed and decompress it
823
-			if($content_encoding != '' && strlen($data))
824
-			{
825
-				if($content_encoding == 'deflate' || $content_encoding == 'gzip')
826
-				{
827
-					// if decoding works, use it. else assume data wasn't gzencoded
828
-					if(function_exists('gzinflate') && in_array($content_encoding, $this->accepted_compression))
829
-					{
830
-						if($content_encoding == 'deflate' && $degzdata = @gzuncompress($data))
831
-						{
832
-							$data = $degzdata;
833
-							if($this->debug > 1)
834
-							{
835
-								$this->debugmsg("\n+++INFLATED REQUEST+++[".strlen($data)." chars]+++\n" . $data . "\n+++END+++");
836
-							}
837
-						}
838
-						elseif($content_encoding == 'gzip' && $degzdata = @gzinflate(substr($data, 10)))
839
-						{
840
-							$data = $degzdata;
841
-							if($this->debug > 1)
842
-								$this->debugmsg("+++INFLATED REQUEST+++[".strlen($data)." chars]+++\n" . $data . "\n+++END+++");
843
-						}
844
-						else
845
-						{
846
-							$r = new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['server_decompress_fail'], $GLOBALS['xmlrpcstr']['server_decompress_fail']);
847
-							return $r;
848
-						}
849
-					}
850
-					else
851
-					{
852
-						//error_log('The server sent deflated data. Your php install must have the Zlib extension compiled in to support this.');
853
-						$r = new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['server_cannot_decompress'], $GLOBALS['xmlrpcstr']['server_cannot_decompress']);
854
-						return $r;
855
-					}
856
-				}
857
-			}
858
-
859
-			// check if client specified accepted charsets, and if we know how to fulfill
860
-			// the request
861
-			if ($this->response_charset_encoding == 'auto')
862
-			{
863
-				$resp_encoding = '';
864
-				if (isset($_SERVER['HTTP_ACCEPT_CHARSET']))
865
-				{
866
-					// here we should check if we can match the client-requested encoding
867
-					// with the encodings we know we can generate.
868
-					/// @todo we should parse q=0.x preferences instead of getting first charset specified...
869
-					$client_accepted_charsets = explode(',', strtoupper($_SERVER['HTTP_ACCEPT_CHARSET']));
870
-					// Give preference to internal encoding
871
-					$known_charsets = array($GLOBALS['xmlrpc_internalencoding'], 'UTF-8', 'ISO-8859-1', 'US-ASCII');
872
-					foreach ($known_charsets as $charset)
873
-					{
874
-						foreach ($client_accepted_charsets as $accepted)
875
-							if (strpos($accepted, $charset) === 0)
876
-							{
877
-								$resp_encoding = $charset;
878
-								break;
879
-							}
880
-						if ($resp_encoding)
881
-							break;
882
-					}
883
-				}
884
-			}
885
-			else
886
-			{
887
-				$resp_encoding = $this->response_charset_encoding;
888
-			}
889
-
890
-			if (isset($_SERVER['HTTP_ACCEPT_ENCODING']))
891
-			{
892
-				$resp_compression = $_SERVER['HTTP_ACCEPT_ENCODING'];
893
-			}
894
-			else
895
-			{
896
-				$resp_compression = '';
897
-			}
898
-
899
-			// 'guestimate' request encoding
900
-			/// @todo check if mbstring is enabled and automagic input conversion is on: it might mingle with this check???
901
-			$req_encoding = guess_encoding(isset($_SERVER['CONTENT_TYPE']) ? $_SERVER['CONTENT_TYPE'] : '',
902
-				$data);
903
-
904
-			return null;
905
-		}
906
-
907
-		/**
908
-		* Parse an xml chunk containing an xmlrpc request and execute the corresponding
909
-		* php function registered with the server
910
-		* @param string $data the xml request
911
-		* @param string $req_encoding (optional) the charset encoding of the xml request
912
-		* @return xmlrpcresp
913
-		* @access private
914
-		*/
915
-		function parseRequest($data, $req_encoding='')
916
-		{
917
-			// 2005/05/07 commented and moved into caller function code
918
-			//if($data=='')
919
-			//{
920
-			//	$data=$GLOBALS['HTTP_RAW_POST_DATA'];
921
-			//}
922
-
923
-			// G. Giunta 2005/02/13: we do NOT expect to receive html entities
924
-			// so we do not try to convert them into xml character entities
925
-			//$data = xmlrpc_html_entity_xlate($data);
926
-
927
-			$GLOBALS['_xh']=array();
928
-			$GLOBALS['_xh']['ac']='';
929
-			$GLOBALS['_xh']['stack']=array();
930
-			$GLOBALS['_xh']['valuestack'] = array();
931
-			$GLOBALS['_xh']['params']=array();
932
-			$GLOBALS['_xh']['pt']=array();
933
-			$GLOBALS['_xh']['isf']=0;
934
-			$GLOBALS['_xh']['isf_reason']='';
935
-			$GLOBALS['_xh']['method']=false; // so we can check later if we got a methodname or not
936
-			$GLOBALS['_xh']['rt']='';
937
-
938
-			// decompose incoming XML into request structure
939
-
940
-			if ($req_encoding != '')
941
-			{
942
-				// Since parsing will fail if charset is not specified in the xml prologue,
943
-				// the encoding is not UTF8 and there are non-ascii chars in the text, we try to work round that...
944
-				// The following code might be better for mb_string enabled installs, but
945
-				// makes the lib about 200% slower...
946
-				//if (!is_valid_charset($req_encoding, array('UTF-8')))
947
-				if (!in_array($req_encoding, array('UTF-8', 'US-ASCII')) && !has_encoding($data)) {
948
-					if ($req_encoding == 'ISO-8859-1') {
949
-						$data = utf8_encode($data);
950
-					} else {
951
-						if (extension_loaded('mbstring')) {
952
-							$data = mb_convert_encoding($data, 'UTF-8', $req_encoding);
953
-						} else {
954
-							error_log('XML-RPC: ' . __METHOD__ . ': invalid charset encoding of received request: ' . $req_encoding);
955
-						}
956
-					}
957
-				}
958
-			}
959
-
960
-			$parser = xml_parser_create();
961
-			xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true);
962
-			// G. Giunta 2005/02/13: PHP internally uses ISO-8859-1, so we have to tell
963
-			// the xml parser to give us back data in the expected charset
964
-			// What if internal encoding is not in one of the 3 allowed?
965
-			// we use the broadest one, ie. utf8
966
-			// This allows to send data which is native in various charset,
967
-			// by extending xmlrpc_encode_entitites() and setting xmlrpc_internalencoding
968
-			if (!in_array($GLOBALS['xmlrpc_internalencoding'], array('UTF-8', 'ISO-8859-1', 'US-ASCII')))
969
-			{
970
-				xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, 'UTF-8');
971
-			}
972
-			else
973
-			{
974
-				xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, $GLOBALS['xmlrpc_internalencoding']);
975
-			}
976
-
977
-			if ($this->functions_parameters_type != 'xmlrpcvals')
978
-				xml_set_element_handler($parser, 'xmlrpc_se', 'xmlrpc_ee_fast');
979
-			else
980
-				xml_set_element_handler($parser, 'xmlrpc_se', 'xmlrpc_ee');
981
-			xml_set_character_data_handler($parser, 'xmlrpc_cd');
982
-			xml_set_default_handler($parser, 'xmlrpc_dh');
983
-			if(!xml_parse($parser, $data, 1))
984
-			{
985
-				// return XML error as a faultCode
986
-				$r=new xmlrpcresp(0,
987
-				$GLOBALS['xmlrpcerrxml']+xml_get_error_code($parser),
988
-				sprintf('XML error: %s at line %d, column %d',
989
-					xml_error_string(xml_get_error_code($parser)),
990
-					xml_get_current_line_number($parser), xml_get_current_column_number($parser)));
991
-				xml_parser_free($parser);
992
-			}
993
-			elseif ($GLOBALS['_xh']['isf'])
994
-			{
995
-				xml_parser_free($parser);
996
-				$r=new xmlrpcresp(0,
997
-					$GLOBALS['xmlrpcerr']['invalid_request'],
998
-					$GLOBALS['xmlrpcstr']['invalid_request'] . ' ' . $GLOBALS['_xh']['isf_reason']);
999
-			}
1000
-			else
1001
-			{
1002
-				xml_parser_free($parser);
1003
-				// small layering violation in favor of speed and memory usage:
1004
-				// we should allow the 'execute' method handle this, but in the
1005
-				// most common scenario (xmlrpcvals type server with some methods
1006
-				// registered as phpvals) that would mean a useless encode+decode pass
1007
-				if ($this->functions_parameters_type != 'xmlrpcvals' || (isset($this->dmap[$GLOBALS['_xh']['method']]['parameters_type']) && ($this->dmap[$GLOBALS['_xh']['method']]['parameters_type'] == 'phpvals')))
1008
-				{
1009
-					if($this->debug > 1)
1010
-					{
1011
-						$this->debugmsg("\n+++PARSED+++\n".var_export($GLOBALS['_xh']['params'], true)."\n+++END+++");
1012
-					}
1013
-					$r = $this->execute($GLOBALS['_xh']['method'], $GLOBALS['_xh']['params'], $GLOBALS['_xh']['pt']);
1014
-				}
1015
-				else
1016
-				{
1017
-					// build an xmlrpcmsg object with data parsed from xml
1018
-					$m=new xmlrpcmsg($GLOBALS['_xh']['method']);
1019
-					// now add parameters in
1020
-					for($i=0; $i<count($GLOBALS['_xh']['params']); $i++)
1021
-					{
1022
-						$m->addParam($GLOBALS['_xh']['params'][$i]);
1023
-					}
1024
-
1025
-					if($this->debug > 1)
1026
-					{
1027
-						$this->debugmsg("\n+++PARSED+++\n".var_export($m, true)."\n+++END+++");
1028
-					}
1029
-					$r = $this->execute($m);
1030
-				}
1031
-			}
1032
-			return $r;
1033
-		}
1034
-
1035
-		/**
1036
-		* Execute a method invoked by the client, checking parameters used
1037
-		* @param mixed $m either an xmlrpcmsg obj or a method name
1038
-		* @param array $params array with method parameters as php types (if m is method name only)
1039
-		* @param array $paramtypes array with xmlrpc types of method parameters (if m is method name only)
1040
-		* @return xmlrpcresp
1041
-		* @access private
1042
-		*/
1043
-		function execute($m, $params=null, $paramtypes=null)
1044
-		{
1045
-			if (is_object($m))
1046
-			{
1047
-				$methName = $m->method();
1048
-			}
1049
-			else
1050
-			{
1051
-				$methName = $m;
1052
-			}
1053
-			$sysCall = $this->allow_system_funcs && (strpos($methName, "system.") === 0);
1054
-			$dmap = $sysCall ? $GLOBALS['_xmlrpcs_dmap'] : $this->dmap;
1055
-
1056
-			if(!isset($dmap[$methName]['function']))
1057
-			{
1058
-				// No such method
1059
-				return new xmlrpcresp(0,
1060
-					$GLOBALS['xmlrpcerr']['unknown_method'],
1061
-					$GLOBALS['xmlrpcstr']['unknown_method']);
1062
-			}
1063
-
1064
-			// Check signature
1065
-			if(isset($dmap[$methName]['signature']))
1066
-			{
1067
-				$sig = $dmap[$methName]['signature'];
1068
-				if (is_object($m))
1069
-				{
1070
-					list($ok, $errstr) = $this->verifySignature($m, $sig);
1071
-				}
1072
-				else
1073
-				{
1074
-					list($ok, $errstr) = $this->verifySignature($paramtypes, $sig);
1075
-				}
1076
-				if(!$ok)
1077
-				{
1078
-					// Didn't match.
1079
-					return new xmlrpcresp(
1080
-						0,
1081
-						$GLOBALS['xmlrpcerr']['incorrect_params'],
1082
-						$GLOBALS['xmlrpcstr']['incorrect_params'] . ": ${errstr}"
1083
-					);
1084
-				}
1085
-			}
1086
-
1087
-			$func = $dmap[$methName]['function'];
1088
-			// let the 'class::function' syntax be accepted in dispatch maps
1089
-			if(is_string($func) && strpos($func, '::'))
1090
-			{
1091
-				$func = explode('::', $func);
1092
-			}
1093
-			// verify that function to be invoked is in fact callable
1094
-			if(!is_callable($func))
1095
-			{
1096
-				error_log("XML-RPC: ".__METHOD__.": function $func registered as method handler is not callable");
1097
-				return new xmlrpcresp(
1098
-					0,
1099
-					$GLOBALS['xmlrpcerr']['server_error'],
1100
-					$GLOBALS['xmlrpcstr']['server_error'] . ": no function matches method"
1101
-				);
1102
-			}
1103
-
1104
-			// If debug level is 3, we should catch all errors generated during
1105
-			// processing of user function, and log them as part of response
1106
-			if($this->debug > 2)
1107
-			{
1108
-				$GLOBALS['_xmlrpcs_prev_ehandler'] = set_error_handler('_xmlrpcs_errorHandler');
1109
-			}
1110
-			try
1111
-			{
1112
-				// Allow mixed-convention servers
1113
-				if (is_object($m))
1114
-				{
1115
-					if ($sysCall)
1116
-					{
1117
-						$r = call_user_func($func, $this, $m);
1118
-					}
1119
-					else
1120
-					{
1121
-						$r = call_user_func($func, $m);
1122
-					}
1123
-					if (!is_a($r, 'xmlrpcresp'))
1124
-					{
1125
-						error_log("XML-RPC: ".__METHOD__.": function $func registered as method handler does not return an xmlrpcresp object");
1126
-						if (is_a($r, 'xmlrpcval'))
1127
-						{
1128
-							$r = new xmlrpcresp($r);
1129
-						}
1130
-						else
1131
-						{
1132
-							$r = new xmlrpcresp(
1133
-								0,
1134
-								$GLOBALS['xmlrpcerr']['server_error'],
1135
-								$GLOBALS['xmlrpcstr']['server_error'] . ": function does not return xmlrpcresp object"
1136
-							);
1137
-						}
1138
-					}
1139
-				}
1140
-				else
1141
-				{
1142
-					// call a 'plain php' function
1143
-					if($sysCall)
1144
-					{
1145
-						array_unshift($params, $this);
1146
-						$r = call_user_func_array($func, $params);
1147
-					}
1148
-					else
1149
-					{
1150
-						// 3rd API convention for method-handling functions: EPI-style
1151
-						if ($this->functions_parameters_type == 'epivals')
1152
-						{
1153
-							$r = call_user_func_array($func, array($methName, $params, $this->user_data));
1154
-							// mimic EPI behaviour: if we get an array that looks like an error, make it
1155
-							// an eror response
1156
-							if (is_array($r) && array_key_exists('faultCode', $r) && array_key_exists('faultString', $r))
1157
-							{
1158
-								$r = new xmlrpcresp(0, (integer)$r['faultCode'], (string)$r['faultString']);
1159
-							}
1160
-							else
1161
-							{
1162
-								// functions using EPI api should NOT return resp objects,
1163
-								// so make sure we encode the return type correctly
1164
-								$r = new xmlrpcresp(php_xmlrpc_encode($r, array('extension_api')));
1165
-							}
1166
-						}
1167
-						else
1168
-						{
1169
-							$r = call_user_func_array($func, $params);
1170
-						}
1171
-					}
1172
-					// the return type can be either an xmlrpcresp object or a plain php value...
1173
-					if (!is_a($r, 'xmlrpcresp'))
1174
-					{
1175
-						// what should we assume here about automatic encoding of datetimes
1176
-						// and php classes instances???
1177
-						$r = new xmlrpcresp(php_xmlrpc_encode($r, $this->phpvals_encoding_options));
1178
-					}
1179
-				}
1180
-			}
1181
-			catch(Exception $e)
1182
-			{
1183
-				// (barring errors in the lib) an uncatched exception happened
1184
-				// in the called function, we wrap it in a proper error-response
1185
-				switch($this->exception_handling)
1186
-				{
1187
-					case 2:
1188
-						throw $e;
1189
-						break;
1190
-					case 1:
1191
-						$r = new xmlrpcresp(0, $e->getCode(), $e->getMessage());
1192
-						break;
1193
-					default:
1194
-						$r = new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['server_error'], $GLOBALS['xmlrpcstr']['server_error']);
1195
-				}
1196
-			}
1197
-			if($this->debug > 2)
1198
-			{
1199
-				// note: restore the error handler we found before calling the
1200
-				// user func, even if it has been changed inside the func itself
1201
-				if($GLOBALS['_xmlrpcs_prev_ehandler'])
1202
-				{
1203
-					set_error_handler($GLOBALS['_xmlrpcs_prev_ehandler']);
1204
-				}
1205
-				else
1206
-				{
1207
-					restore_error_handler();
1208
-				}
1209
-			}
1210
-			return $r;
1211
-		}
1212
-
1213
-		/**
1214
-		* add a string to the 'internal debug message' (separate from 'user debug message')
1215
-		* @param string $string
1216
-		* @access private
1217
-		*/
1218
-		function debugmsg($string)
1219
-		{
1220
-			$this->debug_info .= $string."\n";
1221
-		}
1222
-
1223
-		/**
1224
-		* @access private
1225
-		*/
1226
-		function xml_header($charset_encoding='')
1227
-		{
1228
-			if ($charset_encoding != '')
1229
-			{
1230
-				return "<?xml version=\"1.0\" encoding=\"$charset_encoding\"?" . ">\n";
1231
-			}
1232
-			else
1233
-			{
1234
-				return "<?xml version=\"1.0\"?" . ">\n";
1235
-			}
1236
-		}
1237
-
1238
-		/**
1239
-		* A debugging routine: just echoes back the input packet as a string value
1240
-		* @deprecated
1241
-		*/
1242
-		function echoInput()
1243
-		{
1244
-			$r=new xmlrpcresp(new xmlrpcval( "'Aha said I: '" . $GLOBALS['HTTP_RAW_POST_DATA'], 'string'));
1245
-			print $r->serialize();
1246
-		}
1247
-	}
522
+            if($dispMap)
523
+            {
524
+                $this->dmap = $dispMap;
525
+                if($serviceNow)
526
+                {
527
+                    $this->service();
528
+                }
529
+            }
530
+        }
531
+
532
+        /**
533
+         * @deprecated
534
+         */
535
+        function xmlrpc_client($dispMap=null, $serviceNow=true)
536
+        {
537
+            self::__construct($dispMap, $serviceNow);
538
+        }
539
+
540
+        /**
541
+         * Set debug level of server.
542
+         * @param integer $in debug lvl: determines info added to xmlrpc responses (as xml comments)
543
+         * 0 = no debug info,
544
+         * 1 = msgs set from user with debugmsg(),
545
+         * 2 = add complete xmlrpc request (headers and body),
546
+         * 3 = add also all processing warnings happened during method processing
547
+         * (NB: this involves setting a custom error handler, and might interfere
548
+         * with the standard processing of the php function exposed as method. In
549
+         * particular, triggering an USER_ERROR level error will not halt script
550
+         * execution anymore, but just end up logged in the xmlrpc response)
551
+         * Note that info added at level 2 and 3 will be base64 encoded
552
+         * @access public
553
+         */
554
+        function setDebug($in)
555
+        {
556
+            $this->debug=$in;
557
+        }
558
+
559
+        /**
560
+         * Return a string with the serialized representation of all debug info
561
+         * @param string $charset_encoding the target charset encoding for the serialization
562
+         * @return string an XML comment (or two)
563
+         */
564
+        function serializeDebug($charset_encoding='')
565
+        {
566
+            // Tough encoding problem: which internal charset should we assume for debug info?
567
+            // It might contain a copy of raw data received from client, ie with unknown encoding,
568
+            // intermixed with php generated data and user generated data...
569
+            // so we split it: system debug is base 64 encoded,
570
+            // user debug info should be encoded by the end user using the INTERNAL_ENCODING
571
+            $out = '';
572
+            if ($this->debug_info != '')
573
+            {
574
+                $out .= "<!-- SERVER DEBUG INFO (BASE64 ENCODED):\n".base64_encode($this->debug_info)."\n-->\n";
575
+            }
576
+            if($GLOBALS['_xmlrpc_debuginfo']!='')
577
+            {
578
+
579
+                $out .= "<!-- DEBUG INFO:\n" . xmlrpc_encode_entitites(str_replace('--', '_-', $GLOBALS['_xmlrpc_debuginfo']), $GLOBALS['xmlrpc_internalencoding'], $charset_encoding) . "\n-->\n";
580
+                // NB: a better solution MIGHT be to use CDATA, but we need to insert it
581
+                // into return payload AFTER the beginning tag
582
+                //$out .= "<![CDATA[ DEBUG INFO:\n\n" . str_replace(']]>', ']_]_>', $GLOBALS['_xmlrpc_debuginfo']) . "\n]]>\n";
583
+            }
584
+            return $out;
585
+        }
586
+
587
+        /**
588
+         * Execute the xmlrpc request, printing the response
589
+         * @param string $data the request body. If null, the http POST request will be examined
590
+         * @return xmlrpcresp the response object (usually not used by caller...)
591
+         * @access public
592
+         */
593
+        function service($data=null, $return_payload=false)
594
+        {
595
+            if ($data === null)
596
+            {
597
+                // workaround for a known bug in php ver. 5.2.2 that broke $HTTP_RAW_POST_DATA
598
+                $data = file_get_contents('php://input');
599
+            }
600
+            $raw_data = $data;
601
+
602
+            // reset internal debug info
603
+            $this->debug_info = '';
604
+
605
+            // Echo back what we received, before parsing it
606
+            if($this->debug > 1)
607
+            {
608
+                $this->debugmsg("+++GOT+++\n" . $data . "\n+++END+++");
609
+            }
610
+
611
+            $r = $this->parseRequestHeaders($data, $req_charset, $resp_charset, $resp_encoding);
612
+            if (!$r)
613
+            {
614
+                $r=$this->parseRequest($data, $req_charset);
615
+            }
616
+
617
+            // save full body of request into response, for more debugging usages
618
+            $r->raw_data = $raw_data;
619
+
620
+            if($this->debug > 2 && $GLOBALS['_xmlrpcs_occurred_errors'])
621
+            {
622
+                $this->debugmsg("+++PROCESSING ERRORS AND WARNINGS+++\n" .
623
+                    $GLOBALS['_xmlrpcs_occurred_errors'] . "+++END+++");
624
+            }
625
+
626
+            $payload=$this->xml_header($resp_charset);
627
+            if($this->debug > 0)
628
+            {
629
+                $payload = $payload . $this->serializeDebug($resp_charset);
630
+            }
631
+
632
+            // G. Giunta 2006-01-27: do not create response serialization if it has
633
+            // already happened. Helps building json magic
634
+            if (empty($r->payload))
635
+            {
636
+                $r->serialize($resp_charset);
637
+            }
638
+            $payload = $payload . $r->payload;
639
+
640
+            if ($return_payload)
641
+            {
642
+                return $payload;
643
+            }
644
+
645
+            // if we get a warning/error that has output some text before here, then we cannot
646
+            // add a new header. We cannot say we are sending xml, either...
647
+            if(!headers_sent())
648
+            {
649
+                header('Content-Type: '.$r->content_type);
650
+                // we do not know if client actually told us an accepted charset, but if he did
651
+                // we have to tell him what we did
652
+                header("Vary: Accept-Charset");
653
+
654
+                // http compression of output: only
655
+                // if we can do it, and we want to do it, and client asked us to,
656
+                // and php ini settings do not force it already
657
+                $php_no_self_compress = !ini_get('zlib.output_compression') && (ini_get('output_handler') != 'ob_gzhandler');
658
+                if($this->compress_response && function_exists('gzencode') && $resp_encoding != ''
659
+                    && $php_no_self_compress)
660
+                {
661
+                    if(strpos($resp_encoding, 'gzip') !== false)
662
+                    {
663
+                        $payload = gzencode($payload);
664
+                        header("Content-Encoding: gzip");
665
+                        header("Vary: Accept-Encoding");
666
+                    }
667
+                    elseif (strpos($resp_encoding, 'deflate') !== false)
668
+                    {
669
+                        $payload = gzcompress($payload);
670
+                        header("Content-Encoding: deflate");
671
+                        header("Vary: Accept-Encoding");
672
+                    }
673
+                }
674
+
675
+                // do not ouput content-length header if php is compressing output for us:
676
+                // it will mess up measurements
677
+                if($php_no_self_compress)
678
+                {
679
+                    header('Content-Length: ' . (int)strlen($payload));
680
+                }
681
+            }
682
+            else
683
+            {
684
+                error_log('XML-RPC: '.__METHOD__.': http headers already sent before response is fully generated. Check for php warning or error messages');
685
+            }
686
+
687
+            print $payload;
688
+
689
+            // return request, in case subclasses want it
690
+            return $r;
691
+        }
692
+
693
+        /**
694
+         * Add a method to the dispatch map
695
+         * @param string $methodname the name with which the method will be made available
696
+         * @param string $function the php function that will get invoked
697
+         * @param array $sig the array of valid method signatures
698
+         * @param string $doc method documentation
699
+         * @param array $sigdoc the array of valid method signatures docs (one string per param, one for return type)
700
+         * @access public
701
+         */
702
+        function add_to_map($methodname,$function,$sig=null,$doc=false,$sigdoc=false)
703
+        {
704
+            $this->dmap[$methodname] = array(
705
+                'function'	=> $function,
706
+                'docstring' => $doc
707
+            );
708
+            if ($sig)
709
+            {
710
+                $this->dmap[$methodname]['signature'] = $sig;
711
+            }
712
+            if ($sigdoc)
713
+            {
714
+                $this->dmap[$methodname]['signature_docs'] = $sigdoc;
715
+            }
716
+        }
717
+
718
+        /**
719
+         * Verify type and number of parameters received against a list of known signatures
720
+         * @param array $in array of either xmlrpcval objects or xmlrpc type definitions
721
+         * @param array $sig array of known signatures to match against
722
+         * @return array
723
+         * @access private
724
+         */
725
+        function verifySignature($in, $sig)
726
+        {
727
+            // check each possible signature in turn
728
+            if (is_object($in))
729
+            {
730
+                $numParams = $in->getNumParams();
731
+            }
732
+            else
733
+            {
734
+                $numParams = count($in);
735
+            }
736
+            foreach($sig as $cursig)
737
+            {
738
+                if(count($cursig)==$numParams+1)
739
+                {
740
+                    $itsOK=1;
741
+                    for($n=0; $n<$numParams; $n++)
742
+                    {
743
+                        if (is_object($in))
744
+                        {
745
+                            $p=$in->getParam($n);
746
+                            if($p->kindOf() == 'scalar')
747
+                            {
748
+                                $pt=$p->scalartyp();
749
+                            }
750
+                            else
751
+                            {
752
+                                $pt=$p->kindOf();
753
+                            }
754
+                        }
755
+                        else
756
+                        {
757
+                            $pt= $in[$n] == 'i4' ? 'int' : strtolower($in[$n]); // dispatch maps never use i4...
758
+                        }
759
+
760
+                        // param index is $n+1, as first member of sig is return type
761
+                        if($pt != $cursig[$n+1] && $cursig[$n+1] != $GLOBALS['xmlrpcValue'])
762
+                        {
763
+                            $itsOK=0;
764
+                            $pno=$n+1;
765
+                            $wanted=$cursig[$n+1];
766
+                            $got=$pt;
767
+                            break;
768
+                        }
769
+                    }
770
+                    if($itsOK)
771
+                    {
772
+                        return array(1,'');
773
+                    }
774
+                }
775
+            }
776
+            if(isset($wanted))
777
+            {
778
+                return array(0, "Wanted ${wanted}, got ${got} at param ${pno}");
779
+            }
780
+            else
781
+            {
782
+                return array(0, "No method signature matches number of parameters");
783
+            }
784
+        }
785
+
786
+        /**
787
+         * Parse http headers received along with xmlrpc request. If needed, inflate request
788
+         * @return mixed null on success or an xmlrpcresp
789
+         * @access private
790
+         */
791
+        function parseRequestHeaders(&$data, &$req_encoding, &$resp_encoding, &$resp_compression)
792
+        {
793
+            // check if $_SERVER is populated: it might have been disabled via ini file
794
+            // (this is true even when in CLI mode)
795
+            if (count($_SERVER) == 0)
796
+            {
797
+                error_log('XML-RPC: '.__METHOD__.': cannot parse request headers as $_SERVER is not populated');
798
+            }
799
+
800
+            if($this->debug > 1)
801
+            {
802
+                if(function_exists('getallheaders'))
803
+                {
804
+                    $this->debugmsg(''); // empty line
805
+                    foreach(getallheaders() as $name => $val)
806
+                    {
807
+                        $this->debugmsg("HEADER: $name: $val");
808
+                    }
809
+                }
810
+
811
+            }
812
+
813
+            if(isset($_SERVER['HTTP_CONTENT_ENCODING']))
814
+            {
815
+                $content_encoding = str_replace('x-', '', $_SERVER['HTTP_CONTENT_ENCODING']);
816
+            }
817
+            else
818
+            {
819
+                $content_encoding = '';
820
+            }
821
+
822
+            // check if request body has been compressed and decompress it
823
+            if($content_encoding != '' && strlen($data))
824
+            {
825
+                if($content_encoding == 'deflate' || $content_encoding == 'gzip')
826
+                {
827
+                    // if decoding works, use it. else assume data wasn't gzencoded
828
+                    if(function_exists('gzinflate') && in_array($content_encoding, $this->accepted_compression))
829
+                    {
830
+                        if($content_encoding == 'deflate' && $degzdata = @gzuncompress($data))
831
+                        {
832
+                            $data = $degzdata;
833
+                            if($this->debug > 1)
834
+                            {
835
+                                $this->debugmsg("\n+++INFLATED REQUEST+++[".strlen($data)." chars]+++\n" . $data . "\n+++END+++");
836
+                            }
837
+                        }
838
+                        elseif($content_encoding == 'gzip' && $degzdata = @gzinflate(substr($data, 10)))
839
+                        {
840
+                            $data = $degzdata;
841
+                            if($this->debug > 1)
842
+                                $this->debugmsg("+++INFLATED REQUEST+++[".strlen($data)." chars]+++\n" . $data . "\n+++END+++");
843
+                        }
844
+                        else
845
+                        {
846
+                            $r = new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['server_decompress_fail'], $GLOBALS['xmlrpcstr']['server_decompress_fail']);
847
+                            return $r;
848
+                        }
849
+                    }
850
+                    else
851
+                    {
852
+                        //error_log('The server sent deflated data. Your php install must have the Zlib extension compiled in to support this.');
853
+                        $r = new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['server_cannot_decompress'], $GLOBALS['xmlrpcstr']['server_cannot_decompress']);
854
+                        return $r;
855
+                    }
856
+                }
857
+            }
858
+
859
+            // check if client specified accepted charsets, and if we know how to fulfill
860
+            // the request
861
+            if ($this->response_charset_encoding == 'auto')
862
+            {
863
+                $resp_encoding = '';
864
+                if (isset($_SERVER['HTTP_ACCEPT_CHARSET']))
865
+                {
866
+                    // here we should check if we can match the client-requested encoding
867
+                    // with the encodings we know we can generate.
868
+                    /// @todo we should parse q=0.x preferences instead of getting first charset specified...
869
+                    $client_accepted_charsets = explode(',', strtoupper($_SERVER['HTTP_ACCEPT_CHARSET']));
870
+                    // Give preference to internal encoding
871
+                    $known_charsets = array($GLOBALS['xmlrpc_internalencoding'], 'UTF-8', 'ISO-8859-1', 'US-ASCII');
872
+                    foreach ($known_charsets as $charset)
873
+                    {
874
+                        foreach ($client_accepted_charsets as $accepted)
875
+                            if (strpos($accepted, $charset) === 0)
876
+                            {
877
+                                $resp_encoding = $charset;
878
+                                break;
879
+                            }
880
+                        if ($resp_encoding)
881
+                            break;
882
+                    }
883
+                }
884
+            }
885
+            else
886
+            {
887
+                $resp_encoding = $this->response_charset_encoding;
888
+            }
889
+
890
+            if (isset($_SERVER['HTTP_ACCEPT_ENCODING']))
891
+            {
892
+                $resp_compression = $_SERVER['HTTP_ACCEPT_ENCODING'];
893
+            }
894
+            else
895
+            {
896
+                $resp_compression = '';
897
+            }
898
+
899
+            // 'guestimate' request encoding
900
+            /// @todo check if mbstring is enabled and automagic input conversion is on: it might mingle with this check???
901
+            $req_encoding = guess_encoding(isset($_SERVER['CONTENT_TYPE']) ? $_SERVER['CONTENT_TYPE'] : '',
902
+                $data);
903
+
904
+            return null;
905
+        }
906
+
907
+        /**
908
+         * Parse an xml chunk containing an xmlrpc request and execute the corresponding
909
+         * php function registered with the server
910
+         * @param string $data the xml request
911
+         * @param string $req_encoding (optional) the charset encoding of the xml request
912
+         * @return xmlrpcresp
913
+         * @access private
914
+         */
915
+        function parseRequest($data, $req_encoding='')
916
+        {
917
+            // 2005/05/07 commented and moved into caller function code
918
+            //if($data=='')
919
+            //{
920
+            //	$data=$GLOBALS['HTTP_RAW_POST_DATA'];
921
+            //}
922
+
923
+            // G. Giunta 2005/02/13: we do NOT expect to receive html entities
924
+            // so we do not try to convert them into xml character entities
925
+            //$data = xmlrpc_html_entity_xlate($data);
926
+
927
+            $GLOBALS['_xh']=array();
928
+            $GLOBALS['_xh']['ac']='';
929
+            $GLOBALS['_xh']['stack']=array();
930
+            $GLOBALS['_xh']['valuestack'] = array();
931
+            $GLOBALS['_xh']['params']=array();
932
+            $GLOBALS['_xh']['pt']=array();
933
+            $GLOBALS['_xh']['isf']=0;
934
+            $GLOBALS['_xh']['isf_reason']='';
935
+            $GLOBALS['_xh']['method']=false; // so we can check later if we got a methodname or not
936
+            $GLOBALS['_xh']['rt']='';
937
+
938
+            // decompose incoming XML into request structure
939
+
940
+            if ($req_encoding != '')
941
+            {
942
+                // Since parsing will fail if charset is not specified in the xml prologue,
943
+                // the encoding is not UTF8 and there are non-ascii chars in the text, we try to work round that...
944
+                // The following code might be better for mb_string enabled installs, but
945
+                // makes the lib about 200% slower...
946
+                //if (!is_valid_charset($req_encoding, array('UTF-8')))
947
+                if (!in_array($req_encoding, array('UTF-8', 'US-ASCII')) && !has_encoding($data)) {
948
+                    if ($req_encoding == 'ISO-8859-1') {
949
+                        $data = utf8_encode($data);
950
+                    } else {
951
+                        if (extension_loaded('mbstring')) {
952
+                            $data = mb_convert_encoding($data, 'UTF-8', $req_encoding);
953
+                        } else {
954
+                            error_log('XML-RPC: ' . __METHOD__ . ': invalid charset encoding of received request: ' . $req_encoding);
955
+                        }
956
+                    }
957
+                }
958
+            }
959
+
960
+            $parser = xml_parser_create();
961
+            xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true);
962
+            // G. Giunta 2005/02/13: PHP internally uses ISO-8859-1, so we have to tell
963
+            // the xml parser to give us back data in the expected charset
964
+            // What if internal encoding is not in one of the 3 allowed?
965
+            // we use the broadest one, ie. utf8
966
+            // This allows to send data which is native in various charset,
967
+            // by extending xmlrpc_encode_entitites() and setting xmlrpc_internalencoding
968
+            if (!in_array($GLOBALS['xmlrpc_internalencoding'], array('UTF-8', 'ISO-8859-1', 'US-ASCII')))
969
+            {
970
+                xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, 'UTF-8');
971
+            }
972
+            else
973
+            {
974
+                xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, $GLOBALS['xmlrpc_internalencoding']);
975
+            }
976
+
977
+            if ($this->functions_parameters_type != 'xmlrpcvals')
978
+                xml_set_element_handler($parser, 'xmlrpc_se', 'xmlrpc_ee_fast');
979
+            else
980
+                xml_set_element_handler($parser, 'xmlrpc_se', 'xmlrpc_ee');
981
+            xml_set_character_data_handler($parser, 'xmlrpc_cd');
982
+            xml_set_default_handler($parser, 'xmlrpc_dh');
983
+            if(!xml_parse($parser, $data, 1))
984
+            {
985
+                // return XML error as a faultCode
986
+                $r=new xmlrpcresp(0,
987
+                $GLOBALS['xmlrpcerrxml']+xml_get_error_code($parser),
988
+                sprintf('XML error: %s at line %d, column %d',
989
+                    xml_error_string(xml_get_error_code($parser)),
990
+                    xml_get_current_line_number($parser), xml_get_current_column_number($parser)));
991
+                xml_parser_free($parser);
992
+            }
993
+            elseif ($GLOBALS['_xh']['isf'])
994
+            {
995
+                xml_parser_free($parser);
996
+                $r=new xmlrpcresp(0,
997
+                    $GLOBALS['xmlrpcerr']['invalid_request'],
998
+                    $GLOBALS['xmlrpcstr']['invalid_request'] . ' ' . $GLOBALS['_xh']['isf_reason']);
999
+            }
1000
+            else
1001
+            {
1002
+                xml_parser_free($parser);
1003
+                // small layering violation in favor of speed and memory usage:
1004
+                // we should allow the 'execute' method handle this, but in the
1005
+                // most common scenario (xmlrpcvals type server with some methods
1006
+                // registered as phpvals) that would mean a useless encode+decode pass
1007
+                if ($this->functions_parameters_type != 'xmlrpcvals' || (isset($this->dmap[$GLOBALS['_xh']['method']]['parameters_type']) && ($this->dmap[$GLOBALS['_xh']['method']]['parameters_type'] == 'phpvals')))
1008
+                {
1009
+                    if($this->debug > 1)
1010
+                    {
1011
+                        $this->debugmsg("\n+++PARSED+++\n".var_export($GLOBALS['_xh']['params'], true)."\n+++END+++");
1012
+                    }
1013
+                    $r = $this->execute($GLOBALS['_xh']['method'], $GLOBALS['_xh']['params'], $GLOBALS['_xh']['pt']);
1014
+                }
1015
+                else
1016
+                {
1017
+                    // build an xmlrpcmsg object with data parsed from xml
1018
+                    $m=new xmlrpcmsg($GLOBALS['_xh']['method']);
1019
+                    // now add parameters in
1020
+                    for($i=0; $i<count($GLOBALS['_xh']['params']); $i++)
1021
+                    {
1022
+                        $m->addParam($GLOBALS['_xh']['params'][$i]);
1023
+                    }
1024
+
1025
+                    if($this->debug > 1)
1026
+                    {
1027
+                        $this->debugmsg("\n+++PARSED+++\n".var_export($m, true)."\n+++END+++");
1028
+                    }
1029
+                    $r = $this->execute($m);
1030
+                }
1031
+            }
1032
+            return $r;
1033
+        }
1034
+
1035
+        /**
1036
+         * Execute a method invoked by the client, checking parameters used
1037
+         * @param mixed $m either an xmlrpcmsg obj or a method name
1038
+         * @param array $params array with method parameters as php types (if m is method name only)
1039
+         * @param array $paramtypes array with xmlrpc types of method parameters (if m is method name only)
1040
+         * @return xmlrpcresp
1041
+         * @access private
1042
+         */
1043
+        function execute($m, $params=null, $paramtypes=null)
1044
+        {
1045
+            if (is_object($m))
1046
+            {
1047
+                $methName = $m->method();
1048
+            }
1049
+            else
1050
+            {
1051
+                $methName = $m;
1052
+            }
1053
+            $sysCall = $this->allow_system_funcs && (strpos($methName, "system.") === 0);
1054
+            $dmap = $sysCall ? $GLOBALS['_xmlrpcs_dmap'] : $this->dmap;
1055
+
1056
+            if(!isset($dmap[$methName]['function']))
1057
+            {
1058
+                // No such method
1059
+                return new xmlrpcresp(0,
1060
+                    $GLOBALS['xmlrpcerr']['unknown_method'],
1061
+                    $GLOBALS['xmlrpcstr']['unknown_method']);
1062
+            }
1063
+
1064
+            // Check signature
1065
+            if(isset($dmap[$methName]['signature']))
1066
+            {
1067
+                $sig = $dmap[$methName]['signature'];
1068
+                if (is_object($m))
1069
+                {
1070
+                    list($ok, $errstr) = $this->verifySignature($m, $sig);
1071
+                }
1072
+                else
1073
+                {
1074
+                    list($ok, $errstr) = $this->verifySignature($paramtypes, $sig);
1075
+                }
1076
+                if(!$ok)
1077
+                {
1078
+                    // Didn't match.
1079
+                    return new xmlrpcresp(
1080
+                        0,
1081
+                        $GLOBALS['xmlrpcerr']['incorrect_params'],
1082
+                        $GLOBALS['xmlrpcstr']['incorrect_params'] . ": ${errstr}"
1083
+                    );
1084
+                }
1085
+            }
1086
+
1087
+            $func = $dmap[$methName]['function'];
1088
+            // let the 'class::function' syntax be accepted in dispatch maps
1089
+            if(is_string($func) && strpos($func, '::'))
1090
+            {
1091
+                $func = explode('::', $func);
1092
+            }
1093
+            // verify that function to be invoked is in fact callable
1094
+            if(!is_callable($func))
1095
+            {
1096
+                error_log("XML-RPC: ".__METHOD__.": function $func registered as method handler is not callable");
1097
+                return new xmlrpcresp(
1098
+                    0,
1099
+                    $GLOBALS['xmlrpcerr']['server_error'],
1100
+                    $GLOBALS['xmlrpcstr']['server_error'] . ": no function matches method"
1101
+                );
1102
+            }
1103
+
1104
+            // If debug level is 3, we should catch all errors generated during
1105
+            // processing of user function, and log them as part of response
1106
+            if($this->debug > 2)
1107
+            {
1108
+                $GLOBALS['_xmlrpcs_prev_ehandler'] = set_error_handler('_xmlrpcs_errorHandler');
1109
+            }
1110
+            try
1111
+            {
1112
+                // Allow mixed-convention servers
1113
+                if (is_object($m))
1114
+                {
1115
+                    if ($sysCall)
1116
+                    {
1117
+                        $r = call_user_func($func, $this, $m);
1118
+                    }
1119
+                    else
1120
+                    {
1121
+                        $r = call_user_func($func, $m);
1122
+                    }
1123
+                    if (!is_a($r, 'xmlrpcresp'))
1124
+                    {
1125
+                        error_log("XML-RPC: ".__METHOD__.": function $func registered as method handler does not return an xmlrpcresp object");
1126
+                        if (is_a($r, 'xmlrpcval'))
1127
+                        {
1128
+                            $r = new xmlrpcresp($r);
1129
+                        }
1130
+                        else
1131
+                        {
1132
+                            $r = new xmlrpcresp(
1133
+                                0,
1134
+                                $GLOBALS['xmlrpcerr']['server_error'],
1135
+                                $GLOBALS['xmlrpcstr']['server_error'] . ": function does not return xmlrpcresp object"
1136
+                            );
1137
+                        }
1138
+                    }
1139
+                }
1140
+                else
1141
+                {
1142
+                    // call a 'plain php' function
1143
+                    if($sysCall)
1144
+                    {
1145
+                        array_unshift($params, $this);
1146
+                        $r = call_user_func_array($func, $params);
1147
+                    }
1148
+                    else
1149
+                    {
1150
+                        // 3rd API convention for method-handling functions: EPI-style
1151
+                        if ($this->functions_parameters_type == 'epivals')
1152
+                        {
1153
+                            $r = call_user_func_array($func, array($methName, $params, $this->user_data));
1154
+                            // mimic EPI behaviour: if we get an array that looks like an error, make it
1155
+                            // an eror response
1156
+                            if (is_array($r) && array_key_exists('faultCode', $r) && array_key_exists('faultString', $r))
1157
+                            {
1158
+                                $r = new xmlrpcresp(0, (integer)$r['faultCode'], (string)$r['faultString']);
1159
+                            }
1160
+                            else
1161
+                            {
1162
+                                // functions using EPI api should NOT return resp objects,
1163
+                                // so make sure we encode the return type correctly
1164
+                                $r = new xmlrpcresp(php_xmlrpc_encode($r, array('extension_api')));
1165
+                            }
1166
+                        }
1167
+                        else
1168
+                        {
1169
+                            $r = call_user_func_array($func, $params);
1170
+                        }
1171
+                    }
1172
+                    // the return type can be either an xmlrpcresp object or a plain php value...
1173
+                    if (!is_a($r, 'xmlrpcresp'))
1174
+                    {
1175
+                        // what should we assume here about automatic encoding of datetimes
1176
+                        // and php classes instances???
1177
+                        $r = new xmlrpcresp(php_xmlrpc_encode($r, $this->phpvals_encoding_options));
1178
+                    }
1179
+                }
1180
+            }
1181
+            catch(Exception $e)
1182
+            {
1183
+                // (barring errors in the lib) an uncatched exception happened
1184
+                // in the called function, we wrap it in a proper error-response
1185
+                switch($this->exception_handling)
1186
+                {
1187
+                    case 2:
1188
+                        throw $e;
1189
+                        break;
1190
+                    case 1:
1191
+                        $r = new xmlrpcresp(0, $e->getCode(), $e->getMessage());
1192
+                        break;
1193
+                    default:
1194
+                        $r = new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['server_error'], $GLOBALS['xmlrpcstr']['server_error']);
1195
+                }
1196
+            }
1197
+            if($this->debug > 2)
1198
+            {
1199
+                // note: restore the error handler we found before calling the
1200
+                // user func, even if it has been changed inside the func itself
1201
+                if($GLOBALS['_xmlrpcs_prev_ehandler'])
1202
+                {
1203
+                    set_error_handler($GLOBALS['_xmlrpcs_prev_ehandler']);
1204
+                }
1205
+                else
1206
+                {
1207
+                    restore_error_handler();
1208
+                }
1209
+            }
1210
+            return $r;
1211
+        }
1212
+
1213
+        /**
1214
+         * add a string to the 'internal debug message' (separate from 'user debug message')
1215
+         * @param string $string
1216
+         * @access private
1217
+         */
1218
+        function debugmsg($string)
1219
+        {
1220
+            $this->debug_info .= $string."\n";
1221
+        }
1222
+
1223
+        /**
1224
+         * @access private
1225
+         */
1226
+        function xml_header($charset_encoding='')
1227
+        {
1228
+            if ($charset_encoding != '')
1229
+            {
1230
+                return "<?xml version=\"1.0\" encoding=\"$charset_encoding\"?" . ">\n";
1231
+            }
1232
+            else
1233
+            {
1234
+                return "<?xml version=\"1.0\"?" . ">\n";
1235
+            }
1236
+        }
1237
+
1238
+        /**
1239
+         * A debugging routine: just echoes back the input packet as a string value
1240
+         * @deprecated
1241
+         */
1242
+        function echoInput()
1243
+        {
1244
+            $r=new xmlrpcresp(new xmlrpcval( "'Aha said I: '" . $GLOBALS['HTTP_RAW_POST_DATA'], 'string'));
1245
+            print $r->serialize();
1246
+        }
1247
+    }
1248 1248
 ?>
Please login to merge, or discard this patch.
Spacing   +179 added lines, -179 removed lines patch added patch discarded remove patch
@@ -57,10 +57,10 @@  discard block
 block discarded – undo
57 57
 	);
58 58
 
59 59
 	/* Functions that implement system.XXX methods of xmlrpc servers */
60
-	$_xmlrpcs_getCapabilities_sig=array(array($GLOBALS['xmlrpcStruct']));
61
-	$_xmlrpcs_getCapabilities_doc='This method lists all the capabilites that the XML-RPC server has: the (more or less standard) extensions to the xmlrpc spec that it adheres to';
62
-	$_xmlrpcs_getCapabilities_sdoc=array(array('list of capabilities, described as structs with a version number and url for the spec'));
63
-	function _xmlrpcs_getCapabilities($server, $m=null)
60
+	$_xmlrpcs_getCapabilities_sig = array(array($GLOBALS['xmlrpcStruct']));
61
+	$_xmlrpcs_getCapabilities_doc = 'This method lists all the capabilites that the XML-RPC server has: the (more or less standard) extensions to the xmlrpc spec that it adheres to';
62
+	$_xmlrpcs_getCapabilities_sdoc = array(array('list of capabilities, described as structs with a version number and url for the spec'));
63
+	function _xmlrpcs_getCapabilities($server, $m = null)
64 64
 	{
65 65
 		$outAr = $GLOBALS['xmlrpcs_capabilities'];
66 66
 		// NIL extension
@@ -75,117 +75,117 @@  discard block
 block discarded – undo
75 75
 
76 76
 	// listMethods: signature was either a string, or nothing.
77 77
 	// The useless string variant has been removed
78
-	$_xmlrpcs_listMethods_sig=array(array($GLOBALS['xmlrpcArray']));
79
-	$_xmlrpcs_listMethods_doc='This method lists all the methods that the XML-RPC server knows how to dispatch';
80
-	$_xmlrpcs_listMethods_sdoc=array(array('list of method names'));
81
-	function _xmlrpcs_listMethods($server, $m=null) // if called in plain php values mode, second param is missing
78
+	$_xmlrpcs_listMethods_sig = array(array($GLOBALS['xmlrpcArray']));
79
+	$_xmlrpcs_listMethods_doc = 'This method lists all the methods that the XML-RPC server knows how to dispatch';
80
+	$_xmlrpcs_listMethods_sdoc = array(array('list of method names'));
81
+	function _xmlrpcs_listMethods($server, $m = null) // if called in plain php values mode, second param is missing
82 82
 	{
83 83
 
84
-		$outAr=array();
85
-		foreach($server->dmap as $key => $val)
84
+		$outAr = array();
85
+		foreach ($server->dmap as $key => $val)
86 86
 		{
87
-			$outAr[]=new xmlrpcval($key, 'string');
87
+			$outAr[] = new xmlrpcval($key, 'string');
88 88
 		}
89
-		if($server->allow_system_funcs)
89
+		if ($server->allow_system_funcs)
90 90
 		{
91
-			foreach($GLOBALS['_xmlrpcs_dmap'] as $key => $val)
91
+			foreach ($GLOBALS['_xmlrpcs_dmap'] as $key => $val)
92 92
 			{
93
-				$outAr[]=new xmlrpcval($key, 'string');
93
+				$outAr[] = new xmlrpcval($key, 'string');
94 94
 			}
95 95
 		}
96 96
 		return new xmlrpcresp(new xmlrpcval($outAr, 'array'));
97 97
 	}
98 98
 
99
-	$_xmlrpcs_methodSignature_sig=array(array($GLOBALS['xmlrpcArray'], $GLOBALS['xmlrpcString']));
100
-	$_xmlrpcs_methodSignature_doc='Returns an array of known signatures (an array of arrays) for the method name passed. If no signatures are known, returns a none-array (test for type != array to detect missing signature)';
101
-	$_xmlrpcs_methodSignature_sdoc=array(array('list of known signatures, each sig being an array of xmlrpc type names', 'name of method to be described'));
99
+	$_xmlrpcs_methodSignature_sig = array(array($GLOBALS['xmlrpcArray'], $GLOBALS['xmlrpcString']));
100
+	$_xmlrpcs_methodSignature_doc = 'Returns an array of known signatures (an array of arrays) for the method name passed. If no signatures are known, returns a none-array (test for type != array to detect missing signature)';
101
+	$_xmlrpcs_methodSignature_sdoc = array(array('list of known signatures, each sig being an array of xmlrpc type names', 'name of method to be described'));
102 102
 	function _xmlrpcs_methodSignature($server, $m)
103 103
 	{
104 104
 		// let accept as parameter both an xmlrpcval or string
105 105
 		if (is_object($m))
106 106
 		{
107
-			$methName=$m->getParam(0);
108
-			$methName=$methName->scalarval();
107
+			$methName = $m->getParam(0);
108
+			$methName = $methName->scalarval();
109 109
 		}
110 110
 		else
111 111
 		{
112
-			$methName=$m;
112
+			$methName = $m;
113 113
 		}
114
-		if(strpos($methName, "system.") === 0)
114
+		if (strpos($methName, "system.") === 0)
115 115
 		{
116
-			$dmap=$GLOBALS['_xmlrpcs_dmap']; //$sysCall=1;
116
+			$dmap = $GLOBALS['_xmlrpcs_dmap']; //$sysCall=1;
117 117
 		}
118 118
 		else
119 119
 		{
120
-			$dmap=$server->dmap; //$sysCall=0;
120
+			$dmap = $server->dmap; //$sysCall=0;
121 121
 		}
122
-		if(isset($dmap[$methName]))
122
+		if (isset($dmap[$methName]))
123 123
 		{
124
-			if(isset($dmap[$methName]['signature']))
124
+			if (isset($dmap[$methName]['signature']))
125 125
 			{
126
-				$sigs=array();
127
-				foreach($dmap[$methName]['signature'] as $inSig)
126
+				$sigs = array();
127
+				foreach ($dmap[$methName]['signature'] as $inSig)
128 128
 				{
129
-					$cursig=array();
130
-					foreach($inSig as $sig)
129
+					$cursig = array();
130
+					foreach ($inSig as $sig)
131 131
 					{
132
-						$cursig[]=new xmlrpcval($sig, 'string');
132
+						$cursig[] = new xmlrpcval($sig, 'string');
133 133
 					}
134
-					$sigs[]=new xmlrpcval($cursig, 'array');
134
+					$sigs[] = new xmlrpcval($cursig, 'array');
135 135
 				}
136
-				$r=new xmlrpcresp(new xmlrpcval($sigs, 'array'));
136
+				$r = new xmlrpcresp(new xmlrpcval($sigs, 'array'));
137 137
 			}
138 138
 			else
139 139
 			{
140 140
 				// NB: according to the official docs, we should be returning a
141 141
 				// "none-array" here, which means not-an-array
142
-				$r=new xmlrpcresp(new xmlrpcval('undef', 'string'));
142
+				$r = new xmlrpcresp(new xmlrpcval('undef', 'string'));
143 143
 			}
144 144
 		}
145 145
 		else
146 146
 		{
147
-			$r=new xmlrpcresp(0,$GLOBALS['xmlrpcerr']['introspect_unknown'], $GLOBALS['xmlrpcstr']['introspect_unknown']);
147
+			$r = new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['introspect_unknown'], $GLOBALS['xmlrpcstr']['introspect_unknown']);
148 148
 		}
149 149
 		return $r;
150 150
 	}
151 151
 
152
-	$_xmlrpcs_methodHelp_sig=array(array($GLOBALS['xmlrpcString'], $GLOBALS['xmlrpcString']));
153
-	$_xmlrpcs_methodHelp_doc='Returns help text if defined for the method passed, otherwise returns an empty string';
154
-	$_xmlrpcs_methodHelp_sdoc=array(array('method description', 'name of the method to be described'));
152
+	$_xmlrpcs_methodHelp_sig = array(array($GLOBALS['xmlrpcString'], $GLOBALS['xmlrpcString']));
153
+	$_xmlrpcs_methodHelp_doc = 'Returns help text if defined for the method passed, otherwise returns an empty string';
154
+	$_xmlrpcs_methodHelp_sdoc = array(array('method description', 'name of the method to be described'));
155 155
 	function _xmlrpcs_methodHelp($server, $m)
156 156
 	{
157 157
 		// let accept as parameter both an xmlrpcval or string
158 158
 		if (is_object($m))
159 159
 		{
160
-			$methName=$m->getParam(0);
161
-			$methName=$methName->scalarval();
160
+			$methName = $m->getParam(0);
161
+			$methName = $methName->scalarval();
162 162
 		}
163 163
 		else
164 164
 		{
165
-			$methName=$m;
165
+			$methName = $m;
166 166
 		}
167
-		if(strpos($methName, "system.") === 0)
167
+		if (strpos($methName, "system.") === 0)
168 168
 		{
169
-			$dmap=$GLOBALS['_xmlrpcs_dmap']; //$sysCall=1;
169
+			$dmap = $GLOBALS['_xmlrpcs_dmap']; //$sysCall=1;
170 170
 		}
171 171
 		else
172 172
 		{
173
-			$dmap=$server->dmap; //$sysCall=0;
173
+			$dmap = $server->dmap; //$sysCall=0;
174 174
 		}
175
-		if(isset($dmap[$methName]))
175
+		if (isset($dmap[$methName]))
176 176
 		{
177
-			if(isset($dmap[$methName]['docstring']))
177
+			if (isset($dmap[$methName]['docstring']))
178 178
 			{
179
-				$r=new xmlrpcresp(new xmlrpcval($dmap[$methName]['docstring']), 'string');
179
+				$r = new xmlrpcresp(new xmlrpcval($dmap[$methName]['docstring']), 'string');
180 180
 			}
181 181
 			else
182 182
 			{
183
-				$r=new xmlrpcresp(new xmlrpcval('', 'string'));
183
+				$r = new xmlrpcresp(new xmlrpcval('', 'string'));
184 184
 			}
185 185
 		}
186 186
 		else
187 187
 		{
188
-			$r=new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['introspect_unknown'], $GLOBALS['xmlrpcstr']['introspect_unknown']);
188
+			$r = new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['introspect_unknown'], $GLOBALS['xmlrpcstr']['introspect_unknown']);
189 189
 		}
190 190
 		return $r;
191 191
 	}
@@ -195,7 +195,7 @@  discard block
 block discarded – undo
195 195
 	$_xmlrpcs_multicall_sdoc = array(array('list of response structs, where each struct has the usual members', 'list of calls, with each call being represented as a struct, with members "methodname" and "params"'));
196 196
 	function _xmlrpcs_multicall_error($err)
197 197
 	{
198
-		if(is_string($err))
198
+		if (is_string($err))
199 199
 		{
200 200
 			$str = $GLOBALS['xmlrpcstr']["multicall_${err}"];
201 201
 			$code = $GLOBALS['xmlrpcerr']["multicall_${err}"];
@@ -213,52 +213,52 @@  discard block
 block discarded – undo
213 213
 
214 214
 	function _xmlrpcs_multicall_do_call($server, $call)
215 215
 	{
216
-		if($call->kindOf() != 'struct')
216
+		if ($call->kindOf() != 'struct')
217 217
 		{
218 218
 			return _xmlrpcs_multicall_error('notstruct');
219 219
 		}
220 220
 		$methName = @$call->structmem('methodName');
221
-		if(!$methName)
221
+		if (!$methName)
222 222
 		{
223 223
 			return _xmlrpcs_multicall_error('nomethod');
224 224
 		}
225
-		if($methName->kindOf() != 'scalar' || $methName->scalartyp() != 'string')
225
+		if ($methName->kindOf() != 'scalar' || $methName->scalartyp() != 'string')
226 226
 		{
227 227
 			return _xmlrpcs_multicall_error('notstring');
228 228
 		}
229
-		if($methName->scalarval() == 'system.multicall')
229
+		if ($methName->scalarval() == 'system.multicall')
230 230
 		{
231 231
 			return _xmlrpcs_multicall_error('recursion');
232 232
 		}
233 233
 
234 234
 		$params = @$call->structmem('params');
235
-		if(!$params)
235
+		if (!$params)
236 236
 		{
237 237
 			return _xmlrpcs_multicall_error('noparams');
238 238
 		}
239
-		if($params->kindOf() != 'array')
239
+		if ($params->kindOf() != 'array')
240 240
 		{
241 241
 			return _xmlrpcs_multicall_error('notarray');
242 242
 		}
243 243
 		$numParams = $params->arraysize();
244 244
 
245 245
 		$msg = new xmlrpcmsg($methName->scalarval());
246
-		for($i = 0; $i < $numParams; $i++)
246
+		for ($i = 0; $i<$numParams; $i++)
247 247
 		{
248
-			if(!$msg->addParam($params->arraymem($i)))
248
+			if (!$msg->addParam($params->arraymem($i)))
249 249
 			{
250 250
 				$i++;
251 251
 				return _xmlrpcs_multicall_error(new xmlrpcresp(0,
252 252
 					$GLOBALS['xmlrpcerr']['incorrect_params'],
253
-					$GLOBALS['xmlrpcstr']['incorrect_params'] . ": probable xml error in param " . $i));
253
+					$GLOBALS['xmlrpcstr']['incorrect_params'].": probable xml error in param ".$i));
254 254
 			}
255 255
 		}
256 256
 
257 257
 		$result = $server->execute($msg);
258 258
 
259
-		if($result->faultCode() != 0)
259
+		if ($result->faultCode() != 0)
260 260
 		{
261
-			return _xmlrpcs_multicall_error($result);		// Method returned fault.
261
+			return _xmlrpcs_multicall_error($result); // Method returned fault.
262 262
 		}
263 263
 
264 264
 		return new xmlrpcval(array($result->value()), 'array');
@@ -266,11 +266,11 @@  discard block
 block discarded – undo
266 266
 
267 267
 	function _xmlrpcs_multicall_do_call_phpvals($server, $call)
268 268
 	{
269
-		if(!is_array($call))
269
+		if (!is_array($call))
270 270
 		{
271 271
 			return _xmlrpcs_multicall_error('notstruct');
272 272
 		}
273
-		if(!array_key_exists('methodName', $call))
273
+		if (!array_key_exists('methodName', $call))
274 274
 		{
275 275
 			return _xmlrpcs_multicall_error('nomethod');
276 276
 		}
@@ -278,15 +278,15 @@  discard block
 block discarded – undo
278 278
 		{
279 279
 			return _xmlrpcs_multicall_error('notstring');
280 280
 		}
281
-		if($call['methodName'] == 'system.multicall')
281
+		if ($call['methodName'] == 'system.multicall')
282 282
 		{
283 283
 			return _xmlrpcs_multicall_error('recursion');
284 284
 		}
285
-		if(!array_key_exists('params', $call))
285
+		if (!array_key_exists('params', $call))
286 286
 		{
287 287
 			return _xmlrpcs_multicall_error('noparams');
288 288
 		}
289
-		if(!is_array($call['params']))
289
+		if (!is_array($call['params']))
290 290
 		{
291 291
 			return _xmlrpcs_multicall_error('notarray');
292 292
 		}
@@ -295,14 +295,14 @@  discard block
 block discarded – undo
295 295
 		// base64 or datetime values, but they will be listed as strings here...
296 296
 		//$numParams = count($call['params']);
297 297
 		$pt = array();
298
-		foreach($call['params'] as $val)
298
+		foreach ($call['params'] as $val)
299 299
 			$pt[] = php_2_xmlrpc_type(gettype($val));
300 300
 
301 301
 		$result = $server->execute($call['methodName'], $call['params'], $pt);
302 302
 
303
-		if($result->faultCode() != 0)
303
+		if ($result->faultCode() != 0)
304 304
 		{
305
-			return _xmlrpcs_multicall_error($result);		// Method returned fault.
305
+			return _xmlrpcs_multicall_error($result); // Method returned fault.
306 306
 		}
307 307
 
308 308
 		return new xmlrpcval(array($result->value()), 'array');
@@ -316,7 +316,7 @@  discard block
 block discarded – undo
316 316
 		{
317 317
 			$calls = $m->getParam(0);
318 318
 			$numCalls = $calls->arraysize();
319
-			for($i = 0; $i < $numCalls; $i++)
319
+			for ($i = 0; $i<$numCalls; $i++)
320 320
 			{
321 321
 				$call = $calls->arraymem($i);
322 322
 				$result[$i] = _xmlrpcs_multicall_do_call($server, $call);
@@ -324,8 +324,8 @@  discard block
 block discarded – undo
324 324
 		}
325 325
 		else
326 326
 		{
327
-			$numCalls=count($m);
328
-			for($i = 0; $i < $numCalls; $i++)
327
+			$numCalls = count($m);
328
+			for ($i = 0; $i<$numCalls; $i++)
329 329
 			{
330 330
 				$result[$i] = _xmlrpcs_multicall_do_call_phpvals($server, $m[$i]);
331 331
 			}
@@ -334,7 +334,7 @@  discard block
 block discarded – undo
334 334
 		return new xmlrpcresp(new xmlrpcval($result, 'array'));
335 335
 	}
336 336
 
337
-	$GLOBALS['_xmlrpcs_dmap']=array(
337
+	$GLOBALS['_xmlrpcs_dmap'] = array(
338 338
 		'system.listMethods' => array(
339 339
 			'function' => '_xmlrpcs_listMethods',
340 340
 			'signature' => $_xmlrpcs_listMethods_sig,
@@ -374,24 +374,24 @@  discard block
 block discarded – undo
374 374
 	* NB: in fact a user defined error handler can only handle WARNING, NOTICE and USER_* errors.
375 375
 	*
376 376
 	*/
377
-	function _xmlrpcs_errorHandler($errcode, $errstring, $filename=null, $lineno=null, $context=null)
377
+	function _xmlrpcs_errorHandler($errcode, $errstring, $filename = null, $lineno = null, $context = null)
378 378
 	{
379 379
 		// obey the @ protocol
380 380
 		if (error_reporting() == 0)
381 381
 			return;
382 382
 
383 383
 		//if($errcode != E_NOTICE && $errcode != E_WARNING && $errcode != E_USER_NOTICE && $errcode != E_USER_WARNING)
384
-		if($errcode != E_STRICT)
384
+		if ($errcode != E_STRICT)
385 385
 		{
386
-			$GLOBALS['_xmlrpcs_occurred_errors'] = $GLOBALS['_xmlrpcs_occurred_errors'] . $errstring . "\n";
386
+			$GLOBALS['_xmlrpcs_occurred_errors'] = $GLOBALS['_xmlrpcs_occurred_errors'].$errstring."\n";
387 387
 		}
388 388
 		// Try to avoid as much as possible disruption to the previous error handling
389 389
 		// mechanism in place
390
-		if($GLOBALS['_xmlrpcs_prev_ehandler'] == '')
390
+		if ($GLOBALS['_xmlrpcs_prev_ehandler'] == '')
391 391
 		{
392 392
 			// The previous error handler was the default: all we should do is log error
393 393
 			// to the default error log (if level high enough)
394
-			if(ini_get('log_errors') && (intval(ini_get('error_reporting')) & $errcode))
394
+			if (ini_get('log_errors') && (intval(ini_get('error_reporting')) & $errcode))
395 395
 			{
396 396
 				error_log($errstring);
397 397
 			}
@@ -399,10 +399,10 @@  discard block
 block discarded – undo
399 399
 		else
400 400
 		{
401 401
 			// Pass control on to previous error handler, trying to avoid loops...
402
-			if($GLOBALS['_xmlrpcs_prev_ehandler'] != '_xmlrpcs_errorHandler')
402
+			if ($GLOBALS['_xmlrpcs_prev_ehandler'] != '_xmlrpcs_errorHandler')
403 403
 			{
404 404
 				// NB: this code will NOT work on php < 4.0.2: only 2 params were used for error handlers
405
-				if(is_array($GLOBALS['_xmlrpcs_prev_ehandler']))
405
+				if (is_array($GLOBALS['_xmlrpcs_prev_ehandler']))
406 406
 				{
407 407
 					// the following works both with static class methods and plain object methods as error handler
408 408
 					call_user_func_array($GLOBALS['_xmlrpcs_prev_ehandler'], array($errcode, $errstring, $filename, $lineno, $context));
@@ -415,7 +415,7 @@  discard block
 block discarded – undo
415 415
 		}
416 416
 	}
417 417
 
418
-	$GLOBALS['_xmlrpc_debuginfo']='';
418
+	$GLOBALS['_xmlrpc_debuginfo'] = '';
419 419
 
420 420
 	/**
421 421
 	* Add a string to the debug info that can be later seralized by the server
@@ -427,7 +427,7 @@  discard block
 block discarded – undo
427 427
 	*/
428 428
 	function xmlrpc_debugmsg($m)
429 429
 	{
430
-		$GLOBALS['_xmlrpc_debuginfo'] .= $m . "\n";
430
+		$GLOBALS['_xmlrpc_debuginfo'] .= $m."\n";
431 431
 	}
432 432
 
433 433
 	class xmlrpc_server
@@ -436,20 +436,20 @@  discard block
 block discarded – undo
436 436
 		* Array defining php functions exposed as xmlrpc methods by this server
437 437
 		* @access private
438 438
 		*/
439
-		var $dmap=array();
439
+		var $dmap = array();
440 440
 		/**
441 441
 		* Defines how functions in dmap will be invoked: either using an xmlrpc msg object
442 442
 		* or plain php values.
443 443
 		* valid strings are 'xmlrpcvals', 'phpvals' or 'epivals'
444 444
 		*/
445
-		var $functions_parameters_type='xmlrpcvals';
445
+		var $functions_parameters_type = 'xmlrpcvals';
446 446
 		/**
447 447
 		* Option used for fine-tuning the encoding the php values returned from
448 448
 		* functions registered in the dispatch map when the functions_parameters_types
449 449
 		* member is set to 'phpvals'
450 450
 		* @see php_xmlrpc_encode for a list of values
451 451
 		*/
452
-		var $phpvals_encoding_options = array( 'auto_dates' );
452
+		var $phpvals_encoding_options = array('auto_dates');
453 453
 		/// controls whether the server is going to echo debugging messages back to the client as comments in response body. valid values: 0,1,2,3
454 454
 		var $debug = 1;
455 455
 		/**
@@ -497,11 +497,11 @@  discard block
 block discarded – undo
497 497
 		* @param array $dispmap the dispatch map with definition of exposed services
498 498
 		* @param boolean $servicenow set to false to prevent the server from running upon construction
499 499
 		*/
500
-		function __construct($dispMap=null, $serviceNow=true)
500
+		function __construct($dispMap = null, $serviceNow = true)
501 501
 		{
502 502
 			// if ZLIB is enabled, let the server by default accept compressed requests,
503 503
 			// and compress responses sent to clients that support them
504
-			if(function_exists('gzinflate'))
504
+			if (function_exists('gzinflate'))
505 505
 			{
506 506
 				$this->accepted_compression = array('gzip', 'deflate');
507 507
 				$this->compress_response = true;
@@ -519,10 +519,10 @@  discard block
 block discarded – undo
519 519
 			 * instead, you can use the class add_to_map() function
520 520
 			 * to add functions manually (borrowed from SOAPX4)
521 521
 			 */
522
-			if($dispMap)
522
+			if ($dispMap)
523 523
 			{
524 524
 				$this->dmap = $dispMap;
525
-				if($serviceNow)
525
+				if ($serviceNow)
526 526
 				{
527 527
 					$this->service();
528 528
 				}
@@ -532,7 +532,7 @@  discard block
 block discarded – undo
532 532
 		/**
533 533
 		* @deprecated
534 534
 		*/
535
-		function xmlrpc_client($dispMap=null, $serviceNow=true)
535
+		function xmlrpc_client($dispMap = null, $serviceNow = true)
536 536
 		{
537 537
 			self::__construct($dispMap, $serviceNow);
538 538
 		}
@@ -553,7 +553,7 @@  discard block
 block discarded – undo
553 553
 		*/
554 554
 		function setDebug($in)
555 555
 		{
556
-			$this->debug=$in;
556
+			$this->debug = $in;
557 557
 		}
558 558
 
559 559
 		/**
@@ -561,7 +561,7 @@  discard block
 block discarded – undo
561 561
 		* @param string $charset_encoding the target charset encoding for the serialization
562 562
 		* @return string an XML comment (or two)
563 563
 		*/
564
-		function serializeDebug($charset_encoding='')
564
+		function serializeDebug($charset_encoding = '')
565 565
 		{
566 566
 			// Tough encoding problem: which internal charset should we assume for debug info?
567 567
 			// It might contain a copy of raw data received from client, ie with unknown encoding,
@@ -573,10 +573,10 @@  discard block
 block discarded – undo
573 573
 			{
574 574
 				$out .= "<!-- SERVER DEBUG INFO (BASE64 ENCODED):\n".base64_encode($this->debug_info)."\n-->\n";
575 575
 			}
576
-			if($GLOBALS['_xmlrpc_debuginfo']!='')
576
+			if ($GLOBALS['_xmlrpc_debuginfo'] != '')
577 577
 			{
578 578
 
579
-				$out .= "<!-- DEBUG INFO:\n" . xmlrpc_encode_entitites(str_replace('--', '_-', $GLOBALS['_xmlrpc_debuginfo']), $GLOBALS['xmlrpc_internalencoding'], $charset_encoding) . "\n-->\n";
579
+				$out .= "<!-- DEBUG INFO:\n".xmlrpc_encode_entitites(str_replace('--', '_-', $GLOBALS['_xmlrpc_debuginfo']), $GLOBALS['xmlrpc_internalencoding'], $charset_encoding)."\n-->\n";
580 580
 				// NB: a better solution MIGHT be to use CDATA, but we need to insert it
581 581
 				// into return payload AFTER the beginning tag
582 582
 				//$out .= "<![CDATA[ DEBUG INFO:\n\n" . str_replace(']]>', ']_]_>', $GLOBALS['_xmlrpc_debuginfo']) . "\n]]>\n";
@@ -590,7 +590,7 @@  discard block
 block discarded – undo
590 590
 		* @return xmlrpcresp the response object (usually not used by caller...)
591 591
 		* @access public
592 592
 		*/
593
-		function service($data=null, $return_payload=false)
593
+		function service($data = null, $return_payload = false)
594 594
 		{
595 595
 			if ($data === null)
596 596
 			{
@@ -603,30 +603,30 @@  discard block
 block discarded – undo
603 603
 			$this->debug_info = '';
604 604
 
605 605
 			// Echo back what we received, before parsing it
606
-			if($this->debug > 1)
606
+			if ($this->debug>1)
607 607
 			{
608
-				$this->debugmsg("+++GOT+++\n" . $data . "\n+++END+++");
608
+				$this->debugmsg("+++GOT+++\n".$data."\n+++END+++");
609 609
 			}
610 610
 
611 611
 			$r = $this->parseRequestHeaders($data, $req_charset, $resp_charset, $resp_encoding);
612 612
 			if (!$r)
613 613
 			{
614
-				$r=$this->parseRequest($data, $req_charset);
614
+				$r = $this->parseRequest($data, $req_charset);
615 615
 			}
616 616
 
617 617
 			// save full body of request into response, for more debugging usages
618 618
 			$r->raw_data = $raw_data;
619 619
 
620
-			if($this->debug > 2 && $GLOBALS['_xmlrpcs_occurred_errors'])
620
+			if ($this->debug>2 && $GLOBALS['_xmlrpcs_occurred_errors'])
621 621
 			{
622
-				$this->debugmsg("+++PROCESSING ERRORS AND WARNINGS+++\n" .
623
-					$GLOBALS['_xmlrpcs_occurred_errors'] . "+++END+++");
622
+				$this->debugmsg("+++PROCESSING ERRORS AND WARNINGS+++\n".
623
+					$GLOBALS['_xmlrpcs_occurred_errors']."+++END+++");
624 624
 			}
625 625
 
626
-			$payload=$this->xml_header($resp_charset);
627
-			if($this->debug > 0)
626
+			$payload = $this->xml_header($resp_charset);
627
+			if ($this->debug>0)
628 628
 			{
629
-				$payload = $payload . $this->serializeDebug($resp_charset);
629
+				$payload = $payload.$this->serializeDebug($resp_charset);
630 630
 			}
631 631
 
632 632
 			// G. Giunta 2006-01-27: do not create response serialization if it has
@@ -635,7 +635,7 @@  discard block
 block discarded – undo
635 635
 			{
636 636
 				$r->serialize($resp_charset);
637 637
 			}
638
-			$payload = $payload . $r->payload;
638
+			$payload = $payload.$r->payload;
639 639
 
640 640
 			if ($return_payload)
641 641
 			{
@@ -644,7 +644,7 @@  discard block
 block discarded – undo
644 644
 
645 645
 			// if we get a warning/error that has output some text before here, then we cannot
646 646
 			// add a new header. We cannot say we are sending xml, either...
647
-			if(!headers_sent())
647
+			if (!headers_sent())
648 648
 			{
649 649
 				header('Content-Type: '.$r->content_type);
650 650
 				// we do not know if client actually told us an accepted charset, but if he did
@@ -655,10 +655,10 @@  discard block
 block discarded – undo
655 655
 				// if we can do it, and we want to do it, and client asked us to,
656 656
 				// and php ini settings do not force it already
657 657
 				$php_no_self_compress = !ini_get('zlib.output_compression') && (ini_get('output_handler') != 'ob_gzhandler');
658
-				if($this->compress_response && function_exists('gzencode') && $resp_encoding != ''
658
+				if ($this->compress_response && function_exists('gzencode') && $resp_encoding != ''
659 659
 					&& $php_no_self_compress)
660 660
 				{
661
-					if(strpos($resp_encoding, 'gzip') !== false)
661
+					if (strpos($resp_encoding, 'gzip') !== false)
662 662
 					{
663 663
 						$payload = gzencode($payload);
664 664
 						header("Content-Encoding: gzip");
@@ -674,9 +674,9 @@  discard block
 block discarded – undo
674 674
 
675 675
 				// do not ouput content-length header if php is compressing output for us:
676 676
 				// it will mess up measurements
677
-				if($php_no_self_compress)
677
+				if ($php_no_self_compress)
678 678
 				{
679
-					header('Content-Length: ' . (int)strlen($payload));
679
+					header('Content-Length: '.(int) strlen($payload));
680 680
 				}
681 681
 			}
682 682
 			else
@@ -699,7 +699,7 @@  discard block
 block discarded – undo
699 699
 		* @param array $sigdoc the array of valid method signatures docs (one string per param, one for return type)
700 700
 		* @access public
701 701
 		*/
702
-		function add_to_map($methodname,$function,$sig=null,$doc=false,$sigdoc=false)
702
+		function add_to_map($methodname, $function, $sig = null, $doc = false, $sigdoc = false)
703 703
 		{
704 704
 			$this->dmap[$methodname] = array(
705 705
 				'function'	=> $function,
@@ -733,47 +733,47 @@  discard block
 block discarded – undo
733 733
 			{
734 734
 				$numParams = count($in);
735 735
 			}
736
-			foreach($sig as $cursig)
736
+			foreach ($sig as $cursig)
737 737
 			{
738
-				if(count($cursig)==$numParams+1)
738
+				if (count($cursig) == $numParams+1)
739 739
 				{
740
-					$itsOK=1;
741
-					for($n=0; $n<$numParams; $n++)
740
+					$itsOK = 1;
741
+					for ($n = 0; $n<$numParams; $n++)
742 742
 					{
743 743
 						if (is_object($in))
744 744
 						{
745
-							$p=$in->getParam($n);
746
-							if($p->kindOf() == 'scalar')
745
+							$p = $in->getParam($n);
746
+							if ($p->kindOf() == 'scalar')
747 747
 							{
748
-								$pt=$p->scalartyp();
748
+								$pt = $p->scalartyp();
749 749
 							}
750 750
 							else
751 751
 							{
752
-								$pt=$p->kindOf();
752
+								$pt = $p->kindOf();
753 753
 							}
754 754
 						}
755 755
 						else
756 756
 						{
757
-							$pt= $in[$n] == 'i4' ? 'int' : strtolower($in[$n]); // dispatch maps never use i4...
757
+							$pt = $in[$n] == 'i4' ? 'int' : strtolower($in[$n]); // dispatch maps never use i4...
758 758
 						}
759 759
 
760 760
 						// param index is $n+1, as first member of sig is return type
761
-						if($pt != $cursig[$n+1] && $cursig[$n+1] != $GLOBALS['xmlrpcValue'])
761
+						if ($pt != $cursig[$n+1] && $cursig[$n+1] != $GLOBALS['xmlrpcValue'])
762 762
 						{
763
-							$itsOK=0;
764
-							$pno=$n+1;
765
-							$wanted=$cursig[$n+1];
766
-							$got=$pt;
763
+							$itsOK = 0;
764
+							$pno = $n+1;
765
+							$wanted = $cursig[$n+1];
766
+							$got = $pt;
767 767
 							break;
768 768
 						}
769 769
 					}
770
-					if($itsOK)
770
+					if ($itsOK)
771 771
 					{
772
-						return array(1,'');
772
+						return array(1, '');
773 773
 					}
774 774
 				}
775 775
 			}
776
-			if(isset($wanted))
776
+			if (isset($wanted))
777 777
 			{
778 778
 				return array(0, "Wanted ${wanted}, got ${got} at param ${pno}");
779 779
 			}
@@ -797,12 +797,12 @@  discard block
 block discarded – undo
797 797
 				error_log('XML-RPC: '.__METHOD__.': cannot parse request headers as $_SERVER is not populated');
798 798
 			}
799 799
 
800
-			if($this->debug > 1)
800
+			if ($this->debug>1)
801 801
 			{
802
-				if(function_exists('getallheaders'))
802
+				if (function_exists('getallheaders'))
803 803
 				{
804 804
 					$this->debugmsg(''); // empty line
805
-					foreach(getallheaders() as $name => $val)
805
+					foreach (getallheaders() as $name => $val)
806 806
 					{
807 807
 						$this->debugmsg("HEADER: $name: $val");
808 808
 					}
@@ -810,7 +810,7 @@  discard block
 block discarded – undo
810 810
 
811 811
 			}
812 812
 
813
-			if(isset($_SERVER['HTTP_CONTENT_ENCODING']))
813
+			if (isset($_SERVER['HTTP_CONTENT_ENCODING']))
814 814
 			{
815 815
 				$content_encoding = str_replace('x-', '', $_SERVER['HTTP_CONTENT_ENCODING']);
816 816
 			}
@@ -820,26 +820,26 @@  discard block
 block discarded – undo
820 820
 			}
821 821
 
822 822
 			// check if request body has been compressed and decompress it
823
-			if($content_encoding != '' && strlen($data))
823
+			if ($content_encoding != '' && strlen($data))
824 824
 			{
825
-				if($content_encoding == 'deflate' || $content_encoding == 'gzip')
825
+				if ($content_encoding == 'deflate' || $content_encoding == 'gzip')
826 826
 				{
827 827
 					// if decoding works, use it. else assume data wasn't gzencoded
828
-					if(function_exists('gzinflate') && in_array($content_encoding, $this->accepted_compression))
828
+					if (function_exists('gzinflate') && in_array($content_encoding, $this->accepted_compression))
829 829
 					{
830
-						if($content_encoding == 'deflate' && $degzdata = @gzuncompress($data))
830
+						if ($content_encoding == 'deflate' && $degzdata = @gzuncompress($data))
831 831
 						{
832 832
 							$data = $degzdata;
833
-							if($this->debug > 1)
833
+							if ($this->debug>1)
834 834
 							{
835
-								$this->debugmsg("\n+++INFLATED REQUEST+++[".strlen($data)." chars]+++\n" . $data . "\n+++END+++");
835
+								$this->debugmsg("\n+++INFLATED REQUEST+++[".strlen($data)." chars]+++\n".$data."\n+++END+++");
836 836
 							}
837 837
 						}
838
-						elseif($content_encoding == 'gzip' && $degzdata = @gzinflate(substr($data, 10)))
838
+						elseif ($content_encoding == 'gzip' && $degzdata = @gzinflate(substr($data, 10)))
839 839
 						{
840 840
 							$data = $degzdata;
841
-							if($this->debug > 1)
842
-								$this->debugmsg("+++INFLATED REQUEST+++[".strlen($data)." chars]+++\n" . $data . "\n+++END+++");
841
+							if ($this->debug>1)
842
+								$this->debugmsg("+++INFLATED REQUEST+++[".strlen($data)." chars]+++\n".$data."\n+++END+++");
843 843
 						}
844 844
 						else
845 845
 						{
@@ -912,7 +912,7 @@  discard block
 block discarded – undo
912 912
 		* @return xmlrpcresp
913 913
 		* @access private
914 914
 		*/
915
-		function parseRequest($data, $req_encoding='')
915
+		function parseRequest($data, $req_encoding = '')
916 916
 		{
917 917
 			// 2005/05/07 commented and moved into caller function code
918 918
 			//if($data=='')
@@ -924,16 +924,16 @@  discard block
 block discarded – undo
924 924
 			// so we do not try to convert them into xml character entities
925 925
 			//$data = xmlrpc_html_entity_xlate($data);
926 926
 
927
-			$GLOBALS['_xh']=array();
928
-			$GLOBALS['_xh']['ac']='';
929
-			$GLOBALS['_xh']['stack']=array();
927
+			$GLOBALS['_xh'] = array();
928
+			$GLOBALS['_xh']['ac'] = '';
929
+			$GLOBALS['_xh']['stack'] = array();
930 930
 			$GLOBALS['_xh']['valuestack'] = array();
931
-			$GLOBALS['_xh']['params']=array();
932
-			$GLOBALS['_xh']['pt']=array();
933
-			$GLOBALS['_xh']['isf']=0;
934
-			$GLOBALS['_xh']['isf_reason']='';
935
-			$GLOBALS['_xh']['method']=false; // so we can check later if we got a methodname or not
936
-			$GLOBALS['_xh']['rt']='';
931
+			$GLOBALS['_xh']['params'] = array();
932
+			$GLOBALS['_xh']['pt'] = array();
933
+			$GLOBALS['_xh']['isf'] = 0;
934
+			$GLOBALS['_xh']['isf_reason'] = '';
935
+			$GLOBALS['_xh']['method'] = false; // so we can check later if we got a methodname or not
936
+			$GLOBALS['_xh']['rt'] = '';
937 937
 
938 938
 			// decompose incoming XML into request structure
939 939
 
@@ -951,7 +951,7 @@  discard block
 block discarded – undo
951 951
 						if (extension_loaded('mbstring')) {
952 952
 							$data = mb_convert_encoding($data, 'UTF-8', $req_encoding);
953 953
 						} else {
954
-							error_log('XML-RPC: ' . __METHOD__ . ': invalid charset encoding of received request: ' . $req_encoding);
954
+							error_log('XML-RPC: '.__METHOD__.': invalid charset encoding of received request: '.$req_encoding);
955 955
 						}
956 956
 					}
957 957
 				}
@@ -980,10 +980,10 @@  discard block
 block discarded – undo
980 980
 				xml_set_element_handler($parser, 'xmlrpc_se', 'xmlrpc_ee');
981 981
 			xml_set_character_data_handler($parser, 'xmlrpc_cd');
982 982
 			xml_set_default_handler($parser, 'xmlrpc_dh');
983
-			if(!xml_parse($parser, $data, 1))
983
+			if (!xml_parse($parser, $data, 1))
984 984
 			{
985 985
 				// return XML error as a faultCode
986
-				$r=new xmlrpcresp(0,
986
+				$r = new xmlrpcresp(0,
987 987
 				$GLOBALS['xmlrpcerrxml']+xml_get_error_code($parser),
988 988
 				sprintf('XML error: %s at line %d, column %d',
989 989
 					xml_error_string(xml_get_error_code($parser)),
@@ -993,9 +993,9 @@  discard block
 block discarded – undo
993 993
 			elseif ($GLOBALS['_xh']['isf'])
994 994
 			{
995 995
 				xml_parser_free($parser);
996
-				$r=new xmlrpcresp(0,
996
+				$r = new xmlrpcresp(0,
997 997
 					$GLOBALS['xmlrpcerr']['invalid_request'],
998
-					$GLOBALS['xmlrpcstr']['invalid_request'] . ' ' . $GLOBALS['_xh']['isf_reason']);
998
+					$GLOBALS['xmlrpcstr']['invalid_request'].' '.$GLOBALS['_xh']['isf_reason']);
999 999
 			}
1000 1000
 			else
1001 1001
 			{
@@ -1006,7 +1006,7 @@  discard block
 block discarded – undo
1006 1006
 				// registered as phpvals) that would mean a useless encode+decode pass
1007 1007
 				if ($this->functions_parameters_type != 'xmlrpcvals' || (isset($this->dmap[$GLOBALS['_xh']['method']]['parameters_type']) && ($this->dmap[$GLOBALS['_xh']['method']]['parameters_type'] == 'phpvals')))
1008 1008
 				{
1009
-					if($this->debug > 1)
1009
+					if ($this->debug>1)
1010 1010
 					{
1011 1011
 						$this->debugmsg("\n+++PARSED+++\n".var_export($GLOBALS['_xh']['params'], true)."\n+++END+++");
1012 1012
 					}
@@ -1015,14 +1015,14 @@  discard block
 block discarded – undo
1015 1015
 				else
1016 1016
 				{
1017 1017
 					// build an xmlrpcmsg object with data parsed from xml
1018
-					$m=new xmlrpcmsg($GLOBALS['_xh']['method']);
1018
+					$m = new xmlrpcmsg($GLOBALS['_xh']['method']);
1019 1019
 					// now add parameters in
1020
-					for($i=0; $i<count($GLOBALS['_xh']['params']); $i++)
1020
+					for ($i = 0; $i<count($GLOBALS['_xh']['params']); $i++)
1021 1021
 					{
1022 1022
 						$m->addParam($GLOBALS['_xh']['params'][$i]);
1023 1023
 					}
1024 1024
 
1025
-					if($this->debug > 1)
1025
+					if ($this->debug>1)
1026 1026
 					{
1027 1027
 						$this->debugmsg("\n+++PARSED+++\n".var_export($m, true)."\n+++END+++");
1028 1028
 					}
@@ -1040,7 +1040,7 @@  discard block
 block discarded – undo
1040 1040
 		* @return xmlrpcresp
1041 1041
 		* @access private
1042 1042
 		*/
1043
-		function execute($m, $params=null, $paramtypes=null)
1043
+		function execute($m, $params = null, $paramtypes = null)
1044 1044
 		{
1045 1045
 			if (is_object($m))
1046 1046
 			{
@@ -1053,7 +1053,7 @@  discard block
 block discarded – undo
1053 1053
 			$sysCall = $this->allow_system_funcs && (strpos($methName, "system.") === 0);
1054 1054
 			$dmap = $sysCall ? $GLOBALS['_xmlrpcs_dmap'] : $this->dmap;
1055 1055
 
1056
-			if(!isset($dmap[$methName]['function']))
1056
+			if (!isset($dmap[$methName]['function']))
1057 1057
 			{
1058 1058
 				// No such method
1059 1059
 				return new xmlrpcresp(0,
@@ -1062,7 +1062,7 @@  discard block
 block discarded – undo
1062 1062
 			}
1063 1063
 
1064 1064
 			// Check signature
1065
-			if(isset($dmap[$methName]['signature']))
1065
+			if (isset($dmap[$methName]['signature']))
1066 1066
 			{
1067 1067
 				$sig = $dmap[$methName]['signature'];
1068 1068
 				if (is_object($m))
@@ -1073,37 +1073,37 @@  discard block
 block discarded – undo
1073 1073
 				{
1074 1074
 					list($ok, $errstr) = $this->verifySignature($paramtypes, $sig);
1075 1075
 				}
1076
-				if(!$ok)
1076
+				if (!$ok)
1077 1077
 				{
1078 1078
 					// Didn't match.
1079 1079
 					return new xmlrpcresp(
1080 1080
 						0,
1081 1081
 						$GLOBALS['xmlrpcerr']['incorrect_params'],
1082
-						$GLOBALS['xmlrpcstr']['incorrect_params'] . ": ${errstr}"
1082
+						$GLOBALS['xmlrpcstr']['incorrect_params'].": ${errstr}"
1083 1083
 					);
1084 1084
 				}
1085 1085
 			}
1086 1086
 
1087 1087
 			$func = $dmap[$methName]['function'];
1088 1088
 			// let the 'class::function' syntax be accepted in dispatch maps
1089
-			if(is_string($func) && strpos($func, '::'))
1089
+			if (is_string($func) && strpos($func, '::'))
1090 1090
 			{
1091 1091
 				$func = explode('::', $func);
1092 1092
 			}
1093 1093
 			// verify that function to be invoked is in fact callable
1094
-			if(!is_callable($func))
1094
+			if (!is_callable($func))
1095 1095
 			{
1096 1096
 				error_log("XML-RPC: ".__METHOD__.": function $func registered as method handler is not callable");
1097 1097
 				return new xmlrpcresp(
1098 1098
 					0,
1099 1099
 					$GLOBALS['xmlrpcerr']['server_error'],
1100
-					$GLOBALS['xmlrpcstr']['server_error'] . ": no function matches method"
1100
+					$GLOBALS['xmlrpcstr']['server_error'].": no function matches method"
1101 1101
 				);
1102 1102
 			}
1103 1103
 
1104 1104
 			// If debug level is 3, we should catch all errors generated during
1105 1105
 			// processing of user function, and log them as part of response
1106
-			if($this->debug > 2)
1106
+			if ($this->debug>2)
1107 1107
 			{
1108 1108
 				$GLOBALS['_xmlrpcs_prev_ehandler'] = set_error_handler('_xmlrpcs_errorHandler');
1109 1109
 			}
@@ -1132,7 +1132,7 @@  discard block
 block discarded – undo
1132 1132
 							$r = new xmlrpcresp(
1133 1133
 								0,
1134 1134
 								$GLOBALS['xmlrpcerr']['server_error'],
1135
-								$GLOBALS['xmlrpcstr']['server_error'] . ": function does not return xmlrpcresp object"
1135
+								$GLOBALS['xmlrpcstr']['server_error'].": function does not return xmlrpcresp object"
1136 1136
 							);
1137 1137
 						}
1138 1138
 					}
@@ -1140,7 +1140,7 @@  discard block
 block discarded – undo
1140 1140
 				else
1141 1141
 				{
1142 1142
 					// call a 'plain php' function
1143
-					if($sysCall)
1143
+					if ($sysCall)
1144 1144
 					{
1145 1145
 						array_unshift($params, $this);
1146 1146
 						$r = call_user_func_array($func, $params);
@@ -1155,7 +1155,7 @@  discard block
 block discarded – undo
1155 1155
 							// an eror response
1156 1156
 							if (is_array($r) && array_key_exists('faultCode', $r) && array_key_exists('faultString', $r))
1157 1157
 							{
1158
-								$r = new xmlrpcresp(0, (integer)$r['faultCode'], (string)$r['faultString']);
1158
+								$r = new xmlrpcresp(0, (integer) $r['faultCode'], (string) $r['faultString']);
1159 1159
 							}
1160 1160
 							else
1161 1161
 							{
@@ -1178,11 +1178,11 @@  discard block
 block discarded – undo
1178 1178
 					}
1179 1179
 				}
1180 1180
 			}
1181
-			catch(Exception $e)
1181
+			catch (Exception $e)
1182 1182
 			{
1183 1183
 				// (barring errors in the lib) an uncatched exception happened
1184 1184
 				// in the called function, we wrap it in a proper error-response
1185
-				switch($this->exception_handling)
1185
+				switch ($this->exception_handling)
1186 1186
 				{
1187 1187
 					case 2:
1188 1188
 						throw $e;
@@ -1194,11 +1194,11 @@  discard block
 block discarded – undo
1194 1194
 						$r = new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['server_error'], $GLOBALS['xmlrpcstr']['server_error']);
1195 1195
 				}
1196 1196
 			}
1197
-			if($this->debug > 2)
1197
+			if ($this->debug>2)
1198 1198
 			{
1199 1199
 				// note: restore the error handler we found before calling the
1200 1200
 				// user func, even if it has been changed inside the func itself
1201
-				if($GLOBALS['_xmlrpcs_prev_ehandler'])
1201
+				if ($GLOBALS['_xmlrpcs_prev_ehandler'])
1202 1202
 				{
1203 1203
 					set_error_handler($GLOBALS['_xmlrpcs_prev_ehandler']);
1204 1204
 				}
@@ -1223,15 +1223,15 @@  discard block
 block discarded – undo
1223 1223
 		/**
1224 1224
 		* @access private
1225 1225
 		*/
1226
-		function xml_header($charset_encoding='')
1226
+		function xml_header($charset_encoding = '')
1227 1227
 		{
1228 1228
 			if ($charset_encoding != '')
1229 1229
 			{
1230
-				return "<?xml version=\"1.0\" encoding=\"$charset_encoding\"?" . ">\n";
1230
+				return "<?xml version=\"1.0\" encoding=\"$charset_encoding\"?".">\n";
1231 1231
 			}
1232 1232
 			else
1233 1233
 			{
1234
-				return "<?xml version=\"1.0\"?" . ">\n";
1234
+				return "<?xml version=\"1.0\"?".">\n";
1235 1235
 			}
1236 1236
 		}
1237 1237
 
@@ -1241,7 +1241,7 @@  discard block
 block discarded – undo
1241 1241
 		*/
1242 1242
 		function echoInput()
1243 1243
 		{
1244
-			$r=new xmlrpcresp(new xmlrpcval( "'Aha said I: '" . $GLOBALS['HTTP_RAW_POST_DATA'], 'string'));
1244
+			$r = new xmlrpcresp(new xmlrpcval("'Aha said I: '".$GLOBALS['HTTP_RAW_POST_DATA'], 'string'));
1245 1245
 			print $r->serialize();
1246 1246
 		}
1247 1247
 	}
Please login to merge, or discard this patch.
Braces   +57 added lines, -88 removed lines patch added patch discarded remove patch
@@ -106,16 +106,14 @@  discard block
 block discarded – undo
106 106
 		{
107 107
 			$methName=$m->getParam(0);
108 108
 			$methName=$methName->scalarval();
109
-		}
110
-		else
109
+		} else
111 110
 		{
112 111
 			$methName=$m;
113 112
 		}
114 113
 		if(strpos($methName, "system.") === 0)
115 114
 		{
116 115
 			$dmap=$GLOBALS['_xmlrpcs_dmap']; //$sysCall=1;
117
-		}
118
-		else
116
+		} else
119 117
 		{
120 118
 			$dmap=$server->dmap; //$sysCall=0;
121 119
 		}
@@ -134,15 +132,13 @@  discard block
 block discarded – undo
134 132
 					$sigs[]=new xmlrpcval($cursig, 'array');
135 133
 				}
136 134
 				$r=new xmlrpcresp(new xmlrpcval($sigs, 'array'));
137
-			}
138
-			else
135
+			} else
139 136
 			{
140 137
 				// NB: according to the official docs, we should be returning a
141 138
 				// "none-array" here, which means not-an-array
142 139
 				$r=new xmlrpcresp(new xmlrpcval('undef', 'string'));
143 140
 			}
144
-		}
145
-		else
141
+		} else
146 142
 		{
147 143
 			$r=new xmlrpcresp(0,$GLOBALS['xmlrpcerr']['introspect_unknown'], $GLOBALS['xmlrpcstr']['introspect_unknown']);
148 144
 		}
@@ -159,16 +155,14 @@  discard block
 block discarded – undo
159 155
 		{
160 156
 			$methName=$m->getParam(0);
161 157
 			$methName=$methName->scalarval();
162
-		}
163
-		else
158
+		} else
164 159
 		{
165 160
 			$methName=$m;
166 161
 		}
167 162
 		if(strpos($methName, "system.") === 0)
168 163
 		{
169 164
 			$dmap=$GLOBALS['_xmlrpcs_dmap']; //$sysCall=1;
170
-		}
171
-		else
165
+		} else
172 166
 		{
173 167
 			$dmap=$server->dmap; //$sysCall=0;
174 168
 		}
@@ -177,13 +171,11 @@  discard block
 block discarded – undo
177 171
 			if(isset($dmap[$methName]['docstring']))
178 172
 			{
179 173
 				$r=new xmlrpcresp(new xmlrpcval($dmap[$methName]['docstring']), 'string');
180
-			}
181
-			else
174
+			} else
182 175
 			{
183 176
 				$r=new xmlrpcresp(new xmlrpcval('', 'string'));
184 177
 			}
185
-		}
186
-		else
178
+		} else
187 179
 		{
188 180
 			$r=new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['introspect_unknown'], $GLOBALS['xmlrpcstr']['introspect_unknown']);
189 181
 		}
@@ -295,8 +287,9 @@  discard block
 block discarded – undo
295 287
 		// base64 or datetime values, but they will be listed as strings here...
296 288
 		//$numParams = count($call['params']);
297 289
 		$pt = array();
298
-		foreach($call['params'] as $val)
299
-			$pt[] = php_2_xmlrpc_type(gettype($val));
290
+		foreach($call['params'] as $val) {
291
+					$pt[] = php_2_xmlrpc_type(gettype($val));
292
+		}
300 293
 
301 294
 		$result = $server->execute($call['methodName'], $call['params'], $pt);
302 295
 
@@ -321,8 +314,7 @@  discard block
 block discarded – undo
321 314
 				$call = $calls->arraymem($i);
322 315
 				$result[$i] = _xmlrpcs_multicall_do_call($server, $call);
323 316
 			}
324
-		}
325
-		else
317
+		} else
326 318
 		{
327 319
 			$numCalls=count($m);
328 320
 			for($i = 0; $i < $numCalls; $i++)
@@ -377,8 +369,9 @@  discard block
 block discarded – undo
377 369
 	function _xmlrpcs_errorHandler($errcode, $errstring, $filename=null, $lineno=null, $context=null)
378 370
 	{
379 371
 		// obey the @ protocol
380
-		if (error_reporting() == 0)
381
-			return;
372
+		if (error_reporting() == 0) {
373
+					return;
374
+		}
382 375
 
383 376
 		//if($errcode != E_NOTICE && $errcode != E_WARNING && $errcode != E_USER_NOTICE && $errcode != E_USER_WARNING)
384 377
 		if($errcode != E_STRICT)
@@ -395,8 +388,7 @@  discard block
 block discarded – undo
395 388
 			{
396 389
 				error_log($errstring);
397 390
 			}
398
-		}
399
-		else
391
+		} else
400 392
 		{
401 393
 			// Pass control on to previous error handler, trying to avoid loops...
402 394
 			if($GLOBALS['_xmlrpcs_prev_ehandler'] != '_xmlrpcs_errorHandler')
@@ -406,8 +398,7 @@  discard block
 block discarded – undo
406 398
 				{
407 399
 					// the following works both with static class methods and plain object methods as error handler
408 400
 					call_user_func_array($GLOBALS['_xmlrpcs_prev_ehandler'], array($errcode, $errstring, $filename, $lineno, $context));
409
-				}
410
-				else
401
+				} else
411 402
 				{
412 403
 					$GLOBALS['_xmlrpcs_prev_ehandler']($errcode, $errstring, $filename, $lineno, $context);
413 404
 				}
@@ -663,8 +654,7 @@  discard block
 block discarded – undo
663 654
 						$payload = gzencode($payload);
664 655
 						header("Content-Encoding: gzip");
665 656
 						header("Vary: Accept-Encoding");
666
-					}
667
-					elseif (strpos($resp_encoding, 'deflate') !== false)
657
+					} elseif (strpos($resp_encoding, 'deflate') !== false)
668 658
 					{
669 659
 						$payload = gzcompress($payload);
670 660
 						header("Content-Encoding: deflate");
@@ -678,8 +668,7 @@  discard block
 block discarded – undo
678 668
 				{
679 669
 					header('Content-Length: ' . (int)strlen($payload));
680 670
 				}
681
-			}
682
-			else
671
+			} else
683 672
 			{
684 673
 				error_log('XML-RPC: '.__METHOD__.': http headers already sent before response is fully generated. Check for php warning or error messages');
685 674
 			}
@@ -728,8 +717,7 @@  discard block
 block discarded – undo
728 717
 			if (is_object($in))
729 718
 			{
730 719
 				$numParams = $in->getNumParams();
731
-			}
732
-			else
720
+			} else
733 721
 			{
734 722
 				$numParams = count($in);
735 723
 			}
@@ -746,13 +734,11 @@  discard block
 block discarded – undo
746 734
 							if($p->kindOf() == 'scalar')
747 735
 							{
748 736
 								$pt=$p->scalartyp();
749
-							}
750
-							else
737
+							} else
751 738
 							{
752 739
 								$pt=$p->kindOf();
753 740
 							}
754
-						}
755
-						else
741
+						} else
756 742
 						{
757 743
 							$pt= $in[$n] == 'i4' ? 'int' : strtolower($in[$n]); // dispatch maps never use i4...
758 744
 						}
@@ -813,8 +799,7 @@  discard block
 block discarded – undo
813 799
 			if(isset($_SERVER['HTTP_CONTENT_ENCODING']))
814 800
 			{
815 801
 				$content_encoding = str_replace('x-', '', $_SERVER['HTTP_CONTENT_ENCODING']);
816
-			}
817
-			else
802
+			} else
818 803
 			{
819 804
 				$content_encoding = '';
820 805
 			}
@@ -834,20 +819,18 @@  discard block
 block discarded – undo
834 819
 							{
835 820
 								$this->debugmsg("\n+++INFLATED REQUEST+++[".strlen($data)." chars]+++\n" . $data . "\n+++END+++");
836 821
 							}
837
-						}
838
-						elseif($content_encoding == 'gzip' && $degzdata = @gzinflate(substr($data, 10)))
822
+						} elseif($content_encoding == 'gzip' && $degzdata = @gzinflate(substr($data, 10)))
839 823
 						{
840 824
 							$data = $degzdata;
841
-							if($this->debug > 1)
842
-								$this->debugmsg("+++INFLATED REQUEST+++[".strlen($data)." chars]+++\n" . $data . "\n+++END+++");
843
-						}
844
-						else
825
+							if($this->debug > 1) {
826
+															$this->debugmsg("+++INFLATED REQUEST+++[".strlen($data)." chars]+++\n" . $data . "\n+++END+++");
827
+							}
828
+						} else
845 829
 						{
846 830
 							$r = new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['server_decompress_fail'], $GLOBALS['xmlrpcstr']['server_decompress_fail']);
847 831
 							return $r;
848 832
 						}
849
-					}
850
-					else
833
+					} else
851 834
 					{
852 835
 						//error_log('The server sent deflated data. Your php install must have the Zlib extension compiled in to support this.');
853 836
 						$r = new xmlrpcresp(0, $GLOBALS['xmlrpcerr']['server_cannot_decompress'], $GLOBALS['xmlrpcstr']['server_cannot_decompress']);
@@ -871,18 +854,19 @@  discard block
 block discarded – undo
871 854
 					$known_charsets = array($GLOBALS['xmlrpc_internalencoding'], 'UTF-8', 'ISO-8859-1', 'US-ASCII');
872 855
 					foreach ($known_charsets as $charset)
873 856
 					{
874
-						foreach ($client_accepted_charsets as $accepted)
875
-							if (strpos($accepted, $charset) === 0)
857
+						foreach ($client_accepted_charsets as $accepted) {
858
+													if (strpos($accepted, $charset) === 0)
876 859
 							{
877 860
 								$resp_encoding = $charset;
861
+						}
878 862
 								break;
879 863
 							}
880
-						if ($resp_encoding)
881
-							break;
864
+						if ($resp_encoding) {
865
+													break;
866
+						}
882 867
 					}
883 868
 				}
884
-			}
885
-			else
869
+			} else
886 870
 			{
887 871
 				$resp_encoding = $this->response_charset_encoding;
888 872
 			}
@@ -890,8 +874,7 @@  discard block
 block discarded – undo
890 874
 			if (isset($_SERVER['HTTP_ACCEPT_ENCODING']))
891 875
 			{
892 876
 				$resp_compression = $_SERVER['HTTP_ACCEPT_ENCODING'];
893
-			}
894
-			else
877
+			} else
895 878
 			{
896 879
 				$resp_compression = '';
897 880
 			}
@@ -968,16 +951,16 @@  discard block
 block discarded – undo
968 951
 			if (!in_array($GLOBALS['xmlrpc_internalencoding'], array('UTF-8', 'ISO-8859-1', 'US-ASCII')))
969 952
 			{
970 953
 				xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, 'UTF-8');
971
-			}
972
-			else
954
+			} else
973 955
 			{
974 956
 				xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, $GLOBALS['xmlrpc_internalencoding']);
975 957
 			}
976 958
 
977
-			if ($this->functions_parameters_type != 'xmlrpcvals')
978
-				xml_set_element_handler($parser, 'xmlrpc_se', 'xmlrpc_ee_fast');
979
-			else
980
-				xml_set_element_handler($parser, 'xmlrpc_se', 'xmlrpc_ee');
959
+			if ($this->functions_parameters_type != 'xmlrpcvals') {
960
+							xml_set_element_handler($parser, 'xmlrpc_se', 'xmlrpc_ee_fast');
961
+			} else {
962
+							xml_set_element_handler($parser, 'xmlrpc_se', 'xmlrpc_ee');
963
+			}
981 964
 			xml_set_character_data_handler($parser, 'xmlrpc_cd');
982 965
 			xml_set_default_handler($parser, 'xmlrpc_dh');
983 966
 			if(!xml_parse($parser, $data, 1))
@@ -989,15 +972,13 @@  discard block
 block discarded – undo
989 972
 					xml_error_string(xml_get_error_code($parser)),
990 973
 					xml_get_current_line_number($parser), xml_get_current_column_number($parser)));
991 974
 				xml_parser_free($parser);
992
-			}
993
-			elseif ($GLOBALS['_xh']['isf'])
975
+			} elseif ($GLOBALS['_xh']['isf'])
994 976
 			{
995 977
 				xml_parser_free($parser);
996 978
 				$r=new xmlrpcresp(0,
997 979
 					$GLOBALS['xmlrpcerr']['invalid_request'],
998 980
 					$GLOBALS['xmlrpcstr']['invalid_request'] . ' ' . $GLOBALS['_xh']['isf_reason']);
999
-			}
1000
-			else
981
+			} else
1001 982
 			{
1002 983
 				xml_parser_free($parser);
1003 984
 				// small layering violation in favor of speed and memory usage:
@@ -1011,8 +992,7 @@  discard block
 block discarded – undo
1011 992
 						$this->debugmsg("\n+++PARSED+++\n".var_export($GLOBALS['_xh']['params'], true)."\n+++END+++");
1012 993
 					}
1013 994
 					$r = $this->execute($GLOBALS['_xh']['method'], $GLOBALS['_xh']['params'], $GLOBALS['_xh']['pt']);
1014
-				}
1015
-				else
995
+				} else
1016 996
 				{
1017 997
 					// build an xmlrpcmsg object with data parsed from xml
1018 998
 					$m=new xmlrpcmsg($GLOBALS['_xh']['method']);
@@ -1045,8 +1025,7 @@  discard block
 block discarded – undo
1045 1025
 			if (is_object($m))
1046 1026
 			{
1047 1027
 				$methName = $m->method();
1048
-			}
1049
-			else
1028
+			} else
1050 1029
 			{
1051 1030
 				$methName = $m;
1052 1031
 			}
@@ -1068,8 +1047,7 @@  discard block
 block discarded – undo
1068 1047
 				if (is_object($m))
1069 1048
 				{
1070 1049
 					list($ok, $errstr) = $this->verifySignature($m, $sig);
1071
-				}
1072
-				else
1050
+				} else
1073 1051
 				{
1074 1052
 					list($ok, $errstr) = $this->verifySignature($paramtypes, $sig);
1075 1053
 				}
@@ -1115,8 +1093,7 @@  discard block
 block discarded – undo
1115 1093
 					if ($sysCall)
1116 1094
 					{
1117 1095
 						$r = call_user_func($func, $this, $m);
1118
-					}
1119
-					else
1096
+					} else
1120 1097
 					{
1121 1098
 						$r = call_user_func($func, $m);
1122 1099
 					}
@@ -1126,8 +1103,7 @@  discard block
 block discarded – undo
1126 1103
 						if (is_a($r, 'xmlrpcval'))
1127 1104
 						{
1128 1105
 							$r = new xmlrpcresp($r);
1129
-						}
1130
-						else
1106
+						} else
1131 1107
 						{
1132 1108
 							$r = new xmlrpcresp(
1133 1109
 								0,
@@ -1136,16 +1112,14 @@  discard block
 block discarded – undo
1136 1112
 							);
1137 1113
 						}
1138 1114
 					}
1139
-				}
1140
-				else
1115
+				} else
1141 1116
 				{
1142 1117
 					// call a 'plain php' function
1143 1118
 					if($sysCall)
1144 1119
 					{
1145 1120
 						array_unshift($params, $this);
1146 1121
 						$r = call_user_func_array($func, $params);
1147
-					}
1148
-					else
1122
+					} else
1149 1123
 					{
1150 1124
 						// 3rd API convention for method-handling functions: EPI-style
1151 1125
 						if ($this->functions_parameters_type == 'epivals')
@@ -1156,15 +1130,13 @@  discard block
 block discarded – undo
1156 1130
 							if (is_array($r) && array_key_exists('faultCode', $r) && array_key_exists('faultString', $r))
1157 1131
 							{
1158 1132
 								$r = new xmlrpcresp(0, (integer)$r['faultCode'], (string)$r['faultString']);
1159
-							}
1160
-							else
1133
+							} else
1161 1134
 							{
1162 1135
 								// functions using EPI api should NOT return resp objects,
1163 1136
 								// so make sure we encode the return type correctly
1164 1137
 								$r = new xmlrpcresp(php_xmlrpc_encode($r, array('extension_api')));
1165 1138
 							}
1166
-						}
1167
-						else
1139
+						} else
1168 1140
 						{
1169 1141
 							$r = call_user_func_array($func, $params);
1170 1142
 						}
@@ -1177,8 +1149,7 @@  discard block
 block discarded – undo
1177 1149
 						$r = new xmlrpcresp(php_xmlrpc_encode($r, $this->phpvals_encoding_options));
1178 1150
 					}
1179 1151
 				}
1180
-			}
1181
-			catch(Exception $e)
1152
+			} catch(Exception $e)
1182 1153
 			{
1183 1154
 				// (barring errors in the lib) an uncatched exception happened
1184 1155
 				// in the called function, we wrap it in a proper error-response
@@ -1201,8 +1172,7 @@  discard block
 block discarded – undo
1201 1172
 				if($GLOBALS['_xmlrpcs_prev_ehandler'])
1202 1173
 				{
1203 1174
 					set_error_handler($GLOBALS['_xmlrpcs_prev_ehandler']);
1204
-				}
1205
-				else
1175
+				} else
1206 1176
 				{
1207 1177
 					restore_error_handler();
1208 1178
 				}
@@ -1228,8 +1198,7 @@  discard block
 block discarded – undo
1228 1198
 			if ($charset_encoding != '')
1229 1199
 			{
1230 1200
 				return "<?xml version=\"1.0\" encoding=\"$charset_encoding\"?" . ">\n";
1231
-			}
1232
-			else
1201
+			} else
1233 1202
 			{
1234 1203
 				return "<?xml version=\"1.0\"?" . ">\n";
1235 1204
 			}
Please login to merge, or discard this patch.