diff --git a/core/core.services.yml b/core/core.services.yml index 3bb1e2f..5363020 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -176,7 +176,7 @@ services: arguments: ['@container.namespaces', '@controller_resolver', '@request', '@module_handler', '@cache.cache', '@language_manager'] plugin.manager.menu.local_task: class: Drupal\Core\Menu\LocalTaskManager - arguments: ['@container.namespaces', '@controller_resolver', '@request', '@router.route_provider', '@module_handler', '@url_generator'] + arguments: ['@container.namespaces', '@controller_resolver', '@request', '@router.route_provider', '@module_handler', '@url_generator', '@access_manager'] request: class: Symfony\Component\HttpFoundation\Request # @TODO the synthetic setting must be uncommented whenever drupal_session_initialize() diff --git a/core/lib/Drupal/Core/Menu/LocalTaskBase.php b/core/lib/Drupal/Core/Menu/LocalTaskBase.php index 7a202b5..93a38a3 100644 --- a/core/lib/Drupal/Core/Menu/LocalTaskBase.php +++ b/core/lib/Drupal/Core/Menu/LocalTaskBase.php @@ -73,7 +73,7 @@ public function getRouteName() { * Get the route parameters. */ public function getRouteParameters() { - return $this->pluginDefinition['route_parameters']; + return isset($this->pluginDefinition['route_parameters']) ? $this->pluginDefinition['route_parameters'] : array(); } /** diff --git a/core/lib/Drupal/Core/Menu/LocalTaskManager.php b/core/lib/Drupal/Core/Menu/LocalTaskManager.php index acf2ef0..25f1338 100644 --- a/core/lib/Drupal/Core/Menu/LocalTaskManager.php +++ b/core/lib/Drupal/Core/Menu/LocalTaskManager.php @@ -7,6 +7,7 @@ namespace Drupal\Core\Menu; +use Drupal\Core\Access\AccessManager; use Drupal\Core\Controller\ControllerResolverInterface; use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Plugin\DefaultPluginManager; @@ -59,12 +60,19 @@ class LocalTaskManager extends DefaultPluginManager { protected $urlGenerator; /** + * The access manager. + * + * @var \Drupal\Core\Access\AccessManager + */ + protected $accessManager; + + /** * Constructs a \Drupal\Core\Menu\LocalTaskManager object. * * @param \Traversable $namespaces * An object that implements \Traversable which contains the root paths * keyed by the corresponding namespace to look for plugin implementations, - * @param \Symfony\Component\HttpKernel\Controller\ControllerResolverInterface $controller_resolver + * @param \Drupal\Core\Controller\ControllerResolverInterface $controller_resolver * An object to use in introspecting route methods. * @param \Symfony\Component\HttpFoundation\Request $request * The request object to use for building titles and paths for plugin instances. @@ -72,13 +80,18 @@ class LocalTaskManager extends DefaultPluginManager { * The route provider to load routes by name. * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler * The module handler.u + * @param \Drupal\Core\Routing\UrlGeneratorInterface $url_generator + * The url generator. + * @param \Drupal\Core\Access\AccessManager $access_manager + * The access manager. */ - public function __construct(\Traversable $namespaces, ControllerResolverInterface $controller_resolver, Request $request, RouteProviderInterface $route_provider, ModuleHandlerInterface $module_handler, UrlGeneratorInterface $url_generator) { + public function __construct(\Traversable $namespaces, ControllerResolverInterface $controller_resolver, Request $request, RouteProviderInterface $route_provider, ModuleHandlerInterface $module_handler, UrlGeneratorInterface $url_generator, AccessManager $access_manager) { parent::__construct('Plugin/Menu/LocalTask', $namespaces, array(), 'Drupal\Core\Annotation\Menu\LocalTask'); $this->controllerResolver = $controller_resolver; $this->request = $request; $this->routeProvider = $route_provider; $this->urlGenerator = $url_generator; + $this->accessManager = $access_manager; $this->alterInfo($module_handler, 'local_tasks'); } @@ -193,14 +206,14 @@ public function getLocalTasksForRoute($route_name) { /** * Gets the render array for all local tasks. * - * @param string $route_name + * @param string $current_route_name * The route for which to make renderable local tasks. * * @return array * A render array as expected by theme_menu_local_tasks. */ - public function getTasksBuild($route_name) { - $tree = $this->getLocalTasksForRoute($route_name); + public function getTasksBuild($current_route_name) { + $tree = $this->getLocalTasksForRoute($current_route_name); $build = array(); // Collect all route names. @@ -215,33 +228,30 @@ public function getTasksBuild($route_name) { foreach ($tree as $level => $instances) { foreach ($instances as $child) { - $path = $this->getPath($child); + // In order to get the Drupal path the base URL has to be stripped off. + $route_information = $child->getRouteInformation(); + list($route_name, $route_parameters, $options) = $route_information; + $route_parameters = isset($route_parameters) ? (array) $route_parameters : array(); + + // @todo On the longrun we should be able to use #type link instead. + // so there would be no need for the URL generator here. + $path = $this->urlGenerator->generateFromRoute($route_name, $route_parameters, $options); + // In order to get the Drupal path the base URL has to be stripped off. + $base_url = $this->urlGenerator->getContext()->getBaseUrl(); + if (!empty($base_url) && strpos($path, $base_url) === 0) { + $path = substr($path, strlen($base_url)); + } + $path = trim($path, '/'); + // Find out whether the user has access to the task. - $route = $routes[$child->getRouteName()]; - $map = array(); - // @todo - replace this call when we have a real service for it. - $access = menu_item_route_access($route, $path, $map); + $access = $this->accessManager->checkNamedRoute($route_name, $route_parameters); if ($access) { // Need to flag the list element as active for a tab for the current // route or if the plugin is set active (i.e. the parent tab). - $active = ($route_name == $child->getRouteName() || $child->getActive()); + $active = ($current_route_name == $route_name || $child->getActive()); // @todo It might make sense to use menu link entities instead of // arrays. - // In order to get the Drupal path the base URL has to be stripped off. - $route_information = $child->getRouteInformation(); - list($route_name, $route_parameters, $options) = $route_information; - - // @todo On the longrun we should be able to use #type link instead. - // so there would be no need for the URL generator here. - $path = $this->urlGenerator->generateFromRoute($route_name, $route_parameters, $options); - // In order to get the Drupal path the base URL has to be stripped off. - $base_url = $this->urlGenerator->getContext()->getBaseUrl(); - if (!empty($base_url) && strpos($path, $base_url) === 0) { - $path = substr($path, strlen($base_url)); - } - $path = trim($path, '/'); - $menu_link = array( 'title' => $this->getTitle($child), 'href' => $path,