admin_toolbar_links_access_filter.module in Admin Toolbar 8.2
Same filename and directory in other branches
This module don't show menu links that you don't have access permission for.
File
admin_toolbar_links_access_filter/admin_toolbar_links_access_filter.moduleView source
<?php
/**
* @file
* This module don't show menu links that you don't have access permission for.
*/
use Drupal\Core\Session\AccountInterface;
use Drupal\user\Entity\Role;
use Symfony\Component\Routing\Exception\RouteNotFoundException;
use Drupal\Core\Routing\RouteMatchInterface;
/**
* Implements hook_help().
*/
function admin_toolbar_links_access_filter_help($route_name, RouteMatchInterface $route_match) {
switch ($route_name) {
// Main module help.
case 'help.page.admin_toolbar_links_access_filter':
$output = '';
$output .= '<h3>' . t('About') . '</h3>';
$output .= '<p>' . t('The Admin Toolbar Links Access Filter module provides a workaround for the common problem that users with <em>Use the administration pages and help</em> permission see menu links they done not have access permission for.') . '</p>';
return $output;
}
}
/**
* Implements hook_preprocess_menu().
*
* Hides links from admin menu, if user doesn't have access rights.
*/
function admin_toolbar_links_access_filter_preprocess_menu(&$variables) {
if (empty($variables['items'])) {
// Additional empty check to prevent exotic situations, where the preprocess
// function is entered even without items.
// @see https://www.drupal.org/node/2833885
return;
}
// Ensure that menu_name exists.
if (!isset($variables['menu_name'])) {
// In rare cases (for unknown reasons) menu_name may not be set.
// As fallback, we can fetch it from the first menu item.
$first_link = reset($variables['items']);
/** @var Drupal\Core\Menu\MenuLinkDefault $original_link */
// Fetch the menu_name from the original link.
$original_link = $first_link['original_link'];
$variables['menu_name'] = $original_link
->getMenuName();
}
if ($variables['menu_name'] == 'admin') {
if (!admin_toolbar_links_access_filter_user_has_admin_role($variables['user'])) {
admin_toolbar_links_access_filter_filter_non_accessible_links($variables['items']);
}
}
}
/**
* Hides links from admin menu, if user doesn't have access rights.
*/
function admin_toolbar_links_access_filter_filter_non_accessible_links(array &$items) {
foreach ($items as $route => &$item) {
$route_name = $route;
$route_params = [];
if (!empty($item['original_link'])) {
/** @var \Drupal\Core\Menu\MenuLinkBase $original_link */
$original_link = $item['original_link'];
if ($original_link
->getUrlObject()
->isExternal()) {
// Do not filter external URL at all.
continue;
}
$route_name = $original_link
->getRouteName();
$route_params = $original_link
->getRouteParameters();
}
// Check, if user has access rights to the route.
if (!\Drupal::accessManager()
->checkNamedRoute($route_name, $route_params)) {
unset($items[$route]);
}
else {
if (!empty($items[$route]['below'])) {
// Recursively call this function for the child items.
admin_toolbar_links_access_filter_filter_non_accessible_links($items[$route]['below']);
}
if (empty($items[$route]['below']) && \Drupal::moduleHandler()
->moduleExists('admin_toolbar')) {
// Every child item has been cleared out.
// Now check, if the given route represents an overview page only,
// without having functionality on its own. In this case, we can safely
// unset this item, as there aren't any children left.
// This assumption is only valid, when the admin_toolbar module is
// installed because otherwise we won't have child items at all.
if (admin_toolbar_links_access_filter_is_overview_page($route)) {
unset($items[$route]);
}
else {
// Let's remove the expanded flag.
$items[$route]['is_expanded'] = FALSE;
}
}
}
}
}
/**
* Checks if the given route name is an overview page.
*
* Checks if the given route name matches a pure (admin) overview page that can
* be skipped, if there are no child items set. The typical example are routes
* having the SystemController::systemAdminMenuBlockPage() function as their
* controller callback set.
*
* @param string $route_name
* The route name to check.
*
* @return bool
* TRUE, if the given route name matches a pure admin overview page route,
* FALSE otherwise.
*/
function admin_toolbar_links_access_filter_is_overview_page($route_name) {
// @var \Drupal\Core\Routing\RouteProviderInterface $route_provider.
$route_provider = \Drupal::service('router.route_provider');
$overview_page_controllers = [
'\\Drupal\\system\\Controller\\AdminController::index',
'\\Drupal\\system\\Controller\\SystemController::overview',
'\\Drupal\\system\\Controller\\SystemController::systemAdminMenuBlockPage',
];
try {
$route = $route_provider
->getRouteByName($route_name);
$controller = $route
->getDefault('_controller');
return !empty($controller) && in_array($controller, $overview_page_controllers);
} catch (RouteNotFoundException $ex) {
}
return FALSE;
}
/**
* Checks, if the given user has admin rights.
*
* @param \Drupal\Core\Session\AccountInterface $account
* The account to check.
*
* @return bool
* TRUE, if the given user account has at least one role with admin rights
* assigned, FALSE otherwise.
*/
function admin_toolbar_links_access_filter_user_has_admin_role(AccountInterface $account) {
static $user_has_admin_role = [];
$uid = $account
->id();
if (!isset($user_has_admin_role[$uid])) {
$roles = Role::loadMultiple($account
->getRoles());
foreach ($roles as $role) {
if ($role
->isAdmin()) {
$user_has_admin_role[$uid] = TRUE;
break;
}
$user_has_admin_role[$uid] = FALSE;
}
}
return $user_has_admin_role[$uid];
}
Functions
Name | Description |
---|---|
admin_toolbar_links_access_filter_filter_non_accessible_links | Hides links from admin menu, if user doesn't have access rights. |
admin_toolbar_links_access_filter_help | Implements hook_help(). |
admin_toolbar_links_access_filter_is_overview_page | Checks if the given route name is an overview page. |
admin_toolbar_links_access_filter_preprocess_menu | Implements hook_preprocess_menu(). |
admin_toolbar_links_access_filter_user_has_admin_role | Checks, if the given user has admin rights. |