Issue #2294157 by tim.plunkett, dawehner: Switch getOptions() and getRouteParameters() within LocalActionInterface and LocalTaskInterface to use RouteMatch

8.0.x
Nathaniel Catchpole 2015-01-05 13:47:21 +00:00
parent abe83bfb19
commit c422305234
13 changed files with 106 additions and 86 deletions

View File

@ -367,10 +367,10 @@ services:
arguments: ['@menu.link_tree', '@entity.manager', '@string_translation'] arguments: ['@menu.link_tree', '@entity.manager', '@string_translation']
plugin.manager.menu.local_action: plugin.manager.menu.local_action:
class: Drupal\Core\Menu\LocalActionManager class: Drupal\Core\Menu\LocalActionManager
arguments: ['@controller_resolver', '@request_stack', '@router.route_provider', '@module_handler', '@cache.discovery', '@language_manager', '@access_manager', '@current_user'] arguments: ['@controller_resolver', '@request_stack', '@current_route_match', '@router.route_provider', '@module_handler', '@cache.discovery', '@language_manager', '@access_manager', '@current_user']
plugin.manager.menu.local_task: plugin.manager.menu.local_task:
class: Drupal\Core\Menu\LocalTaskManager class: Drupal\Core\Menu\LocalTaskManager
arguments: ['@controller_resolver', '@request_stack', '@router.route_provider', '@router.builder', '@module_handler', '@cache.discovery', '@language_manager', '@access_manager', '@current_user'] arguments: ['@controller_resolver', '@request_stack', '@current_route_match', '@router.route_provider', '@router.builder', '@module_handler', '@cache.discovery', '@language_manager', '@access_manager', '@current_user']
plugin.manager.menu.contextual_link: plugin.manager.menu.contextual_link:
class: Drupal\Core\Menu\ContextualLinkManager class: Drupal\Core\Menu\ContextualLinkManager
arguments: ['@controller_resolver', '@module_handler', '@cache.discovery', '@language_manager', '@access_manager', '@current_user', '@request_stack'] arguments: ['@controller_resolver', '@module_handler', '@cache.discovery', '@language_manager', '@access_manager', '@current_user', '@request_stack']

View File

