WordPress用户权限层级管理:限制只能管理低级别的用户

上一篇文章详细介绍了WordPress默认用户角色权限,以及如何新增用户角色、添加权限等,参考WordPress用户角色权限详解

在实际开发中,很少需要对默认权限进行修改,通常是添加若干个角色,然后对这些角色赋于不同的权限。

以我之前开发的实体店铺会员系统为例,一共新增了三个角色:经理、主管、店员。其中,经理可以添加、编辑主管和店员,主管只能添加、编辑店员。

首先给经理赋于用户管理的权限:

1
2
3
4
5
6
7
$wp_roles->add_cap('manager', array(
    'list_users' => true,
    'create_users' => true,
    'delete_users' => true,
    'edit_users' => true,
    'remove_users' => true,
));

注意:主管不需要remove_users权限,因为主管下面只有一个店员角色了,并且主管也没有将店员提升为主管的权限。

此时,经理不仅可以管理所有用户,也能修改删除所有用户,这是不符合要求的,因为经理上面还有管理员administrator。

通过Hook users_list_table_query_args可以对不同级别角色进行过滤:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function bzg_editable_roles($roles) {
    global $current_user;
    $role = $current_user->roles;
    $role = $role[0];
    switch($role) {
        case 'administrator' :
            unset($roles['administrator']);
            break;
        case 'manager' :
            unset($roles['administrator']);
            unset($roles['manager']);
            break;
        case 'charge' :
            unset($roles['administrator']);
            unset($roles['manager']);
            unset($roles['charge']);
            break;
        default:
            $roles = null;
    }
    return $roles;
}
add_filter('editable_roles', 'bzg_editable_roles', 10, 1);

此时,在修改角色选项中,经理只能看到主管和店员,接下来过滤用户列表中的显示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function bzg_users_list_table_query_args($args) {
    global $current_user;
    $role = $current_user->roles;
    $role = $role[0];
    switch($role) {
        case 'administrator' :
            $roles = ['administrator', 'manager', 'charge', 'sales'];
            break;
        case 'manager' :
            $roles = ['charge', 'sales'];
            break;
        case 'charge' :
            $roles = ['sales'];
            break;
        default:
            $roles = ['sales'];
    }
    $args['role__in'] = $roles;
    return $args;
}
add_filter('users_list_table_query_args', 'bzg_users_list_table_query_args', 10, 1);

在主管的用户列表中,不再出现经理,但是在顶部的用户导航中仍然显示了管理员和经理的数量,可以使用以下代码过滤:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function bzg_views_users($views) {
    global $current_user;
    $role = $current_user->roles;
    $role = $role[0];
    switch($role) {
        case 'administrator' :
            break;
        case 'manager' :
            unset($views['administrator']);
            unset($views['manager']);
            unset($views['all']);
            break;
        case 'charge' :
            unset($views['administrator']);
            unset($views['manager']);
            unset($views['charge']);
            unset($views['sales']);
            unset($views['all']);
            break;
        default:
    }
    return $views;
}
add_filter('views_users', 'bzg_views_users', 10, 1);

还没完,为了防止用户直接给用户编辑和删除页面传递用户ID参数跳过之前的限制,还需要控制一下权限:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
function bzg_user_has_cap($allcaps, $caps, $args) {
    global $current_user;
    $user_id = 0;
    if(isset($args[2])) {
        $user_id = (int) $args[2];
    } elseif(isset($_REQUEST['user_id'])) {
        $user_id = (int) $_REQUEST['user_id'];
    } elseif(isset($_REQUEST['user'])) {
        $user_id = (int) $_REQUEST['user'];
    }
    if(!$user_id) return $allcaps;

    if(in_array($args[0], array('edit_user', 'delete_users', 'delete_user', 'list_users'))) {
        $user_role = get_user_meta($user_id, 'wp_capabilities', true);
        if(!$user_role)  return $allcaps;
        $user_role = key($user_role);
        $role = $current_user->roles;
        $role = $role[0];
        if(!bzg_role_comparing($role, $user_role)) {
            return false;
        }
    }

    return $allcaps;
}
add_filter('user_has_cap', 'bzg_user_has_cap',10, 3);

这里使用了一个自定义函数来比较用户权限大小:

1
2
3
4
5
6
7
8
9
function bzg_role_comparing($a, $b) {
    $roles = array(
        'administrator' => 10,
        'manager' => 5,
        'charge' => 3,
        'sales' => 1,
    );
    return $roles[$a] > $roles[$b];
}

好了,你可以灵活运用以上Hook来实现不同需求。

原文链接:https://xiaohost.com/2294.html,转载请注明出处。
0