<?phpdeclare(strict_types=1);namespace Hitso\Bundle\CommonBundle\Monitor;use DirectoryIterator;use Symfony\Component\EventDispatcher\EventSubscriberInterface;use Symfony\Component\Filesystem\Filesystem;use Symfony\Component\HttpKernel\KernelEvents;class VisitManager implements EventSubscriberInterface{ /** * @var string */ protected $statPath; /** * @var bool */ protected $wasClean = true; /** * @var bool */ protected $registered = false; /** * @var bool */ protected $debug; public function __construct($statPath, $lockPath, $debug) { $this->statPath = $statPath; $this->debug = $debug; if (!is_dir($statPath)) { $fs = new Filesystem(); $fs->mkdir($statPath); } } public function logVisit($clean) { $statFile = $this->statPath . '/' . strtotime('midnight'); if (file_exists($statFile)) { $stats = unserialize(file_get_contents($statFile)); } else { $stats = []; } $hour = (int) strftime('%H'); if (!isset($stats[$hour])) { $stats[$hour] = [0, 0]; } $stats[$hour][0]++; if (!$clean) { $stats[$hour][1]++; } file_put_contents($statFile, serialize($stats)); } public function readLogs() { $day = strtotime('midnight'); $hour = (int) strftime('%H'); $results = []; $files = new DirectoryIterator($this->statPath); foreach ($files as $file) { if ($file->isFile() && is_numeric($file->getFilename()) && $file->getFilename() <= $day) { $fday = (int) $file->getFilename(); $data = @unserialize(file_get_contents($file->getPathname())); if (!is_array($data)) { continue; } foreach ($data as $fhour => $row) { if ($fday == $day && $fhour >= $hour) { break; } $stamp = $fday + ($fhour * 3600); $results[$stamp] = $row; } } } return $results; } public function clearLogs() { $day = strtotime('midnight'); $hour = (int) strftime('%H'); $files = new DirectoryIterator($this->statPath); foreach ($files as $file) { if ($file->isFile() && is_numeric($file->getFilename()) && $file->getFilename() <= $day) { $fday = $file->getFilename(); if ($fday == $day) { $data = @unserialize(file_get_contents($file->getPathname())); if (!is_array($data)) { @unlink($file->getPathname()); } else { $newData = []; foreach ($data as $fhour => $row) { if ($fhour >= $hour) { $newData[$fhour] = $row; } } file_put_contents($file->getPathname(), serialize($newData)); } } else { @unlink($file->getPathname()); } } } } public function onRequest() { if (!$this->registered && !$this->debug) { register_shutdown_function( function () { $this->logVisit($this->wasClean); } ); } $this->registered = true; } public function onException() { $this->wasClean = false; } public static function getSubscribedEvents() { return [ KernelEvents::REQUEST => ['onRequest', 512], KernelEvents::EXCEPTION => ['onException', 512], ]; }}