La Pages IIFE n'avait pas accès à ipData (défini seulement dans la Country IIFE).
Le ReferenceError faisait tomber le fetch dans le catch → 'Impossible de charger le flux'.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Fix array_merge → + pour préserver clés 7/14/30 dans visitors.json
- Bouton ✕ exclusion AS sorti du div 9rem + stopPropagation
- Handler délégué unique (removeEventListener avant de rajouter)
- Graphique trend : visiteurs uniques/jour depuis ip_data (top 200)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Carte visiteurs uniques non-bot : 7 / 14 / 30 jours en tête de /admin/stats
- Bouton ✕ par AS pour l'exclure des stats ; section AS exclus avec ↺
- Alerte IPs sans résolution AS dans la carte pays
- Parser : fenêtre 30 jours, calcul visiteurs uniques toutes IPs non-bot
- Graphiques adaptés à 30 jours (labels x/3)
- Réactions articles : 👍 uniquement (suppression 🔥 et 🤔)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Agents détectés : UA affiché sans troncature (drill-down et liste)
- Bouton « + bot » pour ajouter un agent aux patterns via AJAX (CSRF)
- Section Agents alimentée par all_uas (tous UAs publics, bots inclus)
- AccessLogParser : bots exclus des compteurs pages/livres/visiteurs
- Caches stats vidés après chaque modification des patterns
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- AccessLogParser : tous chemins/statuts pour IPs publiques (ipAllPaths, ipAllDays, ipAgents)
- Détection bots par patterns (data/bots.json, ~50 patterns initiaux)
- Section « Agents détectés » en bas de page admin/stats avec badge 🤖
- Panneau d'édition des patterns bots (formulaire avec CSRF)
- Drill-down IP : section « Autres chemins » (hors articles/livres)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Drill-down IP : user agents affichés sous l'adresse IP, top 5 par fréquence
- AccessLogParser : regex COMBINED étendue pour capturer le UA (groupe 5)
- Tracking ipAgents [ip => [ua => count]], ip_agents dans le résultat de stats()
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Drill-down IP : articles/livres affichés un par ligne (compteur entre parenthèses), triés par date de dernier accès desc
- AccessLogParser : ipPathTs trace le dernier timestamp par chemin/IP
- ip_top_paths : structure {n, ts} au lieu de count simple
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Admin stats : clic sur un réseau AS affiche les IPs avec mini sparkline 14 jours + articles/livres consultés
- AccessLogParser : calcul ip_data (daily + top paths) inclus dans le cache stats
- Suppression du tableau statique "Répartition par réseau" (fusionné dans accordéon pays)
- PHP-CS-Fixer appliqué sur l'ensemble des fichiers modifiés
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Admin stats : sparklines SVG par page (120×28 px, courbe + dégradé),
carte « Pages les plus visitées » en pleine largeur
- AccessLogParser : données par jour (pages_by_day) sur 14 jours
- AccessLogParser : IPs privées/LAN exclues de la répartition réseau
- ArticleManager : suppression opérateur nullsafe superflu (PHPStan)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Admin stats : sparklines SVG par page (120×28 px, courbe + dégradé),
carte « Pages les plus visitées » en pleine largeur
- AccessLogParser : données par jour (pages_by_day) sur 14 jours
- AccessLogParser : IPs privées/LAN exclues de la répartition réseau
- ArticleManager : suppression opérateur nullsafe superflu (PHPStan)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>