|  |  | @ -4,10 +4,12 @@ declare(strict_types=1); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | namespace flight\core; |  |  |  | namespace flight\core; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | use Closure; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | use Exception; |  |  |  | use Exception; | 
			
		
	
		
		
			
				
					
					|  |  |  | use flight\Engine; |  |  |  | use flight\Engine; | 
			
		
	
		
		
			
				
					
					|  |  |  | use InvalidArgumentException; |  |  |  | use InvalidArgumentException; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | use Psr\Container\ContainerInterface; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | use ReflectionFunction; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | use Throwable; | 
			
		
	
		
		
			
				
					
					|  |  |  | use TypeError; |  |  |  | use TypeError; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | /** |  |  |  | /** | 
			
		
	
	
		
		
			
				
					|  |  | @ -23,41 +25,54 @@ class Dispatcher | 
			
		
	
		
		
			
				
					
					|  |  |  | { |  |  |  | { | 
			
		
	
		
		
			
				
					
					|  |  |  |     public const FILTER_BEFORE = 'before'; |  |  |  |     public const FILTER_BEFORE = 'before'; | 
			
		
	
		
		
			
				
					
					|  |  |  |     public const FILTER_AFTER = 'after'; |  |  |  |     public const FILTER_AFTER = 'after'; | 
			
		
	
		
		
			
				
					
					|  |  |  |     private const FILTER_TYPES = [self::FILTER_BEFORE, self::FILTER_AFTER]; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     /** @var mixed $containerException Exception message if thrown by setting the container as a callable method */ |  |  |  |     /** Exception message if thrown by setting the container as a callable method. */ | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     protected $containerException = null; |  |  |  |     protected ?Throwable $containerException = null; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     /** @var ?Engine $engine Engine instance */ |  |  |  |     /** @var ?Engine $engine Engine instance. */ | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     protected ?Engine $engine = null; |  |  |  |     protected ?Engine $engine = null; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     /** @var array<string, Closure(): (void|mixed)> Mapped events. */ |  |  |  |     /** @var array<string, callable(): (void|mixed)> Mapped events. */ | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     protected array $events = []; |  |  |  |     protected array $events = []; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     /** |  |  |  |     /** | 
			
		
	
		
		
			
				
					
					|  |  |  |      * Method filters. |  |  |  |      * Method filters. | 
			
		
	
		
		
			
				
					
					|  |  |  |      * |  |  |  |      * | 
			
		
	
		
		
			
				
					
					|  |  |  |      * @var array<string, array<'before'|'after', array<int, Closure(array<int, mixed> &$params, mixed &$output): (void|false)>>> |  |  |  |      * @var array<string, array<'before'|'after', array<int, callable(array<int, mixed> &$params, mixed &$output): (void|false)>>> | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |      */ |  |  |  |      */ | 
			
		
	
		
		
			
				
					
					|  |  |  |     protected array $filters = []; |  |  |  |     protected array $filters = []; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     /** |  |  |  |     /** | 
			
		
	
		
		
			
				
					
					|  |  |  |      * 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<int, mixed> $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<int, mixed> $params): (null|object)) $containerHandler | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      * Dependency injection container. | 
			
		
	
		
		
			
				
					
					|  |  |  |      * |  |  |  |      * | 
			
		
	
		
		
			
				
					
					|  |  |  |      * @return void |  |  |  |      * @throws InvalidArgumentException If $containerHandler is not a `callable` or instance of `Psr\Container\ContainerInterface`. | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |      */ |  |  |  |      */ | 
			
		
	
		
		
			
				
					
					|  |  |  |     public function setContainerHandler($containerHandler): void |  |  |  |     public function setContainerHandler($containerHandler): void | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |         $this->containerHandler = $containerHandler; |  |  |  |         $containerInterfaceNS = '\Psr\Container\ContainerInterface'; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         if ( | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             is_a($containerHandler, $containerInterfaceNS) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             || is_callable($containerHandler) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         ) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             $this->containerHandler = $containerHandler; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             return; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         throw new InvalidArgumentException( | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             "\$containerHandler must be of type callable or instance $containerInterfaceNS" | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         ); | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     public function setEngine(Engine $engine): void |  |  |  |     public function setEngine(Engine $engine): void | 
			
		
	
	
		
		
			
				
					|  |  | @ -68,11 +83,11 @@ class Dispatcher | 
			
		
	
		
		
			
				
					
					|  |  |  |     /** |  |  |  |     /** | 
			
		
	
		
		
			
				
					
					|  |  |  |      * Dispatches an event. |  |  |  |      * Dispatches an event. | 
			
		
	
		
		
			
				
					
					|  |  |  |      * |  |  |  |      * | 
			
		
	
		
		
			
				
					
					|  |  |  |      * @param string $name Event name |  |  |  |      * @param string $name Event name. | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |      * @param array<int, mixed> $params Callback parameters. |  |  |  |      * @param array<int, mixed> $params Callback parameters. | 
			
		
	
		
		
			
				
					
					|  |  |  |      * |  |  |  |      * | 
			
		
	
		
		
			
				
					
					|  |  |  |      * @return mixed Output of callback |  |  |  |      * @return mixed Output of callback | 
			
		
	
		
		
			
				
					
					|  |  |  |      * @throws Exception If event name isn't found or if event throws an `Exception` |  |  |  |      * @throws Exception If event name isn't found or if event throws an `Exception`. | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |      */ |  |  |  |      */ | 
			
		
	
		
		
			
				
					
					|  |  |  |     public function run(string $name, array $params = []) |  |  |  |     public function run(string $name, array $params = []) | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
	
		
		
			
				
					|  |  | @ -110,7 +125,7 @@ class Dispatcher | 
			
		
	
		
		
			
				
					
					|  |  |  |         $requestedMethod = $this->get($eventName); |  |  |  |         $requestedMethod = $this->get($eventName); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         if ($requestedMethod === null) { |  |  |  |         if ($requestedMethod === null) { | 
			
		
	
		
		
			
				
					
					|  |  |  |             throw new Exception("Event '{$eventName}' isn't found."); |  |  |  |             throw new Exception("Event '$eventName' isn't found."); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         return $this->execute($requestedMethod, $params); |  |  |  |         return $this->execute($requestedMethod, $params); | 
			
		
	
	
		
		
			
				
					|  |  | @ -138,8 +153,8 @@ class Dispatcher | 
			
		
	
		
		
			
				
					
					|  |  |  |     /** |  |  |  |     /** | 
			
		
	
		
		
			
				
					
					|  |  |  |      * Assigns a callback to an event. |  |  |  |      * Assigns a callback to an event. | 
			
		
	
		
		
			
				
					
					|  |  |  |      * |  |  |  |      * | 
			
		
	
		
		
			
				
					
					|  |  |  |      * @param string $name Event name |  |  |  |      * @param string $name Event name. | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |      * @param Closure(): (void|mixed) $callback Callback function |  |  |  |      * @param callable(): (void|mixed) $callback Callback function. | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |      * |  |  |  |      * | 
			
		
	
		
		
			
				
					
					|  |  |  |      * @return $this |  |  |  |      * @return $this | 
			
		
	
		
		
			
				
					
					|  |  |  |      */ |  |  |  |      */ | 
			
		
	
	
		
		
			
				
					|  |  | @ -153,9 +168,9 @@ class Dispatcher | 
			
		
	
		
		
			
				
					
					|  |  |  |     /** |  |  |  |     /** | 
			
		
	
		
		
			
				
					
					|  |  |  |      * Gets an assigned callback. |  |  |  |      * Gets an assigned callback. | 
			
		
	
		
		
			
				
					
					|  |  |  |      * |  |  |  |      * | 
			
		
	
		
		
			
				
					
					|  |  |  |      * @param string $name Event name |  |  |  |      * @param string $name Event name. | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |      * |  |  |  |      * | 
			
		
	
		
		
			
				
					
					|  |  |  |      * @return null|(Closure(): (void|mixed)) $callback Callback function |  |  |  |      * @return null|(callable(): (void|mixed)) $callback Callback function. | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |      */ |  |  |  |      */ | 
			
		
	
		
		
			
				
					
					|  |  |  |     public function get(string $name): ?callable |  |  |  |     public function get(string $name): ?callable | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
	
		
		
			
				
					|  |  | @ -165,9 +180,9 @@ class Dispatcher | 
			
		
	
		
		
			
				
					
					|  |  |  |     /** |  |  |  |     /** | 
			
		
	
		
		
			
				
					
					|  |  |  |      * Checks if an event has been set. |  |  |  |      * Checks if an event has been set. | 
			
		
	
		
		
			
				
					
					|  |  |  |      * |  |  |  |      * | 
			
		
	
		
		
			
				
					
					|  |  |  |      * @param string $name Event name |  |  |  |      * @param string $name Event name. | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |      * |  |  |  |      * | 
			
		
	
		
		
			
				
					
					|  |  |  |      * @return bool Event status |  |  |  |      * @return bool If event exists or doesn't exists. | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |      */ |  |  |  |      */ | 
			
		
	
		
		
			
				
					
					|  |  |  |     public function has(string $name): bool |  |  |  |     public function has(string $name): bool | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
	
		
		
			
				
					|  |  | @ -177,7 +192,7 @@ class Dispatcher | 
			
		
	
		
		
			
				
					
					|  |  |  |     /** |  |  |  |     /** | 
			
		
	
		
		
			
				
					
					|  |  |  |      * Clears an event. If no name is given, all events will be removed. |  |  |  |      * Clears an event. If no name is given, all events will be removed. | 
			
		
	
		
		
			
				
					
					|  |  |  |      * |  |  |  |      * | 
			
		
	
		
		
			
				
					
					|  |  |  |      * @param ?string $name Event name |  |  |  |      * @param ?string $name Event name. | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |      */ |  |  |  |      */ | 
			
		
	
		
		
			
				
					
					|  |  |  |     public function clear(?string $name = null): void |  |  |  |     public function clear(?string $name = null): void | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
	
		
		
			
				
					|  |  | @ -188,27 +203,38 @@ class Dispatcher | 
			
		
	
		
		
			
				
					
					|  |  |  |             return; |  |  |  |             return; | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         $this->events = []; |  |  |  |         $this->reset(); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         $this->filters = []; |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     /** |  |  |  |     /** | 
			
		
	
		
		
			
				
					
					|  |  |  |      * Hooks a callback to an event. |  |  |  |      * Hooks a callback to an event. | 
			
		
	
		
		
			
				
					
					|  |  |  |      * |  |  |  |      * | 
			
		
	
		
		
			
				
					
					|  |  |  |      * @param string $name Event name |  |  |  |      * @param string $name Event name | 
			
		
	
		
		
			
				
					
					|  |  |  |      * @param 'before'|'after' $type Filter type |  |  |  |      * @param 'before'|'after' $type Filter type. | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |      * @param Closure(array<int, mixed> &$params, string &$output): (void|false) $callback |  |  |  |      * @param callable(array<int, mixed> &$params, mixed &$output): (void|false)|callable(mixed &$output): (void|false) $callback | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |      * |  |  |  |      * | 
			
		
	
		
		
			
				
					
					|  |  |  |      * @return $this |  |  |  |      * @return $this | 
			
		
	
		
		
			
				
					
					|  |  |  |      */ |  |  |  |      */ | 
			
		
	
		
		
			
				
					
					|  |  |  |     public function hook(string $name, string $type, callable $callback): self |  |  |  |     public function hook(string $name, string $type, callable $callback): self | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (!in_array($type, self::FILTER_TYPES, true)) { |  |  |  |         static $filterTypes = [self::FILTER_BEFORE, self::FILTER_AFTER]; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             $noticeMessage = "Invalid filter type '$type', use " . join('|', self::FILTER_TYPES); |  |  |  | 
 | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         if (!in_array($type, $filterTypes, true)) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             $noticeMessage = "Invalid filter type '$type', use " . join('|', $filterTypes); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             trigger_error($noticeMessage, E_USER_NOTICE); |  |  |  |             trigger_error($noticeMessage, E_USER_NOTICE); | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         if ($type === self::FILTER_AFTER) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             $callbackInfo = new ReflectionFunction($callback); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             $parametersNumber = $callbackInfo->getNumberOfParameters(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             if ($parametersNumber === 1) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 /** @disregard &$params in after filters are deprecated. */ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 $callback = fn (array &$params, &$output) => $callback($output); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         $this->filters[$name][$type][] = $callback; |  |  |  |         $this->filters[$name][$type][] = $callback; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         return $this; |  |  |  |         return $this; | 
			
		
	
	
		
		
			
				
					|  |  | @ -217,10 +243,10 @@ class Dispatcher | 
			
		
	
		
		
			
				
					
					|  |  |  |     /** |  |  |  |     /** | 
			
		
	
		
		
			
				
					
					|  |  |  |      * Executes a chain of method filters. |  |  |  |      * Executes a chain of method filters. | 
			
		
	
		
		
			
				
					
					|  |  |  |      * |  |  |  |      * | 
			
		
	
		
		
			
				
					
					|  |  |  |      * @param array<int, Closure(array<int, mixed> &$params, mixed &$output): (void|false)> $filters |  |  |  |      * @param array<int, callable(array<int, mixed> &$params, mixed &$output): (void|false)> $filters | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |      * Chain of filters- |  |  |  |      * Chain of filters. | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |      * @param array<int, mixed> $params Method parameters |  |  |  |      * @param array<int, mixed> $params Method parameters. | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |      * @param mixed $output Method output |  |  |  |      * @param mixed $output Method output. | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |      * |  |  |  |      * | 
			
		
	
		
		
			
				
					
					|  |  |  |      * @throws Exception If an event throws an `Exception` or if `$filters` contains an invalid filter. |  |  |  |      * @throws Exception If an event throws an `Exception` or if `$filters` contains an invalid filter. | 
			
		
	
		
		
			
				
					
					|  |  |  |      */ |  |  |  |      */ | 
			
		
	
	
		
		
			
				
					|  |  | @ -242,16 +268,19 @@ class Dispatcher | 
			
		
	
		
		
			
				
					
					|  |  |  |     /** |  |  |  |     /** | 
			
		
	
		
		
			
				
					
					|  |  |  |      * Executes a callback function. |  |  |  |      * Executes a callback function. | 
			
		
	
		
		
			
				
					
					|  |  |  |      * |  |  |  |      * | 
			
		
	
		
		
			
				
					
					|  |  |  |      * @param callable-string|(Closure(): mixed)|array{class-string|object, string} $callback |  |  |  |      * @param callable-string|(callable(): mixed)|array{class-string|object, string} $callback | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |      * Callback function |  |  |  |      * Callback function. | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |      * @param array<int, mixed> $params Function parameters |  |  |  |      * @param array<int, mixed> $params Function parameters. | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |      * |  |  |  |      * | 
			
		
	
		
		
			
				
					
					|  |  |  |      * @return mixed Function results |  |  |  |      * @return mixed Function results. | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |      * @throws Exception If `$callback` also throws an `Exception`. |  |  |  |      * @throws Exception If `$callback` also throws an `Exception`. | 
			
		
	
		
		
			
				
					
					|  |  |  |      */ |  |  |  |      */ | 
			
		
	
		
		
			
				
					
					|  |  |  |     public function execute($callback, array &$params = []) |  |  |  |     public function execute($callback, array &$params = []) | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (is_string($callback) === true && (strpos($callback, '->') !== false || strpos($callback, '::') !== false)) { |  |  |  |         if ( | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             is_string($callback) === true | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             && (strpos($callback, '->') !== false || strpos($callback, '::') !== false) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         ) { | 
			
		
	
		
		
			
				
					
					|  |  |  |             $callback = $this->parseStringClassAndMethod($callback); |  |  |  |             $callback = $this->parseStringClassAndMethod($callback); | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -263,28 +292,26 @@ class Dispatcher | 
			
		
	
		
		
			
				
					
					|  |  |  |      * |  |  |  |      * | 
			
		
	
		
		
			
				
					
					|  |  |  |      * @param string $classAndMethod Class and method |  |  |  |      * @param string $classAndMethod Class and method | 
			
		
	
		
		
			
				
					
					|  |  |  |      * |  |  |  |      * | 
			
		
	
		
		
			
				
					
					|  |  |  |      * @return array{class-string|object, string} Class and method |  |  |  |      * @return array{0: class-string|object, 1: string} Class and method | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |      */ |  |  |  |      */ | 
			
		
	
		
		
			
				
					
					|  |  |  |     public function parseStringClassAndMethod(string $classAndMethod): array |  |  |  |     public function parseStringClassAndMethod(string $classAndMethod): array | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |         $class_parts = explode('->', $classAndMethod); |  |  |  |         $classParts = explode('->', $classAndMethod); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         if (count($class_parts) === 1) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             $class_parts = explode('::', $class_parts[0]); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         $class = $class_parts[0]; |  |  |  |         if (count($classParts) === 1) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         $method = $class_parts[1]; |  |  |  |             $classParts = explode('::', $classParts[0]); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         return [ $class, $method ]; |  |  |  |         return $classParts; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     /** |  |  |  |     /** | 
			
		
	
		
		
			
				
					
					|  |  |  |      * Calls a function. |  |  |  |      * Calls a function. | 
			
		
	
		
		
			
				
					
					|  |  |  |      * |  |  |  |      * | 
			
		
	
		
		
			
				
					
					|  |  |  |      * @param callable $func Name of function to call |  |  |  |      * @param callable $func Name of function to call. | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |      * @param array<int, mixed> &$params Function parameters |  |  |  |      * @param array<int, mixed> &$params Function parameters. | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |      * |  |  |  |      * | 
			
		
	
		
		
			
				
					
					|  |  |  |      * @return mixed Function results |  |  |  |      * @return mixed Function results. | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |      * @deprecated 3.7.0 Use invokeCallable instead |  |  |  |      * @deprecated 3.7.0 Use invokeCallable instead | 
			
		
	
		
		
			
				
					
					|  |  |  |      */ |  |  |  |      */ | 
			
		
	
		
		
			
				
					
					|  |  |  |     public function callFunction(callable $func, array &$params = []) |  |  |  |     public function callFunction(callable $func, array &$params = []) | 
			
		
	
	
		
		
			
				
					|  |  | @ -295,12 +322,12 @@ class Dispatcher | 
			
		
	
		
		
			
				
					
					|  |  |  |     /** |  |  |  |     /** | 
			
		
	
		
		
			
				
					
					|  |  |  |      * Invokes a method. |  |  |  |      * Invokes a method. | 
			
		
	
		
		
			
				
					
					|  |  |  |      * |  |  |  |      * | 
			
		
	
		
		
			
				
					
					|  |  |  |      * @param array{class-string|object, string} $func Class method |  |  |  |      * @param array{0: class-string|object, 1: string} $func Class method. | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |      * @param array<int, mixed> &$params Class method parameters |  |  |  |      * @param array<int, mixed> &$params Class method parameters. | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |      * |  |  |  |      * | 
			
		
	
		
		
			
				
					
					|  |  |  |      * @return mixed Function results |  |  |  |      * @return mixed Function results. | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |      * @throws TypeError For nonexistent class name. |  |  |  |      * @throws TypeError For nonexistent class name. | 
			
		
	
		
		
			
				
					
					|  |  |  |      * @deprecated 3.7.0 Use invokeCallable instead |  |  |  |      * @deprecated 3.7.0 Use invokeCallable instead. | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |      */ |  |  |  |      */ | 
			
		
	
		
		
			
				
					
					|  |  |  |     public function invokeMethod(array $func, array &$params = []) |  |  |  |     public function invokeMethod(array $func, array &$params = []) | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
	
		
		
			
				
					|  |  | @ -310,12 +337,12 @@ class Dispatcher | 
			
		
	
		
		
			
				
					
					|  |  |  |     /** |  |  |  |     /** | 
			
		
	
		
		
			
				
					
					|  |  |  |      * Invokes a callable (anonymous function or Class->method). |  |  |  |      * Invokes a callable (anonymous function or Class->method). | 
			
		
	
		
		
			
				
					
					|  |  |  |      * |  |  |  |      * | 
			
		
	
		
		
			
				
					
					|  |  |  |      * @param array{class-string|object, string}|Callable $func Class method |  |  |  |      * @param array{0: class-string|object, 1: string}|callable $func Class method. | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |      * @param array<int, mixed> &$params Class method parameters |  |  |  |      * @param array<int, mixed> &$params Class method parameters. | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |      * |  |  |  |      * | 
			
		
	
		
		
			
				
					
					|  |  |  |      * @return mixed Function results |  |  |  |      * @return mixed Function results. | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |      * @throws TypeError For nonexistent class name. |  |  |  |      * @throws TypeError For nonexistent class name. | 
			
		
	
		
		
			
				
					
					|  |  |  |      * @throws InvalidArgumentException If the constructor requires parameters |  |  |  |      * @throws InvalidArgumentException If the constructor requires parameters. | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |      * @version 3.7.0 |  |  |  |      * @version 3.7.0 | 
			
		
	
		
		
			
				
					
					|  |  |  |      */ |  |  |  |      */ | 
			
		
	
		
		
			
				
					
					|  |  |  |     public function invokeCallable($func, array &$params = []) |  |  |  |     public function invokeCallable($func, array &$params = []) | 
			
		
	
	
		
		
			
				
					|  |  | @ -323,56 +350,46 @@ class Dispatcher | 
			
		
	
		
		
			
				
					
					|  |  |  |         // If this is a directly callable function, call it |  |  |  |         // If this is a directly callable function, call it | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (is_array($func) === false) { |  |  |  |         if (is_array($func) === false) { | 
			
		
	
		
		
			
				
					
					|  |  |  |             $this->verifyValidFunction($func); |  |  |  |             $this->verifyValidFunction($func); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             return call_user_func_array($func, $params); |  |  |  |             return call_user_func_array($func, $params); | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         [$class, $method] = $func; |  |  |  |         [$class, $method] = $func; | 
			
		
	
		
		
			
				
					
					|  |  |  |         $resolvedClass = null; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         // Only execute the container handler if it's not a Flight class |  |  |  |         $mustUseTheContainer = $this->containerHandler !== null && ( | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         if ( |  |  |  |             (is_object($class) === true && strpos(get_class($class), 'flight\\') === false) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             $this->containerHandler !== null && |  |  |  |             || is_string($class) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             ( |  |  |  |         ); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 ( |  |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                     is_object($class) === true && |  |  |  |         if ($mustUseTheContainer === true) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                     strpos(get_class($class), 'flight\\') === false |  |  |  |             $resolvedClass = $this->resolveContainerClass($class, $params); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 ) || |  |  |  | 
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 is_string($class) === true |  |  |  |             if ($resolvedClass) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             ) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         ) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             $containerHandler = $this->containerHandler; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             $resolvedClass = $this->resolveContainerClass($containerHandler, $class, $params); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             if ($resolvedClass !== null) { |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                 $class = $resolvedClass; |  |  |  |                 $class = $resolvedClass; | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         $this->verifyValidClassCallable($class, $method, $resolvedClass); |  |  |  |         $this->verifyValidClassCallable($class, $method, $resolvedClass ?? null); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         // Class is a string, and method exists, create the object by hand and inject only the Engine |  |  |  |         // Class is a string, and method exists, create the object by hand and inject only the Engine | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (is_string($class) === true) { |  |  |  |         if (is_string($class)) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |             $class = new $class($this->engine); |  |  |  |             $class = new $class($this->engine); | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         return call_user_func_array([ $class, $method ], $params); |  |  |  |         return call_user_func_array([$class, $method], $params); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     /** |  |  |  |     /** | 
			
		
	
		
		
			
				
					
					|  |  |  |      * Handles invalid callback types. |  |  |  |      * Handles invalid callback types. | 
			
		
	
		
		
			
				
					
					|  |  |  |      * |  |  |  |      * | 
			
		
	
		
		
			
				
					
					|  |  |  |      * @param callable-string|(Closure(): mixed)|array{class-string|object, string} $callback |  |  |  |      * @param callable-string|(callable(): mixed)|array{0: class-string|object, 1: string} $callback | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |      * Callback function |  |  |  |      * Callback function. | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |      * |  |  |  |      * | 
			
		
	
		
		
			
				
					
					|  |  |  |      * @throws InvalidArgumentException If `$callback` is an invalid type |  |  |  |      * @throws InvalidArgumentException If `$callback` is an invalid type. | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |      */ |  |  |  |      */ | 
			
		
	
		
		
			
				
					
					|  |  |  |     protected function verifyValidFunction($callback): void |  |  |  |     protected function verifyValidFunction($callback): void | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |         $isInvalidFunctionName = ( |  |  |  |         if (is_string($callback) && !function_exists($callback)) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             is_string($callback) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             && !function_exists($callback) |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         ); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         if ($isInvalidFunctionName) { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |             throw new InvalidArgumentException('Invalid callback specified.'); |  |  |  |             throw new InvalidArgumentException('Invalid callback specified.'); | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
	
		
		
			
				
					|  |  | @ -381,84 +398,77 @@ class Dispatcher | 
			
		
	
		
		
			
				
					
					|  |  |  |     /** |  |  |  |     /** | 
			
		
	
		
		
			
				
					
					|  |  |  |      * Verifies if the provided class and method are valid callable. |  |  |  |      * Verifies if the provided class and method are valid callable. | 
			
		
	
		
		
			
				
					
					|  |  |  |      * |  |  |  |      * | 
			
		
	
		
		
			
				
					
					|  |  |  |      * @param string|object $class The class name. |  |  |  |      * @param class-string|object $class The class name. | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |      * @param string $method The method name. |  |  |  |      * @param string $method The method name. | 
			
		
	
		
		
			
				
					
					|  |  |  |      * @param object|null $resolvedClass The resolved class. |  |  |  |      * @param object|null $resolvedClass The resolved class. | 
			
		
	
		
		
			
				
					
					|  |  |  |      * |  |  |  |      * | 
			
		
	
		
		
			
				
					
					|  |  |  |      * @throws Exception If the class or method is not found. |  |  |  |      * @throws Exception If the class or method is not found. | 
			
		
	
		
		
			
				
					
					|  |  |  |      * |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |      * @return void |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |      */ |  |  |  |      */ | 
			
		
	
		
		
			
				
					
					|  |  |  |     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) === false && class_exists($class) === false) { | 
			
		
	
		
		
			
				
					
					|  |  |  |             $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 !== null) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             $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) === true && method_exists($class, $method) === false) { | 
			
		
	
		
		
			
				
					
					|  |  |  |             $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 !== null) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |             $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 && |  |  |  |             is_a($this->containerHandler, '\Psr\Container\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, |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |      * |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |      * @return void |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |      */ |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     protected function fixOutputBuffering(): void |  |  |  |     protected function fixOutputBuffering(): void | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |         // Cause PHPUnit has 1 level of output buffering by default |  |  |  |         // Cause PHPUnit has 1 level of output buffering by default | 
			
		
	
	
		
		
			
				
					|  |  | 
 |