We were recently in a situation in a project where we wanted to rebuild/invalidate a cache when a particular post was updated. Some of the key data for the post is stored in postmeta. So we have code that looks like:
$id = wp_insert_post( wp_slash( array( 'post_title' => 'foo', ) ) ); /* ... */ update_postmeta( $id, 'bar', wp_slash( $bar ) ); update_postmeta( $id, 'baz', wp_slash( $baz ) ); wp_set_object_terms( $id, $tags, 'post_tag' );
The problem here is that we can’t reliably use the
save_post action to flush the cache because all of the data is not yet written to the database since this action is fired in
wp_insert_post(). In other words, the post writing was not atomic, so we had to an additional ad hoc action like
do_action( 'acme_after_update_postmeta', $id ) and hook into that action to flush the cache.
I should have been using this already, but it turns out that all of these
wp_set_object_terms() calls can be made by
wp_update_post()) by using the
@type array $tax_input Array of taxonomy terms keyed by their taxonomy name. Default empty. @type array $meta_input Array of post meta values keyed by their post meta key. Default empty.
So the above can be re-written as:
wp_insert_post( wp_slash( array( 'post_title' => 'foo', 'meta_input' => array( 'bar' => $bar, 'baz' => $baz, ), 'tax_input' => array( 'post_tag' => $tags, ), ) ) );
With this “atomic” call, we can then listen for a single
save_post action and be assured that all of the required postmeta will be available.
Not that I am explicitly using
wp_slash() in the examples here as a reminder that these functions expect slashed data, aggravatingly (for backwards compatibility since PHP a long time ago used to espouse the use of “magic quotes”).