XML-RPC and Custom Post Types

@keatch is correct that out-of-the-box WP XML-RPC does not support post types other than ‘post’ and ‘page’. However, a quick stroll through the code indicates that this may be relatively easy to change.

In WP 3.0.4, xmlrpc.php, line 1989, we have the function mw_newPost() (which does the heavy lifting). At line 2005 there is an if-else checking the post type, but it would be easy to extend by inserting additional checks starting at line 2021. Then at line 2059 we have a switch($post_type) that would also be easy to extend.

And … that’s about it for insert. At line 2196 the data is wrapped up and inserted, and at line 2213 the custom fields are attached to the post and nothing else seems to care about post_type.

There are probably a few more places to extend for other commands, but just search on post_type (without the ‘$’) and look to see if it will make any difference.

Note well: this is a core WP file and any hacks thereto are going to get overwritten by the next update to core. On the other hand, these are mostly trivial changes and you could make sure that the client notifies you before they do an update to core.


Reply to Comment: Life is more complicated than Rarst’s comment would make it seem. And the excellent answer he pointed to is solving a problem significantly simpler that what your question appears to be asking about. In kongo09’s comment to Rarst’s own answer in that thread he observed that ‘there is probably no help’ coming in this area.

Custom Posts are a bit of an afterthought in the WP code. When you look at the logic in a number of places you see code that originally said “do this thing with a post”. When pages came along that code had to be expanded to deal with posts and pages. And then it had to be expanded again to deal with customs posts. This is a classic programming evolution: 1, 2, many.

The xmlrpc code is one of the places that is stuck at “2” (and sometimes even at “1”). In trying to add functionality to core code, you are stuck choosing between several possible paths, all of which have their downsides.

  1. Submit a request/bug ticket and wait for it to be fixed by the core team. This may take some time and your client may not be willing to wait. Ref. kongo09’s statement.

  2. Fix the code yourself and submit a patch. Reapply your patch with each new update to core while you wait for it to be accepted. This is sort of what I was suggesting, although I handwaved the details. Managing the revisions across possibly conflicting changes will be easier if you use something like Mercurial’s MqMerge. I wouldn’t try this with SVN. Check each merge carefully because this is the type of code that can get totally hosed across revs.

  3. Copy a substantial amount of the core xmlrpc code, make your changes, and hook it in via the xmlrpc_methods filter mentioned in the post he linked to. This means you have effectively forked the code. Although it makes for an “easy update” it is also an easy way to miss crucial security changes made to the code you forked. This is a not insignificant problem as simply googling on “wordpress xmlrpc security” will show you. Note that 3.0.1 and 3.0.2 both had XML security issues.

You’re probably going to be forced to do #3 or #2 in spades because the more you look at the WP section of xmlrpc, the more you realize how haphazard it is regarding what you can do with what type of objects E.g. using the WP xml interface you can only create a page, but the MW method mw_newPost() (invoked by the WP method wp_newPost()) permits new pages or new posts, but not new custom posts — and so it goes. To fully support custom posts will require a significant effort and keeping it in sync with changes to the core may be problematic, regardless of the method you choose.

Update – 2 weeks later: So a friend just asked me a question that was almost exactly the same as Jeremy’s. It forced me to take a really hard look at the XMLRPC code to see how we can make the changes but avoid the “modify core” problem raised by Rarst. It turns out that there are a very large number of undocumented do_action() hooks plus (more importantly for these purposes) a mentioned-but-undocumented apply_filters('xmlrpc_methods', $this->methods); (line 203) that allows for arbitrary modification/addition/deletion of methods.

I still maintain that the XMLRPC code is a swamp, but this particular apply_filter() lets you take a left turn out of the swamp without modifying core code.