34

I'm still struggling to get my head around this whole hooking into things, so I'm really stuck on trying to do the following task:

If update_post_meta is fired then check to see if the meta_key is equal to something (I want to trigger some code if a particular meta_key is used). If the meta key I'm looking for then run some code that will need to know the $post->ID of the meta key being updated.

I need to hook into the delete_post_meta too that kind of does the reverse as above.

Can anyone provide me with some example code for hooking into update_post_meta and delete_post_meta?

2 Answers 2

56

The update_post_meta hooks are called from the more generic update_metadata() function, so you might not have found it directly. The three hooks are:

  • update_post_metadata, a filter which allows you to "hijack" the metadata update and do something else. If you hook up a function that returns a boolean, execution stops there and the boolean is returned.
  • update_post_meta, an action that gets called before the data is updated in the database.
  • updated_post_meta, an action that gets called after the data is updated in the database.

If the meta key did not exist in the database yet, update_metadata() passes control to add_metadata(), which has the similar hooks add_post_metadata, add_post_meta, and added_post_meta. This happens before update[d]_post_meta gets called. So if you want to do something when the meta key is added or updated, be sure to hook into both the update* and the add* hooks - but notice that while the updated_* and added_* actions pass similar parameters, update_* and add_* do not (add_post_meta does not pass a meta ID first).

delete_metadata() has similar hooks: delete_post_metadata, delete_post_meta and deleted_post_meta.

Sample code:

add_action( 'added_post_meta', 'wpse16835_after_post_meta', 10, 4 );
add_action( 'updated_post_meta', 'wpse16835_after_post_meta', 10, 4 );
function wpse16835_after_post_meta( $meta_id, $post_id, $meta_key, $meta_value )
{
    if ( 'wpse16835_meta_key' == $meta_key ) {
        wpse16835_do_something( $post_id, $meta_value );
    }
}

add_action( 'deleted_post_meta', 'wpse16835_deleted_post_meta', 10, 4 );
function wpse16835_deleted_post_meta( $deleted_meta_ids, $post_id, $meta_key, $only_delete_these_meta_values )
{
    if ( 'wpse16835_meta_key' == $meta_key ) {
        wpse16835_undo_something( $post_id );
    }
}
3
  • super thx for this. I was aware about update_post_meta using update_metadata and in there, there was hooks to added_post_meta and updated_post_meta but thats as far as I could get. I didn't understand how to use. But now I think I've got it :)
    – Scott
    May 10, 2011 at 12:34
  • 5
    More specifically, the hook is updated_{$post_type}_meta Aug 8, 2015 at 3:46
  • Is it possible to hook into where post meta is updated via the REST API? I want to make it such that post revision is created when only post meta is updated via the rest API.
    – Amjad
    Feb 13, 2020 at 18:52
9

Jan answer covers pretty much it above except for the case where a custom metadata is deleted from the Edit Post page. This happens asynchronously as soon as you click on the "Delete" button under the metadata, via a call to wp-admin/admin-ajax.php. Unfortunately, that calls bypass the delete_metadata() function in meta.php and calls delete_meta() in wp-admin/includes/post.php instead (not to be confused with wp-includes/post.php).

There are 2 actions that can still be used though, delete_postmeta (before deletion), and deleted_postmeta (after deletion). Both accept a single parameter $mid, which is the ID of the metadata (not the key). You can retrieve the metadata object using:

$meta = get_post_meta_by_id($mid);  

which returns an object with meta_id, post_id, meta_key abd meta_value. Of course, by the time deleted_postmeta is called the metadata has been deleted so get_post_meta_by_id() won't work (which kinda makes that action useless)

Same goes for updating a custom metadata from the Edit Post page. The update_metadata() function (and its actions) in meta.php is not called, but the update_meta() function in wp-admin/includes/post.php is instead. Two actions again here, update_postmeta and updated_postmeta. The args are $meta_id, $post_id, $meta_key, $meta_value.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.