Wordpress - How to hook update_post_meta and delete_post_meta?
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 );
}
}
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.