src/Service/Top100ProfilesService.php line 111

Open in your IDE?
  1. <?php
  2. namespace App\Service;
  3. use App\Dto\Top100\Top100ProfileQueryByIdsDTO;
  4. use App\Dto\Top100\Top100ProfileQueryRandomDTO;
  5. use App\Entity\Location\City;
  6. use App\Entity\Profile\Genders;
  7. use App\Repository\ProfileCtrRepository;
  8. use App\Service\Top100\Top100ProfileQueryService;
  9. use App\Specification\Profile\ProfileIdNotIn;
  10. use App\Specification\Profile\ProfileIsApproved;
  11. use Psr\Cache\CacheItemPoolInterface;
  12. class Top100ProfilesService
  13. {
  14.     public const LIMIT 100;
  15.     public const CACHE_LIMIT 200;
  16.     public const GENDERS_DEFAULT = [Genders::FEMALE];
  17.     public function __construct(
  18.         private ProfileCtrRepository $profileCtrRepository,
  19.         private Top100ProfileQueryService $profileQueryService,
  20.         private CacheItemPoolInterface $cache,
  21.     ) {}
  22.     public function getCachedProfileIds(City $city): array
  23.     {
  24.         $cacheKey $this->getCacheKey($city);
  25.         $cacheItem $this->cache->getItem($cacheKey);
  26.         if (!$cacheItem->isHit()) {
  27.             return [];
  28.         }
  29.         $profileIds $cacheItem->get();
  30.         return is_array($profileIds) ? $profileIds : [];
  31.     }
  32.     public function refreshProfileIdsCache(City $city): array
  33.     {
  34.         $cacheKey $this->getCacheKey($city);
  35.         $profileIds $this->buildProfileIds($city);
  36.         $cacheItem $this->cache->getItem($cacheKey);
  37.         $cacheItem->set($profileIds);
  38.         $this->cache->save($cacheItem);
  39.         return $profileIds;
  40.     }
  41.     private function buildProfileIds(City $city): array
  42.     {
  43.         $dateStart = new \DateTimeImmutable('-30 days');
  44.         $rankedIds $this->profileCtrRepository->topVisitedApprovedProfileIdsInCity($city$dateStartself::CACHE_LIMIT);
  45.        
  46.         $rankedProfiles = empty($rankedIds)
  47.             ? []
  48.             : $this->profileQueryService->getActiveProfilesByIds(
  49.                 new Top100ProfileQueryByIdsDTO(
  50.                     city$city,
  51.                     ids$rankedIds,
  52.                     filters: [new ProfileIsApproved()],
  53.                     gendersself::GENDERS_DEFAULT,
  54.                     limitself::CACHE_LIMIT,
  55.                 )
  56.             );
  57.         
  58.         $ranked array_map(static fn($profile) => $profile->id$rankedProfiles);
  59.         if (count($ranked) >= self::CACHE_LIMIT) {
  60.             return array_slice($ranked0self::CACHE_LIMIT);
  61.         }
  62.         $toFill self::CACHE_LIMIT count($ranked);
  63.         $randomFilters = [new ProfileIsApproved()];
  64.         if (!empty($ranked)) {
  65.             $randomFilters[] = new ProfileIdNotIn($ranked);
  66.         }
  67.         $randomDto = new Top100ProfileQueryRandomDTO(
  68.             city$city,
  69.             filters$randomFilters,
  70.             gendersself::GENDERS_DEFAULT,
  71.             limit$toFill,
  72.         );
  73.        
  74.         $randomApproved $this->profileQueryService->getRandomProfiles($randomDto);
  75.         
  76.         $randomIds array_map(static fn($profile) => $profile->id$randomApproved);
  77.         return array_merge($ranked$randomIds);
  78.     }
  79.     private function getCacheKey(City $city): string
  80.     {
  81.         return sprintf('listing.top_100.profile_ids.city.%d'$city->getId());
  82.     }
  83.     
  84.     public function getSortedProfilesByVisits(City $city): \Porpaginas\Page
  85.     {
  86.         $rankedIds $this->getCachedProfileIds($city);
  87.         $rankedProfiles $this->profileQueryService->getActiveProfilesByIds(
  88.             new Top100ProfileQueryByIdsDTO(
  89.                 city$city,
  90.                 ids$rankedIds,
  91.                 filters: [new ProfileIsApproved()],
  92.                 gendersself::GENDERS_DEFAULT,
  93.                 limitself::LIMIT,
  94.             )
  95.         );
  96.         if (count($rankedProfiles) < self::LIMIT) {
  97.             $toFill self::LIMIT count($rankedProfiles);
  98.             $rankedProfileIds array_map(static fn($profile) => $profile->id$rankedProfiles);
  99.             $randomFilters = [new ProfileIsApproved()];
  100.             if (!empty($rankedProfileIds)) {
  101.                 $randomFilters[] = new ProfileIdNotIn($rankedProfileIds);
  102.             }
  103.             $randomApproved $this->profileQueryService->getRandomProfiles(
  104.                 new Top100ProfileQueryRandomDTO(
  105.                     city$city,
  106.                     filters$randomFilters,
  107.                     gendersself::GENDERS_DEFAULT,
  108.                     limit$toFill,
  109.                 )
  110.             );
  111.             $rankedProfiles array_merge($rankedProfiles$randomApproved);
  112.         }
  113.         return $this->profileQueryService->createFakePageFromProfiles(count($rankedProfiles), $rankedProfiles);
  114.     }
  115. }