fix(fournisseurs) : ConstructeurSearchFilter utilise EXISTS subquery au lieu de LEFT JOIN

Le LEFT JOIN sur telephones causait une erreur PostgreSQL 'column must appear in GROUP BY' parce que Doctrine sélectionnait aussi les colonnes des téléphones joints. EXISTS subquery corrélée évite la duplication de lignes sans introduire de GROUP BY.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Matthieu
2026-05-13 10:49:43 +02:00
parent d3f269452c
commit a0c4597de0

View File

@@ -7,6 +7,7 @@ namespace App\Filter;
use ApiPlatform\Doctrine\Orm\Filter\AbstractFilter;
use ApiPlatform\Doctrine\Orm\Util\QueryNameGeneratorInterface;
use ApiPlatform\Metadata\Operation;
use App\Entity\ConstructeurTelephone;
use Doctrine\ORM\QueryBuilder;
/**
@@ -38,22 +39,27 @@ final class ConstructeurSearchFilter extends AbstractFilter
}
$alias = $queryBuilder->getRootAliases()[0];
$telAlias = $queryNameGenerator->generateJoinAlias('telephones');
$telAlias = $queryNameGenerator->generateJoinAlias('phoneSearch');
$paramName = $queryNameGenerator->generateParameterName('search');
$likePattern = '%'.mb_strtolower(trim($value)).'%';
$em = $queryBuilder->getEntityManager();
$phoneSubQuery = $em->createQueryBuilder()
->select('1')
->from(ConstructeurTelephone::class, $telAlias)
->where(sprintf('%1$s.constructeur = %2$s', $telAlias, $alias))
->andWhere(sprintf('LOWER(%s.numero) LIKE :%s', $telAlias, $paramName))
->getDQL()
;
$queryBuilder
->leftJoin(sprintf('%s.telephones', $alias), $telAlias)
->andWhere(sprintf(
'LOWER(%1$s.name) LIKE :%4$s OR LOWER(%1$s.email) LIKE :%4$s OR LOWER(%2$s.numero) LIKE :%4$s',
'LOWER(%1$s.name) LIKE :%2$s OR LOWER(%1$s.email) LIKE :%2$s OR EXISTS (%3$s)',
$alias,
$telAlias,
'',
$paramName,
$phoneSubQuery,
))
->setParameter($paramName, $likePattern)
;
$queryBuilder->groupBy(sprintf('%s.id', $alias));
}
}