- Work done on Join and using the @Relation annotation in case there is no join.

- Added some field type (date, Datetime, Time)
- Added a new @Filter annotation which allows to filter repository from relation into a method.
This commit is contained in:
mcndave committed 2021-01-26 16:48:40 +00:00
1 parent 65de1dd849
commit e465ecdf32
17 files changed
+197 -61

No files matched your search

+66 -35
View File
@@ -8,8 +8,8 @@ use Ulmus\Repository,
Ulmus\Common\EntityField;
use Ulmus\Annotation\Classes\{ Method, Table, Collation, };
use Ulmus\Annotation\Property\{ Field, Relation, OrderBy, Where, Join, Virtual };
use Ulmus\Annotation\Property\Field\{ Id, ForeignKey, CreatedAt, UpdatedAt, };
use Ulmus\Annotation\Property\{ Field, Relation, OrderBy, Where, Join, Filter, On };
use Ulmus\Annotation\Property\Field\{ Id, ForeignKey, CreatedAt, UpdatedAt, Datetime as DateTime, Date, Time, };
trait EntityTrait {
use EventTrait;
@@ -40,69 +40,81 @@ trait EntityTrait {
# @TODO REFACTOR THIS CODE ASAP !
if ( $this->isLoaded() ) {
if ( null !== ( $join= $entityResolver->searchFieldAnnotation($name, new Join() ) ) ) {
$annotation = $entityResolver->searchFieldAnnotation($name, new Annotation\Property\Join) ?:
$entityResolver->searchFieldAnnotation($name, new Annotation\Property\Relation);
if ( $annotation ) {
$vars = [];
$entity = $join->entity ?? $entityResolver->properties[$name]['type'];
$len = strlen( $name ) + 1;
foreach($this->entityDatasetUnmatchedFields as $key => $value) {
$len = strlen( $name ) + 1;
if ( substr($key, 0, $len ) === "{$name}$" ) {
$vars[substr($key, $len)] = $value;
}
}
if ( [] !== $data = (array_values(array_unique($vars)) !== [ null ] ? $vars : []) ) {
return ( new $entity() )->fromArray($data);
if ( [] !== $data = (array_values(array_unique($vars)) !== [ null ] ? $vars : []) ) {
$entity = $annotation->entity ?? $entityResolver->properties[$name]['type'];
return $this->$name = ( new $entity() )->fromArray($data)->resetVirtualProperties();
}
}
if ( null !== ( $relation = $entityResolver->searchFieldAnnotation($name, new Relation() ) ) ) {
$relationType = strtolower(str_replace(['-', '_', ' '], '', $relation->type));
$order = $entityResolver->searchFieldAnnotationList($name, new OrderBy() );
$where = $entityResolver->searchFieldAnnotationList($name, new Where() );
$filters = $entityResolver->searchFieldAnnotationList($name, new Filter() );
if ( $relation->entity ?? false ) {
$baseEntity = $relation->entity();
$baseEntity = $relation->entity ?? $relation->bridge ?? $entityResolver->properties[$name]['type'];
$repository = $baseEntity->repository();
$repository = $baseEntity::repository()->open();
foreach($where as $condition) {
$repository->where($condition->field, is_callable($condition->value) ? $f = call_user_func_array($condition->value, [ $this ]) : $condition->value, $condition->operator);
}
foreach($order as $item) {
$repository->orderBy($item->field, $item->order);
}
$field = $relation->key;
foreach ($where as $condition) {
$repository->where($condition->field, is_callable($condition->value) ? call_user_func_array($condition->value, [$this]) : $condition->value, $condition->operator, $condition->condition);
}
switch( $relationType ) {
case 'onetoone':
if ($relation->foreignKey) {
$repository->where( is_object($relation->foreignKey) ? $relation->foreignKey : $baseEntity->field($relation->foreignKey), is_callable($field) ? $field($this) : $this->$field );
$repository->close();
foreach ($order as $item) {
$repository->orderBy($item->field, $item->order);
}
$field = $relation->key;
$applyFilter = function($repository) use ($filters, $name) {
foreach($filters as $filter) {
$repository = call_user_func_array([ $this, $filter->method ], [ $repository, $name ]);
}
return $repository;
};
switch( $relation->normalizeType() ) {
case 'onetoone':
$repository->limit(1);
if ($relation->foreignKey) {
$repository->where( is_object($relation->foreignKey) ? $relation->foreignKey : $baseEntity::field($relation->foreignKey), is_callable($field) ? $field($this) : $this->$field );
}
$this->eventExecute(Event\EntityRelationLoadInterface::class, $name, $repository);
$result = call_user_func([$repository, $relation->function]);
if ( count($result) === 0 ) {
return $baseEntity;
return new $baseEntity();
}
return $this->$name = $result[0];
case 'onetomany':
if ($relation->foreignKey) {
$repository->where( is_object($relation->foreignKey) ? $relation->foreignKey : $baseEntity->field($relation->foreignKey), is_callable($field) ? $field($this) : $this->$field );
$repository->where( is_object($relation->foreignKey) ? $relation->foreignKey : $baseEntity::field($relation->foreignKey), is_callable($field) ? $field($this) : $this->$field );
}
$this->eventExecute(Event\EntityRelationLoadInterface::class, $name, $repository);
return $this->$name = call_user_func([$repository, $relation->function]);
return $this->$name = call_user_func([$applyFilter($repository), $relation->function]);
case 'manytomany':
if ( false === $relation->bridge ?? false ) {
@@ -128,17 +140,21 @@ trait EntityTrait {
->join(Query\Join::TYPE_INNER, $this->resolveEntity()->tableName(), $relation->bridge::field($bridgeRelation->key, $bridgeAlias), static::field($bridgeRelation->foreignKey, $relationAlias), $relationAlias)
->where( static::field($bridgeRelation->foreignKey, $relationAlias), $this->{$bridgeRelation->foreignKey} );
$repository->open();
foreach($where as $condition) {
$repository->where($condition->field, $condition->value, $condition->operator);
}
$repository->close();
foreach($order as $item) {
$repository->orderBy($item->field, $item->order);
}
$this->eventExecute(Event\EntityRelationLoadInterface::class, $name, $repository);
$this->$name = call_user_func([ $repository, $relationRelation->function ]);
$this->$name = call_user_func([ $applyFilter($repository), $relationRelation->function ]);
if ($relation->bridgeField ?? false) {
$repository = $relationRelation->entity::repository();
@@ -148,10 +164,14 @@ trait EntityTrait {
->join(Query\Join::TYPE_INNER, $this->resolveEntity()->tableName(), $relation->bridge::field($bridgeRelation->key, $bridgeAlias), static::field($bridgeRelation->foreignKey, $relationAlias), $relationAlias)
->where( static::field($bridgeRelation->foreignKey, $relationAlias), $this->{$bridgeRelation->foreignKey} );
$repository->open();
foreach($where as $condition) {
$repository->where($condition->field, $condition->value, $condition->operator);
}
$repository->close();
foreach($order as $item) {
$repository->orderBy($item->field, $item->order);
}
@@ -176,8 +196,11 @@ trait EntityTrait {
*/
public function __isset(string $name) : bool
{
#if ( null !== $relation = static::resolveEntity()->searchFieldAnnotation($name, new Relation() ) ) {
# return isset($this->{$relation->key});
#}
if ( $this->isLoaded() && static::resolveEntity()->searchFieldAnnotation($name, new Relation() ) ) {
return true;
return true;
}
return isset($this->$name);
@@ -186,18 +209,18 @@ trait EntityTrait {
/**
* @Ignore
*/
public function entityFillFromDataset(iterable $dataset, bool $isLoadedDataset = false) : self
public function entityFillFromDataset(iterable $dataset) : self
{
$loaded = $this->isLoaded();
$entityResolver = $this->resolveEntity();
foreach($dataset as $key => $value) {
$field = $entityResolver->field(strtolower($key), EntityResolver::KEY_COLUMN_NAME, false) ?? null;
if ( $field === null ) {
$field = $entityResolver->field($key, EntityResolver::KEY_ENTITY_NAME, false);
}
}
if ( $field === null ) {
if ($this->entityStrictFieldsDeclaration ) {
@@ -227,6 +250,9 @@ trait EntityTrait {
$value = substr($value, 0, $annotation->length);
}
}
elseif ( $field['type'] === 'bool' ) {
$this->{$field['name']} = (bool) $value;
}
$this->{$field['name']} = $value;
}
@@ -297,6 +323,10 @@ trait EntityTrait {
case is_array($this->$key):
$dataset[$realKey] = Ulmus::encodeArray($this->$key);
break;
case is_bool($this->$key):
$dataset[$realKey] = (int) $this->$key;
break;
default:
$dataset[$realKey] = $this->$key;
@@ -307,6 +337,7 @@ trait EntityTrait {
}
}
# @TODO Must fix recursive bug !
if ($includeRelations) {
foreach($entityResolver->properties as $name => $field){
$relation = $entityResolver->searchFieldAnnotation($name, new Relation() );