Unpublish Posts on an Expiry Date
Adds an "Unpublish on" date box to the post editor and moves expired posts back to draft automatically, for time-limited offers and announcements.
Opens WPIDE on
Code
add_action( 'add_meta_boxes', function () {
add_meta_box( 'wpide-expiry', 'Unpublish on', function ( $post ) {
wp_nonce_field( 'wpide_expiry_save', 'wpide_expiry_nonce' );
$value = get_post_meta( $post->ID, 'wpide_expires', true );
echo '<label class="screen-reader-text" for="wpide-expires">Unpublish on</label>';
echo '<input type="datetime-local" id="wpide-expires" name="wpide_expires" value="' . esc_attr( $value ) . '" style="width:100%;" />';
echo '<p class="description">Leave empty to keep the post published.</p>';
}, 'post', 'side' );
} );
add_action( 'save_post_post', function ( $post_id ) {
if ( ! isset( $_POST['wpide_expiry_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['wpide_expiry_nonce'] ) ), 'wpide_expiry_save' ) ) {
return;
}
if ( ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) || ! current_user_can( 'edit_post', $post_id ) ) {
return;
}
$value = isset( $_POST['wpide_expires'] ) ? sanitize_text_field( wp_unslash( $_POST['wpide_expires'] ) ) : '';
if ( preg_match( '/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}$/', $value ) ) {
update_post_meta( $post_id, 'wpide_expires', $value );
} else {
delete_post_meta( $post_id, 'wpide_expires' );
}
} );
add_action( 'init', function () {
if ( ! wp_next_scheduled( 'wpide_unpublish_expired_posts' ) ) {
wp_schedule_event( time() + 300, 'hourly', 'wpide_unpublish_expired_posts' );
}
} );
add_action( 'wpide_unpublish_expired_posts', function () {
$expired = get_posts( array(
'post_type' => 'post',
'post_status' => 'publish',
'fields' => 'ids',
'numberposts' => 50,
'meta_query' => array(
array( 'key' => 'wpide_expires', 'value' => '', 'compare' => '!=' ),
array( 'key' => 'wpide_expires', 'value' => current_time( 'Y-m-d\TH:i' ), 'compare' => '<=' ),
),
) );
foreach ( $expired as $post_id ) {
wp_update_post( array( 'ID' => $post_id, 'post_status' => 'draft' ) );
}
} );
Notes
A check runs every hour with WP-Cron, so posts expire within an hour of the chosen time. Dates use the site time zone.
How to add this snippet
- Install WPIDE on your WordPress site (it is free) and open Code Snippets.
- Use snippet above adds it from the library in one click. Or copy the code into a new snippet with the same code type.
- It is added inactive: review the code and settings, then switch it on.