Fix constructors to be compliant with php 7
[plcapi.git] / lib / xmlrpc_wrappers.inc
index 0f3338a..9d901a4 100644 (file)
@@ -3,9 +3,8 @@
  * PHP-XMLRPC "wrapper" functions\r
  * Generate stubs to transparently access xmlrpc methods as php functions and viceversa\r
  *\r
- * @version $Id: xmlrpc_wrappers.inc,v 1.13 2008/09/20 01:23:47 ggiunta Exp $\r
  * @author Gaetano Giunta\r
- * @copyright (C) 2006-2008 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
@@ -22,6 +21,7 @@
        * accepted come from javadoc blocks), return corresponding phpxmlrpc type.\r
        * NB: for php 'resource' types returns empty string, since resources cannot be serialized;\r
        * for php class names returns 'struct', since php objects can be serialized as xmlrpc structs\r
+       * for php arrays always return array, even though arrays sometiles serialize as json structs\r
        * @param string $phptype\r
        * @return string\r
        */\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_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
                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
-                       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
+                               $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
                $valclass = $prefix.'val';\r
                $decodefunc = 'php_'.$prefix.'_decode';\r
 \r
-               $msg =& new $msgclass('system.methodSignature');\r
+               $msg = new $msgclass('system.methodSignature');\r
                $msg->addparam(new $valclass($methodname));\r
                $client->setDebug($debug);\r
                $response =& $client->send($msg, $timeout, $protocol);\r
                                // in online mode, favour speed of operation\r
                                if(!$buildit)\r
                                {\r
-                                       $msg =& new $msgclass('system.methodHelp');\r
+                                       $msg = new $msgclass('system.methodHelp');\r
                                        $msg->addparam(new $valclass($methodname));\r
                                        $response =& $client->send($msg, $timeout, $protocol);\r
                                        if (!$response->faultCode())\r
                //$valclass = $prefix.'val';\r
                $decodefunc = 'php_'.$prefix.'_decode';\r
 \r
-               $msg =& new $msgclass('system.listMethods');\r
+               $msg = new $msgclass('system.listMethods');\r
                $response =& $client->send($msg, $timeout, $protocol);\r
                if($response->faultCode())\r
                {\r
                        $innercode = '';\r
                        $this_ = 'this->';\r
                }\r
-               $innercode .= "\$msg =& new {$prefix}msg('$methodname');\n";\r
+               $innercode .= "\$msg = new {$prefix}msg('$methodname');\n";\r
 \r
                if ($mdesc != '')\r
                {\r
                                $ptype == 'string' || $ptype == 'dateTime.iso8601' || $ptype == 'base64' || $ptype == 'null')\r
                        {\r
                                // only build directly xmlrpcvals when type is known and scalar\r
-                               $innercode .= "\$p$i =& new {$prefix}val(\$p$i, '$ptype');\n";\r
+                               $innercode .= "\$p$i = new {$prefix}val(\$p$i, '$ptype');\n";\r
                        }\r
                        else\r
                        {\r
        */\r
        function build_client_wrapper_code($client, $verbatim_client_copy, $prefix='xmlrpc')\r
        {\r
-               $code = "\$client =& new {$prefix}_client('".str_replace("'", "\'", $client->path).\r
+               $code = "\$client = new {$prefix}_client('".str_replace("'", "\'", $client->path).\r
                        "', '" . str_replace("'", "\'", $client->server) . "', $client->port);\n";\r
 \r
                // copy all client fields to the client that will be generated runtime\r