Posts to expire (deleted) after a date

I did something similar a while ago. I’m not sure deleting a post is a good solution, maybe you can change only the post status to a custom one called Expired for example. But for an example, the code below will delete the post.

First create a daily cron job:

add_action( 'wp', 'delete_expired_coupons_daily' );
function delete_expired_coupons_daily() {
    if ( ! wp_next_scheduled( 'delete_expired_coupons' ) ) {
        wp_schedule_event( time(), 'daily', 'delete_expired_coupons');
    }
}
add_action( 'delete_expired_coupons', 'delete_expired_coupons_callback' );

Then use the delete_expired_coupons_callback function to loop through the coupon posts, check for the date and delete if necessary:

function delete_expired_coupons_callback() {
    $args = array(
        'post_type' => 'coupon',
        'posts_per_page' => -1
    );

    $coupons = new WP_Query($args);
    if ($coupons->have_posts()):
        while($coupons->have_posts()): $coupons->the_post();    

            $expiration_date = get_post_meta( get_the_ID(), 'expiry_date', true );
            $expiration_date_time = strtotime($expiration_date);

            if ($expiration_date_time < time()) {
                wp_delete_post(get_the_ID());
                //Use wp_delete_post(get_the_ID(),true) to delete the post from the trash too.                  
            }

        endwhile;
    endif;
}

Couple of suggestions: When you import the coupons, you can do an strtotime conversion, so the date format is the same in the database. This way you don’t need to loop through all of the posts to check the expiration date, you can use a custom query to check if its expired, so the daily job will run much faster:

    $args = array(
        'post_type' => 'coupon',
        'posts_per_page' => -1,
        'meta_query' => array(
            array(
               'key' => 'expiry_date',
               'value' => time(),
               'compare' => '<'
            )
        )
    );

You can create an Expiration post status to simply disable these posts without deleting them: http://codex.wordpress.org/Function_Reference/register_post_status

And you can change the post status like this, instead of the wp_delete_post function:

// Update post
$my_post = array();
$my_post['ID'] = get_the_ID();
$my_post['post_status'] = 'expired';

// Update the post into the database
wp_update_post( $my_post );

Leave a Comment