问题描述

有点长的问题,但我确实相信这种情况会发生在其他人的其他情况。

我们公司需要创建一个员工援助计划 MU 子目录网站,我们公司可以创建具有自定义用户角色 client 的用户帐户。

client 将是另一家需要为该公司自己的员工使用我们公司的 EAP 服务的公司。

client 必须能够登录到 MU 网站管理员,并为员工添加 employee 用户角色的用户帐户。

那些 employee 帐户将能够登录到前端,并查看受限的 EAP 内容。

对于 employee 用户角色,我使用 code here 在我的主题的 functions.php 中创建:

$result1 = add_role( 'employee', __('Employee'),  
    array(
        'edit_users' => false,
        'create_users' => false,
        'delete_users' => false,
        'read' => true,
        'edit_posts' => false,
        'edit_pages' => false,
        'edit_others_posts' => false,
        'create_posts' => false,
        'manage_categories' => false,
        'publish_posts' => false,
        'edit_themes' => false,
        'install_plugins' => false,
        'update_plugin' => false,
        'update_core' => false
    )
};

我只能指定什么是真实的,而不需要指定什么是错误?

对于 client,我有:

$result2 = add_role( 'client', __('Client Company Admin'),  
    array(
        'edit_users' => true,
        'create_users' => true,
        'delete_users' => true,
        'read' => true,
        'edit_posts' => false,
        'edit_pages' => false,
        'edit_others_posts' => false,
        'create_posts' => false,
        'manage_categories' => false,
        'publish_posts' => false,
        'edit_themes' => false,
        'install_plugins' => false,
        'update_plugin' => false,
        'update_core' => false
    )
);

我需要每个 client 帐户才能编辑和删除由该个人 client 帐户创建的 employee 帐户,而不是其他公司的 employee 帐户。

我收集我可以添加一个隐藏的自定义字段到 employee 用户角色,它将是 client ID(当 client 创建一个 employee 时添加),并且此自定义字段不能由 employee 角色编辑。

我已经搜索了如何向自定义用户角色添加隐藏的自定义字段,并且无法找到解决方案。

所以我的问题是:

  1. 如何将 clientID 隐藏的自定义字段添加到自定义用户角色 (employee)?

  2. 如何确保在 client 创建 employee 时,客户端的用户名或用户名 (不确定哪个是最好的) 被添加到新的 employeeclientID 元字段?

  3. 如何确保 client 只能编辑或删除 employee 帐户 (而不是其他标准用户帐户)?

  4. 扩展 3,如何确保 client 只能编辑和删除 employee 帐户,其中 employee 帐户具有 clientID client 自己的用户名或用户名?

谢谢。

最佳解决方案

客户由管理员添加,客户与员工有父母子女关系,使过滤变得容易。所以我们需要做的就是删除与员工无关的任何东西,并过滤具有某个元值的员工。

首先,首先,每当新用户在我们的 CMS 的管理员端注册时,我们将为其分配一个当前用户的父母,如果该用户是客户端 (假定客户端不能将员工分配给其他客户端):

/**
 * Admin New Employee Function
 * @var int $user_id
 * @return void
 */
function client_register( $user_id ) {
    if( ! is_admin() ) {
        return;
    }

    // Grab the current user
    $current_user = wp_get_current_user();

    // IF the current user ID isn't 0 and our current user is a 'client' role
    if( $current_user->ID && in_array( 'client', $current_user->roles ) ) {

        // Update the new user with a 'parent' usermeta value of the current 'client'
        update_user_meta( $user_id, '_user_parent', $current_user->ID );
    }
}
add_action( 'user_register', 'client_register' );

好的,所以现在每当一个客户端创建一个新的用户 (任何类型的),它被分配一个无论哪个客户端创建它的父。现在,我们需要过滤我们的用户表,只显示我们的客户端的主用户 usermeta 的用户:

/**
 * Pre Get Users filter
 * @var WP_Query Object $query
 * @return void
 */
function theme_pgu( $query ) {
    if( ! is_admin() ) {
        return;
    }

    // Grab our current user
    $current_user = wp_get_current_user();

    // IF our user ID is not 0 and our current user has a role of 'client'
    if( $current_user->ID && in_array( 'client', $current_user->roles ) ) {

        // Set the query to only return employee roles
        $query->set( 'role', 'employee' );

        // Which has a usermeta key '_user_parent' set
        $query->set( 'meta_key', '_user_parent' );

        // and has a usermeta value of the current client user
        $query->set( 'meta_value', $current_user->ID );
    }
}
add_action( 'pre_get_users', 'theme_pgu' );

整齐!现在我们可以解决客户端能够创建任何类型角色的问题,所以我们进入清理过程。在创建新用户或将当前用户编辑为仅 employee 时,以下将删除任何可选择的角色:

/**
 * Selectable roles on the new user and user edit screen
 * @var Multi-dimensional Array $roles
 * @return Array $roles
 */
function client_sel_roles( $roles ) {
    // Grab our current user
    $current_user = wp_get_current_user();

    if( in_array( 'client', $current_user->roles ) ) {
        $roles = array( 'employee' => $roles['employee'] );
    }

    return $roles;
}
add_filter( 'editable_roles', 'client_sel_roles' );

All Users 屏幕上,我们可以看到过滤器视图仍然显示其他用户角色,因此我们也需要修复它:

/**
 * All Users screen filterable views
 * @var Array $views
 * @return Array $views
 */
function client_user_views( $views ) {
    // Grab our current user
    $current_user = wp_get_current_user();

    if( in_array( 'client', $current_user->roles ) ) {
        if( isset( $views['employee'] ) ) {
            $views = array( 'employee' => $views['employee'] );
        } else {
            $views = array();
        }
    }

    return $views;
}
add_filter( 'views_users', 'client_user_views' );

最后,一个监督是,用户可能会改变 URL 来查看其他用户可能不是自己的员工的配置文件,因此我们需要通过添加这个小的重定向来解决这个问题:

/**
 * Stop clients from changing the URL to get to other profiles
 * @var WP_Screen Object $screen
 * @return void
 */
function edit_employees_only( $screen ) {

    // Check if we're on the correct screen
    if( 'user-edit' === $screen->base ) {

        // Ensure our desired user ID is set
        if( isset( $_GET['user_id'] ) && is_numeric( $_GET['user_id'] ) ) {
            $user_id        = absint( $_GET['user_id'] );
            $current_user   = wp_get_current_user();
            $parent         = get_user_meta( $user_id, '_user_parent', true );

            // Ensure that we're viewing a profile that is not our own
            if( $current_user->ID && in_array( 'client', $current_user->roles ) && $user_id !== $current_user->ID && $parent !== $current_user->ID ) {

                // We're viewing an incorrect profile - redirect to clients own profile
                wp_redirect( admin_url( "user-edit.php?user_id={$current_user->ID}" ) );
            }
        }
    }
}
add_action( 'current_screen', 'edit_employees_only' );

那应该这样做。客户端角色只能查看和编辑分配为其 ID 的父级员工。

参考文献

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