Detect type of post status transition

I have a function on my site that it supposed to run when a new post is published (email push notification), with the exception of the same article updated (i.e publish_to_publish transition, I don’t want to send unnecessary push notifications)

I know that I can use the {old_status} to {new_status} action hooks, but this means that I have to specify all the transitions to publish (new_to_publish, draft_to_publish, etc.).

Read More

My question is:

  1. Can I use instead the publish_post hook and detect if it was publish_to_publish so I can explicitly negate it? something like:

    function send_email() {
     if ($transition == 'publish_to_publish') return;
      //(else) send email
    }
      add_action('publish_post', 'send_email', 10, 1);
    
  2. If not, how do I tie multiple hooks to the same action? Do I just list them like so:

    add_action('new_to_publish', 'send_mail', 10, 1);
    add_action('future_to_publish', 'send_mail', 10, 1);
    add_action('draft_to_publish', 'send_mail', 10, 1);
    

Or is there a more elegant way – like passing an array?

Related posts

Leave a Reply

2 comments

  1. If not, how do I tie multiple hooks to the same action? Do I just list
    them like so:

    add_action('new_to_publish', 'save_new_post', 10, 1);
    add_action('future_to_publish', 'save_new_post', 10, 1);
    add_action('draft_to_publish', 'save_new_post', 10, 1);
    

    This is exactly the way to go. Just hook the same callback into each of the status-transition hooks on which you want the callback to fire.

  2. We can do this is one hook by using the transition_post_status. All we need to do is to check that the old status is not publish. We can also exclude other statuses by creating an array of these statuses and check against $old_status

    Note, this requires PHP 5.4+ and is untested

    add_action( 'transition_post_status', function ( $new_status, $old_status, $post )
    {
        // First check if our new status is publish before we do any work
        if ( 'publish' !== $new_status )
            return;
    
        // Create the array of post statuses to check against
        $statuses = ['publish', 'pending', 'private', 'trash'];
    
        // If the old status is an the $statuses array, bail
        if ( in_array( $old_status, $statuses ) )
            return;
    
        // Everything checked out, lets do what we are suppose to do
        // send email
    }, 10, 3 );