Création et modification des articles

C'est génial ! Nous avons un nouveau blog super cool, les gens discutent avec acharnement dans les commentaires et nous avons enfin un peu de temps pour programmer davantage. Bien qu'Adminer soit un excellent outil, il n'est pas tout à fait idéal pour écrire de nouveaux articles de blog. Il est probablement temps de créer un formulaire simple pour ajouter de nouveaux articles directement depuis l'application. Allons-y.

Commençons par concevoir l'interface utilisateur :

  1. Sur la page d'accueil, ajoutons un lien “Écrire un nouvel article”.
  2. Ce lien affichera un formulaire avec un titre et une zone de texte pour le contenu de l'article.
  3. Lorsque nous cliquons sur le bouton Enregistrer, l'article sera enregistré dans la base de données.

Plus tard, nous ajouterons également la connexion et autoriserons l'ajout d'articles uniquement aux utilisateurs connectés. Mais cela viendra plus tard. Quel code devons-nous écrire maintenant pour que tout fonctionne ?

  1. Créons un nouveau presenter avec un formulaire pour ajouter des articles.
  2. Définissons un callback qui se déclenchera après la soumission réussie du formulaire et qui enregistrera le nouvel article dans la base de données.
  3. Créons un nouveau template sur lequel se trouvera ce formulaire.
  4. Ajoutons un lien vers le formulaire dans le template de la page principale.

Nouveau Presenter

Nous appellerons le nouveau presenter EditPresenter et le sauvegarderons dans app/Presentation/Edit/. Il doit également se connecter à la base de données, nous écrirons donc à nouveau un constructeur qui nécessitera une connexion à la base de données :

<?php
namespace App\Presentation\Edit;

use Nette;
use Nette\Application\UI\Form;

final class EditPresenter extends Nette\Application\UI\Presenter
{
	public function __construct(
		private Nette\Database\Explorer $database,
	) {
	}
}

Formulaire de sauvegarde des articles

Nous avons déjà expliqué les formulaires et les composants lors de la création des commentaires. Si ce n'est toujours pas clair, allez consulter la création de formulaires et de composants, nous attendrons ici ;)

Maintenant, ajoutons cette méthode au presenter EditPresenter :

protected function createComponentPostForm(): Form
{
	$form = new Form;
	$form->addText('title', 'Titre :')
		->setRequired();
	$form->addTextArea('content', 'Contenu :')
		->setRequired();

	$form->addSubmit('send', 'Sauvegarder et publier');
	$form->onSuccess[] = $this->postFormSucceeded(...);

	return $form;
}

Sauvegarde d'un nouvel article depuis le formulaire

Continuons en ajoutant une méthode qui traitera les données du formulaire :

private function postFormSucceeded(array $data): void
{
	$post = $this->database
		->table('posts')
		->insert($data);

	$this->flashMessage("L'article a été publié avec succès.", 'success');
	$this->redirect('Post:show', $post->id);
}

Juste un rapide récapitulatif : cette méthode récupère les données du formulaire ($data est un tableau), les insère dans la table posts de la base de données, crée un message flash pour l'utilisateur indiquant que l'article a été sauvegardé avec succès, et redirige vers la page affichant le nouvel article (Post:show) afin que nous puissions voir immédiatement à quoi il ressemble.

Page de création d'un nouvel article

Créons maintenant le template Edit/create.latte :

{block content}
<h1>Nouvel article</h1>

{control postForm}

Tout devrait être clair maintenant. La dernière ligne affiche le formulaire que nous avons défini dans le presenter.

Nous pourrions également créer une méthode renderCreate correspondante, mais ce n'est pas nécessaire. Nous n'avons pas besoin de récupérer de données de la base de données et de les transmettre au template, donc cette méthode serait vide. Dans de tels cas, la méthode n'a pas besoin d'exister du tout.

Lien vers la création d'articles

Vous savez probablement déjà comment ajouter un lien vers EditPresenter et son action create. Essayez-le.

Il suffit d'ajouter au fichier app/Presentation/Home/default.latte :

<a n:href="Edit:create">Écrire un nouvel article</a>

Modification des articles

Maintenant, ajoutons également la possibilité de modifier un article. Ce sera très simple. Nous avons déjà le formulaire postForm prêt et nous pouvons l'utiliser également pour la modification.

Ajoutons une nouvelle action edit (et sa vue renderEdit) au presenter EditPresenter :

public function renderEdit(int $id): void
{
	$post = $this->database
		->table('posts')
		->get($id);

	if (!$post) {
		$this->error('Article non trouvé');
	}

	$this->getComponent('postForm')
		->setDefaults($post->toArray());
}

Et créons le template Edit/edit.latte :

{block content}
<h1>Modifier l'article</h1>

{control postForm}

Maintenant, nous devons modifier la méthode postFormSucceeded, qui sera capable à la fois d'ajouter un nouvel article (comme elle le fait maintenant) et de modifier un article existant :

private function postFormSucceeded(array $data): void
{
	$id = $this->getParameter('id');

	if ($id) {
		$post = $this->database
			->table('posts')
			->get($id);
		$post->update($data);

	} else {
		$post = $this->database
			->table('posts')
			->insert($data);
	}

	$this->flashMessage('L\'article a été publié avec succès.', 'success');
	$this->redirect('Post:show', $post->id);
}

La méthode vérifie maintenant si le paramètre id est présent dans la requête. S'il l'est, cela signifie que nous modifions un article existant. Nous récupérons l'article et mettons à jour ses données avec $post->update($data). S'il n'y a pas de paramètre id, nous insérons un nouvel article comme avant avec $this->database->table('posts')->insert($data).

Mais d'où vient ce paramètre id ? Il s'agit du paramètre qui a été passé à la méthode renderEdit.

Nous pouvons maintenant ajouter un lien dans le template app/Presentation/Post/show.latte pour permettre la modification :

<a n:href="Edit:edit $post->id">Modifier l'article</a>

Résumé

Le blog est maintenant fonctionnel, les visiteurs le commentent activement et nous n'avons plus besoin d'Adminer pour publier. L'application est entièrement indépendante et n'importe qui peut ajouter un nouvel article. Attendez une minute, ce n'est probablement pas tout à fait correct que n'importe qui – et je veux dire vraiment n'importe qui ayant accès à Internet – puisse ajouter de nouveaux articles. Une certaine sécurité est nécessaire pour que seul un utilisateur connecté puisse ajouter un nouvel article. Nous examinerons cela dans le prochain chapitre.