'XMLRPC Server', 'description' => 'Demonstrates server side XMLRPC with Drupal', 'page callback' => 'drupal_get_form', 'page arguments' => array('xmlrpc_example_server_form'), 'access callback' => TRUE, 'weight' => 0, ); // This is the client form menu entry. $items['examples/xmlrpc_client'] = array( 'title' => 'XMLRPC Client', 'description' => 'Demonstrates client side XMLRPC with Drupal', 'page callback' => 'drupal_get_form', 'page arguments' => array('xmlrpc_example_client_form'), 'access callback' => TRUE, 'weight' => 1, ); return $items; } // This is the server part of the module, implementing a simple and little // xmlrpc server with just two simple services. The serveris divided in two // different parts: the UI (settings form) and the xmlrpc implementation. // // The XMLRPC server will define two different services: // // - sub: perform the subtraction of two numbers. The minimum and maximum values // returned by the server can be configured in the settings form. // - add: perform the addition of two numbers. The minimum and maximum values // returned by the server can be configured in the settings form. // // If the result value for the operation is over the maximum limit, an error // 10001 is returned. // If the result value for the operation is below the minimum limit, an error // 10002 is returned. // User interface for the XMLRPC Server part. /** * Present a form to configure the xmlrpc service options. In this case the max * and min values for any of the operations (add or subtraction). */ function xmlrpc_example_server_form() { $form = array(); $form['explanation'] = array( '#markup' => "
" . t("This is the configuration page for the demonstration XMLRPC Server.
Here you may define the maximum and minimum values for the add or subtraction exposed services.
") . "
", ); $form['xmlrpc_example_server_min'] = array( '#type' => 'textfield', '#title' => t("Enter the minimum value returned by sub or add methods"), '#description' => t("An xmlrpc error will result if they sum to more than 10 or the difference is less than 0."), '#default_value' => variable_get('xmlrpc_example_server_min', 0), '#size' => 5, '#required' => TRUE, ); $form['xmlrpc_example_server_max'] = array( '#type' => 'textfield', '#title' => t("Enter the maximum value returned by sub or add methods"), '#default_value' => variable_get('xmlrpc_example_server_max', 10), '#size' => 5, '#required' => TRUE, ); return system_settings_form($form); } // The following code is the XMLRPC implmentation of the server part. The fisrt // step is to define the methods. This methods should be associated to callbacks // that will be defined later. /** * Implements hook_xmlrpc(). * * Provides Drupal with an array to map XML-RPC callbacks to the * functions implemented by this module. * * @see hook_xmlrpc() */ function xmlrpc_example_xmlrpc() { $methods[] = array( 'xmlrpc_example.add', // Method name '_xmlrpc_example_server_add', // Callback to execute array( // Array of types for output/input parameteres 'int', // the type of the return value 'int', // the type of the first argument 'int', // the type of the second argument ), t('Returns the sum of the two arguments.') // Method description ); // The subtract method is similiar to the addition $methods[] = array( 'xmlrpc_example.subtract', '_xmlrpc_example_server_subtract', array('int', 'int', 'int'), t('Return difference of the two arguments.') ); return $methods; } // Here are defined the callbacks for each method in the XMLRPC implementation // of the server: _xmlrpc_example.add and _xmlrpc_example.subtract /** * Sum the two arguments. * * This is the callback for the xmlrpc_example.add xmlrpc method. * * @param $num1 * @param $num2 * @return * The sum of the arguments, or error if it is not in server defined bounds. * * @see xmlrpc_error() */ function _xmlrpc_example_server_add($num1, $num2) { $sum = $num1 + $num2; // If result is not within maximum and minimum limits, return corresponding error if ($sum > variable_get('xmlrpc_example_server_max', 10)) { return xmlrpc_error(10001, t("Result is over the higher limit defined by the server.")); } if ($sum < variable_get('xmlrpc_example_server_min', 0)) { return xmlrpc_error(10002, t("Result is under the lower limit defined by the server.")); } // Otherwise return the result. return $sum; } /** * Return the difference of the two arguments. * * This is the callback for the xmlrpc_example.subtract xmlrpc method. * * @param numeric $num1 * @param numeric $num2 * @return * The difference of the two arguments, or error if it is not in server defined bounds. * * @see xmlrpc_error() */ function _xmlrpc_example_server_subtract($num1, $num2) { $diference = $num1 - $num2; // If result is not within maximum and minimum limits, return corresponding error if ($diference > variable_get('xmlrpc_example_server_max', 10)) { return xmlrpc_error(10001, t("Result is over the higher limit defined by the server.")); } if ($diference < variable_get('xmlrpc_example_server_min', 0)) { return xmlrpc_error(10002, t("Result is under the lower limit defined by the server.")); } // Otherwise return the result. return $diference; } // The server part of the module finishes here. // This is the client part of the module. If defines a form with two input fields // to call xmlrcp_example.add or xmlrpc_example.subtract methods on this host. // Now begins the client/UI portion of the module. /** * Present a form that makes use of xmlrpc services to add or subtract. */ function xmlrpc_example_client_form() { $form = array(); $form['explanation'] = array( '#markup' => "
" . t("The XMLRPC example demonstrates the use of the XMLRPC client in Drupal.
It uses the xmlrpc() function to act as a client, calling itself for some defined methods.
An xmlrpc error will result if the result is out of bounds defined by the server.
") . "
", ); $form['num1'] = array( '#type' => 'textfield', '#title' => t("Enter an integer"), '#default_value' => 2, '#size' => 5, '#required' => TRUE, ); $form['num2'] = array( '#type' => 'textfield', '#title' => t("Enter a second integer"), '#default_value' => 2, '#size' => 5, '#required' => TRUE, ); $form['add'] = array( '#type' => 'submit', '#value' => t("Add the integers"), '#submit' => array('xmlrpc_example_client_add_submit'), ); $form['subtract'] = array( '#type' => 'submit', '#value' => t("Subtract the integers"), '#submit' => array('xmlrpc_example_client_subtract_submit'), ); return $form; } /** * Submit: query the xmlrpc endpoint for the method xmlrpc_example.add * and report the result. * @param $form * @param $form_state * * @see xmlrpc() * @see xmlrpc_errno() * @see xmlrpc_error_msg() */ function xmlrpc_example_client_add_submit($form, &$form_state) { // First define the endpoint of the xmlrcp service, in this case is our // own server. $server = url($GLOBALS['base_url'] . "/xmlrpc.php"); // Then we should pass the method and the arguments to the xmlrpc client. // Make the xmlrpc request and process the results. $result = xmlrpc( $server, // Url of the xmlrpc endpoint 'xmlrpc_example.add', // Method to call (int) $form_state['values']['num1'], // argument 1 (int) $form_state['values']['num2'] // argument 2... ); if ($result === FALSE) { drupal_set_message(t("Error return from xmlrpc(): Error: @errno, Message: @message", array('@errno' => xmlrpc_errno(), '@message' => xmlrpc_error_msg()))); } else { drupal_set_message(t("The XMLRPC server returned this response: @response", array('@response' => print_r($result, TRUE)))); } } /** * Submit for subtraction: Call the xmlrpc method and report the result. * @param $form * @param $form_state * * @see xmlrpc() * @see xmlrpc_errno() * @see xmlrpc_error_msg() * @see xmlrpc_example_client_add_submit() */ function xmlrpc_example_client_subtract_submit($form, &$form_state) { $server = url($GLOBALS['base_url'] . "/xmlrpc.php"); $result = xmlrpc( $server, 'xmlrpc_example.subtract', (int) $form_state['values']['num1'], (int) $form_state['values']['num2'] ); if ($result === FALSE) { drupal_set_message(t("Error return from xmlrpc(): Error: @errno, Message: @message", array('@errno' => xmlrpc_errno(), '@message' => xmlrpc_error_msg()))); } else { drupal_set_message(t("The XMLRPC server returned this response: @response", array('@response' => print_r($result, TRUE)))); } } // End of client part of the module. /** * @} End of "defgroup xmlrpc_example". */