src/Service/Top100ProfilesService.php line 114

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 GENDERS_DEFAULT = [Genders::FEMALE];
  16.     public function __construct(
  17.         private ProfileCtrRepository $profileCtrRepository,
  18.         private Top100ProfileQueryService $profileQueryService,
  19.         private CacheItemPoolInterface $cache,
  20.     ) {}
  21.     public function getCachedProfileIds(City $city): array
  22.     {
  23.         $cacheKey $this->getCacheKey($city);
  24.         $cacheItem $this->cache->getItem($cacheKey);
  25.         if (!$cacheItem->isHit()) {
  26.             return [];
  27.         }
  28.         $profileIds $cacheItem->get();
  29.         return is_array($profileIds) ? $profileIds : [];
  30.     }
  31.     public function refreshProfileIdsCache(City $city): array
  32.     {
  33.         $cacheKey $this->getCacheKey($city);
  34.         $profileIds $this->buildProfileIds($city);
  35.         $cacheItem $this->cache->getItem($cacheKey);
  36.         $cacheItem->set($profileIds);
  37.         $this->cache->save($cacheItem);
  38.         return $profileIds;
  39.     }
  40.     private function buildProfileIds(City $city): array
  41.     {
  42.         $dateStart = new \DateTimeImmutable('-30 days');
  43.         $rankedIds $this->profileCtrRepository->topVisitedApprovedProfileIdsInCity($city$dateStartself::LIMIT);
  44.        
  45.         $rankedProfiles = empty($rankedIds)
  46.             ? []
  47.             : $this->profileQueryService->getActiveProfilesByIds(
  48.                 new Top100ProfileQueryByIdsDTO(
  49.                     city$city,
  50.                     ids$rankedIds,
  51.                     filters: [new ProfileIsApproved()],
  52.                     gendersself::GENDERS_DEFAULT,
  53.                     limitself::LIMIT,
  54.                 )
  55.             );
  56.         
  57.         $ranked array_map(static fn($profile) => $profile->id$rankedProfiles);
  58.         if (count($ranked) >= self::LIMIT) {
  59.             return array_slice($ranked0self::LIMIT);
  60.         }
  61.         $toFill self::LIMIT count($ranked);
  62.         $randomFilters = [new ProfileIsApproved()];
  63.         if (!empty($ranked)) {
  64.             $randomFilters[] = new ProfileIdNotIn($ranked);
  65.         }
  66.         $randomDto = new Top100ProfileQueryRandomDTO(
  67.             city$city,
  68.             filters$randomFilters,
  69.             gendersself::GENDERS_DEFAULT,
  70.             limit$toFill,
  71.         );
  72.        
  73.         $randomApproved $this->profileQueryService->getRandomProfiles($randomDto);
  74.         
  75.         $randomIds array_map(static fn($profile) => $profile->id$randomApproved);
  76.         return array_merge($ranked$randomIds);
  77.     }
  78.     private function getCacheKey(City $city): string
  79.     {
  80.         return sprintf('listing.top_100.profile_ids.city.%d'$city->getId());
  81.     }
  82.     
  83.     public function getSortedProfilesByVisits(City $city): \Porpaginas\Page
  84.     {
  85.         $rankedIds $this->getCachedProfileIds($city);
  86.         
  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.         return $this->profileQueryService->createFakePageFromProfiles(count($rankedProfiles), $rankedProfiles);
  97.     }
  98. }