<?php
// $Id: xmlrpc_server.module,v 1.6.2.14.2.6 2010/10/26 22:54:57 ocyrus Exp $
/**
 * @file
 *  Enable XML-RPC for services module.
 */

/**
 * Implementation of hook_server_info().
 */
function xmlrpc_server_server_info() {
  return array(
    '#name' => 'XMLRPC',
    '#path' => 'xmlrpc'
  );
}

/**
 * Implementation of hook_server().
 */
function xmlrpc_server_server() {
  require_once './includes/xmlrpc.inc';
  require_once './includes/xmlrpcs.inc';

  // 
  return xmlrpc_server(xmlrpc_server_xmlrpc());
}

/**
 * Return an array of all defined services methods and callbacks.
 *
 * @see xmlrpc_server()
 */
function xmlrpc_server_xmlrpc() {
  $callbacks = array();
  foreach (services_get_all() as $method) {
    $callbacks[$method['method']] = 'xmlrpc_server_call_wrapper';
  }
  return $callbacks;
}

/**
 * Pass XMLRPC server requests to the appropriate services method.
 *
 * This function can take varying parameters as are appropriate to
 * the service in question. 
 */
function xmlrpc_server_call_wrapper() {
  $xmlrpc_server = xmlrpc_server_get();
  $method_name = $xmlrpc_server->message->methodname;
  $args = func_get_args();
  return services_method_call($method_name, $args);
}

/**
 * Implementation of hook_server_error().
 * Takes the error message and wraps it into an XMLRPC error object.
 *
 * @param string $message
 *   The error message.
 * @param int $code
 *   Optional. An error code, these should map to the applicable
 *   http error codes as closely as possible.
 *
 * @return
 *   An error as specified by the XMLRPC server.
 * @see xmlrpc_error() 
 */
function xmlrpc_server_server_error($message, $code = 0) {
  if (!is_array($message)) {
    $message = (array)$message;
  }

  $message = implode(' ', $message);

  if ($code === 0) {
    $matches = array();
    if (preg_match("/\#(\d+)/", $message, $matches)) {
      $code = $matches[1];
    } 
    else {
      $code = 1;
    }
  }
  
  return xmlrpc_error($code, strip_tags($message));
}
