The correct way is to use WordPress Cron and schedule your event. Also you should consider adding real cron job as outlined here for better precision.
1.) I modified your draft_the_post
function to support parameter. So now we can specify which post and also i updated the portion that checking the time.
2.) dg_cron_schedule_delete_posts
will schedule the hook if it’s not scheduled when init hook is fired. I set it to hourly
for better precision but you can also set it to daily
. Note: If you are doing this with plugin it’s better to use the activation hook and schedule it here.
3.) dg_delete_posts_handler
is where the deletion is handled. It goes through all the posts and calls the function maybe_draft_the_post
on each. Note: This queries all the posts so depending of how big is your data this may cause performance issues. I suggest implementing some kind of queue but this should be a good starting point.
/**
* Function that will draft specific post on specific conditions
*
* @param \WP_Post $_post
*/
function maybe_draft_the_post( $_post ) {
$expire_date = get_field( "your_field_name" );
// Bail if no expire date set.
if ( ! $expire_date ) {
return;
}
$expire_date = strtotime( $expire_date );
$actual_date = time();
if ( $expire_date <= $actual_date ) {
wp_update_post( array(
'ID' => $_post->ID,
'post_status' => 'draft'
) );
}
}
/**
* Register cron event on init action
*/
function dg_cron_schedule_delete_posts() {
$timestamp = wp_next_scheduled( 'dg_delete_posts' );
if ( $timestamp == false ) {
wp_schedule_event( time(), 'hourly', 'dg_delete_posts' );
}
}
add_action( 'init', 'dg_cron_schedule_delete_posts' );
/**
* Handle deletion of posts periodically.
* - Loop through the posts and call the draft_the_post function.
*/
function dg_delete_posts_handler() {
$posts = get_posts( array(
'posts_per_page' => - 1,
'post_type' => 'post',
'post_status' => 'publish',
) );
foreach ( $posts as $_post ) {
maybe_draft_the_post( $_post );
}
}
add_action( 'dg_delete_posts', 'dg_delete_posts_handler' );