FriendsOfShopware / FroshPlatformTemplateMail

This plugin allows you to use twig mails in Shopware 6.
MIT License
23 stars 17 forks source link

Snippets not translated in mails sent from admin, using flowbuilder, message queue #43

Closed TimWuyts closed 9 months ago

TimWuyts commented 1 year ago

PHP Version

7.4.30

Shopware Version

6.4.17.2

Actual behaviour

Snippets in mail tempates are not being translated, when send using the Flow builder triggered by an event invoked from within the administration. Eg: order confirmation email, when the order is created manually.

When the customer placed an order, the same flow/email is being triggered & the snippets are translated correctly.

The following snippet: {{ "email.shared.greeting"|trans({ '%name%': order.orderCustomer.firstName })|sw_sanitize }} will result in the output email.shared.greeting.

Expected behaviour

Snippets used in mail templates (either stored in the database or provided using template files) should be translated accordingly in all circumstances.

Seems to be related to #11, where this issue was specifically fixed for the soon to be deprecated business events.

Steps to Reproduce?

  1. Add some Twig code using a snippet with the translation filter applied. Eg: {{ "email.shared.greeting"|trans({ '%name%': order.orderCustomer.firstName })|sw_sanitize }}
  2. Trigger the email to be send using the Flow builder, invoked by an action triggered from within the administration.

FYI: The templates that I've used were working in previous Shopware versions & haven't changed in the meanwhile. In that regard I'm not exactly sure since which version this stopped working.

tbkruse commented 1 year ago

@TimWuyts the reason for this bug is this change: https://github.com/shopware/platform/commit/f4c76e150ae6f69db28a98608c2f1a9586c2f6c9

The snippet collections are, starting from Showpare Version 6.4.17.x, filtered by the sales channel request 'theme-name' and 'theme-base-name'. A mail send event triggered by the administration is missing the theme name in the sales channel request.

I created a subscriber in our custom theme that loads the theme and parent theme in the 'onMailTemplatesLoaded' event with the current sales channel id: https://gist.github.com/tbkruse/44c5860bc4cecf196986ae70fc252234 Maybe this will help. In our theme the snippets are loaded again.

TimWuyts commented 1 year ago

@tbkruse Thanks for the provided gist. This was indeed the solution to our problem!

It would be good to refactor your code into the existing MailTemplateSubscriber from this plugin.

tbkruse commented 1 year ago

@TimWuyts I don't know if the change in the SnippetService by Shopware was intended to have this impact on rendering snippets in the administration.

If this fix would be applied it should load the complete (or same part) of the theme inheritance chain and I guess this can have an impact on the performance.

Maybe the "correct" way should be to add mail templates in plugins and not in themes because snippets from plugins are always loaded.

Or the usingThemes code:

$usingThemes = array_filter(array_unique([
            $request ? $request->attributes->get(SalesChannelRequest::ATTRIBUTE_THEME_NAME) : null,
            $request ? $request->attributes->get(SalesChannelRequest::ATTRIBUTE_THEME_BASE_NAME) : null,
            StorefrontPluginRegistry::BASE_THEME_NAME, // Storefront snippets should always be loaded
        ]));

should be changed. But I don't know if we have access to the sales channel id in all requests even if the originate in the administration. Maybe @shyim has an idea.

TimWuyts commented 1 year ago

This seems to be not the case, I've noticed that mails sent using alternative approaches (eg: CLI-command or using the queue) don't receive any context, which causes the translations to be not applied...

gnnrp commented 1 year ago

@tbkruse Is your fix still working with 6.5.1.0? When I create a subscriber as mentioned in your gist all mail is not send anymore.

tbkruse commented 1 year ago

@gnnrp I had a case when the gist didn't work as well for me. I don't remember anymore why but I change the Subscriber to inject all Translations for all the current language and all sales channels (wouldn't recommend it in a shop with many sales channels):

`public function onMailTemplatesLoaded(EntityLoadedEvent $entityLoadedEvent): void { $contextSource = $entityLoadedEvent->getContext()->getSource();

    if ($contextSource instanceof SalesChannelApiSource) {
        // The translations for sales channel requests are correctly loaded
        return;
    }

    $inject = <<<SQL

SELECT l.id AS languageId, sc.id AS salesChannelId, lo.code AS languageCode FROM sales_channel sc INNER JOIN language l ON l.id = :languageId INNER JOIN locale lo ON lo.id = l.locale_id WHERE sc.type_id = :salesChannelTypeStorefront SQL; try { $elements = $this->connection->fetchAllAssociative($inject, [ 'salesChannelTypeStorefront' => Uuid::fromHexToBytes(Defaults::SALES_CHANNEL_TYPE_STOREFRONT), 'languageId' => Uuid::fromHexToBytes($entityLoadedEvent->getContext()->getLanguageId()) ]); foreach ($elements as $element) { $languageId = Uuid::fromBytesToHex($element['languageId']); $salesChannelId = Uuid::fromBytesToHex($element['salesChannelId']); if ( !Uuid::isValid($languageId) || !Uuid::isValid($salesChannelId) ) { continue; } $this->translator->injectSettings( $salesChannelId, $languageId, $element['languageCode'], $entityLoadedEvent->getContext() ); } } catch (Exception|\Throwable $throwable) { $this->logger->error($throwable->getMessage()); } }`

gnnrp commented 1 year ago

Thanks @tbkruse! Still same behaviour - all mails are not send anymore when I change the subscriber as mentioned by you. I will debug and see if I find the problem…

Just to eliminate one error source: My entry in service.xml looks as following: `

` Am I missing something here?