allow Wrapper to generate jsonrpc code; improve formatting for code from Wrapper...
authorgggeek <giunta.gaetano@gmail.com>
Wed, 18 Jan 2023 16:23:45 +0000 (16:23 +0000)
committergggeek <giunta.gaetano@gmail.com>
Wed, 18 Jan 2023 16:23:45 +0000 (16:23 +0000)
debugger/action.php
debugger/controller.php
src/Wrapper.php

index 3b1f557..b7ece5a 100644 (file)
@@ -25,22 +25,18 @@ header('Content-Type: text/html; charset=utf-8');
             font-family: Verdana, Arial, Helvetica, sans-serif;
             font-size: 8pt;
         }
-
         h3 {
             font-size: 9.5pt;
         }
-
         h2 {
             font-size: 12pt;
         }
-
         .dbginfo {
             padding: 1em;
             background-color: #EEEEEE;
             border: 1px dashed silver;
             font-family: monospace;
         }
-
         #response {
             padding: 1em;
             margin-top: 1em;
@@ -49,41 +45,33 @@ header('Content-Type: text/html; charset=utf-8');
             white-space: pre;
             font-family: monospace;
         }
-
         table {
             padding: 2px;
             margin-top: 1em;
         }
-
         th {
             background-color: navy;
             color: white;
             padding: 0.5em;
         }
-
         td {
             padding: 0.5em;
             font-family: monospace;
         }
-
         td form {
             margin: 0;
         }
-
         .oddrow {
             background-color: #EEEEEE;
         }
-
         .evidence {
             color: blue;
         }
-
         #phpcode {
             background-color: #EEEEEE;
             padding: 1em;
             margin-top: 1em;
         }
-
         -->
     </style>
 </head>
@@ -118,11 +106,11 @@ if ($action) {
             }
             $clientClass = '\PhpXmlRpc\JsonRpc\Client';
             $requestClass = '\PhpXmlRpc\JsonRpc\Request';
