src/Controller/SiteController.php line 232

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.         $message $mailer->createMessage();
  552.         $message->setSubject("Восстановление пароля")
  553.             ->setFrom("info@slivki.by"'Slivki.by')
  554.             ->setTo($user->getEmail())
  555.             ->setBody(
  556.                 $this->renderView(
  557.                     'Slivki/emails/lost_password.html.twig',
  558.                     array('password' => $user->getPasswordClear())
  559.                 ),
  560.                 'text/html'
  561.             );
  562.         $mailer->send($message);
  563.         return true;
  564.     }
  565.     /** @deprecated  */
  566.     protected function getOfferTeaserCached(Offer $offer) {
  567.         $softCache = new SoftCache(OfferRepository::CACHE_NAME_TEASERS);
  568.         $offerTeaserCached $softCache->get($offer->getID());
  569.         if ($offerTeaserCached) {
  570.             return $offerTeaserCached;
  571.         }
  572.         $teaserHTML $this->get('twig')->render('Slivki/offers/teaser.html.twig', ['offer' => $offer]);
  573.         $softCache->set($offer->getID(), $teaserHTML24 60 60);
  574.         return $teaserHTML;
  575.     }
  576.     protected function getOfferRateSchedule(Session $session) {
  577.         $user $this->getUser();
  578.         $lastActivity $session->get(self::LAST_OFFER_RATE_ACTIVITY_PARAMETER_NAME);
  579.         if (!$user || !$user->isWantRatePopup() || ($lastActivity && time() - $lastActivity 300) ) {
  580.             return false;
  581.         }
  582.         $dql 'select schedule from Slivki:OfferRateSchedule schedule where schedule.userID = :userID and schedule.showOn < CURRENT_TIMESTAMP() order by schedule.ID ASC';
  583.         $rateSchedule $this->getDoctrine()->getManager()->createQuery($dql)->setParameter('userID'$user->getID())->getResult();
  584.         return count($rateSchedule) > $rateSchedule[0] : false;
  585.     }
  586.     protected function handleFileUpload(KernelInterface $kernel$uploadedFile$destinationPath) {
  587.         $fileSystem = new Filesystem();
  588.         $filePath $kernel->getProjectDir() . '/public' $destinationPath;
  589.         $fileName $uploadedFile->getClientOriginalName();
  590.         while ($fileSystem->exists($filePath $fileName)) {
  591.             $fileName time() . '_' $fileName;
  592.         }
  593.         $uploadedFile->move($filePath$fileName);
  594.         return $fileName;
  595.     }
  596.     public function getShareClicks($entityID) {
  597.         $sql "select month_share.network_name as network, coalesce(yesterday_click_count, 0) as yesterday, coalesce(month_click_count, 0) as month from 
  598.         (select network_name, count(id) as month_click_count from share_click 
  599.         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 
  600.         LEFT JOIN
  601.         (select network_name, count(id) as yesterday_click_count from share_click 
  602.         where entity_id = $entityID and created_on::date = (CURRENT_DATE + INTERVAL '-1 day')::date group by network_name) as yestarday_share 
  603.         on yestarday_share.network_name = month_share.network_name";
  604.         return $this->getDoctrine()->getManager()->getConnection()->executeQuery($sql)->fetchAll();
  605.     }
  606.     public function getMainHotFeed(OfferCacheService $offerCacheServiceSaleCacheService $saleCacheService$limit null$offset 0$type HotFeed::TYPE_MAIN_PAGE$cityID null) {
  607.         $entityManager $this->getDoctrine()->getManager();
  608.         $cityCondition '';
  609.         if ($cityID 0) {
  610.             $cityCondition ' and city_id = ' $cityID;
  611.         }
  612.         $sql 'select * from hot_feed where type = ' . (int)$type $cityCondition order by created_on desc limit " . (int)$limit ' offset ' . (int)$offset;
  613.         $entityIDList $entityManager->getConnection()->executeQuery($sql)->fetchAll();
  614.         $entityList = [];
  615.         $saleRepository $entityManager->getRepository(Sale::class);
  616.         $categorySoftCache = new SoftCache(CategoryRepository::CACHE_NAME);
  617.         $categoryRepository $entityManager->getRepository(Category::class);
  618.         foreach ($entityIDList as $item) {
  619.             $entity null;
  620.             switch ($item['entity_type_id']) {
  621.                 case Category::SALE_CATEGORY_ID:
  622.                     $entity $saleCacheService->getSale($item['entity_id']);
  623.                     break;
  624.                 case Category::OFFER_CATEGORY_ID:
  625.                     $entity $offerCacheService->getOffer($item['entity_id'], true);
  626.                     break;
  627.                 case Category::CATEGORY_ID:
  628.                     $entity $categorySoftCache->get($item['entity_id']);
  629.                     $entity $entity["category"];
  630.                     break;
  631.             }
  632.             if ($entity) {
  633.                 $iconMedia $entity->getHotFeedIconMedia();
  634.                 $isVideoGuide false;
  635.                 switch ($item['entity_type_id']) {
  636.                     case Category::OFFER_CATEGORY_ID:
  637.                         $title $entity->getTitle();
  638.                         $entityUrlType SeoRepository::RESOURCE_URL_OFFER_DETAILS;
  639.                         if (!$iconMedia && $entity->getCategories()->count() > 0) {
  640.                             $categoryID $entity->getCategories()->first()->getID();
  641.                             $category $entityManager->getRepository(Category::class)->findCached($categoryID);
  642.                             if ($category) {
  643.                                 $iconMedia $category['category']->getHotFeedIconMedia();
  644.                             }
  645.                         }
  646.                         $imageMedia $entity->getTeaserMedia();
  647.                         break;
  648.                     case Category::SALE_CATEGORY_ID:
  649.                         $title $entity->getTitle();
  650.                         $entityUrlType SeoRepository::RESOURCE_URL_SALE_DETAILS;
  651.                         $isVideoGuide $entity->isInCategory(Category::SALE_VIDEO_GUIDE_CATEGORY_ID);
  652.                         if (!$iconMedia) {
  653.                             foreach ($entity->getCategories() as $category) {
  654.                                 $category $categoryRepository->findCached($category->getID());
  655.                                 if ($category) {
  656.                                     $iconMedia $category['category']->getHotFeedIconMedia();
  657.                                     if ($iconMedia) {
  658.                                         break;
  659.                                     }
  660.                                 }
  661.                             }
  662.                         }
  663.                         $imageMedia $entity->getIcon();
  664.                         break;
  665.                     case Category::CATEGORY_ID:
  666.                         $title $entity->getHotFeedName() ? $entity->getHotFeedName() : $entity->getName();
  667.                         switch ($entity->getDomainObjectID()) {
  668.                             case Category::OFFER_CATEGORY_ID:
  669.                                 $entityUrlType SeoRepository::RESOURCE_URL_OFFER_CATEGORY;
  670.                                 break;
  671.                             case Category::SALE_CATEGORY_ID:
  672.                                 $entityUrlType SeoRepository::RESOURCE_URL_OFFER_CATEGORY;
  673.                                 break;
  674.                         }
  675.                         $imageMedia $entity->getHotFeedMedia();
  676.                         break;
  677.                 }
  678.                 $createdOn = \DateTime::createFromFormat('Y-m-d H:i:s'$item['created_on']);
  679.                 $todayStart = \DateTime::createFromFormat('Y-m-d H:i:s'date('Y-m-d H:i:s'))->modify('-23 hour');
  680.                 $yesterdayStart = \DateTime::createFromFormat('Y-m-d  H:i:s'date('Y-m-d 00:00:00'))->modify('-1 day');
  681.                 $timeText $createdOn->format('d.m.y');
  682.                 if ($createdOn >= $todayStart) {
  683.                     $timeText $createdOn->format('H:i');
  684.                 } elseif ($createdOn >= $yesterdayStart) {
  685.                     $timeText "вчера";
  686.                 }
  687.                 $entityList[] = [
  688.                     'createdOn' => $createdOn,
  689.                     'title' => $title,
  690.                     'isVideoGuide' => $isVideoGuide,
  691.                     'entityUrlType' => $entityUrlType,
  692.                     'iconMedia'=> $iconMedia,
  693.                     'imageMedia' => $imageMedia,
  694.                     'timeText' => $timeText,
  695.                     'entity' => $entity
  696.                 ];
  697.             }
  698.         }
  699.         return $entityList;
  700.     }
  701.     /**
  702.      * @deprecated use CommentHelper
  703.      */
  704.     public function prepareCommentText($commentText) {
  705.         $commentText str_replace(['<div>''</div>''<br>''<br/>''<br />'], "\n"$commentText);
  706.         $commentText strip_tags($commentText'<img><a>');
  707.         return preg_replace("/[\r\n]+/""\n"$commentText);
  708.     }
  709.     public function sendOfferCommentNotice(Mailer $mailerOffer $offerComment $commentComment $parentComment null) {
  710.         if (!$comment->isConfirmedPhone()) {
  711.             return false;
  712.         }
  713.         // Send Answer To Customer Comment
  714.         if ($parentComment) {
  715.             $email $parentComment->getUser()->getEmail();
  716.             if ($email) {
  717.                 $message $mailer->createMessage();
  718.                 $message->setSubject("Отзыв на акцию")
  719.                     ->setFrom("info@slivki.by"'Slivki.by')
  720.                     ->setTo($parentComment->getUser()->getEmail())
  721.                     ->setBody(
  722.                         $this->renderView(
  723.                             'Slivki/emails/answer_to_customer_comment.html.twig',
  724.                             array('comment' => $comment)
  725.                         ),
  726.                         'text/html'
  727.                     );
  728.                 $mailer->send($message);
  729.             }
  730.         }
  731.         $directors $offer->getDirectors();
  732.         if ($directors && $directors->count() > 0  && $directors->first()->getEmail() != '') {
  733.             $message $mailer->createMessage();
  734.             $message->setSubject("Отзыв на акцию")
  735.                 ->setFrom("info@slivki.by"'Slivki.by')
  736.                 ->setTo($directors->first()->getEmail())
  737.                 ->setBody($this->renderView('Slivki/emails/comment_to_supplier.html.twig', ['comment' => $comment'offer' => $offer]), 'text/html');
  738.             $mailer->send($message);
  739.         }
  740.     }
  741.     public function getCheckAddressResponse($orderInfo) {
  742.         $message '';
  743.         switch ($orderInfo->resultState) {
  744.             case 1:
  745.                 if (isset($orderInfo->problem)) {
  746.                     $message $orderInfo->problem;
  747.                 }
  748.                 if (isset($orderInfo->minSumForFreeDelivery)) {
  749.                     $message = \sprintf('Минимальная сумма заказа %s руб.', (string) $orderInfo->minSumForFreeDelivery);
  750.                 }
  751.                 break;
  752.             case 2:
  753.                 $message 'Извините, в данное время заказ невозможен. Пожалуйста, выберите другое время';
  754.                 break;
  755.             case 3:
  756.                 $message 'Извините, на данный адрес доставка не осуществляется';
  757.                 break;
  758.             case 4:
  759.             case 5:
  760.                 $message 'На данный момент заказ одного из товаров невозможен';
  761.                 break;
  762.             case 9999:
  763.                 $message 'Заказы принимаются с 11:00 по 22:22';
  764.         }
  765.         return [
  766.             'status' => $orderInfo->resultState === 'success' 'error',
  767.             'error' => $orderInfo->resultState != 0,
  768.             'deliveryPrice' => isset($orderInfo->deliveryServiceProductInfo) ? $orderInfo->deliveryServiceProductInfo->productSum 0,
  769.             'message' => $message
  770.         ];
  771.     }
  772.     public function getOptions(
  773.         ImageService $imageService,
  774.         Offer &$offer,
  775.         AbstractDelivery $iikoUtil,
  776.         $sticksCount,
  777.         $shippingType null
  778.     ) {
  779.         $entityManager $this->getDoctrine()->getManager();
  780.         $optionRepository $entityManager->getRepository(FoodOfferOptionExtension::class);
  781.         $options = [];
  782.         $sticks $iikoUtil->getProduct($iikoUtil::STICKS_PRODUCT_ID);
  783.         $sticksID null;
  784.         if ($sticks) {
  785.             $option $optionRepository->findOneBy(['offer' => $offer'partnerItemID' => $sticks->id]);
  786.             if ($option) {
  787.                 $sticksID $sticks->id;
  788.                 $sticks->partnerID $sticks->id;
  789.                 $sticks->id $option->getID();
  790.                 $sticks->offerPrice $sticks->price;
  791.                 $sticks->regularPrice $sticks->price;
  792.                 $sticks->inBasketCount $sticksCount;
  793.                 $sticks->isSticks true;
  794.                 $sticks->isIncluded false;
  795.                 $sticks->position $option->getPosition() ?: CustomProductOfferSorter::DEFAULT_POSITION;
  796.                 $sticks->imageURL '';
  797.                 if (null !== $sticks->images && count($sticks->images) > 0) {
  798.                     if ($sticks->images[count($sticks->images) - 1] instanceof OfferExtensionMedia) {
  799.                         $sticks->imageURL $imageService->getImageURLCached($sticks->images[count($sticks->images) - 1], 5400);
  800.                     } else if ($sticks->images[count($sticks->images) - 1]) {
  801.                         $sticks->imageURL $sticks->images[count($sticks->images) - 1]->imageUrl;
  802.                     }
  803.                 }
  804.                 if ($option->isActive()) {
  805.                     $options[] = $sticks;
  806.                 }
  807.             }
  808.         }
  809.         foreach ($iikoUtil->getOptions() as $item) {
  810.             if (($sticks && $sticksID == $item->id) || (isset($item->isSticks) && $item->isSticks)) {
  811.                 continue;
  812.             }
  813.             $option $optionRepository->findOneBy(['offer' => $offer'partnerItemID' => $item->id]);
  814.             if ($option) {
  815.                 switch ($item->id) {
  816.                     case $iikoUtil::SOY_SAUCE_PRODUCT_ID:
  817.                         $item->isSoySauce true;
  818.                         $item->isIncluded false;
  819.                         break;
  820.                     case $iikoUtil::WASABI_PRODUCT_ID:
  821.                         $item->isWasabi true;
  822.                         $item->isIncluded false;
  823.                         break;
  824.                     case $iikoUtil::GINGER_PRODUCT_ID:
  825.                         $item->isGinger true;
  826.                         $item->isIncluded false;
  827.                 }
  828.                 $item->partnerID $item->id;
  829.                 $item->id $option->getID();
  830.                 $item->offerPrice $item->price;
  831.                 $item->regularPrice $item->price;
  832.                 $item->imageURL null;
  833.                 $item->itemCount = (int) $option->getComponentsCount();
  834.                 $item->weight = (double) $option->getWeight();
  835.                 $item->position $option->getPosition() ?: CustomProductOfferSorter::DEFAULT_POSITION;
  836.                 if (isset($item->images[count($item->images) - 1])) {
  837.                     if ($item->images[count($item->images) - 1] instanceof OfferExtensionMedia) {
  838.                         $item->imageURL $imageService->getImageURLCached($item->images[count($item->images) - 1], 5400);
  839.                     } else if ($item->images[count($item->images) - 1]) {
  840.                         $item->imageURL $item->images[count($item->images) - 1]->imageUrl;
  841.                     }
  842.                 }
  843.                 if ($option->isActive()) {
  844.                     if (null !== $shippingType) {
  845.                         $isShippingType 'getIs' ucfirst($shippingType);
  846.                         if ($option->{$isShippingType}()) {
  847.                             $options[] = $item;
  848.                         }
  849.                     } else {
  850.                         $options[] = $item;
  851.                     }
  852.                 }
  853.             }
  854.         }
  855.         return $options;
  856.     }
  857. }