Let Editor Manage Users in WordPress

Updated to work with PHP7

The Editor user role in WordPress cannot by default edit users. You may want to add that capability for clients whom you keep as ‘Editors’. This will let the Editor add new users (create new users), delete users, and edit users. This is done by adding capabilities to the Editor role with ‘add_cap’.

If you use this code, you may also want to stop the Editor from deleting Administrators (see below), and also hide Administrators on the list of users that the Editor sees (see below).

This lets Editors manage users

/*
 * Let Editors manage users, and run this only once.
 */
function isa_editor_manage_users() {

	if ( get_option( 'isa_add_cap_editor_once' ) != 'done' ) {
	
		// let editor manage users

		$edit_editor = get_role('editor'); // Get the user role
		$edit_editor->add_cap('edit_users');
		$edit_editor->add_cap('list_users');
		$edit_editor->add_cap('promote_users');
		$edit_editor->add_cap('create_users');
		$edit_editor->add_cap('add_users');
		$edit_editor->add_cap('delete_users');

		update_option( 'isa_add_cap_editor_once', 'done' );
	}

}
add_action( 'init', 'isa_editor_manage_users' );

Prevent Editor From Deleting Administrator User

This will stop Editors from deleting, editing, or adding new Administrators. This is only necessary if you used the code above to give Editors the capability to manage users. For example, if you are the real administrator, and you want to prevent your client (the Editor role) from deleting YOU.

//prevent editor from deleting, editing, or creating an administrator
// only needed if the editor was given right to edit users

class ISA_User_Caps {

  // Add our filters
  function __construct() {
    add_filter( 'editable_roles', array(&$this, 'editable_roles'));
    add_filter( 'map_meta_cap', array(&$this, 'map_meta_cap'),10,4);
  }
  // Remove 'Administrator' from the list of roles if the current user is not an admin
  function editable_roles( $roles ){
    if( isset( $roles['administrator'] ) && !current_user_can('administrator') ){
      unset( $roles['administrator']);
    }
    return $roles;
  }
  // If someone is trying to edit or delete an
  // admin and that user isn't an admin, don't allow it
  function map_meta_cap( $caps, $cap, $user_id, $args ){
    switch( $cap ){
        case 'edit_user':
        case 'remove_user':
        case 'promote_user':
            if( isset($args[0]) && $args[0] == $user_id )
                break;
            elseif( !isset($args[0]) )
                $caps[] = 'do_not_allow';
            $other = new WP_User( absint($args[0]) );
            if( $other->has_cap( 'administrator' ) ){
                if(!current_user_can('administrator')){
                    $caps[] = 'do_not_allow';
                }
            }
            break;
        case 'delete_user':
        case 'delete_users':
            if( !isset($args[0]) )
                break;
            $other = new WP_User( absint($args[0]) );
            if( $other->has_cap( 'administrator' ) ){
                if(!current_user_can('administrator')){
                    $caps[] = 'do_not_allow';
                }
            }
            break;
        default:
            break;
    }
    return $caps;
  }

}

$isa_user_caps = new ISA_User_Caps();

Hide Administrator From User List

This is useful when you admin a site for clients, but don’t want to let them see you on the list of users. You know, you want them to think they are the administrator. For example, if you set up the client as ‘Editor’ and gave them the capability of managing users, but you don’t want them to be able to see YOU on the list of users.

