如何允许用户角色在仅低于其级别的角色下创建新用户?


14

我的网站中还有三个角色。

  1. 医生
  2. 接待员
  3. 客人

这些角色通过以下代码添加:

* adding Doctor role */
$doctor_role = add_role('Doctor', __('Doctor'), array('read'=>'true'));

/* adding Receptionist role */
$receptionist_role = add_role('Receptionist', __('Receptionist'), array('read'=>'true'));

/* adding Guest role */
$guest_role = add_role('Guest', __('Guest'), array('read'=>'true'));

默认情况下,Administrator角色创建所有其他角色。但是我想按用户级别限制此分配角色。我的意思是:

  1. 管理员-应该能够创建所有角色用户-默认情况下是可能的。
  2. Doctor- 应能够创建ReceptionistGuest角色用户
  3. 接待员-应该能够创建Guest角色的用户ONLY
  4. 访客- 不允许创建任何用户。

怎么办 如果我不使用任何插件就可以实现这一目标,那就更好了。

Answers:


23

首先,您需要向DoctorReceptionist角色添加以下功能:

  • list_users
  • edit_users
  • create_users
  • delete_users

现在我们可以将工作与控制这些,他们可以创建用户/ edite /删除。让我们从“ helper”函数开始,该函数将返回允许用户编辑的角色:

/**
 * Helper function get getting roles that the user is allowed to create/edit/delete.
 *
 * @param   WP_User $user
 * @return  array
 */
function wpse_188863_get_allowed_roles( $user ) {
    $allowed = array();

    if ( in_array( 'administrator', $user->roles ) ) { // Admin can edit all roles
        $allowed = array_keys( $GLOBALS['wp_roles']->roles );
    } elseif ( in_array( 'Doctor', $user->roles ) ) {
        $allowed[] = 'Receptionist';
        $allowed[] = 'Guest';
    } elseif ( in_array( 'Receptionist', $user->roles ) ) {
        $allowed[] = 'Guest';
    }

    return $allowed;
}

并设置他们可以分配用户的角色:

/**
 * Remove roles that are not allowed for the current user role.
 */
function wpse_188863_editable_roles( $roles ) {
    if ( $user = wp_get_current_user() ) {
        $allowed = wpse_188863_get_allowed_roles( $user );

        foreach ( $roles as $role => $caps ) {
            if ( ! in_array( $role, $allowed ) )
                unset( $roles[ $role ] );
        }
    }

    return $roles;
}

add_filter( 'editable_roles', 'wpse_188863_editable_roles' );

最后,根据角色限制可以编辑/删除的用户:

/**
 * Prevent users deleting/editing users with a role outside their allowance.
 */
function wpse_188863_map_meta_cap( $caps, $cap, $user_ID, $args ) {
    if ( ( $cap === 'edit_user' || $cap === 'delete_user' ) && $args ) {
        $the_user = get_userdata( $user_ID ); // The user performing the task
        $user     = get_userdata( $args[0] ); // The user being edited/deleted

        if ( $the_user && $user && $the_user->ID != $user->ID /* User can always edit self */ ) {
            $allowed = wpse_188863_get_allowed_roles( $the_user );

            if ( array_diff( $user->roles, $allowed ) ) {
                // Target user has roles outside of our limits
                $caps[] = 'not_allowed';
            }
        }
    }

    return $caps;
}

add_filter( 'map_meta_cap', 'wpse_188863_map_meta_cap', 10, 4 );

非常感谢。在我添加功能和您的代码后,它可以按预期工作。但是DoctorsReceptionist并且Guest也无法编辑自己的个人资料。我希望他们编辑自己的个人资料。我怎样才能做到这一点?
斯·斯塔尔

嗨,TheDeadMedic ..你在吗?我赞成你的回答。您能否看一下我的上述评论?
斯·斯塔尔

检查我的修订。
TheDeadMedic 2015年

@TheDeadMedic您的代码对我有很大帮助。我只有一个麻烦。我在多站点上使用它。虽然这段代码解决了我的问题,但它创建了另一个。以超级管理员身份登录后,我根本无法从超级管理员的“网络页面”中选择任何角色。我该如何解决?
jockebq

1
这是对这个问题的绝妙答案。我发现Wordpress自己的文档完全缺乏这方面的内容,甚至充满语法错误。这是一个非常有效的解决方案。
本治

0

上面的答案很好用。但是,角色必须小写

function wpse_188863_get_allowed_roles( $user ) { }

例如:

if ( in_array( 'administrator', $user->roles ) ) { // Admin can edit all roles
    $allowed = array_keys( $GLOBALS['wp_roles']->roles );
} elseif ( in_array( 'doctor', $user->roles ) ) {
    $allowed[] = 'receptionist';
    $allowed[] = 'guest';
} elseif ( in_array( 'receptionist', $user->roles ) ) {
    $allowed[] = 'guest';
}

在大多数情况下,角色的大小写可能应该是小写的。在上面的示例中,子标题和名称都使用标题大小写给出,因此尽管不建议这样做,但从技术上讲这是正确的。
Benji '18
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.