skip to Main Content

I am trying to get the $post_before and $post_after objects for comparison when updating a post in WordPress.

However, when I submit the update, the $post_before and $post_after objects are identical and show the updated post object.

add_action('post_updated', [$this, 'comparePosts'], 10, 3);  
function comparePosts($post_ID, $post_after, $post_before)
    {
        echo '<b>Post ID:</b><br />';
        var_dump($post_ID);

        echo '<b>Post Object AFTER update:</b><br />';
        var_dump($post_after->post_name);

        echo '<b>Post Object BEFORE update:</b><br />';
        var_dump($post_before->post_name);
    }

After researching, I have found two related bug tickets https://core.trac.wordpress.org/ticket/47908 and https://core.trac.wordpress.org/ticket/45114.

The Bug is related to the Gutenberg editor’s order of processing the update hooks. The ticket has been closed, but even in the latest version of WordPress [5.9.2], the issue still exists.

I have also tried to use different hooks including pre_post_update, post_updated, save_post but all of them carry the updated post object in $post_before and $post_after. How can I get the real $post_before and $post_after objects.

2

Answers


  1. Just tested this in WordPress 6.0.2(latest) and latest gutenberg plugin and it’s working as expected. Make note post name is the slug, so you must modify slug to see difference.

    Also if that doesn’t work, do a comparison check first before dumping:

    if ($post_after->post_name !== $post_before->post_name) {
        var_dump($post_after->post_name);
        var_dump($post_before->post_name);
    }
    else {
        var_dump('no change')
    }
    

    I see you tried a bunch of hooks but you can also try wp_after_insert_post hook which works well with gutenberg.

    Login or Signup to reply.
  2. I can confirm this known issue is happening on WP 6.0.2 for me.

    You can overcome this by using both pre_post_update and wp_after_insert_post hooks within a class.

    <?php
    class BeforeAfter {
    
        public string $old_post_name = '';
    
        public string $post_name = '';
    
        public function __construct() {
            add_action( 'pre_post_update', array( $this, 'before_update'), 10, 2 );
            add_action( 'wp_after_insert_post', array( $this, 'after_update'), 10, 4 );
        }
    
        public function before_update( $post_ID, $data ): void {
    
            $this->old_post_name = get_the_title( $post_ID );
        }
        
        public function after_update( $post_ID, $post, $update, $post_before ): void {
    
            $this->post_name = get_the_title( $post_ID );
    
            /* Both available */
            var_dump($this->old_post_name);
            var_dump($this->post_name);
        }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search