Commit 8fbb9369 authored by Fabien Potencier's avatar Fabien Potencier

added a way to delay the attachment of a controller to a route

parent 7134febb
...@@ -4,6 +4,7 @@ Changelog ...@@ -4,6 +4,7 @@ Changelog
1.2.0 (2013-XX-XX) 1.2.0 (2013-XX-XX)
------------------ ------------------
* Added run() on Route to be able to define the controller code
* Deprecated TwigCoreExtension (register the new HttpFragmentServiceProvider instead) * Deprecated TwigCoreExtension (register the new HttpFragmentServiceProvider instead)
* Added HttpFragmentServiceProvider * Added HttpFragmentServiceProvider
......
...@@ -200,7 +200,7 @@ class Application extends \Pimple implements HttpKernelInterface, TerminableInte ...@@ -200,7 +200,7 @@ class Application extends \Pimple implements HttpKernelInterface, TerminableInte
* *
* @return Controller * @return Controller
*/ */
public function match($pattern, $to) public function match($pattern, $to = null)
{ {
return $this['controllers']->match($pattern, $to); return $this['controllers']->match($pattern, $to);
} }
...@@ -213,7 +213,7 @@ class Application extends \Pimple implements HttpKernelInterface, TerminableInte ...@@ -213,7 +213,7 @@ class Application extends \Pimple implements HttpKernelInterface, TerminableInte
* *
* @return Controller * @return Controller
*/ */
public function get($pattern, $to) public function get($pattern, $to = null)
{ {
return $this['controllers']->get($pattern, $to); return $this['controllers']->get($pattern, $to);
} }
...@@ -226,7 +226,7 @@ class Application extends \Pimple implements HttpKernelInterface, TerminableInte ...@@ -226,7 +226,7 @@ class Application extends \Pimple implements HttpKernelInterface, TerminableInte
* *
* @return Controller * @return Controller
*/ */
public function post($pattern, $to) public function post($pattern, $to = null)
{ {
return $this['controllers']->post($pattern, $to); return $this['controllers']->post($pattern, $to);
} }
...@@ -239,7 +239,7 @@ class Application extends \Pimple implements HttpKernelInterface, TerminableInte ...@@ -239,7 +239,7 @@ class Application extends \Pimple implements HttpKernelInterface, TerminableInte
* *
* @return Controller * @return Controller
*/ */
public function put($pattern, $to) public function put($pattern, $to = null)
{ {
return $this['controllers']->put($pattern, $to); return $this['controllers']->put($pattern, $to);
} }
...@@ -252,7 +252,7 @@ class Application extends \Pimple implements HttpKernelInterface, TerminableInte ...@@ -252,7 +252,7 @@ class Application extends \Pimple implements HttpKernelInterface, TerminableInte
* *
* @return Controller * @return Controller
*/ */
public function delete($pattern, $to) public function delete($pattern, $to = null)
{ {
return $this['controllers']->delete($pattern, $to); return $this['controllers']->delete($pattern, $to);
} }
......
...@@ -47,14 +47,19 @@ class ControllerCollection ...@@ -47,14 +47,19 @@ class ControllerCollection
* *
* @return Controller * @return Controller
*/ */
public function match($pattern, $to) public function match($pattern, $to = null)
{ {
$route = clone $this->defaultRoute; $route = clone $this->defaultRoute;
$route->setPath($pattern); $route->setPath($pattern);
$route->setDefault('_controller', $to);
$this->controllers[] = $controller = new Controller($route); $this->controllers[] = $controller = new Controller($route);
if (null === $to) {
$to = function () use ($controller) {
throw new \LogicException(sprintf('The "%s" route must have code to run when it matches.', $controller->getRouteName()));
};
}
$route->setDefault('_controller', $to);
return $controller; return $controller;
} }
...@@ -66,7 +71,7 @@ class ControllerCollection ...@@ -66,7 +71,7 @@ class ControllerCollection
* *
* @return Controller * @return Controller
*/ */
public function get($pattern, $to) public function get($pattern, $to = null)
{ {
return $this->match($pattern, $to)->method('GET'); return $this->match($pattern, $to)->method('GET');
} }
...@@ -79,7 +84,7 @@ class ControllerCollection ...@@ -79,7 +84,7 @@ class ControllerCollection
* *
* @return Controller * @return Controller
*/ */
public function post($pattern, $to) public function post($pattern, $to = null)
{ {
return $this->match($pattern, $to)->method('POST'); return $this->match($pattern, $to)->method('POST');
} }
...@@ -92,7 +97,7 @@ class ControllerCollection ...@@ -92,7 +97,7 @@ class ControllerCollection
* *
* @return Controller * @return Controller
*/ */
public function put($pattern, $to) public function put($pattern, $to = null)
{ {
return $this->match($pattern, $to)->method('PUT'); return $this->match($pattern, $to)->method('PUT');
} }
...@@ -105,7 +110,7 @@ class ControllerCollection ...@@ -105,7 +110,7 @@ class ControllerCollection
* *
* @return Controller * @return Controller
*/ */
public function delete($pattern, $to) public function delete($pattern, $to = null)
{ {
return $this->match($pattern, $to)->method('DELETE'); return $this->match($pattern, $to)->method('DELETE');
} }
......
...@@ -543,7 +543,7 @@ class SecurityServiceProvider implements ServiceProviderInterface ...@@ -543,7 +543,7 @@ class SecurityServiceProvider implements ServiceProviderInterface
foreach ($this->fakeRoutes as $route) { foreach ($this->fakeRoutes as $route) {
list($method, $pattern, $name) = $route; list($method, $pattern, $name) = $route;
$app->$method($pattern, null)->bind($name); $app->$method($pattern)->run(null)->bind($name);
} }
} }
......
...@@ -41,6 +41,20 @@ class Route extends BaseRoute ...@@ -41,6 +41,20 @@ class Route extends BaseRoute
parent::__construct($path, $defaults, $requirements, $options, $host, $schemes, $methods); parent::__construct($path, $defaults, $requirements, $options, $host, $schemes, $methods);
} }
/**
* Sets the route code that should be executed when matched.
*
* @param callable $to PHP callback that returns the response when matched
*
* @return Route $this The current Route instance
*/
public function run($to)
{
$this->setDefault('_controller', $to);
return $this;
}
/** /**
* Sets the requirement for a route variable. * Sets the requirement for a route variable.
* *
......
...@@ -93,7 +93,7 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase ...@@ -93,7 +93,7 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase
return 'foo'; return 'foo';
}); });
$app->get('/bar', function () { $app->get('/bar')->run(function () {
return 'bar'; return 'bar';
}); });
......
...@@ -30,6 +30,19 @@ class ControllerCollectionTest extends \PHPUnit_Framework_TestCase ...@@ -30,6 +30,19 @@ class ControllerCollectionTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(0, count($routes->all())); $this->assertEquals(0, count($routes->all()));
} }
/**
* @expectedException \LogicException
* @expectedExceptionMessage The "foo" route must have code to run when it matches.
*/
public function testGetRouteCollectionWithRouteWithoutController()
{
$controllers = new ControllerCollection(new Route());
$controllers->match('/foo')->bind('foo');
$routes = $controllers->flush();
call_user_func($routes->get('foo')->getDefault('_controller'));
}
public function testGetRouteCollectionWithRoutes() public function testGetRouteCollectionWithRoutes()
{ {
$controllers = new ControllerCollection(new Route()); $controllers = new ControllerCollection(new Route());
......
...@@ -68,6 +68,15 @@ class ControllerTest extends \PHPUnit_Framework_TestCase ...@@ -68,6 +68,15 @@ class ControllerTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(array('bar' => $func), $controller->getRoute()->getOption('_converters')); $this->assertEquals(array('bar' => $func), $controller->getRoute()->getOption('_converters'));
} }
public function testRun()
{
$controller = new Controller(new Route('/foo/{bar}'));
$ret = $controller->run($cb = function () { return 'foo'; });
$this->assertSame($ret, $controller);
$this->assertEquals($cb, $controller->getRoute()->getDefault('_controller'));
}
/** /**
* @dataProvider provideRouteAndExpectedRouteName * @dataProvider provideRouteAndExpectedRouteName
*/ */
......
...@@ -160,6 +160,24 @@ class SecurityServiceProviderTest extends WebTestCase ...@@ -160,6 +160,24 @@ class SecurityServiceProviderTest extends WebTestCase
$client->getRequest()->getSession()->save(); $client->getRequest()->getSession()->save();
} }
public function testFakeRoutesAreSerializable()
{
$app = new Application();
$app->register(new SecurityServiceProvider(), array(
'security.firewalls' => array(
'admin' => array(
'logout' => true,
),
),
));
$app->boot();
$app->flush();
$this->assertCount(1, unserialize(serialize($app['routes'])));
}
public function createApplication($authenticationMethod = 'form') public function createApplication($authenticationMethod = 'form')
{ {
$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