src/EventListener/UserStatsListener.php line 85

  1. <?php
  2. namespace App\EventListener;
  3. use App\Entity\User;
  4. use App\Entity\UserStats;
  5. use App\Event\BookingCompleteEvent;
  6. use App\Event\OrderCompleteEvent;
  7. use App\Services\IPGeolocator;
  8. use Doctrine\Common\Persistence\ObjectManager;
  9. use Doctrine\ORM\EntityManager;
  10. use Psr\Log\LoggerInterface;
  11. use Ramsey\Uuid\Uuid;
  12. use Doctrine\ORM\EntityManagerInterface;
  13. use Symfony\Component\HttpFoundation\Request;
  14. use Symfony\Component\HttpFoundation\Session\Session;
  15. use Symfony\Component\HttpKernel\Event\KernelEvent;
  16. // use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
  17. use Symfony\Component\Security\Core\Authentication\Token\Storage\UsageTrackingTokenStorage;
  18. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  19. class UserStatsListener
  20. {
  21.     /**
  22.      * @var EntityManager $em
  23.      */
  24.     protected $em;
  25.     /**
  26.      * @var Session $session
  27.      */
  28.     protected $session;
  29.     /**
  30.      * @var IPGeolocator $locator
  31.      */
  32.     protected $locator;
  33.     /**
  34.      * @var User $user
  35.      */
  36.     protected $user;
  37.     /**
  38.      * @var LoggerInterface
  39.      */
  40.     protected $logger;
  41.     /**
  42.      * UserStatsListener constructor.
  43.      * @param Session $session
  44.      * @param ObjectManager $em
  45.      * @param IPGeolocator $locator
  46.      * @param TokenStorage $storage
  47.      * @param LoggerInterface $logger
  48.      */
  49.     public function __construct(Session $sessionEntityManagerInterface $emIPGeolocator $locatorUsageTrackingTokenStorage $storageLoggerInterface $logger)
  50.     {
  51.         $this->em $em;
  52.         $this->session $session;
  53.         $this->locator $locator;
  54.         $this->user null;
  55.         $this->logger $logger;
  56.         if (!is_null($token $storage->getToken())) {
  57.             $this->user $storage->getToken()->getUser();
  58.         }
  59.     }
  60.     /**
  61.      * @param Request $request
  62.      * @return mixed
  63.      */
  64.     protected function getPage(Request $request)
  65.     {
  66.         return str_replace('app_dev.php'''$request->getRequestUri());
  67.     }
  68.     /**
  69.      * @param $sessionId
  70.      * @param $uuid
  71.      * @return UserStats|null
  72.      */
  73.     protected function findUserStats($sessionId$uuid)
  74.     {
  75.         return $this->em->getRepository(UserStats::class)->findOneBySessionIdOrUuid($sessionId$uuid);
  76.     }
  77.     /**
  78.      * @param Request $request
  79.      * @param string $sessionId
  80.      * @param string $uuid
  81.      * @return UserStats
  82.      */
  83.     protected function createUserStats(Request $request$sessionId$uuid)
  84.     {
  85.         $userStats = new UserStats();
  86.         $userStats->setSessionId($sessionId);
  87.         $userStats->setIp($request->getClientIp());
  88.         $userStats->setDevice($request->headers->get('USER-AGENT'));
  89.         $userStats->setReferer($request->headers->get('referer'));
  90.         $userStats->setUuid($uuid);
  91.         /**
  92.          * GeoLocation
  93.          */
  94.         $location $this->locator->geoLocate($request->getClientIp());
  95.         if (is_array($location)) {
  96.             $userStats->setLocation($location);
  97.         }
  98.         return $userStats;
  99.     }
  100.     /**
  101.      * @return string
  102.      */
  103.     protected function getSessionUuid()
  104.     {
  105.         if (!$this->session->has('uuid')) {
  106.             $this->session->set('uuid'Uuid::uuid4());
  107.         }
  108.         return $this->session->get('uuid');
  109.     }
  110.     /**
  111.      * Should we track the request?
  112.      * @param KernelEvent $event
  113.      * @return bool
  114.      */
  115.     protected function isValidRequest(KernelEvent $event)
  116.     {
  117.         $request $event->getRequest();
  118.         /**
  119.          * List of not traceable requests
  120.          */
  121.         if (!$event->isMainRequest() || //SubRequest
  122.             $request->isXmlHttpRequest() || //Ajax
  123.             strpos($request->attributes->get('_route'), 'assetic') !== false || //Assetic
  124.             strpos('/_'$request->getRequestUri()) !== false //Hidden url
  125.         ) {
  126.             return false;
  127.         }
  128.         return true;
  129.     }
  130.     /**
  131.      * @param KernelEvent $event
  132.      * @return bool
  133.      */
  134.     public function onKernelRequest(KernelEvent $event)
  135.     {
  136.         try {
  137.             if ($this->isValidRequest($event)) {
  138.                 $request $event->getRequest();
  139.                 if ($sessionId $this->session->getId()) {
  140.                     $uuid $this->getSessionUuid();
  141.                     if (!$userStats $this->findUserStats($sessionId$uuid)) {
  142.                         $userStats $this->createUserStats($request$sessionId$uuid);
  143.                     }
  144.                     $userStats->setLastUpdate(new \DateTime());
  145.                     $userStats->addVisitedPage($this->getPage($request));
  146.                     $userStats->setUser($this->user);
  147.                     $userStats->setLocale($request->getLocale());
  148.                     $this->em->persist($userStats);
  149.                     $this->em->flush();
  150.                 }
  151.                 return true;
  152.             }
  153.             return false;
  154.         } catch (\Exception $e) {
  155.             $this->logger->error('ERROR TRAKING STATS FROM THE USER : ' $e->getMessage() . "[{$e->getTraceAsString()}]");
  156.         }
  157.         return false;
  158.     }
  159.     /**
  160.      * @param OrderCompleteEvent $event
  161.      */
  162.     public function onOrderComplete(OrderCompleteEvent $event)
  163.     {
  164.         $order $event->getOrder();
  165.         $request $event->getRequest();
  166.         if ($sessionId $this->session->getId()) {
  167.             $uuid $this->getSessionUuid();
  168.             if (!$userStats $this->findUserStats($sessionId$uuid)) {
  169.                 $this->createUserStats($request$sessionId$uuid);
  170.             }
  171.             $userStats->addOrderConversion($order);
  172.             $this->em->persist($userStats);
  173.             $this->em->flush();
  174.         }
  175.     }
  176.     /**
  177.      * @param BookingCompleteEvent $event
  178.      */
  179.     public function onBookingComplete(BookingCompleteEvent $event)
  180.     {
  181.         $booking $event->getBooking();
  182.         $request $event->getRequest();
  183.         if ($sessionId $this->session->getId()) {
  184.             $uuid $this->getSessionUuid();
  185.             if (!$userStats $this->findUserStats($sessionId$uuid)) {
  186.                 $this->createUserStats($request$sessionId$uuid);
  187.             }
  188.             $userStats->addBookingConversion($booking);
  189.             $this->em->persist($userStats);
  190.             $this->em->flush();
  191.         }
  192.     }
  193. }