Commit e0b5c888 authored by Fabien Potencier's avatar Fabien Potencier

added route conditions

parent 163be526
Changelog Changelog
========= =========
2.0.0 (2015-XX-XX) 2.0.0 (2016-XX-XX)
------------------ ------------------
* added support for conditions on routes
* added support for the Symfony VarDumper Component * added support for the Symfony VarDumper Component
* added a global Twig variable (an AppVariable instance) * added a global Twig variable (an AppVariable instance)
* [BC BREAK] CSRF has been moved to a standalone provider (``form.secret`` is not available anymore) * [BC BREAK] CSRF has been moved to a standalone provider (``form.secret`` is not available anymore)
......
...@@ -370,6 +370,22 @@ You can also chain these calls:: ...@@ -370,6 +370,22 @@ You can also chain these calls::
->assert('postId', '\d+') ->assert('postId', '\d+')
->assert('commentId', '\d+'); ->assert('commentId', '\d+');
Conditions
~~~~~~~~~~
Besides restricting route matching based on the HTTP method or parameter
requirements, you can set conditions on any part of the request by calling
``when`` on the ``Controller`` object, which is returned by the routing
methods::
$app->get('/blog/{id}', function ($id) {
// ...
})
->when("request.headers.get('User-Agent') matches '/firefox/i'");
The ``when`` argument is a Symfony Expression_ , which means that you need to
add ``symfony/expression-language`` as a dependency of your project.
Default Values Default Values
~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~
...@@ -445,6 +461,7 @@ middleware, a requirement, or a default value), configure it on ...@@ -445,6 +461,7 @@ middleware, a requirement, or a default value), configure it on
->method('get') ->method('get')
->convert('id', function () { /* ... */ }) ->convert('id', function () { /* ... */ })
->before(function () { /* ... */ }) ->before(function () { /* ... */ })
->when('request.isSecure() == true')
; ;
These settings are applied to already registered controllers and they become These settings are applied to already registered controllers and they become
...@@ -785,3 +802,4 @@ Cross-Site-Scripting attacks. ...@@ -785,3 +802,4 @@ Cross-Site-Scripting attacks.
.. _Request: http://api.symfony.com/master/Symfony/Component/HttpFoundation/Request.html .. _Request: http://api.symfony.com/master/Symfony/Component/HttpFoundation/Request.html
.. _Response: http://api.symfony.com/master/Symfony/Component/HttpFoundation/Response.html .. _Response: http://api.symfony.com/master/Symfony/Component/HttpFoundation/Response.html
.. _Monolog: https://github.com/Seldaek/monolog .. _Monolog: https://github.com/Seldaek/monolog
.. _Expression: https://symfony.com/doc/current/book/routing.html#completely-customized-route-matching-with-conditions
...@@ -27,6 +27,7 @@ use Silex\Exception\ControllerFrozenException; ...@@ -27,6 +27,7 @@ use Silex\Exception\ControllerFrozenException;
* @method Controller requireHttps() * @method Controller requireHttps()
* @method Controller before(mixed $callback) * @method Controller before(mixed $callback)
* @method Controller after(mixed $callback) * @method Controller after(mixed $callback)
* @method Controller when(string $condition)
* *
* @author Igor Wiedler <igor@wiedler.ch> * @author Igor Wiedler <igor@wiedler.ch>
*/ */
......
...@@ -32,6 +32,7 @@ use Symfony\Component\HttpFoundation\Request; ...@@ -32,6 +32,7 @@ use Symfony\Component\HttpFoundation\Request;
* @method ControllerCollection requireHttps() * @method ControllerCollection requireHttps()
* @method ControllerCollection before(mixed $callback) * @method ControllerCollection before(mixed $callback)
* @method ControllerCollection after(mixed $callback) * @method ControllerCollection after(mixed $callback)
* @method ControllerCollection when(string $condition)
* *
* @author Igor Wiedler <igor@wiedler.ch> * @author Igor Wiedler <igor@wiedler.ch>
* @author Fabien Potencier <fabien@symfony.com> * @author Fabien Potencier <fabien@symfony.com>
......
...@@ -185,4 +185,18 @@ class Route extends BaseRoute ...@@ -185,4 +185,18 @@ class Route extends BaseRoute
return $this; return $this;
} }
/**
* Sets a condition for the route to match.
*
* @param string $condition The condition
*
* @return Route $this The current Route instance
*/
public function when($condition)
{
$this->setCondition($condition);
return $this;
}
} }
...@@ -194,6 +194,14 @@ class ControllerCollectionTest extends \PHPUnit_Framework_TestCase ...@@ -194,6 +194,14 @@ class ControllerCollectionTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(array('mid1', 'mid2', 'mid3'), $controller->getRoute()->getOption('_after_middlewares')); $this->assertEquals(array('mid1', 'mid2', 'mid3'), $controller->getRoute()->getOption('_after_middlewares'));
} }
public function testWhen()
{
$controllers = new ControllerCollection(new Route());
$controller = $controllers->match('/{id}/{name}/{extra}', function () {})->when('request.isSecure() == true');
$this->assertEquals('request.isSecure() == true', $controller->getRoute()->getCondition());
}
public function testRouteExtension() public function testRouteExtension()
{ {
$route = new MyRoute1(); $route = new MyRoute1();
......
...@@ -232,6 +232,19 @@ class RouterTest extends \PHPUnit_Framework_TestCase ...@@ -232,6 +232,19 @@ class RouterTest extends \PHPUnit_Framework_TestCase
$this->assertTrue($response->isRedirect('https://example.com/secured?query=string')); $this->assertTrue($response->isRedirect('https://example.com/secured?query=string'));
} }
public function testConditionOnRoute()
{
$app = new Application();
$app->match('/secured', function () {
return 'secured content';
})
->when('request.isSecure() == true');
$request = Request::create('http://example.com/secured');
$response = $app->handle($request);
$this->assertEquals(404, $response->getStatusCode());
}
public function testClassNameControllerSyntax() public function testClassNameControllerSyntax()
{ {
$app = new Application(); $app = new Application();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment