19. Modifier un article

Préparer le terrain

Il est temps de s'occuper de la modification d'un article. Pour cela on va déjà modifier notre page qui affiche un article en ajoutant un lien de modification.

Ce lien va ponter vers une nouvelle route, qui sera : editArticle

On va devoir créer la route dans le Router, l'action de contrôleur associée, la méthode dans ArticleDAO qui va s'occuper de l'update, ainsi que la vue associée.

Vous vous sentez d'attaque ? Cela est un très bon exercice pour vous entraîner.

On va diviser notre travail en deux parties, on va d'abord se contenter d'afficher l'article et de préremplir les champs de formulaires, on va ensuite s'occuper de faire la mise à jour.

 

Au travail 😉

 

Étape 1 : Afficher l'article et préremplir les champs de formulaire

 

single.php

<?php $this->title = "Article"; ?>
<h1>Mon blog</h1>
<p>En construction</p>
<div>
    <h2><?= htmlspecialchars($article->getTitle());?></h2>
    <p><?= htmlspecialchars($article->getContent());?></p>
    <p><?= htmlspecialchars($article->getAuthor());?></p>
    <p>Créé le : <?= htmlspecialchars($article->getCreatedAt());?></p>
</div>
<br>
<div class="actions">
    <a href="../public/index.php?route=editArticle&articleId=<?= $article->getId(); ?>">Modifier</a>
</div>
<br>
<a href="../public/index.php">Retour à l'accueil</a>
<div id="comments" class="text-left" style="margin-left: 50px">
    <h3>Commentaires</h3>
    <?php
    foreach ($comments as $comment)
    {
        ?>
        <h4><?= htmlspecialchars($comment->getPseudo());?></h4>
        <p><?= htmlspecialchars($comment->getContent());?></p>
        <p>Posté le <?= htmlspecialchars($comment->getCreatedAt());?></p>
        <?php
    }
    ?>
</div>

Ici, on a juste ajouté notre nouvelle route et on lui a passé aussi l'identifiant de l'article, pour savoir quel article modifier.

Dans votre Router, ajoutez votre nouvelle route :

<?php

namespace App\config;
use App\src\controller\BackController;
use App\src\controller\ErrorController;
use App\src\controller\FrontController;
use Exception;

class Router
{
    private $frontController;
    private $errorController;
    private $backController;
    private $request;

    public function __construct()
    {
        $this->request = new Request();
        $this->frontController = new FrontController();
        $this->backController = new BackController();
        $this->errorController = new ErrorController();
    }

    public function run()
    {
        $route = $this->request->getGet()->get('route');
        try{
            if(isset($route))
            {
                if($route === 'article'){
                    $this->frontController->article($this->request->getGet()->get('articleId'));
                }
                elseif ($route === 'addArticle'){
                    $this->backController->addArticle($this->request->getPost());
                }
                elseif ($route === 'editArticle'){
                    $this->backController->editArticle($this->request->getPost(), $this->request->getGet()->get('articleId'));
                }
                else{
                    $this->errorController->errorNotFound();
                }
            }
            else{
                $this->frontController->home();
            }
        }
        catch (Exception $e)
        {
            $this->errorController->errorServer();
        }
    }
}

Dans notre Router...

Passons au contrôleur 😏

 

On va ici créer une nouvelle méthode, appelée editArticle et qui va récupérer l'article existant basé sur son articleId. On finit par renvoyer la vue associée, appelée edit_article.php.

BackController : 

<?php

namespace App\src\controller;

use App\config\Parameter;

class BackController extends Controller
{
    public function addArticle(Parameter $post)
    {
        if($post->get('submit')) {
            $this->articleDAO->addArticle($post);
            $this->session->set('add_article', 'Le nouvel article a bien été ajouté');
            header('Location: ../public/index.php');
        }
        return $this->view->render('add_article', [
            'post' => $post
        ]);
    }

