Reading a WordPress blog using XML-RPC

No matter where I look, I just can’t find a way to fully connect my app to WordPress. What I’d like to do is: show recent articles (published, of course) and older ones when you’re not logged in and facilitate writing comments for users that are.

It just looks like I have to pull the blog articles from RSS (but what about the text below ‘Read More…’?), and then use XML-RPC* to comment on the articles. Is that the way, or does anyone have a better solution? (*metaWeblog.getRecentPosts isn’t always available on WP)

Read More

I don’t have a lot to say about the implementation of the blog in question, though I could ask the owner to install some plugins. Such as WP-RESTful.

Please point me in the right direction to look, because I’ve spent days searching for a solution that should be simple but just doesn’t seem to be that way. Thanks!

Related posts

Leave a Reply

2 comments

  1. The WordPress mobile team has a repository for the XML-RPC parser they use. It’s fairly simple to implement and use. It consists of a XMLRPCDecode and XMLRPCEncoder.

    https://github.com/wordpress-mobile/wpxmlrpc

    EDIT

    XML-RPC in WordPress is intended for posting. The functionalities for getting posts are quite limited because the WordPress implementation uses wp_get_recent_posts() in the wp.getPosts method. I made the function better by adopting the wp_getPosts method in class-wp-xmlrpc-server.php and replacing wp_get_recent_posts by get_posts. So I can use all parameters like in Wp_Query class.

    The xmlrpc_method filter is then used to override the built in methods. I could post the code, if you want.

    EDIT II

    Nevermind, I’ll post the code… 🙂

    include_once(ABSPATH . 'wp-admin/includes/admin.php');
    
    include_once(ABSPATH . WPINC . '/post.php');
    include_once(ABSPATH . WPINC . '/class-IXR.php');
    include_once(ABSPATH . WPINC . '/class-wp-xmlrpc-server.php');
    
    class jw_xmlrpc_server extends wp_xmlrpc_server {
        function __construct($wp_xmlrpc_server) {
            parent::__construct();
    
            foreach(get_object_vars($wp_xmlrpc_server) as $key => $val) {
                $wp_xmlrpc_server->key = $val;
            }
        }
    
        public function minimum_args($args, $count) {
            return parent::minimum_args($args, $count);
        }
    
        public function _prepare_post($post, $fields) {
            return parent::_prepare_post($post, $fields);
        }
    }
    
    class WP_Post_Converter {
        public function to_array($post) {
            $array = array();
    
            foreach(get_object_vars($post) as $key => $val) {
                $array[$key] = $val;
            }
    
            return $array;
        }
    }
    
    function wp_getPosts($args) {
        global $wp_xmlrpc_server;
        $wp_server_save = $wp_xmlrpc_server;
        $wp_xmlrpc_server = new jw_xmlrpc_server($wp_xmlrpc_server);
    
        if (!$wp_xmlrpc_server->minimum_args($args, 3)) {
            return $wp_xmlrpc_server->error;
        }
    
        $wp_xmlrpc_server->escape($args);
    
        $blog_id    = (int) $args[0];
        $username   = $args[1];
        $password   = $args[2];
        $filter     = isset( $args[3] ) ? $args[3] : array();
    
        if (isset($args[4])) {
            $fields = $args[4];
        }
        else {
            $fields = apply_filters('xmlrpc_default_post_fields', array('post', 'terms', 'custom_fields'), 'wp.getPosts');
        }
    
        if (!$user = $wp_xmlrpc_server->login($username, $password)) {
            return $wp_xmlrpc_server->error;
        }
    
        do_action('xmlrpc_call', 'wp.getPosts');
    
        if (isset($filter['post_type'])) {
            $post_type = get_post_type_object($filter['post_type']);
    
            if (!((bool)$post_type)) {
                return new IXR_Error(403, __('The post type specified is not valid'));
            }
        }
        else {
            $post_type = get_post_type_object('post');
        }
    
        if (!current_user_can($post_type->cap->edit_posts)) {
            return new IXR_Error(401, __('Sorry, you are not allowed to edit posts in this post type'));
        }
    
        $filter['post_type'] = $post_type->name;
    
    //  $posts_list = wp_get_recent_posts( $query );
        $posts_list = get_posts($filter);
    
        if (!$posts_list) {
            return array();
        }
    
        // holds all the posts data
        $struct = array();
    
        foreach ($posts_list as $post) {
            $post = WP_Post_Converter::to_array($post);
            $post_type = get_post_type_object( $post['post_type'] );
    
            if (!current_user_can($post_type->cap->edit_post, $post['ID'])) {
                continue;
            }
    
            $struct[] = $wp_xmlrpc_server->_prepare_post($post, $fields);
        }
    
        $wp_xmlrpc_server = $wp_server_save;
    
        return $struct;
    }
    
    function wp_get_categories($args) {
        global $wp_xmlrpc_server;
        $wp_server_save = $wp_xmlrpc_server;
        $wp_xmlrpc_server = new jw_xmlrpc_server($wp_xmlrpc_server);
    
        $wp_xmlrpc_server->escape($args);
    
        $blog_ID   = (int) $args[0];
        $username  = $args[1];
        $password  = $args[2];
    
        if (!$user = $wp_xmlrpc_server->login($username, $password)) {
            return $wp_xmlrpc_server->error;
        }
    
        if (!current_user_can('edit_posts')) {
            return new IXR_Error(401, __('Sorry, you must be able to edit posts on this site in order to view categories.'));
        }
    
        do_action('xmlrpc_call', 'metaWeblog.getCategories');
    
        $categories_struct = array();
    
        if ($cats = get_categories(array('get' => 'all'))) {
            foreach ($cats as $cat) {
                $struct['categoryId'] = $cat->term_id;
                $struct['parentId'] = $cat->parent;
                $struct['postCount'] = $cat->count;
                $struct['description'] = $cat->name;
                $struct['categoryDescription'] = $cat->description;
                $struct['categoryName'] = $cat->name;
                $struct['htmlUrl'] = esc_html(get_category_link($cat->term_id));
                $struct['rssUrl'] = esc_html(get_category_feed_link($cat->term_id, 'rss2'));
    
                $categories_struct[] = $struct;
            }
        }
    
        $wp_xmlrpc_server = $wp_server_save;
    
        return $categories_struct;
    }
    
    function wp_method_setter($methods) {
        $methods['wp.getPosts'] = 'wp_getPosts';
        $methods['wp.getCategories'] = 'wp_get_categories';
        return $methods;
    }
    add_filter('xmlrpc_methods', 'wp_method_setter');
    
  2. I think xmlrpc is the way to go, that’s the way WP’s own app connects for instance. Why don’t you use it to get the posts as well, why use RSS for that?