@ -9,6 +9,7 @@ namespace Drupal\Core\Menu;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Plugin\PluginBase; use Drupal\Core\Plugin\PluginBase;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Routing\RouteProviderInterface; use Drupal\Core\Routing\RouteProviderInterface;
use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
@ -88,7 +89,7 @@ class LocalActionDefault extends PluginBase implements LocalActionInterface, Con
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function getRouteParameters(Request $request) { public function getRouteParameters(RouteMatchInterface $route_match) {
$parameters = isset($this->pluginDefinition['route_parameters']) ? $this->pluginDefinition['route_parameters'] : array(); $parameters = isset($this->pluginDefinition['route_parameters']) ? $this->pluginDefinition['route_parameters'] : array();
$route = $this->routeProvider->getRouteByName($this->getRouteName()); $route = $this->routeProvider->getRouteByName($this->getRouteName());
$variables = $route->compile()->getVariables(); $variables = $route->compile()->getVariables();
@ -99,7 +100,7 @@ class LocalActionDefault extends PluginBase implements LocalActionInterface, Con
// slugs in the path patterns. For example, if the route's path pattern is // slugs in the path patterns. For example, if the route's path pattern is
// /filter/tips/{filter_format} and the path is /filter/tips/plain_text then // /filter/tips/{filter_format} and the path is /filter/tips/plain_text then
// $raw_variables->get('filter_format') == 'plain_text'. // $raw_variables->get('filter_format') == 'plain_text'.
$raw_variables = $request->attributes->get('_raw_variables'); $raw_variables = $route_match->getRawParameters();
foreach ($variables as $name) { foreach ($variables as $name) {
if (isset($parameters[$name])) { if (isset($parameters[$name])) {
@ -109,8 +110,8 @@ class LocalActionDefault extends PluginBase implements LocalActionInterface, Con
if ($raw_variables && $raw_variables->has($name)) { if ($raw_variables && $raw_variables->has($name)) {
$parameters[$name] = $raw_variables->get($name); $parameters[$name] = $raw_variables->get($name);
} }
elseif ($request->attributes->has($name)) { elseif ($value = $route_match->getRawParameter($name)) {
$parameters[$name] = $request->attributes->get($name); $parameters[$name] = $value;
} }
} }
// The UrlGenerator will throw an exception if expected parameters are // The UrlGenerator will throw an exception if expected parameters are
@ -121,7 +122,8 @@ class LocalActionDefault extends PluginBase implements LocalActionInterface, Con
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function getOptions(Request $request) { public function getOptions(RouteMatchInterface $route_match) {
return (array) $this->pluginDefinition['options']; return (array) $this->pluginDefinition['options'];
} }
} }

View File

@ -7,7 +7,7 @@
namespace Drupal\Core\Menu; namespace Drupal\Core\Menu;
use Symfony\Component\HttpFoundation\Request; use Drupal\Core\Routing\RouteMatchInterface;
/** /**
* Defines an interface for menu local actions. * Defines an interface for menu local actions.
@ -25,13 +25,13 @@ interface LocalActionInterface {
/** /**
* Returns the route parameters needed to render a link for the local action. * Returns the route parameters needed to render a link for the local action.
* *
* @param \Symfony\Component\HttpFoundation\Request $request * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
* The HttpRequest object representing the current request. * The current route match.
* *
* @return array * @return array
* An array of parameter names and values. * An array of parameter names and values.
*/ */
public function getRouteParameters(Request $request); public function getRouteParameters(RouteMatchInterface $route_match);
/** /**
* Returns the weight for the local action. * Returns the weight for the local action.
@ -43,13 +43,13 @@ interface LocalActionInterface {
/** /**
* Returns options for rendering a link for the local action. * Returns options for rendering a link for the local action.
* *
* @param \Symfony\Component\HttpFoundation\Request $request * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
* The HTTP request object representing the current request. * The current route match.
* *
* @return array * @return array
* An associative array of options. * An associative array of options.
*/ */
public function getOptions(Request $request); public function getOptions(RouteMatchInterface $route_match);
/** /**
* Returns the localized title to be shown for this action. * Returns the localized title to be shown for this action.

View File

@ -15,6 +15,7 @@ use Drupal\Core\Plugin\DefaultPluginManager;
use Drupal\Core\Plugin\Discovery\ContainerDerivativeDiscoveryDecorator; use Drupal\Core\Plugin\Discovery\ContainerDerivativeDiscoveryDecorator;
use Drupal\Core\Plugin\Discovery\YamlDiscovery; use Drupal\Core\Plugin\Discovery\YamlDiscovery;
use Drupal\Core\Plugin\Factory\ContainerFactory; use Drupal\Core\Plugin\Factory\ContainerFactory;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Routing\RouteProviderInterface; use Drupal\Core\Routing\RouteProviderInterface;
use Drupal\Core\Url; use Drupal\Core\Url;
use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\RequestStack;
@ -64,6 +65,13 @@ class LocalActionManager extends DefaultPluginManager implements LocalActionMana
*/ */
protected $requestStack; protected $requestStack;
/**
* The current route match.
*
* @var \Drupal\Core\Routing\RouteMatchInterface
*/
protected $routeMatch;
/** /**
* The route provider to load routes by name. * The route provider to load routes by name.
* *
@ -99,6 +107,8 @@ class LocalActionManager extends DefaultPluginManager implements LocalActionMana
* An object to use in introspecting route methods. * An object to use in introspecting route methods.
* @param \Symfony\Component\HttpFoundation\RequestStack $request_stack * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
* The request stack. * The request stack.
* @param \Drupal\Core\Routing\RouteMatchInterface $route_match
* The current route match.
* @param \Drupal\Core\Routing\RouteProviderInterface $route_provider * @param \Drupal\Core\Routing\RouteProviderInterface $route_provider
* The route provider. * The route provider.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
@ -112,7 +122,7 @@ class LocalActionManager extends DefaultPluginManager implements LocalActionMana
* @param \Drupal\Core\Session\AccountInterface $account * @param \Drupal\Core\Session\AccountInterface $account
* The current user. * The current user.
*/ */
public function __construct(ControllerResolverInterface $controller_resolver, RequestStack $request_stack, RouteProviderInterface $route_provider, ModuleHandlerInterface $module_handler, CacheBackendInterface $cache_backend, LanguageManagerInterface $language_manager, AccessManagerInterface $access_manager, AccountInterface $account) { public function __construct(ControllerResolverInterface $controller_resolver, RequestStack $request_stack, RouteMatchInterface $route_match, RouteProviderInterface $route_provider, ModuleHandlerInterface $module_handler, CacheBackendInterface $cache_backend, LanguageManagerInterface $language_manager, AccessManagerInterface $access_manager, AccountInterface $account) {
// Skip calling the parent constructor, since that assumes annotation-based // Skip calling the parent constructor, since that assumes annotation-based
// discovery. // discovery.
$this->discovery = new YamlDiscovery('links.action', $module_handler->getModuleDirectories()); $this->discovery = new YamlDiscovery('links.action', $module_handler->getModuleDirectories());
@ -120,6 +130,7 @@ class LocalActionManager extends DefaultPluginManager implements LocalActionMana
$this->factory = new ContainerFactory($this, 'Drupal\Core\Menu\LocalActionInterface'); $this->factory = new ContainerFactory($this, 'Drupal\Core\Menu\LocalActionInterface');
$this->controllerResolver = $controller_resolver; $this->controllerResolver = $controller_resolver;
$this->requestStack = $request_stack; $this->requestStack = $request_stack;
$this->routeMatch = $route_match;
$this->routeProvider = $route_provider; $this->routeProvider = $route_provider;
$this->accessManager = $access_manager; $this->accessManager = $access_manager;
$this->moduleHandler = $module_handler; $this->moduleHandler = $module_handler;
@ -159,16 +170,16 @@ class LocalActionManager extends DefaultPluginManager implements LocalActionMana
} }
} }
$links = array(); $links = array();
$request = $this->requestStack->getCurrentRequest(); /** @var $plugin \Drupal\Core\Menu\LocalActionInterface */
foreach ($this->instances[$route_appears] as $plugin_id => $plugin) { foreach ($this->instances[$route_appears] as $plugin_id => $plugin) {
$route_name = $plugin->getRouteName(); $route_name = $plugin->getRouteName();
$route_parameters = $plugin->getRouteParameters($request); $route_parameters = $plugin->getRouteParameters($this->routeMatch);
$links[$plugin_id] = array( $links[$plugin_id] = array(
'#theme' => 'menu_local_action', '#theme' => 'menu_local_action',
'#link' => array( '#link' => array(
'title' => $this->getTitle($plugin), 'title' => $this->getTitle($plugin),
'url' => Url::fromRoute($route_name, $route_parameters), 'url' => Url::fromRoute($route_name, $route_parameters),
'localized_options' => $plugin->getOptions($request), 'localized_options' => $plugin->getOptions($this->routeMatch),
), ),
'#access' => $this->accessManager->checkNamedRoute($route_name, $route_parameters, $this->account), '#access' => $this->accessManager->checkNamedRoute($route_name, $route_parameters, $this->account),
'#weight' => $plugin->getWeight(), '#weight' => $plugin->getWeight(),

View File

@ -8,6 +8,7 @@
namespace Drupal\Core\Menu; namespace Drupal\Core\Menu;
use Drupal\Core\Plugin\PluginBase; use Drupal\Core\Plugin\PluginBase;
use Drupal\Core\Routing\RouteMatchInterface;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
/** /**
@ -39,7 +40,7 @@ class LocalTaskDefault extends PluginBase implements LocalTaskInterface {
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function getRouteParameters(Request $request) { public function getRouteParameters(RouteMatchInterface $route_match) {
$parameters = isset($this->pluginDefinition['route_parameters']) ? $this->pluginDefinition['route_parameters'] : array(); $parameters = isset($this->pluginDefinition['route_parameters']) ? $this->pluginDefinition['route_parameters'] : array();
$route = $this->routeProvider()->getRouteByName($this->getRouteName()); $route = $this->routeProvider()->getRouteByName($this->getRouteName());
$variables = $route->compile()->getVariables(); $variables = $route->compile()->getVariables();
@ -51,7 +52,7 @@ class LocalTaskDefault extends PluginBase implements LocalTaskInterface {
// /filter/tips/{filter_format} and the path is /filter/tips/plain_text then // /filter/tips/{filter_format} and the path is /filter/tips/plain_text then
// $raw_variables->get('filter_format') == 'plain_text'. // $raw_variables->get('filter_format') == 'plain_text'.
$raw_variables = $request->attributes->get('_raw_variables'); $raw_variables = $route_match->getRawParameters();
foreach ($variables as $name) { foreach ($variables as $name) {
if (isset($parameters[$name])) { if (isset($parameters[$name])) {
@ -61,8 +62,8 @@ class LocalTaskDefault extends PluginBase implements LocalTaskInterface {
if ($raw_variables && $raw_variables->has($name)) { if ($raw_variables && $raw_variables->has($name)) {
$parameters[$name] = $raw_variables->get($name); $parameters[$name] = $raw_variables->get($name);
} }
elseif ($request->attributes->has($name)) { elseif ($value = $route_match->getRawParameter($name)) {
$parameters[$name] = $request->attributes->get($name); $parameters[$name] = $value;
} }
} }
// The UrlGenerator will throw an exception if expected parameters are // The UrlGenerator will throw an exception if expected parameters are
@ -109,7 +110,7 @@ class LocalTaskDefault extends PluginBase implements LocalTaskInterface {
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function getOptions(Request $request) { public function getOptions(RouteMatchInterface $route_match) {
$options = $this->pluginDefinition['options']; $options = $this->pluginDefinition['options'];
if ($this->active) { if ($this->active) {
if (empty($options['attributes']['class']) || !in_array('active', $options['attributes']['class'])) { if (empty($options['attributes']['class']) || !in_array('active', $options['attributes']['class'])) {

View File

@ -7,7 +7,7 @@
namespace Drupal\Core\Menu; namespace Drupal\Core\Menu;
use Symfony\Component\HttpFoundation\Request; use Drupal\Core\Routing\RouteMatchInterface;
/** /**
* Defines an interface for menu local tasks. * Defines an interface for menu local tasks.
@ -36,13 +36,13 @@ interface LocalTaskInterface {
/** /**
* Returns the route parameters needed to render a link for the local task. * Returns the route parameters needed to render a link for the local task.
* *
* @param \Symfony\Component\HttpFoundation\Request $request * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
* The HttpRequest object representing the current request. * The current route match.
* *
* @return array * @return array
* An array of parameter names and values. * An array of parameter names and values.
*/ */
public function getRouteParameters(Request $request); public function getRouteParameters(RouteMatchInterface $route_match);
/** /**
* Returns the weight of the local task. * Returns the weight of the local task.
@ -55,13 +55,13 @@ interface LocalTaskInterface {
/** /**
* Returns options for rendering a link to the local task. * Returns options for rendering a link to the local task.
* *
* @param \Symfony\Component\HttpFoundation\Request $request * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
* The HttpRequest object representing the current request. * The current route match.
* *
* @return array * @return array
* An associative array of options. * An associative array of options.
*/ */
public function getOptions(Request $request); public function getOptions(RouteMatchInterface $route_match);
/** /**
* Sets the active status. * Sets the active status.

View File

@ -11,6 +11,7 @@ use Drupal\Component\Plugin\Exception\PluginException;
use Drupal\Core\Access\AccessManagerInterface; use Drupal\Core\Access\AccessManagerInterface;
use Drupal\Core\Cache\Cache; use Drupal\Core\Cache\Cache;
use Drupal\Core\Cache\CacheBackendInterface; use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Cache\NullBackend;
use Drupal\Core\Controller\ControllerResolverInterface; use Drupal\Core\Controller\ControllerResolverInterface;
use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Language\LanguageManagerInterface; use Drupal\Core\Language\LanguageManagerInterface;
@ -19,6 +20,7 @@ use Drupal\Core\Plugin\Discovery\ContainerDerivativeDiscoveryDecorator;
use Drupal\Core\Plugin\Discovery\YamlDiscovery; use Drupal\Core\Plugin\Discovery\YamlDiscovery;
use Drupal\Core\Plugin\Factory\ContainerFactory; use Drupal\Core\Plugin\Factory\ContainerFactory;
use Drupal\Core\Routing\RouteBuilderInterface; use Drupal\Core\Routing\RouteBuilderInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Routing\RouteProviderInterface; use Drupal\Core\Routing\RouteProviderInterface;
use Drupal\Core\Session\AccountInterface; use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Url; use Drupal\Core\Url;
@ -67,6 +69,13 @@ class LocalTaskManager extends DefaultPluginManager implements LocalTaskManagerI
*/ */
protected $requestStack; protected $requestStack;
/**
* The current route match.
*
* @var \Drupal\Core\Routing\RouteMatchInterface
*/
protected $routeMatch;
/** /**
* The plugin instances. * The plugin instances.
* *
@ -109,6 +118,8 @@ class LocalTaskManager extends DefaultPluginManager implements LocalTaskManagerI
* An object to use in introspecting route methods. * An object to use in introspecting route methods.
* @param \Symfony\Component\HttpFoundation\RequestStack $request_stack * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
* The request object to use for building titles and paths for plugin instances. * The request object to use for building titles and paths for plugin instances.
* @param \Drupal\Core\Routing\RouteMatchInterface $route_match
* The current route match.
* @param \Drupal\Core\Routing\RouteProviderInterface $route_provider * @param \Drupal\Core\Routing\RouteProviderInterface $route_provider
* The route provider to load routes by name. * The route provider to load routes by name.
* @param \Drupal\Core\Routing\RouteBuilderInterface $route_builder * @param \Drupal\Core\Routing\RouteBuilderInterface $route_builder
@ -124,12 +135,13 @@ class LocalTaskManager extends DefaultPluginManager implements LocalTaskManagerI
* @param \Drupal\Core\Session\AccountInterface $account * @param \Drupal\Core\Session\AccountInterface $account
* The current user. * The current user.
*/ */
public function __construct(ControllerResolverInterface $controller_resolver, RequestStack $request_stack, RouteProviderInterface $route_provider, RouteBuilderInterface $route_builder, ModuleHandlerInterface $module_handler, CacheBackendInterface $cache, LanguageManagerInterface $language_manager, AccessManagerInterface $access_manager, AccountInterface $account) { public function __construct(ControllerResolverInterface $controller_resolver, RequestStack $request_stack, RouteMatchInterface $route_match, RouteProviderInterface $route_provider, RouteBuilderInterface $route_builder, ModuleHandlerInterface $module_handler, CacheBackendInterface $cache, LanguageManagerInterface $language_manager, AccessManagerInterface $access_manager, AccountInterface $account) {
$this->discovery = new YamlDiscovery('links.task', $module_handler->getModuleDirectories()); $this->discovery = new YamlDiscovery('links.task', $module_handler->getModuleDirectories());
$this->discovery = new ContainerDerivativeDiscoveryDecorator($this->discovery); $this->discovery = new ContainerDerivativeDiscoveryDecorator($this->discovery);
$this->factory = new ContainerFactory($this, '\Drupal\Core\Menu\LocalTaskInterface'); $this->factory = new ContainerFactory($this, '\Drupal\Core\Menu\LocalTaskInterface');
$this->controllerResolver = $controller_resolver; $this->controllerResolver = $controller_resolver;
$this->requestStack = $request_stack; $this->requestStack = $request_stack;
$this->routeMatch = $route_match;
$this->routeProvider = $route_provider; $this->routeProvider = $route_provider;
$this->routeBuilder = $route_builder; $this->routeBuilder = $route_builder;
$this->accessManager = $access_manager; $this->accessManager = $access_manager;
@ -289,11 +301,11 @@ class LocalTaskManager extends DefaultPluginManager implements LocalTaskManagerI
// of SQL queries that would otherwise be triggered by the access manager. // of SQL queries that would otherwise be triggered by the access manager.
$routes = $route_names ? $this->routeProvider->getRoutesByNames($route_names) : array(); $routes = $route_names ? $this->routeProvider->getRoutesByNames($route_names) : array();
$request = $this->requestStack->getCurrentRequest();
foreach ($tree as $level => $instances) { foreach ($tree as $level => $instances) {
/** @var $instances \Drupal\Core\Menu\LocalTaskInterface[] */
foreach ($instances as $plugin_id => $child) { foreach ($instances as $plugin_id => $child) {
$route_name = $child->getRouteName(); $route_name = $child->getRouteName();
$route_parameters = $child->getRouteParameters($request); $route_parameters = $child->getRouteParameters($this->routeMatch);
// Find out whether the user has access to the task. // Find out whether the user has access to the task.
$access = $this->accessManager->checkNamedRoute($route_name, $route_parameters, $this->account); $access = $this->accessManager->checkNamedRoute($route_name, $route_parameters, $this->account);
@ -308,7 +320,7 @@ class LocalTaskManager extends DefaultPluginManager implements LocalTaskManagerI
$link = array( $link = array(
'title' => $this->getTitle($child), 'title' => $this->getTitle($child),
'url' => Url::fromRoute($route_name, $route_parameters), 'url' => Url::fromRoute($route_name, $route_parameters),
'localized_options' => $child->getOptions($request), 'localized_options' => $child->getOptions($this->routeMatch),
); );
$build[$level][$plugin_id] = array( $build[$level][$plugin_id] = array(
'#theme' => 'menu_local_task', '#theme' => 'menu_local_task',
@ -340,14 +352,13 @@ class LocalTaskManager extends DefaultPluginManager implements LocalTaskManagerI
// Flag the list element as active if this tab's route and parameters match // Flag the list element as active if this tab's route and parameters match
// the current request's route and route variables. // the current request's route and route variables.
$active = $current_route_name == $route_name; $active = $current_route_name == $route_name;
$request = $this->requestStack->getCurrentRequest();
if ($active) { if ($active) {
// The request is injected, so we need to verify that we have the expected // The request is injected, so we need to verify that we have the expected
// _raw_variables attribute. // _raw_variables attribute.
$raw_variables_bag = $request->attributes->get('_raw_variables'); $raw_variables_bag = $this->routeMatch->getRawParameters();
// If we don't have _raw_variables, we assume the attributes are still the // If we don't have _raw_variables, we assume the attributes are still the
// original values. // original values.
$raw_variables = $raw_variables_bag ? $raw_variables_bag->all() : $request->attributes->all(); $raw_variables = $raw_variables_bag ? $raw_variables_bag->all() : $this->routeMatch->getParameters()->all();
$active = array_intersect_assoc($route_parameters, $raw_variables) == $route_parameters; $active = array_intersect_assoc($route_parameters, $raw_variables) == $route_parameters;
} }
return $active; return $active;

View File

@ -8,8 +8,7 @@
namespace Drupal\block_content\Plugin\Menu\LocalAction; namespace Drupal\block_content\Plugin\Menu\LocalAction;
use Drupal\Core\Menu\LocalActionDefault; use Drupal\Core\Menu\LocalActionDefault;
use Symfony\Cmf\Component\Routing\RouteObjectInterface; use Drupal\Core\Routing\RouteMatchInterface;
use Symfony\Component\HttpFoundation\Request;
/** /**
* Modifies the 'Add custom block' local action. * Modifies the 'Add custom block' local action.
@ -19,18 +18,14 @@ class BlockContentAddLocalAction extends LocalActionDefault {
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function getOptions(Request $request) { public function getOptions(RouteMatchInterface $route_match) {
$options = parent::getOptions($request); $options = parent::getOptions($route_match);
// If the route specifies a theme, append it to the query string. // If the route specifies a theme, append it to the query string.
if ($request->attributes->has('theme')) { if ($theme = $route_match->getParameter('theme')) {
$options['query']['theme'] = $request->attributes->get('theme'); $options['query']['theme'] = $theme;
} }
// Adds a destination on custom block listing. // Adds a destination on custom block listing.
if ($request->attributes->get(RouteObjectInterface::ROUTE_NAME) == 'block_content.list') { if ($route_match->getRouteName() == 'block_content.list') {
$options['query']['destination'] = 'admin/structure/block/block-content';
}
// Adds a destination on custom block listing.
if ($request->attributes->get(RouteObjectInterface::ROUTE_NAME) == 'block_content.list') {
$options['query']['destination'] = 'admin/structure/block/block-content'; $options['query']['destination'] = 'admin/structure/block/block-content';
} }
return $options; return $options;

View File

@ -8,8 +8,8 @@
namespace Drupal\menu_ui\Plugin\Menu\LocalAction; namespace Drupal\menu_ui\Plugin\Menu\LocalAction;
use Drupal\Core\Menu\LocalActionDefault; use Drupal\Core\Menu\LocalActionDefault;
use Symfony\Cmf\Component\Routing\RouteObjectInterface; use Drupal\Core\Routing\RouteMatchInterface;
use Symfony\Component\HttpFoundation\Request; use Drupal\Core\Url;
/** /**
* Modifies the 'Add link' local action to add a destination. * Modifies the 'Add link' local action to add a destination.
@ -19,18 +19,11 @@ class MenuLinkAdd extends LocalActionDefault {
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function getOptions(Request $request) { public function getOptions(RouteMatchInterface $route_match) {
$options = parent::getOptions($request); $options = parent::getOptions($route_match);
// Append the current path as destination to the query string. // Append the current path as destination to the query string.
if ($request->attributes->has(RouteObjectInterface::ROUTE_NAME)) { if ($route_name = $route_match->getRouteName()) {
$route_name = $request->attributes->get(RouteObjectInterface::ROUTE_NAME); $options['query']['destination'] = Url::fromRoute($route_name, $route_match->getRawParameters()->all())->toString();
$raw_variables = array();
if ($request->attributes->has('_raw_variables')) {
$raw_variables = $request->attributes->get('_raw_variables')->all();
}
// @todo Use RouteMatch instead of Request.
// https://www.drupal.org/node/2294157
$options['query']['destination'] = \Drupal::urlGenerator()->generateFromRoute($route_name, $raw_variables);
} }
return $options; return $options;
} }

View File

@ -8,7 +8,7 @@
namespace Drupal\tracker\Plugin\Menu; namespace Drupal\tracker\Plugin\Menu;
use Drupal\Core\Menu\LocalTaskDefault; use Drupal\Core\Menu\LocalTaskDefault;
use Symfony\Component\HttpFoundation\Request; use Drupal\Core\Routing\RouteMatchInterface;
/** /**
* Provides route parameters needed to link to the current user tracker tab. * Provides route parameters needed to link to the current user tracker tab.
@ -41,7 +41,7 @@ class UserTrackerTab extends LocalTaskDefault {
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function getRouteParameters(Request $request) { public function getRouteParameters(RouteMatchInterface $route_match) {
return array('user' => $this->currentUser()->Id()); return array('user' => $this->currentUser()->Id());
} }

View File

@ -14,6 +14,7 @@ use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Language\Language; use Drupal\Core\Language\Language;
use Drupal\Core\Menu\LocalActionManager; use Drupal\Core\Menu\LocalActionManager;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Routing\RouteProviderInterface; use Drupal\Core\Routing\RouteProviderInterface;
use Drupal\Core\Session\AccountInterface; use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Url; use Drupal\Core\Url;
@ -115,8 +116,9 @@ class LocalActionManagerTest extends UnitTestCase {
$this->account = $this->getMock('Drupal\Core\Session\AccountInterface'); $this->account = $this->getMock('Drupal\Core\Session\AccountInterface');
$this->discovery = $this->getMock('Drupal\Component\Plugin\Discovery\DiscoveryInterface'); $this->discovery = $this->getMock('Drupal\Component\Plugin\Discovery\DiscoveryInterface');
$this->factory = $this->getMock('Drupal\Component\Plugin\Factory\FactoryInterface'); $this->factory = $this->getMock('Drupal\Component\Plugin\Factory\FactoryInterface');
$route_match = $this->getMock('Drupal\Core\Routing\RouteMatchInterface');
$this->localActionManager = new TestLocalActionManager($this->controllerResolver, $this->request, $this->routeProvider, $this->moduleHandler, $this->cacheBackend, $this->accessManager, $this->account, $this->discovery, $this->factory); $this->localActionManager = new TestLocalActionManager($this->controllerResolver, $this->request, $route_match, $this->routeProvider, $this->moduleHandler, $this->cacheBackend, $this->accessManager, $this->account, $this->discovery, $this->factory);
} }
/** /**
@ -339,7 +341,7 @@ class LocalActionManagerTest extends UnitTestCase {
class TestLocalActionManager extends LocalActionManager { class TestLocalActionManager extends LocalActionManager {
public function __construct(ControllerResolverInterface $controller_resolver, Request $request, RouteProviderInterface $route_provider, ModuleHandlerInterface $module_handler, CacheBackendInterface $cache_backend, AccessManagerInterface $access_manager, AccountInterface $account, DiscoveryInterface $discovery, FactoryInterface $factory) { public function __construct(ControllerResolverInterface $controller_resolver, Request $request, RouteMatchInterface $route_match, RouteProviderInterface $route_provider, ModuleHandlerInterface $module_handler, CacheBackendInterface $cache_backend, AccessManagerInterface $access_manager, AccountInterface $account, DiscoveryInterface $discovery, FactoryInterface $factory) {
$this->discovery = $discovery; $this->discovery = $discovery;
$this->factory = $factory; $this->factory = $factory;
$this->routeProvider = $route_provider; $this->routeProvider = $route_provider;
@ -348,6 +350,7 @@ class TestLocalActionManager extends LocalActionManager {
$this->controllerResolver = $controller_resolver; $this->controllerResolver = $controller_resolver;
$this->requestStack = new RequestStack(); $this->requestStack = new RequestStack();
$this->requestStack->push($request); $this->requestStack->push($request);
$this->routeMatch = $route_match;
$this->moduleHandler = $module_handler; $this->moduleHandler = $module_handler;
$this->alterInfo('menu_local_actions'); $this->alterInfo('menu_local_actions');
$this->setCacheBackend($cache_backend, 'local_action_plugins', array('local_action')); $this->setCacheBackend($cache_backend, 'local_action_plugins', array('local_action'));

View File

@ -8,9 +8,9 @@
namespace Drupal\Tests\Core\Menu; namespace Drupal\Tests\Core\Menu;
use Drupal\Core\Menu\LocalTaskDefault; use Drupal\Core\Menu\LocalTaskDefault;
use Drupal\Core\Routing\RouteMatch;
use Drupal\Core\Routing\RouteProviderInterface; use Drupal\Core\Routing\RouteProviderInterface;
use Drupal\Tests\UnitTestCase; use Drupal\Tests\UnitTestCase;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Route; use Symfony\Component\Routing\Route;
@ -99,8 +99,8 @@ class LocalTaskDefaultTest extends UnitTestCase {
$this->setupLocalTaskDefault(); $this->setupLocalTaskDefault();
$request = Request::create('/'); $route_match = new RouteMatch('', new Route('/'));
$this->assertEquals(array(), $this->localTaskBase->getRouteParameters($request)); $this->assertEquals(array(), $this->localTaskBase->getRouteParameters($route_match));
} }
/** /**
@ -119,9 +119,8 @@ class LocalTaskDefaultTest extends UnitTestCase {
$this->setupLocalTaskDefault(); $this->setupLocalTaskDefault();
$request = new Request(); $route_match = new RouteMatch('', new Route('/'));
$this->assertEquals(array('parameter' => 'example'), $this->localTaskBase->getRouteParameters($route_match));
$this->assertEquals(array('parameter' => 'example'), $this->localTaskBase->getRouteParameters($request));
} }
/** /**
@ -134,16 +133,17 @@ class LocalTaskDefaultTest extends UnitTestCase {
'route_name' => 'test_route' 'route_name' => 'test_route'
); );
$route = new Route('/test-route/{parameter}');
$this->routeProvider->expects($this->once()) $this->routeProvider->expects($this->once())
->method('getRouteByName') ->method('getRouteByName')
->with('test_route') ->with('test_route')
->will($this->returnValue(new Route('/test-route/{parameter}'))); ->will($this->returnValue($route));
$this->setupLocalTaskDefault(); $this->setupLocalTaskDefault();
$request = new Request(array(), array(), array('parameter' => 'example')); $route_match = new RouteMatch('', $route, array(), array('parameter' => 'example'));
$this->assertEquals(array('parameter' => 'example'), $this->localTaskBase->getRouteParameters($request)); $this->assertEquals(array('parameter' => 'example'), $this->localTaskBase->getRouteParameters($route_match));
} }
/** /**
@ -156,20 +156,16 @@ class LocalTaskDefaultTest extends UnitTestCase {
'route_name' => 'test_route' 'route_name' => 'test_route'
); );
$route = new Route('/test-route/{parameter}');
$this->routeProvider->expects($this->once()) $this->routeProvider->expects($this->once())
->method('getRouteByName') ->method('getRouteByName')
->with('test_route') ->with('test_route')
->will($this->returnValue(new Route('/test-route/{parameter}'))); ->will($this->returnValue($route));
$this->setupLocalTaskDefault(); $this->setupLocalTaskDefault();
$request = new Request(); $route_match = new RouteMatch('', $route, array('parameter' => (object) 'example2'), array('parameter' => 'example'));
$raw_variables = new ParameterBag(); $this->assertEquals(array('parameter' => 'example'), $this->localTaskBase->getRouteParameters($route_match));
$raw_variables->set('parameter', 'example');
$request->attributes->set('parameter', (object) array('example2'));
$request->attributes->set('_raw_variables', $raw_variables);
$this->assertEquals(array('parameter' => 'example'), $this->localTaskBase->getRouteParameters($request));
} }
/** /**
@ -307,8 +303,8 @@ class LocalTaskDefaultTest extends UnitTestCase {
$this->setupLocalTaskDefault(); $this->setupLocalTaskDefault();
$request = Request::create('/'); $route_match = new RouteMatch('', new Route('/'));
$this->assertEquals($this->pluginDefinition['options'], $this->localTaskBase->getOptions($request)); $this->assertEquals($this->pluginDefinition['options'], $this->localTaskBase->getOptions($route_match));
$this->localTaskBase->setActive(TRUE); $this->localTaskBase->setActive(TRUE);
@ -319,7 +315,7 @@ class LocalTaskDefaultTest extends UnitTestCase {
'active' 'active'
) )
) )
), $this->localTaskBase->getOptions($request)); ), $this->localTaskBase->getOptions($route_match));
} }
} }

View File

@ -84,6 +84,13 @@ class LocalTaskManagerTest extends UnitTestCase {
*/ */
protected $accessManager; protected $accessManager;
/**
* The route match.
*
* @var \Drupal\Core\Routing\RouteMatchInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $routeMatch;
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
@ -98,6 +105,7 @@ class LocalTaskManagerTest extends UnitTestCase {
$this->factory = $this->getMock('Drupal\Component\Plugin\Factory\FactoryInterface'); $this->factory = $this->getMock('Drupal\Component\Plugin\Factory\FactoryInterface');
$this->cacheBackend = $this->getMock('Drupal\Core\Cache\CacheBackendInterface'); $this->cacheBackend = $this->getMock('Drupal\Core\Cache\CacheBackendInterface');
$this->accessManager = $this->getMock('Drupal\Core\Access\AccessManagerInterface'); $this->accessManager = $this->getMock('Drupal\Core\Access\AccessManagerInterface');
$this->routeMatch = $this->getMock('Drupal\Core\Routing\RouteMatchInterface');
$this->setupLocalTaskManager(); $this->setupLocalTaskManager();
} }
@ -256,7 +264,7 @@ class LocalTaskManagerTest extends UnitTestCase {
->will($this->returnValue(new Language(array('id' => 'en')))); ->will($this->returnValue(new Language(array('id' => 'en'))));
$account = $this->getMock('Drupal\Core\Session\AccountInterface'); $account = $this->getMock('Drupal\Core\Session\AccountInterface');
$this->manager = new LocalTaskManager($this->controllerResolver, $request_stack, $this->routeProvider, $this->routeBuilder, $module_handler, $this->cacheBackend, $language_manager, $this->accessManager, $account); $this->manager = new LocalTaskManager($this->controllerResolver, $request_stack, $this->routeMatch, $this->routeProvider, $this->routeBuilder, $module_handler, $this->cacheBackend, $language_manager, $this->accessManager, $account);
$property = new \ReflectionProperty('Drupal\Core\Menu\LocalTaskManager', 'discovery'); $property = new \ReflectionProperty('Drupal\Core\Menu\LocalTaskManager', 'discovery');
$property->setAccessible(TRUE); $property->setAccessible(TRUE);