0

I have created a number of custom post statuses using the EdiFlow plugin. Now, what I am trying to do is, if the contribter visits the post edit page and the post status is "assigned" to automatically change into "work in progress". This would allow me to know and send them an e-mail when they start working on it (on post edit page load).

I am trying to use this code which doesn't seem to do anything

function educadme_assigned_to_inprogress( $post_id ) {
if ( current_user_can('edit_post', $post_id) && !current_user_can( 'manage_options' ) ) {

            $post = get_post($post_id);
            if (get_post_type()=='post' && $post->post_status =='assigned' && strstr($_SERVER['REQUEST_URI'], 'wp-admin/post-new.php')) {                                   
                    $post->post_status = 'in-progress'; // use any post status
                    wp_update_post($post); 
                }
    }
}
add_action('add_meta_boxes', 'educadme_assigned_to_inprogress');

Another simplified version with less conditionals might be:

function educadme_assigned_to_inprogress( $post_id ) {
if ( current_user_can('edit_post', $post_id) && !current_user_can( 'manage_options' ) ) {

            $post = get_post($post_id);
            $screen = get_current_screen();

            if ($screen->base != 'post')
                return;

            if ($post->post_status =='assigned') {                                      
                $post->post_status = 'in-progress'; // use any post status
                wp_update_post($post); 
            }
    }
}
add_action('add_meta_boxes', 'educadme_assigned_to_inprogress');

Another similar version which kind of worked but caused an issue explained below was:

function educadme_assigned_to_inprogress( $post_id ) {
if ( current_user_can('edit_post', $post_id) && !current_user_can( 'manage_options' ) ) {

            $post = get_post($post_id);
            if (get_post_type()=='post' && $post->post_status =='assigned' && strstr($_SERVER['REQUEST_URI'], 'wp-admin/post-new.php') || strstr($_SERVER['REQUEST_URI'], 'wp-admin/post.php')) {                                   
                    $post->post_status = 'in-progress'; // use any post status
                    wp_update_post($post); 
                }
    }
}
add_action('add_meta_boxes', 'educadme_assigned_to_inprogress');

The main issue with this code is that it runs not just when the custom status is assigned. Also, it runs on the page listing all the posts, not just inside the individual edit post page. Meaning, if I am viewing the list of posts, it changes their post status!

Any advice or corrections would be appreciated. I am sure others would also find this of use.

4
  • It's hard to see what's wrong with it. Could you try splitting your conditionals so it does one at a time because there's a chance the && and || might not be as clear as it seems. Also you can use get_current_screen() to test for the page. If you refactor your code then we can see what's wrong. May 1, 2014 at 21:30
  • @StevenJones Thanks for your comment. Would the added simplified version suffice? I am not that good with codes :).
    – Dr.Hariri
    May 1, 2014 at 21:41
  • @A.Hariri My suggestion would be to add an actual post status of in-progress that they manually change it to. Otherwise someone might accidentally click on it and change it without them actually start working on it. May 2, 2014 at 1:38
  • @TylerCarter Good point, will look into it. Thanks!
    – Dr.Hariri
    May 2, 2014 at 7:58

2 Answers 2

2

If you want the default post status to be in-progress when contributors click on "New Post", then you can try the following:

/**
 * Set default post status as 'in-progress' for contributors
 *
 * @link https://wordpress.stackexchange.com/a/143128/26350
 *
 * @param  array $data 
 * @return array $data
 */

function wpse_143100_wp_insert_post_data( $data )
{
    $current_user = wp_get_current_user();      

    if( 'auto-draft' === $data['post_status']
        && 'post' === $data['post_type']
        && '0000-00-00 00:00:00' === $data['post_date_gmt']
        && in_array( 'contributor', $current_user->roles, TRUE ) 
    )
        $data['post_status'] = 'in-progress';

    return $data;
}           

add_filter( 'wp_insert_post_data', 'wpse_143100_wp_insert_post_data' );

