Make WordPress Core

Opened 11 years ago

Closed 11 years ago

#31099 closed defect (bug) (fixed)

Hook action on publishing custom post type also firing on update

Reported by: yosmc's profile yosmc Owned by: idealien's profile Idealien
Milestone: 4.2 Priority: normal
Severity: normal Version: 4.1
Component: Posts, Post Types Keywords: good-first-bug has-patch
Focuses: docs Cc:

Description

I am using the following hook to add an action after my custom post type has been published.

add_action('publish_my-custom-post-type', 'my-function-on-publish');

As it turns out, however, it's actually firing every time the post is updated, not just when it's published. According to the handbook, however, it should only fire when status changes TO published.

PS: I'm seeing the same behavior with WordPress 3.9.X as well as 4.X

Attachments (2)

31099.diff (1.2 KB) - added by MikeHansenMe 11 years ago.
31099_Docs.patch (607 bytes) - added by Idealien 11 years ago.
Update to docs of {$old_status}_to_{$new_status}

Download all attachments as: .zip

Change History (11)

#1 @SergeyBiryukov
11 years ago

  • Component changed from General to Posts, Post Types

@MikeHansenMe
11 years ago

#2 @MikeHansenMe
11 years ago

  • Keywords has-patch added

#3 follow-up: @DrewAPicture
11 years ago

  • Focuses docs added
  • Keywords needs-patch added; has-patch removed

Unfortunately, we can't change the behavior of the hook in this way due to back-compat concerns. Whether it seemingly makes sense or not, we have to consider that people now expect it to work the way it does for published posts.

If you're looking to only fire a callback when posts are published, I suggest using the transition_post_status hook instead:

<?php
/**
 * Fire a callback only when my-custom-post-type posts are transitioned to 'publish'.
 *
 * @param string  $new_status New post status.
 * @param string  $old_status Old post status.
 * @param WP_Post $post       Post object.
 */
function wpdocs_run_on_publish_only( $new_status, $old_status, $post ) {
        if ( ( 'publish' == $new_status && 'publish' !== $old_status )
                && 'my-custom-post-type' == $post->post_type
        ) {
                        // do stuff
        }
}
add_action( 'transition_post_status', 'wpdocs_run_on_publish_only', 10, 3 );

One thing we could do here is adjust the docs for the {$new_status}_{$post->post_type}, {$old_status}_to_{$new_status}, and transition_post_status hooks to reflect the expected behavior of the post status not changing when published posts are updated.

Last edited 11 years ago by DrewAPicture (previous) (diff)

#4 @yosmc
11 years ago

Well, first of all thanks for the quick confirmation as well as the provided alternative - top notch.

And yes, updating the docs (possibly including the above solution) seems like the way to go then.

#5 @DrewAPicture
11 years ago

  • Keywords good-first-bug added

@Idealien
11 years ago

Update to docs of {$old_status}_to_{$new_status}

#6 in reply to: ↑ 3 @Idealien
11 years ago

Replying to DrewAPicture:

One thing we could do here is adjust the docs for the {$new_status}_{$post->post_type}, {$old_status}_to_{$new_status}, and transition_post_status hooks to reflect the expected behavior of the post status not changing when published posts are updated.

good-first-bug meet my-first-patch :)

I submit 31099Docs.patch which adds details for publish_{$post->type} suggesting transition_post_status which answers the scenario of the original defect.

This ticket was mentioned in Slack in #core by idealien. View the logs.


11 years ago

#8 @DrewAPicture
11 years ago

  • Keywords has-patch added; needs-patch removed
  • Milestone changed from Awaiting Review to 4.2
  • Owner set to Idealien
  • Status changed from new to assigned

#9 @DrewAPicture
11 years ago

  • Resolution set to fixed
  • Status changed from assigned to closed

In 31461:

Update the descriptions for transition_post_status() and the {$new_stats}_{$post->post_type} hook with more information about the expected behavior of transitioning post statuses.

In some cases, the values of $old_status and $new_status may be the same thing before and after a post status is "transitioned". An example of this would be the scenario where a published post is being updated: the status before and after the update both equal 'publish'.

Further, the documentation clarifies that if the intent is to only execute code when initially transitioningto a post status from something else, the 'transition_post_status' hook should be used instead of one of the dynamic hooks to avoid confusion.

Props Idealien for the initial patch.
Fixes #31099.

Note: See TracTickets for help on using tickets.