2

Is there a way "hook" or custom code to allow user with custom role "abc" to edit and remove another users with custom role "xyz" by using map_meta_cap ?

Thanks

1
  • No, there is no built-in way to allow a user to edit only a subset of users. Managing users includes capabilities that apply to all users - edit_users, list_users, promote_users, create_users, add_users, delete_users. If you just need to grant them access to edit and delete users across the board, using add_cap and assigning whichever of these capabilities you want them to access will do the trick.
    – WebElaine
    Jan 3 '18 at 18:30
1

I think its possible, I have wrote a code in functions.php in the theme and its working fine. If there someone could make it better :D We have a custom meta for each user and that could be done using ACF. Admin only can set that meta to the user (beauticians).

I have 2 custom roles salonowner, and beauticians. salonowner have access to edit, list users. We have a post type "Listing" and salonowner can create a post there. Lets call it Salon1. Admin only can assign beauticians to Salon1 by using ACF "meta" and I have create Relationshop field.. here its called list_for_user.

Here we create the 2 new custom roles:

add_action( 'after_setup_theme', 'create_custom_roles' );
function create_custom_roles() {
    add_role( 'salonowner', 'salonowner');
    add_role( 'beauticians', 'beauticians');
}

Here we assign edit and list users for salonowner role:

add_action('admin_init','add_role_caps',999);
function add_role_caps() {
    $salonowner = get_role('salonowner');
    $salonowner->add_cap('edit_users');
    $salonowner->add_cap('list_users');
}

With this custom code we can deny salonowner from editing any other users and let him only edit the user that have same meta for their Listing "Salon1".

add_filter( 'map_meta_cap', 'custom_map_meta_cap', 10,4);
function map_meta_cap( $caps, $cap, $user_id, $args ){
if ( ! function_exists( 'get_current_screen' ) )
        return;
    $screen = get_current_screen();

    if($screen->base == 'users' || $screen->base == 'user-edit') {

        $user_meta = get_userdata($user_id); 
        $user_roles = $user_meta->roles; 
        if($user_roles){
            if (in_array("salonowner", $user_roles)) {

                if( isset($args[0]) ){
                    $edit_user_id = $args[0];
                }

                $listing_ids = get_user_meta( $edit_user_id, 'list_for_user', true);
                if($listing_ids){
                $arr = get_current_user_posts_can_edit();
                    foreach ($listing_ids as $key => $listing_id) {
                        if (in_array($listing_id, $arr )){
                            return $caps;
                        }else{
                            $caps = 'do_not_allow';
                        }
                    }
                }else{
                    // Don't allow for edit all other users 
                    $user = get_userdata( $edit_user_id );
                    if ( $user ) {
                       $caps = 'do_not_allow';
                    } 
                }
            }
        }
    }
    return $caps;

}

Here the function to get all posts for the current user to check if he can edit the user that assigned for it:

function get_current_user_posts_can_edit(){
    $current_user_id = get_current_user_id();
    $posts = get_posts(array(
        'posts_per_page'    => -1,
        'post_type'         => 'listing',
        'post_status'       => 'publish',           
        'author'            =>  $current_user_id,
    ));  
    $post_ids = array();
    foreach ($posts as $key => $post) {
        $post_ids[] = $post->ID;
    } 
    return $post_ids;
  }

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.