It's informative to investigate the default post status transitions:

  1. Click on "New Post":

    new -> auto-draft
    
  2. Auto-Save:

    auto-draft -> draft
    
  3. Change post status manually to "In Progress" and then press the "Update" button:

    draft -> in-progress
    new   -> inherit (revision created)
    
  4. Press again the "Update" post:

    in-progress -> in-progress
    

You can hook into these transitions with the transition_post_status hook.

Update:

Here's a modification of your example:

function educadme_assigned_to_inprogress()
{    
    global $post;
    if ( get_current_user_id() == $post->post_author  // current user is the post author
         && 'post' === get_post_type()                // current post type is 'post'
         && 'assigned' === get_post_status()          // current post status is 'assigned'
         && ! current_user_can( 'publish_post' )      // current user is 'contributor'
         && function_exists( 'EditFlow' )             // Edit flow plugin is installed
    ):
        if ( $post->ID > 0 ):
            $post->post_status = 'in-progress';  // use any post status
            $pid = wp_update_post( $post );      // update post             
            if ( is_wp_error( $pid ) ):          // debug
                // error_log( $pid->get_error_message(), 1 );
            endif;
        endif;
    endif;
}

add_action( 'admin_head-post.php', 'educadme_assigned_to_inprogress');

where I use the admin_head-post.php hook to narrow it down to the post screen only.

The post status will only change to in-progress if

  • the current user is the post author
  • the current user is a contributor
  • the Edit Flow plugin is installed
  • the current post type is post.
  • the current post status is assigned.

Notice that you will need to refresh to see the updated status.

5
  • Mostly, this would be run when editing a post, not creating a new one. The idea to hook the update to the previous status, if that is possible, is that because before they start working on their piece, I will give them the go by assigning the post to them. Then, once they visit the post to edit it the status would be updated to in-progress.
    – Dr.Hariri
    May 2, 2014 at 8:01
  • Is there a reliable way to change the first code to run on post edit directly if the post status is 'assigned'? The reason why I didn't use post transition hook is because I couldn't see how to implement it in a reliable way, since I want the auto change of the status to occur when the use visits the page rather when I change the post status. Thanks!
    – Dr.Hariri
    May 2, 2014 at 8:04
  • So the workflow is like the following: 1) You create a post. 2) You assign it to a user called Tom, for example. 3) Tom opens the post to do some editing 4) You want the post status to change automatically from assigned to in-progress, so when Tom opens it for the first time, he can already see that it has the in-progress status. - Was this description even close? ;-)
    – birgire
    May 2, 2014 at 15:11
  • Very close but there is a correction. Here is the whole process: 1) Tom creates a new post explaining his idea/proposal for a post. 2) I review it, if good, I change it to 'assigned' which automatically notifies Tom of this + sends him extra information on what to do. 3) Tom visits the same post, edit it this time to write the whole article. At this time when he opens it, it would have 'assigned'. I want it to instead change to 'in-progress'. This way, I can track who have started working on this post and who hasn't :). Is there another suggested way to do this? Thanks!
    – Dr.Hariri
    May 2, 2014 at 19:54
  • @A.Hariri I updated the answer with a modification of your answer.
    – birgire
    May 5, 2014 at 14:04
0

After many tests, it seems that this code is working. Please suggest improvements if you have any! I have tested this but I need to test it more thoroughly:

function educadme_assigned_to_inprogress() {
global $post;
$id = get_the_ID();
if ( current_user_can('edit_post', $id) && !current_user_can( 'manage_options' ) ) {

            $post = get_post($id);
            $screen = get_current_screen();             

            if ($screen->base != 'post')
                return;

            if ( ! function_exists( 'EditFlow' ) )
                return;

            $post_status = get_post_status();

            if ($post_status =='assigned') {                                    
                $post->post_status = 'in-progress'; // use any post status
                wp_update_post($post); 
            }
    }
}
add_action('admin_head', 'educadme_assigned_to_inprogress');

If you use another post status plugin or added them yourself instead of EditFlow then remove this bit:

            if ( ! function_exists( 'EditFlow' ) )
                return;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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