From d912384b7f2e46c5053e0f42514a9ec0516619a0 Mon Sep 17 00:00:00 2001 From: Alexander Schranz Date: Tue, 19 Sep 2023 00:02:41 +0200 Subject: [PATCH] [Mime] Add `TemplatedEmail::locale()` to set the locale for the email rendering --- src/Symfony/Bridge/Twig/CHANGELOG.md | 3 +- src/Symfony/Bridge/Twig/Mime/BodyRenderer.php | 53 ++++++++++++------- .../Bridge/Twig/Mime/TemplatedEmail.php | 16 ++++++ .../Twig/Tests/Mime/BodyRendererTest.php | 22 +++++++- .../Twig/Tests/Mime/TemplatedEmailTest.php | 2 + .../DependencyInjection/TwigExtension.php | 5 ++ src/Symfony/Bundle/TwigBundle/composer.json | 2 +- 7 files changed, 80 insertions(+), 23 deletions(-) diff --git a/src/Symfony/Bridge/Twig/CHANGELOG.md b/src/Symfony/Bridge/Twig/CHANGELOG.md index bb342c44ded49..89f3b00a74e3a 100644 --- a/src/Symfony/Bridge/Twig/CHANGELOG.md +++ b/src/Symfony/Bridge/Twig/CHANGELOG.md @@ -4,7 +4,8 @@ CHANGELOG 6.4 --- -* Allow an array to be passed as the first argument to the `importmap()` Twig function + * Allow an array to be passed as the first argument to the `importmap()` Twig function + * Add `TemplatedEmail::locale()` to set the locale for the email rendering 6.3 --- diff --git a/src/Symfony/Bridge/Twig/Mime/BodyRenderer.php b/src/Symfony/Bridge/Twig/Mime/BodyRenderer.php index d418ee2f38634..18e0eb1f86693 100644 --- a/src/Symfony/Bridge/Twig/Mime/BodyRenderer.php +++ b/src/Symfony/Bridge/Twig/Mime/BodyRenderer.php @@ -18,6 +18,7 @@ use Symfony\Component\Mime\HtmlToTextConverter\HtmlToTextConverterInterface; use Symfony\Component\Mime\HtmlToTextConverter\LeagueHtmlToMarkdownConverter; use Symfony\Component\Mime\Message; +use Symfony\Component\Translation\LocaleSwitcher; use Twig\Environment; /** @@ -28,12 +29,14 @@ final class BodyRenderer implements BodyRendererInterface private Environment $twig; private array $context; private HtmlToTextConverterInterface $converter; + private ?LocaleSwitcher $localeSwitcher = null; - public function __construct(Environment $twig, array $context = [], HtmlToTextConverterInterface $converter = null) + public function __construct(Environment $twig, array $context = [], HtmlToTextConverterInterface $converter = null, LocaleSwitcher $localeSwitcher = null) { $this->twig = $twig; $this->context = $context; $this->converter = $converter ?: (interface_exists(HtmlConverterInterface::class) ? new LeagueHtmlToMarkdownConverter() : new DefaultHtmlToTextConverter()); + $this->localeSwitcher = $localeSwitcher; } public function render(Message $message): void @@ -47,30 +50,42 @@ public function render(Message $message): void return; } - $messageContext = $message->getContext(); + $callback = function () use ($message) { + $messageContext = $message->getContext(); - if (isset($messageContext['email'])) { - throw new InvalidArgumentException(sprintf('A "%s" context cannot have an "email" entry as this is a reserved variable.', get_debug_type($message))); - } + if (isset($messageContext['email'])) { + throw new InvalidArgumentException(sprintf('A "%s" context cannot have an "email" entry as this is a reserved variable.', get_debug_type($message))); + } - $vars = array_merge($this->context, $messageContext, [ - 'email' => new WrappedTemplatedEmail($this->twig, $message), - ]); + $vars = array_merge($this->context, $messageContext, [ + 'email' => new WrappedTemplatedEmail($this->twig, $message), + ]); - if ($template = $message->getTextTemplate()) { - $message->text($this->twig->render($template, $vars)); - } + if ($template = $message->getTextTemplate()) { + $message->text($this->twig->render($template, $vars)); + } - if ($template = $message->getHtmlTemplate()) { - $message->html($this->twig->render($template, $vars)); - } + if ($template = $message->getHtmlTemplate()) { + $message->html($this->twig->render($template, $vars)); + } + + $message->markAsRendered(); - $message->markAsRendered(); + // if text body is empty, compute one from the HTML body + if (!$message->getTextBody() && null !== $html = $message->getHtmlBody()) { + $text = $this->converter->convert(\is_resource($html) ? stream_get_contents($html) : $html, $message->getHtmlCharset()); + $message->text($text, $message->getHtmlCharset()); + } + }; - // if text body is empty, compute one from the HTML body - if (!$message->getTextBody() && null !== $html = $message->getHtmlBody()) { - $text = $this->converter->convert(\is_resource($html) ? stream_get_contents($html) : $html, $message->getHtmlCharset()); - $message->text($text, $message->getHtmlCharset()); + $locale = $message->getLocale(); + + if ($locale && $this->localeSwitcher) { + $this->localeSwitcher->runWithLocale($locale, $callback); + + return; } + + $callback(); } } diff --git a/src/Symfony/Bridge/Twig/Mime/TemplatedEmail.php b/src/Symfony/Bridge/Twig/Mime/TemplatedEmail.php index 777cc06b58984..e5c990f3ba733 100644 --- a/src/Symfony/Bridge/Twig/Mime/TemplatedEmail.php +++ b/src/Symfony/Bridge/Twig/Mime/TemplatedEmail.php @@ -20,6 +20,7 @@ class TemplatedEmail extends Email { private ?string $htmlTemplate = null; private ?string $textTemplate = null; + private ?string $locale = null; private array $context = []; /** @@ -42,6 +43,16 @@ public function htmlTemplate(?string $template): static return $this; } + /** + * @return $this + */ + public function locale(?string $locale): static + { + $this->locale = $locale; + + return $this; + } + public function getTextTemplate(): ?string { return $this->textTemplate; @@ -52,6 +63,11 @@ public function getHtmlTemplate(): ?string return $this->htmlTemplate; } + public function getLocale(): ?string + { + return $this->locale; + } + /** * @return $this */ diff --git a/src/Symfony/Bridge/Twig/Tests/Mime/BodyRendererTest.php b/src/Symfony/Bridge/Twig/Tests/Mime/BodyRendererTest.php index 6af152dad6c5e..ddc6f46d19873 100644 --- a/src/Symfony/Bridge/Twig/Tests/Mime/BodyRendererTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Mime/BodyRendererTest.php @@ -18,8 +18,10 @@ use Symfony\Component\Mime\HtmlToTextConverter\DefaultHtmlToTextConverter; use Symfony\Component\Mime\HtmlToTextConverter\HtmlToTextConverterInterface; use Symfony\Component\Mime\Part\Multipart\AlternativePart; +use Symfony\Component\Translation\LocaleSwitcher; use Twig\Environment; use Twig\Loader\ArrayLoader; +use Twig\TwigFunction; class BodyRendererTest extends TestCase { @@ -131,7 +133,16 @@ public function testRenderedOnceUnserializableContext() $this->assertEquals('Text', $email->getTextBody()); } - private function prepareEmail(?string $text, ?string $html, array $context = [], HtmlToTextConverterInterface $converter = null): TemplatedEmail + public function testRenderWithLocale() + { + $localeSwitcher = new LocaleSwitcher('en', []); + $email = $this->prepareEmail(null, 'Locale: {{ locale_switcher_locale() }}', [], new DefaultHtmlToTextConverter(), $localeSwitcher, 'fr'); + + $this->assertEquals('Locale: fr', $email->getTextBody()); + $this->assertEquals('Locale: fr', $email->getHtmlBody()); + } + + private function prepareEmail(?string $text, ?string $html, array $context = [], HtmlToTextConverterInterface $converter = null, LocaleSwitcher $localeSwitcher = null, string $locale = null): TemplatedEmail { $twig = new Environment(new ArrayLoader([ 'text' => $text, @@ -139,12 +150,19 @@ private function prepareEmail(?string $text, ?string $html, array $context = [], 'document.txt' => 'Some text document...', 'image.jpg' => 'Some image data', ])); - $renderer = new BodyRenderer($twig, [], $converter); + + if ($localeSwitcher instanceof LocaleSwitcher) { + $twig->addFunction(new TwigFunction('locale_switcher_locale', [$localeSwitcher, 'getLocale'])); + } + + $renderer = new BodyRenderer($twig, [], $converter, $localeSwitcher); $email = (new TemplatedEmail()) ->to('fabien@symfony.com') ->from('helene@symfony.com') + ->locale($locale) ->context($context) ; + if (null !== $text) { $email->textTemplate('text'); } diff --git a/src/Symfony/Bridge/Twig/Tests/Mime/TemplatedEmailTest.php b/src/Symfony/Bridge/Twig/Tests/Mime/TemplatedEmailTest.php index 019be16ff4bcf..f796c7a05db7e 100644 --- a/src/Symfony/Bridge/Twig/Tests/Mime/TemplatedEmailTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Mime/TemplatedEmailTest.php @@ -58,6 +58,7 @@ public function testSymfonySerialize() $e->to('you@example.com'); $e->textTemplate('email.txt.twig'); $e->htmlTemplate('email.html.twig'); + $e->locale('en'); $e->context(['foo' => 'bar']); $e->addPart(new DataPart('Some Text file', 'test.txt')); $expected = clone $e; @@ -66,6 +67,7 @@ public function testSymfonySerialize() { "htmlTemplate": "email.html.twig", "textTemplate": "email.txt.twig", + "locale": "en", "context": { "foo": "bar" }, diff --git a/src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php b/src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php index deac87b8b62ce..546afd55f499c 100644 --- a/src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php +++ b/src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php @@ -22,6 +22,7 @@ use Symfony\Component\Form\Form; use Symfony\Component\HttpKernel\DependencyInjection\Extension; use Symfony\Component\Mailer\Mailer; +use Symfony\Component\Translation\LocaleSwitcher; use Symfony\Component\Translation\Translator; use Symfony\Contracts\Service\ResetInterface; use Twig\Extension\ExtensionInterface; @@ -85,6 +86,10 @@ public function load(array $configs, ContainerBuilder $container) if ($htmlToTextConverter = $config['mailer']['html_to_text_converter'] ?? null) { $container->getDefinition('twig.mime_body_renderer')->setArgument('$converter', new Reference($htmlToTextConverter)); } + + if (ContainerBuilder::willBeAvailable('symfony/translation', LocaleSwitcher::class, ['symfony/framework-bundle'])) { + $container->getDefinition('twig.mime_body_renderer')->setArgument('$localeSwitcher', new Reference('translation.locale_switcher')); + } } if ($container::willBeAvailable('symfony/asset-mapper', AssetMapper::class, ['symfony/twig-bundle'])) { diff --git a/src/Symfony/Bundle/TwigBundle/composer.json b/src/Symfony/Bundle/TwigBundle/composer.json index 602fa21ee7981..835ccc219e940 100644 --- a/src/Symfony/Bundle/TwigBundle/composer.json +++ b/src/Symfony/Bundle/TwigBundle/composer.json @@ -20,7 +20,7 @@ "composer-runtime-api": ">=2.1", "symfony/config": "^6.1|^7.0", "symfony/dependency-injection": "^6.1|^7.0", - "symfony/twig-bridge": "^6.3|^7.0", + "symfony/twig-bridge": "^6.4|^7.0", "symfony/http-foundation": "^5.4|^6.0|^7.0", "symfony/http-kernel": "^6.2|^7.0", "twig/twig": "^2.13|^3.0.4" pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy