web-dev-qa-db-fra.com

Créer un rôle d'utilisateur personnalisé (client) pouvant créer un autre rôle d'utilisateur personnalisé (employé) de ce client

C'est une longue question, mais je pense que cette situation se produira pour d'autres personnes dans d'autres contextes.

Notre société doit créer un site de réseau de sous-répertoires MU (Employee Assistance Program) où notre société peut créer des comptes utilisateur avec un rôle utilisateur personnalisé client.

La client sera une autre entreprise devant utiliser les services de PAE de notre entreprise pour ses propres employés.

La client doit pouvoir se connecter à l’administrateur du site réseau de la MU et ajouter des comptes d’utilisateur avec un rôle utilisateur employee pour leurs employés.

Ces comptes employee pourront se connecter au serveur et afficher le contenu EAP restreint.

Pour le rôle d'utilisateur employee, j'ai utilisé le code ici pour créer dans le functions.php de mon thème:

$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
    )
};

Puis-je m'en tirer en précisant seulement ce qui est vrai et sans avoir besoin de spécifier ce qui est faux?

Pour la client, j'ai:

$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
    )
);

J'ai besoin que chaque compte client ne puisse modifier et supprimer que les comptes employee créés par ce compte client individuel et non les comptes employee d'une autre société.

Je suppose que je pourrais ajouter au rôle d'utilisateur employee un champ personnalisé masqué qui sera l'ID client (ajouté lorsque le client crée un employee). Ce champ personnalisé ne doit pas être éditable par le rôle employee.

J'ai cherché comment ajouter un champ personnalisé masqué à un rôle d'utilisateur personnalisé et je n'ai pas trouvé de solution.

Donc, mes questions sont:

  1. Comment ajouter un champ personnalisé masqué appelé clientID à un rôle d'utilisateur personnalisé (employee)?
  2. Comment garantir que, quand une client crée une employee, l'ID utilisateur ou le nom d'utilisateur du client (qui ne correspond pas au mieux) est ajouté au nouveau champ méta de la employee's clientID?
  3. Comment puis-je m'assurer que la client ne peut modifier ou supprimer qu'un compte employee (et pas d'autres comptes d'utilisateur standard)?
  4. En étendant 3, comment puis-je m'assurer que client ne peut éditer et supprimer qu'un compte employee où le compte employee a un identifiant d'utilisateur ou un nom d'utilisateur clientIDclient?

Merci.

6
Steve

Les clients sont ajoutés par les administrateurs, ils ont une relation parent-enfant avec les employés, ce qui facilite le filtrage. Il suffit donc de supprimer tout ce qui ne concerne pas les employés et de filtrer les employés avec une certaine méta-valeur.

Tout d'abord, chaque fois qu'un nouvel utilisateur est enregistré sur le côté admin de notre CMS, nous lui attribuons le parent de l'utilisateur actuel SI cet utilisateur est un client (en supposant que les clients ne peuvent pas affecter d'employés à d'autres clients):

/**
 * 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' );

Génial, alors chaque fois qu'un client crée un nouvel utilisateur (quel que soit son type), il est assigné à un parent du client qui l'a créé. Nous devons maintenant filtrer notre table d'utilisateurs pour afficher uniquement les utilisateurs de notre client parent 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' );

Soigné! Nous pouvons maintenant aborder le problème de la capacité des clients à créer des rôles de tout type. Nous passons donc au processus de nettoyage. La liste ci-dessous supprimera tout rôle pouvant être sélectionné lors de la création d'un nouvel utilisateur ou de la modification d'un utilisateur actuel uniquement en 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' );

Sur l'écran All Users, nous pouvons voir que les vues de filtre affichent toujours d'autres rôles d'utilisateur. Nous devons donc résoudre ce problème également:

/**
 * 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' );

Enfin, un oubli est que l'utilisateur pourrait pourrait potentiellement modifier l'URL pour afficher les profils d'autres utilisateurs qui ne sont peut-être pas leurs propres employés. Nous devons donc résoudre ce problème en ajoutant cette petite redirection:

/**
 * 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' );

Et cela devrait le faire. Les rôles client ne peuvent voir et éditer que les employés avec le parent assigné comme identifiant.

6
Howdy_McGee