Commentaires
Nous reviendrons sur la page d'édition de profil plus tard, puisque cette page est accessible aussi par les personnes non administratrices. Cela nous permettra de voir comment gérer notre propre layout.

Arthur, l'apprenti développeurD'accord !

L'affichage de tous les commentaires


On va plutôt continuer nos vues liées à notre panneau d'administration. On va donc faire pour commencer la vue qui permet d'afficher tous nos commentaires. C'est assez simple, ça ressemble grandement à celle qui permet d'afficher tous les utilisateurs.
Simple amélioration, je vais utiliser @if de Blade pour faire une condition et afficher si le commentaire est signalé ou non !
{"language":"text/html","content":"<x-app-layout>\n <x-slot:header>\n <h2 class=\"font-semibold text-xl text-gray-800 leading-tight\">\n Gestion des commentaires\n </h2>\n </x-slot>\n\n <div class=\"py-12\">\n <div class=\"max-w-7xl mx-auto sm:px-6 lg:px-8\">\n <div class=\"bg-white overflow-hidden shadow-sm sm:rounded-lg\">\n <h3 class=\"text-3xl mx-4 my-4\">Les commentaires du site</h3>\n <div class=\"flex flex-col\">\n <div class=\"-my-2 overflow-x-auto sm:-mx-6 lg:-mx-8\">\n <div class=\"py-2 align-middle inline-block min-w-full sm:px-6 lg:px-8\">\n <div class=\"shadow overflow-hidden border-b border-gray-200 sm:rounded-lg\">\n <table class=\"min-w-full divide-y divide-gray-200\">\n <thead class=\"bg-gray-50\">\n <tr>\n <th scope=\"col\" class=\"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider\">\n Titre\n </th>\n <th scope=\"col\" class=\"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider\">\n Auteur\n </th>\n <th scope=\"col\" class=\"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider\">\n Contenu\n </th>\n <th scope=\"col\" class=\"px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider\">\n Statut\n </th>\n <th scope=\"col\" class=\"relative px-6 py-3\">\n <span class=\"sr-only\">Modifier/Supprimer</span>\n </th>\n </tr>\n </thead>\n <tbody class=\"bg-white divide-y divide-gray-200\">\n @foreach($comments as $comment)\n <tr>\n <td class=\"px-6 py-4 whitespace-nowrap\">\n <div class=\"text-sm font-medium text-gray-900\">\n {{ $comment->title }}\n </div>\n </td>\n <td class=\"px-6 py-4 whitespace-nowrap\">\n <div class=\"text-sm font-medium text-gray-900\">\n {{ $comment->author }}\n </div>\n </td>\n <td class=\"px-6 py-4 whitespace-nowrap\">\n <div class=\"text-sm font-medium text-gray-900\">\n {{ $comment->content }}\n </div>\n </td>\n <td class=\"px-6 py-4 whitespace-nowrap\">\n <div class=\"text-sm font-medium text-gray-900\">\n @if($comment->reported)\n <span class=\"text-red-600\">Signalé</span>\n @else\n Non signalé\n @endif\n </div>\n </td>\n <td class=\"px-6 py-4 whitespace-nowrap text-right text-sm font-medium\">\n <a href=\"{{ route('comments.edit', $comment) }}\" class=\"text-indigo-600 hover:text-indigo-900\">Modifier</a>\n <a href=\"{{ route('comments.destroy', $comment) }}\" class=\"text-red-600 hover:text-red-900\">Supprimer</a>\n </td>\n </tr>\n @endforeach\n </tbody>\n </table>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n</x-app-layout>","filename":"resources/views/comments/index.blade.php"}

Arthur, l'apprenti développeurEt comment on pourrait faire pour afficher le titre du post dans lequel a été écrit le commentaire ?
Bien vu Arthur. On va se baser sur les relationships. Dans notre entité Comment on a créé la méthode post qui nous permet de le récupérer ce fameux post. Vois comment on utilise ça :
{"language":"application/x-httpd-php","content":"<td class=\"px-6 py-4 whitespace-nowrap\">\n <div class=\"text-sm font-medium text-gray-900\">\n <a href=\"{{ route('posts.show', $comment->post) }}\">\n {{ $comment->post->title }}\n </a>\n </div>\n</td>","filename":"resources/views/comments/index.blade.php"}

