diff --git a/core/modules/views/lib/Drupal/views/Plugin/Derivative/ViewsLocalTask.php b/core/modules/views/lib/Drupal/views/Plugin/Derivative/ViewsLocalTask.php new file mode 100644 index 0000000..3a24b14 --- /dev/null +++ b/core/modules/views/lib/Drupal/views/Plugin/Derivative/ViewsLocalTask.php @@ -0,0 +1,147 @@ +routeProvider = $route_provider; + $this->state = $state; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, $base_plugin_id) { + return new static( + $container->get('router.route_provider'), + $container->get('state') + ); + } + + /** + * {@inheritdoc} + */ + public function getDerivativeDefinitions(array $base_plugin_definition) { + $this->derivatives = array(); + foreach (views_get_applicable_views('uses_hook_menu') as $pair) { + /** @var $executable \Drupal\views\ViewExecutable */ + list($executable, $display_id) = $pair; + + $executable->setDisplay($display_id); + $menu = $executable->display_handler->getOption('menu'); + if (in_array($menu['type'], array('tab', 'default tab'))) { + $plugin_id = 'view.' . $executable->storage->id() . '.' . $display_id; + $route_name = $this->state[$executable->storage->id() . '.' . $display_id]; + $this->derivatives[$plugin_id] = array( + 'route_name' => $route_name, + 'class' => 'Drupal\views\Plugin\Menu\LocalTask\ViewsLocalTask', + 'weight' => $menu['weight'] + ); + } + } + return $this->derivatives; + } + + /** + * Alters tab_root_id and tab_parent_id into the views local tasks. + */ + public function alterLocalTasks(&$local_tasks) { + foreach (views_get_applicable_views('uses_hook_menu') as $pair) { + /** @var $executable \Drupal\views\ViewExecutable */ + list($executable, $display_id) = $pair; + + $executable->setDisplay($display_id); + $menu = $executable->display_handler->getOption('menu'); + if (in_array($menu['type'], array('tab', 'default tab'))) { + $plugin_id = 'view.' . $executable->storage->id() . '.' . $display_id; + $view_route_name = $this->state[$executable->storage->id() . '.' . $display_id]; + + // Don't add a local task for views which override existing routes. + if ($view_route_name != $plugin_id) { + unset($local_tasks[$plugin_id]); + continue; + } + + // Find out the parent route. + // @todo Find out how to find both the root and parent tab. + $path = $executable->display_handler->getPath(); + $split = explode('/', $path); + array_pop($split); + $path = implode('/', $split); + $pattern = '/' . str_replace('%', '{}', $path); + if ($routes = $this->routeProvider->getRoutesByPattern($pattern)) { + foreach ($routes->all() as $name => $route) { + if ($parent_task = $this->getTaskFromRoute($name, $local_tasks)) { + $this->derivatives[$plugin_id]['tab_root_id'] = $parent_task; + } + // Skip after the first found route. + break; + } + } + } + } + + $foo = 123; + } + + /** + * Find the local task ID of the parent route given the route name. + * + * @param string $route_name + * The route name of the parent local task. + * @param array $local_tasks + * An array of all local task definitions. + * + * @return bool|string + * Returns the local task ID of the parent task, otherwise return FALSE. + */ + protected function getTaskFromRoute($route_name, &$local_tasks) { + $local_task = FALSE; + foreach ($local_tasks as $plugin_id => $local_task) { + if ($local_task['route_name'] == $route_name) { + $local_task = $plugin_id; + break; + } + } + + return $local_task; + } + +} diff --git a/core/modules/views/lib/Drupal/views/Plugin/Menu/LocalTask/ViewsLocalTask.php b/core/modules/views/lib/Drupal/views/Plugin/Menu/LocalTask/ViewsLocalTask.php new file mode 100644 index 0000000..417de72 --- /dev/null +++ b/core/modules/views/lib/Drupal/views/Plugin/Menu/LocalTask/ViewsLocalTask.php @@ -0,0 +1,23 @@ +get($cid); } +/** + * Implements hook_local_tasks_alter(). + */ +function views_local_tasks_alter(&$local_tasks) { + $container = \Drupal::getContainer(); + $local_task = ViewsLocalTask::create($container, 'views_view'); + $local_task->alterLocalTasks($local_tasks); +}