Same name in this branch
  1. 10 core/lib/Drupal/Core/Menu/MenuActiveTrail.php \Drupal\Core\Menu\MenuActiveTrail
  2. 10 core/lib/Drupal/Core/ProxyClass/Menu/MenuActiveTrail.php \Drupal\Core\ProxyClass\Menu\MenuActiveTrail
Same name and namespace in other branches
  1. 8.9.x core/lib/Drupal/Core/Menu/MenuActiveTrail.php \Drupal\Core\Menu\MenuActiveTrail
  2. 9 core/lib/Drupal/Core/Menu/MenuActiveTrail.php \Drupal\Core\Menu\MenuActiveTrail

Provides the default implementation of the active menu trail service.

It uses the current route name and route parameters to compare with the ones of the menu links.

Hierarchy

Expanded class hierarchy of MenuActiveTrail

1 file declares its use of MenuActiveTrail
MenuActiveTrailTest.php in core/tests/Drupal/Tests/Core/Menu/MenuActiveTrailTest.php
1 string reference to 'MenuActiveTrail'
core.services.yml in core/core.services.yml
core/core.services.yml
1 service uses MenuActiveTrail
menu.active_trail in core/core.services.yml
Drupal\Core\Menu\MenuActiveTrail

File

core/lib/Drupal/Core/Menu/MenuActiveTrail.php, line 16

Namespace

Drupal\Core\Menu
View source
class MenuActiveTrail extends CacheCollector implements MenuActiveTrailInterface {

  /**
   * The menu link plugin manager.
   *
   * @var \Drupal\Core\Menu\MenuLinkManagerInterface
   */
  protected $menuLinkManager;

  /**
   * The route match object for the current page.
   *
   * @var \Drupal\Core\Routing\RouteMatchInterface
   */
  protected $routeMatch;

  /**
   * Constructs a \Drupal\Core\Menu\MenuActiveTrail object.
   *
   * @param \Drupal\Core\Menu\MenuLinkManagerInterface $menu_link_manager
   *   The menu link plugin manager.
   * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
   *   A route match object for finding the active link.
   * @param \Drupal\Core\Cache\CacheBackendInterface $cache
   *   The cache backend.
   * @param \Drupal\Core\Lock\LockBackendInterface $lock
   *   The lock backend.
   */
  public function __construct(MenuLinkManagerInterface $menu_link_manager, RouteMatchInterface $route_match, CacheBackendInterface $cache, LockBackendInterface $lock) {
    parent::__construct(NULL, $cache, $lock);
    $this->menuLinkManager = $menu_link_manager;
    $this->routeMatch = $route_match;
  }

  /**
   * {@inheritdoc}
   *
   * @see ::getActiveTrailIds()
   */
  protected function getCid() {
    if (!isset($this->cid)) {
      $route_parameters = $this->routeMatch
        ->getRawParameters()
        ->all();
      ksort($route_parameters);
      $this->cid = 'active-trail:route:' . $this->routeMatch
        ->getRouteName() . ':route_parameters:' . serialize($route_parameters);
    }
    return $this->cid;
  }

  /**
   * {@inheritdoc}
   *
   * @see ::getActiveTrailIds()
   */
  protected function resolveCacheMiss($menu_name) {
    $this->storage[$menu_name] = $this
      ->doGetActiveTrailIds($menu_name);
    $this->tags[] = 'config:system.menu.' . $menu_name;
    $this
      ->persist($menu_name);
    return $this->storage[$menu_name];
  }

  /**
   * {@inheritdoc}
   *
   * This implementation caches all active trail IDs per route match for *all*
   * menus whose active trails are calculated on that page. This ensures 1 cache
   * get for all active trails per page load, rather than N.
   *
   * It uses the cache collector pattern to do this.
   *
   * @see ::get()
   * @see \Drupal\Core\Cache\CacheCollectorInterface
   * @see \Drupal\Core\Cache\CacheCollector
   */
  public function getActiveTrailIds($menu_name) {
    return $this
      ->get($menu_name);
  }

