diff --git a/src/MenuTrailByPathActiveTrail.php b/src/MenuTrailByPathActiveTrail.php index cd154d0..2fb6ae7 100644 --- a/src/MenuTrailByPathActiveTrail.php +++ b/src/MenuTrailByPathActiveTrail.php @@ -100,17 +100,46 @@ class MenuTrailByPathActiveTrail extends MenuActiveTrail { public function getActiveTrailLink($menu_name) { $menu_links = $this->menuHelper->getMenuLinks($menu_name); $trail_urls = $this->pathHelper->getUrls(); - + $matches = NULL; foreach (array_reverse($trail_urls) as $trail_url) { - foreach (array_reverse($menu_links) as $menu_link) { - /* @var $menu_link \Drupal\Core\Menu\MenuLinkInterface */ - /* @var $trail_url \Drupal\Core\Url */ - if ($menu_link->getUrlObject()->toString() == $trail_url->toString()) { - return $menu_link; + if (empty($matches)) { + foreach (array_reverse($menu_links) as $menu_link) { + /* @var $menu_link \Drupal\Core\Menu\MenuLinkInterface */ + /* @var $trail_url \Drupal\Core\Url */ + if ($menu_link->getUrlObject()->toString() == $trail_url->toString()) { + $matches[] = $menu_link; + } } } } + if ($matches) { + $match = $this->getBestMatch($matches, $menu_name); + return $match; + } return NULL; } + + /** + * @param \Drupal\Core\Menu\MenuLinkInterface[] $matches + * @param string $menuName + * @return \Drupal\Core\Menu\MenuLinkInterface + */ + private function getBestMatch(array $matches, string $menuName) { + if (count($matches) === 1) { + return reset($matches); + } + $requestUrl = \Drupal::request()->getRequestUri(); + + /** @var \Drupal\Core\Menu\MenuLinkInterface $match */ + foreach ($matches as $match) { + /** @var \Drupal\Core\Menu\MenuLinkInterface $parentMenuLink */ + $parentMenuLink = \Drupal::service('plugin.manager.menu.link')->getInstance(['id' => $match->getParent()]); + if ($parentMenuLink && strpos($requestUrl, $parentMenuLink->getUrlObject()->toString()) === 0) { + return $match; + } + } + // No matching url found, just return the first one + return reset($matches); + } }