class NavigationMenuLinkTreeManipulators
Provides a menu link tree manipulator for the navigation menu block.
Hierarchy
- class \Drupal\navigation\Menu\NavigationMenuLinkTreeManipulators uses \Drupal\Core\StringTranslation\StringTranslationTrait
Expanded class hierarchy of NavigationMenuLinkTreeManipulators
2 files declare their use of NavigationMenuLinkTreeManipulators
- NavigationMenuBlock.php in core/
modules/ navigation/ src/ Plugin/ Block/ NavigationMenuBlock.php - NavigationMenuLinkTreeManipulatorsTest.php in core/
modules/ navigation/ tests/ src/ Unit/ NavigationMenuLinkTreeManipulatorsTest.php
File
-
core/
modules/ navigation/ src/ Menu/ NavigationMenuLinkTreeManipulators.php, line 19
Namespace
Drupal\navigation\MenuView source
class NavigationMenuLinkTreeManipulators {
use StringTranslationTrait;
public function __construct(protected readonly RouteProviderInterface $routeProvider, protected readonly StaticMenuLinkOverridesInterface $overrides, TranslationInterface $translation) {
$this->setStringTranslation($translation);
}
/**
* Adds an "overview" child link to second level menu links with children.
*
* In the navigation menu, a second-level menu item is a link if it does not
* have children, but if it does, it instead becomes a button that opens
* its child menu. To provide a way to access the page a second-level menu
* item links to, add an "overview" link that links to the page as a child
* (third-level) menu item.
*
* @param \Drupal\Core\Menu\MenuLinkTreeElement[] $tree
* The menu link tree to manipulate.
*
* @return \Drupal\Core\Menu\MenuLinkTreeElement[]
* The manipulated menu link tree.
*/
public function addSecondLevelOverviewLinks(array $tree) : array {
if (!$tree) {
return [];
}
foreach ($tree as $item) {
if (!$this->isEnabledAndAccessible($item)) {
continue;
}
foreach ($item->subtree as $sub_item) {
if ($this->shouldAddOverviewLink($sub_item)) {
$this->addOverviewLink($sub_item);
}
}
}
return $tree;
}
/**
* Whether a menu tree element should have an overview link added to it.
*
* @param \Drupal\Core\Menu\MenuLinkTreeElement $element
* The menu link tree element to check.
*
* @return bool
* TRUE if menu tree element should have a child overview link added.
*/
protected function shouldAddOverviewLink(MenuLinkTreeElement $element) : bool {
if (empty($element->subtree) || !$this->isEnabledAndAccessible($element)) {
return FALSE;
}
$route_name = $element->link
->getRouteName();
if (in_array($route_name, [
'<nolink>',
'<button>',
])) {
return FALSE;
}
$has_visible_children = FALSE;
foreach ($element->subtree as $sub_element) {
// Do not add overview link if there are no accessible or enabled
// children.
if ($this->isEnabledAndAccessible($sub_element)) {
$has_visible_children = TRUE;
}
// Do not add overview link if there is already a child linking to the
// same URL.
if ($sub_element->link
->getRouteName() === $route_name) {
return FALSE;
}
}
if (!$has_visible_children) {
return FALSE;
}
// The systemAdminMenuBlockPage() method in SystemController returns a list
// of child menu links for the page. If the second-level menu item link's
// route uses that controller, do not add the overview link, because that
// duplicates what is already in the navigation menu.
try {
$controller = ltrim($this->routeProvider
->getRouteByName($route_name)
->getDefault('_controller') ?? '', "\\");
return $controller !== SystemController::class . '::systemAdminMenuBlockPage';
} catch (RouteNotFoundException) {
return TRUE;
}
}
/**
* Checks whether the menu link tree element is accessible and enabled.
*
* Generally, the 'checkAccess' manipulator should run before this manipulator
* does, so the access objects should be set on all the links, but if it is
* not, treat the link as accessible for the purpose of adding the overview
* child link.
*
* @param \Drupal\Core\Menu\MenuLinkTreeElement $element
* The menu link tree element to be checked.
*
* @return bool
* TRUE if the menu link tree element is enabled and has access allowed.
*/
protected function isEnabledAndAccessible(MenuLinkTreeElement $element) : bool {
return $element->link
->isEnabled() && (!isset($element->access) || $element->access
->isAllowed());
}
/**
* Adds "overview" menu tree element as child of a menu tree element.
*
* @param \Drupal\Core\Menu\MenuLinkTreeElement $element
* The menu link tree element to add the overview child element to.
*/
protected function addOverviewLink(MenuLinkTreeElement $element) : void {
// Copy the menu link for the menu link element to a new menu link
// definition, except with overrides to make 'Overview' the title, set the
// parent to the original menu link, and set weight to a low number so that
// it likely goes to the top.
$definition = [
'title' => $this->t('Overview', [
'@title' => $element->link
->getTitle(),
]),
'parent' => $element->link
->getPluginId(),
'provider' => 'navigation',
'weight' => -1000,
] + $element->link
->getPluginDefinition();
$link = new MenuLinkDefault([], $element->link
->getPluginId() . '.navigation_overview', $definition, $this->overrides);
$overview_element = new MenuLinkTreeElement($link, FALSE, $element->depth + 1, $element->inActiveTrail, []);
$overview_element->access = $element->access ? clone $element->access : NULL;
$element->subtree[$element->link
->getPluginId() . '.navigation_overview'] = $overview_element;
}
}
Members
Title Sort descending | Modifiers | Object type | Summary | Overrides |
---|---|---|---|---|
NavigationMenuLinkTreeManipulators::addOverviewLink | protected | function | Adds "overview" menu tree element as child of a menu tree element. | |
NavigationMenuLinkTreeManipulators::addSecondLevelOverviewLinks | public | function | Adds an "overview" child link to second level menu links with children. | |
NavigationMenuLinkTreeManipulators::isEnabledAndAccessible | protected | function | Checks whether the menu link tree element is accessible and enabled. | |
NavigationMenuLinkTreeManipulators::shouldAddOverviewLink | protected | function | Whether a menu tree element should have an overview link added to it. | |
NavigationMenuLinkTreeManipulators::__construct | public | function | ||
StringTranslationTrait::$stringTranslation | protected | property | The string translation service. | 3 |
StringTranslationTrait::formatPlural | protected | function | Formats a string containing a count of items. | |
StringTranslationTrait::getNumberOfPlurals | protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait::getStringTranslation | protected | function | Gets the string translation service. | |
StringTranslationTrait::setStringTranslation | public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait::t | protected | function | Translates a string to the current language or to a given language. | 1 |
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.