From dee54c9120e7c5e842c759330085657ed10be85f Mon Sep 17 00:00:00 2001 From: "Bruno O. Notario" Date: Tue, 6 Feb 2024 10:07:01 -0300 Subject: [PATCH] auto Factory support! Make your on Factory object magically... --- system/engine/autoload.php | 22 ++++++- system/engine/factory.php | 71 ++++++++++++++++++++++ system/engine/registry.php | 121 +++++++++++++++++++++++++------------ 3 files changed, 176 insertions(+), 38 deletions(-) create mode 100644 system/engine/factory.php diff --git a/system/engine/autoload.php b/system/engine/autoload.php index d1cdc7b..5bd7b59 100644 --- a/system/engine/autoload.php +++ b/system/engine/autoload.php @@ -98,7 +98,8 @@ 'Exception', 'Render', 'Debug', - 'RESTful' + 'RESTful', + 'Factory' ]; /** @@ -518,6 +519,21 @@ } + /** + * Support for Factory class. + * Need only for PHP 5.6 to 7.1 + * @return bool + */ + private function setFactoryAliases(){ + $class = self::$class; + if (substr($class, -7) === "Factory" && $class !== "Phacil\Framework\Factory") { + class_alias("Phacil\Framework\Factory", $class); + return true; + } + + return false; + } + /** * Load Composer * @@ -600,6 +616,10 @@ if($autoload->loadModularWithoutNamespacesPrefix()) return; + if (version_compare(phpversion(), "7.2.0", "<")) { + if($autoload->setFactoryAliases()) return; + } + //if($autoload->loadModularNamespaceShift()) return; //if($autoload->loadComposer()) return; diff --git a/system/engine/factory.php b/system/engine/factory.php new file mode 100644 index 0000000..bcefb90 --- /dev/null +++ b/system/engine/factory.php @@ -0,0 +1,71 @@ +class = $class; + } + + /** + * Sets the name of the class to be instantiated by the factory. + * + * @param string $class The name of the class. + * @return void + */ + public function setClass($class) { + $this->class = $class; + $this; + } + + /** + * Gets the name of the class currently configured to be instantiated by the factory. + * + * @return string + */ + public function getClass() { + return $this->class; + } + + /** + * Creates an instance of the class configured in the factory. + * + * @param array $args (Optional) Additional arguments for the class constructor. + * @return mixed The created instance. + * + * @throws \ReflectionException + * @throws \Phacil\Framework\Exception + * @throws \Exception + */ + public function create(array $args = []) { + return \Phacil\Framework\Registry::getInstance()->create($this->class, $args); + } +} \ No newline at end of file diff --git a/system/engine/registry.php b/system/engine/registry.php index ff2025c..c25dd57 100644 --- a/system/engine/registry.php +++ b/system/engine/registry.php @@ -303,12 +303,18 @@ final class Registry { * @throws \Exception * @throws \Phacil\Framework\Exception */ - public function injectionClass($class, $args = array(), $forceCreate = false) + public function injectionClass($class, $args = array(), $forceCreate = false, $factored = null) { $argsToInject = !empty($args) ? $args : false; $originalClass = $class; $class = self::checkPreference($class); $originalClass = $originalClass == $class ? null : $originalClass; + /* if (substr($class, -7) === "Factory") { + $refClass = substr($class, 0, -7); + if(isset($args[0]) && $this->getInstance($args[0], [], true)) return $this->getInstance($args[0]); + + return self::setAutoInstance($this->create("Phacil\Framework\Factory", $args), $originalClass); + } */ $refClass = new ReflectionClass($class); @@ -328,50 +334,91 @@ final class Registry { } - $rMethod = new ReflectionMethod($class, "__construct"); - if(!$argsToInject){ - $params = $rMethod->getParameters(); - $argsToInject = []; - foreach ($params as $param) { - //$param is an instance of ReflectionParameter - try { - if (version_compare(phpversion(), "7.2.0", "<")) { - if ($param->getClass()) { - $injectionClass = $param->getClass()->name; - 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"); - } - } - } else { - if ($param->getType()) { - $injectionClass = $param->getType()->getName(); - if (class_exists($injectionClass)) { - $argsToInject[$param->getPosition()] = $this->injectionClass($injectionClass); - continue; + try { + //code... + $rMethod = new ReflectionMethod($class, "__construct"); + if (!$argsToInject) { + $params = $rMethod->getParameters(); + $argsToInject = []; + foreach ($params as $param) { + //$param is an instance of ReflectionParameter + try { + if (version_compare(phpversion(), "7.2.0", "<")) { + if ($param->getClass()) { + $injectionClass = $param->getClass()->name; + //if (substr($injectionClass, -7) === "Factory") { + if ($injectionClass === "Phacil\Framework\Factory") { + $declaringClass = $param->__toString(); + $pattern = '/Parameter #\d+ \[ ([^\s]+) \$\w+ \]/'; + + if (preg_match($pattern, $declaringClass, $matches)) { + $classFactoryName = $matches[1]; + if($classFactoryName !== $injectionClass){ + $factoredRefClass = substr($classFactoryName, 0, -7); + //$jatem = ($this->getInstance($classFactoryName, [], true)) ?: false; + $argsToInject[$param->getPosition()] = ($this->getInstance($classFactoryName, [], true)) ? : self::setAutoInstance($this->create("Phacil\Framework\Factory", [$factoredRefClass]), $classFactoryName); + continue; + } + } + } + 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"); + } } - if (!$param->isOptional()) { - throw new \Phacil\Framework\Exception\ReflectionException("Error Processing Request: " . $injectionClass . "not exist"); + } else { + if ($param->getType()) { + $injectionClass = $param->getType()->getName(); + if (class_exists($injectionClass)) { + $argsToInject[$param->getPosition()] = $this->injectionClass($injectionClass); + continue; + } elseif (substr($injectionClass, -7) === "Factory") { + $factoredRefClass = substr($injectionClass, 0, -7); + $argsToInject[$param->getPosition()] = ($this->getInstance($injectionClass, [], true)) ?: self::setAutoInstance($this->create("Phacil\Framework\Factory", [$factoredRefClass]), $injectionClass); + class_alias("Phacil\Framework\Factory", $injectionClass); + continue; + } + if (!$param->isOptional()) { + throw new \Phacil\Framework\Exception\ReflectionException("Error Processing Request: " . $injectionClass . "not exist"); + } } } + } catch (\ReflectionException $th) { + /* $pattern = '/Class\s+(\S+)\s+/'; + + // Procurar por correspondências na mensagem + if (!$factored && preg_match($pattern, $th->getMessage(), $matches)) { + // O nome da classe estará na segunda posição do array de correspondências + $className = $matches[1]; + + class_alias("Phacil\Framework\Factory", $className); + + return $this->injectionClass($class, $args, $forceCreate, $className); + // Exibir o nome da classe + echo $className; + } else { */ + throw new \Phacil\Framework\Exception\ReflectionException($th->getMessage(), $th->getCode(), $th); + //} + + } catch (\Exception $th) { + throw new \Phacil\Framework\Exception($th->getMessage()); } - } catch (\Exception $th) { - throw $th; - } - if ($param->isOptional() && $param->isDefaultValueAvailable()) { - $argsToInject[] = $param->getDefaultValue(); - continue; - } - if ($param->isOptional()) { - $argsToInject[] = null; + if ($param->isOptional() && $param->isDefaultValueAvailable()) { + $argsToInject[] = $param->getDefaultValue(); + continue; + } + if ($param->isOptional()) { + $argsToInject[] = null; + } } } + } catch (\ReflectionException $th) { + throw new \Phacil\Framework\Exception\ReflectionException($th->getMessage()); } - return self::setAutoInstance($refClass->newInstanceArgs($argsToInject), $originalClass); }