menu_per_role-8.x-1.x-dev/menu_per_role.module
menu_per_role.module
<?php
/**
* @file
* Allows restricting access to menu items per role.
*/
declare(strict_types=1);
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\menu_per_role\Form\MenuPerRoleAdminSettings;
/**
* Implements hook_help().
*/
function menu_per_role_help(string $route_name, RouteMatchInterface $route_match): string {
$output = '';
switch ($route_name) {
case 'help.page.menu_per_role':
$output .= '<h3>' . \t('About') . '</h3>';
$output .= '<p>' . \t('The Menu Per Role module allows you to restrict access of menu items per roles.') . '</p>';
$output .= '<h3>' . \t('Limitation') . '</h3>';
$output .= '<p>' . \t("Menu Per role only acts on content menu link (content entity). Menu links provided by configuration (example: Views) or by *.links.menu.yml files can't be managed by this module.") . '</p>';
$output .= '<h3>' . \t('Configuration') . '</h3>';
$output .= '<p>' . \t('Just activate the Menu Per Role module and edit a menu item as usual. There will be one or two fieldsets, depending on the configuration of the module, that allows you to restrict access by role.') . '</p>';
$output .= '<p>' . \t("If you don't check any roles the default access permissions will be kept. Otherwise the module will additionally restrict access to the chosen user roles.") . '</p>';
}
return $output;
}
/**
* Implements hook_entity_base_field_info().
*
* Adds two fields to menu_link_content, so access restrictions can be set.
*/
function menu_per_role_entity_base_field_info(EntityTypeInterface $entity_type): array {
$fields = [];
if ($entity_type->id() != 'menu_link_content') {
return $fields;
}
$fields['menu_per_role__show_role'] = BaseFieldDefinition::create('entity_reference')
->setName('menu_per_role__show_role')
->setTargetEntityTypeId('menu_link_content')
->setLabel(\t('Roles able to see the menu link'))
->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED)
->setSetting('target_type', 'user_role')
->setDisplayOptions('form', [
'type' => 'options_buttons',
'weight' => 0,
]);
$fields['menu_per_role__hide_role'] = BaseFieldDefinition::create('entity_reference')
->setName('menu_per_role__hide_role')
->setTargetEntityTypeId('menu_link_content')
->setLabel(\t('Roles not able see the menu link.'))
->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED)
->setSetting('target_type', 'user_role')
->setDisplayOptions('form', [
'type' => 'options_buttons',
'weight' => 0,
]);
return $fields;
}
/**
* Implements hook_form_FORM_ID_alter().
*
* Alter menu_link_content fields to hide extra fields on content.
*/
function menu_per_role_form_menu_link_content_form_alter(array &$form, FormStateInterface $form_state, string $form_id): void {
$config = \Drupal::config('menu_per_role.settings');
// Get config properties.
$hide_show_mode = $config->get('hide_show') ?? MenuPerRoleAdminSettings::MODE_DISPLAY_BOTH;
$hide_on_content_mode = $config->get('hide_on_content') ?? MenuPerRoleAdminSettings::MODE_DISPLAY_ON_CONTENT_ALWAYS;
// Check if content mode setting applies, and if fields should be hidden.
$is_content = FALSE;
if ($hide_on_content_mode != MenuPerRoleAdminSettings::MODE_DISPLAY_ON_CONTENT_ALWAYS) {
/** @var \Drupal\menu_link_content\Form\MenuLinkContentForm $form_obj */
$form_obj = $form_state->getFormObject();
/** @var \Drupal\menu_link_content\MenuLinkContentInterface $menu_link */
$menu_link = $form_obj->getEntity();
if (!$menu_link->isNew()) {
$link_url = $menu_link->getUrlObject();
if ($link_url->isRouted()) {
$route_params = $link_url->getRouteParameters();
if (\array_key_exists('node', $route_params)) {
// Nodes routes will contain a 'node' with 'nid' value.
if ($hide_on_content_mode == MenuPerRoleAdminSettings::MODE_DISPLAY_ON_CONTENT_NO_NODE_ACCESS) {
// For the existence of any hook_node_grants() implementations.
$is_content = \Drupal::moduleHandler()->hasImplementations('node_grants');
}
// If false, then check if the setting is display never.
$is_content = $is_content || $hide_on_content_mode == MenuPerRoleAdminSettings::MODE_DISPLAY_ON_CONTENT_NEVER;
}
}
}
}
// Check for the display of each field.
$display_show_roles = (!$is_content && $hide_show_mode != MenuPerRoleAdminSettings::MODE_DISPLAY_ONLY_HIDE);
$display_hide_roles = (!$is_content && $hide_show_mode != MenuPerRoleAdminSettings::MODE_DISPLAY_ONLY_SHOW);
// Hide fields if they need to be.
if (!$display_show_roles) {
$form['menu_per_role__show_role']['#access'] = FALSE;
}
if (!$display_hide_roles) {
$form['menu_per_role__hide_role']['#access'] = FALSE;
}
}
