diff --git a/Slim/App.php b/Slim/App.php index cfeb9ba09..0bfac9498 100644 --- a/Slim/App.php +++ b/Slim/App.php @@ -235,7 +235,9 @@ public function any($pattern, $callable) */ public function map(array $methods, $pattern, $callable) { - $callable = new DeferredCallable($callable, $this->container); + if ($callable instanceof Closure) { + $callable = $callable->bindTo($this->container); + } $route = $this->container->get('router')->map($methods, $pattern, $callable); if (is_callable([$route, 'setContainer'])) { diff --git a/Slim/Routable.php b/Slim/Routable.php index 23759f7f5..ac3986885 100644 --- a/Slim/Routable.php +++ b/Slim/Routable.php @@ -18,6 +18,8 @@ */ abstract class Routable { + use CallableResolverAwareTrait; + /** * Route callable * diff --git a/Slim/Route.php b/Slim/Route.php index d79a3f43e..3cb4a0e28 100644 --- a/Slim/Route.php +++ b/Slim/Route.php @@ -311,6 +311,8 @@ public function run(ServerRequestInterface $request, ResponseInterface $response */ public function __invoke(ServerRequestInterface $request, ResponseInterface $response) { + $this->callable = $this->resolveCallable($this->callable); + /** @var InvocationStrategyInterface $handler */ $handler = isset($this->container) ? $this->container->get('foundHandler') : new RequestResponse(); diff --git a/Slim/RouteGroup.php b/Slim/RouteGroup.php index 5d17ff220..a0cdf4d47 100644 --- a/Slim/RouteGroup.php +++ b/Slim/RouteGroup.php @@ -18,7 +18,6 @@ */ class RouteGroup extends Routable implements RouteGroupInterface { - use CallableResolverAwareTrait; /** * Create a new RouteGroup * diff --git a/tests/Mocks/InvocationStrategyTest.php b/tests/Mocks/InvocationStrategyTest.php new file mode 100644 index 000000000..49b37db56 --- /dev/null +++ b/tests/Mocks/InvocationStrategyTest.php @@ -0,0 +1,39 @@ +routeFactory(); @@ -384,4 +384,28 @@ public function testInvokeWhenDisablingOutputBuffer() $output = ob_get_clean(); $this->assertEquals('foo', $output); } + + /** + * Ensure that `foundHandler` is called on actual callable + */ + public function testInvokeDeferredCallable() + { + $container = new Container(); + $container['CallableTest'] = new CallableTest; + $container['foundHandler'] = function () { + return new InvocationStrategyTest(); + }; + + $route = new Route(['GET'], '/', 'CallableTest:toCall'); + $route->setContainer($container); + + $uri = Uri::createFromString('https://example.com:80'); + $body = new Body(fopen('php://temp', 'r+')); + $request = new Request('GET', $uri, new Headers(), [], Environment::mock()->all(), $body); + + $result = $route->callMiddlewareStack($request, new Response); + + $this->assertInstanceOf('Slim\Http\Response', $result); + $this->assertEquals([$container['CallableTest'], 'toCall'], InvocationStrategyTest::$LastCalledFor); + } }