'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".
*/