Here are 3 variations to hide users from the Users list. Choose 1 of the following.

  1. If you only have 1 administrator to hide, and you know that their ID is ‘1’, use this:
    // Hide admin from user list
    
    add_action('pre_user_query','isa_pre_user_query');
    function isa_pre_user_query($user_search) {
      $user = wp_get_current_user();
      if ($user->ID!=1) { // Is not administrator, remove administrator
        global $wpdb;
        $user_search->query_where = str_replace('WHERE 1=1',
          "WHERE 1=1 AND {$wpdb->users}.ID<>1",$user_search->query_where);
      }
    }
    
  2. If you want to choose individual IDs to hide from the User list, use this (replace ‘1,5,7,9’ on line 6 with the User IDs which you want to hide):

    // Hide specified users from user list.
    
    add_action('pre_user_query','isa_pre_user_query');
    function isa_pre_user_query($user_search) {
    
    	$admin_ids = '1,5,7,9'; // REPLACE THESE NUMBERS WITH IDs TO HIDE.
    	
    	$user = wp_get_current_user();
    	$admin_array = explode($admin_ids, ',');
    	if ( ! in_array( $user->ID, $admin_array ) ) {
    		global $wpdb;
    		$user_search->query_where = str_replace('WHERE 1=1', "WHERE 1=1 AND {$wpdb->users}.ID NOT IN($admin_ids)",$user_search->query_where);
    	
    	}
    }
    
  3. If you simply want to hide ALL administrators, use this:
    // Hide all administrators from user list.
    
    add_action('pre_user_query','isa_pre_user_query');
    function isa_pre_user_query($user_search) {
    
    	$user = wp_get_current_user();
    	
    	if ( ! current_user_can( 'manage_options' ) ) {
      
    		global $wpdb;
    	
    		$user_search->query_where = 
        	    str_replace('WHERE 1=1', 
                "WHERE 1=1 AND {$wpdb->users}.ID IN (
                     SELECT {$wpdb->usermeta}.user_id FROM $wpdb->usermeta 
                        WHERE {$wpdb->usermeta}.meta_key = '{$wpdb->prefix}capabilities'
                        AND {$wpdb->usermeta}.meta_value NOT LIKE '%administrator%')", 
                $user_search->query_where
            );
    
    	}
    }
    

See more:

