Ask your WordPress questions! Pay money and get answers fast! Comodo Trusted Site Seal
Official PayPal Seal

Expire Posts based on User Role WordPress


I'm trying to have posts automatically expire based on the role of the author of the post. While there are a lot of wordpress expiration plugins out there, the majority of them are granular in the sense that they let you set the expiration on a post by post basis. I was able to find one plugin (over 2 years old) which supposedly worked by user role and custom post type, but it was no longer working correctly. Ideally, what I need to accomplish is:

- I have a CPT called animals (this is a lost/found board for local animal control)
- Open (guest) posts is possible via the frontend. These posts get posted as the main admin role
- Animal service officers can also post (with logged in accounts) which all have a custom role of 'oawofficer' assigned to them
- After post expiration, the status should be changed to draft

Officers are only posting 'found' pets, and those posts must expire after 5 days (because they then head to adoption). Posts by all other users expire after 30 days.

I had someone post a 'solution' on [[LINK href=""]]stackoverflow[[/LINK]], but it does not appear to be working -- not sure if the cron job isn't running (did try using alternative cron in wp-config but made no difference) or if there is another issue with the solution that was posted.

Thanks in advance!

Answers (3)


Rempty answers:

Add this to your functions.php, i set to role=oawofficer, cpt= animals and expiration 5 days after publish.

if ( ! wp_next_scheduled( 'change_post_status' ) ) {
wp_schedule_event( time(), 'hourly', 'my_cronhook' );
add_action( 'my_cronhook', 'change_post_status' );

function change_post_status() {
$blogusers = get_users( 'role='.$role );
foreach ( $blogusers as $user ) {
global $wpdb;
$post_ids = $wpdb->get_results( "SELECT ID,post_date FROM $wpdb->posts WHERE post_status ='publish' AND post_author IN (".implode(',',$userids).") AND post_type='".$cpt."' " );
foreach($post_ids as $pp){
$origpostdate= strtotime ($pp->post_date);
$expiration_value = strtotime ( '+5 day' , $origpostdate );
$current_date=strtotime(date("Y-m-d H:i:s"));
$current_post = get_post( $pp->ID, 'ARRAY_A' );
$current_post['post_status'] = 'draft';

You can test in your localhost loading the function
Modify the publish date and test, i tested the code with posts

Andrew Clemente comments:

This seem to work great! Thanks!


Andrea P answers:

hi there!

that function you posted was a bit of a mess. lot of typos and some not recommended code practices.
I've reviewed and corrected it

if you add this to functions.php it should create a cron job which will check hourly if any post of the animals post_type should be put as a draft.
the code at the moment is expiring after 5 days if author has the role of 'oawofficer', otherwise any other animal post will expire after 30 days. let me know if I got it wrong.

function auto_expire_posts(){
//get all animals posts
$animals = get_posts('post_type=animals');

foreach($animals as $animal){
unset ( $post_date, $author_roles);
$post_date = get_the_date( 'Y-m-d', $animal->ID );
$author_roles = get_the_author_meta( 'roles', $animal->post_author );

if ( in_array("oawofficer", $author_roles) ) {
$expiration_date = strtotime ( '+5 day' , strtotime ($post_date) );
else {
$expiration_date = strtotime ( '+30 day' , strtotime ($post_date) );

$todays_date = date("Y-m-d");
$today = strtotime($todays_date);

if ($expiration_date < $today) {

// it is expired, we set post status to draft, without changing anything
$my_post = array();
$my_post['ID'] = $animal->ID;
$my_post['post_status'] = 'draft';

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




//verify event has not been scheduled

if ( !wp_next_scheduled( 'auto_expire_posts_cron_hook' ) ) {

//schedule the event to run daily
wp_schedule_event( time(), 'hourly', 'auto_expire_posts_cron_hook' );



Arnav Joy answers:

which plugin you are using ?? which is 2 years old ??