Quellcode durchsuchen

Modification du voter pour gérer l'aperçu (view)

Sangfroid vor 2 Monaten
Ursprung
Commit
0cd944d969

+ 12 - 0
assets/styles/app.css

@@ -247,6 +247,18 @@ main h1 a:hover {
   display: none !important;
 }
 
+.unpublished {
+  display: block;
+  margin: 0px;
+  padding: 20px;
+  border-radius: 15px;
+  background-color: rgb(197, 109, 9);
+  color : white;
+  text-align: center;
+  font-weight: bold;
+  font-size: 1.5em;
+}
+
 @media screen and (max-width: 1400px) {
   #header {
     height: 250px;

+ 3 - 3
src/Controller/ArticleController.php

@@ -58,7 +58,7 @@ final class ArticleController extends AbstractController
             $entityManager->persist($article);
             $entityManager->flush();
 
-            return $this->redirectToRoute('app_article_index', [], Response::HTTP_SEE_OTHER);
+            return $this->redirectToRoute('app_view', ['slug' => $article->getSlug()], Response::HTTP_SEE_OTHER);
         }
 
         return $this->render('article/new.html.twig', [
@@ -68,7 +68,7 @@ final class ArticleController extends AbstractController
     }
 
     #[Route('/{id}', name: 'app_article_show', methods: ['GET'])]
-    #[IsGranted('view', 'article')]
+    #[IsGranted('show', 'article')]
     public function show(Article $article): Response
     {
         return $this->render('article/show.html.twig', [
@@ -106,7 +106,7 @@ final class ArticleController extends AbstractController
 
             $entityManager->flush();
 
-            return $this->redirectToRoute('app_article_index', [], Response::HTTP_SEE_OTHER);
+            return $this->redirectToRoute('app_view', ['slug' => $article->getSlug()], Response::HTTP_SEE_OTHER);
         }
 
         return $this->render('article/edit.html.twig', [

+ 2 - 0
src/Controller/ViewController.php

@@ -7,10 +7,12 @@ use Symfony\Bridge\Doctrine\Attribute\MapEntity;
 use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
 use Symfony\Component\HttpFoundation\Response;
 use Symfony\Component\Routing\Attribute\Route;
+use Symfony\Component\Security\Http\Attribute\IsGranted;
 
 class ViewController extends AbstractController
 {
     #[Route('/post/{slug}', name: 'app_view')]
+    #[IsGranted('view', 'article')]
     public function index(
         #[MapEntity(mapping: ['slug' => 'slug'])]
         Article $article

+ 21 - 10
src/Security/Voter/ArticleVoter.php

@@ -11,11 +11,12 @@ use Symfony\Component\Security\Core\Authorization\Voter\Voter;
 final class ArticleVoter extends Voter
 {
     public const EDIT = 'edit';
+    public const SHOW = 'show';
     public const VIEW = 'view';
     public const PUBLISH = 'publish';
 
     public function __construct(
-        private readonly Security $security
+        private readonly Security $security,
     )
     {
         
@@ -25,7 +26,7 @@ final class ArticleVoter extends Voter
     {
         // replace with your own logic
         // https://symfony.com/doc/current/security/voters.html
-        return in_array($attribute, [self::EDIT, self::VIEW, self::PUBLISH])
+        return in_array($attribute, [self::EDIT, self::VIEW, self::PUBLISH, self::SHOW])
             && $subject instanceof \App\Entity\Article;
     }
 
@@ -33,32 +34,42 @@ final class ArticleVoter extends Voter
     {
         $user = $token->getUser();
 
-        // if the user is anonymous, do not grant access
-        if (!$user instanceof User) {
-            return false;
-        }
+        // // if the user is anonymous, do not grant access
+        // if (!$user instanceof User) {
+        //     return false;
+        // }
 
         $article = $subject;
 
         return match($attribute) {
             self::VIEW => $this->canView($article, $user),
+            self::SHOW => $this->canShow($article, $user),
             self::EDIT => $this->canEdit($article, $user),
             self::PUBLISH => $this->canPublish($article, $user),
             default => throw new \LogicException('This code should not be reached!')
         };
     }
 
-    private function canView(Article $article, User $user): bool
+    private function canView(Article $article, ?User $user): bool
     {
-        return $this->canEdit($article, $user);
+        return $article->getState() === 'published' || $this->canEdit($article, $user);
     }
 
-    private function canEdit(Article $article, User $user): bool
+    private function canShow(Article $article, ?User $user): bool
     {
+        return $this->canEdit($article, $user) || $this->security->isGranted('ROLE_MODERATOR');
+    }
+
+    private function canEdit(Article $article, ?User $user): bool
+    {
+        if(!$user instanceof User) {
+            return false;
+        }
+ 
         return $user === $article->getAuthor() || $this->security->isGranted('ROLE_ADMIN');
     }
 
-    private function canPublish(Article $article, User $user) :bool
+    private function canPublish(Article $article, ?User $user) :bool
     {
         if ($this->canEdit($article, $user) && $article->getState() !== 'reviewed') {
             return true;

+ 1 - 1
templates/article/index.html.twig

@@ -29,7 +29,7 @@
                 <td><span class="badge badge-{{ article.state }}">{{ article.state | trans }}</span></td>
                 <td>{{ article.author }}</td>
                 <td>
-                    {% if is_granted('view', article) %}
+                    {% if is_granted('show', article) %}
                     <a href="{{ path('app_article_show', {'id': article.id}) }}" class="btn btn-blue">Voir</a>
                     {% endif %}
 

+ 5 - 0
templates/article/show.html.twig

@@ -15,6 +15,10 @@
                 <th>Titre</th>
                 <td>{{ article.title }}</td>
             </tr>
+            <tr>
+                <th>Permalien</th>
+                <td>{{ article.slug }}</td>
+            </tr>
             <tr>
                 <th>Date de publication</th>
                 <td>{{ article.publicationDate ? article.publicationDate|date('Y-m-d H:i:s') : '' }}</td>
@@ -36,6 +40,7 @@
     <a href="{{ path('app_article_index') }}">Retour à la liste</a>
 
     <a href="{{ path('app_article_edit', {'id': article.id}) }}" class="btn btn-blue">Editer</a>
+    <a href="{{ path('app_view', {'slug': article.slug}) }}" class="btn btn-green">Aperçu</a>
 
     {{ include('article/_delete_form.html.twig') }}
     {{ include('article/_bouton_agrandir.html.twig') }}

+ 7 - 0
templates/view/index.html.twig

@@ -4,6 +4,13 @@
 
 {% block body %}
 <a href="{{ path('app_index')}}">Retour au blog</a>
+
+{% if not workflow_has_marked_place(article, 'published') %}
+<div class="unpublished">
+    {{ article.state | trans }}
+</div>
+{% endif %}
+
 <div>
     <article class="article">
         <header>