I sent it to you on Twitter, but here it is again.
I made this little class to help me do XML-RPC faster.
abstract class MZAXMLRPC {
protected $calls = Array();
protected $namespace = "myxmlrpc";
function __construct($namespace){
$this->namespace = $namespace;
$reflector = new ReflectionClass($this);
foreach ( $reflector->getMethods(ReflectionMethod::IS_PUBLIC) as $method){
if ($method->isUserDefined() && $method->getDeclaringClass()->name != get_class()){
$this->calls[] = $method->name;
}
}
add_filter('xmlrpc_methods', array($this, 'xmlrpc_methods'));
}
public function xmlrpc_methods($methods)
{
foreach ($this->calls as $call){
$methods[$this->namespace . "." . $call] = array($this, "dispatch");
}
return $methods;
}
public function dispatch($args){
global $wp_xmlrpc_server;
$username = $args[1];
$password = $args[2];
$data = $args[3];
if ( !$wp_xmlrpc_server->login($username, $password) )
return $wp_xmlrpc_server->error;
$call = $this->get_called_method();
if (method_exists($this, $call)){
$status = call_user_func_array(array($this, $call), array($data));
return $status;
}else{
return "Method not allowed";
}
}
private function get_called_method(){
global $wp_xmlrpc_server;
$call = $wp_xmlrpc_server->message->methodName;
$pieces = explode(".", $call);
return $pieces[1];
}
}
This is an abstract class. You won’t instantiate objects out of it. What you’ll do is create a new class that inherits from MZAXMLRPC, and in it you’ll make public methods for each XML-RPC call you want to expose.
The constructor uses Reflection to find all the user-defined public methods of the child class that is inheriting from it. Then it will tell WordPress that we’re accepting XML-RPC calls for this methods. The XML-RPC methods are exposed with the name $namespace.$public_method_name.
All those new XML-RPC will arrive to the same method, dispatch. This method will fist validate the user/pass for the remote call, then it will check that effectively there is a method declared to take care of the XML-RPC call. If all validates ok it will dispatch the call to the appropriate method of the child class, passing along all the data that came through the XML-RPC server.
Enough gibberish already! The only thing you need to do is:
class MY_XMLRPC extends MZAXMLRPC{
public function QuoteUpload($data){
if (!isset($data["author"]))
return "Missing 'author' parameter";
if (!isset($data["quote"]))
return "Missing 'quote' parameter";
$author = $data["author"];
$quote = $data["quote"];
$new_post = array(
'post_status' => 'publish',
'post_type' => 'mzaquotes',
'post_title' => $quote
);
$new_post_id = wp_insert_post($new_post);
wp_set_post_terms( $new_post_id, $author, 'quote_author' );
return "OK";
}
}
new MY_XMLRPC('my_function');
This little piece of code will expose a XML-RPC method called my_function.QuoteUpload. The parent class will deal with authentication and WordPress APIs for you.