It looks like the xmlrpc_prepare_post
filter is only applied to the output of the wp_getPost
and wp_getRevision
methods of the wp_xmlrpc_server
class.
It would be great if this code line:
do_action( 'xmlrpc_call', 'wp.newPost' );
would be replaced with extra input arguments, for example:
do_action( 'xmlrpc_call', 'wp.newPost', ..., $content_struct );
but that’s not going to happen according to this ticket.
So we need to find another way around this.
Possible workarounds:
Here are some untested ideas using the xmlrpc_call
and the xmlrpc_wp_insert_post_data
filters.
Modify input data before it’s inserted with wp_insert_posts()
:
/**
* Prevent duplicate posts when doing wp.newPost via XML-RPC
*
* @see http://wordpress.stackexchange.com/a/157261/26350
*/
add_action( 'xmlrpc_call', 'wpse_xmlrpc_call' );
function wpse_xmlrpc_call( $method )
{
if( 'wp.newPost' === $method )
add_filter( 'xmlrpc_wp_insert_post_data', 'wpse_xmlrpc_wp_insert_post_data' );
}
function wpse_xmlrpc_wp_insert_post_data( $post_data )
{
// Check if the post title exists:
$tmp = get_page_by_title(
$post_data['post_title'],
OBJECT,
$post_data['post_type']
);
// Go from 'insert' to 'update' mode within wp_insert_post():
if( is_object ( $tmp ) )
$post_data['ID'] = $tmp->ID;
return $post_data;
}
Here we try to find an existing post with the same title, during wp.newPost
calls. If we find one, we add it’s ID
to the $post_data
array, so it will be updated instead.
Notice that we could also have modified the post_status
instead with:
$post_data['post_status'] = 'trash';
so all extra inserts are directed to the trash.
You could also try to create your own insert method via the xmlrpc_methods
filter.
I hope you can modify this to your needs, assuming this will work 😉
Update: I’ve now tested this idea and it works, I can both trash the duplicated posts or update it directly.
Thanks to @DavidPeterson for noticing my silly PHP syntax errors from when I edited the code within the WPSE editor 😉