From d7695a4e3fb133b3e7ef18a3bbbffa37dd39fc9e Mon Sep 17 00:00:00 2001 From: jgauthi Date: Sun, 11 Jun 2023 12:21:13 +0200 Subject: [PATCH] Messenger: First prototype, fix #1 --- README.md | 46 +++++++++------------- config/packages/messenger.yaml | 2 +- src/DataFixtures/CommentFixtures.php | 15 ++++++- src/Message/SendComment.php | 11 ++---- src/MessageHandler/SendCommentHandler.php | 19 +++++---- src/Service/SendDossierCommentsService.php | 25 +++++++++--- templates/email/new_comment.html.twig | 7 ++-- 7 files changed, 69 insertions(+), 56 deletions(-) diff --git a/README.md b/README.md index 6ed68b5..f869307 100644 --- a/README.md +++ b/README.md @@ -9,26 +9,9 @@ More information on [symfony website](https://symfony.com/doc/6.2/reference/requirements.html). -## Features developed -Messenger showcase. +## Messenger POC +Messenger provides a message bus with the ability to send messages and then handle them immediately in your application or send them through transports (e.g. queues) to be handled later. To learn more deeply about it, read the [Messenger component docs](https://symfony.com/doc/6.2/messenger.htmlcomponents/messenger.html). -**Current study:** Please review, edit and commit them: these files are yours. - -symfony/messenger instructions: - -* You're ready to use the Messenger component. You can define your own message buses - or start using the default one right now by injecting the message_bus service - or type-hinting Symfony\Component\Messenger\MessageBusInterface in your code. - -* To send messages to a transport and handle them asynchronously: - - 1. Update the MESSENGER_TRANSPORT_DSN env var in .env if needed - and framework.messenger.transports.async in config/packages/messenger.yaml; - 2. (if using Doctrine) Generate a Doctrine migration bin/console doctrine:migration:diff - and execute it bin/console doctrine:migration:migrate - 3. Route your message classes to the async transport in config/packages/messenger.yaml. - -* Read the documentation at https://symfony.com/doc/current/messenger.html ## Installation Command lines: @@ -41,24 +24,31 @@ composer install php bin/console doctrine:database:create php bin/console doctrine:migrations:migrate -n - -# Optional -php bin/console doctrine:fixtures:load -n ``` -For the asset symlink install, launch a terminal on administrator in windows environment. ## Usage Just execute this command to run the built-in web server _(require [symfony installer](https://symfony.com/download))_ and access the application in your browser at : ```bash -# Dev env +# Edit "MAILER_DSN" in .env.local with SMTP service (example: mailtrap) + +# Install fixtures (only for dev environnement), start server +symfony console doctrine:fixtures:load -n symfony server:start -# Test env -APP_ENV=test php -d variables_order=EGPCS -S 127.0.0.1:8000 -t public/ +# Launch Messages service +symfony console messenger:consume async ``` -Alternatively, you can [configure a web server](https://symfony.com/doc/current/cookbook/configuration/web_server_configuration.html) like Nginx or Apache to run the application. +Debug commands: + +```shell +php bin/console messenger:consume async -vv + +# Retry failed messages several times (3 attempts) +php bin/console messenger:failed:show +php bin/console messenger:failed:retry +``` -Your commit is checked by several dev tools (like phpstan, php cs fixer...). These tools were managed by [Grumphp](https://github.com/phpro/grumphp), you can edit configuration on file [grumphp.yml](./grumphp.yml) or check manually with the command: `./vendor/bin/grumphp run`. \ No newline at end of file +Enjoy! \ No newline at end of file diff --git a/config/packages/messenger.yaml b/config/packages/messenger.yaml index 17a2dd4..f221e01 100644 --- a/config/packages/messenger.yaml +++ b/config/packages/messenger.yaml @@ -15,4 +15,4 @@ framework: routing: # Route your messages to the transports # 'App\Message\YourMessage': async - # App\Messenger\Message\SendNewsletterMessage: async \ No newline at end of file + App\Message\SendComment: async \ No newline at end of file diff --git a/src/DataFixtures/CommentFixtures.php b/src/DataFixtures/CommentFixtures.php index bfe1c0a..b87c5ae 100644 --- a/src/DataFixtures/CommentFixtures.php +++ b/src/DataFixtures/CommentFixtures.php @@ -2,17 +2,19 @@ namespace App\DataFixtures; use App\Entity\{Comment, Dossier, User}; +use App\Message\SendComment; use Doctrine\Bundle\FixturesBundle\Fixture; use Doctrine\Common\DataFixtures\DependentFixtureInterface; use Doctrine\Persistence\ObjectManager; use Faker\Factory as FakerFactory; +use Symfony\Component\Messenger\MessageBusInterface; class CommentFixtures extends Fixture implements DependentFixtureInterface { public const NB_FIXTURE = 10; private \Faker\Generator $faker; - public function __construct() + public function __construct(private MessageBusInterface $bus) { $this->faker = FakerFactory::create(); } @@ -36,6 +38,17 @@ public function load(ObjectManager $manager): void } $manager->flush(); + + // Add Comments to Symfony BUS + for ($i = 0; $i < self::NB_FIXTURE; ++$i) { + /** @var Comment $comment */ + $comment = $this->getReference("comment_$i"); + if (empty($comment->getId())) { + continue; + } + + $this->bus->dispatch(new SendComment($comment->getId())); + } } public function getDependencies(): array diff --git a/src/Message/SendComment.php b/src/Message/SendComment.php index 3604fa8..ea911ef 100644 --- a/src/Message/SendComment.php +++ b/src/Message/SendComment.php @@ -3,17 +3,12 @@ class SendComment { - public function __construct(private readonly int $userId, private readonly int $dossierId) + public function __construct(private readonly int $commentId) { } - public function getUserId(): int + public function getCommentId(): int { - return $this->userId; - } - - public function getDossierId(): int - { - return $this->dossierId; + return $this->commentId; } } diff --git a/src/MessageHandler/SendCommentHandler.php b/src/MessageHandler/SendCommentHandler.php index 1bf5308..872da70 100644 --- a/src/MessageHandler/SendCommentHandler.php +++ b/src/MessageHandler/SendCommentHandler.php @@ -1,29 +1,28 @@ em->find(User::class, $message->getUserId()); - $comment = $this->em->find(Comment::class, $message->getCommentId()); + $comment = $this->commentRepository->find($message->getCommentId()); - // On vérifie qu'on a toutes les informations nécessaires - if($newsletter !== null && $user !== null){ + if (!empty($comment) && empty($comment->getSent())) { $this->service->send($comment); } } -} \ No newline at end of file +} diff --git a/src/Service/SendDossierCommentsService.php b/src/Service/SendDossierCommentsService.php index 4ffdf85..0b06c0a 100644 --- a/src/Service/SendDossierCommentsService.php +++ b/src/Service/SendDossierCommentsService.php @@ -2,24 +2,39 @@ namespace App\Service; use App\Entity\Comment; +use Doctrine\ORM\EntityManagerInterface; use Symfony\Bridge\Twig\Mime\TemplatedEmail; +use Symfony\Component\Mailer\Exception\TransportExceptionInterface; use Symfony\Component\Mailer\MailerInterface; +use Symfony\Component\Mime\Address; class SendDossierCommentsService { - public function __construct(private readonly MailerInterface $mailer) + public function __construct(private readonly MailerInterface $mailer, private EntityManagerInterface $em) { } + /** + * @throws TransportExceptionInterface + */ public function send(Comment $comment): void { $email = (new TemplatedEmail) - ->from('dossier+comment@sfdemo.fr') - ->to($comment->getDossier()->getAuthor()->getEmail()) + ->from(new Address('dossier+comments@sfdemo.fr', 'SF-Demo')) + ->to(new Address($comment->getDossier()->getAuthor()->getEmail(), $comment->getDossier()->getAuthor()->getName())) ->subject('New comment in folder: '.$comment->getDossier()->getTitle()) - ->htmlTemplate('emails/newsletter.html.twig') + ->htmlTemplate('email/new_comment.html.twig') ->context(compact('comment')) ; + + if (!empty($comment->getAuthor())) { + $email->addCc(new Address($comment->getAuthor()->getEmail(), $comment->getAuthor()->getName())); + } + $this->mailer->send($email); + + $comment->setSent(new \DateTime); + $this->em->persist($comment); + $this->em->flush(); } -} \ No newline at end of file +} diff --git a/templates/email/new_comment.html.twig b/templates/email/new_comment.html.twig index 20ca3ac..c8d209e 100644 --- a/templates/email/new_comment.html.twig +++ b/templates/email/new_comment.html.twig @@ -1,5 +1,6 @@ -

{{ dossier.title }}

+

New comments in dossier: {{ comment.dossier.title }}

+

On {{ comment.createdDate|date('d/m/Y') }}, by {{ comment.author.username|capitalize }}.

- {{newsletter.content|raw}} -
\ No newline at end of file + {{comment.content|nl2br}} +