FabRiviere / Livre_Or_Symfony

Développement du projet concernant un livre d'or sur les conférences. Projet du livre Symfony 6.
0 stars 0 forks source link

Notifications dans le navigateur #43

Closed FabRiviere closed 1 year ago

FabRiviere commented 1 year ago
FabRiviere commented 1 year ago

Modification du ConferenceController.php :


 #[Route('/conference/{slug}', name: 'conference')]
    public function show(Request $request, Conference $conference, CommentRepository $commentRepository,
                            #[Autowire('%photo_dir%')] string $photoDir, NotifierInterface $notifier): Response
    {
        $comment = new Comment();
        $formComment = $this->createForm(CommentType::class, $comment);
        $formComment->handleRequest($request);

        if ($formComment->isSubmitted() && $formComment->isValid()) {
            $comment->setConference($conference);

            //! Traitement des photos
            if ($photo = $formComment['photo']->getData()) {
                $filename = bin2hex(random_bytes(6)).'.'.$photo->guessExtension();
                $photo->move($photoDir, $filename);
                $comment->setPhotoFilename($filename);
            }

            $this->entityManager->persist($comment);
            $this->entityManager->flush();

            //! vérification si présence de spam avant de stocker les commentaires en DB
            $context = [
                'user_ip' => $request->getClientIp(),
                'user_agent' => $request->headers->get('user-agent'),
                'referrer' => $request->headers->get('referer'),
                'permalink' => $request->getUri(),
            ];
            // ! mis en commentaire pour utilisation du MessageBusInterface à la place de SpamChecker
            // if (2 === $spamChecker->getSpamScore($comment, $context)) {
            //     throw new \RuntimeException('Blatant spam, go away !! 😵‍💫😟');
            // }

            // $this->entityManager->flush();
            // ! Utilisation du MessageBusInterface
            $this->bus->dispatch(new CommentMessage($comment->getId(), $context));

            // ! Ajout d'une Notification lorsque succès
            $notifier->send(new Notification('Thank you for the feedback; your comment will be post after moderation.', ['browser']));

            return $this->redirectToRoute('conference', ['slug' => $conference->getSlug()]);
        }

        // ! Ajout d'une Notification lorsque erreur
        if ($formComment->isSubmitted()) {
            $notifier->send(new Notification('Can you check your submission ? There are somme problems with it.', ['browser']));
        }

        $offset = max(0, $request->query->getInt('offset', 0));
        $paginator = $commentRepository->getCommentPaginator($conference, $offset);

        return $this->render('conference/show.html.twig', [
            'conference' => $conference,
            'comments' => $paginator,
            'previous' => $offset - CommentRepository::PAGINATOR_PER_PAGE,
            'next' => min(count($paginator), $offset + CommentRepository::PAGINATOR_PER_PAGE),
            'comment_form' => $formComment,
        ]);
    }

Modification du template show.html.twig :

{% block body %}
    {% for message in app.flashes('notification') %}
        <div class="alert alert-info alert-dismissible fade show">
            {{ message }}
            <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close">
                <span aria-hidden="true">$times;</span>
            </button>
        </div>        
    {% endfor %}
    <h2 class="mb-5">
        {{ conference }} Conference
    </h2>

Modification du CommentMessageHandler.php :

public function __invoke(CommentMessage $message)
    {
        $comment = $this->commentRepository->find($message->getId());
        if (!$comment) {
            return;
        }

        // ! Mis en commentaire pour utilisation du WorkflowInterface
        // if (2 === $this->spamChecker->getSpamScore($comment, $message->getContext())) {
        //     $comment->setState('spam');
        // } else {
        //     $comment->setState('published');
        // }

        // $this->entityManager->flush();

        //! Utilisation du Workflow
        if ($this->commentStateMachine->can($comment, 'accept')) {
            $score = $this->spamChecker->getSpamScore($comment, $message->getContext());
            $transition = match ($score) {
                2 => 'reject_spam',
                1 => 'might_be_spam',
                default => 'accept',
            };
            $this->commentStateMachine->apply($comment, $transition);
            $this->entityManager->flush();
            $this->bus->dispatch($message);
        } elseif ($this->commentStateMachine->can($comment, 'publish') || $this->commentStateMachine->can($comment, 'publish_ham')) {
            $this->notifier->send(new CommentReviewNotification($comment), ...$this->notifier->getAdminRecipients());
        } elseif ($this->logger) {
            $this->logger->debug('Dropping comment message', ['comment' => $comment->getId(), 'state' => $comment->getState()]);
        }
    }

Modification du fichier config/packages/notifier.yaml :

admin_recipients:
            - { email: "%env(string:default:default_admin_email:ADMIN_EMAIL)%" }

Création de la classe CommentReviewNotification.php :

<?php

namespace App\Notification;

use App\Entity\Comment;
use Symfony\Component\Notifier\Message\EmailMessage;
use Symfony\Component\Notifier\Notification\Notification;
use Symfony\Component\Notifier\Notification\EmailNotificationInterface;
use Symfony\Component\Notifier\Recipient\EmailRecipientInterface;

class CommentReviewNotifaction extends Notification implements EmailNotificationInterface
{
    public function __construct(private Comment $comment)
    {
        parent::__construct('New comment posted');
    }

    public function asEmailMessage(EmailRecipientInterface $recipient, string $transport = null): ?EmailMessage
    {
        $message = EmailMessage::fromNotification($this, $recipient, $transport);
        $message->getMessage()
            ->htmlTemplate('emails/comment_notification.html.twig')
            ->context(['comment' => $this->comment])
        ;

        return $message;
    }
}

A continuer avec l'issue #44