<?
/**
* Exit the script with an error message.
*/
function wrapper_fatal_error($err) {
header("Status: 404 $err");
echo $err;
error_log($err);
exit();
}
header('Content-Type: text/xml');
// header('Content-Type: text/plain');
// -- locate the class and create class instance ------------------------------
// we must have this variable available
if (isset($HTTP_SERVER_VARS['PATH_INFO']) == false) {
wrapper_fatal_error('Class and constructor data not available.');
}
// get the name of the class and the initialisers
$init_parameters = explode('/', substr($HTTP_SERVER_VARS['PATH_INFO'], 1));
if (count($init_parameters) < 1) {
wrapper_fatal_error('Class name not defined.');
}
$class_name = array_shift($init_parameters);
// load the class data
@include_once("./class." . $class_name . ".php");
if (class_exists($class_name) == false) {
wrapper_fatal_error("Class '$class_name' cannot be found.");
}
// create the object
$x = '$class_instance = new ' . $class_name . '(';
$i = 0;
foreach($init_parameters as $parameter) {
if ($i != 0) $x .= ', ';
$i++;
$x .= "'$parameter'";
}
$x .= ');';
@eval($x);
// have we created an object?
if (isset($class_instance) == false) {
wrapper_fatal_error("Could not create the object.");
}
// init the object now, but only if the method is
// defined; this will give the object a chance to
// return false if something is wrong
if (method_exists($class_instance, '_init')) {
// the _init method must verify all parameters
// and return false if an error is found (say, not enough
// parameters defined
$r = @call_user_method_array('_init', $class_instance, $init_parameters);
if ($r == false) {
wrapper_fatal_error('Object initialisation failed.');
}
}
// -- locate or create a request ----------------------------------------------
// is it GET or POST
// if it is GET - use URL variables
// otherwise expect XML-RPC payload
if ($HTTP_SERVER_VARS['REQUEST_METHOD'] == 'GET') {
// get the method name from the parameter list
$method_name = strtolower($HTTP_GET_VARS['_method']);
// construct the XML-RPC payload
// enumerate GET parameters and transform
// them into XML
$request_xml = '<?xml version="1.0"?>';
$request_xml .= '<methodCall>';
$request_xml .= '<methodName>';
// todo: escape $method_name
$request_xml .= $method_name;
$request_xml .= '</methodName>';
$request_xml .= '<params>';
// params go here
foreach($HTTP_GET_VARS as $key => $value) {
// skip over our internal method
if ($key == '_method') continue;
// todo: escape parameter values
$request_xml .= '<param><string>' . $value . '</string></param>';
}
$request_xml .= '</params>';
$request_xml .= '</methodCall>';
} else
if ($HTTP_SERVER_VARS['REQUEST_METHOD'] == 'POST') {
// with a POST method, we always assume XML-RPC payload
// copy the payload from the raw POST data
$request_xml = $HTTP_RAW_POST_DATA;
// todo: lowercase the method name
} else {
// fatal error, unsupported access method
wrapper_fatal_error("Unsuported method");
}
// -- actual XML-RPC processing -----------------------------------------------
/**
* All XML-RPC method calls go through this
* gateway function.
*/
function xmlrpc_gateway($method_name, $params, $app_data) {
global $class_instance;
return call_user_method_array($method_name, $class_instance, $params);
}
// create a server instance
$xmlrpc_server = xmlrpc_server_create();
if($xmlrpc_server == false) {
// could not create the server
// todo:
}
// register public class methods
// with the xmlrpc server
$class_methods = get_class_methods($class_name);
foreach($class_methods as $method_name) {
// ignore private methods
// private methods are those
// starting with an underscore
if (ereg("^_", $method_name)) continue;
// register the method
xmlrpc_server_register_method($xmlrpc_server, $method_name, 'xmlrpc_gateway');
}
// execute the method call
$foo = @xmlrpc_server_call_method($xmlrpc_server, $request_xml, '', array(output_type => "xml"));
echo $foo;
// free server resources
xmlrpc_server_destroy($xmlrpc_server);
?>
|