| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210 |
- <?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;
- }
- }
- }
- }
|