Add PSR/Container dependency for type hint and expose the API

pull/567/head
fadrian06 10 months ago
parent 43b689fa6c
commit 389ebfd329

@ -24,8 +24,8 @@
], ],
"require": { "require": {
"php": "^7.4|^8.0|^8.1|^8.2|^8.3", "php": "^7.4|^8.0|^8.1|^8.2|^8.3",
"ext-json": "*"
"ext-json": "*", "ext-json": "*",
"psr/container": "^2.0",
"symfony/polyfill-php80": "^1.29" "symfony/polyfill-php80": "^1.29"
}, },
"autoload": { "autoload": {

@ -7,6 +7,7 @@ namespace flight\core;
use Exception; use Exception;
use flight\Engine; use flight\Engine;
use InvalidArgumentException; use InvalidArgumentException;
use Psr\Container\ContainerInterface;
use ReflectionFunction; use ReflectionFunction;
use TypeError; use TypeError;
@ -43,21 +44,25 @@ class Dispatcher
/** /**
* This is a container for the dependency injection. * 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; protected $containerHandler = null;
/** /**
* Sets the dependency injection container handler. * Sets the dependency injection container handler.
* *
* @param callable|object $containerHandler Dependency injection container * @param ContainerInterface|(callable(string $classString, array $params): (null|object)) $containerHandler
* * Dependency injection container.
* @return void
*/ */
public function setContainerHandler($containerHandler): void public function setContainerHandler($containerHandler): void
{ {
if (
$containerHandler instanceof ContainerInterface
|| is_callable($containerHandler)
) {
$this->containerHandler = $containerHandler; $this->containerHandler = $containerHandler;
} }
}
public function setEngine(Engine $engine): void public function setEngine(Engine $engine): void
{ {
@ -390,67 +395,66 @@ class Dispatcher
*/ */
protected function verifyValidClassCallable($class, $method, $resolvedClass): void 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 // 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) { if (!is_object($class) && !class_exists($class)) {
$final_exception = new Exception("Class '$class' not found. Is it being correctly autoloaded with Flight::path()?"); $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 // If this tried to resolve a class in a container and failed somehow, throw the exception
} elseif (isset($resolvedClass) === false && $this->containerException !== null) { } elseif (!$resolvedClass && $this->containerException) {
$final_exception = $this->containerException; $exception = $this->containerException;
// Class is there, but no method // Class is there, but no method
} elseif (is_object($class) === true && method_exists($class, $method) === false) { } elseif (is_object($class) && !method_exists($class, $method)) {
$final_exception = new Exception("Class found, but method '" . get_class($class) . "::$method' not found."); $classNamespace = get_class($class);
$exception = new Exception("Class found, but method '$classNamespace::$method' not found.");
} }
if ($final_exception !== null) { if ($exception) {
$this->fixOutputBuffering(); $this->fixOutputBuffering();
throw $final_exception;
throw $exception;
} }
} }
/** /**
* Resolves the container class. * Resolves the container class.
* *
* @param callable|object $container_handler Dependency injection container
* @param class-string $class Class name. * @param class-string $class Class name.
* @param array<int, mixed> &$params Class constructor parameters. * @param array<int, mixed> &$params Class constructor parameters.
* *
* @return ?object Class object. * @return ?object Class object.
*/ */
protected function resolveContainerClass($container_handler, $class, array &$params) protected function resolveContainerClass(string $class, array &$params)
{ {
$class_object = null;
// PSR-11 // PSR-11
if ( if (
is_object($container_handler) === true && $this->containerHandler instanceof ContainerInterface
method_exists($container_handler, 'has') === true && && $this->containerHandler->has($class)
$container_handler->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.) // Just a callable where you configure the behavior (Dice, PHP-DI, etc.)
} elseif (is_callable($container_handler) === true) { if (is_callable($this->containerHandler)) {
// This is to catch all the error that could be thrown by whatever container you are using /* This is to catch all the error that could be thrown by whatever
container you are using */
try { try {
$class_object = call_user_func($container_handler, $class, $params); return ($this->containerHandler)($class, $params);
} catch (Exception $e) {
// could not resolve a class for some reason
$class_object = null;
// could not resolve a class for some reason
} catch (Exception $exception) {
// If the container throws an exception, we need to catch it // If the container throws an exception, we need to catch it
// and store it somewhere. If we just let it throw itself, it // and store it somewhere. If we just let it throw itself, it
// doesn't properly close the output buffers and can cause other // doesn't properly close the output buffers and can cause other
// issues. // issues.
// This is thrown in the verifyValidClassCallable method // This is thrown in the verifyValidClassCallable method.
$this->containerException = $e; $this->containerException = $exception;
} }
} }
return $class_object; return null;
} }
/** Because this could throw an exception in the middle of an output buffer, */ /** Because this could throw an exception in the middle of an output buffer, */

Loading…
Cancel
Save