Question

(Moderator's note: The original title was "Custom User Role Restrictions")

A project I am working on requires me to create two new user roles - one for the owner of the website and the other for agents of the company.

With the website owner user role I was just looking for a way to restrict users in this group from modifying core site settings while having access to modify all other settings.

The code below seems to work perfectly for everything other than the user management area. I did want users of this group to be able to add/modify website users BUT where I am running into a problem is that users of this group currently have the ability to create users in the "Administrator" category and they are also able to deleting existing "Administrators".

What I am looking for is a way to modify the code below so that such users can NOT delete or modify a user account which is set as "Administrator" and restrict the user from being able to create a new Administrator account.

Does anyone know how this can be done?

// CREATE CUSTOM - SITE OWNER - USER ROLE WITH CUSTOM CAPABILITIES
if (!get_role('website_owner')) {
  //let's use the editor as the base capabilities
  $caps = get_role('editor')->capabilities; 
  $caps = array_merge( $caps, array(
    'install_plugins'               => false,
    'activate_plugins'              => false,
    'update_plugins'                => false,
    'delete_plugins'                => false,
    'list_users'                    => true,
    'add_users'                     => true,
    'create_users'                  => true,
    'edit_users'                    => true,
    'delete_users'                  => true,
    'remove_users'                  => true,
    'unfiltered_upload'             => true,
    'install_themes'                => false,
    'update_themes'                 => false,
    'delete_themes'                 => false,
    'switch_themes'                 => false,
    'edit_theme_options'            => true,
    'manage_options'                => false,
    'import'                        => false,
    'update_core'                   => false,
    'edit_dashboard'                => false,
    'gravityforms_view_entries'     => true,
    'gravityforms_edit_entries'     => true,
    'gravityforms_delete_entries'   => true,
    'gravityforms_export_entries'   => true,
    'gravityforms_view_entry_notes' => true,
    'gravityforms_edit_entry_notes' => true,
    'gravityforms_feed'             => true,
  )); //adding new capabilities.
  // Ref: http://codex.wordpress.org/Roles_and_Capabilities#Capability_vs._Role_Table
  add_role( 'website_owner', 'Website Owner', $caps );
}
Was it helpful?

Solution

Hi @NetConstructor:

I think this is what you need. Note that I didn't include the full setup of your 'website_owner' role, just the addition of a new capability called 'manage_administrators'.

Also, I only attempted to remove the "Delete" link from any users that don't have the 'manage_administrators' capability (which you'll need to add to the administrator role, of course) and I also simply removed the Administrator as a role option on the "Add New User" page. I didn't attempt to ensure they can't delete or add administrators via some nefarious method, and I didn't disable any other feature that might allow them to add or delete administrators. That said, maybe this is sufficient?

add_action('user_row_actions','yoursite_user_row_actions',10,2);
function yoursite_user_row_actions($actions, $user_object) {  // remove the ability to delete an administrator
  global $pagenow;
  if ($pagenow=='users.php' && isset($user_object->caps['administrator']) && !current_user_can('manage_administrators'))
    unset($actions['edit']);
    unset($actions['delete']);
  return $actions;
}
add_action('editable_roles','yoursite_editable_roles');
function yoursite_editable_roles($all_roles) { // remove the ability to add an administrator
  global $pagenow;
if (in_array($pagenow,array('user-edit.php','user-new.php')) &&           
       !current_user_can('manage_administrators'))
    unset($all_roles['administrator']);
  return $all_roles;
}
add_action('admin_init','yoursite_admin_init');
function yoursite_admin_init() {
  $wp_roles = new WP_Roles();
  $wp_roles->use_db = true;
  $administrator = $wp_roles->get_role('administrator');
  if (!$administrator->has_cap('manage_administrators'))
    $wp_roles->add_cap('administrator','manage_administrators');

  $website_owner = $wp_roles->get_role('website_owner');
  if (!$website_owner) {
    //let's use the editor as the base capabilities
    $caps = get_role('editor')->capabilities;
    $caps = array_merge( $caps, array(
      'install_plugins'               => false,
      'activate_plugins'              => false,
      'update_plugins'                => false,
      'delete_plugins'                => false,
      'list_users'                    => true,
      'add_users'                     => true,
      'create_users'                  => true,
      'edit_users'                    => true,
      'delete_users'                  => true,
      'remove_users'                  => true,
      'unfiltered_upload'             => true,
      'install_themes'                => false,
      'update_themes'                 => false,
      'delete_themes'                 => false,
      'switch_themes'                 => false,
      'edit_theme_options'            => true,
      'manage_options'                => false,
      'import'                        => false,
      'update_core'                   => false,
      'edit_dashboard'                => false,
      'gravityforms_view_entries'     => true,
      'gravityforms_edit_entries'     => true,
      'gravityforms_delete_entries'   => true,
      'gravityforms_export_entries'   => true,
      'gravityforms_view_entry_notes' => true,
      'gravityforms_edit_entry_notes' => true,
      'gravityforms_feed'             => true,
      'manage_administrators'         => false,
    ));
    $wp_roles->add_role('website_owner','Website Owner',$caps);
  }
}

OTHER TIPS

I believe this is now meant to be done using map_meta_cap :

For example to block deleting or editing the admin user who has an id of 1 you would do this:

add_filter('map_meta_cap', function( $required_caps, $cap, $user_id, $args ){

   $protected_user = 1; // ID of admin user you want to block from being edited

    if ( $user_id === $protected_user ) // Don't block caps if current user = protected user
        return $required_caps;
    $blocked_caps = array(
        'delete_user',
        'edit_user',
        'remove_user'
        );
    if ( in_array( $cap, $blocked_caps ) && $args[0] === $protected_user )
        $required_caps[] = 'do_not_allow';
    return $required_caps;
}, 10, 4 );

You can add any additional capabilities that you want blocked to the $blocked_caps array.

I also add this in for hiding myself from the wp-admin/users.php page. It would probably be better unsetting the user with php, but it doesn't really make a different since the admin can't be edited anyway if you are using the above function.

function hide_admin_user_bw() {
  ?>
    <style type="text/css">
    .users-php tr#user-1 {
        display: none!important;
    }
    .users-php li.administrator {
        display: none!important;
    }
    </style>
  <?php
}
add_action('admin_head-users.php', 'hide_admin_user_bw');
Licensed under: CC-BY-SA with attribution
Not affiliated with wordpress.stackexchange
scroll top