- WIP on attributes ; on testing phase

This commit is contained in:
mcndave committed 2023-01-26 13:25:59 +00:00
1 parent 5295a335b3
commit e6d0279c1a
44 files changed
+763 -142

No files matched your search

+42 -26
View File
@@ -2,7 +2,17 @@
namespace Ulmus\Repository;
use Ulmus\{ Ulmus, Annotation, Query, Common, Common\EntityResolver, Repository, Event, EntityCollection, };
use Ulmus\{Attribute\Property\Field,
Ulmus,
Annotation,
Attribute,
Query,
Common,
Common\EntityResolver,
Repository,
Event,
EntityCollection};
use Ulmus\Annotation\Property\{Filter, OrderBy, Relation, Relation\Ignore as RelationIgnore, Where, WithJoin, };
use Closure;
@@ -15,7 +25,7 @@ class RelationBuilder
protected Repository $repository;
protected /*object|string*/ $entity;
protected object|string $entity;
protected EntityResolver $resolver;
@@ -27,7 +37,7 @@ class RelationBuilder
protected array $joins;
public function __construct(/*string|object*/ $entity, ? Repository $repository = null)
public function __construct(string|object $entity, ? Repository $repository = null)
{
$this->entity = $entity;
$this->resolver = $entity::resolveEntity();
@@ -48,7 +58,7 @@ class RelationBuilder
return $this->resolveRelation($name) ?: $this->resolveVirtual($name) ?: false;
}
else {
if ( $relation = $this->resolver->searchFieldAnnotation($name, new Relation() ) ) {
if ( $relation = $this->resolver->searchFieldAnnotation($name, [ Attribute\Property\Relation::class , Relation::class ] ) ) {
return $this->instanciateEmptyObject($name, $relation);
}
elseif ($virtual = $this->resolveVirtual($name)) {
@@ -59,9 +69,9 @@ class RelationBuilder
return false;
}
protected function resolveVirtual(string $name) /* : bool|object|EntityCollection */
protected function resolveVirtual(string $name) : bool|object
{
if (null !== ($virtual = $this->resolver->searchFieldAnnotation($name, new Annotation\Property\Virtual()))) {
if (null !== ($virtual = $this->resolver->searchFieldAnnotation($name, [ Attribute\Property\Virtual::class, Annotation\Property\Virtual::class ]))) {
if ($virtual->closure ?? false) {
return call_user_func_array($virtual->closure, [ $this->entity ]);
}
@@ -72,17 +82,18 @@ class RelationBuilder
return false;
}
protected function resolveRelation(string $name) /* : bool|object|EntityCollection */
protected function resolveRelation(string $name) : bool|object
{
if ( null !== ( $relation = $this->resolver->searchFieldAnnotation($name, new Relation() ) ) ) {
$this->orders = $this->resolver->searchFieldAnnotationList($name, new OrderBy() );
$this->wheres = $this->resolver->searchFieldAnnotationList($name, new Where() );
$this->filters = $this->resolver->searchFieldAnnotationList($name, new Filter() );
$this->joins = $this->resolver->searchFieldAnnotationList($name, new WithJoin() );
if ( null !== ( $relation = $this->resolver->searchFieldAnnotation($name, [ Attribute\Property\Relation::class, Relation::class ] ) ) ) {
$this->orders = $this->resolver->searchFieldAnnotationList($name, [ Attribute\Property\OrderBy::class, OrderBy::class ] );
$this->wheres = $this->resolver->searchFieldAnnotationList($name, [ Attribute\Property\Where::class, Where::class ] );
$this->filters = $this->resolver->searchFieldAnnotationList($name, [ Attribute\Property\Filter::class, Filter::class ] );
$this->joins = $this->resolver->searchFieldAnnotationList($name, [ Attribute\Property\WithJoin::class, WithJoin::class ] );
switch( true ) {
case $relation->isOneToOne():
if ( $relation->hasBridge() ) {
#dump($name, $relation);
# @TODO ! dump($this->relationAnnotations($name, $relation));
}
else {
@@ -155,7 +166,7 @@ class RelationBuilder
}
}
protected function instanciateEmptyEntity(string $name, Relation $relation) : object
protected function instanciateEmptyEntity(string $name, Relation|Attribute\Property\Relation $relation) : object
{
$class = $relation->entity ?? $this->resolver->properties[$name]['type'];
@@ -163,7 +174,7 @@ class RelationBuilder
}
protected function instanciateEmptyObject(string $name, Relation $relation) : object
protected function instanciateEmptyObject(string $name, Relation|Attribute\Property\Relation $relation) : object
{
switch( true ) {
case $relation->isOneToOne():
@@ -181,16 +192,18 @@ class RelationBuilder
return new $class();
}
protected function fetchFromDataset($name, ? array $data = null) /* object|bool */
protected function fetchFromDataset($name, ? array $data = null) : object|bool
{
$annotation = $this->resolver->searchFieldAnnotation($name, new Annotation\Property\Join) ?:
$this->resolver->searchFieldAnnotation($name, new Annotation\Property\Relation);
$annotation = $this->resolver->searchFieldAnnotation($name, [ Attribute\Property\Join::class, Annotation\Property\Join::class ]) ?:
$this->resolver->searchFieldAnnotation($name, [ Attribute\Property\Relation::class, Annotation\Property\Relation::class ]);
if ( $annotation ) {
$vars = [];
$len = strlen( $name ) + 1;
if ( ( $annotation instanceof Relation ) && $annotation->isManyToMany() ) {
$isRelation = ( $annotation instanceof Relation ) || ($annotation instanceof Attribute\Property\Relation);
if ( $isRelation && $annotation->isManyToMany() ) {
$entity = $this->relationAnnotations($name, $annotation)['relationRelation']->entity;
}
else {
@@ -231,12 +244,12 @@ class RelationBuilder
return false;
}
public function oneToOne(string $name, Relation $relation) : Repository
public function oneToOne(string $name, Relation|Attribute\Property\Relation $relation) : Repository
{
return $this->oneToMany($name, $relation)->limit(1);
}
public function oneToMany(string $name, Relation $relation) : Repository
public function oneToMany(string $name, Relation|Attribute\Property\Relation $relation) : Repository
{
$baseEntity = $relation->entity ?? $this->resolver->properties[$name]['type'];
@@ -249,13 +262,17 @@ class RelationBuilder
$field = $relation->key;
if ($relation->foreignKey) {
$this->repository->where( is_object($relation->foreignKey) ? $relation->foreignKey : $baseEntity::field($relation->foreignKey), ! is_string($field) && is_callable($field) ? $field($this->entity) : $this->entity->$field );
# dump($baseEntity::resolveEntity()->searchField($field));
# dump($this->resolver->properties[$name], $field);
$value = ! is_string($field) && is_callable($field) ? $field($this->entity) : $this->entity->$field;
$this->repository->where( is_object($relation->foreignKey) ? $relation->foreignKey : $baseEntity::field($relation->foreignKey), $value );
}
return $this->applyFilter($this->repository, $name);
}
public function manyToMany(string $name, Relation $relation, ? Relation & $relationRelation = null, bool $selectBridgeField = true) : Repository
public function manyToMany(string $name, Relation|Attribute\Property\Relation $relation, Relation|Attribute\Property\Relation & $relationRelation = null, bool $selectBridgeField = true) : Repository
{
extract($this->relationAnnotations($name, $relation));
@@ -272,7 +289,6 @@ class RelationBuilder
})->where( $this->entity::field($bridgeRelation->foreignKey, $relationAlias), is_string($this->entity) ? $this->entity::field($bridgeRelation->foreignKey) : $this->entity->{$bridgeRelation->foreignKey} );
$this->applyWhere();
$this->applyOrderBy();
@@ -284,7 +300,7 @@ class RelationBuilder
return $this->applyFilter($this->repository, $name);
}
public static function relationAnnotations(string $name, Relation $relation) : array
public static function relationAnnotations(string $name, Relation|Attribute\Property\Relation $relation) : array
{
if ( $relation->isOneToOne() || $relation->isManyToMany() ) {
if ( ! $relation->hasBridge() ) {
@@ -292,8 +308,8 @@ class RelationBuilder
}
$bridgeEntity = Ulmus::resolveEntity($relation->bridge);
$bridgeRelation = $bridgeEntity->searchFieldAnnotation($relation->field, new Relation() );
$relationRelation = $bridgeEntity->searchFieldAnnotation($relation->foreignField, new Relation() );
$bridgeRelation = $bridgeEntity->searchFieldAnnotation($relation->field, [ Attribute\Property\Relation::class, Relation::class ]);
$relationRelation = $bridgeEntity->searchFieldAnnotation($relation->foreignField, [ Attribute\Property\Relation::class, Relation::class ]);
if ($relationRelation === null) {
throw new \Exception("@Relation annotation not found for field `{$relation->foreignField}` in entity {$relation->bridge}");