MDL-53962 webservices: Make XML-RPC backwards compatible
authorCameron Ball <cameron@moodle.com>
Mon, 16 May 2016 16:39:05 +0000 (00:39 +0800)
committerCameron Ball <cameron@moodle.com>
Tue, 17 May 2016 03:39:15 +0000 (11:39 +0800)
webservice/upgrade.txt
webservice/xmlrpc/lib.php
webservice/xmlrpc/locallib.php

index 02f9224..9d5a009 100644 (file)
@@ -17,6 +17,8 @@ This information is intended for authors of webservices, not people writing webs
   on the string returned by the getMessage() method of the thrown exception.
 * With Zend_SOAP dropped, moodle_zend_soap_server is now also deprecated.
 * As mentioned in the 2.9 notes, deprecated web service functions have now been removed.
+* Since our new XML-RPC server implementation does not support introspection, it is critical that all clients send
+  parameters in the correct order.
 
 === 3.0 ===
 
index 2a46887..6d48200 100644 (file)
@@ -79,6 +79,8 @@ class webservice_xmlrpc_client {
         );
 
         // Encode the request.
+        // See MDL-53962 - needed for backwards compatibility on <= 3.0
+        $params = array_values($params);
         $request = xmlrpc_encode_request($functionname, $params, $outputoptions);
 
         // Set the headers.
index e8eddf3..87cd695 100644 (file)
@@ -78,16 +78,15 @@ class webservice_xmlrpc_server extends webservice_base_server {
 
         // Decode the request to get the decoded parameters and the name of the method to be called.
         $decodedparams = xmlrpc_decode_request($rawpostdata, $methodname);
+        $methodinfo = external_api::external_function_info($methodname);
+        $methodparams = array_keys($methodinfo->parameters_desc->keys);
 
         // Add the decoded parameters to the methodvariables array.
         if (is_array($decodedparams)) {
-            foreach ($decodedparams as $param) {
-                // Check if decoded param is an associative array.
-                if (is_array($param) && array_keys($param) !== range(0, count($param) - 1)) {
-                    $methodvariables = array_merge($methodvariables, $param);
-                } else {
-                    $methodvariables[] = $param;
-                }
+            foreach ($decodedparams as $index => $param) {
+                // See MDL-53962 - XML-RPC requests will usually be sent as an array (as in, one with indicies).
+                // We need to use a bit of "magic" to add the correct index back. Zend used to do this for us.
+                $methodvariables[$methodparams[$index]] = $param;
             }
         }