From 78008b36b39318d8df665d57d155f282c337392b Mon Sep 17 00:00:00 2001 From: Ivan Dudarev Date: Sat, 17 Apr 2021 22:14:39 +0700 Subject: [PATCH 1/3] Array routes --- Slim/CallableResolver.php | 20 +++++++++++++++++ tests/CallableResolverTest.php | 40 +++++++++++++++++++++++++++++++--- 2 files changed, 57 insertions(+), 3 deletions(-) diff --git a/Slim/CallableResolver.php b/Slim/CallableResolver.php index f2c5fe4cd..407724b5d 100644 --- a/Slim/CallableResolver.php +++ b/Slim/CallableResolver.php @@ -51,6 +51,7 @@ public function __construct(?ContainerInterface $container = null) */ public function resolve($toResolve): callable { + $toResolve = $this->prepareToResolve($toResolve); if (is_callable($toResolve)) { return $this->bindToContainer($toResolve); } @@ -90,6 +91,7 @@ public function resolveMiddleware($toResolve): callable */ private function resolveByPredicate($toResolve, callable $predicate, string $defaultMethod): callable { + $toResolve = $this->prepareToResolve($toResolve); if (is_callable($toResolve)) { return $this->bindToContainer($toResolve); } @@ -187,4 +189,22 @@ private function bindToContainer(callable $callable): callable } return $callable; } + + /** + * @param string|callable $toResolve + * @return string|callable + */ + private function prepareToResolve($toResolve) + { + if (!is_array($toResolve)) { + return $toResolve; + } + $array = $toResolve; + $class = array_shift($array); + $method = array_shift($array); + if (is_string($class) && is_string($method)) { + return $class . ':' . $method; + } + return $toResolve; + } } diff --git a/tests/CallableResolverTest.php b/tests/CallableResolverTest.php index 727164c48..8d739154b 100644 --- a/tests/CallableResolverTest.php +++ b/tests/CallableResolverTest.php @@ -133,6 +133,23 @@ public function testSlimCallable() $this->assertEquals(3, CallableTest::$CalledCount); } + public function testSlimCallableAsArray() + { + $resolver = new CallableResolver(); // No container injected + $callable = $resolver->resolve([CallableTest::class, 'toCall']); + $callableRoute = $resolver->resolveRoute([CallableTest::class, 'toCall']); + $callableMiddleware = $resolver->resolveMiddleware([CallableTest::class, 'toCall']); + + $callable(); + $this->assertEquals(1, CallableTest::$CalledCount); + + $callableRoute(); + $this->assertEquals(2, CallableTest::$CalledCount); + + $callableMiddleware(); + $this->assertEquals(3, CallableTest::$CalledCount); + } + public function testSlimCallableContainer() { /** @var ContainerInterface $container */ @@ -150,6 +167,23 @@ public function testSlimCallableContainer() $this->assertEquals($container, CallableTest::$CalledContainer); } + public function testSlimCallableAsArrayContainer() + { + /** @var ContainerInterface $container */ + $container = $this->containerProphecy->reveal(); + $resolver = new CallableResolver($container); + $resolver->resolve([CallableTest::class, 'toCall']); + $this->assertEquals($container, CallableTest::$CalledContainer); + + CallableTest::$CalledContainer = null; + $resolver->resolveRoute([CallableTest::class, 'toCall']); + $this->assertEquals($container, CallableTest::$CalledContainer); + + CallableTest::$CalledContainer = null; + $resolver->resolveMiddleware([CallableTest::class ,'toCall']); + $this->assertEquals($container, CallableTest::$CalledContainer); + } + public function testContainer() { $this->containerProphecy->has('callable_service')->willReturn(true); @@ -474,7 +508,7 @@ public function testMiddlewareClassNotFoundThrowException() public function testCallableClassNotFoundThrowException() { $this->expectException(RuntimeException::class); - $this->expectExceptionMessage('is not resolvable'); + $this->expectExceptionMessage('Callable Unknown does not exist'); /** @var ContainerInterface $container */ $container = $this->containerProphecy->reveal(); @@ -485,7 +519,7 @@ public function testCallableClassNotFoundThrowException() public function testRouteCallableClassNotFoundThrowException() { $this->expectException(RuntimeException::class); - $this->expectExceptionMessage('is not resolvable'); + $this->expectExceptionMessage('Callable Unknown does not exist'); /** @var ContainerInterface $container */ $container = $this->containerProphecy->reveal(); @@ -496,7 +530,7 @@ public function testRouteCallableClassNotFoundThrowException() public function testMiddlewareCallableClassNotFoundThrowException() { $this->expectException(RuntimeException::class); - $this->expectExceptionMessage('is not resolvable'); + $this->expectExceptionMessage('Callable Unknown does not exist'); /** @var ContainerInterface $container */ $container = $this->containerProphecy->reveal(); From 985052c2eab3bb20ce57280cc722c57b54ed0060 Mon Sep 17 00:00:00 2001 From: Ivan Dudarev Date: Sun, 18 Apr 2021 15:36:34 +0700 Subject: [PATCH 2/3] Rename variable --- Slim/CallableResolver.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Slim/CallableResolver.php b/Slim/CallableResolver.php index 407724b5d..a622dcbee 100644 --- a/Slim/CallableResolver.php +++ b/Slim/CallableResolver.php @@ -199,9 +199,9 @@ private function prepareToResolve($toResolve) if (!is_array($toResolve)) { return $toResolve; } - $array = $toResolve; - $class = array_shift($array); - $method = array_shift($array); + $candidate = $toResolve; + $class = array_shift($candidate); + $method = array_shift($candidate); if (is_string($class) && is_string($method)) { return $class . ':' . $method; } From 2b8774e9011a1afbf7992984a31d7f234989ab6f Mon Sep 17 00:00:00 2001 From: Ivan Dudarev Date: Sun, 18 Apr 2021 15:43:06 +0700 Subject: [PATCH 3/3] Add method name to error message --- Slim/CallableResolver.php | 3 +++ tests/CallableResolverTest.php | 12 ++++++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/Slim/CallableResolver.php b/Slim/CallableResolver.php index a622dcbee..c1c351276 100644 --- a/Slim/CallableResolver.php +++ b/Slim/CallableResolver.php @@ -146,6 +146,9 @@ private function resolveSlimNotation(string $toResolve): array $instance = $this->container->get($class); } else { if (!class_exists($class)) { + if ($method) { + $class .= '::' . $method . '()'; + } throw new RuntimeException(sprintf('Callable %s does not exist', $class)); } $instance = new $class($this->container); diff --git a/tests/CallableResolverTest.php b/tests/CallableResolverTest.php index 8d739154b..27e0823a5 100644 --- a/tests/CallableResolverTest.php +++ b/tests/CallableResolverTest.php @@ -475,7 +475,7 @@ public function testMiddlewareFunctionNotFoundThrowException() public function testClassNotFoundThrowException() { $this->expectException(RuntimeException::class); - $this->expectExceptionMessage('Callable Unknown does not exist'); + $this->expectExceptionMessage('Callable Unknown::notFound() does not exist'); /** @var ContainerInterface $container */ $container = $this->containerProphecy->reveal(); @@ -486,7 +486,7 @@ public function testClassNotFoundThrowException() public function testRouteClassNotFoundThrowException() { $this->expectException(RuntimeException::class); - $this->expectExceptionMessage('Callable Unknown does not exist'); + $this->expectExceptionMessage('Callable Unknown::notFound() does not exist'); /** @var ContainerInterface $container */ $container = $this->containerProphecy->reveal(); @@ -497,7 +497,7 @@ public function testRouteClassNotFoundThrowException() public function testMiddlewareClassNotFoundThrowException() { $this->expectException(RuntimeException::class); - $this->expectExceptionMessage('Callable Unknown does not exist'); + $this->expectExceptionMessage('Callable Unknown::notFound() does not exist'); /** @var ContainerInterface $container */ $container = $this->containerProphecy->reveal(); @@ -508,7 +508,7 @@ public function testMiddlewareClassNotFoundThrowException() public function testCallableClassNotFoundThrowException() { $this->expectException(RuntimeException::class); - $this->expectExceptionMessage('Callable Unknown does not exist'); + $this->expectExceptionMessage('Callable Unknown::notFound() does not exist'); /** @var ContainerInterface $container */ $container = $this->containerProphecy->reveal(); @@ -519,7 +519,7 @@ public function testCallableClassNotFoundThrowException() public function testRouteCallableClassNotFoundThrowException() { $this->expectException(RuntimeException::class); - $this->expectExceptionMessage('Callable Unknown does not exist'); + $this->expectExceptionMessage('Callable Unknown::notFound() does not exist'); /** @var ContainerInterface $container */ $container = $this->containerProphecy->reveal(); @@ -530,7 +530,7 @@ public function testRouteCallableClassNotFoundThrowException() public function testMiddlewareCallableClassNotFoundThrowException() { $this->expectException(RuntimeException::class); - $this->expectExceptionMessage('Callable Unknown does not exist'); + $this->expectExceptionMessage('Callable Unknown::notFound() does not exist'); /** @var ContainerInterface $container */ $container = $this->containerProphecy->reveal();