无法阻止使用SAVE_POST触发两次的函数

时间:2018-07-15 作者:Ben H

我正在使用save_post 用于在用户更新帖子时发送电子邮件的功能。这是发射两次,我知道这是由于后期修订和自动保存。

我试图通过包装我的wp_mail 在条件语句中,但仍会激发两次。我需要做哪些调整以确保在用户更新帖子时只触发一次?

function updated_search_notification($post_id)
{

    $post_type = get_post_type($post_id);
    if ($post_type === \'utility-search\') {

        if ((wp_is_post_revision($post_id)) || (wp_is_post_autosave($post_id))) {
            // post is autosave
        } else {

            // Message Variables
            $siteurl                 = get_option(\'siteurl\');
            $post_url                = \'\' . $siteurl . \'/wp-admin/post.php?post=\' . $post_id . \'&action=edit\';
            $new_search_name         = \'\';
            //$new_search_email = get_option( \'new_search_email\' );
            $new_search_email        = \'[email]\';
            $utility_search_customer = \'\';
            $subject                 = \'Your search has been updated\';

            // Message Contents
            $message = "[Message Contents]";


            // Send Email    
            wp_mail($new_search_email, $subject, $message);
        }
    }


}
add_action(\'save_post\', \'updated_search_notification\', 10, 3);

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

首先,您可以使用此挂钩仅针对一个自定义类型:
https://developer.wordpress.org/reference/hooks/save_post_post-post_type/

该挂钩(和save_post) 第一次单击“新建…”时调用然后用调用钩子$update = FALSE.

然后,要仅在对象更新时发送电子邮件,可以测试$update 像这样:

const UTILITY_SEARCH_POST_TYPE = "utility-search";


add_action("save_post_" . UTILITY_SEARCH_POST_TYPE, function ($post_ID, $post, $update) {

    if (wp_is_post_autosave($post_ID)) {
        return;
    }

    if (!$update) { // if new object
        return;
    }


    // preparing e-mail
    ...

    // sending e-mail
    wp_mail(...);


}, 10, 3);

SO网友:Uriahs Victor

批准的答案对我不起作用。我最后尝试了几个条件,但电子邮件仍会被发送两次:

function xxx_send_mail($id, $post, $update){  

                if (defined(\'DOING_AUTOSAVE\') && DOING_AUTOSAVE ) {
                    return;
                }

                if (wp_is_post_revision($id)) {
                    return;
                }

                if (wp_is_post_autosave($id)) {
                    return;
                }

                // if new post
                if (!$update) {
                    return;
                }

                wp_mail(\'john@doe.com\', \'The subject\', \'The message\');
         }
add_action( \'save_post_{the_post_type}\', \'xxx_send_mail\', 10, 3 );
我最终通过添加一个由WP提供的方便函数来解决这个问题,该函数名为did_action():

    function xxx_send_mail($id, $post, $update){  

                        if (defined(\'DOING_AUTOSAVE\') && DOING_AUTOSAVE ) {
                            return;
                        }

                        if (wp_is_post_revision($id)) {
                            return;
                        }

                        if (wp_is_post_autosave($id)) {
                            return;
                        }

                        // if new post
                        if (!$update) {
                            return;
                        }

                $times = did_action(\'save_post_{the_post_type}\');
                if( $times === 1){
                        wp_mail(\'john@doe.com\', \'The subject\', \'The message\');
                 }
    }
add_action( \'save_post_{the_post_type}\', \'xxx_send_mail\', 10, 3 );
希望这对某人有帮助

SO网友:Atlas_Gondal

在函数中尝试以下代码:

if ( defined( \'DOING_AUTOSAVE\' ) && DOING_AUTOSAVE ) return;
或者,您可以使用publish_post 钩如果您只想在post状态为publish时触发此功能。

SO网友:Muhammad Saqib Sarwar

已经批准的答案对我来说并不适用,@Nico Pernice的评论起到了帮助作用。

如果代码中的条件如下所示:

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

    // Check if it is a REST Request
    if ( defined( \'REST_REQUEST\' ) && REST_REQUEST ) {
        return;
    }

    // Check if it is an autosave or a revision.
    if ( wp_is_post_autosave( $post_id ) || wp_is_post_revision( $post_id ) ) {
        return;
    }

    // Check if it is a new post
    if ( ! $update ) {
        return;
    }

    // my reseting code...

}

add_action( \'save_post_cpt\', \'reset_cpt_expire\', 10,3 );

结束