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.
The short answer is,
post_date
andpost_date_gmt
will be set to the date you scheduled the post to be published – not the date you created the post -, sopost_date
andpost_date_gmt
are holding the publishing date.Update:
As reply to comment:
When will the
wp_insert_post
hook be triggered?wp_insert_post()
is invoking the hook itself – see source;wp_publish_post()
– see source;check_and_publish_future_post()
– see source;post.php
, always helps to understand what’s really happening.Can/should you use the function
time()
?post_date
andpost_date_gmt
hold the information you need, which would be, as it has been established, the publishing date, use it.post_modified
andpost_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.