merged branch niklasf/request-matcher-interface (PR #4363)
Commits -------2277500
[Routing][HttpKernel] Add RequestMatcherInterface. Discussion ---------- [Routing][HttpKernel] Add RequestMatcherInterface. First try at implementing #4351. Bug fix: no Feature addition: yes Backwards compatibility break: no Fixes the following tickets: - Todo: - License of the code: MIT --------------------------------------------------------------------------- by travisbot at 2012-05-21T19:37:07Z This pull request [fails](http://travis-ci.org/symfony/symfony/builds/1392716) (merged 457496db intoea33d4d3
). --------------------------------------------------------------------------- by travisbot at 2012-05-21T19:47:51Z This pull request [passes](http://travis-ci.org/symfony/symfony/builds/1392939) (merged 78effa98 intoea33d4d3
). --------------------------------------------------------------------------- by everzet at 2012-05-21T20:17:03Z No tests? --------------------------------------------------------------------------- by travisbot at 2012-05-21T20:18:18Z This pull request [passes](http://travis-ci.org/symfony/symfony/builds/1393392) (merged 6564fb6a intoea33d4d3
). --------------------------------------------------------------------------- by schmittjoh at 2012-05-21T20:35:14Z You need to remove the type-hint from the constructor, and probably add an exception instead where the matching methods are called to ensure that either ``UrlMatcherInterface``, or ``RequestMatcherInterface`` were passed. Alternatively, you could also add such a check to the constructor. --------------------------------------------------------------------------- by fabpot at 2012-05-22T06:52:01Z related to symfony/symfony#4020 --------------------------------------------------------------------------- by niklasf at 2012-05-25T11:11:45Z Reverted the changes to UrlMatcher.php. --------------------------------------------------------------------------- by fabpot at 2012-05-25T12:46:06Z @niklasf: it looks good now except for the listener constructor (see @schmittjoh suggestion above). Can you fix that and add some unit tests to ensure that everything works as expected? Thanks. --------------------------------------------------------------------------- by stof at 2012-05-25T12:52:59Z Another solution could be to make the ``RequestMatcherInterface`` extend the ``MatcherInterface`` to keep the typehint in the constructor --------------------------------------------------------------------------- by fabpot at 2012-05-25T13:52:26Z I thought about that as well, but that does not make sense. --------------------------------------------------------------------------- by stof at 2012-05-25T14:12:19Z Well, the RouterInterface extends UrlMatcherInterface anyway (and it should stay this way as it would be a huge BC break) so I guess most people will implement both interfaces when implementing the RquestMatcherInterface --------------------------------------------------------------------------- by travisbot at 2012-05-25T15:26:22Z This pull request [fails](http://travis-ci.org/symfony/symfony/builds/1433963) (merged 8f36204c intoff4d446c
). --------------------------------------------------------------------------- by travisbot at 2012-05-25T15:33:13Z This pull request [fails](http://travis-ci.org/symfony/symfony/builds/1433996) (merged 6d2f2cd9 intoff4d446c
). --------------------------------------------------------------------------- by travisbot at 2012-05-25T15:39:01Z This pull request [fails](http://travis-ci.org/symfony/symfony/builds/1434060) (merged 3c1d89e2 intoff4d446c
). --------------------------------------------------------------------------- by travisbot at 2012-05-25T22:06:34Z This pull request [fails](http://travis-ci.org/symfony/symfony/builds/1437398) (merged 3ab997c1 intoff4d446c
). --------------------------------------------------------------------------- by travisbot at 2012-05-25T22:06:47Z This pull request [fails](http://travis-ci.org/symfony/symfony/builds/1437385) (merged d8c0e387 intoff4d446c
). --------------------------------------------------------------------------- by fabpot at 2012-05-26T06:41:31Z Can you add a note in the CHANGELOG of the component? --------------------------------------------------------------------------- by travisbot at 2012-05-26T08:12:40Z This pull request [fails](http://travis-ci.org/symfony/symfony/builds/1440435) (merged c7458733 into9e951991
). --------------------------------------------------------------------------- by niklasf at 2012-05-26T08:14:41Z @fabpot: Sorry, not sure how: Under 2.1.0 or in a new section? As the first or last entry of the list? --------------------------------------------------------------------------- by stof at 2012-05-26T10:20:23Z @niklasf the new interface should be mentioned in the changelog of the Routing component --------------------------------------------------------------------------- by travisbot at 2012-05-26T10:30:06Z This pull request [fails](http://travis-ci.org/symfony/symfony/builds/1440837) (merged 34ea86a9 into9e951991
). --------------------------------------------------------------------------- by niklasf at 2012-06-02T15:27:01Z Ah ... so there were two pitfalls: - PHPUnit clones the arguments of mocked functions. So they wouldn't equal. - createGetResponseEventForUri() disables routing on purpose. So not using that helper, now. Tests should be passing. --------------------------------------------------------------------------- by travisbot at 2012-06-02T15:30:28Z This pull request [passes](http://travis-ci.org/symfony/symfony/builds/1509054) (merged 7fab0118 into1541fe26
).
This commit is contained in:
commit
1787992d0c
@ -20,6 +20,7 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
|||||||
use Symfony\Component\Routing\Exception\MethodNotAllowedException;
|
use Symfony\Component\Routing\Exception\MethodNotAllowedException;
|
||||||
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
|
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
|
||||||
use Symfony\Component\Routing\Matcher\UrlMatcherInterface;
|
use Symfony\Component\Routing\Matcher\UrlMatcherInterface;
|
||||||
|
use Symfony\Component\Routing\Matcher\RequestMatcherInterface;
|
||||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -29,12 +30,16 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
|||||||
*/
|
*/
|
||||||
class RouterListener implements EventSubscriberInterface
|
class RouterListener implements EventSubscriberInterface
|
||||||
{
|
{
|
||||||
private $urlMatcher;
|
private $matcher;
|
||||||
private $logger;
|
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;
|
$this->logger = $logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,7 +48,7 @@ class RouterListener implements EventSubscriberInterface
|
|||||||
$request = $event->getRequest();
|
$request = $event->getRequest();
|
||||||
|
|
||||||
if (HttpKernelInterface::MASTER_REQUEST === $event->getRequestType()) {
|
if (HttpKernelInterface::MASTER_REQUEST === $event->getRequestType()) {
|
||||||
$this->urlMatcher->getContext()->fromRequest($request);
|
$this->matcher->getContext()->fromRequest($request);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($request->attributes->has('_controller')) {
|
if ($request->attributes->has('_controller')) {
|
||||||
@ -53,7 +58,12 @@ class RouterListener implements EventSubscriberInterface
|
|||||||
|
|
||||||
// add attributes based on the path info (routing)
|
// add attributes based on the path info (routing)
|
||||||
try {
|
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) {
|
if (null !== $this->logger) {
|
||||||
$this->logger->info(sprintf('Matched route "%s" (parameters: %s)', $parameters['_route'], $this->parametersToString($parameters)));
|
$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);
|
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
|
2.1.0
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
* added RequestMatcherInterface
|
||||||
* added RequestContext::fromRequest()
|
* added RequestContext::fromRequest()
|
||||||
* the UrlMatcher does not throw a \LogicException anymore when the required
|
* the UrlMatcher does not throw a \LogicException anymore when the required
|
||||||
scheme is not the current one
|
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