问题描述

我很确定我了解 WordPress 中的角色和功能设置:细粒度的功能,可以分配给可以分配给用户的角色。代码应该检查粒度能力,而不是角色 (因为特定角色的功能可以改变) 。角色不一定是分层的 (尽管默认角色是) 。

有没有办法为用户分配多个角色?或者,具有多个能力组,并且将一个或多个组与用户相关联?我的网站的工作方式,有很多明显的职责:更新网页,主持论坛,更新活动日历等。每个职责都有一组能力来执行与之相关的任务。我想让用户执行一个或多个职责。因此,用户 A 可以更新网页和事件日历,但不能适应论坛 (不够巧妙),但用户 B 可以适度的论坛,更新活动日历,但不允许在网页附近。

没有为每个可能的责任组合确定一个角色,有没有办法这样做?

最佳解决方案

由于底层的 WP_User 类支持多个角色,缺少多个角色已经使我很长时间了。我甚至考虑寻找替代软件解决方案。 @lpryor – 阅读你的帖子后,我是 re-motivated 自己实现的。

尽管我不得不劫持 users.php 文件,但由于我太懒了,无法为我创建一个单独的插件,所以我花费了惊人的短线。显然,这是错误的做法,所以如果我今后有足够的动力,我可能会尝试做到这一点。

如果您不关心能够升级到最新版本的 WordPress(您应该) – 您可以使用下面的代码段来实现多个角色。请记住,我不是一个 wordpress 专家。我刚刚打开相关文件并进行了更改,而不试图了解我正在做的全部影响。这段代码对我来说似乎是合理的,但我不会相信我的生活。

(我使用 3.2,所以你的行号可能会有所不同) 在 class-wp-users-list-table.php 之前的行 150 添加一些如下:

<div class="alignleft actions">
    <label class="screen-reader-text" for="remove_role"><?php _e( 'Remove role &hellip;' ) ?></label>
    <select name="remove_role" id="remove_role">
        <option value=''><?php _e( 'Remove role &hellip;' ) ?></option>
        <?php wp_dropdown_roles(); ?>
    </select>
    <?php submit_button( __( 'Remove' ), 'secondary', 'changeit', false ); ?>
</div>

然后更改 current_account 功能看起来像这样

function current_action() {
    if ( isset($_REQUEST['changeit']) ) {
        if ( !empty($_REQUEST['new_role']) )
            return 'promote';
        elseif ( !empty($_REQUEST['remove_role']) )
            return 'remove_role';
    }

    return parent::current_action();

}

现在在 users.php 注释线 71-76

/*
if ( $id == $current_user->ID && !$wp_roles->role_objects[$_REQUEST['new_role']]->has_cap('promote_users') ) {
    $update = 'err_admin_role';
    continue;
}
*/

用 add_role 替换第 83 行中的 set_role

$user->add_role($_REQUEST['new_role']);

在第 92 行添加以下内容 (这只是从促销操作中轻轻编辑的复制和粘贴 – 我还没有检查确保 promote_user 功能适合删除角色)

case 'remove_role':
    check_admin_referer('bulk-users');

    if ( ! current_user_can( 'promote_users' ) )
            wp_die( __( 'You can’t edit that user.' ) );

    if ( empty($_REQUEST['users']) ) {
            wp_redirect($redirect);
            exit();
    }

    $editable_roles = get_editable_roles();
    if ( empty( $editable_roles[$_REQUEST['remove_role']] ) )
            wp_die(__('You can’t remove that role'));

    $userids = $_REQUEST['users'];
    $update = 'remove_role';
    foreach ( $userids as $id ) {
            $id = (int) $id;

            if ( ! current_user_can('promote_user', $id) )
                    wp_die(__('You can’t edit that user.'));
            // The new role of the current user must also have promote_users caps
            // Need to think this through
            /*
            if ( $id == $current_user->ID && !$wp_roles->role_objects[$_REQUEST['new_role']]->has_cap('promote_users') ) {
                    $update = 'err_admin_role';
                    continue;
            }
            */

            // If the user doesn't already belong to the blog, bail.
            if ( is_multisite() && !is_user_member_of_blog( $id ) )
                    wp_die(__('Cheatin’ uh?'));

            $user = new WP_User($id);
            $user->remove_role($_REQUEST['remove_role']);
    }

    wp_redirect(add_query_arg('update', $update, $redirect));
    exit();

在第 370 行添加以下内容

case 'remove_role':
    $messages[] = '<div id="message" class="updated"><p>' . __('Removed role.') . '</p></div>';
    break;

参考文献

注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。