diff --git a/Annotation/Annotation.php b/Annotation/Annotation.php index 580e5de0..67b3dc59 100644 --- a/Annotation/Annotation.php +++ b/Annotation/Annotation.php @@ -16,92 +16,160 @@ class Annotation extends Component { - private Loader $_loader; + private Loader $_loader; - public function init(): void - { - $this->_loader = new Loader(); - } + private array $_model_sets = []; + private array $_model_gets = []; + private array $_model_relate = []; - /** - * @return Loader - */ - public function getLoader(): Loader - { - return $this->_loader; - } + /** + * @param string $class + * @param string $setName + * @param string $method + */ + public function addSets(string $class, string $setName, string $method) + { + $this->_model_sets[$class . '::' . $setName] = $method; + } + + /** + * @param string $class + * @param string $setName + * @param string $method + */ + public function addGets(string $class, string $setName, string $method) + { + $this->_model_gets[$class . '::' . $setName] = $method; + } + + /** + * @param string $class + * @param string $setName + * @param string $method + */ + public function addRelate(string $class, string $setName, string $method) + { + $this->_model_relate[$class . '::' . $setName] = $method; + } - /** - * @param Loader $loader - * @return Loader - */ - public function setLoader(Loader $loader): Loader - { - return $this->_loader = $loader; - } + /** + * @param string $class + * @param string $setName + * @return mixed|null + */ + public function getGetMethodName(string $class, string $setName): ?string + { + if (isset($this->_model_relate[$class . '::' . $setName])) { + return $this->_model_relate[$class . '::' . $setName]; + } + if (isset($this->_model_gets[$class . '::' . $setName])) { + return $this->_model_gets[$class . '::' . $setName]; + } + return null; + } - /** - * @param string $className - * @param string $method - * @return array 根据类名获取注解 - * 根据类名获取注解 - */ - public function getMethods(string $className, string $method = ''): mixed - { - return $this->_loader->getMethod($className, $method); - } + + /** + * @param string $class + * @param string $setName + * @return mixed|null + */ + public function getSetMethodName(string $class, string $setName): ?string + { + if (isset($this->_model_sets[$class . '::' . $setName])) { + return $this->_model_relate[$class . '::' . $setName]; + } + return null; + } - /** - * @param object $class - */ - public function injectProperty(object $class) - { - $this->_loader->injectProperty(get_class($class), $class); - } + public function init(): void + { + $this->_loader = new Loader(); + } - /** - * @param string $path - * @param string $namespace - * @param string $alias - * @return void - * @throws Exception - */ - public function read(string $path, string $namespace, string $alias = 'root'): void - { - - $this->_loader->_scanDir(new DirectoryIterator($path), $namespace); - } + /** + * @return Loader + */ + public function getLoader(): Loader + { + return $this->_loader; + } - /** - * @param string $dir - * @param string|array $outPath - * @throws Exception - */ - public function runtime(string $dir, string|array $outPath = '') - { - if (empty($outPath)) { - $outPath = []; - } else if (is_string($outPath)) { - $outPath = [$outPath]; - } - $this->_loader->loadByDirectory($dir, $outPath); - } + /** + * @param Loader $loader + * @return Loader + */ + public function setLoader(Loader $loader): Loader + { + return $this->_loader = $loader; + } - /** - * @param string $filename - * @return mixed - */ - public function getFilename(string $filename): mixed - { - return $this->_loader->getClassByFilepath($filename); - } + /** + * @param string $className + * @param string $method + * @return array 根据类名获取注解 + * 根据类名获取注解 + */ + public function getMethods(string $className, string $method = ''): mixed + { + return $this->_loader->getMethod($className, $method); + } + + + /** + * @param object $class + */ + public function injectProperty(object $class) + { + $this->_loader->injectProperty(get_class($class), $class); + } + + + /** + * @param string $path + * @param string $namespace + * @param string $alias + * @return void + * @throws Exception + */ + public function read(string $path, string $namespace, string $alias = 'root'): void + { + + $this->_loader->_scanDir(new DirectoryIterator($path), $namespace); + } + + + /** + * @param string $dir + * @param string|array $outPath + * @throws Exception + */ + public function runtime(string $dir, string|array $outPath = '') + { + if (empty($outPath)) { + $outPath = []; + } else if (is_string($outPath)) { + $outPath = [$outPath]; + } + $this->_loader->loadByDirectory($dir, $outPath); + } + + + /** + * @param string $filename + * @return mixed + */ + public function getFilename(string $filename): mixed + { + return $this->_loader->getClassByFilepath($filename); + } } diff --git a/Annotation/Loader.php b/Annotation/Loader.php index 75fa57ff..8a04bf58 100644 --- a/Annotation/Loader.php +++ b/Annotation/Loader.php @@ -4,6 +4,9 @@ namespace Annotation; +use Annotation\Model\Get; +use Annotation\Model\Relation; +use Annotation\Model\Set; use Attribute; use DirectoryIterator; use Exception; @@ -394,19 +397,31 @@ class Loader extends BaseObject if (empty($classes)) { return; } + $annotation = Snowflake::app()->getAnnotation(); foreach ($classes as $className) { $annotations = $this->_classes[$className] ?? null; if ($annotations === null) { continue; } - $class = Snowflake::createObject($annotations['handler']); foreach ($annotations['target'] ?? [] as $value) { $value->execute([$class]); } + + $isGet = $annotations instanceof Get; + $isSet = $annotations instanceof Set; + $isRelate = $annotations instanceof Relation; foreach ($annotations['methods'] as $name => $attribute) { foreach ($attribute as $value) { - $value->execute([$class, $name]); + if ($isGet) { + $annotation->addGets($annotations['handler'], $value->name, $name); + } else if ($isSet) { + $annotation->addSets($annotations['handler'], $value->name, $name); + } else if ($isRelate) { + $annotation->addRelate($annotations['handler'], $value->name, $name); + } else { + $value->execute([$class, $name]); + } } } } diff --git a/Database/Base/BaseActiveRecord.php b/Database/Base/BaseActiveRecord.php index 5fa7ef1d..d2f6461b 100644 --- a/Database/Base/BaseActiveRecord.php +++ b/Database/Base/BaseActiveRecord.php @@ -134,6 +134,7 @@ abstract class BaseActiveRecord extends Component implements IOrm, ArrayAccess */ public function init() { + $this->event = Snowflake::app()->getEvent(); if (!Context::hasContext(Relation::class)) { $relation = Snowflake::createObject(Relation::class); $this->_relation = Context::setContext(Relation::class, $relation); @@ -149,14 +150,14 @@ abstract class BaseActiveRecord extends Component implements IOrm, ArrayAccess */ public function createAnnotation() { - $annotation = Snowflake::getAnnotation(); - $annotation->injectProperty($this); - $methods = $annotation->getMethods(get_called_class()); - foreach ($methods as $method => $attributes) { - foreach ($attributes as $attribute) { - $attribute->execute([$this, $method]); - } - } +// $annotation = Snowflake::getAnnotation(); +// $annotation->injectProperty($this); +// $methods = $annotation->getMethods(get_called_class()); +// foreach ($methods as $method => $attributes) { +// foreach ($attributes as $attribute) { +// $attribute->execute([$this, $method]); +// } +// } } @@ -833,11 +834,11 @@ abstract class BaseActiveRecord extends Component implements IOrm, ArrayAccess parent::__set($name, $value); return; } - if ($this->hasAnnotation($name, 'set')) { - $this->runAnnotation($name, $value, self::ANNOTATION_SET); - } else { - $this->_attributes[$name] = $value; + $method = annotation()->getSetMethodName(get_called_class(), $name); + if (!empty($method)) { + $value = $this->{$method}($value); } + $this->_attributes[$name] = $value; } @@ -849,15 +850,14 @@ abstract class BaseActiveRecord extends Component implements IOrm, ArrayAccess public function __get($name): mixed { $value = $this->_attributes[$name] ?? null; - if ($this->hasAnnotation($name)) { - return $this->runAnnotation($name, $value); + + $loader = Snowflake::app()->getAnnotation(); + if (!empty($method = $loader->getGetMethodName(get_called_class(), $name))) { + return $this->{$method}(); } if (array_key_exists($name, $this->_attributes)) { return static::getColumns()->_decode($name, $value); } - if (in_array($name, $this->_with)) { - return $this->with($name); - } if (Snowflake::app()->has($name)) { return Snowflake::app()->get($name); }