Nous allons apprendre à retourner un résultat à partir d'une recherche en utilisant Doctrine dans Symfony.
Un exemple complet et fonctionnel de ce qui sera abordé ici est disponible sur mon projet Github Symfony Basics.
Création de la fonction
Pour parvenir à créer ce dont nous avons besoin, tout va se dérouler dans le repository de notre choix. La première chose à faire est de créer une nouvelle fonction qui sera findBySearchQuery ici :
public function findBySearchQuery(): array
{
}
Dans cette fonction, nous allons ajouter la prise en compte de la requête que l'on va nommer query et retourner un array :
public function findBySearchQuery(string $query): array
{
return $this->createQueryBuilder('p')
->getQuery()
->getResult();
}
Cette fonction n'utilise pas encore la requête, elle se contente d'envoyer toutes les entités disponibles, il va falloir découper la requête en termes de recherches, pour cela nous allons créer une seconde fonction extractSearchTerms et l'utiliser dans findBySearchQuery.
...
use function Symfony\Component\String\u;
public function findBySearchQuery(string $query): array
{
$searchTerms = $this->extractSearchTerms($query);
return $this->createQueryBuilder('p')
->getQuery()
->getResult();
}
private function extractSearchTerms(string $searchQuery): array
{
$terms = array_unique(u($searchQuery)->replaceMatches('/[[:space:]]+/', ' ')->trim()->split(' '));
return $terms;
}
Maintenant, il faut prendre en compte chacun des termes de la recherche pour ne retourner que ce qui nous interesse :
public function findBySearchQuery(string $query): array
{
$searchTerms = $this->extractSearchTerms($query);
$queryBuilder = $this->createQueryBuilder('p');
foreach ($searchTerms as $key => $term) {
$queryBuilder
->andWhere('p.title LIKE :t_'.$key)
->setParameter('t_'.$key, '%'.$term.'%');
}
$result = $queryBuilder
->getQuery()
->getResult();
return $result;
}
La dernière chose qu'il nous reste à faire est de prendre en compte le fait que la requête peut ne rien contenir, nous allons afficher toutes les entités si c'est le cas :
public function findBySearchQuery(string $query): array
{
$searchTerms = $this->extractSearchTerms($query);
$queryBuilder = $this->createQueryBuilder('p');
if (0 === \count($searchTerms)) {
return $queryBuilder
->getQuery()
->getResult();
}
foreach ($searchTerms as $key => $term) {
$queryBuilder
->andWhere('p.title LIKE :t_'.$key)
->setParameter('t_'.$key, '%'.$term.'%');
}
$result = $queryBuilder
->getQuery()
->getResult();
return $result;
}
Tout est prêt il ne reste plus qu'à utiliser et modifier ce que nous venons de voir selon nos besoins.