初始化多态一对一关系

@param \Imi\Model\Model $model
@param string $propertyName
@param \Imi\Model\Annotation\Relation\PolymorphicOneToOne $annotation
@return void
16116
public static function initByPolymorphicOneToOne($model, $propertyName, $annotation)
    {
        $className = BeanFactory::getObjectClass($model);

        if(class_exists($annotation->model))
        {
            $modelClass = $annotation->model;
        }
        else
        {
            $modelClass = Imi::getClassNamespace($className) . '\\' . $annotation->model;
        }

        $struct = new PolymorphicOneToOne($className, $propertyName, $annotation);
        $leftField = $struct->getLeftField();
        $rightField = $struct->getRightField();

        if(null === $model->$leftField)
        {
            $rightModel = $modelClass::newInstance();
        }
        else
        {
            $rightModel = $modelClass::query()->where($annotation->type, '=', $annotation->typeValue)->where($rightField, '=', $model->$leftField)->select()->get();
            if(null === $rightModel)
            {
                $rightModel = $modelClass::newInstance();
            }
        }

        $model->$propertyName = $rightModel;
    }
274295
public static function init($model, $propertyName, $annotation, $forceInit = false)
    {
        $className = BeanFactory::getObjectClass($model);

        if(!$forceInit)
        {
            $autoSelect = AnnotationManager::getPropertyAnnotations($className, $propertyName, AutoSelect::class)[0] ?? null;
            if($autoSelect && !$autoSelect->status)
            {
                return;
            }
        }

        if(is_array($annotation))
        {
            $firstAnnotation = reset($annotation);
            if($firstAnnotation instanceof \Imi\Model\Annotation\Relation\PolymorphicToOne)
            {
                static::initByPolymorphicToOne($model, $propertyName, $annotation);
            }
        }
        else if($annotation instanceof \Imi\Model\Annotation\Relation\OneToOne)
        {
            static::initByOneToOne($model, $propertyName, $annotation);
        }
        else if($annotation instanceof \Imi\Model\Annotation\Relation\OneToMany)
        {
            static::initByOneToMany($model, $propertyName, $annotation);
        }
        else if($annotation instanceof \Imi\Model\Annotation\Relation\ManyToMany)
        {
            static::initByManyToMany($model, $propertyName, $annotation);
        }
        else if($annotation instanceof \Imi\Model\Annotation\Relation\PolymorphicOneToOne)
        {
            static::initByPolymorphicOneToOne($model, $propertyName, $annotation);
        }
        else if($annotation instanceof \Imi\Model\Annotation\Relation\PolymorphicOneToMany)
        {
            static::initByPolymorphicOneToMany($model, $propertyName, $annotation);
        }
        else if($annotation instanceof \Imi\Model\Annotation\Relation\PolymorphicManyToMany)
        {
            static::initByPolymorphicManyToMany($model, $propertyName, $annotation);
        }
        else if($annotation instanceof \Imi\Model\Annotation\Relation\PolymorphicToMany)
        {
            static::initByPolymorphicToMany($model, $propertyName, $annotation);
        }
    }
609740
private void loadPropertyAnnotation(CodeBuilder b,
                                        StorableProperty property,
                                        StorablePropertyAnnotation annotation) {
        /* Example
           UserInfo.class.getMethod("setFirstName", new Class[] {String.class})
               .getAnnotation(LengthConstraint.class)
        */

        String methodName = annotation.getAnnotatedMethod().getName();
        boolean isAccessor = !methodName.startsWith("set");

        b.loadConstant(TypeDesc.forClass(property.getEnclosingType()));
        b.loadConstant(methodName);
        if (isAccessor) {
            // Accessor method has no parameters.
            b.loadNull();
        } else {
            // Mutator method has one parameter.
            b.loadConstant(1);
            b.newObject(TypeDesc.forClass(Class[].class));
            b.dup();
            b.loadConstant(0);
            b.loadConstant(TypeDesc.forClass(property.getType()));
            b.storeToArray(TypeDesc.forClass(Class[].class));
        }
        b.invokeVirtual(Class.class.getName(), "getMethod",
                        TypeDesc.forClass(Method.class), new TypeDesc[] {
                            TypeDesc.STRING, TypeDesc.forClass(Class[].class)
                        });
        b.loadConstant(TypeDesc.forClass(annotation.getAnnotationType()));
        b.invokeVirtual(Method.class.getName(), "getAnnotation",
                        TypeDesc.forClass(Annotation.class), new TypeDesc[] {
                            TypeDesc.forClass(Class.class)
                        });
        b.checkCast(TypeDesc.forClass(annotation.getAnnotationType()));
    }
