<?php
declare(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],
];
}
}