I have a few sites in a network. I don’t want the site administrators to manage things like network plugins, but I would like them to be able to edit profiles of all network users, not use those on their site.
At the top of the /wp-admin/network/users.php
file is this:
if ( ! current_user_can( 'manage_network_users' ) ) wp_die( __( 'You do not have permission to access this page.' ) );
How can I grant site administrators priviledges to manage_network_users
without promoting them to Super Admin?
Here’s what the code is looking like:
/** * Retrieve a list of super admins. * * @since 3.0.0 * * @uses $super_admins Super admins global variable, if set. * * @return array List of super admin logins */ function get_super_admins() { global $super_admins; if ( isset($super_admins) ) return $super_admins; else return get_site_option( 'site_admins', array('admin') ); }
/** * Determine if user is a site admin. * * @since 3.0.0 * * @param int $user_id (Optional) The ID of a user. Defaults to the current user. * @return bool True if the user is a site admin. */ function is_super_admin( $user_id = false ) { if ( $user_id ) $user = new WP_User( $user_id ); else $user = wp_get_current_user(); if ( empty( $user->id ) ) return false; if ( is_multisite() ) { $super_admins = get_super_admins(); if ( is_array( $super_admins ) && in_array( $user->user_login, $super_admins ) ) return true; } else { if ( $user->has_cap('delete_users') ) return true; } return false; }
/** * Whether user has capability or role name. * * This is useful for looking up whether the user has a specific role * assigned to the user. The second optional parameter can also be used to * check for capabilities against a specfic post. * * @since 2.0.0 * @access public * * @param string|int $cap Capability or role name to search. * @param int $post_id Optional. Post ID to check capability against specific post. * @return bool True, if user has capability; false, if user does not have capability. */ function has_cap( $cap ) { # fb($cap); if ( is_numeric( $cap ) ) { _deprecated_argument( __FUNCTION__, '2.0', __('Usage of user levels by plugins and themes is deprecated. Use roles and capabilities instead.') ); $cap = $this->translate_level_to_cap( $cap ); } $args = array_slice( func_get_args(), 1 ); $args = array_merge( array( $cap, $this->ID ), $args ); $caps = call_user_func_array( 'map_meta_cap', $args ); // Multisite super admin has all caps by definition, Unless specifically denied. if ( is_multisite() && is_super_admin( $this->ID ) ) { if ( in_array('do_not_allow', $caps) ) return false; return true; } // Must have ALL requested caps $capabilities = apply_filters( 'user_has_cap', $this->allcaps, $caps, $args ); $capabilities['exist'] = true; // Everyone is allowed to exist foreach ( (array) $caps as $cap ) { //echo "Checking cap $cap
"; if ( empty( $capabilities[$cap] ) || !$capabilities[$cap] ) return false; } return true; }
Code from users.php in wp-admin showing a second capability check for editing network users:
// Only allow super admins on multisite to edit every user. if ( is_multisite() && ! current_user_can( 'manage_network_users' ) && $user_id != $current_user->ID && ! apply_filters( 'enable_edit_any_user_configuration', true ) ) wp_die( __( 'You do not have permission to edit this user.' ) );
Here’s a solution that worked for me:
http://thereforei.am/2011/03/15/how-to-allow-administrators-to-edit-users-in-a-wordpress-network/
Pretty elegant and doesn’t involve messing with core.
Unfortunately I don’t have enough points to add a comment or vote up @Michael‘s answer above, but I wanted to point out to another post which gives a nicer solution to the problem of stopping non-admin users from editing admin/super-admin accounts.
The solution in the post link given by Michael works fine, I just applied it to a WP multi-site v4.1. However, it calls
die()
function when a non-admin user tries to edit an admin account. So instead I used this solution (which is initially for a single site installation of WP) which hides all admin user accounts from the list of user when it is accessed by a non-admin user.The final solution, a combination of the above two, gives this…
The code above only hides the super admin with ID = 1. Here’s a a code to hide all super users: