Grant Edit Access to Specific Posts Only to a Specific Role

WordPress has a decent role management system for users but there can be cases when you need a specialized set of restrictions to put in place that the default system wouldn’t allow you. One such instance would be to limit user’s access for the pages or posts in the WP Admin panel. There can be situations you would like to grant users editing access to a limited set of pages or posts.

Below we will see how we can restrict editing capabilities of users to grant them access to a set of pages or posts only, in our example we will be using Editor role but you can modify the code as per your requirement. You might find a plugin too that achieves the same result but here we are doing it without installing any plugin.

Don’t forget to modify the logic in can_user_edit_the_object to your requirements.

<?php
// this is helper function that when called will tell if user should be allowed
// to edit the object, add your custom logic
function can_user_edit_the_object($user_id, $object_id) {
    $allowed_ids = [1, 2, 3];
    // if user id is 1 and the object is not in allowed list then return false
    if( $user_id == 1 && !in_array($object_id, $allowed_ids) ) return false;
    
    // by default editing allowed
    return true; 
}

// add the map_meta_cap to modify the caps of our concern
add_filter( 'map_meta_cap', function ( $caps, $cap, $user_id, $args ) {
    $u = wp_get_current_user();

    // if not the role we are modifying the caps for then return $caps
    if( !in_array('editor', (array) $u->roles) ) return $caps;
    
    // list of capabilities that we are modifying    
    $to_filter = [ 'edit_post', 'delete_post', 'edit_page', 'delete_page' ];

    // if not the cap we are modifying then return $caps
    if ( ! in_array( $cap, $to_filter, true ) ) {
        return $caps;
    }

    // $args[0] will contain the object id (post/page id)
    if ( ! $args || empty( $args[0] ) || ! can_user_edit_the_object( $user_id, $args[0] ) ) {
        // deny access
        return [ 'do_not_allow' ];
    }
    
    return $caps;

}, 10, 4 );

We used the map_meta_cap to modify the capabilities for the user. To make sure that above code works as expected don’t forget to grant the user you are modifying capabilities that grants them access to edit others posts and pages, i.e., edit_others_posts and edit_others_pages. You can use add_cap to achieve that.

Leave a Reply

Your email address will not be published. Required fields are marked *