You are here

xmlrpc_example.module in xmlrpc 8

Module file for xmlrpc_example module.

File

xmlrpc_example/xmlrpc_example.module
View source
<?php

/**
 * @file
 * Module file for xmlrpc_example module.
 */

/**
 * @defgroup xmlrpc_example Example: XML-RPC
 * @ingroup examples
 * @{
 * Demonstration of XML-RPC in Drupal 8.
 *
 * This is an example of how to implement and XML-RPC server by registering
 * callbacks to specific methods and how to make xmlrpc calls using the built-in
 * xmlrpc() factory provided by the XML-RPC module.
 *
 * @see hook_xmlrpc()
 * @see xmlrpc()
 * @see xmlrpc_errno()
 * @see xmlrpc_error_msg()
 */

/**
 * Implements hook_xmlrpc().
 *
 * Provides Drupal with an array to map XML-RPC callbacks to existing functions.
 * These functions may be defined in other modules. The example implementation
 * defines specific functions for the example services.
 *
 * This is the server part of the module, implementing a simple and little
 * server with just two simple services. The server is divided in two
 * different parts: the XML-RPC implementation (required) and a webform
 * interface (optional) to configure some settings in the server side.
 *
 * The XMLRPC server will define two different services:
 *
 * - subtract: perform the subtraction of two numbers. The minimum and maximum
 *   values returned by the server can be configured in the server configuration
 *   form.
 * - add: perform the addition of two numbers. The minimum and maximum values
 *   returned by the server can be configured in the server configuration form.
 *
 * If the result value for the operation is over the maximum limit, a custom
 * error number 10001 is returned. This is an arbitrary number and could be any
 * number.
 *
 * If the result value for the operation is below the minimum limit, a custom
 * error number 10002 is returned. Again, this value is arbitrary and could be
 * any other number. Client applications must know the meaning of the error
 * numbers returned by the server.
 *
 * The following code is the XML-RPC implementation of the server part.
 * The first step is to define the methods. This methods should be associated
 * to callbacks that will be defined later.
 *
 * Note: the XML-RPC server built in this module already includes several
 * methods by default:
 *
 * Service discovery methods:
 * - system.listMethods: return a list of the methods the server has, by name.
 * - system.methodSignature: return a description of the argument format a
 *   particular method expects.
 * - system.methodHelp: returns a text description of a particular method.
 *
 * Other:
 * - system.multicall: perform several method calls in a single XML-RPC request.
 * - system.getCapabilities: determine if a given capability is supported.
 *
 * The methods defined by hook_xmlrpc() will be added to those provided by
 * default by the XML-RPC server built in the module.
 *
 * @see hook_xmlrpc()
 */
function xmlrpc_example_xmlrpc() {
  $methods[] = [
    // First argument is the method name.
    'xmlrpc_example.add',
    // Callback to execute when this method is requested.
    '_xmlrpc_example_server_add',
    // An array defines the types of output and input values for this method.
    [
      // The first value is the return type, an integer in this case.
      'int',
      // First operand is an integer.
      'int',
      // Second operand is an integer.
      'int',
    ],
    // Include a little description that is shown when XML-RPC server is
    // requested for the implemented methods list.
    // Method description.
    t('Returns the sum of the two arguments.'),
  ];

  // The subtract method is similar to the addition, only the method name,
  // callback and description are different.
  $methods[] = [
    'xmlrpc_example.subtract',
    '_xmlrpc_example_server_subtract',
    [
      'int',
      'int',
      'int',
    ],
    t('Return difference of the two arguments.'),
  ];
  return $methods;
}

