[Routing] Expose request in route conditions, if needed and possible

This commit is contained in:
Roland Franssen 2017-05-04 19:29:31 +02:00 committed by Fabien Potencier
parent 1c2c3fc677
commit 94371d052b
4 changed files with 28 additions and 3 deletions

View File

@ -49,7 +49,7 @@ abstract class RedirectableUrlMatcher extends UrlMatcher implements Redirectable
protected function handleRouteRequirements($pathinfo, $name, Route $route)
{
// expression condition
if ($route->getCondition() && !$this->getExpressionLanguage()->evaluate($route->getCondition(), array('context' => $this->context, 'request' => $this->request))) {
if ($route->getCondition() && !$this->getExpressionLanguage()->evaluate($route->getCondition(), array('context' => $this->context, 'request' => $this->request ?: $this->createRequest($pathinfo)))) {
return array(self::REQUIREMENT_MISMATCH, null);
}

View File

@ -105,7 +105,7 @@ class TraceableUrlMatcher extends UrlMatcher
// check condition
if ($condition = $route->getCondition()) {
if (!$this->getExpressionLanguage()->evaluate($condition, array('context' => $this->context, 'request' => $this->request))) {
if (!$this->getExpressionLanguage()->evaluate($condition, array('context' => $this->context, 'request' => $this->request ?: $this->createRequest($pathinfo)))) {
$this->addTrace(sprintf('Condition "%s" does not evaluate to "true"', $condition), self::ROUTE_ALMOST_MATCHES, $name, $route);
continue;

View File

@ -207,7 +207,7 @@ class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface
protected function handleRouteRequirements($pathinfo, $name, Route $route)
{
// expression condition
if ($route->getCondition() && !$this->getExpressionLanguage()->evaluate($route->getCondition(), array('context' => $this->context, 'request' => $this->request))) {
if ($route->getCondition() && !$this->getExpressionLanguage()->evaluate($route->getCondition(), array('context' => $this->context, 'request' => $this->request ?: $this->createRequest($pathinfo)))) {
return array(self::REQUIREMENT_MISMATCH, null);
}
@ -248,4 +248,19 @@ class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface
return $this->expressionLanguage;
}
/**
* @internal
*/
protected function createRequest($pathinfo)
{
if (!class_exists('Symfony\Component\HttpFoundation\Request')) {
return null;
}
return Request::create($this->context->getScheme().'://'.$this->context->getHost().$this->context->getBaseUrl().$pathinfo, $this->context->getMethod(), $this->context->getParameters(), array(), array(), array(
'SCRIPT_FILENAME' => $this->context->getBaseUrl(),
'SCRIPT_NAME' => $this->context->getBaseUrl(),
));
}
}

View File

@ -337,6 +337,16 @@ class UrlMatcherTest extends TestCase
$matcher->match('/foo');
}
public function testRequestCondition()
{
$coll = new RouteCollection();
$route = new Route('/foo/{bar}');
$route->setCondition('request.getBaseUrl() == "/sub/front.php" and request.getPathInfo() == "/foo/bar"');
$coll->add('foo', $route);
$matcher = new UrlMatcher($coll, new RequestContext('/sub/front.php'));
$this->assertEquals(array('bar' => 'bar', '_route' => 'foo'), $matcher->match('/foo/bar'));
}
public function testDecodeOnce()
{
$coll = new RouteCollection();