diff --git a/core/includes/menu.inc b/core/includes/menu.inc index d205ac0..7303d3f 100644 --- a/core/includes/menu.inc +++ b/core/includes/menu.inc @@ -969,7 +969,8 @@ function _menu_link_translate(&$item, $translate = FALSE) { */ function menu_item_route_access(Route $route, $href, &$map) { $request = Request::create('/' . $href); - $request->attributes->set('_system_path', $href); + $system_path = $href = \Drupal::service('path_processor_manager')->processInbound($href, $request); + $request->attributes->set('_system_path', $system_path); // Attempt to match this path to provide a fully built request to the // access checker. try { diff --git a/core/lib/Drupal/Core/Menu/LocalTaskBase.php b/core/lib/Drupal/Core/Menu/LocalTaskBase.php index 7568d2b..7a202b5 100644 --- a/core/lib/Drupal/Core/Menu/LocalTaskBase.php +++ b/core/lib/Drupal/Core/Menu/LocalTaskBase.php @@ -26,13 +26,6 @@ protected $t; /** - * URL generator object. - * - * @var \Symfony\Component\Routing\Generator\UrlGeneratorInterface - */ - protected $generator; - - /** * TRUE if this plugin is forced active for options attributes. * * @var bool @@ -50,13 +43,10 @@ * The plugin implementation definition. * @param \Drupal\Core\StringTranslation\Translator\TranslatorInterface $string_translation * The string translation object. - * @param \Symfony\Component\Routing\Generator\UrlGeneratorInterface $generator - * The url generator object. */ - public function __construct(array $configuration, $plugin_id, array $plugin_definition, TranslatorInterface $string_translation, UrlGeneratorInterface $generator) { + public function __construct(array $configuration, $plugin_id, array $plugin_definition, TranslatorInterface $string_translation) { // This is available for subclasses that need to translate a dynamic title. $this->t = $string_translation; - $this->generator = $generator; parent::__construct($configuration, $plugin_id, $plugin_definition); } @@ -68,8 +58,7 @@ public static function create(ContainerInterface $container, array $configuratio $configuration, $plugin_id, $plugin_definition, - $container->get('string_translation'), - $container->get('url_generator') + $container->get('string_translation') ); } @@ -81,6 +70,13 @@ public function getRouteName() { } /** + * Get the route parameters. + */ + public function getRouteParameters() { + return $this->pluginDefinition['route_parameters']; + } + + /** * {@inheritdoc} */ public function getTitle() { @@ -91,17 +87,8 @@ public function getTitle() { /** * {@inheritdoc} */ - public function getPath() { - // Subclasses may set a request into the generator or use any desired method - // to generate the path. - // @todo - use the new method from https://drupal.org/node/2031353 - $path = $this->generator->generate($this->getRouteName()); - // In order to get the Drupal path the base URL has to be stripped off. - $base_url = $this->generator->getContext()->getBaseUrl(); - if (!empty($base_url) && strpos($path, $base_url) === 0) { - $path = substr($path, strlen($base_url)); - } - return trim($path, '/'); + public function getRouteInformation() { + return array($this->getRouteName(), $this->getRouteParameters(), array()); } /** diff --git a/core/lib/Drupal/Core/Menu/LocalTaskInterface.php b/core/lib/Drupal/Core/Menu/LocalTaskInterface.php index b7f581d..f5d1539 100644 --- a/core/lib/Drupal/Core/Menu/LocalTaskInterface.php +++ b/core/lib/Drupal/Core/Menu/LocalTaskInterface.php @@ -32,15 +32,16 @@ public function getRouteName(); public function getTitle(); /** - * Returns an internal Drupal path to use when creating the link for the tab. + * Returns the route information needed to render the local task. * * Subclasses may add optional arguments like NodeInterface $node = NULL that * will be supplied by the ControllerResolver. * - * @return string - * The path of this local task. + * @return array + * An array of the first element be the route name and the second an optional + * array of parameters. */ - public function getPath(); + public function getRouteInformation(); /** * Returns the weight of the local task. diff --git a/core/lib/Drupal/Core/Menu/LocalTaskManager.php b/core/lib/Drupal/Core/Menu/LocalTaskManager.php index 00837c5..acf2ef0 100644 --- a/core/lib/Drupal/Core/Menu/LocalTaskManager.php +++ b/core/lib/Drupal/Core/Menu/LocalTaskManager.php @@ -7,11 +7,12 @@ namespace Drupal\Core\Menu; +use Drupal\Core\Controller\ControllerResolverInterface; use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Plugin\DefaultPluginManager; use Drupal\Core\Routing\RouteProviderInterface; +use Drupal\Core\Routing\UrlGeneratorInterface; use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface; /** * Manages discovery and instantiation of menu local task plugins. @@ -51,6 +52,13 @@ class LocalTaskManager extends DefaultPluginManager { protected $routeProvider; /** + * The URL generator. + * + * @var \Drupal\Core\Routing\UrlGeneratorInterface + */ + protected $urlGenerator; + + /** * Constructs a \Drupal\Core\Menu\LocalTaskManager object. * * @param \Traversable $namespaces @@ -65,11 +73,12 @@ class LocalTaskManager extends DefaultPluginManager { * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler * The module handler.u */ - public function __construct(\Traversable $namespaces, ControllerResolverInterface $controller_resolver, Request $request, RouteProviderInterface $route_provider, ModuleHandlerInterface $module_handler) { + public function __construct(\Traversable $namespaces, ControllerResolverInterface $controller_resolver, Request $request, RouteProviderInterface $route_provider, ModuleHandlerInterface $module_handler, UrlGeneratorInterface $url_generator) { 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->alterInfo($module_handler, 'local_tasks'); } @@ -89,16 +98,17 @@ public function getTitle(LocalTaskInterface $local_task) { } /** - * Gets the Drupal path for a local task. + * Gets the route information for a local task. * * @param \Drupal\Core\Menu\LocalTaskInterface $local_task * The local task plugin instance to get the path for. * - * @return string - * The path. + * @return array + * An array of the first element be the route name and the second an optional + * array of parameters. */ - public function getPath(LocalTaskInterface $local_task) { - $controller = array($local_task, 'getPath'); + public function getRouteInformation(LocalTaskInterface $local_task) { + $controller = array($local_task, 'getRouteInformation'); $arguments = $this->controllerResolver->getArguments($this->request, $controller); return call_user_func_array($controller, $arguments); } @@ -217,6 +227,21 @@ public function getTasksBuild($route_name) { $active = ($route_name == $child->getRouteName() || $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, diff --git a/core/tests/Drupal/Tests/Core/Menu/LocalTaskManagerTest.php b/core/tests/Drupal/Tests/Core/Menu/LocalTaskManagerTest.php index 5d61a9c..05c6edd 100644 --- a/core/tests/Drupal/Tests/Core/Menu/LocalTaskManagerTest.php +++ b/core/tests/Drupal/Tests/Core/Menu/LocalTaskManagerTest.php @@ -62,6 +62,13 @@ class LocalTaskManagerTest extends UnitTestCase { */ protected $factory; + /** + * The mocked URL generator. + * + * @var \Drupal\Core\Routing\UrlGeneratorInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $urlGenerator; + public static function getInfo() { return array( 'name' => 'Local tasks manager.', @@ -81,6 +88,7 @@ protected function setUp() { $this->routeProvider = $this->getMock('Drupal\Core\Routing\RouteProviderInterface'); $this->pluginDiscovery = $this->getMock('Drupal\Component\Plugin\Discovery\DiscoveryInterface'); $this->factory = $this->getMock('Drupal\Component\Plugin\Factory\FactoryInterface'); + $this->urlGenerator = $this->getMock('Drupal\Core\Routing\UrlGeneratorInterface'); $this->setupLocalTaskManager(); } @@ -159,21 +167,21 @@ public function testGetTitle() { } /** - * Tests the getPath method. + * Tests the getRouteInformation method. * - * @see \Drupal\system\Plugin\Type\MenuLocalTaskManager::getPath() + * @see \Drupal\system\Plugin\Type\MenuLocalTaskManager::getRouteInformation() */ - public function testGetPath() { + public function testGetRouteInformation() { $menu_local_task = $this->getMock('Drupal\Core\Menu\LocalTaskInterface'); $menu_local_task->expects($this->once()) - ->method('getPath'); + ->method('getRouteInformation'); $this->controllerResolver->expects($this->once()) ->method('getArguments') - ->with($this->request, array($menu_local_task, 'getPath')) + ->with($this->request, array($menu_local_task, 'getRouteInformation')) ->will($this->returnValue(array())); - $this->manager->getPath($menu_local_task); + $this->manager->getRouteInformation($menu_local_task); } /** @@ -194,6 +202,10 @@ protected function setupLocalTaskManager() { $property->setAccessible(TRUE); $property->setValue($this->manager, $this->request); + $property = new \ReflectionProperty('Drupal\Core\Menu\LocalTaskManager', 'urlGenerator'); + $property->setAccessible(TRUE); + $property->setValue($this->manager, $this->urlGenerator); + $property = new \ReflectionProperty('Drupal\Core\Menu\LocalTaskManager', 'discovery'); $property->setAccessible(TRUE); $property->setValue($this->manager, $this->pluginDiscovery);