Warning: Illegal string offset 'css' in /home/peking5/public_html/wp-content/plugins/flgs-per-post-code-safe.php on line 82

Warning: Illegal string offset 'js' in /home/peking5/public_html/wp-content/plugins/flgs-per-post-code-safe.php on line 82



WordPress: make posts expire or auto-delete

Posted in hack, WordPress

While working on a website, the client needed the homepage to function differently from other websites and blogs.

Rather than having the home page show the last x number of posts or editing the loop through query_posts to only show posts within a certain timeframe, the posts would either need to appear on the homepage until:

  • a specific date – and then the post will either be archived or deleted
  • or if no date is set, the post should appear for a month

I knew that there was a way to makes posts “expire” by setting a date and time as a custom field and editing the loop. A search on Google reveals several articles (all of which are identical – exactly the same, so I don’t know the original article which I could link to). I then also found an article that edited the expire posts code so that the post would auto delete rather than expire: Modify you WordPress theme to enable an expiration date for your posting.

There a few drawbacks to the methods I found:

  • they needed post custom fields, which aren’t the most user friendly interface for end users to employ
  • custom fields do not look nice
  • the custom field entry needed to be in the format mm/dd/yyyy 00:00:00 not exactly user friendly nor easy to understand (is 17:00:00 7pm or 5pm??)
  • posts would either only expire (be archived) or be deleted

So now I needed to put on my PHP hat and find a way to get what needed to be done and avoid the drawbacks listed above. I knew right away that I would need to use custom write panels to make everything easy to look at and use. I wrote about using them here, WordPress Custom Write Panels & prioritizing what to display and used this as my reference, Revisited: Creating Custom Write Panels in WordPress

In the end, this is what my WordPress custom write panel looked like:
WordPress make posts expire or auto-delete

Obviously, this is for posts in the “announcements” category. Anyway, open up your themes functions.php (or make one) and add this code in:

<?php
//start  post meta box
$key = "Announcements";
$meta_boxes = array(

"expimo" => array(
"name" => "expimo",
"title" => "Expiration Month",
"description" => "Select a date in the future for this post to expire.  Default date is one month into the future",
"option" => array('01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12')),

"expida" => array(
"name" => "expida",
"title" => "Expiration Day",
"description" => "Select Day",
"options" => array('-', '01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31')),

"expiye" => array(
"name" => "expiye",
"title" => "Expiration Year",
"description" => "Select Month",
"options" => array('-', '2013', '2012', '2011', '2010')),

"expiti" => array(
"name" => "expiti",
"title" => "Expiration Time",
"description" => "Select Time",
"options" => array('00:00:00', '01:00:00', '02:00:00', '03:00:00', '04:00:00', '05:00:00', '06:00:00', '07:00:00', '08:00:00', '09:00:00', '10:00:00', '11:00:00', '12:00:00', '13:00:00', '14:00:00', '15:00:00', '16:00:00', '17:00:00', '18:00:00', '19:00:00', '20:00:00', '21:00:00', '22:00:00', '23:00:00')),

"autodelp" => array(
"name" => "autodelp",
"title" => "Delete Post On Expiration",
"description" => "Choose if a post should be deleted after expiration.  Choosing NO will remove the post from the homepage and archive it upon expiration",
"options" => array('no', 'yes')),

);

function create_meta_box() {
global $key;

if( function_exists( 'add_meta_box' ) ) {
add_meta_box( 'new-meta-boxes', ucfirst( $key ) . ' Post Options', 'display_meta_box', 'post', 'normal', 'high' );
}
}

