Simplification

This commit is contained in:
julien
2026-03-30 15:05:13 +02:00
parent b4a80013d5
commit b4593840a8
30 changed files with 526 additions and 781 deletions

206
README.md
View File

@@ -1,190 +1,74 @@
# F3 Simple Blog
Blog simple construit avec Fat-Free Framework et SQLite.
Blog minimal en **Fat-Free Framework** avec **SQLite**.
Le projet vise un blog léger, lisible et facile à déployer, avec un petit back-office dadministration, une médiathèque locale et un rendu Markdown sécurisé.
- rendu côté serveur
- routes dans `config.ini`
- modèles `DB\SQL\Mapper`
- édition en Markdown
- médiathèque paginée séparée de léditeur
- nettoyage des fichiers orphelins via script CLI
## Fonctionnalités
## Prérequis
- listing public des articles avec pagination ;
- page article ;
- authentification admin ;
- création, modification et suppression darticles ;
- médiathèque locale avec upload, texte alternatif, copie de la syntaxe Markdown et suppression ;
- vignette de carte dérivée de la première image du contenu ;
- rendu Markdown avec images locales `media:...` ;
- stockage des images en **JPG/PNG bruts** sans transformation.
- PHP 8.3+
- extensions PHP : `pdo_sqlite`, `mbstring`, `intl`, `dom`, `gd`
- Composer
## Installation
```bash
composer install
php scripts/install.php
php scripts/create-admin.php admin
```
Lancer ensuite un serveur local :
```bash
php -S 127.0.0.1:8000 -t public
```
## Structure
```text
project/
├── app/
│ ├── bootstrap.php
│ ├── config.ini
│ ├── helpers.php
│ ├── Controllers/
│ ├── Models/
│ ├── Services/
│ └── Views/
├── db/
├── logs/
├── public/
│ ├── assets/
│ └── uploads/media/
├── docker/
├── scripts/
│ ├── bootstrap.php
│ ├── install.php
│ └── create-admin.php
└── tmp/uploads/
app/ contrôleurs, modèles, vues et service Markdown
public/ assets et fichiers médias
scripts/ installation, création dadmin, nettoyage des orphelins
```
## Architecture
## Flux éditorial
Le backend sappuie sur un petit noyau :
- Les articles sont rédigés en Markdown.
- Les images sont gérées dans la médiathèque.
- La médiathèque fournit un bouton **Copier le Markdown**.
- Léditeur reste simple : textarea, petite toolbar Markdown et lien vers la médiathèque.
- `SiteController` : pages publiques ;
- `AuthController` : connexion / déconnexion ;
- `AdminController` : back-office articles et médiathèque ;
- `Controller` : rendu, session courante, flash, CSRF ;
- `Post`, `Media`, `User` : modèles `DB\SQL\Mapper` ;
- `MarkdownService` : compilation et sanitation du contenu Markdown.
## Médias
## Intégration F3
La table `media` est la référence côté application.
Le projet utilise directement les briques natives du framework :
- Supprimer un média retire la ligne SQL.
- Les fichiers orphelins éventuels sont nettoyés via un script CLI.
- routes et aliases dans `app/config.ini` ;
- `DB\SQL\Mapper` pour les tables principales ;
- `Auth` pour la connexion ;
- `Session` pour la session ;
- `Template` pour le rendu ;
- `Web::receive()` pour la réception des uploads ;
- `Markdown` pour le parsing Markdown ;
- `Web::slug()` pour les slugs.
## Contenu et médiathèque
Les articles contiennent leur texte en Markdown. Les images sont insérées dans le corps du contenu, et la première image rendue dans `body_html` sert de vignette dans les cartes darticle.
Les images du contenu utilisent la syntaxe :
```md
![Texte alternatif](media:nom-de-fichier.jpg)
```
La médiathèque :
- accepte uniquement **JPG** et **PNG** ;
- vérifie que le fichier reçu est bien une image ;
- conserve le fichier tel quel, sans réencodage ;
- stocke en base le nom du fichier, le texte alternatif, la largeur, la hauteur et la date de création.
## Contrat Markdown
Le rendu Markdown suit les règles suivantes :
- le HTML brut saisi par lauteur nest pas rendu ;
- les liens sont filtrés avant rendu ;
- seules les images locales en `media:...` sont rendues ;
- les images externes ne sont pas affichées ;
- avec le parseur Markdown de F3, il faut laisser une ligne vide entre deux blocs (titre, liste, citation, image, code) pour un rendu fiable.
## Sécurité
Le projet inclut :
- session dadministration ;
- jeton CSRF sur les formulaires ;
- rotation du jeton CSRF après connexion et déconnexion ;
- sanitation du HTML produit à partir du Markdown ;
- validation des uploads image ;
- cookies `httponly` et `samesite=Lax`.
## Pré-requis
### Développement local
- PHP 8.3+
- Composer
- extensions PHP : `pdo_sqlite`, `mbstring`, `intl`, `dom`
### Déploiement Docker
- Docker
- Docker Compose
## Démarrage local
Lister les orphelins :
```bash
composer install
cp config.local.ini.example config.local.ini
php scripts/install.php
php -S 127.0.0.1:8080 -t public
php scripts/clean-orphan-media.php list
```
Puis ouvrir `http://127.0.0.1:8080`.
Créer un compte admin :
Supprimer les orphelins :
```bash
php scripts/create-admin.php admin
php scripts/clean-orphan-media.php delete
```
## Configuration
## Déploiement Docker
Le fichier `app/config.ini` contient les valeurs par défaut. Tu peux les surcharger dans `config.local.ini`.
Exemple minimal en production :
```ini
[globals]
app.env=prod
app.timezone=Europe/Paris
```
Le paramètre `app.env` doit être défini à `prod` sur un déploiement réel.
## Déploiement Docker derrière Caddy
Déploiement Docker recommandé :
- Apache sert `public/` dans le conteneur ;
- `compose.yaml` expose lapplication sur `127.0.0.1:8888` par défaut ;
- Caddy termine TLS et reverse-proxy vers cette cible ;
- SQLite, les logs et les uploads sont montés sur des volumes persistants.
Exemple :
Une configuration Docker est fournie :
```bash
cp config.local.ini.example config.local.ini
# édite config.local.ini : app.env=prod
docker compose up -d --build
docker compose up --build
```
Créer un compte admin dans le conteneur :
```bash
docker compose exec app php scripts/create-admin.php admin
```
La commande demande ensuite le mot de passe du compte.
Le `Caddyfile.example` fournit une base de reverse proxy. En production, il faut exposer publiquement **Caddy uniquement**. Lapplication Apache/PHP ne doit pas être accessible directement depuis Internet.
## Sauvegarde
Pour sauvegarder le blog, il faut au minimum conserver :
- `db/app.sqlite`
- `public/uploads/media/`
Les logs peuvent aussi être conservés si tu veux garder lhistorique derreurs.
## Limites assumées
- base SQLite ;
- instance applicative unique ;
- pas de système de migrations automatique ;
- en cas de changement de schéma, une migration manuelle ou une base recréée sera nécessaire.
Lapplication écoute sur `127.0.0.1:8888` par défaut.