From ebcd2f007f124b83a0fe76206dc9d54023f88146 Mon Sep 17 00:00:00 2001 From: julien Date: Sun, 22 Feb 2026 14:36:40 +0100 Subject: [PATCH] first commit --- .gitignore | 3 ++ README.md | 1 + composer.json | 15 +++++++ migrate.php | 36 +++++++++++++++++ public/index.php | 58 +++++++++++++++++++++++++++ src/Models/Post.php | 16 ++++++++ src/routes.php | 94 ++++++++++++++++++++++++++++++++++++++++++++ views/admin.twig | 30 ++++++++++++++ views/layout.twig | 21 ++++++++++ views/post_form.twig | 31 +++++++++++++++ views/posts.twig | 14 +++++++ 11 files changed, 319 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 composer.json create mode 100644 migrate.php create mode 100644 public/index.php create mode 100644 src/Models/Post.php create mode 100644 src/routes.php create mode 100644 views/admin.twig create mode 100644 views/layout.twig create mode 100644 views/post_form.twig create mode 100644 views/posts.twig diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..80180ec --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +composer.lock +database/ +vendor/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..add73e3 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# blog-slim diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..35e7373 --- /dev/null +++ b/composer.json @@ -0,0 +1,15 @@ +{ + "name": "user/blog-slim", + "require": { + "slim/slim": "4.*", + "slim/psr7": "^1.8", + "illuminate/database": "^12.52", + "twig/twig": "^3.23", + "slim/twig-view": "^3.4" + }, + "autoload": { + "psr-4": { + "App\\": "src/" + } + } +} diff --git a/migrate.php b/migrate.php new file mode 100644 index 0000000..79a1c48 --- /dev/null +++ b/migrate.php @@ -0,0 +1,36 @@ +addConnection([ + 'driver' => 'sqlite', + // __DIR__ pointe sur le répertoire racine du projet + // le fichier SQLite se trouve dans le sous‑dossier `database` + 'database' => realpath(__DIR__ . '/database/blog.sqlite'), + 'prefix' => '', +]); + +$capsule->setAsGlobal(); +$capsule->bootEloquent(); + +// --------------------------------------------------------------------- +// Création de la table `posts` si elle n'existe pas déjà +// --------------------------------------------------------------------- +if (!Capsule::schema()->hasTable('posts')) { + Capsule::schema()->create('posts', function ($table) { + $table->increments('id'); // clé primaire auto‑incrémentée + $table->string('title'); // titre de l'article + $table->text('content'); // contenu de l'article + }); + echo "Table 'posts' créée avec succès.\n"; +} else { + echo "La table 'posts' existe déjà.\n"; +} diff --git a/public/index.php b/public/index.php new file mode 100644 index 0000000..a5bcf41 --- /dev/null +++ b/public/index.php @@ -0,0 +1,58 @@ +addErrorMiddleware(true, true, true); + +/* ------------------------------------------------- + Twig (templates) + ------------------------------------------------- */ +$twig = Twig::create(__DIR__ . '/../views', ['cache' => false]); +$app->add(TwigMiddleware::create($app, $twig)); + +/* ------------------------------------------------- + Vérification / création du fichier SQLite + ------------------------------------------------- */ +$dbFile = __DIR__ . '/../database/blog.sqlite'; +if (!file_exists($dbFile)) { + // crée un fichier vide et lui donne les permissions d’écriture + touch($dbFile); + chmod($dbFile, 0664); +} + +/* ------------------------------------------------- + Eloquent (connexion SQLite) + ------------------------------------------------- */ +$capsule = new Capsule; +$capsule->addConnection([ + 'driver' => 'sqlite', + // le chemin relatif fonctionne ; SQLite créera le fichier si besoin + 'database' => $dbFile, + 'prefix' => '', +]); +$capsule->setAsGlobal(); +$capsule->bootEloquent(); + +/* ------------------------------------------------- + Chargement des routes + ------------------------------------------------- */ +(require __DIR__ . '/../src/routes.php')($app); + +/* ------------------------------------------------- + Démarrage de l’application + ------------------------------------------------- */ +$app->run(); diff --git a/src/Models/Post.php b/src/Models/Post.php new file mode 100644 index 0000000..72e0084 --- /dev/null +++ b/src/Models/Post.php @@ -0,0 +1,16 @@ +get('/', function (Request $request, Response $response) use ($app) { + $posts = Post::orderByDesc('id')->get(); + + /** @var Twig $view */ + $view = $request->getAttribute('view'); // <-- récupération correcte + return $view->render($response, 'posts.twig', ['posts' => $posts]); + }); + + // ------------------------------------------------- + // Page admin – tableau de bord + // ------------------------------------------------- + $app->get('/admin', function (Request $request, Response $response) use ($app) { + $posts = Post::orderByDesc('id')->get(); + + /** @var Twig $view */ + $view = $request->getAttribute('view'); + return $view->render($response, 'admin.twig', ['posts' => $posts]); + }); + + // ------------------------------------------------- + // Création d'un article (POST depuis admin) + // ------------------------------------------------- + $app->post('/admin/create', function (Request $request, Response $response) { + $data = $request->getParsedBody(); + + Post::create([ + 'title' => $data['title'], + 'content' => $data['content'], + ]); + + return $response + ->withHeader('Location', '/admin') + ->withStatus(302); + }); + + // ------------------------------------------------- + // Formulaire d'édition (GET depuis admin) + // ------------------------------------------------- + $app->get('/admin/edit/{id}', function (Request $request, Response $response, $args) use ($app) { + $id = (int)$args['id']; + $post = $id ? Post::findOrFail($id) : null; // id=0 → création + + /** @var Twig $view */ + $view = $request->getAttribute('view'); + + return $view->render($response, 'post_form.twig', [ + 'action' => $id ? "/admin/edit/{$id}" : "/admin/create", + 'post' => $post, + ]); + }); + + // ------------------------------------------------- + // Enregistrement des modifications (POST depuis admin) + // ------------------------------------------------- + $app->post('/admin/edit/{id}', function (Request $request, Response $response, $args) { + $post = Post::findOrFail($args['id']); + $data = $request->getParsedBody(); + + $post->update([ + 'title' => $data['title'], + 'content' => $data['content'], + ]); + + return $response + ->withHeader('Location', '/admin') + ->withStatus(302); + }); + + // ------------------------------------------------- + // Suppression d'un article (POST depuis admin) + // ------------------------------------------------- + $app->post('/admin/delete/{id}', function (Request $request, Response $response, $args) { + $post = Post::findOrFail($args['id']); + $post->delete(); + + return $response + ->withHeader('Location', '/admin') + ->withStatus(302); + }); +}; diff --git a/views/admin.twig b/views/admin.twig new file mode 100644 index 0000000..9b21930 --- /dev/null +++ b/views/admin.twig @@ -0,0 +1,30 @@ +{% extends "layout.twig" %} + +{% block title %}Admin – Gestion des articles{% endblock %} + +{% block content %} +

