問題描述

有點長的問題,但我確實相信這種情況會發生在其他人的其他情況。

我們公司需要建立一個員工援助計劃 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 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。