src/Component/Stats/Event/Listener/StatisticsListener.php line 45

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace BitBag\OpenMarketplace\Component\Stats\Event\Listener;
  4. use BitBag\OpenMarketplace\Component\Channel\Entity\ChannelInterface;
  5. use BitBag\OpenMarketplace\Component\Stats\Assigner\VendorToAnalyticsAssigner;
  6. use BitBag\OpenMarketplace\Component\Stats\Checker\ExcludedRoutesCheckerInterface;
  7. use BitBag\OpenMarketplace\Component\Stats\Entity\AnalyticsInterface;
  8. use BitBag\OpenMarketplace\Component\Stats\Entity\StatisticsInterface;
  9. use BitBag\OpenMarketplace\Component\Stats\Factory\AnalyticsFactoryInterface;
  10. use BitBag\OpenMarketplace\Component\Stats\Factory\CrawlerDetect\CrawlerDetectFactoryInterface;
  11. use BitBag\OpenMarketplace\Component\Stats\Factory\StatisticsFactoryInterface;
  12. use BitBag\OpenMarketplace\Component\Stats\Handler\ImpressionsStatisticsAndAnalyticsHandler;
  13. use BitBag\OpenMarketplace\Component\Stats\Repository\AnalyticsRepositoryInterface;
  14. use BitBag\OpenMarketplace\Component\Stats\Resolver\UserCountryByUserIPResolver;
  15. use Doctrine\ORM\EntityManagerInterface;
  16. use Psr\Log\LoggerInterface;
  17. use Sylius\Component\Channel\Context\ChannelContextInterface;
  18. use Symfony\Component\HttpKernel\Event\TerminateEvent;
  19. final class StatisticsListener
  20. {
  21.     private AnalyticsInterface $analytics;
  22.     private StatisticsInterface $statistics;
  23.     public function __construct(
  24.         private EntityManagerInterface $analyticsManager,
  25.         private AnalyticsRepositoryInterface $analyticsRepository,
  26.         private LoggerInterface $logger,
  27.         private ChannelContextInterface $channelContext,
  28.         private ImpressionsStatisticsAndAnalyticsHandler $impressionsStatisticsAndAnalyticsHandler,
  29.         private VendorToAnalyticsAssigner $vendorToAnalyticsAssigner,
  30.         private UserCountryByUserIPResolver $userCountryByUserIPResolver,
  31.         private ExcludedRoutesCheckerInterface $excludedRoutesChecker,
  32.         private AnalyticsFactoryInterface $analyticsFactory,
  33.         private StatisticsFactoryInterface $statisticsFactory,
  34.         private CrawlerDetectFactoryInterface $crawlerDetectFactory,
  35.         private string $excludedIps,
  36.         ) {
  37.     }
  38.     public function onKernelTerminate(TerminateEvent $event): void
  39.     {
  40.         if ($this->isCrawler()) {
  41.             return;
  42.         }
  43.         $request $event->getRequest();
  44.         $excludedIps explode(','$this->excludedIps);
  45.         if (in_array($request->getClientIp(), $excludedIps)) {
  46.             return;
  47.         }
  48.         if (!$event->isMainRequest()
  49.             || $this->excludedRoutesChecker->shouldSkipRequest($request)) {
  50.             return;
  51.         }
  52.         $route $request->attributes->get('_route');
  53.         $localeFromRequest $request->getLocale();
  54.         $url mb_substr($request->getUri(), 0254);
  55.         $this->statistics $this->statisticsFactory->createStatistics(
  56.             (string) $request->getClientIp(),
  57.             $url,
  58.             (string) $request->headers->get('referer'),
  59.             $localeFromRequest
  60.         );
  61.         /** @var AnalyticsInterface|null $existingAnalytics */
  62.         $existingAnalytics $this->analyticsRepository->findOneBy(['url' => $url]);
  63.         if (null === $existingAnalytics) {
  64.             $this->analytics $this->analyticsFactory->createAnalytics(
  65.                 $url,
  66.                 $route,
  67.                 $request->attributes->get('slug'),
  68.                 $localeFromRequest
  69.             );
  70.         } else {
  71.             $this->analytics $existingAnalytics;
  72.         }
  73.         $request $event->getRequest();
  74.         if ('sylius_shop_product_show' === $route) {
  75.             $slug $request->attributes->get('slug');
  76.             /** @var ChannelInterface $channel */
  77.             $channel $this->channelContext->getChannel();
  78.             $localeCode $localeFromRequest;
  79.             $this->vendorToAnalyticsAssigner->assignVendorToAnalyticsByProductSlug(
  80.                 $this->analytics,
  81.                 $channel,
  82.                 $localeCode,
  83.                 $slug
  84.             );
  85.         } elseif ('bitbag_sylius_elasticsearch_plugin_shop_list_products' === $route) {
  86.             $locale $request->getLocale();
  87.             $clientIp = (string) $request->getClientIp();
  88.             $this->impressionsStatisticsAndAnalyticsHandler->handleImpressionsStatisticsAndAnalytics(
  89.                 $locale,
  90.                 $clientIp
  91.             );
  92.         }
  93.         $this->statistics->setUserCountry(
  94.             $this->userCountryByUserIPResolver->getUserCountryByIP(
  95.                 (string) $request->getClientIp()
  96.             )
  97.         );
  98.         $this->persistAndFlushAnalyticsAndStatistics();
  99.     }
  100.     private function persistAndFlushAnalyticsAndStatistics(): void
  101.     {
  102.         try {
  103.             $this->statistics->setAnalytics($this->analytics);
  104.             $this->analytics->addStatistic($this->statistics);
  105.             $this->analyticsManager->persist($this->analytics);
  106.             $this->analyticsManager->flush();
  107.         } catch (\Throwable $exception) {
  108.             $this->logger->error($exception->getMessage());
  109.         }
  110.     }
  111.     private function isCrawler(): bool
  112.     {
  113.         return $this->crawlerDetectFactory->createNew()->isCrawler();
  114.     }
  115. }