1

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).

1
  • You get endless loop because your hook calls wp_update_post() which calls wp_insert_post() which calls your hook... And the circle have closed.
    – Rarst
    Oct 26, 2012 at 21:57

4 Answers 4

0

Have you tried to use "wp_insert_post_data" instead of "pre_post_update"?

2
  • something like this: add_filter('wp_insert_post_data', 'change_post_status', 99, 2);
    – Daniel
    Oct 26, 2012 at 21:27
  • I have not, I will give it a shot. Never used that filter before. Not sure how to use it without $post_id as a parameter.
    – tyler
    Oct 29, 2012 at 15:02
0

Since your logic is based on role, just not give it publish_posts capability? The way native Contributor role works.

1
  • This would work, however the way it is set up I made custom post types and the user posts listings via gravity forms. Once their listing is accepted an admin publishes it so after that point the user can update whenever they want. I need it so when they update the post becomes a draft until it is reviewed again.
    – tyler
    Oct 29, 2012 at 15:01
0

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;
}
-1

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 );
}
2
  • This is wrong. is_admin() does not check for the administrator role, and the code should run in backend too, that’s the whole point. The check for a user role works exactly as it should.
    – fuxia
    Sep 13, 2013 at 0:24
  • If the original issue needed to be done to every post, then its OK. My issue was setting a status to 'draft' after a user edited his post in the frontend (with wp_user_frontend). After that the admin in the backend could not publish the post, because it updated the status to "draft" all the time. That is why i needed to restrict it to the frontend, and that is exactly what is_admin() does - checks if you are in the backend.
    – Asped
    Sep 13, 2013 at 7:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.