diff --git a/src/Symfony/Bridge/Twig/Mime/BodyRenderer.php b/src/Symfony/Bridge/Twig/Mime/BodyRenderer.php index 5e75a69bb3..dfd348937d 100644 --- a/src/Symfony/Bridge/Twig/Mime/BodyRenderer.php +++ b/src/Symfony/Bridge/Twig/Mime/BodyRenderer.php @@ -46,6 +46,14 @@ final class BodyRenderer implements BodyRendererInterface } $messageContext = $message->getContext(); + + $previousRenderingKey = $messageContext[__CLASS__] ?? null; + unset($messageContext[__CLASS__]); + $currentRenderingKey = md5(serialize([$messageContext, $message->getTextTemplate(), $message->getHtmlTemplate()])); + if ($previousRenderingKey === $currentRenderingKey) { + return; + } + if (isset($messageContext['email'])) { throw new InvalidArgumentException(sprintf('A "%s" context cannot have an "email" entry as this is a reserved variable.', \get_class($message))); } @@ -66,6 +74,7 @@ final class BodyRenderer implements BodyRendererInterface if (!$message->getTextBody() && null !== $html = $message->getHtmlBody()) { $message->text($this->convertHtmlToText(\is_resource($html) ? stream_get_contents($html) : $html)); } + $message->context($message->getContext() + [__CLASS__ => $currentRenderingKey]); } private function convertHtmlToText(string $html): string diff --git a/src/Symfony/Bridge/Twig/Tests/Mime/BodyRendererTest.php b/src/Symfony/Bridge/Twig/Tests/Mime/BodyRendererTest.php index 316d41c159..f13ab213c3 100644 --- a/src/Symfony/Bridge/Twig/Tests/Mime/BodyRendererTest.php +++ b/src/Symfony/Bridge/Twig/Tests/Mime/BodyRendererTest.php @@ -79,6 +79,27 @@ HTML; $this->prepareEmail('Text', '', ['email' => 'reserved!']); } + public function testRenderedOnce() + { + $twig = new Environment(new ArrayLoader([ + 'text' => 'Text', + ])); + $renderer = new BodyRenderer($twig); + $email = (new TemplatedEmail()) + ->to('fabien@symfony.com') + ->from('helene@symfony.com') + ; + $email->textTemplate('text'); + + $renderer->render($email); + $this->assertEquals('Text', $email->getTextBody()); + + $email->text('reset'); + + $renderer->render($email); + $this->assertEquals('reset', $email->getTextBody()); + } + private function prepareEmail(?string $text, ?string $html, array $context = []): TemplatedEmail { $twig = new Environment(new ArrayLoader([