Commit bd468f23 authored by alexpott's avatar alexpott

Issue #2223615 by znerol: Use request stack in local task/action manager.

parent 0b807696
......@@ -222,10 +222,10 @@ services:
arguments: ['@container.namespaces']
plugin.manager.menu.local_action:
class: Drupal\Core\Menu\LocalActionManager
arguments: ['@controller_resolver', '@request', '@router.route_provider', '@module_handler', '@cache.discovery', '@language_manager', '@access_manager', '@current_user']
arguments: ['@controller_resolver', '@request_stack', '@router.route_provider', '@module_handler', '@cache.discovery', '@language_manager', '@access_manager', '@current_user']
plugin.manager.menu.local_task:
class: Drupal\Core\Menu\LocalTaskManager
arguments: ['@controller_resolver', '@request', '@router.route_provider', '@router.builder', '@module_handler', '@cache.discovery', '@language_manager', '@access_manager', '@current_user']
arguments: ['@controller_resolver', '@request_stack', '@router.route_provider', '@router.builder', '@module_handler', '@cache.discovery', '@language_manager', '@access_manager', '@current_user']
plugin.manager.menu.contextual_link:
class: Drupal\Core\Menu\ContextualLinkManager
arguments: ['@controller_resolver', '@module_handler', '@cache.discovery', '@language_manager', '@access_manager', '@current_user', '@request_stack']
......
......@@ -19,7 +19,7 @@
use Drupal\Core\Plugin\Discovery\YamlDiscovery;
use Drupal\Core\Plugin\Factory\ContainerFactory;
use Drupal\Core\Routing\RouteProviderInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
use Drupal\Core\Session\AccountInterface;
......@@ -65,11 +65,11 @@ class LocalActionManager extends DefaultPluginManager {
protected $controllerResolver;
/**
* A request object.
* The request stack.
*
* @var \Symfony\Component\HttpFoundation\Request
* @var \Symfony\Component\HttpFoundation\RequestStack
*/
protected $request;
protected $requestStack;
/**
* The route provider to load routes by name.
......@@ -92,7 +92,7 @@ class LocalActionManager extends DefaultPluginManager {
*/
protected $account;
/**
/**
* The plugin instances.
*
* @var \Drupal\Core\Menu\LocalActionInterface[]
......@@ -104,9 +104,8 @@ class LocalActionManager extends DefaultPluginManager {
*
* @param \Symfony\Component\HttpKernel\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.
* @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
* The request stack.
* @param \Drupal\Core\Routing\RouteProviderInterface $route_provider
* The route provider.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
......@@ -120,18 +119,18 @@ class LocalActionManager extends DefaultPluginManager {
* @param \Drupal\Core\Session\AccountInterface $account
* The current user.
*/
public function __construct(ControllerResolverInterface $controller_resolver, Request $request, RouteProviderInterface $route_provider, ModuleHandlerInterface $module_handler, CacheBackendInterface $cache_backend, LanguageManagerInterface $language_manager, AccessManager $access_manager, AccountInterface $account) {
public function __construct(ControllerResolverInterface $controller_resolver, RequestStack $request_stack, RouteProviderInterface $route_provider, ModuleHandlerInterface $module_handler, CacheBackendInterface $cache_backend, LanguageManagerInterface $language_manager, AccessManager $access_manager, AccountInterface $account) {
// Skip calling the parent constructor, since that assumes annotation-based
// discovery.
$this->discovery = new YamlDiscovery('local_actions', $module_handler->getModuleDirectories());
$this->discovery = new ContainerDerivativeDiscoveryDecorator($this->discovery);
$this->factory = new ContainerFactory($this);
$this->controllerResolver = $controller_resolver;
$this->requestStack = $request_stack;
$this->routeProvider = $route_provider;
$this->accessManager = $access_manager;
$this->moduleHandler = $module_handler;
$this->account = $account;
$this->controllerResolver = $controller_resolver;
$this->request = $request;
$this->alterInfo('menu_local_actions');
$this->setCacheBackend($cache_backend, $language_manager, 'local_action_plugins', array('local_action' => TRUE));
}
......@@ -150,7 +149,7 @@ public function __construct(ControllerResolverInterface $controller_resolver, Re
*/
public function getTitle(LocalActionInterface $local_action) {
$controller = array($local_action, 'getTitle');
$arguments = $this->controllerResolver->getArguments($this->request, $controller);
$arguments = $this->controllerResolver->getArguments($this->requestStack->getCurrentRequest(), $controller);
return call_user_func_array($controller, $arguments);
}
......@@ -182,16 +181,17 @@ public function getActionsForRoute($route_appears) {
}
}
$links = array();
$request = $this->requestStack->getCurrentRequest();
foreach ($this->instances[$route_appears] as $plugin_id => $plugin) {
$route_name = $plugin->getRouteName();
$route_parameters = $plugin->getRouteParameters($this->request);
$route_parameters = $plugin->getRouteParameters($request);
$links[$plugin_id] = array(
'#theme' => 'menu_local_action',
'#link' => array(
'title' => $this->getTitle($plugin),
'route_name' => $route_name,
'route_parameters' => $route_parameters,
'localized_options' => $plugin->getOptions($this->request),
'localized_options' => $plugin->getOptions($request),
),
'#access' => $this->accessManager->checkNamedRoute($route_name, $route_parameters, $this->account),
'#weight' => $plugin->getWeight(),
......
......@@ -21,7 +21,7 @@
use Drupal\Core\Routing\RouteBuilderInterface;
use Drupal\Core\Routing\RouteProviderInterface;
use Drupal\Core\Session\AccountInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
/**
* Manages discovery and instantiation of menu local task plugins.
......@@ -64,11 +64,11 @@ class LocalTaskManager extends DefaultPluginManager {
protected $controllerResolver;
/**
* A request object.
* The request stack.
*
* @var \Symfony\Component\HttpFoundation\Request
* @var \Symfony\Component\HttpFoundation\RequestStack
*/
protected $request;
protected $requestStack;
/**
* The plugin instances.
......@@ -110,7 +110,7 @@ class LocalTaskManager extends DefaultPluginManager {
*
* @param \Drupal\Core\Controller\ControllerResolverInterface $controller_resolver
* An object to use in introspecting route methods.
* @param \Symfony\Component\HttpFoundation\Request $request
* @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
* The request object to use for building titles and paths for plugin instances.
* @param \Drupal\Core\Routing\RouteProviderInterface $route_provider
* The route provider to load routes by name.
......@@ -127,12 +127,12 @@ class LocalTaskManager extends DefaultPluginManager {
* @param \Drupal\Core\Session\AccountInterface $account
* The current user.
*/
public function __construct(ControllerResolverInterface $controller_resolver, Request $request, RouteProviderInterface $route_provider, RouteBuilderInterface $route_builder, ModuleHandlerInterface $module_handler, CacheBackendInterface $cache, LanguageManager $language_manager, AccessManager $access_manager, AccountInterface $account) {
public function __construct(ControllerResolverInterface $controller_resolver, RequestStack $request_stack, RouteProviderInterface $route_provider, RouteBuilderInterface $route_builder, ModuleHandlerInterface $module_handler, CacheBackendInterface $cache, LanguageManager $language_manager, AccessManager $access_manager, AccountInterface $account) {
$this->discovery = new YamlDiscovery('local_tasks', $module_handler->getModuleDirectories());
$this->discovery = new ContainerDerivativeDiscoveryDecorator($this->discovery);
$this->factory = new ContainerFactory($this);
$this->controllerResolver = $controller_resolver;
$this->request = $request;
$this->requestStack = $request_stack;
$this->routeProvider = $route_provider;
$this->routeBuilder = $route_builder;
$this->accessManager = $access_manager;
......@@ -164,7 +164,8 @@ public function processDefinition(&$definition, $plugin_id) {
*/
public function getTitle(LocalTaskInterface $local_task) {
$controller = array($local_task, 'getTitle');
$arguments = $this->controllerResolver->getArguments($this->request, $controller);
$request = $this->requestStack->getCurrentRequest();
$arguments = $this->controllerResolver->getArguments($request, $controller);
return call_user_func_array($controller, $arguments);
}
......@@ -312,10 +313,11 @@ public function getTasksBuild($current_route_name) {
// of SQL queries that would otherwise be triggered by the access manager.
$routes = $route_names ? $this->routeProvider->getRoutesByNames($route_names) : array();
$request = $this->requestStack->getCurrentRequest();
foreach ($tree as $level => $instances) {
foreach ($instances as $plugin_id => $child) {
$route_name = $child->getRouteName();
$route_parameters = $child->getRouteParameters($this->request);
$route_parameters = $child->getRouteParameters($request);
// Find out whether the user has access to the task.
$access = $this->accessManager->checkNamedRoute($route_name, $route_parameters, $this->account);
......@@ -331,7 +333,7 @@ public function getTasksBuild($current_route_name) {
'title' => $this->getTitle($child),
'route_name' => $route_name,
'route_parameters' => $route_parameters,
'localized_options' => $child->getOptions($this->request),
'localized_options' => $child->getOptions($request),
);
$build[$level][$plugin_id] = array(
'#theme' => 'menu_local_task',
......@@ -363,13 +365,14 @@ protected function isRouteActive($current_route_name, $route_name, $route_parame
// Flag the list element as active if this tab's route and parameters match
// the current request's route and route variables.
$active = $current_route_name == $route_name;
$request = $this->requestStack->getCurrentRequest();
if ($active) {
// The request is injected, so we need to verify that we have the expected
// _raw_variables attribute.
$raw_variables_bag = $this->request->attributes->get('_raw_variables');
$raw_variables_bag = $request->attributes->get('_raw_variables');
// If we don't have _raw_variables, we assume the attributes are still the
// original values.
$raw_variables = $raw_variables_bag ? $raw_variables_bag->all() : $this->request->attributes->all();
$raw_variables = $raw_variables_bag ? $raw_variables_bag->all() : $request->attributes->all();
$active = array_intersect_assoc($route_parameters, $raw_variables) == $route_parameters;
}
return $active;
......
......@@ -19,6 +19,7 @@
use Drupal\Core\Session\AccountInterface;
use Drupal\Tests\UnitTestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
/**
......@@ -378,7 +379,8 @@ public function __construct(ControllerResolverInterface $controller_resolver, Re
$this->accessManager = $access_manager;
$this->account = $account;
$this->controllerResolver = $controller_resolver;
$this->request = $request;
$this->requestStack = new RequestStack();
$this->requestStack->push($request);
$this->moduleHandler = $module_handler;
$this->alterInfo('menu_local_actions');
$this->setCacheBackend($cache_backend, $language_manager, 'local_action_plugins', array('local_action' => TRUE));
......
......@@ -12,6 +12,7 @@
use Drupal\Core\Plugin\Discovery\YamlDiscovery;
use Drupal\Tests\UnitTestCase;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpFoundation\RequestStack;
if (!defined('DRUPAL_ROOT')) {
define('DRUPAL_ROOT', dirname(dirname(substr(__DIR__, 0, -strlen(__NAMESPACE__)))));
......@@ -63,9 +64,10 @@ protected function getLocalTaskManager($module_dirs, $route_name, $route_params)
// todo mock a request with a route.
$request = $this->getMock('Symfony\Component\HttpFoundation\Request');
$property = new \ReflectionProperty('Drupal\Core\Menu\LocalTaskManager', 'request');
$request_stack = new RequestStack();
$property = new \ReflectionProperty('Drupal\Core\Menu\LocalTaskManager', 'requestStack');
$property->setAccessible(TRUE);
$property->setValue($manager, $request);
$property->setValue($manager, $request_stack);
$accessManager = $this->getMockBuilder('Drupal\Core\Access\AccessManager')
->disableOriginalConstructor()
......
......@@ -11,6 +11,7 @@
use Drupal\Core\Language\Language;
use Drupal\Tests\UnitTestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Zend\Stdlib\ArrayObject;
/**
......@@ -263,9 +264,11 @@ protected function setupLocalTaskManager() {
$property->setAccessible(TRUE);
$property->setValue($this->manager, $this->controllerResolver);
$property = new \ReflectionProperty('Drupal\Core\Menu\LocalTaskManager', 'request');
$request_stack = new RequestStack();
$request_stack->push($this->request);
$property = new \ReflectionProperty('Drupal\Core\Menu\LocalTaskManager', 'requestStack');
$property->setAccessible(TRUE);
$property->setValue($this->manager, $this->request);
$property->setValue($this->manager, $request_stack);
$property = new \ReflectionProperty('Drupal\Core\Menu\LocalTaskManager', 'accessManager');
$property->setAccessible(TRUE);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment