* Generate stubs to transparently access xmlrpc methods as php functions and viceversa\r
*\r
* @author Gaetano Giunta\r
- * @copyright (C) 2006-2013 G. Giunta\r
+ * @copyright (C) 2006-2014 G. Giunta\r
* @license code licensed under the BSD License: http://phpxmlrpc.sourceforge.net/license.txt\r
*\r
* @todo separate introspection from code generation for func-2-method wrapping\r
* carried out by the lib, while datetime vals are passed around as strings)\r
*\r
* Known limitations:\r
- * - requires PHP 5.0.3 +\r
* - only works for user-defined functions, not for PHP internal functions\r
* (reflection does not support retrieving number/type of params for those)\r
* - functions returning php objects will generate special xmlrpc responses:\r
$decode_php_objects = isset($extra_options['decode_php_objs']) ? (bool)$extra_options['decode_php_objs'] : false;\r
$catch_warnings = isset($extra_options['suppress_warnings']) && $extra_options['suppress_warnings'] ? '@' : '';\r
\r
- if(version_compare(phpversion(), '5.0.3') == -1)\r
+ $exists = false;\r
+ if (is_string($funcname) && strpos($funcname, '::') !== false)\r
{\r
- // up to php 5.0.3 some useful reflection methods were missing\r
- error_log('XML-RPC: cannot not wrap php functions unless running php version bigger than 5.0.3');\r
- return false;\r
+ $funcname = explode('::', $funcname);\r
+ }\r
+ if(is_array($funcname))\r
+ {\r
+ if(count($funcname) < 2 || (!is_string($funcname[0]) && !is_object($funcname[0])))\r
+ {\r
+ error_log('XML-RPC: syntax for function to be wrapped is wrong');\r
+ return false;\r
+ }\r
+ if(is_string($funcname[0]))\r
+ {\r
+ $plainfuncname = implode('::', $funcname);\r
+ }\r
+ elseif(is_object($funcname[0]))\r
+ {\r
+ $plainfuncname = get_class($funcname[0]) . '->' . $funcname[1];\r
+ }\r
+ $exists = method_exists($funcname[0], $funcname[1]);\r
+ }\r
+ else\r
+ {\r
+ $plainfuncname = $funcname;\r
+ $exists = function_exists($funcname);\r
}\r
-\r
- $exists = false;\r
- if (is_string($funcname) && strpos($funcname, '::') !== false)\r
- {\r
- $funcname = explode('::', $funcname);\r
- }\r
- if(is_array($funcname))\r
- {\r
- if(count($funcname) < 2 || (!is_string($funcname[0]) && !is_object($funcname[0])))\r
- {\r
- error_log('XML-RPC: syntax for function to be wrapped is wrong');\r
- return false;\r
- }\r
- if(is_string($funcname[0]))\r
- {\r
- $plainfuncname = implode('::', $funcname);\r
- }\r
- elseif(is_object($funcname[0]))\r
- {\r
- $plainfuncname = get_class($funcname[0]) . '->' . $funcname[1];\r
- }\r
- $exists = method_exists($funcname[0], $funcname[1]);\r
- if (!$exists && version_compare(phpversion(), '5.1') < 0)\r
- {\r
- // workaround for php 5.0: static class methods are not seen by method_exists\r
- $exists = is_callable( $funcname );\r
- }\r
- }\r
- else\r
- {\r
- $plainfuncname = $funcname;\r
- $exists = function_exists($funcname);\r
- }\r
\r
if(!$exists)\r
{\r
{\r
if(is_array($funcname))\r
{\r
- if(is_string($funcname[0]))\r
- $xmlrpcfuncname = "{$prefix}_".implode('_', $funcname);\r
- else\r
- $xmlrpcfuncname = "{$prefix}_".get_class($funcname[0]) . '_' . $funcname[1];\r
+ if(is_string($funcname[0]))\r
+ $xmlrpcfuncname = "{$prefix}_".implode('_', $funcname);\r
+ else\r
+ $xmlrpcfuncname = "{$prefix}_".get_class($funcname[0]) . '_' . $funcname[1];\r
}\r
else\r
{\r
// start to introspect PHP code\r
if(is_array($funcname))\r
{\r
- $func = new ReflectionMethod($funcname[0], $funcname[1]);\r
- if($func->isPrivate())\r
- {\r
- error_log('XML-RPC: method to be wrapped is private: '.$plainfuncname);\r
- return false;\r
- }\r
- if($func->isProtected())\r
- {\r
- error_log('XML-RPC: method to be wrapped is protected: '.$plainfuncname);\r
- return false;\r
- }\r
- if($func->isConstructor())\r
- {\r
- error_log('XML-RPC: method to be wrapped is the constructor: '.$plainfuncname);\r
- return false;\r
- }\r
- // php 503 always says isdestructor = true...\r
- if( version_compare(phpversion(), '5.0.3') != 0 && $func->isDestructor())\r
- {\r
- error_log('XML-RPC: method to be wrapped is the destructor: '.$plainfuncname);\r
- return false;\r
- }\r
- if($func->isAbstract())\r
- {\r
- error_log('XML-RPC: method to be wrapped is abstract: '.$plainfuncname);\r
- return false;\r
- }\r
- /// @todo add more checks for static vs. nonstatic?\r
- }\r
+ $func = new ReflectionMethod($funcname[0], $funcname[1]);\r
+ if($func->isPrivate())\r
+ {\r
+ error_log('XML-RPC: method to be wrapped is private: '.$plainfuncname);\r
+ return false;\r
+ }\r
+ if($func->isProtected())\r
+ {\r
+ error_log('XML-RPC: method to be wrapped is protected: '.$plainfuncname);\r
+ return false;\r
+ }\r
+ if($func->isConstructor())\r
+ {\r
+ error_log('XML-RPC: method to be wrapped is the constructor: '.$plainfuncname);\r
+ return false;\r
+ }\r
+ if($func->isDestructor())\r
+ {\r
+ error_log('XML-RPC: method to be wrapped is the destructor: '.$plainfuncname);\r
+ return false;\r
+ }\r
+ if($func->isAbstract())\r
+ {\r
+ error_log('XML-RPC: method to be wrapped is abstract: '.$plainfuncname);\r
+ return false;\r
+ }\r
+ /// @todo add more checks for static vs. nonstatic?\r
+ }\r
else\r
{\r
- $func = new ReflectionFunction($funcname);\r
- }\r
+ $func = new ReflectionFunction($funcname);\r
+ }\r
if($func->isInternal())\r
{\r
// Note: from PHP 5.1.0 onward, we will possibly be able to use invokeargs\r
\r
$innercode .= "\$np = false;\n";\r
// since there are no closures in php, if we are given an object instance,\r
- // we store a pointer to it in a global var...\r
+ // we store a pointer to it in a global var...\r
if ( is_array($funcname) && is_object($funcname[0]) )\r
{\r
- $GLOBALS['xmlrpcWPFObjHolder'][$xmlrpcfuncname] =& $funcname[0];\r
- $innercode .= "\$obj =& \$GLOBALS['xmlrpcWPFObjHolder']['$xmlrpcfuncname'];\n";\r
- $realfuncname = '$obj->'.$funcname[1];\r
+ $GLOBALS['xmlrpcWPFObjHolder'][$xmlrpcfuncname] =& $funcname[0];\r
+ $innercode .= "\$obj =& \$GLOBALS['xmlrpcWPFObjHolder']['$xmlrpcfuncname'];\n";\r
+ $realfuncname = '$obj->'.$funcname[1];\r
}\r
else\r
{\r
- $realfuncname = $plainfuncname;\r
- }\r
+ $realfuncname = $plainfuncname;\r
+ }\r
foreach($parsvariations as $pars)\r
{\r
$innercode .= "if (\$paramcount == " . count($pars) . ") \$retval = {$catch_warnings}$realfuncname(" . implode(',', $pars) . "); else\n";\r
}\r
}\r
\r
- /**\r
- * Given a user-defined PHP class or php object, map its methods onto a list of\r
+ /**\r
+ * Given a user-defined PHP class or php object, map its methods onto a list of\r
* PHP 'wrapper' functions that can be exposed as xmlrpc methods from an xmlrpc_server\r
* object and called from remote clients (as well as their corresponding signature info).\r
*\r
- * @param mixed $classname the name of the class whose methods are to be exposed as xmlrpc methods, or an object instance of that class\r
- * @param array $extra_options see the docs for wrap_php_method for more options\r
- * 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\r
- * @return array or false on failure\r
- *\r
- * @todo get_class_methods will return both static and non-static methods.\r
- * we have to differentiate the action, depending on wheter we recived a class name or object\r
- */\r
- function wrap_php_class($classname, $extra_options=array())\r
- {\r
+ * @param mixed $classname the name of the class whose methods are to be exposed as xmlrpc methods, or an object instance of that class\r
+ * @param array $extra_options see the docs for wrap_php_method for more options\r
+ * 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\r
+ * @return array or false on failure\r
+ *\r
+ * @todo get_class_methods will return both static and non-static methods.\r
+ * we have to differentiate the action, depending on whether we received a class name or object\r
+ */\r
+ function wrap_php_class($classname, $extra_options=array())\r
+ {\r
$methodfilter = isset($extra_options['method_filter']) ? $extra_options['method_filter'] : '';\r
$methodtype = isset($extra_options['method_type']) ? $extra_options['method_type'] : 'auto';\r
\r
- if(version_compare(phpversion(), '5.0.3') == -1)\r
- {\r
- // up to php 5.0.3 some useful reflection methods were missing\r
- error_log('XML-RPC: cannot not wrap php functions unless running php version bigger than 5.0.3');\r
- return false;\r
- }\r
-\r
- $result = array();\r
+ $result = array();\r
$mlist = get_class_methods($classname);\r
foreach($mlist as $mname)\r
{\r
- if ($methodfilter == '' || preg_match($methodfilter, $mname))\r
- {\r
- // echo $mlist."\n";\r
- $func = new ReflectionMethod($classname, $mname);\r
- if(!$func->isPrivate() && !$func->isProtected() && !$func->isConstructor() && !$func->isDestructor() && !$func->isAbstract())\r
- {\r
- if(($func->isStatic && ($methodtype == 'all' || $methodtype == 'static' || ($methodtype == 'auto' && is_string($classname)))) ||\r
- (!$func->isStatic && ($methodtype == 'all' || $methodtype == 'nonstatic' || ($methodtype == 'auto' && is_object($classname)))))\r
- {\r
- $methodwrap = wrap_php_function(array($classname, $mname), '', $extra_options);\r
- if ( $methodwrap )\r
- {\r
- $result[$methodwrap['function']] = $methodwrap['function'];\r
- }\r
- }\r
- }\r
+ if ($methodfilter == '' || preg_match($methodfilter, $mname))\r
+ {\r
+ // echo $mlist."\n";\r
+ $func = new ReflectionMethod($classname, $mname);\r
+ if(!$func->isPrivate() && !$func->isProtected() && !$func->isConstructor() && !$func->isDestructor() && !$func->isAbstract())\r
+ {\r
+ if(($func->isStatic && ($methodtype == 'all' || $methodtype == 'static' || ($methodtype == 'auto' && is_string($classname)))) ||\r
+ (!$func->isStatic && ($methodtype == 'all' || $methodtype == 'nonstatic' || ($methodtype == 'auto' && is_object($classname)))))\r
+ {\r
+ $methodwrap = wrap_php_function(array($classname, $mname), '', $extra_options);\r
+ if ( $methodwrap )\r
+ {\r
+ $result[$methodwrap['function']] = $methodwrap['function'];\r
+ }\r
+ }\r
+ }\r
}\r
}\r
- return $result;\r
- }\r
+ return $result;\r
+ }\r
\r
/**\r
* Given an xmlrpc client and a method name, register a php wrapper function\r
* that will call it and return results using native php types for both\r
* params and results. The generated php function will return an xmlrpcresp\r
- * oject for failed xmlrpc calls\r
+ * object for failed xmlrpc calls\r
*\r
* Known limitations:\r
* - server must support system.methodsignature for the wanted xmlrpc method\r
* - for methods that expose many signatures, only one can be picked (we\r
- * could in priciple check if signatures differ only by number of params\r
+ * could in principle check if signatures differ only by number of params\r
* and not by type, but it would be more complication than we can spare time)\r
* - nested xmlrpc params: the caller of the generated php function has to\r
* encode on its own the params passed to the php function if these are structs\r
*\r
* @param xmlrpc_client $client an xmlrpc client set up correctly to communicate with target server\r
* @param string $methodname the xmlrpc method to be mapped to a php function\r
- * @param array $extra_options array of options that specify conversion details. valid ptions include\r
+ * @param array $extra_options array of options that specify conversion details. valid options include\r
* integer signum the index of the method signature to use in mapping (if method exposes many sigs)\r
* integer timeout timeout (in secs) to be used when executing function/calling remote method\r
* string protocol 'http' (default), 'http11' or 'https'\r
- * string new_function_name the name of php function to create. If unsepcified, lib will pick an appropriate name\r
+ * string new_function_name the name of php function to create. If unspecified, lib will pick an appropriate name\r
* string return_source if true return php code w. function definition instead fo function name\r
* bool encode_php_objs let php objects be sent to server using the 'improved' xmlrpc notation, so server can deserialize them as php objects\r
* bool decode_php_objs --- WARNING !!! possible security hazard. only use it with trusted servers ---\r
\r
$encode_php_objects = isset($extra_options['encode_php_objs']) ? (bool)$extra_options['encode_php_objs'] : false;\r
$decode_php_objects = isset($extra_options['decode_php_objs']) ? (bool)$extra_options['decode_php_objs'] : false;\r
+ // it seems like the meaning of 'simple_client_copy' here is swapped wrt client_copy_mode later on...\r
$simple_client_copy = isset($extra_options['simple_client_copy']) ? (int)($extra_options['simple_client_copy']) : 0;\r
$buildit = isset($extra_options['return_source']) ? !($extra_options['return_source']) : true;\r
$prefix = isset($extra_options['prefix']) ? $extra_options['prefix'] : 'xmlrpc';\r