Merge branch '5.2' into 5.x
* 5.2: bug #40427 [Console] Stop accepting ints as InputOption defaults Fix fingerprint when context is not serializable Fix `ConstraintViolation#getMessageTemplate()` to always return `string`
This commit is contained in:
commit
7f65a27996
@ -49,7 +49,7 @@ final class BodyRenderer implements BodyRendererInterface
|
|||||||
|
|
||||||
$previousRenderingKey = $messageContext[__CLASS__] ?? null;
|
$previousRenderingKey = $messageContext[__CLASS__] ?? null;
|
||||||
unset($messageContext[__CLASS__]);
|
unset($messageContext[__CLASS__]);
|
||||||
$currentRenderingKey = md5(serialize([$messageContext, $message->getTextTemplate(), $message->getHtmlTemplate()]));
|
$currentRenderingKey = $this->getFingerPrint($message);
|
||||||
if ($previousRenderingKey === $currentRenderingKey) {
|
if ($previousRenderingKey === $currentRenderingKey) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -77,6 +77,23 @@ final class BodyRenderer implements BodyRendererInterface
|
|||||||
$message->context($message->getContext() + [__CLASS__ => $currentRenderingKey]);
|
$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
|
private function convertHtmlToText(string $html): string
|
||||||
{
|
{
|
||||||
if (null !== $this->converter) {
|
if (null !== $this->converter) {
|
||||||
|
@ -100,6 +100,27 @@ HTML;
|
|||||||
$this->assertEquals('reset', $email->getTextBody());
|
$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
|
private function prepareEmail(?string $text, ?string $html, array $context = []): TemplatedEmail
|
||||||
{
|
{
|
||||||
$twig = new Environment(new ArrayLoader([
|
$twig = new Environment(new ArrayLoader([
|
||||||
|
@ -429,9 +429,9 @@ class Command
|
|||||||
/**
|
/**
|
||||||
* Adds an option.
|
* Adds an option.
|
||||||
*
|
*
|
||||||
* @param string|array|null $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts
|
* @param string|array|null $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts
|
||||||
* @param int|null $mode The option mode: One of the InputOption::VALUE_* constants
|
* @param int|null $mode The option mode: One of the InputOption::VALUE_* constants
|
||||||
* @param string|string[]|int|bool|null $default The default value (must be null for InputOption::VALUE_NONE)
|
* @param string|string[]|bool|null $default The default value (must be null for InputOption::VALUE_NONE)
|
||||||
*
|
*
|
||||||
* @throws InvalidArgumentException If option mode is invalid or incompatible
|
* @throws InvalidArgumentException If option mode is invalid or incompatible
|
||||||
*
|
*
|
||||||
|
@ -34,11 +34,11 @@ class InputOption
|
|||||||
private $description;
|
private $description;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $name The option name
|
* @param string $name The option name
|
||||||
* @param string|array|null $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts
|
* @param string|array|null $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts
|
||||||
* @param int|null $mode The option mode: One of the VALUE_* constants
|
* @param int|null $mode The option mode: One of the VALUE_* constants
|
||||||
* @param string $description A description text
|
* @param string $description A description text
|
||||||
* @param string|string[]|int|bool|null $default The default value (must be null for self::VALUE_NONE)
|
* @param string|string[]|bool|null $default The default value (must be null for self::VALUE_NONE)
|
||||||
*
|
*
|
||||||
* @throws InvalidArgumentException If option mode is invalid or incompatible
|
* @throws InvalidArgumentException If option mode is invalid or incompatible
|
||||||
*/
|
*/
|
||||||
@ -158,7 +158,7 @@ class InputOption
|
|||||||
/**
|
/**
|
||||||
* Sets the default value.
|
* Sets the default value.
|
||||||
*
|
*
|
||||||
* @param string|string[]|int|bool|null $default The default value
|
* @param string|string[]|bool|null $default The default value
|
||||||
*
|
*
|
||||||
* @throws LogicException When incorrect default value is given
|
* @throws LogicException When incorrect default value is given
|
||||||
*/
|
*/
|
||||||
@ -185,7 +185,7 @@ class InputOption
|
|||||||
/**
|
/**
|
||||||
* Returns the default value.
|
* Returns the default value.
|
||||||
*
|
*
|
||||||
* @return string|string[]|int|bool|null The default value
|
* @return string|string[]|bool|null The default value
|
||||||
*/
|
*/
|
||||||
public function getDefault()
|
public function getDefault()
|
||||||
{
|
{
|
||||||
|
@ -100,7 +100,7 @@ class ConstraintViolation implements ConstraintViolationInterface
|
|||||||
*/
|
*/
|
||||||
public function getMessageTemplate()
|
public function getMessageTemplate()
|
||||||
{
|
{
|
||||||
return $this->messageTemplate;
|
return (string) $this->messageTemplate;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -171,4 +171,19 @@ EOF;
|
|||||||
))->getPropertyPath()
|
))->getPropertyPath()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testRetrievedMessageTemplateIsAStringEvenIfNotSet()
|
||||||
|
{
|
||||||
|
self::assertSame(
|
||||||
|
'',
|
||||||
|
(new ConstraintViolation(
|
||||||
|
'irrelevant',
|
||||||
|
null,
|
||||||
|
[],
|
||||||
|
'irrelevant',
|
||||||
|
'irrelevant',
|
||||||
|
null
|
||||||
|
))->getMessageTemplate()
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user