74572
private static function saveModelPropertyRow(ActiveRecord $model, Property $propertyModel)
    {
        $modelId = $model->id;
        $propertyId = $propertyModel->id;
        $key = $propertyModel->key;
        $values = (array) $model->$key;
        if (count($values) === 0) {
            return [];
        }
        $valueField = self::dataTypeToEavColumn($propertyModel->data_type);
        $rows = [];
        if (true === $propertyModel->canTranslate()) {
            foreach ($values as $langId => $data) {
                $rows = array_merge($rows, self::prepareRows($data, $modelId, $propertyId, $valueField, $langId));
            }
        } else {
            $rows = array_merge($rows, self::prepareRows($values, $modelId, $propertyId, $valueField));
        }
        return $rows;
    }
488703
public static function collect(string $className, $objectAnnotation = null, string $propertyName = '', string $methodName = '', $propertyValue = null)
    {
        if ($objectAnnotation instanceof Reference) {
            // phpdoc解析
            $phpReader     = new PhpDocReader();
            $property      = new \ReflectionProperty($className, $propertyName);
            $propertyClass = $phpReader->getPropertyClass($property);
            $name          = $objectAnnotation->getName();
            $pool          = $objectAnnotation->getPool();
            $version       = $objectAnnotation->getVersion();
            $breaker       = $objectAnnotation->getBreaker();
            $packer        = $objectAnnotation->getPacker();
            $fallback      = $objectAnnotation->getFallback();

            $className      = sprintf("%s.%s.%s.%s.%s.%s", $name, $propertyClass, $version, $pool, $breaker, $packer);
            $className      = md5($className);
            $proxyClassName = str_replace("\\", '_', $propertyClass);
            $className      = $proxyClassName . '_' . $className;

            if (empty($name)) {
                throw new RpcClientException('@Reference must be define name! ');
            }
            if (isset(self::$references[$className])) {
                return $className;
            }

            self::$references[$className] = [
                $name,
                $propertyClass,
                $version,
                $pool,
                $breaker,
                $packer,
                $fallback
            ];

            return $className;
        }

        return null;
    }
461692
public function setProperty($propName, $value)
    {
        if (self::isAttribute($propName)) {
            $this->setAttribute($propName, $value);
        } else {
            if ($setterName = $this->setterExists($propName)) {
                $this->$setterName($value);
            } elseif (self::hasPublicProperty($propName)) {
                $this->$propName = $value;
            } else {
                throw new Exception\RuntimeException(
                    sprintf("Can't write unknown property '%s' for model %s", $propName, get_called_class())
                );
            }
        }
    }
625971
private function createGetter(Entity $entity, $property, $annotation)
    {
        if ($annotation->getter === null) {
            $getter = new PropertyGetter($entity, $property);
        } else {
            if ($annotation->getter === true) {
                $methodName = 'get' . ucfirst($property);
            } else {
                $methodName = $annotation->getter;
            }
            $getter = new MethodGetter($entity, $methodName);
        }

        return $getter;
    }
458222
public static function parseByPolymorphicOneToOne($model, $propertyName, $annotation)
    {
        $className = BeanFactory::getObjectClass($model);

        $struct = new PolymorphicOneToOne($className, $propertyName, $annotation);
        $leftField = $struct->getLeftField();
        $rightField = $struct->getRightField();

        $model->$propertyName->$rightField = $model->$leftField;
        $model->$propertyName->{$annotation->type} = $annotation->typeValue;
        $model->$propertyName->insert();
    }
266008
public function parser(string $className, $objectAnnotation = null, string $propertyName = "", string $methodName = "", $propertyValue = null)
    {
        $injectValue = $objectAnnotation->getName();
        if (!empty($injectValue)) {
            return [$injectValue, true];
        }

        // phpdoc解析
        $phpReader = new PhpDocReader();
        $property = new \ReflectionProperty($className, $propertyName);
        $propertyClass = $phpReader->getPropertyClass($property);

        $isRef = true;
        $injectProperty = $propertyClass;
        return [$injectProperty, $isRef];
    }
1254372
public static function hasPropertyAnnotation(\ReflectionProperty $property, $annotationClass, AnnotationReader $reader)
    {
        if (null === self::getPropertyAnnotation($property, $annotationClass, $reader)) {
            return false;
        }

        return true;
    }
