navigation_extra-1.0.x-dev/src/Plugin/Navigation/Extra/UsersPlugin.php
src/Plugin/Navigation/Extra/UsersPlugin.php
<?php
namespace Drupal\navigation_extra\Plugin\Navigation\Extra;
use Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException;
use Drupal\Component\Plugin\Exception\PluginNotFoundException;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\navigation_extra\NavigationExtraPluginBase;
use Drupal\police_core\Police;
use Drupal\user\RoleInterface;
/**
* An NavigationExtraPlugin for content navigation links.
*
* @NavigationExtraPlugin(
* id = "users",
* name = @Translation("Users"),
* description = @Translation("Provides navigation links for users (people)."),
* weight = 0,
* entity_type = "user",
* dependencies = {
* "user"
* }
* )
*/
class UsersPlugin extends NavigationExtraPluginBase {
/**
* {@inheritdoc}
*/
public function buildConfigForm(array &$form, FormStateInterface $form_state): array {
$elements = parent::buildConfigForm($form, $form_state);
$elements += $this->buildConfigFormRoleItems($form, $form_state);
$elements['people'] = [
'#type' => 'radios',
'#title' => $this->t('People item'),
'#description' => $this->t('Set how the people link should be displayed.'),
'#default_value' => $this->config->get("plugins.users.people") ?? '',
'#options' => [
'' => $this->t('Default'),
'hide' => $this->t('Hide'),
'content' => $this->t('Show in content'),
],
];
$elements['add_new_user'] = [
'#type' => 'radios',
'#title' => $this->t('Add new user item'),
'#description' => $this->t('Set how the add new user link should be displayed.'),
'#default_value' => $this->config->get("plugins.users.add_new_user") ?? '',
'#options' => [
'' => $this->t('Default'),
'hide' => $this->t('Hide'),
'entity.user.collection' => $this->t('Show in people item'),
],
];
return $elements;
}
/**
* Add config fields to a plugin config form when it is using recent items.
*
* @param array $form
* The complete config form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The form state.
*
* @return array
* An array of elements for configuring the recent items.
*/
protected function buildConfigFormRoleItems(array &$form, FormStateInterface $form_state): array {
$elements = [];
$elements['roles'] = [
'#type' => 'checkbox',
'#title' => $this->t('Show role items'),
'#description' => $this->t('Show a menu item for each (selected) role.'),
'#default_value' => $this->config->get('plugins.users.roles') ?? 0,
];
$roles = $this->getRoles();
$elements['roles_to_hide'] = [
'#type' => 'checkboxes',
'#title' => $this->t('Roles to hide'),
'#description' => $this->t('Select which roles should not be displayed.'),
'#description_display' => 'before',
'#default_value' => $this->config->get('plugins.users.roles_to_hide') ?? [],
'#options' => $roles,
'#states' => [
'visible' => [
':input[name="users[roles]"]' => ['checked' => TRUE],
],
],
];
return $elements;
}
/**
* {@inheritdoc}
*/
public function alterDiscoveredMenuLinks(array &$links): void {
$add_new_user_link = $this->config->get("plugins.users.add_new_user") ?? '';
if ($add_new_user_link === 'hide') {
$this->removeLink('user.admin_create', $links);
}
$show_roles = $this->config->get("plugins.users.roles") ?? FALSE;
if ($show_roles) {
$roles_to_hide = $this->config->get("plugins.users.roles_to_hide") ?? [];
$roles = $this->getRoles();
$delta = 0;
foreach ($roles as $rid => $label) {
if (!empty($roles_to_hide) && in_array($rid, $roles_to_hide)) {
continue;
}
// Move the item to the people menu.
$this->addLink('navigation.users.role.' . $rid, [
'title' => $label,
'weight' => $delta++,
'route_name' => 'entity.user.collection',
'description' => $this->t('Show %role users', ['%role' => strtolower($label)]),
'parent' => 'entity.user.collection',
'options' => [
'query' => [
'role' => $rid,
],
'attributes' => [
'class' => [
'navigation-extra--users--role--' . $rid,
],
],
],
] + ($links['entity.user.collection'] ?? []), $links);
}
}
}
/**
* {@inheritdoc}
*/
public function postAlterDiscoveredMenuLinks(array &$links): void {
$people_link = $this->config->get("plugins.users.people") ?? '';
if ($people_link === 'hide') {
$this->removeLink('entity.user.collection', $links);
}
elseif ($people_link === 'content') {
// Move the item to content menu.
$this->addLink('entity.user.collection', [
'menu_name' => 'content',
'parent' => NULL,
'weight' => $this->config->get("plugins.users.weight") ?? 0,
'options' => [
'attributes' => [
'class' => [
'navigation-extra--users',
],
],
],
] + ($links['entity.user.collection'] ?? []), $links);
}
$add_new_user_link = $this->config->get("plugins.users.add_new_user") ?? '';
if ($add_new_user_link === 'hide') {
$this->removeLink('user.admin_create', $links);
}
elseif ($add_new_user_link === 'entity.user.collection') {
// Move the item to the people menu.
$this->addLink('navigation.create.user', [
'title' => $this->t('Add new user'),
'weight' => -99,
'parent' => 'entity.user.collection',
'options' => [
'attributes' => [
'class' => [
'navigation-extra--users--add_new_user',
],
],
],
] + ($links['navigation.create.user'] ?? []), $links);
}
}
/**
* {@inheritdoc}
*/
public function needsMenuLinkRebuild(EntityInterface $entity): bool {
return (bool) ($this->config->get('plugins.users.roles') ?? 0);
}
/**
* Get the roles.
*
* @return array
* An array of roles keyed by rid and label as value.
*/
public function getRoles(): array {
try {
$roleStorage = $this->entityTypeManager->getStorage('user_role');
}
catch (InvalidPluginDefinitionException | PluginNotFoundException $e) {
Police::logException($e);
return [];
}
$roles = $roleStorage->loadMultiple();
unset($roles[RoleInterface::ANONYMOUS_ID]);
unset($roles[RoleInterface::AUTHENTICATED_ID]);
return array_map(fn(RoleInterface $role) => $role->label(), $roles);
}
}
