From 47e0233492e1f64fd92972088d01591f1ccccbd8 Mon Sep 17 00:00:00 2001 From: Larry Garfield Date: Thu, 19 Apr 2012 01:00:47 -0500 Subject: [PATCH] Switch to a new UrlMatcher and RouterListener so that we can use a full Request object for routing purposes, and look to the attributes for our main routing information. --- core/lib/Drupal/Core/DrupalKernel.php | 6 +- .../Core/EventSubscriber/RouterListener.php | 28 +++++++++ core/lib/Drupal/Core/UrlMatcher.php | 62 ++++++++++++++++--- 3 files changed, 84 insertions(+), 12 deletions(-) create mode 100644 core/lib/Drupal/Core/EventSubscriber/RouterListener.php diff --git a/core/lib/Drupal/Core/DrupalKernel.php b/core/lib/Drupal/Core/DrupalKernel.php index 26ff906b3f3..00b1d086dda 100644 --- a/core/lib/Drupal/Core/DrupalKernel.php +++ b/core/lib/Drupal/Core/DrupalKernel.php @@ -17,7 +17,7 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\EventDispatcher\Event; use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface; use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; -use Symfony\Component\HttpKernel\EventListener\RouterListener; +//use Symfony\Component\HttpKernel\EventListener\RouterListener; use Symfony\Component\HttpKernel\EventListener\ExceptionListener; use Drupal\Core\EventSubscriber\ViewSubscriber; use Drupal\Core\EventSubscriber\AccessSubscriber; @@ -25,6 +25,7 @@ use Drupal\Core\EventSubscriber\PathSubscriber; use Drupal\Core\EventSubscriber\LegacyControllerSubscriber; use Drupal\Core\EventSubscriber\MaintenanceModeSubscriber; use Drupal\Core\EventSubscriber\RequestCloseSubscriber; +use Drupal\Core\EventSubscriber\RouterListener; use Exception; @@ -61,8 +62,7 @@ class DrupalKernel extends HttpKernel { $this->dispatcher = $dispatcher; $this->resolver = $resolver; - $context = new RequestContext(); - $this->matcher = new UrlMatcher($context); + $this->matcher = new UrlMatcher(); $this->dispatcher->addSubscriber(new RouterListener($this->matcher)); $negotiation = new ContentNegotiation(); diff --git a/core/lib/Drupal/Core/EventSubscriber/RouterListener.php b/core/lib/Drupal/Core/EventSubscriber/RouterListener.php new file mode 100644 index 00000000000..d4b5dc5a0a8 --- /dev/null +++ b/core/lib/Drupal/Core/EventSubscriber/RouterListener.php @@ -0,0 +1,28 @@ +urlMatcher = $urlMatcher; + } + + public function onKernelRequest(GetResponseEvent $event) { + $this->urlMatcher->setRequest($event->getRequest()); + parent::onKernelRequest($event); + } + +} diff --git a/core/lib/Drupal/Core/UrlMatcher.php b/core/lib/Drupal/Core/UrlMatcher.php index 585fc45512e..4ed1c75bc98 100644 --- a/core/lib/Drupal/Core/UrlMatcher.php +++ b/core/lib/Drupal/Core/UrlMatcher.php @@ -8,8 +8,10 @@ namespace Drupal\Core; +use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Exception\MethodNotAllowedException; use Symfony\Component\Routing\Exception\ResourceNotFoundException; +use Symfony\Component\Routing\Matcher\UrlMatcherInterface; use Symfony\Component\Routing\Matcher\UrlMatcher as SymfonyUrlMatcher; use Symfony\Component\Routing\RequestContext; use Symfony\Component\Routing\Route; @@ -18,7 +20,7 @@ use Symfony\Component\Routing\RouteCollection; /** * UrlMatcher matches URL based on a set of routes. */ -class UrlMatcher extends SymfonyUrlMatcher { +class UrlMatcher implements UrlMatcherInterface { /** * The request context for this matcher. @@ -28,15 +30,56 @@ class UrlMatcher extends SymfonyUrlMatcher { protected $context; /** - * Constructor. + * The request object for this matcher. * - * @param RequestContext $context - * The request context object. + * @var Symfony\Component\HttpFoundation\Request */ - public function __construct(RequestContext $context) { + protected $request; + + public function __construct() { + // We will not actually use this object, but it's needed to conform to + // the interface. + $this->context = new RequestContext(); + } + + /** + * Sets the request context. + * + * This method is just to satisfy the interface, and is largely vestigial. + * The request context object does not contain the information we need, so + * we will use the original request object. + * + * @param RequestContext $context + * The context + * + * @api + */ + public function setContext(RequestContext $context) { $this->context = $context; } + /** + * Gets the request context. + * + * This method is just to satisfy the interface, and is largely vestigial. + * The request context object does not contain the information we need, so + * we will use the original request object. + * + * @return RequestContext + * The context + */ + public function getContext() { + return $this->context; + } + + public function setRequest(Request $request) { + $this->request = $request; + } + + public function getRequest() { + return $this->request; + } + /** * {@inheritDoc} * @@ -44,15 +87,16 @@ class UrlMatcher extends SymfonyUrlMatcher { */ public function match($pathinfo) { - $this->allow = array(); + $dpathinfo = $this->request->attributes->get('system_path'); - // Symfony uses a prefixing / but we don't yet. - $dpathinfo = ltrim($pathinfo, '/'); + if (!$dpathinfo) { + // Symfony uses a prefixing / but we don't yet. + $dpathinfo = ltrim($pathinfo, '/'); + } // Do our fancy frontpage logic. if (empty($dpathinfo)) { $dpathinfo = variable_get('site_frontpage', 'user'); - $pathinfo = '/' . $dpathinfo; } if ($router_item = $this->matchDrupalItem($dpathinfo)) {