|
|
@@ -0,0 +1,210 @@
|
|
|
+<?php
|
|
|
+declare(strict_types=1);
|
|
|
+
|
|
|
+namespace App\Service\Mailer;
|
|
|
+
|
|
|
+use App\Entity\Message\ReportEmail;
|
|
|
+use App\Enum\Core\EmailSendingTypeEnum;
|
|
|
+use App\Enum\Message\MessageStatusEnum;
|
|
|
+use App\Service\Mailer\Model\MailerModelInterface;
|
|
|
+use App\Service\ServiceIterator\Mailer\BuilderIterator;
|
|
|
+use App\Service\Utils\StringsUtils;
|
|
|
+use App\Enum\Message\ReportMessageSatusEnum;
|
|
|
+use Doctrine\Common\Collections\ArrayCollection;
|
|
|
+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;
|
|
|
+use Symfony\Component\Mime\Email as SymfonyEmail;
|
|
|
+
|
|
|
+/**
|
|
|
+ * Classe Mailer : Service assurant l'envoie d'un mail à un destinataire
|
|
|
+ */
|
|
|
+class Mailer
|
|
|
+{
|
|
|
+ public function __construct(
|
|
|
+ private MailerInterface $symfonyMailer,
|
|
|
+ private string $opentalentNoReplyEmailAddress,
|
|
|
+ private BuilderIterator $builderIterator,
|
|
|
+ private StringsUtils $stringsUtils,
|
|
|
+ private EntityManagerInterface $entityManager
|
|
|
+ )
|
|
|
+ {
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Main fonction qui itère les différentes étapes nécessaires à l'envoie d'un email
|
|
|
+ * - Le Build
|
|
|
+ * - Le Send
|
|
|
+ * - Le Reporting
|
|
|
+ *
|
|
|
+ * @param MailerModelInterface $mailerModel
|
|
|
+ * @throws \Exception
|
|
|
+ */
|
|
|
+ public function main(MailerModelInterface $mailerModel): void{
|
|
|
+ $builderService = $this->builderIterator->getBuilderFor($mailerModel);
|
|
|
+ $emailsCollection = $builderService->build($mailerModel);
|
|
|
+
|
|
|
+ // @todo
|
|
|
+ //$emailsCollection = $this->reduceEmailsCollectionInPreproduction($emailsCollection);
|
|
|
+
|
|
|
+ foreach ($emailsCollection as $email){
|
|
|
+ $this->send($email);
|
|
|
+
|
|
|
+ $this->persistEmailEntity($email);
|
|
|
+ }
|
|
|
+
|
|
|
+ $this->report($emailsCollection);
|
|
|
+
|
|
|
+ $this->entityManager->flush();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Fonction d'envoie
|
|
|
+ * @param EmailInterface $email
|
|
|
+ */
|
|
|
+ public function send(EmailInterface $email): void{
|
|
|
+ //On créer le mail
|
|
|
+ $symfonyMail = $this->createSymfonyEmail($email);
|
|
|
+
|
|
|
+ $this->addRecipients($symfonyMail, $email);
|
|
|
+
|
|
|
+ $this->addHeaders($symfonyMail, $email);
|
|
|
+
|
|
|
+ // @todo
|
|
|
+ //$this->addAttachments();
|
|
|
+
|
|
|
+ //On tente d'envoyer
|
|
|
+ try {
|
|
|
+ $this->symfonyMailer->send($symfonyMail);
|
|
|
+ $email->getEmailEntity()->setStatus(MessageStatusEnum::SEND()->getValue());
|
|
|
+ $email->getEmailEntity()->setDateSent(new \DateTime('now'));
|
|
|
+ } catch (\Exception $e) {
|
|
|
+ $email->getEmailEntity()->setStatus(MessageStatusEnum::FAILED()->getValue());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Fonction de rapport
|
|
|
+ * @param ArrayCollection $emails
|
|
|
+ */
|
|
|
+ public function report(ArrayCollection $emails): void{
|
|
|
+ $delivered = [];
|
|
|
+ $unDelivered = [];
|
|
|
+
|
|
|
+ foreach ($emails as $email){
|
|
|
+ $emailRecipients = $email->getEmailRecipients();
|
|
|
+ /** @var EmailRecipient $emailRecipient */
|
|
|
+ foreach ($emailRecipients as $emailRecipient){
|
|
|
+ if($emailRecipient->getSendStatus() === ReportMessageSatusEnum::MISSING()->getValue()){
|
|
|
+ $unDelivered[] = $emailRecipient;
|
|
|
+ }else if($emailRecipient->getSendStatus() === ReportMessageSatusEnum::DELIVERED()->getValue()){
|
|
|
+ $delivered[] = $emailRecipient;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ $templatedMail = (new TemplatedEmail())
|
|
|
+ ->from($this->opentalentNoReplyEmailAddress)
|
|
|
+ ->subject(sprintf('Rapport d\'envoie du message : %s', $emails->first()->getEmailEntity()->getAbout()))
|
|
|
+ ->htmlTemplate('@templates/emails/report.html.twig')
|
|
|
+ ->context(
|
|
|
+ [
|
|
|
+ 'email_example' => $emails->first()->getEmailEntity(),
|
|
|
+ 'delivered' => $delivered,
|
|
|
+ 'unDelivered' => $unDelivered
|
|
|
+ ]
|
|
|
+ )
|
|
|
+ ->addTo(new Address($this->opentalentNoReplyEmailAddress))
|
|
|
+ ;
|
|
|
+
|
|
|
+ try {
|
|
|
+ $this->symfonyMailer->send($templatedMail);
|
|
|
+ } catch (TransportExceptionInterface $e) {
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Persist l'Email et les ReportEmail
|
|
|
+ * @param Email $email
|
|
|
+ */
|
|
|
+ public function persistEmailEntity(Email $email){
|
|
|
+ $emailEntity = $email->getEmailEntity();
|
|
|
+
|
|
|
+ /** @var EmailRecipient $emailRecipient */
|
|
|
+ foreach ($email->getEmailRecipients() as $emailRecipient){
|
|
|
+ $report = (new ReportEmail())
|
|
|
+ ->setAddressEmail($emailRecipient->getEmailAddress())
|
|
|
+ ->setAccess($emailRecipient->getAccess())
|
|
|
+ ->setOrganization($emailRecipient->getOrganization())
|
|
|
+ ->setDateSend(new \DateTime('now'))
|
|
|
+ ->setStatus($emailRecipient->getSendStatus())
|
|
|
+ ;
|
|
|
+ $emailEntity->addReport($report);
|
|
|
+ }
|
|
|
+ $this->entityManager->persist($emailEntity);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Reduit le nombre d'emails a envoyer si on ne se trouve pas en prod
|
|
|
+ * @param ArrayCollection $emailsCollection
|
|
|
+ */
|
|
|
+ public function reduceEmailsCollectionInPreproduction(ArrayCollection $emailsCollection): ArrayCollection {
|
|
|
+ if($_ENV['env'] === 'prod') return $emailsCollection;
|
|
|
+
|
|
|
+ $startEmails = $emailsCollection->slice(0, 10);
|
|
|
+ $endEmails = $emailsCollection->slice($emailsCollection->count() - 11, 10);
|
|
|
+
|
|
|
+ return new ArrayCollection([...$startEmails, ...$endEmails]);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param SymfonyEmail $symfonyMail
|
|
|
+ * @param Email $email
|
|
|
+ */
|
|
|
+ public function addHeaders(SymfonyEmail $symfonyMail, Email $email){
|
|
|
+ // $symfonyMail->getHeaders()->addTextHeader('List-Unsubscribe','mailto:'.$email->getOriginator().'?subject=désabonnement');
|
|
|
+
|
|
|
+ $symfonyMail->getHeaders()->addTextHeader('X-ID-OT', $email->getEmailEntity()->getUniqueSendId());
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Création du Mail qui sera envoyé via le Mailer de Symfony
|
|
|
+ * @param Email $email
|
|
|
+ * @return SymfonyEmail
|
|
|
+ */
|
|
|
+ public function createSymfonyEmail(Email $email): SymfonyEmail{
|
|
|
+ return (new SymfonyEmail())
|
|
|
+ ->from($email->getFrom())
|
|
|
+ ->subject($email->getEmailEntity()->getAbout())
|
|
|
+ ->html($email->getContent())
|
|
|
+ ->text($this->stringsUtils->convertHtmlToText($email->getContent()))
|
|
|
+ ;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * On ajoute les destinataires suivant le type d'envoie souhaité
|
|
|
+ * @param SymfonyEmail $symfonyMail
|
|
|
+ * @param Address $addressesMail
|
|
|
+ */
|
|
|
+ public function addRecipients(SymfonyEmail $symfonyMail, Email $email): void{
|
|
|
+ foreach ($email->getEmailRecipients() as $emailRecipient){
|
|
|
+ $addressMail = new Address($emailRecipient->getEmailAddress(), $emailRecipient->getName());
|
|
|
+
|
|
|
+ switch($emailRecipient->getSendType()){
|
|
|
+ case EmailSendingTypeEnum::TO()->getValue():
|
|
|
+ $symfonyMail->addTo($addressMail);
|
|
|
+ break;
|
|
|
+ case EmailSendingTypeEnum::BBC()->getValue():
|
|
|
+ $symfonyMail->addBcc($addressMail);
|
|
|
+ break;
|
|
|
+ case EmailSendingTypeEnum::CC()->getValue():
|
|
|
+ $symfonyMail->addCc($addressMail);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|