Search code examples
phpwordpresshook

Any change in post update inlcuding metadata?


Having code below (given in a class)

class X 
{

    public function __construct() 
    {                    
        add_action( 'post_updated', array( $this, 'datachangecheck' ), 10, 3 );        
    }

    function datachangecheck( $post_id, $post_after, $post_before ) 
    {
        if ( $post_before->post_title != $post_after->post_title )
        {
        //do whatever
        }
        return;
    }   

}

Above works fine when checking if a title has been changed, but is there any away way of managing the same thing when having metadata related to it?

I only want to know if any data has changed (I don't need any returned values). I can't manage to find any hook where I can see like meta_post_before and meta_post_after or similar. Can someone point me into right direction? Thank you!


Solution

  • This was kind of tricky, so I guess someone else might have the same issue so I share some code here and hopefully someone has any help from it :-) I have the most important part in the code below:

     public function __construct() 
     {                    
         add_action( 'post_updated', array( $this, 'datachangecheck' ), 10, 3 );        
     }
    
     /*
     *   datachangecheck
     * 
     *  This function is called upon hook post_updated. 
     *  The function checks if data for updated post has been changed,
     *  and saves a file when data has been changed
     * 
     *  @param string $post_id                      id of post affected
     *  @param WP_Post $post_after          WP_Post after post has been updated
     *  @param WP_Post $post_before       WP_Post before post has been updated
     *  @return N/A
     *               
     */   
    function datachangecheck( $post_id, $post_after, $post_before ) 
    {
        //Cast postobjects into arrays, so comparision is possible with builtin-php functions        
        $spf = (array)$post_before;
        $spa = (array)$post_after;
    
        //These would differ every update. so remove them for possible comparision
        unset ( $spf['post_modified']);
        unset ( $spf['post_modified_gmt']);
        unset ( $spa['post_modified']);
        unset ( $spa['post_modified_gmt']);
    
        //Check if any difference between arrays (if empty no difference)
        //If not empty, save file that tells plugin that data has been changed
        $ard = array_diff ( $spf, $spa);            
        if ( !empty ( $ard ) )
        {               
            $this->datahaschanged_save();
        }
        else 
        {
            //No change of post native data, check if any metapost data has been changed
            //Remove edit_last and edit_lock because they could differ without data being changed            
            $this->metadata_before = get_post_meta( $post_id );
            unset ( $this->metadata_before['_edit_last']);
            unset ( $this->metadata_before['_edit_lock']);
            add_action('updated_post_meta', array( $this, 'checkmetadata_after'), 10, 2);                       
        }        
        return;
    }     
    
    
    /*
     *   checkmetadata_after
     * 
     *  This function is called upon hook updated_post_meta when data has been update, but no change in native post data
     *  has been made and saves a file when data has been changed
     * 
     *  @param string $post_id                      id of post affected
     *  @param WP_Post $post_after          WP_Post after post has been updated
     *  @param WP_Post $post_before       WP_Post before post has been updated
     *  @return N/A
     *               
     */   
    function checkmetadata_after( $meta_id, $post_id )
    {
        //Because updated_post_meta is used, now we can grab the actual updated values
        //Remove edit_last and edit_lock because they could differ without data being changed
        $this->metadata_after = get_post_meta( $post_id );
        unset ( $this->metadata_after['_edit_last']);
        unset ( $this->metadata_after['_edit_lock']);
    
        //Make one-level index arrays of metadata
        //so array_diff works correctly down below
        $arr_mdb = $this->onelevel_array( $this->metadata_before );
        $arr_mda = $this->onelevel_array( $this->metadata_after );
    
        //Compare array with metapost values before and after
        //If not empty, save file that tells plugin that data has been changed
        $ard_metadata = array_diff ( $arr_mdb, $arr_mda );
        if (!empty ( $ard_metadata))
        {
            $this->datahaschanged_save();                         
        }                        
        return;            
    }