src/Service/Stats/VisitorLogger.php line 23

Open in your IDE?
  1. <?php
  2. namespace App\Service\Stats;
  3. use App\Entity\Stats\Visitor;
  4. use Doctrine\ORM\EntityManagerInterface;
  5. use Symfony\Component\HttpFoundation\RequestStack;
  6. use Symfony\Component\Security\Core\Security;
  7. class VisitorLogger
  8. {
  9.     private $entityManager;
  10.     private $requestStack;
  11.     private $security;
  12.     public function __construct(EntityManagerInterface $entityManagerRequestStack $requestStackSecurity $security)
  13.     {
  14.         $this->entityManager $entityManager;
  15.         $this->requestStack $requestStack;
  16.         $this->security $security;
  17.     }
  18.     public function logVisit()
  19.     {
  20.         $request $this->requestStack->getCurrentRequest();
  21.         if (!$request) {
  22.             return;
  23.         }
  24.         $route $request->attributes->get('_route');
  25.         // Skip logging for certain route prefixes
  26.         if ($this->shouldSkipLogging($route) || $this->isJsonRequest($request)) {
  27.             return;
  28.         }
  29.         $ip $request->getClientIp();
  30.         $url $request->getUri();
  31.         $userAgent $request->headers->get('User-Agent');
  32.         $referrer $request->headers->get('referer');
  33.         $country $this->getCountry($ip);
  34.         $city $this->getCity($ip);
  35.         $visitor $this->entityManager->getRepository(Visitor::class)->findOneBy([
  36.             'ip' => $ip,
  37.             'route' => $route,
  38.         ]);
  39.         $currentTimestamp = new \DateTime();
  40.         if ($visitor) {
  41.             // Check if the time difference from the last visit is greater than 3 seconds
  42.             $lastVisitedAt $visitor->getLastVisitedAt();
  43.             $timeDiff $currentTimestamp->getTimestamp() - $lastVisitedAt->getTimestamp();
  44.             if ($timeDiff >= 3) {
  45.                 $visitor->setLastVisitedAt($currentTimestamp);
  46.                 $visitor->setVisits($visitor->getVisits() + 1);
  47.                 $this->entityManager->flush();
  48.             }
  49.         } else {
  50.             $visitor = new Visitor();
  51.             $visitor->setLastVisitedAt($currentTimestamp);
  52.             $visitor->setVisits(1);
  53.             $visitor->setRoute($route);
  54.             $visitor->setUrl($url);
  55.             $visitor->setReferrer($referrer);
  56.             $visitor->setIp($ip);
  57.             $visitor->setOs($this->getOS($userAgent));
  58.             $visitor->setBrowser($this->getBrowser($userAgent));
  59.             $visitor->setCountry($country);
  60.             $visitor->setCity($city);
  61.             $this->entityManager->persist($visitor);
  62.             $this->entityManager->flush();
  63.         }
  64.     }
  65.     private function shouldSkipLogging(string $route): bool
  66.     {
  67.         $excludedPrefixes = [
  68.             'api_'// Example prefix for API routes
  69.             'login'// Example prefix for API routes
  70.             '_'// Example prefix for internal routes like _wdt, _profiler, etc.
  71.             'admin'// Example prefix for admin routes
  72.         ];
  73.         foreach ($excludedPrefixes as $prefix) {
  74.             if (strpos($route$prefix) === 0) {
  75.                 return true;
  76.             }
  77.         }
  78.         return false;
  79.     }
  80.     private function isJsonRequest($request): bool
  81.     {
  82.         return str_contains($request->headers->get('Accept'), 'application/json');
  83.     }
  84.     private function getOS(string $userAgent): string
  85.     {
  86.         if (preg_match('/Linux/'$userAgent)) {
  87.             return 'Linux';
  88.         } elseif (preg_match('/Mac/i'$userAgent)) {
  89.             return 'Mac';
  90.         } elseif (preg_match('/Windows/'$userAgent)) {
  91.             return 'Windows';
  92.         } else {
  93.             return 'Unknown OS';
  94.         }
  95.     }
  96.     private function getBrowser(string $userAgent): string
  97.     {
  98.         if (preg_match('/Firefox/'$userAgent)) {
  99.             return 'Firefox';
  100.         } elseif (preg_match('/Chrome/'$userAgent)) {
  101.             return 'Chrome';
  102.         } elseif (preg_match('/Safari/'$userAgent)) {
  103.             return 'Safari';
  104.         } elseif (preg_match('/MSIE/'$userAgent)) {
  105.             return 'Internet Explorer';
  106.         } else {
  107.             return 'Unknown Browser';
  108.         }
  109.     }
  110.     private function getCountry(string $ip): string
  111.     {
  112.         return 'Unknown Country';
  113.     }
  114.     private function getCity(string $ip): string
  115.     {
  116.         return 'Unknown City';
  117.     }
  118. }