I have three extra roles in my site.
- Doctor
- Receptionist
- Guest
those roles are added by following code:
* 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'));
By default Administrator role create all other roles. But I want to limit this assigning role by user level.
What I mean is:
- Administrator – should be able to create all role users – possible by default.
- Doctor – should be able to create
ReceptionistandGuestrole users ONLY - Receptionist – should be able to create
Guestrole users ONLY - Guest – Not allowed to create any users.
How can do this?
Better if I can achieve this without using any plugins.
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
Firstly, you need to add the following capabilities to the Doctor and Receptionist role:
list_usersedit_userscreate_usersdelete_users
Now we can get to work with controlling which users they can create/edite/delete. Let’s start with a “helper” function that will return which roles a user is allowed to edit:
/**
* 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;
}
And to set which roles they can assign a user:
/**
* 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' );
And finally, limit which users they can edit/delete based on their role:
/**
* 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 );
Method 2
The above answer worked great. However, the roles need to be lowercase for
function wpse_188863_get_allowed_roles( $user ) { }
For instance:
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';
}
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0