diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/routing.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/routing.xml index 78aedcc0ca..d4d181a8fd 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/routing.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/routing.xml @@ -89,6 +89,7 @@ + diff --git a/src/Symfony/Component/HttpKernel/EventListener/RouterListener.php b/src/Symfony/Component/HttpKernel/EventListener/RouterListener.php index be43a72dd2..bb64f96d8e 100644 --- a/src/Symfony/Component/HttpKernel/EventListener/RouterListener.php +++ b/src/Symfony/Component/HttpKernel/EventListener/RouterListener.php @@ -21,25 +21,33 @@ use Symfony\Component\Routing\Exception\MethodNotAllowedException; use Symfony\Component\Routing\Exception\ResourceNotFoundException; use Symfony\Component\Routing\Matcher\UrlMatcherInterface; use Symfony\Component\Routing\Matcher\RequestMatcherInterface; +use Symfony\Component\Routing\RequestContext; +use Symfony\Component\Routing\RequestContextAwareInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; /** - * Initializes request attributes based on a matching route. + * Initializes the context from the request and sets request attributes based on a matching route. * * @author Fabien Potencier */ class RouterListener implements EventSubscriberInterface { private $matcher; + private $context; private $logger; - public function __construct($matcher, LoggerInterface $logger = null) + public function __construct($matcher, RequestContext $context = null, LoggerInterface $logger = null) { if (!$matcher instanceof UrlMatcherInterface && !$matcher instanceof RequestMatcherInterface) { throw new \InvalidArgumentException('Matcher must either implement UrlMatcherInterface or RequestMatcherInterface.'); } + + if (null === $context && !$matcher instanceof RequestContextAwareInterface) { + throw new \InvalidArgumentException('You must either pass a RequestContext or the matcher must implement RequestContextAwareInterface.'); + } $this->matcher = $matcher; + $this->context = $context ?: $matcher->getContext(); $this->logger = $logger; } @@ -47,8 +55,9 @@ class RouterListener implements EventSubscriberInterface { $request = $event->getRequest(); + // initialize the context that is also used by the generator (assuming matcher and generator share the same context instance) if (HttpKernelInterface::MASTER_REQUEST === $event->getRequestType()) { - $this->matcher->getContext()->fromRequest($request); + $this->context->fromRequest($request); } if ($request->attributes->has('_controller')) { @@ -56,9 +65,9 @@ class RouterListener implements EventSubscriberInterface return; } - // add attributes based on the path info (routing) + // add attributes based on the request (routing) try { - // matching requests is more powerful than matching URLs only, so try that first + // matching a request is more powerful than matching a URL path + context, so try that first if ($this->matcher instanceof RequestMatcherInterface) { $parameters = $this->matcher->matchRequest($request); } else { diff --git a/src/Symfony/Component/HttpKernel/Tests/EventListener/RouterListenerTest.php b/src/Symfony/Component/HttpKernel/Tests/EventListener/RouterListenerTest.php index 9ac028c652..5e224e257a 100644 --- a/src/Symfony/Component/HttpKernel/Tests/EventListener/RouterListenerTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/EventListener/RouterListenerTest.php @@ -92,18 +92,13 @@ class RouterListenerTest extends \PHPUnit_Framework_TestCase $request = Request::create('http://localhost/'); $event = new GetResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST); - $context = new RequestContext(); - $requestMatcher = $this->getMock('Symfony\Component\Routing\Matcher\RequestMatcherInterface'); - $requestMatcher->expects($this->any()) - ->method('getContext') - ->will($this->returnValue($context)); $requestMatcher->expects($this->once()) ->method('matchRequest') ->with($this->isInstanceOf('Symfony\Component\HttpFoundation\Request')) ->will($this->returnValue(array())); - $listener = new RouterListener($requestMatcher); + $listener = new RouterListener($requestMatcher, new RequestContext()); $listener->onKernelRequest($event); } } diff --git a/src/Symfony/Component/Routing/Matcher/RequestMatcherInterface.php b/src/Symfony/Component/Routing/Matcher/RequestMatcherInterface.php index 66b6ba5a3a..d636cd093c 100644 --- a/src/Symfony/Component/Routing/Matcher/RequestMatcherInterface.php +++ b/src/Symfony/Component/Routing/Matcher/RequestMatcherInterface.php @@ -12,7 +12,6 @@ namespace Symfony\Component\Routing\Matcher; use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\Routing\RequestContextAwareInterface; use Symfony\Component\Routing\Exception\ResourceNotFoundException; use Symfony\Component\Routing\Exception\MethodNotAllowedException; @@ -21,7 +20,7 @@ use Symfony\Component\Routing\Exception\MethodNotAllowedException; * * @author Fabien Potencier */ -interface RequestMatcherInterface extends RequestContextAwareInterface +interface RequestMatcherInterface { /** * Tries to match a request with a set of routes.