src/Repository/CentreRepository.php line 66

Open in your IDE?
  1. <?php
  2. namespace App\Repository;
  3. use App\Entity\Centre;
  4. use App\Entity\Client;
  5. use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
  6. use Doctrine\Persistence\ManagerRegistry;
  7. /**
  8.  * @method Centre|null find($id, $lockMode = null, $lockVersion = null)
  9.  * @method Centre|null findOneBy(array $criteria, array $orderBy = null)
  10.  * @method Centre[]    findAll()
  11.  * @method Centre[]    findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
  12.  */
  13. class CentreRepository extends ServiceEntityRepository
  14. {
  15.     public function __construct(ManagerRegistry $registry)
  16.     {
  17.         parent::__construct($registryCentre::class);
  18.     }
  19.     /**
  20.      * @return Centre[] Returns an array of Centre search
  21.      */
  22.     /*  public function findByCoordonates(float $longitude, float $latitude)
  23.     {
  24.         // gets all the centres in a diameter of 15 km
  25.         $distance = 0.1;
  26.         return $this->createQueryBuilder('c')
  27.             ->where('c.longitude BETWEEN  :min_longitude AND :max_longitude')
  28.             ->andWhere('c.latitude BETWEEN  :min_latitude AND :max_latitude')
  29.             ->setParameter('min_longitude', $longitude - $distance)
  30.             ->setParameter('max_longitude', $longitude + $distance)
  31.             ->setParameter('min_latitude', $latitude - $distance)
  32.             ->setParameter('max_latitude',  $latitude + $distance)
  33.             ->getQuery()
  34.             ->getResult();
  35.     }*/
  36.     public function findByCoordonates(float $longitudefloat $latitude$page 1$limit 10)
  37.     {
  38.         $distance 0.4;
  39.         $qb $this->createQueryBuilder('c');
  40.         $qb->select('c')
  41.             ->addSelect('(
  42.            (c.longitude - :longitude) * (c.longitude - :longitude) +
  43.            (c.latitude - :latitude) * (c.latitude - :latitude)
  44.        ) AS HIDDEN distance')
  45.             ->setParameter('longitude'$longitude)
  46.             ->setParameter('latitude'$latitude)
  47.             ->andWhere('c.longitude BETWEEN :min_longitude AND :max_longitude')
  48.             ->andWhere('c.latitude BETWEEN :min_latitude AND :max_latitude')
  49.             ->setParameter('min_longitude'$longitude $distance)
  50.             ->setParameter('max_longitude'$longitude $distance)
  51.             ->setParameter('min_latitude'$latitude $distance)
  52.             ->setParameter('max_latitude'$latitude $distance)
  53.             ->orderBy('distance''ASC')
  54.             ->setFirstResult(($page 1) * $limit)
  55.             ->setMaxResults($limit);
  56.         return $qb->getQuery()->getResult();
  57.     }
  58.     public function findByDistance(float $longitudefloat $latitudefloat $radiusKm 2int $limit 4)
  59.     {
  60.         $distanceLat $radiusKm 111;
  61.         $distanceLng $radiusKm / (111 cos(deg2rad($latitude)));
  62.         $qb $this->createQueryBuilder('c');
  63.         $qb->select('c')
  64.             ->andWhere('c.longitude BETWEEN :min_longitude AND :max_longitude')
  65.             ->andWhere('c.latitude BETWEEN :min_latitude AND :max_latitude')
  66.             ->andWhere('c.isValid = :is_valid')
  67.             ->setParameter('min_longitude'$longitude $distanceLng)
  68.             ->setParameter('max_longitude'$longitude $distanceLng)
  69.             ->setParameter('min_latitude'$latitude $distanceLat)
  70.             ->setParameter('max_latitude'$latitude $distanceLat)
  71.             ->setParameter('is_valid'true)
  72.             ->setMaxResults($limit);
  73.         return $qb->getQuery()->getResult();
  74.     }
  75.     public function findByDistanceKm(float $longitudefloat $latitudeint $limit 4)
  76.     {
  77.         $qb $this->createQueryBuilder('c');
  78.         $qb->addSelect(
  79.             '(6371 * acos(cos(radians(:latitude)) * cos(radians(c.latitude)) 
  80.         * cos(radians(c.longitude) - radians(:longitude)) + sin(radians(:latitude)) 
  81.         * sin(radians(c.latitude)))) AS distance'
  82.         )
  83.             ->having('distance <= c.zoneKm')
  84.             ->andWhere('c.isValid = :is_valid')
  85.             ->setParameter('latitude'$latitude)
  86.             ->setParameter('longitude'$longitude)
  87.             ->setParameter('is_valid'true)
  88.             ->orderBy('distance''ASC')
  89.             ->setMaxResults($limit);
  90.         return $qb->getQuery()->getResult();
  91.     }
  92.     /**
  93.      * @return Centre[] Returns an array of Centre search
  94.      */
  95.     public function findByAdress(string $address)
  96.     {
  97.         // gets all the centres in a diameter of 15 km
  98.         return $this->createQueryBuilder('c')
  99.             ->Where('c.address LIKE CONCAT(\'%\',:query,\'%\')')
  100.             ->setParameter('query'$address)
  101.             ->getQuery()
  102.             ->getResult();
  103.     }
  104.     /**
  105.      * @return Centre[] Returns an array of Centre search
  106.      */
  107.     public function findByQuery(String $query)
  108.     {
  109.         return $this->createQueryBuilder('c')
  110.             ->where('c.name LIKE CONCAT(\'%\',:query,\'%\')')
  111.             ->orWhere(':query LIKE CONCAT(\'%\',c.name,\'%\')')
  112.             ->orWhere('c.postale LIKE CONCAT(\'%\',:query,\'%\')')
  113.             ->orWhere(':query LIKE CONCAT(\'%\',c.postale,\'%\')')
  114.             ->orWhere('c.city LIKE CONCAT(\'%\',:query,\'%\')')
  115.             ->orWhere(':query LIKE CONCAT(\'%\',c.city,\'%\')')
  116.             ->orWhere('c.address LIKE CONCAT(\'%\',:query,\'%\')')
  117.             ->orWhere(':query LIKE CONCAT(\'%\',c.address,\'%\')')
  118.             ->setParameter('query'$query)
  119.             ->getQuery()
  120.             ->getResult();
  121.     }
  122.     /**
  123.      * @return int[] Returns an array of Centre search
  124.      */
  125.     public function findByName(string $name)
  126.     {
  127.         $conn $this->getEntityManager()->getConnection();
  128.         $sql '
  129.         SELECT audio_centre.id_centre_id
  130.         FROM audio_centre 
  131.         INNER JOIN audio ON audio.id = audio_centre.id_audio_id 
  132.         WHERE (CONCAT(audio.name," ",audio.lastname)  LIKE :name) OR (CONCAT(audio.lastname," ",audio.name)  LIKE :name)
  133.         UNION
  134.         SELECT centre.id
  135.         FROM centre
  136.         WHERE centre.name LIKE :name;
  137.         ';
  138.         $stmt $conn->prepare($sql);
  139.         $result =  $stmt->executeQuery(['name' => '%' $name '%']);
  140.         // returns the number of audio that have the specified 
  141.         return $result->fetchFirstColumn();
  142.         // gets all the centres in a diameter of 15 km
  143.     }
  144.     /**
  145.      * @return int[] Returns an array of Centre search
  146.      */
  147.     public function findByRdvTaken(Client $client)
  148.     {
  149.         $conn $this->getEntityManager()->getConnection();
  150.         $sql '
  151.         SELECT  centre.id
  152.         FROM centre 
  153.         INNER JOIN rdv ON centre.id = rdv.id_centre_id
  154.         WHERE rdv.id_client_id = :client_id
  155.         ';
  156.         $stmt $conn->prepare($sql);
  157.         $result =   $stmt->executeQuery(['client_id' => $client->getId()]);
  158.         // returns the number of audio that have the specified 
  159.         return $result->fetchFirstColumn();
  160.         // gets all the centres in a diameter of 15 km
  161.     }
  162.     /**
  163.      * @return int  Returns an array of Centre search
  164.      */
  165.     public function centreHasMotif(int $centreIdint $motifId): int
  166.     {
  167.         $conn $this->getEntityManager()->getConnection();
  168.         $sql '
  169.             SELECT COUNT(1) 
  170.             FROM `audio_motif` 
  171.             INNER JOIN audio ON audio.id = audio_motif.id_audio_id 
  172.             INNER JOIN audio_centre ON audio.id = audio_centre.id_audio_id 
  173.             WHERE `id_motif_id` = :motifId AND `id_centre_id`=:centreId;
  174.         ';
  175.         $stmt $conn->prepare($sql);
  176.         $result =  $stmt->executeQuery(['centreId' => $centreId'motifId' => $motifId]);
  177.         // returns the number of audio that have the specified 
  178.         return (int) $result->fetchFirstColumn()[0];
  179.     }
  180.     public function findVisibleCenters(): array
  181.     {
  182.         return $this->createQueryBuilder('c')
  183.             ->andWhere('c.isVisible IS NULL')
  184.             ->getQuery()
  185.             ->getResult();
  186.     }
  187.     // /**
  188.     //  * @return Centre[] Returns an array of Centre objects
  189.     //  */
  190.     /*
  191.     public function findByExampleField($value)
  192.     {
  193.         return $this->createQueryBuilder('c')
  194.             ->andWhere('c.exampleField = :val')
  195.             ->setParameter('val', $value)
  196.             ->orderBy('c.id', 'ASC')
  197.             ->setMaxResults(10)
  198.             ->getQuery()
  199.             ->getResult()
  200.         ;
  201.     }
  202.     */
  203.     /*
  204.     public function findOneBySomeField($value): ?Centre
  205.     {
  206.         return $this->createQueryBuilder('c')
  207.             ->andWhere('c.exampleField = :val')
  208.             ->setParameter('val', $value)
  209.             ->getQuery()
  210.             ->getOneOrNullResult()
  211.         ;
  212.     }
  213.     */
  214.     public function countByPeriod(?\DateTime $from, ?\DateTime $tostring $dateField): int
  215.     {
  216.         $qb $this->createQueryBuilder('e');
  217.         if ($from) {
  218.             $qb->andWhere("e.{$dateField} >= :from")->setParameter('from'$from);
  219.         }
  220.         if ($to) {
  221.             $qb->andWhere("e.{$dateField} <= :to")->setParameter('to'$to);
  222.         }
  223.         return (int) $qb->select('COUNT(e.id)')
  224.             ->getQuery()
  225.             ->getSingleScalarResult();
  226.     }
  227.     public function findByFilters(
  228.         ?string $postalCode,
  229.         ?string $subscriptionType,
  230.         ?string $centerStatus,
  231.         ?string $signupDateFrom,
  232.         ?string $signupDateTo,
  233.         ?array $contractTypes// new
  234.         ?string $city // ← add this
  235.     ): array {
  236.         $qb $this->createQueryBuilder('c');
  237.         if ($postalCode) {
  238.             $qb->andWhere('c.postale = :postalCode')
  239.                 ->setParameter('postalCode'$postalCode);
  240.         }
  241.         if ($centerStatus) {
  242.             switch ($centerStatus) {
  243.                 case 'active':
  244.                     $qb->andWhere('c.isValid = true')
  245.                         ->andWhere('c.isResilied = false')
  246.                         ->andWhere('c.isBlocked = false');
  247.                     break;
  248.                 case 'cancelled':
  249.                     $qb->andWhere('c.isResilied = true');
  250.                     break;
  251.                 case 'blocked':
  252.                     $qb->andWhere('c.isBlocked = true');
  253.                     break;
  254.             }
  255.         }
  256.         if ($signupDateFrom) {
  257.             $from = new \DateTime($signupDateFrom);
  258.             $from->setTime(000);
  259.             $qb->andWhere('c.signupDate >= :from')
  260.                 ->setParameter('from'$from);
  261.         }
  262.         if ($signupDateTo) {
  263.             $to = new \DateTime($signupDateTo);
  264.             $to->setTime(235959);
  265.             $qb->andWhere('c.signupDate <= :to')
  266.                 ->setParameter('to'$to);
  267.         }
  268.         if ($subscriptionType) {
  269.             $qb->join('c.subscription''s'// Assuming 'subscription' is the relation name in Centre entity
  270.                 ->andWhere('s.planInterval = :planInterval')
  271.                 ->setParameter('planInterval'$subscriptionType);
  272.         }
  273.         if ($city) {
  274.             $cities array_map('trim'explode(','$city));
  275.             $qb->andWhere('c.city IN (:cities)')
  276.                 ->setParameter('cities'$cities);
  277.         }
  278.         if ($contractTypes && is_array($contractTypes)) {
  279.             $qb->join('c.specificSubscription''ss'// adjust if different relation
  280.                 ->andWhere('ss.contractCategory IN (:contractTypes)')
  281.                 ->setParameter('contractTypes'$contractTypes);
  282.         }
  283.         return $qb->getQuery()->getResult();
  284.     }
  285.     /**
  286.      * Recherche universelle dans tous les champs pertinents d'un centre avec pagination
  287.      */
  288.     public function searchByQuery(string $queryint $page 1int $limit 20): array
  289.     {
  290.         $qb $this->createQueryBuilder('c');
  291.         // Nettoyer la query
  292.         $cleanQuery trim($query);
  293.         
  294.         // Si la query n'est pas vide, ajouter les conditions de recherche
  295.         if (!empty($cleanQuery)) {
  296.             $searchParam '%' $cleanQuery '%';
  297.             // Rechercher dans tous les champs pertinents
  298.             $qb->where('c.name LIKE :query')
  299.                 ->orWhere('c.city LIKE :query')
  300.                 ->orWhere('c.postale LIKE :query')
  301.                 ->orWhere('c.address LIKE :query')
  302.                 ->orWhere('c.rue LIKE :query')
  303.                 ->orWhere('c.phone LIKE :query')
  304.                 ->orWhere('c.siret LIKE :query')
  305.                 ->orWhere('c.finess LIKE :query')
  306.                 ->setParameter('query'$searchParam);
  307.             // Si c'est un code postal exact (5 chiffres)
  308.             if (preg_match('/^\d{5}$/'$cleanQuery)) {
  309.                 $qb->orWhere('c.postale = :exactPostal')
  310.                     ->setParameter('exactPostal'$cleanQuery);
  311.             }
  312.         }
  313.         // Si la query est vide, on ne met aucune condition WHERE pour récupérer tous les centres
  314.         // Pagination
  315.         $qb->setFirstResult(($page 1) * $limit)
  316.             ->setMaxResults($limit);
  317.         return $qb->getQuery()->getResult();
  318.     }
  319.     /**
  320.      * Compter les résultats de la recherche universelle
  321.      */
  322.     public function countByQuery(string $query): int
  323.     {
  324.         $qb $this->createQueryBuilder('c');
  325.         // Nettoyer la query
  326.         $cleanQuery trim($query);
  327.         
  328.         $qb->select('COUNT(c.id)');
  329.         
  330.         // Si la query n'est pas vide, ajouter les conditions de recherche
  331.         if (!empty($cleanQuery)) {
  332.             $searchParam '%' $cleanQuery '%';
  333.             // Rechercher dans tous les champs pertinents
  334.             $qb->where('c.name LIKE :query')
  335.                 ->orWhere('c.city LIKE :query')
  336.                 ->orWhere('c.postale LIKE :query')
  337.                 ->orWhere('c.address LIKE :query')
  338.                 ->orWhere('c.rue LIKE :query')
  339.                 ->orWhere('c.phone LIKE :query')
  340.                 ->orWhere('c.siret LIKE :query')
  341.                 ->orWhere('c.finess LIKE :query')
  342.                 ->setParameter('query'$searchParam);
  343.             // Si c'est un code postal exact (5 chiffres)
  344.             if (preg_match('/^\d{5}$/'$cleanQuery)) {
  345.                 $qb->orWhere('c.postale = :exactPostal')
  346.                     ->setParameter('exactPostal'$cleanQuery);
  347.             }
  348.         }
  349.         // Si la query est vide, on ne met aucune condition WHERE pour compter tous les centres
  350.         return (int) $qb->getQuery()->getSingleScalarResult();
  351.     }
  352.     /**
  353.      * Recherche géographique avec query optionnelle
  354.      */
  355.     public function searchByGeographyAndQuery(float $latitudefloat $longitudefloat $radiusKm 10, ?string $query nullint $page 1int $limit 20): array
  356.     {
  357.         $qb $this->createQueryBuilder('c');
  358.         // Calcul approximatif des limites géographiques
  359.         // 1 degré de latitude ≈ 111 km
  360.         // 1 degré de longitude varie selon la latitude
  361.         $latDelta $radiusKm 111;
  362.         $lngDelta $radiusKm / (111 cos(deg2rad($latitude)));
  363.         // Recherche par zone géographique approximative
  364.         $qb->select('c')
  365.             ->andWhere('c.longitude BETWEEN :min_longitude AND :max_longitude')
  366.             ->andWhere('c.latitude BETWEEN :min_latitude AND :max_latitude')
  367.             ->setParameter('min_longitude'$longitude $lngDelta)
  368.             ->setParameter('max_longitude'$longitude $lngDelta)
  369.             ->setParameter('min_latitude'$latitude $latDelta)
  370.             ->setParameter('max_latitude'$latitude $latDelta);
  371.         // Ajouter la recherche textuelle si fournie et non vide
  372.         if ($query && trim($query) !== '') {
  373.             $cleanQuery trim($query);
  374.             $searchParam '%' $cleanQuery '%';
  375.             $qb->andWhere(
  376.                 $qb->expr()->orX(
  377.                     'c.name LIKE :query',
  378.                     'c.city LIKE :query',
  379.                     'c.postale LIKE :query',
  380.                     'c.address LIKE :query',
  381.                     'c.rue LIKE :query'
  382.                 )
  383.             )->setParameter('query'$searchParam);
  384.         }
  385.         // Pagination
  386.         $qb->setFirstResult(($page 1) * $limit)
  387.             ->setMaxResults($limit);
  388.         return $qb->getQuery()->getResult();
  389.     }
  390.     /**
  391.      * Compter les résultats de la recherche géographique avec query optionnelle
  392.      */
  393.     public function countByGeographyAndQuery(float $latitudefloat $longitudefloat $radiusKm 10, ?string $query null): int
  394.     {
  395.         $qb $this->createQueryBuilder('c');
  396.         // Calcul approximatif des limites géographiques
  397.         $latDelta $radiusKm 111;
  398.         $lngDelta $radiusKm / (111 cos(deg2rad($latitude)));
  399.         // Recherche par zone géographique approximative
  400.         $qb->select('COUNT(c.id)')
  401.             ->andWhere('c.longitude BETWEEN :min_longitude AND :max_longitude')
  402.             ->andWhere('c.latitude BETWEEN :min_latitude AND :max_latitude')
  403.             ->setParameter('min_longitude'$longitude $lngDelta)
  404.             ->setParameter('max_longitude'$longitude $lngDelta)
  405.             ->setParameter('min_latitude'$latitude $latDelta)
  406.             ->setParameter('max_latitude'$latitude $latDelta);
  407.         // Ajouter la recherche textuelle si fournie et non vide
  408.         if ($query && trim($query) !== '') {
  409.             $cleanQuery trim($query);
  410.             $searchParam '%' $cleanQuery '%';
  411.             $qb->andWhere(
  412.                 $qb->expr()->orX(
  413.                     'c.name LIKE :query',
  414.                     'c.city LIKE :query',
  415.                     'c.postale LIKE :query',
  416.                     'c.address LIKE :query',
  417.                     'c.rue LIKE :query'
  418.                 )
  419.             )->setParameter('query'$searchParam);
  420.         }
  421.         return (int) $qb->getQuery()->getSingleScalarResult();
  422.     }
  423. }