[HttpKernel] added support for controllers as arrays and object with an __invoke method
Controllers can now be any valid PHP callable
This commit is contained in:
parent
db8b118e8a
commit
c6818d8bf7
@ -60,7 +60,7 @@ class ControllerResolver implements ControllerResolverInterface
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($controller instanceof \Closure) {
|
||||
if (is_array($controller) || method_exists($controller, '__invoke')) {
|
||||
return $controller;
|
||||
}
|
||||
|
||||
@ -92,15 +92,21 @@ class ControllerResolver implements ControllerResolverInterface
|
||||
if (is_array($controller)) {
|
||||
$r = new \ReflectionMethod($controller[0], $controller[1]);
|
||||
$repr = sprintf('%s::%s()', get_class($controller[0]), $controller[1]);
|
||||
} elseif (is_object($controller)) {
|
||||
$r = new \ReflectionObject($controller);
|
||||
$r = $r->getMethod('__invoke');
|
||||
$repr = get_class($controller);
|
||||
} else {
|
||||
$r = new \ReflectionFunction($controller);
|
||||
$repr = 'Closure';
|
||||
$repr = $controller;
|
||||
}
|
||||
|
||||
$arguments = array();
|
||||
foreach ($r->getParameters() as $param) {
|
||||
if (array_key_exists($param->getName(), $attributes)) {
|
||||
$arguments[] = $attributes[$param->getName()];
|
||||
} elseif ($param->getClass() && $param->getClass()->isInstance($request)) {
|
||||
$arguments[] = $request;
|
||||
} elseif ($param->isDefaultValueAvailable()) {
|
||||
$arguments[] = $param->getDefaultValue();
|
||||
} else {
|
||||
|
@ -36,6 +36,18 @@ class ControllerResolverTest extends \PHPUnit_Framework_TestCase
|
||||
$controller = $resolver->getController($request);
|
||||
$this->assertSame($lambda, $controller);
|
||||
|
||||
$request->attributes->set('_controller', $this);
|
||||
$controller = $resolver->getController($request);
|
||||
$this->assertSame($this, $controller);
|
||||
|
||||
$request->attributes->set('_controller', array($this, 'controllerMethod1'));
|
||||
$controller = $resolver->getController($request);
|
||||
$this->assertSame(array($this, 'controllerMethod1'), $controller);
|
||||
|
||||
$request->attributes->set('_controller', array('Symfony\Tests\Component\HttpKernel\ControllerResolverTest', 'controllerMethod4'));
|
||||
$controller = $resolver->getController($request);
|
||||
$this->assertSame(array('Symfony\Tests\Component\HttpKernel\ControllerResolverTest', 'controllerMethod4'), $controller);
|
||||
|
||||
$request->attributes->set('_controller', 'foo');
|
||||
try {
|
||||
$resolver->getController($request);
|
||||
@ -98,6 +110,14 @@ class ControllerResolverTest extends \PHPUnit_Framework_TestCase
|
||||
} catch (\Exception $e) {
|
||||
$this->assertInstanceOf('\RuntimeException', $e, '->getArguments() throws a \RuntimeException exception if it cannot determine the argument value');
|
||||
}
|
||||
|
||||
$request = Request::create('/');
|
||||
$controller = array(new self(), 'controllerMethod5');
|
||||
$this->assertEquals(array($request), $resolver->getArguments($request, $controller), '->getArguments() injects the request');
|
||||
}
|
||||
|
||||
public function __invoke()
|
||||
{
|
||||
}
|
||||
|
||||
protected function controllerMethod1($foo)
|
||||
@ -111,4 +131,12 @@ class ControllerResolverTest extends \PHPUnit_Framework_TestCase
|
||||
protected function controllerMethod3($foo, $bar = null, $foobar)
|
||||
{
|
||||
}
|
||||
|
||||
static protected function controllerMethod4()
|
||||
{
|
||||
}
|
||||
|
||||
protected function controllerMethod5(Request $request)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
@ -88,6 +88,47 @@ class HttpKernelTest extends \PHPUnit_Framework_TestCase
|
||||
$kernel->handle(new Request());
|
||||
}
|
||||
|
||||
public function testHandleWhenNoControllerIsAClosure()
|
||||
{
|
||||
$response = new Response('foo');
|
||||
$dispatcher = new EventDispatcher();
|
||||
$kernel = new HttpKernel($dispatcher, $this->getResolver(function () use ($response) { return $response; }));
|
||||
|
||||
$this->assertSame($response, $kernel->handle(new Request()));
|
||||
}
|
||||
|
||||
public function testHandleWhenNoControllerIsAnObjectWithInvoke()
|
||||
{
|
||||
$dispatcher = new EventDispatcher();
|
||||
$kernel = new HttpKernel($dispatcher, $this->getResolver(new Controller()));
|
||||
|
||||
$this->assertEquals(new Response('foo'), $kernel->handle(new Request()));
|
||||
}
|
||||
|
||||
public function testHandleWhenNoControllerIsAFunction()
|
||||
{
|
||||
$dispatcher = new EventDispatcher();
|
||||
$kernel = new HttpKernel($dispatcher, $this->getResolver('Symfony\Tests\Component\HttpKernel\controller_func'));
|
||||
|
||||
$this->assertEquals(new Response('foo'), $kernel->handle(new Request()));
|
||||
}
|
||||
|
||||
public function testHandleWhenNoControllerIsAnArray()
|
||||
{
|
||||
$dispatcher = new EventDispatcher();
|
||||
$kernel = new HttpKernel($dispatcher, $this->getResolver(array(new Controller(), 'controller')));
|
||||
|
||||
$this->assertEquals(new Response('foo'), $kernel->handle(new Request()));
|
||||
}
|
||||
|
||||
public function testHandleWhenNoControllerIsAStaticArray()
|
||||
{
|
||||
$dispatcher = new EventDispatcher();
|
||||
$kernel = new HttpKernel($dispatcher, $this->getResolver(array('Symfony\Tests\Component\HttpKernel\Controller', 'staticcontroller')));
|
||||
|
||||
$this->assertEquals(new Response('foo'), $kernel->handle(new Request()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException LogicException
|
||||
*/
|
||||
@ -140,3 +181,26 @@ class HttpKernelTest extends \PHPUnit_Framework_TestCase
|
||||
return $resolver;
|
||||
}
|
||||
}
|
||||
|
||||
class Controller
|
||||
{
|
||||
public function __invoke()
|
||||
{
|
||||
return new Response('foo');
|
||||
}
|
||||
|
||||
public function controller()
|
||||
{
|
||||
return new Response('foo');
|
||||
}
|
||||
|
||||
static public function staticController()
|
||||
{
|
||||
return new Response('foo');
|
||||
}
|
||||
}
|
||||
|
||||
function controller_func()
|
||||
{
|
||||
return new Response('foo');
|
||||
}
|
||||
|
Reference in New Issue
Block a user