WordPress函数将一个帖子保存两次并更新所有帖子

时间:2018-07-28 作者:Gregory Schultz

我对自定义函数有问题。此函数用于统计帖子并为该帖子分配一个数字。然后将数字保存到自定义字段,然后将永久链接更新到帖子。

我的问题是:

1) 。保存帖子时,会将帖子保存两次(显示为两次修订)。我正试图找到一种方法,这样它就可以保存一次。

2) 。我还试图找到一种方法,使函数只工作一次。我注意到以前的帖子正在被编辑,虽然它们保持不变,但它们确实出现了很多修改。例如:如果我有5篇文章,第一篇文章将显示10个修订。

这是我的代码:

// opens a function
function updateNumbers( $post_id ){

// sets global 
global $pagenow;

// if current page is a new post and in the post CPT
if ($pagenow == \'post.php\' &&  \'post\' == get_post_type()) {

    // counts all posts
    global $wpdb;
    $querystr = "SELECT $wpdb->posts.* FROM $wpdb->posts WHERE
    $wpdb->posts.post_status = \'publish\' AND $wpdb->posts.post_type = \'post\' ";
    $pageposts = $wpdb->get_results($querystr, OBJECT);
    $counts = 0 ;
    if ($pageposts):
    foreach ($pageposts as $post):
    $counts++;

    // saves the number to a custom field
    add_post_meta($post->ID, \'incr_number\', $counts, true);
    remove_action(\'save_post\', \'updateNumbers\');
    wp_update_post(array(\'ID\' => $post->ID,\'post_name\' => get_post_meta($post->ID,\'incr_number\', true)));
    endforeach;
    endif;
}}

// close the function and save
add_action(\'save_post\', \'updateNumbers\');

2 个回复
最合适的回答,由SO网友:Hồ Trọng Linh Ân 整理而成

它是重复的,因为当您运行wp_update_post(), 它将使用wp_insert_post() 功能和行动save_post 将再次运行。

请使用过滤器wp_insert_post_data 保存前筛选值。https://codex.wordpress.org/Plugin_API/Filter_Reference/wp_insert_post_data

示例:

function wpse309780_filter_post_data($data , $postarr) {
    $data[\'post_name\'] = wp_count_posts( \'post\' )->publish;
    return $data;
}

add_filter( \'wp_insert_post_data\', \'wpse309780_filter_post_data\' );

SO网友:Andrius Vlasovas

始终依靠WordPress Codex。

在这种情况下,您使用的是“save\\u post”操作挂钩,因此我们可以参考WordPress CodexWordPress Code Reference 第页。

只需检查这些链接,我们就可以看到此操作有3个参数,可以在函数中使用:$post\\u ID、$post、$update。

为了使用最后一个参数$update 例如,我们必须设置$accepted_args 中的参数\'save_post\' 钩这是最后一个数字,可以说,在您正在声明和修改的操作中,操作如下所示:add\\u action(\'save\\u post\',\'updateNumbers\',10,3);

现在,我们还看到最后一个数字之前的数字“10”-这是决定何时启动行动的优先级。

因此,如果我们想更早地启动我们的操作,我们将修改我们的操作:add\\u action(\'save\\u post\',\'updateNumbers\',5,3);

看看你的功能,有很多方法可以改进它。虽然问题的核心很清楚,但有几种方法可以用来优化函数。因为目前,您是:

执行一个操作,该操作在帖子保存或更新时触发(这很好);

在你的函数中,你可以得到数据库中的所有帖子(看起来还行);

检查数据库中是否有带有if ($pageposts): (在某些情况下可以跳过,但让我们保留它);

然后对数据库中找到的每个帖子执行以下操作(是的,不仅仅是这篇,而是每个帖子,所以基本上,当您更新单个帖子时,实际上是在更新查询中的所有帖子,这就是为什么您也会为其他帖子生成多个修订的原因-这很糟糕,因为您还表示不希望这样):

您正在用当前$count 价值

通过删除\'save_post\' 行动,这是伟大的,因为你打电话\'wp_update_post\' 也将调用\'save_post\', 如果不删除挂钩函数,则会导致无限循环。但是,您打电话后忘记重新挂接\'wp_update_post\'.

您正在使用自定义元字段的值更新post slug。

你应该澄清几件事:

您正在使用\'incr_number\' 其他地方的自定义字段,还是只是为了更新slug?如果您没有在其他任何地方使用此自定义字段,则应将其删除。请记住,这个自定义元字段与post-slug完全相同,您应该将其丢弃,并在需要时用post-slug的值替换。也就是说,如果在最初将Slug设置为数字后不打算更改Slug。

我看到评论:

//如果当前页面是新帖子并且在帖子CPT中

您是否打算仅在新帖子发布时更新permalink?那么我不会说您的实现是这样做的最佳选择。实际上,这就是你要使用第三个参数的地方$update 这一行动提供了。

这就是我将如何修改您的功能(然而,由于缺乏信息,并且没有明确的行动目标,这可能不是最终的)。

// Update permalink of newly created Post
add_action(\'save_post\', \'theme_save_post_number_to_slug\', 12, 3);

function theme_save_post_number_to_slug($post_id, $post, $update) {

    $post_type = get_post_type($post_id);

    // terminate early if post type is not \'post\' and if we are updating post object and not creating it.
    if ( "post" != $post_type && !$update )
        return;

    global $wpdb;
    $count = 0 ;

    // Fetches all posts with status \'publish\' from the database
    $querystr = "SELECT $wpdb->posts.* FROM $wpdb->posts WHERE
    $wpdb->posts.post_status = \'publish\' AND $wpdb->posts.post_type = \'post\' ";
    $dbPosts = $wpdb->get_results($querystr, OBJECT);

    if ($dbPosts) {
        foreach ($dbPosts as $p):
            $count++;

            // saves the number to a custom field
            add_post_meta($p->ID, \'incr_number\', $count, true);

            remove_action(\'save_post\', \'theme_save_post_number_to_slug\', 12, 3);
            wp_update_post(array(\'ID\' => $p->ID, \'post_name\' => get_post_meta($p->ID, \'incr_number\', true)));
            add_action(\'save_post\', \'theme_save_post_number_to_slug\', 12, 3);

        endforeach;
    }

}
这个功能还不够完美,因为我不知道你想要实现什么,另外我希望你能完全理解它(这就是我们作为开发人员的成长方式)。

老实说,有很多怪癖可以通过详细的解释来解决。你甚至可以自己问问,然后查阅WordPress Codex。

我希望我至少把你们引向正确的方向。

结束

相关推荐

对WooCommerce的Functions.php更改不起作用

我正在尝试将其添加到函数中。php。在我的另一个站点上的测试实验室中,它可以很好地添加测试信息。但在这个网站上,我试图把它添加到什么都没有发生的情况下。该网站正在使用最新的woocommerce运行一个建筑节俭主题。有什么想法吗?我基本上只是想在每个产品页面上添加一行类似于免责声明但无法添加的文本。add_action(\'woocommerce_before_add_to_cart_form\',\'print_something_below_short_description\');