- <?php
- namespace Slivki\EventSubscriber;
- use Doctrine\ORM\EntityManagerInterface;
- use Slivki\Controller\SiteController;
- use Slivki\Entity\MailingCampaign;
- use Slivki\Entity\MailingStatistic;
- use Slivki\Entity\Seo;
- use Slivki\Entity\User;
- use Slivki\Enum\Order\Domain;
- use Slivki\Services\City\CityCacheService;
- use Slivki\Services\City\CityProvider;
- use Slivki\Services\MailingCampaign\Partner\PartnerMailingCampaignClickHandler;
- use Slivki\Util\CommonUtil;
- use Slivki\Entity\City;
- use Slivki\Util\Iiko\BurgerKing;
- use Slivki\Util\Iiko\Crabs;
- use Slivki\Util\Iiko\DinnerBuffet;
- use Slivki\Util\Iiko\Dodo;
- use Slivki\Util\Iiko\Dominos;
- use Slivki\Util\Iiko\PirogiBy;
- use Slivki\Util\Iiko\Pirogovaya1;
- use Slivki\Util\Iiko\Shtolle;
- use Slivki\Util\Iiko\SushiChefArts;
- use Slivki\Util\Iiko\SushiVesla;
- use Slivki\Util\Iiko\Urbanfood;
- use Slivki\Util\Iiko\WokiToki;
- use Slivki\Util\SoftCache;
- use Symfony\Component\EventDispatcher\EventSubscriberInterface;
- use Symfony\Component\HttpFoundation\Cookie;
- use Symfony\Component\HttpFoundation\RedirectResponse;
- use Symfony\Component\HttpFoundation\Request;
- use Symfony\Component\HttpFoundation\Response;
- use Symfony\Component\HttpKernel\Event\RequestEvent;
- use Symfony\Component\HttpKernel\Event\ResponseEvent;
- use Symfony\Component\HttpKernel\KernelEvents;
- final class KernelControllerSubscriber implements EventSubscriberInterface
- {
-     private const PATTERNS_FOR_NOT_REDIRECT = [
-         'delivery',
-         'gift-certificate',
-         'login',
-         'api/online-order/',
-     ];
-     private array $allowedSubdomains = [
-         'tokiny',
-         'sushihouse',
-         'm',
-         'marketplace',
-         'okpirog',
-         SushiChefArts::DOMAIN,
-         'citysushi',
-         'tuna',
-         'fsushi',
-         'moresushi',
-         '73',
-         WokiToki::DOMAIN,
-         DinnerBuffet::DOMAIN,
-         Dominos::DOMAIN,
-         'sushi-master',
-         'mp',
-         PirogiBy::DOMAIN,
-         Pirogovaya1::DOMAIN,
-         BurgerKing::DOMAIN,
-         Crabs::DOMAIN,
-         'deka',
-         Shtolle::DOMAIN,
-         Dodo::DOMAIN,
-         'whitelotus',
-         'marsel',
-         'shah',
-         'avokado',
-         'express-pizza',
-         'heropark',
-         'thesushi',
-         SushiVesla::DOMAIN,
-         Urbanfood::DOMAIN,
-         'profisushi',
-         'artsushi',
-         'byrolls',
-         'ajia',
-         'jasmin',
-         'ustrica',
-         'pastadeli',
-         Domain::OUSHEN,
-         'sea',
-         'wineseafood',
-         'izumi',
-         'delyga',
-         'zhanchay',
-         'sushimaster',
-         Domain::TOKIO_SUSHI,
-         Domain::MEGASUN,
-         'lotosart',
-     ];
-     private array $placeHolderDomains = [];
-     private $baseDomain;
-     private EntityManagerInterface $entityManager;
-     private CityCacheService $cityCacheService;
-     private PartnerMailingCampaignClickHandler $partnerMailingCampaignClickHandler;
-     private CityProvider $cityProvider;
-     public function __construct(
-         EntityManagerInterface $entityManager,
-         CityCacheService $cityCacheService,
-         PartnerMailingCampaignClickHandler $partnerMailingCampaignClickHandler,
-         CityProvider $cityProvider,
-         string $baseDomain
-     ) {
-         $this->baseDomain = $baseDomain;
-         $this->entityManager = $entityManager;
-         $this->cityCacheService = $cityCacheService;
-         $this->partnerMailingCampaignClickHandler = $partnerMailingCampaignClickHandler;
-         $this->cityProvider = $cityProvider;
-     }
-     public static function getSubscribedEvents(): array
-     {
-         return [
-             KernelEvents::REQUEST => ['onKernelRequest', 33],
-             KernelEvents::RESPONSE => ['onKernelResponse', 33]
-         ];
-     }
-     public function onKernelRequest(RequestEvent $event): void
-     {
-         if (!$event->isMainRequest()) {
-             return;
-         }
-         $request = $event->getRequest();
-         $pathInfo = $request->getPathInfo();
-         $hostExploded = explode('.', $request->getHost());
-         $subDomain = $hostExploded[0];
-         if ($subDomain === 'delyga') {
-             return;
-         }
-         if (\in_array($subDomain, $this->allowedSubdomains, true) && !$this->isIncludedToRoute($pathInfo)) {
-             $event->setResponse(new RedirectResponse(
-                 \sprintf(
-                     'https://%s%s%s',
-                     $request->getSession()->get(City::CITY_DOMAIN_SESSION_KEY, 'www'),
-                     $this->baseDomain,
-                     $pathInfo,
-                 ),
-                 Response::HTTP_TEMPORARY_REDIRECT,
-             ));
-             return;
-         }
-         $cityID = $this->cityProvider->getDefaultCityId();
-         $request->getSession()->set(City::CITY_ID_SESSION_KEY, $cityID);
-         if (!in_array($subDomain, $this->allowedSubdomains, true)) {
-             if ('' !== $subDomain && 'www' !== $subDomain) {
-                 $subDomainCityId = $this->cityCacheService->getCityIdByDomain($subDomain);
-                 if (null === $subDomainCityId) {
-                     $event->setResponse(new RedirectResponse($this->baseDomain . $pathInfo, 302));
-                 } else {
-                     $cityID = $subDomainCityId;
-                 }
-             }
-             $request->getSession()->set(City::CITY_ID_SESSION_KEY, $cityID);
-             $request->getSession()->set(City::CITY_DOMAIN_SESSION_KEY, $subDomain);
-             if (City::DEFAULT_CITY_ID === $cityID && 'www' !== $subDomain) {
-                 $event->setResponse(new RedirectResponse('https://www' . $this->baseDomain, 301));
-                 return;
-             }
-         }
-         $this->saveMailingStatistic($request);
-         $this->partnerMailingCampaignClickHandler->handle($request);
-         $seoRepository = $this->entityManager->getRepository(Seo::class);
-         $metaInfo = $seoRepository->getByAlias($pathInfo, $subDomain, $this->baseDomain);
-         if (isset($this->placeHolderDomains[$subDomain])) {
-             $request->attributes->set('_controller', "Slivki\\Controller\\DefaultController::domainPlaceHolderAction");
-             $request->attributes->set("entityID", $this->placeHolderDomains[$subDomain]);
-             return;
-         }
-         if ($metaInfo && $metaInfo != SoftCache::EMPTY_VALUE) {
-             $exploded = explode(':', $metaInfo->getResourceURL());
-             $url = "Slivki\\Controller\\" . $exploded[1] . "Controller::" . $exploded[2] . 'Action';
-             $request->attributes->set('_controller', $url);
-             $request->attributes->set("entityID", $metaInfo->getEntityID());
-             $request->attributes->set(SiteController::PARAMETER_META_INFO, $metaInfo);
-             if (!$metaInfo->isActive() && !in_array($subDomain, $this->allowedSubdomains)) {
-                 $redirectURL = $metaInfo->getRedirectURL();;
-                 if ($request->query->count()) {
-                     $parameters = [];
-                     foreach ($request->query->all() as $key => $value) {
-                         $parameters[] = $key . '=' . $value;
-                     }
-                     $redirectURL .= '?' . implode('&', $parameters);
-                 }
-                 $event->setResponse(new RedirectResponse($redirectURL, 301));
-             }
-         }
-     }
-     public function onKernelResponse(ResponseEvent $event) {
-         $refID = $event->getRequest()->query->get('ref');
-         if ($refID) {
-             $cookie = Cookie::create('refID', $refID, new \DateTime('+1 month'));
-             $event->getResponse()->headers->setCookie($cookie);
-         }
-     }
-     private function saveMailingStatistic(Request $request) {
-         $query = $request->query;
-         $mailingCampaignID = $query->getInt('utm_campaign');
-         $userID = $query->getInt('utm_b');
-         $entityID = $query->getInt('utm_c');
-         $entityType = $query->getInt('utm_d');
-         $entityManager = $this->entityManager;
-         // Рассылка с бонусом для Могилева
-         if ($mailingCampaignID == 1041 && $userID) {
-             $user = $entityManager->find(User::class, $userID);
-             if (!$user) {
-                 return;
-             }
-             if ($entityManager->getRepository(User::class)->setMogilevMailingBonus($user)) {
-                 $request->getSession()->getFlashBag()->add('showMogilevMailingBonusPopup', '1');
-             }
-             return;
-         }
-         // Рассылка с бонусом для Гомеля
-         if ($mailingCampaignID == 1042 && $userID) {
-             $user = $entityManager->find(User::class, $userID);
-             if (!$user) {
-                 return;
-             }
-             if ($entityManager->getRepository(User::class)->setGomelMailingBonus($user)) {
-                 $request->getSession()->getFlashBag()->add('showMogilevMailingBonusPopup', '1');
-             }
-             return;
-         }
-         if (!$mailingCampaignID || !$entityType || !$entityID) {
-             return;
-         }
-         $mailingCampaign = $entityManager->find(MailingCampaign::class, $mailingCampaignID);
-         if (!$mailingCampaign) {
-             return;
-         }
-         $mailingStatistic = new MailingStatistic();
-         $mailingStatistic->setMobileVersion(CommonUtil::isMobileDevice($request));
-         $user = null;
-         if ($userID) {
-             $user = $entityManager->find(User::class, $userID);
-             if ($user) {
-                 $mailingStatistic->setUser($user);
-             }
-         }
-         $mailingStatistic->setIpAddress($request->getClientIp());
-         $mailingStatistic->setMailingCampaign($mailingCampaign);
-         $mailingStatistic->setEntityID($entityID);
-         $mailingStatistic->setEntityType($entityType);
-         $entityManager->persist($mailingStatistic);
-         $entityManager->flush();
-     }
-     private function isIncludedToRoute(string $pathInfo): bool
-     {
-         $matches = \array_filter(
-             self::PATTERNS_FOR_NOT_REDIRECT,
-             static fn(string $needle): bool => false !== strpos($pathInfo, $needle),
-         );
-         return 0 < \count($matches);
-     }
- }
-