[Routing][HttpKernel] Add RequestMatcherInterface.
While UrlMatcherInterface is only for matching URLs with routes, add RequestMatcherInterface, that allows to match against whole requests.
This commit is contained in:
parent
1541fe26e4
commit
2277500835
@ -20,6 +20,7 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
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\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
/**
|
||||
@ -29,12 +30,16 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
*/
|
||||
class RouterListener implements EventSubscriberInterface
|
||||
{
|
||||
private $urlMatcher;
|
||||
private $matcher;
|
||||
private $logger;
|
||||
|
||||
public function __construct(UrlMatcherInterface $urlMatcher, LoggerInterface $logger = null)
|
||||
public function __construct($matcher, LoggerInterface $logger = null)
|
||||
{
|
||||
$this->urlMatcher = $urlMatcher;
|
||||
if (!$matcher instanceof UrlMatcherInterface && !$matcher instanceof RequestMatcherInterface) {
|
||||
throw new \InvalidArgumentException('Matcher must either implement UrlMatcherInterface or RequestMatcherInterface.');
|
||||
}
|
||||
|
||||
$this->matcher = $matcher;
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
@ -43,7 +48,7 @@ class RouterListener implements EventSubscriberInterface
|
||||
$request = $event->getRequest();
|
||||
|
||||
if (HttpKernelInterface::MASTER_REQUEST === $event->getRequestType()) {
|
||||
$this->urlMatcher->getContext()->fromRequest($request);
|
||||
$this->matcher->getContext()->fromRequest($request);
|
||||
}
|
||||
|
||||
if ($request->attributes->has('_controller')) {
|
||||
@ -53,7 +58,12 @@ class RouterListener implements EventSubscriberInterface
|
||||
|
||||
// add attributes based on the path info (routing)
|
||||
try {
|
||||
$parameters = $this->urlMatcher->match($request->getPathInfo());
|
||||
// matching requests is more powerful than matching URLs only, so try that first
|
||||
if ($this->matcher instanceof RequestMatcherInterface) {
|
||||
$parameters = $this->matcher->matchRequest($request);
|
||||
} else {
|
||||
$parameters = $this->matcher->match($request->getPathInfo());
|
||||
}
|
||||
|
||||
if (null !== $this->logger) {
|
||||
$this->logger->info(sprintf('Matched route "%s" (parameters: %s)', $parameters['_route'], $this->parametersToString($parameters)));
|
||||
|
@ -77,4 +77,33 @@ class RouterListenerTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
return new GetResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \InvalidArgumentException
|
||||
*/
|
||||
public function testInvalidMatcher()
|
||||
{
|
||||
new RouterListener(new \stdClass());
|
||||
}
|
||||
|
||||
public function testRequestMatcher()
|
||||
{
|
||||
$kernel = $this->getMock('Symfony\Component\HttpKernel\HttpKernelInterface');
|
||||
$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->onKernelRequest($event);
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ CHANGELOG
|
||||
2.1.0
|
||||
-----
|
||||
|
||||
* added RequestMatcherInterface
|
||||
* added RequestContext::fromRequest()
|
||||
* the UrlMatcher does not throw a \LogicException anymore when the required
|
||||
scheme is not the current one
|
||||
|
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* UrlMatcherInterface is the interface that all URL matcher classes must implement.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
interface RequestMatcherInterface extends RequestContextAwareInterface
|
||||
{
|
||||
/**
|
||||
* Tries to match a request with a set of routes.
|
||||
*
|
||||
* If the matcher can not find information, it must throw one of the exceptions documented
|
||||
* below.
|
||||
*
|
||||
* @param Request $request The request to match
|
||||
*
|
||||
* @return array An array of parameters
|
||||
*
|
||||
* @throws ResourceNotFoundException If no matching resource could be found
|
||||
* @throws MethodNotAllowedException If a matching resource was found but the request method is not allowed
|
||||
*/
|
||||
function matchRequest(Request $request);
|
||||
}
|
Reference in New Issue
Block a user