Arthur, l'apprenti développeurTout simplement !
Hé oui, comme souvent dans Laravel, c'est très simple...

La création d'un post


On va passer à la création d'un post maintenant. On va donc traiter les formulaires !

Arthur, l'apprenti développeurIntéressant !
Comme d'habitude on commence par créer notre vue. Ici, ce sera dans resources/views/posts/create.blade.php.
Voici ce que je te propose pour le formulaire. Y'a-t-il des choses qui te choquent ?

{"language":"text/html","content":"<x-app-layout>\n <x-slot:header>\n <h2 class=\"font-semibold text-xl text-gray-800 leading-tight\">\n Gestion des posts\n </h2>\n </x-slot>\n\n <div class=\"py-12\">\n <div class=\"max-w-7xl mx-auto sm:px-6 lg:px-8\">\n <div class=\"bg-white overflow-hidden shadow-sm sm:rounded-lg\">\n <h3 class=\"text-3xl mx-4 my-4\">Création d'un post</h3>\n <form action=\"{{ route('posts.store') }}\" method=\"POST\" class=\"mx-auto\">\n @csrf\n <div class=\"px-4 py-5 bg-white sm:p-6\">\n <div class=\"py-2\">\n <label for=\"title\" class=\"block text-sm font-medium text-gray-700\">Titre</label>\n <input type=\"text\" name=\"title\" id=\"title\" class=\"mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md\">\n </div>\n <div class=\"py-2\">\n <label for=\"content\" class=\"block text-sm font-medium text-gray-700\">Contenu</label>\n <textarea id=\"content\" name=\"content\" rows=\"3\" class=\"shadow-sm focus:ring-indigo-500 focus:border-indigo-500 mt-1 block w-full sm:text-sm border-gray-300 rounded-md\"></textarea>\n </div>\n <div class=\"py-2\">\n <input type=\"submit\" class=\"cursor-pointer inline-flex items-center w-1/4 py-4 border border-gray-400 shadow-sm text-base font-medium rounded-md text-gray-700 bg-white justify-center\" value=\"Créer\">\n </div>\n </div>\n </form>\n </div>\n </div>\n </div>\n</x-app-layout>","filename":"resources/views/posts/create.blade.php"}

Arthur, l'apprenti développeurC'est quoi @csrf ?

Je t'en avais un petit peu parlé, c'est pour éviter que notre site soit sensible à faille CSRF. Cette fonction de blade va gérer un input hidden qui contient un token de sécurité. Si tu fais inspecter l'élément, tu verras à input de cette forme :
{"language":"text/html","content":"<input type=\"hidden\" name=\"_token\" value=\"VY9XpHxUGgfWk7mx9oOgozAPALBAnPWpL7GRLgQA\">","filename":""}

Si on ne le met pas, on aura une erreur lors de la soumission du formulaire. L'utilisation du token CSRF est obligatoire ;)

Arthur, l'apprenti développeurDonc c'est tout ce qu'il faut savoir au niveau des formulaires ?
Non. Tu te rappelles de $request->validate ? Je t'avais dit que si des erreurs étaient soulevées, on retournait au formulaire. Mais il faut maintenant afficher les erreurs ! Qui seront en Français grâce aux traductions qu'on a téléchargées au début du cours ;)
Pour ça, Blade met à notre disposition la fonction @error qu'on utilise comme suit :
{"language":"text/html","content":"<form action=\"{{ route('posts.store') }}\" method=\"POST\" class=\"mx-auto\">\n @csrf\n <div class=\"px-4 py-5 bg-white sm:p-6\">\n <div class=\"py-2\">\n <label for=\"title\" class=\"block text-sm font-medium text-gray-700\">Titre</label>\n <input type=\"text\" name=\"title\" id=\"title\" class=\"mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md\" value=\"{{ old('title') }}\">\n @error('title')\n <span class=\"text-red-600\">{{ $message }}</span>\n @enderror\n </div>\n <div class=\"py-2\">\n <label for=\"content\" class=\"block text-sm font-medium text-gray-700\">Contenu</label>\n <textarea id=\"content\" name=\"content\" rows=\"3\" class=\"shadow-sm focus:ring-indigo-500 focus:border-indigo-500 mt-1 block w-full sm:text-sm border-gray-300 rounded-md\">{{ old('content') }}</textarea>\n @error('content')\n <span class=\"text-red-600\">{{ $message }}</span>\n @enderror\n </div>\n <div class=\"py-2\">\n <input type=\"submit\" class=\"cursor-pointer inline-flex items-center w-1/4 py-4 border border-gray-400 shadow-sm text-base font-medium rounded-md text-gray-700 bg-white justify-center\" value=\"Créer\">\n </div>\n </div>\n</form>","filename":"views/posts/create.blade.php"}