    public function editArticle(Parameter $post, $articleId)
    {
        $article = $this->articleDAO->getArticle($articleId);

        return $this->view->render('edit_article', [
            'article' => $article
        ]);
    }
}

edit_article.php : 

<?php $this->title = "Modifier l'article"; ?>
<h1>Mon blog</h1>
<p>En construction</p>
<div>
    <form method="post" action="../public/index.php?route=editArticle&articleId=<?= htmlspecialchars($article->getId()); ?>">
        <label for="title">Titre</label><br>
        <input type="text" id="title" name="title" value="<?= htmlspecialchars($article->getTitle()); ?>"><br>
        <label for="content">Contenu</label><br>
        <textarea id="content" name="content"><?= htmlspecialchars($article->getContent()); ?></textarea><br>
        <label for="author">Auteur</label><br>
        <input type="text" id="author" name="author" value="<?= htmlspecialchars($article->getAuthor()); ?>"><br>
        <input type="submit" value="Mettre à jour" id="submit" name="submit">
    </form>
    <a href="../public/index.php">Retour à l'accueil</a>
</div>

Ce fichier est en partie le même que add_article créé quelques chapitres plus tôt, dont on a modifié quelquels détails : 

- L'action envoie vers editArticle et prend en paramètre l'articleId.

- Chaque champ récupère la valeur

- Le bouton de soumission a la valeur "mettre à jour".

Si vous passez par l'affichage d'un article et que vous cliquez sur "modifier", vous devriez avoir l'affichage suivant : 


La première étape est maintenant terminée 😄

 

Étape 2 : Mettre à jour l'article dans la base de données

Passons maintenant aux choses sérieuses : la mise à jour de l'article. Pour cela, on suivra le même fonctionnement que pour l'ajout d'article.

Lorsque l'article sera soumis, on mettra à jour l'article en conséquence.

Voici notre contrôleur actualisé : 

<?php

namespace App\src\controller;

use App\config\Parameter;

class BackController extends Controller
{
    public function addArticle(Parameter $post)
    {
        if($post->get('submit')) {
            $this->articleDAO->addArticle($post);
            $this->session->set('add_article', 'Le nouvel article a bien été ajouté');
            header('Location: ../public/index.php');
        }
        return $this->view->render('add_article', [
            'post' => $post
        ]);
    }

    public function editArticle(Parameter $post, $articleId)
    {
        $article = $this->articleDAO->getArticle($articleId);
        if($post->get('submit')) {
            $this->articleDAO->editArticle($post, $articleId);
            $this->session->set('edit_article', 'L\' article a bien été modifié');
            header('Location: ../public/index.php');
        }
        return $this->view->render('edit_article', [
            'article' => $article
        ]);
    }
}

On doit aussi mettre à jour ArticleDAO.php en ajoutant la méthode editArticle

<?php

namespace App\src\DAO;

use App\config\Parameter;
use App\src\model\Article;

class ArticleDAO extends DAO
{
    //...

    public function editArticle(Parameter $post, $articleId)
    {
        $sql = 'UPDATE article SET title=:title, content=:content, author=:author WHERE id=:articleId';
        $this->createQuery($sql, [
            'title' => $post->get('title'),
            'content' => $post->get('content'),
            'author' => $post->get('author'),
            'articleId' => $articleId
        ]);
    }
}

Il nous reste maintenant à modifier notre fichier home.php (pour afficher le message de modification). Ajoutez la ligne suivante dans le fichier : 

<?= $this->session->show('edit_article'); ?>

Il ne nous reste plus qu'à essayer pour vérifier que tout fonctionne. Ouvrez un article, essayez de modifier son contenu et soumettez vos données...

La modification fonctionne 😉

 

Bilan

Dans ce chapitre, nous avons mis en place la fonctionnalité de modification d'un article.

Vous pouvez retrouver le code associé à ce chapitre sur GitHub.