diff --git a/admin_toolbar.module b/admin_toolbar.module index e2f0bd6..ae1d1bd 100644 --- a/admin_toolbar.module +++ b/admin_toolbar.module @@ -8,6 +8,8 @@ use Drupal\Core\Menu\MenuTreeParameters; use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\Url; +use Drupal\Core\Menu\InaccessibleMenuLink; +use Drupal\Core\Access\AccessResult; /** * Implements hook_toolbar_alter(). @@ -54,6 +56,7 @@ function admin_toolbar_prerender_toolbar_administration_tray(array $element) { array('callable' => 'menu.default_tree_manipulators:checkAccess'), array('callable' => 'menu.default_tree_manipulators:generateIndexAndSort'), array('callable' => 'toolbar_tools_menu_navigation_links'), + array('callable' => 'admin_toolbar_remove_items_with_empty_subtrees'), ); $tree = $menu_tree->transform($tree, $manipulators); $element['administration_menu'] = $menu_tree->build($tree); @@ -87,3 +90,43 @@ function toolbar_tools_menu_navigation_links(array $tree) { } return $tree; } + +/** + * Removes menu items with subtrees in which none of the children are accessible. + * + * This fixes a regression in Drupal 8 core and reverts to the Drupal 7 core + * behavior, by hiding the menu items. + * + * @param \Drupal\Core\Menu\MenuLinkTreeElement[] $tree + * The menu link tree to manipulate. + * + * @return \Drupal\Core\Menu\MenuLinkTreeElement[] + * The manipulated menu link tree. + * + * @see \Drupal\Core\Menu\DefaultMenuLinkTreeManipulators::checkAccess() + */ +function admin_toolbar_remove_items_with_empty_subtrees(array $tree) { + foreach ($tree as $key => $element) { + if ($tree[$key]->access->isAllowed()) { + // If there is a subtree, check if we have access to any of the children. + if ($tree[$key]->subtree) { + $tree[$key]->subtree = admin_toolbar_remove_items_with_empty_subtrees($tree[$key]->subtree); + + $subtree_has_child_with_access = FALSE; + foreach ($tree[$key]->subtree as $subtree_key => $subtree_element) { + if ($tree[$key]->subtree[$subtree_key]->access->isAllowed()) { + $subtree_has_child_with_access = TRUE; + } + } + if (!$subtree_has_child_with_access) { + // Remove item with empty subtree by setting access to neutral. + $tree[$key]->access = AccessResult::neutral()->cachePerPermissions(); + // Replace the link with an InaccessibleMenuLink object, so that if it + // is accidentally rendered, no sensitive information is divulged. + $tree[$key]->link = new InaccessibleMenuLink($tree[$key]->link); + } + } + } + } + return $tree; +} diff --git a/admin_toolbar_tools/admin_toolbar_tools.module b/admin_toolbar_tools/admin_toolbar_tools.module index 81db4d0..f820c6b 100644 --- a/admin_toolbar_tools/admin_toolbar_tools.module +++ b/admin_toolbar_tools/admin_toolbar_tools.module @@ -174,6 +174,12 @@ function admin_toolbar_tools_menu_links_discovered_alter(&$links) { 'menu_name' => 'admin', 'parent' => 'entity.user.collection', ); + $links['admin_toolbar_tools.user.logout'] = array( + 'title' => t('Logout'), + 'route_name' => 'user.logout', + 'parent' => 'admin_toolbar_tools.help', + 'weight' => 10, + ); $links['user.role_add'] = array( 'title' => t('Add a new role'), 'route_name' => 'user.role_add',