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

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.         $parsedUrl parse_url($request->getUri());
  55.         $scheme = isset($parsedUrl['scheme']) ? $parsedUrl['scheme'] . '://' '';
  56.         $host preg_replace('/^www\./'''$parsedUrl['host'] ?? '');
  57.         $port = isset($parsedUrl['port']) ? ':' $parsedUrl['port'] : '';
  58.         $path $parsedUrl['path'] ?? '';
  59.         $mainUrl $scheme $host $port $path;
  60.         $url mb_substr($mainUrl0254);
  61.         $this->statistics $this->statisticsFactory->createStatistics(
  62.             (string) $request->getClientIp(),
  63.             $url,
  64.             (string) $request->headers->get('referer'),
  65.             $localeFromRequest
  66.         );
  67.         /** @var AnalyticsInterface|null $existingAnalytics */
  68.         $existingAnalytics $this->analyticsRepository->findOneByUrlAndLocale($url$localeFromRequest);
  69.         if (null === $existingAnalytics) {
  70.             $this->analytics $this->analyticsFactory->createAnalytics(
  71.                 $url,
  72.                 $route,
  73.                 $request->attributes->get('slug'),
  74.                 $localeFromRequest
  75.             );
  76.         } else {
  77.             $this->analytics $existingAnalytics;
  78.         }
  79.         $request $event->getRequest();
  80.         if ('sylius_shop_product_show' === $route) {
  81.             $slug $request->attributes->get('slug');
  82.             /** @var ChannelInterface $channel */
  83.             $channel $this->channelContext->getChannel();
  84.             $localeCode $localeFromRequest;
  85.             $this->vendorToAnalyticsAssigner->assignVendorToAnalyticsByProductSlug(
  86.                 $this->analytics,
  87.                 $channel,
  88.                 $localeCode,
  89.                 $slug
  90.             );
  91.         } elseif ('bitbag_sylius_elasticsearch_plugin_shop_list_products' === $route) {
  92.             $locale $request->getLocale();
  93.             $clientIp = (string) $request->getClientIp();
  94.             $this->impressionsStatisticsAndAnalyticsHandler->handleImpressionsStatisticsAndAnalytics(
  95.                 $locale,
  96.                 $clientIp
  97.             );
  98.         }
  99.         $this->statistics->setUserCountry(
  100.             $this->userCountryByUserIPResolver->getUserCountryByIP(
  101.                 (string) $request->getClientIp()
  102.             )
  103.         );
  104.         $this->persistAndFlushAnalyticsAndStatistics();
  105.     }
  106.     private function persistAndFlushAnalyticsAndStatistics(): void
  107.     {
  108.         try {
  109.             $this->statistics->setAnalytics($this->analytics);
  110.             $this->analytics->addStatistic($this->statistics);
  111.             $this->analyticsManager->persist($this->analytics);
  112.             $this->analyticsManager->flush();
  113.         } catch (\Throwable $exception) {
  114.             $this->logger->error($exception->getMessage());
  115.         }
  116.     }
  117.     private function isCrawler(): bool
  118.     {
  119.         return $this->crawlerDetectFactory->createNew()->isCrawler();
  120.     }
  121. }