  /**
   * Helper method for ::getActiveTrailIds().
   */
  protected function doGetActiveTrailIds($menu_name) {

    // Parent ids; used both as key and value to ensure uniqueness.
    // We always want all the top-level links with parent == ''.
    $active_trail = [
      '' => '',
    ];

    // If a link in the given menu indeed matches the route, then use it to
    // complete the active trail.
    if ($active_link = $this
      ->getActiveLink($menu_name)) {
      if ($parents = $this->menuLinkManager
        ->getParentIds($active_link
        ->getPluginId())) {
        $active_trail = $parents + $active_trail;
      }
    }
    return $active_trail;
  }

  /**
   * {@inheritdoc}
   */
  public function getActiveLink($menu_name = NULL) {

    // Note: this is a very simple implementation. If you need more control
    // over the return value, such as matching a prioritized list of menu names,
    // you should substitute your own implementation for the 'menu.active_trail'
    // service in the container.
    // The menu links coming from the storage are already sorted by depth,
    // weight and ID.
    $found = NULL;
    $route_name = $this->routeMatch
      ->getRouteName();

    // On a default (not custom) 403 page the route name is NULL. On a custom
    // 403 page we will get the route name for that page, so we can consider
    // it a feature that a relevant menu tree may be displayed.
    if ($route_name) {
      $route_parameters = $this->routeMatch
        ->getRawParameters()
        ->all();

      // Load links matching this route.
      $links = $this->menuLinkManager
        ->loadLinksByRoute($route_name, $route_parameters, $menu_name);

      // Select the first matching link.
      if ($links) {
        $found = reset($links);
      }
    }
    return $found;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
CacheCollector::$cache protected property The cache backend that should be used. 1
CacheCollector::$cacheCreated protected property Stores the cache creation time.
CacheCollector::$cacheInvalidated protected property Flag that indicates of the cache has been invalidated.
CacheCollector::$cacheLoaded protected property Indicates if the collected cache was already loaded.
CacheCollector::$cid protected property The cache id that is used for the cache entry.
CacheCollector::$keysToPersist protected property An array of keys to add to the cache on service termination.
CacheCollector::$keysToRemove protected property An array of keys to remove from the cache on service termination.
CacheCollector::$lock protected property The lock backend that should be used. 1
CacheCollector::$storage protected property Storage for the data itself.
CacheCollector::$tags protected property A list of tags that are used for the cache entry.
CacheCollector::clear public function Clears the collected cache entry. Overrides CacheCollectorInterface::clear 1
CacheCollector::delete public function Deletes the element. Overrides CacheCollectorInterface::delete
CacheCollector::destruct public function Performs destruct operations. Overrides DestructableInterface::destruct
CacheCollector::get public function Gets value from the cache. Overrides CacheCollectorInterface::get 2
CacheCollector::has public function Returns whether data exists for this key. Overrides CacheCollectorInterface::has 1
CacheCollector::invalidateCache protected function Invalidate the cache.
CacheCollector::lazyLoadCache protected function Loads the cache if not already done. 1
CacheCollector::normalizeLockName protected function Normalizes a cache ID in order to comply with database limitations. 1
CacheCollector::persist protected function Flags an offset value to be written to the persistent cache.
CacheCollector::reset public function Resets the local cache. Overrides CacheCollectorInterface::reset 1
CacheCollector::set public function Implements \Drupal\Core\Cache\CacheCollectorInterface::set(). Overrides CacheCollectorInterface::set 1
CacheCollector::updateCache protected function Writes a value to the persistent cache immediately. 1
MenuActiveTrail::$menuLinkManager protected property The menu link plugin manager.
MenuActiveTrail::$routeMatch protected property The route match object for the current page.
MenuActiveTrail::doGetActiveTrailIds protected function Helper method for ::getActiveTrailIds().
MenuActiveTrail::getActiveLink public function
MenuActiveTrail::getActiveTrailIds public function This implementation caches all active trail IDs per route match for *all* menus whose active trails are calculated on that page. This ensures 1 cache get for all active trails per page load, rather than N.
MenuActiveTrail::getCid protected function Overrides CacheCollector::getCid
MenuActiveTrail::resolveCacheMiss protected function Overrides CacheCollector::resolveCacheMiss
MenuActiveTrail::__construct public function Constructs a \Drupal\Core\Menu\MenuActiveTrail object. Overrides CacheCollector::__construct