如何在需要时验证XML-RPC帖子的创建和取消?

时间:2014-08-09 作者:Vallieres

我有一个IFTTT recipe 这会在某些情况下为我创建帖子,但出于某种奇怪的原因,它会创建三个,有时是四个内容相同的帖子。

我想添加一个add_action 钩住/回调以验证新帖子的内容,如果已经存在,则取消该帖子,或将其移动到垃圾桶或类似的地方。

我找到了xmlrpc_prepare_post 但我想我不能从那里取消它。除非我可以更新某些属性并将其设置为垃圾?

Update.

我尝试了以下操作,它只会进入xmlrpc\\u调用,而不会进入xmlrpc\\u wp\\u insert\\u post\\u meta。我甚至添加了一个硬编码的add\\u 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\\u wp\\u insert\\u post\\u data”,但它从不执行hueman\\u xmlrpc\\u wp\\u insert\\u post\\u data函数…:(

3 个回复
最合适的回答,由SO网友:birgire 整理而成

看起来像xmlrpc_prepare_post 过滤器仅应用于wp_getPostwp_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 过滤器。

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;  
}
在这里,我们尝试在wp.newPost 呼叫。如果我们找到一个,我们加上ID$post_data 数组,因此它将被更新。

请注意,我们还可以修改post_status 改为:

    $post_data[\'post_status\'] = \'trash\'; 
因此,所有额外的插入都被定向到垃圾桶。

你也可以试着create your own 插入方法xmlrpc_methods 滤器

我希望您可以根据自己的需要对此进行修改,前提是这会起作用;-)

Update: 我现在已经测试了这个想法,它是有效的,我既可以丢弃重复的帖子,也可以直接更新。

感谢@DavidPeterson在我在WPSE编辑器中编辑代码时注意到我愚蠢的PHP语法错误;-)

SO网友:Brynner Ferreira

在wp includes/class wp xmlrpc服务器中。php文件

在函数mw\\u 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);
    */
}

SO网友:Juanma Rodríguez

以前的解决方案都不适用于我(可能是因为我正在使用metaWeblog.newPost

所以我做了自己的:

1-复制xmlrpc。php并重命名为xmlrpc2。php以防止WordPress更新。

2-将代码粘贴在此部分下方:

/** Include the bootstrap for setting up WordPress environment */
require_once __DIR__ . \'/wp-load.php\';
粘贴此代码以防止标题重复:

$mixml = file_get_contents(\'php://input\');
$mixml2 = simplexml_load_string($mixml);
$json = json_encode($mixml2);

if ( ! is_admin() ) {
    require_once( ABSPATH . \'wp-admin/includes/post.php\' );
}

$jsonIterator = new RecursiveIteratorIterator(
    new RecursiveArrayIterator(json_decode($json, TRUE)),
    RecursiveIteratorIterator::SELF_FIRST);

$nextok=false;
//Sorry for the noob parsing :)
foreach ($jsonIterator as $key => $val) {   
    if ($val=="title") $nextok=true;    
    if (($key=="string")&&($nextok)) { 
        $nextok=false;      
        $post_id = post_exists($val);
        //already exists, so I break the posting with exit
        if ($post_id) exit;                             
    }                   
}
Explanation:

读取XMLRPC输入post_exists 稍后exit sonothing已发布您可以修改原始xmlrpc.php 文件,但您可能会在将来的更新中丢失更改。

正在重命名xmlrpc。建议使用php文件,因为某些服务器会阻止该文件路径,并且一些暴力攻击会以该路径为目标。

结束

相关推荐

如果Have_Posts包含来自某一类别的帖子

这个问题现在终于由我自己解决了。在本文末尾找到解决方案。问题简而言之:How can i ask in my WP template, IF the whole array of have_posts contains any post from a certain category我对标签页进行了编程,以便根据类别将输出分为三个样式框。循环进行了三次,如果我对类别进行了分类,则使用IF。这是一个简化的工作结构草案:<div><ul> <?php if (have_p