src/Controller/SaleController.php line 736

Open in your IDE?
  1. <?php
  2. namespace Slivki\Controller;
  3. use Slivki\Entity\Banner;
  4. use Slivki\Entity\Category;
  5. use Slivki\Entity\City;
  6. use Slivki\Entity\Comment;
  7. use Slivki\Entity\EntityVote;
  8. use Slivki\Entity\MainMenu;
  9. use Slivki\Entity\Sale;
  10. use Slivki\Entity\SaleLoadMoreBtnDescription;
  11. use Slivki\Entity\SaleProduct;
  12. use Slivki\Entity\UserGroup;
  13. use Slivki\Entity\Visit;
  14. use Slivki\Entity\VisitCounter;
  15. use Slivki\Enum\SwitcherFeatures;
  16. use Slivki\Repository\OfferRepository;
  17. use Slivki\Repository\SaleRepository;
  18. use Slivki\Services\Category\CategoryCacheService;
  19. use Slivki\Services\Offer\OfferCacheService;
  20. use Slivki\Services\Sale\CategoryBoxService;
  21. use Slivki\Services\Sale\SaleCacheService;
  22. use Slivki\Services\Switcher\ServerFeatureStateChecker;
  23. use Slivki\Util\CommonUtil;
  24. use Slivki\Util\SoftCache;
  25. use Symfony\Component\HttpFoundation\JsonResponse;
  26. use Symfony\Component\HttpFoundation\Request;
  27. use Symfony\Component\HttpFoundation\Response;
  28. use Symfony\Component\Routing\Annotation\Route;
  29. class SaleController extends SiteController
  30. {
  31.     /**
  32.      * @Route("/skidki-i-rasprodazhi", name="sales")
  33.      */
  34.     public function indexAction(
  35.         Request $request,
  36.         CategoryBoxService $categoryBoxService,
  37.         OfferCacheService $offerCacheService,
  38.         SaleCacheService $saleCacheService,
  39.         ServerFeatureStateChecker $serverFeatureStateChecker
  40.     ) {
  41.         if (!$serverFeatureStateChecker->isServerFeatureEnabled(SwitcherFeatures::SALES())) {
  42.             return new Response(''Response::HTTP_NOT_FOUND);
  43.         }
  44.         $isMobileDevice self::getMobileDevice($request);
  45.         $data = [];
  46.         $saleMenu $this->getCategoryRepository()->getSaleCategoriesSortedBySaleVisits();
  47.         $companyNewsSaleCategory null;
  48.         $data['saleMenu'] = [];
  49.         foreach ($saleMenu as $menuItem) {
  50.             $data['saleMenu'][] = ['category' => $menuItem];
  51.         }
  52.         $data['categoryList'] = $this->getSaleCategoryList($categoryBoxService02false$isMobileDevice);
  53.         $data['offerRateSchedule'] = $this->getOfferRateSchedule($request->getSession());
  54.         $data['firstBanner'] = $this->getBannerRepository()->findOneBy(['typeID' => Banner::TYPE_SALE_BANNER'active' => true'positionRow' => 1]);
  55.         $data['secondBanner'] = $this->getBannerRepository()->findOneBy(['typeID' => Banner::TYPE_SALE_BANNER'active' => true'positionRow' => 2]);
  56.         $data['menuSelected'] = MainMenu::MENU_ID_SALE;
  57.         $softCache = new SoftCache(SaleRepository::CACHE_NAME);
  58.         $data['saleVisitCount'] = $softCache->get(SaleRepository::VISIT_COUNT_CACHE_KEY);
  59.         $data['visitedSales'] = $softCache->get(SaleRepository::VISITED_SALE_COUNT_CACHE_KEY);
  60.         $data['saleVisitCountTooltip'] = 'Количество читателей раздела "Новости скидок" за 30 дней';
  61.         $data['visitedSalesTooltip'] = 'Количество прочитанных статей за 30 дней';
  62.         $data['currentCategoryID'] = 0;
  63.         $mainHotFeed '';
  64.         foreach ($this->getMainHotFeed($offerCacheService$saleCacheService20) as $entity) {
  65.             $mainHotFeed .= $this->renderView($isMobileDevice 'Slivki/mobile/hot_feed_teaser.html.twig' 'Slivki/top_main_feed_teaser_mobile.html.twig'$entity);
  66.         }
  67.         $data['mainHotFeed'] = $mainHotFeed;
  68.         $data['locationInfo'] = '';
  69.         $deviceType $isMobileDevice self::DEVICE_TYPE_MOBILE self::DEVICE_TYPE_DESKTOP;
  70.         $this->addVisit(0Visit::TYPE_SALE_MAIN_PAGE$deviceType$this->getUser(), $request->getClientIp(), $request->headers->get('referer'''));
  71.         return $this->render($isMobileDevice 'Slivki/mobile/sale/index.html.twig' 'Slivki/sale/index.html.twig'$data);
  72.     }
  73.     /**
  74.      * @Route("/skidki-i-rasprodazhi/get-category-box")
  75.      */
  76.     public function getSaleCategoryBoxListAction(Request $requestCategoryBoxService $categoryBoxService) {
  77.         $offset $request->request->get('offset'0);
  78.         $length $request->request->get('length'1);
  79.         $data['categoryList'] = $this->getSaleCategoryList($categoryBoxService$offset$lengthtrueself::getMobileDevice($request));
  80.         if (empty($data['categoryList'])) {
  81.             $response = new Response('');
  82.         } else {
  83.             $response $this->render(self::getMobileDevice($request) ? 'Slivki/mobile/sale/category.html.twig'
  84.                 'Slivki/sale/sale_list_box.html.twig'$data);
  85.         }
  86.         return $response;
  87.     }
  88.     private function getSaleCategoryList(CategoryBoxService $categoryBoxService$offset$length$excludeNewCategory false$isMobileDevice false) {
  89.         $categoryList $this->getCategoryRepository()->getSaleCategoriesSortedBySaleVisits();
  90.         $result = [];
  91.         $categoryList array_slice($categoryList$offset$length);
  92.         if ($length == && $excludeNewCategory && isset($categoryList[0]) && $categoryList[0]->getID() == Category::NEW_SALE_CATEGORY_ID) {
  93.             return $this->getSaleCategoryList($offset 11);
  94.         }
  95.         foreach ($categoryList as $category) {
  96.             $result[] = [
  97.                 "category" => $category,
  98.                 "categoryBox" => $categoryBoxService->getCategoryBox($category->getID(), false$isMobileDevice)
  99.             ];
  100.         }
  101.         return $result;
  102.     }
  103.     //TODO: total refactoring this piece of shit and related functions
  104.     public function categoryAction(
  105.         Request $request,
  106.         CategoryBoxService $categoryBoxService,
  107.         CategoryCacheService $categoryCacheService,
  108.         ServerFeatureStateChecker $serverFeatureStateChecker,
  109.         $entityID
  110.     ) {
  111.         if (!$serverFeatureStateChecker->isServerFeatureEnabled(SwitcherFeatures::SALES())) {
  112.             return new Response(''Response::HTTP_NOT_FOUND);
  113.         }
  114.         $isMobileDevice self::getMobileDevice($request);
  115.         $categoryRepository $this->getCategoryRepository();
  116.         $category $categoryRepository->findCached($entityID);
  117.         if (!$category) {
  118.             return $this->redirect("/");
  119.         }
  120.         $isChildOfFlier $category['category']->isChildOf(Category::FLIER_SALE_CATEGORY_ID);
  121.         if ($entityID == Category::FLIER_SALE_CATEGORY_ID || $isChildOfFlier) {
  122.             return $this->fliersAction($request$category);
  123.         }
  124.         $isChildOfVideoguide $category['category']->isChildOf(Category::SALE_VIDEO_GUIDE_CATEGORY_ID) ||
  125.             $category['category']->isChildOf(Category::SALE_VIDEO_GUIDE_AUTORS_CATEGORY_ID);
  126.         if ($entityID == Category::SALE_VIDEO_GUIDE_CATEGORY_ID || $isChildOfVideoguide) {
  127.             return $this->videoguidesAction($request$categoryBoxService$category);
  128.         }
  129.         $categoryRepository $this->getCategoryRepository();
  130.         $topParentCategory $category['category']->getTopParentCategory();
  131.         $parentId $topParentCategory instanceof Category && $topParentCategory->getID() !== $entityID $topParentCategory->getID() : 0;
  132.         $categoryList $categoryRepository->getActiveCategories($parentId, [Category::DEFAULT_CATEGORY_TYPE], Category::SALE_CATEGORY_ID);
  133.         $categoryListHasCategory false;
  134.         foreach ($categoryList as $item) {
  135.             if ((int) $item->getID() === $entityID) {
  136.                 $categoryListHasCategory true;
  137.                 break;
  138.             }
  139.         }
  140.         if (!$categoryListHasCategory) {
  141.             $categoryList[] = $category['category'];
  142.         }
  143.         if ($parentId 0) {
  144.             $data['parentCategory'] = $this->getCategoryRepository()->findCached($parentId);
  145.         }
  146.         foreach ($categoryList as $key => $value) {
  147.             $categoryList[$key] = [
  148.                 'category' => $value,
  149.                 'categoryBox' => $value->getID() == $entityID $categoryBoxService->getCategoryBox($entityIDtrue$isMobileDevice) : false
  150.             ];
  151.         }
  152.         $data['categoryList'] = $categoryList;
  153.         $data['offerRateSchedule'] = $this->getOfferRateSchedule($request->getSession());
  154.         $data['searchIn'] = SearchController::SEARCH_SALES;
  155.         if ($this->getUser() && in_array($this->getUser()->getEmail(), ['anna@slivkki.by''maxmailmax@gmail.com''igor@slivki.by'])) {
  156.             $categoryMonthlyVisitCache = new SoftCache(Visit::CATEGORY_MONTHLY_VISITS_CACHE_NAME);
  157.             $currentCategoryMonthlyVisits $categoryMonthlyVisitCache->get($entityID);
  158.             if ($currentCategoryMonthlyVisits) {
  159.                 $data['currentCategoryMonthlyVisits'] = $currentCategoryMonthlyVisits;
  160.             }
  161.         }
  162.         $data['currentCategory'] = $category;
  163.         $data['currentCategoryID'] = $entityID;
  164.         $data['unfoldedCategory'] = true;
  165.         $data['menuSelected'] = MainMenu::MENU_ID_SALE;
  166.         if ($entityID == Category::PHOTOGUIDE_SALE_CATEGORY_ID) {
  167.             $data['searchIn'] = SearchController::SEARCH_PHOTO_GUIDES;
  168.             $data['menuSelected'] = MainMenu::MENU_ID_PHOTOGUIDE;
  169.         }
  170.         $softCache = new SoftCache(SaleRepository::CACHE_NAME);
  171.         $data['saleVisitCount'] = $softCache->get(SaleRepository::VISIT_COUNT_CACHE_KEY);
  172.         $data['visitedSales'] = $softCache->get(SaleRepository::VISITED_SALE_COUNT_CACHE_KEY);
  173.         $data['saleVisitCountTooltip'] = 'Количество читателей раздела "Новости скидок" за 30 дней';
  174.         $data['visitedSalesTooltip'] = 'Количество прочитанных статей за 30 дней';
  175.         $data['saleMenu'] = $categoryList;
  176.         $deviceType $isMobileDevice self::DEVICE_TYPE_MOBILE self::DEVICE_TYPE_DESKTOP;
  177.         $this->addVisit($entityIDVisit::TYPE_SALE_CATEGORY$deviceType$this->getUser(), $request->getClientIp(),
  178.             $request->headers->get('referer'''));
  179.         return $this->render($isMobileDevice 'Slivki/mobile/sale/index.html.twig' 'Slivki/sale/index.html.twig'$data);
  180.     }
  181.     public function videoguidesAction(Request $requestCategoryBoxService $categoryBoxService$category) {
  182.         $isMobileDevice self::getMobileDevice($request);
  183.         $categoryID $category['category']->getID();
  184.         $categoryRepository $this->getCategoryRepository();
  185.         $data['isVideoguideCategory'] = true;
  186.         $data['videoguideCategoryMenu'] = $categoryRepository->getSaleVideoguideCategoryMenu();
  187.         $data['videoguideAutorsCategoryMenu'] = '';
  188.         $data['menuSelected'] = Category::SALE_VIDEO_GUIDE_CATEGORY_ID;
  189.         $softCache = new SoftCache(SaleRepository::CACHE_NAME);
  190.         $data['saleVisitCountTooltip'] = 'Количество читателей раздела "Новости скидок" за 30 дней';
  191.         $data['visitedSalesTooltip'] = 'Количество прочитанных статей за 30 дней';
  192.         $data['saleVisitCount'] = $softCache->get(SaleRepository::VISIT_COUNT_CACHE_KEY);
  193.         $data['visitedSales'] = $softCache->get(SaleRepository::VISITED_SALE_COUNT_CACHE_KEY);
  194.         $data['currentCategory'] = $category;
  195.         $data['currentCategoryID'] = $categoryID;
  196.         $data['unfoldedCategory'] = true;
  197.         $user $this->getUser();
  198.         $data['statViewer'] = $user and $this->isGranted('ROLE_MANAGER_STATISTICS');
  199.         $deviceType $isMobileDevice self::DEVICE_TYPE_MOBILE self::DEVICE_TYPE_DESKTOP;
  200.         if ($categoryID == Category::SALE_VIDEO_GUIDE_CATEGORY_ID) {
  201.             $this->addVisit(0Visit::TYPE_SLIVKI_TV_MAIN_PAGE$deviceType$this->getUser(), $request->getClientIp());
  202.         } else {
  203.             $this->addVisit($categoryIDVisit::TYPE_SLIVKI_TV_CATEGORY$deviceType$this->getUser(), $request->getClientIp());
  204.         }
  205.         $view $isMobileDevice 'Slivki/mobile/sale/index.html.twig' 'Slivki/sale/index.html.twig';
  206.         if ($categoryID == Category::SALE_VIDEO_GUIDE_CATEGORY_ID) {
  207.             $data['categoryHTML'] = $categoryBoxService->getVideoGuidesMainPage($isMobileDevice);
  208.             $view $isMobileDevice 'Slivki/mobile/sale/videoguide/index.html.twig' 'Slivki/sale/videoguide_index.html.twig';
  209.         } else {
  210.             $videoguideCategoryList[0]['category'] = $category['category'];
  211.             $videoguideCategoryList[0]['categoryBox'] = $categoryBoxService->getCategoryBox($categoryIDtrue$isMobileDevice);
  212.             $data['isChildOfVideoGuide'] = true;
  213.             $data['categoryList'] = $videoguideCategoryList;
  214.             $data['videoguideCategory'] = $categoryRepository->findCached(Category::SALE_VIDEO_GUIDE_CATEGORY_ID);
  215.         }
  216.         return $this->render($view$data);
  217.     }
  218.     public function fliersAction(Request $request$category) {
  219.         $isChildOfFlier $category['category']->isChildOf(Category::FLIER_SALE_CATEGORY_ID);
  220.         $softCache = new SoftCache(SaleRepository::CACHE_NAME);
  221.         $data['menuSelected'] = MainMenu::MENU_ID_FLIER;
  222.         $data['searchIn'] = SearchController::SEARCH_FLIERS;
  223.         $data['saleVisitCount'] = $softCache->get(SaleRepository::FLIER_VISIT_COUNT_CACHE_KEY);
  224.         $data['visitedSales'] = $softCache->get(SaleRepository::VISITED_FLIER_COUNT_CACHE_KEY);
  225.         $data['saleVisitCountTooltip'] = 'Количество читателей раздела "Листовки" за 30 дней';
  226.         $data['visitedSalesTooltip'] = 'Количество прочитанных листовок за 30 дней';
  227.         $data['currentCategoryID'] = $category['category']->getID();
  228.         $data['currentCategory'] = $category;
  229.         $mainMenuRepository $this->getDoctrine()->getManager()->getRepository(MainMenu::class);
  230.         $flierMenu $mainMenuRepository->getItemListCached(MainMenu::MENU_ID_FLIERCity::DEFAULT_CITY_ID);
  231.         $flierMenuCount 0;
  232.         $cityName $request->query->get('city');
  233.         $selectedCity null;
  234.         if ($cityName) {
  235.             $cityList $softCache->get(SaleRepository::CITIES_CACHE_KEY);
  236.             foreach ($cityList as $item) {
  237.                 $firstChar mb_substr($cityName01);
  238.                 if (isset($cityList[$firstChar])) {
  239.                     foreach ($cityList[$firstChar] as $city) {
  240.                         if ($city['cityName'] == $cityName) {
  241.                             $selectedCity $city;
  242.                             $data['selectedCity'] = $cityName;
  243.                             break;
  244.                         }
  245.                     }
  246.                 }
  247.             }
  248.         }
  249.         $flierMenuTemp = [];
  250.         foreach ($flierMenu as $flierMenuItem) {
  251.             if (in_array($flierMenuItem->getType(), [MainMenu::TYPE_OFFER_CATEGORYMainMenu::TYPE_SALE_CATEGORY])) {
  252.                 $flierCategory $this->getCategoryRepository()->findCached($flierMenuItem->getEntityID());
  253.                 if ($flierCategory) {
  254.                     $entityCount 0;
  255.                     if ($selectedCity) {
  256.                         $entityCount count(array_unique(array_intersect($selectedCity['entityList'], $flierCategory['entityList'])));
  257.                     } else {
  258.                         $entityCount $flierCategory['category']->getEntityCount();
  259.                     }
  260.                     if ($entityCount 0) {
  261.                         $flierMenuItem->setEntityCount($entityCount);
  262.                         $flierMenuCount += $entityCount;
  263.                         $flierMenuTemp[] = $flierMenuItem;
  264.                     }
  265.                 }
  266.             }
  267.         }
  268.         $flierMenu $flierMenuTemp;
  269.         $cityList $softCache->get(SaleRepository::CITIES_CACHE_KEY);
  270.         $data['cityList'] = $cityList $cityList : [];
  271.         $flierCategoryList = [];
  272.         if ($isChildOfFlier) {
  273.             $flierCategoryList[0]['category'] = $category['category'];
  274.             $flierCategoryList[0]['saleList'] = $this->getSaleRepository()->getActiveSalesByCategoryID($category['category']->getID());
  275.             $data['isChildOfFlier'] = true;
  276.         } else {
  277.             $i 0;
  278.             /** @var MainMenu $flierMenuItem */
  279.             foreach ($flierMenu as $flierMenuItem) {
  280.                 if ($selectedCity && count(array_intersect($selectedCity['entityList'], $category['entityList'])) == 0) {
  281.                     continue;
  282.                 }
  283.                 $category $this->getCategoryRepository()->findCached($flierMenuItem->getEntityID());
  284.                 if ($category && $category['entityList'] && ($category['category']->getID() != Category::POPULAR_FLIER_CATEGORY_ID)) {
  285.                     $flierCategoryList[$i]['category'] = $category['category'];
  286.                     $flierCategoryList[$i]['saleList'] = $this->getSaleRepository()->getActiveSalesByCategoryID($category['category']->getID());
  287.                     if (self::getMobileDevice($request)) {
  288.                         $flierCategoryList[$i]['saleList'] = array_slice($flierCategoryList[$i]['saleList'], 04);
  289.                     }
  290.                     $i++;
  291.                 }
  292.             }
  293.         }
  294.         if ($selectedCity) {
  295.             foreach ($flierCategoryList as $key => $item) {
  296.                 $saleListTemp = [];
  297.                 foreach ($item['saleList'] as $sale) {
  298.                     if (in_array($sale->getID(), $selectedCity['entityList'])) {
  299.                         $saleListTemp[] = $sale;
  300.                     }
  301.                 }
  302.                 $flierCategoryList[$key]['saleList'] = $saleListTemp;
  303.                 $flierCategoryList[$key]['category']->setEntityCount(count($saleListTemp));
  304.             }
  305.         }
  306.         $data['flierMenu'] = $flierMenu;
  307.         $data['flierMenuCount'] = $flierMenuCount;
  308.         $data['flierCategoryList'] = $flierCategoryList;
  309.         $data['categoryList'] = $flierCategoryList;
  310.         $deviceType self::getMobileDevice($request) ? self::DEVICE_TYPE_MOBILE self::DEVICE_TYPE_DESKTOP;
  311.         $response '';
  312.         if (self::getMobileDevice($request)) {
  313.             $response $this->render('Slivki/mobile/sale/flier/index.html.twig'$data);
  314.         } else {
  315.             if ($isChildOfFlier && !$data['isChildOfFlier']) {
  316.                 $response $this->render('Slivki/sale/index.html.twig'$data);
  317.             } else {
  318.                 $entityID 0;
  319.                 $entityTypeID Visit::TYPE_FLIER_MAIN_PAGE;
  320.                 if ($isChildOfFlier) {
  321.                     $entityID $category['category']->getID();
  322.                     $entityTypeID Visit::TYPE_FLIER_CATEGORY;
  323.                 }
  324.                 $this->addVisit($entityID$entityTypeID$deviceType$this->getUser(), $request->getClientIp());
  325.                 $response $this->render('Slivki/sale/flier_index.html.twig'$data);
  326.             }
  327.         }
  328.         return $response;
  329.     }
  330.     public function detailsAction(
  331.         Request $request,
  332.         SaleCacheService $saleCacheService,
  333.         ServerFeatureStateChecker $serverFeatureStateChecker,
  334.         $entityID
  335.     ) {
  336.         if (!$serverFeatureStateChecker->isServerFeatureEnabled(SwitcherFeatures::SALES())) {
  337.             return new Response(''Response::HTTP_NOT_FOUND);
  338.         }
  339.         $saleRepository $this->getSaleRepository();
  340.         $preview $request->query->get("preview"false);
  341.         $versionID $request->query->get('version');
  342.         $sale $saleCacheService->getSale($entityIDtrue);
  343.         if (!$sale || $preview) {
  344.             $sale $this->getDoctrine()->getRepository(Sale::class)->find($entityID);
  345.             if (!$sale || ((!$sale->isActive() || !$sale->isInActivePeriod()) && !$preview)) {
  346.                 throw $this->createNotFoundException("Sale $entityID not found");
  347.             }
  348.         }
  349.         $deviceType self::getMobileDevice($request) ? self::DEVICE_TYPE_MOBILE self::DEVICE_TYPE_DESKTOP;
  350.         $salesOffset = ['popular' => 0'new' => 0'extra' => 0];
  351.         $salesOffsetLastDate $request->getSession()->get('sales-offset-last-date'null);
  352.         if ($salesOffsetLastDate != null && $salesOffsetLastDate >= (new \DateTime('-30 minutes'))) {
  353.             $salesOffsetSession $request->getSession()->get('sales-offset'$salesOffset);
  354.             foreach ($salesOffset as $offsetKey => $offsetValue) {
  355.                 if (isset($salesOffsetSession[$offsetKey])) {
  356.                     $salesOffset[$offsetKey] = $salesOffsetSession[$offsetKey];
  357.                 } else {
  358.                     $offsetKey[$offsetKey] = 0;
  359.                 }
  360.             }
  361.         }
  362.         $request->getSession()->set('sales-offset-last-date', (new \DateTime()));
  363.         $saleVersion null;
  364.         if ($versionID) {
  365.             $saleVersion $sale->getVersionByID($versionID);
  366.         } else {
  367.             $saleVersion $sale->getCurrentVersion();
  368.         }
  369.         $isVideoguide $sale->isVideoguide();
  370.         $isFlier $sale->isFlier();
  371.         $data = [
  372.             'sale' => $sale,
  373.             'saleGeoLocationData' => $this->getSaleGeoLocationData($sale$request->getPathInfo()),
  374.             'commentsAmount' => $this->getCommentRepository()->getCommentsCountByEntityID($entityIDComment::TYPE_SALE_COMMENT),
  375.             'menuSelected' => MainMenu::MENU_ID_SALE,
  376.             'isFlier' => $isFlier,
  377.             'saleVersion' => $saleVersion
  378.         ];
  379.         if (!$isVideoguide) {
  380.             $data['relatedSales'] = $saleCacheService->getRelatedSales($sale$salesOffset);
  381.         }
  382.         $user $this->getUser();
  383.         $entityManager $this->getDoctrine()->getManager();
  384.         if ($user) {
  385.             $entityVote $entityManager->getRepository(EntityVote::class)->findOneBy([
  386.                 'entityID' => $sale->getID(),
  387.                 'entityTypeID' => EntityVote::TYPE_SALE,
  388.                 'user' => $user
  389.             ]);
  390.             $data['userVote'] = 0;
  391.             if ($entityVote) {
  392.                 $data['userVote'] = $entityVote->getVote();
  393.             }
  394.         }
  395.         $request->getSession()->set('sales-offset'$salesOffset);
  396.         $data['parentCategoryList'] = $this->getParentCategoryList($request$sale->getDefaultCategoryID());
  397.         $data['offerRateSchedule'] = $this->getOfferRateSchedule($request->getSession());
  398.         $data['daysFromStart'] = $sale->getCreatedOn()->setTime(000)->diff(new \DateTime())->format('%a');
  399.         if ($data['daysFromStart'] > 45) {
  400.             $data['daysFromStart'] = 45;
  401.         }
  402.         if ($data['daysFromStart'] == 0) {
  403.             $data['daysFromStart'] = 1;
  404.         }
  405.         $data['director'] = null;
  406.         if ($sale->getDirectors()->count() > 0) {
  407.             $data['director'] = $sale->getDirectors()->first();
  408.         }
  409.         $data['descriptions'] = $this->renderView(CommonUtil::isMobileDevice($request) ? 'Slivki/mobile/sale/sale_description_block.html.twig'
  410.             'Slivki/sale/sale_description_block.html.twig', [
  411.             'descriptions' => $this->getSaleDescriptionPortion($saleVersion)
  412.         ]);
  413.         $view 'Slivki/sale/sale.html.twig';
  414.         if (self::getMobileDevice($request)) {
  415.             $view 'Slivki/mobile/sale/details.html.twig';
  416.         }
  417.         $visitCounterRepository $entityManager->getRepository(VisitCounter::class);
  418.         $visitCounter $visitCounterRepository->findBy(['type' => VisitCounter::TYPE_SALE'entityID' => $sale->getID()]);
  419.         $data['dayVisitCount'] = 0;
  420.         if ($isVideoguide) {
  421.             $authorCategory $saleRepository->getVideoguideAutorCategory($sale);
  422.             if ($authorCategory) {
  423.                 $categoryVisitCount 0;
  424.                 foreach ($saleRepository->getActiveSalesByCategoryID($authorCategory->getID()) as $saleItem) {
  425.                     $categoryVisitCount += $visitCounterRepository->getVisitCount($saleItem->getID(), VisitCounter::TYPE_SALEfalse);
  426.                 }
  427.                 $data['authorCategory'] = [
  428.                     'category' => $authorCategory,
  429.                     'visitCount' => $categoryVisitCount
  430.                 ];
  431.             }
  432.             $data['visitCount'] = 0;
  433.             if ($visitCounter) {
  434.                 $data['visitCount'] = $visitCounter[0]->getVisitCount();
  435.             }
  436.             $session $request->getSession();
  437.             if ($request->get('utm_source') != 'video_sidebar') {
  438.                 $seenVideoguides = [$sale->getID()];
  439.             } else {
  440.                 $seenVideoguides $session->get('seenVideoguides', []);
  441.                 $seenVideoguides[] = $sale->getID();
  442.                 $seenVideoguides array_unique($seenVideoguides);
  443.             }
  444.             $session->set('seenVideoguides'$seenVideoguides);
  445.             $data['seenVideoguides'] = json_encode($seenVideoguides);
  446.             $data['sidebarVideoguides'] = $this->getSidebarVideoguides($saleCacheService$request$sale->getID(), 020);
  447.             $data['videoguideCategory'] = $this->getCategoryRepository()->findCached(Category::SALE_VIDEO_GUIDE_CATEGORY_ID);
  448.             $view 'Slivki/sale/videoguide.html.twig';
  449.             if (self::getMobileDevice($request)) {
  450.                 $view 'Slivki/mobile/sale/videoguide/details.html.twig';
  451.             }
  452.             $this->addVisit($entityIDVisit::TYPE_SLIVKI_TV_GUIDES$deviceType$this->getUser(), $request->getClientIp());
  453.         } else {
  454.             $data['visitCount'] = $entityManager->getRepository(Visit::class)
  455.                 ->getVisitCount($sale->getID(), Category::SALE_CATEGORY_ID$data['daysFromStart'], true);
  456.             if ($visitCounter) {
  457.                 $data['dayVisitCount'] = $visitCounter[0]->getVisitCountRecent();
  458.             }
  459.             if ($sale->getID() == 253587) {
  460.                 $data['visitCount'] += 10188;
  461.             }
  462.         }
  463.         if ($user && $user->hasRole(UserGroup::STATISTICS_VIEWER)) {
  464.             $data['yesterdayShareClicks'] = $this->getShareClicks($entityID);
  465.         }
  466.         $response $this->render($view$data);
  467.         if ($isFlier) {
  468.             $this->addVisit($entityIDVisit::TYPE_FLIER_DETAILS$deviceType$this->getUser(), $request->getClientIp());
  469.         }
  470.         $this->addVisit($entityIDVisit::TYPE_SALE$deviceType$this->getUser(), $request->getClientIp());
  471.         return $response;
  472.     }
  473.     public function getSaleGeoLocationData(Sale $sale$saleURL) {
  474.         $features = [];
  475.         $saleID $sale->getID();
  476.         foreach ($sale->getGeoLocations() as $geoLocation) {
  477.             $caption $geoLocation->getStreet() . ', ' $geoLocation->getHouse();
  478.             $features[] = [
  479.                 'type' => 'Feature',
  480.                 'id' => $geoLocation->getID(),
  481.                 'geometry' => [
  482.                     'type' => 'Point',
  483.                     'coordinates' => [$geoLocation->getLatitude(), $geoLocation->getLongitude()]
  484.                 ],
  485.                 'properties' => [
  486.                     'iconClass' => 'always-caption',
  487.                     'iconContent' => '',
  488.                     'locationID' => $geoLocation->getID(),
  489.                     'offerID' => $saleID,
  490.                     'url' => $saleURL,
  491.                     'hintContent' => $caption
  492.                 ]
  493.             ];
  494.         }
  495.         $getLocationData = ['type' => 'FeatureCollection''features' => $features];
  496.         return json_encode($getLocationData);
  497.     }
  498.     /**
  499.      * @Route("/sales/get_descriptions/{saleID}/{saleVersionID}/{lastSortOrder}")
  500.      */
  501.     public function getDescriptionsAction(Request $requestSaleCacheService $saleCacheService$saleID$saleVersionID$lastSortOrder) {
  502.         $saleID = (int)$saleID;
  503.         $sale $saleCacheService->getSale($saleIDtrue);
  504.         if (!$sale) {
  505.             $sale $this->getDoctrine()->getRepository(Sale::class)->find($saleID);
  506.             if (!$sale) {
  507.                 throw $this->createNotFoundException("Sale $saleID not found");
  508.             }
  509.         }
  510.         $saleVersion $sale->getVersionByID($saleVersionID);
  511.         return $this->render(CommonUtil::isMobileDevice($request) ? 'Slivki/mobile/sale/sale_description_block.html.twig'
  512.             'Slivki/sale/sale_description_block.html.twig', [
  513.             'descriptions' => $this->getSaleDescriptionPortion($saleVersion$lastSortOrder)
  514.         ]);
  515.     }
  516.     private function getSaleDescriptionPortion($saleVersion$lastSortOrder = -INF) {
  517.         $allDescriptions $saleVersion->getAllDescriptions();
  518.         $result = [];
  519.         foreach ($allDescriptions as $description) {
  520.             if ($lastSortOrder >= $description->getSortOrder()) {
  521.                 continue;
  522.             }
  523.             $result[] = $description;
  524.             if ($description instanceof SaleLoadMoreBtnDescription) {
  525.                 break;
  526.             }
  527.         }
  528.         return $result;
  529.     }
  530.     /**
  531.      * @Route("/sales/get_more_videoguides/{saleID}/{offset}/{limit}")
  532.      */
  533.     public function getMoreSidebarVideoguides(Request $requestSaleCacheService $saleCacheService$saleID$offset$limit) {
  534.         $view 'Slivki/sale/videoguide_sidebar_list.html.twig';
  535.         if (self::getMobileDevice($request)) {
  536.             $view 'Slivki/mobile/sale/videoguide/next.html.twig';
  537.         }
  538.         return $this->render($view, [
  539.             'sidebarVideoguides' => $this->getSidebarVideoguides($saleCacheService$request$saleID$offset$limit)
  540.         ]);
  541.     }
  542.     private function getSidebarVideoguides(SaleCacheService $saleCacheService$request$saleID$offset 0$limit 20) {
  543.         $session $request->getSession();
  544.         $seenVideoguides $session->get('seenVideoguides', []);
  545.         $topVideoguides = [];
  546.         if ($offset == 0) {
  547.             $sale $this->getSaleRepository()->getActiveSaleByID($saleID);
  548.             if ($sale) {
  549.                 $defaultCategoryID $sale->getDefaultCategoryID();
  550.                 if (!$defaultCategoryID) {
  551.                     /** @var Category $category */
  552.                     foreach ($sale->getCategories() as $category) {
  553.                         if ($category->isChildOf(Category::SALE_VIDEO_GUIDE_CATEGORY_ID) && $category->getID() != Category::SALE_VIDEO_GUIDE_AUTORS_CATEGORY_ID) {
  554.                             $defaultCategoryID $category->getID();
  555.                             break;
  556.                         }
  557.                     }
  558.                 }
  559.                 if ($defaultCategoryID) {
  560.                     $topVideoguides $this->getSaleRepository()->getActiveSalesByCategoryID($defaultCategoryID);
  561.                     $implodedIDs '';
  562.                     foreach ($topVideoguides as $key => $videoguide) {
  563.                         if (!in_array($videoguide->getID(), $seenVideoguides)) {
  564.                             $implodedIDs .= $sale->getID() . ',';
  565.                         } else {
  566.                             unset($topVideoguides[$key]);
  567.                         }
  568.                     }
  569.                     $implodedIDs trim($implodedIDs',');
  570.                     if ($implodedIDs != '') {
  571.                         $sql 'select entity_id, visit_count from visit_count_aggregated where entity_id in (' $implodedIDs ') and days_count = 7';
  572.                         $result $this->getDoctrine()->getManager()->getConnection()->executeQuery($sql)->fetchAll(\PDO::FETCH_ASSOC);
  573.                         $visitCountList = [];
  574.                         foreach ($result as $item) {
  575.                             $visitCountList[$item['entity_id']] = $item['visit_count'];
  576.                         }
  577.                         usort($topVideoguides, function ($sale$sale1) use (&$visitCountList) {
  578.                             $visitCount = isset($visitCountList[$sale->getID()]) ? $visitCountList[$sale->getID()] : 0;
  579.                             $visitCount1 = isset($visitCountList[$sale1->getID()]) ? $visitCountList[$sale1->getID()] : 0;
  580.                             if ($visitCount == $visitCount1) {
  581.                                 return $sale->getID() > $sale1->getID() ? -1;
  582.                             }
  583.                             return $visitCount $visitCount1 ? -1;
  584.                         });
  585.                         $topVideoguides array_slice($topVideoguides03);
  586.                         foreach ($topVideoguides as $videoguide) {
  587.                             $seenVideoguides[] = $videoguide->getID();
  588.                         }
  589.                     }
  590.                 }
  591.             }
  592.         }
  593.         $allVideoguides $saleCacheService->getSalesByCategoryID(Category::SALE_VIDEO_GUIDE_CATEGORY_ID);
  594.         if (count($allVideoguides) == 0) {
  595.             return [];
  596.         }
  597.         $implodedIDs '';
  598.         foreach ($allVideoguides as $key => $sale) {
  599.             if (!in_array($sale->getID(), $seenVideoguides)) {
  600.                 $implodedIDs .= $sale->getID() . ',';
  601.             } else {
  602.                 unset($allVideoguides[$key]);
  603.             }
  604.         }
  605.         $implodedIDs trim($implodedIDs',');
  606.         $sql 'select entity_id, visit_count from visit_count_aggregated where entity_id in (' $implodedIDs ') and days_count = 7';
  607.         $result $this->getDoctrine()->getManager()->getConnection()->executeQuery($sql)->fetchAll(\PDO::FETCH_ASSOC);
  608.         $visitCountList = [];
  609.         foreach ($result as $item) {
  610.             $visitCountList[$item['entity_id']] = $item['visit_count'];
  611.         }
  612.         usort($allVideoguides, function ($sale$sale1) use (&$visitCountList) {
  613.             $visitCount = isset($visitCountList[$sale->getID()]) ? $visitCountList[$sale->getID()] : 0;
  614.             $visitCount1 = isset($visitCountList[$sale1->getID()]) ? $visitCountList[$sale1->getID()] : 0;
  615.             if ($visitCount == $visitCount1) {
  616.                 return $sale->getID() > $sale1->getID() ? -1;
  617.             }
  618.             return $visitCount $visitCount1 ? -1;
  619.         });
  620.         $result array_slice($allVideoguides$offset$limit);
  621.         if ($offset == 0) {
  622.             $result array_merge($topVideoguides$result);
  623.         }
  624.         return $result;
  625.     }
  626.     /** @Route("/sale/filter/map/{categoryID}") */
  627.     public function mapFilterAction(Request $request$categoryID) {
  628.         $offerIDList $request->request->get('offerList', []);
  629.         $offerIDFiltered $offerIDList;
  630.         $category null;
  631.         if ($categoryID 0) {
  632.             $category $this->getDoctrine()->getRepository(Category::class)->findCached($categoryID);
  633.             $offerList $this->getDoctrine()->getRepository(Category::class)->getActiveEntityListByCategory($categoryID);
  634.             $offerIDFiltered = [];
  635.             foreach ($offerList as $offer) {
  636.                 if (in_array($offer->getID(), $offerIDList)) {
  637.                     $offerIDFiltered[] = $offer->getID();
  638.                 }
  639.             }
  640.         }
  641.         $flierCategory false;
  642.         $cacheName OfferRepository::CACHE_NAME_TEASERS;
  643.         if ($category && ($categoryID == Category::FLIER_SALE_CATEGORY_ID || $category['category']->isChildOf(Category::FLIER_SALE_CATEGORY_ID))) {
  644.             $cacheName SaleRepository::CACHE_NAME_TEASERS_FLIER;
  645.             $flierCategory true;
  646.         }
  647.         $teasersCache = new SoftCache($cacheName);
  648.         $teaserList $teasersCache->getMulti($offerIDFiltered);
  649.         $result = ['html' => '''count' => 0];
  650.         if ($teaserList) {
  651.             $html '';
  652.             if ($categoryID == Category::FLIER_SALE_CATEGORY_ID) {
  653.                 $html implode(''$teaserList);
  654.             } else {
  655.                 $html $this->get('twig')->render('Slivki/sale/teasers.html.twig', ['teaserList' => $teaserList]);
  656.                 $html '<div class="sale-list-box map-filtered-list"><div class="sale-list-box-table"><div class="table-item sales-list"><ul class="table-item-list">' $html '</ul></div></div></div>';
  657.             }
  658.             $result = [
  659.                 'html' => $html,
  660.                 'count' => count($teaserList),
  661.                 'flierCategory' => $flierCategory
  662.             ];
  663.         }
  664.         return new JsonResponse($result);
  665.     }
  666.     /** @Route("/sale/location-info/{categoryID}/{limit}/{offset}") */
  667.     public function getLocationInfoAction($categoryID$limit$offset) {
  668.         $saleGeoLocationCache = new SoftCache(SaleRepository::CACHE_NAME_GEO_LOCATION_DATA);
  669.         $features $saleGeoLocationCache->get($categoryID, []);
  670.         if (!$features) {
  671.             $features = [];
  672.         }
  673.         $features array_slice($features$offset$limit);
  674.         if (empty($features)) {
  675.             return new Response(json_encode([]));
  676.         }
  677.         $getLocationData = ['type' => 'FeatureCollection''features' => $features];
  678.         return new Response(json_encode($getLocationData));
  679.     }
  680.     /** @Route("/profile/vote_sale/{saleID}/{vote}") */
  681.     public function voteSaleAction($saleID$vote) {
  682.         $user $this->getUser();
  683.         $entityManager $this->getDoctrine()->getManager();
  684.         $entityVote $entityManager->getRepository(EntityVote::class)->findOneBy([
  685.             'entityID' => $saleID,
  686.             'entityTypeID' => EntityVote::TYPE_SALE,
  687.             'user' => $user
  688.         ]);
  689.         if (!$entityVote) {
  690.             $entityVote = new EntityVote();
  691.             $entityVote->setEntityID($saleID);
  692.             $entityVote->setCreatedOn(new \DateTime());
  693.             $entityVote->setUser($user);
  694.             $entityVote->setEntityTypeID(EntityVote::TYPE_SALE);
  695.             $entityManager->persist($entityVote);
  696.         }
  697.         $entityVote->setLastModified(new \DateTime());
  698.         $entityVote->setVote($vote);
  699.         $entityManager->flush();
  700.         return new JsonResponse($entityManager->getRepository(Comment::class)->getEntityRatingWithCount(Category::SALE_CATEGORY_ID$saleID));
  701.     }
  702.     /** @Route("/listovki", name = "flierLanding") */
  703.     public function hyperShopAction(
  704.         Request $request,
  705.         SaleCacheService $saleCacheService,
  706.         ServerFeatureStateChecker $serverFeatureStateChecker
  707.     ) {
  708.         if (!$serverFeatureStateChecker->isServerFeatureEnabled(SwitcherFeatures::FLIERS())) {
  709.             return new Response(''Response::HTTP_NOT_FOUND);
  710.         }
  711.         $productLength 5;
  712.         $data = [];
  713.         $entityManager $this->getDoctrine()->getManager();
  714.         $saleProductRepository $entityManager->getRepository(SaleProduct::class);
  715.         $saleRepository $this->getSaleRepository();
  716.         $softCache = new SoftCache(SaleRepository::CACHE_NAME);
  717.         $data['menuSelected'] = MainMenu::MENU_ID_FLIER;
  718.         $data['saleVisitCount'] = $softCache->get(SaleRepository::FLIER_VISIT_COUNT_CACHE_KEY);
  719.         $data['visitedSales'] = $softCache->get(SaleRepository::VISITED_FLIER_COUNT_CACHE_KEY);
  720.         $data['saleVisitCountTooltip'] = 'Количество читателей раздела "Листовки" за 30 дней';
  721.         $data['visitedSalesTooltip'] = 'Количество прочитанных листовок за 30 дней';
  722.         $fliers $saleCacheService->getSalesByCategoryID(Category::POPULAR_FLIER_CATEGORY_ID);
  723.         $data['fliersCount'] = count($fliers);
  724.         $fliersSliderData '';
  725.         $isMobileDevice self::getMobileDevice($request);
  726.         $view =  $isMobileDevice 'Slivki/mobile/sale/flier/teaser.html.twig' 'Slivki/sale/flier.html.twig';
  727.         foreach (array_slice($fliers010) as $sale) {
  728.             $fliersSliderData .= $this->renderView($view, ['sale' => $sale'additionalClass' => 'swiper-slide']);
  729.         }
  730.         $data['fliersSliderData'] = $fliersSliderData;
  731.         $saleProductList $saleRepository->getSaleProductsCached();
  732.         $foodProductListID $saleRepository->getSaleProductsIDByCategoryID(Category::FOOD_SALE_CATEGORY_ID);
  733.         $foodProductListID array_slice(array_reverse($foodProductListID), 0$productLength);
  734.         $data['saleProductList'] = [];
  735.         foreach ($foodProductListID as $productID) {
  736.             $data['saleProductList'][] = $saleProductRepository->find($productID);
  737.         }
  738.         $data['productCount'] = count($data['saleProductList']);
  739.         $mainMenuRepository $entityManager->getRepository(MainMenu::class);
  740.         $flierMenu $mainMenuRepository->getItemListCached(MainMenu::MENU_ID_FLIERCity::DEFAULT_CITY_ID);
  741.         $flierMenuCount 0;
  742.         $cityName $request->query->get('city');
  743.         $selectedCity null;
  744.         if ($cityName) {
  745.             $cityList $softCache->get(SaleRepository::CITIES_CACHE_KEY);
  746.             foreach ($cityList as $item) {
  747.                 $firstChar mb_substr($cityName01);
  748.                 if (isset($cityList[$firstChar])) {
  749.                     foreach ($cityList[$firstChar] as $city) {
  750.                         if ($city['cityName'] == $cityName) {
  751.                             $selectedCity $city;
  752.                             $data['selectedCity'] = $cityName;
  753.                             break;
  754.                         }
  755.                     }
  756.                 }
  757.             }
  758.         }
  759.         $flierMenuTemp = [];
  760.         foreach ($flierMenu as $flierMenuItem) {
  761.             if (in_array($flierMenuItem->getType(), [MainMenu::TYPE_OFFER_CATEGORYMainMenu::TYPE_SALE_CATEGORY])) {
  762.                 $flierCategory $this->getCategoryRepository()->findCached($flierMenuItem->getEntityID());
  763.                 if ($flierCategory) {
  764.                     $entityCount 0;
  765.                     if ($selectedCity) {
  766.                         $entityCount count(array_unique(array_intersect($selectedCity['entityList'], $flierCategory['entityList'])));
  767.                     } else {
  768.                         $entityCount $flierCategory['category']->getEntityCount();
  769.                     }
  770.                     if ($entityCount 0) {
  771.                         $flierMenuItem->setEntityCount($entityCount);
  772.                         $flierMenuCount += $entityCount;
  773.                         $flierMenuTemp[] = $flierMenuItem;
  774.                     }
  775.                 }
  776.             }
  777.         }
  778.         $flierMenu $flierMenuTemp;
  779.         $cityList $softCache->get(SaleRepository::CITIES_CACHE_KEY);
  780.         $data['cityList'] = $cityList $cityList : [];
  781.         $flierCategoryList = [];
  782.         $i 0;
  783.         /** @var MainMenu $flierMenuItem */
  784.         foreach ($flierMenu as $flierMenuItem) {
  785.             $category $this->getCategoryRepository()->findCached($flierMenuItem->getEntityID());
  786.             if (!isset($category['entityList']) || ($selectedCity && count(array_intersect($selectedCity['entityList'], $category['entityList'])) == 0)) {
  787.                 continue;
  788.             }
  789.             if ($category && $category['entityList'] && ($category['category']->getID() != Category::POPULAR_FLIER_CATEGORY_ID)) {
  790.                 $flierCategoryList[$i]['category'] = $category['category'];
  791.                 $flierCategoryList[$i]['saleList'] = $saleCacheService->getSalesByCategoryID($category['category']->getID());
  792.                 if (self::getMobileDevice($request)) {
  793.                     $flierCategoryList[$i]['saleList'] = array_slice($flierCategoryList[$i]['saleList'], 04);
  794.                 }
  795.                 $i++;
  796.             }
  797.         }
  798.         if ($selectedCity) {
  799.             foreach ($flierCategoryList as $key => $item) {
  800.                 $saleListTemp = [];
  801.                 foreach ($item['saleList'] as $sale) {
  802.                     if (in_array($sale->getID(), $selectedCity['entityList'])) {
  803.                         $saleListTemp[] = $sale;
  804.                     }
  805.                 }
  806.                 $flierCategoryList[$key]['saleList'] = $saleListTemp;
  807.                 $flierCategoryList[$key]['category']->setEntityCount(count($saleListTemp));
  808.             }
  809.         }
  810.         $data['flierCategoryList'] = $flierCategoryList;
  811.         $view $isMobileDevice 'Slivki/mobile/sale/flier/hyper_shop.html.twig' 'Slivki/sale/hyper_shop.html.twig';
  812.         return $this->render($view$data);
  813.     }
  814.     /** @Route("/new-hyper-shop/more/{offset}/{limit}") */
  815.     public function hyperShopMoreAction(Request $request$limit$offset) {
  816.         $fliers $this->getSaleRepository()->getActiveSalesByCategoryID(Category::FLIER_SALE_CATEGORY_ID);
  817.         $result '';
  818.         $view self::getMobileDevice($request) ? 'Slivki/mobile/sale/flier/teaser.html.twig' 'Slivki/sale/flier.html.twig';
  819.         foreach (array_slice($fliers$offset$limit) as $sale) {
  820.             $result .= $this->renderView($view, ['sale' => $sale'additionalClass' => 'swiper-slide']);
  821.         }
  822.         return new Response($result);
  823.     }
  824. }