-            $protoName = 'JSONRPC';
+            $protoName = 'JSON-RPC';
         } else {
             $clientClass = '\PhpXmlRpc\Client';
             $requestClass = '\PhpXmlRpc\Request';
-            $protoName = 'XMLRPC';
+            $protoName = 'XML-RPC';
         }
 
         if ($port != "") {
@@ -227,7 +215,7 @@ if ($action) {
                     die("Tsk tsk tsk, please stop it or I will have to call in the cops!");
                 }
                 $msg[0] = new $requestClass($method, array(), $id);
-                // hack! build xml payload by hand
+                // hack! build payload by hand
                 if ($wstype == 1) {
                     $msg[0]->payload = "{\n" .
                         '"method": "' . $method . "\",\n\"params\": [" .
@@ -384,7 +372,38 @@ if ($action) {
                                     foreach($x as $k => $y) {
                                         if ($k == 0) continue;
                                         echo htmlspecialchars($y->scalarval(), ENT_COMPAT, \PhpXmlRpc\PhpXmlRpc::$xmlrpc_internalencoding);
-                                        if ($wstype != 1) {
+                                        if ($wstype == 1) {
+                                            switch($y->scalarval()) {
+                                                case 'string':
+                                                case 'dateTime.iso8601':
+                                                case 'base64':
+                                                    $payload .= '""';
+                                                    break;
+                                                case 'i4':
+                                                case 'i8':
+                                                case 'int':
+                                                    $payload .= '0';
+                                                    break;
+                                                case 'double':
+                                                    $payload .= '0.0';
+                                                    break;
+                                                case 'bool':
+                                                case 'boolean':
+                                                    $payload .= 'true';
+                                                    break;
+                                                case 'null':
+                                                    $payload .= 'null';
+                                                    break;
+                                                case 'array':
+                                                    $payload .= '[]';
+                                                    break;
+                                                case 'struct':
+                                                    $payload .= '{}';
+                                                    break;
+                                                default:
+                                                    break;
+                                            }
+                                        } else {
                                             $type = $y->scalarval();
                                             $payload .= '<param><value>';
                                             switch($type) {
@@ -404,6 +423,9 @@ if ($action) {
                                         $alt_payload .= $y->scalarval();
                                         if ($k < $x->count() - 1) {
                                             $alt_payload .= ';';
+                                            if ($wstype == 1) {
+                                                $payload .= ', ';
+                                            }
                                             echo ", ";
                                         }
                                     }
@@ -440,9 +462,9 @@ if ($action) {
                                 "<input type=\"hidden\" name=\"altmethodpayload\" value=\"" . htmlspecialchars($alt_payload, ENT_COMPAT, $inputcharset) . "\" />" .
                                 "<input type=\"hidden\" name=\"wstype\" value=\"$wstype\" />" .
                                 "<input type=\"hidden\" name=\"action\" value=\"execute\" />";
-                            if ($wstype != 1) {
+                            //if ($wstype != 1) {
                                 echo "<input type=\"submit\" value=\"Load method synopsis\" />";
-                            }
+                            //}
                             echo "</form></td>\n";
 
                             echo "<td$class><form action=\"controller.php\" target=\"frmcontroller\" method=\"get\">" .
@@ -492,8 +514,7 @@ if ($action) {
                         $msig = $msig[$methodsig];
                         $proto = ($protocol == 1) ? 'http11' : ( $protocol == 2 ? 'https' : ( $protocol == 3 ? 'h2' : ( $protocol == 4 ? 'h2c' : '' ) ) );
                         if ($proxy == '' && $username == '' && !$requestcompression && !$responsecompression &&
-                            $clientcookies == ''
-                        ) {
+                            $clientcookies == '') {
                             $opts = 1; // simple client copy in stub code
                         } else {
                             $opts = 0; // complete client copy in stub code
@@ -503,12 +524,16 @@ if ($action) {
                         } else {
                             $prefix = 'xmlrpc';
                         }
-                        $wrapper = new PhpXmlRpc\Wrapper();
+                        if ($wstype == 1) {
+                            $wrapper = new PhpXmlRpc\JsonRpc\Wrapper();
+                        } else {
+                            $wrapper = new PhpXmlRpc\Wrapper();
+                        }
                         $code = $wrapper->buildWrapMethodSource($client, $method, array('timeout' => $timeout, 'protocol' => $proto, 'simple_client_copy' => $opts, 'prefix' => $prefix), str_replace('.', '_', $prefix . '_' . $method), $msig, $mdesc);
                         //if ($code)
                         //{
                         echo "<div id=\"phpcode\">\n";
-                        highlight_string("<?php\n" . $code['docstring'] . $code['source'] . '?>');
+                        highlight_string("<?php\n" . $code['docstring'] . $code['source']);
                         echo "\n</div>";
                         //}
                         //else
index b666537..bcc759f 100644 (file)
@@ -223,7 +223,7 @@ if (defined('JSXMLRPC_BASEURL')) {
         }
 
         function activateeditor() {
-            var url = '<?php echo $editorurlpath; ?>visualeditor.html?params=<?php echo str_replace(array("\\", "'"), array( "\\\\","\\'"), $alt_payload); ?>';
+            var url = '<?php echo $editorurlpath; ?>visualeditor.html?params=<?php echo str_replace(array("\\", "'"), array( "\\\\", "\\'"), $alt_payload); ?>';
             if (document.frmaction.wstype.value == "1")
                 url += '&type=jsonrpc';
             var wnd = window.open(url, '_blank', 'width=750, height=400, location=0, resizable=1, menubar=0, scrollbars=1');
index 71d878f..0f36fa9 100644 (file)
@@ -26,6 +26,8 @@ class Wrapper
 
     protected static $logger;
 
+    protected static $namespace = '\\PhpXmlRpc\\';
+
     public function getLogger()
     {
         if (self::$logger === null) {
@@ -433,10 +435,9 @@ class Wrapper
          */
         $function = function($req) use($callable, $extraOptions, $funcDesc)
         {
-            $nameSpace = '\\PhpXmlRpc\\';
-            $encoderClass = $nameSpace.'Encoder';
-            $responseClass = $nameSpace.'Response';
-            $valueClass = $nameSpace.'Value';
+            $encoderClass = static::$namespace.'Encoder';
+            $responseClass = static::$namespace.'Response';
+            $valueClass = static::$namespace.'Value';
 
             // validate number of parameters received
             // this should be optional really, as we assume the server does the validation
@@ -534,8 +535,6 @@ class Wrapper
      */
     protected function buildWrapFunctionSource($callable, $newFuncName, $extraOptions, $plainFuncName, $funcDesc)
     {
-        $namespace = '\\PhpXmlRpc\\';
-
         $encodePhpObjects = isset($extraOptions['encode_php_objs']) ? (bool)$extraOptions['encode_php_objs'] : false;
         $decodePhpObjects = isset($extraOptions['decode_php_objs']) ? (bool)$extraOptions['decode_php_objs'] : false;
         $catchWarnings = isset($extraOptions['suppress_warnings']) && $extraOptions['suppress_warnings'] ? '@' : '';
@@ -572,9 +571,9 @@ class Wrapper
         // build body of new function
 
         $innerCode = "\$paramCount = \$req->getNumParams();\n";
-        $innerCode .= "if (\$paramCount < $minPars || \$paramCount > $maxPars) return new {$namespace}Response(0, " . PhpXmlRpc::$xmlrpcerr['incorrect_params'] . ", '" . PhpXmlRpc::$xmlrpcstr['incorrect_params'] . "');\n";
+        $innerCode .= "if (\$paramCount < $minPars || \$paramCount > $maxPars) return new " . static::$namespace . "Response(0, " . PhpXmlRpc::$xmlrpcerr['incorrect_params'] . ", '" . PhpXmlRpc::$xmlrpcstr['incorrect_params'] . "');\n";
 
-        $innerCode .= "\$encoder = new {$namespace}Encoder();\n";
+        $innerCode .= "\$encoder = new " . static::$namespace . "Encoder();\n";
         if ($decodePhpObjects) {
             $innerCode .= "\$p = \$encoder->decode(\$req, array('decode_php_objs'));\n";
         } else {
@@ -595,14 +594,14 @@ class Wrapper
             if ($i < (count($parsVariations) - 1))
                 $innerCode .= "else\n";
         }
-        $innerCode .= "if (is_a(\$retval, '{$namespace}Response')) return \$retval; else\n";
+        $innerCode .= "if (is_a(\$retval, '" . static::$namespace . "Response')) return \$retval; else\n";
         if ($funcDesc['returns'] == Value::$xmlrpcDateTime || $funcDesc['returns'] == Value::$xmlrpcBase64) {
-            $innerCode .= "return new {$namespace}Response(new {$namespace}Value(\$retval, '{$funcDesc['returns']}'));";
+            $innerCode .= "return new " . static::$namespace . "Response(new " . static::$namespace . "Value(\$retval, '{$funcDesc['returns']}'));";
         } else {
             if ($encodePhpObjects) {
-                $innerCode .= "return new {$namespace}Response(\$encoder->encode(\$retval, array('encode_php_objs')));\n";
+                $innerCode .= "return new " . static::$namespace . "Response(\$encoder->encode(\$retval, array('encode_php_objs')));\n";
             } else {
-                $innerCode .= "return new {$namespace}Response(\$encoder->encode(\$retval));\n";
+                $innerCode .= "return new " . static::$namespace . "Response(\$encoder->encode(\$retval));\n";
             }
         }
         // shall we exclude functions returning by ref?
@@ -751,10 +750,9 @@ class Wrapper
      */
     protected function retrieveMethodSignature($client, $methodName, array $extraOptions = array())
     {
-        $namespace = '\\PhpXmlRpc\\';
-        $reqClass = $namespace . 'Request';
-        $valClass = $namespace . 'Value';
-        $decoderClass = $namespace . 'Encoder';
+        $reqClass = static::$namespace . 'Request';
+        $valClass = static::$namespace . 'Value';
+        $decoderClass = static::$namespace . 'Encoder';
 
         $debug = isset($extraOptions['debug']) ? ($extraOptions['debug']) : 0;
         $timeout = isset($extraOptions['timeout']) ? (int)$extraOptions['timeout'] : 0;
@@ -793,9 +791,8 @@ class Wrapper
      */
     protected function retrieveMethodHelp($client, $methodName, array $extraOptions = array())
     {
-        $namespace = '\\PhpXmlRpc\\';
-        $reqClass = $namespace . 'Request';
-        $valClass = $namespace . 'Value';
+        $reqClass = static::$namespace . 'Request';
+        $valClass = static::$namespace . 'Value';
 
         $debug = isset($extraOptions['debug']) ? ($extraOptions['debug']) : 0;
         $timeout = isset($extraOptions['timeout']) ? (int)$extraOptions['timeout'] : 0;
@@ -843,10 +840,9 @@ class Wrapper
                 $decodeFault = false;
             }
 
-            $namespace = '\\PhpXmlRpc\\';
-            $reqClass = $namespace . 'Request';
-            $encoderClass = $namespace . 'Encoder';
-            $valueClass = $namespace . 'Value';
+            $reqClass = static::$namespace . 'Request';
+            $encoderClass = static::$namespace . 'Encoder';
+            $valueClass = static::$namespace . 'Value';
 
             $encoder = new $encoderClass();
             $encodeOptions = array();
@@ -935,13 +931,11 @@ class Wrapper
             $faultResponse = '';
         }
 
-        $namespace = '\\PhpXmlRpc\\';
-
-        $code = "function $newFuncName (";
+        $code = "function $newFuncName(";
         if ($clientCopyMode < 2) {
             // client copy mode 0 or 1 == full / partial client copy in emitted code
             $verbatimClientCopy = !$clientCopyMode;
-            $innerCode = $this->buildClientWrapperCode($client, $verbatimClientCopy, $prefix, $namespace);
+            $innerCode = '  ' . str_replace("\n", "\n  ", $this->buildClientWrapperCode($client, $verbatimClientCopy, $prefix, static::$namespace));
             $innerCode .= "\$client->setDebug(\$debug);\n";
             $this_ = '';
         } else {
@@ -949,17 +943,18 @@ class Wrapper
             $innerCode = '';
             $this_ = 'this->';
         }
-        $innerCode .= "\$req = new {$namespace}Request('$methodName');\n";
+        $innerCode .= "  \$req = new " . static::$namespace . "Request('$methodName');\n";
 
         if ($mDesc != '') {
             // take care that PHP comment is not terminated unwillingly by method description
-            $mDesc = "/**\n* " . str_replace('*/', '* /', $mDesc) . "\n";
+            /// @todo according to the spec, method desc can have html in it. We should run it through strip_tags...
+            $mDesc = "/**\n * " . str_replace('*/', '* /', $mDesc) . "\n";
         } else {
-            $mDesc = "/**\nFunction $newFuncName\n";
+            $mDesc = "/**\n * Function $newFuncName.\n";
         }
 
         // param parsing
-        $innerCode .= "\$encoder = new {$namespace}Encoder();\n";
+        $innerCode .= "  \$encoder = new " . static::$namespace . "Encoder();\n";
         $plist = array();
         $pCount = count($mSig);
         for ($i = 1; $i < $pCount; $i++) {
@@ -969,25 +964,25 @@ class Wrapper
                 $pType == 'string' || $pType == 'dateTime.iso8601' || $pType == 'base64' || $pType == 'null'
             ) {
                 // only build directly xmlrpc values when type is known and scalar
-                $innerCode .= "\$p$i = new {$namespace}Value(\$p$i, '$pType');\n";
+                $innerCode .= "  \$p$i = new " . static::$namespace . "Value(\$p$i, '$pType');\n";
             } else {
                 if ($encodePhpObjects) {
-                    $innerCode .= "\$p$i = \$encoder->encode(\$p$i, array('encode_php_objs'));\n";
+                    $innerCode .= "  \$p$i = \$encoder->encode(\$p$i, array('encode_php_objs'));\n";
                 } else {
-                    $innerCode .= "\$p$i = \$encoder->encode(\$p$i);\n";
+                    $innerCode .= "  \$p$i = \$encoder->encode(\$p$i);\n";
                 }
             }
-            $innerCode .= "\$req->addparam(\$p$i);\n";
-            $mDesc .= '* @param ' . $this->xmlrpc2PhpType($pType) . " \$p$i\n";
+            $innerCode .= "  \$req->addparam(\$p$i);\n";
+            $mDesc .= ' * @param ' . $this->xmlrpc2PhpType($pType) . " \$p$i\n";
         }
         if ($clientCopyMode < 2) {
-            $plist[] = '$debug=0';
-            $mDesc .= "* @param int \$debug when 1 (or 2) will enable debugging of the underlying {$prefix} call (defaults to 0)\n";
+            $plist[] = '$debug = 0';
+            $mDesc .= " * @param int \$debug when 1 (or 2) will enable debugging of the underlying {$prefix} call (defaults to 0)\n";
         }
         $plist = implode(', ', $plist);
-        $mDesc .= "* @return {$namespace}Response|" . $this->xmlrpc2PhpType($mSig[0]) . " (an {$namespace}Response obj instance if call fails)\n*/\n";
+        $mDesc .= " * @return " . static::$namespace . "Response|" . $this->xmlrpc2PhpType($mSig[0]) . " (a " . static::$namespace . "Response obj instance if call fails)\n */\n";
 
-        $innerCode .= "\$res = \${$this_}client->send(\$req, $timeout, '$protocol');\n";
+        $innerCode .= "  \$res = \${$this_}client->send(\$req, $timeout, '$protocol');\n";
         if ($decodeFault) {
             if (is_string($faultResponse) && ((strpos($faultResponse, '%faultCode%') !== false) || (strpos($faultResponse, '%faultString%') !== false))) {
                 $respCode = "str_replace(array('%faultCode%', '%faultString%'), array(\$res->faultCode(), \$res->faultString()), '" . str_replace("'", "''", $faultResponse) . "')";
@@ -998,12 +993,12 @@ class Wrapper
             $respCode = '$res';
         }
         if ($decodePhpObjects) {
-            $innerCode .= "if (\$res->faultcode()) return $respCode; else return \$encoder->decode(\$res->value(), array('decode_php_objs'));";
+            $innerCode .= "  if (\$res->faultcode()) return $respCode; else return \$encoder->decode(\$res->value(), array('decode_php_objs'));";
         } else {
-            $innerCode .= "if (\$res->faultcode()) return $respCode; else return \$encoder->decode(\$res->value());";
+            $innerCode .= "  if (\$res->faultcode()) return $respCode; else return \$encoder->decode(\$res->value());";
         }
 
-        $code = $code . $plist . ") {\n" . $innerCode . "\n}\n";
+        $code = $code . $plist . ")\n{\n" . $innerCode . "\n}\n";
 
         return array('source' => $code, 'docstring' => $mDesc);
     }
@@ -1038,10 +1033,9 @@ class Wrapper
         $verbatimClientCopy = isset($extraOptions['simple_client_copy']) ? !($extraOptions['simple_client_copy']) : true;
         $buildIt = isset($extraOptions['return_source']) ? !($extraOptions['return_source']) : true;
         $prefix = isset($extraOptions['prefix']) ? $extraOptions['prefix'] : 'xmlrpc';
-        $namespace = '\\PhpXmlRpc\\';
 
-        $reqClass = $namespace . 'Request';
-        $decoderClass = $namespace . 'Encoder';
+        $reqClass = static::$namespace . 'Request';
+        $decoderClass = static::$namespace . 'Encoder';
 
         // retrieve the list of methods
         $req = new $reqClass('system.listMethods');
@@ -1077,7 +1071,7 @@ class Wrapper
         /// @todo add method setDebug() to new class, to enable/disable debugging
         $source = "class $xmlrpcClassName\n{\npublic \$client;\n\n";
         $source .= "function __construct()\n{\n";
-        $source .= $this->buildClientWrapperCode($client, $verbatimClientCopy, $prefix, $namespace);
+        $source .= $this->buildClientWrapperCode($client, $verbatimClientCopy, $prefix, static::$namespace);
         $source .= "\$this->client = \$client;\n}\n\n";
         $opts = array(
             'return_source' => true,