custom XMLRPC method plus authentication of user & WooCommerce order

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.

Leave a Comment