This commit is contained in:
julien
2026-03-09 15:14:57 +01:00
parent 50831ea83a
commit 4d678f1211
8 changed files with 86 additions and 30 deletions

21
.gitignore vendored
View File

@@ -1,13 +1,20 @@
# Environnement local
# ============================================
# Environnement & Configuration
# ============================================
.env
# Composer
# ============================================
# Dépendances Composer
# ============================================
/vendor/
composer.lock
# Base de données SQLite
/database/*.sqlite
/database/*.db
# ============================================
# Base de données
# ============================================
/database/
# Cache et logs
/var/
# ============================================
# Cache & Logs
# ============================================
/var/

View File

@@ -15,7 +15,8 @@
"slim/psr7": "*",
"twig/twig": "*",
"slim/twig-view": "^3.4",
"catfan/medoo": "2.*"
"catfan/medoo": "2.*",
"vlucas/phpdotenv": "^5.6"
},
"autoload": {
"psr-4": {
@@ -25,4 +26,4 @@
"require-dev": {
"friendsofphp/php-cs-fixer": "^3.94"
}
}
}

View File

@@ -4,6 +4,12 @@ declare(strict_types=1);
require __DIR__ . '/../vendor/autoload.php';
use Dotenv\Dotenv;
// Charger les variables d'environnement
$dotenv = Dotenv::createImmutable(__DIR__ . '/..');
$dotenv->load();
use Slim\Factory\AppFactory;
use Slim\Views\TwigMiddleware;
use Slim\Views\Twig;
@@ -18,9 +24,12 @@ $env = $_ENV['APP_ENV'] ?? 'production';
$isDev = strtolower($env) === 'development';
// Dossier de cache Twig (false en dev, chemin en prod)
$twigCache = $isDev ? false : __DIR__ . '/../var/cache/twig';
if ($twigCache && !is_dir($twigCache)) {
@mkdir($twigCache, 0755, true);
$twigCache = false;
if (!$isDev) {
$twigCache = __DIR__ . '/../var/cache/twig';
if (!is_dir($twigCache)) {
@mkdir($twigCache, 0755, true);
}
}
// Chemin base de données
@@ -76,6 +85,7 @@ $app->add(TwigMiddleware::create($app, $twig));
$controller = new PostController($twig, $db);
$app->get('/', [$controller, 'index']);
$app->get('/article/{slug}', [$controller, 'show']);
$app->get('/admin', [$controller, 'admin']);
$app->get('/admin/edit/{id}', [$controller, 'form']);
$app->post('/admin/create', [$controller, 'create']);

View File

@@ -30,6 +30,33 @@ class PostController
return $this->view->render($res, 'pages/home.twig', ['posts' => $posts]);
}
/**
* Affiche un article complet par son slug.
*/
public function show(Request $req, Response $res, array $args): Response
{
$slug = (string)($args['slug'] ?? '');
// Récupérer tous les posts et chercher celui qui correspond au slug
$rows = $this->db->select('post', '*', ['ORDER' => ['id' => 'DESC']]);
$post = null;
foreach ($rows ?: [] as $row) {
$postObj = Post::fromArray($row);
if ($postObj->getSlug() === $slug) {
$post = $postObj;
break;
}
}
if (!$post) {
$res->getBody()->write('Article non trouvé');
return $res->withStatus(404);
}
return $this->view->render($res, 'pages/post_detail.twig', ['post' => $post]);
}
/**
* Affiche la page d'administration.
*/

View File

@@ -135,18 +135,6 @@ final class Post
return trim($slug, '-');
}
/**
* Indique si l'article a été créé récemment.
*
* @param int $days Nombre de jours
* @return bool
*/
public function isRecent(int $days = 7): bool
{
$limit = new DateTime("-{$days} days");
return $this->createdAt > $limit;
}
/**
* Retourne les données prêtes à persister en DB.
*

View File

@@ -25,9 +25,6 @@
<tr>
<td>
<strong>{{ post.title }}</strong>
{% if post.isRecent(7) %}
<span class="badge badge-new">Nouveau</span>
{% endif %}
</td>
<td>{{ post.createdAt|date("d/m/Y H:i") }}</td>
<td>{{ post.updatedAt|date("d/m/Y H:i") }}</td>

View File

@@ -9,9 +9,6 @@
<div class="post-meta">
<small>Publié le {{ post.createdAt|date("d/m/Y à H:i") }}</small>
{% if post.isRecent(7) %}
<span class="badge badge-new">Nouveau</span>
{% endif %}
</div>
<p>{{ post.getExcerpt(200) }}</p>

View File

@@ -0,0 +1,29 @@
{% extends "layout.twig" %}
{% block title %}{{ post.title }} Mon Blog{% endblock %}
{% block content %}
<article class="post">
<h1>{{ post.title }}</h1>
<div class="post-meta">
<small>Publié le {{ post.createdAt|date("d/m/Y à H:i") }}</small>
</div>
{% if post.updatedAt != post.createdAt %}
<div class="post-updated">
<small><em>Mis à jour le {{ post.updatedAt|date("d/m/Y à H:i") }}</em></small>
</div>
{% endif %}
<div class="post-content">
{{ post.content|raw }}
</div>
<hr>
<p>
<a href="/">← Retour aux articles</a>
</p>
</article>
{% endblock %}