Mercurial > hg > isophonics-drupal-site
diff core/lib/Drupal/Core/Menu/MenuActiveTrail.php @ 0:4c8ae668cc8c
Initial import (non-working)
author | Chris Cannam |
---|---|
date | Wed, 29 Nov 2017 16:09:58 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/lib/Drupal/Core/Menu/MenuActiveTrail.php Wed Nov 29 16:09:58 2017 +0000 @@ -0,0 +1,143 @@ +<?php + +namespace Drupal\Core\Menu; + +use Drupal\Core\Cache\CacheBackendInterface; +use Drupal\Core\Cache\CacheCollector; +use Drupal\Core\Lock\LockBackendInterface; +use Drupal\Core\Routing\RouteMatchInterface; + +/** + * 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. + */ +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); + return '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; + } + +}