src/Repository/ShopReviewRepository.php line 55

Open in your IDE?
  1. <?php
  2. namespace App\Repository;
  3. use App\Entity\Shop;
  4. use App\Entity\ShopReview;
  5. use App\Entity\User;
  6. use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
  7. use Doctrine\Persistence\ManagerRegistry;
  8. /**
  9.  * @extends ServiceEntityRepository<ShopReview>
  10.  */
  11. class ShopReviewRepository extends ServiceEntityRepository
  12. {
  13.     public function __construct(ManagerRegistry $registry)
  14.     {
  15.         parent::__construct($registryShopReview::class);
  16.     }
  17.     /**
  18.      * Récupérer les avis d'une boutique
  19.      */
  20.     public function findByShop(Shop $shopbool $onlyVisible true): array
  21.     {
  22.         $qb $this->createQueryBuilder('sr')
  23.             ->where('sr.shop = :shop')
  24.             ->setParameter('shop'$shop)
  25.             ->orderBy('sr.createdAt''DESC');
  26.         if ($onlyVisible) {
  27.             $qb->andWhere('sr.isVisible = :visible')
  28.                ->setParameter('visible'true);
  29.         }
  30.         return $qb->getQuery()->getResult();
  31.     }
  32.     /**
  33.      * Trouver les avis d'un utilisateur
  34.      */
  35.     public function findByUser(User $user): array
  36.     {
  37.         return $this->createQueryBuilder('sr')
  38.             ->where('sr.user = :user')
  39.             ->setParameter('user'$user)
  40.             ->orderBy('sr.createdAt''DESC')
  41.             ->getQuery()
  42.             ->getResult();
  43.     }
  44.     /**
  45.      * Vérifier si un utilisateur a déjà laissé un avis pour une boutique
  46.      */
  47.     public function hasUserReviewedShop(User $userShop $shop): bool
  48.     {
  49.         $result $this->createQueryBuilder('sr')
  50.             ->select('COUNT(sr.id)')
  51.             ->where('sr.user = :user')
  52.             ->andWhere('sr.shop = :shop')
  53.             ->setParameter('user'$user)
  54.             ->setParameter('shop'$shop)
  55.             ->getQuery()
  56.             ->getSingleScalarResult();
  57.         return $result 0;
  58.     }
  59.     /**
  60.      * Obtenir les statistiques d'avis d'une boutique
  61.      */
  62.     public function getShopReviewStats(Shop $shop): array
  63.     {
  64.         $qb $this->createQueryBuilder('sr')
  65.             ->select([
  66.                 'AVG(sr.rating) as averageRating',
  67.                 'COUNT(sr.id) as totalReviews',
  68.                 'SUM(CASE WHEN sr.rating = 5 THEN 1 ELSE 0 END) as fiveStars',
  69.                 'SUM(CASE WHEN sr.rating = 4 THEN 1 ELSE 0 END) as fourStars',
  70.                 'SUM(CASE WHEN sr.rating = 3 THEN 1 ELSE 0 END) as threeStars',
  71.                 'SUM(CASE WHEN sr.rating = 2 THEN 1 ELSE 0 END) as twoStars',
  72.                 'SUM(CASE WHEN sr.rating = 1 THEN 1 ELSE 0 END) as oneStar',
  73.                 'SUM(CASE WHEN sr.isVerified = true THEN 1 ELSE 0 END) as verifiedReviews'
  74.             ])
  75.             ->where('sr.shop = :shop')
  76.             ->andWhere('sr.isVisible = :visible')
  77.             ->setParameter('shop'$shop)
  78.             ->setParameter('visible'true);
  79.         $result $qb->getQuery()->getSingleResult();
  80.         return [
  81.             'averageRating' => round($result['averageRating'] ?? 01),
  82.             'totalReviews' => (int) ($result['totalReviews'] ?? 0),
  83.             'fiveStars' => (int) ($result['fiveStars'] ?? 0),
  84.             'fourStars' => (int) ($result['fourStars'] ?? 0),
  85.             'threeStars' => (int) ($result['threeStars'] ?? 0),
  86.             'twoStars' => (int) ($result['twoStars'] ?? 0),
  87.             'oneStar' => (int) ($result['oneStar'] ?? 0),
  88.             'verifiedReviews' => (int) ($result['verifiedReviews'] ?? 0),
  89.             'positivePercentage' => $this->calculatePositivePercentage($result)
  90.         ];
  91.     }
  92.     /**
  93.      * Calculer le pourcentage d'avis positifs (4-5 étoiles)
  94.      */
  95.     private function calculatePositivePercentage(array $stats): float
  96.     {
  97.         $total $stats['totalReviews'] ?? 0;
  98.         if ($total === 0) {
  99.             return 0;
  100.         }
  101.         $positive = ($stats['fiveStars'] ?? 0) + ($stats['fourStars'] ?? 0);
  102.         return round(($positive $total) * 1001);
  103.     }
  104.     /**
  105.      * Obtenir les avis récents
  106.      */
  107.     public function findRecentReviews(int $limit 10): array
  108.     {
  109.         return $this->createQueryBuilder('sr')
  110.             ->where('sr.isVisible = :visible')
  111.             ->setParameter('visible'true)
  112.             ->orderBy('sr.createdAt''DESC')
  113.             ->setMaxResults($limit)
  114.             ->getQuery()
  115.             ->getResult();
  116.     }
  117.     /**
  118.      * Obtenir les avis par note
  119.      */
  120.     public function findByRating(Shop $shopint $rating): array
  121.     {
  122.         return $this->createQueryBuilder('sr')
  123.             ->where('sr.shop = :shop')
  124.             ->andWhere('sr.rating = :rating')
  125.             ->andWhere('sr.isVisible = :visible')
  126.             ->setParameter('shop'$shop)
  127.             ->setParameter('rating'$rating)
  128.             ->setParameter('visible'true)
  129.             ->orderBy('sr.createdAt''DESC')
  130.             ->getQuery()
  131.             ->getResult();
  132.     }
  133.     /**
  134.      * Obtenir les avis vérifiés uniquement
  135.      */
  136.     public function findVerifiedReviews(Shop $shop): array
  137.     {
  138.         return $this->createQueryBuilder('sr')
  139.             ->where('sr.shop = :shop')
  140.             ->andWhere('sr.isVerified = :verified')
  141.             ->andWhere('sr.isVisible = :visible')
  142.             ->setParameter('shop'$shop)
  143.             ->setParameter('verified'true)
  144.             ->setParameter('visible'true)
  145.             ->orderBy('sr.createdAt''DESC')
  146.             ->getQuery()
  147.             ->getResult();
  148.     }
  149.     /**
  150.      * Rechercher des avis par mot-clé
  151.      */
  152.     public function searchReviews(Shop $shopstring $keyword): array
  153.     {
  154.         return $this->createQueryBuilder('sr')
  155.             ->where('sr.shop = :shop')
  156.             ->andWhere('sr.comment LIKE :keyword')
  157.             ->andWhere('sr.isVisible = :visible')
  158.             ->setParameter('shop'$shop)
  159.             ->setParameter('keyword''%' $keyword '%')
  160.             ->setParameter('visible'true)
  161.             ->orderBy('sr.createdAt''DESC')
  162.             ->getQuery()
  163.             ->getResult();
  164.     }
  165.     /**
  166.      * Obtenir les avis les plus utiles
  167.      */
  168.     public function findMostHelpfulReviews(Shop $shopint $limit 5): array
  169.     {
  170.         return $this->createQueryBuilder('sr')
  171.             ->where('sr.shop = :shop')
  172.             ->andWhere('sr.isVisible = :visible')
  173.             ->setParameter('shop'$shop)
  174.             ->setParameter('visible'true)
  175.             ->orderBy('sr.helpfulCount''DESC')
  176.             ->addOrderBy('sr.createdAt''DESC')
  177.             ->setMaxResults($limit)
  178.             ->getQuery()
  179.             ->getResult();
  180.     }
  181.     /**
  182.      * Obtenir les statistiques globales des avis
  183.      */
  184.     public function getGlobalStats(): array
  185.     {
  186.         $qb $this->createQueryBuilder('sr')
  187.             ->select([
  188.                 'AVG(sr.rating) as averageRating',
  189.                 'COUNT(sr.id) as totalReviews',
  190.                 'COUNT(DISTINCT sr.shop) as shopsWithReviews',
  191.                 'SUM(CASE WHEN sr.isVerified = true THEN 1 ELSE 0 END) as verifiedReviews'
  192.             ])
  193.             ->where('sr.isVisible = :visible')
  194.             ->setParameter('visible'true);
  195.         $result $qb->getQuery()->getSingleResult();
  196.         return [
  197.             'averageRating' => round($result['averageRating'] ?? 01),
  198.             'totalReviews' => (int) ($result['totalReviews'] ?? 0),
  199.             'shopsWithReviews' => (int) ($result['shopsWithReviews'] ?? 0),
  200.             'verifiedReviews' => (int) ($result['verifiedReviews'] ?? 0)
  201.         ];
  202.     }
  203. }