Merge branch 'master' of https://git.mcnd.ca/mcndave/ulmus
This commit is contained in:
		
						commit
						8f9332fbad
					
				@ -11,7 +11,7 @@ class Id extends \Ulmus\Annotation\Property\Field {
 | 
				
			|||||||
        $this->attributes['primary_key'] = true;
 | 
					        $this->attributes['primary_key'] = true;
 | 
				
			||||||
        $this->attributes['auto_increment'] = true;
 | 
					        $this->attributes['auto_increment'] = true;
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        parent::__construct('int');
 | 
					        parent::__construct('bigint');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -12,7 +12,9 @@ class Where implements \Ulmus\Annotation\Annotation {
 | 
				
			|||||||
    
 | 
					    
 | 
				
			||||||
    public string $operator;
 | 
					    public string $operator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function __construct(/* stringable */ $field = null, $value = null, ? string $operator = null)
 | 
					    public string $condition;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    public function __construct(? string $field = null, $value = null, ? string $operator = null, ? string $condition = null)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if ( $field !== null ) {
 | 
					        if ( $field !== null ) {
 | 
				
			||||||
            $this->field = $field;
 | 
					            $this->field = $field;
 | 
				
			||||||
@ -22,11 +24,7 @@ class Where implements \Ulmus\Annotation\Annotation {
 | 
				
			|||||||
            $this->value = $value;
 | 
					            $this->value = $value;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        if ( $operator !== null ) {
 | 
					        $this->operator = $operator !== null ? $operator : Query\Where::OPERATOR_EQUAL; 
 | 
				
			||||||
            $this->operator = $operator;
 | 
					        $this->condition = $condition !== null ? $condition : Query\Where::CONDITION_AND; 
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        else {
 | 
					 | 
				
			||||||
            $this->operator = Query\Where::OPERATOR_EQUAL;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -26,11 +26,11 @@ class EntityCollection extends \ArrayObject {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
    public function filtersCollection(Callable $callback, bool $yieldValueOnly = false, bool $replaceCollection = false) : self
 | 
					    public function filtersCollection(Callable $callback, bool $replaceCollection = false) : self
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $collection = new static();
 | 
					        $collection = new static();
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        foreach($this->filters($callback, $yieldValueOnly) as $item) {
 | 
					        foreach($this->filters($callback, true) as $item) {
 | 
				
			||||||
            $collection->append($item);
 | 
					            $collection->append($item);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -78,6 +78,13 @@ class EntityCollection extends \ArrayObject {
 | 
				
			|||||||
        return $removed;
 | 
					        return $removed;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					    public function clear() : self
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->exchangeArray([]);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        return $this;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    public function search($value, string $field, bool $strict = true) : Generator 
 | 
					    public function search($value, string $field, bool $strict = true) : Generator 
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        foreach($this->filters(fn($v) => $strict ? $v->$field === $value : $v->$field == $value) as $key => $item) {
 | 
					        foreach($this->filters(fn($v) => $strict ? $v->$field === $value : $v->$field == $value) as $key => $item) {
 | 
				
			||||||
@ -106,6 +113,11 @@ class EntityCollection extends \ArrayObject {
 | 
				
			|||||||
        return $obj;
 | 
					        return $obj;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					    public function searchInstances(string $className) : self
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->filtersCollection(fn($obj) => is_a($obj, $className));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    public function column($field, bool $unique = false) : array
 | 
					    public function column($field, bool $unique = false) : array
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $list = [];
 | 
					        $list = [];
 | 
				
			||||||
@ -118,8 +130,8 @@ class EntityCollection extends \ArrayObject {
 | 
				
			|||||||
                $value = $item->$field;
 | 
					                $value = $item->$field;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            if ($unique && in_array($value, $list)) {
 | 
					            if ($unique && in_array($value, $list, true)) {
 | 
				
			||||||
                break;
 | 
					                continue;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $list[] = $value;
 | 
					            $list[] = $value;
 | 
				
			||||||
@ -250,13 +262,20 @@ class EntityCollection extends \ArrayObject {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    public function mergeWith( /*array|EntityCollection*/ $datasets ) : self
 | 
					    public function mergeWith(... $datasets) : self
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if ( is_object($datasets) ) {
 | 
					        $list = [];
 | 
				
			||||||
            $datasets = $datasets->getArrayCopy();
 | 
					        
 | 
				
			||||||
 | 
					        foreach($datasets as $dataset) {
 | 
				
			||||||
 | 
					            if ( is_object($dataset) ) {
 | 
				
			||||||
 | 
					                $list = array_merge($dataset->getArrayCopy(), $list);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else {
 | 
				
			||||||
 | 
					                $list = array_merge($dataset, $list);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        $this->exchangeArray( array_merge( $this->getArrayCopy(), $datasets ) );
 | 
					        $this->exchangeArray( array_merge( $this->getArrayCopy(), $list ) );
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        return $this;
 | 
					        return $this;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -287,4 +306,16 @@ class EntityCollection extends \ArrayObject {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        return $this;
 | 
					        return $this;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function rsort(callable $callback, $function = "uasort") : self
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->sort(...func_get_args());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $this->reverse();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function reverse() : self
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->replaceWith(array_reverse($this->getArrayCopy()));;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -8,7 +8,7 @@ use Ulmus\Repository,
 | 
				
			|||||||
    Ulmus\Common\EntityField;
 | 
					    Ulmus\Common\EntityField;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use Ulmus\Annotation\Classes\{ Method, Table, Collation, };
 | 
					use Ulmus\Annotation\Classes\{ Method, Table, Collation, };
 | 
				
			||||||
use Ulmus\Annotation\Property\{ Field, Relation, OrderBy, Where, Join, Filter, On };
 | 
					use Ulmus\Annotation\Property\{ Field, Filter, Relation, OrderBy, Where, Join, Virtual, On, };
 | 
				
			||||||
use Ulmus\Annotation\Property\Field\{ Id, ForeignKey, CreatedAt, UpdatedAt, Datetime as DateTime, Date, Time, };
 | 
					use Ulmus\Annotation\Property\Field\{ Id, ForeignKey, CreatedAt, UpdatedAt, Datetime as DateTime, Date, Time, };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
trait EntityTrait {
 | 
					trait EntityTrait {
 | 
				
			||||||
@ -67,7 +67,6 @@ trait EntityTrait {
 | 
				
			|||||||
                $filters = $entityResolver->searchFieldAnnotationList($name, new Filter() );
 | 
					                $filters = $entityResolver->searchFieldAnnotationList($name, new Filter() );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                $baseEntity = $relation->entity ?? $relation->bridge ?? $entityResolver->properties[$name]['type'];
 | 
					                $baseEntity = $relation->entity ?? $relation->bridge ?? $entityResolver->properties[$name]['type'];
 | 
				
			||||||
 | 
					 | 
				
			||||||
                $repository = $baseEntity::repository()->open();
 | 
					                $repository = $baseEntity::repository()->open();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                foreach($where as $condition) {
 | 
					                foreach($where as $condition) {
 | 
				
			||||||
@ -80,6 +79,14 @@ trait EntityTrait {
 | 
				
			|||||||
                    $repository->orderBy($item->field, $item->order);
 | 
					                    $repository->orderBy($item->field, $item->order);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                                
 | 
					                                
 | 
				
			||||||
 | 
					                $applyFilter = function($repository) use ($filters, $name) {
 | 
				
			||||||
 | 
					                    foreach($filters as $filter) {
 | 
				
			||||||
 | 
					                        $repository = call_user_func_array([ $this, $filter->method ], [ $repository, $name ]);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    
 | 
				
			||||||
 | 
					                    return $repository;
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                $field = $relation->key;
 | 
					                $field = $relation->key;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                $applyFilter = function($repository) use ($filters, $name) {
 | 
					                $applyFilter = function($repository) use ($filters, $name) {
 | 
				
			||||||
@ -112,6 +119,7 @@ trait EntityTrait {
 | 
				
			|||||||
                        if ($relation->foreignKey) {
 | 
					                        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);
 | 
					                        $this->eventExecute(Event\EntityRelationLoadInterface::class, $name, $repository);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        return $this->$name = call_user_func([$applyFilter($repository), $relation->function]);
 | 
					                        return $this->$name = call_user_func([$applyFilter($repository), $relation->function]);
 | 
				
			||||||
 | 
				
			|||||||
@ -177,6 +177,64 @@ class Repository
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function loadCollectionRelation(EntityCollection $collection, /*array|string*/ $fields) : void
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        foreach((array) $fields as $name) {
 | 
				
			||||||
 | 
					            if ( null !== ( $relation = $this->entityResolver->searchFieldAnnotation($name, new Annotation\Property\Relation() ) ) ) {
 | 
				
			||||||
 | 
					                $relationType = strtolower(str_replace(['-', '_', ' '], '', $relation->type));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $order = $this->entityResolver->searchFieldAnnotationList($name, new Annotation\Property\OrderBy() );
 | 
				
			||||||
 | 
					                $where = $this->entityResolver->searchFieldAnnotationList($name, new Annotation\Property\Where() );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $baseEntity = $relation->entity ?? $relation->bridge ?? $this->entityResolver->properties[$name]['type'];
 | 
				
			||||||
 | 
					                $baseEntityResolver = $baseEntity::resolveEntity();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $property = ( $baseEntityResolver->field($relation->foreignKey, 01, false) ?: $baseEntityResolver->field($relation->foreignKey, 02) )['name'];
 | 
				
			||||||
 | 
					                $entityProperty = ( $this->entityResolver->field($relation->key, 01, false) ?: $this->entityResolver->field($relation->key, 02) )['name'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $repository = $baseEntity::repository();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                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);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                foreach($order as $item) {
 | 
				
			||||||
 | 
					                    $repository->orderBy($item->field, $item->order);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $field = $relation->key;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $values = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $key = is_object($relation->foreignKey) ? $relation->foreignKey : $baseEntity::field($relation->foreignKey);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                foreach($collection as $item) {
 | 
				
			||||||
 | 
					                    $values[] = is_callable($field) ? $field($item) : $item->$entityProperty;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $repository->where($key, $values);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                switch( $relationType ) {
 | 
				
			||||||
 | 
					                    case 'onetoone':
 | 
				
			||||||
 | 
					                        $results = call_user_func([ $repository, "loadOne" ]);
 | 
				
			||||||
 | 
					                        $item->$name = $results ?: new $baseEntity();
 | 
				
			||||||
 | 
					                        
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                        
 | 
				
			||||||
 | 
					                    case 'onetomany':
 | 
				
			||||||
 | 
					                        $results = call_user_func([ $repository, $relation->function ]);
 | 
				
			||||||
 | 
					                        
 | 
				
			||||||
 | 
					                        foreach($collection as $item) {
 | 
				
			||||||
 | 
					                            $item->$name = $baseEntity::entityCollection();
 | 
				
			||||||
 | 
					                            $item->$name->mergeWith( $results->filtersCollection(fn($e) => $e->$property === $item->$entityProperty ) );
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    public function truncate(? string $table = null, ? string $alias = null, ? string $schema = null) : self
 | 
					    public function truncate(? string $table = null, ? string $alias = null, ? string $schema = null) : self
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $schema = $schema ?: $this->entityResolver->schemaName();
 | 
					        $schema = $schema ?: $this->entityResolver->schemaName();
 | 
				
			||||||
 | 
				
			|||||||
@ -25,9 +25,9 @@ trait ConditionTrait
 | 
				
			|||||||
        return $this;
 | 
					        return $this;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function where($field, $value, string $operator = Query\Where::OPERATOR_EQUAL) : self
 | 
					    public function where($field, $value, string $operator = Query\Where::OPERATOR_EQUAL, $condition = Query\Where::CONDITION_AND) : self
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->queryBuilder->where($field, $value, $operator, Query\Where::CONDITION_AND);
 | 
					        $this->queryBuilder->where($field, $value, $operator, $condition);
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        return $this;
 | 
					        return $this;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -67,9 +67,9 @@ trait ConditionTrait
 | 
				
			|||||||
        return $this;
 | 
					        return $this;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function having($field, $value, string $operator = Query\Where::OPERATOR_EQUAL) : self
 | 
					    public function having($field, $value, string $operator = Query\Where::OPERATOR_EQUAL, $condition = Query\Where::CONDITION_AND) : self
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->queryBuilder->having($field, $value, $operator, Query\Where::CONDITION_AND);
 | 
					        $this->queryBuilder->having($field, $value, $operator, $condition);
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        return $this;
 | 
					        return $this;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user