WordPress Multisite is a powerful feature that allows me to manage multiple WordPress websites (or subsites) from a single installation. However, one of the frustrating limitations is that subsite administrators cannot edit users. This restriction is primarily designed to maintain security and control over network-wide user management. In a WordPress 3.x+ Network, only Super Admins are granted the privilege to edit users. In my case, I need subsite administrators to edit potentially hundreds of subsite users.
Diagnosing the Problem
The first instinct was to assign the edit_users
capability to the admin role. After all, if a user has the edit_users
capability, it seems logical that they should be able to edit other users’ profiles. However, it’s not that straightforward.
Upon closer inspection, I discovered that, even though administrators don’t have the ability to edit users, they do, in fact, possess the edit_users
capability. Like I said, frustrating.
The Heart of the Matter
To understand why administrators can’t edit users in a WordPress Multisite network, I looked and found the map_meta_cap
capability, which can be found in the capabilities.php
file.
case 'edit_users':
// If multisite, these caps are allowed only for super admins.
if ( is_multisite() && !is_super_admin( $user_id ) )
$caps[] = 'do_not_allow';
else
$caps[] = 'edit_users'; // Explicit due to primitive fall through
break;
This code snippet reveals the master override that prevents any role other than Super Admin from editing other users.
Using the map_meta_cap Filter
Fortunately, WordPress offers a solution through the use of filters. The $caps
array, which contains the capabilities for a user, is passed through a filter before being returned:
return apply_filters('map_meta_cap', $caps, $cap, $user_id, $args);
To overcome the limitation, I used the map_meta_cap
filter to transform the do_not_allow
capability in the $caps
array into either edit_users
, delete_users
, or create_users
. This filter modifies the capabilities assigned to users, effectively granting administrators the ability to edit users in a Multisite network.
/**
* Allows subsite administrators to edit users in a WordPress Multisite network.
*
* In a WordPress 3.x Network, the Super Admin role is the only role allowed to edit users.
*
* @param array $caps The user's capabilities.
* @param string $cap The capability being checked.
* @param int $user_id The user ID.
* @param mixed $args Additional arguments.
*
* @return array Modified user capabilities.
*/
function wppd_admin_users_caps( $caps, $cap, $user_id, $args ) {
foreach ( $caps as $key => $capability ) {
if ( $capability != 'do_not_allow' ) {
continue;
}
switch ( $cap ) {
case 'edit_user':
case 'edit_users':
$caps[$key] = 'edit_users';
break;
case 'delete_user':
case 'delete_users':
$caps[$key] = 'delete_users';
break;
case 'create_users':
$caps[$key] = $cap;
break;
}
}
return $caps;
}
// Apply the wppd_admin_users_caps function to the 'map_meta_cap' filter.
add_filter( 'map_meta_cap', 'wppd_admin_users_caps', 1, 4 );
// Remove all filters for 'enable_edit_any_user_configuration'.
remove_all_filters( 'enable_edit_any_user_configuration' );
// Add a filter to enable editing any user configuration.
add_filter( 'enable_edit_any_user_configuration', '__return_true' );
/**
* Checks that both the editing user and the user being edited are
* members of the same blog and prevents editing super admin users.
*/
function wppd_edit_permission_check() {
global $current_user, $profileuser;
$screen = get_current_screen();
get_currentuserinfo();
if ( ! is_super_admin( $current_user->ID ) && in_array( $screen->base, [ 'user-edit', 'user-edit-network' ] ) ) {
// Editing a user profile.
if ( is_super_admin( $profileuser->ID ) ) {
// Trying to edit a super admin while not being a super admin.
wp_die( __( 'You do not have permission to edit this user.' ) );
} elseif ( ! ( is_user_member_of_blog( $profileuser->ID, get_current_blog_id() ) && is_user_member_of_blog( $current_user->ID, get_current_blog_id() ) ) ) {
// Editing user and edited user aren't members of the same blog.
wp_die( __( 'You do not have permission to edit this user.' ) );
}
}
}
// Apply the wppd_edit_permission_check function to the 'admin_head' filter.
add_filter( 'admin_head', 'wppd_edit_permission_check', 1, 4 );
Conclusion
This restores the edit_users
, delete_users
and create_users
capabilities to their former glory.
If a user has the admin role, or has been manually assigned any of these capabilities, they will then be able to edit users.
Put the code above in a must-use
plugin in the /wp-content/mu-plugins/
directory.
Photo by Fikret tozak on Unsplash