requireAuth(); } public function create(): void { $this->renderForm('Nouvel article', $this->f3->alias('post_store'), Post::emptyForm()); } public function store(): void { $this->verifyCsrf(); $media = new Media($this->db); $input = $this->postInput(); try { (new Post($this->db))->create($input, $media); $this->flash('success', 'Article créé.'); $this->f3->reroute('@dashboard'); } catch (RuntimeException $e) { $this->renderForm('Nouvel article', $this->f3->alias('post_store'), $input, $e->getMessage(), $media); } } public function edit(): void { $post = (new Post($this->db))->findForEdit((int) $this->f3->get('PARAMS.id')); if ($post === null) { $this->f3->error(404, 'Article introuvable.'); return; } $this->renderForm('Modifier l\'article', $this->f3->alias('post_update', ['id' => $post['id']]), $post); } public function update(): void { $this->verifyCsrf(); $media = new Media($this->db); $id = (int) $this->f3->get('PARAMS.id'); $input = $this->postInput() + ['id' => $id]; try { $updated = (new Post($this->db))->updatePost($id, $input, $media); if (!$updated) { $this->f3->error(404, 'Article introuvable.'); return; } $this->flash('success', 'Article mis à jour.'); $this->f3->reroute('@dashboard'); } catch (RuntimeException $e) { $this->renderForm('Modifier l\'article', $this->f3->alias('post_update', ['id' => $id]), $input, $e->getMessage(), $media); } } public function delete(): void { $this->verifyCsrf(); try { (new Post($this->db))->delete((int) $this->f3->get('PARAMS.id')); $this->flash('success', 'Article supprimé.'); } catch (RuntimeException $e) { $this->flash('error', $e->getMessage()); } $this->f3->reroute('@dashboard'); } private function renderForm(string $pageTitle, string $formAction, array $post, ?string $error = null, ?Media $media = null): void { $media ??= new Media($this->db); $coverPreview = null; if (!empty($post['cover_media_id'])) { $coverPreview = $media->findById((int) $post['cover_media_id']); } $mediaItems = $media->latest(self::MEDIA_PICKER_LIMIT); $mediaCount = $media->count(); $flash = $error !== null ? ['type' => 'error', 'message' => $error] : null; $this->render('admin/post_form.html', [ 'pageTitle' => $pageTitle, 'formAction' => $formAction, 'post' => $post, 'coverPreview' => $coverPreview, 'mediaItems' => $mediaItems, 'mediaCount' => $mediaCount, 'mediaPickerLimit' => self::MEDIA_PICKER_LIMIT, 'mediaPickerTruncated' => $mediaCount > count($mediaItems), 'titleMax' => Post::TITLE_MAX_LENGTH, 'excerptMax' => Post::EXCERPT_MAX_LENGTH, 'flash' => $flash, ]); } private function postInput(): array { return [ 'title' => trim((string) ($this->f3->get('POST.title') ?? '')), 'excerpt' => trim((string) ($this->f3->get('POST.excerpt') ?? '')), 'cover_media_id' => (string) ($this->f3->get('POST.cover_media_id') ?? ''), 'body_markdown' => trim((string) ($this->f3->get('POST.body_markdown') ?? '')), ]; } }