Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit fb59ac0

Browse filesBrowse files
committed
[Mailer][TwigBridge] Add support for translatable subject
1 parent 86c8a8a commit fb59ac0
Copy full SHA for fb59ac0

File tree

8 files changed

+76
-3
lines changed
Filter options

8 files changed

+76
-3
lines changed

‎src/Symfony/Bridge/Twig/CHANGELOG.md

Copy file name to clipboardExpand all lines: src/Symfony/Bridge/Twig/CHANGELOG.md
+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ CHANGELOG
66

77
* Add `is_granted_for_user()` Twig function
88
* Add `field_id()` Twig form helper function
9+
* Add `TemplatedEmail::translatableSubject` method
910

1011
7.2
1112
---

‎src/Symfony/Bridge/Twig/Mime/TemplatedEmail.php

Copy file name to clipboardExpand all lines: src/Symfony/Bridge/Twig/Mime/TemplatedEmail.php
+21-1
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,36 @@
1212
namespace Symfony\Bridge\Twig\Mime;
1313

1414
use Symfony\Component\Mime\Email;
15+
use Symfony\Contracts\Translation\TranslatableInterface;
1516

1617
/**
1718
* @author Fabien Potencier <fabien@symfony.com>
1819
*/
1920
class TemplatedEmail extends Email
2021
{
22+
private string|\Stringable|null $subject = null;
2123
private ?string $htmlTemplate = null;
2224
private ?string $textTemplate = null;
2325
private ?string $locale = null;
2426
private array $context = [];
2527

28+
/**
29+
* @return $this
30+
*/
31+
public function subject(string|\Stringable $subject): static
32+
{
33+
parent::subject($subject);
34+
35+
$this->subject = $subject;
36+
37+
return $this;
38+
}
39+
40+
public function getTranslatableSubject(): string|\Stringable|null
41+
{
42+
return $this->subject;
43+
}
44+
2645
/**
2746
* @return $this
2847
*/
@@ -100,7 +119,7 @@ public function markAsRendered(): void
100119
*/
101120
public function __serialize(): array
102121
{
103-
return [$this->htmlTemplate, $this->textTemplate, $this->context, parent::__serialize(), $this->locale];
122+
return [$this->htmlTemplate, $this->textTemplate, $this->context, parent::__serialize(), $this->locale, $this->subject];
104123
}
105124

106125
/**
@@ -110,6 +129,7 @@ public function __unserialize(array $data): void
110129
{
111130
[$this->htmlTemplate, $this->textTemplate, $this->context, $parentData] = $data;
112131
$this->locale = $data[4] ?? null;
132+
$this->subject = $data[5] ?? null;
113133

114134
parent::__unserialize($parentData);
115135
}

‎src/Symfony/Bridge/Twig/Tests/Mime/TemplatedEmailTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Bridge/Twig/Tests/Mime/TemplatedEmailTest.php
+4
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
2222
use Symfony\Component\Serializer\Normalizer\PropertyNormalizer;
2323
use Symfony\Component\Serializer\Serializer;
24+
use Symfony\Component\Translation\TranslatableMessage;
2425

2526
class TemplatedEmailTest extends TestCase
2627
{
@@ -44,13 +45,15 @@ public function testSerialize()
4445
->htmlTemplate('text.html.twig')
4546
->context($context = ['a' => 'b'])
4647
->locale($locale = 'fr_FR')
48+
->subject($subject = new TranslatableMessage('hello {{ name }}', ['name' => 'John'], 'greetings'))
4749
;
4850

4951
$email = unserialize(serialize($email));
5052
$this->assertEquals('text.txt.twig', $email->getTextTemplate());
5153
$this->assertEquals('text.html.twig', $email->getHtmlTemplate());
5254
$this->assertEquals($context, $email->getContext());
5355
$this->assertEquals($locale, $email->getLocale());
56+
$this->assertEquals($subject, $email->getTranslatableSubject());
5457
}
5558

5659
public function testSymfonySerialize()
@@ -67,6 +70,7 @@ public function testSymfonySerialize()
6770

6871
$expectedJson = <<<EOF
6972
{
73+
"subject": null,
7074
"htmlTemplate": "email.html.twig",
7175
"textTemplate": "email.txt.twig",
7276
"locale": "en",

‎src/Symfony/Bundle/TwigBundle/Resources/config/mailer.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/TwigBundle/Resources/config/mailer.php
+5-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@
1818
return static function (ContainerConfigurator $container) {
1919
$container->services()
2020
->set('twig.mailer.message_listener', MessageListener::class)
21-
->args([null, service('twig.mime_body_renderer')])
21+
->args([
22+
null,
23+
service('twig.mime_body_renderer'),
24+
'$translator' => service('translator')->ignoreOnInvalid(),
25+
])
2226
->tag('kernel.event_subscriber')
2327

2428
->set('twig.mime_body_renderer', BodyRenderer::class)

‎src/Symfony/Component/Mailer/CHANGELOG.md

Copy file name to clipboardExpand all lines: src/Symfony/Component/Mailer/CHANGELOG.md
+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ CHANGELOG
99
* Add DSN param `source_ip` to allow binding to a (specific) IPv4 or IPv6 address.
1010
* Add DSN param `require_tls` to enforce use of TLS/STARTTLS
1111
* Add `DkimSignedMessageListener`, `SmimeEncryptedMessageListener`, and `SmimeSignedMessageListener`
12+
* Add support for translatable subject
1213

1314
7.2
1415
---

‎src/Symfony/Component/Mailer/EventListener/MessageListener.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Mailer/EventListener/MessageListener.php
+15-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Component\Mailer\EventListener;
1313

14+
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
1415
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
1516
use Symfony\Component\Mailer\Event\MessageEvent;
1617
use Symfony\Component\Mailer\Exception\InvalidArgumentException;
@@ -19,9 +20,11 @@
1920
use Symfony\Component\Mime\Header\Headers;
2021
use Symfony\Component\Mime\Header\MailboxListHeader;
2122
use Symfony\Component\Mime\Message;
23+
use Symfony\Component\Translation\TranslatableMessage;
24+
use Symfony\Contracts\Translation\TranslatorInterface;
2225

2326
/**
24-
* Manipulates the headers and the body of a Message.
27+
* Manipulates the headers, subject and the body of a Message.
2528
*
2629
* @author Fabien Potencier <fabien@symfony.com>
2730
*/
@@ -45,6 +48,7 @@ public function __construct(
4548
private ?Headers $headers = null,
4649
private ?BodyRendererInterface $renderer = null,
4750
array $headerRules = self::DEFAULT_RULES,
51+
private ?TranslatorInterface $translator = null,
4852
) {
4953
foreach ($headerRules as $headerName => $rule) {
5054
$this->addHeaderRule($headerName, $rule);
@@ -68,6 +72,7 @@ public function onMessage(MessageEvent $event): void
6872
}
6973

7074
$this->setHeaders($message);
75+
$this->translateSubject($message);
7176
$this->renderMessage($message);
7277
}
7378

@@ -115,6 +120,15 @@ private function setHeaders(Message $message): void
115120
}
116121
}
117122

