src/Service/Sidebar.php line 131

Open in your IDE?
  1. <?php
  2. namespace App\Service;
  3. use App\Entity\Location\City;
  4. use App\Entity\Profile\Genders;
  5. use App\Entity\Profile\Profile;
  6. use App\Entity\Sales\PaidPlacementPrice;
  7. use App\Entity\Sales\Profile\SidebarPlacement;
  8. use App\Entity\Sales\SidebarPlacementType;
  9. use App\Entity\Saloon\Saloon;
  10. use App\Event\Profile\ProfilesShownEvent;
  11. use App\Repository\ProfileSidebarPlacementRepository;
  12. use App\Repository\SaloonSidebarPlacementRepository;
  13. use App\Repository\SidebarPlacementRepository;
  14. use Carbon\Carbon;
  15. use Carbon\CarbonImmutable;
  16. use Doctrine\ORM\EntityManagerInterface;
  17. use Psr\Cache\CacheItemPoolInterface;
  18. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  19. use Symfony\Contracts\Cache\ItemInterface;
  20. class Sidebar
  21. {
  22.     CONST MINUTES_TO_BE_NEW 2;
  23.     public function __construct(
  24.         private EntityManagerInterface $entityManager,
  25.         private ProfileSidebarPlacementRepository $profileSidebarPlacementRepository,
  26.         private SaloonSidebarPlacementRepository $saloonSidebarPlacementRepository,
  27.         private SidebarPlacementRepository $sidebarPlacementRepository,
  28.         private CacheItemPoolInterface $sidebarNewCheckCoolDownCache,
  29.         private EventDispatcherInterface $eventDispatcher
  30.     ) {}
  31.     public function doPlaceProfileOnSidebar(Profile $profileSidebarPlacementType $placementTypePaidPlacementPrice $placementPrice\DateTimeImmutable $placedAt\DateTimeImmutable $placedUntil): void
  32.     {
  33.         if(false == $placementType->isVip() && false == $placementType->isUltraVip()) {
  34.             throw new \DomainException('Must be vip or ultra vip placement');
  35.         }
  36.         if($placementType->isVip() || $placementType->isUltraVip()) {
  37.             $creationMethod SidebarPlacementType::getCamelCaseLabel($placementType->getValue());
  38.             $sidebarPlacement SidebarPlacement::$creationMethod($profile$placementPrice$placedAt$placedUntil);
  39.             $this->entityManager->persist($sidebarPlacement);
  40.         }
  41.     }
  42.     public function deleteProfileFromSidebar(Profile $profile): void
  43.     {
  44.         $sidebarPlacement $this->profileSidebarPlacementRepository->getPlacementByProfile($profile);
  45.         if($sidebarPlacement) {
  46.             $this->entityManager->remove($sidebarPlacement);
  47.         }
  48.     }
  49.     public function prolongProfilePlacement(Profile $profileCarbonImmutable $nextHour): void
  50.     {
  51.         $sidebarPlacement $this->profileSidebarPlacementRepository->getPlacementByProfile($profile);
  52.         if($sidebarPlacement) {
  53.             $sidebarPlacement->prolong($nextHour);
  54.         }
  55.     }
  56.     public function doPlaceSaloonOnSidebar(Saloon $saloonSidebarPlacementType $placementTypePaidPlacementPrice $placementPrice\DateTimeImmutable $placedAt\DateTimeImmutable $placedUntil): void
  57.     {
  58.         if(false == $placementType->isVip() && false == $placementType->isUltraVip()) {
  59.             throw new \DomainException('Must be vip or ultra vip placement');
  60.         }
  61.         if($placementType->isVip() || $placementType->isUltraVip()) {
  62.             $creationMethod SidebarPlacementType::getCamelCaseLabel($placementType->getValue());
  63.             $sidebarPlacement \App\Entity\Sales\Saloon\SidebarPlacement::$creationMethod($saloon$placementPrice$placedAt$placedUntil);
  64.             $this->entityManager->persist($sidebarPlacement);
  65.         }
  66.     }
  67.     public function deleteSaloonFromSidebar(Saloon $saloon): void
  68.     {
  69.         $sidebarPlacement $this->saloonSidebarPlacementRepository->getPlacementBySaloon($saloon);
  70.         if($sidebarPlacement) {
  71.             $this->entityManager->remove($sidebarPlacement);
  72.         }
  73.     }
  74.     public function prolongSaloonPlacement(Saloon $saloonCarbonImmutable $nextHour): void
  75.     {
  76.         $sidebarPlacement $this->saloonSidebarPlacementRepository->getPlacementBySaloon($saloon);
  77.         if($sidebarPlacement) {
  78.             $sidebarPlacement->prolong($nextHour);
  79.         }
  80.     }
  81.     //////////////////////////////////
  82.     /// ROTATION
  83.     //////////////////////////////////
  84.     protected function checkOutdatedNew(City $cityint $type, array $genders = [Genders::FEMALE], array $gendersToUpdate = [Genders::FEMALE]): void
  85.     {
  86.         //максимальное кол-во показов по городу
  87.         $maxShowsByCity $this->sidebarPlacementRepository->getMaxShowsForOldPlacementsByTypeInCity($city$type/*, $genders*/);
  88.         $date Carbon::now();
  89.         $date->modify(sprintf('-%s minutes'self::MINUTES_TO_BE_NEW));
  90.         $this->sidebarPlacementRepository->updateNewPlacementsByTypeOlderThanInCity($city$type$date$maxShowsByCity$gendersToUpdate);
  91. //        $new = $this->sidebarPlacementRepository->getNewPlacementsByTypeOlderThanInCity($city, $type, $date, $maxShowsByCity, $genders);
  92. //        array_map(function(\App\Entity\Sales\SidebarPlacement $placement) use ($maxShowsByCity) {
  93. //            //"новым", которые перешли по сроку в "не новые", ставим кол-во просмотров макс. по городу + просмотры самого плейсмента
  94. //            $placement->setIsNew(false);
  95. //            $placement->setShows($placement->getShows() + $maxShowsByCity);
  96. //        }, $new);
  97.         $this->entityManager->flush();
  98.     }
  99.     protected function processShowOnPlacementsByTypeExcluding(City $cityint $typeint $count, array $exclude, array $genders = [Genders::FEMALE], bool $onlyProfile falsebool $onlyMasseur falsebool $onlySaloon false): array
  100.     {
  101.         $placements $this->sidebarPlacementRepository->getPlacementsOrderedByShowsExcluding($city$type$exclude$count$genders$onlyProfile$onlyMasseur$onlySaloon);
  102.         array_map(function(\App\Entity\Sales\SidebarPlacement $placement): void {
  103.             $placement->show();
  104.         }, $placements);
  105.         $this->entityManager->flush();
  106.         return $placements;
  107.     }
  108.     public function getPlacementsToShow(City $cityint $typeint $count, array $exclude, array $genders = [Genders::FEMALE], bool $onlyProfile falsebool $onlyMasseur falsebool $onlySaloon false): array
  109.     {
  110.         $coolDownKey 'cool_down_'.$city->getId().'_'.$type.'_'.implode($genders);
  111.         $this->sidebarNewCheckCoolDownCache->get($coolDownKey, function (ItemInterface $item) use ($city$type$genders$coolDownKey): int {
  112.             $this->checkOutdatedNew($city$type$genders$genders);
  113.             return 1;
  114.         });
  115.         $placements $this->processShowOnPlacementsByTypeExcluding($city$type$count$exclude$genders$onlyProfile$onlyMasseur$onlySaloon);
  116.         $new = []; $old = [];
  117.         foreach ($placements as $placement) {
  118.             /** @var \App\Entity\Sales\SidebarPlacement $placement */
  119.             $placement->isNew()
  120.                 ? $new[] = $placement
  121.                 $old[] = $placement;
  122.         }
  123.         shuffle($new);
  124.         shuffle($old);
  125.         $placements array_merge($new$old);
  126.         $profileIds = [];
  127.         foreach ($placements as $placement) {
  128.             if($placement instanceof SidebarPlacement)
  129.                 $profileIds[] = $placement->getProfile()->getId();
  130.         }
  131.         $this->eventDispatcher->dispatch(new ProfilesShownEvent($profileIds'sidebar'), ProfilesShownEvent::NAME);
  132.         return $placements;
  133.     }
  134. }