Index: includes/common.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/common.inc,v retrieving revision 1.1204 diff -u -p -r1.1204 common.inc --- includes/common.inc 10 Aug 2010 01:00:42 -0000 1.1204 +++ includes/common.inc 13 Aug 2010 18:59:11 -0000 @@ -6747,16 +6747,22 @@ function entity_form_submit_build_entity /** * Performs one or more XML-RPC request(s). * + * Usage example: + * @code + * $result = xmlrpc('http://example.com/xmlrpc.php', array( + * 'service.methodName' => array($parameter, $second, $third), + * )); + * @endcode + * * @param $url * An absolute URL of the XML-RPC endpoint. - * Example: - * http://www.example.com/xmlrpc.php - * @param ... - * For one request: - * The method name followed by a variable number of arguments to the method. - * For multiple requests (system.multicall): - * An array of call arrays. Each call array follows the pattern of the single - * request: method name followed by the arguments to the method. + * @param $args + * An associative array whose keys are the methods to call and whose values + * are the arguments to pass to the respective method. If multiple methods + * are specified, a system.multicall is performed. + * @param $options + * (optional) An array of options to pass along to drupal_http_request(). + * * @return * For one request: * Either the return value of the method on success, or FALSE. @@ -6766,10 +6772,9 @@ function entity_form_submit_build_entity * returned by the method called, or an xmlrpc_error object if the call * failed. See xmlrpc_error(). */ -function xmlrpc($url) { +function xmlrpc($url, $args, $options = array()) { require_once DRUPAL_ROOT . '/includes/xmlrpc.inc'; - $args = func_get_args(); - return call_user_func_array('_xmlrpc', $args); + return _xmlrpc($url, $args, $options); } /** Index: includes/xmlrpc.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/xmlrpc.inc,v retrieving revision 1.68 diff -u -p -r1.68 xmlrpc.inc --- includes/xmlrpc.inc 22 Jul 2010 16:20:15 -0000 1.68 +++ includes/xmlrpc.inc 13 Aug 2010 18:56:26 -0000 @@ -528,14 +528,14 @@ function xmlrpc_base64_get_xml($xmlrpc_b * Performs one or more XML-RPC requests. * * @param $url - * The absolute URL of the XML-RPC endpoint. Example: - * http://www.example.com/xmlrpc.php - * @param ... - * - For one request: The method name followed by a variable number of - * arguments to the method. - * - For multiple requests (system.multicall): An array of call arrays. Each - * call array follows the pattern of the single request: method name - * followed by the arguments to the method. + * An absolute URL of the XML-RPC endpoint, e.g., + * http://example.com/xmlrpc.php + * @param $args + * An associative array whose keys are the methods to call and whose values + * are the arguments to pass to the respective method. If multiple methods + * are specified, a system.multicall is performed. + * @param $options + * (optional) An array of options to pass along to drupal_http_request(). * * @return * A single response (single request) or an array of responses (multicall @@ -544,27 +544,25 @@ function xmlrpc_base64_get_xml($xmlrpc_b * is returned, see xmlrpc_errno() and xmlrpc_error_msg() to get more * information. */ -function _xmlrpc() { - $args = func_get_args(); - $url = array_shift($args); +function _xmlrpc($url, $args, $options = array()) { xmlrpc_clear_error(); - if (is_array($args[0])) { - $method = 'system.multicall'; + if (count($args) > 1) { $multicall_args = array(); - foreach ($args[0] as $call) { - $multicall_args[] = array('methodName' => array_shift($call), 'params' => $call); + foreach ($args as $method => $call) { + $multicall_args[] = array('methodName' => $method, 'params' => $call); } + $method = 'system.multicall'; $args = array($multicall_args); } else { - $method = array_shift($args); + $method = key($args); + $args = $args[$method]; } $xmlrpc_request = xmlrpc_request($method, $args); - $options = array( - 'headers' => array('Content-Type' => 'text/xml'), - 'method' => 'POST', - 'data' => $xmlrpc_request->xml, - ); + // Required options which will replace any that are passed in. + $options['method'] = 'POST'; + $options['headers']['Content-Type'] = 'text/xml'; + $options['data'] = $xmlrpc_request->xml; $result = drupal_http_request($url, $options); if ($result->code != 200) { xmlrpc_error($result->code, $result->error); Index: modules/simpletest/tests/xmlrpc.test =================================================================== RCS file: /cvs/drupal/drupal/modules/simpletest/tests/xmlrpc.test,v retrieving revision 1.19 diff -u -p -r1.19 xmlrpc.test --- modules/simpletest/tests/xmlrpc.test 5 Aug 2010 23:53:38 -0000 1.19 +++ modules/simpletest/tests/xmlrpc.test 13 Aug 2010 17:41:53 -0000 @@ -29,7 +29,7 @@ class XMLRPCBasicTestCase extends Drupal // Invoke XML-RPC call to get list of methods. $url = url(NULL, array('absolute' => TRUE)) . 'xmlrpc.php'; - $methods = xmlrpc($url, 'system.listMethods'); + $methods = xmlrpc($url, array('system.listMethods' => array())); // Ensure that the minimum methods were found. $count = 0; @@ -74,8 +74,8 @@ class XMLRPCBasicTestCase extends Drupal class XMLRPCValidator1IncTestCase extends DrupalWebTestCase { public static function getInfo() { return array( - 'name' => 'XML-RPC validator', - 'description' => 'See !validator-link.', array('!validator-link' => l('the xmlrpc validator1 specification', 'http://www.xmlrpc.com/validator1Docs')), + 'name' => 'XML-RPC validator', + 'description' => 'See the xmlrpc validator1 specification.', 'group' => 'XML-RPC', ); } @@ -92,7 +92,6 @@ class XMLRPCValidator1IncTestCase extend srand(); mt_srand(); - $array_1 = array(array('curly' => mt_rand(-100, 100)), array('curly' => mt_rand(-100, 100)), array('larry' => mt_rand(-100, 100)), @@ -102,29 +101,26 @@ class XMLRPCValidator1IncTestCase extend array('larry' => mt_rand(-100, 100))); shuffle($array_1); $l_res_1 = xmlrpc_test_arrayOfStructsTest($array_1); - $r_res_1 = xmlrpc($xml_url, 'validator1.arrayOfStructsTest', $array_1); - $this->assertIdentical($l_res_1, $r_res_1, 'array of structs test: %s'); - + $r_res_1 = xmlrpc($xml_url, array('validator1.arrayOfStructsTest' => array($array_1))); + $this->assertIdentical($l_res_1, $r_res_1); $string_2 = 't\'&>>zf"md>yr>xlcev">>uai"np&s>>q\'&b<>"&&&'; $l_res_2 = xmlrpc_test_countTheEntities($string_2); - $r_res_2 = xmlrpc($xml_url, 'validator1.countTheEntities', $string_2); - $this->assertIdentical($l_res_2, $r_res_2, 'count the entities test: %s'); - + $r_res_2 = xmlrpc($xml_url, array('validator1.countTheEntities' => array($string_2))); + $this->assertIdentical($l_res_2, $r_res_2); $struct_3 = array('moe' => mt_rand(-100, 100), 'larry' => mt_rand(-100, 100), 'curly' => mt_rand(-100, 100), 'homer' => mt_rand(-100, 100)); $l_res_3 = xmlrpc_test_easyStructTest($struct_3); - $r_res_3 = xmlrpc($xml_url, 'validator1.easyStructTest', $struct_3); - $this->assertIdentical($l_res_3, $r_res_3, 'easy struct test: %s'); - + $r_res_3 = xmlrpc($xml_url, array('validator1.easyStructTest' => array($struct_3))); + $this->assertIdentical($l_res_3, $r_res_3); $struct_4 = array('sub1' => array('bar' => 13), 'sub2' => 14, 'sub3' => array('foo' => 1, 'baz' => 2), 'sub4' => array('ss' => array('sss' => array('ssss' => 'sssss')))); $l_res_4 = xmlrpc_test_echoStructTest($struct_4); - $r_res_4 = xmlrpc($xml_url, 'validator1.echoStructTest', $struct_4); - $this->assertIdentical($l_res_4, $r_res_4, 'echo struct test: %s'); + $r_res_4 = xmlrpc($xml_url, array('validator1.echoStructTest' => array($struct_4))); + $this->assertIdentical($l_res_4, $r_res_4); $int_5 = mt_rand(-100, 100); $bool_5 = (($int_5 % 2) == 0); @@ -133,12 +129,11 @@ class XMLRPCValidator1IncTestCase extend $time_5 = REQUEST_TIME; $base64_5 = $this->randomName(100); $l_res_5 = xmlrpc_test_manyTypesTest($int_5, $bool_5, $string_5, $double_5, xmlrpc_date($time_5), $base64_5); - $l_res_5[5] = $l_res_5[5]->data; /* override warpping */ - $r_res_5 = xmlrpc($xml_url, 'validator1.manyTypesTest', $int_5, $bool_5, $string_5, $double_5, xmlrpc_date($time_5), xmlrpc_base64($base64_5)); - /* Contains objects, objects are not equal */ // See http://drupal.org/node/37766 why this currently fails - $this->assertEqual($l_res_5, $r_res_5, 'many types test: %s'); - + $l_res_5[5] = $l_res_5[5]->data; + $r_res_5 = xmlrpc($xml_url, array('validator1.manyTypesTest' => array($int_5, $bool_5, $string_5, $double_5, xmlrpc_date($time_5), xmlrpc_base64($base64_5)))); + // @todo Contains objects, objects are not equal. + $this->assertEqual($l_res_5, $r_res_5); $size = mt_rand(100, 200); $array_6 = array(); @@ -147,9 +142,8 @@ class XMLRPCValidator1IncTestCase extend } $l_res_6 = xmlrpc_test_moderateSizeArrayCheck($array_6); - $r_res_6 = xmlrpc($xml_url, 'validator1.moderateSizeArrayCheck', $array_6); - $this->assertIdentical($l_res_6, $r_res_6, 'moderate size array check: %s'); - + $r_res_6 = xmlrpc($xml_url, array('validator1.moderateSizeArrayCheck' => array($array_6))); + $this->assertIdentical($l_res_6, $r_res_6); $struct_7 = array(); for ($y = 2000; $y < 2002; $y++) { @@ -165,29 +159,29 @@ class XMLRPCValidator1IncTestCase extend } } $l_res_7 = xmlrpc_test_nestedStructTest($struct_7); - $r_res_7 = xmlrpc($xml_url, 'validator1.nestedStructTest', $struct_7); - $this->assertIdentical($l_res_7, $r_res_7, 'nested struct test: %s'); + $r_res_7 = xmlrpc($xml_url, array('validator1.nestedStructTest' => array($struct_7))); + $this->assertIdentical($l_res_7, $r_res_7); $int_8 = mt_rand(-100, 100); $l_res_8 = xmlrpc_test_simpleStructReturnTest($int_8); - $r_res_8 = xmlrpc($xml_url, 'validator1.simpleStructReturnTest', $int_8); - $this->assertIdentical($l_res_8, $r_res_8, 'simple struct test: %s'); + $r_res_8 = xmlrpc($xml_url, array('validator1.simpleStructReturnTest' => array($int_8))); + $this->assertIdentical($l_res_8, $r_res_8); /* Now test multicall */ $x = array(); - $x[] = array('validator1.arrayOfStructsTest', $array_1); - $x[] = array('validator1.countTheEntities', $string_2); - $x[] = array('validator1.easyStructTest', $struct_3); - $x[] = array('validator1.echoStructTest', $struct_4); - $x[] = array('validator1.manyTypesTest', $int_5, $bool_5, $string_5, $double_5, xmlrpc_date($time_5), xmlrpc_base64($base64_5)); - $x[] = array('validator1.moderateSizeArrayCheck', $array_6); - $x[] = array('validator1.nestedStructTest', $struct_7); - $x[] = array('validator1.simpleStructReturnTest', $int_8); + $x['validator1.arrayOfStructsTest'] = array($array_1); + $x['validator1.countTheEntities'] = array($string_2); + $x['validator1.easyStructTest'] = array($struct_3); + $x['validator1.echoStructTest'] = array($struct_4); + $x['validator1.manyTypesTest'] = array($int_5, $bool_5, $string_5, $double_5, xmlrpc_date($time_5), xmlrpc_base64($base64_5)); + $x['validator1.moderateSizeArrayCheck'] = array($array_6); + $x['validator1.nestedStructTest'] = array($struct_7); + $x['validator1.simpleStructReturnTest'] = array($int_8); $a_l_res = array($l_res_1, $l_res_2, $l_res_3, $l_res_4, $l_res_5, $l_res_6, $l_res_7, $l_res_8); $a_r_res = xmlrpc($xml_url, $x); - $this->assertEqual($a_l_res, $a_r_res, 'multicall equals result'); + $this->assertEqual($a_l_res, $a_r_res); } } @@ -212,7 +206,7 @@ class XMLRPCMessagesTestCase extends Dru $sizes = array(8, 80, 160); foreach ($sizes as $size) { $xml_message_l = xmlrpc_test_message_sized_in_kb($size); - $xml_message_r = xmlrpc($xml_url, 'messages.messageSizedInKB', $size); + $xml_message_r = xmlrpc($xml_url, array('messages.messageSizedInKB' => array($size))); $this->assertEqual($xml_message_l, $xml_message_r, t('XML-RPC messages.messageSizedInKB of %s Kb size received', array('%s' => $size))); }