Page d'accueil et /tendances lisent uniquement le cache trending_{period}.json
produit par le flux RSS /trending?period=…. Aucun parsing de logs en dehors du
flux RSS. Rubrique renommée "Meilleures audiences · 1 heure".
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- TrendingParser : lit les logs Apache, compte les visiteurs uniques (IPs, HTTP 200),
supporte plusieurs préfixes (/post/, /book/) et un seul parse via topGrouped()
- /trending?period=… : flux RSS des 50 articles les plus consultés, 10 périodes
de 10 min à 1 an, cache TTL adaptatif
- /tendances : page publique avec sélecteur de période, top 20 articles,
tableau des flux RSS et section méthodologie
- /admin/stats : remplace AccessLogParser (hits) par TrendingParser (visiteurs uniques)
- Page d'accueil : rubrique Tendances alimentée par les logs 1h (fallback DB)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Les données coûteuses (parsing des logs, batchLookup ASN) sont mises en cache
dans DATA_PATH/.stats_cache.json. Le cache expire après 60 secondes via filemtime.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Le bouton "Mettre à jour" appelle désormais `sudo /usr/local/bin/folio-upgrade.sh`
via exec() plutôt que d'exécuter git pull + composer + migrations directement en PHP.
Le script shell (template dans scripts/server/) gère la séquence complète : clone fresh,
permissions www-data, restauration .env, composer install, migrations SQL, .sessions,
safe.directory. Le journal de la dernière mise à jour est conservé dans DATA_PATH/.upgrade-log
et affiché en <details> dans l'admin.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- oidc/start.php : arrêt immédiat (500) si session_start() échoue, évite
un flux OIDC condamné à l'échec silencieux (ex. session.save_path absent)
- oidc/callback.php : même garde + error_log sur échec du contrôle de state
pour faciliter le diagnostic (STATE absent/présent + session_id)
- consignes.md : règle PHP-FPM — toujours user=www-data, pas le compte admin
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Ajouter DATA_PATH dans le tableau des variables .env avec note prod
- Étape 6 : permissions sur DATA_PATH (hors document root) au lieu de data/
- Étape 7 : référencer $DATA_PATH/site_settings.json
- Mentionner scripts/setup.sh
- Structure : retirer data/ (géré par DATA_PATH), ajouter scripts/
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
bootstrap.php ne suffisait pas — index.php, feed.php et sitemap.php passent
par config/config.php. DATA_PATH est maintenant défini là, juste après le
chargement du .env. file.php charge désormais config/config.php.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- DATA_PATH : chemin /data hors document root, configurable via .env
(fallback sur BASE_PATH/data si absent)
- DataGit : auto-commit git sur toutes les écritures articles/livres
(create, update, delete, meta, tags, fichiers, liens…) sauf autosave
- UpdateChecker : getBranch() / getLastChecked() / clearCache(),
branche configurable via FOLIO_UPDATE_BRANCH (plus de main hardcodé)
- Admin dashboard : affiche la branche suivie, date du dernier contrôle,
bouton Vérifier pour forcer le check sans attendre le TTL
- CLAUDE.md : architecture DATA_PATH et flux de déploiement documentés
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- AccessLogParser : parse COMBINED, agrège hits /post/ et /book/, cache 10 min
- AsnLookup : batch lookup ip-api.com, cache 30j, agrégation et groupes AS
- Onglet Statistiques dans l'admin : top pages, top livres, répartition réseau
- Filtrage par groupe AS (badges) + formulaire de configuration des groupes
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Ajoute un concept de "livre" (série de pages ordonnées) avec :
- BookManager : CRUD JSON dans data/books/<slug>.json
- Route /book/<slug> → page de sommaire (table des matières)
- Navigation chapitre ← → en bas de chaque article membre du livre
- Bandeau "Chapitre X/N — Nom du livre" en haut de l'article
- Admin → onglet Livres : créer, éditer, supprimer un livre, ajouter/ordonner les pages via textarea slug
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Balaye tous les fichiers correspondant au pattern (ex: *-access.log)
et leurs rotations .gz/.tar.gz. Valeur par défaut : *-access.log.
Label renommé en "Pattern des logs d'accès".
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- logFiles() utilise glob() au lieu d'un range fixe 1-14
- Support .tar.gz via PharData
- Champ apache_access_log déplacé du tab Site vers un bloc dédié
dans le tab Recherches (action admin_save_searches_config)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Ajoute apacheAccessLog() dans SiteSettings — priorité au réglage admin,
fallback sur APACHE_ACCESS_LOG dans .env. Champ ajouté dans le formulaire
Site de l'administration.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Crée les dossiers requis, applique setgid sur data/ et _cache/ pour
que les fichiers héritent du groupe web (www-data) quelle que soit
leur origine (PHP ou rsync), installe les dépendances et lance les
migrations SQL.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
file_put_contents() échouait silencieusement (permissions), provoquant
un saved=1 trompeur. Les deux fonctions retournent maintenant bool ;
les callers redirigent vers ?error=write et le template affiche un
message d'erreur explicite.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remplace la redirection 301 vers le premier résultat par une redirection
302 vers /search?q=... pour laisser l'utilisateur choisir parmi les
résultats.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- ArticleManager : invalider le cache si index.md est plus récent que meta.json
- migration_001 : touch(meta.json) après maj index.md pour forcer l'invalidation
- post_view.php : masquer le H1 initial du contenu (déjà affiché par le template)
- step1.php : en-tête "Modifier" sans le titre de l'article
- wizard.js : retirer scrollToCursor (erroné sur auto-resize) ; Ctrl+Home/End via scrollIntoView
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>