From 5fa000f9182be9f4e258e48491e2d983ac522d01 Mon Sep 17 00:00:00 2001 From: "Bruno O. Notario" Date: Wed, 24 Jan 2024 15:07:28 -0300 Subject: [PATCH] Auto class injection --- system/Exception/ReflectionException.php | 19 +++++ system/database/databases/object/result.php | 1 + system/engine/front.php | 81 +++++++++++++++++---- system/engine/registry.php | 57 ++++++++++++++- 4 files changed, 141 insertions(+), 17 deletions(-) create mode 100644 system/Exception/ReflectionException.php diff --git a/system/Exception/ReflectionException.php b/system/Exception/ReflectionException.php new file mode 100644 index 0000000..c050399 --- /dev/null +++ b/system/Exception/ReflectionException.php @@ -0,0 +1,19 @@ +rows = $rows; + $this->row = isset($rows[0]) ? $this->rows[0] : null; return $this; } diff --git a/system/engine/front.php b/system/engine/front.php index 89c398a..045cf4d 100644 --- a/system/engine/front.php +++ b/system/engine/front.php @@ -70,13 +70,13 @@ final class Front implements frontInterface { $action = $this->execute($action); } } - + /** * @param object $action - * @return \Phacil\Framework\Interfaces\Action|\Phacil\Framework\Controller + * @return \Phacil\Framework\Interfaces\Action|\Phacil\Framework\Interfaces\Controller|null * @throws Exception */ - private function execute($action) { + private function execute(\Phacil\Framework\Interfaces\Action $action) { $file = $action->getFile(); $class = $action->getClass(); $classAlt = $action->getClassAlt(); @@ -91,20 +91,21 @@ final class Front implements frontInterface { foreach($classAlt as $classController){ try { if(class_exists($classController)){ - $controller = new $classController($this->registry); - if(!is_subclass_of($controller, 'Phacil\Framework\Controller')){ + $action = $this->callController($this->injectionClass($classController), $method, $args); + + /* if(!is_subclass_of($controller, 'Phacil\Framework\Controller')){ throw new Exception('PHACIL ERROR: Controller '. get_class($controller) . ' doesn\'t have Phacil\Framework\Controller implemented'); - } + } */ break; } - } catch (Exception $th) { - //throw $th; + } catch (\Phacil\Framework\Exception\Throwable $th) { + throw $th; } } - try { + /* try { if (is_callable(array($controller, $method))) { $action = call_user_func_array(array($controller, $method), $args); } else { @@ -113,7 +114,7 @@ final class Front implements frontInterface { $this->error = ''; throw new Exception("The controller can't be loaded", 1); } - } catch (Exception $th) { + } catch (\Phacil\Framework\Exception\Throwable $th) { //throw $th; $action = new Action($this->error); @@ -121,13 +122,14 @@ final class Front implements frontInterface { throw new Exception("The controller can't be loaded: ".$th->getMessage(), $th->getCode(), $th); - } + } */ } elseif(!$file && isset($classAlt['class'])) { try { - $controller = new $classAlt['class']($this->registry); + $this->injectionClass($classController); + $action = $this->callController(new $classAlt['class']($this->registry), $method, $args); - if (!is_subclass_of($controller, 'Phacil\Framework\Controller')) { + /* if (!is_subclass_of($controller, 'Phacil\Framework\Controller')) { throw new Exception('PHACIL ERROR: Controller ' . get_class($controller) . ' doesn\'t have Phacil\Framework\Controller implemented'); } @@ -139,9 +141,9 @@ final class Front implements frontInterface { new Exception("PHACIL ERROR: Controller class " . get_class($controller) . "->".$method."() is not a callable function"); } else { $action = call_user_func_array(array($controller, $method), $args); - } - } catch (Exception $th) { - throw new Exception("The controller can't be loaded: " . $th->getMessage(), $th->getCode(), $th); + } */ + } catch (\Phacil\Framework\Exception\Throwable $th) { + throw ($th); } }else { $action = new Action($this->error); @@ -151,4 +153,51 @@ final class Front implements frontInterface { return $action; } + + /** + * + * @param \Phacil\Framework\Interfaces\Controller $controller + * @return \Phacil\Framework\Interfaces\Controller|\Phacil\Framework\Interfaces\Action|null + * @throws \Phacil\Framework\Exception + */ + protected function callController(\Phacil\Framework\Interfaces\Controller $controller, $method, $args = array()) { + try { + //code... + if (is_callable(array($controller, $method))) { + $action = call_user_func_array(array($controller, $method), $args); + } else { + $action = new Action($this->error); + + $this->error = ''; + //throw new Exception("The controller can't be loaded", 1); + new Exception("PHACIL ERROR: Controller class " . get_class($controller) . "->" . $method . "() is not a callable function"); + } + return $action; + } catch (\Exception $th) { + throw new Exception($th->getMessage(), $th->getCode(), $th); + //throw $th; + } + } + + protected function injectionClass($class){ + /* $refClass = new ReflectionClass($class); + + if(!$refClass->getConstructor()){ + if($refClass->hasMethod('getInstance') && $refClass->getMethod('getInstance')->isStatic()){ + return $refClass->getMethod('getInstance')->invoke(null); + } + + return $refClass->newInstanceWithoutConstructor(); + } + + try { + if ($autoInstance = $this->registry->getInstance($class)) + return $autoInstance; + } catch (\Throwable $th) { + //throw $th; + } */ + + + return $this->registry->injectionClass($class); + } } diff --git a/system/engine/registry.php b/system/engine/registry.php index 2a854f5..7291db3 100644 --- a/system/engine/registry.php +++ b/system/engine/registry.php @@ -107,7 +107,7 @@ final class Registry { * @return \Phacil\Framework\Registry * @since 2.0.0 */ - static public function getInstance($class = null, $args = []) { + static public function getInstance($class = null, $args = [], $onlyCheckInstances = false) { if(!$class) return \Phacil\Framework\startEngineExacTI::getRegistry(); $registry = \Phacil\Framework\startEngineExacTI::getRegistry(); @@ -127,6 +127,8 @@ final class Registry { if($return) return $return; + if($onlyCheckInstances) return $return; + if(is_string($class)) { $reflector = new ReflectionClass($class); return self::setAutoInstance($reflector->newInstanceArgs($args)); @@ -165,4 +167,57 @@ final class Registry { return isset(self::$autoInstances[get_class($class)]) ? self::$autoInstances[get_class($class)] : self::setAutoInstance($class); } + + + public function injectionClass($class) + { + $refClass = new ReflectionClass($class); + + if (!$refClass->getConstructor()) { + if ($refClass->hasMethod('getInstance') && $refClass->getMethod('getInstance')->isStatic()) { + return $refClass->getMethod('getInstance')->invoke(null); + } + + return $refClass->newInstanceWithoutConstructor(); + } + + try { + if ( $autoInstance = $this->getInstance($class, [], true)) + return $autoInstance; + } catch (\Throwable $th) { + //throw $th; + } + + + $rMethod = new ReflectionMethod($class, "__construct"); + $params = $rMethod->getParameters(); + $argsToInject = []; + foreach ($params as $param) { + //$param is an instance of ReflectionParameter + try { + if ($param->getType()) { + $injectionClass = $param->getType()->getName(); + if (class_exists($injectionClass)) { + $argsToInject[$param->getPosition()] = $this->injectionClass($injectionClass); + continue; + } + if (!$param->isOptional()) { + throw new \Phacil\Framework\Exception\ReflectionException("Error Processing Request: " . $injectionClass . "not exist"); + } + } + } catch (\Exception $th) { + throw $th; + } + + if ($param->isOptional() && $param->isDefaultValueAvailable()) { + $argsToInject[] = $param->getDefaultValue(); + continue; + } + if ($param->isOptional()) { + $argsToInject[] = null; + } + } + + return self::setAutoInstance($refClass->newInstanceArgs($argsToInject)); + } }