/**
 * This is the callback for the xmlrpc_example.add method.
 *
 * Sum the two arguments and return value or an error if the result is out of
 * the configured limits.
 *
 * The following code for the server is optional if the callbacks already exist.
 * A server may implement methods associated to callbacks like node_load(),
 * config() or any other existing function (php functions as well).
 *
 * If the callbacks associated to the methods don't exist they must be
 * created. This implementation requires two specific callbacks:
 * - _xmlrpc_example_server_add()
 * - _xmlrpc_example_server_subtract()
 *
 * @param int $num1
 *   The first number to be summed.
 * @param int $num2
 *   The second number to be summed.
 *
 * @return int|object
 *   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.
  $config = \Drupal::config('xmlrpc_example.server');
  $max = $config
    ->get('max');
  $min = $config
    ->get('min');
  if ($sum > $max) {
    return xmlrpc_error(10001, t('Result is over the upper limit (@max) defined by the server.', [
      '@max' => $max,
    ]));
  }
  if ($sum < $min) {
    return xmlrpc_error(10002, t('Result is below the lower limit defined by the server (@min).', [
      '@min' => $min,
    ]));
  }

  // Otherwise return the result.
  return $sum;
}

/**
 * This is the callback for the xmlrpc_example.subtract xmlrpc method.
 *
 * Return the difference of the two arguments, or an error if the result is out
 * of the configured limits.
 *
 * @param int $num1
 *   First number.
 * @param int $num2
 *   Second number.
 *
 * @return int|object
 *   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) {
  $difference = $num1 - $num2;

  // If result is not within maximum and minimum limits,
  // return corresponding error.
  $config = \Drupal::config('xmlrpc_example.server');
  $max = $config
    ->get('max');
  $min = $config
    ->get('min');
  if ($difference > $max) {
    return xmlrpc_error(10001, t('Result is above the upper limit (@max) defined by the server.', [
      '@max' => $max,
    ]));
  }
  if ($difference < $min) {
    return xmlrpc_error(10002, t('Result is below the lower limit (@min) defined by the server.', [
      '@min' => $min,
    ]));
  }

  // Otherwise return the result.
  return $difference;
}

/**
 * Implements hook_xmlrpc_alter().
 *
 * Check to see if xmlrpc_example.add and xmlrpc_example.subtract methods are
 * defined and replace their callbacks with custom code.
 *
 * The alteration part of the module starts here. hook_xmlrpc_alter() is
 * useful when you want to extend, limit or alter methods defined by other
 * modules. This part is not required to have an XML-RPC server or client
 * working, but is useful to understand what can we do using current xmlrpc
 * API provided by drupal.
 *
 * This code can be defined in other module to alter the methods exposed by
 * this xmlrpc demonstration server, or can be used to alter methods defined
 * by other modules implementing hook_xmlrpc()
 *
 * As with the rest of the example module, an user interface is not required to
 * make use of this hook. A configuration form is included to enable/disable
 * this functionality, but this part is optional if you want to implement
 * hook_xmlrpc_alter()
 *
 * This is the XML-RPC code for the alteration part. It will check if an option
 * to enable the functionality is enabled and then alter it. We alter the
 * 'xmlrpc_example.add' and 'xmlrpc_example.subtract' methods, changing the
 * associated callback with custom functions. The modified methods (with
 * new callbacks associated) will perform the addition or subtraction of the
 * integer inputs, but will never check for limits nor return errors.
 *
 * @see hook_xmlrpc_alter()
 */
function xmlrpc_example_xmlrpc_alter(&$methods) {
  $config = \Drupal::config('xmlrpc_example.server');

  // Only perform alterations if instructed to do so.
  if (!$config
    ->get('alter_enabled')) {
    return;
  }

  // Loop all defined methods (other modules may include additional methods).
  foreach ($methods as $index => $method) {

    // First element in the method array is the method name.
    if ($method[0] == 'xmlrpc_example.add') {

      // Replace current callback with custom callback
      // (second argument of the array).
      $methods[$index][1] = '_xmlrpc_example_alter_add';
    }

    // Do the same for the subtraction method.
    if ($method[0] == 'xmlrpc_example.subtract') {
      $methods[$index][1] = '_xmlrpc_example_alter_subtract';
    }
  }
}

/**
 * Sum the two arguments without limit checking.
 *
 * This is the replacement callback for the xmlrpc_example.add xmlrpc method.
 *
 * Now we define the custom callbacks replacing the original defined by the
 * altered methods: xmlrpc_example.add and _xmlrpc_example.subtract. These
 * new callbacks will not check if the result of the operation is within the
 * limits defined by the server and will always return value of the operation.
 *
 * @param int $num1
 *   First number.
 * @param int $num2
 *   Second number.
 *
 * @return int
 *   The sum of the arguments
 */
function _xmlrpc_example_alter_add($num1, $num2) {
  return $num1 + $num2;
}

/**
 * Return the difference of the two arguments without limit checking.
 *
 * This is the replacement callback for xmlrpc_example.subtract xmlrpc method.
 *
 * @param int $num1
 *   First number.
 * @param int $num2
 *   Second number.
 *
 * @return int
 *   The difference of the two arguments
 */
function _xmlrpc_example_alter_subtract($num1, $num2) {
  return $num1 - $num2;
}

/**
 * @} End of "defgroup xmlrpc_example".
 */

Functions

Namesort descending Description
xmlrpc_example_xmlrpc Implements hook_xmlrpc().
xmlrpc_example_xmlrpc_alter Implements hook_xmlrpc_alter().
_xmlrpc_example_alter_add Sum the two arguments without limit checking.
_xmlrpc_example_alter_subtract Return the difference of the two arguments without limit checking.
_xmlrpc_example_server_add This is the callback for the xmlrpc_example.add method.
_xmlrpc_example_server_subtract This is the callback for the xmlrpc_example.subtract xmlrpc method.