<?php
declare(strict_types=1);
/*
* Copyright (C) Office National de Publication et de Communication - All Rights Reserved
*
* Unauthorized copying of this file, via any medium is strictly prohibited by law
* This file is proprietary and confidential
*/
namespace App\Repository;
use App\Entity\Ville;
use App\Entity\Region;
use App\Service\Tools;
use Doctrine\ORM\Query;
use App\Entity\Departement;
use App\Common\LieuInterface;
use App\Entity\AncienneRegion;
use App\Repository\Helper\CachedTrait;
use Doctrine\Persistence\ManagerRegistry;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
/**
* @method null|Ville find($id, $lockMode = null, $lockVersion = null)
* @method null|Ville findOneBy(array $criteria, array $orderBy = null)
* @method Ville[] findAll()
* @method Ville[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
final class VilleRepository extends ServiceEntityRepository
{
use CachedTrait;
private const CACHE_LIFETIME = 60;
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Ville::class);
}
public function createQueryBuilder($alias, $indexBy = null)
{
return parent::createQueryBuilder($alias, $indexBy)
->leftJoin("${alias}.coordonnees", 'coordonnees')
->addSelect('coordonnees');
}
public function findImportantes()
{
return $this->findBy([
'id' => [
'20004', // Ajaccio
'80021', // Aimens
'25056', // Besançon
'33063', // Bordeaux
'14118', // Caen
'51108', // Chalons-en-Champagne
'63113', // Clermont-Ferrand
'21231', // Dijon
'59350', // Lille
'87085', // Limoges
'69300', // Lyon
'13200', // Marseille
'57463', // Metz
'34172', // Montpellier
'44109', // Nantes
'45234', // Orléans
'75100', // Paris
'86194', // Poitiers
'35238', // Rennes
'76540', // Rouen
'67482', // Strasbourg
'31555', // Toulouse
],
], ['libelle' => 'ASC']);
}
public function findRelatifsAuLieu(LieuInterface $lieu, ?string $onglet = null, ?array $idsVilleContexte = null): array
{
$queryBuilder = $this->createQueryBuilder('v');
$queryBuilder
->orderBy('v.libelle', 'ASC')
->andWhere($queryBuilder->expr()->isNotNull('v.libelle'));
// ->setMaxResults(7000);
// Force $lieu du type ville devenir un département
if ($lieu instanceof Ville) {
$lieu = $lieu->getDepartement();
}
if ($lieu instanceof Departement) {
$queryBuilder
->andWhere($queryBuilder->expr()->eq('v.departement', ':departement'))
->setParameter('departement', $lieu->getId());
}
if ($lieu instanceof AncienneRegion) {
$queryBuilder
->leftJoin('v.departement', 'd')
->andWhere($queryBuilder->expr()->eq('d.ancienneRegion', ':ancienneRegion'))
->setParameter('ancienneRegion', $lieu);
}
if ($lieu instanceof Region) {
$queryBuilder
->leftJoin('v.departement', 'd')
->leftJoin('d.ancienneRegion', 'ac')
->andWhere($queryBuilder->expr()->eq('ac.region', ':region'))
->setParameter('region', $lieu);
}
if ($onglet && in_array($onglet, Tools::getOngletsList())) {
$queryBuilder
->andWhere($queryBuilder->expr()->like('v.onglets', ':onglet'))
->setParameter('onglet', sprintf('%%%s%%', $onglet));
}
if (!is_null($idsVilleContexte)) {
$queryBuilder
->andWhere($queryBuilder->expr()->in('v.id', ':idsVilleContexte'))
->setParameter('idsVilleContexte', $idsVilleContexte);
}
return $queryBuilder
->getQuery()
->setHint(Query::HINT_FORCE_PARTIAL_LOAD, true)
->enableResultCache(3600)
->getResult();
}
public function findAllByTerm(string $term, int $max): array
{
$term = trim($term);
if (empty($term)) {
return [];
}
$villes = $this->findAllByTermLike($term.'%', $max, []);
if (\count($villes) < $max) {
$newMax = $max - \count($villes);
$notIn = [];
foreach ($villes as $ville) {
$notIn[] = $ville->getId();
}
$villes = array_merge(
$villes,
$this->findAllByTermLike('%'.$term.'%', $newMax, $notIn)
);
}
return $villes;
}
public function getSlugs(): array
{
$list = $this
->createQueryBuilder('v')
->select('v.slug')
->getQuery()
->getResult();
return array_map(static function ($value) {
return $value['slug'];
}, $list);
}
private function findAllByTermLike(string $term, int $max, array $notIn): array
{
$term = trim($term);
$term = str_replace([' ', '-'], '%', $term);
if (empty($term)) {
return [];
}
$queryBuilder = $this->createQueryBuilder('v');
$queryBuilder
->orderBy('v.libelle', 'ASC')
->andWhere($queryBuilder->expr()->isNotNull('v.libelle'))
->andWhere($queryBuilder->expr()->isNotNull('v.slug'))
->andWhere(
$queryBuilder->expr()->orX(
$queryBuilder->expr()->like('v.libelle', ':term'),
$queryBuilder->expr()->like('v.codePostal', ':term')
)
)
->setParameter('term', $term);
if (!empty($notIn)) {
$queryBuilder->andWhere($queryBuilder->expr()->notIn('v.id', $notIn));
}
return $queryBuilder
->setMaxResults($max)
->getQuery()
->setHint(Query::HINT_FORCE_PARTIAL_LOAD, true)
->useResultCache(true, self::CACHE_LIFETIME)
->getResult();
}
public function findAllByEtablissement(): array
{
$queryBuilder = $this->createQueryBuilder('v');
return $queryBuilder
->leftJoin('v.departement', 'd')
->leftJoin('d.etablissements', 'e')
->addOrderBy('v.libelle', 'ASC')
->Where("e.ville IS NOT NULL")
->getQuery()
->setHint(Query::HINT_FORCE_PARTIAL_LOAD, true)
->useResultCache(true, self::CACHE_LIFETIME)
->getResult();
}
}