diff --git a/src/Controllers/PostController.php b/src/Controllers/PostController.php index 97d860e..81a4e17 100644 --- a/src/Controllers/PostController.php +++ b/src/Controllers/PostController.php @@ -9,6 +9,7 @@ use Psr\Http\Message\ServerRequestInterface as Request; use Slim\Views\Twig; use App\Repositories\PostRepositoryInterface as PostRepository; use App\Requests\PostRequest; +use App\Models\Post; /** * Contrôleur pour les posts. @@ -26,7 +27,7 @@ class PostController public function index(Request $req, Response $res): Response { - $posts = $this->repo->allDesc(); + $posts = $this->repo->allDesc(); // Post[] return $this->view->render($res, 'pages/home.twig', ['posts' => $posts]); } @@ -51,9 +52,11 @@ class PostController // Si id fourni mais post introuvable -> 404 if ($id > 0 && $post === null) { - return $res->withStatus(404)->write('Article non trouvé'); + $res->getBody()->write('Article non trouvé'); + return $res->withStatus(404); } + // Twig peut accéder aux getters (post.title, post.content) $action = $id ? "/admin/edit/{$id}" : "/admin/create"; return $this->view->render($res, 'pages/post_form.twig', ['post' => $post, 'action' => $action]); } @@ -62,12 +65,12 @@ class PostController { $postRequest = PostRequest::fromArray($req->getParsedBody()); if (! $postRequest->isValid()) { - // Simple gestion d'erreur : rediriger vers admin (on peut ajouter flash messages plus tard) return $res->withHeader('Location', '/admin')->withStatus(302); } - $data = $postRequest->validated(); - $this->repo->create($data); + // Utilisation du helper toModel() pour construire l'entité Post + $post = $postRequest->toModel(0); + $this->repo->create($post); return $res->withHeader('Location', '/admin')->withStatus(302); } @@ -76,7 +79,8 @@ class PostController $id = (int)$args['id']; $existing = $this->repo->find($id); if ($existing === null) { - return $res->withStatus(404)->write('Article non trouvé'); + $res->getBody()->write('Article non trouvé'); + return $res->withStatus(404); } $postRequest = PostRequest::fromArray($req->getParsedBody()); @@ -84,8 +88,8 @@ class PostController return $res->withHeader('Location', '/admin')->withStatus(302); } - $data = $postRequest->validated(); - $this->repo->update($id, $data); + $post = $postRequest->toModel($id); + $this->repo->update($id, $post); return $res->withHeader('Location', '/admin')->withStatus(302); } @@ -94,7 +98,8 @@ class PostController $id = (int)$args['id']; $existing = $this->repo->find($id); if ($existing === null) { - return $res->withStatus(404)->write('Article non trouvé'); + $res->getBody()->write('Article non trouvé'); + return $res->withStatus(404); } $this->repo->delete($id); diff --git a/src/Models/Post.php b/src/Models/Post.php new file mode 100644 index 0000000..0aa9ab7 --- /dev/null +++ b/src/Models/Post.php @@ -0,0 +1,78 @@ +id = $id; + $this->title = $title; + $this->content = $content; + } + + /** + * Crée une instance depuis un tableau (par ex. ligne DB ou formulaire). + * + * Ce helper facilite la migration depuis le format tableau existant. + * + * @param array $data Clé 'id' (optionnelle), 'title', 'content' + * @return self + */ + public static function fromArray(array $data): self + { + $id = isset($data['id']) ? (int)$data['id'] : 0; + $title = isset($data['title']) ? (string)$data['title'] : ''; + $content = isset($data['content']) ? (string)$data['content'] : ''; + + return new self($id, $title, $content); + } + + /** @return int */ + public function getId(): int + { + return $this->id; + } + + /** @return string */ + public function getTitle(): string + { + return $this->title; + } + + /** @return string */ + public function getContent(): string + { + return $this->content; + } + + /** + * Retourne un tableau simple utile pour la persistance. + * + * @return array{title:string,content:string} + */ + public function toPersistableArray(): array + { + return [ + 'title' => $this->title, + 'content' => $this->content, + ]; + } +} diff --git a/src/Repositories/PostRepositoryInterface.php b/src/Repositories/PostRepositoryInterface.php index 9350464..5d6b69e 100644 --- a/src/Repositories/PostRepositoryInterface.php +++ b/src/Repositories/PostRepositoryInterface.php @@ -4,6 +4,8 @@ declare(strict_types=1); namespace App\Repositories; +use App\Models\Post; + /** * Interface décrivant les opérations sur les posts. */ @@ -12,7 +14,7 @@ interface PostRepositoryInterface /** * Retourne tous les posts triés par id descendant. * - * @return array + * @return Post[] Tableau d'objets Post */ public function allDesc(): array; @@ -20,26 +22,26 @@ interface PostRepositoryInterface * Trouve un post par son id. * * @param int $id - * @return array{id:int, title:string, content:string}|null + * @return Post|null */ - public function find(int $id): ?array; + public function find(int $id): ?Post; /** * Crée un post. * - * @param array{title:string,content:string} $data + * @param Post $post Instance contenant les données à insérer (id ignoré) * @return int id inséré */ - public function create(array $data): int; + public function create(Post $post): int; /** * Met à jour un post. * * @param int $id - * @param array{title:string,content:string} $data + * @param Post $post Données à mettre à jour (id ignoré) * @return void */ - public function update(int $id, array $data): void; + public function update(int $id, Post $post): void; /** * Supprime un post. diff --git a/src/Repositories/PostRepositoryMedoo.php b/src/Repositories/PostRepositoryMedoo.php index 4592674..ef3c06f 100644 --- a/src/Repositories/PostRepositoryMedoo.php +++ b/src/Repositories/PostRepositoryMedoo.php @@ -5,10 +5,12 @@ declare(strict_types=1); namespace App\Repositories; use Medoo\Medoo; +use App\Models\Post; /** * Repository pour "post" basé sur Medoo. - * Retourne et consomme des tableaux associatifs. + * + * Cette implémentation convertit les lignes DB en objets App\Models\Post. */ class PostRepositoryMedoo implements PostRepositoryInterface { @@ -25,19 +27,23 @@ class PostRepositoryMedoo implements PostRepositoryInterface public function allDesc(): array { $rows = $this->db->select('post', ['id', 'title', 'content'], ['ORDER' => ['id' => 'DESC']]); - return is_array($rows) ? array_map(function ($r) { - return [ - 'id' => (int)($r['id'] ?? 0), - 'title' => (string)($r['title'] ?? ''), - 'content' => (string)($r['content'] ?? ''), - ]; - }, $rows) : []; + if (!is_array($rows)) { + return []; + } + + return array_map(function ($r) { + return new Post( + (int)($r['id'] ?? 0), + (string)($r['title'] ?? ''), + (string)($r['content'] ?? '') + ); + }, $rows); } /** * @inheritDoc */ - public function find(int $id): ?array + public function find(int $id): ?Post { $row = $this->db->get('post', ['id', 'title', 'content'], ['id' => $id]); @@ -45,34 +51,31 @@ class PostRepositoryMedoo implements PostRepositoryInterface return null; } - return [ - 'id' => (int)($row['id'] ?? 0), - 'title' => (string)($row['title'] ?? ''), - 'content' => (string)($row['content'] ?? ''), - ]; + return new Post( + (int)($row['id'] ?? 0), + (string)($row['title'] ?? ''), + (string)($row['content'] ?? '') + ); } /** * @inheritDoc */ - public function create(array $data): int + public function create(Post $post): int { - $this->db->insert('post', [ - 'title' => $data['title'] ?? '', - 'content' => $data['content'] ?? '', - ]); + $data = $post->toPersistableArray(); + + $this->db->insert('post', $data); return (int)$this->db->id(); } /** * @inheritDoc */ - public function update(int $id, array $data): void + public function update(int $id, Post $post): void { - $this->db->update('post', [ - 'title' => $data['title'] ?? '', - 'content' => $data['content'] ?? '', - ], ['id' => $id]); + $data = $post->toPersistableArray(); + $this->db->update('post', $data, ['id' => $id]); } /** diff --git a/src/Requests/PostRequest.php b/src/Requests/PostRequest.php index 624ecdd..7803bb5 100644 --- a/src/Requests/PostRequest.php +++ b/src/Requests/PostRequest.php @@ -4,6 +4,8 @@ declare(strict_types=1); namespace App\Requests; +use App\Models\Post; + /** * Classe simple responsable de la validation / sanitation des données * provenant des formulaires de post. @@ -65,4 +67,17 @@ final class PostRequest { return $this->title !== '' && $this->content !== ''; } + + /** + * Convertit la requête validée en modèle App\Models\Post. + * + * Ce helper facilite la construction d'un Post directement depuis la requête. + * + * @param int $id Identifiant (0 si nouvel enregistrement) + * @return Post + */ + public function toModel(int $id = 0): Post + { + return new Post($id, $this->title, $this->content); + } } diff --git a/views/pages/home.twig b/views/pages/home.twig index 128701e..2126840 100644 --- a/views/pages/home.twig +++ b/views/pages/home.twig @@ -10,5 +10,4 @@ {% else %}

Aucun article publié.

- {% endfor %} -{% endblock %} + {% endblock %} diff --git a/views/pages/post_form.twig b/views/pages/post_form.twig index cbbe43f..a466f48 100644 --- a/views/pages/post_form.twig +++ b/views/pages/post_form.twig @@ -28,7 +28,7 @@

@@ -45,7 +45,7 @@