671983
public static function toPropertyValue($obj,$propertyName,$value)
    {
        if(property_exists($obj, $propertyName)){
            $obj->$propertyName=$value;
        }
    }
1268321
public function execute(RequestAnnotation $annotation, PropertyParserBuilder $propertyParser)
    {
        $propertyParser->addValidator(
            ValidatorBuilder::builder()
            ->withClass($annotation->getAssociatedClass())
            ->withSpecification($annotation->getValue())
            ->build()
        );
    }
964922
public function parser(string $className, $objectAnnotation = null, string $propertyName = "", string $methodName = "", $propertyValue = null)
    {
        $injectValue = $objectAnnotation->getName();
        $envValue    = $objectAnnotation->getEnv();
        if (empty($injectValue) && empty($envValue)) {
            throw new \InvalidArgumentException("the name and env of @Value can't be empty! class={$className} property={$propertyName}");
        }

        $isRef          = false;
        $injectProperty = null;
        if (!empty($injectValue)) {
            list($injectProperty, $isRef) = $this->annotationResource->getTransferProperty($injectValue);
        }

        if (!empty($envValue)) {
            $value          = $this->getEnvValue($envValue);
            $isArray        = $this->isEnvArrayValue($className, $propertyName);
            $value          = $this->getTransferEnvValue($value, $isArray);
            $injectProperty = ($value !== null) ? $value : $injectProperty;
            $isRef          = ($value !== null) ? false : $isRef;
        }

        return [$injectProperty, $isRef];
    }
1354349
public static function deleteModel($model)
    {
        foreach(AnnotationManager::getPropertiesAnnotations(BeanFactory::getObjectClass($model), RelationBase::class) as $propertyName => $annotations)
        {
            if(null === $model[$propertyName])
            {
                continue;
            }
            $annotation = $annotations[0];
            Delete::parse($model, $propertyName, $annotation);
        }
    }
830758
public static function collect(string $className, $objectAnnotation = null, string $propertyName = '', string $methodName = '', $propertyValue = null)
    {
        // collect service
        if ($objectAnnotation instanceof Service) {

            $rc = new \ReflectionClass($className);
            $interfaces = $rc->getInterfaceNames();
            $methods = $rc->getMethods(\ReflectionMethod::IS_PUBLIC);
            $version = $objectAnnotation->getVersion();

            foreach ($interfaces as $interfaceClass){
                foreach ($methods as $method){
                    $methodName = $method->getName();
                    self::$serviceMapping[$interfaceClass][$version][$methodName] = [$className, $methodName];
                }
            }

            return;
        }
    }
710112
public static function parse($model, $propertyName, $annotation)
    {
        if(!$model->$propertyName)
        {
            return;
        }
        $className = BeanFactory::getObjectClass($model);
        $autoInsert = AnnotationManager::getPropertyAnnotations($className, $propertyName, AutoInsert::class)[0] ?? null;
        $autoSave = AnnotationManager::getPropertyAnnotations($className, $propertyName, AutoSave::class)[0] ?? null;

        if($autoInsert)
        {
            if(!$autoInsert->status)
            {
                return;
            }
        }
        else if(!$autoSave || !$autoSave->status)
        {
            return;
        }

        if($annotation instanceof \Imi\Model\Annotation\Relation\OneToOne)
        {
            static::parseByOneToOne($model, $propertyName, $annotation);
        }
        else if($annotation instanceof \Imi\Model\Annotation\Relation\OneToMany)
        {
            static::parseByOneToMany($model, $propertyName, $annotation);
        }
        else if($annotation instanceof \Imi\Model\Annotation\Relation\ManyToMany)
        {
            static::parseByManyToMany($model, $propertyName, $annotation);
        }
        else if($annotation instanceof \Imi\Model\Annotation\Relation\PolymorphicOneToOne)
        {
            static::parseByPolymorphicOneToOne($model, $propertyName, $annotation);
        }
        else if($annotation instanceof \Imi\Model\Annotation\Relation\PolymorphicOneToMany)
        {
            static::parseByPolymorphicOneToMany($model, $propertyName, $annotation);
        }
        else if($annotation instanceof \Imi\Model\Annotation\Relation\PolymorphicManyToMany)
        {
            static::parseByPolymorphicManyToMany($model, $propertyName, $annotation);
        }
    }
877512
public function parser(string $className, $objectAnnotation = null, string $propertyName = "", string $methodName = "", $propertyValue = null)
    {
        Collector::$methodAnnotations[$className][$methodName][] = get_class($objectAnnotation);
        return null;
    }