diff --git a/src/Attribute/Property/OrWhere.php b/src/Attribute/Property/OrWhere.php index 568eb9b..877c7cc 100644 --- a/src/Attribute/Property/OrWhere.php +++ b/src/Attribute/Property/OrWhere.php @@ -13,7 +13,7 @@ class OrWhere extends Where { public string $operator = Query\Where::OPERATOR_EQUAL, public string $condition = Query\Where::CONDITION_OR, public string|\Stringable|array|null $fieldValue = null, - public null|array $generateValue = null, + public null|array|\Closure $generateValue = null, ) { parent::__construct($field, $value, $operator, $condition, $fieldValue, $generateValue); } diff --git a/src/Attribute/Property/Where.php b/src/Attribute/Property/Where.php index ce90e21..3dc9f9b 100644 --- a/src/Attribute/Property/Where.php +++ b/src/Attribute/Property/Where.php @@ -13,7 +13,7 @@ class Where { public string $operator = Query\Where::OPERATOR_EQUAL, public string $condition = Query\Where::CONDITION_AND, public string|\Stringable|array|null $fieldValue = null, - public null|array $generateValue = null, + public null|array|\Closure $generateValue = null, ) { $this->field = Attribute::handleArrayField($field); $this->fieldValue = Attribute::handleArrayField($fieldValue); @@ -29,6 +29,9 @@ class Where { throw new \Exception(sprintf("Could not generate value from non-instanciated entity for field %s.", (string) $this->field)); } } + elseif ($this->fieldValue && $entity) { + throw new \Exception(sprintf("Field value, from %s, could not be included in query since the entity is already loaded; it is meant to be used with a OneToOne relation loaded within a join.", (string) $this->fieldValue)); + } return $this->fieldValue ?? $this->value; } diff --git a/src/Entity/InformationSchema/Table.php b/src/Entity/InformationSchema/Table.php index 17c306b..89b9875 100644 --- a/src/Entity/InformationSchema/Table.php +++ b/src/Entity/InformationSchema/Table.php @@ -5,7 +5,7 @@ namespace Ulmus\Entity\InformationSchema; use Ulmus\EntityCollection, Ulmus\Entity\Field\Datetime; -use Ulmus\{Attribute\Obj\Table as TableObj}; +use Ulmus\{Attribute\Obj\Table as TableObj, Entity\EntityInterface}; use Ulmus\Attribute\Property\{Field, Filter, FilterJoin, Relation, Join, Virtual, Where}; #[TableObj(name: "tables", database: "information_schema")] @@ -83,6 +83,12 @@ class Table public ? string $temporary; #[Relation(type: "oneToMany", key: "name", foreignKey: [ Column::class, 'tableName' ], entity: Column::class)] - #[Where('TABLE_SCHEMA', fieldValue: [ Column::class, 'tableSchema' ])] + #[Where(field: 'TABLE_SCHEMA', generateValue: [ Table::class, 'getSchema' ])] public EntityCollection $columns; + + # Awaiting PHP 8.5 https://wiki.php.net/rfc/closures_in_const_expr + public static function getSchema(Table $entity) : string + { + return $entity->schema; + } } \ No newline at end of file diff --git a/src/Entity/Mysql/Table.php b/src/Entity/Mysql/Table.php index 05f8c1e..3683ada 100644 --- a/src/Entity/Mysql/Table.php +++ b/src/Entity/Mysql/Table.php @@ -12,6 +12,6 @@ use Ulmus\Attribute\Property\{Field, Filter, FilterJoin, Relation, Join, Virtual class Table extends \Ulmus\Entity\InformationSchema\Table { #[Relation(type: "oneToMany", key: "name", foreignKey: [ Column::class, 'tableName' ], entity: Column::class)] - #[Where('TABLE_SCHEMA', fieldValue: [ Column::class, 'tableSchema' ])] + #[Where('TABLE_SCHEMA', generateValue: [ Table::class, 'getSchema' ])] public EntityCollection $columns; } \ No newline at end of file diff --git a/src/Repository.php b/src/Repository.php index 05fc893..30e5a97 100644 --- a/src/Repository.php +++ b/src/Repository.php @@ -476,23 +476,23 @@ class Repository implements RepositoryInterface $foreignKey = is_string($attribute->foreignKey) ? $entity::field($attribute->foreignKey, $alias) : $attribute->foreignKey; $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, [ Where::class ]) as $condition) { - if ( ! is_object($condition->field) ) { - $field = $this->entityClass::field($condition->field); - } - else { - $field = clone $condition->field; - } + if ( ! in_array(WithOptionEnum::SkipJoinWhere, $options)) { + foreach($this->entityResolver->searchFieldAnnotationList($item, [ Where::class ]) as $condition) { + if ( ! is_object($condition->field) ) { + $field = $this->entityClass::field($condition->field); + } + else { + $field = clone $condition->field; + } - # Adding directly - if ( $field->entityClass === $entity ) { - $field->alias = $alias; + # Adding directly + if ( $field->entityClass === $entity ) { + $field->alias = $alias; - $join->where(is_object($field) ? $field : $entity::field($field, $alias), $condition->getValue(), $condition->operator); + $join->where(is_object($field) ? $field : $entity::field($field, $alias), $condition->getValue(), $condition->operator); + } } } - } if ( ! in_array(WithOptionEnum::SkipJoinFilter, $options) ) { foreach ($this->entityResolver->searchFieldAnnotationList($item, [ FilterJoin::class ]) as $filter) { @@ -594,7 +594,7 @@ class Repository implements RepositoryInterface foreach ($where as $condition) { # $repository->where($condition->field, is_callable($condition->value) ? call_user_func_array($condition->value, [$this]) : $condition->getValue(), $condition->operator, $condition->condition); - $repository->where($condition->field, $condition->getValue($this), $condition->operator, $condition->condition); + $repository->where($condition->field, $condition->getValue(/* why repository sent here ??? $this */), $condition->operator, $condition->condition); } foreach ($order as $item) {