function display_meta_box() {
global $post, $meta_boxes, $key;
?>

<div class="form-wrap">

<?php



wp_nonce_field( plugin_basename( __FILE__ ), $key . '_wpnonce', false, true );





foreach($meta_boxes as $meta_box) {
$data = get_post_meta($post->ID, $key, true);





?>
<?php if($meta_box[ 'name'] != 'expimo' && 
         $meta_box[ 'name'] != 'expida' &&
         $meta_box[ 'name'] != 'expiye' &&
		 $meta_box[ 'name'] != 'autodep' &&
		 $meta_box[ 'name'] != 'expiti' &&
		 $meta_box[ 'name'] != 'autodelp'
) { ?>
<div class="form-field form-required">


<label for="<?php echo $meta_box[ 'name' ]; ?>"><?php echo $meta_box[ 'title' ]; ?></label>

<input type="text" name="<?php echo $meta_box[ 'name' ]; ?>" value="<?php echo htmlspecialchars( $data[ $meta_box[ 'name' ] ] ); ?>" />  

<p><?php echo $meta_box[ 'description' ]; ?></p></div>
<?php } elseif ($meta_box[ 'name'] == 'expimo') {

echo '<div class="form-field form-required"><label for="Post Expiration Date">Post Expiration Date</label>';
echo '<select name="expimo" id="expimo">';
	foreach ($meta_boxes['expimo']['option'] as $option) {
	if ($option == '01') {$optionez = 'January';
} elseif ($option == '02') {$optionez = 'February';
} elseif ($option == '03') {$optionez = 'March';
} elseif ($option == '04') {$optionez = 'April';
} elseif ($option == '05') {$optionez = 'May';
} elseif ($option == '06') {$optionez = 'June';
} elseif ($option == '07') {$optionez = 'July';
} elseif ($option == '08') {$optionez = 'August';
} elseif ($option == '09') {$optionez = 'September';
} elseif ($option == '10') {$optionez = 'August';
} elseif ($option == '11') {$optionez = 'November';
} else {$optionez = 'December';}
		echo '<option', ' value="', $option, '"', $data[ 'expimo' ] == $option ? ' selected="selected"' : '', '>', $optionez, '</option>';
                }
                echo '</select>';
echo '<select name="expida" id="expida">';
	foreach ($meta_boxes['expida']['options'] as $option) {
		echo '<option', ' value="', $option, '"', $data[ 'expida' ] == $option ? ' selected="selected"' : '', '>', $option, '</option>';
                }
                echo '</select>';
echo '<select name="expiye" id="expiye">';
	foreach ($meta_boxes['expiye']['options'] as $option) {
		echo '<option', $data[ 'expiye' ] == $option ? ' selected="selected"' : '', '>', $option, '</option>';
                }
                echo '</select>';
echo '<select name="expiti" id="expiti">';
	foreach ($meta_boxes['expiti']['options'] as $option) {
if ($option == '00:00:00') {$optionez = '12MN';
} elseif ($option == '01:00:00') {$optionez = '1AM';
} elseif ($option == '02:00:00') {$optionez = '2AM';
} elseif ($option == '03:00:00') {$optionez = '3AM';
} elseif ($option == '04:00:00') {$optionez = '4AM';
} elseif ($option == '05:00:00') {$optionez = '5AM';
} elseif ($option == '06:00:00') {$optionez = '6AM';
} elseif ($option == '07:00:00') {$optionez = '7AM';
} elseif ($option == '08:00:00') {$optionez = '8AM';
} elseif ($option == '09:00:00') {$optionez = '9AM';
} elseif ($option == '10:00:00') {$optionez = '10AM';
} elseif ($option == '11:00:00') {$optionez = '11AM';
} elseif ($option == '12:00:00') {$optionez = '12NN';
} elseif ($option == '13:00:00') {$optionez = '1PM';
} elseif ($option == '14:00:00') {$optionez = '2PM';
} elseif ($option == '15:00:00') {$optionez = '3PM';
} elseif ($option == '16:00:00') {$optionez = '4PM';
} elseif ($option == '17:00:00') {$optionez = '5PM';
} elseif ($option == '18:00:00') {$optionez = '6PM';
} elseif ($option == '19:00:00') {$optionez = '7PM';
} elseif ($option == '20:00:00') {$optionez = '8PM';
} elseif ($option == '21:00:00') {$optionez = '9PM';
} elseif ($option == '22:00:00') {$optionez = '10PM';
} else {$optionez = '11PM';}
		echo '<option', ' value="', $option, '"',$data[ 'expiti' ] == $option ? ' selected="selected"' : '', '>', $optionez, '</option>';
                }
                echo '</select>';
echo '<p>Select a date in the future for this post to expire.  Default date is one month into the future</p></div>';
} elseif ($meta_box[ 'name'] == 'autodelp') {
echo '<label for="Auto Delete">Auto Delete?</label>';
echo '<select name="autodelp" id="autodelp">';
                foreach ($meta_boxes['autodelp']['options'] as $option) {
                    echo '<option', $data[ 'autodelp' ] == $option ? ' selected="selected"' : '', '>', $option, '</option>';
                }
                echo '</select><p>', $meta_box[ 'description' ], '</p></div>';
} else {} 
?>

<?php 
}; ?>


<?php 
if (get_the_time('m') == 12) {$mononet = 1;
} else {$mononet = 1 + get_the_time('m');}
$slashhh = '/';
      $spaceeee = ' ';
if ( $data[ 'expida'] == '-') {$datarr = $mononet.$slashhh.get_the_time('d/Y').$spaceeee.$data[ 'expiti' ];
} else {$datarr = $data[ 'expimo' ].$slashhh.$data[ 'expida' ].$slashhh.$data[ 'expiye' ].$spaceeee.$data[ 'expiti' ];} ?>
<?php update_post_meta($post->ID, 'expiration', $datarr); ?> 
</div>
<?php
}
function save_meta_box( $post_id ) {
global $post, $meta_boxes, $key;

foreach( $meta_boxes as $meta_box ) {
$data[ $meta_box[ 'name' ] ] = $_POST[ $meta_box[ 'name' ] ];
}

if ( !wp_verify_nonce( $_POST[ $key . '_wpnonce' ], plugin_basename(__FILE__) ) )
return $post_id;

if ( !current_user_can( 'edit_post', $post_id ))
return $post_id;

update_post_meta( $post_id, $key, $data );
}

