Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

transition_post_status hook always return the same status value for $old_status and $new_status arguments. #12797

Closed
avillegasn opened this issue Dec 11, 2018 · 8 comments
Labels
Needs Technical Feedback Needs testing from a developer perspective. REST API Interaction Related to REST API

Comments

@avillegasn
Copy link
Contributor

Describe the bug
The action transition_post_status is fired when you change the status of a post. It has three parameters according to the documentation:

  • $new_status (string): New post status.
  • $old_status (string): Old post status.
  • $post (WP_Post): Post object.

In the classic editor, the hook worked fine. In Gutenberg (block editor) the hook fires properly but the values of $new_status and $old_status are always the same. When you have a draft and save it as pending, the hook is called with both $old_status and $new_status to 'pending'. The same happens all the time when you change the status of a post.

To Reproduce
Steps to reproduce the behavior:

  1. Hook into transition_post_status. Something like the following code in functions.php will do the job:
add_action( 'transition_post_status', 'log_data', 10, 3 );
function log_data( $new_status, $old_status, $post ) {
   error_log( 'From ' . $old_status . ' to ' . $new_status . ' for post ' . $post->ID );
}
  1. Change the status of a post in the new block editor.
  2. Check the error log and you'll see the same value for $new_status and $old_status.

Expected behavior
$old_status should take the proper value instead of always returning the same value as $new_status.

@swissspidy swissspidy added REST API Interaction Related to REST API Needs Technical Feedback Needs testing from a developer perspective. labels Dec 11, 2018
@TimothyBJacobs
Copy link
Member

I haven't been able to replicate this. I see proper transitions from draft to pending and pending back to draft. Do you have any classic meta boxes in the Block Editor?

@avillegasn
Copy link
Contributor Author

avillegasn commented Dec 11, 2018

Yes, I have. Now that's weird @TimothyBJacobs. When I put the code in functions.php and deactivate the plugins that add the classic meta boxes, everything works fine.

But when I activate the plugin that hooks to transition_post_status, the log from the functions.php works fine but the log in that plugin shows the same value for both new and old status.

The code in the theme is linked directly to transition_post_status (as in the example) while the hook in the plugin is linked to transition_post_status inside a function that is executed in the hook plugins_loaded. Not sure if that may be the problem, but that worked before in the Classic Editor. I'm confused.

@TimothyBJacobs
Copy link
Member

And the error log is entirely of the same status to same status? No entries that are correct?

@avillegasn
Copy link
Contributor Author

avillegasn commented Dec 11, 2018

The entries that are correct are those from the code in functions.php. The entries from the plugin are entirely of the same status to same status. Both codes are the same, but the code in the theme works while the code in the plugin don't.

I got the following after transitioning from draft to post in the error log:

[11-Dec-2018 16:11:32 UTC] THEME: From draft to pending for post 281
[11-Dec-2018 16:11:32 UTC] PLUGIN: From pending to pending for post 281
[11-Dec-2018 16:11:32 UTC] THEME: From pending to pending for post 281

@avillegasn
Copy link
Contributor Author

@TimothyBJacobs apparently I found the problem. The hook in the plugin is only done when is_admin(). It seems that is_admin() is not set to true in Gutenberg REST API requests, and that's why the hook was not working as expected.

According to #11138, @swissspidy indicated "Since Gutenberg uses the REST API to save posts, you would have to check for that, not is_admin or wp_doing_ajax". What substitutes is_admin() in this case is not clear to me. Is there an is_rest() method? I tried checking REST_REQUEST as indicated here but didn't work.

In some cases (like transition_post_status) I just want to hook when is_admin() or "is_rest" to avoid adding more load in the front end. Any clues? Thanks!

@swissspidy
Copy link
Member

Yeah the REST_REQUEST constant can be used for that, e.g. by checking for defined( 'REST_REQUEST' ) && REST_REQUEST.

I don't see the need for that though. transition_post_status is likely never to be called on the front end, and hooking into an action that's never called has basically no impact on performance. So to me that sounds like you make it more complicated than it needs to be :-)

@avillegasn
Copy link
Contributor Author

Thanks for the comment @swissspidy. That's true, we where doing things more complicated than they should be. I've reorganized the hooks to avoid problems like this one. The issue is now closed :-)

@niklaz
Copy link

niklaz commented Apr 24, 2019

Hi,
I can confirm that when using transition_post_status, for new posts that get published it has only:
'new_to_auto-draft' and 'publish_to_publish'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs Technical Feedback Needs testing from a developer perspective. REST API Interaction Related to REST API
Projects
None yet
Development

No branches or pull requests

4 participants