Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Which WordPress hook fires after save all post data and post meta?

I have a custom post type crm, and i need to send a mail after each crm saved or updated. i user cmb2 for some custom meta like subject, to users etc. I know the save_post hook fires after post save (according to WordPress codex) in my case when i call save_post with two parameters (id and post) the post does not contains update values. here is my code :

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 ); 

And i also try publish_post hook , that works fine when new post created but when updated it works same. I have tried edit_post and post_updated hook also, but i never be able to retrieve my update data.

So how can i solve it? which action hook will give me all the new data? thanks in advance.

like image 836
M. K Hossain Avatar asked Jun 13 '17 10:06

M. K Hossain


People also ask

What is the use of Post_updated hook?

Use this hook whenever you need to compare values before and after the post update. This hook runs after the database update.

How do you save a post on WordPress?

To save a post as a draft, go to your blog's admin area > Posts > Add New. Write the post and when you wish to save your progress, click on Save Draft. To save a page as a draft, go to your blog's admin area > Pages > Add New. Enter the content of the new page and click on Save Draft.

How do I use hooks in WordPress?

To use either, you need to write a custom function known as a Callback , and then register it with a WordPress hook for a specific action or filter. Actions allow you to add data or change how WordPress operates. Actions will run at a specific point in the execution of WordPress Core, plugins, and themes.


2 Answers

The correct and simpler answer is to use the wp_insert_post action.

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

An important distinction of wp_insert_post action is that it is fired after update_post_meta has been called.

There are 3 parameters available - the $update flag tells you if this is a new or updated post.

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

So - to implement your code after all post meta has been updated, use something like this:

add_action('wp_insert_post', 'run_after_post_updated', 10, 3);    
function run_after_post_updated($post_ID, $post, $update ) {
   //  ...
}
like image 159
Dave Hilditch Avatar answered Sep 28 '22 02:09

Dave Hilditch


This might be a bit old but just wanted to give an update since from version 5.6.0 a new hook is available. The hook is wp_after_insert_post and you can find more information here . This hook is triggered after a post is created or updated and all of its terms and meta are updated. You can find an example below:

add_action( 'wp_after_insert_post', 'send_mail_to_user', 90, 4 );

/**
 * Callback to: 'wp_after_insert_post'
 * Fires once a post, its terms and meta data has been saved
 * @param int     $post_id Post ID.
 * @param WP_Post $post    Post object.
 * @param bool    $update  Whether this is an existing post being updated.
 * @param null|WP_Post $post_before Null for new posts, the WP_Post object prior to the update for updated posts.
 *
 */
public static function sync_product_registrations_on_update( $post_id, $post, $update, $post_before ) {

    if ( 'post' !== $post->post_type ) {
        //Only to process the below when post type is 'post' else return
        return;
    }

    if ( ! in_array( $post->post_status, [ 'private', 'publish' ] ) ) {
        //To only process when status is private or publish
        return;
    }

    //The rest of your code goes here


}

like image 39
Omar Tanti Avatar answered Sep 28 '22 03:09

Omar Tanti