src/Controller/DefaultController.php line 1452

Open in your IDE?
  1. <?php
  2. namespace Slivki\Controller;
  3. use Doctrine\ORM\Query;
  4. use Slivki\Dao\GiftCertificate\GiftCertificateDaoInterface;
  5. use Slivki\Dao\Offer\FavouriteOfferDaoInterface;
  6. use Slivki\Dao\Offer\OfferDaoInterface;
  7. use Slivki\Dao\OfferCode\PurchaseCountWithCorrectionDaoInterface;
  8. use Slivki\Dao\TireFilter\TireFilterDaoInterface;
  9. use Slivki\Entity\AlternativeOffer;
  10. use Slivki\Entity\BankCurrency;
  11. use Slivki\Entity\Banner\MobileLandingBanner;
  12. use Slivki\Entity\Director;
  13. use Slivki\Entity\FoodOrder;
  14. use Slivki\Entity\GiftCertificate;
  15. use Slivki\Entity\MailingCampaign;
  16. use Slivki\Entity\SearchQuery;
  17. use Slivki\Entity\Seo;
  18. use Slivki\Entity\UserPhone;
  19. use Slivki\Enum\SwitcherFeatures;
  20. use Slivki\Repository\Comment\CommentRepositoryInterface;
  21. use Slivki\Services\CategoryBoxCacheService;
  22. use Slivki\Services\City\CityProvider;
  23. use Slivki\Services\Comment\CommentCacheService;
  24. use Slivki\Services\DeviceTypeService;
  25. use Slivki\Services\Offer\GalleryVideo\VideoPackageDtoGetter;
  26. use Slivki\Services\Sidebar\SidebarCacheService;
  27. use Slivki\Services\Subscription\SubscriptionService;
  28. use Slivki\Services\Switcher\ServerFeatureStateChecker;
  29. use Slivki\Services\VoiceMessage\VoiceMessageUploader;
  30. use Slivki\Util\Iiko\Dodo;
  31. use Slivki\Util\Iiko\Dominos;
  32. use Symfony\Component\HttpFoundation\Cookie;
  33. use Symfony\Component\Routing\Annotation\Route;
  34. use Slivki\Entity\Booking;
  35. use Slivki\Entity\Category;
  36. use Slivki\Entity\ChatSession;
  37. use Slivki\Entity\City;
  38. use Slivki\Entity\Comment;
  39. use Slivki\Entity\CommentLike;
  40. use Slivki\Entity\EntityOption;
  41. use Slivki\Entity\GeoLocation;
  42. use Slivki\Entity\HotFeed;
  43. use Slivki\Entity\InfoPage;
  44. use Slivki\Entity\MainMenu;
  45. use Slivki\Entity\Media;
  46. use Slivki\Entity\MediaType;
  47. use Slivki\Entity\Offer;
  48. use Slivki\Entity\OfferOrder;
  49. use Slivki\Entity\OfferProposal;
  50. use Slivki\Entity\ReadabilityStat;
  51. use Slivki\Entity\Sale;
  52. use Slivki\Entity\SearchStatistic;
  53. use Slivki\Entity\Subscriber;
  54. use Slivki\Entity\User;
  55. use Slivki\Entity\UserGroup;
  56. use Slivki\Repository\CityRepository;
  57. use Slivki\Repository\CommentRepository;
  58. use Slivki\Repository\OfferRepository;
  59. use Slivki\Repository\SaleRepository;
  60. use Slivki\Repository\SeoRepository;
  61. use Slivki\Services\BannerService;
  62. use Slivki\Services\CacheService;
  63. use Slivki\Services\Category\CategoryCacheService;
  64. use Slivki\Services\Mailer;
  65. use Slivki\Services\Offer\OfferCacheService;
  66. use Slivki\Services\Sale\SaleCacheService;
  67. use Slivki\Services\TextCacheService;
  68. use Slivki\Twig\SlivkiTwigExtension;
  69. use Slivki\Util\CommonUtil;
  70. use Slivki\Util\Iiko\AbstractDelivery;
  71. use Slivki\Util\Iiko\SushiHouse;
  72. use Slivki\Services\ImageService;
  73. use Slivki\Util\Logger;
  74. use Slivki\Util\SoftCache;
  75. use Slivki\Util\CensureLibrary\Censure;
  76. use Symfony\Component\HttpFoundation\JsonResponse;
  77. use Symfony\Component\HttpFoundation\Request;
  78. use Symfony\Component\HttpFoundation\Response;
  79. use Symfony\Component\Filesystem\Filesystem;
  80. use Slivki\Entity\Visit;
  81. use Symfony\Component\HttpKernel\KernelInterface;
  82. use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
  83. use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
  84. use Symfony\Component\Validator\Constraints\Email;
  85. class DefaultController extends SiteController {
  86.     const OFFERS_PER_PAGE 24;
  87.     const LONG_CATEGORIES_PER_PAGE 36;
  88.     const SIDEBAR_CACHE_PATH '/slivki-cache/sidebar';
  89.     const CATEGORY_BOX_PATH '/slivki-cache/categorybox/';
  90.     const LONG_CATEGORIES = [
  91.         Category::TIRE_FITTING_CATEGORY_ID,
  92.         Category::LASER_EPILATION_CATEGORY_ID,
  93.     ];
  94.     private TireFilterDaoInterface $tireFilterDao;
  95.     private OfferDaoInterface $offerDao;
  96.     public function __construct(
  97.         KernelInterface $kernel,
  98.         TireFilterDaoInterface $tireFilterDao,
  99.         OfferDaoInterface $offerDao
  100.     ) {
  101.         parent::__construct($kernel);
  102.         $this->tireFilterDao $tireFilterDao;
  103.         $this->offerDao $offerDao;
  104.     }
  105.     /**
  106.      * @Route("/", name="homepage")
  107.      */
  108.     public function indexAction(
  109.         Request $request,
  110.         BannerService $bannerService,
  111.         OfferCacheService $offerCacheService,
  112.         SaleCacheService $saleCacheService,
  113.         CategoryBoxCacheService $categoryBoxCacheService,
  114.         CategoryCacheService $categoryCacheService,
  115.         CommentRepositoryInterface $commentRepository
  116.     ) {
  117.         $isMobileDevice self::getMobileDevice($request);
  118.         if ($request->getHost() == 'm.slivki.by') {
  119.             return $this->render($isMobileDevice'Slivki/m/mobile/index.html.twig' 'Slivki/m/index.html.twig');
  120.         }
  121.         $cityID $request->getSession()->get(City::CITY_ID_SESSION_KEYCity::DEFAULT_CITY_ID);
  122.         $referrer $request->headers->get('referer''');
  123.         $response = new Response();
  124.         if (self::getMobileDevice($request)) {
  125.             $urlParsed parse_url($referrer);
  126.             $referrerHost = isset($urlParsed['host']) ? $urlParsed['host']: '';
  127.             if ($referrer != $request->getSchemeAndHttpHost() . '/landing' && $referrerHost != $request->getHost() && $cityID == City::DEFAULT_CITY_ID) {
  128.                 return $this->redirect('/landing');
  129.             }
  130.         }
  131.         $mainMenuItems $this->getDoctrine()->getManager()->getRepository(MainMenu::class)->getItemListCached(MainMenu::MENU_ID_MAIN$cityID);
  132.         $categoryBoxList = [];
  133.         $expanded count($mainMenuItems) == 1;
  134.         $i 0;
  135.         foreach ($mainMenuItems as $menuItem) {
  136.             $category $categoryCacheService->getCategory($menuItem->getEntityID());
  137.             $categoryBoxTarantool $categoryBoxCacheService->getCategoryBox(
  138.                 $menuItem->getEntityID(),
  139.                 CategoryBoxCacheService::SORT_BY_DEFAULT_COLUMN,
  140.                 $isMobileDevice,
  141.                 0,
  142.                 $category[8]
  143.             );
  144.             $categoryBox = \str_replace(
  145.                 '<!-- categoryTeasersPlaceholder -->',
  146.                 $categoryBoxTarantool['categoryBoxHtml'],
  147.                 $categoryBoxCacheService->getCategoryPage($menuItem->getEntityID(), false$isMobileDevice)
  148.             );
  149.             if ($categoryBox) {
  150.                 $categoryBoxList[$menuItem->getEntityID()] = $categoryBox;
  151.             }
  152.             if ($i == 0) {
  153.                 break;
  154.             }
  155.             $i++;
  156.         }
  157.         // getSidebarBanner
  158.         if (!$isMobileDevice) {
  159.             if ($this->getUser() && $this->getUser()->hasRole(UserGroup::ROLE_ADS_FREE)) {
  160.                 $data['sidebarBanner'] = '';
  161.             } else {
  162.                 $sidebarBannerCached $bannerService->getSidebarBannerCached($cityID);
  163.                 $data['sidebarBanner'] = $sidebarBannerCached['html'];
  164.             }
  165.             $data['lastComments'] = $commentRepository->getLastOfferComments(3);
  166.         }
  167.         $data['categoryBoxList'] = $categoryBoxList;
  168.         $data['salesList'] = $this->getSaleRepository()->getMainSales($cityIDself::getMobileDevice($request));
  169.         $data['mainPage'] = true;
  170.         $data['smallCity'] = $expanded;
  171.         $deviceType $isMobileDevice self::DEVICE_TYPE_MOBILE self::DEVICE_TYPE_DESKTOP;
  172.         $this->addVisit(0Visit::TYPE_MAIN_PAGE$deviceType$this->getUser(), $request->getClientIp(), $referrer);
  173.         $data['cityID'] = $cityID;
  174.         $request->attributes->set('mainPage'true);
  175.         $data['offerRateSchedule'] = $this->getOfferRateSchedule($request->getSession());
  176.         $mainHotFeed '';
  177.         $mainHotFeedEntities $this->getMainHotFeed($offerCacheService$saleCacheService200HotFeed::TYPE_MAIN_PAGE$cityID);
  178.         if (count($mainHotFeedEntities) > 4) {
  179.             foreach ($mainHotFeedEntities as $entity) {
  180.                 $mainHotFeed .= $this->renderView($isMobileDevice 'Slivki/mobile/hot_feed_teaser.html.twig'
  181.                     'Slivki/top_main_feed_teaser_mobile.html.twig',  $entity);
  182.             }
  183.         }
  184.         $data['mainHotFeed'] = $mainHotFeed;
  185.         $topLevelCategoryIDList = [];
  186.         foreach ($mainMenuItems as $menuItem) {
  187.             $topLevelCategoryIDList[] = $menuItem->getEntityID();
  188.         }
  189.         $data['topLevelCategoryIDList'] = $topLevelCategoryIDList;
  190.         $response->setContent($this->renderView($isMobileDevice 'Slivki/mobile/index.html.twig' 'Slivki/index.html.twig'$data));
  191.         return $response;
  192.     }
  193.     /** @Route("/auth") */
  194.     public function auth(Request $request) {
  195.         $path $request->query->get('path''/');
  196.         $response = new Response();
  197.         if ($this->getUser()) {
  198.             return $this->redirect($path);
  199.         }
  200.         return $this->render(CommonUtil::isMobileDevice($request) ? 'Slivki/mobile/auth.html.twig' 'Slivki/auth.html.twig');
  201.     }
  202.     /** @Route("/main_top_sales/{offset}") */
  203.     public function getMainOffsetSales(Request $request$offset) {
  204.         $cityID $request->getSession()->get(City::CITY_ID_SESSION_KEYCity::DEFAULT_CITY_ID);
  205.         $result = [];
  206.         $data['sale'] = $this->getSaleRepository()->getMainSales($cityIDself::getMobileDevice($request), $offset);
  207.         foreach ($data['sale'] as $sale) {
  208.             $result['result'][] = $this->renderView('Slivki/news/mobile_top_news.html.twig'$sale);
  209.         }
  210.         return new JsonResponse($result);
  211.     }
  212.     /** @Route("/main_hot_feed/{limit}/{offset}/{type}/{isNewMobileVersion}/{cityID}") */
  213.     public function getMainHotFeedAction(Request $requestSaleCacheService $saleCacheServiceOfferCacheService $offerCacheService$limit$offset$type$isNewMobileVersion$cityID) {
  214.         $result '';
  215.         foreach ($this->getMainHotFeed($offerCacheService$saleCacheService$limit$offset$type$cityID) as $entity) {
  216.             $result .= $this->renderView($isNewMobileVersion == 'true' ?  'Slivki/mobile/hot_feed_teaser.html.twig':
  217.                 'Slivki/top_main_feed_teaser_mobile.html.twig',  $entity);
  218.         }
  219.         return new Response($result);
  220.     }
  221.     public function categoryAction(
  222.         Request $request,
  223.         CategoryCacheService $categoryCacheService,
  224.         CategoryBoxCacheService $categoryBoxCacheService,
  225.         $entityID
  226.     ) {
  227.         return $this->tarantoolCategory($request$categoryCacheService$categoryBoxCacheService$entityID);
  228.     }
  229.     private function tarantoolCategory(
  230.         Request $request,
  231.         CategoryCacheService $categoryCacheService,
  232.         CategoryBoxCacheService $categoryBoxCacheService,
  233.         $entityID
  234.     ) {
  235.         $currentPage $request->query->get('page'1);
  236.         $isMobileDevice CommonUtil::isMobileDevice($request);
  237.         $deviceType $isMobileDevice self::DEVICE_TYPE_MOBILE self::DEVICE_TYPE_DESKTOP;
  238.         $this->addVisit(
  239.             $entityID,
  240.             Visit::TYPE_OFFER_CATEGORY,
  241.             $deviceType,
  242.             $this->getUser(),
  243.             $request->getClientIp(),
  244.             $request->headers->get('referer''')
  245.         );
  246.         $category $categoryCacheService->getCategory($entityID);
  247.         $response = new Response();
  248.         $perPage in_array($entityIDself::LONG_CATEGORIES) ? self::LONG_CATEGORIES_PER_PAGE self::OFFERS_PER_PAGE;
  249.         $categoryBox $categoryBoxCacheService->getCategoryBox(
  250.             $entityID,
  251.             CategoryBoxCacheService::SORT_BY_DEFAULT_COLUMN,
  252.             $isMobileDevice,
  253.             ($currentPage 1) * $perPage,
  254.             $perPage,
  255.         );
  256.         $categoryPageContent str_replace(
  257.             '<!-- categoryTeasersPlaceholder -->',
  258.             $categoryBox['categoryBoxHtml'],
  259.             $categoryBoxCacheService->getCategoryPage($entityIDtrue$isMobileDevice)
  260.         );
  261.         $paginationHtml $this->renderView('Slivki/pagination.html.twig', [
  262.             'paginationID' => 'categoryPagination',
  263.             'total' => ceil($categoryBox['totalTeaserCount'] / self::OFFERS_PER_PAGE),
  264.             'current' => $currentPage,
  265.             'url' => $request->getRequestUri() . '?page='
  266.         ]);
  267.         $categoryPageContent str_replace(
  268.             '<!-- categoryPaginationPlaceholder -->',
  269.             $paginationHtml,
  270.             $categoryPageContent
  271.         );
  272.         $tireFilterCategories $this->tireFilterDao->getCategoriesByParentCategory($entityID);
  273.         if (!== \count($tireFilterCategories)) {
  274.             $categoryPageContent = \str_replace(
  275.                 '<!-- tireFilerPlaceholder -->',
  276.                 $this->renderView('Slivki/tire/tire_filter.html.twig', [
  277.                     'categories' => $tireFilterCategories,
  278.                 ]),
  279.                 $categoryPageContent,
  280.             );
  281.         }
  282.         $data = [
  283.             'categoryID' => $entityID,
  284.             'category' => $categoryPageContent,
  285.             'brandingBannerCategoryIDs' => [$entityID]
  286.         ];
  287.         $response->setContent($this->renderView($isMobileDevice 'Slivki/mobile/offer/category.html.twig'
  288.             'Slivki/offers/category_page.html.twig'$data));
  289.         return $response;
  290.     }
  291.     public function categoryRatingAction(Request $requestTextCacheService $textCacheService$entityID) {
  292.         $isMobile CommonUtil::isMobileDevice($request);
  293.         $content $textCacheService->getText($entityID$isMobile TextCacheService::CATEGORY_COMPANIES_RATING_PAGE_MOBILE_TYPE TextCacheService::CATEGORY_COMPANIES_RATING_PAGE_TYPE);
  294.         if (!$content) {
  295.             throw $this->createNotFoundException();
  296.         }
  297.         return $this->render($isMobile 'Slivki/mobile/offer/category_rating_page.html.twig' 'Slivki/offers/category_rating_page.html.twig', [
  298.             'content' => $content,
  299.             'robotsMeta' => 'noindex, follow'
  300.         ]);
  301.     }
  302.     /** @Route("/category/load-more/{categoryID}/{pageNumber}/{sortBy}") */
  303.     public function categoryLoadMoreAction(
  304.         Request $request,
  305.         CategoryBoxCacheService $categoryBoxCacheService,
  306.         $categoryID,
  307.         $pageNumber,
  308.         $sortBy
  309.     ) {
  310.         return $this->categoryLoadMoreTarantool($request$categoryBoxCacheService$categoryID$pageNumber$sortBy);
  311.     }
  312.     private function categoryLoadMoreTarantool(
  313.         Request $request,
  314.         CategoryBoxCacheService $categoryBoxCacheService,
  315.         $categoryID,
  316.         $pageNumber,
  317.         $sortBy
  318.     ) {
  319.         $referer $request->headers->get('referer');
  320.         if (!$referer) {
  321.             return new Response('Referer is invalid or empty.');
  322.         }
  323.         $refererPathInfo Request::create($referer)->getPathInfo();
  324.         $isMobileDevice CommonUtil::isMobileDevice($request);
  325.         switch ($sortBy) {
  326.             case 'popularity':
  327.                 $sortByColumn CategoryBoxCacheService::SORT_BY_PURCHASE_COLUMN;
  328.                 break;
  329.             case 'visit':
  330.                 $sortByColumn CategoryBoxCacheService::SORT_BY_VISIT_COLUMN;
  331.                 break;
  332.             case 'distance':
  333.             case 'timetable':
  334.             case 'rating':
  335.                 break;
  336.             case 'update-date':
  337.                 $sortByColumn CategoryBoxCacheService::SORT_BY_CREATED_ON_COLUMN;
  338.                 break;
  339.             case 'price-asc':
  340.                 $sortByColumn CategoryBoxCacheService::SORT_BY_PRICE_ASC_COLUMN;
  341.                 break;
  342.             case 'price-desc':
  343.                 $sortByColumn CategoryBoxCacheService::SORT_BY_PRICE_DESC_COLUMN;
  344.                 break;
  345.             default:
  346.                 $sortByColumn CategoryBoxCacheService::SORT_BY_DEFAULT_COLUMN;
  347.         }
  348.         $perPage in_array($categoryIDself::LONG_CATEGORIES) ? self::LONG_CATEGORIES_PER_PAGE self::OFFERS_PER_PAGE;
  349.         if ($sortBy == 'distance') {
  350.             $categoryBox $categoryBoxCacheService->getCategoryBoxSortedByLocation(
  351.                 $categoryID,
  352.                 $request->cookies->get(User::CURRENT_LOCATION_COOKIEGeoLocation::DEFAULT_LOCATION),
  353.                 $isMobileDevice,
  354.                 ($pageNumber 1) * $perPage,
  355.                 $perPage,
  356.             );
  357.         } elseif ($sortBy == 'timetable') {
  358.             $categoryBox $categoryBoxCacheService->getCategoryBoxSortedByTimetable(
  359.                 $categoryID,
  360.                 $isMobileDevice,
  361.                 ($pageNumber 1) * $perPage,
  362.                 $perPage,
  363.             );
  364.         } elseif ($sortBy == 'rating') {
  365.             $categoryBox $categoryBoxCacheService->getCategoryBoxSortedByRating(
  366.                 $categoryID,
  367.                 $isMobileDevice,
  368.                 ($pageNumber 1) * $perPage,
  369.                 $perPage,
  370.             );
  371.         } else {
  372.             $categoryBox $categoryBoxCacheService->getCategoryBox(
  373.                 $categoryID,
  374.                 $sortByColumn,
  375.                 $isMobileDevice,
  376.                 ($pageNumber 1) * $perPage,
  377.                 $perPage,
  378.             );
  379.         }
  380.         return new JsonResponse([
  381.             'teasers' => $categoryBox['categoryBoxHtml'],
  382.             'pagination' => $this->renderView('Slivki/pagination.html.twig', [
  383.                 'paginationID' => 'categoryPagination',
  384.                 'total' => ceil($categoryBox['totalTeaserCount'] / self::OFFERS_PER_PAGE),
  385.                 'current' => $pageNumber,
  386.                 'url' => $refererPathInfo '?page='
  387.             ])
  388.         ]);
  389.     }
  390.     /**
  391.      * @Route("/categoryBoxNotExpanded/{categoryID}")
  392.      */
  393.     public function categoryBoxNotExpandedAction(
  394.         Request $request,
  395.         CategoryBoxCacheService $categoryBoxCacheService,
  396.         CategoryCacheService $categoryCacheService,
  397.         $categoryID
  398.     ) {
  399.         $isMobileDevice CommonUtil::isMobileDevice($request);
  400.         $category $categoryCacheService->getCategory($categoryID);
  401.         $categoryBoxTarantool $categoryBoxCacheService->getCategoryBox(
  402.             $categoryID,
  403.             CategoryBoxCacheService::SORT_BY_DEFAULT_COLUMN,
  404.             $isMobileDevice,
  405.             0,
  406.             $category[8]
  407.         );
  408.         $categoryBox = \str_replace(
  409.             '<!-- categoryTeasersPlaceholder -->',
  410.             $categoryBoxTarantool['categoryBoxHtml'],
  411.             $categoryBoxCacheService->getCategoryPage($categoryIDfalse$isMobileDevice)
  412.         );
  413.         return new Response($categoryBox);
  414.     }
  415.     /**
  416.      * @Route("/moreOffers")
  417.      */
  418.     public function moreOffers(Request $request) {
  419.         $categoryID = (int)$request->query->get("categoryID"0);
  420.         $data['categoryBoxID'] = $request->query->get("categoryBoxId"0);
  421.         $moreCount = (int)$request->query->get("moreCount"150);
  422.         $position = (int)$request->query->get("position"0);
  423.         $category $this->getCategoryRepository()->findCached($categoryID)['category'];
  424.         if (!$category) {
  425.             return new Response();
  426.         }
  427.         $offerIDList = [];
  428.         $sql "select entity_id from offer_category_position where category_id = $categoryID order by position offset $position limit $moreCount + 1";
  429.         $offersByPosition $this->getDoctrine()->getManager()->getConnection()->executeQuery($sql)->fetchAll(Query::HYDRATE_ARRAY);
  430.         $i 0;
  431.         foreach ($offersByPosition as $offerPosition) {
  432.             if ($i>=$moreCount) {
  433.                 break;
  434.             }
  435.             $offerIDList[] = $offerPosition['entity_id'];
  436.             $i++;
  437.         }
  438.         $softCache = new SoftCache(OfferRepository::CACHE_NAME);
  439.         $offerListCached $softCache->getMulti($offerIDList);
  440.         if(!$offerListCached) {
  441.             return new Response('');
  442.         }
  443.         $moreOfferList = [];
  444.         foreach ($offerListCached as $offer) {
  445.             $moreOfferList[] = $offer;
  446.         }
  447.         $data['position'] = $position $moreCount;
  448.         $data['expanded'] = !count($offersByPosition) > count($offerIDList);
  449.         $data['showCollapse'] = true;
  450.         $data['isMailing'] = false;
  451.         $teaserBanners $this->getOfferRepository()->getTeaserBanners($category);
  452.         $data['teaserBanners'] = $teaserBanners['teaserBanners'];
  453.         $data['absolutePosition'] = $position 1;
  454.         $data['withVerticalBannersRowList'] = $teaserBanners['withVerticalBannersRowList'];
  455.         $data['category'] = $category;
  456.         $data['offerList'] = $moreOfferList;
  457.         $response $this->render("Slivki/offers/teasers.html.twig"$data);
  458.         return $response;
  459.     }
  460.     public function detailsAction(
  461.         Request $request,
  462.         BannerService $bannerService,
  463.         OfferCacheService $offerCacheService,
  464.         CacheService $cacheService,
  465.         $entityID,
  466.         ImageService $imageService,
  467.         SubscriptionService $subscriptionService,
  468.         GiftCertificateDaoInterface $giftCertificateDao,
  469.         ServerFeatureStateChecker $serverFeatureStateChecker,
  470.         VideoPackageDtoGetter $videoPackageDtoGetter,
  471.         CityProvider $cityProvider,
  472.         PurchaseCountWithCorrectionDaoInterface $purchaseCountWithCorrectionDao,
  473.         FavouriteOfferDaoInterface $favouriteOfferDao
  474.     ) {
  475.         ini_set('memory_limit''10g');
  476.         $data['currentPage'] = $request->query->getInt('page'1);
  477.         $this->get('session')->set('userCommentImages', []);
  478.         $entityManager $this->getDoctrine()->getManager();
  479.         $offerRepository $this->getOfferRepository();
  480.         $offer $offerCacheService->getOffer($entityIDfalsetrue);
  481.         $data['usersWithOfferInFavouritesCount'] = $favouriteOfferDao->getUsersWithOfferInFavouritesCount($entityID);
  482.         if ($offer instanceof Offer && $offer->getDefaultCityId() === City::TASHKENT_CITY_ID && $cityProvider->getDefaultCityId() !== City::TASHKENT_CITY_ID) {
  483.             return $this->redirect('https://www.slivki.uz' $request->getRequestUri(), Response::HTTP_MOVED_PERMANENTLY);
  484.         }
  485.         if ($offer instanceof Offer && $offer->getDefaultCityId() !== City::TASHKENT_CITY_ID && $cityProvider->getDefaultCityId() === City::TASHKENT_CITY_ID) {
  486.             Logger::instance('excdebug')->info($offer->getDefaultCityId());
  487.             Logger::instance('excdebug')->info($cityProvider->getDefaultCityId());
  488.             //throw $this->createNotFoundException();
  489.         }
  490.         $dreamLangPartner $request->getSession()->get(EntityOption::OPTION_DREAMLAND_PARTNER);
  491.         if ($this->getUser() && $dreamLangPartner && !$entityManager->getRepository(User::class)->getDreamlandOption($this->getUser()->getID())) {
  492.             $option = new EntityOption();
  493.             $option->setEntityTypeID(EntityOption::USER_TYPE);
  494.             $option->setEntityID($this->getUser()->getID());
  495.             $option->setName(EntityOption::OPTION_DREAMLAND_PARTNER);
  496.             $option->setValue($dreamLangPartner);
  497.             $entityManager->persist($option);
  498.             $entityManager->flush();
  499.             $request->getSession()->remove(EntityOption::OPTION_DREAMLAND_PARTNER);
  500.         }
  501.         $pastOffer false;
  502.         $timeNow = new \DateTime();
  503.         $preview $request->query->get("preview"false);
  504.         if (!$offer || $preview) {
  505.             $offer $offerRepository->find($entityID);
  506.             if (!$offer || ((!$offer->isInVisiblePeriod() || !$offer->isActive()) && !$preview)) {
  507.                 throw $this->createNotFoundException();
  508.             }
  509.             if ((!$offer->isActive() || $offer->getActiveTill() < $timeNow || $offer->getActiveSince() > $timeNow) && !$preview) {
  510.                 $pastOffer true;
  511.             }
  512.             if ($preview || $pastOffer) {
  513.                 $mediaRepository $this->getMediaRepository();
  514.                 $offer->setDetailMeidas($mediaRepository->getOfferDetailMedias($offer->getID()));
  515.                 $offer->setShopMedias($mediaRepository->getOfferShopMedias($offer->getID()));
  516.             } else {
  517.                 Logger::instance('CACHE DEBUG')->info('Offer ' $entityID ' is not found in cache');
  518.                 $offer $offerCacheService->reloadOfferCache($entityID);
  519.             }
  520.         }
  521.         if ((!$offer->isActive() || $offer->getActiveTill() < $timeNow || $offer->getActiveSince() > $timeNow) && !$preview) {
  522.             $pastOffer true;
  523.         }
  524.         if ($entityID == 131841 && ($pastOffer || $offer->isHidden())) { // issue #2688
  525.             return $this->redirect($this->getSeoRepository()->getByEntity(SeoRepository::RESOURCE_URL_OFFER_CATEGORY509)->getMainAlias());
  526.         }
  527.         if ($offer->isHidden()) {
  528.             throw $this->createNotFoundException();
  529.         }
  530.         $response = new Response();
  531.         $offerRateSchedule $this->getOfferRateSchedule($request->getSession());
  532.         if ($offerRateSchedule) {
  533.             if ($offerRateSchedule->getOffer()->getID() == $entityID) {
  534.                 $request->getSession()->set(SiteController::LAST_OFFER_RATE_ACTIVITY_PARAMETER_NAMEtime());
  535.                 $sql 'delete from offer_rate_schedule where user_id = ' . (int)$this->getUser()->getID() . ' and offer_id = ' . (int)$entityID;
  536.                 $entityManager->getConnection()->executeQuery($sql);
  537.             } else {
  538.                 $data['offerRateSchedule'] = $offerRateSchedule;
  539.             }
  540.         }
  541.         $data['pastOffer'] = $pastOffer;
  542.         $data['todayPurchaseCount'] = $purchaseCountWithCorrectionDao->findLastDayByOfferId($offer->getID());
  543.         if (!$pastOffer && $offer->getFreeCodesCount() > 0) {
  544.             $lastPurchaseTime $offerRepository->getLastPurchaseTime($offer->getID());
  545.             if ($lastPurchaseTime) {
  546.                 $now = new \DateTime();
  547.                 $lastPurchaseInterval $now->diff($lastPurchaseTime);
  548.                 $lastPurchaseText '';
  549.                 if ($lastPurchaseInterval->0) {
  550.                     $lastPurchaseText $lastPurchaseInterval->' час' CommonUtil::plural(['''а''ов'], $lastPurchaseInterval->h) . ' ';
  551.                 }
  552.                 $lastPurchaseMinutes $lastPurchaseInterval->== && $lastPurchaseInterval->$lastPurchaseInterval->i;
  553.                 $lastPurchaseText .= $lastPurchaseMinutes ' минут' CommonUtil::plural(['у''ы'''], $lastPurchaseMinutes) . ' назад';
  554.                 $data['lastPurchaseText'] = $lastPurchaseText;
  555.             }
  556.         } elseif (!self::getMobileDevice($request)) {
  557.             $data['relatedOfferListHtml'] = implode(''$this->getRelatedOffersTeasers($cacheService$offer));
  558.         }
  559.         $data['offer'] = $offer;
  560.         $data['galleryVideos'] = $videoPackageDtoGetter->getByOfferId($offer->getID());
  561.         $userGeoLocation $request->cookies->get(User::CURRENT_LOCATION_COOKIEnull);
  562.         if ($userGeoLocation) {
  563.             $userGeoLocation explode(','$userGeoLocation);
  564.         }
  565.         $data['offerGeoLocationData'] = $offerRepository->getOfferGeoLocationData($offer$userGeoLocation$imageService);
  566.         $data['freeCodesCount'] = 0;
  567.         $buyCodePopup "";
  568.         /** @var User $user */
  569.         $user $this->getUser();
  570.         $data['offerIsFreeForUser'] = $offerRepository->isOfferFreeForUser($offer$user);
  571.         $codeCost $offerRepository->getCodeCost($offer);
  572.         if (!$pastOffer) {
  573.             if ($user && !$subscriptionService->isSubscriber($user) && !$data['offerIsFreeForUser']) {
  574.                 $data['testSubscriptionGroupID'] = true;
  575.             }
  576.             $data['canBuyFromBalance'] = false;
  577.             $data['freeCodesCount'] = $offer->getFreeCodesCount();
  578.             if ($offer->getID() != Offer::DREAMLAND_OFFER_ID) {
  579.                 if (!$user) {
  580.                     $buyCodePopup ".modal-auth";
  581.                 } else {
  582.                     if ($user->getFullBalance() >= $codeCost || $data['offerIsFreeForUser']) {
  583.                         $buyCodePopup "#confirmBox";
  584.                         $data['canBuyFromBalance'] = true;
  585.                     }
  586.                     if (isset($data['testSubscriptionGroupID'])) {
  587.                         $buyCodePopup "#confirmBox";
  588.                     }
  589.                 }
  590.             }
  591.         }
  592.         if (!$serverFeatureStateChecker->isServerFeatureEnabled(SwitcherFeatures::REPLENISHMENT_BALANCE())) {
  593.             $buyCodePopup "#confirmBox";
  594.             $data['canBuyFromBalance'] = false;
  595.         }
  596.         if ($user) {
  597.             $subscription $subscriptionService->getSubscription($user);
  598.             $data['allowedCodesCountBySubscription'] = $subscriptionService->isSubscriber($user)
  599.                 ? $subscription->getNumberOfCodes()
  600.                 : 0;
  601.         }
  602.         $buyButtonLabel 'Получить скидку ';
  603.         if ($data['offer']->isOneOfOnlineOrderAllowedOnSite()) {
  604.             $buyButtonLabel 'Получить промокод ';
  605.         }
  606.         if ($data['offerIsFreeForUser']) {
  607.             $buyButtonLabel 'Бесплатный промокод';
  608.         } else {
  609.             if ($offer->isActiveCurrencyCalculator() && is_numeric($offer->getDiscount())) {
  610.                 $bankCurrency $entityManager->getRepository(BankCurrency::class)->findOneBy(['currency' => $offer->getBankCurrency()->getCurrency()]);
  611.                 if ($bankCurrency) {
  612.                     $buyButtonLabel .= round($bankCurrency->getRate() * $offer->getDiscount(), 2);
  613.                 }
  614.             } else {
  615.                 $buyButtonLabel .= $offer->getDiscount();
  616.             }
  617.             $buyButtonLabel mb_strtoupper($buyButtonLabel);
  618.         }
  619.         if ($entityID == Offer::DREAMLAND_OFFER_ID) {
  620.             $buyButtonLabel 'Купить билет от ' $offer->getOfferPrice($offer)  . ' руб.';
  621.         }
  622.         $isMobile CommonUtil::isMobileDevice($request);
  623.         $commentsCacheName $isMobile CommentCacheService::MOBILE_CACHE_NAME CommentCacheService::CACHE_NAME;
  624.         if ($data['currentPage'] == 1) {
  625.             $comments $this->getComments($request$bannerService$entityIDComment::TYPE_OFFER_COMMENT000$commentsCacheName);
  626.         } else {
  627.             $comments $this->getCommentsByOffer($entityID$data['currentPage'], CommentRepository::COMMENTS_PER_PAGE$isMobile);
  628.         }
  629.         $commentsAmount $this->getCommentRepository()->getCommentsCountByEntityID($entityIDComment::TYPE_OFFER_COMMENT);
  630.         $data['comments'] = $this->renderView($isMobile 'Slivki/mobile/comment/block.html.twig' 'Slivki/comments/comments_list.html.twig', [
  631.             'entityID' => $entityID,
  632.             'type' => Comment::TYPE_OFFER_COMMENT,
  633.             'comments' => $comments,
  634.             'commentsAmount' => $commentsAmount,
  635.             'showCommentsAmount' => true,
  636.             'rating' => $offer->getRating(),
  637.         ]);
  638.         $data['items'] = []; //$offer->getItems();
  639.         $dataItemsCount count($data['items']);
  640.         if ($dataItemsCount 0) {
  641.             $minOfferPrice INF;
  642.             foreach ($data['items'] as $item) {
  643.                 if ($item->getOfferPrice() < $minOfferPrice) {
  644.                     $minOfferPrice $item->getOfferPrice();
  645.                 }
  646.             }
  647.             $buyButtonLabel 'Купить билет от ' number_format($minOfferPrice,2',''') . ' руб.';
  648.         }
  649.         $buyCodeBtnText $offer->getBuyCodeButtonText();
  650.         $buyCodeBtnText $buyCodeBtnText $buyCodeBtnText '';
  651.         $data['buyButtonLabel'] = $buyCodeBtnText == '' mb_strtoupper(mb_substr($buyButtonLabel01)) . mb_strtolower(mb_substr($buyButtonLabel1)) : $buyCodeBtnText;
  652.         if ($offer->isOneOfOnlineOrderAllowedOnSite()) {
  653.             $data['buyButtonLabelOnline'] = $offer->isBuyCodeDisable() ? 'Оформить сертификат онлайн' 'Заказать онлайн';
  654.         }
  655.         $data['isAllowedByOnlyCode'] =  $dataItemsCount == || ($dataItemsCount && $offer->isAllowedBuyOnlyCode());
  656.         $data['showGlobalcard'] = false;
  657.         $data['showGlobalcardFitness'] = false;
  658.         $data['tour3dName'] = '';
  659.         $softCache = new SoftCache(OfferRepository::CACHE_NAME);
  660.         $cacheKey 'alt-offers-box-' $entityID;
  661.         $altOffersBox $softCache->get($cacheKey);
  662.         if ($altOffersBox == SoftCache::LOCKED_KEY) {
  663.             $altOffersBox $softCache->getDataForLockedKey($cacheKey30);
  664.         } else if (!$altOffersBox) {
  665.             $softCache->add($cacheKeySoftCache::LOCKED_KEY30);
  666.             $cacheExpire strtotime(date('Y-m-d 05:00:00'strtotime('+1 day'))) - time();
  667.             $altOffersBox "";
  668.             $altOfferList $this->getDoctrine()->getRepository(AlternativeOffer::class)->getByOfferID($entityID);
  669.             if ($altOfferList) {
  670.                 if (count($altOfferList) < 3) {
  671.                     $altOffersBox SoftCache::EMPTY_VALUE;
  672.                 } else {
  673.                     if (count($altOfferList) < 6) {
  674.                         $altOfferList array_slice($altOfferList03);
  675.                     }
  676.                     foreach ($altOfferList as $altOffer) {
  677.                         $alternativeOffer $offerCacheService->getOffer($altOffer->getAlternativeOfferID(), true);
  678.                         if ($alternativeOffer) {
  679.                             $altOffersBox .= $this->get('twig')->render('Slivki/offers/teaser.html.twig', ['offer' => $alternativeOffer'noLazyLoad' => true]);
  680.                         } else {
  681.                             $this->getLogger()->error('Alternative offer ' $altOffer->getOfferID() . " not found in cache");
  682.                             $altOffersBox "";
  683.                             break;
  684.                         }
  685.                     }
  686.                 }
  687.             }
  688.             $softCache->set($cacheKey$altOffersBox$cacheExpire);
  689.             if ($altOffersBox == SoftCache::EMPTY_VALUE) {
  690.                 $altOffersBox "";
  691.             }
  692.         }
  693.         if ($user && $subscriptionService->isSubscriber($user)) {
  694.             $buyCodePopup '#confirmBox';
  695.         }
  696.         $data['altOffersBox'] = $altOffersBox;
  697.         $data['geoLocations'] = $offer->getGeoLocations();
  698.         $data['codeCost'] = $codeCost;
  699.         $data['buyCodePopup'] = $buyCodePopup;
  700.         $data['siteSettings'] = $this->getSiteSettings();
  701.         $data['parentCategoryList'] = $this->getParentCategoryList($request$offer->getDefaultCategoryID());
  702.         $data['categoryURL'] = '/';
  703.         $data['preview'] = $preview;
  704.         $data['commentsAmount'] = $this->getCommentRepository()->getCommentsCountByEntityID($offer->getID(), Comment::TYPE_OFFER_COMMENT);
  705.         $data['isOfferFavourite'] = $user $user->isOfferFavourite($offer) : false;
  706.         $data['detailMediaList'] = $offer->getDetailMedias();
  707.         $data['foodExtensions'] = $offer->getFoodExtensions();
  708.         $categoryRepository =  $this->getDoctrine()->getManager()->getRepository(Category::class);
  709.         $categoryID $offer->getDefaultCategoryID();
  710.         if ($categoryID) {
  711.             $category $categoryRepository->findCached($categoryID);
  712.             if (!$category) {
  713.                 $category['category'] = $categoryRepository->find($categoryID);
  714.             }
  715.             if ($category['category'] && $category['category']->isActive() && !$category['category']->isPast()) {
  716.                 $data['categoryURL'] = $this->getSeoRepository()->getCategoryURL($category['category']);
  717.             }
  718.         }
  719.         $deviceType self::getMobileDevice($request) ? self::DEVICE_TYPE_MOBILE self::DEVICE_TYPE_DESKTOP;
  720.         $this->addVisit($entityIDVisit::TYPE_OFFER$deviceType$user$request->getClientIp());
  721.         if ($entityID == Offer::FITNESS_WORLD_OFFER_ID) {
  722.             $data['fitnessOffer'] = true;
  723.         }
  724.         $data['confirmedUserPhoneNumber'] = null;
  725.         $dateDiff date_diff($offer->getActiveTill(), new \DateTime());
  726.         $data['daysLeft'] = $dateDiff->days;
  727.         $data['hoursLeft'] = $dateDiff->format('%h');
  728.         $data['minutesLeft'] = $dateDiff->format('%i');
  729.         $data['usedCodesCount'] = $pastOffer
  730.             $offer->getUsedCodesCountForPastOffer()
  731.             : $purchaseCountWithCorrectionDao->findTotalByOfferId($offer->getID()) + $offer->getLastCodePoolStartPurchaseCount();
  732.         $data['allCodesCount'] = $data['usedCodesCount'] + $offer->getFreeCodesCount();
  733.         $data['ratingWithCount'] = $entityManager->getRepository(Comment::class)->getEntityRatingWithCount(Category::OFFER_CATEGORY_ID$entityID);
  734.         $data['ratingPercentage'] = $data['ratingWithCount']['rating'] * 100 5;
  735.         $data['todayVisitCount'] = $offerRepository->getVisitCount($offertrue);
  736.         $data['visitCount'] = $entityManager->getRepository(Visit::class)->getVisitCount($entityIDVisit::TYPE_OFFER30true);
  737.         $data['phoneNumbersCount'] = count($offer->getPhoneNumbers());
  738.         if ($entityID == Offer::BOOKING_OFFER_ID) {
  739.             $entityOption $entityManager->getRepository(EntityOption::class)->findOneBy([
  740.                 "entityID" => $entityID,
  741.                 "entityTypeID" => EntityOption::BOOKING_RESERVED_DATES,
  742.                 "name" => EntityOption::OPTION_BOOKING_DATES
  743.             ]);
  744.             if ($entityOption) {
  745.                 $dateToFormat = [];
  746.                 foreach (explode(','$entityOption->getValue()) as $date) {
  747.                     $dateToFormat[] = date('Y-m-d'strtotime($date));
  748.                 }
  749.                 $data['bookedDates'] = implode(','$dateToFormat);
  750.             }
  751.             $data['bookingTypeList'] = Booking::BOOKING_TYPE_LIST;
  752.             $userCurrentPhone =  $user $user->getCurrentPhone() : null;
  753.             if ($userCurrentPhone and $userCurrentPhone->isConfirmed()) {
  754.                 $data['confirmedUserPhoneNumber'] = $userCurrentPhone->getPhoneNumber();
  755.             }
  756.         }
  757.         if ($user && $user->hasRole(UserGroup::STATISTICS_VIEWER)) {
  758.             $data['yesterdayShareClicks'] = $this->getShareClicks($entityID);
  759.         }
  760.         $utmMedium trim(mb_strtolower($request->query->get('utm_medium''')));
  761.         if ($request->query->get('utm_source') == 'search_result' && $utmMedium != '') {
  762.             $searchQuery $entityManager->getRepository(SearchQuery::class)
  763.                 ->findOneByQuery(($utmMedium));
  764.             if ($searchQuery) {
  765.                 $searchStatistic = new SearchStatistic();
  766.                 $searchStatistic->setSearchQuery($searchQuery);
  767.                 $searchStatistic->setEntityID($offer->getID());
  768.                 $searchStatistic->setEntityType(SearchStatistic::ENTITY_TYPE_OFFER);
  769.                 if ($user) {
  770.                     $searchStatistic->setUserID($user->getID());
  771.                 }
  772.                 $searchStatistic->setIpAddress($request->getClientIp());
  773.                 $searchStatistic->setRefferer($request->headers->get('referer'));
  774.                 $entityManager->persist($searchStatistic);
  775.                 $entityManager->flush();
  776.             }
  777.         }
  778.         $codesCount 1;
  779.         if ($entityID == Offer::DREAMLAND_OFFER_ID) {
  780.             $codesCount 5;
  781.             if ($user) {
  782.                 if ($entityManager->getRepository(User::class)->getDreamlandOption($user->getID())) {
  783.                     $codesCount 1;
  784.                 }
  785.             }
  786.         }
  787.         $data['codesCount'] = $codesCount;
  788.         $data['brandingBannerCategoryIDs'] = $categoryRepository->getParentCategoryIDsByOfferID($entityID);
  789.         $data['deliveryLink'] = '/delivery/select/' $offer->getID();
  790.         $onlineSettings $offer->getOnlineOrderSettings();
  791.         if (!$pastOffer && $offer->isOneOfOnlineOrderAllowedOnSite()) {
  792.             $data['hasDelivery'] = true;
  793.             $data['foodExtensions'] = [];
  794.             $data['items'] = [];
  795.             if (count($offer->getFoodExtensions())) {
  796.                 $orderUtil AbstractDelivery::instance($offer);
  797.                 if ($orderUtil::SPLIT_PAYMENT) {
  798.                     $data['domain'] = $orderUtil::DOMAIN;
  799.                 }
  800.                 if ($onlineSettings && $onlineSettings->isSplitPayment()) {
  801.                     if ($onlineSettings->getDomain()) {
  802.                         $data['domain'] = trim($onlineSettings->getDomain());
  803.                     }
  804.                 }
  805.             } elseif ($giftCertificateDao->getCountActiveByOfferId($entityID)) {
  806.                 $dql 'select giftCertificate from Slivki:GiftCertificate giftCertificate where giftCertificate.offer = :offer';
  807.                 $giftCertificates $entityManager->createQuery($dql)
  808.                     ->setParameter('offer'$offer)->getResult();
  809.                 if ($giftCertificates[0]->getLastActiveCodePool()) {
  810.                     $multiplePoolOfferFreeCodesCount 0;
  811.                     $multiplePoolOfferUsedCodesCount 0;
  812.                     /** @var GiftCertificate $giftCertificate */
  813.                     foreach ($giftCertificates as $giftCertificate) {
  814.                         $giftCertificateCodePool $giftCertificate->getLastActiveCodePool();
  815.                         $multiplePoolOfferFreeCodesCount += $giftCertificateCodePool->getFreeCodesCount();
  816.                         $multiplePoolOfferUsedCodesCount += $giftCertificateCodePool->getUsedCodesCount();
  817.                     }
  818.                     $data['multiplePoolOfferFreeCodesCount'] = $multiplePoolOfferFreeCodesCount;
  819.                     $data['multiplePoolOfferUsedCodesCount'] = $multiplePoolOfferUsedCodesCount;
  820.                 }
  821.                 $data['deliveryLink'] = '/gift-certificate/select/' $offer->getID();
  822.                 if ($onlineSettings && $onlineSettings->isSplitPayment()) {
  823.                     if ($onlineSettings->getDomain()) {
  824.                         $data['domain'] = trim($onlineSettings->getDomain());
  825.                     }
  826.                 }
  827.             } else {
  828.                 $offer $entityManager->merge($offer);
  829.                 if (count($offer->getTireExtensions())) {
  830.                     $data['deliveryLink'] = '/online-zapis/' $offer->getID();
  831.                     if ($onlineSettings && $onlineSettings->isSplitPayment()) {
  832.                         if ($onlineSettings->getDomain()) {
  833.                             $data['domain'] = trim($onlineSettings->getDomain());
  834.                         }
  835.                     }
  836.                 }
  837.             }
  838.             $directorID $offer->getDirectorID();
  839.             if ($offer->getID() == Offer::DREAMLAND_OFFER_ID) {
  840.                 $data['domain'] = 'mp';
  841.             } else if ($entityID == 139498) {
  842.                 $data['domain'] = 'deka';
  843.             } else if ($entityID == 141075) {
  844.                 $data['domain'] = 'whitelotus';
  845.             } else if ($directorID == Director::MARSEL_DIRECTOR_ID) {
  846.                 $data['domain'] = 'marsel';
  847.             } else if ($directorID == Director::SHAH_DIRECTOR_ID) {
  848.                 $data['domain'] = 'shah';
  849.             } else if ($entityID == Offer::HEROPARK_OFFER_ID) {
  850.                 $data['domain'] = 'heropark';
  851.             }
  852.         }
  853.         if (isset($data['domain']) && $data['domain'] != '') {
  854.             $data['deliveryLink'] = 'https://' $data['domain'] . str_replace('https://www.''.'$this->getParameter('base_url')) . $data['deliveryLink'];
  855.         }
  856.         if ($offer->getExternalOfferLink() && $offer->getIsShowExternalOfferLink()) {
  857.             $data['deliveryLink'] = $offer->getExternalOfferLink();
  858.         }
  859.         if ($user) {
  860.             $siteSettings $this->getSiteSettings();
  861.             $data['subscriptionPrice'] = $subscriptionService->isSubscriptionFinished($user) ? $siteSettings->getSubscriptionPrice() : $siteSettings->getSubscriptionFirstPayment();
  862.             $data['subscriptionFullPrice'] = $siteSettings->getSubscriptionPrice();
  863.             $data['subscriptionTerm'] = $subscriptionService->isSubscriptionFinished($user) ? 30 7;
  864.         }
  865.         if ($preview) {
  866.             $data['robotsMeta'] = 'noindex, follow';
  867.         }
  868.         if (!$offer->hasFreeCodes()) {
  869.             $data['deliveryLink'] = 'javascript:void(0);';
  870.         }
  871.         $data['hadSubscription'] = null !== $user $subscriptionService->isExistBySubscriber($user) : false;
  872.         $data['codeCostInCurrency'] = $offer->getSumInCurrency((float) $codeCost);
  873.         $view $isMobile 'Slivki/mobile/offer/details.html.twig' 'Slivki/offers/details.html.twig';
  874.         $response->setContent($this->renderView($view$data));
  875.         return $response;
  876.     }
  877.     /**
  878.      * @Route("/offer/comment/get/{offerID}/{page}")
  879.      */
  880.     public function getOfferComments(Request $requestOfferCacheService $offerCacheService$offerID$page) {
  881.         $offer $offerCacheService->getOffer($offerIDfalsetrue);
  882.         if (!$offer) {
  883.             return new Response();
  884.         }
  885.         $isMobile CommonUtil::isMobileDevice($request);
  886.         return new Response($this->getCommentsByOffer($offer->getID(), $pageCommentRepository::COMMENTS_PER_PAGE$isMobile));
  887.     }
  888.     private function getCommentsByOffer($offerID$page$perPage$isMobile) {
  889.         $entityManager $this->getDoctrine()->getManager();
  890.         $offset = ($page 1) * $perPage;
  891.         $commentList $entityManager->getRepository(Comment::class)->getCommentsByOfferIDReversed($offerID$offset$perPage);
  892.         $commentsAmount $this->getCommentRepository()->getCommentsCountByEntityID($offerIDComment::TYPE_OFFER_COMMENT);
  893.         return  $this->renderView($isMobile 'Slivki/mobile/comment/list.html.twig' 'Slivki/comments/comments.html.twig', [
  894.             'comments' => $commentList,
  895.             'pagination' => $this->renderView('Slivki/pagination.html.twig', [
  896.                 'paginationID' => 'offerCommentPagination',
  897.                 'current' => $page,
  898.                 'total' => ceil($commentsAmount/$perPage),
  899.                 'url' => $entityManager->getRepository(Seo::class)->getOfferURL($offerID)->getMainAlias() . '?page='
  900.             ]),
  901.             'showBanners' => true,
  902.             'hasMore' => false
  903.         ]);
  904.     }
  905.     /**
  906.      * @Route("/additional_offer_details/{entityID}/{offerPreview}")
  907.      */
  908.     public function additionalOfferDetailsAction(Request $requestOfferCacheService $offerCacheService$entityID$offerPreview false) {
  909.         $entityManager $this->getDoctrine()->getManager();
  910.         $offerRepository $this->getOfferRepository();
  911.         $offer $offerCacheService->getOffer($entityIDfalsetrue);
  912.         $pastOffer false;
  913.         $timeNow = new \DateTime();
  914.         if (!$offer || $offerPreview) {
  915.             $offer $offerRepository->find($entityID);
  916.             if (!$offer || ((!$offer->isInVisiblePeriod() || !$offer->isActive()) && !$offerPreview)) {
  917.                 throw $this->createNotFoundException();
  918.             }
  919.             $mediaRepository $this->getMediaRepository();
  920.             $offer->setDetailMeidas($mediaRepository->getOfferDetailMedias($offer->getID()));
  921.             $offer->setShopMedias($mediaRepository->getOfferShopMedias($offer->getID()));
  922.         }
  923.         $data['parentCategoryList'] = null;
  924.         $data['offer'] = $offer;
  925.         $data['tour3dName'] = '';
  926.         $softCache = new SoftCache(OfferRepository::CACHE_NAME);
  927.         $cacheKey 'alt-offers-box-1-' $entityID;
  928.         $altOffersBox $softCache->get($cacheKey);
  929.         if ($altOffersBox == SoftCache::LOCKED_KEY) {
  930.             $altOffersBox $softCache->getDataForLockedKey($cacheKey30);
  931.         } else if (!$altOffersBox) {
  932.             $softCache->add($cacheKeySoftCache::LOCKED_KEY30);
  933.             $cacheExpire strtotime(date('Y-m-d 05:00:00'strtotime('+1 day'))) - time();
  934.             $altOffersBox "";
  935.             $altOfferList $this->getDoctrine()->getRepository(AlternativeOffer::class)->getByOfferID($entityID);
  936.             if ($altOfferList) {
  937.                 if (count($altOfferList) < 3) {
  938.                     $altOffersBox SoftCache::EMPTY_VALUE;
  939.                 } else {
  940.                     if (count($altOfferList) < 6) {
  941.                         $altOfferList array_slice($altOfferList03);
  942.                     }
  943.                     foreach ($altOfferList as $altOffer) {
  944.                         $alternativeOffer $offerCacheService->getOffer($altOffer->getAlternativeOfferID(), true);
  945.                         if ($alternativeOffer) {
  946.                             $altOffersBox .= $this->get('twig')->render('Slivki/offers/teaser.html.twig', ['offer' => $alternativeOffer'noLazyLoad' => true]);
  947.                         } else {
  948.                             $this->getLogger()->error('Alternative offer ' $altOffer->getOfferID() . " not found in cache");
  949.                             $altOffersBox "";
  950.                             break;
  951.                         }
  952.                     }
  953.                 }
  954.             }
  955.             $softCache->set($cacheKey$altOffersBox$cacheExpire);
  956.             if ($altOffersBox == SoftCache::EMPTY_VALUE) {
  957.                 $altOffersBox "";
  958.             }
  959.         }
  960.         $data['altOffersBox'] = $altOffersBox;
  961.         $view $request->query->get('offerCondition') ? 'Slivki/offers/condition.html.twig' 'Slivki/offers/additional_offer_details.html.twig';
  962.         if (self::getMobileDevice($request)) {
  963.             $view 'Slivki/mobile/offer/description.html.twig';
  964.         }
  965.         return $this->render($view$data);
  966.     }
  967.     /**
  968.      * @Route("/offer_location/{entityID}")
  969.      */
  970.     public function offerLocationAction(Request $requestOfferCacheService $offerCacheService$entityID) {
  971.         $offerRepository $this->getOfferRepository();
  972.         $offer $offerCacheService->getOffer($entityIDfalsetrue);
  973.         if (!$offer) {
  974.             $offer $offerRepository->find($entityID);
  975.             if (!$offer) {
  976.                 throw $this->createNotFoundException();
  977.             }
  978.             $mediaRepository $this->getMediaRepository();
  979.             $offer->setDetailMeidas($mediaRepository->getOfferDetailMedias($offer->getID()));
  980.             $offer->setShopMedias($mediaRepository->getOfferShopMedias($offer->getID()));
  981.         }
  982.         $data['offer'] = $offer;
  983.         $data['geoLocations'] = $offer->getGeoLocations();
  984.         return $this->render('Slivki/offers/location.html.twig'$data);
  985.     }
  986.     /**
  987.      * @Route("/get_comment_box/{type}/{entityID}/{mobileCache}")
  988.      */
  989.     public function getCommentBoxAction(Request $requestBannerService $bannerService$type$entityID$mobileCache null) {
  990.         if ($entityID == 140503) {
  991.             Logger::instance('COMMENT-DEBUG')->info('start');
  992.         }
  993.         ini_set('memory_limit''512M');
  994.         $directorID 0;
  995.         if ($type == Comment::TYPE_OFFER_COMMENT) {
  996.             $offer $this->getDoctrine()->getManager()->find(Offer::class, $entityID);
  997.             if ($offer->getDirectors()->count() > 0) {
  998.                 $directorID $offer->getDirectors()->first()->getID();
  999.             }
  1000.         }
  1001.         if ($entityID == 140503) {
  1002.             Logger::instance('COMMENT-DEBUG')->info('05');
  1003.         }
  1004.         $cacheName $mobileCache CommentCacheService::MOBILE_CACHE_NAME CommentCacheService::CACHE_NAME;
  1005.         $data = [
  1006.             'entityID' => $entityID,
  1007.             'type' => $type,
  1008.             'comments' => $this->getComments($request$bannerService$entityID$type00$directorID$cacheName),
  1009.             'commentsAmount' => $this->getCommentRepository()->getCommentsCountByEntityID($entityID$type),
  1010.             'showCommentsAmount' => $type == Comment::TYPE_SALE_COMMENT false true
  1011.         ];
  1012.         if ($entityID == 140503) {
  1013.             Logger::instance('COMMENT-DEBUG')->info('1');
  1014.         }
  1015.         $view 'Slivki/comments/comments_list.html.twig';
  1016.         if ($entityID == 140503) {
  1017.             Logger::instance('COMMENT-DEBUG')->info('2');
  1018.         }
  1019.         if ($cacheName == CommentRepository::MOBILE_CACHE_NAME) {
  1020.             $view 'Slivki/mobile/comment/block.html.twig';
  1021.         }
  1022.         if ($entityID == 140503) {
  1023.             Logger::instance('COMMENT-DEBUG')->info('3');
  1024.         }
  1025.         $response = new Response();
  1026.         $response->setContent($this->get('twig')->render($view$data));
  1027.         if ($entityID == 140503) {
  1028.             Logger::instance('COMMENT-DEBUG')->info('status code ' $response->getStatusCode());
  1029.         }
  1030.         return $response;
  1031.     }
  1032.     /**
  1033.      * @Route("/landing")
  1034.      */
  1035.     public function mobileLandingAction(
  1036.         Request $request,
  1037.         OfferCacheService $offerCacheService,
  1038.         SubscriptionService $subscriptionService,
  1039.         DeviceTypeService $deviceTypeService,
  1040.         ServerFeatureStateChecker $serverFeatureStateChecker
  1041.     ): Response {
  1042.         if (!$deviceTypeService->isMobileDevice($request) || !$serverFeatureStateChecker->isServerFeatureEnabled(SwitcherFeatures::ALLOW_MOBILE_LANDING_PAGE())) {
  1043.             return $this->redirectToRoute('homepage');
  1044.         }
  1045.         $response = new Response();
  1046.         $entityManager $this->getDoctrine()->getManager();
  1047.         $user $this->getUser();
  1048.         $carouselOffersIDs = [Dominos::OFFER_IDSushiHouse::OFFER_IDOffer::KFC_OFFER_IDOffer::FREESTYLE_OFFER_IDDodo::OFFER_ID];
  1049.         $data['recomended'] = true;
  1050.         if ($user) {
  1051.             $sql 'select entity_id from visit where user_id = ' $user->getID()
  1052.                 . ' and entity_type_id = ' Category::OFFER_CATEGORY_ID
  1053.                 ' group by 1 order by max(created_on) desc limit 10';
  1054.             $visitedOfferIDs $this->getDoctrine()->getManager()->getConnection()->executeQuery($sql)->fetchAll(\PDO::FETCH_COLUMN);
  1055.             if (!empty($visitedOfferIDs)) {
  1056.                 $carouselOffersIDs $visitedOfferIDs;
  1057.                 $data['recomended'] = false;
  1058.             }
  1059.         }
  1060.         $carouselOffers $offerCacheService->getOffers($carouselOffersIDs);
  1061.         if ($data['recomended']) {
  1062.             shuffle($carouselOffers);
  1063.         }
  1064.         $data['carouselOffers'] = $carouselOffers;
  1065.         $data['categoryList'] = $this->getCategoryRepository()->getUserFavouriteCategories($user);
  1066.         $data['showWatchList'] = $user && $this->getUser() && $this->getVisitedByUserCount($user->getID()) > 0;
  1067.         $abTestViews = [
  1068.             'Slivki/mobile/landing_new.html.twig'
  1069.         ];
  1070.         $landingABCookieName 'landingab';
  1071.         $landingABCookieValue $request->cookies->get($landingABCookieName);
  1072.         if (!$landingABCookieValue) {
  1073.             $landingABCookieValue array_rand($abTestViews);
  1074.         } else {
  1075.             $landingABCookieValue = (int)$landingABCookieValue;
  1076.             $landingABCookieValue++;
  1077.             if ($landingABCookieValue >= count($abTestViews)) {
  1078.                 $landingABCookieValue 0;
  1079.             }
  1080.         }
  1081.         $landingABCookie Cookie::create($landingABCookieName$landingABCookieValuetime() + 315360000'/'$this->getParameter('base_domain'));
  1082.         $response->headers->setCookie($landingABCookie);
  1083.         $data['subscription'] = null !== $user $subscriptionService->getSubscription($user) : null;
  1084.         $data['hadSubscription'] = null !== $user $subscriptionService->isExistBySubscriber($user) : null;
  1085.         $landingBannerRepository $entityManager->getRepository(MobileLandingBanner::class);
  1086.         $bannerList $landingBannerRepository->findBy(['active' => true], ['position' => 'ASC']);
  1087.         $data['landingBannerHtmlTop'] = $this->get('twig')->render('Slivki/banners/landing_banner_top.html.twig', ['bannerList' => $bannerList]);
  1088.         $data['landingBannerHtmlBottom'] = $this->get('twig')->render('Slivki/banners/landing_banner_bottom.html.twig', ['bannerList' => $bannerList]);
  1089.         $response->setContent($this->renderView($abTestViews[$landingABCookieValue], $data));
  1090.         return $response;
  1091.     }
  1092.     private function getVisitedByUserCount($userID) {
  1093.         $sql 'select count(distinct entity_id) from visit where user_id = ' $userID ' and entity_type_id = ' Category::OFFER_CATEGORY_ID;
  1094.         return $this->getDoctrine()->getManager()->getConnection()->executeQuery($sql)->fetchColumn();
  1095.     }
  1096.     public function getRelatedOffersTeasers(CacheService $cacheService$offerID) {
  1097.         $entityManager $this->getDoctrine()->getManager();
  1098.         $offer $entityManager->find(Offer::class, $offerID);
  1099.         $defaultCategoryID $offer->getDefaultCategoryID();
  1100.         if (empty($defaultCategoryID)) {
  1101.             return '';
  1102.         }
  1103.         $entityIDList $this->offerDao->findActiveOffersByCategoryIds([$defaultCategoryID]);
  1104.         if (== count($entityIDList)) {
  1105.             return '';
  1106.         }
  1107.         $sql 'select entity_id, purchase_count_recent from purchase_count where entity_id in (' implode(','$entityIDList) . ') order by 2 desc limit 12;';
  1108.         try {
  1109.             $purschaseCountList $entityManager->getConnection()->executeQuery($sql)->fetchAll(\PDO::FETCH_KEY_PAIR);
  1110.         } catch (\PDOException $e) {
  1111.             Logger::instance('Related offers')->info($offerID);
  1112.         }
  1113.         return $cacheService->getTeaserList(array_keys($purschaseCountList), false);
  1114.     }
  1115.     /**
  1116.      * @Route("/comments/add_like/{commentID}")
  1117.      */
  1118.     public function addLike($commentIDRequest $request) {
  1119.         if ($this->isGranted(UserGroup::COMMENTS_BANNED_ROLE_NAME)) {
  1120.             return new Response();
  1121.         }
  1122.         $user $this->getUser();
  1123.         if(!$user) {
  1124.             return new Response(json_encode(['error' => 1]));
  1125.         }
  1126.         /** @var Comment $comment */
  1127.         $comment $this->getCommentRepository()->find($commentID);
  1128.         $like = new CommentLike();
  1129.         $like->setUserID($user->getID());
  1130.         $like->setVote((bool)$request->request->get('vote'));
  1131.         $comment->addLike($like);
  1132.         $entityManager $this->getDoctrine()->getManager();
  1133.         $entityManager->flush();
  1134.         $result $comment->getLikesAmount();
  1135.         $this->resetCommentsCache($comment->getEntityID(), $comment->getTypeID());
  1136.         return new Response(json_encode($result));
  1137.     }
  1138.     private function validateComment(Request $request) {
  1139.         $commentText trim($request->request->get('comment'''));
  1140.         if($commentText == '') {
  1141.             $result 'Отзыв не может быть пустым';
  1142.             return $result;
  1143.         }
  1144.         return true;
  1145.     }
  1146.     /**
  1147.      * @Route("/ostavit-otziv/{typeID}/{entityID}/{parentID}", defaults = {"parentID" = 0})
  1148.      */
  1149.     public function addComment($typeID$entityID$parentIDRequest $request) {
  1150.         if (!self::getMobileDevice($request)) {
  1151.             return $this->redirectToRoute('homepage');
  1152.         }
  1153.         $typeID = (int)$typeID;
  1154.         $entityID = (int)$entityID;
  1155.         $parentID = (int)$parentID;
  1156.         if (!in_array($typeID, [Comment::TYPE_OFFER_COMMENTComment::TYPE_SALE_COMMENTComment::TYPE_MALL_BRAND_COMMENTComment::TYPE_DIRECTOR_COMMENT])) {
  1157.             return $this->redirectToRoute('homepage');
  1158.         }
  1159.         if ($parentID 0) {
  1160.             $parentComment $this->getCommentRepository()->find($parentID);
  1161.             if (!$parentComment || $parentComment->getEntityID() != $entityID) {
  1162.                 return $this->redirectToRoute('homepage');
  1163.             }
  1164.         }
  1165.         return $this->render('Slivki/mobile/comment/add.html.twig', [
  1166.             'typeID' => $typeID,
  1167.             'entityID' => $entityID,
  1168.             'parentID' => $parentID,
  1169.             'referer' => $request->headers->get('referer''/')
  1170.         ]);
  1171.     }
  1172.     /**
  1173.      * @Route("/redaktirovat-otziv/{commentID}")
  1174.      */
  1175.     public function editComment($commentIDRequest $request) {
  1176.         if (!self::getMobileDevice($request)) {
  1177.             return $this->redirectToRoute('homepage');
  1178.         }
  1179.         $commentRepository $this->getCommentRepository();
  1180.         /** @var Comment $comment */
  1181.         $comment $commentRepository->find($commentID);
  1182.         if (!$comment) {
  1183.             return $this->redirectToRoute('homepage');
  1184.         }
  1185.         $user $this->getUser();
  1186.         if (!$user || !($user->getID() == $comment->getUser()->getID())) {
  1187.             return $this->redirectToRoute('homepage');
  1188.         }
  1189.         $commentRating $comment->getRating();
  1190.         return $this->render('Slivki/mobile/comment/edit.html.twig', [
  1191.             'comment' => $comment,
  1192.             'commentRating' => $commentRating,
  1193.             'isUserAllowedToRate' => $commentRating 0,
  1194.             'referer' => $request->headers->get('referer''/')
  1195.         ]);
  1196.     }
  1197.     /**
  1198.      * @Route("/udalit-otziv/{commentID}")
  1199.      */
  1200.     public function deleteComment($commentIDRequest $request) {
  1201.         if (!self::getMobileDevice($request)) {
  1202.             return $this->redirectToRoute('homepage');
  1203.         }
  1204.         $comment $this->getCommentRepository()->find($commentID);
  1205.         if (!$comment) {
  1206.             return $this->redirectToRoute('homepage');
  1207.         }
  1208.         $user $this->getUser();
  1209.         if (!$user || !($user->getID() == $comment->getUser()->getID())) {
  1210.             return $this->redirectToRoute('homepage');
  1211.         }
  1212.         return $this->render('Slivki/mobile/comment/delete.html.twig', [
  1213.             'comment' => $comment,
  1214.             'referer' => $request->headers->get('referer''/')
  1215.         ]);
  1216.     }
  1217.     /**
  1218.      * @Route("/comments/add/{type}/{entityID}")
  1219.      */
  1220.     public function commentAdd(
  1221.         int $type,
  1222.         int $entityID,
  1223.         Request $request,
  1224.         Mailer $mailer,
  1225.         ServerFeatureStateChecker $serverFeatureStateChecker,
  1226.         VoiceMessageUploader $voiceMessageUploader
  1227.     ): Response {
  1228.         $user $this->getUser ();
  1229.         if (!$user) {
  1230.             return new Response('Войдите, чтобы мы могли учесть Ваше мнение!');
  1231.         }
  1232.         if ($this->isGranted(UserGroup::COMMENTS_BANNED_ROLE_NAME)) {
  1233.             return new Response('Добавление комментариев заблокировано администратором');
  1234.         }
  1235.         $validateCommentResult $this->validateComment($request);
  1236.         if ($validateCommentResult !== true) {
  1237.             return new Response($validateCommentResult);
  1238.         }
  1239.         $parentCommentID = (int)$request->request->get('parentVoteId');
  1240.         $commentText trim($request->request->get('comment'''));
  1241.         if (Censure::parse($commentText)) {
  1242.             $response = new Response();
  1243.             $response->setStatusCode(406);
  1244.             return $response;
  1245.         }
  1246.         $entityManager $this->getDoctrine()->getManager();
  1247.         $userPhone $user->getCurrentPhone();
  1248.         $confirmedPhone true;
  1249.         if ($serverFeatureStateChecker->isServerFeatureEnabled(SwitcherFeatures::NEED_CONFIRM_PHONE_TO_COMMENT())
  1250.             && (!$userPhone || !$userPhone->isConfirmed() || !$userPhone->isBelorussian())) {
  1251.             $confirmedPhone false;
  1252.         }
  1253.         if ($type == Comment::TYPE_OFFER_COMMENT) {
  1254.             $sql 'DELETE FROM offer_rate_schedule WHERE user_id = ' . (int)$user->getID() . ' AND offer_id = ' . (int)$entityID;
  1255.             $entityManager->getConnection()->executeQuery($sql);
  1256.         }
  1257.         $parentComment $this->getCommentRepository()->find($parentCommentID);
  1258.         $comment = new Comment();
  1259.         $comment->setComment($this->prepareCommentText($commentText));
  1260.         $rating $request->request->get('actionRating');
  1261.         $comment->setRating($rating);
  1262.         if ($parentComment) {
  1263.             $comment->setParentComment($parentComment);
  1264.         }
  1265.         $comment->setEntityID($entityID);
  1266.         $comment->setHidden(false);
  1267.         $comment->setTypeID($type);
  1268.         $comment->setMobileVersion(CommonUtil::isMobileDevice($request));
  1269.         $comment->setChecked(false);
  1270.         $comment->setUser ($user);
  1271.         $comment->setConfirmedPhone($confirmedPhone);
  1272.         if ($userPhone instanceof UserPhone) {
  1273.             $comment->setPhone($userPhone->getPhoneNumber());
  1274.         }
  1275.         $comment->setAllowToContact($request->request->getBoolean('allowToContact'));
  1276.         $voiceFile $request->files->get('voice_message');
  1277.         if ($voiceFile) {
  1278.             $voicePath $voiceMessageUploader->upload($voiceFile);
  1279.             if ($voicePath !== null) {
  1280.                 $comment->setVoicePath($voicePath);
  1281.             }
  1282.         }
  1283.         $entityManager->persist($comment);
  1284.         $session $request->getSession();
  1285.         $userCommentImages $session->get('userCommentImages', []);
  1286.         foreach ($userCommentImages as $key => $value) {
  1287.             $media = new Media\CommentMedia();
  1288.             $media->setMediaType($entityManager->getRepository(MediaType::class)->find(MediaType::TYPE_USER_VOTE_IMAGE_ID));
  1289.             $media->setPath(MediaType::TYPE_USER_VOTE_IMAGE_PATH);
  1290.             $media->setName($value);
  1291.             $media->setSortOrder($key);
  1292.             $comment->addMedia($media);
  1293.         }
  1294.         $session->set('userCommentImages', []);
  1295.         $entityManager->flush($comment);
  1296.         if ($type == Comment::TYPE_OFFER_COMMENT && $confirmedPhone) {
  1297.             $offer $this->getOfferRepository()->find($entityID);
  1298.             $this->sendOfferCommentNotice($mailer$offer$comment$parentComment);
  1299.         }
  1300.         $this->resetCommentsCache($entityID$type);
  1301.         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');
  1302.     }
  1303.     /**
  1304.      * @Route("/comments-live")
  1305.      * @Route("/comments-live/{alias}")
  1306.      */
  1307.     public function commentsLiveRedirect($alias null) {
  1308.         $routeName 'commentsLive';
  1309.         $routeParameters = [];
  1310.         if ($alias != '') {
  1311.             $routeName 'commentsByCategory';
  1312.             $routeParameters['alias'] = $alias;
  1313.         }
  1314.         return $this->redirectToRoute($routeName$routeParameters301);
  1315.     }
  1316.     /**
  1317.      * @Route("/otzyvy", name="commentsLive")
  1318.      */
  1319.     public function commentsLiveAction(Request $request) { //TODO: total refactoring commentsLiveAction and commentsByCategory
  1320.         $isMobileDevice self::getMobileDevice($request);
  1321.         $commentRepository $this->getCommentRepository();
  1322.         $topMenu $commentRepository->getTopMenu();
  1323.         $data['offerRateSchedule'] = $this->getOfferRateSchedule($request->getSession());
  1324.         $data['comments'] = $commentRepository->getLiveComments(20);
  1325.         $data['isLiveComments'] = 1;
  1326.         $data['hasMore'] = true;
  1327.         $data['commentsAmount'] = 20;
  1328.         $comments $this->get('twig')->render($isMobileDevice 'Slivki/mobile/comment/list.html.twig' 'Slivki/comments/comments.html.twig'$data);
  1329.         $deviceType self::getMobileDevice($request) ? self::DEVICE_TYPE_MOBILE self::DEVICE_TYPE_DESKTOP;
  1330.         $this->addVisit(0Visit::TYPE_COMMENTS_MAIN_PAGE$deviceType$this->getUser(), $request->getClientIp(), $request->headers->get('referer'''));
  1331.         return $this->render($isMobileDevice 'Slivki/mobile/comment/index.html.twig' 'Slivki/comments/comments_live.html.twig', [
  1332.             'comments' => $comments,
  1333.             'topMenu' => $topMenu
  1334.         ]);
  1335.     }
  1336.     /**
  1337.      * @Route("/otzyvy/{alias}", name="commentsByCategory")
  1338.      */
  1339.     public function commentsByCategoryAction(Request $request$alias null) {
  1340.         $page $request->query->get('page'1);
  1341.         $isMobileDevice self::getMobileDevice($request);
  1342.         $seo $request->attributes->get(SiteController::PARAMETER_META_INFO);
  1343.         if (!$seo && $alias) {
  1344.             $seo $this->getSeoRepository()->findOneBy(['mainAlias' => '/' $alias]);
  1345.         }
  1346.         if (!$seo) {
  1347.             return $this->redirectToRoute('commentsLive');
  1348.         }
  1349.         $seoType $seo->getResourceURL();
  1350.         $entityID $seo->getEntityID();
  1351.         $commentRepository $this->getCommentRepository();
  1352.         switch($seoType) {
  1353.             case SeoRepository::RESOURCE_URL_CATEGORY_COMMENTS:
  1354.             case SeoRepository::RESOURCE_URL_OFFER_CATEGORY:
  1355.                 $categoryRepository $this->getCategoryRepository();
  1356.                 $categoryCached $categoryRepository->findCached($entityID);
  1357.                 if(!$categoryCached) {
  1358.                     return $this->redirectToRoute('commentsLive');
  1359.                 }
  1360.                 $category $categoryCached['category'];
  1361.                 $subCategories $categoryRepository->getSubCategories($category);
  1362.                 $data['isLiveComments'] = 1;
  1363.                 $data['hasMore'] = true;
  1364.                 $data['categoryID'] = $entityID;
  1365.                 $data['commentsAmount'] = 10;
  1366.                 if ($category->getTypeID() == Category::SUPPLIER_CATEGORY_TYPE) {
  1367.                     $data['comments'] = $commentRepository->getOfferCategoryComments($entityID$page);
  1368.                     $data['hasMore'] = false;
  1369.                 } else {
  1370.                     $data['comments'] = $commentRepository->getCommentsByCategoryID($category->getID(), $data['commentsAmount']);
  1371.                 }
  1372.                 $comments $this->renderView($isMobileDevice 'Slivki/mobile/comment/list.html.twig' 'Slivki/comments/comments.html.twig'$data);
  1373.                 $title mb_strtoupper('<h1>ОТЗЫВЫ ' $category->getName() . '</h1>');
  1374.                 return $this->render($isMobileDevice 'Slivki/mobile/comment/index.html.twig' 'Slivki/comments/comments_live.html.twig', [
  1375.                     'commentsCount' => $commentRepository->getOfferCategoryCommentsCount($category->getID()),
  1376.                     'page' => $page,
  1377.                     'comments' => $comments,
  1378.                     'subCategories' => $subCategories,
  1379.                     'title' => $title,
  1380.                     'categoryID' => $entityID,
  1381.                     'category' => $category,
  1382.                     'parentCategories' => $categoryRepository->getCategoryParentList($category)
  1383.                 ]);
  1384.                 break;
  1385.             case SeoRepository::RESOURCE_URL_OFFER_DETAILS:
  1386.             case SeoRepository::RESOURCE_URL_SALE_DETAILS:
  1387.                 return $this->redirect('/' $alias301);
  1388.                 break;
  1389.         }
  1390.         return $this->redirect(CityRepository::$mainPageURL);
  1391.     }
  1392.     /**
  1393.      * @Route("/comments/load")
  1394.      */
  1395.     public function commentLoad(Request $requestBannerService $bannerService) {
  1396.         $offerID $request->request->get('marketActionOID');
  1397.         $typeID $request->request->get('typeID');
  1398.         $lastCommentID $request->request->get('lastCommentOID');
  1399.         $categoryID $request->request->getInt('categoryID');
  1400.         $directorID $request->request->getInt('directorID');
  1401.         $cacheName $request->request->getInt('isMobileCache') == CommentCacheService::CACHE_NAME CommentCacheService::MOBILE_CACHE_NAME;
  1402.         return new Response($this->getComments($request$bannerService$offerID$typeID$lastCommentID$categoryID$directorID$cacheName));
  1403.     }
  1404.     /**
  1405.      * @Route("/comments/get_by_user/{userID}")
  1406.      */
  1407.     public function commentsGetByUser($userIDRequest $request) {
  1408.         $offerID $request->query->get('offerID');
  1409.         if (!$offerID) {
  1410.             return new Response();
  1411.         }
  1412.         $dql "select comment from Slivki:Comment comment 
  1413.             where comment.userID = :userID and comment.entityID = :offerID 
  1414.             and (comment.hidden = false or comment.hidden is null)
  1415.             and (comment.deleted = false or comment.deleted is null)
  1416.             and comment.confirmedPhone = true
  1417.             order by comment.createdOn desc";
  1418.         $data['comments'] = $this->getDoctrine()->getManager()->createQuery($dql)
  1419.             ->setParameter('userID'$userID)
  1420.             ->setParameter('offerID'$offerID)
  1421.             ->getResult();
  1422.         return $this->render('Slivki/comments/comments_by_user.html.twig'$data);
  1423.     }
  1424.     /**
  1425.      * @Route("/comment/image_upload")
  1426.      */
  1427.     public function commentImageUpload(Request $requestKernelInterface $kernel) {
  1428.         $imageFolder $kernel->getProjectDir() . '/public' ImageService::MEDIA_ROOT ImageService::INITIAL_PATH MediaType::TYPE_USER_VOTE_IMAGE_PATH;
  1429.         $uploadedFile $request->files->get('imageUploadForm');
  1430.         if ($uploadedFile) {
  1431.             if (!in_array(mb_strtolower($uploadedFile->getClientOriginalExtension()), ['jpg''png''gif''jpeg'])) {
  1432.                 return new Response("error=true;result=Разрешены только .jpg, .jpeg, .png или .gif изображения");
  1433.             };
  1434.             $fs = new Filesystem();
  1435.             $newFileName time() . '_' $uploadedFile->getClientOriginalName();
  1436.             while($fs->exists($imageFolder $newFileName)) {
  1437.                 $newFileName time() . '_' $newFileName;
  1438.             }
  1439.             $uploadedFile->move($imageFolder$newFileName);
  1440.             $session $request->getSession();
  1441.             $userCommentImages $session->get('userCommentImages', []);
  1442.             $userCommentImages[] = $newFileName;
  1443.             $session->set('userCommentImages'$userCommentImages);
  1444.             return new Response("error=false;result=" ImageService::MEDIA_ROOT ImageService::INITIAL_PATH MediaType::TYPE_USER_VOTE_IMAGE_PATH $newFileName);
  1445.         } else {
  1446.             return new Response("error=true;result=Error");
  1447.         }
  1448.     }
  1449.     /**
  1450.      * @Route("/comment/image_remove")
  1451.      */
  1452.     public function commentImageRemove(Request $request) {
  1453.         $imageIndex $request->request->get('imageIndex');
  1454.         $mediaID $request->request->getInt('id');
  1455.         if ($mediaID != 0) {
  1456.             $entityManager $this->getDoctrine()->getManager();
  1457.             $media $entityManager->getRepository(Media\CommentMedia::class)->find($mediaID);
  1458.             if ($media && $this->getUser() && $media->getComment()->getUserID() == $this->getUser()->getID()) {
  1459.                 $entityManager->remove($media);
  1460.                 $entityManager->flush();
  1461.             }
  1462.         }
  1463.         $session $request->getSession();
  1464.         $userCommentImages $session->get('userCommentImages', []);
  1465.         if (isset($userCommentImages[$imageIndex])) {
  1466.             unset($userCommentImages[$imageIndex]);
  1467.         }
  1468.         $session->set('userCommentImages'array_values($userCommentImages));
  1469.         return new Response("error=false;result=");
  1470.     }
  1471.     /**
  1472.      * @Route("/comment/get/{commentID}")
  1473.      */
  1474.     public function commentGet($commentID) {
  1475.         $comment $this->getCommentRepository()->find($commentID);
  1476.         return new Response(json_encode([
  1477.             'comment' => $comment,
  1478.             'commentMediasHtml' => $this->renderView('Slivki/comments/medias_preview.html.twig', ['medias' => $comment->getMedias()])
  1479.         ]));
  1480.     }
  1481.     /**
  1482.      * @Route("/comment/is_user_allowed_to_rate/{typeID}/{entityID}")
  1483.      */
  1484.     public function isUserAllowedToRate($typeID$entityID) {
  1485.         $user $this->getUser();
  1486.         if (!$user) {
  1487.             return new JsonResponse(json_encode(false));
  1488.         }
  1489.         return new Response(json_encode($this->getCommentRepository()->isUserAllowedToRate($user->getID(), $entityID$typeID)));
  1490.     }
  1491.     /**
  1492.      * @Route("/comment/edit/{commentID}")
  1493.      */
  1494.     public function commentEdit($commentIDRequest $request) {
  1495.         $entityManager $this->getDoctrine()->getManager();
  1496.         /** @var \Slivki\Entity\Comment $comment */
  1497.         $comment $this->getCommentRepository()->find($commentID);
  1498.         if (!$comment) {
  1499.             return new Response('');
  1500.         }
  1501.         if ($comment->getCreatedOn()->format('U') < strtotime('-7 days') || $comment->getUserID() != $this->getUser()->getID()) {
  1502.             return new Response('');
  1503.         }
  1504.         $commentText trim($request->request->get('comment'''));
  1505.         if (Censure::parse($commentText)) {
  1506.             $response = new Response();
  1507.             $response->setStatusCode(406);
  1508.             return $response;
  1509.         }
  1510.         if ($comment->getRating() > 0) {
  1511.             $rating $request->request->getInt('rating');
  1512.             if ($rating $comment->getRating()) {
  1513.                 $comment->setRating($rating);
  1514.             }
  1515.         }
  1516.         $commentChildren $comment->getChildren()->toArray();
  1517.         if (empty($commentChildren)) {
  1518.             $comment->setComment($this->prepareCommentText($commentText));
  1519.             $comment->setChecked(false);
  1520.         }
  1521.         $comment->setAllowToContact($request->request->getBoolean('allowToContact'));
  1522.         $session $request->getSession();
  1523.         $userCommentImages $session->get('userCommentImages', []);
  1524.         $mediaTypeRepository $entityManager->getRepository(MediaType::class);
  1525.         foreach ($userCommentImages as $key=>$value) {
  1526.             $media = new Media\CommentMedia();
  1527.             $media->setMediaType($mediaTypeRepository->find(MediaType::TYPE_USER_VOTE_IMAGE_ID));
  1528.             $media->setPath(MediaType::TYPE_USER_VOTE_IMAGE_PATH);
  1529.             $media->setName($value);
  1530.             $media->setSortOrder($key);
  1531.             $comment->addMedia($media);
  1532.         }
  1533.         $session->set('userCommentImages', []);
  1534.         $entityManager->flush();
  1535.         $this->resetCommentsCache($comment->getEntityID(), $comment->getTypeID());
  1536.         $comment->setComment(nl2br($comment->getComment()));
  1537.         return new Response(json_encode([
  1538.             'comment' => $comment,
  1539.             'mediasHtml' => $this->renderView('Slivki/comments/medias.html.twig', ['medias' => $comment->getMedias()->toArray()])
  1540.         ]));
  1541.     }
  1542.     /**
  1543.      * @Route("/comment/delete/{commentID}")
  1544.      */
  1545.     public function commentDelete($commentIDRequest $request) {
  1546.         /** @var \Slivki\Entity\Comment $comment */
  1547.         $entityManager $this->getDoctrine()->getManager();
  1548.         $comment $entityManager->getRepository(Comment::class)->find($commentID);
  1549.         if (!$comment) {
  1550.             return new Response('');
  1551.         }
  1552.         if ($comment->getCreatedOn()->format('U') < strtotime('-24 hours') || $comment->getUserID() != $this->getUser()->getID()) {
  1553.             return new Response('');
  1554.         }
  1555.         $commentTypeID $comment->getTypeID();
  1556.         $commentEntityID $comment->getEntityID();
  1557.         $comment->setDeleted(true);
  1558.         $comment->setChecked(false);
  1559.         $comment->setRating(0);
  1560.         $entityManager->flush();
  1561.         $this->resetCommentsCache($commentEntityID$commentTypeID);
  1562.         return new Response('');
  1563.     }
  1564.     /**
  1565.      * @Route("/mailing_seen_it_cheaper")
  1566.      */
  1567.     public function seenCheaperAction(Request $requestMailer $mailer){
  1568.         $email $request->request->get("sender_email");
  1569.         $body $request->request->get("body");
  1570.         $link $request->request->get("link_to_sale");
  1571.         if($this->checkSeenCheaperForm($request)) {
  1572.             $message $mailer->createMessage();
  1573.             $message->setSubject("ОКО: Лучшее предложение")
  1574.                 ->setFrom("info@slivki.by"'Slivki.by')
  1575.                 ->setTo('info@slivki.by')
  1576.                 ->setBody($this->renderView('Slivki/emails/seen_it_cheaper.html.twig',
  1577.                     array('email' => $email'message' => $body'link' => $link)),
  1578.                     'text/html');
  1579.             $mailer->send($message);
  1580.             $result['status'] = "success";
  1581.         } else {
  1582.             $result['status'] = "error";
  1583.         }
  1584.         return new Response(json_encode($result));
  1585.     }
  1586.     public function checkSeenCheaperForm(Request $request){
  1587.         $email $request->request->get("sender_email");
  1588.         if (!filter_var($emailFILTER_VALIDATE_EMAIL)) {
  1589.             return false;
  1590.         }
  1591.         return true;
  1592.     }
  1593.     /**
  1594.      * @Route("/ajax_get_map_placemarks_by_category")
  1595.      */
  1596.     public function ajaxGetMapPlacemarksByCategory(Request $request) {
  1597.         if (!$request->isXmlHttpRequest()) {
  1598.             return $this->redirect("/");
  1599.         }
  1600.         ini_set('memory_limit''1024m');
  1601.         $categoryID $request->request->get('categoryOID');
  1602.         $result = array();
  1603.         $offerRepository $this->getOfferRepository();
  1604.         $offers $offerRepository->getActiveOffersByCategoryID($categoryID);
  1605.         foreach($offers as $offer) {
  1606.             if (!$offer) {
  1607.                 continue;
  1608.             }
  1609.             $result array_merge($result$offerRepository->getOfferGeoLocations($offer));
  1610.         }
  1611.         return new Response(json_encode($result));
  1612.     }
  1613.     /**
  1614.      * @Route("/mailing_campaign/{mailingCampaignID}")
  1615.      */
  1616.     public function mailingCampaignAction($mailingCampaignID) {
  1617.         $entityManager $this->getDoctrine()->getManager();
  1618.         $mailingCampaignRepository $entityManager->getRepository(MailingCampaign::class);
  1619.         $mailingCampaign $mailingCampaignRepository->find($mailingCampaignID);
  1620.         if(!$mailingCampaign) {
  1621.             return $this->redirect("/");
  1622.         }
  1623.         $mailBody $mailingCampaign->getMailBody();
  1624.         $template $this->get('twig')->createTemplate($mailBody);
  1625.         return new Response($template->render([]));
  1626.     }
  1627.     public function sendOfferMessageFormAction(Request $request) {
  1628.         return $this->render(self::getMobileDevice($request) ?
  1629.             'Slivki/mobile/offer/create_own_offer.html.twig' 'Slivki/offers/send_offer_messsage.html.twig');
  1630.     }
  1631.     /**
  1632.      * @Route("/send_offer_message")
  1633.      */
  1634.     public function sendOfferMessage(Request $requestMailer $mailer) {
  1635.         $offerProposal = new OfferProposal();
  1636.         $offerProposal->setType(OfferProposal::PROPOSAL_TYPE);
  1637.         $offerProposal->setPhone($request->request->get('offerPhone'));
  1638.         $offerProposal->setEmail($request->request->get('offerEmail'));
  1639.         $offerProposal->setBuisnessName($request->request->get('offerBuisness'));
  1640.         $offerProposal->setOfferConditions($request->request->get('termsOfPromotion'));
  1641.         $subject 'NEW: Разместить акцию';
  1642.         $messageText '<b>Телефон:</b> ' $request->request->get('offerPhone') . '<br>'
  1643.             '<b>E-mail:</b> ' $request->request->get('offerEmail') . '<br>'
  1644.             '<b>Юр.лицо:</b> ' $request->request->get('offerBuisness') . '<br>'
  1645.             '<b>Условия акции:</b> ' $request->request->get('termsOfPromotion') . '<br>';
  1646.         $message $mailer->createMessage();
  1647.         $message->setSubject($subject)
  1648.             ->setFrom("info@slivki.by"'Slivki.by')
  1649.             ->setTo('info@slivki.by')
  1650.             ->setBody(
  1651.                 $messageText,
  1652.                 'text/html'
  1653.             );
  1654.         $mailer->send($message);
  1655.         try {
  1656.             $em $this->getDoctrine()->getManager();
  1657.             $em->persist($offerProposal);
  1658.             $em->flush();
  1659.         } catch (\Exception $e) {
  1660.             return new Response('Ваше сообщение успешно отправлено');
  1661.         }
  1662.         return new Response('Ваше сообщение успешно отправлено');
  1663.     }
  1664.     /**
  1665.      * @Route("/humorfm")
  1666.      */
  1667.     public function humorFM(Request $request) {
  1668.         if($this->getMobileDevice($request)){
  1669.             return $this->render('Slivki/mobile_humorfm.html.twig');
  1670.         } else{
  1671.             return $this->render('Slivki/humorfm.html.twig');
  1672.         }
  1673.     }
  1674.     /**
  1675.      * @Route("/subscribe/mobile")
  1676.      */
  1677.     public function subscribeForm(Request $request) {
  1678.         if ($this->getMobileDevice($request) and (!$this->getUser() or !$this->getUser()->getAcceptNewsletter())) {
  1679.             return $this->render('Slivki/subscribe_mobile.html.twig');
  1680.         } else {
  1681.             return $this->redirect("/");
  1682.         }
  1683.     }
  1684.     /**
  1685.      * @Route("/send-contact-form")
  1686.      */
  1687.     public function sendContactForm(Request $requestMailer $mailer) {
  1688.         $data = [
  1689.             'email' => $request->request->get('email'''),
  1690.             'name' => $request->request->get('name'''),
  1691.             'body' => $request->request->get('body''')
  1692.         ];
  1693.         $error '';
  1694.         if (!filter_var(trim($data['email'], FILTER_VALIDATE_EMAIL))) {
  1695.             $error .= 'Пожалуйста, введите Ваш E-Mail.<br>';
  1696.         }
  1697.         if (trim($data['body']) == '') {
  1698.             $error .= 'Пожалуйста, введите текст сообщения.<br>';
  1699.         }
  1700.         if ($error != '') {
  1701.             return new Response($error);
  1702.         }
  1703.         $recipientEmail = (strpos($request->headers->get('referer'), '/beznal')) ? 'beznal@slivki.by' 'info@slivki.by';
  1704.         $message $mailer->createMessage();
  1705.         $message->setSubject("Сообщение")
  1706.             ->setFrom("info@slivki.by"'Slivki.by')
  1707.             ->setTo($recipientEmail)
  1708.             ->setBody(
  1709.                 $this->renderView(
  1710.                     'Slivki/emails/contact_email.html.twig',
  1711.                     $data
  1712.                 ),
  1713.                 'text/html'
  1714.             );
  1715.         $mailer->send($message);
  1716.         return new Response();
  1717.     }
  1718.     /**
  1719.      * @Route("/contact-mail-result")
  1720.      */
  1721.     public function contactMailResult(Request $request) {
  1722.         $data['lastComments'] = $this->getDoctrine()->getRepository(Comment::class)->findBy(["hidden" => false], ["createdOn" => "desc"], 3);
  1723.         return $this->render(CommonUtil::isMobileDevice($request) ?
  1724.             'Slivki/mobile/info_pages/contacts_form_result.html.twig' 'Slivki/contact_mail_result.html.twig'$data);
  1725.     }
  1726.     /**
  1727.      * @Route("/readability_sale_stat")
  1728.      */
  1729.     public function readabilitySaleStat(Request $request) {
  1730.         $id $request->request->get('saleID');
  1731.         $timeOnPage $request->request->get('timeOnPage');
  1732.         $percentOfScrolling $request->request->get('percentOfScrolling');
  1733.         $userID $this->getUser();
  1734.         if ($userID) {
  1735.             $userID $this->getUser()->getID();
  1736.         }
  1737.         $pageHeight $request->request->get('pageHeight');
  1738.         $readPx $request->request->get('readPx');
  1739.         $date = new \DateTime();
  1740.         $readabilityStat = new ReadabilityStat();
  1741.         $readabilityStat->setEntityID($id);
  1742.         $readabilityStat->setPercentOfScrolling($percentOfScrolling);
  1743.         $readabilityStat->setTimeOnPage($timeOnPage);
  1744.         $readabilityStat->setCreatedOn($date);
  1745.         $readabilityStat->setUserID($userID);
  1746.         $readabilityStat->setPageHeight($pageHeight);
  1747.         $readabilityStat->setReadPx($readPx);
  1748.         $em $this->getDoctrine()->getManager();
  1749.         $em->persist($readabilityStat);
  1750.         $em->flush($readabilityStat);
  1751.         return new Response('');
  1752.     }
  1753.     /**
  1754.      * @Route("/jivo/hooks")
  1755.      */
  1756.     public function jivoHookAction(Request $request) {
  1757.         $data json_decode($request->getContent(), true);
  1758.         $logger Logger::instance('JIVO HOOK');
  1759.         $entityManager $this->getDoctrine()->getManager();
  1760.         $chatSession null;
  1761.         switch ($data['event_name']) {
  1762.             case 'chat_accepted':
  1763.                 $chatSession = new ChatSession();
  1764.                 $chatSession->setChatID($data['chat_id']);
  1765.                 $entityManager->persist($chatSession);
  1766.                 $chatSession->setOperatorEmail($data['agent']['email']);
  1767.                 $chatSession->setOperatorName($data['agent']['name']);
  1768.                 break;
  1769.             case 'chat_finished':
  1770.                 $chatSession $entityManager->getRepository(ChatSession::class)->findOneByChatID($data['chat_id']);
  1771.                 if (!$chatSession) {
  1772.                     $logger->info('Chat ' $data['chat_id'] . ' not found');
  1773.                     return new Response();
  1774.                 }
  1775.                 $chatSession->setFinishedOn(new \DateTime());
  1776.                 $chatHistory '';
  1777.                 foreach ($data['chat']['messages'] as $message) {
  1778.                     $chatHistory .= date('d.m.Y'$message['timestamp']) . '<br>';
  1779.                     $chatHistory .= ($message['type'] == 'agent' 'Консультант' 'Клиент') . '<br>';
  1780.                     $chatHistory .= $message['message'] . '<br><br>';
  1781.                 }
  1782.                 $chatSession->setChatHistory($chatHistory);
  1783.                 break;
  1784.             default:
  1785.                 return new Response();
  1786.         }
  1787.         if (!$chatSession->getUser() && isset($data['user_token'])) {
  1788.             $user $entityManager->getRepository(User::class)->find($data['user_token']);
  1789.             if ($user) {
  1790.                 $chatSession->setUser($user);
  1791.             } else {
  1792.                 $logger->info('User ' $data['user_token'] . ' not found');
  1793.             }
  1794.         }
  1795.         $entityManager->flush($chatSession);
  1796.         if ($data['event_name'] == 'chat_accepted') {
  1797.             $data['result'] = 'ok';
  1798.             $user $chatSession->getUser();
  1799.             if ($user) {
  1800.                 $data['custom_data'][0]['title'] = 'Баланс';
  1801.                 $data['custom_data'][0]['content'] = number_format($user->getFullBalance(), 2);
  1802.                 $data['contact_info']['name'] = $user->getFirstName();
  1803.                 $data['contact_info']['phone'] = $user->getPhone();
  1804.                 $data['contact_info']['email'] = $user->getEmail();
  1805.                 $data['contact_info']['description'] = '';
  1806.             }
  1807.             $response = new JsonResponse();
  1808.             $response->setCharset('UTF-8');
  1809.             $response->setEncodingOptions(JSON_UNESCAPED_UNICODE);
  1810.             $response->setData($data);
  1811.             return $response;
  1812.         }
  1813.         return new Response();
  1814.     }
  1815.     /**
  1816.      * @Route("/subscribe")
  1817.      */
  1818.     public function subscribeAction(Request $requestMailer $mailer) {
  1819.         $email mb_strtolower(trim($request->request->get('email')));
  1820.         $entityManager $this->getDoctrine()->getManager();
  1821.         $user $entityManager->getRepository(User::class)->loadUserByUsername($emailfalse);
  1822.         if ($user && ($user->getAcceptNewsletter() || $user->getID() == $this->getUser()->getID())) {
  1823.             if (!$user->getAcceptNewsletter()) {
  1824.                 $user->setAcceptNewsletter(true);
  1825.                 $entityManager->flush($user);
  1826.             }
  1827.             return new Response('0');
  1828.         }
  1829.         $subscriber $entityManager->getRepository(Subscriber::class)->findOneByEmail($email);
  1830.         if ($subscriber && $subscriber->getConfirmationCode() == '') {
  1831.             return new Response('0');
  1832.         }
  1833.         if (!$subscriber) {
  1834.             $validator $this->get('validator');
  1835.             $emailConstraint = new Email();
  1836.             if ($email == '' || $validator->validate($email$emailConstraint) != '') {
  1837.                 return new Response('1');
  1838.             }
  1839.             $subscriber = new Subscriber();
  1840.             $subscriber->setEmail($email);
  1841.             $entityManager->persist($subscriber);
  1842.             $confirmationCode md5($subscriber->getID() . $subscriber->getEmail());
  1843.             $subscriber->setConfirmationCode($confirmationCode);
  1844.             $entityManager->flush($subscriber);
  1845.         }
  1846.         $messageBody $this->get('twig')->render('Slivki/emails/confirm_email.html.twig', ['confirmationCode' => $subscriber->getConfirmationCode()]);
  1847.         $message $mailer->createMessage('Вы станете богаче!'$messageBody'text/html')->addTo($email)->addFrom('info@slivki.by');
  1848.         $mailer->send($message);
  1849.         return new Response('2');
  1850.     }
  1851.     /** @Route("/subscribe-from-email/{userHash}") */
  1852.     public function subscribeFromEmailAction(Request $request$userHash) {
  1853.         $entityManager $this->getDoctrine()->getManager();
  1854.         $user null;
  1855.         $sql "select email from customer where md5(id || email) = '" pg_escape_string($userHash) . "'";
  1856.         $query $entityManager->getConnection()->executeQuery($sql);
  1857.         if ($query->rowCount() != 1) {
  1858.             return $this->redirect('/');
  1859.         }
  1860.         $user $entityManager->getRepository(User::class)->loadUserByUsername($query->fetchColumn(), false);
  1861.         if (!$user) {
  1862.             return $this->redirect('/');
  1863.         }
  1864.         $currentUser $this->getUser();
  1865.         if (!$currentUser || ($currentUser->getID() != $user->getID())) {
  1866.             $passwordToken = new UsernamePasswordToken($user$user->getPassword(), 'main'$user->getRoles());
  1867.             $this->get('security.token_storage')->setToken($passwordToken);
  1868.             $event = new InteractiveLoginEvent($request$passwordToken);
  1869.             $this->get('event_dispatcher')->dispatch('security.interactive_login'$event);
  1870.         }
  1871.         return $this->redirect('/profile' '#profile_subscribe');
  1872.     }
  1873.     /**
  1874.      * @Route("/confirm/email/{confirmationCode}")
  1875.      */
  1876.     public function confirmEmailAction($confirmationCode) {
  1877.         $confirmationCode pg_escape_string($confirmationCode);
  1878.         $entityManager $this->getDoctrine()->getManager();
  1879.         $sql "select id, email from subscriber where md5(id::text || email) = '$confirmationCode'";
  1880.         $subscriber $entityManager->getConnection()->executeQuery($sql)->fetch();
  1881.         if (!$subscriber) {
  1882.             $this->addFlash(self::SHOW_INFO_DIALOG_PARAMETER'Пользователь не найден');
  1883.             return $this->redirect(CityRepository::$mainPageURL);
  1884.         }
  1885.         $user $entityManager->getRepository(User::class)->loadUserByUsername($subscriber['email'], false);
  1886.         if ($user) {
  1887.             $user->setAcceptNewsletter(true);
  1888.             $entityManager->flush($user);
  1889.             $entityManager->getConnection()->executeQuery("delete from subscriber where id = $subscriber[id]");
  1890.         } else {
  1891.             $entityManager->getConnection()->executeQuery("update subscriber set confirmation_code = '' where id = $subscriber[id]");
  1892.         }
  1893.         $this->addFlash(self::SHOW_INFO_DIALOG_PARAMETER'Вы успешно подписаны на рассылку');
  1894.         return $this->redirect(CityRepository::$mainPageURL);
  1895.     }
  1896.     /**
  1897.      * @Route("/oplata-promokoda-azs")
  1898.      */
  1899.     public function getGasStationCode(
  1900.         Request $request,
  1901.         OfferCacheService $offerCacheService,
  1902.         SubscriptionService $subscriptionService
  1903.     ): Response {
  1904.         $entityManager $this->getDoctrine()->getManager();
  1905.         $user $this->getUser();
  1906.         $userID $user->getID();
  1907.         $offerID Offer::PETROL_OFFER_ID;
  1908.         $sql "select id from offer_order where user_id = $userID and offer_id = $offerID order by id DESC limit 1";
  1909.         $orderID $entityManager->getConnection()->executeQuery($sql)->fetchColumn();
  1910.         if ($orderID) {
  1911.             $entityOption$entityManager->getRepository(EntityOption::class)->findBy(['entityID' => $orderID]);
  1912.             foreach ($entityOption as $val) {
  1913.                 switch ($val->getName()) {
  1914.                     case "car_model":
  1915.                         $data['carModel'] = $val->getValue();
  1916.                         break;
  1917.                     case "car_number":
  1918.                         $data['carNumber'] = $val->getValue();
  1919.                         break;
  1920.                     case "phone_number":
  1921.                         $data['phoneNumber'] = $val->getValue();
  1922.                         break;
  1923.                 }
  1924.             }
  1925.         }
  1926.         $data['offerID'] = Offer::PETROL_OFFER_ID;
  1927.         $offerRepository $this->getOfferRepository();
  1928.         $offer $offerCacheService->getOffer(Offer::PETROL_OFFER_ID);
  1929.         $data['codeCost'] = $offerRepository->getCodeCost($offer);
  1930.         $data['freeCodesCount'] = $offer->getFreeCodesCount();
  1931.         $data['freeCode'] = $offerRepository->isOfferFreeForUser($offer$this->getUser());
  1932.         $data['useBalance'] =  $this->getUser()->getFullBalance() >= $offerRepository->getCodeCost($offer);
  1933.         $userPhone $user->getCurrentPhone();
  1934.         if ($userPhone) {
  1935.             $data['phoneNumber'] = $userPhone->getPhoneNumber();
  1936.         }
  1937.         $siteSettings $this->getSiteSettings();
  1938.         $data['subscriptionPrice'] = $subscriptionService->isSubscriptionFinished($user)
  1939.             ? $siteSettings->getSubscriptionPrice()
  1940.             : $siteSettings->getSubscriptionFirstPayment();
  1941.         $data['subscriptionFullPrice'] = $siteSettings->getSubscriptionPrice();
  1942.         $subscription $subscriptionService->getSubscription($user);
  1943.         $data['allowedCodesCountBySubscription'] = $subscriptionService->isSubscriber($user)
  1944.             ? $subscription->getNumberOfCodes()
  1945.             : 0;
  1946.         return $this->render(self::getMobileDevice($request) ? 'Slivki/mobile/payment/fuel.html.twig'
  1947.             'Slivki/offers/get_code_for_gas_station.html.twig'$data);
  1948.     }
  1949.     /**
  1950.      * @Route("/get_offer_comment_medias_list")
  1951.      */
  1952.     public function getOfferCommentMediasList(Request $request) {
  1953.         $entityID $request->request->get('entityID');
  1954.         $entityType $request->request->get('entityType');
  1955.         $offset $request->request->get('offset');
  1956.         $limit $request->request->get('limit');
  1957.         switch ($entityType) {
  1958.             case 'category':
  1959.                 $data['commentAndMediaList'] = $this->getMediaRepository()->getOfferCommentMediaListByCategoryID($entityID$offset$limit);
  1960.                 break;
  1961.             case 'offer':
  1962.                 $data['commentAndMediaList'] = $this->getMediaRepository()->getOfferCommentMediaListByOfferID($entityID$offset$limit);
  1963.                 break;
  1964.             case 'all':
  1965.                 $data['commentAndMediaList'] = $this->getMediaRepository()->getOfferCommentMediaList($offset$limit);
  1966.                 break;
  1967.         }
  1968.         return $this->render('Slivki/comments/media_block_list.html.twig'$data);
  1969.     }
  1970.     /**
  1971.      * @Route("/get_top_comment_list")
  1972.      */
  1973.     public function getTopCommentList(Request $request) {
  1974.         $offset $request->request->get('offset');
  1975.         $limit $request->request->get('limit');
  1976.         $data['commentList'] = $this->getCommentRepository()->findBy(['checked' => true'rating' => 5], ['ID' => 'DESC'], $limit$offset);
  1977.         return $this->render('Slivki/category_dividers/comment_list.html.twig'$data);
  1978.     }
  1979.     /** @Route("/ne-nashli-chto-iskali") */
  1980.     public function lookingForAction(Request $request) {
  1981.         return $this->render(self::getMobileDevice($request) ? 'Slivki/mobile/looking_for.html.twig' 'Slivki/looking_for.html.twig');
  1982.     }
  1983.     /** @Route("/send-looking-for") */
  1984.     public function sendLookingForAction(Request $requestMailer $mailer) {
  1985.         if (!$request->getMethod('POST')) {
  1986.             return new Response();
  1987.         }
  1988.         $message $mailer->createMessage();
  1989.         $mailBody "<b>Текст:</b><br>"
  1990.             $request->request->get('text')
  1991.             . "<br><br><b>Email:</b><br>"
  1992.             $request->request->get('email')
  1993.             . "<br><br><b>Телефон:</b><br>"
  1994.             $request->request->get('phone');
  1995.         $message->setSubject("Не нашли, что искали")
  1996.             ->setFrom('info@slivki.by''Slivki.by')
  1997.             ->setTo('info@slivki.by')
  1998.             ->setBody($mailBody'text/html');
  1999.         $mailer->send($message);
  2000.         return new Response();
  2001.     }
  2002.     /**
  2003.      * @Route("/get_sidebar")
  2004.      */
  2005.     public function getSidebar(SlivkiTwigExtension $extension) {
  2006.         return new Response($extension->getSidebar($this->get('twig')));
  2007.     }
  2008.     /**
  2009.      * @Route("/get_sidebar_item_list")
  2010.      */
  2011.     public function getSidebarItemListContent(
  2012.         Request $request,
  2013.         SidebarCacheService $sidebarCacheService
  2014.     ): Response {
  2015.         $offset $request->request->get('offset'0);
  2016.         $length $request->request->get('length'20);
  2017.         $sidebarCached $sidebarCacheService->getSidebarCached();
  2018.         if (null === $sidebarCached) {
  2019.             return new Response('');
  2020.         }
  2021.         $sidebarItemList array_slice($sidebarCached->getItemList(), $offset$length);
  2022.         if (empty($sidebarItemList)) {
  2023.             return new Response('');
  2024.         }
  2025.         $sidebarContent implode(''$sidebarItemList);
  2026.         return new Response($sidebarContent);
  2027.     }
  2028.     /**
  2029.      * @Route("/widget/{alias}")
  2030.      * @Route("/widget/map/{alias}")
  2031.      */
  2032.     public function widgetMapTireAction($alias) {
  2033.         $softCache = new SoftCache('tire-widget');
  2034.         $result $softCache->get($alias);
  2035.         if ($result) {
  2036.             return new Response($result);
  2037.         }
  2038.         $offers null;
  2039.         if ($alias == 'map_tire') {
  2040.             $offers $this->getOfferRepository()->getActiveOffersByCategoryIDNoCache(492);
  2041.         }
  2042.         if (!$offers) {
  2043.             $seo $this->getSeoRepository()->getByAlias('/' $alias);
  2044.             if (!$seo) {
  2045.                 return new Response();
  2046.             }
  2047.             switch ($seo->getResourceURL()) {
  2048.                 case SeoRepository::RESOURCE_URL_OFFER_CATEGORY:
  2049.                     $offers $this->getOfferRepository()->getActiveOffersByCategoryID($seo->getEntityID());
  2050.                     break;
  2051.                 case SeoRepository::RESOURCE_URL_OFFER_DETAILS:
  2052.                     $offer $this->getOfferRepository()->getAnyWay($seo->getEntityID());
  2053.                     if ($offer) {
  2054.                         $offers[] = $offer;
  2055.                     }
  2056.             }
  2057.         }
  2058.         if (!$offers || count($offers) == 0) {
  2059.             return new Response();
  2060.         }
  2061.         $result = [];
  2062.         $i 0;
  2063.         $seoRepository $this->getSeoRepository(Seo::class);
  2064.         foreach($offers as $offer) {
  2065.             if (!$offer) {
  2066.                 continue;
  2067.             }
  2068.             $geoLocations $offer->getGeoLocations();
  2069.             foreach ($geoLocations as $geoLocation) {
  2070.                 $geoLocationInfos['markerAnnotation'] = $geoLocation->getDescription();
  2071.                 $geoLocationInfos['latitude'] = $geoLocation->getLatitude();
  2072.                 $geoLocationInfos['longitude'] = $geoLocation->getLongitude();
  2073.                 $result[$i]['geoLocationInfos'][] = $geoLocationInfos;
  2074.                 $seo $seoRepository->getByEntity('Slivki:Default:details'$offer->getID());
  2075.                 $url '';
  2076.                 if ($seo) {
  2077.                     $url $seo->getMainAlias();
  2078.                 }
  2079.                 $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>";
  2080.                 $i++;
  2081.             }
  2082.         }
  2083.         $result $this->renderView('Slivki/widget/map_tire.html.twig', ['placemarkList' => $result]);
  2084.         $softCache->set($alias$result12 60 60);
  2085.         return new Response($result);
  2086.     }
  2087.     /** @Route("/get_sidebar_banner/{cityID}") */
  2088.     public function getSidebarBanner(BannerService $bannerService$cityID) {
  2089.         $cityID = (int)$cityID;
  2090.         if (!$cityID) {
  2091.             $cityID City::DEFAULT_CITY_ID;
  2092.         }
  2093.         return new JsonResponse($bannerService->getSidebarBannerCached($cityID));
  2094.     }
  2095.     /** @Route("/log/browser") */
  2096.     public function browserLogAction(Request $request) {
  2097.         Logger::instance('BrowserLog')->info($request->request->get('message'));
  2098.         return new Response();
  2099.     }
  2100.     /** @Route("/category/filter/map/{categoryID}") */
  2101.     public function categoryMapFilterAction(Request $requestCacheService $cacheService$categoryID) {
  2102.         ini_set('memory_limit''512M');
  2103.         $offerIDList $request->request->get('offerList', []);
  2104.         $teaserList $cacheService->getTeaserList($offerIDListCommonUtil::isMobileDevice($request));
  2105.         $result = ['html' => '''count' => 0];
  2106.         if ($teaserList) {
  2107.             $data = ['offerList' => array_values($teaserList), 'offersInARow' => self::getMobileDevice($request) ? 3];
  2108.             $result = [
  2109.                 'html' => $this->get('twig')->render('Slivki/offers/teasers.html.twig'$data),
  2110.                 'count' => count($teaserList)
  2111.             ];
  2112.         }
  2113.         return new JsonResponse($result);
  2114.     }
  2115.     /** @Route("/category/location-info/{categoryID}/{limit}/{offset}") */
  2116.     public function getLocationInfoAction($categoryID$limit$offset) {
  2117.         $offerGeoLocationCache = new SoftCache(OfferRepository::CACHE_NAME_GEO_LOCATION_DATA);
  2118.         $features $offerGeoLocationCache->get($categoryID, []);
  2119.         if (!$features) {
  2120.             $features = [];
  2121.         }
  2122.         $features array_slice($features$offset$limit);
  2123.         if (empty($features)) {
  2124.             return new Response(json_encode([]));
  2125.         }
  2126.         $getLocationData = ['type' => 'FeatureCollection''features' => $features];
  2127.         return new Response(json_encode($getLocationData));
  2128.     }
  2129.     /** @Route("/top500") */
  2130.     public function topAction() {
  2131.         $data['infoPage'] = new InfoPage();
  2132.         $data['text'] = $data['infoPage']->getContent();
  2133.         return $this->render('Slivki/pages/pages.html.twig'$data);
  2134.     }
  2135.     /** @Route("/category/get_supplier_address_tab/{directorID}") */
  2136.     public function getSupplierAddressTab(Request $request$directorID) {
  2137.         $entityManager $this->getDoctrine()->getManager();
  2138.         $director $entityManager->getRepository(Director::class)->find($directorID);
  2139.         if (!$director) {
  2140.             return new Response();
  2141.         }
  2142.         $directorUniqueGeoLocations = [];
  2143.         /** @var Offer $offer */
  2144.         foreach ($director->getOffers() as $offer) {
  2145.             if (!$offer->isActive() || !$offer->isInActivePeriod()) {
  2146.                 continue;
  2147.             }
  2148.             /** @var GeoLocation $geoLocation */
  2149.             foreach ($offer->getGeoLocations() as $geoLocation) {
  2150.                 $isUniqueGeoLoation true;
  2151.                 /** @var GeoLocation $uniqueGeoLocation */
  2152.                 foreach ($directorUniqueGeoLocations as $uniqueGeoLocation) {
  2153.                     if ($geoLocation->getCity() == $uniqueGeoLocation->getCity() && $geoLocation->getStreet() == $uniqueGeoLocation->getStreet()
  2154.                         && $geoLocation->getHouse() == $uniqueGeoLocation->getHouse()) {
  2155.                         $isUniqueGeoLoation false;
  2156.                         break;
  2157.                     }
  2158.                 }
  2159.                 if ($isUniqueGeoLoation) {
  2160.                     $directorUniqueGeoLocations[] = $geoLocation;
  2161.                 }
  2162.             }
  2163.         }
  2164.         $data['geoLocationList'] = $directorUniqueGeoLocations;
  2165.         return $this->render(self::getMobileDevice($request) ? 'Slivki/mobile/offer/supplier_address_tab.html.twig'
  2166.             'Slivki/offers/supplier_address_tab.html.twig'$data);
  2167.     }
  2168.     /** @Route("/category/get_supplier_photoguide_tab/{directorID}") */
  2169.     public function getSupplierPhotoguideTab($directorID) {
  2170.         $entityManager $this->getDoctrine()->getManager();
  2171.         $director $entityManager->getRepository(Director::class)->find($directorID);
  2172.         if (!$director) {
  2173.             return new Response();
  2174.         }
  2175.         $teaserList = [];
  2176.         $saleRepository $this->getSaleRepository();
  2177.         /** @var Sale $sale */
  2178.         foreach ($director->getSales() as $sale) {
  2179.             $saleCached $saleRepository->findCached($sale->getID());
  2180.             $teaserList[] = $this->renderView('Slivki/sale/teaser.html.twig', ['sale' => $saleCached]);
  2181.         }
  2182.         $data['teaserList'] = $teaserList;
  2183.         return $this->render('Slivki/offers/supplier_photoguide_tab.html.twig'$data);
  2184.     }
  2185.     /** @Route("/get-sorted-sidebar") */
  2186.     public function getSortedSidebar(Request $request) {
  2187.         if (!$request->isMethod(Request::METHOD_POST)) {
  2188.             return $this->redirectToRoute('homepage');
  2189.         }
  2190.         $requestParameters $request->request->all();
  2191.         if (!isset($requestParameters['sortBy'])) {
  2192.             $requestParameters['sortBy'] = 'default';
  2193.         }
  2194.         $categoryID $requestParameters['categoryID'] ? $requestParameters['categoryID'] : null;
  2195.         $coordinates $requestParameters['coordinates'] != '' explode(','$requestParameters['coordinates']) : null;
  2196.         $sortedSaleIDList $this->getSaleRepository()->getSaleIDSorted(
  2197.             $requestParameters['sortBy'], $categoryID$requestParameters['offset'],
  2198.             $requestParameters['limit'], $coordinates);
  2199.         $softCache = new SoftCache(SaleRepository::CACHE_NAME);
  2200.         $sortedSaleList $softCache->getMulti($sortedSaleIDList);
  2201.         if (!is_array($sortedSaleList)) {
  2202.             $sortedSaleList = [];
  2203.         }
  2204.         $sidebarContent '';
  2205.         foreach ($sortedSaleList as $sale) {
  2206.             if (!$sale) {
  2207.                 continue;
  2208.             }
  2209.             $sidebarContent .= $this->renderView('Slivki/sidebar/sale_teaser.html.twig', ['sale' => $sale]);
  2210.         }
  2211.         return new Response($sidebarContent);
  2212.     }
  2213.     /** @Route("/offer/food-extension-order") */
  2214.     public function offerFoodExtensionOrder(Request $request) {
  2215.         if (!self::getMobileDevice($request)) {
  2216.             return $this->redirectToRoute('homepage');
  2217.         }
  2218.         return $this->render('Slivki/offers/food_extension/mobile/order.html.twig');
  2219.     }
  2220.     /** @Route("/offer/food-extension-order-confirm") */
  2221.     public function offerFoodExtensionOrderConfirm(Request $request) {
  2222.         if (!self::getMobileDevice($request)) {
  2223.             return $this->redirectToRoute('homepage');
  2224.         }
  2225.         return $this->render('Slivki/offers/food_extension/mobile/order_confirm.html.twig');
  2226.     }
  2227.     /** @Route("/food-order/check/{orderID}") */
  2228.     public function checkFoodOrderStateActioin($orderID) {
  2229.         $order $this->getDoctrine()->getManager()->find(FoodOrder::class, $orderID);
  2230.         if (!$order || $order->getStatus() != OfferOrder::STATUS_INIT) {
  2231.             return new Response('paid');
  2232.         }
  2233.         return new Response();
  2234.     }
  2235.     /** @Route("/offer_supplier_image/{offerID}/{limit}/{offset}") */
  2236.     public function getOfferSupplierSliderAction(CacheService $cacheService$offerID$limit$offset) {
  2237.         $supplierOfferPhotoList $cacheService->getMediaList($offerIDMedia\OfferSupplierPhotoMedia::TYPE$offset$limit);
  2238.         if (empty($supplierOfferPhotoList)) {
  2239.             return new Response('');
  2240.         }
  2241.         return $this->render('Slivki/comments/offer_supplier_photos.html.twig',
  2242.             ['supplierOfferPhotoList' => $supplierOfferPhotoList]);
  2243.     }
  2244.     /** @Route("/location/confirm/test") */
  2245.     public function testLocationConfirmAction(Request $request) {
  2246.         $request->request->set('showLocationConfirm'true);
  2247.         return $this->indexAction($request);
  2248.     }
  2249.     /**
  2250.      * @Route("/dreamland-registration/{code}")
  2251.      */
  2252.     public function dreamlandPartnerAction(Request $request$code) {
  2253.         $entityManager $this->getDoctrine()->getManager();
  2254.         $entityOptionRepository $entityManager->getRepository(EntityOption::class);
  2255.         $partnerCode $entityOptionRepository->findOneBy([
  2256.             'entityTypeID' => null,
  2257.             'name' => EntityOption::OPTION_DREAMLAND_PARTNER,
  2258.             'value' => $code
  2259.         ]);
  2260.         if (!$partnerCode) {
  2261.             return $this->redirect('/');
  2262.         }
  2263.         if ($this->getUser()) {
  2264.             $option $entityOptionRepository->findOneBy([
  2265.                 'entityTypeID' => EntityOption::USER_TYPE,
  2266.                 'name' => EntityOption::OPTION_DREAMLAND_PARTNER,
  2267.                 'entityID' => $this->getUser()->getID()
  2268.             ]);
  2269.             if (!$option) {
  2270.                 $option = new EntityOption();
  2271.                 $option->setEntityTypeID(EntityOption::USER_TYPE);
  2272.                 $option->setEntityID($this->getUser()->getID());
  2273.                 $option->setName(EntityOption::OPTION_DREAMLAND_PARTNER);
  2274.                 $option->setValue($code);
  2275.                 $entityManager->persist($option);
  2276.                 $entityManager->flush();
  2277.             }
  2278.             return $this->redirect($entityManager->getRepository(Seo::class)->getOfferURL(Offer::DREAMLAND_OFFER_ID)->getMainAlias());
  2279.         }
  2280.         $request->getSession()->set(EntityOption::OPTION_DREAMLAND_PARTNER$code);
  2281.         if (CommonUtil::isMobileDevice($request)) {
  2282.             return $this->redirect($entityManager->getRepository(Seo::class)->getOfferURL(Offer::DREAMLAND_OFFER_ID)->getMainAlias());
  2283.         }
  2284.         return $this->redirect($entityManager->getRepository(Seo::class)->getOfferURL(Offer::DREAMLAND_OFFER_ID)->getMainAlias());
  2285.     }
  2286.     /** @Route("/newadformat") */
  2287.     public function newAdFormatActioin() {
  2288.         return $this->render('Slivki/newadformat/index.html.twig');
  2289.     }
  2290.     public function domainPlaceHolderAction(Request $request$entityID) {
  2291.         $offer $this->getDoctrine()->getManager()->find(Offer::class, $entityID);
  2292.         $director $offer->getDirectors()->first();
  2293.         return $this->render(CommonUtil::isMobileDevice($request) ? 'Slivki/m/mobile/index.html.twig' 'Slivki/m/index.html.twig', ['director' => $director]);
  2294.     }
  2295.     /** @Route("/email-test") */
  2296.     public function emailTestAction(Mailer $mailer) {
  2297.         $message $mailer->createMessage('test''test');
  2298.         $message->addTo('igoradv@gmail.com');
  2299.         $message->setFrom('info@slivki.by''Slivki.by');
  2300.         $mailer->send($message);
  2301.         return new Response('sent');
  2302.     }
  2303.     /** @Route("/prilozhenie-skidok", name = "mobileApp") */
  2304.     public function appPageAction(Request $request) {
  2305.         $view CommonUtil::isMobileDevice($request) ? 'Slivki/mobile/mobile_app.html.twig' 'Slivki/mobile_app.html.twig';
  2306.         return $this->render($view);
  2307.     }
  2308.     /** @Route("/betera-advent") */
  2309.     public function beteraAdventCalendar(Request $request) {
  2310.         return $this->render(self::getMobileDevice($request) ? 'Slivki/mobile/betera_advent/base.html.twig' 'Slivki/betera_advent/base.html.twig');
  2311.     }
  2312.     /** @Route("/profile/oplata-pay") */
  2313.     public function balanceWirtuallWallet(Request $request) {
  2314.         return $this->render(self::getMobileDevice($request) ? 'Slivki/mobile/payment/slivki_pay/index.html.twig' 'Slivki/payment/slivki_pay/index.html.twig');
  2315.     }
  2316.     /** @Route("/virtual-wallet-pay") */
  2317.     public function balanceWirtuallWalletQuery(Request $request) {
  2318.         return $this->render(self::getMobileDevice($request) ? 'Slivki/mobile/payment/slivki_pay/wirtualWallet.html.twig' 'Slivki/payment/slivki_pay/wirtualWallet.html.twig');
  2319.     }
  2320.     /** @Route("/callback") */
  2321.     public function callbackRequest(Request $request) {
  2322.         return $this->render(self::getMobileDevice($request) ? 'Slivki/mobile/callback/index.html.twig' 'Slivki/callback/index.html.twig');
  2323.     }
  2324.     /** @Route("/profile/transfer-balance") */
  2325.     public function transferBalanceIsNotSlivkiPay(Request $request) {
  2326.         return $this->render(self::getMobileDevice($request) ? 'Slivki/mobile/transfer_balance/index.html.twig' 'Slivki/transfer_balance/index.html.twig');
  2327.     }
  2328. }