WordPress.org

Codex

Interested in functions, hooks, classes, or methods? Check out the new WordPress Code Reference!

Post Status Transitions

WordPress 2.3 introduced some new actions that plugins can use to hook into post status transitions. Prior to Version 2.3, WordPress had a private_to_published (deprecated) action that only announced when a post transitioned from private to published. As of Version 2.3, there are actions for every possible transition.

There are three kinds of post status transition action hooks:

All three actions are called by wp_transition_post_status() in wp-includes/post.php.

The available post statuses are:

  • new – When there’s no previous status (this means these hooks are always run whenever "save_post" runs.
  • publish – A published post or page.
  • pending – A post pending review.
  • draft – A post in draft status.
  • auto-draft – A newly created post with no content.
  • future – A post scheduled to publish in the future.
  • private – Not visible to users who are not logged in.
  • inherit – A revision or attachment (see get_children()).
  • trash – Post is in the trash (added with Version 2.9).

transition_post_status Hook

transition_post_status is a generic action that is called every time a post changes status. When do_action() is called for transition_post_status, three arguments are passed to it: $new_status, $old_status and the $post object. Therefore, these are also available to be used in the callback function. In the add_action() call, the action priority may be set between 0 and 20 (default is 10) and it is necessary to specify the number of arguments do_action() should pass to the callback function.

function on_all_status_transitions( $new_status, $old_status, $post ) {
    if ( $new_status != $old_status ) {
        // A function to perform actions any time any post changes status.
    }
}
add_action(  'transition_post_status',  'on_all_status_transitions', 10, 3 );
function post_unpublished( $new_status, $old_status, $post ) {
    if ( $old_status == 'publish'  &&  $new_status != 'publish' ) {
        // A function to perform actions when a post status changes from publish to any non-public status.
    }
}
add_action( 'transition_post_status', 'post_unpublished', 10, 3 );

Don’t confuse the transition_post_status action hook with the wp_transition_post_status() function or the private function _transition_post_status(). The function wp_transition_post_status() is used to call the post status transition actions and can be found in wp-includes/post.php. This function would be useful if your plugin directly modifies the database, thereby bypassing the usual post status transition action hooks. If you want to transition the status of a post, rather than perform actions when a post status is transitioned, use wp_update_post() or wp_publish_post().

{old_status}_to_{new_status} Hook

An {old_status}_to_{new_status} action will execute when a post transitions from {old_status} to {new_status}. The action is accompanied by the $post object. In the add_action() function call, the action priority may be set between 0 and 20 (default is 10) and it is necessary to specify the number of arguments do_action() should pass to the callback function.

function on_publish_pending_post( $post ) {
    // A function to perform when a pending post is published.
}
add_action(  'pending_to_publish',  'on_publish_pending_post', 10, 1 );

{status}_{post_type} Hook

A {status}_{post_type} action will execute when a post of type {post_type} transitions to {status} from any other status. For example, when a post is published, a publish_post action is triggered. The action is accompanied by the post ID and $post object. Default values for post type are post, page, attachment, revision, navigation. Additionally, custom post types may also be used.

function on_post_publish( $ID, $post ) {
    // A function to perform actions when a post is published.
}
add_action(  'publish_post',  'on_post_publish', 10, 2 );
function on_post_scheduled( $ID, $post ) {
    // A function to perform actions when a post is scheduled to be published.
}
add_action(  'future_post',  'on_post_scheduled', 10, 2 );

Not Deprecated Hooks

The publish_post and publish_page actions had been identified as deprecated on the Action Reference page and the publish_post and publish_page action pages. This was not correct. Prior to WordPress 2.3, the callback function for publish_post took only the post ID as an argument and no other arguments were passed to the action by default. Since Version 2.3, both the post ID and the $post object are passed to the action and the add_action() call should specify the action priority and the number of arguments the action accepts. If called correctly, publish_post and publish_page are still legitimate action hooks.

Deprecated Hooks

private_to_published is deprecated but may be replaced with private_to_publish.

publish_future_post is deprecated but may be replaced with future_to_publish.

Related

transition_post_status
wp_transition_post_status()
publish_post
publish_page
Post Types
add_action()
wp_update_post()
wp_publish_post()

Source File

See wp_transition_post_status() in wp-includes/post.php.