diff --git a/core/modules/user/src/RoleStorage.php b/core/modules/user/src/RoleStorage.php index a3f6d0fa95990a8..38781664fce49df 100644 --- a/core/modules/user/src/RoleStorage.php +++ b/core/modules/user/src/RoleStorage.php @@ -29,14 +29,4 @@ class RoleStorage extends ConfigEntityStorage implements RoleStorageInterface { return $has_permission; } - /** - * {@inheritdoc} - */ - public function deleteRoleReferences(array $rids) { - // Remove the role from all users. - db_delete('user__roles') - ->condition('target_id', $rids) - ->execute(); - } - } diff --git a/core/modules/user/src/RoleStorageInterface.php b/core/modules/user/src/RoleStorageInterface.php index 1764de638596a98..7ad3511e21caac5 100644 --- a/core/modules/user/src/RoleStorageInterface.php +++ b/core/modules/user/src/RoleStorageInterface.php @@ -27,12 +27,4 @@ interface RoleStorageInterface extends ConfigEntityStorageInterface { */ public function isPermissionInRoles($permission, array $rids); - /** - * Delete role references. - * - * @param array $rids - * The list of role IDs being deleted. The storage should - * remove permission and user references to this role. - */ - public function deleteRoleReferences(array $rids); } diff --git a/core/modules/user/src/Tests/UserRoleDeleteTest.php b/core/modules/user/src/Tests/UserRoleDeleteTest.php new file mode 100644 index 000000000000000..99750460d4f9673 --- /dev/null +++ b/core/modules/user/src/Tests/UserRoleDeleteTest.php @@ -0,0 +1,78 @@ +installEntitySchema('user'); + } + + /** + * Tests removal of role references on role entity delete. + * + * @see user_user_role_delete() + */ + public function testRoleDeleteUserRoleReferenceDelete() { + // Create two test roles. + $role_storage = $this->container->get('entity.manager')->getStorage('user_role'); + $role_storage->create(array('id' => 'test_role_one'))->save(); + $role_storage->create(array('id' => 'test_role_two'))->save(); + + // Create user and assign both test roles. + $values = array( + 'uid' => 1, + 'roles' => array('test_role_one', 'test_role_two'), + ); + $user = User::create($values); + $user->save(); + + // Check that user has both roles. + $this->assertTrue($user->hasRole('test_role_one')); + $this->assertTrue($user->hasRole('test_role_two')); + + // Delete test role one. + $test_role_one = $role_storage->load('test_role_one'); + $test_role_one->delete(); + + // Load user again from the database. + $user = User::load($user->id()); + + // Check that user does not have role one anymore, still has role two. + $this->assertFalse($user->hasRole('test_role_one')); + $this->assertTrue($user->hasRole('test_role_two')); + + // Create new role with same name. + $role_storage->create(array('id' => 'test_role_one'))->save(); + + // Load user again from the database. + $user = User::load($user->id()); + + // Check that user does not have role one. + $this->assertFalse($user->hasRole('test_role_one')); + $this->assertTrue($user->hasRole('test_role_two')); + + } + +} diff --git a/core/modules/user/src/UserStorage.php b/core/modules/user/src/UserStorage.php index b51b1eec764c467..f404b8d43f4232c 100644 --- a/core/modules/user/src/UserStorage.php +++ b/core/modules/user/src/UserStorage.php @@ -116,4 +116,16 @@ class UserStorage extends SqlContentEntityStorage implements UserStorageInterfac $this->resetCache(array($account->id())); } + /** + * {@inheritdoc} + */ + public function deleteRoleReferences(array $rids) { + // Remove the role from all users. + $this->database->delete('user__roles') + ->condition('roles_target_id', $rids) + ->execute(); + + $this->resetCache(); + } + } diff --git a/core/modules/user/src/UserStorageInterface.php b/core/modules/user/src/UserStorageInterface.php index 104c4aecd03cc72..2614bc34dfa5515 100644 --- a/core/modules/user/src/UserStorageInterface.php +++ b/core/modules/user/src/UserStorageInterface.php @@ -32,4 +32,13 @@ interface UserStorageInterface extends EntityStorageInterface{ */ public function updateLastAccessTimestamp(AccountInterface $account, $timestamp); + /** + * Delete role references. + * + * @param array $rids + * The list of role IDs being deleted. The storage should + * remove permission and user references to this role. + */ + public function deleteRoleReferences(array $rids); + } diff --git a/core/modules/user/user.module b/core/modules/user/user.module index b3fe3222d92738a..7995031993699a3 100644 --- a/core/modules/user/user.module +++ b/core/modules/user/user.module @@ -1079,6 +1079,10 @@ function user_user_role_insert(RoleInterface $role) { * Implements hook_ENTITY_TYPE_delete() for user_role entities. */ function user_user_role_delete(RoleInterface $role) { + // Delete role references for all users. + $user_storage = \Drupal::entityManager()->getStorage('user'); + $user_storage->deleteRoleReferences(array($role->id())); + // Ignore the authenticated and anonymous roles or the role is being synced. if (in_array($role->id(), array(DRUPAL_AUTHENTICATED_RID, DRUPAL_ANONYMOUS_RID)) || $role->isSyncing()) { return;