requireAuth(); $this->disableCache(); } public function create(): void { $this->renderForm('Nouvel article', $this->f3->alias('post_store'), Post::emptyForm()); } public function store(): void { $this->verifyCsrf(); $input = $this->postInput(); try { (new Post($this->db))->create($input); Cache::instance()->reset('.url'); // invalide le cache des pages publiques $this->flash('success', 'Article créé.'); $this->f3->reroute('@dashboard'); } catch (RuntimeException $e) { $this->renderForm('Nouvel article', $this->f3->alias('post_store'), $input, $e->getMessage()); } } 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(); $id = (int) $this->f3->get('PARAMS.id'); $input = $this->postInput() + ['id' => $id]; try { $updated = (new Post($this->db))->updatePost($id, $input); if (!$updated) { $this->f3->error(404, 'Article introuvable.'); return; } Cache::instance()->reset('.url'); // invalide le cache des pages publiques $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()); } } public function delete(): void { $this->verifyCsrf(); (new Post($this->db))->delete((int) $this->f3->get('PARAMS.id')); Cache::instance()->reset('.url'); // invalide le cache des pages publiques $this->flash('success', 'Article supprimé.'); $this->f3->reroute('@dashboard'); } private function renderForm(string $pageTitle, string $formAction, array $post, ?string $error = null): void { $coverPreview = null; if (!empty($post['cover_media_id'])) { $coverPreview = (new Media($this->db))->findById((int) $post['cover_media_id']); } $media = new Media($this->db); $mediaItems = $media->latest(self::MEDIA_PICKER_LIMIT); $mediaCount = $media->countAll(); $flash = $error !== null ? ['type' => 'error', 'message' => $error] : null; $this->renderSession('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, ], true); } 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') ?? '')), ]; } }