- WIP on Notes v2.x
This commit is contained in:
		
							parent
							
								
									1dd9da6eb6
								
							
						
					
					
						commit
						75231f32b3
					
				| @ -2,7 +2,7 @@ | ||||
| 
 | ||||
| namespace Ulmus\Adapter; | ||||
| 
 | ||||
| use Ulmus\{ConnectionAdapter, Entity\InformationSchema\Table, Migration\FieldDefinition, Repository, QueryBuilder\Sql\MysqlQueryBuilder}; | ||||
| use Ulmus\{ConnectionAdapter, Entity\InformationSchema\Table, Migration\FieldDefinition, Repository, QueryBuilder\Sql\MysqlQueryBuilder, Entity}; | ||||
| 
 | ||||
| trait DefaultAdapterTrait | ||||
| { | ||||
|  | ||||
| @ -64,7 +64,6 @@ class SQLite implements AdapterInterface, MigrateInterface, SqlAdapterInterface | ||||
|     public function escapeIdentifier(string $segment, int $type) : string  | ||||
|     { | ||||
|         switch($type) { | ||||
|             default: | ||||
|             case static::IDENTIFIER_DATABASE: | ||||
|             case static::IDENTIFIER_TABLE: | ||||
|             case static::IDENTIFIER_FIELD: | ||||
|  | ||||
| @ -2,6 +2,8 @@ | ||||
| 
 | ||||
| namespace Ulmus\Common; | ||||
| 
 | ||||
| use Notes\Common\ReflectedClass; | ||||
| use Notes\Common\ReflectedProperty; | ||||
| use Psr\SimpleCache\CacheInterface; | ||||
| use Ulmus\Ulmus, | ||||
|     Ulmus\Annotation\Classes\Table, | ||||
| @ -24,13 +26,7 @@ class EntityResolver { | ||||
| 
 | ||||
|     public string $entityClass; | ||||
| 
 | ||||
|     public array $uses; | ||||
| 
 | ||||
|     public array $class; | ||||
| 
 | ||||
|     public array $properties; | ||||
| 
 | ||||
|     public array $methods; | ||||
|     public ReflectedClass $reflectedClass; | ||||
|      | ||||
|     protected array $fieldList = []; | ||||
| 
 | ||||
| @ -38,14 +34,10 @@ class EntityResolver { | ||||
|     { | ||||
|         $this->entityClass = $entityClass; | ||||
| 
 | ||||
|         list($this->uses, $this->class, $this->methods, $this->properties) = array_values( | ||||
|             ObjectReflection::fromClass($entityClass, $cache)->read() | ||||
|         ); | ||||
|          | ||||
|         $this->resolveAnnotations(); | ||||
|         $this->reflectedClass = ObjectReflection::fromClass($entityClass, $cache)->reflectClass(); | ||||
|     } | ||||
| 
 | ||||
|     public function field($name, $fieldKey = self::KEY_ENTITY_NAME, $throwException = true) : ? array | ||||
|     public function field($name, $fieldKey = self::KEY_ENTITY_NAME, $throwException = true) : ? ReflectedProperty | ||||
|     { | ||||
|         try{ | ||||
|             return $this->fieldList($fieldKey)[$name] ?? null; | ||||
| @ -68,25 +60,25 @@ class EntityResolver { | ||||
|     { | ||||
|         $fieldList = []; | ||||
| 
 | ||||
|         foreach($this->properties as $item) { | ||||
|             foreach($item['tags'] ?? [] as $tag) { | ||||
|                 if ( $tag['object'] instanceof Field or $tag['object'] instanceof Attribute\Property\Field ) { | ||||
|                     if ( $skipVirtual && ($tag['object'] instanceof Virtual or $tag['object'] instanceof Attribute\Property\Virtual )) { | ||||
|         foreach($this->reflectedClass->getProperties(true) as $item) { | ||||
|             foreach($item->getAttributes() as $tag) { | ||||
|                 if ( $tag->object instanceof Attribute\Property\Field ) { | ||||
|                     if ( $skipVirtual && $tag->object instanceof Attribute\Property\Virtual ) { | ||||
|                         break; | ||||
|                     } | ||||
| 
 | ||||
|                     switch($fieldKey) { | ||||
|                         case static::KEY_LC_ENTITY_NAME: | ||||
|                             $key = strtolower($item['name']); | ||||
|                             $key = strtolower($item->name); | ||||
|                             break; | ||||
| 
 | ||||
| 
 | ||||
|                         case static::KEY_ENTITY_NAME: | ||||
|                             $key = $item['name']; | ||||
|                             $key = $item->name; | ||||
|                         break; | ||||
| 
 | ||||
|                         case static::KEY_COLUMN_NAME: | ||||
|                             $key = strtolower($tag['object']->name ?? $item['name']); | ||||
|                             $key = strtolower($tag->object->name ?? $item->name); | ||||
|                         break; | ||||
| 
 | ||||
|                         default: | ||||
| @ -103,26 +95,24 @@ class EntityResolver { | ||||
|         return $fieldList; | ||||
|     } | ||||
| 
 | ||||
|     public function relation(string $name) : ? array | ||||
|     public function relation(string $name) : array | ||||
|     { | ||||
|         $property = $this->reflectedClass->getProperties(true)[$name] ?? false; | ||||
| 
 | ||||
|         try{ | ||||
|             if ( null !== ( $this->properties[$name] ?? null ) ) { | ||||
|                 foreach($this->properties[$name]['tags'] ?? [] as $tag) { | ||||
|                     if ( $tag['object'] instanceof Relation or $tag['object'] instanceof Attribute\Property\Relation ) { | ||||
|                         return $this->properties[$name]; | ||||
|             if ( $property ) { | ||||
|                 foreach($property->getAttributes() as $tag) { | ||||
|                     if ( $tag->object instanceof Relation or $tag->object instanceof Attribute\Property\Relation ) { | ||||
|                         return $property; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|              | ||||
| 
 | ||||
|             return []; | ||||
|         } | ||||
|         catch(\Throwable $e) { | ||||
|            # if ( $throwException) {
 | ||||
|                 throw new \InvalidArgumentException("Can't find entity relation's column named `$name` from entity {$this->entityClass}");    | ||||
|            # }
 | ||||
|             throw new \InvalidArgumentException("Can't find entity relation's column named `$name` from entity {$this->entityClass}"); | ||||
|         } | ||||
|          | ||||
|         return null; | ||||
|     } | ||||
|      | ||||
|     public function searchFieldAnnotation(string $field, array|object|string $annotationType, bool $caseSensitive = true) : ? object | ||||
| @ -134,15 +124,17 @@ class EntityResolver { | ||||
|     { | ||||
|         $list = []; | ||||
| 
 | ||||
|         $search = $caseSensitive ? $this->properties : array_change_key_case($this->properties, \CASE_LOWER); | ||||
|         $properties = $this->reflectedClass->getProperties(true); | ||||
| 
 | ||||
|         $search = $caseSensitive ? $properties : array_change_key_case($properties, \CASE_LOWER); | ||||
| 
 | ||||
|         $annotations = is_array($annotationType) ? $annotationType : [ $annotationType ]; | ||||
| 
 | ||||
|         if ( null !== ( $search[$field] ?? null ) ) { | ||||
|             foreach($search[$field]['tags'] ?? [] as $tag) { | ||||
|             foreach($search[$field]->getAttributes() as $tag) { | ||||
|                 foreach($annotations as $annotation) { | ||||
|                     if ( $tag['object'] instanceof $annotation ) { | ||||
|                         $list[] = $tag['object']; | ||||
|                     if ( $tag->object instanceof $annotation ) { | ||||
|                         $list[] = $tag->object; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
| @ -256,6 +248,7 @@ class EntityResolver { | ||||
|      */ | ||||
|     public function getAnnotationFromClassname(string $className, bool $throwError = true) : ? object | ||||
|     { | ||||
|         exit(__FILE__); | ||||
|         if ( $name = $this->uses[$className] ?? false ) { | ||||
|             foreach(array_reverse($this->class['tags']) as $item) { | ||||
|                 if ( $item['tag'] === $name ) { | ||||
| @ -292,9 +285,9 @@ class EntityResolver { | ||||
| 
 | ||||
|     public function getAttributeImplementing(string $interface) : ? object | ||||
|     { | ||||
|         foreach (array_reverse($this->class['tags']) as $item) { | ||||
|             if ($item['object'] instanceof $interface) { | ||||
|                 return $item['object']; | ||||
|         foreach (array_reverse($this->reflectedClass->getAttributes(true)) as $item) { | ||||
|             if ($item->object instanceof $interface) { | ||||
|                 return $item->object; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
| @ -303,61 +296,11 @@ class EntityResolver { | ||||
| 
 | ||||
|     public function instanciateAnnotationObject(array|\ReflectionAttribute $tagDefinition) : object | ||||
|     { | ||||
| 
 | ||||
|         if ($tagDefinition instanceof \ReflectionAttribute) { | ||||
|             $obj = $tagDefinition->newInstance(); | ||||
|         } | ||||
|         else { | ||||
|             $arguments = $this->extractArguments($tagDefinition['arguments']); | ||||
| 
 | ||||
|             if (false === $class = array_search($tagDefinition['tag'], $this->uses)) { | ||||
|                 throw new \InvalidArgumentException("Annotation class `{$tagDefinition['tag']}` was not found within {$this->entityClass} uses statement (or it's children / traits)"); | ||||
|             } | ||||
| 
 | ||||
|             $obj = new $class(... $arguments['constructor']); | ||||
| 
 | ||||
|             foreach ($arguments['setter'] as $key => $value) { | ||||
|                 $obj->$key = $value; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         return $obj; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Extracts arguments from an Annotation definition, easing object's declaration. | ||||
|      */ | ||||
|     protected function extractArguments(array $arguments) : array | ||||
|     { | ||||
|         $list = [ | ||||
|             'setter' => [], | ||||
|             'constructor' => [], | ||||
|         ]; | ||||
| 
 | ||||
|         ksort($arguments); | ||||
| 
 | ||||
|         foreach($arguments as $key => $value) { | ||||
|             $list[ is_int($key) ? 'constructor' : 'setter' ][$key] = $value; | ||||
|         } | ||||
| 
 | ||||
|         return $list; | ||||
|     } | ||||
| 
 | ||||
|     protected function resolveAnnotations() | ||||
|     { | ||||
|         foreach($this->class['tags'] as &$tag) { | ||||
|             $tag['object'] ??= $this->instanciateAnnotationObject($tag); | ||||
|         } | ||||
| 
 | ||||
|         foreach($this->properties as &$property) { | ||||
|             foreach($property['tags'] as &$tag){ | ||||
|                 $tag['object'] ??= $this->instanciateAnnotationObject($tag); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         foreach($this->methods as &$method) { | ||||
|             foreach($method['tags'] as &$tag){ | ||||
|                 $tag['object'] ??= $this->instanciateAnnotationObject($tag); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -40,8 +40,10 @@ trait EntityTrait { | ||||
|         $entityResolver = $this->resolveEntity(); | ||||
| 
 | ||||
|         foreach($dataset as $key => $value) { | ||||
|             $field = $entityResolver->field(strtolower($key), EntityResolver::KEY_COLUMN_NAME, false) ?? null; | ||||
|             $field ??= $entityResolver->field(strtolower($key), EntityResolver::KEY_LC_ENTITY_NAME, false); | ||||
|             $field = $entityResolver->field(strtolower($key), EntityResolver::KEY_COLUMN_NAME, false) ?? $entityResolver->field(strtolower($key), EntityResolver::KEY_LC_ENTITY_NAME, false); | ||||
| 
 | ||||
|             # Temp. fix, incoming patch soon
 | ||||
|             $type = $field->getTypes()[0]; | ||||
| 
 | ||||
|             if ( $field === null ) { | ||||
|                 if ($this->entityStrictFieldsDeclaration ) { | ||||
| @ -52,12 +54,12 @@ trait EntityTrait { | ||||
|                 } | ||||
|             } | ||||
|             elseif ( is_null($value) ) { | ||||
|                 $this->{$field['name']} = null; | ||||
|                 $this->{$field->name} = null; | ||||
|             } | ||||
|             elseif ( $field['type'] === 'array' ) { | ||||
|             elseif ( $field->expectType('array') ) { | ||||
|                 if ( is_string($value)) { | ||||
|                     if (substr($value, 0, 1) === "a") { | ||||
|                         $this->{$field['name']} = unserialize($value); | ||||
|                         $this->{$field->name} = unserialize($value); | ||||
|                     } | ||||
|                     else { | ||||
|                         $data = json_decode($value, true); | ||||
| @ -66,41 +68,41 @@ trait EntityTrait { | ||||
|                             throw new \Exception(sprintf("JSON error while decoding in EntityTrait : '%s' given %s", json_last_error_msg(), $value)); | ||||
|                         } | ||||
| 
 | ||||
|                         $this->{$field['name']} = $data; | ||||
|                         $this->{$field->name} = $data; | ||||
|                     } | ||||
|                 } | ||||
|                 elseif ( is_array($value) ) { | ||||
|                     $this->{$field['name']} = $value; | ||||
|                     $this->{$field->name} = $value; | ||||
|                 } | ||||
|             } | ||||
|             elseif ( EntityField::isScalarType($field['type']) ) { | ||||
|             elseif ( EntityField::isScalarType($type->type) ) { | ||||
| 
 | ||||
|                 if ( $field['type'] === 'string' ) { | ||||
|                     $annotation = $entityResolver->searchFieldAnnotation($field['name'], [ Attribute\Property\Field::class, Field::class ] ); | ||||
|                 if ( $type->type === 'string' ) { | ||||
|                     $annotation = $entityResolver->searchFieldAnnotation($field->name, [ Attribute\Property\Field::class ] ); | ||||
| 
 | ||||
|                     if ( $annotation->length ?? null ) { | ||||
|                         $value = mb_substr($value, 0, $annotation->length); | ||||
|                     } | ||||
|                 } | ||||
|                 elseif ( $field['type'] === 'bool' ) { | ||||
|                 elseif ( $type->type === 'bool' ) { | ||||
|                     $value = (bool) $value; | ||||
|                 } | ||||
| 
 | ||||
|                 $this->{$field['name']} = $value; | ||||
|                 $this->{$field->name} = $value; | ||||
|             } | ||||
|             elseif ( $value instanceof \UnitEnum ) { | ||||
|                 $this->{$field['name']} = $value; | ||||
|                 $this->{$field->name} = $value; | ||||
|             } | ||||
|             elseif (enum_exists($field['type'])) { | ||||
|                 $this->{$field['name']} = $field['type']::from($value); | ||||
|             elseif (enum_exists($type->type)) { | ||||
|                 $this->{$field->name} = $type->type::from($value); | ||||
|             } | ||||
|             elseif ( ! $field['builtin'] ) { | ||||
|             elseif ( ! $type->builtIn ) { | ||||
|                 try { | ||||
|                     $this->{$field['name']} = Ulmus::instanciateObject($field['type'], [ $value ]); | ||||
|                     $this->{$field->name} = Ulmus::instanciateObject($type->type, [ $value ]); | ||||
|                 } | ||||
|                 catch(\Error $e) { | ||||
|                     $f = $field['type']; | ||||
|                     throw new \Error(sprintf("%s for class '%s' on field '%s'", $e->getMessage(), get_class($this), $field['name'])); | ||||
|                     $f = $type->type; | ||||
|                     throw new \Error(sprintf("%s for class '%s' on field '%s'", $e->getMessage(), get_class($this), $field->name)); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
| @ -123,9 +125,9 @@ trait EntityTrait { | ||||
|     #[Ignore]
 | ||||
|     public function resetVirtualProperties() : self | ||||
|     { | ||||
|         foreach($this->resolveEntity()->properties as $prop => $property) { | ||||
|             foreach($property['tags'] as $tag) { | ||||
|                 if ( in_array(strtolower($tag['tag']), [ 'relation', 'join', 'virtual' ] ) ) { | ||||
|         foreach($this->resolveEntity()->reflectedClass->getProperties(true) as $prop => $property) { | ||||
|             foreach($property->attributes as $tag) { | ||||
|                 if ( in_array(strtolower($tag->tag), [ 'relation', 'join', 'virtual' ] ) ) { | ||||
|                     unset($this->$prop); | ||||
|                 } | ||||
|             } | ||||
| @ -155,7 +157,7 @@ trait EntityTrait { | ||||
|         $entityResolver = $this->resolveEntity(); | ||||
| 
 | ||||
|         foreach($entityResolver->fieldList(Common\EntityResolver::KEY_ENTITY_NAME, true) as $key => $field) { | ||||
|             $annotation = $entityResolver->searchFieldAnnotation($key, [ Attribute\Property\Field::class, Field::class ]); | ||||
|             $annotation = $entityResolver->searchFieldAnnotation($key, [ Attribute\Property\Field::class ]); | ||||
| 
 | ||||
|             if ( isset($this->$key) ) { | ||||
|                 $dataset[$annotation->name ?? $key] = $rewriteValue ? | ||||
| @ -163,13 +165,13 @@ trait EntityTrait { | ||||
|                 : | ||||
|                     $this->$key; | ||||
|             } | ||||
|             elseif ( $field['nullable'] ) { | ||||
|             elseif ( $field->allowsNull() ) { | ||||
|                 $dataset[$annotation->name ?? $key] = null; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         if ($includeRelations) { | ||||
|             foreach($entityResolver->properties as $name => $field){ | ||||
|             foreach($entityResolver->reflectedClass->getProperties(true) as $name => $field){ | ||||
|                 $relation = $entityResolver->searchFieldAnnotation($name, [ Attribute\Property\Relation::class ] ); | ||||
| 
 | ||||
|                 if ($relation) { | ||||
| @ -178,7 +180,7 @@ trait EntityTrait { | ||||
|                     if ($ignore && $ignore->ignoreExport) { | ||||
|                         if ( $relation->isOneToOne() ) { | ||||
|                             # empty object
 | ||||
|                             $dataset[$name] = ( new \ReflectionClass($field['type']) )->newInstanceWithoutConstructor(); | ||||
|                             $dataset[$name] = ( new \ReflectionClass($field->getTypes()[0]) )->newInstanceWithoutConstructor(); | ||||
|                         } | ||||
|                         else { | ||||
|                             # empty collection
 | ||||
| @ -326,7 +328,9 @@ trait EntityTrait { | ||||
|     { | ||||
|         $default = ( $alias === false ? '' : Repository::DEFAULT_ALIAS ); # bw compatibility, to be deprecated
 | ||||
| 
 | ||||
|         return new EntityField(static::class, $name, $alias ? Ulmus::repository(static::class)->adapter->adapter()->escapeIdentifier($alias, Adapter\AdapterInterface::IDENTIFIER_FIELD) : $default, Ulmus::resolveEntity(static::class)); | ||||
|         $alias = $alias ? Ulmus::repository(static::class)->adapter->adapter()->escapeIdentifier($alias, Adapter\AdapterInterface::IDENTIFIER_FIELD) : $default; | ||||
| 
 | ||||
|         return new EntityField(static::class, $name, $alias, Ulmus::resolveEntity(static::class)); | ||||
|     } | ||||
| 
 | ||||
|     #[Ignore]
 | ||||
|  | ||||
| @ -2,6 +2,7 @@ | ||||
| 
 | ||||
| namespace Ulmus\Migration; | ||||
| 
 | ||||
| use Notes\Common\ReflectedProperty; | ||||
| use Ulmus\Adapter\AdapterInterface; | ||||
| use Ulmus\Annotation\Property\Field; | ||||
| use Ulmus\Attribute; | ||||
| @ -29,25 +30,28 @@ class FieldDefinition { | ||||
| 
 | ||||
|     public AdapterInterface $adapter; | ||||
| 
 | ||||
|     public function __construct(AdapterInterface $adapter, array $data) | ||||
|     public function __construct(AdapterInterface $adapter, ReflectedProperty $data) | ||||
|     { | ||||
|         $this->adapter = $adapter; | ||||
| 
 | ||||
|         $this->name = $data['name']; | ||||
|         $this->builtIn = $data['builtin']; | ||||
|         $this->tags = $data['tags']; | ||||
|         # Patch coming soon
 | ||||
|         $type = $data->getTypes()[0]; | ||||
| 
 | ||||
|         if (isset($data['value'])) { | ||||
|             $this->default = $data['value']; | ||||
|         $this->name = $data->name; | ||||
|         $this->builtIn = $type->builtIn; | ||||
|         $this->tags = $data->getAttributes(); | ||||
| 
 | ||||
|         if (isset($data->value)) { | ||||
|             $this->default = $data->value; | ||||
|         } | ||||
| 
 | ||||
|         $field = $this->getFieldTag(); | ||||
|         $adapter->whitelistAttributes($field->attributes); | ||||
| 
 | ||||
|         $this->type = $field->type ?? $data['type']; | ||||
|         $this->type = $field->type ?? $type->type; | ||||
|         $this->length = $field->length ?? null; | ||||
|         $this->precision = $field->precision ?? null; | ||||
|         $this->nullable = $data['nullable'] ?: $field->nullable; | ||||
|         $this->nullable = $data->allowsNull() ?: $field->nullable; | ||||
|         $this->update = $field->attributes['update'] ?? null; | ||||
|     } | ||||
| 
 | ||||
| @ -76,11 +80,11 @@ class FieldDefinition { | ||||
|         ])); | ||||
|     } | ||||
| 
 | ||||
|     public function getFieldTag() : Field|Attribute\Property\Field|null | ||||
|     public function getFieldTag() : Attribute\Property\Field|null | ||||
|     { | ||||
|         $field = array_filter($this->tags, fn($item) => $item['object'] instanceof Field || $item['object'] instanceof Attribute\Property\Field); | ||||
|         $field = array_filter($this->tags, fn($item) => $item->object instanceof Attribute\Property\Field); | ||||
| 
 | ||||
|         return array_pop($field)['object']; | ||||
|         return array_pop($field)->object; | ||||
|     } | ||||
| 
 | ||||
|     public function getColumnName() : ? string | ||||
|  | ||||
| @ -133,8 +133,6 @@ class Repository | ||||
| 
 | ||||
|             return $this->deleteFromPk($entity->$pkField); | ||||
|         } | ||||
| 
 | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     public function destroyAll(EntityCollection $collection) : void | ||||
| @ -397,8 +395,8 @@ class Repository | ||||
|         $prependField and ($prependField .= "$"); | ||||
| 
 | ||||
|         foreach ($entity::resolveEntity()->fieldList(Common\EntityResolver::KEY_COLUMN_NAME, true) as $key => $field) { | ||||
|             if (null === $entity::resolveEntity()->searchFieldAnnotation($field['name'], [ Attribute\Property\Relation\Ignore::class, RelationIgnore::class ])) { | ||||
|                 $this->select(sprintf("%s.$key as {$prependField}{$field['name']}", $this->escapeIdentifier($alias))); | ||||
|             if (null === $entity::resolveEntity()->searchFieldAnnotation($field->name, [ Attribute\Property\Relation\Ignore::class, RelationIgnore::class ])) { | ||||
|                 $this->select(sprintf("%s.$key as {$prependField}{$field->name}", $this->escapeIdentifier($alias))); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
| @ -410,9 +408,9 @@ class Repository | ||||
|         $fieldlist = []; | ||||
| 
 | ||||
|         foreach ($entity::resolveEntity()->fieldList(Common\EntityResolver::KEY_COLUMN_NAME, true) as $key => $field) { | ||||
|             if (null === $entity::resolveEntity()->searchFieldAnnotation($field['name'], [ Attribute\Property\Relation\Ignore::class, RelationIgnore::class ])) { | ||||
|             if (null === $entity::resolveEntity()->searchFieldAnnotation($field->name, [ Attribute\Property\Relation\Ignore::class, RelationIgnore::class ])) { | ||||
|                 $fieldlist[] = $key; | ||||
|                 $fieldlist[] = $entity::field($field['name'], $this->escapeIdentifier($alias)); | ||||
|                 $fieldlist[] = $entity::field($field->name, $this->escapeIdentifier($alias)); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
| @ -625,26 +623,26 @@ class Repository | ||||
|                 $this->joined[$item] = true; | ||||
|             } | ||||
| 
 | ||||
|             $annotation = $this->entityResolver->searchFieldAnnotation($item, [ Attribute\Property\Join::class, Join::class ]) ?: | ||||
|                 $this->entityResolver->searchFieldAnnotation($item, [ Attribute\Property\Relation::class, Relation::class ]); | ||||
|             $annotation = $this->entityResolver->searchFieldAnnotation($item, [ Attribute\Property\Join::class  ]) ?: | ||||
|                 $this->entityResolver->searchFieldAnnotation($item, [ Attribute\Property\Relation::class ]); | ||||
| 
 | ||||
|             $isRelation = ( $annotation instanceof Relation ) || ($annotation instanceof Attribute\Property\Relation); | ||||
| 
 | ||||
|             if ($isRelation && ( $annotation->isManyToMany() )) { | ||||
|                 throw new Exception("Many-to-many relation can not be preloaded within joins."); | ||||
|                 throw new \Exception("Many-to-many relation can not be preloaded within joins."); | ||||
|             } | ||||
| 
 | ||||
|             if ( $annotation ) { | ||||
|                 $alias = $annotation->alias ?? $item; | ||||
| 
 | ||||
|                 $entity = $annotation->entity ?? $this->entityResolver->properties[$item]['type']; | ||||
|                 $entity = $annotation->entity ?? $this->entityResolver->reflectedClass->getProperties(true)[$item]->getTypes()[0]->type; | ||||
| 
 | ||||
|                 foreach($entity::resolveEntity()->fieldList(Common\EntityResolver::KEY_COLUMN_NAME, true) as $key => $field) { | ||||
|                     if ( null === $entity::resolveEntity()->searchFieldAnnotation($field['name'], [ Attribute\Property\Relation\Ignore::class, RelationIgnore::class ]) ) { | ||||
|                     if ( null === $entity::resolveEntity()->searchFieldAnnotation($field->name, [ Attribute\Property\Relation\Ignore::class ]) ) { | ||||
|                         $escAlias = $this->escapeIdentifier($alias); | ||||
|                         $fieldName = $this->escapeIdentifier($key); | ||||
| 
 | ||||
|                         $name = $entity::resolveEntity()->searchFieldAnnotation($field['name'], [ Attribute\Property\Field::class, Field::class ])->name ?? $field['name']; | ||||
|                         $name = $entity::resolveEntity()->searchFieldAnnotation($field->name, [ Attribute\Property\Field::class ])->name ?? $field->name; | ||||
| 
 | ||||
| 
 | ||||
|                         $this->select("$escAlias.$fieldName as $alias\${$name}"); | ||||
| @ -654,7 +652,7 @@ class Repository | ||||
|                 $this->open(); | ||||
| 
 | ||||
|                 if ( ! in_array(WithOptionEnum::SkipWhere, $options)) { | ||||
|                 foreach($this->entityResolver->searchFieldAnnotationList($item, [ Attribute\Property\Where::class, Where::class ] ) as $condition) { | ||||
|                 foreach($this->entityResolver->searchFieldAnnotationList($item, [ Attribute\Property\Where::class ] ) as $condition) { | ||||
|                     if ( is_object($condition->field) && ( $condition->field->entityClass !== $entity ) ) { | ||||
|                         $this->where(is_object($condition->field) ? $condition->field : $entity::field($condition->field),  $condition->getValue(), $condition->operator); | ||||
|                     } | ||||
| @ -662,13 +660,13 @@ class Repository | ||||
|                 } | ||||
| 
 | ||||
|                 if ( ! in_array(WithOptionEnum::SkipHaving, $options)) { | ||||
|                     foreach ($this->entityResolver->searchFieldAnnotationList($item, [Attribute\Property\Having::class, Having::class]) as $condition) { | ||||
|                     foreach ($this->entityResolver->searchFieldAnnotationList($item, [ Attribute\Property\Having::class ]) as $condition) { | ||||
|                         $this->having(is_object($condition->field) ? $condition->field : $entity::field($condition->field), $condition->getValue(), $condition->operator); | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
|                 if ( ! in_array(WithOptionEnum::SkipFilter, $options)) { | ||||
|                     foreach ($this->entityResolver->searchFieldAnnotationList($item, [Attribute\Property\Filter::class, Filter::class]) as $filter) { | ||||
|                     foreach ($this->entityResolver->searchFieldAnnotationList($item, [ Attribute\Property\Filter::class ]) as $filter) { | ||||
|                         call_user_func_array([$this->entityClass, $filter->method], [$this, $item, true]); | ||||
|                     } | ||||
|                 } | ||||
| @ -681,7 +679,7 @@ class Repository | ||||
| 
 | ||||
|                 $this->join("LEFT", $entity::resolveEntity()->tableName(), $key, $foreignKey, $alias, function($join) use ($item, $entity, $alias, $options) { | ||||
|                     if (  !  in_array(WithOptionEnum::SkipJoinWhere, $options)) { | ||||
|                     foreach($this->entityResolver->searchFieldAnnotationList($item, [ Attribute\Property\Where::class, Where::class ]) as $condition) { | ||||
|                     foreach($this->entityResolver->searchFieldAnnotationList($item, [ Attribute\Property\Where::class ]) as $condition) { | ||||
|                         if ( ! is_object($condition->field) ) { | ||||
|                             $field = $this->entityClass::field($condition->field); | ||||
|                         } | ||||
| @ -699,7 +697,7 @@ class Repository | ||||
|                     } | ||||
| 
 | ||||
|                     if ( ! in_array(WithOptionEnum::SkipJoinFilter, $options) ) { | ||||
|                          foreach ($this->entityResolver->searchFieldAnnotationList($item, [Attribute\Property\FilterJoin::class, FilterJoin::class]) as $filter) { | ||||
|                          foreach ($this->entityResolver->searchFieldAnnotationList($item, [ Attribute\Property\FilterJoin::class ]) as $filter) { | ||||
|                             call_user_func_array([$this->entityClass, $filter->method], [$join, $item, true]); | ||||
|                         } | ||||
|                     } | ||||
| @ -726,7 +724,7 @@ class Repository | ||||
| 
 | ||||
|         # Apply FILTER annotation to this too !
 | ||||
|         foreach(array_filter((array) $fields) as $item) { | ||||
|             if ( $relation = $this->entityResolver->searchFieldAnnotation($item, [ Attribute\Property\Relation::class, Relation::class ]) ) { | ||||
|             if ( $relation = $this->entityResolver->searchFieldAnnotation($item, [ Attribute\Property\Relation::class ]) ) { | ||||
|                 $alias = $relation->alias ?? $item; | ||||
| 
 | ||||
|                 if ( $relation->isManyToMany() ) { | ||||
| @ -747,11 +745,11 @@ class Repository | ||||
| 
 | ||||
|                 #  $relation->isManyToMany() and $repository->selectJsonEntity($relation->bridge, $relation->bridgeField, true);
 | ||||
| 
 | ||||
|                 foreach($this->entityResolver->searchFieldAnnotationList($item, [ Attribute\Property\Where::class, Where::class ]) as $condition) { | ||||
|                 foreach($this->entityResolver->searchFieldAnnotationList($item, [ Attribute\Property\Where::class ]) as $condition) { | ||||
|                     $repository->where(is_object($condition->field) ? $condition->field : $entity::field($condition->field), $condition->getValue(), $condition->operator); | ||||
|                 } | ||||
| 
 | ||||
|                 foreach($this->entityResolver->searchFieldAnnotationList($item, [ Attribute\Property\Having::class, Having::class ] ) as $condition) { | ||||
|                 foreach($this->entityResolver->searchFieldAnnotationList($item, [ Attribute\Property\Having::class ] ) as $condition) { | ||||
|                     $repository->having(is_object($condition->field) ? $condition->field : $entity::field($condition->field), $condition->getValue(), $condition->operator); | ||||
|                 } | ||||
| 
 | ||||
| @ -778,9 +776,9 @@ class Repository | ||||
|     public function loadCollectionRelation(EntityCollection $collection, array|string $fields) : void | ||||
|     { | ||||
|         foreach ((array)$fields as $name) { | ||||
|             if (null !== ($relation = $this->entityResolver->searchFieldAnnotation($name, [ Attribute\Property\Relation::class, Relation::class ] ))) { | ||||
|                 $order = $this->entityResolver->searchFieldAnnotationList($name, [ Attribute\Property\OrderBy::class, OrderBy::class ]); | ||||
|                 $where = $this->entityResolver->searchFieldAnnotationList($name, [ Attribute\Property\Where::class, Where::class ]); | ||||
|             if (null !== ($relation = $this->entityResolver->searchFieldAnnotation($name, [ Attribute\Property\Relation::class ] ))) { | ||||
|                 $order = $this->entityResolver->searchFieldAnnotationList($name, [ Attribute\Property\OrderBy::class ]); | ||||
|                 $where = $this->entityResolver->searchFieldAnnotationList($name, [ Attribute\Property\Where::class ]); | ||||
| 
 | ||||
|                 $baseEntity = $relation->entity ?? $relation->bridge ?? $this->entityResolver->properties[$name]['type']; | ||||
|                 $baseEntityResolver = $baseEntity::resolveEntity(); | ||||
| @ -791,7 +789,7 @@ class Repository | ||||
|                 $repository = $baseEntity::repository(); | ||||
| 
 | ||||
|                 foreach ($baseEntityResolver->fieldList(Common\EntityResolver::KEY_COLUMN_NAME, true) as $key => $field) { | ||||
|                     if (null === $baseEntityResolver->searchFieldAnnotation($field['name'], [ Attribute\Property\Relation\Ignore::class, RelationIgnore::class ])) { | ||||
|                     if (null === $baseEntityResolver->searchFieldAnnotation($field->name, [ Attribute\Property\Relation\Ignore::class ])) { | ||||
|                         $repository->select($baseEntityResolver->entityClass::field($key)); | ||||
|                     } | ||||
|                 } | ||||
| @ -953,7 +951,7 @@ class Repository | ||||
|     { | ||||
|         if ( null === $this->queryBuilder->getFragment(Query\Select::class) ) { | ||||
|             $fields = $this->entityResolver->fieldList(EntityResolver::KEY_COLUMN_NAME, true); | ||||
|             $this->select($this->entityClass::fields(array_map(fn($f) => $f['object']->name ?? $f['name'], $fields))); | ||||
|             $this->select($this->entityClass::fields(array_map(fn($f) => $f->object->name ?? $f->name, $fields))); | ||||
|         } | ||||
| 
 | ||||
|         if ( null === $this->queryBuilder->getFragment(Query\From::class) ) { | ||||
|  | ||||
| @ -219,7 +219,7 @@ class RelationBuilder | ||||
|                 $entity = $this->relationAnnotations($name, $annotation)['relationRelation']->entity; | ||||
|             } | ||||
|             else { | ||||
|                 $entity = $annotation->entity ?? $this->resolver->properties[$name]['type']; | ||||
|                 $entity = $annotation->entity ?? $this->resolver->reflectedClass->getProperties()[$name]->getTypes()[0]->type; | ||||
|             } | ||||
| 
 | ||||
|             $name = strtolower($name); | ||||
| @ -266,7 +266,7 @@ class RelationBuilder | ||||
| 
 | ||||
|     public function oneToMany(string $name, Relation|Attribute\Property\Relation $relation) : Repository | ||||
|     { | ||||
|         $baseEntity = $relation->entity ?? $this->resolver->properties[$name]['type']; | ||||
|         $baseEntity = $relation->entity ?? $this->resolver->reflectedClass->getProperties()[$name]->getTypes()[0]->type; | ||||
| 
 | ||||
|         $this->repository = $baseEntity::repository(); | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user