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="http://stackoverflow.com/questions/34954508/wordpress-expire-posts-based-on-user-role/34956885#34956885"]]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!
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() {
$role="oawofficer";
$cpt="animals";
$blogusers = get_users( 'role='.$role );
foreach ( $blogusers as $user ) {
$userids[]=$user->ID;
}
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"));
if($expiration_value<=$current_date){
$current_post = get_post( $pp->ID, 'ARRAY_A' );
$current_post['post_status'] = 'draft';
wp_update_post($current_post);
}
}
}
You can test in your localhost loading the function
change_post_status()
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) );
}
if($expiration_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' );
}
add_action('auto_expire_posts_cron_hook','auto_expire_posts');