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 index 662d365..b443a48 100644 --- a/core/modules/user/lib/Drupal/user/Plugin/Core/Entity/Role.php +++ b/core/modules/user/lib/Drupal/user/Plugin/Core/Entity/Role.php @@ -20,6 +20,10 @@ * module = "user", * controllers = { * "storage" = "Drupal\user\RoleStorageController" + * "list" = "Drupal\user\RoleListController", + * "form" = { + * "default" = "Drupal\user\RoleFormController" + * } * }, * config_prefix = "user.role", * entity_keys = { @@ -59,4 +63,17 @@ class Role extends ConfigEntityBase { */ public $weight; + /** + * {@inheritdoc} + */ + public function uri() { + return array( + 'path' => 'admin/people/roles/manage/' . $this->id(), + 'options' => array( + 'entity_type' => $this->entityType, + 'entity' => $this, + ), + ); + } + } diff --git a/core/modules/user/lib/Drupal/user/RoleFormController.php b/core/modules/user/lib/Drupal/user/RoleFormController.php new file mode 100644 index 0000000..1ee9b83 --- /dev/null +++ b/core/modules/user/lib/Drupal/user/RoleFormController.php @@ -0,0 +1,89 @@ + 'textfield', + '#title' => t('Role name'), + '#default_value' => $entity->label(), + '#size' => 30, + '#required' => TRUE, + '#maxlength' => 64, + '#description' => t('The name for this role. Example: "Moderator", "Editorial board", "Site architect".'), + ); + $form['id'] = array( + '#type' => 'machine_name', + '#default_value' => $entity->id(), + '#required' => TRUE, + '#disabled' => !$entity->isNew(), + '#size' => 30, + '#maxlength' => 64, + '#machine_name' => array( + 'exists' => 'user_role_load', + ), + ); + $form['weight'] = array( + '#type' => 'value', + '#value' => $entity->get('weight'), + ); + + return parent::form($form, $form_state, $entity); + } + + /** + * {@inheritdoc} + */ + protected function actions(array $form, array &$form_state) { + $entity = $this->getEntity($form_state); + $actions = parent::actions($form, $form_state); + // Disable delete of new and built-in roles. + $actions['delete']['#access'] = !$entity->isNew() && !in_array($entity->id(), array(DRUPAL_ANONYMOUS_RID, DRUPAL_AUTHENTICATED_RID)); + return $actions; + } + + /** + * {@inheritdoc} + */ + public function save(array $form, array &$form_state) { + $entity = $this->getEntity($form_state); + + // Prevent leading and trailing spaces in role names. + $entity->set('label', trim($entity->label())); + $uri = $entity->uri(); + if ($entity->save() == SAVED_UPDATED) { + drupal_set_message(t('Role %label has been updated.', array('%label' => $entity->label()))); + watchdog('user', 'Role %label has been updated.', array('%label' => $entity->label()), WATCHDOG_NOTICE, l(t('Edit'), $uri['path'])); + } + else { + drupal_set_message(t('Role %label has been added.', array('%label' => $entity->label()))); + watchdog('user', 'Role %label has been added.', array('%label' => $entity->label()), WATCHDOG_NOTICE, l(t('Edit'), $uri['path'])); + } + $form_state['redirect'] = 'admin/people/roles'; + } + + /** + * {@inheritdoc} + */ + public function delete(array $form, array &$form_state) { + $entity = $this->getEntity($form_state); + $form_state['redirect'] = 'admin/people/roles/manage/' . $entity->id() . '/delete'; + } + +} diff --git a/core/modules/user/lib/Drupal/user/RoleListController.php b/core/modules/user/lib/Drupal/user/RoleListController.php new file mode 100644 index 0000000..177b2d6 --- /dev/null +++ b/core/modules/user/lib/Drupal/user/RoleListController.php @@ -0,0 +1,139 @@ + t('Edit permissions'), + 'href' => 'admin/people/permissions/' . $entity->id(), + 'weight' => 20, + ); + // Built-in roles could not be deleted or disabled. + if (in_array($entity->id(), array(DRUPAL_ANONYMOUS_RID, DRUPAL_AUTHENTICATED_RID))) { + unset($operations['delete']); + unset($operations['disable']); + } + return $operations; + } + + /** + * {@inheritdoc} + */ + public function buildRow(EntityInterface $entity) { + $row = parent::buildRow($entity); + + // Override default values to markup elements. + $row['#attributes']['class'][] = 'draggable'; + unset($row['id']); + + $row['label'] = array( + '#markup' => check_plain($row['label']), + ); + $row['#weight'] = $entity->get('weight'); + // Add weight column. + $row['weight'] = array( + '#type' => 'weight', + '#title' => t('Weight for @title', array('@title' => $entity->label())), + '#title_display' => 'invisible', + '#default_value' => $entity->get('weight'), + '#attributes' => array('class' => array('weight')), + ); + return $row; + } + + /** + * {@inheritdoc} + */ + public function render() { + return drupal_get_form($this); + } + + /** + * {@inheritdoc} + */ + public function buildForm(array $form, array &$form_state) { + $form['entities'] = array( + '#type' => 'table', + '#header' => $this->buildHeader(), + '#empty' => t('There is no @label yet.', array('@label' => $this->entityInfo['label'])), + '#tabledrag' => array( + array('order', 'sibling', 'weight'), + ), + ); + + foreach ($this->load() as $entity) { + $form['entities'][$entity->id()] = $this->buildRow($entity); + } + + $form['actions']['#type'] = 'actions'; + $form['actions']['submit'] = array( + '#type' => 'submit', + '#value' => t('Save order'), + '#button_type' => 'primary', + ); + + return $form; + } + + /** + * {@inheritdoc} + */ + public function validateForm(array &$form, array &$form_state) { + // No validation. + } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, array &$form_state) { + $values = $form_state['values']['entities']; + + $entities = entity_load_multiple($this->entityType, array_keys($values)); + foreach ($values as $id => $value) { + if (isset($entities[$id]) && $value['weight'] != $entities[$id]->get('weight')) { + // Update changed weight. + $entities[$id]->set('weight', $value['weight']); + $entities[$id]->save(); + } + } + + drupal_set_message(t('The role settings have been updated.')); + } +} diff --git a/core/modules/user/lib/Drupal/user/RoleStorageController.php b/core/modules/user/lib/Drupal/user/RoleStorageController.php index f5f6575..680b412 100644 --- a/core/modules/user/lib/Drupal/user/RoleStorageController.php +++ b/core/modules/user/lib/Drupal/user/RoleStorageController.php @@ -2,7 +2,7 @@ /** * @file - * Contains Drupal\user\RoleStorageController. + * Contains \Drupal\user\RoleStorageController. */ namespace Drupal\user; @@ -16,7 +16,7 @@ class RoleStorageController extends ConfigStorageController { /** - * Overrides ConfigStorageController::preSave(). + * {@inheritdoc} */ public function preSave(EntityInterface $entity) { if (!isset($entity->weight) && $roles = entity_load_multiple('user_role')) { @@ -30,7 +30,7 @@ public function preSave(EntityInterface $entity) { } /** - * Overrides ConfigStorageController::resetCache(). + * {@inheritdoc} */ public function resetCache(array $ids = NULL) { parent::resetCache($ids); @@ -41,7 +41,7 @@ public function resetCache(array $ids = NULL) { } /** - * Overrides ConfigStorageController::postDelete(). + * {@inheritdoc} */ protected function postDelete($entities) { $rids = array_keys($entities); @@ -57,7 +57,7 @@ protected function postDelete($entities) { } /** - * Overrides ConfigStorageController::attachLoad(). + * {@inheritdoc} */ protected function attachLoad(&$queried_entities, $revision_id = FALSE) { // Sort the queried roles by their weight. diff --git a/core/modules/user/lib/Drupal/user/Tests/UserRoleAdminTest.php b/core/modules/user/lib/Drupal/user/Tests/UserRoleAdminTest.php index 0025873..43b9827 100644 --- a/core/modules/user/lib/Drupal/user/Tests/UserRoleAdminTest.php +++ b/core/modules/user/lib/Drupal/user/Tests/UserRoleAdminTest.php @@ -38,9 +38,9 @@ function testRoleAdministration() { // correspond to an integer, to test that the role administration pages // correctly distinguish between role names and IDs.) $role_name = '123'; - $edit = array('role[label]' => $role_name, 'role[id]' => $role_name); - $this->drupalPost('admin/people/roles', $edit, t('Add role')); - $this->assertText(t('The role has been added.'), 'The role has been added.'); + $edit = array('label' => $role_name, 'id' => $role_name); + $this->drupalPost('admin/people/roles/add', $edit, t('Save')); + $this->assertRaw(t('Role %label has been added.', array('%label' => 123))); $role = entity_load('user_role', $role_name); $this->assertTrue(is_object($role), 'The role was successfully retrieved from the database.'); @@ -48,31 +48,31 @@ function testRoleAdministration() { $this->assertEqual($role->langcode, $default_langcode); // Try adding a duplicate role. - $this->drupalPost(NULL, $edit, t('Add role')); + $this->drupalPost('admin/people/roles/add', $edit, t('Save')); $this->assertRaw(t('The machine-readable name is already in use. It must be unique.'), 'Duplicate role warning displayed.'); // Test renaming a role. $old_name = $role_name; $role_name = '456'; - $edit = array('role[label]' => $role_name); - $this->drupalPost("admin/people/roles/edit/{$role->id()}", $edit, t('Save role')); - $this->assertText(t('The role has been renamed.'), 'The role has been renamed.'); + $edit = array('label' => $role_name); + $this->drupalPost("admin/people/roles/manage/{$role->id()}", $edit, t('Save')); + $this->assertRaw(t('Role %label has been updated.', array('%label' => $role_name))); $new_role = entity_load('user_role', $old_name); $this->assertEqual($new_role->label(), $role_name, 'The role name has been successfully changed.'); // Test deleting a role. - $this->drupalPost("admin/people/roles/edit/{$role->id()}", NULL, t('Delete role')); - $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->id()}", 'Role edit link removed.'); + $this->drupalPost("admin/people/roles/manage/{$role->id()}", array(), t('Delete')); + $this->drupalPost(NULL, array(), t('Delete')); + $this->assertRaw(t('Role %label has been deleted.', array('%label' => $role_name))); + $this->assertNoLinkByHref("admin/people/roles/manage/{$role->id()}", 'Role edit link removed.'); $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. - $this->drupalGet('admin/people/roles/edit/' . DRUPAL_ANONYMOUS_RID); + $this->drupalGet('admin/people/roles/manage/' . DRUPAL_ANONYMOUS_RID); $this->assertResponse(200, 'Access granted when trying to edit the built-in anonymous role.'); $this->assertNoText(t('Delete role'), 'Delete button for the anonymous role is not present.'); - $this->drupalGet('admin/people/roles/edit/' . DRUPAL_AUTHENTICATED_RID); + $this->drupalGet('admin/people/roles/manage/' . DRUPAL_AUTHENTICATED_RID); $this->assertResponse(200, 'Access granted when trying to edit the built-in authenticated role.'); $this->assertNoText(t('Delete role'), 'Delete button for the authenticated role is not present.'); } @@ -90,7 +90,7 @@ function testRoleWeightOrdering() { // Change the role weights to make the roles in reverse order. $edit = array(); foreach ($roles as $role) { - $edit['roles['. $role->id() .'][weight]'] = $weight; + $edit['entities['. $role->id() .'][weight]'] = $weight; $new_role_weights[$role->id()] = $weight; $saved_rids[] = $role->id; $weight--; diff --git a/core/modules/user/user.admin.inc b/core/modules/user/user.admin.inc index 768bb96..2f92e82 100644 --- a/core/modules/user/user.admin.inc +++ b/core/modules/user/user.admin.inc @@ -459,213 +459,31 @@ function theme_user_permission_description($variables) { } /** - * Form to re-order roles or add a new one. + * Page callback: Lists roles and allows to reorder them. * - * @ingroup forms - * @see theme_user_admin_roles() - */ -function user_admin_roles($form, $form_state) { - $roles = user_roles(); - - $form['roles'] = array( - '#tree' => TRUE, - ); - - foreach ($roles as $rid => $role) { - $form['roles'][$rid]['#role'] = $role; - $form['roles'][$rid]['#weight'] = $role->weight; - $form['roles'][$rid]['name'] = array( - '#markup' => check_plain($role->label()), - ); - $form['roles'][$rid]['weight'] = array( - '#type' => 'textfield', - '#title' => t('Weight for @title', array('@title' => $role->label())), - '#title_display' => 'invisible', - '#size' => 4, - '#default_value' => $role->weight, - '#attributes' => array('class' => array('role-weight')), - ); - $links['edit'] = array( - 'title' => t('Edit role'), - 'href' => 'admin/people/roles/edit/' . $rid, - 'weight' => 0, - ); - $links['permissions'] = array( - 'title' => t('Edit permissions'), - 'href' => 'admin/people/permissions/' . $rid, - 'weight' => 5, - ); - $form['roles'][$rid]['operations'] = array( - '#type' => 'operations', - '#links' => $links, - ); - } - - // Embed the role add form. - $add_role = entity_create('user_role', array( - 'id' => NULL, - 'label' => NULL, - )); - $add_form = user_admin_role(array(), $form_state, $add_role); - $add_form['actions']['submit']['#submit'] = array('user_admin_role_submit'); - $add_form['role']['actions'] = $add_form['actions']; - unset($add_form['actions']); - $form += $add_form; - - $form['actions']['#type'] = 'actions'; - $form['actions']['submit'] = array( - '#type' => 'submit', - '#value' => t('Save order'), - // Do not validate the add form when saving the order. - '#limit_validation_errors' => array(array('roles')), - '#submit' => array('user_admin_roles_order_submit'), - ); - - return $form; -} - -/** - * Form submit function. Update the role weights. + * @see user_menu() */ -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']; - $role->save(); - } - drupal_set_message(t('The role settings have been updated.')); +function user_admin_roles_list() { + return Drupal::service('plugin.manager.entity') + ->getListController('user_role')->render(); } /** - * Returns HTML for the role order and new role form. - * - * @param $variables - * An associative array containing: - * - form: A render element representing the form. + * Page callback: Presents the role creation form. * - * @ingroup themeable + * @see user_menu() */ -function theme_user_admin_roles($variables) { - $form = $variables['form']; - - $header = array(t('Name'), t('Weight'), t('Operations')); - foreach (element_children($form['roles']) as $rid) { - $row = array(); - foreach (element_children($form['roles'][$rid]) as $column) { - $row[] = drupal_render($form['roles'][$rid][$column]); - } - $rows[] = array('data' => $row, 'class' => array('draggable')); - } - - // Distribute the role add form into table columns. - $form['role']['name']['#title_display'] = 'invisible'; - unset($form['role']['name']['#description']); - unset($form['role']['rid']['#description']); - - $actions = $form['role']['actions']; - unset($form['role']['actions']); - unset($form['role']['weight']); - $row = array(); - $row[] = drupal_render($form['role']); - // Empty placeholder for the weight column. - $row[] = ''; - $row[] = array('data' => drupal_render($actions), 'colspan' => 2); - $rows[] = array('data' => $row); - - drupal_add_tabledrag('user-roles', 'order', 'sibling', 'role-weight'); - - $output = theme('table', array('header' => $header, 'rows' => $rows, 'attributes' => array('id' => 'user-roles'))); - $output .= drupal_render_children($form); - - return $output; -} - -/** - * Form to configure a single role. - * - * @ingroup forms - * @see user_admin_role_submit() - * - * @todo Move into a RoleFormController. - */ -function user_admin_role($form, $form_state, $role) { - $form['role'] = array( - '#tree' => TRUE, - '#parents' => array('role'), - ); - $form['role']['label'] = array( - '#type' => 'textfield', - '#title' => t('Role name'), - '#default_value' => $role->label(), - '#size' => 30, - '#required' => TRUE, - '#maxlength' => 64, - '#description' => t('The name for this role. Example: "Moderator", "Editorial board", "Site architect".'), - ); - $form['role']['id'] = array( - '#type' => 'machine_name', - '#default_value' => $role->id(), - '#required' => TRUE, - '#disabled' => !$role->isNew(), - '#size' => 30, - '#maxlength' => 64, - '#machine_name' => array( - 'exists' => 'user_role_load', - 'source' => array('role', 'label'), - ), - ); - // @todo Remove once moved to RoleFormController. - $form['role']['langcode'] = array( - '#type' => 'value', - '#value' => !$role->isNew() ? $role->langcode : language_default()->langcode, - ); - $form['role']['weight'] = array( - '#type' => 'value', - '#value' => $role->weight, - ); - $form['actions'] = array('#type' => 'actions'); - $form['actions']['submit'] = array( - '#type' => 'submit', - '#value' => !$role->isNew() ? t('Save role') : t('Add role'), - ); - $form['actions']['delete'] = array( - '#type' => 'submit', - '#value' => t('Delete role'), - '#access' => !$role->isNew() && !in_array($role->id(), array(DRUPAL_ANONYMOUS_RID, DRUPAL_AUTHENTICATED_RID)), - '#submit' => array('user_admin_role_delete_submit'), - ); - - return $form; -} - -/** - * Form submit handler for the user_admin_role() form. - */ -function user_admin_role_submit($form, &$form_state) { - // Prevent leading and trailing spaces in role names. - $form_state['values']['role']['label'] = trim($form_state['values']['role']['label']); - - $role = entity_create('user_role', $form_state['values']['role']); - if ($role->save() == SAVED_UPDATED) { - drupal_set_message(t('The role has been renamed.')); - } - else { - drupal_set_message(t('The role has been added.')); - } - $form_state['redirect'] = 'admin/people/roles'; -} - -/** - * Form submit handler for the user_admin_role() form. - */ -function user_admin_role_delete_submit($form, &$form_state) { - $form_state['redirect'] = 'admin/people/roles/delete/' . $form_state['values']['role']['id']; +function user_admin_role_add() { + drupal_set_title(t('Add role')); + $role = entity_create('user_role', array()); + return entity_get_form($role); } /** * Form to confirm role delete operation. */ function user_admin_role_delete_confirm($form, &$form_state, $role) { + $form_state['user_role'] = $role; $form['id'] = array( '#type' => 'value', '#value' => $role->id(), @@ -677,7 +495,11 @@ function user_admin_role_delete_confirm($form, &$form_state, $role) { * Form submit handler for user_admin_role_delete_confirm(). */ function user_admin_role_delete_confirm_submit($form, &$form_state) { - entity_delete_multiple('user_role', array($form_state['values']['id'])); - drupal_set_message(t('The role has been deleted.')); + $role = $form_state['user_role']; + $role->delete(); + + drupal_set_message(t('Role %label has been deleted.', array('%label' => $role->label()))); + watchdog('user', 'Role %label has been deleted.', array('%label' => $role->label()), WATCHDOG_NOTICE); + $form_state['redirect'] = 'admin/people/roles'; } diff --git a/core/modules/user/user.module b/core/modules/user/user.module index 710e56d..9847ee6 100644 --- a/core/modules/user/user.module +++ b/core/modules/user/user.module @@ -99,10 +99,6 @@ function user_theme() { 'render element' => 'form', 'file' => 'user.admin.inc', ), - 'user_admin_roles' => array( - 'render element' => 'form', - 'file' => 'user.admin.inc', - ), 'user_permission_description' => array( 'variables' => array('permission_item' => NULL, 'hide' => NULL), 'file' => 'user.admin.inc', @@ -967,23 +963,37 @@ function user_menu() { $items['admin/people/roles'] = array( 'title' => 'Roles', 'description' => 'List, edit, or add user roles.', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('user_admin_roles'), + 'page callback' => 'user_admin_roles_list', 'access arguments' => array('administer permissions'), 'file' => 'user.admin.inc', 'type' => MENU_LOCAL_TASK, ); - $items['admin/people/roles/edit/%user_role'] = array( + $items['admin/people/roles/add'] = array( + 'title' => 'Add role', + 'page callback' => 'user_admin_role_add', + 'access arguments' => array('administer permissions'), + 'type' => MENU_LOCAL_ACTION, + 'file' => 'user.admin.inc', + ); + + $items['admin/people/roles/manage/%user_role'] = array( 'title' => 'Edit role', - 'page arguments' => array('user_admin_role', 4), + 'page callback' => 'entity_get_form', + 'page arguments' => array(4), 'access arguments' => array('administer permissions'), ); - $items['admin/people/roles/delete/%user_role'] = array( + $items['admin/people/roles/manage/%user_role/edit'] = array( + 'title' => 'Edit', + 'type' => MENU_DEFAULT_LOCAL_TASK, + ); + $items['admin/people/roles/manage/%user_role/delete'] = array( 'title' => 'Delete role', 'page callback' => 'drupal_get_form', 'page arguments' => array('user_admin_role_delete_confirm', 4), 'access callback' => 'user_role_delete_access', 'access arguments' => array(4), + 'weight' => 10, + 'context' => MENU_CONTEXT_INLINE, 'file' => 'user.admin.inc', );