function LocalTaskManager::getLocalTasksForRoute

Same name in other branches
  1. 9 core/lib/Drupal/Core/Menu/LocalTaskManager.php \Drupal\Core\Menu\LocalTaskManager::getLocalTasksForRoute()
  2. 8.9.x core/lib/Drupal/Core/Menu/LocalTaskManager.php \Drupal\Core\Menu\LocalTaskManager::getLocalTasksForRoute()
  3. 10 core/lib/Drupal/Core/Menu/LocalTaskManager.php \Drupal\Core\Menu\LocalTaskManager::getLocalTasksForRoute()

Overrides LocalTaskManagerInterface::getLocalTasksForRoute

1 call to LocalTaskManager::getLocalTasksForRoute()
LocalTaskManager::getTasksBuild in core/lib/Drupal/Core/Menu/LocalTaskManager.php

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] = [];
        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 = [];
            $parents = [];
            $children = [];
            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 = [
                '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];
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.