5

In wordpress, by default, authors can create and make all changes to their posts.

I'm looking for a way to restrict them from making to any change to a post if administrator has made any modification to that particular post (after the admin click "update" button).

For posts that have not been modified by administrator, the author still can make any change they want.

I have tried through a number of user role plugins, but cannot find any plugin that can help.

Thank you very much.

1 Answer 1

6

You can try the following:

/**
 * Post Update Locker For Authors
 * If an administrator has updated the post, then lock it for author updates.
 * @see http://wordpress.stackexchange.com/a/168578/26350
 */

add_action( 'pre_post_update', function( $post_ID, $data ) {

    // Target only authors:
    if( ! current_user_can( 'edit_post' ) || current_user_can( 'edit_others_posts' ) )      
        return;

    // Target only 'post' post types:
    if( get_post_type( $post_ID ) !== 'post' )
        return;

    // Fetch all administrators:
    $admins_ids = get_users( 
        array( 
            'role'   => 'administrator', 
            'fields' => 'ID' 
        ) 
    );

    // or hardcoded if needed:
    // $admins_ids = array( 1 );

    // Check if administrators have modified the current post, by checking the revisions:
    $posts = get_posts( 
        array( 
            'no_found_rows'             => true,
            'update_post_meta_cache'    => false,
            'update_post_term_cache'    => false,
            'posts_per_page'            => -1, 
            'fields'                    => 'ids', 
            'post_parent'               => $post_ID, 
            'post_type'                 => 'revision', 
            'post_status'               => 'any', 
            'author__in '               => $admin_ids,  
        ) 
    );

    // Halt if an administrator has modified the post:
    if( count( $posts ) > 0 )
        wp_die( __( "Sorry, you can't modify this post, it's already been modified by an administrator! " ) );

}, 10, 2 );

You might have to adjust this and test further.

Update:

Here's an additional example how one can remove the submitdiv metabox for authors that can't update the current post anymore:

/**
 * Hide the publish metabox for authors if an administrator has updated the post.
 * @see http://wordpress.stackexchange.com/a/168578/26350
 */

add_action( 'admin_menu', function() {
    add_action( 'load-post.php', 'wpse_author_update_locking' );
});

function wpse_author_update_locking()
{
    // Setup - Modify this to your needs:
    $admin_ids = array( 1 );
    $cpt       = 'post';

    // User input:
    $_pid    = filter_input( INPUT_GET, 'post',   FILTER_SANITIZE_NUMBER_INT );

    // Target only $cpt post types:
    if( get_post_type( $_pid ) !== $cpt )
        return;

    // Target only authors:
    if( ! current_user_can( 'edit_post' ) || current_user_can( 'edit_others_posts' ) )      
        return;

    if( $_pid > 0 )
    {
        // Check if administrators have modified the current post, 
        // by checking the revisions:
        $posts = get_posts( 
            array( 
                'no_found_rows'             => true,
                'update_post_meta_cache'    => false,
                'update_post_term_cache'    => false,
                'posts_per_page'            => -1, 
                'fields'                    => 'ids', 
                'post_parent'               => $_pid, 
                'post_type'                 => 'revision', 
                'post_status'               => 'any', 
                'author__in '               => $admin_ids,  
            ) 
        );

        // Halt if an administrator has modified the post:
        if( count( $posts ) > 0 )
        {
            remove_meta_box( 'submitdiv', $cpt , 'side' ); 
            add_meta_box( 
                'submitdivmod', 
                __( 'Publish' ), 
                'wpse_post_submit_meta_box', 
                $cpt, 
                'side', 
                'core' 
            ); 
        }
    }
}

function wpse_post_submit_meta_box()
{
    _e("Sorry, you can't modify this post, it's already been modified by an administrator!");
}

and then instead of this metabox:

The publish metabox available

the author sees this:

The publish metabox NOT available

3
  • I have to say that this is very nice! To OP, I suggest to optimise it a little bit, like add the admin ID's directly into the get_users() query.
    – Christine Cooper
    Nov 16, 2014 at 15:10
  • I have just tested this and it works. I have learnt some more things about wordpress. Thank you very much :). Thanks Christine Cooper for your suggestion. I may need to consider it also
    – aye
    Nov 16, 2014 at 15:14
  • 1
    I agree with @ChristineCooper, there are many ways to adjust and fine tune it, for example if you got a only a single admin then there's no need to make an extra user query. Similarly if your user base is very large, then you could consider storing the admins in an options/transients. I updated the answer with an additional example on how to remove the publish metabox for the authors that can't update anymore, to have a better user experience.
    – birgire
    Nov 16, 2014 at 17:01

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.