Gestion des articles

+ + + + Ajouter un article + + {% for post in posts %} +
+

{{ post.title }}

+

{{ post.content|nl2br }}

+ +
+ Éditer + +
+ +
+
+
+ {% else %} +

Aucun article à gérer.

+ {% endfor %} +{% endblock %} diff --git a/views/layout.twig b/views/layout.twig new file mode 100644 index 0000000..b173cd4 --- /dev/null +++ b/views/layout.twig @@ -0,0 +1,21 @@ + + + + + {% block title %}Mon Blog{% endblock %} + + + +

+ Mon Blog | + Admin +

+ {% block content %}{% endblock %} + + + diff --git a/views/post_form.twig b/views/post_form.twig new file mode 100644 index 0000000..70e8a09 --- /dev/null +++ b/views/post_form.twig @@ -0,0 +1,31 @@ + +{% extends "layout.twig" %} + +{% block title %} + {% if post is defined %}Éditer l’article{% else %}Créer un article{% endif %} +{% endblock %} + +{% block content %} +

+ {% if post is defined %}Éditer{% else %}Créer{% endif %} un article +

+ +
+

+ +

+

+ +

+ +
+ +

Retour à l’admin

+{% endblock %} diff --git a/views/posts.twig b/views/posts.twig new file mode 100644 index 0000000..99e0f3a --- /dev/null +++ b/views/posts.twig @@ -0,0 +1,14 @@ +{% extends "layout.twig" %} + +{% block title %}Articles{% endblock %} + +{% block content %} + {% for post in posts %} +
+

{{ post.title }}

+

{{ post.content|nl2br }}

+
+ {% else %} +

Aucun article publié.

+ {% endfor %} +{% endblock %}