From a4578fe8f9512a3b14afeca1b045262650c01484 Mon Sep 17 00:00:00 2001 From: Soner Sayakci Date: Sun, 6 Dec 2020 16:23:31 +0100 Subject: [PATCH] Add compatibility for 6.3.4.0 --- CHANGELOG_de-DE.md | 4 + CHANGELOG_en-GB.md | 14 +- composer.json | 9 +- .../OrderServiceGeneratorPass.php | 101 --------- src/FroshPlatformTemplateMail.php | 1 - src/Resources/config/services.xml | 11 +- src/Services/MailFinderService.php | 3 +- .../MailDataBagFilterSubscriber.php | 71 ------- src/Subscriber/MailSendSubscriber.php | 193 ++++++++++++++---- 9 files changed, 180 insertions(+), 227 deletions(-) delete mode 100644 src/DependencyInjection/OrderServiceGeneratorPass.php delete mode 100644 src/Subscriber/MailDataBagFilterSubscriber.php diff --git a/CHANGELOG_de-DE.md b/CHANGELOG_de-DE.md index 529acc0..08ffcc2 100644 --- a/CHANGELOG_de-DE.md +++ b/CHANGELOG_de-DE.md @@ -1,3 +1,7 @@ +# 0.3.3 + +* Kompatiblität mit 6.3.4.0 + # 0.3.2 * Kompatiblität mit 6.3.3.0 diff --git a/CHANGELOG_en-GB.md b/CHANGELOG_en-GB.md index 96c5df9..84f0bb9 100644 --- a/CHANGELOG_en-GB.md +++ b/CHANGELOG_en-GB.md @@ -1,14 +1,18 @@ +# 0.3.3 + +* Compatibility 6.3.4.0 + # 0.3.2 -* Compability mit 6.3.3.0 +* Compatibility 6.3.3.0 # 0.3.1 -* Compability mit 6.3.3.0 +* Compatibility 6.3.3.0 # 0.3.0 -* Compability mit 6.3.3.0 +* Compatibility 6.3.3.0 # 0.2.1 @@ -18,11 +22,11 @@ # 0.2.0 -* Compability mit 6.3 +* Compatibility mit 6.3 # 0.1.2 -* Compability mit 6.2 +* Compatibility mit 6.2 # 0.1.1 diff --git a/composer.json b/composer.json index f8957d2..6410142 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { "name": "frosh/frosh-platform-template-mail", - "version": "0.3.2", + "version": "0.3.3", "type": "shopware-platform-plugin", "description": "Load mail templates from theme", "keywords": [ @@ -40,9 +40,8 @@ } }, "require": { - "shopware/core": "~6.3.3.0", - "shopware/administration": "~6.3.3.0", - "lorenzo/pinky": "^1.0", - "nikic/php-parser": "4.3.0" + "shopware/core": "~6.3.4.0", + "shopware/administration": "~6.3.4.0", + "lorenzo/pinky": "^1.0" } } diff --git a/src/DependencyInjection/OrderServiceGeneratorPass.php b/src/DependencyInjection/OrderServiceGeneratorPass.php deleted file mode 100644 index 813b3f6..0000000 --- a/src/DependencyInjection/OrderServiceGeneratorPass.php +++ /dev/null @@ -1,101 +0,0 @@ -create(ParserFactory::ONLY_PHP7); - $orderActionNodes = $phpParser->parse(file_get_contents($orderAction->getFileName())); - - $nodeFinder = new NodeFinder(); - /** @var Namespace_ $namespace */ - $namespace = $nodeFinder->findFirstInstanceOf($orderActionNodes, Namespace_::class); - $namespace->name = new Name(__NAMESPACE__); - - /** @var Class_ $class */ - $class = $nodeFinder->findFirstInstanceOf($orderActionNodes, Class_::class); - $class->extends = new Name('\\' . OrderService::class); - - // EventDispatcher property - array_unshift($class->stmts, $builder->property('froshEventDispatcher')->getNode()); - - $methods = $nodeFinder->findInstanceOf($class->stmts, ClassMethod::class); - - $propertyFetch = $builder->propertyFetch($builder->var('this'), 'froshEventDispatcher'); - $argCount = null; - - /** @var ClassMethod $method */ - foreach ($methods as $method) { - if ($method->name->name === '__construct') { - $method->params[] = $builder->param('froshEventDispatcher')->getNode(); - $argCount = count($method->params); - $method->stmts[] = new Expression(new Assign($propertyFetch, $builder->var('froshEventDispatcher'))); - } else if($method->name->name === 'sendMail') { - foreach ($method->stmts as $i => $stmt) { - if (!$stmt instanceof Expression) { - continue; - } - - if (!$stmt->expr instanceof MethodCall) { - continue; - } - - if ($stmt->expr->name->name !== 'send') { - continue; - } - - if (! $stmt->expr->var instanceof PropertyFetch) { - continue; - } - - if (!$stmt->expr->var->name->name === 'mailService') { - continue; - } - - // Fetch order context to pass it into the event - $orderContextStmt = new Expression(new Assign($builder->var('orderContext'), $builder->methodCall($builder->var('this'), 'getOrderContext', [$builder->var('context'), $builder->var('order')]))); - // Fire event - $arg = $builder->new('\\' . MailDataBagFilter::class, [$builder->var('data'), $builder->var('mailTemplate'), $builder->var('orderContext')]); - $newStmt = new Expression($builder->methodCall($propertyFetch, 'dispatch', [$arg])); - - array_splice($method->stmts, $i, 0, [$orderContextStmt, $newStmt]); - } - } - } - - $printer = new Standard(); - - file_put_contents(__DIR__ . '/OrderService.php', $printer->prettyPrintFile($orderActionNodes)); - - $container->getDefinition(OrderService::class) - ->setClass(__NAMESPACE__ . '\\OrderService') - ->setArgument($argCount - 1, new Reference(EventDispatcherInterface::class)); - } -} diff --git a/src/FroshPlatformTemplateMail.php b/src/FroshPlatformTemplateMail.php index 4866af8..ae4731d 100644 --- a/src/FroshPlatformTemplateMail.php +++ b/src/FroshPlatformTemplateMail.php @@ -21,7 +21,6 @@ class FroshPlatformTemplateMail extends Plugin public function build(ContainerBuilder $container): void { $container->addCompilerPass(new CacheCompilerPass()); - $container->addCompilerPass(new OrderServiceGeneratorPass()); parent::build($container); } } diff --git a/src/Resources/config/services.xml b/src/Resources/config/services.xml index 12a9759..d6f040b 100644 --- a/src/Resources/config/services.xml +++ b/src/Resources/config/services.xml @@ -9,16 +9,15 @@ - + + + + + - - - - - diff --git a/src/Services/MailFinderService.php b/src/Services/MailFinderService.php index eb27387..0273877 100644 --- a/src/Services/MailFinderService.php +++ b/src/Services/MailFinderService.php @@ -4,6 +4,7 @@ use Frosh\TemplateMail\Services\MailLoader\LoaderInterface; use Shopware\Core\Framework\Adapter\Translation\Translator; +use Shopware\Core\Framework\Api\Context\SalesChannelApiSource; use Shopware\Core\Framework\Context; use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface; use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria; @@ -54,7 +55,7 @@ public function findTemplateByTechnicalName(string $type, string $technicalName, $paths = $this->filesystemLoader->getPaths(); $searchFolder = [$businessEvent->getContext()->getLanguageId(), 'global']; - if ($businessEvent->getContext()->getSource() instanceof Context\SalesChannelApiSource) { + if ($businessEvent->getContext()->getSource() instanceof SalesChannelApiSource) { array_unshift($searchFolder, $businessEvent->getContext()->getSource()->getSalesChannelId()); } diff --git a/src/Subscriber/MailDataBagFilterSubscriber.php b/src/Subscriber/MailDataBagFilterSubscriber.php deleted file mode 100644 index 51ec711..0000000 --- a/src/Subscriber/MailDataBagFilterSubscriber.php +++ /dev/null @@ -1,71 +0,0 @@ -mailTemplateTypeRepository = $mailTemplateTypeRepository; - $this->mailFinderService = $mailFinderService; - } - - public static function getSubscribedEvents(): array - { - return [ - MailDataBagFilter::class => 'filterMailData' - ]; - } - - public function filterMailData(MailDataBagFilter $bagFilter): void - { - /** @var MailTemplateTypeEntity $mailTemplateType */ - $mailTemplateType = $this->mailTemplateTypeRepository->search(new Criteria([$bagFilter->getMailTemplateEntity()->getMailTemplateTypeId()]), Context::createDefaultContext()) ->first(); - - $technicalName = $mailTemplateType->getTechnicalName(); - $event = $this->createBusinessEventFromBag($bagFilter->getDataBag(), $bagFilter->getContext()); - - $html = $this->mailFinderService->findTemplateByTechnicalName(MailFinderService::TYPE_HTML, $technicalName, $event); - $plain = $this->mailFinderService->findTemplateByTechnicalName(MailFinderService::TYPE_PLAIN, $technicalName, $event); - $subject = $this->mailFinderService->findTemplateByTechnicalName(MailFinderService::TYPE_SUBJECT, $technicalName, $event); - - if ($html) { - $bagFilter->getDataBag()->set('contentHtml', $html); - } - - if ($plain) { - $bagFilter->getDataBag()->set('contentPlain', $plain); - } - - if ($subject) { - $bagFilter->getDataBag()->set('subject', $subject); - } - } - - private function createBusinessEventFromBag(ParameterBag $dataBag, Context $context): BusinessEvent - { - return new TemplateMailBusinessEvent($dataBag->get('salesChannelId'), $context); - } -} diff --git a/src/Subscriber/MailSendSubscriber.php b/src/Subscriber/MailSendSubscriber.php index 64eca67..fcbda90 100644 --- a/src/Subscriber/MailSendSubscriber.php +++ b/src/Subscriber/MailSendSubscriber.php @@ -2,17 +2,20 @@ namespace Frosh\TemplateMail\Subscriber; -use Frosh\TemplateMail\Services\Configuration; use Frosh\TemplateMail\Services\MailFinderService; use Frosh\TemplateMail\Services\MailFinderServiceInterface; -use kranemora\Html2Text\Html2Text; +use Psr\Log\LoggerInterface; +use Shopware\Core\Checkout\Document\DocumentService; use Shopware\Core\Content\MailTemplate\Exception\MailEventConfigurationException; +use Shopware\Core\Content\MailTemplate\MailTemplateActions; use Shopware\Core\Content\MailTemplate\MailTemplateEntity; -use Shopware\Core\Content\MailTemplate\Service\MailService; +use Shopware\Core\Content\MailTemplate\Service\MailServiceInterface; use Shopware\Core\Content\MailTemplate\Subscriber\MailSendSubscriber as ShopwareMailSenderSubscriber; +use Shopware\Core\Content\MailTemplate\Subscriber\MailSendSubscriberConfig; +use Shopware\Core\Content\Media\MediaService; +use Shopware\Core\Framework\Context; use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface; use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria; -use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter; use Shopware\Core\Framework\Event\BusinessEvent; use Shopware\Core\Framework\Event\EventData\EventDataType; use Shopware\Core\Framework\Event\MailActionInterface; @@ -21,8 +24,11 @@ class MailSendSubscriber implements EventSubscriberInterface { + public const ACTION_NAME = MailTemplateActions::MAIL_TEMPLATE_MAIL_SEND_ACTION; + public const MAIL_CONFIG_EXTENSION = 'mail-attachments'; + /** - * @var MailService + * @var MailServiceInterface */ private $mailService; @@ -31,22 +37,56 @@ class MailSendSubscriber implements EventSubscriberInterface */ private $mailTemplateRepository; + /** + * @var MediaService + */ + private $mediaService; + + /** + * @var EntityRepositoryInterface + */ + private $mediaRepository; + + /** + * @var DocumentService + */ + private $documentService; + + /** + * @var EntityRepositoryInterface + */ + private $documentRepository; + + /** + * @var LoggerInterface + */ + private $logger; + /** * @var MailFinderServiceInterface */ private $mailFinderService; public function __construct( - MailService $mailService, + MailServiceInterface $mailService, EntityRepositoryInterface $mailTemplateRepository, + MediaService $mediaService, + EntityRepositoryInterface $mediaRepository, + EntityRepositoryInterface $documentRepository, + DocumentService $documentService, + LoggerInterface $logger, MailFinderServiceInterface $mailFinderService ) { $this->mailService = $mailService; $this->mailTemplateRepository = $mailTemplateRepository; + $this->mediaService = $mediaService; + $this->mediaRepository = $mediaRepository; + $this->documentRepository = $documentRepository; + $this->documentService = $documentService; + $this->logger = $logger; $this->mailFinderService = $mailFinderService; } - public static function getSubscribedEvents(): array { return [ @@ -58,6 +98,20 @@ public function sendMail(BusinessEvent $event): void { $mailEvent = $event->getEvent(); + $extension = $event->getContext()->getExtension(self::MAIL_CONFIG_EXTENSION); + if (!$extension instanceof MailSendSubscriberConfig) { + $extension = new MailSendSubscriberConfig(false, [], []); + } + + if ($extension->skip()) { + return; + } + + if (!$mailEvent instanceof MailActionInterface) { + throw new MailEventConfigurationException('Not a instance of MailActionInterface', get_class($mailEvent)); + } + + if (!$mailEvent instanceof MailActionInterface) { throw new MailEventConfigurationException('Not a instance of MailActionInterface', get_class($mailEvent)); } @@ -66,7 +120,13 @@ public function sendMail(BusinessEvent $event): void throw new MailEventConfigurationException('Configuration mail_template_type_id missing.', get_class($mailEvent)); } - $mailTemplate = $this->loadMailTemplate($event); + $config = $event->getConfig(); + + if (!isset($config['mail_template_id'])) { + return; + } + + $mailTemplate = $this->getMailTemplate($config['mail_template_id'], $event->getContext()); if ($mailTemplate === null) { return; @@ -79,20 +139,63 @@ public function sendMail(BusinessEvent $event): void $subject = $this->mailFinderService->findTemplateByTechnicalName(MailFinderService::TYPE_SUBJECT, $technicalName, $event); $data = new DataBag(); - $data->set('recipients', $mailEvent->getMailStruct()->getRecipients()); + $recipients = $mailEvent->getMailStruct()->getRecipients(); + if (isset($config['recipients'])) { + $recipients = $config['recipients']; + } + + $data->set('recipients', $recipients); $data->set('senderName', $mailTemplate->getTranslation('senderName')); $data->set('salesChannelId', $mailEvent->getSalesChannelId()); + $data->set('templateId', $mailTemplate->getId()); + $data->set('customFields', $mailTemplate->getCustomFields()); $data->set('contentHtml', $html ? $html : $mailTemplate->getTranslation('contentHtml')); $data->set('contentPlain', $plain ? $plain : $mailTemplate->getTranslation('contentPlain')); $data->set('subject', $subject ? $subject : $mailTemplate->getTranslation('subject')); $data->set('mediaIds', []); - $this->mailService->send( - $data->all(), - $event->getContext(), - $this->getTemplateData($mailEvent) - ); + $attachments = $this->buildAttachments($event, $mailTemplate, $extension); + + if (!empty($attachments)) { + $data->set('binAttachments', $attachments); + } + + try { + $this->mailService->send( + $data->all(), + $event->getContext(), + $this->getTemplateData($mailEvent) + ); + + $writes = array_map(static function ($id) { + return ['id' => $id, 'sent' => true]; + }, $extension->getDocumentIds()); + + if (!empty($writes)) { + $this->documentRepository->update($writes, $event->getContext()); + } + } catch (\Exception $e) { + $this->logger->error( + "Could not send mail:\n" + . $e->getMessage() . "\n" + . 'Error Code:' . $e->getCode() . "\n" + . "Template data: \n" + . json_encode($data->all()) . "\n" + ); + } + } + + private function getMailTemplate(string $id, Context $context): ?MailTemplateEntity + { + $criteria = new Criteria([$id]); + $criteria->addAssociation('media.media'); + $criteria->addAssociation('mailTemplateType'); + $criteria->setLimit(1); + + return $this->mailTemplateRepository + ->search($criteria, $context) + ->first(); } /** @@ -114,36 +217,52 @@ private function getTemplateData(MailActionInterface $event): array return $data; } - protected function loadMailTemplate(BusinessEvent $event) + private function buildAttachments(BusinessEvent $event, MailTemplateEntity $mailTemplate, MailSendSubscriberConfig $config): array { - $mailTemplateTypeId = $event->getConfig()['mail_template_type_id']; - $mailEvent = $event->getEvent(); + $attachments = []; - $criteria = new Criteria(); - $criteria->addFilter(new EqualsFilter('mailTemplateTypeId', $mailTemplateTypeId)); - $criteria->addAssociation('mailTemplateType'); - $criteria->setLimit(1); + if ($mailTemplate->getMedia() !== null) { + foreach ($mailTemplate->getMedia() as $mailTemplateMedia) { + if ($mailTemplateMedia->getMedia() === null) { + continue; + } + if ($mailTemplateMedia->getLanguageId() !== null && $mailTemplateMedia->getLanguageId() !== $event->getContext()->getLanguageId()) { + continue; + } + + $attachments[] = $this->mediaService->getAttachment( + $mailTemplateMedia->getMedia(), + $event->getContext() + ); + } + } - if ($mailEvent->getSalesChannelId()) { - $criteria->addFilter(new EqualsFilter('mail_template.salesChannels.salesChannel.id', $mailEvent->getSalesChannelId())); + if (!empty($config->getMediaIds())) { + $entities = $this->mediaRepository->search(new Criteria($config->getMediaIds()), $event->getContext()); - /** @var MailTemplateEntity|null $mailTemplate */ - $mailTemplate = $this->mailTemplateRepository->search($criteria, $event->getContext())->first(); + foreach ($entities as $media) { + $attachments[] = $this->mediaService->getAttachment($media, $event->getContext()); + } + } - // Fallback if no template for the saleschannel is found - if ($mailTemplate === null) { - $criteria = new Criteria(); - $criteria->addFilter(new EqualsFilter('mailTemplateTypeId', $mailTemplateTypeId)); - $criteria->addAssociation('mailTemplateType'); - $criteria->setLimit(1); + if (!empty($config->getDocumentIds())) { + $criteria = new Criteria($config->getDocumentIds()); + $criteria->addAssociation('documentMediaFile'); + $criteria->addAssociation('documentType'); - /** @var MailTemplateEntity|null $mailTemplate */ - $mailTemplate = $this->mailTemplateRepository->search($criteria, $event->getContext())->first(); + $entities = $this->documentRepository->search($criteria, $event->getContext()); + + foreach ($entities as $document) { + $document = $this->documentService->getDocument($document, $event->getContext()); + + $attachments[] = [ + 'content' => $document->getFileBlob(), + 'fileName' => $document->getFilename(), + 'mimeType' => $document->getContentType(), + ]; } - } else { - /** @var MailTemplateEntity|null $mailTemplate */ - $mailTemplate = $this->mailTemplateRepository->search($criteria, $event->getContext())->first(); } - return $mailTemplate; + + return $attachments; } }