Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit fb59ac0

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

File tree

8 files changed

+76
-3
lines changed

8 files changed

+76
-3
lines changed

src/Symfony/Bridge/Twig/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
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

Lines changed: 21 additions & 1 deletion
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 <[email protected]>
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

Lines changed: 4 additions & 0 deletions
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

Lines changed: 5 additions & 1 deletion
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

Lines changed: 1 addition & 0 deletions
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

Lines changed: 15 additions & 1 deletion
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 <[email protected]>
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

Lines changed: 28 additions & 0 deletions
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('[email protected]'), [new Address('[email protected]')]), 'smtp');
141+
$listener->onMessage($event);
142+
143+
$this->assertSame('Hello World', $message->getSubject());
144+
}
117145
}

src/Symfony/Component/Mailer/composer.json

Lines changed: 1 addition & 0 deletions
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)