diff --git a/src/Bridge/Repository/AbstractEntityRepository.php b/src/Bridge/Repository/AbstractEntityRepository.php index caecaf1..2a1260c 100644 --- a/src/Bridge/Repository/AbstractEntityRepository.php +++ b/src/Bridge/Repository/AbstractEntityRepository.php @@ -57,6 +57,7 @@ abstract class AbstractEntityRepository implements EntityRepositoryInterface private array $tableAliases = []; private array $additionalFieldsToSelect = []; + private array $joins = []; public function __construct( private string $entityClassName, @@ -138,6 +139,8 @@ public function updateSingleField(int $id, string $field, mixed $newValue): bool public function createFindByQueryBuilder(array $criteria, ?array $orderBy): QueryBuilder { + $this->resetProperties(); + $normalizedCriteria = $this->normalizeCriteria($criteria); $this->tableAliases['p'] = $this->getEntityBaseFields(); @@ -531,6 +534,10 @@ private function createNestedCriteria(QueryBuilder $queryBuilder, NestedConditio private function joinSelfMetaTable(QueryBuilder $queryBuilder, bool $incrementIfNecessary = false): string { $applyJoin = function (QueryBuilder $queryBuilder, string $alias): void { + if (in_array($alias, $this->joins, true)) { + return; + } + if (!array_key_exists($alias, $this->tableAliases)) { $this->tableAliases[$alias] = []; } @@ -541,6 +548,8 @@ private function joinSelfMetaTable(QueryBuilder $queryBuilder, bool $incrementIf $alias, sprintf('p.%s = %s.%s', static::TABLE_IDENTIFIER, $alias, static::TABLE_META_IDENTIFIER), ); + + $this->registerJoin($alias); }; static $aliasNumber = 1; @@ -569,7 +578,7 @@ private function hasJoin(QueryBuilder $queryBuilder, string $joinAlias): bool return count(array_filter($matches, static fn (array $match) => $match[2] === $joinAlias)) > 0; } } catch (QueryException) { - return false; + return array_key_exists($joinAlias, $this->joins); } return false; @@ -622,6 +631,8 @@ private function createRelationshipCriteria( ->setParameter(sprintf('%s_field', $alias), $condition->getRelationshipFieldName()) ; + $this->registerJoin($alias); + if (!empty($condition->getAlias())) { $trimmedAlias = trim($condition->getAlias(), '_'); @@ -685,6 +696,8 @@ private function createTermRelationshipCriteria( ) ; + $this->registerJoin(["tr_{$aliasNumber}", "tt_{$aliasNumber}", $termTableAlias]); + $prefixedCriteria = $this->getPrefixedCriteriaForTermRelationshipCondition( $condition->getCriteria(), $termTableAlias, @@ -732,6 +745,8 @@ private function createPostRelationshipCriteria( ) ; + $this->registerJoin(["tr_{$aliasNumber}", "p_{$aliasNumber}"]); + $this->additionalFieldsToSelect[] = 'tt.term_taxonomy_id'; $this->addPostMetaJoinForPostRelationshipCondition($queryBuilder, $condition, $aliasNumber); $prefixedCriteria = $this->getPrefixedCriteriaForPostRelationshipCondition($condition, $aliasNumber); @@ -769,6 +784,8 @@ private function addPostMetaJoinForPostRelationshipCondition( sprintf('p_%d.id = pm_%d.%s', $aliasNumber, $aliasNumber, self::TABLE_META_IDENTIFIER), ); + $this->registerJoin($alias); + foreach ($extraFields as $extraField) { $this->tableAliases[$alias][] = property_to_field($extraField); } @@ -825,6 +842,7 @@ private function selectColumns(QueryBuilder $queryBuilder, array $extraFields, S if (in_array($column, $extraFields, true)) { $mappedMetaKey = $this->getMappedMetaKey($column); $selects[] = select_from_eav($column, $mappedMetaKey); + $this->joinSelfMetaTable($queryBuilder); } elseif (str_starts_with($column, 'MAX(')) { $selects[] = $column; $this->joinSelfMetaTable($queryBuilder); @@ -843,4 +861,22 @@ private function selectColumns(QueryBuilder $queryBuilder, array $extraFields, S $queryBuilder->select(...$selects, ...$this->additionalFieldsToSelect); $this->additionalFieldsToSelect = []; } + + private function registerJoin(string|array $alias): void + { + if (is_array($alias)) { + $this->joins = array_merge($this->joins, $alias); + } else { + $this->joins[] = $alias; + } + + $this->joins = array_unique($this->joins); + } + + private function resetProperties(): void + { + $this->tableAliases = []; + $this->additionalFieldsToSelect = []; + $this->joins = []; + } } diff --git a/test/Test/Bridge/Repository/ProductRepositoryTest.php b/test/Test/Bridge/Repository/ProductRepositoryTest.php index c5b2ff1..93581d1 100644 --- a/test/Test/Bridge/Repository/ProductRepositoryTest.php +++ b/test/Test/Bridge/Repository/ProductRepositoryTest.php @@ -552,4 +552,14 @@ public function testOperatorIsNotNullNested(): void self::assertContainsOnlyInstancesOf(Product::class, $products); self::assertEquals([17, 20, 23], array_column($products, 'id')); } + + public function testSelectEntityFieldWithoutQueryingIt(): void + { + $product = $this->repository->findOneBy([ + new SelectColumns(['id', 'sku']), + 'post_title' => 'Hoodie', + ]); + + $this->assertSame('woo-hoodie', $product->sku); + } }