diff --git a/config/schema/roleassign.schema.yml b/config/schema/roleassign.schema.yml index bdd4f2e56a340d925a32dfa4bb73e09f55b5cab4..3e7e62fb7d00e586db549e68660e7a729d88264b 100644 --- a/config/schema/roleassign.schema.yml +++ b/config/schema/roleassign.schema.yml @@ -8,3 +8,6 @@ roleassign.settings: sequence: type: string label: 'role' + roleassign_negate: + type: boolean + label: 'Negate condition' diff --git a/roleassign.install b/roleassign.install new file mode 100644 index 0000000000000000000000000000000000000000..ce64edf5ab8e293dc5dc7698c61f53c3b8b344b3 --- /dev/null +++ b/roleassign.install @@ -0,0 +1,16 @@ +<?php + +/** + * @file + * Install hooks for roleassign module. + */ + +/** + * Set default config value for roleassign_negate option. + */ +function roleassign_update_100001() { + $config_factory = \Drupal::service('config.factory'); + $config = $config_factory->getEditable('roleassign.settings'); + $config->set('roleassign_negate', FALSE); + $config->save(); +} diff --git a/roleassign.module b/roleassign.module index 5041a0d47a50149bfe8f7b44c1c7566f8f5c97bf..5654382082049a1abeb7ae9a85d4f2be80c88ea0 100755 --- a/roleassign.module +++ b/roleassign.module @@ -239,14 +239,20 @@ function _roleassign_restrict_access() { * that only has "assign roles" permission, not "administer permissions". */ function _roleassign_get_assignable_roles() { - $config = \Drupal::service('config.factory'); - $roleassign_roles = array_flip($config->get('roleassign.settings')->get('roleassign_roles')); + $config_factory = \Drupal::service('config.factory'); + $config = $config_factory->get('roleassign.settings'); + $roleassign_roles = array_flip($config->get('roleassign_roles')); $roles = Role::loadMultiple(); unset($roles[RoleInterface::ANONYMOUS_ID]); // Ignore Authenticated user as this is not required. unset($roles[RoleInterface::AUTHENTICATED_ID]); $roles = array_map(fn(RoleInterface $role) => $role->label(), $roles); - return array_intersect_key($roles, $roleassign_roles); + if ($config->get('roleassign_negate') === TRUE) { + return array_diff_key($roles, $roleassign_roles); + } + else { + return array_intersect_key($roles, $roleassign_roles); + } } /** diff --git a/src/Form/RoleAssignAdminForm.php b/src/Form/RoleAssignAdminForm.php index a71a82d36f22ef754f55d2c0ea595f739234fce6..096770b4e6738c5ba1e2ee523e415f913d53a451 100644 --- a/src/Form/RoleAssignAdminForm.php +++ b/src/Form/RoleAssignAdminForm.php @@ -73,6 +73,13 @@ class RoleAssignAdminForm extends ConfigFormBase { '#options' => $roles, '#description' => $this->t('Select roles that should be available for assignment.'), ]; + // Negate condition. + $form['roleassign_negate'] = [ + '#type' => 'checkbox', + '#title' => $this->t('Negate'), + '#default_value' => $config->get('roleassign_negate'), + '#description' => $this->t('Checking this will negate the above selection, therefore all roles except the selected will be available for assignment.'), + ]; } return parent::buildForm($form, $form_state); @@ -92,6 +99,7 @@ class RoleAssignAdminForm extends ConfigFormBase { $this->config('roleassign.settings') ->set('roleassign_roles', $roleassign_roles) + ->set('roleassign_negate', $form_state->getValue('roleassign_negate')) ->save(); parent::submitForm($form, $form_state); diff --git a/tests/src/Functional/RoleAssignPermissionTest.php b/tests/src/Functional/RoleAssignPermissionTest.php index af89cc04cd61024e6af573aba6a16e0a9690adf2..59205735c4b788a825693e3cd8de081433c93eb0 100644 --- a/tests/src/Functional/RoleAssignPermissionTest.php +++ b/tests/src/Functional/RoleAssignPermissionTest.php @@ -72,6 +72,7 @@ class RoleAssignPermissionTest extends BrowserTestBase { 'editor' => 'editor', 'webmaster' => 'webmaster', ]) + ->set('roleassign_negate', FALSE) ->save(); // Create a testAccount that we will be trying to assign roles. @@ -97,11 +98,15 @@ class RoleAssignPermissionTest extends BrowserTestBase { * Tests that RoleAssign settings are set up correctly. */ public function testRoleAssignSettings() { - $assignable_roles = array_filter(\Drupal::config('roleassign.settings')->get('roleassign_roles')); + $config = \Drupal::config('roleassign.settings'); + $assignable_roles = array_filter($config->get('roleassign_roles')); $this->assertSame([ 'editor' => 'editor', 'webmaster' => 'webmaster', ], $assignable_roles); + $negate = $config->get('roleassign_negate'); + $this->assertIsBool($negate); + $this->assertFalse($negate); } /** @@ -121,6 +126,18 @@ class RoleAssignPermissionTest extends BrowserTestBase { $this->assertSession()->fieldNotExists('edit-roles-siteadmin'); $this->drupalGet('user/' . $this->testAccount->id() . '/edit'); + // Set negate roles option. + $this->config('roleassign.settings')->set('roleassign_negate', TRUE)->save(); + $this->drupalGet('user/' . $this->testAccount->id() . '/edit'); + $this->assertSession()->fieldExists('edit-roles-siteadmin'); + $this->assertSession()->fieldNotExists('edit-roles-editor'); + $this->assertSession()->fieldNotExists('edit-roles-webmaster'); + $this->config('roleassign.settings')->set('roleassign_negate', FALSE)->save(); + $this->drupalGet('user/' . $this->testAccount->id() . '/edit'); + $this->assertSession()->fieldNotExists('edit-roles-siteadmin'); + $this->assertSession()->fieldExists('edit-roles-editor'); + $this->assertSession()->fieldExists('edit-roles-webmaster'); + // Assign the role "editor" to the account. $this->submitForm(["roles[editor]" => "editor"], 'Save'); $this->assertSession()->pageTextContains('The changes have been saved.');