- <?php
- namespace Slivki\Controller;
- use Doctrine\ORM\Query;
- use Slivki\Dao\Comment\CommentRatingDaoInterface;
- use Slivki\Dao\GiftCertificate\GiftCertificateDaoInterface;
- use Slivki\Dao\Offer\FavouriteOfferDaoInterface;
- use Slivki\Dao\Offer\OfferDaoInterface;
- use Slivki\Dao\OfferCode\PurchaseCountWithCorrectionDaoInterface;
- use Slivki\Dao\TireFilter\TireFilterDaoInterface;
- use Slivki\Entity\AlternativeOffer;
- use Slivki\Entity\BankCurrency;
- use Slivki\Entity\Banner\MobileLandingBanner;
- use Slivki\Entity\Director;
- use Slivki\Entity\FoodOrder;
- use Slivki\Entity\GiftCertificate;
- use Slivki\Entity\MailingCampaign;
- use Slivki\Entity\SearchQuery;
- use Slivki\Entity\Seo;
- use Slivki\Entity\UserPhone;
- use Slivki\Enum\SwitcherFeatures;
- use Slivki\Repository\Comment\CommentRepositoryInterface;
- use Slivki\Services\CategoryBoxCacheService;
- use Slivki\Services\City\CityProvider;
- use Slivki\Services\Comment\CommentCacheService;
- use Slivki\Services\Comment\CommentService;
- use Slivki\Services\DeviceTypeService;
- use Slivki\Services\Offer\GalleryVideo\VideoPackageDtoGetter;
- use Slivki\Services\Sidebar\SidebarCacheService;
- use Slivki\Services\Subscription\SubscriptionService;
- use Slivki\Services\Switcher\ServerFeatureStateChecker;
- use Slivki\Services\VoiceMessage\VoiceMessageUploader;
- use Slivki\Util\Iiko\Dodo;
- use Slivki\Util\Iiko\Dominos;
- use Symfony\Component\HttpFoundation\Cookie;
- use Symfony\Component\Routing\Annotation\Route;
- use Slivki\Entity\Booking;
- use Slivki\Entity\Category;
- use Slivki\Entity\ChatSession;
- use Slivki\Entity\City;
- use Slivki\Entity\Comment;
- use Slivki\Entity\CommentLike;
- use Slivki\Entity\EntityOption;
- use Slivki\Entity\GeoLocation;
- use Slivki\Entity\HotFeed;
- use Slivki\Entity\InfoPage;
- use Slivki\Entity\MainMenu;
- use Slivki\Entity\Media;
- use Slivki\Entity\MediaType;
- use Slivki\Entity\Offer;
- use Slivki\Entity\OfferOrder;
- use Slivki\Entity\OfferProposal;
- use Slivki\Entity\ReadabilityStat;
- use Slivki\Entity\Sale;
- use Slivki\Entity\SearchStatistic;
- use Slivki\Entity\Subscriber;
- use Slivki\Entity\User;
- use Slivki\Entity\UserGroup;
- use Slivki\Repository\CityRepository;
- use Slivki\Repository\CommentRepository;
- use Slivki\Repository\OfferRepository;
- use Slivki\Repository\SaleRepository;
- use Slivki\Repository\SeoRepository;
- use Slivki\Services\BannerService;
- use Slivki\Services\CacheService;
- use Slivki\Services\Category\CategoryCacheService;
- use Slivki\Services\Mailer;
- use Slivki\Services\Offer\OfferCacheService;
- use Slivki\Services\Sale\SaleCacheService;
- use Slivki\Services\TextCacheService;
- use Slivki\Twig\SlivkiTwigExtension;
- use Slivki\Util\CommonUtil;
- use Slivki\Util\Iiko\AbstractDelivery;
- use Slivki\Util\Iiko\SushiHouse;
- use Slivki\Services\ImageService;
- use Slivki\Util\Logger;
- use Slivki\Util\SoftCache;
- use Slivki\Util\CensureLibrary\Censure;
- use Symfony\Component\HttpFoundation\JsonResponse;
- use Symfony\Component\HttpFoundation\Request;
- use Symfony\Component\HttpFoundation\Response;
- use Symfony\Component\Filesystem\Filesystem;
- use Slivki\Entity\Visit;
- use Symfony\Component\HttpKernel\KernelInterface;
- use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
- use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
- use Symfony\Component\Validator\Constraints\Email;
- class DefaultController extends SiteController {
-     const OFFERS_PER_PAGE = 24;
-     const LONG_CATEGORIES_PER_PAGE = 36;
-     const SIDEBAR_CACHE_PATH = '/slivki-cache/sidebar';
-     const CATEGORY_BOX_PATH = '/slivki-cache/categorybox/';
-     const LONG_CATEGORIES = [
-         Category::TIRE_FITTING_CATEGORY_ID,
-         Category::LASER_EPILATION_CATEGORY_ID,
-     ];
-     private TireFilterDaoInterface $tireFilterDao;
-     private OfferDaoInterface $offerDao;
-     private CommentRatingDaoInterface $commentRatingDao;
-     public function __construct(
-         KernelInterface           $kernel,
-         TireFilterDaoInterface    $tireFilterDao,
-         OfferDaoInterface         $offerDao,
-         CommentRatingDaoInterface $commentRatingDao
-     ) {
-         parent::__construct($kernel);
-         $this->tireFilterDao = $tireFilterDao;
-         $this->offerDao = $offerDao;
-         $this->commentRatingDao = $commentRatingDao;
-     }
-     /**
-      * @Route("/", name="homepage")
-      */
-     public function indexAction(
-         Request $request,
-         BannerService $bannerService,
-         OfferCacheService $offerCacheService,
-         SaleCacheService $saleCacheService,
-         CategoryBoxCacheService $categoryBoxCacheService,
-         CategoryCacheService $categoryCacheService,
-         CommentRepositoryInterface $commentRepository
-     ) {
-         $isMobileDevice = self::getMobileDevice($request);
-         if ($request->getHost() == 'm.slivki.by') {
-             return $this->render($isMobileDevice? 'Slivki/m/mobile/index.html.twig' : 'Slivki/m/index.html.twig');
-         }
-         $cityID = $request->getSession()->get(City::CITY_ID_SESSION_KEY, City::DEFAULT_CITY_ID);
-         $referrer = $request->headers->get('referer', '');
-         $response = new Response();
-         if (self::getMobileDevice($request)) {
-             $urlParsed = parse_url($referrer);
-             $referrerHost = isset($urlParsed['host']) ? $urlParsed['host']: '';
-             if ($referrer != $request->getSchemeAndHttpHost() . '/landing' && $referrerHost != $request->getHost() && $cityID == City::DEFAULT_CITY_ID) {
-                 return $this->redirect('/landing');
-             }
-         }
-         $mainMenuItems = $this->getDoctrine()->getManager()->getRepository(MainMenu::class)->getItemListCached(MainMenu::MENU_ID_MAIN, $cityID);
-         $categoryBoxList = [];
-         $expanded = count($mainMenuItems) == 1;
-         $i = 0;
-         foreach ($mainMenuItems as $menuItem) {
-             $category = $categoryCacheService->getCategory($menuItem->getEntityID());
-             $categoryBoxTarantool = $categoryBoxCacheService->getCategoryBox(
-                 $menuItem->getEntityID(),
-                 CategoryBoxCacheService::SORT_BY_DEFAULT_COLUMN,
-                 $isMobileDevice,
-                 0,
-                 $category[8]
-             );
-             $categoryBox = \str_replace(
-                 '<!-- categoryTeasersPlaceholder -->',
-                 $categoryBoxTarantool['categoryBoxHtml'],
-                 $categoryBoxCacheService->getCategoryPage($menuItem->getEntityID(), false, $isMobileDevice)
-             );
-             if ($categoryBox) {
-                 $categoryBoxList[$menuItem->getEntityID()] = $categoryBox;
-             }
-             if ($i == 0) {
-                 break;
-             }
-             $i++;
-         }
-         // getSidebarBanner
-         if (!$isMobileDevice) {
-             if ($this->getUser() && $this->getUser()->hasRole(UserGroup::ROLE_ADS_FREE)) {
-                 $data['sidebarBanner'] = '';
-             } else {
-                 $sidebarBannerCached = $bannerService->getSidebarBannerCached($cityID);
-                 $data['sidebarBanner'] = $sidebarBannerCached['html'];
-             }
-             $data['lastComments'] = $commentRepository->getLastOfferComments(3);
-         }
-         $data['categoryBoxList'] = $categoryBoxList;
-         $data['salesList'] = $this->getSaleRepository()->getMainSales($cityID, self::getMobileDevice($request));
-         $data['mainPage'] = true;
-         $data['smallCity'] = $expanded;
-         $deviceType = $isMobileDevice ? self::DEVICE_TYPE_MOBILE : self::DEVICE_TYPE_DESKTOP;
-         $this->addVisit(0, Visit::TYPE_MAIN_PAGE, $deviceType, $this->getUser(), $request->getClientIp(), $referrer);
-         $data['cityID'] = $cityID;
-         $request->attributes->set('mainPage', true);
-         $data['offerRateSchedule'] = $this->getOfferRateSchedule($request->getSession());
-         $mainHotFeed = '';
-         $mainHotFeedEntities = $this->getMainHotFeed($offerCacheService, $saleCacheService, 20, 0, HotFeed::TYPE_MAIN_PAGE, $cityID);
-         if (count($mainHotFeedEntities) > 4) {
-             foreach ($mainHotFeedEntities as $entity) {
-                 $mainHotFeed .= $this->renderView($isMobileDevice ? 'Slivki/mobile/hot_feed_teaser.html.twig'
-                     : 'Slivki/top_main_feed_teaser_mobile.html.twig',  $entity);
-             }
-         }
-         $data['mainHotFeed'] = $mainHotFeed;
-         $topLevelCategoryIDList = [];
-         foreach ($mainMenuItems as $menuItem) {
-             $topLevelCategoryIDList[] = $menuItem->getEntityID();
-         }
-         $data['topLevelCategoryIDList'] = $topLevelCategoryIDList;
-         $response->setContent($this->renderView($isMobileDevice ? 'Slivki/mobile/index.html.twig' : 'Slivki/index.html.twig', $data));
-         return $response;
-     }
-     /** @Route("/auth") */
-     public function auth(Request $request) {
-         $path = $request->query->get('path', '/');
-         $response = new Response();
-         if ($this->getUser()) {
-             return $this->redirect($path);
-         }
-         return $this->render(CommonUtil::isMobileDevice($request) ? 'Slivki/mobile/auth.html.twig' : 'Slivki/auth.html.twig');
-     }
-     /** @Route("/main_top_sales/{offset}") */
-     public function getMainOffsetSales(Request $request, $offset) {
-         $cityID = $request->getSession()->get(City::CITY_ID_SESSION_KEY, City::DEFAULT_CITY_ID);
-         $result = [];
-         $data['sale'] = $this->getSaleRepository()->getMainSales($cityID, self::getMobileDevice($request), $offset);
-         foreach ($data['sale'] as $sale) {
-             $result['result'][] = $this->renderView('Slivki/news/mobile_top_news.html.twig', $sale);
-         }
-         return new JsonResponse($result);
-     }
-     /** @Route("/main_hot_feed/{limit}/{offset}/{type}/{isNewMobileVersion}/{cityID}") */
-     public function getMainHotFeedAction(Request $request, SaleCacheService $saleCacheService, OfferCacheService $offerCacheService, $limit, $offset, $type, $isNewMobileVersion, $cityID) {
-         $result = '';
-         foreach ($this->getMainHotFeed($offerCacheService, $saleCacheService, $limit, $offset, $type, $cityID) as $entity) {
-             $result .= $this->renderView($isNewMobileVersion == 'true' ?  'Slivki/mobile/hot_feed_teaser.html.twig':
-                 'Slivki/top_main_feed_teaser_mobile.html.twig',  $entity);
-         }
-         return new Response($result);
-     }
-     public function categoryAction(
-         Request $request,
-         CategoryCacheService $categoryCacheService,
-         CategoryBoxCacheService $categoryBoxCacheService,
-         $entityID
-     ) {
-         return $this->tarantoolCategory($request, $categoryCacheService, $categoryBoxCacheService, $entityID);
-     }
-     private function tarantoolCategory(
-         Request $request,
-         CategoryCacheService $categoryCacheService,
-         CategoryBoxCacheService $categoryBoxCacheService,
-         $entityID
-     ) {
-         $currentPage = $request->query->get('page', 1);
-         $isMobileDevice = CommonUtil::isMobileDevice($request);
-         $deviceType = $isMobileDevice ? self::DEVICE_TYPE_MOBILE : self::DEVICE_TYPE_DESKTOP;
-         $this->addVisit(
-             $entityID,
-             Visit::TYPE_OFFER_CATEGORY,
-             $deviceType,
-             $this->getUser(),
-             $request->getClientIp(),
-             $request->headers->get('referer', '')
-         );
-         $category = $categoryCacheService->getCategory($entityID);
-         $response = new Response();
-         $perPage = in_array($entityID, self::LONG_CATEGORIES) ? self::LONG_CATEGORIES_PER_PAGE : self::OFFERS_PER_PAGE;
-         $categoryBox = $categoryBoxCacheService->getCategoryBox(
-             $entityID,
-             CategoryBoxCacheService::SORT_BY_DEFAULT_COLUMN,
-             $isMobileDevice,
-             ($currentPage - 1) * $perPage,
-             $perPage,
-         );
-         $categoryPageContent = str_replace(
-             '<!-- categoryTeasersPlaceholder -->',
-             $categoryBox['categoryBoxHtml'],
-             $categoryBoxCacheService->getCategoryPage($entityID, true, $isMobileDevice)
-         );
-         $paginationHtml = $this->renderView('Slivki/pagination.html.twig', [
-             'paginationID' => 'categoryPagination',
-             'total' => ceil($categoryBox['totalTeaserCount'] / self::OFFERS_PER_PAGE),
-             'current' => $currentPage,
-             'url' => $request->getRequestUri() . '?page='
-         ]);
-         $categoryPageContent = str_replace(
-             '<!-- categoryPaginationPlaceholder -->',
-             $paginationHtml,
-             $categoryPageContent
-         );
-         $tireFilterCategories = $this->tireFilterDao->getCategoriesByParentCategory($entityID);
-         if (0 !== \count($tireFilterCategories)) {
-             $categoryPageContent = \str_replace(
-                 '<!-- tireFilerPlaceholder -->',
-                 $this->renderView('Slivki/tire/tire_filter.html.twig', [
-                     'categories' => $tireFilterCategories,
-                 ]),
-                 $categoryPageContent,
-             );
-         }
-         $data = [
-             'categoryID' => $entityID,
-             'category' => $categoryPageContent,
-             'brandingBannerCategoryIDs' => [$entityID]
-         ];
-         $response->setContent($this->renderView($isMobileDevice ? 'Slivki/mobile/offer/category.html.twig'
-             : 'Slivki/offers/category_page.html.twig', $data));
-         return $response;
-     }
-     public function categoryRatingAction(Request $request, TextCacheService $textCacheService, $entityID) {
-         $isMobile = CommonUtil::isMobileDevice($request);
-         $content = $textCacheService->getText($entityID, $isMobile ? TextCacheService::CATEGORY_COMPANIES_RATING_PAGE_MOBILE_TYPE : TextCacheService::CATEGORY_COMPANIES_RATING_PAGE_TYPE);
-         if (!$content) {
-             throw $this->createNotFoundException();
-         }
-         return $this->render($isMobile ? 'Slivki/mobile/offer/category_rating_page.html.twig' : 'Slivki/offers/category_rating_page.html.twig', [
-             'content' => $content,
-             'robotsMeta' => 'noindex, follow'
-         ]);
-     }
-     /** @Route("/category/load-more/{categoryID}/{pageNumber}/{sortBy}") */
-     public function categoryLoadMoreAction(
-         Request $request,
-         CategoryBoxCacheService $categoryBoxCacheService,
-         $categoryID,
-         $pageNumber,
-         $sortBy
-     ) {
-         return $this->categoryLoadMoreTarantool($request, $categoryBoxCacheService, $categoryID, $pageNumber, $sortBy);
-     }
-     private function categoryLoadMoreTarantool(
-         Request $request,
-         CategoryBoxCacheService $categoryBoxCacheService,
-         $categoryID,
-         $pageNumber,
-         $sortBy
-     ) {
-         $referer = $request->headers->get('referer');
-         if (!$referer) {
-             return new Response('Referer is invalid or empty.');
-         }
-         $refererPathInfo = Request::create($referer)->getPathInfo();
-         $isMobileDevice = CommonUtil::isMobileDevice($request);
-         switch ($sortBy) {
-             case 'popularity':
-                 $sortByColumn = CategoryBoxCacheService::SORT_BY_PURCHASE_COLUMN;
-                 break;
-             case 'visit':
-                 $sortByColumn = CategoryBoxCacheService::SORT_BY_VISIT_COLUMN;
-                 break;
-             case 'distance':
-             case 'timetable':
-             case 'rating':
-                 break;
-             case 'update-date':
-                 $sortByColumn = CategoryBoxCacheService::SORT_BY_CREATED_ON_COLUMN;
-                 break;
-             case 'price-asc':
-                 $sortByColumn = CategoryBoxCacheService::SORT_BY_PRICE_ASC_COLUMN;
-                 break;
-             case 'price-desc':
-                 $sortByColumn = CategoryBoxCacheService::SORT_BY_PRICE_DESC_COLUMN;
-                 break;
-             default:
-                 $sortByColumn = CategoryBoxCacheService::SORT_BY_DEFAULT_COLUMN;
-         }
-         $perPage = in_array($categoryID, self::LONG_CATEGORIES) ? self::LONG_CATEGORIES_PER_PAGE : self::OFFERS_PER_PAGE;
-         if ($sortBy == 'distance') {
-             $categoryBox = $categoryBoxCacheService->getCategoryBoxSortedByLocation(
-                 $categoryID,
-                 $request->cookies->get(User::CURRENT_LOCATION_COOKIE, GeoLocation::DEFAULT_LOCATION),
-                 $isMobileDevice,
-                 ($pageNumber - 1) * $perPage,
-                 $perPage,
-             );
-         } elseif ($sortBy == 'timetable') {
-             $categoryBox = $categoryBoxCacheService->getCategoryBoxSortedByTimetable(
-                 $categoryID,
-                 $isMobileDevice,
-                 ($pageNumber - 1) * $perPage,
-                 $perPage,
-             );
-         } elseif ($sortBy == 'rating') {
-             $categoryBox = $categoryBoxCacheService->getCategoryBoxSortedByRating(
-                 $categoryID,
-                 $isMobileDevice,
-                 ($pageNumber - 1) * $perPage,
-                 $perPage,
-             );
-         } else {
-             $categoryBox = $categoryBoxCacheService->getCategoryBox(
-                 $categoryID,
-                 $sortByColumn,
-                 $isMobileDevice,
-                 ($pageNumber - 1) * $perPage,
-                 $perPage,
-             );
-         }
-         return new JsonResponse([
-             'teasers' => $categoryBox['categoryBoxHtml'],
-             'pagination' => $this->renderView('Slivki/pagination.html.twig', [
-                 'paginationID' => 'categoryPagination',
-                 'total' => ceil($categoryBox['totalTeaserCount'] / self::OFFERS_PER_PAGE),
-                 'current' => $pageNumber,
-                 'url' => $refererPathInfo . '?page='
-             ])
-         ]);
-     }
-     /**
-      * @Route("/categoryBoxNotExpanded/{categoryID}")
-      */
-     public function categoryBoxNotExpandedAction(
-         Request $request,
-         CategoryBoxCacheService $categoryBoxCacheService,
-         CategoryCacheService $categoryCacheService,
-         $categoryID
-     ) {
-         $isMobileDevice = CommonUtil::isMobileDevice($request);
-         $category = $categoryCacheService->getCategory($categoryID);
-         $categoryBoxTarantool = $categoryBoxCacheService->getCategoryBox(
-             $categoryID,
-             CategoryBoxCacheService::SORT_BY_DEFAULT_COLUMN,
-             $isMobileDevice,
-             0,
-             $category[8]
-         );
-         $categoryBox = \str_replace(
-             '<!-- categoryTeasersPlaceholder -->',
-             $categoryBoxTarantool['categoryBoxHtml'],
-             $categoryBoxCacheService->getCategoryPage($categoryID, false, $isMobileDevice)
-         );
-         return new Response($categoryBox);
-     }
-     /**
-      * @Route("/moreOffers")
-      */
-     public function moreOffers(Request $request) {
-         $categoryID = (int)$request->query->get("categoryID", 0);
-         $data['categoryBoxID'] = $request->query->get("categoryBoxId", 0);
-         $moreCount = (int)$request->query->get("moreCount", 150);
-         $position = (int)$request->query->get("position", 0);
-         $category = $this->getCategoryRepository()->findCached($categoryID)['category'];
-         if (!$category) {
-             return new Response();
-         }
-         $offerIDList = [];
-         $sql = "select entity_id from offer_category_position where category_id = $categoryID order by position offset $position limit $moreCount + 1";
-         $offersByPosition = $this->getDoctrine()->getManager()->getConnection()->executeQuery($sql)->fetchAll(Query::HYDRATE_ARRAY);
-         $i = 0;
-         foreach ($offersByPosition as $offerPosition) {
-             if ($i>=$moreCount) {
-                 break;
-             }
-             $offerIDList[] = $offerPosition['entity_id'];
-             $i++;
-         }
-         $softCache = new SoftCache(OfferRepository::CACHE_NAME);
-         $offerListCached = $softCache->getMulti($offerIDList);
-         if(!$offerListCached) {
-             return new Response('');
-         }
-         $moreOfferList = [];
-         foreach ($offerListCached as $offer) {
-             $moreOfferList[] = $offer;
-         }
-         $data['position'] = $position + $moreCount;
-         $data['expanded'] = !count($offersByPosition) > count($offerIDList);
-         $data['showCollapse'] = true;
-         $data['isMailing'] = false;
-         $teaserBanners = $this->getOfferRepository()->getTeaserBanners($category);
-         $data['teaserBanners'] = $teaserBanners['teaserBanners'];
-         $data['absolutePosition'] = $position + 1;
-         $data['withVerticalBannersRowList'] = $teaserBanners['withVerticalBannersRowList'];
-         $data['category'] = $category;
-         $data['offerList'] = $moreOfferList;
-         $response = $this->render("Slivki/offers/teasers.html.twig", $data);
-         return $response;
-     }
-     public function detailsAction(
-         Request $request,
-         BannerService $bannerService,
-         OfferCacheService $offerCacheService,
-         CacheService $cacheService,
-         $entityID,
-         ImageService $imageService,
-         SubscriptionService $subscriptionService,
-         GiftCertificateDaoInterface $giftCertificateDao,
-         ServerFeatureStateChecker $serverFeatureStateChecker,
-         VideoPackageDtoGetter $videoPackageDtoGetter,
-         CityProvider $cityProvider,
-         PurchaseCountWithCorrectionDaoInterface $purchaseCountWithCorrectionDao,
-         FavouriteOfferDaoInterface $favouriteOfferDao,
-         CommentService $commentService
-     ) {
-         ini_set('memory_limit', '10g');
-         $data['currentPage'] = $request->query->getInt('page', 1);
-         $this->get('session')->set('userCommentImages', []);
-         $entityManager = $this->getDoctrine()->getManager();
-         $offerRepository = $this->getOfferRepository();
-         $offer = $offerCacheService->getOffer($entityID, false, true);
-         $data['usersWithOfferInFavouritesCount'] = $favouriteOfferDao->getUsersWithOfferInFavouritesCount($entityID);
-         if ($offer instanceof Offer && $offer->getDefaultCityId() === City::TASHKENT_CITY_ID && $cityProvider->getDefaultCityId() !== City::TASHKENT_CITY_ID) {
-             return $this->redirect('https://www.slivki.uz' . $request->getRequestUri(), Response::HTTP_MOVED_PERMANENTLY);
-         }
-         if ($offer instanceof Offer && $offer->getDefaultCityId() !== City::TASHKENT_CITY_ID && $cityProvider->getDefaultCityId() === City::TASHKENT_CITY_ID) {
-             Logger::instance('excdebug')->info($offer->getDefaultCityId());
-             Logger::instance('excdebug')->info($cityProvider->getDefaultCityId());
-             //throw $this->createNotFoundException();
-         }
-         $dreamLangPartner = $request->getSession()->get(EntityOption::OPTION_DREAMLAND_PARTNER);
-         if ($this->getUser() && $dreamLangPartner && !$entityManager->getRepository(User::class)->getDreamlandOption($this->getUser()->getID())) {
-             $option = new EntityOption();
-             $option->setEntityTypeID(EntityOption::USER_TYPE);
-             $option->setEntityID($this->getUser()->getID());
-             $option->setName(EntityOption::OPTION_DREAMLAND_PARTNER);
-             $option->setValue($dreamLangPartner);
-             $entityManager->persist($option);
-             $entityManager->flush();
-             $request->getSession()->remove(EntityOption::OPTION_DREAMLAND_PARTNER);
-         }
-         $pastOffer = false;
-         $timeNow = new \DateTime();
-         $preview = $request->query->get("preview", false);
-         if (!$offer || $preview) {
-             $offer = $offerRepository->find($entityID);
-             if (!$offer || ((!$offer->isInVisiblePeriod() || !$offer->isActive()) && !$preview)) {
-                 throw $this->createNotFoundException();
-             }
-             if ((!$offer->isActive() || $offer->getActiveTill() < $timeNow || $offer->getActiveSince() > $timeNow) && !$preview) {
-                 $pastOffer = true;
-             }
-             if ($preview || $pastOffer) {
-                 $mediaRepository = $this->getMediaRepository();
-                 $offer->setDetailMeidas($mediaRepository->getOfferDetailMedias($offer->getID()));
-                 $offer->setShopMedias($mediaRepository->getOfferShopMedias($offer->getID()));
-             } else {
-                 Logger::instance('CACHE DEBUG')->info('Offer ' . $entityID . ' is not found in cache');
-                 $offer = $offerCacheService->reloadOfferCache($entityID);
-             }
-         }
-         if ((!$offer->isActive() || $offer->getActiveTill() < $timeNow || $offer->getActiveSince() > $timeNow) && !$preview) {
-             $pastOffer = true;
-         }
-         if ($entityID == 131841 && ($pastOffer || $offer->isHidden())) { // issue #2688
-             return $this->redirect($this->getSeoRepository()->getByEntity(SeoRepository::RESOURCE_URL_OFFER_CATEGORY, 509)->getMainAlias());
-         }
-         if ($offer->isHidden()) {
-             throw $this->createNotFoundException();
-         }
-         $response = new Response();
-         $offerRateSchedule = $this->getOfferRateSchedule($request->getSession());
-         if ($offerRateSchedule) {
-             if ($offerRateSchedule->getOffer()->getID() == $entityID) {
-                 $request->getSession()->set(SiteController::LAST_OFFER_RATE_ACTIVITY_PARAMETER_NAME, time());
-                 $sql = 'delete from offer_rate_schedule where user_id = ' . (int)$this->getUser()->getID() . ' and offer_id = ' . (int)$entityID;
-                 $entityManager->getConnection()->executeQuery($sql);
-             } else {
-                 $data['offerRateSchedule'] = $offerRateSchedule;
-             }
-         }
-         $data['pastOffer'] = $pastOffer;
-         $data['todayPurchaseCount'] = $purchaseCountWithCorrectionDao->findLastDayByOfferId($offer->getID());
-         if (!$pastOffer && $offer->getFreeCodesCount() > 0) {
-             $lastPurchaseTime = $offerRepository->getLastPurchaseTime($offer->getID());
-             if ($lastPurchaseTime) {
-                 $now = new \DateTime();
-                 $lastPurchaseInterval = $now->diff($lastPurchaseTime);
-                 $lastPurchaseText = '';
-                 if ($lastPurchaseInterval->h > 0) {
-                     $lastPurchaseText = $lastPurchaseInterval->h . ' час' . CommonUtil::plural(['', 'а', 'ов'], $lastPurchaseInterval->h) . ' ';
-                 }
-                 $lastPurchaseMinutes = $lastPurchaseInterval->h == 0 && $lastPurchaseInterval->i < 2 ? 1 : $lastPurchaseInterval->i;
-                 $lastPurchaseText .= $lastPurchaseMinutes . ' минут' . CommonUtil::plural(['у', 'ы', ''], $lastPurchaseMinutes) . ' назад';
-                 $data['lastPurchaseText'] = $lastPurchaseText;
-             }
-         } elseif (!self::getMobileDevice($request)) {
-             $data['relatedOfferListHtml'] = implode('', $this->getRelatedOffersTeasers($cacheService, $offer));
-         }
-         $data['offer'] = $offer;
-         $data['galleryVideos'] = $videoPackageDtoGetter->getByOfferId($offer->getID());
-         $userGeoLocation = $request->cookies->get(User::CURRENT_LOCATION_COOKIE, null);
-         if ($userGeoLocation) {
-             $userGeoLocation = explode(',', $userGeoLocation);
-         }
-         $data['offerGeoLocationData'] = $offerRepository->getOfferGeoLocationData($offer, $userGeoLocation, $imageService);
-         $data['freeCodesCount'] = 0;
-         $buyCodePopup = "";
-         /** @var User $user */
-         $user = $this->getUser();
-         $data['offerIsFreeForUser'] = $offerRepository->isOfferFreeForUser($offer, $user);
-         $codeCost = $offerRepository->getCodeCost($offer);
-         if (!$pastOffer) {
-             if ($user && !$subscriptionService->isSubscriber($user) && !$data['offerIsFreeForUser']) {
-                 $data['testSubscriptionGroupID'] = true;
-             }
-             $data['canBuyFromBalance'] = false;
-             $data['freeCodesCount'] = $offer->getFreeCodesCount();
-             if ($offer->getID() != Offer::DREAMLAND_OFFER_ID) {
-                 if (!$user) {
-                     $buyCodePopup = ".modal-auth";
-                 } else {
-                     if ($user->getFullBalance() >= $codeCost || $data['offerIsFreeForUser']) {
-                         $buyCodePopup = "#confirmBox";
-                         $data['canBuyFromBalance'] = true;
-                     }
-                     if (isset($data['testSubscriptionGroupID'])) {
-                         $buyCodePopup = "#confirmBox";
-                     }
-                 }
-             }
-         }
-         if (!$serverFeatureStateChecker->isServerFeatureEnabled(SwitcherFeatures::REPLENISHMENT_BALANCE())) {
-             $buyCodePopup = "#confirmBox";
-             $data['canBuyFromBalance'] = false;
-         }
-         if ($user) {
-             $subscription = $subscriptionService->getSubscription($user);
-             $data['allowedCodesCountBySubscription'] = $subscriptionService->isSubscriber($user)
-                 ? $subscription->getNumberOfCodes()
-                 : 0;
-         }
-         $buyButtonLabel = 'Получить скидку ';
-         if ($data['offer']->isOneOfOnlineOrderAllowedOnSite()) {
-             $buyButtonLabel = 'Получить промокод ';
-         }
-         if ($data['offerIsFreeForUser']) {
-             $buyButtonLabel = 'Бесплатный промокод';
-         } else {
-             if ($offer->isActiveCurrencyCalculator() && is_numeric($offer->getDiscount())) {
-                 $bankCurrency = $entityManager->getRepository(BankCurrency::class)->findOneBy(['currency' => $offer->getBankCurrency()->getCurrency()]);
-                 if ($bankCurrency) {
-                     $buyButtonLabel .= round($bankCurrency->getRate() * $offer->getDiscount(), 2);
-                 }
-             } else {
-                 $buyButtonLabel .= $offer->getDiscount();
-             }
-             $buyButtonLabel = mb_strtoupper($buyButtonLabel);
-         }
-         if ($entityID == Offer::DREAMLAND_OFFER_ID) {
-             $buyButtonLabel = 'Купить билет от ' . $offer->getOfferPrice($offer)  . ' руб.';
-         }
-         $isMobile = CommonUtil::isMobileDevice($request);
-         $commentsCacheName = $isMobile ? CommentCacheService::MOBILE_CACHE_NAME : CommentCacheService::CACHE_NAME;
-         if ($data['currentPage'] == 1) {
-             $comments = $this->getComments($request, $bannerService, $entityID, Comment::TYPE_OFFER_COMMENT, 0, 0, 0, $commentsCacheName);
-         } else {
-             $comments = $this->getCommentsByOffer($entityID, $data['currentPage'], CommentRepository::COMMENTS_PER_PAGE, $isMobile);
-         }
-         $commentsAmount = $this->getCommentRepository()->getCommentsCountByEntityID($entityID, Comment::TYPE_OFFER_COMMENT);
-         $offerRating = $this->commentRatingDao->getCommentRatingByOfferId($offer->getID());
-         $data['comments'] = $this->renderView($isMobile ? 'Slivki/mobile/comment/block.html.twig' : 'Slivki/comments/comments_list.html.twig', [
-             'entityID' => $entityID,
-             'type' => Comment::TYPE_OFFER_COMMENT,
-             'comments' => $comments,
-             'commentsAmount' => $commentsAmount,
-             'showCommentsAmount' => true,
-             'rating' => $offerRating,
-         ]);
-         $data['items'] = []; //$offer->getItems();
-         $dataItemsCount = count($data['items']);
-         if ($dataItemsCount > 0) {
-             $minOfferPrice = INF;
-             foreach ($data['items'] as $item) {
-                 if ($item->getOfferPrice() < $minOfferPrice) {
-                     $minOfferPrice = $item->getOfferPrice();
-                 }
-             }
-             $buyButtonLabel = 'Купить билет от ' . number_format($minOfferPrice,2, ',', '') . ' руб.';
-         }
-         $buyCodeBtnText = $offer->getBuyCodeButtonText();
-         $buyCodeBtnText = $buyCodeBtnText ? $buyCodeBtnText : '';
-         $data['buyButtonLabel'] = $buyCodeBtnText == '' ? mb_strtoupper(mb_substr($buyButtonLabel, 0, 1)) . mb_strtolower(mb_substr($buyButtonLabel, 1)) : $buyCodeBtnText;
-         if ($offer->isOneOfOnlineOrderAllowedOnSite()) {
-             $data['buyButtonLabelOnline'] = $offer->isBuyCodeDisable() ? 'Оформить сертификат онлайн' : 'Заказать онлайн';
-         }
-         $data['isAllowedByOnlyCode'] =  $dataItemsCount == 0 || ($dataItemsCount > 0 && $offer->isAllowedBuyOnlyCode());
-         $data['showGlobalcard'] = false;
-         $data['showGlobalcardFitness'] = false;
-         $data['tour3dName'] = '';
-         $softCache = new SoftCache(OfferRepository::CACHE_NAME);
-         $cacheKey = 'alt-offers-box-' . $entityID;
-         $altOffersBox = $softCache->get($cacheKey);
-         if ($altOffersBox == SoftCache::LOCKED_KEY) {
-             $altOffersBox = $softCache->getDataForLockedKey($cacheKey, 30);
-         } else if (!$altOffersBox) {
-             $softCache->add($cacheKey, SoftCache::LOCKED_KEY, 30);
-             $cacheExpire = strtotime(date('Y-m-d 05:00:00', strtotime('+1 day'))) - time();
-             $altOffersBox = "";
-             $altOfferList = $this->getDoctrine()->getRepository(AlternativeOffer::class)->getByOfferID($entityID);
-             if ($altOfferList) {
-                 if (count($altOfferList) < 3) {
-                     $altOffersBox = SoftCache::EMPTY_VALUE;
-                 } else {
-                     if (count($altOfferList) < 6) {
-                         $altOfferList = array_slice($altOfferList, 0, 3);
-                     }
-                     foreach ($altOfferList as $altOffer) {
-                         $alternativeOffer = $offerCacheService->getOffer($altOffer->getAlternativeOfferID(), true);
-                         if ($alternativeOffer) {
-                             $altOffersBox .= $this->get('twig')->render('Slivki/offers/teaser.html.twig', ['offer' => $alternativeOffer, 'noLazyLoad' => true]);
-                         } else {
-                             $this->getLogger()->error('Alternative offer ' . $altOffer->getOfferID() . " not found in cache");
-                             $altOffersBox = "";
-                             break;
-                         }
-                     }
-                 }
-             }
-             $softCache->set($cacheKey, $altOffersBox, $cacheExpire);
-             if ($altOffersBox == SoftCache::EMPTY_VALUE) {
-                 $altOffersBox = "";
-             }
-         }
-         if ($user && $subscriptionService->isSubscriber($user)) {
-             $buyCodePopup = '#confirmBox';
-         }
-         $data['altOffersBox'] = $altOffersBox;
-         $data['geoLocations'] = $offer->getGeoLocations();
-         $data['codeCost'] = $codeCost;
-         $data['buyCodePopup'] = $buyCodePopup;
-         $data['siteSettings'] = $this->getSiteSettings();
-         $data['parentCategoryList'] = $this->getParentCategoryList($request, $offer->getDefaultCategoryID());
-         $data['categoryURL'] = '/';
-         $data['preview'] = $preview;
-         $data['commentsAmount'] = $this->getCommentRepository()->getCommentsCountByEntityID($offer->getID(), Comment::TYPE_OFFER_COMMENT);
-         $data['isOfferFavourite'] = $user ? $user->isOfferFavourite($offer) : false;
-         $data['detailMediaList'] = $offer->getDetailMedias();
-         $data['foodExtensions'] = $offer->getFoodExtensions();
-         $categoryRepository =  $this->getDoctrine()->getManager()->getRepository(Category::class);
-         $categoryID = $offer->getDefaultCategoryID();
-         if ($categoryID) {
-             $category = $categoryRepository->findCached($categoryID);
-             if (!$category) {
-                 $category['category'] = $categoryRepository->find($categoryID);
-             }
-             if ($category['category'] && $category['category']->isActive() && !$category['category']->isPast()) {
-                 $data['categoryURL'] = $this->getSeoRepository()->getCategoryURL($category['category']);
-             }
-         }
-         $deviceType = self::getMobileDevice($request) ? self::DEVICE_TYPE_MOBILE : self::DEVICE_TYPE_DESKTOP;
-         $this->addVisit($entityID, Visit::TYPE_OFFER, $deviceType, $user, $request->getClientIp());
-         if ($entityID == Offer::FITNESS_WORLD_OFFER_ID) {
-             $data['fitnessOffer'] = true;
-         }
-         $data['confirmedUserPhoneNumber'] = null;
-         $dateDiff = date_diff($offer->getActiveTill(), new \DateTime());
-         $data['daysLeft'] = $dateDiff->days;
-         $data['hoursLeft'] = $dateDiff->format('%h');
-         $data['minutesLeft'] = $dateDiff->format('%i');
-         $data['usedCodesCount'] = $pastOffer
-             ? $offer->getUsedCodesCountForPastOffer()
-             : $purchaseCountWithCorrectionDao->findTotalByOfferId($offer->getID()) + $offer->getLastCodePoolStartPurchaseCount();
-         $data['allCodesCount'] = $data['usedCodesCount'] + $offer->getFreeCodesCount();
-         $data['ratingWithCount'] = $entityManager->getRepository(Comment::class)->getEntityRatingWithCount(Category::OFFER_CATEGORY_ID, $entityID);
-         $data['ratingPercentage'] = $data['ratingWithCount']['rating'] * 100 / 5;
-         $data['todayVisitCount'] = $offerRepository->getVisitCount($offer, true);
-         $data['visitCount'] = $entityManager->getRepository(Visit::class)->getVisitCount($entityID, Visit::TYPE_OFFER, 30, true);
-         $data['phoneNumbersCount'] = count($offer->getPhoneNumbers());
-         if ($entityID == Offer::BOOKING_OFFER_ID) {
-             $entityOption = $entityManager->getRepository(EntityOption::class)->findOneBy([
-                 "entityID" => $entityID,
-                 "entityTypeID" => EntityOption::BOOKING_RESERVED_DATES,
-                 "name" => EntityOption::OPTION_BOOKING_DATES
-             ]);
-             if ($entityOption) {
-                 $dateToFormat = [];
-                 foreach (explode(',', $entityOption->getValue()) as $date) {
-                     $dateToFormat[] = date('Y-m-d', strtotime($date));
-                 }
-                 $data['bookedDates'] = implode(',', $dateToFormat);
-             }
-             $data['bookingTypeList'] = Booking::BOOKING_TYPE_LIST;
-             $userCurrentPhone =  $user ? $user->getCurrentPhone() : null;
-             if ($userCurrentPhone and $userCurrentPhone->isConfirmed()) {
-                 $data['confirmedUserPhoneNumber'] = $userCurrentPhone->getPhoneNumber();
-             }
-         }
-         if ($user && $user->hasRole(UserGroup::STATISTICS_VIEWER)) {
-             $data['yesterdayShareClicks'] = $this->getShareClicks($entityID);
-         }
-         $utmMedium = trim(mb_strtolower($request->query->get('utm_medium', '')));
-         if ($request->query->get('utm_source') == 'search_result' && $utmMedium != '') {
-             $searchQuery = $entityManager->getRepository(SearchQuery::class)
-                 ->findOneByQuery(($utmMedium));
-             if ($searchQuery) {
-                 $searchStatistic = new SearchStatistic();
-                 $searchStatistic->setSearchQuery($searchQuery);
-                 $searchStatistic->setEntityID($offer->getID());
-                 $searchStatistic->setEntityType(SearchStatistic::ENTITY_TYPE_OFFER);
-                 if ($user) {
-                     $searchStatistic->setUserID($user->getID());
-                 }
-                 $searchStatistic->setIpAddress($request->getClientIp());
-                 $searchStatistic->setRefferer($request->headers->get('referer'));
-                 $entityManager->persist($searchStatistic);
-                 $entityManager->flush();
-             }
-         }
-         $codesCount = 1;
-         if ($entityID == Offer::DREAMLAND_OFFER_ID) {
-             $codesCount = 5;
-             if ($user) {
-                 if ($entityManager->getRepository(User::class)->getDreamlandOption($user->getID())) {
-                     $codesCount = 1;
-                 }
-             }
-         }
-         $data['codesCount'] = $codesCount;
-         $data['brandingBannerCategoryIDs'] = $categoryRepository->getParentCategoryIDsByOfferID($entityID);
-         $data['deliveryLink'] = '/delivery/select/' . $offer->getID();
-         $onlineSettings = $offer->getOnlineOrderSettings();
-         if (!$pastOffer && $offer->isOneOfOnlineOrderAllowedOnSite()) {
-             $data['hasDelivery'] = true;
-             $data['foodExtensions'] = [];
-             $data['items'] = [];
-             if (count($offer->getFoodExtensions())) {
-                 $orderUtil = AbstractDelivery::instance($offer);
-                 if ($orderUtil::SPLIT_PAYMENT) {
-                     $data['domain'] = $orderUtil::DOMAIN;
-                 }
-                 if ($onlineSettings && $onlineSettings->isSplitPayment()) {
-                     if ($onlineSettings->getDomain()) {
-                         $data['domain'] = trim($onlineSettings->getDomain());
-                     }
-                 }
-             } elseif ($giftCertificateDao->getCountActiveByOfferId($entityID)) {
-                 $dql = 'select giftCertificate from Slivki:GiftCertificate giftCertificate where giftCertificate.offer = :offer';
-                 $giftCertificates = $entityManager->createQuery($dql)
-                     ->setParameter('offer', $offer)->getResult();
-                 if ($giftCertificates[0]->getLastActiveCodePool()) {
-                     $multiplePoolOfferFreeCodesCount = 0;
-                     $multiplePoolOfferUsedCodesCount = 0;
-                     /** @var GiftCertificate $giftCertificate */
-                     foreach ($giftCertificates as $giftCertificate) {
-                         $giftCertificateCodePool = $giftCertificate->getLastActiveCodePool();
-                         $multiplePoolOfferFreeCodesCount += $giftCertificateCodePool->getFreeCodesCount();
-                         $multiplePoolOfferUsedCodesCount += $giftCertificateCodePool->getUsedCodesCount();
-                     }
-                     $data['multiplePoolOfferFreeCodesCount'] = $multiplePoolOfferFreeCodesCount;
-                     $data['multiplePoolOfferUsedCodesCount'] = $multiplePoolOfferUsedCodesCount;
-                 }
-                 $data['deliveryLink'] = '/gift-certificate/select/' . $offer->getID();
-                 if ($onlineSettings && $onlineSettings->isSplitPayment()) {
-                     if ($onlineSettings->getDomain()) {
-                         $data['domain'] = trim($onlineSettings->getDomain());
-                     }
-                 }
-             } else {
-                 $offer = $entityManager->merge($offer);
-                 if (count($offer->getTireExtensions())) {
-                     $data['deliveryLink'] = '/online-zapis/' . $offer->getID();
-                     if ($onlineSettings && $onlineSettings->isSplitPayment()) {
-                         if ($onlineSettings->getDomain()) {
-                             $data['domain'] = trim($onlineSettings->getDomain());
-                         }
-                     }
-                 }
-             }
-             $directorID = $offer->getDirectorID();
-             if ($offer->getID() == Offer::DREAMLAND_OFFER_ID) {
-                 $data['domain'] = 'mp';
-             } else if ($entityID == 139498) {
-                 $data['domain'] = 'deka';
-             } else if ($entityID == 141075) {
-                 $data['domain'] = 'whitelotus';
-             } else if ($directorID == Director::MARSEL_DIRECTOR_ID) {
-                 $data['domain'] = 'marsel';
-             } else if ($directorID == Director::SHAH_DIRECTOR_ID) {
-                 $data['domain'] = 'shah';
-             } else if ($entityID == Offer::HEROPARK_OFFER_ID) {
-                 $data['domain'] = 'heropark';
-             }
-         }
-         if (isset($data['domain']) && $data['domain'] != '') {
-             $data['deliveryLink'] = 'https://' . $data['domain'] . str_replace('https://www.', '.', $this->getParameter('base_url')) . $data['deliveryLink'];
-         }
-         if ($offer->getExternalOfferLink() && $offer->getIsShowExternalOfferLink()) {
-             $data['deliveryLink'] = $offer->getExternalOfferLink();
-         }
-         if ($user) {
-             $siteSettings = $this->getSiteSettings();
-             $data['subscriptionPrice'] = $subscriptionService->isSubscriptionFinished($user) ? $siteSettings->getSubscriptionPrice() : $siteSettings->getSubscriptionFirstPayment();
-             $data['subscriptionFullPrice'] = $siteSettings->getSubscriptionPrice();
-             $data['subscriptionTerm'] = $subscriptionService->isSubscriptionFinished($user) ? 30 : 7;
-         }
-         if ($preview) {
-             $data['robotsMeta'] = 'noindex, follow';
-         }
-         if (!$offer->hasFreeCodes()) {
-             $data['deliveryLink'] = 'javascript:void(0);';
-         }
-         $data['hadSubscription'] = null !== $user ? $subscriptionService->isExistBySubscriber($user) : false;
-         $data['codeCostInCurrency'] = $offer->getSumInCurrency((float) $codeCost);
-         $data['rating'] = $offerRating;
-         $view = $isMobile ? 'Slivki/mobile/offer/details.html.twig' : 'Slivki/offers/details.html.twig';
-         $response->setContent($this->renderView($view, $data));
-         return $response;
-     }
-     /**
-      * @Route("/offer/comment/get/{offerID}/{page}")
-      */
-     public function getOfferComments(Request $request, OfferCacheService $offerCacheService, $offerID, $page) {
-         $offer = $offerCacheService->getOffer($offerID, false, true);
-         if (!$offer) {
-             return new Response();
-         }
-         $isMobile = CommonUtil::isMobileDevice($request);
-         return new Response($this->getCommentsByOffer($offer->getID(), $page, CommentRepository::COMMENTS_PER_PAGE, $isMobile));
-     }
-     private function getCommentsByOffer($offerID, $page, $perPage, $isMobile) {
-         $entityManager = $this->getDoctrine()->getManager();
-         $offset = ($page - 1) * $perPage;
-         $commentList = $entityManager->getRepository(Comment::class)->getCommentsByOfferIDReversed($offerID, $offset, $perPage);
-         $commentsAmount = $this->getCommentRepository()->getCommentsCountByEntityID($offerID, Comment::TYPE_OFFER_COMMENT);
-         return  $this->renderView($isMobile ? 'Slivki/mobile/comment/list.html.twig' : 'Slivki/comments/comments.html.twig', [
-             'comments' => $commentList,
-             'pagination' => $this->renderView('Slivki/pagination.html.twig', [
-                 'paginationID' => 'offerCommentPagination',
-                 'current' => $page,
-                 'total' => ceil($commentsAmount/$perPage),
-                 'url' => $entityManager->getRepository(Seo::class)->getOfferURL($offerID)->getMainAlias() . '?page='
-             ]),
-             'showBanners' => true,
-             'hasMore' => false
-         ]);
-     }
-     /**
-      * @Route("/additional_offer_details/{entityID}/{offerPreview}")
-      */
-     public function additionalOfferDetailsAction(Request $request, OfferCacheService $offerCacheService, $entityID, $offerPreview = false) {
-         $entityManager = $this->getDoctrine()->getManager();
-         $offerRepository = $this->getOfferRepository();
-         $offer = $offerCacheService->getOffer($entityID, false, true);
-         $pastOffer = false;
-         $timeNow = new \DateTime();
-         if (!$offer || $offerPreview) {
-             $offer = $offerRepository->find($entityID);
-             if (!$offer || ((!$offer->isInVisiblePeriod() || !$offer->isActive()) && !$offerPreview)) {
-                 throw $this->createNotFoundException();
-             }
-             $mediaRepository = $this->getMediaRepository();
-             $offer->setDetailMeidas($mediaRepository->getOfferDetailMedias($offer->getID()));
-             $offer->setShopMedias($mediaRepository->getOfferShopMedias($offer->getID()));
-         }
-         $data['parentCategoryList'] = null;
-         $data['offer'] = $offer;
-         $data['tour3dName'] = '';
-         $softCache = new SoftCache(OfferRepository::CACHE_NAME);
-         $cacheKey = 'alt-offers-box-1-' . $entityID;
-         $altOffersBox = $softCache->get($cacheKey);
-         if ($altOffersBox == SoftCache::LOCKED_KEY) {
-             $altOffersBox = $softCache->getDataForLockedKey($cacheKey, 30);
-         } else if (!$altOffersBox) {
-             $softCache->add($cacheKey, SoftCache::LOCKED_KEY, 30);
-             $cacheExpire = strtotime(date('Y-m-d 05:00:00', strtotime('+1 day'))) - time();
-             $altOffersBox = "";
-             $altOfferList = $this->getDoctrine()->getRepository(AlternativeOffer::class)->getByOfferID($entityID);
-             if ($altOfferList) {
-                 if (count($altOfferList) < 3) {
-                     $altOffersBox = SoftCache::EMPTY_VALUE;
-                 } else {
-                     if (count($altOfferList) < 6) {
-                         $altOfferList = array_slice($altOfferList, 0, 3);
-                     }
-                     foreach ($altOfferList as $altOffer) {
-                         $alternativeOffer = $offerCacheService->getOffer($altOffer->getAlternativeOfferID(), true);
-                         if ($alternativeOffer) {
-                             $altOffersBox .= $this->get('twig')->render('Slivki/offers/teaser.html.twig', ['offer' => $alternativeOffer, 'noLazyLoad' => true]);
-                         } else {
-                             $this->getLogger()->error('Alternative offer ' . $altOffer->getOfferID() . " not found in cache");
-                             $altOffersBox = "";
-                             break;
-                         }
-                     }
-                 }
-             }
-             $softCache->set($cacheKey, $altOffersBox, $cacheExpire);
-             if ($altOffersBox == SoftCache::EMPTY_VALUE) {
-                 $altOffersBox = "";
-             }
-         }
-         $data['altOffersBox'] = $altOffersBox;
-         $view = $request->query->get('offerCondition') ? 'Slivki/offers/condition.html.twig' : 'Slivki/offers/additional_offer_details.html.twig';
-         if (self::getMobileDevice($request)) {
-             $view = 'Slivki/mobile/offer/description.html.twig';
-         }
-         return $this->render($view, $data);
-     }
-     /**
-      * @Route("/offer_location/{entityID}")
-      */
-     public function offerLocationAction(Request $request, OfferCacheService $offerCacheService, $entityID) {
-         $offerRepository = $this->getOfferRepository();
-         $offer = $offerCacheService->getOffer($entityID, false, true);
-         if (!$offer) {
-             $offer = $offerRepository->find($entityID);
-             if (!$offer) {
-                 throw $this->createNotFoundException();
-             }
-             $mediaRepository = $this->getMediaRepository();
-             $offer->setDetailMeidas($mediaRepository->getOfferDetailMedias($offer->getID()));
-             $offer->setShopMedias($mediaRepository->getOfferShopMedias($offer->getID()));
-         }
-         $data['offer'] = $offer;
-         $data['geoLocations'] = $offer->getGeoLocations();
-         return $this->render('Slivki/offers/location.html.twig', $data);
-     }
-     /**
-      * @Route("/get_comment_box/{type}/{entityID}/{mobileCache}")
-      */
-     public function getCommentBoxAction(Request $request, BannerService $bannerService, $type, $entityID, $mobileCache = null) {
-         if ($entityID == 140503) {
-             Logger::instance('COMMENT-DEBUG')->info('start');
-         }
-         ini_set('memory_limit', '512M');
-         $directorID = 0;
-         if ($type == Comment::TYPE_OFFER_COMMENT) {
-             $offer = $this->getDoctrine()->getManager()->find(Offer::class, $entityID);
-             if ($offer->getDirectors()->count() > 0) {
-                 $directorID = $offer->getDirectors()->first()->getID();
-             }
-         }
-         if ($entityID == 140503) {
-             Logger::instance('COMMENT-DEBUG')->info('05');
-         }
-         $cacheName = $mobileCache ? CommentCacheService::MOBILE_CACHE_NAME : CommentCacheService::CACHE_NAME;
-         $data = [
-             'entityID' => $entityID,
-             'type' => $type,
-             'comments' => $this->getComments($request, $bannerService, $entityID, $type, 0, 0, $directorID, $cacheName),
-             'commentsAmount' => $this->getCommentRepository()->getCommentsCountByEntityID($entityID, $type),
-             'showCommentsAmount' => $type == Comment::TYPE_SALE_COMMENT ? false : true
-         ];
-         if ($entityID == 140503) {
-             Logger::instance('COMMENT-DEBUG')->info('1');
-         }
-         $view = 'Slivki/comments/comments_list.html.twig';
-         if ($entityID == 140503) {
-             Logger::instance('COMMENT-DEBUG')->info('2');
-         }
-         if ($cacheName == CommentRepository::MOBILE_CACHE_NAME) {
-             $view = 'Slivki/mobile/comment/block.html.twig';
-         }
-         if ($entityID == 140503) {
-             Logger::instance('COMMENT-DEBUG')->info('3');
-         }
-         $response = new Response();
-         $response->setContent($this->get('twig')->render($view, $data));
-         if ($entityID == 140503) {
-             Logger::instance('COMMENT-DEBUG')->info('status code ' . $response->getStatusCode());
-         }
-         return $response;
-     }
-     /**
-      * @Route("/landing")
-      */
-     public function mobileLandingAction(
-         Request $request,
-         OfferCacheService $offerCacheService,
-         SubscriptionService $subscriptionService,
-         DeviceTypeService $deviceTypeService,
-         ServerFeatureStateChecker $serverFeatureStateChecker
-     ): Response {
-         if (!$deviceTypeService->isMobileDevice($request) || !$serverFeatureStateChecker->isServerFeatureEnabled(SwitcherFeatures::ALLOW_MOBILE_LANDING_PAGE())) {
-             return $this->redirectToRoute('homepage');
-         }
-         $response = new Response();
-         $entityManager = $this->getDoctrine()->getManager();
-         $user = $this->getUser();
-         $carouselOffersIDs = [Dominos::OFFER_ID, SushiHouse::OFFER_ID, Offer::KFC_OFFER_ID, Offer::FREESTYLE_OFFER_ID, Dodo::OFFER_ID];
-         $data['recomended'] = true;
-         if ($user) {
-             $sql = 'select entity_id from visit where user_id = ' . $user->getID()
-                 . ' and entity_type_id = ' . Category::OFFER_CATEGORY_ID
-                 . ' group by 1 order by max(created_on) desc limit 10';
-             $visitedOfferIDs = $this->getDoctrine()->getManager()->getConnection()->executeQuery($sql)->fetchAll(\PDO::FETCH_COLUMN);
-             if (!empty($visitedOfferIDs)) {
-                 $carouselOffersIDs = $visitedOfferIDs;
-                 $data['recomended'] = false;
-             }
-         }
-         $carouselOffers = $offerCacheService->getOffers($carouselOffersIDs);
-         if ($data['recomended']) {
-             shuffle($carouselOffers);
-         }
-         $data['carouselOffers'] = $carouselOffers;
-         $data['categoryList'] = $this->getCategoryRepository()->getUserFavouriteCategories($user);
-         $data['showWatchList'] = $user && $this->getUser() && $this->getVisitedByUserCount($user->getID()) > 0;
-         $abTestViews = [
-             'Slivki/mobile/landing_new.html.twig'
-         ];
-         $landingABCookieName = 'landingab';
-         $landingABCookieValue = $request->cookies->get($landingABCookieName);
-         if (!$landingABCookieValue) {
-             $landingABCookieValue = array_rand($abTestViews);
-         } else {
-             $landingABCookieValue = (int)$landingABCookieValue;
-             $landingABCookieValue++;
-             if ($landingABCookieValue >= count($abTestViews)) {
-                 $landingABCookieValue = 0;
-             }
-         }
-         $landingABCookie = Cookie::create($landingABCookieName, $landingABCookieValue, time() + 315360000, '/', $this->getParameter('base_domain'));
-         $response->headers->setCookie($landingABCookie);
-         $data['subscription'] = null !== $user ? $subscriptionService->getSubscription($user) : null;
-         $data['hadSubscription'] = null !== $user ? $subscriptionService->isExistBySubscriber($user) : null;
-         $landingBannerRepository = $entityManager->getRepository(MobileLandingBanner::class);
-         $bannerList = $landingBannerRepository->findBy(['active' => true], ['position' => 'ASC']);
-         $data['landingBannerHtmlTop'] = $this->get('twig')->render('Slivki/banners/landing_banner_top.html.twig', ['bannerList' => $bannerList]);
-         $data['landingBannerHtmlBottom'] = $this->get('twig')->render('Slivki/banners/landing_banner_bottom.html.twig', ['bannerList' => $bannerList]);
-         $response->setContent($this->renderView($abTestViews[$landingABCookieValue], $data));
-         return $response;
-     }
-     private function getVisitedByUserCount($userID) {
-         $sql = 'select count(distinct entity_id) from visit where user_id = ' . $userID . ' and entity_type_id = ' . Category::OFFER_CATEGORY_ID;
-         return $this->getDoctrine()->getManager()->getConnection()->executeQuery($sql)->fetchColumn();
-     }
-     public function getRelatedOffersTeasers(CacheService $cacheService, $offerID) {
-         $entityManager = $this->getDoctrine()->getManager();
-         $offer = $entityManager->find(Offer::class, $offerID);
-         $defaultCategoryID = $offer->getDefaultCategoryID();
-         if (empty($defaultCategoryID)) {
-             return '';
-         }
-         $entityIDList = $this->offerDao->findActiveOffersByCategoryIds([$defaultCategoryID]);
-         if (0 == count($entityIDList)) {
-             return '';
-         }
-         $sql = 'select entity_id, purchase_count_recent from purchase_count where entity_id in (' . implode(',', $entityIDList) . ') order by 2 desc limit 12;';
-         try {
-             $purschaseCountList = $entityManager->getConnection()->executeQuery($sql)->fetchAll(\PDO::FETCH_KEY_PAIR);
-         } catch (\PDOException $e) {
-             Logger::instance('Related offers')->info($offerID);
-         }
-         return $cacheService->getTeaserList(array_keys($purschaseCountList), false);
-     }
-     /**
-      * @Route("/comments/add_like/{commentID}")
-      */
-     public function addLike($commentID, Request $request) {
-         if ($this->isGranted(UserGroup::COMMENTS_BANNED_ROLE_NAME)) {
-             return new Response();
-         }
-         $user = $this->getUser();
-         if(!$user) {
-             return new Response(json_encode(['error' => 1]));
-         }
-         /** @var Comment $comment */
-         $comment = $this->getCommentRepository()->find($commentID);
-         $like = new CommentLike();
-         $like->setUserID($user->getID());
-         $like->setVote((bool)$request->request->get('vote'));
-         $comment->addLike($like);
-         $entityManager = $this->getDoctrine()->getManager();
-         $entityManager->flush();
-         $result = $comment->getLikesAmount();
-         $this->resetCommentsCache($comment->getEntityID(), $comment->getTypeID());
-         return new Response(json_encode($result));
-     }
-     private function validateComment(Request $request) {
-         $commentText = trim($request->request->get('comment', ''));
-         if($commentText == '') {
-             $result = 'Отзыв не может быть пустым';
-             return $result;
-         }
-         return true;
-     }
-     /**
-      * @Route("/ostavit-otziv/{typeID}/{entityID}/{parentID}", defaults = {"parentID" = 0})
-      */
-     public function addComment($typeID, $entityID, $parentID, Request $request) {
-         if (!self::getMobileDevice($request)) {
-             return $this->redirectToRoute('homepage');
-         }
-         $typeID = (int)$typeID;
-         $entityID = (int)$entityID;
-         $parentID = (int)$parentID;
-         if (!in_array($typeID, [Comment::TYPE_OFFER_COMMENT, Comment::TYPE_SALE_COMMENT, Comment::TYPE_MALL_BRAND_COMMENT, Comment::TYPE_DIRECTOR_COMMENT])) {
-             return $this->redirectToRoute('homepage');
-         }
-         if ($parentID > 0) {
-             $parentComment = $this->getCommentRepository()->find($parentID);
-             if (!$parentComment || $parentComment->getEntityID() != $entityID) {
-                 return $this->redirectToRoute('homepage');
-             }
-         }
-         return $this->render('Slivki/mobile/comment/add.html.twig', [
-             'typeID' => $typeID,
-             'entityID' => $entityID,
-             'parentID' => $parentID,
-             'referer' => $request->headers->get('referer', '/')
-         ]);
-     }
-     /**
-      * @Route("/redaktirovat-otziv/{commentID}")
-      */
-     public function editComment($commentID, Request $request) {
-         if (!self::getMobileDevice($request)) {
-             return $this->redirectToRoute('homepage');
-         }
-         $commentRepository = $this->getCommentRepository();
-         /** @var Comment $comment */
-         $comment = $commentRepository->find($commentID);
-         if (!$comment) {
-             return $this->redirectToRoute('homepage');
-         }
-         $user = $this->getUser();
-         if (!$user || !($user->getID() == $comment->getUser()->getID())) {
-             return $this->redirectToRoute('homepage');
-         }
-         $commentRating = $comment->getRating();
-         return $this->render('Slivki/mobile/comment/edit.html.twig', [
-             'comment' => $comment,
-             'commentRating' => $commentRating,
-             'isUserAllowedToRate' => $commentRating > 0,
-             'referer' => $request->headers->get('referer', '/')
-         ]);
-     }
-     /**
-      * @Route("/udalit-otziv/{commentID}")
-      */
-     public function deleteComment($commentID, Request $request) {
-         if (!self::getMobileDevice($request)) {
-             return $this->redirectToRoute('homepage');
-         }
-         $comment = $this->getCommentRepository()->find($commentID);
-         if (!$comment) {
-             return $this->redirectToRoute('homepage');
-         }
-         $user = $this->getUser();
-         if (!$user || !($user->getID() == $comment->getUser()->getID())) {
-             return $this->redirectToRoute('homepage');
-         }
-         return $this->render('Slivki/mobile/comment/delete.html.twig', [
-             'comment' => $comment,
-             'referer' => $request->headers->get('referer', '/')
-         ]);
-     }
-     /**
-      * @Route("/comments/add/{type}/{entityID}")
-      */
-     public function commentAdd(
-         int $type,
-         int $entityID,
-         Request $request,
-         Mailer $mailer,
-         ServerFeatureStateChecker $serverFeatureStateChecker,
-         VoiceMessageUploader $voiceMessageUploader
-     ): Response {
-         $user = $this->getUser ();
-         if (!$user) {
-             return new Response('Войдите, чтобы мы могли учесть Ваше мнение!');
-         }
-         if ($this->isGranted(UserGroup::COMMENTS_BANNED_ROLE_NAME)) {
-             return new Response('Добавление комментариев заблокировано администратором');
-         }
-         $validateCommentResult = $this->validateComment($request);
-         if ($validateCommentResult !== true) {
-             return new Response($validateCommentResult);
-         }
-         $parentCommentID = (int)$request->request->get('parentVoteId');
-         $commentText = trim($request->request->get('comment', ''));
-         if (Censure::parse($commentText)) {
-             $response = new Response();
-             $response->setStatusCode(406);
-             return $response;
-         }
-         $entityManager = $this->getDoctrine()->getManager();
-         $userPhone = $user->getCurrentPhone();
-         $confirmedPhone = true;
-         if ($serverFeatureStateChecker->isServerFeatureEnabled(SwitcherFeatures::NEED_CONFIRM_PHONE_TO_COMMENT())
-             && (!$userPhone || !$userPhone->isConfirmed() || !$userPhone->isBelorussian())) {
-             $confirmedPhone = false;
-         }
-         if ($type == Comment::TYPE_OFFER_COMMENT) {
-             $sql = 'DELETE FROM offer_rate_schedule WHERE user_id = ' . (int)$user->getID() . ' AND offer_id = ' . (int)$entityID;
-             $entityManager->getConnection()->executeQuery($sql);
-         }
-         $parentComment = $this->getCommentRepository()->find($parentCommentID);
-         $comment = new Comment();
-         $comment->setComment($this->prepareCommentText($commentText));
-         $rating = $request->request->get('actionRating');
-         $comment->setRating($rating);
-         if ($parentComment) {
-             $comment->setParentComment($parentComment);
-         }
-         $comment->setEntityID($entityID);
-         $comment->setHidden(false);
-         $comment->setTypeID($type);
-         $comment->setMobileVersion(CommonUtil::isMobileDevice($request));
-         $comment->setChecked(false);
-         $comment->setUser ($user);
-         $comment->setConfirmedPhone($confirmedPhone);
-         if ($userPhone instanceof UserPhone) {
-             $comment->setPhone($userPhone->getPhoneNumber());
-         }
-         $comment->setAllowToContact($request->request->getBoolean('allowToContact'));
-         $voiceFile = $request->files->get('voice_message');
-         if ($voiceFile) {
-             $voicePath = $voiceMessageUploader->upload($voiceFile);
-             if ($voicePath !== null) {
-                 $comment->setVoicePath($voicePath);
-             }
-         }
-         $entityManager->persist($comment);
-         $session = $request->getSession();
-         $userCommentImages = $session->get('userCommentImages', []);
-         foreach ($userCommentImages as $key => $value) {
-             $media = new Media\CommentMedia();
-             $media->setMediaType($entityManager->getRepository(MediaType::class)->find(MediaType::TYPE_USER_VOTE_IMAGE_ID));
-             $media->setPath(MediaType::TYPE_USER_VOTE_IMAGE_PATH);
-             $media->setName($value);
-             $media->setSortOrder($key);
-             $comment->addMedia($media);
-         }
-         $session->set('userCommentImages', []);
-         $entityManager->flush($comment);
-         if ($type == Comment::TYPE_OFFER_COMMENT && $confirmedPhone) {
-             $offer = $this->getOfferRepository()->find($entityID);
-             $this->sendOfferCommentNotice($mailer, $offer, $comment, $parentComment);
-         }
-         $this->resetCommentsCache($entityID, $type);
-         return new Response($confirmedPhone ? '<p class="mb-3" style="font-size: 30px;">😊 </p><strong style="font-family:SF Pro Rounded Bold">Благодарим за оставленный отзыв!</strong> <br><br> <p class="mb-4" style="font-family:SF Pro Rounded;font-weight: 100;">Такие отзывы, как ваш, помогают другим людям находить самые лучшие акции и интересные места</p>' : 'confirm');
-     }
-     /**
-      * @Route("/comments-live")
-      * @Route("/comments-live/{alias}")
-      */
-     public function commentsLiveRedirect($alias = null) {
-         $routeName = 'commentsLive';
-         $routeParameters = [];
-         if ($alias != '') {
-             $routeName = 'commentsByCategory';
-             $routeParameters['alias'] = $alias;
-         }
-         return $this->redirectToRoute($routeName, $routeParameters, 301);
-     }
-     /**
-      * @Route("/otzyvy", name="commentsLive")
-      */
-     public function commentsLiveAction(Request $request) { //TODO: total refactoring commentsLiveAction and commentsByCategory
-         $isMobileDevice = self::getMobileDevice($request);
-         $commentRepository = $this->getCommentRepository();
-         $topMenu = $commentRepository->getTopMenu();
-         $data['offerRateSchedule'] = $this->getOfferRateSchedule($request->getSession());
-         $data['comments'] = $commentRepository->getLiveComments(20);
-         $data['isLiveComments'] = 1;
-         $data['hasMore'] = true;
-         $data['commentsAmount'] = 20;
-         $comments = $this->get('twig')->render($isMobileDevice ? 'Slivki/mobile/comment/list.html.twig' : 'Slivki/comments/comments.html.twig', $data);
-         $deviceType = self::getMobileDevice($request) ? self::DEVICE_TYPE_MOBILE : self::DEVICE_TYPE_DESKTOP;
-         $this->addVisit(0, Visit::TYPE_COMMENTS_MAIN_PAGE, $deviceType, $this->getUser(), $request->getClientIp(), $request->headers->get('referer', ''));
-         return $this->render($isMobileDevice ? 'Slivki/mobile/comment/index.html.twig' : 'Slivki/comments/comments_live.html.twig', [
-             'comments' => $comments,
-             'topMenu' => $topMenu
-         ]);
-     }
-     /**
-      * @Route("/otzyvy/{alias}", name="commentsByCategory")
-      */
-     public function commentsByCategoryAction(Request $request, $alias = null) {
-         $page = $request->query->get('page', 1);
-         $isMobileDevice = self::getMobileDevice($request);
-         $seo = $request->attributes->get(SiteController::PARAMETER_META_INFO);
-         if (!$seo && $alias) {
-             $seo = $this->getSeoRepository()->findOneBy(['mainAlias' => '/' . $alias]);
-         }
-         if (!$seo) {
-             return $this->redirectToRoute('commentsLive');
-         }
-         $seoType = $seo->getResourceURL();
-         $entityID = $seo->getEntityID();
-         $commentRepository = $this->getCommentRepository();
-         switch($seoType) {
-             case SeoRepository::RESOURCE_URL_CATEGORY_COMMENTS:
-             case SeoRepository::RESOURCE_URL_OFFER_CATEGORY:
-                 $categoryRepository = $this->getCategoryRepository();
-                 $categoryCached = $categoryRepository->findCached($entityID);
-                 if(!$categoryCached) {
-                     return $this->redirectToRoute('commentsLive');
-                 }
-                 $category = $categoryCached['category'];
-                 $subCategories = $categoryRepository->getSubCategories($category);
-                 $data['isLiveComments'] = 1;
-                 $data['hasMore'] = true;
-                 $data['categoryID'] = $entityID;
-                 $data['commentsAmount'] = 10;
-                 if ($category->getTypeID() == Category::SUPPLIER_CATEGORY_TYPE) {
-                     $data['comments'] = $commentRepository->getOfferCategoryComments($entityID, $page);
-                     $data['hasMore'] = false;
-                 } else {
-                     $data['comments'] = $commentRepository->getCommentsByCategoryID($category->getID(), $data['commentsAmount']);
-                 }
-                 $comments = $this->renderView($isMobileDevice ? 'Slivki/mobile/comment/list.html.twig' : 'Slivki/comments/comments.html.twig', $data);
-                 $title = mb_strtoupper('<h1>ОТЗЫВЫ ' . $category->getName() . '</h1>');
-                 return $this->render($isMobileDevice ? 'Slivki/mobile/comment/index.html.twig' : 'Slivki/comments/comments_live.html.twig', [
-                     'commentsCount' => $commentRepository->getOfferCategoryCommentsCount($category->getID()),
-                     'page' => $page,
-                     'comments' => $comments,
-                     'subCategories' => $subCategories,
-                     'title' => $title,
-                     'categoryID' => $entityID,
-                     'category' => $category,
-                     'parentCategories' => $categoryRepository->getCategoryParentList($category)
-                 ]);
-                 break;
-             case SeoRepository::RESOURCE_URL_OFFER_DETAILS:
-             case SeoRepository::RESOURCE_URL_SALE_DETAILS:
-                 return $this->redirect('/' . $alias, 301);
-                 break;
-         }
-         return $this->redirect(CityRepository::$mainPageURL);
-     }
-     /**
-      * @Route("/comments/load")
-      */
-     public function commentLoad(Request $request, BannerService $bannerService) {
-         $offerID = $request->request->get('marketActionOID');
-         $typeID = $request->request->get('typeID');
-         $lastCommentID = $request->request->get('lastCommentOID');
-         $categoryID = $request->request->getInt('categoryID');
-         $directorID = $request->request->getInt('directorID');
-         $cacheName = $request->request->getInt('isMobileCache') == 0 ? CommentCacheService::CACHE_NAME : CommentCacheService::MOBILE_CACHE_NAME;
-         return new Response($this->getComments($request, $bannerService, $offerID, $typeID, $lastCommentID, $categoryID, $directorID, $cacheName));
-     }
-     /**
-      * @Route("/comments/get_by_user/{userID}")
-      */
-     public function commentsGetByUser($userID, Request $request) {
-         $offerID = $request->query->get('offerID');
-         if (!$offerID) {
-             return new Response();
-         }
-         $dql = "select comment from Slivki:Comment comment 
-             where comment.userID = :userID and comment.entityID = :offerID 
-             and (comment.hidden = false or comment.hidden is null)
-             and (comment.deleted = false or comment.deleted is null)
-             and comment.confirmedPhone = true
-             order by comment.createdOn desc";
-         $data['comments'] = $this->getDoctrine()->getManager()->createQuery($dql)
-             ->setParameter('userID', $userID)
-             ->setParameter('offerID', $offerID)
-             ->getResult();
-         return $this->render('Slivki/comments/comments_by_user.html.twig', $data);
-     }
-     /**
-      * @Route("/comment/image_upload")
-      */
-     public function commentImageUpload(Request $request, KernelInterface $kernel) {
-         $imageFolder = $kernel->getProjectDir() . '/public' . ImageService::MEDIA_ROOT . ImageService::INITIAL_PATH . MediaType::TYPE_USER_VOTE_IMAGE_PATH;
-         $uploadedFile = $request->files->get('imageUploadForm');
-         if ($uploadedFile) {
-             if (!in_array(mb_strtolower($uploadedFile->getClientOriginalExtension()), ['jpg', 'png', 'gif', 'jpeg'])) {
-                 return new Response("error=true;result=Разрешены только .jpg, .jpeg, .png или .gif изображения");
-             };
-             $fs = new Filesystem();
-             $newFileName = time() . '_' . $uploadedFile->getClientOriginalName();
-             while($fs->exists($imageFolder . $newFileName)) {
-                 $newFileName = time() . '_' . $newFileName;
-             }
-             $uploadedFile->move($imageFolder, $newFileName);
-             $session = $request->getSession();
-             $userCommentImages = $session->get('userCommentImages', []);
-             $userCommentImages[] = $newFileName;
-             $session->set('userCommentImages', $userCommentImages);
-             return new Response("error=false;result=" . ImageService::MEDIA_ROOT . ImageService::INITIAL_PATH . MediaType::TYPE_USER_VOTE_IMAGE_PATH . $newFileName);
-         } else {
-             return new Response("error=true;result=Error");
-         }
-     }
-     /**
-      * @Route("/comment/image_remove")
-      */
-     public function commentImageRemove(Request $request) {
-         $imageIndex = $request->request->get('imageIndex');
-         $mediaID = $request->request->getInt('id');
-         if ($mediaID != 0) {
-             $entityManager = $this->getDoctrine()->getManager();
-             $media = $entityManager->getRepository(Media\CommentMedia::class)->find($mediaID);
-             if ($media && $this->getUser() && $media->getComment()->getUserID() == $this->getUser()->getID()) {
-                 $entityManager->remove($media);
-                 $entityManager->flush();
-             }
-         }
-         $session = $request->getSession();
-         $userCommentImages = $session->get('userCommentImages', []);
-         if (isset($userCommentImages[$imageIndex])) {
-             unset($userCommentImages[$imageIndex]);
-         }
-         $session->set('userCommentImages', array_values($userCommentImages));
-         return new Response("error=false;result=");
-     }
-     /**
-      * @Route("/comment/get/{commentID}")
-      */
-     public function commentGet($commentID) {
-         $comment = $this->getCommentRepository()->find($commentID);
-         return new Response(json_encode([
-             'comment' => $comment,
-             'commentMediasHtml' => $this->renderView('Slivki/comments/medias_preview.html.twig', ['medias' => $comment->getMedias()])
-         ]));
-     }
-     /**
-      * @Route("/comment/is_user_allowed_to_rate/{typeID}/{entityID}")
-      */
-     public function isUserAllowedToRate($typeID, $entityID) {
-         $user = $this->getUser();
-         if (!$user) {
-             return new JsonResponse(json_encode(false));
-         }
-         return new Response(json_encode($this->getCommentRepository()->isUserAllowedToRate($user->getID(), $entityID, $typeID)));
-     }
-     /**
-      * @Route("/comment/edit/{commentID}")
-      */
-     public function commentEdit($commentID, Request $request) {
-         $entityManager = $this->getDoctrine()->getManager();
-         /** @var \Slivki\Entity\Comment $comment */
-         $comment = $this->getCommentRepository()->find($commentID);
-         if (!$comment) {
-             return new Response('');
-         }
-         if ($comment->getCreatedOn()->format('U') < strtotime('-7 days') || $comment->getUserID() != $this->getUser()->getID()) {
-             return new Response('');
-         }
-         $commentText = trim($request->request->get('comment', ''));
-         if (Censure::parse($commentText)) {
-             $response = new Response();
-             $response->setStatusCode(406);
-             return $response;
-         }
-         if ($comment->getRating() > 0) {
-             $rating = $request->request->getInt('rating');
-             if ($rating > $comment->getRating()) {
-                 $comment->setRating($rating);
-             }
-         }
-         $commentChildren = $comment->getChildren()->toArray();
-         if (empty($commentChildren)) {
-             $comment->setComment($this->prepareCommentText($commentText));
-             $comment->setChecked(false);
-         }
-         $comment->setAllowToContact($request->request->getBoolean('allowToContact'));
-         $session = $request->getSession();
-         $userCommentImages = $session->get('userCommentImages', []);
-         $mediaTypeRepository = $entityManager->getRepository(MediaType::class);
-         foreach ($userCommentImages as $key=>$value) {
-             $media = new Media\CommentMedia();
-             $media->setMediaType($mediaTypeRepository->find(MediaType::TYPE_USER_VOTE_IMAGE_ID));
-             $media->setPath(MediaType::TYPE_USER_VOTE_IMAGE_PATH);
-             $media->setName($value);
-             $media->setSortOrder($key);
-             $comment->addMedia($media);
-         }
-         $session->set('userCommentImages', []);
-         $entityManager->flush();
-         $this->resetCommentsCache($comment->getEntityID(), $comment->getTypeID());
-         $comment->setComment(nl2br($comment->getComment()));
-         return new Response(json_encode([
-             'comment' => $comment,
-             'mediasHtml' => $this->renderView('Slivki/comments/medias.html.twig', ['medias' => $comment->getMedias()->toArray()])
-         ]));
-     }
-     /**
-      * @Route("/comment/delete/{commentID}")
-      */
-     public function commentDelete($commentID, Request $request) {
-         /** @var \Slivki\Entity\Comment $comment */
-         $entityManager = $this->getDoctrine()->getManager();
-         $comment = $entityManager->getRepository(Comment::class)->find($commentID);
-         if (!$comment) {
-             return new Response('');
-         }
-         if ($comment->getCreatedOn()->format('U') < strtotime('-24 hours') || $comment->getUserID() != $this->getUser()->getID()) {
-             return new Response('');
-         }
-         $commentTypeID = $comment->getTypeID();
-         $commentEntityID = $comment->getEntityID();
-         $comment->setDeleted(true);
-         $comment->setChecked(false);
-         $comment->setRating(0);
-         $entityManager->flush();
-         $this->resetCommentsCache($commentEntityID, $commentTypeID);
-         return new Response('');
-     }
-     /**
-      * @Route("/mailing_seen_it_cheaper")
-      */
-     public function seenCheaperAction(Request $request, Mailer $mailer){
-         $email = $request->request->get("sender_email");
-         $body = $request->request->get("body");
-         $link = $request->request->get("link_to_sale");
-         if($this->checkSeenCheaperForm($request)) {
-             $message = $mailer->createMessage();
-             $message->setSubject("ОКО: Лучшее предложение")
-                 ->setFrom("info@slivki.by", 'Slivki.by')
-                 ->setTo('info@slivki.by')
-                 ->setBody($this->renderView('Slivki/emails/seen_it_cheaper.html.twig',
-                     array('email' => $email, 'message' => $body, 'link' => $link)),
-                     'text/html');
-             $mailer->send($message);
-             $result['status'] = "success";
-         } else {
-             $result['status'] = "error";
-         }
-         return new Response(json_encode($result));
-     }
-     public function checkSeenCheaperForm(Request $request){
-         $email = $request->request->get("sender_email");
-         if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
-             return false;
-         }
-         return true;
-     }
-     /**
-      * @Route("/ajax_get_map_placemarks_by_category")
-      */
-     public function ajaxGetMapPlacemarksByCategory(Request $request) {
-         if (!$request->isXmlHttpRequest()) {
-             return $this->redirect("/");
-         }
-         ini_set('memory_limit', '1024m');
-         $categoryID = $request->request->get('categoryOID');
-         $result = array();
-         $offerRepository = $this->getOfferRepository();
-         $offers = $offerRepository->getActiveOffersByCategoryID($categoryID);
-         foreach($offers as $offer) {
-             if (!$offer) {
-                 continue;
-             }
-             $result = array_merge($result, $offerRepository->getOfferGeoLocations($offer));
-         }
-         return new Response(json_encode($result));
-     }
-     /**
-      * @Route("/mailing_campaign/{mailingCampaignID}")
-      */
-     public function mailingCampaignAction($mailingCampaignID) {
-         $entityManager = $this->getDoctrine()->getManager();
-         $mailingCampaignRepository = $entityManager->getRepository(MailingCampaign::class);
-         $mailingCampaign = $mailingCampaignRepository->find($mailingCampaignID);
-         if(!$mailingCampaign) {
-             return $this->redirect("/");
-         }
-         $mailBody = $mailingCampaign->getMailBody();
-         $template = $this->get('twig')->createTemplate($mailBody);
-         return new Response($template->render([]));
-     }
-     public function sendOfferMessageFormAction(Request $request) {
-         return $this->render(self::getMobileDevice($request) ?
-             'Slivki/mobile/offer/create_own_offer.html.twig' : 'Slivki/offers/send_offer_messsage.html.twig');
-     }
-     /**
-      * @Route("/send_offer_message")
-      */
-     public function sendOfferMessage(Request $request, Mailer $mailer) {
-         $offerProposal = new OfferProposal();
-         $offerProposal->setType(OfferProposal::PROPOSAL_TYPE);
-         $offerProposal->setPhone($request->request->get('offerPhone'));
-         $offerProposal->setEmail($request->request->get('offerEmail'));
-         $offerProposal->setBuisnessName($request->request->get('offerBuisness'));
-         $offerProposal->setOfferConditions($request->request->get('termsOfPromotion'));
-         $subject = 'NEW: Разместить акцию';
-         $messageText = '<b>Телефон:</b> ' . $request->request->get('offerPhone') . '<br>'
-             . '<b>E-mail:</b> ' . $request->request->get('offerEmail') . '<br>'
-             . '<b>Юр.лицо:</b> ' . $request->request->get('offerBuisness') . '<br>'
-             . '<b>Условия акции:</b> ' . $request->request->get('termsOfPromotion') . '<br>';
-         $message = $mailer->createMessage();
-         $message->setSubject($subject)
-             ->setFrom("info@slivki.by", 'Slivki.by')
-             ->setTo('info@slivki.by')
-             ->setBody(
-                 $messageText,
-                 'text/html'
-             );
-         $mailer->send($message);
-         try {
-             $em = $this->getDoctrine()->getManager();
-             $em->persist($offerProposal);
-             $em->flush();
-         } catch (\Exception $e) {
-             return new Response('Ваше сообщение успешно отправлено');
-         }
-         return new Response('Ваше сообщение успешно отправлено');
-     }
-     /**
-      * @Route("/humorfm")
-      */
-     public function humorFM(Request $request) {
-         if($this->getMobileDevice($request)){
-             return $this->render('Slivki/mobile_humorfm.html.twig');
-         } else{
-             return $this->render('Slivki/humorfm.html.twig');
-         }
-     }
-     /**
-      * @Route("/subscribe/mobile")
-      */
-     public function subscribeForm(Request $request) {
-         if ($this->getMobileDevice($request) and (!$this->getUser() or !$this->getUser()->getAcceptNewsletter())) {
-             return $this->render('Slivki/subscribe_mobile.html.twig');
-         } else {
-             return $this->redirect("/");
-         }
-     }
-     /**
-      * @Route("/send-contact-form")
-      */
-     public function sendContactForm(Request $request, Mailer $mailer) {
-         $data = [
-             'email' => $request->request->get('email', ''),
-             'name' => $request->request->get('name', ''),
-             'body' => $request->request->get('body', '')
-         ];
-         $error = '';
-         if (!filter_var(trim($data['email'], FILTER_VALIDATE_EMAIL))) {
-             $error .= 'Пожалуйста, введите Ваш E-Mail.<br>';
-         }
-         if (trim($data['body']) == '') {
-             $error .= 'Пожалуйста, введите текст сообщения.<br>';
-         }
-         if ($error != '') {
-             return new Response($error);
-         }
-         $recipientEmail = (strpos($request->headers->get('referer'), '/beznal')) ? 'beznal@slivki.by' : 'info@slivki.by';
-         $message = $mailer->createMessage();
-         $message->setSubject("Сообщение")
-             ->setFrom("info@slivki.by", 'Slivki.by')
-             ->setTo($recipientEmail)
-             ->setBody(
-                 $this->renderView(
-                     'Slivki/emails/contact_email.html.twig',
-                     $data
-                 ),
-                 'text/html'
-             );
-         $mailer->send($message);
-         return new Response();
-     }
-     /**
-      * @Route("/contact-mail-result")
-      */
-     public function contactMailResult(Request $request) {
-         $data['lastComments'] = $this->getDoctrine()->getRepository(Comment::class)->findBy(["hidden" => false], ["createdOn" => "desc"], 3);
-         return $this->render(CommonUtil::isMobileDevice($request) ?
-             'Slivki/mobile/info_pages/contacts_form_result.html.twig' : 'Slivki/contact_mail_result.html.twig', $data);
-     }
-     /**
-      * @Route("/readability_sale_stat")
-      */
-     public function readabilitySaleStat(Request $request) {
-         $id = $request->request->get('saleID');
-         $timeOnPage = $request->request->get('timeOnPage');
-         $percentOfScrolling = $request->request->get('percentOfScrolling');
-         $userID = $this->getUser();
-         if ($userID) {
-             $userID = $this->getUser()->getID();
-         }
-         $pageHeight = $request->request->get('pageHeight');
-         $readPx = $request->request->get('readPx');
-         $date = new \DateTime();
-         $readabilityStat = new ReadabilityStat();
-         $readabilityStat->setEntityID($id);
-         $readabilityStat->setPercentOfScrolling($percentOfScrolling);
-         $readabilityStat->setTimeOnPage($timeOnPage);
-         $readabilityStat->setCreatedOn($date);
-         $readabilityStat->setUserID($userID);
-         $readabilityStat->setPageHeight($pageHeight);
-         $readabilityStat->setReadPx($readPx);
-         $em = $this->getDoctrine()->getManager();
-         $em->persist($readabilityStat);
-         $em->flush($readabilityStat);
-         return new Response('');
-     }
-     /**
-      * @Route("/jivo/hooks")
-      */
-     public function jivoHookAction(Request $request) {
-         $data = json_decode($request->getContent(), true);
-         $logger = Logger::instance('JIVO HOOK');
-         $entityManager = $this->getDoctrine()->getManager();
-         $chatSession = null;
-         switch ($data['event_name']) {
-             case 'chat_accepted':
-                 $chatSession = new ChatSession();
-                 $chatSession->setChatID($data['chat_id']);
-                 $entityManager->persist($chatSession);
-                 $chatSession->setOperatorEmail($data['agent']['email']);
-                 $chatSession->setOperatorName($data['agent']['name']);
-                 break;
-             case 'chat_finished':
-                 $chatSession = $entityManager->getRepository(ChatSession::class)->findOneByChatID($data['chat_id']);
-                 if (!$chatSession) {
-                     $logger->info('Chat ' . $data['chat_id'] . ' not found');
-                     return new Response();
-                 }
-                 $chatSession->setFinishedOn(new \DateTime());
-                 $chatHistory = '';
-                 foreach ($data['chat']['messages'] as $message) {
-                     $chatHistory .= date('d.m.Y', $message['timestamp']) . '<br>';
-                     $chatHistory .= ($message['type'] == 'agent' ? 'Консультант' : 'Клиент') . '<br>';
-                     $chatHistory .= $message['message'] . '<br><br>';
-                 }
-                 $chatSession->setChatHistory($chatHistory);
-                 break;
-             default:
-                 return new Response();
-         }
-         if (!$chatSession->getUser() && isset($data['user_token'])) {
-             $user = $entityManager->getRepository(User::class)->find($data['user_token']);
-             if ($user) {
-                 $chatSession->setUser($user);
-             } else {
-                 $logger->info('User ' . $data['user_token'] . ' not found');
-             }
-         }
-         $entityManager->flush($chatSession);
-         if ($data['event_name'] == 'chat_accepted') {
-             $data['result'] = 'ok';
-             $user = $chatSession->getUser();
-             if ($user) {
-                 $data['custom_data'][0]['title'] = 'Баланс';
-                 $data['custom_data'][0]['content'] = number_format($user->getFullBalance(), 2);
-                 $data['contact_info']['name'] = $user->getFirstName();
-                 $data['contact_info']['phone'] = $user->getPhone();
-                 $data['contact_info']['email'] = $user->getEmail();
-                 $data['contact_info']['description'] = '';
-             }
-             $response = new JsonResponse();
-             $response->setCharset('UTF-8');
-             $response->setEncodingOptions(JSON_UNESCAPED_UNICODE);
-             $response->setData($data);
-             return $response;
-         }
-         return new Response();
-     }
-     /**
-      * @Route("/subscribe")
-      */
-     public function subscribeAction(Request $request, Mailer $mailer) {
-         $email = mb_strtolower(trim($request->request->get('email')));
-         $entityManager = $this->getDoctrine()->getManager();
-         $user = $entityManager->getRepository(User::class)->loadUserByUsername($email, false);
-         if ($user && ($user->getAcceptNewsletter() || $user->getID() == $this->getUser()->getID())) {
-             if (!$user->getAcceptNewsletter()) {
-                 $user->setAcceptNewsletter(true);
-                 $entityManager->flush($user);
-             }
-             return new Response('0');
-         }
-         $subscriber = $entityManager->getRepository(Subscriber::class)->findOneByEmail($email);
-         if ($subscriber && $subscriber->getConfirmationCode() == '') {
-             return new Response('0');
-         }
-         if (!$subscriber) {
-             $validator = $this->get('validator');
-             $emailConstraint = new Email();
-             if ($email == '' || $validator->validate($email, $emailConstraint) != '') {
-                 return new Response('1');
-             }
-             $subscriber = new Subscriber();
-             $subscriber->setEmail($email);
-             $entityManager->persist($subscriber);
-             $confirmationCode = md5($subscriber->getID() . $subscriber->getEmail());
-             $subscriber->setConfirmationCode($confirmationCode);
-             $entityManager->flush($subscriber);
-         }
-         $messageBody = $this->get('twig')->render('Slivki/emails/confirm_email.html.twig', ['confirmationCode' => $subscriber->getConfirmationCode()]);
-         $message = $mailer->createMessage('Вы станете богаче!', $messageBody, 'text/html')->addTo($email)->addFrom('info@slivki.by');
-         $mailer->send($message);
-         return new Response('2');
-     }
-     /**
-      * @Route("/confirm/email/{confirmationCode}")
-      */
-     public function confirmEmailAction($confirmationCode) {
-         $confirmationCode = pg_escape_string($confirmationCode);
-         $entityManager = $this->getDoctrine()->getManager();
-         $sql = "select id, email from subscriber where md5(id::text || email) = '$confirmationCode'";
-         $subscriber = $entityManager->getConnection()->executeQuery($sql)->fetch();
-         if (!$subscriber) {
-             $this->addFlash(self::SHOW_INFO_DIALOG_PARAMETER, 'Пользователь не найден');
-             return $this->redirect(CityRepository::$mainPageURL);
-         }
-         $user = $entityManager->getRepository(User::class)->loadUserByUsername($subscriber['email'], false);
-         if ($user) {
-             $user->setAcceptNewsletter(true);
-             $entityManager->flush($user);
-             $entityManager->getConnection()->executeQuery("delete from subscriber where id = $subscriber[id]");
-         } else {
-             $entityManager->getConnection()->executeQuery("update subscriber set confirmation_code = '' where id = $subscriber[id]");
-         }
-         $this->addFlash(self::SHOW_INFO_DIALOG_PARAMETER, 'Вы успешно подписаны на рассылку');
-         return $this->redirect(CityRepository::$mainPageURL);
-     }
-     /**
-      * @Route("/oplata-promokoda-azs")
-      */
-     public function getGasStationCode(
-         Request $request,
-         OfferCacheService $offerCacheService,
-         SubscriptionService $subscriptionService
-     ): Response {
-         $entityManager = $this->getDoctrine()->getManager();
-         $user = $this->getUser();
-         $userID = $user->getID();
-         $offerID = Offer::PETROL_OFFER_ID;
-         $sql = "select id from offer_order where user_id = $userID and offer_id = $offerID order by id DESC limit 1";
-         $orderID = $entityManager->getConnection()->executeQuery($sql)->fetchColumn();
-         if ($orderID) {
-             $entityOption= $entityManager->getRepository(EntityOption::class)->findBy(['entityID' => $orderID]);
-             foreach ($entityOption as $val) {
-                 switch ($val->getName()) {
-                     case "car_model":
-                         $data['carModel'] = $val->getValue();
-                         break;
-                     case "car_number":
-                         $data['carNumber'] = $val->getValue();
-                         break;
-                     case "phone_number":
-                         $data['phoneNumber'] = $val->getValue();
-                         break;
-                 }
-             }
-         }
-         $data['offerID'] = Offer::PETROL_OFFER_ID;
-         $offerRepository = $this->getOfferRepository();
-         $offer = $offerCacheService->getOffer(Offer::PETROL_OFFER_ID);
-         $data['codeCost'] = $offerRepository->getCodeCost($offer);
-         $data['freeCodesCount'] = $offer->getFreeCodesCount();
-         $data['freeCode'] = $offerRepository->isOfferFreeForUser($offer, $this->getUser());
-         $data['useBalance'] =  $this->getUser()->getFullBalance() >= $offerRepository->getCodeCost($offer);
-         $userPhone = $user->getCurrentPhone();
-         if ($userPhone) {
-             $data['phoneNumber'] = $userPhone->getPhoneNumber();
-         }
-         $siteSettings = $this->getSiteSettings();
-         $data['subscriptionPrice'] = $subscriptionService->isSubscriptionFinished($user)
-             ? $siteSettings->getSubscriptionPrice()
-             : $siteSettings->getSubscriptionFirstPayment();
-         $data['subscriptionFullPrice'] = $siteSettings->getSubscriptionPrice();
-         $subscription = $subscriptionService->getSubscription($user);
-         $data['allowedCodesCountBySubscription'] = $subscriptionService->isSubscriber($user)
-             ? $subscription->getNumberOfCodes()
-             : 0;
-         return $this->render(self::getMobileDevice($request) ? 'Slivki/mobile/payment/fuel.html.twig'
-             : 'Slivki/offers/get_code_for_gas_station.html.twig', $data);
-     }
-     /**
-      * @Route("/get_offer_comment_medias_list")
-      */
-     public function getOfferCommentMediasList(Request $request) {
-         $entityID = $request->request->get('entityID');
-         $entityType = $request->request->get('entityType');
-         $offset = $request->request->get('offset');
-         $limit = $request->request->get('limit');
-         switch ($entityType) {
-             case 'category':
-                 $data['commentAndMediaList'] = $this->getMediaRepository()->getOfferCommentMediaListByCategoryID($entityID, $offset, $limit);
-                 break;
-             case 'offer':
-                 $data['commentAndMediaList'] = $this->getMediaRepository()->getOfferCommentMediaListByOfferID($entityID, $offset, $limit);
-                 break;
-             case 'all':
-                 $data['commentAndMediaList'] = $this->getMediaRepository()->getOfferCommentMediaList($offset, $limit);
-                 break;
-         }
-         return $this->render('Slivki/comments/media_block_list.html.twig', $data);
-     }
-     /**
-      * @Route("/get_top_comment_list")
-      */
-     public function getTopCommentList(Request $request) {
-         $offset = $request->request->get('offset');
-         $limit = $request->request->get('limit');
-         $data['commentList'] = $this->getCommentRepository()->findBy(['checked' => true, 'rating' => 5], ['ID' => 'DESC'], $limit, $offset);
-         return $this->render('Slivki/category_dividers/comment_list.html.twig', $data);
-     }
-     /** @Route("/ne-nashli-chto-iskali") */
-     public function lookingForAction(Request $request) {
-         return $this->render(self::getMobileDevice($request) ? 'Slivki/mobile/looking_for.html.twig' : 'Slivki/looking_for.html.twig');
-     }
-     /** @Route("/send-looking-for") */
-     public function sendLookingForAction(Request $request, Mailer $mailer) {
-         if (!$request->getMethod('POST')) {
-             return new Response();
-         }
-         $message = $mailer->createMessage();
-         $mailBody = "<b>Текст:</b><br>"
-             . $request->request->get('text')
-             . "<br><br><b>Email:</b><br>"
-             . $request->request->get('email')
-             . "<br><br><b>Телефон:</b><br>"
-             . $request->request->get('phone');
-         $message->setSubject("Не нашли, что искали")
-             ->setFrom('info@slivki.by', 'Slivki.by')
-             ->setTo('info@slivki.by')
-             ->setBody($mailBody, 'text/html');
-         $mailer->send($message);
-         return new Response();
-     }
-     /**
-      * @Route("/get_sidebar")
-      */
-     public function getSidebar(SlivkiTwigExtension $extension) {
-         return new Response($extension->getSidebar($this->get('twig')));
-     }
-     /**
-      * @Route("/get_sidebar_item_list")
-      */
-     public function getSidebarItemListContent(
-         Request $request,
-         SidebarCacheService $sidebarCacheService
-     ): Response {
-         $offset = $request->request->get('offset', 0);
-         $length = $request->request->get('length', 20);
-         $sidebarCached = $sidebarCacheService->getSidebarCached();
-         if (null === $sidebarCached) {
-             return new Response('');
-         }
-         $sidebarItemList = array_slice($sidebarCached->getItemList(), $offset, $length);
-         if (empty($sidebarItemList)) {
-             return new Response('');
-         }
-         $sidebarContent = implode('', $sidebarItemList);
-         return new Response($sidebarContent);
-     }
-     /**
-      * @Route("/widget/{alias}")
-      * @Route("/widget/map/{alias}")
-      */
-     public function widgetMapTireAction($alias) {
-         $softCache = new SoftCache('tire-widget');
-         $result = $softCache->get($alias);
-         if ($result) {
-             return new Response($result);
-         }
-         $offers = null;
-         if ($alias == 'map_tire') {
-             $offers = $this->getOfferRepository()->getActiveOffersByCategoryIDNoCache(492);
-         }
-         if (!$offers) {
-             $seo = $this->getSeoRepository()->getByAlias('/' . $alias);
-             if (!$seo) {
-                 return new Response();
-             }
-             switch ($seo->getResourceURL()) {
-                 case SeoRepository::RESOURCE_URL_OFFER_CATEGORY:
-                     $offers = $this->getOfferRepository()->getActiveOffersByCategoryID($seo->getEntityID());
-                     break;
-                 case SeoRepository::RESOURCE_URL_OFFER_DETAILS:
-                     $offer = $this->getOfferRepository()->getAnyWay($seo->getEntityID());
-                     if ($offer) {
-                         $offers[] = $offer;
-                     }
-             }
-         }
-         if (!$offers || count($offers) == 0) {
-             return new Response();
-         }
-         $result = [];
-         $i = 0;
-         $seoRepository = $this->getSeoRepository(Seo::class);
-         foreach($offers as $offer) {
-             if (!$offer) {
-                 continue;
-             }
-             $geoLocations = $offer->getGeoLocations();
-             foreach ($geoLocations as $geoLocation) {
-                 $geoLocationInfos['markerAnnotation'] = $geoLocation->getDescription();
-                 $geoLocationInfos['latitude'] = $geoLocation->getLatitude();
-                 $geoLocationInfos['longitude'] = $geoLocation->getLongitude();
-                 $result[$i]['geoLocationInfos'][] = $geoLocationInfos;
-                 $seo = $seoRepository->getByEntity('Slivki:Default:details', $offer->getID());
-                 $url = '';
-                 if ($seo) {
-                     $url = $seo->getMainAlias();
-                 }
-                 $result[$i]['longMarkerDescription'] = "<div class=\"map-balloon-description--description\">" . $offer->getTitle() . "</div><div class=\"map-balloon-description--link\"><a target='_blank' href=\"" . $url . "\">Подробнее</a></div>";
-                 $i++;
-             }
-         }
-         $result = $this->renderView('Slivki/widget/map_tire.html.twig', ['placemarkList' => $result]);
-         $softCache->set($alias, $result, 12 * 60 * 60);
-         return new Response($result);
-     }
-     /** @Route("/get_sidebar_banner/{cityID}") */
-     public function getSidebarBanner(BannerService $bannerService, $cityID) {
-         $cityID = (int)$cityID;
-         if (!$cityID) {
-             $cityID = City::DEFAULT_CITY_ID;
-         }
-         return new JsonResponse($bannerService->getSidebarBannerCached($cityID));
-     }
-     /** @Route("/log/browser") */
-     public function browserLogAction(Request $request) {
-         Logger::instance('BrowserLog')->info($request->request->get('message'));
-         return new Response();
-     }
-     /** @Route("/category/filter/map/{categoryID}") */
-     public function categoryMapFilterAction(Request $request, CacheService $cacheService, $categoryID) {
-         ini_set('memory_limit', '512M');
-         $offerIDList = $request->request->get('offerList', []);
-         $teaserList = $cacheService->getTeaserList($offerIDList, CommonUtil::isMobileDevice($request));
-         $result = ['html' => '', 'count' => 0];
-         if ($teaserList) {
-             $data = ['offerList' => array_values($teaserList), 'offersInARow' => self::getMobileDevice($request) ? 2 : 3];
-             $result = [
-                 'html' => $this->get('twig')->render('Slivki/offers/teasers.html.twig', $data),
-                 'count' => count($teaserList)
-             ];
-         }
-         return new JsonResponse($result);
-     }
-     /** @Route("/category/location-info/{categoryID}/{limit}/{offset}") */
-     public function getLocationInfoAction($categoryID, $limit, $offset) {
-         $offerGeoLocationCache = new SoftCache(OfferRepository::CACHE_NAME_GEO_LOCATION_DATA);
-         $features = $offerGeoLocationCache->get($categoryID, []);
-         if (!$features) {
-             $features = [];
-         }
-         $features = array_slice($features, $offset, $limit);
-         if (empty($features)) {
-             return new Response(json_encode([]));
-         }
-         $getLocationData = ['type' => 'FeatureCollection', 'features' => $features];
-         return new Response(json_encode($getLocationData));
-     }
-     /** @Route("/top500") */
-     public function topAction() {
-         $data['infoPage'] = new InfoPage();
-         $data['text'] = $data['infoPage']->getContent();
-         return $this->render('Slivki/pages/pages.html.twig', $data);
-     }
-     /** @Route("/category/get_supplier_address_tab/{directorID}") */
-     public function getSupplierAddressTab(Request $request, $directorID) {
-         $entityManager = $this->getDoctrine()->getManager();
-         $director = $entityManager->getRepository(Director::class)->find($directorID);
-         if (!$director) {
-             return new Response();
-         }
-         $directorUniqueGeoLocations = [];
-         /** @var Offer $offer */
-         foreach ($director->getOffers() as $offer) {
-             if (!$offer->isActive() || !$offer->isInActivePeriod()) {
-                 continue;
-             }
-             /** @var GeoLocation $geoLocation */
-             foreach ($offer->getGeoLocations() as $geoLocation) {
-                 $isUniqueGeoLoation = true;
-                 /** @var GeoLocation $uniqueGeoLocation */
-                 foreach ($directorUniqueGeoLocations as $uniqueGeoLocation) {
-                     if ($geoLocation->getCity() == $uniqueGeoLocation->getCity() && $geoLocation->getStreet() == $uniqueGeoLocation->getStreet()
-                         && $geoLocation->getHouse() == $uniqueGeoLocation->getHouse()) {
-                         $isUniqueGeoLoation = false;
-                         break;
-                     }
-                 }
-                 if ($isUniqueGeoLoation) {
-                     $directorUniqueGeoLocations[] = $geoLocation;
-                 }
-             }
-         }
-         $data['geoLocationList'] = $directorUniqueGeoLocations;
-         return $this->render(self::getMobileDevice($request) ? 'Slivki/mobile/offer/supplier_address_tab.html.twig'
-             : 'Slivki/offers/supplier_address_tab.html.twig', $data);
-     }
-     /** @Route("/category/get_supplier_photoguide_tab/{directorID}") */
-     public function getSupplierPhotoguideTab($directorID) {
-         $entityManager = $this->getDoctrine()->getManager();
-         $director = $entityManager->getRepository(Director::class)->find($directorID);
-         if (!$director) {
-             return new Response();
-         }
-         $teaserList = [];
-         $saleRepository = $this->getSaleRepository();
-         /** @var Sale $sale */
-         foreach ($director->getSales() as $sale) {
-             $saleCached = $saleRepository->findCached($sale->getID());
-             $teaserList[] = $this->renderView('Slivki/sale/teaser.html.twig', ['sale' => $saleCached]);
-         }
-         $data['teaserList'] = $teaserList;
-         return $this->render('Slivki/offers/supplier_photoguide_tab.html.twig', $data);
-     }
-     /** @Route("/get-sorted-sidebar") */
-     public function getSortedSidebar(Request $request) {
-         if (!$request->isMethod(Request::METHOD_POST)) {
-             return $this->redirectToRoute('homepage');
-         }
-         $requestParameters = $request->request->all();
-         if (!isset($requestParameters['sortBy'])) {
-             $requestParameters['sortBy'] = 'default';
-         }
-         $categoryID = $requestParameters['categoryID'] ? $requestParameters['categoryID'] : null;
-         $coordinates = $requestParameters['coordinates'] != '' ? explode(',', $requestParameters['coordinates']) : null;
-         $sortedSaleIDList = $this->getSaleRepository()->getSaleIDSorted(
-             $requestParameters['sortBy'], $categoryID, $requestParameters['offset'],
-             $requestParameters['limit'], $coordinates);
-         $softCache = new SoftCache(SaleRepository::CACHE_NAME);
-         $sortedSaleList = $softCache->getMulti($sortedSaleIDList);
-         if (!is_array($sortedSaleList)) {
-             $sortedSaleList = [];
-         }
-         $sidebarContent = '';
-         foreach ($sortedSaleList as $sale) {
-             if (!$sale) {
-                 continue;
-             }
-             $sidebarContent .= $this->renderView('Slivki/sidebar/sale_teaser.html.twig', ['sale' => $sale]);
-         }
-         return new Response($sidebarContent);
-     }
-     /** @Route("/offer/food-extension-order") */
-     public function offerFoodExtensionOrder(Request $request) {
-         if (!self::getMobileDevice($request)) {
-             return $this->redirectToRoute('homepage');
-         }
-         return $this->render('Slivki/offers/food_extension/mobile/order.html.twig');
-     }
-     /** @Route("/offer/food-extension-order-confirm") */
-     public function offerFoodExtensionOrderConfirm(Request $request) {
-         if (!self::getMobileDevice($request)) {
-             return $this->redirectToRoute('homepage');
-         }
-         return $this->render('Slivki/offers/food_extension/mobile/order_confirm.html.twig');
-     }
-     /** @Route("/food-order/check/{orderID}") */
-     public function checkFoodOrderStateActioin($orderID) {
-         $order = $this->getDoctrine()->getManager()->find(FoodOrder::class, $orderID);
-         if (!$order || $order->getStatus() != OfferOrder::STATUS_INIT) {
-             return new Response('paid');
-         }
-         return new Response();
-     }
-     /** @Route("/offer_supplier_image/{offerID}/{limit}/{offset}") */
-     public function getOfferSupplierSliderAction(CacheService $cacheService, $offerID, $limit, $offset) {
-         $supplierOfferPhotoList = $cacheService->getMediaList($offerID, Media\OfferSupplierPhotoMedia::TYPE, $offset, $limit);
-         if (empty($supplierOfferPhotoList)) {
-             return new Response('');
-         }
-         return $this->render('Slivki/comments/offer_supplier_photos.html.twig',
-             ['supplierOfferPhotoList' => $supplierOfferPhotoList]);
-     }
-     /** @Route("/location/confirm/test") */
-     public function testLocationConfirmAction(Request $request) {
-         $request->request->set('showLocationConfirm', true);
-         return $this->indexAction($request);
-     }
-     /**
-      * @Route("/dreamland-registration/{code}")
-      */
-     public function dreamlandPartnerAction(Request $request, $code) {
-         $entityManager = $this->getDoctrine()->getManager();
-         $entityOptionRepository = $entityManager->getRepository(EntityOption::class);
-         $partnerCode = $entityOptionRepository->findOneBy([
-             'entityTypeID' => null,
-             'name' => EntityOption::OPTION_DREAMLAND_PARTNER,
-             'value' => $code
-         ]);
-         if (!$partnerCode) {
-             return $this->redirect('/');
-         }
-         if ($this->getUser()) {
-             $option = $entityOptionRepository->findOneBy([
-                 'entityTypeID' => EntityOption::USER_TYPE,
-                 'name' => EntityOption::OPTION_DREAMLAND_PARTNER,
-                 'entityID' => $this->getUser()->getID()
-             ]);
-             if (!$option) {
-                 $option = new EntityOption();
-                 $option->setEntityTypeID(EntityOption::USER_TYPE);
-                 $option->setEntityID($this->getUser()->getID());
-                 $option->setName(EntityOption::OPTION_DREAMLAND_PARTNER);
-                 $option->setValue($code);
-                 $entityManager->persist($option);
-                 $entityManager->flush();
-             }
-             return $this->redirect($entityManager->getRepository(Seo::class)->getOfferURL(Offer::DREAMLAND_OFFER_ID)->getMainAlias());
-         }
-         $request->getSession()->set(EntityOption::OPTION_DREAMLAND_PARTNER, $code);
-         if (CommonUtil::isMobileDevice($request)) {
-             return $this->redirect($entityManager->getRepository(Seo::class)->getOfferURL(Offer::DREAMLAND_OFFER_ID)->getMainAlias());
-         }
-         return $this->redirect($entityManager->getRepository(Seo::class)->getOfferURL(Offer::DREAMLAND_OFFER_ID)->getMainAlias());
-     }
-     /** @Route("/newadformat") */
-     public function newAdFormatActioin() {
-         return $this->render('Slivki/newadformat/index.html.twig');
-     }
-     public function domainPlaceHolderAction(Request $request, $entityID) {
-         $offer = $this->getDoctrine()->getManager()->find(Offer::class, $entityID);
-         $director = $offer->getDirectors()->first();
-         return $this->render(CommonUtil::isMobileDevice($request) ? 'Slivki/m/mobile/index.html.twig' : 'Slivki/m/index.html.twig', ['director' => $director]);
-     }
-     /** @Route("/email-test") */
-     public function emailTestAction(Mailer $mailer) {
-         $message = $mailer->createMessage('test', 'test');
-         $message->addTo('igoradv@gmail.com');
-         $message->setFrom('info@slivki.by', 'Slivki.by');
-         $mailer->send($message);
-         return new Response('sent');
-     }
-     /** @Route("/prilozhenie-skidok", name = "mobileApp") */
-     public function appPageAction(Request $request) {
-         $view = CommonUtil::isMobileDevice($request) ? 'Slivki/mobile/mobile_app.html.twig' : 'Slivki/mobile_app.html.twig';
-         return $this->render($view);
-     }
-     /** @Route("/betera-advent") */
-     public function beteraAdventCalendar(Request $request) {
-         return $this->render(self::getMobileDevice($request) ? 'Slivki/mobile/betera_advent/base.html.twig' : 'Slivki/betera_advent/base.html.twig');
-     }
-     /** @Route("/profile/oplata-pay") */
-     public function balanceWirtuallWallet(Request $request) {
-         return $this->render(self::getMobileDevice($request) ? 'Slivki/mobile/payment/slivki_pay/index.html.twig' : 'Slivki/payment/slivki_pay/index.html.twig');
-     }
-     /** @Route("/virtual-wallet-pay") */
-     public function balanceWirtuallWalletQuery(Request $request) {
-         return $this->render(self::getMobileDevice($request) ? 'Slivki/mobile/payment/slivki_pay/wirtualWallet.html.twig' : 'Slivki/payment/slivki_pay/wirtualWallet.html.twig');
-     }
-     /** @Route("/callback") */
-     public function callbackRequest(Request $request) {
-         return $this->render(self::getMobileDevice($request) ? 'Slivki/mobile/callback/index.html.twig' : 'Slivki/callback/index.html.twig');
-     }
-     /** @Route("/profile/transfer-balance") */
-     public function transferBalanceIsNotSlivkiPay(Request $request) {
-         return $this->render(self::getMobileDevice($request) ? 'Slivki/mobile/transfer_balance/index.html.twig' : 'Slivki/transfer_balance/index.html.twig');
-     }
-     /** @Route("/bonuses") */
-     public function getBonusesPartner(Request $request) {
-         return $this->render(self::getMobileDevice($request) ? 'Slivki/mobile/bonuses_partner/index.html.twig' : 'Slivki/bonuses_partner/index.html.twig');
-     }
-     /** @Route("/error/{statusCode}") */
-     public function errorAction($statusCode): Response {
-         return new Response('', $statusCode);
-     }
- }