123+
private function translateSubject(Message $message): void
124+
{
125+
if (!$message instanceof TemplatedEmail || !$this->translator || !$message->getTranslatableSubject() instanceof TranslatableMessage) {
126+
return;
127+
}
128+
129+
$message->subject($message->getTranslatableSubject()->trans($this->translator, $message->getLocale()));
130+
}
131+
118132
private function renderMessage(Message $message): void
119133
{
120134
if (!$this->renderer) {

‎src/Symfony/Component/Mailer/Tests/EventListener/MessageListenerTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Mailer/Tests/EventListener/MessageListenerTest.php
+28
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\Mailer\Tests\EventListener;
1313

1414
use PHPUnit\Framework\TestCase;
15+
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
1516
use Symfony\Component\Mailer\Envelope;
1617
use Symfony\Component\Mailer\Event\MessageEvent;
1718
use Symfony\Component\Mailer\EventListener\MessageListener;
@@ -20,6 +21,8 @@
2021
use Symfony\Component\Mime\Header\MailboxListHeader;
2122
use Symfony\Component\Mime\Header\UnstructuredHeader;
2223
use Symfony\Component\Mime\Message;
24+
use Symfony\Component\Translation\TranslatableMessage;
25+
use Symfony\Contracts\Translation\TranslatorInterface;
2326

2427
class MessageListenerTest extends TestCase
2528
{
@@ -114,4 +117,29 @@ public static function provideHeaders(): iterable
114117
];
115118
yield 'Capitalized header rule (case-insensitive), replace if set' => [$initialHeaders, $defaultHeaders, $defaultHeaders, $rules];
116119
}
120+
121+
public function testTranslatableSubject()
122+
{
123+
if (!method_exists(TemplatedEmail::class, 'getTranslatableSubject')) {
124+
$this->markTestSkipped();
125+
}
126+
127+
$message = new TemplatedEmail();
128+
$message->subject(new TranslatableMessage('hello.world'));
129+
$listener = new MessageListener(translator: new class implements TranslatorInterface {
130+
public function trans(string $id, array $parameters = [], ?string $domain = null, ?string $locale = null): string
131+
{
132+
return 'Hello World';
133+
}
134+
135+
public function getLocale(): string
136+
{
137+
return 'en';
138+
}
139+
});
140+
$event = new MessageEvent($message, new Envelope(new Address('sender@example.com'), [new Address('recipient@example.com')]), 'smtp');
141+
$listener->onMessage($event);
142+
143+
$this->assertSame('Hello World', $message->getSubject());
144+
}
117145
}

‎src/Symfony/Component/Mailer/composer.json

Copy file name to clipboardExpand all lines: src/Symfony/Component/Mailer/composer.json
+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
"symfony/console": "^6.4|^7.0",
2929
"symfony/http-client": "^6.4|^7.0",
3030
"symfony/messenger": "^6.4|^7.0",
31+
"symfony/translation": "^6.4|^7.0",
3132
"symfony/twig-bridge": "^6.4|^7.0"
3233
},
3334
"conflict": {

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.