diff --git a/webservice/xmlrpc/lib.php b/webservice/xmlrpc/lib.php
index a4eb5bbfe6c..06c499d5599 100644
--- a/webservice/xmlrpc/lib.php
+++ b/webservice/xmlrpc/lib.php
@@ -73,16 +73,7 @@ class webservice_xmlrpc_client {
$this->serverurl->param('wstoken', $this->token);
}
- // Set output options.
- $outputoptions = array(
- 'encoding' => 'utf-8',
- 'escaping' => 'markup',
- );
-
- // Encode the request.
- // See MDL-53962 - needed for backwards compatibility on <= 3.0
- $params = array_values($params);
- $request = xmlrpc_encode_request($functionname, $params, $outputoptions);
+ $request = $this->encode_request($functionname, $params);
// Set the headers.
$headers = array(
@@ -103,4 +94,24 @@ class webservice_xmlrpc_client {
return $result;
}
+
+ /**
+ * Generates XML for a method request.
+ *
+ * @param string $functionname Name of the method to call.
+ * @param mixed $params Method parameters compatible with the method signature.
+ * @return string
+ */
+ protected function encode_request($functionname, $params) {
+
+ $outputoptions = array(
+ 'encoding' => 'utf-8',
+ 'escaping' => 'markup',
+ );
+
+ // See MDL-53962 - needed for backwards compatibility on <= 3.0.
+ $params = array_values($params);
+
+ return xmlrpc_encode_request($functionname, $params, $outputoptions);
+ }
}
diff --git a/webservice/xmlrpc/tests/lib_test.php b/webservice/xmlrpc/tests/lib_test.php
index 8adc4384f5d..6a7c7fe3428 100644
--- a/webservice/xmlrpc/tests/lib_test.php
+++ b/webservice/xmlrpc/tests/lib_test.php
@@ -88,6 +88,27 @@ class webservice_xmlrpc_test extends advanced_testcase {
$this->expectException('moodle_exception');
$client->call('testfunction');
}
+
+ /**
+ * Test the XML-RPC request encoding.
+ */
+ public function test_encode_request() {
+
+ $client = new webservice_xmlrpc_client_mock('/webservice/xmlrpc/server.php', 'anytoken');
+
+ // Encode the request with the proper encoding and escaping options.
+ $xml = $client->encode_request('do_it', ['foo' => 'ŠČŘŽÝÁÍÉ']);
+
+ // Assert that decoding with explicit encoding will work. This appeared
+ // to fail if the markup escaping was not set.
+ $this->assertEquals(['ŠČŘŽÝÁÍÉ'], xmlrpc_decode($xml, 'UTF-8'));
+
+ // Our experiments show that even with default/implicit encoding,
+ // requests encoded with markup escaping set are also decoded
+ // correctly. This is known to be used in some servers so we test it
+ // here, too.
+ $this->assertEquals(['ŠČŘŽÝÁÍÉ'], xmlrpc_decode($xml));
+ }
}
/**
@@ -137,4 +158,15 @@ class webservice_xmlrpc_client_mock extends webservice_xmlrpc_client {
return $result;
}
+
+ /**
+ * Allows to test the request encoding.
+ *
+ * @param string $functionname Name of the method to call.
+ * @param mixed $params Method parameters compatible with the method signature.
+ * @return string
+ */
+ public function encode_request($functionname, $params) {
+ return parent::encode_request($functionname, $params);
+ }
}