src/Services/Sale/SaleCacheService.php line 61

Open in your IDE?
  1. <?php
  2. namespace Slivki\Services\Sale;
  3. use Doctrine\ORM\EntityManagerInterface;
  4. use Slivki\Entity\Category;
  5. use Slivki\Entity\GeoLocation;
  6. use Slivki\Entity\Media;
  7. use Slivki\Entity\OfferPayedCategory;
  8. use Slivki\Entity\Sale;
  9. use Slivki\Repository\Category\CategoryRepositoryInterface;
  10. use Slivki\Repository\SaleRepository;
  11. use Slivki\Services\CacheService;
  12. use Slivki\Services\TextCacheService;
  13. use Slivki\Util\SoftCache;
  14. use Slivki\Util\TarantoolCache;
  15. use Symfony\Component\Security\Acl\Exception\Exception;
  16. use Symfony\Component\Serializer\Encoder\JsonEncoder;
  17. use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
  18. use Symfony\Component\Serializer\Serializer;
  19. class SaleCacheService extends CacheService {
  20.     public const SPACE_NAME 'sale';
  21.     private EntityManagerInterface $entityManager;
  22.     private CategoryRepositoryInterface $categoryRepository;
  23.     public function __construct(
  24.         TextCacheService $textCacheService,
  25.         EntityManagerInterface $entityManager,
  26.         CategoryRepositoryInterface $categoryRepository
  27.     ) {
  28.         parent::__construct($textCacheService);
  29.         $this->entityManager $entityManager;
  30.         $this->categoryRepository $categoryRepository;
  31.     }
  32.     public function reloadSaleCache($saleID$reloadMemcache true) {
  33.         $sale null;
  34.         if ($reloadMemcache) {
  35.             $sale $this->entityManager->getRepository(Sale::class)->reloadCacheForSale($saleID);
  36.         } else {
  37.             $sale $this->entityManager->getRepository(Sale::class)->findCached($saleID);
  38.         }
  39.         if (!$sale) {
  40.             $this->deleteSale($saleID);
  41.             return false;
  42.         }
  43.         $tarantool = new TarantoolCache(self::SPACE_NAME);
  44.         $tarantool->set($saleID, [$saleIDjson_encode($sale)]);
  45.         $this->cacheGeoLocations($saleID$sale->getGeoLocations()->toArray());
  46.         return $sale;
  47.     }
  48.     public function getSale($saleID$fullData false) {
  49.         $saleID = (int)$saleID;
  50.         $tarantool = new TarantoolCache(self::SPACE_NAME);
  51.         $data $tarantool->get($saleID);
  52.         if (!$data) {
  53.             return $this->entityManager->getRepository(Sale::class)->getActiveSaleByID($saleID);
  54.         }
  55.         $serializer = new Serializer([new ObjectNormalizer()], [new JsonEncoder()]);
  56.         /** @var Sale $sale */
  57.         $sale $serializer->deserialize($data[0][1], Sale::class, 'json');
  58.         $sale->fromJSON(json_decode($data[0][1]));
  59.         $sale->setIcon($this->entityManager->getRepository(Media::class)->getSaleIconMedia($sale->getID()));
  60.         if ($fullData) {
  61.             $sale->setGeoLocations($this->getGeoLocations(GeoLocation::TYPEGeoLocation::class, $saleID));
  62.         }
  63.         return $sale;
  64.     }
  65.     public function deleteSale($saleID) {
  66.         $tarantool = new TarantoolCache(self::SPACE_NAME);
  67.         $tarantool->callFunction('deleteSale', [(int)$saleID]);
  68.     }
  69.     public function getSalesByCategoryID($categoryID) {
  70.         $softCache = new SoftCache(SaleRepository::CACHE_NAME);
  71.         $saleListByCategory $softCache->get(SaleRepository::ACTIVE_SALES_BY_CATEGORY);
  72.         $tarantool = new TarantoolCache();
  73.         $sales = [];
  74.         if (isset($saleListByCategory[$categoryID])) {
  75.             $salesData $tarantool->callFunction('getSales', [$saleListByCategory[$categoryID]]);
  76.             if (!$salesData || (isset($salesData[0][0][0]) && count($salesData[0][0][0]) == 0)) {
  77.                 return [];
  78.             }
  79.             foreach ($salesData[0][0] as $data) {
  80.                 $sale $this->unserializeSale($data);
  81.                 if ($sale) {
  82.                     $sales[] = $sale;
  83.                 }
  84.             }
  85.         }
  86.         return $sales;
  87.     }
  88.     private function unserializeSale($data) {
  89.         if (count($data) == 0) {
  90.             return false;
  91.         }
  92.         $serializer = new Serializer([new ObjectNormalizer()], [new JsonEncoder()]);
  93.         /** @var Sale $sale */
  94.         $sale $serializer->deserialize($data[0][1], Sale::class, 'json');
  95.         $sale->fromJSON(json_decode($data[0][1]));
  96.         $sale->setGeoLocations($this->getGeoLocations(GeoLocation::TYPEGeoLocation::class, $data[0][0]));
  97.         $sale->setIcon($this->entityManager->getRepository(Media::class)->getSaleIconMedia($sale->getID()));
  98.         $sale->setFlierMedia($this->entityManager->getRepository(Media::class)->getFlierImageMedia($sale->getID()));
  99.         return $sale;
  100.     }
  101.     public function getSalesSorted($categoryID) {
  102.         $saleList $this->getSalesByCategoryID($categoryID);
  103.         $payedPositions $this->entityManager->getRepository(OfferPayedCategory::class)->findBy(
  104.             ['categoryID' => $categoryID], ['position' => 'asc']);
  105.         if ($payedPositions) {
  106.             foreach ($payedPositions as $position) {
  107.                 foreach ($saleList as $key => $sale) {
  108.                     if ($sale->getID() == $position->getEntityID()) {
  109.                         unset($saleList[$key]);
  110.                         array_splice($saleList$position->getPosition() - 10, [$sale]);
  111.                         break;
  112.                     }
  113.                 }
  114.             }
  115.         }
  116.         return $saleList;
  117.     }
  118.     public function getRelatedSales(Sale $sale, &$salesOffset) {
  119.         $result = [];
  120.         $this->getRelatedSalesByCategory($saleSaleRepository::POPULAR_SALE_CATEGORY_ID$resultfalse$salesOffset'popular');
  121.         $this->getRelatedSalesByCategory($saleCategory::SALE_VIDEO_GUIDE_CATEGORY_ID$resultfalse$salesOffset'new');
  122.         $categoryID null;
  123.         $entiityManager $this->entityManager;
  124.         $sale $entiityManager->merge($sale);
  125.         $entiityManager->detach($sale);
  126.         foreach ($sale->getCategories() as $category) {
  127.             if ($category->getEntityCount() > && !in_array($category->getID(), [SaleRepository::POPULAR_SALE_CATEGORY_IDSaleRepository::NEW_CATEGORY_IDCategory::PHOTOGUIDE_SALE_CATEGORY_ID])) {
  128.                 $categoryID $category->getID();
  129.                 break;
  130.             }
  131.         }
  132.         if (!$categoryID) {
  133.             foreach ($sale->getCategories() as $category) {
  134.                 if ($category->getID() == SaleRepository::POPULAR_SALE_CATEGORY_ID || $category->getEntityCount() < 4) {
  135.                     continue;
  136.                 }
  137.                 $categoryID $category->getID();
  138.                 if (in_array($categoryID, [SaleRepository::SOS_CATEGORY_IDSaleRepository::NEW_CATEGORY_IDCategory::PHOTOGUIDE_SALE_CATEGORY_ID])) {
  139.                     $this->getRelatedSalesByCategory($sale$categoryID$resulttrue$salesOffset'extra');
  140.                 } else {
  141.                     $this->getRelatedSalesByCategory($sale$categoryID$resultfalse$salesOffset'extra');
  142.                 }
  143.                 break;
  144.             }
  145.         } else {
  146.             $this->getRelatedSalesByCategory($sale$categoryID$result,  false$salesOffset'extra');
  147.         }
  148.         return $result;
  149.     }
  150.     private function getRelatedSalesByCategory(Sale $sale$categoryID, &$saleList$isFakeCategory, &$salesOffset$key) {
  151.         $count 0;
  152.         $limit 4;
  153.         $salesByCategory $this->getSalesSorted($categoryID);
  154.         $countSalesByCategory count($salesByCategory);
  155.         if (!isset($salesOffset[$key]) || $salesOffset[$key] * $limit >= ceil($countSalesByCategory 2)) {
  156.             $salesOffset[$key] = 0;
  157.         }
  158.         $salesByCategory array_slice($salesByCategory$salesOffset[$key] * $limit);
  159.         $salesOffset[$key]++;
  160.         foreach ($salesByCategory as $saleItem) {
  161.             if ($sale->getID() != $saleItem->getID()) {
  162.                 $found false;
  163.                 foreach ($saleList as $category) {
  164.                     foreach ($category as $saleListItem) {
  165.                         if ($saleListItem->getID() == $saleItem->getID()) {
  166.                             $found true;
  167.                             break;
  168.                         }
  169.                     }
  170.                 }
  171.                 if (!$found) {
  172.                     if($isFakeCategory) {
  173.                         $saleList[SaleRepository::FAKE_CATEGORY_ID][] = $saleItem;
  174.                     } else {
  175.                         $saleList[$categoryID][] = $saleItem;
  176.                     }
  177.                     $count++;
  178.                 }
  179.                 if ($count == $limit) {
  180.                     return;
  181.                 }
  182.             }
  183.         }
  184.     }
  185.     // TODO: Refactor this piece of shit
  186.     public function getActiveSalesGroupedByCategory(): array
  187.     {
  188.         $saleCategoryList $this->categoryRepository->findParentActiveSaleCategories();
  189.         $activeSalesAmount 0;
  190.         $salesList = [];
  191.         foreach ($saleCategoryList as $saleCategory) {
  192.             $saleList $this->getSalesByCategoryID($saleCategory->getID());
  193.             $activeSalesAmount += count($saleList);
  194.             $categoryID $saleCategory->getID();
  195.             $payedPositions $this->entityManager->getRepository(OfferPayedCategory::class)->findBy(
  196.                 ['categoryID' => $categoryID], ['position' => 'asc']);
  197.             if ($payedPositions) {
  198.                 foreach ($payedPositions as $position) {
  199.                     foreach ($saleList as $key => $sale) {
  200.                         if ($sale->getID() == $position->getEntityID()) {
  201.                             unset($saleList[$key]);
  202.                             array_splice($saleList$position->getPosition() - 10, [$sale]);
  203.                             break;
  204.                         }
  205.                     }
  206.                 }
  207.             }
  208.             $categoryItem = [
  209.                 "category" => $saleCategory,
  210.                 "saleList" => $saleList
  211.             ];
  212.             if ($saleCategory->getID() == Category::COMPANY_NEWS_SALE_CATEGORY_ID) {
  213.                 array_unshift($salesList$categoryItem);
  214.             } else {
  215.                 $salesList[] = $categoryItem;
  216.             }
  217.         }
  218.         return ['salesList' => $salesList'activeSalesAmount' => $activeSalesAmount];
  219.     }
  220. }