WordPress Post Expiration

Here’s a nifty function I built recently for a project that needed to have real-time post expiration. Place this in your functions.php file. This function assumes you are using a custom field called expiration. If the post expiration field has passed, the post status will be set to draft, thus disabling it from the default WordPress query.

For the post expiration custom field, I created a custom meta box and used the jQuery UI datepicker.

function is_post_expired($post_ID = null){
    
    if(!$post_ID) global $post;
    
    $post_ID = $post_ID ? $post_ID : $post->ID;
    
    //Human Friendly Expiration Date
    $expiration = get_post_meta($post_ID, 'expiration', true);
    
    //Adjust server time for your timezone
    date_default_timezone_set('American/New_York');
    
    $expiration_timestamp = strtotime($expiration);
    $time_left = $expiration_timestamp - time();

    if($time_left < 0):
        if(expire_post($post_ID))
            return true;
    endif;
        
}

function expire_post($post_ID){
    
    $args = array(
        'ID' => $post_ID,
        'post_status' => 'draft'
    );
    if(wp_update_post($args))
        return true;
}

Usage

Simply include the following in the loop.

if(!is_post_expired()):
    //Do something awesome here
else:
    continue;
endif;

Final Thoughts

This function works during the loop iteration. The only caveat is the archive listing at times will not show the defined number of posts to display if a post expires during that loop. (i.e. General Settings -> Reading -> “Blog pages show at most”) The next page load will display the correct amount of posts. You technically could hook this into a WordPress action before the post is rendered to maintain the query integrity.

View on github:gist