feat : versionnage semver, migrations contenu, bandeau mise à jour admin
- CHANGELOG.md : structure semver (1.0.0 / 1.1.0 / 1.2.0) remplace le journal non versionné - public/version.txt : généré à chaque push depuis la première entrée CHANGELOG - scripts/push.sh : extrait la version CHANGELOG avant git add - src/UpdateChecker.php : compare version déployée vs version Gitea (raw file), cache 1 h - templates/layout.php : bandeau alerte admin (nouvelle version / migrations en attente) - templates/admin.php : dashboard moteur Folio (version déployée / disponible) - scripts/migrate_content.php + migration_001 : ajout # titre dans les articles existants - templates/maintenance.php : page HTTP 503 pendant une migration - src/helpers.php : extractMarkdownTitle(), normalisation \r\n dans lineDiff() - templates/wizard/step1.php : suppression champ titre, plan TOC dynamique - public/assets/js/wizard.js : scope titleEl, scrollToCursor, buildToc, handlers externalisés Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+63
-125
@@ -1,140 +1,78 @@
|
||||
# Changelog — varlog
|
||||
# Changelog
|
||||
|
||||
## [Unreleased] — 2026-05-13
|
||||
Toutes les modifications notables sont documentées ici.
|
||||
Format : [Keep a Changelog](https://keepachangelog.com/fr/1.0.0/) — versionnage [semver](https://semver.org/lang/fr/).
|
||||
|
||||
### Performances
|
||||
---
|
||||
|
||||
- **Cache multi-niveaux pour les vues d'articles** : temps de chargement réduit
|
||||
de +5 s à ~0,4 s sur 1 062 articles.
|
||||
- Mémoïsation de `getAll()` et `getSearchIndex()` dans la requête PHP
|
||||
(`$allCache`, `$searchIndexCache`) — évite les appels répétés.
|
||||
- Cache disque par article (`_cache/articles/{uuid}.json`) avec invalidation
|
||||
par comparaison `mtime` — 1 lecture au lieu de 2 par article.
|
||||
- Slug index (`_cache/slug_index.json`) : `getBySlug()` en O(1) sans scanner
|
||||
tous les articles ; construit depuis `search_index.json` en un seul fichier.
|
||||
- `getCategories()` et `$_allPublished` chargés depuis `search_index.json`
|
||||
au lieu de `getAll()` — 1 fichier lu quelle que soit la taille du catalogue.
|
||||
- `search_index.json` enrichi avec `cover`, `created_at`, `author` ; rebuild
|
||||
automatique si le format est obsolète.
|
||||
- `SearchEngine::scorePool()` : tokenise chaque article une seule fois pour
|
||||
N mots de titre (vs N passes séparées qui retokenisaient chaque article
|
||||
N fois et calculaient la similarité trigramme sur le contenu).
|
||||
- Le nombre de lectures de fichiers par vue d'article est désormais constant
|
||||
(~4), indépendamment du nombre total d'articles.
|
||||
- Documentation : `docs/cache-architecture.md`.
|
||||
## [Unreleased]
|
||||
|
||||
---
|
||||
|
||||
## [1.2.0] - 2026-05-14
|
||||
|
||||
### Ajouté
|
||||
- Wizard multi-étapes pour la création (5 écrans) et l'édition (6 écrans) d'articles (#58)
|
||||
- Auto-sauvegarde en brouillon (debounce 3 s) avec indicateur visible
|
||||
- Étape tags : champ plat avec détection automatique depuis le texte (abréviations, CamelCase, noms propres)
|
||||
- Étape SEO : aperçu moteur de recherche en temps réel
|
||||
- Étape 6 (édition) : diff ligne à ligne avant confirmation
|
||||
- Plan Markdown dynamique (TOC) dans la colonne droite de l'éditeur
|
||||
- Titre extrait du premier `# …` du contenu Markdown (plus de champ titre séparé)
|
||||
- Système de migrations de contenu (`scripts/migrate_content.php`)
|
||||
- Mode maintenance automatique (`data/.maintenance` → page HTTP 503)
|
||||
- Migration `001` : ajout du titre Markdown dans les articles existants
|
||||
- Bouton "Mettre à jour" dans l'administration (sans accès CLI)
|
||||
- `UpdateChecker` : détection de mise à jour et migrations en attente
|
||||
- Bandeau d'alerte pour les administrateurs sur toutes les pages
|
||||
- Dashboard `/admin` : version déployée vs version disponible
|
||||
|
||||
### Modifié
|
||||
- `ArticleManager` : +6 méthodes pour les brouillons overlay
|
||||
- `lineDiff` : normalisation `\r\n` → `\n`, seuil relevé à 2 000 000, fallback ligne par ligne
|
||||
- `push.sh` : génère `public/version.txt` (numéro de version semver) à chaque release
|
||||
|
||||
### Corrigé
|
||||
|
||||
- **Upload de fichiers (#48)** : les fichiers > 8 Mo étaient rejetés silencieusement.
|
||||
Le serveur utilise `mod_php` (non PHP-FPM) ; les limites ont été corrigées dans
|
||||
`/etc/php/8.3/apache2/php.ini` : `upload_max_filesize = 500M`, `post_max_size = 2048M`.
|
||||
Le handler `add_files` détecte désormais le dépassement et affiche un message
|
||||
d'erreur explicite au lieu de rediriger sans rien faire.
|
||||
|
||||
### Fonctionnalités
|
||||
|
||||
- **Réactions visiteurs** : trois boutons (👍 Utile / 🔥 Important / 🤔 À creuser)
|
||||
affichés sous chaque article. Toggle : recliquer retire la réaction. Accessible sans
|
||||
compte via un cookie UUID (`vl_vid`, 1 an, `HttpOnly`). Comportement async fetch avec
|
||||
fallback formulaire natif (compatible CSP `script-src 'self'`). Routes :
|
||||
`POST /react`. Table BDD : `article_reactions`.
|
||||
|
||||
- **Commentaires avec vérification email** : formulaire nom + email (non publié) +
|
||||
texte (2 000 caractères max). Protection honeypot + CSRF en session. Un code à
|
||||
6 chiffres est envoyé par email (expire 24 h) ; le commentaire est auto-publié au clic
|
||||
sur le lien de confirmation. Routes : `POST /comment`,
|
||||
`GET /verify-comment/<6chiffres>`. Table BDD : `comments`.
|
||||
|
||||
- **Modération commentaires** : onglet **Commentaires** dans `/admin/comments` listant
|
||||
tous les commentaires avec statut (vérifié / publié) et actions masquer/republier.
|
||||
Route : `POST /comment-moderate`.
|
||||
|
||||
- **Page de confirmation à l'enregistrement** : cliquer sur "Enregistrer" affiche une
|
||||
page intermédiaire avec le diff du contenu, le slug (déplacé ici depuis le formulaire,
|
||||
avec suggestion auto si le titre a changé), un commentaire de révision pré-rempli
|
||||
d'après les modifications détectées, et un aperçu SEO (snippet Google). La
|
||||
sauvegarde effective n'a lieu qu'après confirmation.
|
||||
|
||||
- **URLs propres** : toutes les routes internes migrent vers des chemins lisibles.
|
||||
Les anciennes URLs `/?action=…` restent fonctionnelles (compatibilité).
|
||||
| Ancienne URL | Nouvelle URL |
|
||||
|---|---|
|
||||
| `/?action=edit&uuid=<u>` | `/edit/<u>` |
|
||||
| `/?action=sources&uuid=<u>` | `/sources/<u>` |
|
||||
| `/?action=diff&uuid=<u>&rev=<n>` | `/diff/<u>/<n>` |
|
||||
| `/?action=create` | `/new` |
|
||||
| `/?action=admin[&tab=<t>]` | `/admin[/<t>]` |
|
||||
| `/?action=categories` | `/categories` |
|
||||
| `/?action=profile` | `/profile` |
|
||||
| `/?action=about\|legal\|licenses\|contact` | `/about`, `/legal`… |
|
||||
| `/?action=regen_thumbs` | `/admin/regen-thumbs` |
|
||||
| `/?action=add_files&uuid=<u>` | `/files/<u>/add` |
|
||||
| `/?action=import_image&uuid=<u>` | `/import/<u>` |
|
||||
| `/?cat=<cat>` | `/categorie/<cat>` |
|
||||
| `/?cursor=<uuid>` | `/page/<uuid>` |
|
||||
|
||||
- **Moteur de recherche** : index trigram+substring pré-construit (`search_index.json`,
|
||||
reconstruit à chaque écriture), accessible depuis la navbar.
|
||||
|
||||
### Corrections
|
||||
|
||||
- **Métadonnées fichiers (sources)** : `addFileMeta()` ne sauvegardait pas l'auteur et
|
||||
l'URL source en raison d'un guard `file_exists()` trop strict — supprimé.
|
||||
- **Authentification OIDC** (`State invalide.`) : `session_start()` était appelé avant
|
||||
`bootstrap.php` dans les fichiers OIDC, écrasant les paramètres de cookie
|
||||
(`SameSite=Lax`, `Secure`, `HttpOnly`) — corrigé dans `start.php`, `callback.php`
|
||||
et `me.php`.
|
||||
- **Sidebar droite de l'article** : classe Bootstrap `flex-nowrap-lg` inexistante,
|
||||
remplacée par `flex-lg-nowrap` — la sidebar ne tombe plus en bas de page.
|
||||
- **Date d'affichage en liste** : `created_at` affiché à la place de `published_at`
|
||||
— corrigé avec fallback approprié.
|
||||
- **Formulaire d'édition** : "Fichiers existants" déplacé dans la colonne de droite ;
|
||||
attribution auteur/source étendue à tous les types de fichiers (pas seulement images).
|
||||
- **Historique des révisions** : plus de révision créée si le contenu et le titre
|
||||
sont inchangés. Ajout des boutons de suppression par révision et suppression globale.
|
||||
- **Canonical URL catégorie** : passe de `/?cat=…` à `/categorie/…`.
|
||||
- **Flux RSS** : `/rss` et `/rss.xml` redirigent en 301 vers `/feed` (URL
|
||||
canonique) ; les articles des catégories privées sont exclus du flux ;
|
||||
la description est convertie depuis Markdown en texte brut.
|
||||
- Diff étape 6 "violent" (tout supprimé/ajouté) dû aux fins de ligne `\r\n` du navigateur
|
||||
|
||||
---
|
||||
|
||||
## 2026-05-09
|
||||
## [1.1.0] - 2026-05-13
|
||||
|
||||
### Fonctionnalités
|
||||
### Ajouté
|
||||
- **Réactions visiteurs** : boutons 👍 / 🔥 / 🤔 sous chaque article, toggle async avec fallback formulaire natif
|
||||
- **Commentaires avec vérification email** : code 6 chiffres, honeypot + CSRF, modération dans `/admin`
|
||||
- **URLs propres** : `/edit/<u>`, `/new`, `/admin`, `/categorie/<cat>`, `/files/<u>/add`, `/import/<u>`, etc.
|
||||
- **Moteur de recherche** : index trigramme+substring pré-construit, résultats scorés avec mise en évidence
|
||||
|
||||
- **SEO** : balises canonical, `sitemap.xml`, `robots.txt`, JSON-LD (`BlogPosting` /
|
||||
`WebSite`), `noindex` sur les pages d'administration.
|
||||
- **Recherche** : page de résultats avec score de pertinence, mise en évidence des
|
||||
termes, lien vers la catégorie depuis les résultats.
|
||||
- **Support HEIC/HEIF** : conversion automatique en JPEG à l'upload.
|
||||
- **Support SVG** : upload autorisé, servi avec Content-Type correct.
|
||||
- **Avant-première** : article visible en liste mais verrouillé avant sa date de
|
||||
publication.
|
||||
- **Pagination curseur** : navigation par UUID de dernier article vu, sans offset SQL.
|
||||
- **Layout article 3 colonnes** : sidebar gauche (catégorie), contenu central,
|
||||
sidebar droite (pièces jointes, liens externes, articles liés).
|
||||
- **Import depuis URL** : téléchargement de fichiers distants avec extraction
|
||||
automatique des métadonnées (EXIF, OpenGraph, PDF).
|
||||
- **Gestion des pièces jointes** dans le formulaire d'édition, avec attribution
|
||||
auteur/source affichée dans la vue article.
|
||||
### Amélioré
|
||||
- **Cache multi-niveaux** : chargement réduit de ~5 s à ~0,4 s sur 1 000+ articles (mémoïsation, cache disque, slug index O(1))
|
||||
- **Upload fichiers** : détection et message d'erreur explicite pour les fichiers > limite PHP
|
||||
|
||||
### Corrections
|
||||
|
||||
- Login intégré dans `layout.php`, chemins CSS en absolu.
|
||||
- Redéclaration de `url()` dans `config.php` — fatal error corrigée.
|
||||
- Correction permissions `www-data` sur `data/`.
|
||||
### Corrigé
|
||||
- Métadonnées fichiers (`addFileMeta`) : guard `file_exists()` trop strict supprimé
|
||||
- Sidebar droite article : classe Bootstrap `flex-nowrap-lg` → `flex-lg-nowrap`
|
||||
- Flux RSS : exclusion catégories privées, redirection 301 `/rss` → `/feed`
|
||||
|
||||
---
|
||||
|
||||
## 2026-04 et antérieur
|
||||
## [1.0.0] - 2026-05-09
|
||||
|
||||
- Flux RSS paginé (`/feed`, `/rss`, `/rss.xml`) avec autodiscovery.
|
||||
- Stockage des articles en fichiers Markdown (migration depuis base de données).
|
||||
- SSO via Keycloak/OIDC avec PKCE.
|
||||
- Images de couverture (liste, vue article, `og:image`).
|
||||
- Brouillons visibles uniquement par l'auteur.
|
||||
- Formulaire de contact (CSRF, honeypot, rate-limit).
|
||||
- Pages : mentions légales (LCEN/RGPD), licences, à propos.
|
||||
- Auto-hébergement Bootstrap 5, police Inter, favicon SVG.
|
||||
- Headers HTTP de sécurité, CSP stricte.
|
||||
### Ajouté
|
||||
- Moteur de blog PHP Folio — première release versionnée
|
||||
- Articles en Markdown avec fichiers attachés, liens externes, images de couverture
|
||||
- Authentification par lien magique envoyé par email (#29)
|
||||
- SSO via Keycloak/OIDC avec PKCE
|
||||
- Rôles, capacités et gestion des utilisateurs
|
||||
- Catégories avec swatches couleur générées algorithmiquement
|
||||
- Tags par type avec suggestions
|
||||
- SEO : canonical, `sitemap.xml`, `robots.txt`, JSON-LD, `og:image`
|
||||
- Avant-premières (articles futurs visibles aux utilisateurs autorisés)
|
||||
- Pagination curseur (sans offset SQL)
|
||||
- Import depuis URL (EXIF, OpenGraph, PDF)
|
||||
- Historique des révisions avec diff
|
||||
- Flux RSS (`/feed`) paginé avec autodiscovery
|
||||
- Formulaire de contact (CSRF, honeypot, rate-limit)
|
||||
- Pages légales (LCEN/RGPD), licences, à propos
|
||||
- Migrations SQL versionnées (`database/migrate.php`)
|
||||
- Système de déploiement par rsync
|
||||
|
||||
Reference in New Issue
Block a user