Ce qui serait bien aussi, c'est de remettre les champs avec leur ancienne valeur s'il y a eu une erreur. Encore une fois, Blade a ce qu'il nous faut ! On va utiliser la fonction old().

{"language":"text/html","content":"<input type=\"text\" name=\"title\" id=\"title\" class=\"mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md\" value=\"{{ old('title') }}\">","filename":"views/posts/create.blade.php"}

Et enfin, on retournait un message de succès si tout avait fonctionné. Il serait temps de l'afficher ! Les messages flash sont stockés dans des sessions et comme d'habitude Blade a une fonction pour afficher le contenu d'une clé de session. Au final, notre code ressemble donc à :

{"language":"text/html","content":"<x-app-layout>\n <x-slot:header>\n <h2 class=\"font-semibold text-xl text-gray-800 leading-tight\">\n Gestion des posts\n </h2>\n </x-slot>\n\n <div class=\"py-12\">\n <div class=\"max-w-7xl mx-auto sm:px-6 lg:px-8\">\n <div class=\"bg-white overflow-hidden shadow-sm sm:rounded-lg\">\n <h3 class=\"text-3xl mx-4 my-4\">Création d'un post</h3>\n @if(session('success'))\n <div class=\"text-xl text-green-400\">\n {{ session('success') }}\n </div>\n @endif\n <form action=\"{{ route('posts.store') }}\" method=\"POST\" class=\"mx-auto\">\n @csrf\n <div class=\"px-4 py-5 bg-white sm:p-6\">\n <div class=\"py-2\">\n <label for=\"title\" class=\"block text-sm font-medium text-gray-700\">Titre</label>\n <input type=\"text\" name=\"title\" id=\"title\" class=\"mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md\" value=\"{{ old('title') }}\">\n @error('title')\n <span class=\"text-red-600\">{{ $message }}</span>\n @enderror\n </div>\n <div class=\"py-2\">\n <label for=\"content\" class=\"block text-sm font-medium text-gray-700\">Contenu</label>\n <textarea id=\"content\" name=\"content\" rows=\"3\" class=\"shadow-sm focus:ring-indigo-500 focus:border-indigo-500 mt-1 block w-full sm:text-sm border-gray-300 rounded-md\">{{ old('content') }}</textarea>\n @error('content')\n <span class=\"text-red-600\">{{ $message }}</span>\n @enderror\n </div>\n <div class=\"py-2\">\n <input type=\"submit\" class=\"cursor-pointer inline-flex items-center w-1/4 py-4 border border-gray-400 shadow-sm text-base font-medium rounded-md text-gray-700 bg-white justify-center\" value=\"Créer\">\n </div>\n </div>\n </form>\n </div>\n </div>\n </div>\n</x-app-layout>","filename":"resources/views/posts/create.blade.php"}


Arthur, l'apprenti développeurOn a vu beaucoup de choses ! Mais je suis si impatient de tester !
Hé bien, tu le peux, je te laisse remplir le formulaire et créer ton premier post !

Il nous resterait encore 2 vues à voir du côté du tableau de bord : l'édition des posts et des commentaires. Pour t'entrainer, je ne te fournis pas la solution. Quelques indications tout de même :
- Pour utiliser old() avec une valeur par défaut, on peut faire {{ old('valeur', $valeurParDefaut) }}, par exemple old('title', $post->title)
- Nos routes pour les requêtes d'update sont de type PUT ou PATCH. On ne peut pas préciser ce type de requête dans method="" d'un formulaire, il faut utiliser method="POST" et rajouter un champ hidden généré par Laravel comme @csrf. Dans le cas de PUT, on mettra @method('PUT').

Arthur, l'apprenti développeurOk je vais essayer de faire ça ! Merci !
J'ai terminé cette partie
Demander de l'assistance