I am trying to use the draft_to_publish hook (http://codex.wordpress.org/Post_Status_Transitions) to run a function when a post that is a draft becomes published. This hook does not appear to be working:

add_action('draft_to_publish', 'myFunction');

When I use this in my plug-in, myFunction is never fired. I have used/tested the function before. I know it is the hook, not the contents of myFunction.

All 'solutions' I found just link to the Codex page above. Any ideas about why this hook is not working?

Edit: Here is an example. It the email will not be sent, because the action never fires:

function myfunction () {
        $to = "[email protected]";
        $subject = "Hi!";
        $body = "Hi,\n\nHow are you?";
        if (mail($to, $subject, $body)) {
          echo("<p>Message successfully sent!</p>");
         } else {
          echo("<p>Message delivery failed...</p>");
add_action('draft_to_publish', 'myFunction');
  • There is not enough information to answer your question. Please try to add more detail, more code, and some debugging information.
    – s_ha_dum
    Commented Dec 28, 2012 at 15:36
  • What happens if you use wp_mail() as you should?
    – fuxia
    Commented Dec 28, 2012 at 18:38

1 Answer 1


You certainly have the right hook, but keep in mind that you are hooking your functionality specifically to the draft_to_publish action, i.e. to the specific case of a post-object pre-existing in the database with draft status being updated to publish. Note that this action ignores drafts which are automatically saved by Wordpress when a new post is created - these "drafts" have a post_status of auto-draft.

I'm not exactly sure how you've been debugging the issue up to this point, but if you haven't already, I would recommend verifying that the action itself is firing when you expect it to, perhaps by attaching some simple, arbitrary, and obvious function to it:

function kill_wp( $post ) {
  die( 'draft_to_publish fired for post #' . $post['ID'] . ' entitled, "' . $post['post_title'] . '"' );
add_action( 'draft_to_publish', 'kill_wp' );

That said, part of your problem may lie in capitalization - the action callback in your example references the function myFunction while the function that is defined has been named myfunction.

Though I am not sure as to what you are trying to accomplish, you could alternately attempt to attach your functionality to the generic action transition_post_status which gets passed the the new status of the post, the previous status of the post, and the post object such that you would have something similar to

function wpse77561_mail_on_publish( $new_status, $old_status, $post ) {
  if (get_post_type($post) !== 'post')
        return;    //Don't touch anything that's not a post (i.e. ignore links and attachments and whatnot )

    //If some variety of a draft is being published, dispatch an email
    if( ( 'draft' === $old_status || 'auto-draft' === $old_status ) && $new_status === 'publish' ) {
        $to      = '[email protected]';
        $subject = 'Hi!';
        $body    = 'Hi,' . chr(10) . chr(10) . 'How are you?';

        if( wp_mail( $to, $subject, $body ) ) {
            echo('<p>Message successfully sent!</p>');
        } else {
            echo('<p>Message delivery failed...</p>');
add_action('transition_post_status', 'wpse77561_mail_on_publish');

There are also a number of tools available that might grant you more insight into Wordpress' action execution such as the action hooks inspector for the Debug Bar plugin.

  • @bosco , it should my_function( $strNewStatus, $strOldStatus, $post ) not my_function( $strOldStatus, $strNewStatus, $post ). Thank you.
    – Eray
    Commented Apr 14, 2015 at 16:40
  • 1
    Nice catch, @Eray! Updated with the proper parameter order and to use the same variables as the Codex.
    – bosco
    Commented Apr 14, 2015 at 17:22
  • Actually, this is wrong: "Note that this action [draft_to_publish] ignores drafts which are automatically saved by Wordpress when a new post is created - these 'drafts' have a post_status of auto-draft." It does in fact include those posts too. I've tested it. So I'm using draft_to_publish without problems. However, in my case I'm also using the hook publish_to_publish so that I fetch clicks to 'Update' a blog post as well.
    – Magne
    Commented Sep 29, 2015 at 12:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.