diff --git a/README.md b/README.md index e640987..24ae504 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,44 @@ # Shopware 6 Dutch transactional email templates -Tip: use this with [frosh/frosh-platform-template-mail](https://github.com/FriendsOfShopware/FroshTemplateMail) - Since I couldn't find translations anywhere, here's a community project. If you find any typo's, please create a PR :) +## Import templates +A console command is available to import the templates into your database. *Be aware that this overwrites your existing mail templates!* + +``` +$ bin/console elgentos-dutch-email-templates:import +Succesfully upserted mail template translation for contact_form. +Succesfully upserted mail template translation for customer.group.registration.accepted. +Succesfully upserted mail template translation for customer.group.registration.declined. +Succesfully upserted mail template translation for customer.recovery.request. +Succesfully upserted mail template translation for customer_group_change_accept. +Succesfully upserted mail template translation for customer_group_change_reject. +Succesfully upserted mail template translation for customer_register. +Succesfully upserted mail template translation for customer_register.double_opt_in. +Succesfully upserted mail template translation for guest_order.double_opt_in. +Succesfully upserted mail template translation for newsletterDoubleOptIn. +Succesfully upserted mail template translation for newsletterRegister. +Succesfully upserted mail template translation for order.state.cancelled. +Succesfully upserted mail template translation for order.state.completed. +Succesfully upserted mail template translation for order.state.in_progress. +Succesfully upserted mail template translation for order.state.open. +Succesfully upserted mail template translation for order_confirmation_mail. +Succesfully upserted mail template translation for order_delivery.state.cancelled. +Succesfully upserted mail template translation for order_delivery.state.returned. +Succesfully upserted mail template translation for order_delivery.state.returned_partially. +Succesfully upserted mail template translation for order_delivery.state.shipped. +Succesfully upserted mail template translation for order_delivery.state.shipped_partially. +Succesfully upserted mail template translation for order_transaction.state.cancelled. +Succesfully upserted mail template translation for order_transaction.state.open. +Succesfully upserted mail template translation for order_transaction.state.paid. +Succesfully upserted mail template translation for order_transaction.state.paid_partially. +Succesfully upserted mail template translation for order_transaction.state.refunded. +Succesfully upserted mail template translation for order_transaction.state.refunded_partially. +Succesfully upserted mail template translation for order_transaction.state.reminded. +Succesfully upserted mail template translation for password_change. +Succesfully upserted mail template translation for product_stock_warning. +Succesfully upserted mail template translation for sepa_confirmation. +Succesfully upserted mail template translation for user.recovery.request. +``` + Huge thanks to @MelvinAchterhuis for providing a large number of these :) diff --git a/src/Command/TemplateImport.php b/src/Command/TemplateImport.php new file mode 100644 index 0000000..219ea21 --- /dev/null +++ b/src/Command/TemplateImport.php @@ -0,0 +1,157 @@ +languageRepository = $languageRepository; + $this->mailTemplateRepository = $mailTemplateRepository; + $this->mailTemplateTranslationRepository = $mailTemplateTranslationRepository; + $this->mailTemplateTypeRepository = $mailTemplateTypeRepository; + } + + protected function configure(): void + { + $this->addOption('languageName', 'l', InputOption::VALUE_OPTIONAL, 'Language name', 'Nederlands'); + } + + protected function execute(InputInterface $input, OutputInterface $output): int + { + $languageName = $input->getOption('languageName'); + + // Find language based on language name + $criteria = new Criteria(); + $criteria->addAssociation('locale'); + $criteria->addFilter(new EqualsFilter('name', $languageName)); + $context = Context::createDefaultContext(); + /** @var LanguageEntity $language */ + try { + $language = $this->languageRepository->search($criteria, $context)->first(); + } catch (\Exception $e) { + $output->writeln(sprintf('Could not find mail language with name %s', $languageName)); + return 1; + } + + $languageCode = $language->getLocale() ? $language->getLocale()->getCode() : null; + if (!$languageCode) { + $output->writeln(sprintf('Could not find mail language locale with name %s', $languageName)); + return 1; + } + + // Filter out non-directories or relatives + $this->basePath = __DIR__ . '/../Resources/views/email/' . $languageCode . '/'; + $mailTypes = array_filter(scandir($this->basePath), function ($input) { + return strlen($input) > 2 && is_dir($this->basePath . $input); + }); + + // Loop through mail types to add the templates + foreach ($mailTypes as $mailTypeTechnicalName) { + try { + $mailTemplateType = $this->getMailTemplateTypeByTechnicalName($mailTypeTechnicalName, $context); + $mailTemplate = $mailTemplateType ? $this->getMailTemplateByMailTemplateTypeId($mailTemplateType, $context) : null; + $mailTemplateContent = $this->getMailTemplateContent($mailTemplate, $mailTypeTechnicalName, $mailTemplateType->getId(), $language); + if (empty($mailTemplateContent)) { + $output->writeln(sprintf('No HTML and/or text content for %s (%s) found. Skipping.', $mailTypeTechnicalName, $languageName)); + continue; + } + try { + // If the 'id' field is set, create a new mail template. If the 'mailTemplateId' is set, create a new mail translation template + if (isset($mailTemplateContent['id'])) { + $this->mailTemplateRepository->upsert([$mailTemplateContent], $context); + $output->writeln(sprintf('Succesfully upserted mail template for %s.', $mailTypeTechnicalName)); + } elseif (isset($mailTemplateContent['mailTemplateId'])) { + $mailTemplateContent['languageId'] = $language->getId(); + $this->mailTemplateTranslationRepository->upsert([$mailTemplateContent], $context); + $output->writeln(sprintf('Succesfully upserted mail template translation for %s.', $mailTypeTechnicalName)); + } + } catch (\Exception $e) { + $output->writeln(sprintf('Could not upsert mail template for %s; %s.', $mailTypeTechnicalName, $e->getMessage())); + } + } catch (\Exception $e) { + $output->writeln(sprintf('Could not find mail template type for %s; %s', $mailTypeTechnicalName, $e->getMessage())); + } + } + + return 0; + } + + private function getMailTemplateContent(?MailTemplateEntity $mailTemplate, string $mailTypeTechnicalName, string $mailTypeId, LanguageEntity $language): array + { + $contentHtml = @file_get_contents($this->basePath . $mailTypeTechnicalName . '/html.twig'); + $contentText = @file_get_contents($this->basePath . $mailTypeTechnicalName . '/plain.twig'); + $subject = @file_get_contents($this->basePath . $mailTypeTechnicalName . '/subject.twig'); + + if (!$contentHtml || !$contentText) { + return []; + } + + $data = [ + 'description' => $mailTypeTechnicalName . ' (' . $language->getName() . ')', + 'systemDefault' => true, + 'senderName' => '{{ salesChannel.name }}', + 'subject' => $subject ? trim($subject) : $mailTypeTechnicalName, + 'contentHtml' => $contentHtml, + 'contentPlain' => $contentText, + 'mailTemplateTypeId' => $mailTypeId, + ]; + + // If the mail template already exists, pass along the mail template ID, otherwise create a new UUID + if ($mailTemplate) { + $data['mailTemplateId'] = $mailTemplate->getId(); + } else { + $data['id'] = Uuid::randomHex(); + } + + return $data; + } + + protected function getMailTemplateTypeByTechnicalName(string $mailTypeTechnicalName, Context $context): ?MailTemplateTypeEntity + { + $mailTemplateTypeCriteria = new Criteria(); + $mailTemplateTypeCriteria->addFilter(new EqualsFilter('technicalName', $mailTypeTechnicalName)); + return $this->mailTemplateTypeRepository->search($mailTemplateTypeCriteria, $context)->first(); + } + + protected function getMailTemplateByMailTemplateTypeId(MailTemplateTypeEntity $mailTemplateType, Context $context): ?MailTemplateEntity + { + $mailTemplateCriteria = new Criteria(); + $mailTemplateCriteria->addFilter(new EqualsFilter('mailTemplateTypeId', $mailTemplateType->getId())); + return $this->mailTemplateRepository->search($mailTemplateCriteria, $context)->first(); + } +} diff --git a/src/Resources/config/services.xml b/src/Resources/config/services.xml new file mode 100644 index 0000000..3ede10f --- /dev/null +++ b/src/Resources/config/services.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + diff --git a/src/Resources/views/email/nl-NL/product_stock_warning/plain.html.twig b/src/Resources/views/email/nl-NL/product_stock_warning/plain.twig similarity index 100% rename from src/Resources/views/email/nl-NL/product_stock_warning/plain.html.twig rename to src/Resources/views/email/nl-NL/product_stock_warning/plain.twig diff --git a/src/Resources/views/email/nl-NL/sepa_confirmation/plain.html.twig b/src/Resources/views/email/nl-NL/sepa_confirmation/plain.twig similarity index 100% rename from src/Resources/views/email/nl-NL/sepa_confirmation/plain.html.twig rename to src/Resources/views/email/nl-NL/sepa_confirmation/plain.twig