Merge branch 'wip-MDL-60594-master' of git://github.com/marinaglancy/moodle

This commit is contained in:
Eloy Lafuente (stronk7) 2017-12-19 00:36:28 +01:00
commit 2b7fda50d9
2 changed files with 65 additions and 1 deletions

View File

@ -89,7 +89,7 @@ class webservice_xmlrpc_client {
$response = download_file_content($this->serverurl->out(false), $headers, $request);
// Decode the response.
$result = xmlrpc_decode($response);
$result = $this->decode_response($response);
if (is_array($result) && xmlrpc_is_fault($result)) {
throw new Exception($result['faultString'], $result['faultCode']);
}
@ -116,4 +116,23 @@ class webservice_xmlrpc_client {
return xmlrpc_encode_request($functionname, $params, $outputoptions);
}
/**
* Parses and decodes the response XML
*
* @param string $response
* @return array
*/
protected function decode_response($response) {
// XMLRPC server in Moodle encodes response using function xmlrpc_encode_request() with method==null
// see {@link webservice_xmlrpc_server::prepare_response()} . We should use xmlrpc_decode_request() for decoding too.
$method = null;
$encoding = null;
if (preg_match('/^<\?xml version="1.0" encoding="([^"]*)"\?>/', $response, $matches)) {
// Sometimes xmlrpc_decode_request() fails to recognise encoding, let's help it.
$encoding = $matches[1];
}
$r = xmlrpc_decode_request($response, $method, $encoding);
return $r;
}
}

View File

@ -103,12 +103,47 @@ class webservice_xmlrpc_test extends advanced_testcase {
// to fail if the markup escaping was not set.
$this->assertEquals(['<bar>ŠČŘŽÝÁÍÉ</bar>'], xmlrpc_decode($xml, 'UTF-8'));
// Decoding also works with our wrapper method.
$this->assertEquals(['<bar>ŠČŘŽÝÁÍÉ</bar>'], $client->decode_response($xml));
// 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.
// However, this does not work for all strings, see next test.
$this->assertEquals(['<bar>ŠČŘŽÝÁÍÉ</bar>'], xmlrpc_decode($xml));
}
/**
* Test the XML-RPC response decoding
*/
public function test_decode_response() {
$client = new webservice_xmlrpc_client_mock('/webservice/xmlrpc/server.php', 'anytoken');
$teststring = '<bar>Recherche thématique:Villes & Développement durable</bar>';
// Encode the string with the proper encoding and escaping options. Assert that decoding will work.
$xml = $client->encode_request('do_it', [$teststring]);
$this->assertEquals([$teststring], $client->decode_response($xml));
// For this particular string bare decoding function does not work.
// It can't really be explained why it works for the string 'ŠČŘŽÝÁÍÉ' in the previous test but not this one.
// Symbol é comes as chr(233) . It looks like '<bar>Recherche th<74>matique:Villes & D<>veloppement durable</bar>'.
$this->assertEquals([preg_replace('/é/', chr(233), $teststring)], xmlrpc_decode($xml));
// Encode the string without any options (default encoding "iso-8859-1" is used). Assert that decoding will work.
$xml = xmlrpc_encode_request('do_it', [$teststring]);
$this->assertEquals([$teststring], $client->decode_response($xml));
$this->assertEquals([$teststring], xmlrpc_decode($xml));
// Another example of the string where bare xmlrpc_decode() does not work but our wrapper does.
$teststring = 'Formación Docente';
$xml = $client->encode_request('do_it', [$teststring]);
$this->assertEquals([$teststring], $client->decode_response($xml));
// Bare decoding function xmlrpc_decode() does not work.
// Symbol ó comes as chr(243), it looks like 'Formaci<63>n Docente'.
$this->assertEquals([preg_replace('/ó/', chr(243), $teststring)], xmlrpc_decode($xml));
}
}
/**
@ -169,4 +204,14 @@ class webservice_xmlrpc_client_mock extends webservice_xmlrpc_client {
public function encode_request($functionname, $params) {
return parent::encode_request($functionname, $params);
}
/**
* Allows to test the response decoding.
*
* @param string $response
* @return array
*/
public function decode_response($response) {
return parent::decode_response($response);
}
}