3 namespace Drupal\views\Plugin\Derivative;
5 use Drupal\Core\Entity\EntityStorageInterface;
6 use Drupal\Core\State\StateInterface;
7 use Drupal\Component\Plugin\Derivative\DeriverBase;
8 use Drupal\Core\Plugin\Discovery\ContainerDeriverInterface;
9 use Drupal\Core\Routing\RouteProviderInterface;
10 use Drupal\views\Views;
11 use Symfony\Component\DependencyInjection\ContainerInterface;
14 * Provides local task definitions for all views configured as local tasks.
16 class ViewsLocalTask extends DeriverBase implements ContainerDeriverInterface {
21 * @var \Drupal\Core\Routing\RouteProviderInterface
23 protected $routeProvider;
26 * The state key value store.
28 * @var \Drupal\Core\State\StateInterface
35 * @var \Drupal\Core\Entity\EntityStorageInterface
37 protected $viewStorage;
40 * Constructs a \Drupal\views\Plugin\Derivative\ViewsLocalTask instance.
42 * @param \Drupal\Core\Routing\RouteProviderInterface $route_provider
44 * @param \Drupal\Core\State\StateInterface $state
45 * The state key value store.
46 * @param \Drupal\Core\Entity\EntityStorageInterface $view_storage
49 public function __construct(RouteProviderInterface $route_provider, StateInterface $state, EntityStorageInterface $view_storage) {
50 $this->routeProvider = $route_provider;
51 $this->state = $state;
52 $this->viewStorage = $view_storage;
58 public static function create(ContainerInterface $container, $base_plugin_id) {
60 $container->get('router.route_provider'),
61 $container->get('state'),
62 $container->get('entity.manager')->getStorage('view')
69 public function getDerivativeDefinitions($base_plugin_definition) {
70 $this->derivatives = [];
72 $view_route_names = $this->state->get('views.view_route_names');
73 foreach ($this->getApplicableMenuViews() as $pair) {
74 /** @var $executable \Drupal\views\ViewExecutable */
75 list($view_id, $display_id) = $pair;
76 $executable = $this->viewStorage->load($view_id)->getExecutable();
78 $executable->setDisplay($display_id);
79 $menu = $executable->display_handler->getOption('menu');
80 if (in_array($menu['type'], ['tab', 'default tab'])) {
81 $plugin_id = 'view.' . $executable->storage->id() . '.' . $display_id;
82 $route_name = $view_route_names[$executable->storage->id() . '.' . $display_id];
84 // Don't add a local task for views which override existing routes.
85 // @todo Alternative it could just change the existing entry.
86 if ($route_name != $plugin_id) {
90 $this->derivatives[$plugin_id] = [
91 'route_name' => $route_name,
92 'weight' => $menu['weight'],
93 'title' => $menu['title'],
94 ] + $base_plugin_definition;
96 // Default local tasks have themselves as root tab.
97 if ($menu['type'] == 'default tab') {
98 $this->derivatives[$plugin_id]['base_route'] = $route_name;
102 return $this->derivatives;
106 * Alters base_route and parent_id into the views local tasks.
108 public function alterLocalTasks(&$local_tasks) {
109 $view_route_names = $this->state->get('views.view_route_names');
111 foreach ($this->getApplicableMenuViews() as $pair) {
112 list($view_id, $display_id) = $pair;
113 /** @var $executable \Drupal\views\ViewExecutable */
114 $executable = $this->viewStorage->load($view_id)->getExecutable();
116 $executable->setDisplay($display_id);
117 $menu = $executable->display_handler->getOption('menu');
119 // We already have set the base_route for default tabs.
120 if (in_array($menu['type'], ['tab'])) {
121 $plugin_id = 'view.' . $executable->storage->id() . '.' . $display_id;
122 $view_route_name = $view_route_names[$executable->storage->id() . '.' . $display_id];
124 // Don't add a local task for views which override existing routes.
125 if ($view_route_name != $plugin_id) {
126 unset($local_tasks[$plugin_id]);
130 // Find out the parent route.
131 // @todo Find out how to find both the root and parent tab.
132 $path = $executable->display_handler->getPath();
133 $split = explode('/', $path);
135 $path = implode('/', $split);
137 $pattern = '/' . str_replace('%', '{}', $path);
138 if ($routes = $this->routeProvider->getRoutesByPattern($pattern)) {
139 foreach ($routes->all() as $name => $route) {
140 $local_tasks['views_view:' . $plugin_id]['base_route'] = $name;
141 // Skip after the first found route.
150 * Return a list of all views and display IDs that have a menu entry.
153 * A list of arrays containing the $view and $display_id.
156 * array($view, $display_id),
157 * array($view, $display_id),
161 protected function getApplicableMenuViews() {
162 return Views::getApplicableViews('uses_menu_links');