diff --git a/og_ui/og_ui.links.action.yml b/og_ui/og_ui.links.action.yml new file mode 100644 index 000000000..d08588ae0 --- /dev/null +++ b/og_ui/og_ui.links.action.yml @@ -0,0 +1,5 @@ +og_ui.role_add: + route_name: og_ui.role_add_form + title: 'Add role' + appears_on: + - og_ui.roles_overview diff --git a/og_ui/og_ui.links.menu.yml b/og_ui/og_ui.links.menu.yml index e315cbf0b..41b603b64 100644 --- a/og_ui/og_ui.links.menu.yml +++ b/og_ui/og_ui.links.menu.yml @@ -11,3 +11,19 @@ og_ui.settings: parent: og_ui.admin_index description: 'Administer OG settings.' route_name: og_ui.settings + +og_ui.roles_overview: + title: 'OG roles' + parent: og_ui.admin_index + description: 'Administer OG roles.' + route_name: og_ui.roles_permissions_overview + route_parameters: + type: 'roles' + +og_ui.permissions_overview: + title: 'OG permissions' + parent: og_ui.admin_index + description: 'Administer OG permissions.' + route_name: og_ui.roles_permissions_overview + route_parameters: + type: 'permissions' diff --git a/og_ui/og_ui.routing.yml b/og_ui/og_ui.routing.yml index 04c448b52..b428d1b9d 100644 --- a/og_ui/og_ui.routing.yml +++ b/og_ui/og_ui.routing.yml @@ -25,18 +25,56 @@ og_ui.roles_permissions_overview: _permission: 'administer group' type: '^(roles|permissions)$' -og_ui.roles_form: +og_ui.roles_overview: path: 'admin/config/group/roles/{entity_type}/{bundle}' defaults: - _form: '\Drupal\og_ui\Form\OgRolesForm' - _title: '@todo - create title callback' + _controller: '\Drupal\og_ui\Controller\OgUiController::rolesOverviewPage' + _title_callback: '\Drupal\og_ui\Controller\OgUiController::rolesOverviewPageTitleCallback' + requirements: + _permission: 'administer group' + +og_ui.role_add_form: + path: 'admin/config/group/role/{entity_type}/{bundle}/add' + defaults: + _controller: '\Drupal\og_ui\Controller\OgRoleController::addGroupTypeRole' + _title_callback: '\Drupal\og_ui\Form\OgRoleForm::addRoleTitleCallback' + requirements: + # Todo: This should become a dedicated permission: + # _entity_access: og_role.add + _permission: 'administer group' + +og_ui.group_role_add_form: + path: 'admin/config/group/role/{entity_type}/{entity}/add' + defaults: + _controller: '\Drupal\og_ui\Controller\OgRoleController::addGroupRole' + _title_callback: '\Drupal\og_ui\Form\OgRoleForm::addRoleTitleCallback' requirements: + # Todo: This should become a dedicated permission: + # _entity_access: og_role.add _permission: 'administer group' -og_ui.permissions_form: +entity.og_role.edit_form: + path: 'admin/config/group/role/{og_role}/edit' + defaults: + _entity_form: og_role.default + _title_callback: '\Drupal\og_ui\Form\OgRoleForm::editRoleTitleCallback' + requirements: + # Todo: This should become a dedicated permission: + # _entity_access: og_role.update + _permission: 'administer group' + +og_ui.permissions_overview: path: 'admin/config/group/permissions/{entity_type}/{bundle}' defaults: _form: '\Drupal\og_ui\Form\OgPermissionsForm' _title: '@todo - create title callback' requirements: _permission: 'administer group' + +og_ui.permissions_edit_form: + path: 'admin/config/group/permission/{og_role}/edit' + defaults: + _form: '\Drupal\og_ui\Form\OgPermissionsEditForm' + _title_callback: '\Drupal\og_ui\Form\OgPermissionsEditForm::titleCallback' + requirements: + _permission: 'administer group' diff --git a/og_ui/src/Controller/OgRoleController.php b/og_ui/src/Controller/OgRoleController.php new file mode 100644 index 000000000..7c67f07e6 --- /dev/null +++ b/og_ui/src/Controller/OgRoleController.php @@ -0,0 +1,45 @@ +t('Create New Role'); + + // Show the actual reply box. + $og_role = $this->entityManager()->getStorage('og_role')->create(array( + 'group_type' => $entity_type, + 'group_bundle' => $bundle, + )); + $build['og_role_form'] = $this->entityFormBuilder()->getForm($og_role); + + return $build; + } + + public function addGroupRole(Entity $entity) { + + } + +} \ No newline at end of file diff --git a/og_ui/src/Controller/OgUiController.php b/og_ui/src/Controller/OgUiController.php index 42a0fc084..ceecc4609 100644 --- a/og_ui/src/Controller/OgUiController.php +++ b/og_ui/src/Controller/OgUiController.php @@ -6,8 +6,12 @@ use Drupal\Core\Entity\EntityTypeBundleInfoInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Link; +use Drupal\og\GroupManager; +use Drupal\og\Og; use Drupal\og\GroupTypeManager; use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * The OG UI controller. @@ -86,7 +90,7 @@ public function rolesPermissionsOverviewPage($type) { 'data' => $definition->getLabel() . ' - ' . $bundle_info[$bundle]['label'], ], [ - 'data' => Link::createFromRoute($action, 'og_ui.' . $type . '_form', [ + 'data' => Link::createFromRoute($action, 'og_ui.' . $type . '_overview', [ 'entity_type' => $entity_type, 'bundle' => $bundle, ]), @@ -106,7 +110,7 @@ public function rolesPermissionsOverviewPage($type) { } /** - * Title callback for rolesPermissionsOverviewPage. + * Title callback for rolesPermissionsOverviewPage(). * * @param string $type * The type of overview, either 'roles' or 'permissions'. @@ -118,4 +122,82 @@ public function rolesPermissionsOverviewTitleCallback($type) { return $this->t('OG @type overview', ['@type' => $type]); } + /** + * Returns the OG role overview page for a given entity type and bundle. + * + * @param string $entity_type + * The entity type for which to show the OG roles. + * @param string $bundle + * The bundle for which to show the OG roles. + * + * @return array + * The overview as a render array. + */ + public function rolesOverviewPage($entity_type = '', $bundle = '') { + // Return a 404 error when this is not a group. + if (!Og::isGroup($entity_type, $bundle)) { + throw new NotFoundHttpException(); + } + + $rows = []; + + $properties = [ + 'group_type' => $entity_type, + 'group_bundle' => $bundle, + ]; + /** @var \Drupal\og\Entity\OgRole $role */ + foreach ($this->entityTypeManager->getStorage('og_role')->loadByProperties($properties) as $role) { + // Add the role name cell. + $columns = [['data' => $role->getLabel()]]; + + // Add the edit role link if the role is editable. + if (!$role->isLocked()) { + $columns[] = [ + 'data' => Link::createFromRoute($this->t('Edit role'), 'entity.og_role.edit_form', [ + 'og_role' => $role->id(), + ]), + ]; + } + else { + $columns[] = ['data' => $this->t('Locked')]; + } + + // Add the edit permissions link. + $columns[] = [ + 'data' => Link::createFromRoute($this->t('Edit permissions'), 'og_ui.permissions_edit_form', [ + 'og_role' => $role->id(), + ]), + ]; + + $rows[] = $columns; + } + + return [ + '#theme' => 'table', + '#header' => [ + $this->t('Role name'), + ['data' => $this->t('Operations'), 'colspan' => 2], + ], + '#rows' => $rows, + '#empty' => $this->t('No roles available.'), + ]; + } + + /** + * Title callback for the roles overview page. + * + * @param string $entity_type + * The group entity type. + * @param string $bundle + * The group bundle. + * + * @return \Drupal\Core\StringTranslation\TranslatableMarkup + */ + public function rolesOverviewPageTitleCallback($entity_type, $bundle) { + return $this->t('OG @type - @bundle roles', [ + '@type' => $this->entityTypeManager->getDefinition($entity_type)->getLabel(), + '@bundle' => $this->entityTypeBundleInfo->getBundleInfo($entity_type)[$bundle]['label'], + ]); + } + } diff --git a/og_ui/src/Form/OgRoleForm.php b/og_ui/src/Form/OgRoleForm.php new file mode 100644 index 000000000..eab8b1465 --- /dev/null +++ b/og_ui/src/Form/OgRoleForm.php @@ -0,0 +1,111 @@ +entity; + $form['label'] = [ + '#type' => 'textfield', + '#title' => $this->t('Role name'), + '#default_value' => $entity->label(), + '#size' => 30, + '#required' => TRUE, + '#maxlength' => 64, + '#description' => $this->t('The name for this role. Example: "Moderator", "Editorial board", "Site architect".'), + ]; + $form['name'] = array( + '#type' => 'machine_name', + '#default_value' => $entity->id(), + '#required' => TRUE, + '#disabled' => !$entity->isNew(), + '#size' => 30, + '#maxlength' => 64, + '#machine_name' => array( + 'exists' => ['\Drupal\og_uid\Entity\OgRole', 'load'], + ), + ); + $form['weight'] = array( + '#type' => 'value', + '#value' => $entity->getWeight(), + ); + + return parent::form($form, $form_state, $entity); + } + + /** + * {@inheritdoc} + */ + public function save(array $form, FormStateInterface $form_state) { + $entity = $this->entity; + + // Prevent leading and trailing spaces in role names. + $entity->set('label', trim($entity->label())); + $entity->set('name', trim($entity->get('name'))); + $status = $entity->save(); + + $edit_link = $this->entity->link($this->t('Edit')); + if ($status == SAVED_UPDATED) { + drupal_set_message($this->t('OG role %label has been updated.', ['%label' => $entity->label()])); + $this->logger('user')->notice('OG role %label has been updated.', ['%label' => $entity->label(), 'link' => $edit_link]); + } + else { + drupal_set_message($this->t('OG role %label has been added.', ['%label' => $entity->label()])); + $this->logger('user')->notice('OG role %label has been added.', ['%label' => $entity->label(), 'link' => $edit_link]); + } + $form_state->setRedirect('og_ui.roles_overview', [ + 'entity_type' => $entity->getGroupType(), + 'bundle' => $entity->getGroupBundle(), + ]); + } + + /** + * Title callback for the edit form for an OG role. + * + * @param \Drupal\og\Entity\OgRole $og_role + * The OG role being edited. + * + * @return \Drupal\Core\StringTranslation\TranslatableMarkup + * An object that, when cast to a string, returns the translated title + * callback. + */ + public function editRoleTitleCallback(OgRole $og_role) { + return $this->t('Edit OG role %label', [ + '%label' => $og_role->getLabel(), + ]); + } + + /** + * @param string $bundle + * Entity type bundle. + * + * @return \Drupal\Core\StringTranslation\TranslatableMarkup + * An object that, when cast to a string, returns the translated title + * callback. + */ + public function addRoleTitleCallback($bundle) { + return $this->t('Create %bundle OG role', [ + '%bundle' => $bundle, + ]); + } + +} diff --git a/src/Entity/OgRole.php b/src/Entity/OgRole.php index 3884db523..84ba3d270 100644 --- a/src/Entity/OgRole.php +++ b/src/Entity/OgRole.php @@ -16,12 +16,24 @@ * @ConfigEntityType( * id = "og_role", * label = @Translation("OG role"), + * handlers = { + * "form" = { + * "default" = "Drupal\og_ui\Form\OgRoleForm", + * "delete" = "Drupal\Core\Entity\EntityDeleteForm" + * } + * }, * static_cache = TRUE, * entity_keys = { * "id" = "id", * "label" = "label", * "weight" = "weight" * }, + * links = { + * "delete-form" = "/admin/config/group/role/{og_role}/delete", + * "edit-form" = "/admin/config/group/role/{og_role}/edit", + * "edit-permissions-form" = "/admin/config/group/permission/{og_role}/edit", + * "collection" = "/admin/config/group/roles", + * }, * config_export = { * "id", * "label", @@ -192,6 +204,13 @@ public function setRoleType($role_type) { return $this->set('role_type', $role_type); } + /** + * {@inheritdoc} + */ + public function isLocked() { + return $this->get('role_type') !== OgRoleInterface::ROLE_TYPE_STANDARD; + } + /** * {@inheritdoc} */ diff --git a/src/OgRoleInterface.php b/src/OgRoleInterface.php index f34f07e24..6fed2741e 100644 --- a/src/OgRoleInterface.php +++ b/src/OgRoleInterface.php @@ -49,6 +49,17 @@ interface OgRoleInterface { */ public function setId($id); + /** + * Returns whether or not a role can be changed. + * + * This will return FALSE for all roles except the default roles 'non-member' + * and 'member'. + * + * @return bool + * Whether or not the role is locked. + */ + public function isLocked(); + /** * Returns the role name. *