4

I have the following hook which sets a default "hotness" for a post. For context, hotness is a meta_value saved to the post, and changes every time someone upvotes or downvotes the post. I use this meta_value to sort posts on a 'What is hot right now?' page.

Because at the time the post is created in WordPress, the "score" of upvotes vs. downvotes is 0. Therefore I can completely omit the score's portion of the hotness calculation. When the post is created, only the creation time is taken into account:

/* Hook: Add custom postmeta when a new post is created
 * Since: 8.0
 */
add_action( 'wp_insert_post', tjnz_prepare_postmeta );
function tjnz_prepare_postmeta( $post_id ) {
    if ( !wp_is_post_revision( $post_id ) ) {
        $hotness = round( ( time() - 1211380200 ) / 800000, 7 );
        add_post_meta( $post_id, '_tjnz_favorites', 0, true );
        add_post_meta( $post_id, '_tjnz_plays', 0, true );
        add_post_meta( $post_id, '_tjnz_downloads', 0, true );
        add_post_meta( $post_id, '_tjnz_upvotes', 0.000, true );
        add_post_meta( $post_id, '_tjnz_downvotes', 0.000, true );
        add_post_meta( $post_id, '_tjnz_hotness', $hotness, true );
    }
}

I'm wondering what happens when you schedule a post in WordPress. Will the hook be triggered when I click Schedule, or when the WordPress cronjob publishes the post?

If the hook is triggered when I click Schedule, how can I effectively change that so that the time inserted into the database is actually the post's publish time, rather than when I clicked to schedule the post?

The Codex page for wp_insert_post states that the $post object has a 'post_date_gmt' member. It's documented as:

'post_date_gmt' => [ Y-m-d H:i:s ] // The time post was made, in GMT.

To me, it is unclear if they mean when it's inserted into the database (time of clicking the schedule button) or when it's 'meant' to be created (the time which I entered in the scheduler). Can someone please clarify this?

Edit:

After examining ialocin's answer, I have concluded that my current usage of the wp_insert_post hook is not going to yield the desired results. I will try another approach, but want to clarify my intentions to help others understand why I need this.

As I said earlier, I calculate a 'hotness' value for every post I make. Without the influence of a score, the hotness still gradually increases over time. At Unix Epoch + 1211380200 seconds is my 'personal site Epoch'. If a post's post_date_gmt = 1211380200, it is essentially posted at the 'birth' of my site (this is May 21st, 2008).

For every new post, I want to save it's initial hotness value, so I have to know the post's publish date (in GMT Unix timestamp) and subtract the time different between Unix Epoch and my Epoch, which is 1211380200 seconds.

When I post content, I often schedule multiple posts to go 'on air' throughout the week, because I don't have enough time to post every day. It is important that posts get the initial value right, because it is the basis for any further calculation.

My new approach would be to hook into post status transitions. Please help me get this right:

add_action( 'transition_post_status', 'tjnz_prepare_postmeta', 10, 3 );
function tjnz_prepare_postmeta( $new_status, $old_status, $post ) {
    if ( $new_status == 'publish' && $old_status != 'publish' ) {
        $hotness = round( ( $post->post_date_gmt - 1211380200 ) / 800000, 7 );
        update_post_meta( $post->ID, '_tjnz_favorites', 0 );
        update_post_meta( $post->ID, '_tjnz_plays', 0 );
        update_post_meta( $post->ID, '_tjnz_downloads', 0 );
        update_post_meta( $post->ID, '_tjnz_upvotes', 0.000 );
        update_post_meta( $post->ID, '_tjnz_downvotes', 0.000 );
        update_post_meta( $post->ID, '_tjnz_hotness', $hotness );
    }
}

The reason I also check for $old_status is because I am assuming that when I update an already published post, both $new_status and $old_status would be 'publish'. I do not want to accidentally reset any of the meta values every time I update an existing published post.

I also changed add_post_meta to update_post_meta because that way I can ensure the correct values are inserted into the database whether a post is Published directly or Scheduled. I believe if the meta values do not yet exist, update_post_meta will actually act as an add_post_meta function.

1 Answer 1

4
+50

The short answer is, post_date and post_date_gmt will be set to the date you scheduled the post to be published - not the date you created the post -, so post_date and post_date_gmt are holding the publishing date.


Update:

As reply to comment:

  1. When will the wp_insert_post hook be triggered?

    • Actually both times, so on clicking Schedule and on the scheduled change of the post status from future to publish.
    • Why? Firstly because:
    • And secondly because it is part of:
    • Which gets triggered by:
    • Take a closer look at the documentation(s) and getting to know the source code, here mainly post.php, always helps to understand what's really happening.

  2. Can/should you use the function time()?

    • You certainly can, take the new information from 1. into consideration.
    • If you should depends on the fact, is the information you need already available. If it is, then there is no reason to get the same information twice.
    • So if post_date and post_date_gmt hold the information you need, which would be, as it has been established, the publishing date, use it.
    • Or use post_modified and post_modified_gmt if you want to reflect changes.

The actual approach you'll going to chose really depends on your needs/plans, which I know little about. As far as I can tell one thing you definitely should consider is using another hook - or hooks. Take a look at Post Status Transitions for other ones to consider. Additionally inspect the source - post.php - to get deeper into when and how those are hooks used. There are many questions about this on here, just search for it.

8
  • Can you improve your answer to clarify whether time() should be used in the hooked function, or if it should take post_date_gmt from the passed $post object? Your answer does not clarify if the hook is triggered when the WP Cronjob publishes the post, or when I have clicked Schedule. I think that really makes a difference if time() can be used. Commented Feb 17, 2014 at 10:53
  • 1
    I added some additional information to the answer, That should clarify things for you. Hope it helps - good luck! @MarcDingena Commented Feb 17, 2014 at 17:03
  • Thank you for your clarifications. It would seem that using different hooks would be better in my situation, since the wp_insert_post hook is not triggering my function when the post transitions from future to publish, or draft to publish. It also appears that the post_date_gmt is left at default value for drafts (0000-00-00 00:00:00), which is no good for my function. I will update my question with my intended functionality. If you'd be so kind to let me know if I'm going for the right approach, I'd really appreciate that. Commented Feb 17, 2014 at 20:09
  • You really should ask a new question, because WPSE more or less handles one problem per question, because that's just better from a community standpoint. I'll take a look at the new question. Just notify me here. @MarcDingena Commented Feb 17, 2014 at 20:12
  • I just updated my answer. I'm not used to creating a new question for a follow-up question. To me that seems a bit like polution, but I understand your point of view regarding Q&A based communities. Please take a look at my updated question and if the need is still there, I can split it off into a new question, where you could provide your answer if you want to. Commented Feb 17, 2014 at 20:31

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.