9

我有一个自定义帖子类型 crm,我需要在每个 crm 保存或更新后发送一封邮件。我使用 cmb2 来获取一些自定义元数据,例如主题、用户等。我知道当我使用两个参数(id 和 post)调用帖子不包含更新值时,在我的情况下,save_post钩子会在保存后触发(根据 WordPress 法典) 。这是我的代码:save_post

function send_mail_to_user($id, $post){
    $crm = $post;
    $user_email = array();
    if($crm->vc_all_vc == 'on'){
        $args = array('orderby' => 'display_name');
        $wp_user_query = new WP_User_Query($args);
        $authors = $wp_user_query->get_results();
        if (!empty($authors)) {
            foreach ($authors as $author) {
                array_push($user_email , $author->user_email );
            }
        } 
    }
    else{
        $to_users = $crm->vc_users;
        $to_program = $crm->vc_program;
        $to_group = $crm->vc_group;
        $to_excode = $crm->vc_ex_code;
        foreach ($to_users as $key => $value) {
            $user_data = get_userdata($value);
            array_push($user_email, $user_data->user_email);
        }
        foreach ($to_program as $key => $value) {
            $users = get_users( array('meta_key'     => 'programs'  ) );
            if($users){ 
                foreach ($users as $index => $data) {
                    if(in_array($value , explode('#', $data->programs))){
                        if(! in_array($data->user_email, $user_email)  )
                        {
                            array_push($user_email, $data->user_email);
                        }
                    }
                }
            }
        }
        foreach($to_group as $group) {
            $term = get_term_by('slug', esc_attr($group), 'user-group');
            $user_ids = get_objects_in_term($term->term_id, 'user-group');
            foreach($user_ids as $user_id){
                $fc_user = get_userdata($user_id);
                if(! in_array($fc_user->user_email, $user_email)  )
                {
                    array_push($user_email, $fc_user->user_email);
                }
            }   
        }
        foreach($to_excode as $codes) {
            $value = explode('*',$codes)[1];
            $users = get_users( array('meta_key'     => 'programs'  ) );
            if($users){ 
                foreach ($users as $index => $data) {
                    if(in_array($value , explode('#', $data->programs))){
                        if(! in_array($data->user_email, $user_email)  )
                        {
                            array_push($user_email, $data->user_email);
                        }
                    }
                }
            }   
        }
    }
    foreach($user_email as $index => $email){
        $to      = $email;
        $subject = $crm->vc_subject;
        $body    = $crm->post_content;
        $headers = array(
        'Content-Type: text/html; charset=UTF-8'
        );
        wp_mail($to, $subject, $body, $headers);
    }
}

add_action( 'save_post', 'send_mail_to_user', 10, 2 ); 

我也尝试publish_post了 hook ,创建新帖子时效果很好,但更新后效果相同。我也尝试过edit_postpost_updated挂钩,但我永远无法检索我的更新数据。

那么我该如何解决呢?哪个动作挂钩会给我所有的新数据?提前致谢。

4

7 回答 7

7

你可以使用这样的东西,

function your_custom_function($meta_id, $post_id, $meta_key='', $meta_value='') {
    if($meta_key=='_edit_lock') {
        // if post meta is updated
    }
}
add_action('updated_post_meta', 'your_custom_function', 10, 4); 
于 2017-12-06T19:15:51.717 回答
4

你可以在你的函数中使用这个save_post钩子。将您的钩子优先级更改为 100,它将为您提供更新的帖子

add_action( 'save_post', 'send_mail_to_user', 100, 2 );
于 2017-06-13T10:29:37.480 回答
4

尝试post_updated使用$post_after对象。 https://codex.wordpress.org/Plugin_API/Action_Reference/post_updated

于 2017-06-13T10:34:05.313 回答
2

您可以使用rest_after_insert_{$this->post_type}钩子(其中$this->post_type替换为帖子类型,例如'post' 或'myposttype')。

感谢 Florian Brinkmann 提供此链接

add_action('rest_after_insert_myposttype', 'myfunction', 10, 3);

function myfunction($post, $request, $creating) {
   // $creating is TRUE if the post is created for the first time,
   // false if it's an update

   //  ...
}

另请参见此处

于 2020-10-28T21:16:42.420 回答
1

一些解决方法是使用 $_POST['meta_field'] 与卫生:

$to_users = $_POST['vc_users'];
$to_program = $_POST['vc_program'];
$to_group = $_POST['vc_group'];
$to_excode = $_POST['vc_ex_code'];

$to_users = sanitize_text_field($to_users);
$to_program = sanitize_text_field($to_program);
$to_group = sanitize_text_field($to_group);
$to_excode = sanitize_text_field($to_excode);

注意字段名称,使用 ACF 会使您使用字段键。

这个问题比乍看起来要复杂得多:

我们的 'post_updated' 挂钩在 post 更新之前运行,因此每次获取元数据的尝试都将使用以前的数据。此外,Wordpress (v5.7.2) 在帖子保存后似乎没有挂钩。

此外,'save_post' 挂钩非常复杂,因为它会为每个保存或创建的帖子(包括修订)运行,并且 $update 布尔值仍然不够可靠。

于 2021-05-30T09:51:42.787 回答
1

您可以使用具有更高优先级的 save_post 操作,以便在保存所有元数据后调用您的函数。

add_action( 'save_post',  'action_woocommerce_update_product', 20, 3 );
Here I have used higher priority 20
于 2021-12-06T10:45:42.200 回答
0

正确和简单的答案是使用wp_insert_post动作。

https://developer.wordpress.org/reference/hooks/wp_insert_post/

wp_insert_post 动作的一个重要区别是它在 update_post_meta 被调用后被触发。

有 3 个参数可用 - $update 标志告诉您这是新帖子还是更新帖子。

do_action( 'wp_insert_post', int $post_ID, WP_Post $post, bool $update )

所以 - 要在所有帖子元已更新后实现您的代码,请使用以下内容:

add_action('wp_insert_post', 'run_after_post_updated', 10, 3);    
function run_after_post_updated($post_ID, $post, $update ) {
   //  ...
}
于 2022-02-09T15:35:35.863 回答