私は IFTTTレシピ を持っていることがありますが、奇妙な理由でそれは同じ内容の記事を3つ、場合によっては4つ作成します。
私はadd_action
フック/コールバックを追加して新しい投稿になるものを検証し、それが既に存在する場合は投稿をキャンセルするか、ゴミ箱などに移動します。
私はxmlrpc_prepare_post
を見つけましたが、そこからキャンセルすることはできないと思います。ある属性を更新してそれをゴミ箱に設定できないのであれば?
Update.
私は以下を試しました、そして、それは今までxmlrpc_callに入るだけです、しかし決してxmlrpc_wp_insert_post_metaの中に決して入ったことがありません。私はハードコードされたadd_filter呼び出しさえ追加しました(if newPostの場合だけではありません)、そして私のログはそのようなロギングメッセージを決して表示しません。
これがコードです:
function hueman_xmlrpc_call( $method )
{
error_log("XMLRPC | hueman_xmlrpc_call Method = $method \n" , 3, '/home/.../debug.log');
if( 'wp.newPost' === $method || 'metaWeblog.newPost' === $method )
{
error_log("XMLRPC | hueman_xmlrpc_call method = " . $method . " \n" , 3, '/home/.../debug.log');
add_filter( 'xmlrpc_wp_insert_post_data', 'hueman_xmlrpc_wp_insert_post_data' );
}
}
add_action('xmlrpc_call', 'hueman_xmlrpc_call', 1 );
add_filter( 'xmlrpc_wp_insert_post_data', 'hueman_xmlrpc_wp_insert_post_data' );
function hueman_xmlrpc_wp_insert_post_data( $post_data )
{
error_log("XMLRPC | hueman_xmlrpc_wp_insert_post_data \n" , 3, '/home/.../debug.log');
// Check if the post title exists:
$tmp = get_page_by_title(
$post_data['post_title'],
OBJECT,
$post_data['post_type']
);
if( is_object ( $tmp ) )
{
// Go from 'insert' to 'update' mode within wp_insert_post():
//$post_data['ID'] = $tmp->ID;
$post_data['post_status'] = 'trash';
error_log("XMLRPC | hueman_xmlrpc_wp_insert_post_data I TRASHED IT! \n" , 3, '/home/.../debug.log');
}
return $post_data;
}
ログには、このようなログステートメントがあります。
XMLRPC | hueman_xmlrpc_call Method = mt.supportedMethods
XMLRPC | hueman_xmlrpc_call Method = metaWeblog.getRecentPosts
XMLRPC | hueman_xmlrpc_call Method = mt.supportedMethods
XMLRPC | hueman_xmlrpc_call Method = metaWeblog.getRecentPosts
XMLRPC | hueman_xmlrpc_call Method = mt.supportedMethods
XMLRPC | hueman_xmlrpc_call Method = metaWeblog.getRecentPosts
XMLRPC | hueman_xmlrpc_call Method = metaWeblog.getCategories
XMLRPC | hueman_xmlrpc_call Method = metaWeblog.newPost
XMLRPC | hueman_xmlrpc_call method = metaWeblog.newPost
その後、記事が作成されたときに追加した他のフィルタが表示されます。私はたぶんそこで記事を修正することになるでしょうが、私はこのXMLRPCフィルタ/アクションがうまくいくはずであると確信しています。
ログから、私はそれがif newPostの中に入ってフィルタ 'xmlrpc_wp_insert_post_data'を追加するのを見ますが、それはhueman_xmlrpc_wp_insert_post_data関数を決して実行しません... :(
xmlrpc_prepare_post
フィルタはwp_getPost
クラスのwp_getRevision
およびwp_xmlrpc_server
メソッドの出力にのみ適用されるようです。
このコード行があればそれは素晴らしいでしょう:
do_action( 'xmlrpc_call', 'wp.newPost' );
以下のように、追加の入力引数に置き換えられます。
do_action( 'xmlrpc_call', 'wp.newPost', ..., $content_struct );
しかし、これは ticket に従っては起こらないでしょう。
だから我々はこれを回避する別の方法を見つける必要があります。
これはxmlrpc_call
とxmlrpc_wp_insert_post_data
フィルターを使った未検証のアイデアです。
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;
}
ここでは、wp.newPost
呼び出し中に、同じタイトルの既存の投稿を見つけようとします。見つかった場合は、それをID
を$post_data
配列に追加するので、代わりに更新されます。
代わりにpost_status
を変更することもできます。
$post_data['post_status'] = 'trash';
そのため、追加の挿入はすべて trash に送られます。
xmlrpc_methods
フィルタを介して 独自に作成 insert methodを試すこともできます。
これがうまくいくと仮定して、あなたのニーズに合わせてこれを変更できることを願っています;-)
Update:私は今このアイディアをテストしました、そしてそれはうまくいきます、私は両方とも重複したポストをゴミ箱に入れるか、それを直接更新することができます。
WPSEエディタでコードを編集したときの愚かなPHP構文エラーに気付いた@DavidPetersonに感謝します;-)
Wp-includes/class-wp-xmlrpc-server.phpファイル内
これらの行の後の関数mw_newPost()の中:
$post_title = isset( $content_struct['title'] ) ? $content_struct['title'] : null;
$post_content = isset( $content_struct['description'] ) ? $content_struct['description'] : null;
追加:
global $wpdb;
$some_post = $wpdb->get_row("
SELECT ID
FROM {$wpdb->posts}
WHERE post_title = '{$post_title}'
");
そしてステートメントを作成します。
if (!empty($some_post->ID) and $some_post->ID > 0) {
return 0;
} else {
// the rest of the code that already exists in the function
/*
$post_status = $publish ? 'publish' : 'draft';
...
return strval($post_ID);
*/
}