Execute function when post is published

I try to use this function i have created when a post is published for the first time.

function a_new_post($post){$post_id = $post->ID; if ( !get_post_meta($post_id, 'firstpublish', $single = true ) ) { // ...run code once update_post_meta($post_id, 'firstpublish', true );
}
}


I can't see anything wrong with it, but when i try to create some sample posts i check the database and the field "firstpublished" has not been created.

Does anyone see anything wrong?

-
shouldn't you change the hook to publish_post. draft_to_publish won't run for all the cases –  Mridul Aggarwal Oct 19 '12 at 7:40
I tried publish_post and it does not work (wordpress.stackexchange.com/questions/141779/…) –  user11948 Apr 21 '14 at 22:28
This is the most frustrating thing I have ever dealt with in WordPress. There is absolutely now way to catch publish and block update. Now way, no how. –  user11948 May 1 '14 at 20:53

The correct action is 'draft_to_publish'.

To be sure you used the correct status try to get a list of all registered post statuses (including custom statuses) with:

<pre><?php print '- ' . implode( "\n- ", array_keys( get_post_stati() ) );?></pre>


On a vanilla installation you should get:

• publish
• future
• draft
• pending
• private
• trash
• auto-draft
• inherit

Note that publish_post is called each time you edit a published post.

Note also get_post_stati() is one of these unpredictable names in WordPress: it is plain wrong. The plural of the noun status is statuses in English and statūs in Latin. :D

You could also hook into 'transition_post_status', depending on your needs. You get the new and the old status as arguments, the third argument is the post object. It will catch future_to_publish too, and also posts that were trashed once and republished now (trash_to_publish).

Example:

add_action( 'transition_post_status', 'a_new_post', 10, 3 );

function a_new_post( $new_status,$old_status, $post ) { if ( 'publish' !==$new_status or 'publish' === $old_status ) return; if ( 'post' !==$post->post_type )
return; // restrict the filter to a specific post type

// do something awesome
}

-
+1 for the fourth- / u-declension –  Johannes Pille Oct 19 '12 at 9:34
Can you tell me how this might be tailored to what I am trying to do @tocsho? See my question at wordpress.stackexchange.com/questions/141779/… -- thanks, greatly appreciated –  user11948 Apr 21 '14 at 22:37
@H.Ferrence Replace your publish_post with transition_post_status (don’t forget the 10, 3 at the end). Set my checks on top of the callback function, then run your custom code where my example says do something awesome. –  toscho Apr 21 '14 at 22:39
ok...everything else stays the same? –  user11948 Apr 21 '14 at 22:40
@H.Ferrence You don’t need the get_post() call from your code anymore, because the third parameters is the complete post object. –  toscho Apr 21 '14 at 22:45