add_action( 'admin_menu', 'create_meta_box' );
add_action( 'save_post', 'save_meta_box' );
//end  post meta box
?>

It’s a bit lengthy, but it does what it needs to.

Now open up your index.php or whichever file has the loop which you will need to edit and modify your loop between the while (have_posts()) and endwhile statements as such:

<?php while (have_posts()) : the_post(); $data = get_post_meta( $post->ID, 'Announcements', true ); 
	$expirationtime = get_post_custom_values('expiration');
if (is_array($expirationtime)) {
$expirestring = implode($expirationtime);
}
$secondsbetween = strtotime($expirestring)-time() + 14400;
if ( $secondsbetween <= 0 && $data[ 'autodelp'] == 'yes') {
wp_delete_post($post->ID, false);
} elseif ( $secondsbetween <= 0 && $data[ 'autodelp'] == 'no') {
} elseif ( $secondsbetween > 0) {
	?>
<!--start your loop contents here. For example...-->
	<h2><a href="<?php the_permalink() ?>"><?php the_title(); ?></a></h2>
<p>Posted on <?php the_time('M.d, Y') ?></p>
<?php the_content('Read more &raquo;'); ?>
<!--end your loop contents here-->
	<?php } else {}
	endwhile; ?>

Please note that 14400on line 06 is to change the time to my current time zone, US Eastern Time. For best results, you should change this number to reflect your current timezone. To calculate the number you would use for your timezone, use this from Modify you WordPress theme to enable an expiration date for your posting:

Let say, you are in GMT +7 time zone, you are ahead of time, so instead of “+”, you will need to “-” the difference, 7 hours = 7 * 60 *60 = 25200.

Don’t forget to save and upload your changes. To use the panel, while writing or editing a post, in the custom write panel named Announcements Post Options, simply select the date and time which you would like the post to expire under the Post Expiration Date section. If you want the post to be deleted upon expiration, select yes in the Auto Delete section. If no date is chosen, the post will automatically expire one month from the “publish date” of the post.

Hope you like that and find it useful.


18 Comments for this entry

  • seorocks

    Many thanks for sharing the code above.. its Great.

    would it be possible to show JUST the list of expired events? can you post all the code needed to create such page?

    i am after creating (past events) page..

    thanks in advance

    T

  • coco

    Great post, many thanks! However, can I make it function so that it automatically expires all posts on the next day of creation for example at 6am?

  • Ron

    I need to be able to set an offset from the post date for it to be deleted. For example the deltetion date for any post should be post date + x where x can be a day, a week, a month, etc.

    Ideally this is a one time setting for all posts so I only have to set it up once and posts that meet the deletion criteria will automatically be deleted.

    Does your code do this? Also will this work with the latest version of WP?

    thanks

    • Jason

      all you have to do is set $expirestring to be your publish date + whatever time period you specify.

      Haven’t tested this on the latest version of WP, but it should work, none of the WP functions I use have been deprecated to my knowledge

  • Art Galus

    I have been hunting for this solution for some time. I am not a regular user of PHP, having retired long ago. But I volunteered to help some friends with their website which was created in WordPress. They are interested in expiring only specific posts. How would I change your code to apply to any category of posts or did I miss instructions for that in this article?

    BTW: A short posting time of one day would be ideal for a central announcement hub for a small business or activity to allow production teams to ‘heads up’ their managers daily.

    Thank you again.
    Art Galus

    • Jason

      looks like I didn’t add anything to limit it to any particular category. So long as the category you want uses the loop code above, it will work.

      If you only need a short posting time one day, why not just show one post on the homepage (if that’s one post/day)? Or use a script to send a user to the latest current day’s archive page? (with the “Day and Name” permalink setting, url is the date like domain.com/2011/06/23/)

  • edwardhanat

    wow! very cool, its a lot more complex than I expected, but i am psyched to try it out.

  • Daniel

    Hi, how can I set up this to work with a date that is already the tag of the post – Each of my posts have a tag indicating the date for which the info on the post is expired, how i can use that tag instead to give manually a expire date to each post ?

  • ENIX

    @Jason,

    on line 88 you have a typo, it says ‘AUGUST’ but it should be ‘OCTOBER’ :)

  • Javier

    Hi Jason!

    It is driving me crazy cause I´m not a programmer ( …just a designer) and my knowledge of php is “copy-paste”… but I achieved it works with normal post!!!

    :( Really, I need that it works wiith custom content type!!!! Any help?!

    Thanks for your cool code!

  • Rhev

    is there anyway i can make this work thru front end posting?

  • sergio

    Is it possible to make it work but for comments?
    Put an expiration date for comments..

1 Trackback or Pingback for this entry

Leave a Reply