src/Hitso/Bundle/CommonBundle/Repository/VisitLogRepository.php line 19

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace Hitso\Bundle\CommonBundle\Repository;
  4. use Hitso\Bundle\CommonBundle\Doctrine\Repository\EntityRepository;
  5. use Hitso\Bundle\CommonBundle\Entity\VisitLog;
  6. use Symfony\Bridge\Doctrine\RegistryInterface;
  7. use Webmozart\Assert\Assert;
  8. class VisitLogRepository extends EntityRepository
  9. {
  10.     public function __construct(RegistryInterface $registrystring $className VisitLog::class)
  11.     {
  12.         parent::__construct($registry$className);
  13.     }
  14.     public function logVisit(string $visitor): void
  15.     {
  16.         Assert::true(
  17.             in_array($visitor, [VisitLog::TYPE_GOOGLEVisitLog::TYPE_MONITORVisitLog::TYPE_HITSO_MONITORING]),
  18.             'Invalid visitor'
  19.         );
  20.         $log = new VisitLog();
  21.         $log->setVisitor($visitor);
  22.         $this->_em->persist($log);
  23.         $this->_em->flush();
  24.         $this->deleteLogs(new \DateTime('-3 days'));
  25.     }
  26.     /**
  27.      * @param $visitor
  28.      *
  29.      * @return bool|\DateTime
  30.      */
  31.     public function getLastTime($visitor)
  32.     {
  33.         /** @var VisitLog $entity */
  34.         $entity $this->findOneBy(['visitor' => $visitor], ['createdAt' => 'DESC']);
  35.         return $entity $entity->getCreatedAt() : false;
  36.     }
  37.     /**
  38.      * @param     $visitor
  39.      * @param int $days
  40.      * @param int $samples
  41.      *
  42.      * @return array
  43.      */
  44.     public function getChartData($visitor$days 3$samples 4)
  45.     {
  46.         $sampleSize 86400 $samples;
  47.         $midnight   strtotime('midnight');
  48.         $todaySamples = (int) floor((time() - $midnight) / $sampleSize);
  49.         $endOfLast    $todaySamples $sampleSize $midnight;
  50.         $startOfFirst $endOfLast - ($days 86400);
  51.         $qb $this->createQueryBuilder('v');
  52.         $qb->select()
  53.             ->where($qb->expr()->eq('v.visitor'$qb->expr()->literal($visitor)))
  54.             ->andWhere($qb->expr()->gte('v.createdAt'':start'))
  55.             ->andWhere($qb->expr()->lte('v.createdAt'':end'))
  56.             ->orderBy('v.createdAt''ASC');
  57.         $startDate = new \DateTime('@' $startOfFirst);
  58.         $endDate   = new \DateTime('@' $endOfLast);
  59.         $tz = new \DateTimeZone(date_default_timezone_get());
  60.         $startDate->setTimezone($tz);
  61.         $endDate->setTimezone($tz);
  62.         /** @var VisitLog[] $logs */
  63.         $logs $qb->getQuery()->execute(
  64.             [
  65.                 'start' => $startDate,
  66.                 'end'   => $endDate,
  67.             ]
  68.         );
  69.         $start $startOfFirst;
  70.         $end   $startOfFirst $sampleSize;
  71.         $keys range($startOfFirst$endOfLast 1$sampleSize);
  72.         $data array_combine($keysarray_fill(0count($keys), 0));
  73.         foreach ($logs as $log) {
  74.             $stamp $log->getCreatedAt()->getTimestamp();
  75.             while ($stamp $end) {
  76.                 $start += $sampleSize;
  77.                 $end   += $sampleSize;
  78.             }
  79.             ++$data[$start];
  80.         }
  81.         $results = [];
  82.         foreach ($data as $start => $count) {
  83.             $label           sprintf('%s-%s'date('Y-m-d H:i'$start), date('H:i'$start $sampleSize 1));
  84.             $results[$label] = $count;
  85.         }
  86.         return $results;
  87.     }
  88.     private function deleteLogs(\DateTime $before): void
  89.     {
  90.         if (random_int(110) > 3) {
  91.             return;
  92.         }
  93.         $qb $this->createQueryBuilder('v');
  94.         $qb->delete()
  95.             ->andWhere('v.createdAt < :limit')
  96.             ->setParameter('limit'$before)
  97.             ->getQuery()
  98.             ->execute();
  99.     }
  100. }