Skip to content

Commit 1a9aa12

Browse files
committed
bug #39733 [TwigBridge] Render email once (jderusse)
This PR was merged into the 4.4 branch. Discussion ---------- [TwigBridge] Render email once | Q | A | ------------- | --- | Branch? | 4.4 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | Fix #39718 | License | MIT | Doc PR | - When `\Symfony\Component\Mailer\Mailer` send an email via the Bus (async) it dispatches an `MessageEvent`, then the consumer call the `\Symfony\Component\Mailer\Transport\AbstractTransport::send` method which also dispatches an `MessageEvent`. This event is listened by `\Symfony\Bridge\Twig\Mime\BodyRenderer::render` which rendered twice an email. I'm not sure why the event is send twice, and if we could safely remove one of them (or maybe deprecating the `MessageEvent`, in favor of `SendMessageEvent` + `AsyncMessageEvent`) This PR store a flag in the Message to avoid rendering it twice. Commits ------- 186ea59180 Render email once
2 parents e18a7f7 + 6246705 commit 1a9aa12

File tree

2 files changed

+30
-0
lines changed

2 files changed

+30
-0
lines changed

Mime/BodyRenderer.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,14 @@ public function render(Message $message): void
4646
}
4747

4848
$messageContext = $message->getContext();
49+
50+
$previousRenderingKey = $messageContext[__CLASS__] ?? null;
51+
unset($messageContext[__CLASS__]);
52+
$currentRenderingKey = md5(serialize([$messageContext, $message->getTextTemplate(), $message->getHtmlTemplate()]));
53+
if ($previousRenderingKey === $currentRenderingKey) {
54+
return;
55+
}
56+
4957
if (isset($messageContext['email'])) {
5058
throw new InvalidArgumentException(sprintf('A "%s" context cannot have an "email" entry as this is a reserved variable.', \get_class($message)));
5159
}
@@ -66,6 +74,7 @@ public function render(Message $message): void
6674
if (!$message->getTextBody() && null !== $html = $message->getHtmlBody()) {
6775
$message->text($this->convertHtmlToText(\is_resource($html) ? stream_get_contents($html) : $html));
6876
}
77+
$message->context($message->getContext() + [__CLASS__ => $currentRenderingKey]);
6978
}
7079

7180
private function convertHtmlToText(string $html): string

Tests/Mime/BodyRendererTest.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,27 @@ public function testRenderWithContextReservedEmailEntry()
7979
$this->prepareEmail('Text', '', ['email' => 'reserved!']);
8080
}
8181

82+
public function testRenderedOnce()
83+
{
84+
$twig = new Environment(new ArrayLoader([
85+
'text' => 'Text',
86+
]));
87+
$renderer = new BodyRenderer($twig);
88+
$email = (new TemplatedEmail())
89+
90+
91+
;
92+
$email->textTemplate('text');
93+
94+
$renderer->render($email);
95+
$this->assertEquals('Text', $email->getTextBody());
96+
97+
$email->text('reset');
98+
99+
$renderer->render($email);
100+
$this->assertEquals('reset', $email->getTextBody());
101+
}
102+
82103
private function prepareEmail(?string $text, ?string $html, array $context = []): TemplatedEmail
83104
{
84105
$twig = new Environment(new ArrayLoader([

0 commit comments

Comments
 (0)