I have been fiddling with this code for days trying to get this to work. Time to pay someone who's better than me!
What I need to do is query a custom post type for posts that were published within the last 15 days and if they are older than two weeks, by publish date, I want to change the meta_key listing_status to inactive
I also need to change the value of meta_key until_expires to be equal to the number of seconds until the post reaches the two-week limit, if the post is not yet expired.
I hope that makes sense. Here is what I've been playing with:
// This function run hourly to expire posts that have been live for two weeks or more
function expire_job_listing() {
$args = array (
'post_type' => 'job_listing',
'posts_per_page' => '-1',
'post_status' => 'publish',
'listing_status' => 'active',
'date_query' => array(
array(
'column' => 'post_date_gmt',
'after' => '60 days ago',
),
),
);
$the_query = new WP_Query( $args );
if ( $the_query->have_posts() ) {
while ( $the_query->have_posts() ) {
$the_query->the_post();
date_default_timezone_set('America/Los_Angeles');
$now = time();
$jobstart = get_post_time('U', true);
$expirein = 1209600; //1209600 <-Two weeks in seconds
if (($jobstart + $expirein) <= $now) { //if timestamp of publish date + the length of time before expiration is in the past, it's expired
update_post_meta($post->ID, 'listing_status', 'inactive');
$untilexp = 0;
update_post_meta($post->ID, 'until_expires', $untilexp);
} else { //else the post isn't expired yet
$untilexp = (($jobstart + $expirein) - $now);
update_post_meta($post->ID, 'until_expires', $untilexp);
}
}
}
wp_reset_postdata();
}
//Set the expire_job_listing function to run hourly
if (!wp_next_scheduled( 'expire_event' )) {
wp_schedule_event(time(), 'hourly', 'expire_event');
}
add_action( 'expire_event', 'expire_job_listing' );
Sébastien | French WordpressDesigner answers:
<blockquote>I also need to change the value of meta_key until_expires to be equal to the number of seconds until the post reaches the two-week limit, if the post is not yet expired.</blockquote>
It's very strange. If you need a countdown for your post (in frontend), it's not the good way.
Zac Eckstein comments:
You're right. You can ignore that part, it doesn't make sense to do that.
Sébastien | French WordpressDesigner comments:
what is this action "expire_event" ?
Sébastien | French WordpressDesigner comments:
Forget this last question...
Zac Eckstein comments:
It's the hook used to schedule the hourly expiration check, unless I'm doing that part incorrectly.
Zac Eckstein comments:
Oh ok never mind.
Sébastien | French WordpressDesigner comments:
Zack, I found a bug in your code.
You can detect this bug like that :
add this code in index.php for example. It's simply the loop you use in your code
$args = array (
'post_type' => 'job_listing',
'posts_per_page' => '-1',
'post_status' => 'publish',
'listing_status' => 'active',
'date_query' => array(
array(
'column' => 'post_date_gmt',
'after' => '60 days ago',
),
),
);
$the_query = new WP_Query( $args );
if ( $the_query->have_posts() ) {
while ( $the_query->have_posts() ) {
$the_query->the_post();
$now = time();
echo '<br>titre : ';
the_title();
date_default_timezone_set('America/Los_Angeles');
$now = time();
$now = date('l dS \o\f F Y h:i:s A', $now);
echo "<br>$now : " . $now;
$jobstart = get_post_time('U', true);
$jobstart = date('l dS \o\f F Y h:i:s A', $jobstart);
echo "<br>$jobstart after $now : " . $jobstart;
$expirein = 1209600; //1209600 <-Two weeks in seconds
}
}
wp_reset_postdata();
Now, add a post (job) and look what displays this loop. If the code is ok, you must read the same value for $now and for $jobstart.
But it's not the case !
You must declare the variable $jobstart above date_default_timezone_set('America/Los_Angeles');
like that
$args = array (
'post_type' => 'job_listing',
'posts_per_page' => '-1',
'post_status' => 'publish',
'listing_status' => 'active',
'date_query' => array(
array(
'column' => 'post_date_gmt',
'after' => '60 days ago',
),
),
);
$the_query = new WP_Query( $args );
if ( $the_query->have_posts() ) {
while ( $the_query->have_posts() ) {
$the_query->the_post();
$now = time();
echo '<br>titre : ';
the_title();
$jobstart = get_post_time('U', true);
date_default_timezone_set('America/Los_Angeles');
$now = time();
$now = date('l dS \o\f F Y h:i:s A', $now);
echo "<br>$now : " . $now;
$jobstart = date('l dS \o\f F Y h:i:s A', $jobstart);
echo "<br>$jobstart after $now : " . $jobstart;
$expirein = 1209600; //1209600 <-Two weeks in seconds
}
}
wp_reset_postdata();
If you post another job to test another time this loop, now you can see same value for both variables.
Now you can remove this testing code
and replace your current code by this code, in functions.php
//Set the expire_job_listing function to run hourly
if (!wp_next_scheduled( 'expire_event' )) {
wp_schedule_event(time(), 'hourly', 'expire_event');
}
add_action( 'expire_event', 'expire_job_listing' );
// This function run hourly to expire posts that have been live for two weeks or more
function expire_job_listing() {
$args = array (
'post_type' => 'job_listing',
'posts_per_page' => '-1',
'post_status' => 'publish',
'meta_key' => 'listing_status',
'meta_value' => 'active',
'date_query' => array(
array(
'column' => 'post_date_gmt',
'after' => '60 days ago',
),
),
);
$the_query = new WP_Query( $args );
if ( $the_query->have_posts() ) {
while ( $the_query->have_posts() ) {
$the_query->the_post();
$jobstart = get_post_time('U', true);
date_default_timezone_set('America/Los_Angeles');
$now = time();
$expirein = 1209600; //1209600 <-Two weeks in seconds
if (($jobstart + $expirein) <= $now) { //if timestamp of publish date + the length of time before expiration is in the past, it's expired
update_post_meta($post->ID, 'listing_status', 'inactive');
}
}
}
wp_reset_postdata();
}
Good night !
Let me know when you try my code.
ps : and tell me please if my english is correct...
Sébastien | French WordpressDesigner comments:
$args = array (
'post_type' => 'job_listing',
'posts_per_page' => '-1',
'post_status' => 'publish',
'listing_status' => 'active',
'date_query' => array(
array(
'column' => 'post_date_gmt',
'after' => '60 days ago',
),
),
);
by
$args = array (
'post_type' => 'job_listing',
'posts_per_page' => '-1',
'post_status' => 'publish',
'meta_key' => 'listing_status',
'meta_value' => 'active',
'date_query' => array(
array(
'column' => 'post_date_gmt',
'after' => '60 days ago',
),
),
);
So... the first testing code is :
$args = array (
'post_type' => 'job_listing',
'posts_per_page' => '-1',
'post_status' => 'publish',
'meta_key' => 'listing_status',
'meta_value' => 'active',
'date_query' => array(
array(
'column' => 'post_date_gmt',
'after' => '60 days ago',
),
),
);
$the_query = new WP_Query( $args );
if ( $the_query->have_posts() ) {
while ( $the_query->have_posts() ) {
$the_query->the_post();
$now = time();
echo '<br>titre : ';
the_title();
date_default_timezone_set('America/Los_Angeles');
$now = time();
$now = date('l dS \o\f F Y h:i:s A', $now);
echo "<br>$now : " . $now;
$jobstart = get_post_time('U', true);
$jobstart = date('l dS \o\f F Y h:i:s A', $jobstart);
echo "<br>$jobstart after $now : " . $jobstart;
$expirein = 1209600; //1209600 <-Two weeks in seconds
}
}
wp_reset_postdata();
and the second code is :
$args = array (
'post_type' => 'job_listing',
'posts_per_page' => '-1',
'post_status' => 'publish',
'meta_key' => 'listing_status',
'meta_value' => 'active',
'date_query' => array(
array(
'column' => 'post_date_gmt',
'after' => '60 days ago',
),
),
);
$the_query = new WP_Query( $args );
if ( $the_query->have_posts() ) {
while ( $the_query->have_posts() ) {
$the_query->the_post();
$now = time();
echo '<br>titre : ';
the_title();
$jobstart = get_post_time('U', true);
date_default_timezone_set('America/Los_Angeles');
$now = time();
$now = date('l dS \o\f F Y h:i:s A', $now);
echo "<br>$now : " . $now;
$jobstart = date('l dS \o\f F Y h:i:s A', $jobstart);
echo "<br>$jobstart after $now : " . $jobstart;
$expirein = 1209600; //1209600 <-Two weeks in seconds
}
}
wp_reset_postdata();
and the code for the file functions.php is ok.
Zac Eckstein comments:
Thank you! I think this will work. I will test later today (I have to go to work first) and then I will come back and let you know.
Thanks!
Sébastien | French WordpressDesigner comments:
Ok. I'm in France, so I'll be in bed in 5 hours
Hariprasad Vijayan answers:
Hello,
Try this
// This function run hourly to expire posts that have been live for two weeks or more
function expire_job_listing() {
$args = array (
'post_type' => 'job_listing',
'posts_per_page' => '-1',
'post_status' => 'publish',
'meta_key' => 'listing_status',
'meta_value' => 'active',
'date_query' => array(
array(
'column' => 'post_date_gmt',
'after' => '2 month ago',
),
),
);
$the_query = new WP_Query( $args );
if ( $the_query->have_posts() ) {
while ( $the_query->have_posts() ) {
$the_query->the_post();
date_default_timezone_set('America/Los_Angeles');
$now = time();
$jobstart = get_post_time('U', true);
$expirein = 1209600; //1209600 <-Two weeks in seconds
if (($jobstart + $expirein) <= $now) { //if timestamp of publish date + the length of time before expiration is in the past, it's expired
update_post_meta($post->ID, 'listing_status', 'inactive');
$untilexp = 0;
update_post_meta($post->ID, 'until_expires', $untilexp);
} else { //else the post isn't expired yet
$untilexp = (($jobstart + $expirein) - $now);
update_post_meta($post->ID, 'until_expires', $untilexp);
}
}
}
wp_reset_postdata();
}
//Set the expire_job_listing function to run hourly
if (!wp_next_scheduled( 'expire_event' )) {
wp_schedule_event(time(), 'hourly', 'expire_event');
}
add_action( 'expire_event', 'expire_job_listing' );
Let me know
Zac Eckstein comments:
Thank you, this has gotten me the farthest so far, not quite there yet though. I am off to bed (it is late here) and I will keep testing tomorrow. Thanks.
Hariprasad Vijayan comments:
Okay. Let me know if you have trouble.
Zac Eckstein comments:
OK, this seems to work! Thank you for the help.
John Cotton answers:
<blockquote>I also need to change the value of meta_key until_expires to be equal to the number of seconds until the post reaches the two-week limit, if the post is not yet expired.</blockquote>
Do you really need to do that?
Assuming that you are using that value for some query, why can't you just query the date?
A second after you've stored "seconds to expire" it's wrong, so what's the value in it?
Zac Eckstein comments:
Yeah, you're right. I probably would have realized that once I got it working. We can ignore that part of the question.