Fix fingerprint when context is not serializable

This commit is contained in:
Jérémy Derussé 2021-03-11 14:53:29 +01:00
parent 756522e977
commit c3e30ebda2
No known key found for this signature in database
GPG Key ID: 2083FA5758C473D2
2 changed files with 39 additions and 1 deletions

View File

@ -49,7 +49,7 @@ final class BodyRenderer implements BodyRendererInterface
$previousRenderingKey = $messageContext[__CLASS__] ?? null;
unset($messageContext[__CLASS__]);
$currentRenderingKey = md5(serialize([$messageContext, $message->getTextTemplate(), $message->getHtmlTemplate()]));
$currentRenderingKey = $this->getFingerPrint($message);
if ($previousRenderingKey === $currentRenderingKey) {
return;
}
@ -77,6 +77,23 @@ final class BodyRenderer implements BodyRendererInterface
$message->context($message->getContext() + [__CLASS__ => $currentRenderingKey]);
}
private function getFingerPrint(TemplatedEmail $message): string
{
$messageContext = $message->getContext();
unset($messageContext[__CLASS__]);
$payload = [$messageContext, $message->getTextTemplate(), $message->getHtmlTemplate()];
try {
$serialized = serialize($payload);
} catch (\Exception $e) {
// Serialization of 'Closure' is not allowed
// Happens when context contain a closure, in that case, we assume that context always change.
$serialized = random_bytes(8);
}
return md5($serialized);
}
private function convertHtmlToText(string $html): string
{
if (null !== $this->converter) {

View File

@ -100,6 +100,27 @@ HTML;
$this->assertEquals('reset', $email->getTextBody());
}
public function testRenderedOnceUnserializableContext()
{
$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');
$email->context([
'foo' => static function () {
return 'bar';
},
]);
$renderer->render($email);
$this->assertEquals('Text', $email->getTextBody());
}
private function prepareEmail(?string $text, ?string $html, array $context = []): TemplatedEmail
{
$twig = new Environment(new ArrayLoader([