diff --git a/core/modules/block/block.admin.inc b/core/modules/block/block.admin.inc index ffa0b0b..b9666f9 100644 --- a/core/modules/block/block.admin.inc +++ b/core/modules/block/block.admin.inc @@ -465,7 +465,7 @@ function block_admin_configure($form, &$form_state, $module, $delta) { ':module' => $block->module, ':delta' => $block->delta, ))->fetchCol(); - $role_options = array_map('check_plain', user_roles()); + $role_options = array_map('check_plain', user_role_names()); $form['visibility']['role'] = array( '#type' => 'details', '#title' => t('Roles'), diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module index ab757a9..443ef08 100644 --- a/core/modules/comment/comment.module +++ b/core/modules/comment/comment.module @@ -1284,9 +1284,12 @@ function comment_node_update_index(Node $node, $langcode) { if ($index_comments === NULL) { // Find and save roles that can 'access comments' or 'search content'. $perms = array('access comments' => array(), 'search content' => array()); - $result = db_query("SELECT rid, permission FROM {role_permission} WHERE permission IN ('access comments', 'search content')"); - foreach ($result as $record) { - $perms[$record->permission][$record->rid] = $record->rid; + foreach (user_roles() as $role) { + foreach ($perms as $permission => $roles) { + if (array_key_exists($permission, $role->permissions)) { + $perms[$permission][$role->rid] = $role->rid; + } + } } // Prevent indexing of comments if there are any roles that can search but diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentLinksTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentLinksTest.php index d049aa3..91cab48 100644 --- a/core/modules/comment/lib/Drupal/comment/Tests/CommentLinksTest.php +++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentLinksTest.php @@ -39,7 +39,7 @@ function testCommentLinks() { // Remove additional user permissions from $this->web_user added by setUp(), // since this test is limited to anonymous and authenticated roles only. - user_role_delete(key($this->web_user->roles)); + entity_delete_multiple('user_role', array(key($this->web_user->roles))); // Matrix of possible environmental conditions and configuration settings. // See setEnvironment() for details. diff --git a/core/modules/filter/filter.admin.inc b/core/modules/filter/filter.admin.inc index c01fb93..0b75ba0 100644 --- a/core/modules/filter/filter.admin.inc +++ b/core/modules/filter/filter.admin.inc @@ -190,7 +190,7 @@ function filter_admin_format_form($form, &$form_state, $format) { $form['roles'] = array( '#type' => 'checkboxes', '#title' => t('Roles'), - '#options' => array_map('check_plain', user_roles()), + '#options' => array_map('check_plain', user_role_names()), '#disabled' => $is_fallback, ); if ($is_fallback) { diff --git a/core/modules/filter/filter.module b/core/modules/filter/filter.module index 1aff070..632edde 100644 --- a/core/modules/filter/filter.module +++ b/core/modules/filter/filter.module @@ -505,11 +505,11 @@ function filter_formats_reset() { function filter_get_roles_by_format($format) { // Handle the fallback format upfront (all roles have access to this format). if ($format->format == filter_fallback_format()) { - return user_roles(); + return user_role_names(); } // Do not list any roles if the permission does not exist. $permission = filter_permission_name($format); - return !empty($permission) ? user_roles(FALSE, $permission) : array(); + return !empty($permission) ? user_role_names(FALSE, $permission) : array(); } /** diff --git a/core/modules/filter/lib/Drupal/filter/Tests/FilterFormatAccessTest.php b/core/modules/filter/lib/Drupal/filter/Tests/FilterFormatAccessTest.php index 4636610..9c2fd68 100644 --- a/core/modules/filter/lib/Drupal/filter/Tests/FilterFormatAccessTest.php +++ b/core/modules/filter/lib/Drupal/filter/Tests/FilterFormatAccessTest.php @@ -147,7 +147,7 @@ function testFormatRoles() { $this->assertFalse(in_array($this->disallowed_format->format, array_keys(filter_get_formats_by_role($rid))), 'A text format which a role does not have access to does not appear in the list of formats available to that role.'); // Check that the fallback format is always allowed. - $this->assertEqual(filter_get_roles_by_format(filter_format_load(filter_fallback_format())), user_roles(), 'All roles have access to the fallback format.'); + $this->assertEqual(filter_get_roles_by_format(filter_format_load(filter_fallback_format())), user_role_names(), 'All roles have access to the fallback format.'); $this->assertTrue(in_array(filter_fallback_format(), array_keys(filter_get_formats_by_role($rid))), 'The fallback format appears in the list of allowed formats for any role.'); } diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeAccessLanguageTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeAccessLanguageTest.php index 6ff6ae0..8c250a6 100644 --- a/core/modules/node/lib/Drupal/node/Tests/NodeAccessLanguageTest.php +++ b/core/modules/node/lib/Drupal/node/Tests/NodeAccessLanguageTest.php @@ -41,11 +41,10 @@ function assertNodeAccess($ops, $node, $account, $langcode = NULL) { function setUp() { parent::setUp(); - // Clear permissions for authenticated users. - db_delete('role_permission') - ->condition('rid', DRUPAL_AUTHENTICATED_RID) - ->execute(); + $role = entity_load('user_role', DRUPAL_AUTHENTICATED_RID); + $role->permissions = array(); + $role->save(); } /** diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeAccessTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeAccessTest.php index 4f87348..4e6f2a1 100644 --- a/core/modules/node/lib/Drupal/node/Tests/NodeAccessTest.php +++ b/core/modules/node/lib/Drupal/node/Tests/NodeAccessTest.php @@ -36,9 +36,9 @@ function assertNodeAccess($ops, $node, $account) { function setUp() { parent::setUp(); // Clear permissions for authenticated users. - db_delete('role_permission') - ->condition('rid', DRUPAL_AUTHENTICATED_RID) - ->execute(); + $role = entity_load('user_role', DRUPAL_AUTHENTICATED_RID); + $role->permissions = array(); + $role->save(); } /** diff --git a/core/modules/node/node.views.inc b/core/modules/node/node.views.inc index a67b870..f159e39 100644 --- a/core/modules/node/node.views.inc +++ b/core/modules/node/node.views.inc @@ -690,20 +690,11 @@ function node_views_analyze($view) { // check for no access control $access = $display->getOption('access'); if (empty($access['type']) || $access['type'] == 'none') { - $select = db_select('role', 'r'); - $select->innerJoin('role_permission', 'p', 'r.rid = p.rid'); - $result = $select->fields('r', array('rid')) - ->fields('p', array('permission')) - ->condition('r.rid', array('anonymous', 'authenticated'), 'IN') - ->condition('p.permission', 'access content') - ->execute(); - - foreach ($result as $role) { - $role->safe = TRUE; - $roles[$role->rid] = $role; - } - if (!($roles['anonymous']->safe && $roles['authenticated']->safe)) { - $ret[] = Analyzer::formatMessage(t('Some roles lack permission to access content, but display %display has no access control.', array('%display' => $display['display_title'])), 'warning'); + // Find out whether anonymous and authenticated role have the + // 'access content' permission. + $roles = user_roles(FALSE, 'access content'); + if (!isset($roles[DRUPAL_ANONYMOUS_RID]) && !isset($roles[DRUPAL_AUTHENTICATED_RID])) { + $ret[] = Analyzer::formatMessage(t('Some roles lack permission to access content, but display %display has no access control.', array('%display' => $display->display['display_title'])), 'warning'); } $filters = $display->getOption('filters'); foreach ($filters as $filter) { diff --git a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php index 001e521..6a5e4fc 100644 --- a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php +++ b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php @@ -481,10 +481,11 @@ protected function drupalCreateRole(array $permissions, $rid = NULL, $name = NUL } // Create new role. - $role = new stdClass(); - $role->rid = $rid; - $role->name = $name; - $result = user_role_save($role); + $role = entity_create('user_role', array( + 'rid' => $rid, + 'name' => $name, + )); + $result = $role->save(); $this->assertIdentical($result, SAVED_NEW, t('Created role ID @rid with name @name.', array( '@name' => var_export($role->name, TRUE), @@ -496,8 +497,8 @@ protected function drupalCreateRole(array $permissions, $rid = NULL, $name = NUL if (!empty($permissions)) { user_role_grant_permissions($role->rid, $permissions); - $assigned_permissions = db_query('SELECT permission FROM {role_permission} WHERE rid = :rid', array(':rid' => $role->rid))->fetchCol(); - $missing_permissions = array_diff($permissions, $assigned_permissions); + $roles = user_roles(); + $missing_permissions = array_diff($permissions, array_keys($roles[$role->rid]->permissions)); if (!$missing_permissions) { $this->pass(t('Created permissions: @perms', array('@perms' => implode(', ', $permissions))), t('Role')); } diff --git a/core/modules/system/lib/Drupal/system/Tests/Module/UninstallTest.php b/core/modules/system/lib/Drupal/system/Tests/Module/UninstallTest.php index 3345d2f..a710435 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Module/UninstallTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Module/UninstallTest.php @@ -38,8 +38,7 @@ function testUserPermsUninstalled() { module_disable(array('module_test')); module_uninstall(array('module_test')); - // Are the perms defined by module_test removed from {role_permission}. - $count = db_query("SELECT COUNT(rid) FROM {role_permission} WHERE permission = :perm", array(':perm' => 'module_test perm'))->fetchField(); - $this->assertEqual(0, $count, 'Permissions were all removed.'); + // Are the perms defined by module_test removed. + $this->assertFalse(user_roles(FALSE, 'module_test perm'), 'Permissions were all removed.'); } } diff --git a/core/modules/system/lib/Drupal/system/Tests/Upgrade/LanguageUpgradePathTest.php b/core/modules/system/lib/Drupal/system/Tests/Upgrade/LanguageUpgradePathTest.php index 73f563b..284b866 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Upgrade/LanguageUpgradePathTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/LanguageUpgradePathTest.php @@ -178,11 +178,10 @@ public function testLanguagePermissionsUpgrade() { $this->assertTrue($this->performUpgrade(), 'The upgrade was completed successfully.'); + $roles = user_roles(); // Check that translate content role doesn't exist on database. - $old_permission_exists = db_query('SELECT * FROM {role_permission} WHERE permission LIKE ?', array('translate content'))->fetchObject(); - $this->assertFalse($old_permission_exists, 'No translate content role left on database.'); + $this->assertFalse(array_key_exists('translate content', $roles[DRUPAL_AUTHENTICATED_RID]->permissions), 'No translate content role left on database.'); // Check that translate content has been renamed to translate all content. - $new_permission_exists = db_query('SELECT * FROM {role_permission} WHERE permission LIKE ?', array('translate all content'))->fetchObject(); - $this->assertTrue($new_permission_exists, 'Rename role translate content to translate all content was completed successfully.'); + $this->assertTrue(array_key_exists('translate all content', $roles[DRUPAL_AUTHENTICATED_RID]->permissions), 'Rename role translate content to translate all content was completed successfully.'); } } diff --git a/core/modules/translation/translation.install b/core/modules/translation/translation.install index 61d014d..2d9463a 100644 --- a/core/modules/translation/translation.install +++ b/core/modules/translation/translation.install @@ -10,10 +10,14 @@ * Rename the translate content permission. */ function translation_update_8000() { - db_update('role_permission') - ->fields(array('permission' => 'translate all content')) - ->condition('permission', 'translate content') - ->execute(); + foreach (config_get_storage_names_with_prefix('user.role.') as $name) { + $role = config($name)->get(); + if (array_key_exists('translate content', $role['permissions'])) { + unset($role['permissions']['translate content']); + $role['permissions']['translate all content'] = 'translate all content'; + config($name)->setData($role)->save(); + } + } } /** diff --git a/core/modules/user/config/user.role.anonymous.yml b/core/modules/user/config/user.role.anonymous.yml new file mode 100644 index 0000000..6b3f713 --- /dev/null +++ b/core/modules/user/config/user.role.anonymous.yml @@ -0,0 +1,3 @@ +rid: anonymous +name: Anonymous user +weight: 0 diff --git a/core/modules/user/config/user.role.authenticated.yml b/core/modules/user/config/user.role.authenticated.yml new file mode 100644 index 0000000..1375647 --- /dev/null +++ b/core/modules/user/config/user.role.authenticated.yml @@ -0,0 +1,3 @@ +rid: authenticated +name: Authenticated user +weight: 1 diff --git a/core/modules/user/lib/Drupal/user/AccountFormController.php b/core/modules/user/lib/Drupal/user/AccountFormController.php index 512f703..b3043de 100644 --- a/core/modules/user/lib/Drupal/user/AccountFormController.php +++ b/core/modules/user/lib/Drupal/user/AccountFormController.php @@ -126,7 +126,7 @@ public function form(array $form, array &$form_state, EntityInterface $account) '#access' => $admin, ); - $roles = array_map('check_plain', user_roles(TRUE)); + $roles = array_map('check_plain', user_role_names(TRUE)); // The disabled checkbox subelement for the 'authenticated user' role // must be generated separately and added to the checkboxes element, // because of a limitation in Form API not supporting a single disabled diff --git a/core/modules/user/lib/Drupal/user/Plugin/Core/Entity/Role.php b/core/modules/user/lib/Drupal/user/Plugin/Core/Entity/Role.php new file mode 100644 index 0000000..3cd550b --- /dev/null +++ b/core/modules/user/lib/Drupal/user/Plugin/Core/Entity/Role.php @@ -0,0 +1,74 @@ +rid; + } + +} diff --git a/core/modules/user/lib/Drupal/user/Plugin/views/access/Role.php b/core/modules/user/lib/Drupal/user/Plugin/views/access/Role.php index 2a07d79..146968a 100644 --- a/core/modules/user/lib/Drupal/user/Plugin/views/access/Role.php +++ b/core/modules/user/lib/Drupal/user/Plugin/views/access/Role.php @@ -46,7 +46,7 @@ public function summaryTitle() { return t('Multiple roles'); } else { - $rids = user_roles(); + $rids = user_role_names(); $rid = reset($this->options['role']); return check_plain($rids[$rid]); } diff --git a/core/modules/user/lib/Drupal/user/Plugin/views/argument/RolesRid.php b/core/modules/user/lib/Drupal/user/Plugin/views/argument/RolesRid.php index 634307e..1d18b0b 100644 --- a/core/modules/user/lib/Drupal/user/Plugin/views/argument/RolesRid.php +++ b/core/modules/user/lib/Drupal/user/Plugin/views/argument/RolesRid.php @@ -23,16 +23,7 @@ class RolesRid extends ManyToOne { function title_query() { - $titles = array(); - - $query = db_select('role', 'r'); - $query->addField('r', 'name'); - $query->condition('r.rid', $this->value); - $result = $query->execute(); - foreach ($result as $term) { - $titles[] = check_plain($term->name); - } - return $titles; + return array(entity_load('user_role', $this->value)->name); } } diff --git a/core/modules/user/lib/Drupal/user/Plugin/views/argument_validator/User.php b/core/modules/user/lib/Drupal/user/Plugin/views/argument_validator/User.php index a31b0af..36a6a5a 100644 --- a/core/modules/user/lib/Drupal/user/Plugin/views/argument_validator/User.php +++ b/core/modules/user/lib/Drupal/user/Plugin/views/argument_validator/User.php @@ -56,7 +56,7 @@ public function buildOptionsForm(&$form, &$form_state) { $form['roles'] = array( '#type' => 'checkboxes', '#title' => t('Restrict to the selected roles'), - '#options' => array_map('check_plain', user_roles(TRUE)), + '#options' => array_map('check_plain', user_role_names(TRUE)), '#default_value' => $this->options['roles'], '#description' => t('If no roles are selected, users from any role will be allowed.'), '#states' => array( diff --git a/core/modules/user/lib/Drupal/user/Plugin/views/field/Permissions.php b/core/modules/user/lib/Drupal/user/Plugin/views/field/Permissions.php index 98cb021..5e1cb34 100644 --- a/core/modules/user/lib/Drupal/user/Plugin/views/field/Permissions.php +++ b/core/modules/user/lib/Drupal/user/Plugin/views/field/Permissions.php @@ -46,28 +46,19 @@ function pre_render(&$values) { } if ($uids) { - // Get a list of all the modules implementing a hook_permission() and sort by - // display name. - $module_info = system_get_info('module'); - $modules = array(); - foreach (module_implements('permission') as $module) { - $modules[$module] = $module_info[$module]['name']; - } - asort($modules); - - $permissions = module_invoke_all('permission'); - - $query = db_select('role_permission', 'rp'); - $query->join('users_roles', 'u', 'u.rid = rp.rid'); - $query->fields('u', array('uid', 'rid')); - $query->addField('rp', 'permission'); - $query->condition('u.uid', $uids); - $query->condition('rp.module', array_keys($modules)); - $query->orderBy('rp.permission'); - $result = $query->execute(); - - foreach ($result as $perm) { - $this->items[$perm->uid][$perm->permission]['permission'] = $permissions[$perm->permission]['title']; + // Load all permissions to be able show the label. + $all_permissions = module_invoke_all('permission'); + $roles = user_roles(); + + foreach ($values as $row) { + $account = $this->get_entity($row); + // Get a list of roles of all the users to load all permissions of each + // user. + foreach ($roles as $role) { + foreach ($role->permissions as $permission => $value) { + $this->items[$account->uid][$permission]['permission'] = $all_permissions[$permission]['title']; + } + } } } } diff --git a/core/modules/user/lib/Drupal/user/Plugin/views/filter/Roles.php b/core/modules/user/lib/Drupal/user/Plugin/views/filter/Roles.php index 8ee3569..139856e 100644 --- a/core/modules/user/lib/Drupal/user/Plugin/views/filter/Roles.php +++ b/core/modules/user/lib/Drupal/user/Plugin/views/filter/Roles.php @@ -23,7 +23,7 @@ class Roles extends ManyToOne { function get_value_options() { - $this->value_options = user_roles(TRUE); + $this->value_options = user_role_names(TRUE); unset($this->value_options[DRUPAL_AUTHENTICATED_RID]); } diff --git a/core/modules/user/lib/Drupal/user/RoleStorageController.php b/core/modules/user/lib/Drupal/user/RoleStorageController.php new file mode 100644 index 0000000..225bcf9 --- /dev/null +++ b/core/modules/user/lib/Drupal/user/RoleStorageController.php @@ -0,0 +1,71 @@ +name = trim($entity->name); + + if (!isset($entity->weight)) { + $roles = entity_load_multiple('entity_roles'); + // Set a role weight to make this new role last. + $max = array_reduce($roles, function($max, $entity) { + return $max > $entity['weight'] ? $max : $entity['weight']; + }); + $entity->weight = $max + 1; + } + + return parent::save($entity); + } + + /** + * Overrides Drupal\Core\Entity\ConfigStorageController::resetCache(). + */ + public function resetCache(array $ids = NULL) { + parent::resetCache($ids); + + // Clear the user access cache. + drupal_static_reset('user_access'); + drupal_static_reset('user_roles'); + } + + /** + * Overrides Drupal\Core\Entity\ConfigStorageController::postDelete(). + */ + protected function postDelete($entities) { + // Update the users who have this role set: + db_delete('users_roles') + ->condition('rid', array_keys($entities)) + ->execute(); + } + + /** + * Overrides Drupal\Core\Entity\ConfigStorageController::attachLoad(). + */ + protected function attachLoad(&$queried_entities, $revision_id = FALSE) { + // Sort the queried roles by their weight. + uasort($queried_entities, 'Drupal\Core\Config\Entity\ConfigEntityBase::sort'); + + parent::attachLoad($queried_entities, $revision_id); + } + +} diff --git a/core/modules/user/lib/Drupal/user/Tests/UserPermissionsTest.php b/core/modules/user/lib/Drupal/user/Tests/UserPermissionsTest.php index 2455b10..9f75a7d 100644 --- a/core/modules/user/lib/Drupal/user/Tests/UserPermissionsTest.php +++ b/core/modules/user/lib/Drupal/user/Tests/UserPermissionsTest.php @@ -47,7 +47,7 @@ function testUserPermissionChanges() { $this->drupalPost('admin/people/permissions', $edit, t('Save permissions')); $this->assertText(t('The changes have been saved.'), 'Successful save message displayed.'); drupal_static_reset('user_access'); - drupal_static_reset('user_role_permissions'); + drupal_static_reset('user_roles'); $this->assertTrue(user_access('administer nodes', $account), 'User now has "administer nodes" permission.'); // Remove a permission. @@ -57,7 +57,7 @@ function testUserPermissionChanges() { $this->drupalPost('admin/people/permissions', $edit, t('Save permissions')); $this->assertText(t('The changes have been saved.'), 'Successful save message displayed.'); drupal_static_reset('user_access'); - drupal_static_reset('user_role_permissions'); + drupal_static_reset('user_roles'); $this->assertFalse(user_access('access user profiles', $account), 'User no longer has "access user profiles" permission.'); } @@ -80,6 +80,8 @@ function testAdministratorRole() { // Aggregator depends on file module, enable that as well. $edit['modules[Core][file][enable]'] = TRUE; $this->drupalPost('admin/modules', $edit, t('Save configuration')); + drupal_static_reset('user_access'); + drupal_static_reset('user_roles'); $this->assertTrue(user_access('administer news feeds', $this->admin_user), 'The permission was automatically assigned to the administrator role'); } diff --git a/core/modules/user/lib/Drupal/user/Tests/UserRoleAdminTest.php b/core/modules/user/lib/Drupal/user/Tests/UserRoleAdminTest.php index 50d4da7..cc143ff 100644 --- a/core/modules/user/lib/Drupal/user/Tests/UserRoleAdminTest.php +++ b/core/modules/user/lib/Drupal/user/Tests/UserRoleAdminTest.php @@ -40,7 +40,7 @@ function testRoleAdministration() { $edit = array('role[name]' => $role_name, 'role[rid]' => $role_name); $this->drupalPost('admin/people/roles', $edit, t('Add role')); $this->assertText(t('The role has been added.'), 'The role has been added.'); - $role = user_role_load($role_name); + $role = entity_load('user_role', $role_name); $this->assertTrue(is_object($role), 'The role was successfully retrieved from the database.'); // Try adding a duplicate role. @@ -53,7 +53,7 @@ function testRoleAdministration() { $edit = array('role[name]' => $role_name); $this->drupalPost("admin/people/roles/edit/{$role->rid}", $edit, t('Save role')); $this->assertText(t('The role has been renamed.'), 'The role has been renamed.'); - $new_role = user_role_load($old_name); + $new_role = entity_load('user_role', $old_name); $this->assertEqual($new_role->name, $role_name, 'The role name has been successfully changed.'); // Test deleting a role. @@ -61,7 +61,7 @@ function testRoleAdministration() { $this->drupalPost(NULL, NULL, t('Delete')); $this->assertText(t('The role has been deleted.'), 'The role has been deleted'); $this->assertNoLinkByHref("admin/people/roles/edit/{$role->rid}", 'Role edit link removed.'); - $this->assertFalse(user_role_load($role_name), 'A deleted role can no longer be loaded.'); + $this->assertFalse(entity_load('user_role', $role_name), 'A deleted role can no longer be loaded.'); // Make sure that the system-defined roles can be edited via the user // interface. @@ -80,8 +80,8 @@ function testRoleWeightChange() { $this->drupalLogin($this->admin_user); // Pick up a random role and get its weight. - $rid = array_rand(user_roles()); - $role = user_role_load($rid); + $rid = array_rand(user_role_names()); + $role = entity_load('user_role', $rid); $old_weight = $role->weight; // Change the role weight and submit the form. @@ -90,7 +90,7 @@ function testRoleWeightChange() { $this->assertText(t('The role settings have been updated.'), 'The role settings form submitted successfully.'); // Retrieve the saved role and compare its weight. - $role = user_role_load($rid); + $role = entity_load('user_role', $rid); $new_weight = $role->weight; $this->assertTrue(($old_weight + 1) == $new_weight, 'Role weight updated successfully.'); } diff --git a/core/modules/user/lib/Drupal/user/UserStorageController.php b/core/modules/user/lib/Drupal/user/UserStorageController.php index 2b532c9..119b005 100644 --- a/core/modules/user/lib/Drupal/user/UserStorageController.php +++ b/core/modules/user/lib/Drupal/user/UserStorageController.php @@ -34,9 +34,9 @@ function attachLoad(&$queried_users, $load_revision = FALSE) { } // Add any additional roles from the database. - $result = db_query('SELECT r.rid, r.name, ur.uid FROM {role} r INNER JOIN {users_roles} ur ON ur.rid = r.rid WHERE ur.uid IN (:uids)', array(':uids' => array_keys($queried_users))); + $result = db_query('SELECT ur.rid, ur.uid FROM {users_roles} ur WHERE ur.uid IN (:uids)', array(':uids' => array_keys($queried_users))); foreach ($result as $record) { - $queried_users[$record->uid]->roles[$record->rid] = $record->name; + $queried_users[$record->uid]->roles[$record->rid] = $record->rid; } // Call the default attachLoad() method. This will add fields and call diff --git a/core/modules/user/user.admin.inc b/core/modules/user/user.admin.inc index 3668aae..2675bd5 100644 --- a/core/modules/user/user.admin.inc +++ b/core/modules/user/user.admin.inc @@ -5,6 +5,8 @@ * Admin page callback file for the user module. */ +use Drupal\user\Plugin\Core\Entity\Role; + function user_admin($callback_arg = '') { $op = isset($_POST['op']) ? $_POST['op'] : $callback_arg; @@ -193,8 +195,7 @@ function user_admin_account() { $destination = drupal_get_destination(); $status = array(t('blocked'), t('active')); - $roles = array_map('check_plain', user_roles(TRUE)); - $accounts = array(); + $roles = array_map('check_plain', user_role_names(TRUE)); foreach ($result as $account) { $account = user_load($account->uid); $users_roles = array(); @@ -301,7 +302,7 @@ function user_admin_settings($form, &$form_state) { // Do not allow users to set the anonymous or authenticated user roles as the // administrator role. - $roles = user_roles(); + $roles = user_role_names(); unset($roles[DRUPAL_ANONYMOUS_RID]); unset($roles[DRUPAL_AUTHENTICATED_RID]); $roles[0] = t('disabled'); @@ -645,14 +646,13 @@ function user_admin_settings_submit($form, &$form_state) { * @see theme_user_admin_permissions() */ function user_admin_permissions($form, $form_state, $rid = NULL) { - // Retrieve role names for columns. - $role_names = user_roles(); + $role_names = user_role_names(); if (isset($rid)) { $role_names = array($rid => $role_names[$rid]); } // Fetch permissions for all roles or the one selected role. - $role_permissions = user_role_permissions($role_names); + $roles = user_roles(); // Store $role_names for use when saving the data. $form['role_names'] = array( @@ -693,7 +693,7 @@ function user_admin_permissions($form, $form_state, $rid = NULL) { ); foreach ($role_names as $rid => $name) { // Builds arrays for checked boxes for each role - if (isset($role_permissions[$rid][$perm])) { + if (isset($roles[$rid]->permissions[$perm])) { $status[$rid][] = $perm; } } @@ -748,7 +748,7 @@ function user_admin_permissions_submit($form, &$form_state) { function theme_user_admin_permissions($variables) { $form = $variables['form']; - $roles = user_roles(); + $roles = user_role_names(); foreach (element_children($form['permission']) as $key) { $row = array(); // Module name @@ -817,12 +817,7 @@ function theme_user_permission_description($variables) { * @see theme_user_admin_roles() */ function user_admin_roles($form, $form_state) { - $roles = db_select('role', 'r') - ->addTag('translatable') - ->fields('r') - ->orderBy('weight') - ->orderBy('name') - ->execute(); + $roles = entity_load_multiple('user_role'); $form['roles'] = array( '#tree' => TRUE, @@ -889,8 +884,10 @@ function user_admin_roles($form, $form_state) { function user_admin_roles_order_submit($form, &$form_state) { foreach ($form_state['values']['roles'] as $rid => $role_values) { $role = $form['roles'][$rid]['#role']; - $role->weight = $role_values['weight']; - user_role_save($role); + if ($role->weight != $role_values['weight']) { + $role->weight = $role_values['weight']; + $role->save(); + } } drupal_set_message(t('The role settings have been updated.')); } @@ -942,8 +939,9 @@ function theme_user_admin_roles($variables) { /** * Form to configure a single role. * - * @ingroup forms * @see user_admin_role_submit() + * + * @ingroup forms */ function user_admin_role($form, $form_state, $role) { $form['role'] = array( @@ -992,12 +990,11 @@ function user_admin_role($form, $form_state, $role) { } /** - * Form submit handler for the user_admin_role() form. + * Form submission handler for the user_admin_role() form. */ function user_admin_role_submit($form, &$form_state) { - $role = (object) $form_state['values']['role']; - $status = user_role_save($role); - if ($status === SAVED_UPDATED) { + $role = entity_create('user_role', $form_state['values']['role']); + if ($role->save() === SAVED_UPDATED) { drupal_set_message(t('The role has been renamed.')); } else { @@ -1014,9 +1011,17 @@ function user_admin_role_delete_submit($form, &$form_state) { } /** - * Form to confirm role delete operation. + * Page callback: Form constructor for the role deletion form. + * + * @param Drupal\user\Plugin\Core\Entity\Role $role + * + * @see user_menu() + * @see user_admin_role_delete_confirm_submit() + * + * @ingroup forms */ -function user_admin_role_delete_confirm($form, &$form_state, $role) { +function user_admin_role_delete_confirm($form, &$form_state, Role $role) { + $form_state['user_role'] = $role; $form['rid'] = array( '#type' => 'value', '#value' => $role->rid, @@ -1025,10 +1030,11 @@ function user_admin_role_delete_confirm($form, &$form_state, $role) { } /** - * Form submit handler for user_admin_role_delete_confirm(). + * Form submission handler for user_admin_role_delete_confirm(). */ function user_admin_role_delete_confirm_submit($form, &$form_state) { - user_role_delete($form_state['values']['rid']); + $role = $form_state['user_role']; + $role->delete(); drupal_set_message(t('The role has been deleted.')); $form_state['redirect'] = 'admin/people/roles'; } diff --git a/core/modules/user/user.install b/core/modules/user/user.install index bb86002..e4ab895 100644 --- a/core/modules/user/user.install +++ b/core/modules/user/user.install @@ -191,75 +191,6 @@ function user_schema() { ), ); - $schema['role'] = array( - 'description' => 'Stores user roles.', - 'fields' => array( - 'rid' => array( - 'type' => 'varchar', - // The role ID is often used as part of a compound index; at least MySQL - // has a maximum index length of 1000 characters (333 on utf8), so we - // limit the maximum length. - 'length' => 64, - 'not null' => TRUE, - 'description' => 'Primary Key: Unique role ID.', - ), - 'name' => array( - 'type' => 'varchar', - 'length' => 255, - 'not null' => TRUE, - 'default' => '', - 'description' => 'Role label.', - 'translatable' => TRUE, - ), - 'weight' => array( - 'type' => 'int', - 'not null' => TRUE, - 'default' => 0, - 'description' => 'The weight of this role in listings and the user interface.', - ), - ), - 'primary key' => array('rid'), - 'indexes' => array( - 'name_weight' => array('name', 'weight'), - ), - ); - - $schema['role_permission'] = array( - 'description' => 'Stores the permissions assigned to user roles.', - 'fields' => array( - 'rid' => array( - 'type' => 'varchar', - 'length' => 64, - 'not null' => TRUE, - 'description' => 'Foreign Key: {role}.rid.', - ), - 'permission' => array( - 'type' => 'varchar', - 'length' => 128, - 'not null' => TRUE, - 'default' => '', - 'description' => 'A single permission granted to the role identified by rid.', - ), - 'module' => array( - 'type' => 'varchar', - 'length' => 255, - 'not null' => TRUE, - 'default' => '', - 'description' => "The module declaring the permission.", - ), - ), - 'primary key' => array('rid', 'permission'), - 'indexes' => array( - 'permission' => array('permission'), - ), - 'foreign keys' => array( - 'role' => array( - 'table' => 'role', - 'columns' => array('rid' => 'rid'), - ), - ), - ); - $schema['users_data'] = array( 'description' => 'Stores module data as key/value pairs per user.', 'fields' => array( @@ -369,13 +300,16 @@ function user_install() { 'status' => 1, )) ->execute(); +} - // Insert built-in roles. - db_insert('role') - ->fields(array('rid', 'name', 'weight')) - ->values(array(DRUPAL_ANONYMOUS_RID, 'Anonymous user', 0)) - ->values(array(DRUPAL_AUTHENTICATED_RID, 'Authenticated user', 1)) - ->execute(); +/** + * Implements hook_update_dependencies(). + */ +function user_update_dependencies() { + $dependencies['user'][8017] = array( + 'node' => 8013, + ); + return $dependencies; } /** @@ -964,6 +898,34 @@ function user_update_8016() { } /** + * Turn the {role} table into configuration entities. + */ +function user_update_8017() { + $roles = db_select('role', 'r') + ->fields('r') + ->execute() + ->fetchAll(); + + foreach ($roles as $role) { + $permissions = db_select('role_permission', 'rp') + ->fields('rp', array('permission')) + ->condition('rid', $role->rid) + ->execute() + ->fetchAllKeyed(0, 0); + + config('user.role.' . $role->rid) + ->set('rid', $role->rid) + ->set('name', $role->name) + ->set('weight', $role->weight) + ->set('permissions', $permissions ?: array()) + ->save(); + } + + db_drop_table('role'); + db_drop_table('role_permission'); +} + +/** * @} End of "addtogroup updates-7.x-to-8.x". */ diff --git a/core/modules/user/user.module b/core/modules/user/user.module index ec43ade..d5e0661 100644 --- a/core/modules/user/user.module +++ b/core/modules/user/user.module @@ -1,6 +1,7 @@ roles. - * - * @return - * An array indexed by role ID. Each value is an array whose keys are the - * permission strings for the given role ID. - */ -function user_role_permissions($roles = array()) { - $cache = &drupal_static(__FUNCTION__, array()); - - $role_permissions = $fetch = array(); - - if ($roles) { - foreach ($roles as $rid => $name) { - if (isset($cache[$rid])) { - $role_permissions[$rid] = $cache[$rid]; - } - else { - // Add this rid to the list of those needing to be fetched. - $fetch[] = $rid; - // Prepare in case no permissions are returned. - $cache[$rid] = array(); - } - } - - if ($fetch) { - // Get from the database permissions that were not in the static variable. - // Only role IDs with at least one permission assigned will return rows. - $result = db_query("SELECT rid, permission FROM {role_permission} WHERE rid IN (:fetch)", array(':fetch' => $fetch)); - - foreach ($result as $row) { - $cache[$row->rid][$row->permission] = TRUE; - } - foreach ($fetch as $rid) { - // For every rid, we know we at least assigned an empty array. - $role_permissions[$rid] = $cache[$rid]; - } - } - } - - return $role_permissions; -} - -/** * Determine whether the user has a given privilege. * * @param $string @@ -451,10 +406,8 @@ function user_role_permissions($roles = array()) { * can perform all actions. */ function user_access($string, $account = NULL) { - global $user; - if (!isset($account)) { - $account = $user; + $account = $GLOBALS['user']; } // User #1 has all privileges: @@ -462,22 +415,19 @@ function user_access($string, $account = NULL) { return TRUE; } - // To reduce the number of SQL queries, we cache the user's permissions - // in a static variable. - // Use the advanced drupal_static() pattern, since this is called very often. + // To reduce the number of queries, we cache the user's permissions in a + // static variable. Use the advanced drupal_static() pattern, since this is + // called very often. static $drupal_static_fast; if (!isset($drupal_static_fast)) { $drupal_static_fast['perm'] = &drupal_static(__FUNCTION__); } $perm = &$drupal_static_fast['perm']; if (!isset($perm[$account->uid])) { - $role_permissions = user_role_permissions($account->roles); - - $perms = array(); - foreach ($role_permissions as $one_role) { - $perms += $one_role; + $perm[$account->uid] = array(); + foreach (array_intersect_key(user_roles(), $account->roles) as $role) { + $perm[$account->uid] = array_merge($perm[$account->uid], $role->permissions); } - $perm[$account->uid] = $perms; } return isset($perm[$account->uid][$string]); @@ -2038,147 +1988,65 @@ function user_mail_tokens(&$replacements, $data, $options) { } } -/*** Administrative features ***********************************************/ +/** + * Retrieves an array of names of roles matching specified conditions. + * + * @param bool $membersonly + * Set this to TRUE to exclude the 'anonymous' role. + * @param string $permission + * A string containing a permission. If set, only names of roles containing + * that permission are returned. + * + * @return array + * An associative array with the role id as the key and the role name as + * value. + */ +function user_role_names($membersonly = FALSE, $permission = NULL) { + return array_map(function($item) { + return $item->name; + }, user_roles($membersonly, $permission)); +} /** - * Retrieve an array of roles matching specified conditions. + * Retrieves an array of roles matching specified conditions. * - * @param $membersonly + * @param bool $membersonly * Set this to TRUE to exclude the 'anonymous' role. - * @param $permission - * A string containing a permission. If set, only roles containing that + * @param string $permission + * A string representing a permission. If set, only roles containing that * permission are returned. * - * @return - * An associative array with the role id as the key and the role name as + * @return array + * An associative array with the role id as the key and the role object as * value. */ function user_roles($membersonly = FALSE, $permission = NULL) { - $user_roles = &drupal_static(__FUNCTION__); - - // Do not cache roles for specific permissions. This data is not requested - // frequently enough to justify the additional memory use. - if (empty($permission)) { - $cid = $membersonly ? DRUPAL_AUTHENTICATED_RID : DRUPAL_ANONYMOUS_RID; - if (isset($user_roles[$cid])) { - return $user_roles[$cid]; - } + $cache = &drupal_static(__FUNCTION__); + if (!isset($cache)) { + $cache = entity_load_multiple('user_role'); } - $query = db_select('role', 'r'); - $query->addTag('translatable'); - $query->fields('r', array('rid', 'name')); - $query->orderBy('weight'); - $query->orderBy('name'); - if (!empty($permission)) { - $query->innerJoin('role_permission', 'p', 'r.rid = p.rid'); - $query->condition('p.permission', $permission); - } + $roles = $cache; if ($membersonly) { - $query->condition('r.rid', DRUPAL_ANONYMOUS_RID, '!='); - } - $roles = $query->execute()->fetchAllKeyed(); - - if (empty($permission)) { - $user_roles[$cid] = $roles; - return $user_roles[$cid]; + unset($roles[DRUPAL_ANONYMOUS_RID]); } - return $roles; + return !$permission ? $roles : array_filter($roles, function ($role) use ($permission) { + return isset($role->permissions[$permission]); + }); } /** * Fetches a user role by role ID. * - * @param $rid + * @param string $rid * A string representing the role ID. * - * @return - * A fully-loaded role object if a role with the given ID exists, or FALSE - * otherwise. + * @return Drupal\user\Plugin\Core\Entity\Role + * A fully-loaded role object or FALSE if there is no role with the given id. */ function user_role_load($rid) { - return db_select('role', 'r') - ->fields('r') - ->condition('rid', $rid) - ->execute() - ->fetchObject(); -} - -/** - * Save a user role to the database. - * - * @param $role - * A role object to modify or add. - * - * @return - * Status constant indicating if role was created or updated. - * Failure to write the user role record will return FALSE. Otherwise - * SAVED_NEW or SAVED_UPDATED is returned depending on the operation - * performed. - */ -function user_role_save($role) { - if ($role->name) { - // Prevent leading and trailing spaces in role names. - $role->name = trim($role->name); - } - if (!isset($role->weight)) { - // Set a role weight to make this new role last. - $query = db_select('role'); - $query->addExpression('MAX(weight)'); - $role->weight = $query->execute()->fetchField() + 1; - } - - // Let modules modify the user role before it is saved to the database. - module_invoke_all('user_role_presave', $role); - - $exists = db_select('role', 'r') - ->fields('r', array('rid')) - ->condition('rid', $role->rid) - ->execute() - ->fetchAll(); - - if (empty($exists)) { - $status = drupal_write_record('role', $role); - module_invoke_all('user_role_insert', $role); - } - else { - $status = drupal_write_record('role', $role, 'rid'); - module_invoke_all('user_role_update', $role); - } - - // Clear the user access cache. - drupal_static_reset('user_access'); - drupal_static_reset('user_role_permissions'); - - return $status; -} - -/** - * Delete a user role from database. - * - * @param $role - * A string with the role ID. - */ -function user_role_delete($role) { - $role = user_role_load($role); - - db_delete('role') - ->condition('rid', $role->rid) - ->execute(); - db_delete('role_permission') - ->condition('rid', $role->rid) - ->execute(); - // Update the users who have this role set: - db_delete('users_roles') - ->condition('rid', $role->rid) - ->execute(); - - module_invoke_all('user_role_delete', $role); - - // Clear the user access cache. - drupal_static_reset('user_access'); - drupal_static_reset('user_role_permissions'); + return entity_load('user_role', $rid); } /** @@ -2194,23 +2062,6 @@ function user_role_delete_access($role) { } /** - * Determine the modules that permissions belong to. - * - * @return - * An associative array in the format $permission => $module. - */ -function user_permission_get_modules() { - $permissions = array(); - foreach (module_implements('permission') as $module) { - $perms = module_invoke($module, 'permission'); - foreach ($perms as $key => $value) { - $permissions[$key] = $module; - } - } - return $permissions; -} - -/** * Change permissions for a user role. * * This function may be used to grant and revoke multiple permissions at once. @@ -2264,23 +2115,14 @@ function user_role_change_permissions($rid, array $permissions = array()) { * @see user_role_revoke_permissions() */ function user_role_grant_permissions($rid, array $permissions = array()) { - $modules = user_permission_get_modules(); // Grant new permissions for the role. - foreach ($permissions as $name) { - db_merge('role_permission') - ->key(array( - 'rid' => $rid, - 'permission' => $name, - )) - ->fields(array( - 'module' => $modules[$name], - )) - ->execute(); - } + $role = entity_load('user_role', $rid); + $role->permissions = array_merge($role->permissions, array_combine($permissions, $permissions)); + $role->save(); // Clear the user access cache. drupal_static_reset('user_access'); - drupal_static_reset('user_role_permissions'); + drupal_static_reset('user_roles'); } /** @@ -2296,14 +2138,13 @@ function user_role_grant_permissions($rid, array $permissions = array()) { */ function user_role_revoke_permissions($rid, array $permissions = array()) { // Revoke permissions for the role. - db_delete('role_permission') - ->condition('rid', $rid) - ->condition('permission', $permissions, 'IN') - ->execute(); + $role = entity_load('user_role', $rid); + $role->permissions = array_diff_key($role->permissions, array_flip($permissions)); + $role->save(); // Clear the user access cache. drupal_static_reset('user_access'); - drupal_static_reset('user_role_permissions'); + drupal_static_reset('user_roles'); } /** @@ -2325,7 +2166,7 @@ function user_user_operations($form = array(), $form_state = array()) { ); if (user_access('administer permissions')) { - $roles = user_roles(TRUE); + $roles = user_role_names(TRUE); unset($roles[DRUPAL_AUTHENTICATED_RID]); // Can't edit authenticated role. $add_roles = array(); @@ -2410,7 +2251,7 @@ function user_user_operations_block($accounts) { * Callback function for admin mass adding/deleting a user role. */ function user_multiple_role_edit($accounts, $operation, $rid) { - $role_name = db_query('SELECT name FROM {role} WHERE rid = :rid', array(':rid' => $rid))->fetchField(); + $role_name = entity_load('user_role', $rid)->name; switch ($operation) { case 'add_role': @@ -2546,7 +2387,7 @@ function user_multiple_cancel_confirm_submit($form, &$form_state) { function user_filters() { // Regular filters $filters = array(); - $roles = user_roles(TRUE); + $roles = user_role_names(TRUE); unset($roles[DRUPAL_AUTHENTICATED_RID]); // Don't list authorized role. if (count($roles)) { $filters['role'] = array( @@ -2605,13 +2446,14 @@ function user_build_filter_query(SelectInterface $query) { if ($key == 'permission') { $account = entity_create('user', array()); $account->uid = 'user_filter'; - $account->roles = array(DRUPAL_AUTHENTICATED_RID => 1); + $account->roles = array(DRUPAL_AUTHENTICATED_RID => DRUPAL_AUTHENTICATED_RID); if (user_access($value, $account)) { continue; } + + $roles = array_keys(user_roles(FALSE, $value)); $users_roles_alias = $query->join('users_roles', 'ur', '%alias.uid = u.uid'); - $permission_alias = $query->join('role_permission', 'p', $users_roles_alias . '.rid = %alias.rid'); - $query->condition($permission_alias . '.permission', $value); + $query->condition($users_roles_alias . '.rid', $roles ?: NULL); } elseif ($key == 'role') { $users_roles_alias = $query->join('users_roles', 'ur', '%alias.uid = u.uid'); @@ -2905,8 +2747,7 @@ function user_form_field_ui_field_edit_form_submit($form, &$form_state) { */ function user_modules_installed($modules) { // Assign all available permissions to the administrator role. - $rid = config('user.settings')->get('admin_role'); - if ($rid) { + if ($rid = config('user.settings')->get('admin_role')) { $permissions = array(); foreach ($modules as $module) { if ($module_permissions = module_invoke($module, 'permission')) { @@ -2923,9 +2764,11 @@ function user_modules_installed($modules) { * Implements hook_modules_uninstalled(). */ function user_modules_uninstalled($modules) { - db_delete('role_permission') - ->condition('module', $modules, 'IN') - ->execute(); + $permissions = array_keys(module_invoke_all('permission')); + // Delete all permissions that are no longer available. + foreach (user_roles() as $role) { + user_role_revoke_permissions($role->rid, array_diff($role->permissions, $permissions)); + } // Remove any potentially orphan module data stored for users. drupal_container()->get('user.data')->delete($modules); } diff --git a/core/modules/user/user.views.inc b/core/modules/user/user.views.inc index 48b6138..d9a0efa 100644 --- a/core/modules/user/user.views.inc +++ b/core/modules/user/user.views.inc @@ -351,22 +351,6 @@ function user_views_data() { ), ); - // role table - - $data['role']['table']['join'] = array( - // Directly links to users table. - 'users' => array( - 'left_table' => 'users_roles', - 'left_field' => 'rid', - 'field' => 'rid', - ), - // needed for many to one helper sometimes - 'users_roles' => array( - 'left_field' => 'rid', - 'field' => 'rid', - ), - ); - // permission table $data['role_permission']['table']['group'] = t('User'); $data['role_permission']['table']['join'] = array( diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/filter/FilterPluginBase.php b/core/modules/views/lib/Drupal/views/Plugin/views/filter/FilterPluginBase.php index 6b32ca3..9a3a224 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/views/filter/FilterPluginBase.php +++ b/core/modules/views/lib/Drupal/views/Plugin/views/filter/FilterPluginBase.php @@ -548,7 +548,7 @@ public function buildExposeForm(&$form, &$form_state) { '#default_value' => $this->options['expose']['remember'], ); - $role_options = array_map('check_plain', user_roles()); + $role_options = array_map('check_plain', user_role_names()); $form['expose']['remember_roles'] = array( '#type' => 'checkboxes', '#title' => t('User roles'), diff --git a/core/profiles/standard/standard.install b/core/profiles/standard/standard.install index 071bf31..9f722b3 100644 --- a/core/profiles/standard/standard.install +++ b/core/profiles/standard/standard.install @@ -394,11 +394,12 @@ function standard_install() { user_role_grant_permissions(DRUPAL_AUTHENTICATED_RID, array('access content', 'access comments', 'post comments', 'skip comment approval', $filtered_html_permission)); // Create a default role for site administrators, with all available permissions assigned. - $admin_role = new stdClass(); - $admin_role->rid = 'administrator'; - $admin_role->name = 'Administrator'; - $admin_role->weight = 2; - user_role_save($admin_role); + $admin_role = entity_create('user_role', array( + 'rid' => 'administrator', + 'name' => 'Administrator', + 'weight' => 2, + )); + $admin_role->save(); user_role_grant_permissions($admin_role->rid, array_keys(module_invoke_all('permission'))); // Set this as the administrator role. $user_settings->set('admin_role', $admin_role->rid)->save();