We've 52 Responses

  1. October 18th, 2012 at 11:09 am

    Thanks so much for this! Combining it with the Capabilities Manager Extended plugin allowed me to create a new Role for the client that allows them to Add/Edit/Delete users, without being able to Add/Edit/Delete Administrators – so we can keep our Administrator user account on the system without worrying about them accidentally locking us out in the future. πŸ™‚

    Cas
  2. November 21st, 2013 at 7:37 am

    Thank you! Even after using User Role Editor, the users list wasn’t appearing on my site for anyone other than the admin.

    Your code did the trick!

    Nathan
  3. April 20th, 2014 at 2:22 pm

    I noticed that if i try to create a new user with the role editor, using your code, does not allow me to create a user with the role of editor, but it creates automatically with the role of subscriber. There is a fix?

    thanks!

    ziogoogle
  4. May 12th, 2014 at 5:43 pm

    Hi Isabel,
    I paste the code in my function.php
    but when I actualize there is a bug, the code appears above my admin bar…

    Do you have an issue to that ?

    Thanks

    Pierre
  5. May 13th, 2014 at 7:33 pm

    Thanks Isabel just what I was looking for. Just checking as still a bit new to WordPress do I need to make a child theme and a functions.php so the file isn’t overwritten with theme updates?

    Kenn
  6. September 29th, 2014 at 10:24 am

    Thanks Isabel, works great on WP 4.

    Just one thing, WordPress will still show number of admin users in the top navigation of user list.

    You can use the followin snippet to hide the count:

    function hide_user_count(){
    ?>
    <style>
    span.count {display:none;}
    </style>
    <?php
    }
    
    add_action('admin_head','hide_user_count');
    
    Juan
    • June 17th, 2015 at 7:35 am

      A little improvement on Juan’s:

      /**
       * Now hide the administrators tab for non-dmin
       */
      function hide_user_count(){
          $user = wp_get_current_user();
          if ( $user->ID != 1 ) { ?>
              <style>
                  li.administrator { display: none; }
              </style> <?php
          }
      }
      
      add_action('admin_head','hide_user_count');
      
      Jamesy
  7. April 10th, 2015 at 6:08 pm

    Thanks for this Isabel.

    I have a question How does the ISA_User_Caps object get executed by WordPress? The class doesn’t extend another class and there is no “hook” registered so I’m struggling to understand how WP core even knows this code exists?

    Is there some significance in the naming convention maybe?

    Thanks in advance.

    Mark
    • April 10th, 2015 at 10:00 pm

      Hi. The last line (line 55) instantiates (or executes) the class with the “new” keyword. You can name the class anything you like by changing “ISA_User_Caps()” to “Your_Class_Name()”. Then line 55 would be:

      $your_class_name = new Your_Class_Name();

      Then you would also have to change “ISA_User_Caps” on lines 4 and 7 to “Your_Class_Name”. Hope that helps.

      Isabel
      • April 10th, 2015 at 10:23 pm

        Ah of course. I forgot that the method that is named the same as the class get executed when the object is instantiated. Thanks for a great response and tip.

        Mark
  8. September 23rd, 2015 at 11:30 am

    That’s godsend Isabel, many thanks for sharing!

    Checked out some of your other content and plugins, looks like a real treasure trove of goodies!

    Nice clean site too πŸ™‚

    Aurovrata
  9. November 5th, 2015 at 6:00 am

    Hi Isabel

    Does the code go in the functions.php file of WordPress directory or the activated theme?

    When I log in as editor instead of admin, I don’t see users menu.

    Thanks for help

    M Paulo
  10. January 8th, 2016 at 9:27 pm

    Hi Isabel, thanks for this post, just what I needed.

    But if you have more admins only the one with ID # 1 is hidden.
    How would you add more ID’s to the last snippet to hide more administrators?

    Jentan
  11. January 18th, 2016 at 6:32 pm

    Hi Isabel. Thanks for this great tutorial. In my site the “editor” role is the new “administrator” role (for my clients). I need to send all email notifications (for example: new user registration) to the editor user. Can you help me with this? Thanks. Greetings from Argentina!

    gaston
  12. November 4th, 2016 at 2:44 pm

    I get the following error when trying 2nd option to prevent Editor from deleting Administrator:

    “Sorry, but your code causes a ‘Fatal error’, so it is not applied!
    Please, check the code and try again.”

    When 1st code option is applied, Editor can now change their own role to Administrator. I don’t think that is what was intended.

    Jason
  13. September 5th, 2017 at 10:39 am

    With PHP7 you can’t have a class and function with the same nameβ€”it generates an error. And I’m having trouble finding the right syntax to fix it. Isabel, can you update?

    Peter Mumford
  14. November 6th, 2017 at 1:43 pm

    Just to add line to remove Super Admin from select dropdown options:

    
      // Remove 'Administrator' from the list of roles if the current user is not an admin
      function editable_roles( $roles ){
        if( isset( $roles['administrator'] ) && !current_user_can('administrator') ){
              // unset( $roles['subscriber']);
    	  unset( $roles['administrator']);
    	  unset( $roles['super_admin']);
        }
        return $roles;
      }
    
    
    Saint Michael
  15. December 14th, 2018 at 9:51 am

    Hi Isabel,

    Great code. First part of the code is used once, but after that I can’t change it anymore, because I want to add a multisite function to it like Rodrigo added.

    How to change it back to normal state or with the changes I made? Thanks in advance!

    Julien
  16. February 1st, 2019 at 3:17 pm

    I found this code. It hides the one user from all others, including other administrators. Also fixes the problem of counting users, without using CSS to hide. It’s worth implementing in your code.
    Thank you.

    //Hides an admin user from all other users, including other WordPress admins
    //Replace "hiddenuser" by the user you want to hide
    add_action('pre_user_query','dt_pre_user_query');
    function dt_pre_user_query($user_search) {
       global $current_user;
       $username = $current_user->user_login;
    
       if ($username != 'hiddenuser') {
          global $wpdb;
          $user_search->query_where = str_replace('WHERE 1=1',
             "WHERE 1=1 AND {$wpdb->users}.user_login != 'hiddenuser'",$user_search->query_where);
       }
    }
    
    add_filter("views_users", "dt_list_table_views");
    function dt_list_table_views($views){
       $users = count_users();
       $admins_num = $users['avail_roles']['administrator'] - 1;
       $all_num = $users['total_users'] - 1;
       $class_adm = ( strpos($views['administrator'], 'current') === false ) ? "" : "current";
       $class_all = ( strpos($views['all'], 'current') === false ) ? "" : "current";
       $views['administrator'] = '<a href="users.php?role=administrator" class="' . $class_adm . '">' . translate_user_role('Administrator') . ' <span class="count">(' . $admins_num . ')</span></a>';
       $views['all'] = '<a href="users.php" class="' . $class_all . '">' . __('All') . ' <span class="count">(' . $all_num . ')</span></a>';
       return $views;
    }
    
    Fernando Lopes

Questions and Comments are Welcome

Your email address will not be published. All comments will be moderated.

Please wrap code in "code" bracket tags like this:

[code]

YOUR CODE HERE 

[/code]