What is considered the post’s creation date for wp_insert_post?

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:

Read More
/* 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.

Related posts

1 comment

  1. 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.

Comments are closed.