From 62d98a7ea308ee20142dbc18597222aecafccb08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Stan=C4=9Bk?= Date: Fri, 13 Oct 2023 16:20:52 +0200 Subject: [PATCH] send mails from queue --- app/ApiModule/Presenters/MailPresenter.php | 9 + app/Mailing/SrsMail.php | 8 +- app/Mailing/SrsMailData.php | 15 +- .../Commands/Handlers/CreateMailHandler.php | 25 ++- .../Handlers/CreateTemplateMailHandler.php | 9 +- .../Commands/Handlers/SendMailsHandler.php | 51 ++++++ app/Model/Mailing/Commands/SendMails.php | 12 ++ app/Model/Mailing/MailQueue.php | 19 +- .../Repositories/MailQueueRepository.php | 15 ++ app/Services/IMailService.php | 32 ---- app/Services/MailService.php | 163 ------------------ 11 files changed, 133 insertions(+), 225 deletions(-) create mode 100644 app/Model/Mailing/Commands/Handlers/SendMailsHandler.php create mode 100644 app/Model/Mailing/Commands/SendMails.php delete mode 100644 app/Services/IMailService.php delete mode 100644 app/Services/MailService.php diff --git a/app/ApiModule/Presenters/MailPresenter.php b/app/ApiModule/Presenters/MailPresenter.php index 7e47bf148..99488fe45 100644 --- a/app/ApiModule/Presenters/MailPresenter.php +++ b/app/ApiModule/Presenters/MailPresenter.php @@ -6,6 +6,7 @@ use App\Model\Acl\Permission; use App\Model\Acl\SrsResource; +use App\Model\Mailing\Commands\SendMails; use App\Model\Settings\Commands\SetSettingStringValue; use App\Model\Settings\Queries\SettingStringValueQuery; use App\Model\Settings\Settings; @@ -26,6 +27,14 @@ class MailPresenter extends ApiBasePresenter #[Inject] public QueryBus $queryBus; + /** + * Odešle e-maily z fronty. + */ + public function actionSend(): void + { + $this->commandBus->handle(new SendMails()); + } + /** * Ověří e-mail semináře. * diff --git a/app/Mailing/SrsMail.php b/app/Mailing/SrsMail.php index 0aab9cf1a..083921340 100644 --- a/app/Mailing/SrsMail.php +++ b/app/Mailing/SrsMail.php @@ -18,13 +18,7 @@ class SrsMail extends AbstractMail implements IComposableMail public function compose(Message $message, IMessageData|null $mailData = null): void { $message->setFrom($mailData->getFrom()->getEmail(), $mailData->getFrom()->getName()); - - foreach ($mailData->getRecipients() as $recipient) { - if (! empty($recipient->getEmail())) { - $message->addBcc($recipient->getEmail(), $recipient->getName()); - } - } - + $message->addTo($mailData->getTo()->getEmail(), $mailData->getTo()->getName()); $message->setSubject($mailData->getSubject()); $this->template->subject = $mailData->getSubject(); diff --git a/app/Mailing/SrsMailData.php b/app/Mailing/SrsMailData.php index 2d1a5eb47..9bac4dc98 100644 --- a/app/Mailing/SrsMailData.php +++ b/app/Mailing/SrsMailData.php @@ -13,14 +13,14 @@ class SrsMailData implements IMessageData { /** - * @param Recipient $from Odesilatel mailu. - * @param Recipient[] $recipients Příjemci mailu. - * @param string $subject Předmět mailu. - * @param string $text Text mailu. + * @param Recipient $from Odesilatel mailu. + * @param Recipient $to Příjemce mailu. + * @param string $subject Předmět mailu. + * @param string $text Text mailu. */ public function __construct( private readonly Recipient $from, - private readonly array $recipients, + private readonly Recipient $to, private readonly string $subject, private readonly string $text, ) { @@ -31,10 +31,9 @@ public function getFrom(): Recipient return $this->from; } - /** @return Recipient[] */ - public function getRecipients(): array + public function getTo(): Recipient { - return $this->recipients; + return $this->to; } public function getSubject(): string diff --git a/app/Model/Mailing/Commands/Handlers/CreateMailHandler.php b/app/Model/Mailing/Commands/Handlers/CreateMailHandler.php index b9eab2056..9161f7113 100644 --- a/app/Model/Mailing/Commands/Handlers/CreateMailHandler.php +++ b/app/Model/Mailing/Commands/Handlers/CreateMailHandler.php @@ -4,22 +4,31 @@ namespace App\Model\Mailing\Commands\Handlers; +use App\Model\Acl\Repositories\RoleRepository; use App\Model\Mailing\Commands\CreateMail; use App\Model\Mailing\Mail; use App\Model\Mailing\MailQueue; +use App\Model\Mailing\Recipient; use App\Model\Mailing\Repositories\MailQueueRepository; use App\Model\Mailing\Repositories\MailRepository; +use App\Model\Structure\Repositories\SubeventRepository; +use App\Model\User\Repositories\UserRepository; use DateTimeImmutable; use Doctrine\ORM\EntityManagerInterface; use function array_unique; +use const SORT_REGULAR; + class CreateMailHandler { public function __construct( private readonly EntityManagerInterface $em, private readonly MailRepository $mailRepository, private readonly MailQueueRepository $mailQueueRepository, + private readonly UserRepository $userRepository, + private readonly RoleRepository $roleRepository, + private readonly SubeventRepository $subeventRepository, ) { } @@ -32,28 +41,30 @@ public function __invoke(CreateMail $command): void if ($command->getRecipientUsers() !== null) { $mail->setRecipientUsers($command->getRecipientUsers()); foreach ($command->getRecipientUsers() as $user) { - $recipients[] = $user->getEmail(); + $recipients[] = Recipient::createFromUser($user); } } if ($command->getRecipientRoles() !== null) { $mail->setRecipientRoles($command->getRecipientRoles()); - foreach ($command->getRecipientUsers() as $user) { //todo - $recipients[] = $user->getEmail(); + $rolesIds = $this->roleRepository->findRolesIds($command->getRecipientRoles()); + foreach ($this->userRepository->findAllApprovedInRoles($rolesIds) as $user) { + $recipients[] = Recipient::createFromUser($user); } } if ($command->getRecipientSubevents() !== null) { $mail->setRecipientSubevents($command->getRecipientSubevents()); - foreach ($command->getRecipientUsers() as $user) { //todo - $recipients[] = $user->getEmail(); + $subeventsIds = $this->subeventRepository->findSubeventsIds($command->getRecipientSubevents()); + foreach ($this->userRepository->findAllWithSubevents($subeventsIds) as $user) { + $recipients[] = Recipient::createFromUser($user); } } if ($command->getRecipientEmails() !== null) { $mail->setRecipientEmails($command->getRecipientEmails()->toArray()); foreach ($command->getRecipientEmails() as $email) { - $recipients[] = $email; + $recipients[] = new Recipient($email); } } @@ -64,7 +75,7 @@ public function __invoke(CreateMail $command): void $this->mailRepository->save($mail); - foreach (array_unique($recipients) as $recipient) { + foreach (array_unique($recipients, SORT_REGULAR) as $recipient) { $this->mailQueueRepository->save(new MailQueue($recipient, $mail, new DateTimeImmutable())); } }); diff --git a/app/Model/Mailing/Commands/Handlers/CreateTemplateMailHandler.php b/app/Model/Mailing/Commands/Handlers/CreateTemplateMailHandler.php index f0eaef9e5..213f0153d 100644 --- a/app/Model/Mailing/Commands/Handlers/CreateTemplateMailHandler.php +++ b/app/Model/Mailing/Commands/Handlers/CreateTemplateMailHandler.php @@ -7,6 +7,7 @@ use App\Model\Mailing\Commands\CreateTemplateMail; use App\Model\Mailing\Mail; use App\Model\Mailing\MailQueue; +use App\Model\Mailing\Recipient; use App\Model\Mailing\Repositories\MailQueueRepository; use App\Model\Mailing\Repositories\MailRepository; use App\Model\Mailing\Repositories\TemplateRepository; @@ -18,6 +19,8 @@ use function str_replace; use function strval; +use const SORT_REGULAR; + class CreateTemplateMailHandler { public function __construct( @@ -55,14 +58,14 @@ public function __invoke(CreateTemplateMail $command): void if ($command->getRecipientUsers() !== null) { $mail->setRecipientUsers($command->getRecipientUsers()); foreach ($command->getRecipientUsers() as $user) { - $recipients[] = $user->getEmail(); + $recipients[] = Recipient::createFromUser($user); } } if ($command->getRecipientEmails() !== null) { $mail->setRecipientEmails($command->getRecipientEmails()->toArray()); foreach ($command->getRecipientEmails() as $email) { - $recipients[] = $email; + $recipients[] = new Recipient($email); } } @@ -73,7 +76,7 @@ public function __invoke(CreateTemplateMail $command): void $this->mailRepository->save($mail); - foreach (array_unique($recipients) as $recipient) { + foreach (array_unique($recipients, SORT_REGULAR) as $recipient) { $this->mailQueueRepository->save(new MailQueue($recipient, $mail, new DateTimeImmutable())); } }); diff --git a/app/Model/Mailing/Commands/Handlers/SendMailsHandler.php b/app/Model/Mailing/Commands/Handlers/SendMailsHandler.php new file mode 100644 index 000000000..99105ce8f --- /dev/null +++ b/app/Model/Mailing/Commands/Handlers/SendMailsHandler.php @@ -0,0 +1,51 @@ +mailQueueRepository->findMailsToSend(50); + + if ($mailsToSend->isEmpty()) { + return; + } + + $from = new Recipient( + $this->queryBus->handle(new SettingStringValueQuery(Settings::SEMINAR_EMAIL)), + $this->queryBus->handle(new SettingStringValueQuery(Settings::SEMINAR_NAME)), + ); + + foreach ($mailsToSend as $mailToSend) { + $to = new Recipient($mailToSend->getRecipientEmail(), $mailToSend->getRecipientName()); + $messageData = new SrsMailData($from, $to, $mailToSend->getMail()->getSubject(), $mailToSend->getMail()->getText()); + $mail = $this->mailFactory->createByType(SrsMail::class, $messageData); + $mail->send(); + + $mailToSend->setSent(true); + $mailToSend->setSendDatetime(new DateTimeImmutable()); + $this->mailQueueRepository->save($mailToSend); + } + } +} diff --git a/app/Model/Mailing/Commands/SendMails.php b/app/Model/Mailing/Commands/SendMails.php new file mode 100644 index 000000000..13563d39b --- /dev/null +++ b/app/Model/Mailing/Commands/SendMails.php @@ -0,0 +1,12 @@ +recipient = $recipient; + $this->recipientEmail = $recipient->getEmail(); + $this->recipientName = $recipient->getName(); $this->mail = $mail; $this->enqueueDatetime = $enqueueDatetime; } @@ -52,9 +56,14 @@ public function getId(): int|null return $this->id; } - public function getRecipient(): string + public function getRecipientEmail(): string + { + return $this->recipientEmail; + } + + public function getRecipientName(): string|null { - return $this->recipient; + return $this->recipientName; } public function getMail(): Mail diff --git a/app/Model/Mailing/Repositories/MailQueueRepository.php b/app/Model/Mailing/Repositories/MailQueueRepository.php index 12f8508c3..9b4d563d4 100644 --- a/app/Model/Mailing/Repositories/MailQueueRepository.php +++ b/app/Model/Mailing/Repositories/MailQueueRepository.php @@ -6,6 +6,8 @@ use App\Model\Infrastructure\Repositories\AbstractRepository; use App\Model\Mailing\MailQueue; +use Doctrine\Common\Collections\ArrayCollection; +use Doctrine\Common\Collections\Collection; use Doctrine\ORM\EntityManagerInterface; /** @@ -18,6 +20,19 @@ public function __construct(EntityManagerInterface $em) parent::__construct($em, MailQueue::class); } + /** @return Collection */ + public function findMailsToSend(int $limit): Collection + { + $result = $this->createQueryBuilder('m') + ->where('m.sent = false') + ->orderBy('m.enqueueDatetime') + ->setMaxResults($limit) + ->getQuery() + ->getResult(); + + return new ArrayCollection($result); + } + /** * Uloží e-mail. */ diff --git a/app/Services/IMailService.php b/app/Services/IMailService.php deleted file mode 100644 index 006bf5a97..000000000 --- a/app/Services/IMailService.php +++ /dev/null @@ -1,32 +0,0 @@ -|null $recipientsRoles - * @param Collection|null $recipientsSubevents - * @param Collection|null $recipientsUsers - * @param Collection|null $recipientEmails - */ - public function sendMail(Collection|null $recipientsRoles, Collection|null $recipientsSubevents, Collection|null $recipientsUsers, Collection|null $recipientEmails, string $subject, string $text, bool $automatic = false): void; - - /** - * Rozešle e-mail podle šablony. - * - * @param Collection|null $recipientsUsers - * @param Collection|null $recipientsEmails - * @param string[] $parameters - */ - public function sendMailFromTemplate(Collection|null $recipientsUsers, Collection|null $recipientsEmails, string $type, array $parameters): void; -} diff --git a/app/Services/MailService.php b/app/Services/MailService.php deleted file mode 100644 index e723bf3f6..000000000 --- a/app/Services/MailService.php +++ /dev/null @@ -1,163 +0,0 @@ -|null $recipientsRoles - * @param Collection|null $recipientsSubevents - * @param Collection|null $recipientsUsers - * @param Collection|null $recipientEmails - * - * @throws Throwable - * @throws MailingMailCreationException - */ - public function sendMail(Collection|null $recipientsRoles, Collection|null $recipientsSubevents, Collection|null $recipientsUsers, Collection|null $recipientEmails, string $subject, string $text, bool $automatic = false): void - { - $recipients = []; - - if ($recipientsRoles !== null) { - foreach ($this->userRepository->findAllApprovedInRoles($this->roleRepository->findRolesIds($recipientsRoles)) as $user) { - $recipient = Recipient::createFromUser($user); - if (! in_array($recipient, $recipients)) { - $recipients[] = $recipient; - } - } - } - - if ($recipientsSubevents !== null) { - foreach ($this->userRepository->findAllWithSubevents($this->subeventRepository->findSubeventsIds($recipientsSubevents)) as $user) { - $recipient = Recipient::createFromUser($user); - if (! in_array($recipient, $recipients)) { - $recipients[] = $recipient; - } - } - } - - if ($recipientsUsers !== null) { - foreach ($recipientsUsers as $user) { - $recipient = Recipient::createFromUser($user); - if (! in_array($recipient, $recipients)) { - $recipients[] = $recipient; - } - } - } - - if ($recipientEmails !== null) { - foreach ($recipientEmails as $email) { - $recipient = new Recipient($email); - if (! in_array($recipient, $recipients)) { - $recipients[] = $recipient; - } - } - } - - $from = new Recipient($this->queryBus->handle(new SettingStringValueQuery(Settings::SEMINAR_EMAIL)), $this->queryBus->handle(new SettingStringValueQuery(Settings::SEMINAR_NAME))); - - $messageData = new SrsMailData($from, $recipients, $subject, $text); - $mail = $this->mailFactory->createByType(SrsMail::class, $messageData); - $mail->send(); - - $mailLog = new Mail(); - - if ($recipientsRoles !== null) { - $mailLog->setRecipientRoles($recipientsRoles); - } - - if ($recipientsSubevents !== null) { - $mailLog->setRecipientSubevents($recipientsSubevents); - } - - if ($recipientsUsers !== null) { - $mailLog->setRecipientUsers($recipientsUsers); - } - - $mailLog->setSubject($subject); - $mailLog->setText($text); - $mailLog->setDatetime(new DateTimeImmutable()); - $mailLog->setAutomatic($automatic); - $this->mailRepository->save($mailLog); - } - - /** - * Rozešle e-mail podle šablony. - * - * @param Collection|null $recipientsUsers - * @param Collection|null $recipientsEmails - * @param mixed[] $parameters - * - * @throws MailingMailCreationException - * @throws SettingsItemNotFoundException - * @throws Throwable - */ - public function sendMailFromTemplate(Collection|null $recipientsUsers, Collection|null $recipientsEmails, string $type, array $parameters): void - { - $template = $this->templateRepository->findByType($type); - - if (! $template->isActive()) { - return; - } - - $subject = $template->getSubject(); - $text = $template->getText(); - - foreach ($template->getVariables() as $variable) { - $variableName = '%' . $this->translator->translate('common.mailing.variable_name.' . $variable->getName()) . '%'; - $value = $parameters[$variable->getName()]; - - $subject = str_replace($variableName, strval($value), $subject); - $text = str_replace($variableName, strval($value), $text); - } - - $this->sendMail(null, null, $recipientsUsers, $recipientsEmails, $subject, $text, true); - } -}