From 389ebfd32978c9556367c76f2d121bf52dd507ba Mon Sep 17 00:00:00 2001 From: fadrian06 Date: Mon, 1 Apr 2024 18:59:23 -0400 Subject: [PATCH] Add PSR/Container dependency for type hint and expose the API --- composer.json | 2 +- flight/core/Dispatcher.php | 70 ++++++++++++++++++++------------------ 2 files changed, 38 insertions(+), 34 deletions(-) diff --git a/composer.json b/composer.json index e30b937..df9bfb0 100644 --- a/composer.json +++ b/composer.json @@ -24,8 +24,8 @@ ], "require": { "php": "^7.4|^8.0|^8.1|^8.2|^8.3", - "ext-json": "*" "ext-json": "*", + "psr/container": "^2.0", "symfony/polyfill-php80": "^1.29" }, "autoload": { diff --git a/flight/core/Dispatcher.php b/flight/core/Dispatcher.php index f08d1f0..77184e7 100644 --- a/flight/core/Dispatcher.php +++ b/flight/core/Dispatcher.php @@ -7,6 +7,7 @@ namespace flight\core; use Exception; use flight\Engine; use InvalidArgumentException; +use Psr\Container\ContainerInterface; use ReflectionFunction; use TypeError; @@ -43,20 +44,24 @@ class Dispatcher /** * This is a container for the dependency injection. * - * @var callable|object|null + * @var null|ContainerInterface|(callable(string $classString, array $params): (null|object)) */ protected $containerHandler = null; /** * Sets the dependency injection container handler. * - * @param callable|object $containerHandler Dependency injection container - * - * @return void + * @param ContainerInterface|(callable(string $classString, array $params): (null|object)) $containerHandler + * Dependency injection container. */ public function setContainerHandler($containerHandler): void { - $this->containerHandler = $containerHandler; + if ( + $containerHandler instanceof ContainerInterface + || is_callable($containerHandler) + ) { + $this->containerHandler = $containerHandler; + } } public function setEngine(Engine $engine): void @@ -390,67 +395,66 @@ class Dispatcher */ protected function verifyValidClassCallable($class, $method, $resolvedClass): void { - $final_exception = null; + $exception = null; // Final check to make sure it's actually a class and a method, or throw an error - if (is_object($class) === false && class_exists($class) === false) { - $final_exception = new Exception("Class '$class' not found. Is it being correctly autoloaded with Flight::path()?"); + if (!is_object($class) && !class_exists($class)) { + $exception = new Exception("Class '$class' not found. Is it being correctly autoloaded with Flight::path()?"); - // If this tried to resolve a class in a container and failed somehow, throw the exception - } elseif (isset($resolvedClass) === false && $this->containerException !== null) { - $final_exception = $this->containerException; + // If this tried to resolve a class in a container and failed somehow, throw the exception + } elseif (!$resolvedClass && $this->containerException) { + $exception = $this->containerException; - // Class is there, but no method - } elseif (is_object($class) === true && method_exists($class, $method) === false) { - $final_exception = new Exception("Class found, but method '" . get_class($class) . "::$method' not found."); + // Class is there, but no method + } elseif (is_object($class) && !method_exists($class, $method)) { + $classNamespace = get_class($class); + $exception = new Exception("Class found, but method '$classNamespace::$method' not found."); } - if ($final_exception !== null) { + if ($exception) { $this->fixOutputBuffering(); - throw $final_exception; + + throw $exception; } } /** * Resolves the container class. * - * @param callable|object $container_handler Dependency injection container * @param class-string $class Class name. * @param array &$params Class constructor parameters. * * @return ?object Class object. */ - protected function resolveContainerClass($container_handler, $class, array &$params) + protected function resolveContainerClass(string $class, array &$params) { - $class_object = null; - // PSR-11 if ( - is_object($container_handler) === true && - method_exists($container_handler, 'has') === true && - $container_handler->has($class) + $this->containerHandler instanceof ContainerInterface + && $this->containerHandler->has($class) ) { - $class_object = call_user_func([$container_handler, 'get'], $class); + return $this->containerHandler->get($class); + } // Just a callable where you configure the behavior (Dice, PHP-DI, etc.) - } elseif (is_callable($container_handler) === true) { - // This is to catch all the error that could be thrown by whatever container you are using + if (is_callable($this->containerHandler)) { + /* This is to catch all the error that could be thrown by whatever + container you are using */ try { - $class_object = call_user_func($container_handler, $class, $params); - } catch (Exception $e) { - // could not resolve a class for some reason - $class_object = null; + return ($this->containerHandler)($class, $params); + // could not resolve a class for some reason + } catch (Exception $exception) { // If the container throws an exception, we need to catch it // and store it somewhere. If we just let it throw itself, it // doesn't properly close the output buffers and can cause other // issues. - // This is thrown in the verifyValidClassCallable method - $this->containerException = $e; + // This is thrown in the verifyValidClassCallable method. + $this->containerException = $exception; } } - return $class_object; + return null; } /** Because this could throw an exception in the middle of an output buffer, */