I have tried using many hooks to achieve this. I don't want one of my post meta to be updated when we update post.

I tried doing something like :

add_filter( 'update_post_metadata', 'wpse_163859', 10, 5 );
function wpse_163859( $check, $object_id, $meta_key, $meta_value, $prev_value )
    return false;

I tried looking at meta.php in wp-includes, tried whole day with lots of code, appreciate any help.


How to stop WordPress from updating the post meta

Prior to updating meta data, WordPress fires the filter "update_{$meta_type}_metadata". This is a dynamic filter that depends upon the post type that the meta data is attached to. For instance, the update_post_metadata will fire prior to the updating of a post post_type. Likewise, update_page_metadata will fire prior to updating the page metadata.

One problem could be that your post type is not a post, in which case the hook will never fire. The code you provide should short circuit the updating of all post meta data.

Another likely scenario is that there is another plugin or theme that is hooking into update_post_metadata after you. In your code, you're hooking in at a priority of 10. You can hook into the event at a later time such as 9999. Other functions/methods hooked to this filter would run before yours and you essentially override them.

add_filter( 'update_post_metadata', 'wpse_249566', 9999, 5 );
function wpse_249566( $check, $object_id, $meta_key, $meta_value, $prev_value ) {
  //* Return true or false depending on if the meta_value is empty
  return '' === $meta_value ? false : true;

If neither of those solve the issue, then the only other possible problem I can see is that you're adding the filter after WordPress has processed the update_post_metadata hook.

If nothing seems to be working and you want to intercept all metadata prior to being inserted into the database, for instance to test whether the hooks are actually firing, then you can use something like this.

//* Hook into admin_init to add filters to wp-admin
add_action( 'admin_init', function() {
  //* Basically foreach $post_type
  array_map( function( $post_type ) {
    //* Add a filter for when each of the post_type metadata updates
    add_filter( "update_{$post_type}_metadata", function(){ 
      //* Add action to wp_head to alert us
      add_action( 'wp_head', function() use ( $post_type ) {
        print "alert( \"Prevented $post_type metadata from updating.\" );"
      return false;
    }, 9999 );
  }, array_keys( get_post_types() ) );
  • Good info here Nathan - one correction to note. The dynamic portion of the filter name {$meta_type} is listed as the post type in your answer. This is actually the meta type (comment, post, user, etc). – jdm2112 Jul 15 '19 at 18:26

Your Answer

