change a post status when users update posts?

Is there an efficient way to change a post status from ‘published’ to ‘draft’ when a user of a certain type tries to update their posts. I tried something along these lines

function change_post_status($post_id)
{
  if(current_user_can('rolename'))
  {
    $current_post = get_post( $post_id, 'ARRAY_A' );
    $current_post['post_status'] = 'draft';
    wp_update_post($current_post);
  }
}

add_action('pre_post_update','change_post_status'); 

The code looks good to me but for some reason it doesnt work properly and I think it creates an endless loop(forcing me to restart my SQL server).

Related posts

Leave a Reply

4 comments

  1. So I ended up using the wp_insert_post_data filter and came up with the following, which after testing, seems to be working properly.

    add_filter('wp_insert_post_data', 'change_post_status', '99');
    
    function change_post_status($data)
    {
        if( (current_user_can('role')) && ($data['post_type'] == 'custom_post_type') )
        {
            if(defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;
            //then set the fields you want to update
            $data['post_status'] = 'draft';     
        }
        return $data;
    }
    
  2. I would like to add one more issue. When you use the code above, it will happen to EVERY post, also if you do an update in the backend! Because wp_insert_post_data is triggered eveytime a post is updated, so also if e.g. the admin wants to publish a post – it will automatically trigger again, and set the post to draft. So it will not be possible to publist anymore.
    Here a modified code which worked for me, check if we are in the admin backend:

    function change_post_status( $data, $postarr ) {
          $data[ 'post_status' ] = 'draft';
          return $data;
    }
    if (!(is_admin())) {
      add_filter( 'wp_insert_post_data' , 'change_post_status' , '99', 2 );
    }