vendor/shopware/core/Content/MailTemplate/Subscriber/MailSendSubscriber.php line 101

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Shopware\Core\Content\MailTemplate\Subscriber;
  3. use Psr\Log\LoggerInterface;
  4. use Shopware\Core\Checkout\Document\DocumentService;
  5. use Shopware\Core\Content\Mail\Service\AbstractMailService;
  6. use Shopware\Core\Content\MailTemplate\Event\MailSendSubscriberBridgeEvent;
  7. use Shopware\Core\Content\MailTemplate\Exception\MailEventConfigurationException;
  8. use Shopware\Core\Content\MailTemplate\Exception\SalesChannelNotFoundException;
  9. use Shopware\Core\Content\MailTemplate\MailTemplateActions;
  10. use Shopware\Core\Content\MailTemplate\MailTemplateEntity;
  11. use Shopware\Core\Content\Media\MediaService;
  12. use Shopware\Core\Framework\Adapter\Translation\Translator;
  13. use Shopware\Core\Framework\Context;
  14. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
  15. use Shopware\Core\Framework\DataAbstractionLayer\Exception\InconsistentCriteriaIdsException;
  16. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  17. use Shopware\Core\Framework\Event\BusinessEvent;
  18. use Shopware\Core\Framework\Event\MailActionInterface;
  19. use Shopware\Core\Framework\Feature;
  20. use Shopware\Core\Framework\Log\Package;
  21. use Shopware\Core\Framework\Validation\DataBag\DataBag;
  22. use Shopware\Core\System\Locale\LanguageLocaleCodeProvider;
  23. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  24. use Symfony\Contracts\EventDispatcher\Event;
  25. use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
  26. /**
  27.  * @deprecated tag:v6.5.0 - reason:remove-subscriber - Will be removed in v6.5.0 Use SendMailAction instead
  28.  */
  29. #[Package('sales-channel')]
  30. class MailSendSubscriber implements EventSubscriberInterface
  31. {
  32.     public const ACTION_NAME MailTemplateActions::MAIL_TEMPLATE_MAIL_SEND_ACTION;
  33.     public const MAIL_CONFIG_EXTENSION 'mail-attachments';
  34.     private EntityRepositoryInterface $mailTemplateRepository;
  35.     private MediaService $mediaService;
  36.     private EntityRepositoryInterface $mediaRepository;
  37.     private DocumentService $documentService;
  38.     private EntityRepositoryInterface $documentRepository;
  39.     private LoggerInterface $logger;
  40.     private AbstractMailService $emailService;
  41.     private EventDispatcherInterface $eventDispatcher;
  42.     private EntityRepositoryInterface $mailTemplateTypeRepository;
  43.     private Translator $translator;
  44.     private LanguageLocaleCodeProvider $languageLocaleProvider;
  45.     /**
  46.      * @internal
  47.      */
  48.     public function __construct(
  49.         AbstractMailService $emailService,
  50.         EntityRepositoryInterface $mailTemplateRepository,
  51.         MediaService $mediaService,
  52.         EntityRepositoryInterface $mediaRepository,
  53.         EntityRepositoryInterface $documentRepository,
  54.         DocumentService $documentService,
  55.         LoggerInterface $logger,
  56.         EventDispatcherInterface $eventDispatcher,
  57.         EntityRepositoryInterface $mailTemplateTypeRepository,
  58.         Translator $translator,
  59.         LanguageLocaleCodeProvider $languageLocaleProvider
  60.     ) {
  61.         $this->mailTemplateRepository $mailTemplateRepository;
  62.         $this->mediaService $mediaService;
  63.         $this->mediaRepository $mediaRepository;
  64.         $this->documentRepository $documentRepository;
  65.         $this->documentService $documentService;
  66.         $this->logger $logger;
  67.         $this->emailService $emailService;
  68.         $this->eventDispatcher $eventDispatcher;
  69.         $this->mailTemplateTypeRepository $mailTemplateTypeRepository;
  70.         $this->translator $translator;
  71.         $this->languageLocaleProvider $languageLocaleProvider;
  72.     }
  73.     public static function getSubscribedEvents(): array
  74.     {
  75.         return [
  76.             self::ACTION_NAME => 'sendMail',
  77.         ];
  78.     }
  79.     /**
  80.      * @throws MailEventConfigurationException
  81.      * @throws SalesChannelNotFoundException
  82.      * @throws InconsistentCriteriaIdsException
  83.      */
  84.     public function sendMail(Event $event): void
  85.     {
  86.         if (Feature::isActive('FEATURE_NEXT_17858')) {
  87.             return;
  88.         }
  89.         if (!$event instanceof BusinessEvent) {
  90.             return;
  91.         }
  92.         $mailEvent $event->getEvent();
  93.         $extension $event->getContext()->getExtension(self::MAIL_CONFIG_EXTENSION);
  94.         if (!$extension instanceof MailSendSubscriberConfig) {
  95.             $extension = new MailSendSubscriberConfig(false, [], []);
  96.         }
  97.         if ($extension->skip()) {
  98.             return;
  99.         }
  100.         if (!$mailEvent instanceof MailActionInterface) {
  101.             throw new MailEventConfigurationException('Not a instance of MailActionInterface', \get_class($mailEvent));
  102.         }
  103.         $config $event->getConfig();
  104.         if (!isset($config['mail_template_id'])) {
  105.             return;
  106.         }
  107.         $mailTemplate $this->getMailTemplate($config['mail_template_id'], $event->getContext());
  108.         if ($mailTemplate === null) {
  109.             return;
  110.         }
  111.         $injectedTranslator $this->injectTranslator($mailEvent);
  112.         $data = new DataBag();
  113.         $recipients $mailEvent->getMailStruct()->getRecipients();
  114.         if (isset($config['recipients']) && !empty($config['recipients'])) {
  115.             $recipients $config['recipients'];
  116.         }
  117.         $data->set('recipients'$recipients);
  118.         $data->set('senderName'$mailTemplate->getTranslation('senderName'));
  119.         $data->set('salesChannelId'$mailEvent->getSalesChannelId());
  120.         $data->set('templateId'$mailTemplate->getId());
  121.         $data->set('customFields'$mailTemplate->getCustomFields());
  122.         $data->set('contentHtml'$mailTemplate->getTranslation('contentHtml'));
  123.         $data->set('contentPlain'$mailTemplate->getTranslation('contentPlain'));
  124.         $data->set('subject'$mailTemplate->getTranslation('subject'));
  125.         $data->set('mediaIds', []);
  126.         $attachments $this->buildAttachments($event$mailTemplate$extension);
  127.         if (!empty($attachments)) {
  128.             $data->set('binAttachments'$attachments);
  129.         }
  130.         $this->eventDispatcher->dispatch(new MailSendSubscriberBridgeEvent($data$mailTemplate$event));
  131.         if ($data->has('templateId')) {
  132.             try {
  133.                 $this->mailTemplateTypeRepository->update([[
  134.                     'id' => $mailTemplate->getMailTemplateTypeId(),
  135.                     'templateData' => $this->getTemplateData($mailEvent),
  136.                 ]], $mailEvent->getContext());
  137.             } catch (\Throwable $e) {
  138.                 // Dont throw errors if this fails // Fix with NEXT-15475
  139.             }
  140.         }
  141.         try {
  142.             $this->emailService->send(
  143.                 $data->all(),
  144.                 $event->getContext(),
  145.                 $this->getTemplateData($mailEvent)
  146.             );
  147.             $writes array_map(static function ($id) {
  148.                 return ['id' => $id'sent' => true];
  149.             }, $extension->getDocumentIds());
  150.             if (!empty($writes)) {
  151.                 $this->documentRepository->update($writes$event->getContext());
  152.             }
  153.         } catch (\Exception $e) {
  154.             $this->logger->error(
  155.                 "Could not send mail:\n"
  156.                 $e->getMessage() . "\n"
  157.                 'Error Code:' $e->getCode() . "\n"
  158.                 "Template data: \n"
  159.                 json_encode($data->all()) . "\n"
  160.             );
  161.         }
  162.         if ($injectedTranslator) {
  163.             $this->translator->resetInjection();
  164.         }
  165.     }
  166.     private function getMailTemplate(string $idContext $context): ?MailTemplateEntity
  167.     {
  168.         $criteria = new Criteria([$id]);
  169.         $criteria->addAssociation('media.media');
  170.         $criteria->setLimit(1);
  171.         return $this->mailTemplateRepository
  172.             ->search($criteria$context)
  173.             ->first();
  174.     }
  175.     /**
  176.      * @throws MailEventConfigurationException
  177.      */
  178.     private function getTemplateData(MailActionInterface $event): array
  179.     {
  180.         $data = [];
  181.         foreach (array_keys($event::getAvailableData()->toArray()) as $key) {
  182.             $getter 'get' ucfirst($key);
  183.             if (method_exists($event$getter)) {
  184.                 $data[$key] = $event->$getter();
  185.             } else {
  186.                 throw new MailEventConfigurationException('Data for ' $key ' not available.', \get_class($event));
  187.             }
  188.         }
  189.         return $data;
  190.     }
  191.     private function buildAttachments(BusinessEvent $eventMailTemplateEntity $mailTemplateMailSendSubscriberConfig $config): array
  192.     {
  193.         $attachments = [];
  194.         if ($mailTemplate->getMedia() !== null) {
  195.             foreach ($mailTemplate->getMedia() as $mailTemplateMedia) {
  196.                 if ($mailTemplateMedia->getMedia() === null) {
  197.                     continue;
  198.                 }
  199.                 if ($mailTemplateMedia->getLanguageId() !== null && $mailTemplateMedia->getLanguageId() !== $event->getContext()->getLanguageId()) {
  200.                     continue;
  201.                 }
  202.                 $attachments[] = $this->mediaService->getAttachment(
  203.                     $mailTemplateMedia->getMedia(),
  204.                     $event->getContext()
  205.                 );
  206.             }
  207.         }
  208.         if (!empty($config->getMediaIds())) {
  209.             $entities $this->mediaRepository->search(new Criteria($config->getMediaIds()), $event->getContext());
  210.             foreach ($entities as $media) {
  211.                 $attachments[] = $this->mediaService->getAttachment($media$event->getContext());
  212.             }
  213.         }
  214.         if (!empty($config->getDocumentIds())) {
  215.             $criteria = new Criteria($config->getDocumentIds());
  216.             $criteria->addAssociation('documentMediaFile');
  217.             $criteria->addAssociation('documentType');
  218.             $entities $this->documentRepository->search($criteria$event->getContext());
  219.             foreach ($entities as $document) {
  220.                 $document $this->documentService->getDocument($document$event->getContext());
  221.                 $attachments[] = [
  222.                     'content' => $document->getFileBlob(),
  223.                     'fileName' => $document->getFilename(),
  224.                     'mimeType' => $document->getContentType(),
  225.                 ];
  226.             }
  227.         }
  228.         return $attachments;
  229.     }
  230.     private function injectTranslator(MailActionInterface $event): bool
  231.     {
  232.         if ($event->getSalesChannelId() === null) {
  233.             return false;
  234.         }
  235.         if ($this->translator->getSnippetSetId() !== null) {
  236.             return false;
  237.         }
  238.         $this->translator->injectSettings(
  239.             $event->getSalesChannelId(),
  240.             $event->getContext()->getLanguageId(),
  241.             $this->languageLocaleProvider->getLocaleForLanguageId($event->getContext()->getLanguageId()),
  242.             $event->getContext()
  243.         );
  244.         return true;
  245.     }
  246. }