diff -u b/core/core.services.yml b/core/core.services.yml --- b/core/core.services.yml +++ b/core/core.services.yml @@ -479,7 +479,7 @@ class: Drupal\Core\EventSubscriber\RouterListener tags: - { name: event_subscriber } - arguments: ['@router', '@route_match_stack'] + arguments: ['@router', '@route_match_stack', '@request_stack', '@router.request_context'] content_negotiation: class: Drupal\Core\ContentNegotiation view_subscriber: reverted: --- b/core/includes/install.core.inc +++ a/core/includes/install.core.inc @@ -19,11 +19,9 @@ use Drupal\Core\StringTranslation\Translator\FileTranslation; use Drupal\Core\Extension\ExtensionDiscovery; use Drupal\Core\DependencyInjection\ContainerBuilder; -use Drupal\Core\Routing\RouteMatch; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\Routing\Route; use GuzzleHttp\Exception\RequestException; @@ -370,7 +368,6 @@ $container->enterScope('request'); $container->set('request', $request, 'request'); $container->get('request_stack')->push($request); - $container->get('route_match_stack')->push(new RouteMatch('', new Route(''))); // Register the file translation service. if (isset($GLOBALS['config']['locale.settings']['translation.path'])) { diff -u b/core/lib/Drupal/Core/EventSubscriber/RouterListener.php b/core/lib/Drupal/Core/EventSubscriber/RouterListener.php --- b/core/lib/Drupal/Core/EventSubscriber/RouterListener.php +++ b/core/lib/Drupal/Core/EventSubscriber/RouterListener.php @@ -7,11 +7,13 @@ namespace Drupal\Core\EventSubscriber; +use Drupal\Core\Routing\NullRouteMatch; use Drupal\Core\Routing\RouteMatch; use Drupal\Core\Routing\RouteMatchStack; use Symfony\Cmf\Component\Routing\RouteObjectInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpKernel\Event\FinishRequestEvent; use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException; @@ -20,7 +22,7 @@ use Symfony\Component\Routing\Exception\MethodNotAllowedException; use Symfony\Component\Routing\Exception\ResourceNotFoundException; use Symfony\Component\Routing\Matcher\RequestMatcherInterface; -use Symfony\Component\Routing\Route; +use Symfony\Component\Routing\RequestContext; /** * Performs routing. @@ -29,6 +31,8 @@ protected $matcher; protected $routeMatchStack; + protected $requestStack; + protected $requestContext; /** * Constructor. @@ -37,10 +41,16 @@ * The Request matcher. * @param \Drupal\Core\Routing\RouteMatchStack $route_match_stack * The RouteMatch stack. + * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack + * The request stack. + * @param \Symfony\Component\Routing\RequestContext $request_context + * The request context. */ - public function __construct(RequestMatcherInterface $matcher, RouteMatchStack $route_match_stack) { + public function __construct(RequestMatcherInterface $matcher, RouteMatchStack $route_match_stack, RequestStack $request_stack, RequestContext $request_context) { $this->matcher = $matcher; $this->routeMatchStack = $route_match_stack; + $this->requestStack = $request_stack; + $this->requestContext = $request_context; } /** @@ -55,14 +65,19 @@ public function onKernelRequest(GetResponseEvent $event) { $request = $event->getRequest(); + // Initialize the context that is also used by other services, such as the + // URL generator, if they share the same context instance. + $this->requestContext->fromRequest($request); + + // We might return early or throw an exception prior to calling + // processRouteArguments(), but we need something pushed onto the stack + // in all cases. + $this->routeMatchStack->push(new NullRouteMatch()); + // The controller might already be set, for example, as part of handling a // subrequest from an exception handler (@see // \Symfony\Component\HttpKernel\EventListener\ExceptionListener). if ($request->attributes->has('_controller')) { - // If we're skipping routing, then we still need to push something onto - // the route match stack. - // @todo Would pushing NULL be better than a fake RouteMatch? - $this->routeMatchStack->push(new RouteMatch('', new Route(''))); return; } @@ -114,6 +129,10 @@ } } $route_match = new RouteMatch($route_name, $route, $arguments, $raw_arguments); + + // Now that we have a route match, replace the NULL item that was added at + // the beginning of onKernelRequest(). + $this->routeMatchStack->pop(); $this->routeMatchStack->push($route_match); // @todo Remove. See https://drupal.org/node/2124749. @@ -121,16 +140,16 @@ } /** - * Pops the route match stack when the request is finished. + * Synchronizes route match stack and request context to the parent request. * * @param \Symfony\Component\HttpKernel\Event\FinishRequestEvent $event * The Event to process. */ public function onKernelFinishRequest(FinishRequestEvent $event) { $this->routeMatchStack->pop(); + $this->requestContext->fromRequest($this->requestStack->getParentRequest()); } - /** * {@inheritdoc} */ diff -u b/core/lib/Drupal/Core/Routing/RouteMatch.php b/core/lib/Drupal/Core/Routing/RouteMatch.php --- b/core/lib/Drupal/Core/Routing/RouteMatch.php +++ b/core/lib/Drupal/Core/Routing/RouteMatch.php @@ -2,7 +2,7 @@ /** * @file - * Contains Drupal\Core\Routing\RouteMatchStack. + * Contains Drupal\Core\Routing\RouteMatch. */ namespace Drupal\Core\Routing; diff -u b/core/lib/Drupal/Core/Routing/RouteMatchStack.php b/core/lib/Drupal/Core/Routing/RouteMatchStack.php --- b/core/lib/Drupal/Core/Routing/RouteMatchStack.php +++ b/core/lib/Drupal/Core/Routing/RouteMatchStack.php @@ -22,6 +22,7 @@ * @see Symfony\Component\HttpFoundation\RequestStack * */ + class RouteMatchStack { protected $routeMatches = array(); @@ -31,11 +32,11 @@ } public function pop() { - return array_pop($this->routeMatches); + array_pop($this->routeMatches); } public function getCurrentRouteMatch() { - return end($this->routeMatches) ?: NULL; + return end($this->routeMatches) ?: new NullRouteMatch(); } } only in patch2: unchanged: --- /dev/null +++ b/core/lib/Drupal/Core/Routing/NullRouteMatch.php @@ -0,0 +1,21 @@ +routeName = NULL; + $this->route = NULL; + $this->arguments = new ParameterBag(); + $this->rawArguments = new ParameterBag(); + } + +}