src/Controller/SiteController.php line 638

Open in your IDE?
  1. <?php
  2. namespace Slivki\Controller;
  3. use Psr\Container\ContainerInterface;
  4. use Slivki\Entity\AuthToken;
  5. use Slivki\Entity\Banner;
  6. use Slivki\Entity\Category;
  7. use Slivki\Entity\City;
  8. use Slivki\Entity\Comment;
  9. use Slivki\Entity\FoodOfferOptionExtension;
  10. use Slivki\Entity\FoodOrder;
  11. use Slivki\Entity\GeoLocation;
  12. use Slivki\Entity\GiftCertificate;
  13. use Slivki\Entity\GiftCertificateOrder;
  14. use Slivki\Entity\HotFeed;
  15. use Slivki\Entity\Media;
  16. use Slivki\Entity\Media\OfferExtensionMedia;
  17. use Slivki\Entity\Offer;
  18. use Slivki\Entity\OfferOrder;
  19. use Slivki\Entity\OfferOrderDetails;
  20. use Slivki\Entity\Partner;
  21. use Slivki\Entity\PartnerOffer;
  22. use Slivki\Entity\Sale;
  23. use Slivki\Entity\Seo;
  24. use Slivki\Entity\SiteSettings;
  25. use Slivki\Entity\User;
  26. use Slivki\Entity\UserActivity;
  27. use Slivki\Entity\UserBalanceActivityType;
  28. use Slivki\Entity\UserConfirmation;
  29. use Slivki\Entity\UserGroup;
  30. use Slivki\Entity\Visit;
  31. use Slivki\Repository\CategoryRepository;
  32. use Slivki\Repository\OfferRepository;
  33. use Slivki\Repository\SeoRepository;
  34. use Slivki\Services\BannerService;
  35. use Slivki\Services\Comment\CommentCacheService;
  36. use Slivki\Services\ImageService;
  37. use Slivki\Services\Mailer;
  38. use Slivki\Services\Offer\CustomProductOfferSorter;
  39. use Slivki\Services\Offer\OfferCacheService;
  40. use Slivki\Services\QRCodeGenerator\Generators\SosediBarcodeGenerator;
  41. use Slivki\Services\Sale\SaleCacheService;
  42. use Slivki\Util\Iiko\AbstractDelivery;
  43. use Slivki\Util\Logger;
  44. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  45. use Symfony\Bundle\FrameworkBundle\Controller\Controller;
  46. use Symfony\Component\Filesystem\Filesystem;
  47. use Symfony\Component\HttpFoundation\Request;
  48. use Symfony\Component\HttpFoundation\Response;
  49. use Symfony\Component\HttpFoundation\Cookie;
  50. use Symfony\Component\HttpFoundation\Session\Session;
  51. use Symfony\Component\HttpKernel\KernelInterface;
  52. use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
  53. use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
  54. use Slivki\Util\SoftCache;
  55. use Slivki\Util\CommonUtil;
  56. use Slivki\Repository\CommentRepository;
  57. use Mpdf\Config\ConfigVariables;
  58. use Mpdf\Config\FontVariables;
  59. use Mpdf\Mpdf;
  60. class SiteController extends AbstractController {
  61.     const UTM_SOURCE_COOKIE_NAME 'utmSource';
  62.     const PARAMETER_MOBILE_DEVICE "mobileDevice";
  63.     const PARAMETER_META_INFO "slivkiMetaInfo";
  64.     const USER_TOKEN_COOKIE ='visitedoffers4';
  65.     const SHOW_INFO_DIALOG_PARAMETER 'showInfoPopup';
  66.     const DEVICE_TYPE_DESKTOP 0;
  67.     const DEVICE_TYPE_MOBILE 1;
  68.     const DEVICE_TYPE_MOBILE_APP 2;
  69.     const DEVICE_TYPE_FOOD_COURT 3;
  70.     const LAST_OFFER_RATE_ACTIVITY_PARAMETER_NAME 'lastOfferRateActivity';
  71.     const TARANTOOL_CATEGORY_BOX true;
  72.     public function __construct(KernelInterface $kernel) {
  73.         $this->setUtmSourceCookie();
  74.         $this->kernel $kernel;
  75.     }
  76.     public function setContainer(ContainerInterface $container): ?ContainerInterface {
  77.         $previous parent::setContainer($container);
  78.         if ($container) {
  79.             $user $this->getUser();
  80.             if ($user && !$user->isAccountNonLocked()) {
  81.                 $user->setToken('');
  82.                 $this->getDoctrine()->getManager()->flush($user);
  83.                 $this->get('security.token_storage')->setToken(null);
  84.                 $this->get('request_stack')->getCurrentRequest()->getSession()->invalidate();
  85.             }
  86.         }
  87.         return $previous;
  88.     }
  89.     private function setUtmSourceCookie() {
  90.         $request Request::createFromGlobals();
  91.         $utmSource $request->query->get('utm_source');
  92.         $referer $request->headers->get('referer');
  93.         $response = new Response();
  94.         if ($utmSource && $referer && parse_url($referer)['host'] != $request->getHost()) {
  95.             $cookie = [
  96.                 'utmSource' => $utmSource,
  97.                 'utm_medium' => $request->query->get('utm_medium'),
  98.                 'utm_campaign' => $request->query->get('utm_campaign'),
  99.                 'utm_term' => $request->query->get('utm_term'),
  100.                 'utm_content' => $request->query->get('utm_content'),
  101.                 'ref_code' => $request->query->get('ref_code'),
  102.                 'time' => time(),
  103.             ];
  104.             $expire $utmSource == 'rtbhouse' 60*60*24*30 604800;
  105.             $cookie Cookie::create(self::UTM_SOURCE_COOKIE_NAMEserialize($cookie),  $expire time());
  106.             $response->headers->setCookie($cookie);
  107.             $response->sendHeaders();
  108.         }
  109.     }
  110.     protected function getUtmSourceCookie(Request $request) {
  111.         $cookie $request->cookies->get(self::UTM_SOURCE_COOKIE_NAME);
  112.         if (!$cookie) {
  113.             return false;
  114.         }
  115.         $result unserialize($cookie);
  116.         if (count($result) < 2) {
  117.             return false;
  118.         }
  119.         $result['period'] = round((time() - $result['time']) / 86400);
  120.         return $result;
  121.     }
  122.     protected function getUtmSourceArray(Request $request) {
  123.         return [
  124.             'utm_source' => $request->query->get('utm_source'''),
  125.             'utm_medium' => $request->query->get('utm_medium'''),
  126.             'utm_campaign' => $request->query->get('utm_campaign'''),
  127.             'utm_term' => $request->query->get('utm_term'''),
  128.             'utm_content' => $request->query->get('utm_content''')
  129.         ];
  130.     }
  131.     protected function getUtmDataFromReferer($referer) {
  132.         $query parse_url($refererPHP_URL_QUERY);
  133.         if ($query) {
  134.             $utmArray = [];
  135.             $parameters explode('&'$query);
  136.             foreach ($parameters as $parameter) {
  137.                 if (CommonUtil::isBeginsWith($parameter'utm_')) {
  138.                     $utmArray[] = $parameter;
  139.                 }
  140.             }
  141.             return implode('&'$utmArray);
  142.         }
  143.         return '';
  144.     }
  145.     public static function getMobileDevice(Request $request) {
  146.         return CommonUtil::isMobileDevice($request);
  147.     }
  148.     /**
  149.      * @return \Slivki\Repository\PartnerOfferRepository
  150.      */
  151.     protected function getPartnerOfferRepository() {
  152.         return $this->getDoctrine()->getRepository(PartnerOffer::class);
  153.     }
  154.     protected function getGiftSupplierRepository(){
  155.         return $this->getDoctrine()->getRepository(Partner::class);
  156.     }
  157.     /**
  158.      * @return \Slivki\Repository\OfferRepository
  159.      */
  160.     protected function getOfferRepository() {
  161.         return $this->getDoctrine()->getRepository(Offer::class);
  162.     }
  163.     /**
  164.      * @return \Slivki\Repository\CategoryRepository
  165.      */
  166.     protected function getCategoryRepository() {
  167.         return $this->getDoctrine()->getRepository(Category::class);
  168.     }
  169.     /**
  170.      * @return \Slivki\Repository\SaleRepository
  171.      */
  172.     protected function getSaleRepository() {
  173.         return $this->getDoctrine()->getRepository(Sale::class);
  174.     }
  175.     /**
  176.      * @return \Slivki\Repository\MediaRepository
  177.      */
  178.     protected function getMediaRepository() {
  179.         return $this->getDoctrine()->getRepository(Media::class);
  180.     }
  181.     /**
  182.      * @return \Slivki\Repository\OfferOrderRepository
  183.      */
  184.     protected function getOfferOrderRepository() {
  185.         return $this->getDoctrine()->getRepository(OfferOrder::class);
  186.     }
  187.     /**
  188.      * @return \Slivki\Repository\OfferOrderDetails
  189.      */
  190.     protected function getOfferOrderDetailsRepository() {
  191.         return $this->getDoctrine()->getRepository(OfferOrderDetails::class);
  192.     }
  193.     /**
  194.      * @return \Slivki\Repository\SeoRepository
  195.      */
  196.     protected function getSeoRepository() {
  197.         return $this->getDoctrine()->getRepository(Seo::class);
  198.     }
  199.     /**
  200.      * @return \Slivki\Repository\GeoLocationRepository
  201.      */
  202.     protected function getGeoLocationRepository() {
  203.         return $this->getDoctrine()->getRepository(GeoLocation::class);
  204.     }
  205.     /**
  206.      * @return \Slivki\Repository\CommentRepository
  207.      */
  208.     protected function getCommentRepository() {
  209.         return $this->getDoctrine()->getRepository(Comment::class);
  210.     }
  211.     /**
  212.      * @return \Slivki\Repository\BannerRepository
  213.      */
  214.     protected function getBannerRepository() {
  215.         return $this->getDoctrine()->getRepository(Banner::class);
  216.     }
  217.     /**
  218.      * @return \Slivki\Repository\UserBalanceActivityType
  219.      */
  220.     protected function getUserBalanceActivityTypeRepository() {
  221.         return $this->getDoctrine()->getRepository(UserBalanceActivityType::class);
  222.     }
  223.     /**
  224.      * @return \Slivki\Repository\SiteSettingsRepository
  225.      */
  226.     protected  function getSiteSettingsRepository(){
  227.         return $this->getDoctrine()->getRepository(SiteSettings::class);
  228.     }
  229.     
  230.     /**
  231.      * @return \Slivki\Repository\UserRepository
  232.      */
  233.     protected function getUserRepository() {
  234.         return $this->getDoctrine()->getRepository(User::class);
  235.     }
  236.     /**
  237.      * @return \Slivki\Repository\UserActivity
  238.      */
  239.     protected function getUserActivityRepository() {
  240.         return $this->getDoctrine()->getRepository(UserActivity::class);
  241.     }
  242.     /**
  243.      * @return \Slivki\Entity\SiteSettings
  244.      */
  245.     protected function getSiteSettings() {
  246.         return $this->getDoctrine()->getRepository(SiteSettings::class)->getSiteSettingsCached();
  247.     }
  248.     /**
  249.      * @return \Slivki\Repository\Visit
  250.      */
  251.     protected function getVisitRepository() {
  252.         return $this->getDoctrine()->getRepository(Visit::class);
  253.     }
  254.     public function sendCode(Mailer $mailerOfferOrder $offerOrder): void
  255.     {
  256.         if ($offerOrder instanceof GiftCertificateOrder || $offerOrder instanceof FoodOrder) {
  257.             return;
  258.         }
  259.         $email trim($offerOrder->getUser()->getEmail());
  260.         if (!$email || $email == '') {
  261.             return;
  262.         }
  263.         if ($offerOrder instanceof GiftCertificateOrder) {
  264.             foreach ($offerOrder->getOfferOrderDetails() as $offerOrderDetails) {
  265.                 if ($offerOrder->getUser()->getEmail()) {
  266.                     $mpdf $this->getGiftCertificateMpdf($this->kernel$offerOrderDetails);
  267.                     if (!$mpdf) {
  268.                         continue;
  269.                     }
  270.                     $path '/tmp/certificate'.$offerOrderDetails->getID().'.pdf';
  271.                     $mpdf->Output($path'F');
  272.                     $message $mailer->createMessage();
  273.                     $message->setSubject('Slivki.by - промокод на акцию')
  274.                         ->setFrom('info@slivki.by''Slivki.by')
  275.                         ->setTo($offerOrder->getUser()->getEmail())
  276.                         ->setBody($this->get('twig')->render('Slivki/emails/code.html.twig', ['offerOrder' => $offerOrder]), 'text/html')
  277.                         ->attachFromPath($path);
  278.                     $mailer->send($message);
  279.                 }
  280.             }
  281.         } else {
  282.             if ($offerOrder->getUser()->getEmail()) {
  283.                 $message $mailer->createMessage();
  284.                 $message->setSubject('Slivki.by - промокод на акцию')
  285.                     ->setFrom('info@slivki.by''Slivki.by')
  286.                     ->setTo($offerOrder->getUser()->getEmail())
  287.                     ->setBody($this->get('twig')->render('Slivki/emails/code.html.twig', ['offerOrder' => $offerOrder]), 'text/html');
  288.                 $mailer->send($message);
  289.             }
  290.         }
  291.     }
  292.     private function sendGiftCertificate(KernelInterface $kernelMailer $mailerOfferOrder $order) {
  293.         foreach ($order->getOfferOrderDetails() as $offerOrderDetails) {
  294.             $mpdf $this->getGiftCertificateMpdf($kernel$offerOrderDetails);
  295.             if (!$mpdf) {
  296.                 continue;
  297.             }
  298.             $content $mpdf->Output('''S');
  299.             // save preview
  300.             $iMagick = new \Imagick();
  301.             $iMagick->readImageBlob($content);
  302.             $iMagick->setImageFormat('png');
  303.             $iMagick->writeImage($kernel->getProjectDir() . GiftCertificate::PREVIEW_PATH $offerOrderDetails->getID() . '.png');
  304.             $attachment = new \Swift_Attachment($content'certificate.pdf''application/pdf');
  305.             $message $mailer->createMessage();
  306.             $user $offerOrderDetails->getOfferOrder()->getUser();
  307.             $message->setSubject('Подарочный сертификат Slivki.by')
  308.                 ->setFrom("info@slivki.by"'Slivki.by')
  309.                 ->setTo($user->getEmail())
  310.                 ->attach($attachment)
  311.                 ->setBody($this->renderView('Slivki/emails/gift_certificate.html.twig', [
  312.                     'name' => $user->getFirstName()]), 'text/html');
  313.             $mailer->send($message);
  314.         }
  315.     }
  316.     /**
  317.      * @return null|\Mpdf\Mpdf
  318.      */
  319.     protected function getGiftCertificateMpdf(KernelInterface $kernelOfferOrderDetails $offerOrderDetails) {
  320.         $giftCertificate $offerOrderDetails->getGiftCertificate();
  321.         if (!$giftCertificate) {
  322.             return null;
  323.         }
  324.         $customFontDir $kernel->getProjectDir() . '/public/fonts/crt-fonts/ttf';
  325.         $defaultConfig = (new ConfigVariables())->getDefaults();
  326.         $defaultFontDir $defaultConfig['fontDir'];
  327.         $defaultFontConfig = (new FontVariables())->getDefaults();
  328.         $defaultFontData $defaultFontConfig['fontdata'];
  329.         $mpdf = new Mpdf([
  330.             'fontDir' => array_merge($defaultFontDir, [
  331.                 $customFontDir,
  332.             ]),
  333.             'tempDir' => '/tmp',
  334.             'fontdata' => $defaultFontData + [
  335.                     'sfrounded' => [
  336.                         'R' => 'SFRounded-Ultralight.ttf',
  337.                     ],
  338.                     'sf' => [
  339.                         'R' => 'SFProText-Regular.ttf',
  340.                     ],
  341.                 ],
  342.             'mode' => 'utf-8',
  343.             'format' => 'A4',
  344.             'orientation' => 'P',
  345.             'margin_top' => 10,
  346.             'margin_bottom' => 0,
  347.             'margin_left' => 0,
  348.             'margin_right' => 0,
  349.         ]);
  350.         $mpdf->curlAllowUnsafeSslRequests true;
  351.         $template 'Slivki/gift_certificates/crt_pdf.html.twig';
  352.         if (SosediBarcodeGenerator::OFFER_ID === (int) $offerOrderDetails->getOfferOrder()->getOffer()->getID()) {
  353.             $template 'Slivki/gift_certificates/sosedi_pdf.html.twig';
  354.         }
  355.         $mpdf->WriteHTML($this->renderView($template, [
  356.             'offerOrderDetails' => $offerOrderDetails,
  357.             'giftCertificate' => $giftCertificate,
  358.             'offer' => $giftCertificate->getOffer(),
  359.         ]));
  360.         return $mpdf;
  361.     }
  362.     protected function sendConfirm(Mailer $mailer$user) {
  363.         $userConfirmation $this->getDoctrine()->getRepository(UserConfirmation::class)->findOneByUserID($user->getID());
  364.         if(!$userConfirmation){
  365.             return false;
  366.         }
  367.         $confirmURL "/confirm/" md5($userConfirmation->getID() . $user->getID());
  368.         $message $mailer->createMessage();
  369.         $message->setSubject("Регистрация на Slivki.by")
  370.             ->setFrom("info@slivki.by"'Slivki.by')
  371.             ->setTo($user->getEmail())
  372.             ->setBody(
  373.                 $this->renderView(
  374.                     'Slivki/emails/confirm_user.html.twig',
  375.                     array('link' => $confirmURL)
  376.                 ),
  377.                 'text/html'
  378.             );
  379.         $mailer->send($message);
  380.         
  381.         return true;
  382.     }
  383.     /**
  384.      * @deprecated Use OfferOrderRepository::getNewOrderNumber
  385.      */
  386.     protected function getNewOrderNumber() {
  387.         return $this->getDoctrine()->getRepository(OfferOrder::class)->getNewOrderNumber();
  388.     }
  389.     protected function getLogger() {
  390.         return Logger::instance('Controller');
  391.     }
  392.     protected function log($text) {
  393.         $this->getLogger()->info($this->container->get('request_stack')->getMainRequest()->getRequestUri() . ": $text");
  394.     }
  395.     protected function getComments(Request $requestBannerService $bannerService$entityID$typeID$lastCommentID 0$categoryID 0$directorID 0$cacheName CommentCacheService::CACHE_NAME) {
  396.         $firstPage $lastCommentID == && $entityID != 0;
  397.         $softCache = new SoftCache($cacheName);
  398.         $commentsBlock '';
  399.         $cacheKey $typeID '-' $entityID;
  400.         $mobileDevice false;
  401.         $cityID $request->getSession()->get(City::CITY_ID_SESSION_KEYCity::DEFAULT_CITY_ID);
  402.         if ($cacheName == CommentRepository::MOBILE_CACHE_NAME) {
  403.             $mobileDevice true;
  404.         }
  405.         $offerId === $typeID $entityID null;
  406.         if ($firstPage) {
  407.             $commentsBlock $softCache->getDataForLockedKey($cacheKey0);
  408.             if ($commentsBlock == SoftCache::LOCKED_KEY) {
  409.                 return '';
  410.             }
  411.             if ($commentsBlock) {
  412.                 return $directorID != 5596 $this->insertBannersToComments($bannerService$commentsBlock$mobileDevice$cityID$offerId) : $commentsBlock;
  413.             }
  414.             $softCache->set($cacheKeySoftCache::LOCKED_KEY10);
  415.         }
  416.         if ($entityID == ) {
  417.             $commentRepository $this->getCommentRepository();
  418.             if ($categoryID == 0) {
  419.                 $data['isLiveComments'] = 1;
  420.                 if ($directorID 0) {
  421.                     $data['comments'] = $commentRepository->getCommentsByDirectorID($directorID,CommentRepository::COMMENTS_PER_PAGE$lastCommentID);
  422.                 } else {
  423.                     $data['comments'] = $commentRepository->getLiveComments(CommentRepository::COMMENTS_PER_PAGE$lastCommentID);
  424.                 }
  425.                 $data['commentsAmount'] = CommentRepository::COMMENTS_PER_PAGE;
  426.                 $data['hasMore'] = true;
  427.             } else {
  428.                 $data['isLiveComments'] = 1;
  429.                 $data['hasMore'] = true;
  430.                 $data['commentsAmount'] = CommentRepository::COMMENTS_PER_PAGE;
  431.                 $data['categoryID'] = $categoryID;
  432.                 $data['comments'] = $commentRepository->getCommentsByCategoryID($categoryID$data['commentsAmount'], $lastCommentID);
  433.             }
  434.         } else {
  435.             $comments $this->getCommentRepository()->getCommentsByEntityID($entityIDCommentRepository::COMMENTS_PER_PAGE$lastCommentID);
  436.             if (empty($comments)) {
  437.                 return '';
  438.             }
  439.             $lastCommentID $comments[count($comments) - 1]->getID();
  440.             $data['comments'] = $comments;
  441.             if ($firstPage && $typeID == Comment::TYPE_OFFER_COMMENT) {
  442.                 $offer $this->getOfferRepository()->getAnyWay($entityID);
  443.                 if ($offer && !$offer->isHideBannersInComments()) {
  444.                     $data['showBanners'] = true;
  445.                 }
  446.             }
  447.             $data['commentsAmount'] = CommentRepository::COMMENTS_PER_PAGE;
  448.             $dql 'select comment from Slivki:Comment comment
  449.                 where comment.entityID = :entityID and comment.typeID = :typeID and comment.parentID is null and comment.ID < :lastCommentID and comment.hidden = false and comment.confirmedPhone = true';
  450.             $query $this->getDoctrine()->getManager()->createQuery($dql)
  451.                 ->setParameter('entityID'$entityID)->setParameter('lastCommentID'$lastCommentID)->setParameter('typeID'$typeID);
  452.             $query->setMaxResults(1);
  453.             if ($typeID == Comment::TYPE_OFFER_COMMENT) {
  454.                 $commentsAmount $this->getCommentRepository()->getCommentsCountByEntityID($entityIDComment::TYPE_OFFER_COMMENT);
  455.                 $data['hasMore'] = false;
  456.                 $data['pagination'] = $this->renderView('Slivki/pagination.html.twig', [
  457.                     'paginationID' => 'offerCommentPagination',
  458.                     'current' => 1,
  459.                     'total' => ceil($commentsAmount/CommentRepository::COMMENTS_PER_PAGE),
  460.                     'url' => $this->getDoctrine()->getRepository(Seo::class)->getOfferURL($entityID)->getMainAlias() . '?page='
  461.                 ]);
  462.             } else {
  463.                 $data['hasMore'] = count($query->getResult()) > 0;
  464.             }
  465.         }
  466.         $view 'Slivki/comments/comments.html.twig';
  467.         if ($mobileDevice) {
  468.             $view 'Slivki/mobile/comment/list.html.twig';
  469.         }
  470.         $response $this->get('twig')->render($view$data);
  471.         if ($firstPage) {
  472.             $softCache->set($cacheKey$response48 60 60);
  473.         }
  474.         return $directorID != 5596 $this->insertBannersToComments($bannerService$response$mobileDevice$cityID$offerId) : $response;
  475.     }
  476.     // TODO: Refactor and remove to service
  477.     private function insertBannersToComments(BannerService $bannerService$commentsHTML$mobileDevice$cityID City::DEFAULT_CITY_ID$offerId null) {
  478.         $bannerList = [];
  479.         if (!($this->getUser() and $this->getUser()->hasRole(UserGroup::ROLE_ADS_FREE))) {
  480.             $bannerList $bannerService->getCommentsBanners($mobileDevice$cityID$offerId);
  481.             if (count($bannerList) == && $cityID != City::DEFAULT_CITY_ID) {
  482.                 $bannerList $bannerService->getCommentsBanners($mobileDeviceCity::DEFAULT_CITY_ID$offerId);
  483.             }
  484.         }
  485.         if (count($bannerList) == 0) {
  486.             return $commentsHTML;
  487.         }
  488.         $session = new Session();
  489.         $sessionKey 'lastBannerIndex';
  490.         foreach ($bannerList as $position => $banners) {
  491.             $bannerHTML '';
  492.             if (count($banners) == 1) {
  493.                 $bannerHTML $banners[0];
  494.             } else {
  495.                 $lastBannerIndex $session->get($sessionKey $position0);
  496.                 $nextBannerIndex $lastBannerIndex count($banners) ? $lastBannerIndex 0;
  497.                 $bannerHTML $banners[$nextBannerIndex];
  498.                 $session->set($sessionKey $position$nextBannerIndex);
  499.             }
  500.             $commentsHTML str_replace('<span id="commentBannerPlaceHolder' . ($position 1) . '" class="hidden"></span>'$bannerHTML$commentsHTML);
  501.         }
  502.         return $commentsHTML;
  503.     }
  504.     /**
  505.      * @deprecated use CommentCacheService
  506.      */
  507.     public function resetCommentsCache($entityID$typeID) {
  508.         (new SoftCache(CommentCacheService::CACHE_NAME))->delete($typeID '-' $entityID);
  509.         (new SoftCache(CommentCacheService::MOBILE_CACHE_NAME))->delete($typeID '-' $entityID);
  510.     }
  511.     public function getParentCategoryList(Request $request$defaultCategoryID null) {
  512.         $data['siteSettings'] = $this->getSiteSettings();
  513.         $parentCategoryID $request->cookies->get('referrerCategory');
  514.         if (!$parentCategoryID) {
  515.             $parentCategoryID $defaultCategoryID;
  516.         }
  517.         if (!$parentCategoryID) {
  518.             return false;
  519.         }
  520.         $categoryRepository $this->getCategoryRepository();
  521.         $category $categoryRepository->findCached($parentCategoryID);
  522.         if (!$category) {
  523.             return false;
  524.         }
  525.         $parentCategoryList $this->getCategoryRepository()->getCategoryParentList($category['category']);
  526.         $parentCategoryList[] = $category['category'];
  527.         return $parentCategoryList;
  528.     }
  529.     protected function addVisit($entityID$entityTypeID$deviceType$user$clientIPAddress$referrer '') {
  530.         $visit = new Visit();
  531.         $visit->setEntityID($entityID);
  532.         $visit->setEntityTypeID($entityTypeID);
  533.         if($user) {
  534.             $visit->setUser($user);
  535.         }
  536.         $visit->setDeviceType($deviceType);
  537.         $visit->setReferrer($referrer);
  538.         $visit->setIPAddress($clientIPAddress);
  539.         $entityManager $this->getDoctrine()->getManager();
  540.         $entityManager->persist($visit);
  541.         $entityManager->flush($visit);
  542.     }
  543.     protected function sendPassword(Mailer $mailer$email) {
  544.         if (!$email) {
  545.             return false;
  546.         }
  547.         $user $this->getDoctrine()->getRepository(User::class)->loadUserByUsername($emailfalse);
  548.         if(!$user){
  549.             return false;
  550.         }
  551.         $securityCode rand(100000999999);
  552.         $user->setSecurityCode($securityCode);
  553.         $this->getDoctrine()->getManager()->flush();
  554.         $message $mailer->createMessage();
  555.         $message->setSubject("Восстановление пароля")
  556.             ->setFrom("info@slivki.by"'Slivki.by')
  557.             ->setTo($user->getEmail())
  558.             ->setBody(
  559.                 $this->renderView(
  560.                     'Slivki/emails/lost_password.html.twig',
  561.                     array('securityCode' => $securityCode)
  562.                 ),
  563.                 'text/html'
  564.             );
  565.         $mailer->send($message);
  566.         return true;
  567.     }
  568.     /** @deprecated  */
  569.     protected function getOfferTeaserCached(Offer $offer) {
  570.         $softCache = new SoftCache(OfferRepository::CACHE_NAME_TEASERS);
  571.         $offerTeaserCached $softCache->get($offer->getID());
  572.         if ($offerTeaserCached) {
  573.             return $offerTeaserCached;
  574.         }
  575.         $teaserHTML $this->get('twig')->render('Slivki/offers/teaser.html.twig', ['offer' => $offer]);
  576.         $softCache->set($offer->getID(), $teaserHTML24 60 60);
  577.         return $teaserHTML;
  578.     }
  579.     protected function getOfferRateSchedule(Session $session) {
  580.         $user $this->getUser();
  581.         $lastActivity $session->get(self::LAST_OFFER_RATE_ACTIVITY_PARAMETER_NAME);
  582.         if (!$user || !$user->isWantRatePopup() || ($lastActivity && time() - $lastActivity 300) ) {
  583.             return false;
  584.         }
  585.         $dql 'select schedule from Slivki:OfferRateSchedule schedule where schedule.userID = :userID and schedule.showOn < CURRENT_TIMESTAMP() order by schedule.ID ASC';
  586.         $rateSchedule $this->getDoctrine()->getManager()->createQuery($dql)->setParameter('userID'$user->getID())->getResult();
  587.         return count($rateSchedule) > $rateSchedule[0] : false;
  588.     }
  589.     protected function handleFileUpload(KernelInterface $kernel$uploadedFile$destinationPath) {
  590.         $fileSystem = new Filesystem();
  591.         $filePath $kernel->getProjectDir() . '/public' $destinationPath;
  592.         $fileName $uploadedFile->getClientOriginalName();
  593.         while ($fileSystem->exists($filePath $fileName)) {
  594.             $fileName time() . '_' $fileName;
  595.         }
  596.         $uploadedFile->move($filePath$fileName);
  597.         return $fileName;
  598.     }
  599.     public function getShareClicks($entityID) {
  600.         $sql "select month_share.network_name as network, coalesce(yesterday_click_count, 0) as yesterday, coalesce(month_click_count, 0) as month from 
  601.         (select network_name, count(id) as month_click_count from share_click 
  602.         where entity_id = $entityID and created_on::date between (CURRENT_DATE + INTERVAL '-31 day')::date and CURRENT_DATE group by network_name) as month_share 
  603.         LEFT JOIN
  604.         (select network_name, count(id) as yesterday_click_count from share_click 
  605.         where entity_id = $entityID and created_on::date = (CURRENT_DATE + INTERVAL '-1 day')::date group by network_name) as yestarday_share 
  606.         on yestarday_share.network_name = month_share.network_name";
  607.         return $this->getDoctrine()->getManager()->getConnection()->executeQuery($sql)->fetchAll();
  608.     }
  609.     public function getMainHotFeed(OfferCacheService $offerCacheServiceSaleCacheService $saleCacheService$limit null$offset 0$type HotFeed::TYPE_MAIN_PAGE$cityID null) {
  610.         $entityManager $this->getDoctrine()->getManager();
  611.         $cityCondition '';
  612.         if ($cityID 0) {
  613.             $cityCondition ' and city_id = ' $cityID;
  614.         }
  615.         $sql 'select * from hot_feed where type = ' . (int)$type $cityCondition order by created_on desc limit " . (int)$limit ' offset ' . (int)$offset;
  616.         $entityIDList $entityManager->getConnection()->executeQuery($sql)->fetchAll();
  617.         $entityList = [];
  618.         $saleRepository $entityManager->getRepository(Sale::class);
  619.         $categorySoftCache = new SoftCache(CategoryRepository::CACHE_NAME);
  620.         $categoryRepository $entityManager->getRepository(Category::class);
  621.         foreach ($entityIDList as $item) {
  622.             $entity null;
  623.             switch ($item['entity_type_id']) {
  624.                 case Category::SALE_CATEGORY_ID:
  625.                     $entity $saleCacheService->getSale($item['entity_id']);
  626.                     break;
  627.                 case Category::OFFER_CATEGORY_ID:
  628.                     $entity $offerCacheService->getOffer($item['entity_id'], true);
  629.                     break;
  630.                 case Category::CATEGORY_ID:
  631.                     $entity $categorySoftCache->get($item['entity_id']);
  632.                     $entity $entity["category"];
  633.                     break;
  634.             }
  635.             if ($entity) {
  636.                 $iconMedia $entity->getHotFeedIconMedia();
  637.                 $isVideoGuide false;
  638.                 switch ($item['entity_type_id']) {
  639.                     case Category::OFFER_CATEGORY_ID:
  640.                         $title $entity->getTitle();
  641.                         $entityUrlType SeoRepository::RESOURCE_URL_OFFER_DETAILS;
  642.                         if (!$iconMedia && $entity->getCategories()->count() > 0) {
  643.                             $categoryID $entity->getCategories()->first()->getID();
  644.                             $category $entityManager->getRepository(Category::class)->findCached($categoryID);
  645.                             if ($category) {
  646.                                 $iconMedia $category['category']->getHotFeedIconMedia();
  647.                             }
  648.                         }
  649.                         $imageMedia $entity->getTeaserMedia();
  650.                         break;
  651.                     case Category::SALE_CATEGORY_ID:
  652.                         $title $entity->getTitle();
  653.                         $entityUrlType SeoRepository::RESOURCE_URL_SALE_DETAILS;
  654.                         $isVideoGuide $entity->isInCategory(Category::SALE_VIDEO_GUIDE_CATEGORY_ID);
  655.                         if (!$iconMedia) {
  656.                             foreach ($entity->getCategories() as $category) {
  657.                                 $category $categoryRepository->findCached($category->getID());
  658.                                 if ($category) {
  659.                                     $iconMedia $category['category']->getHotFeedIconMedia();
  660.                                     if ($iconMedia) {
  661.                                         break;
  662.                                     }
  663.                                 }
  664.                             }
  665.                         }
  666.                         $imageMedia $entity->getIcon();
  667.                         break;
  668.                     case Category::CATEGORY_ID:
  669.                         $title $entity->getHotFeedName() ? $entity->getHotFeedName() : $entity->getName();
  670.                         switch ($entity->getDomainObjectID()) {
  671.                             case Category::OFFER_CATEGORY_ID:
  672.                                 $entityUrlType SeoRepository::RESOURCE_URL_OFFER_CATEGORY;
  673.                                 break;
  674.                             case Category::SALE_CATEGORY_ID:
  675.                                 $entityUrlType SeoRepository::RESOURCE_URL_OFFER_CATEGORY;
  676.                                 break;
  677.                         }
  678.                         $imageMedia $entity->getHotFeedMedia();
  679.                         break;
  680.                 }
  681.                 $createdOn = \DateTime::createFromFormat('Y-m-d H:i:s'$item['created_on']);
  682.                 $todayStart = \DateTime::createFromFormat('Y-m-d H:i:s'date('Y-m-d H:i:s'))->modify('-23 hour');
  683.                 $yesterdayStart = \DateTime::createFromFormat('Y-m-d  H:i:s'date('Y-m-d 00:00:00'))->modify('-1 day');
  684.                 $timeText $createdOn->format('d.m.y');
  685.                 if ($createdOn >= $todayStart) {
  686.                     $timeText $createdOn->format('H:i');
  687.                 } elseif ($createdOn >= $yesterdayStart) {
  688.                     $timeText "вчера";
  689.                 }
  690.                 $entityList[] = [
  691.                     'createdOn' => $createdOn,
  692.                     'title' => $title,
  693.                     'isVideoGuide' => $isVideoGuide,
  694.                     'entityUrlType' => $entityUrlType,
  695.                     'iconMedia'=> $iconMedia,
  696.                     'imageMedia' => $imageMedia,
  697.                     'timeText' => $timeText,
  698.                     'entity' => $entity
  699.                 ];
  700.             }
  701.         }
  702.         return $entityList;
  703.     }
  704.     /**
  705.      * @deprecated use CommentHelper
  706.      */
  707.     public function prepareCommentText($commentText) {
  708.         $commentText str_replace(['<div>''</div>''<br>''<br/>''<br />'], "\n"$commentText);
  709.         $commentText strip_tags($commentText'<img><a>');
  710.         return preg_replace("/[\r\n]+/""\n"$commentText);
  711.     }
  712.     public function sendOfferCommentNotice(Mailer $mailerOffer $offerComment $commentComment $parentComment null) {
  713.         if (!$comment->isConfirmedPhone()) {
  714.             return false;
  715.         }
  716.         // Send Answer To Customer Comment
  717.         if ($parentComment) {
  718.             $email $parentComment->getUser()->getEmail();
  719.             if ($email) {
  720.                 $message $mailer->createMessage();
  721.                 $message->setSubject("Отзыв на акцию")
  722.                     ->setFrom("info@slivki.by"'Slivki.by')
  723.                     ->setTo($parentComment->getUser()->getEmail())
  724.                     ->setBody(
  725.                         $this->renderView(
  726.                             'Slivki/emails/answer_to_customer_comment.html.twig',
  727.                             array('comment' => $comment)
  728.                         ),
  729.                         'text/html'
  730.                     );
  731.                 $mailer->send($message);
  732.             }
  733.         }
  734.         $directors $offer->getDirectors();
  735.         if ($directors && $directors->count() > 0  && $directors->first()->getEmail() != '') {
  736.             $message $mailer->createMessage();
  737.             $message->setSubject("Отзыв на акцию")
  738.                 ->setFrom("info@slivki.by"'Slivki.by')
  739.                 ->setTo($directors->first()->getEmail())
  740.                 ->setBody($this->renderView('Slivki/emails/comment_to_supplier.html.twig', ['comment' => $comment'offer' => $offer]), 'text/html');
  741.             $mailer->send($message);
  742.         }
  743.     }
  744.     public function getCheckAddressResponse($orderInfo) {
  745.         $message '';
  746.         switch ($orderInfo->resultState) {
  747.             case 1:
  748.                 if (isset($orderInfo->problem)) {
  749.                     $message $orderInfo->problem;
  750.                 }
  751.                 if (isset($orderInfo->minSumForFreeDelivery)) {
  752.                     $message = \sprintf('Минимальная сумма заказа %s руб.', (string) $orderInfo->minSumForFreeDelivery);
  753.                 }
  754.                 break;
  755.             case 2:
  756.                 $message 'Извините, в данное время заказ невозможен. Пожалуйста, выберите другое время';
  757.                 break;
  758.             case 3:
  759.                 $message 'Извините, на данный адрес доставка не осуществляется';
  760.                 break;
  761.             case 4:
  762.             case 5:
  763.                 $message 'На данный момент заказ одного из товаров невозможен';
  764.                 break;
  765.             case 9999:
  766.                 $message 'Заказы принимаются с 11:00 по 22:22';
  767.         }
  768.         return [
  769.             'status' => $orderInfo->resultState === 'success' 'error',
  770.             'error' => $orderInfo->resultState != 0,
  771.             'deliveryPrice' => isset($orderInfo->deliveryServiceProductInfo) ? $orderInfo->deliveryServiceProductInfo->productSum 0,
  772.             'message' => $message
  773.         ];
  774.     }
  775.     public function getOptions(
  776.         ImageService $imageService,
  777.         Offer &$offer,
  778.         AbstractDelivery $iikoUtil,
  779.         $sticksCount,
  780.         $shippingType null
  781.     ) {
  782.         $entityManager $this->getDoctrine()->getManager();
  783.         $optionRepository $entityManager->getRepository(FoodOfferOptionExtension::class);
  784.         $options = [];
  785.         $sticks $iikoUtil->getProduct($iikoUtil::STICKS_PRODUCT_ID);
  786.         $sticksID null;
  787.         if ($sticks) {
  788.             $option $optionRepository->findOneBy(['offer' => $offer'partnerItemID' => $sticks->id]);
  789.             if ($option) {
  790.                 $sticksID $sticks->id;
  791.                 $sticks->partnerID $sticks->id;
  792.                 $sticks->id $option->getID();
  793.                 $sticks->offerPrice $sticks->price;
  794.                 $sticks->regularPrice $sticks->price;
  795.                 $sticks->inBasketCount $sticksCount;
  796.                 $sticks->isSticks true;
  797.                 $sticks->isIncluded false;
  798.                 $sticks->position $option->getPosition() ?: CustomProductOfferSorter::DEFAULT_POSITION;
  799.                 $sticks->imageURL '';
  800.                 if (null !== $sticks->images && count($sticks->images) > 0) {
  801.                     if ($sticks->images[count($sticks->images) - 1] instanceof OfferExtensionMedia) {
  802.                         $sticks->imageURL $imageService->getImageURLCached($sticks->images[count($sticks->images) - 1], 5400);
  803.                     } else if ($sticks->images[count($sticks->images) - 1]) {
  804.                         $sticks->imageURL $sticks->images[count($sticks->images) - 1]->imageUrl;
  805.                     }
  806.                 }
  807.                 if ($option->isActive()) {
  808.                     $options[] = $sticks;
  809.                 }
  810.             }
  811.         }
  812.         foreach ($iikoUtil->getOptions() as $item) {
  813.             if (($sticks && $sticksID == $item->id) || (isset($item->isSticks) && $item->isSticks)) {
  814.                 continue;
  815.             }
  816.             $option $optionRepository->findOneBy(['offer' => $offer'partnerItemID' => $item->id]);
  817.             if ($option) {
  818.                 switch ($item->id) {
  819.                     case $iikoUtil::SOY_SAUCE_PRODUCT_ID:
  820.                         $item->isSoySauce true;
  821.                         $item->isIncluded false;
  822.                         break;
  823.                     case $iikoUtil::WASABI_PRODUCT_ID:
  824.                         $item->isWasabi true;
  825.                         $item->isIncluded false;
  826.                         break;
  827.                     case $iikoUtil::GINGER_PRODUCT_ID:
  828.                         $item->isGinger true;
  829.                         $item->isIncluded false;
  830.                 }
  831.                 $item->partnerID $item->id;
  832.                 $item->id $option->getID();
  833.                 $item->offerPrice $item->price;
  834.                 $item->regularPrice $item->price;
  835.                 $item->imageURL null;
  836.                 $item->itemCount = (int) $option->getComponentsCount();
  837.                 $item->weight = (double) $option->getWeight();
  838.                 $item->position $option->getPosition() ?: CustomProductOfferSorter::DEFAULT_POSITION;
  839.                 if (isset($item->images[count($item->images) - 1])) {
  840.                     if ($item->images[count($item->images) - 1] instanceof OfferExtensionMedia) {
  841.                         $item->imageURL $imageService->getImageURLCached($item->images[count($item->images) - 1], 5400);
  842.                     } else if ($item->images[count($item->images) - 1]) {
  843.                         $item->imageURL $item->images[count($item->images) - 1]->imageUrl;
  844.                     }
  845.                 }
  846.                 if ($option->isActive()) {
  847.                     if (null !== $shippingType) {
  848.                         $isShippingType 'getIs' ucfirst($shippingType);
  849.                         if ($option->{$isShippingType}()) {
  850.                             $options[] = $item;
  851.                         }
  852.                     } else {
  853.                         $options[] = $item;
  854.                     }
  855.                 }
  856.             }
  857.         }
  858.         return $options;
  859.     }
  860. }