From f555e0382968cecc64395b7af19b75842b6734f3 Mon Sep 17 00:00:00 2001 From: mapogolions Date: Sun, 18 Aug 2019 01:00:21 +0500 Subject: [PATCH 1/4] Eliminate a duplicate code via HOF --- Slim/CallableResolver.php | 132 ++++++++++++++++++-------------------- 1 file changed, 64 insertions(+), 68 deletions(-) diff --git a/Slim/CallableResolver.php b/Slim/CallableResolver.php index 8fc015693..512854401 100644 --- a/Slim/CallableResolver.php +++ b/Slim/CallableResolver.php @@ -4,7 +4,6 @@ * * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License) */ - declare(strict_types=1); namespace Slim; @@ -41,16 +40,16 @@ public function __construct(?ContainerInterface $container = null) */ public function resolve($toResolve): callable { + if (is_callable($toResolve)) { + return $this->bindToContainer($toResolve); + } $resolved = $toResolve; - - if (!is_callable($toResolve) && is_string($toResolve)) { - $resolved = $this->resolveInstanceAndMethod($toResolve); - if ($resolved[1] === null) { - $resolved[1] = '__invoke'; - } + if (is_string($toResolve)) { + $resolved = $this->resolveSlimNotation($toResolve); + $resolved[1] = $resolved[1] ?? '__invoke'; } - - return $this->assertCallableAndBindClosureToContainer($resolved, $toResolve); + $callable = $this->assertCallable($resolved, $toResolve); + return $this->bindToContainer($callable); } /** @@ -58,25 +57,10 @@ public function resolve($toResolve): callable */ public function resolveRoute($toResolve): callable { - $resolved = $toResolve; - - if (!is_callable($toResolve) && is_string($toResolve)) { - [$instance, $method] = $this->resolveInstanceAndMethod($toResolve); - - // For a class that implements RequestHandlerInterface, we will call handle() - // if no method has been specified explicitly - if ($instance instanceof RequestHandlerInterface && $method === null) { - $method = 'handle'; - } - - $resolved = [$instance, $method ?? '__invoke']; - } - - if ($resolved instanceof RequestHandlerInterface) { - $resolved = [$resolved, 'handle']; - } - - return $this->assertCallableAndBindClosureToContainer($resolved, $toResolve); + $predicate = function ($it) { + return $it instanceof RequestHandlerInterface; + }; + return $this->resolveByPredicate($toResolve, $predicate, 'handle'); } /** @@ -84,46 +68,50 @@ public function resolveRoute($toResolve): callable */ public function resolveMiddleware($toResolve): callable { - $resolved = $toResolve; - - if (!is_callable($toResolve) && is_string($toResolve)) { - [$instance, $method] = $this->resolveInstanceAndMethod($toResolve); + $predicate = function ($it) { + return $it instanceof MiddlewareInterface; + }; + return $this->resolveByPredicate($toResolve, $predicate, 'process'); + } - // For a class that implements MiddlewareInterface, we will call process() - // if no method has been specified explicitly - if ($instance instanceof MiddlewareInterface && $method === null) { - $method = 'process'; + /** + * @param string|callable $toResolve + * @param Closure $predicate + * @param string $defaultMethod + * + * @throws RuntimeException + * + * @return callable + */ + private function resolveByPredicate($toResolve, Closure $predicate, string $defaultMethod): callable + { + if (is_callable($toResolve)) { + return $this->bindToContainer($toResolve); + } + $resolved = $toResolve; + if ($predicate($toResolve)) { + $resolved = [$toResolve, $defaultMethod]; + } + if (is_string($toResolve)) { + [$instance, $method] = $this->resolveSlimNotation($toResolve); + if ($predicate($instance) && $method === null) { + $method = $defaultMethod; } - $resolved = [$instance, $method ?? '__invoke']; } - - if ($resolved instanceof MiddlewareInterface) { - $resolved = [$resolved, 'process']; - } - - return $this->assertCallableAndBindClosureToContainer($resolved, $toResolve); + $callable = $this->assertCallable($resolved, $toResolve); + return $this->bindToContainer($callable); } /** - * Resolves the given param and if successful returns an instance as well - * as a method name. - * * @param string $toResolve * * @return array [Instance, Method Name] */ - private function resolveInstanceAndMethod(string $toResolve): array + private function resolveSlimNotation(string $toResolve): array { - $class = $toResolve; - $instance = null; - $method = null; - - // Check for Slim callable as `class:method` - if (preg_match(CallableResolver::$callablePattern, $toResolve, $matches)) { - $class = $matches[1]; - $method = $matches[2]; - } + preg_match(CallableResolver::$callablePattern, $toResolve, $matches); + [$class, $method] = $matches ? [$matches[1], $matches[2]] : [$toResolve, null]; if ($this->container && $this->container->has($class)) { $instance = $this->container->get($class); @@ -133,17 +121,18 @@ private function resolveInstanceAndMethod(string $toResolve): array } $instance = new $class($this->container); } - return [$instance, $method]; } /** - * @param mixed $resolved - * @param string|object|array|callable $toResolve + * @param mixed $resolved + * @param mixed $toResolve * - * @return callable + * @throws RuntimeException + * + * @returns callable */ - private function assertCallableAndBindClosureToContainer($resolved, $toResolve): callable + private function assertCallable($resolved, $toResolve): callable { if (!is_callable($resolved)) { throw new RuntimeException(sprintf( @@ -152,15 +141,22 @@ private function assertCallableAndBindClosureToContainer($resolved, $toResolve): json_encode($toResolve) : $toResolve )); } + return $resolved; + } - if (is_array($resolved) && $resolved[0] instanceof Closure) { - $resolved = $resolved[0]; + /** + * @param callable $callable + * + * @return callable + */ + private function bindToContainer(callable $callable): callable + { + if (is_array($callable) && $callable[0] instanceof Closure) { + $callable = $callable[0]; } - - if ($this->container && $resolved instanceof Closure) { - $resolved = $resolved->bindTo($this->container); + if ($this->container && $callable instanceof Closure) { + $callable = $callable->bindTo($this->container); } - - return $resolved; + return $callable; } } From b3d2377119c1370f2ee3921779b13d7c2592dd48 Mon Sep 17 00:00:00 2001 From: mapogolions Date: Sun, 18 Aug 2019 01:13:11 +0500 Subject: [PATCH 2/4] Fix typo --- Slim/CallableResolver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Slim/CallableResolver.php b/Slim/CallableResolver.php index 512854401..7f10aecb5 100644 --- a/Slim/CallableResolver.php +++ b/Slim/CallableResolver.php @@ -130,7 +130,7 @@ private function resolveSlimNotation(string $toResolve): array * * @throws RuntimeException * - * @returns callable + * @return callable */ private function assertCallable($resolved, $toResolve): callable { From c1e43d7304e93c4ddc31abefbf51c8be99001f54 Mon Sep 17 00:00:00 2001 From: mapogolions Date: Mon, 19 Aug 2019 00:20:55 +0500 Subject: [PATCH 3/4] Take a predicates out of the methods --- Slim/CallableResolver.php | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/Slim/CallableResolver.php b/Slim/CallableResolver.php index 7f10aecb5..1587dd001 100644 --- a/Slim/CallableResolver.php +++ b/Slim/CallableResolver.php @@ -57,10 +57,7 @@ public function resolve($toResolve): callable */ public function resolveRoute($toResolve): callable { - $predicate = function ($it) { - return $it instanceof RequestHandlerInterface; - }; - return $this->resolveByPredicate($toResolve, $predicate, 'handle'); + return $this->resolveByPredicate($toResolve, [$this, 'isRoute'], 'handle'); } /** @@ -68,22 +65,19 @@ public function resolveRoute($toResolve): callable */ public function resolveMiddleware($toResolve): callable { - $predicate = function ($it) { - return $it instanceof MiddlewareInterface; - }; - return $this->resolveByPredicate($toResolve, $predicate, 'process'); + return $this->resolveByPredicate($toResolve, [$this, 'isMiddleware'], 'process'); } /** * @param string|callable $toResolve - * @param Closure $predicate + * @param callable $predicate * @param string $defaultMethod * * @throws RuntimeException * * @return callable */ - private function resolveByPredicate($toResolve, Closure $predicate, string $defaultMethod): callable + private function resolveByPredicate($toResolve, callable $predicate, string $defaultMethod): callable { if (is_callable($toResolve)) { return $this->bindToContainer($toResolve); @@ -103,9 +97,31 @@ private function resolveByPredicate($toResolve, Closure $predicate, string $defa return $this->bindToContainer($callable); } + /** + * @param mixed $toResolve + * + * @return bool + */ + private function isRoute($toResolve): bool + { + return $toResolve instanceof RequestHandlerInterface; + } + + /** + * @param mixed $toResolve + * + * @return bool + */ + private function isMiddleware($toResolve): bool + { + return $toResolve instanceof MiddlewareInterface; + } + /** * @param string $toResolve * + * @throws RuntimeException + * * @return array [Instance, Method Name] */ private function resolveSlimNotation(string $toResolve): array From 706f3be8d62af62560d97e20cfbe6662d378fe35 Mon Sep 17 00:00:00 2001 From: mapogolions Date: Mon, 19 Aug 2019 00:22:16 +0500 Subject: [PATCH 4/4] Add empty line --- Slim/CallableResolver.php | 1 + 1 file changed, 1 insertion(+) diff --git a/Slim/CallableResolver.php b/Slim/CallableResolver.php index 1587dd001..71ed24dd0 100644 --- a/Slim/CallableResolver.php +++ b/Slim/CallableResolver.php @@ -4,6 +4,7 @@ * * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License) */ + declare(strict_types=1); namespace Slim;