Posts to expire (deleted) after a date

I am creating a coupon site from scratch. I have reviewed many code examples on the Internet, but have not found anything that will work, as my requirements are little different.

I need help in creating an expiry function that would delete the “coupon” (post_type) automatically.

As a coupon site, all coupons are imported in bulk, so the expiry date format (e.g. 01/12/2014, 01-12-2014, or 1 Dec 2014) differs from coupon to coupon in a particular import (session). This creates a problem when the date format differs, and it’s never the same.

Custom field is “expiry_date”, it will store the date.

Does any one have a good solution for this problem?

2 Answers
2

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