public function LocalTaskManager::getLocalTasksForRoute

public LocalTaskManager::getLocalTasksForRoute($route_name)

Find all local tasks that appear on a named route.

Parameters

string $route_name: The route for which to find local tasks.

Return value

array Returns an array of task levels. Each task level contains instances of local tasks (LocalTaskInterface) which appear on the tab route. The array keys are the depths and the values are arrays of plugin instances.

Overrides LocalTaskManagerInterface::getLocalTasksForRoute

File

core/lib/Drupal/Core/Menu/LocalTaskManager.php, line 197

Class

LocalTaskManager
Provides the default local task manager using YML as primary definition.

Namespace

Drupal\Core\Menu

Code

public function getLocalTasksForRoute($route_name) {
  if (!isset($this->instances[$route_name])) {
    $this->instances[$route_name] = array();
    if ($cache = $this->cacheBackend->get($this->cacheKey . ':' . $route_name)) {
      $base_routes = $cache->data['base_routes'];
      $parents = $cache->data['parents'];
      $children = $cache->data['children'];
    }
    else {
      $definitions = $this->getDefinitions();
      // We build the hierarchy by finding all tabs that should
      // appear on the current route.
      $base_routes = array();
      $parents = array();
      $children = array();
      foreach ($definitions as $plugin_id => $task_info) {
        // Fill in the base_route from the parent to insure consistency.
        if (!empty($task_info['parent_id']) && !empty($definitions[$task_info['parent_id']])) {
          $task_info['base_route'] = $definitions[$task_info['parent_id']]['base_route'];
          // Populate the definitions we use in the next loop. Using a
          // reference like &$task_info causes bugs.
          $definitions[$plugin_id]['base_route'] = $definitions[$task_info['parent_id']]['base_route'];
        }
        if ($route_name == $task_info['route_name']) {
          if (!empty($task_info['base_route'])) {
            $base_routes[$task_info['base_route']] = $task_info['base_route'];
          }
          // Tabs that link to the current route are viable parents
          // and their parent and children should be visible also.
          // @todo - this only works for 2 levels of tabs.
          // instead need to iterate up.
          $parents[$plugin_id] = TRUE;
          if (!empty($task_info['parent_id'])) {
            $parents[$task_info['parent_id']] = TRUE;
          }
        }
      }
      if ($base_routes) {
        // Find all the plugins with the same root and that are at the top
        // level or that have a visible parent.
        foreach ($definitions as $plugin_id => $task_info) {
          if (!empty($base_routes[$task_info['base_route']]) && (empty($task_info['parent_id']) || !empty($parents[$task_info['parent_id']]))) {
            // Concat '> ' with root ID for the parent of top-level tabs.
            $parent = empty($task_info['parent_id']) ? '> ' . $task_info['base_route'] : $task_info['parent_id'];
            $children[$parent][$plugin_id] = $task_info;
          }
        }
      }
      $data = array(
        'base_routes' => $base_routes,
        'parents' => $parents,
        'children' => $children,
      );
      $this->cacheBackend->set($this->cacheKey . ':' . $route_name, $data, Cache::PERMANENT, $this->cacheTags);
    }
    // Create a plugin instance for each element of the hierarchy.
    foreach ($base_routes as $base_route) {
      // Convert the tree keyed by plugin IDs into a simple one with
      // integer depth.  Create instances for each plugin along the way.
      $level = 0;
      // We used this above as the top-level parent array key.
      $next_parent = '> ' . $base_route;
      do {
        $parent = $next_parent;
        $next_parent = FALSE;
        foreach ($children[$parent] as $plugin_id => $task_info) {
          $plugin = $this->createInstance($plugin_id);
          $this->instances[$route_name][$level][$plugin_id] = $plugin;
          // Normally, the link generator compares the href of every link with
          // the current path and sets the active class accordingly. But the
          // parents of the current local task may be on a different route in
          // which case we have to set the class manually by flagging it
          // active.
          if (!empty($parents[$plugin_id]) && $route_name != $task_info['route_name']) {
            $plugin->setActive();
          }
          if (isset($children[$plugin_id])) {
            // This tab has visible children.
            $next_parent = $plugin_id;
          }
        }
        $level++;
      } while ($next_parent);
    }

  }
  return $this->instances[$route_name];
}

© 2001–2016 by the original authors
Licensed under the GNU General Public License, version 2 and later.
Drupal is a registered trademark of Dries Buytaert.
https://api.drupal.org/api/drupal/core!lib!Drupal!Core!Menu!LocalTaskManager.php/function/LocalTaskManager::getLocalTasksForRoute/8.1.x