feat: visiteurs uniques par article (7/14/30 j) stockés dans visitors.json
- AccessLogParser : suivi des IPs non-bot uniques par /post/ sur 3 fenêtres (7/14/30 j) - index.php : écriture de data/UUID/visitors.json à chaque recalcul des stats admin - post_view.php : affichage du compteur de lecteurs dans la zone hero Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+38
-11
@@ -10,7 +10,14 @@ class AccessLogParser
|
||||
private int $cacheTtl;
|
||||
private int $days;
|
||||
/** @var list<string> */
|
||||
private array $botPatterns;
|
||||
private array $botPatterns;
|
||||
|
||||
/** @var array<string,array<string,true>> */
|
||||
private array $artIp7 = [];
|
||||
/** @var array<string,array<string,true>> */
|
||||
private array $artIp14 = [];
|
||||
/** @var array<string,array<string,true>> */
|
||||
private array $artIp30 = [];
|
||||
|
||||
private static ?array $memo = null;
|
||||
|
||||
@@ -46,7 +53,8 @@ class AccessLogParser
|
||||
* ip_top_paths:array<string,array<string,array{n:int,ts:int}>>,
|
||||
* ip_agents:array<string,list<string>>,
|
||||
* all_uas:array<string,int>,
|
||||
* unique_visitors:array<int,int>
|
||||
* unique_visitors:array<int,int>,
|
||||
* article_unique_visitors:array<string,array<int,int>>
|
||||
* }
|
||||
*/
|
||||
public function stats(): array
|
||||
@@ -151,16 +159,27 @@ class AccessLogParser
|
||||
}
|
||||
}
|
||||
|
||||
// Visiteurs uniques par article (IPs publiques non-bot, /post/ statut 200)
|
||||
$articleUv = [];
|
||||
foreach ($this->artIp30 as $path => $ips) {
|
||||
$articleUv[$path] = [
|
||||
'7' => count($this->artIp7[$path] ?? []),
|
||||
'14' => count($this->artIp14[$path] ?? []),
|
||||
'30' => count($ips),
|
||||
];
|
||||
}
|
||||
|
||||
$result = [
|
||||
'pages' => $pages,
|
||||
'books' => $books,
|
||||
'ips' => $ips,
|
||||
'pages_by_day' => $pagesByDay,
|
||||
'ips_by_day' => $ipsByDay,
|
||||
'ip_top_paths' => $ipTopPaths,
|
||||
'ip_agents' => $ipTopAgents,
|
||||
'all_uas' => array_slice($allUas, 0, 300, true),
|
||||
'unique_visitors' => $uniqueVisitors,
|
||||
'pages' => $pages,
|
||||
'books' => $books,
|
||||
'ips' => $ips,
|
||||
'pages_by_day' => $pagesByDay,
|
||||
'ips_by_day' => $ipsByDay,
|
||||
'ip_top_paths' => $ipTopPaths,
|
||||
'ip_agents' => $ipTopAgents,
|
||||
'all_uas' => array_slice($allUas, 0, 300, true),
|
||||
'unique_visitors' => $uniqueVisitors,
|
||||
'article_unique_visitors' => $articleUv,
|
||||
];
|
||||
@mkdir(dirname($this->cacheFile), 0755, true);
|
||||
@file_put_contents($this->cacheFile, json_encode($result, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
||||
@@ -290,6 +309,14 @@ class AccessLogParser
|
||||
if ($tsVal > ($ipPathTs[$ip][$path] ?? 0)) {
|
||||
$ipPathTs[$ip][$path] = $tsVal;
|
||||
}
|
||||
// Visiteurs uniques par article (IPs publiques non-bot uniquement)
|
||||
$this->artIp30[$path][$ip] = true;
|
||||
if ($dayOffset >= $this->days - 14) {
|
||||
$this->artIp14[$path][$ip] = true;
|
||||
}
|
||||
if ($dayOffset >= $this->days - 7) {
|
||||
$this->artIp7[$path][$ip] = true;
|
||||
}
|
||||
}
|
||||
} elseif (str_ends_with($path, '/') === false && str_starts_with($path, '/book/') && strlen($path) > 6) {
|
||||
$books[$path] = ($books[$path] ?? 0) + 1;
|
||||
|
||||
Reference in New Issue
Block a user