diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd b/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd
index 2ec204f6f1..84151a2099 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd
+++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd
@@ -414,6 +414,7 @@
+
@@ -444,12 +445,21 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/messenger_transports.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/messenger_transports.php
index 68ff360746..0aff440e85 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/messenger_transports.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/messenger_transports.php
@@ -3,6 +3,7 @@
$container->loadFromExtension('framework', [
'serializer' => true,
'messenger' => [
+ 'failure_transport' => 'failed',
'serializer' => [
'default_serializer' => 'messenger.transport.symfony_serializer',
],
@@ -12,7 +13,14 @@ $container->loadFromExtension('framework', [
'dsn' => 'amqp://localhost/%2f/messages?exchange_name=exchange_name',
'options' => ['queue' => ['name' => 'Queue']],
'serializer' => 'messenger.transport.native_php_serializer',
+ 'retry_strategy' => [
+ 'max_retries' => 10,
+ 'delay' => 7,
+ 'multiplier' => 3,
+ 'max_delay' => 100,
+ ],
],
+ 'failed' => 'in-memory:///',
'redis' => 'redis://127.0.0.1:6379/messages',
],
],
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/messenger_transports.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/messenger_transports.xml
index bb698cbc17..837db14c1c 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/messenger_transports.xml
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/messenger_transports.xml
@@ -7,7 +7,7 @@
-
+
@@ -16,7 +16,9 @@
Queue
+
+
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/messenger_transports.yml b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/messenger_transports.yml
index 2fc1f48265..daab75bd87 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/messenger_transports.yml
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/messenger_transports.yml
@@ -1,6 +1,7 @@
framework:
serializer: true
messenger:
+ failure_transport: failed
serializer:
default_serializer: messenger.transport.symfony_serializer
transports:
@@ -11,4 +12,10 @@ framework:
queue:
name: Queue
serializer: 'messenger.transport.native_php_serializer'
+ retry_strategy:
+ max_retries: 10
+ delay: 7
+ multiplier: 3
+ max_delay: 100
+ failed: 'in-memory:///'
redis: 'redis://127.0.0.1:6379/messages'
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php
index 0ee3b892aa..657b67e8f0 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php
@@ -627,6 +627,13 @@ abstract class FrameworkExtensionTest extends TestCase
$this->assertSame('redis://127.0.0.1:6379/messages', $transportArguments[0]);
$this->assertTrue($container->hasDefinition('messenger.transport.redis.factory'));
+
+ $this->assertSame(10, $container->getDefinition('messenger.retry.multiplier_retry_strategy.customised')->getArgument(0));
+ $this->assertSame(7, $container->getDefinition('messenger.retry.multiplier_retry_strategy.customised')->getArgument(1));
+ $this->assertSame(3, $container->getDefinition('messenger.retry.multiplier_retry_strategy.customised')->getArgument(2));
+ $this->assertSame(100, $container->getDefinition('messenger.retry.multiplier_retry_strategy.customised')->getArgument(3));
+
+ $this->assertEquals(new Reference('messenger.transport.failed'), $container->getDefinition('messenger.failure.send_failed_message_to_failure_transport_listener')->getArgument(0));
}
public function testMessengerRouting()
diff --git a/src/Symfony/Component/DomCrawler/Form.php b/src/Symfony/Component/DomCrawler/Form.php
index 6d8cced74f..56d10108c1 100644
--- a/src/Symfony/Component/DomCrawler/Form.php
+++ b/src/Symfony/Component/DomCrawler/Form.php
@@ -273,7 +273,7 @@ class Form extends Link implements \ArrayAccess
/**
* Gets a named field.
*
- * @return FormField The field instance
+ * @return FormField|FormField[]|FormField[][] The value of the field
*
* @throws \InvalidArgumentException When field is not present in this form
*/
@@ -317,7 +317,7 @@ class Form extends Link implements \ArrayAccess
*
* @param string $name The field name
*
- * @return FormField The associated Field instance
+ * @return FormField|FormField[]|FormField[][] The value of the field
*
* @throws \InvalidArgumentException if the field does not exist
*/
diff --git a/src/Symfony/Component/DomCrawler/FormFieldRegistry.php b/src/Symfony/Component/DomCrawler/FormFieldRegistry.php
index f8764119a2..7cfdd53494 100644
--- a/src/Symfony/Component/DomCrawler/FormFieldRegistry.php
+++ b/src/Symfony/Component/DomCrawler/FormFieldRegistry.php
@@ -66,7 +66,7 @@ class FormFieldRegistry
/**
* Returns the value of the field based on the fully qualifed name and its children.
*
- * @return mixed The value of the field
+ * @return FormField|FormField[]|FormField[][] The value of the field
*
* @throws \InvalidArgumentException if the field does not exist
*/
diff --git a/src/Symfony/Component/DomCrawler/Tests/FormTest.php b/src/Symfony/Component/DomCrawler/Tests/FormTest.php
index 9975b91afe..52e778bed9 100644
--- a/src/Symfony/Component/DomCrawler/Tests/FormTest.php
+++ b/src/Symfony/Component/DomCrawler/Tests/FormTest.php
@@ -12,6 +12,7 @@
namespace Symfony\Component\DomCrawler\Tests;
use PHPUnit\Framework\TestCase;
+use Symfony\Component\DomCrawler\Field\TextareaFormField;
use Symfony\Component\DomCrawler\Form;
use Symfony\Component\DomCrawler\FormFieldRegistry;
@@ -965,7 +966,7 @@ class FormTest extends TestCase
return $dom;
}
- public function testgetPhpValuesWithEmptyTextarea()
+ public function testGetPhpValuesWithEmptyTextarea()
{
$dom = new \DOMDocument();
$dom->loadHTML('
@@ -980,4 +981,34 @@ class FormTest extends TestCase
$form = new Form($nodes->item(0), 'http://example.com');
$this->assertEquals($form->getPhpValues(), ['example' => '']);
}
+
+ public function testGetReturnTypes()
+ {
+ $dom = new \DOMDocument();
+ $dom->loadHTML('
+
+
+ '
+ );
+
+ $nodes = $dom->getElementsByTagName('form');
+ $form = new Form($nodes->item(0), 'http://example.com');
+
+ // FormField
+ $this->assertInstanceOf(TextareaFormField::class, $textareaFormField = $form->get('foo[collection][0][bar]'));
+
+ // Array of FormField
+ $this->assertSame([
+ 'bar' => $textareaFormField,
+ ], $form->get('foo[collection][0]'));
+
+ // Array of array of FormField
+ $this->assertSame([
+ [
+ 'bar' => $textareaFormField,
+ ],
+ ], $form->get('foo[collection]'));
+ }
}
diff --git a/src/Symfony/Component/Dotenv/README.md b/src/Symfony/Component/Dotenv/README.md
index c21223b04e..10bfff14ba 100644
--- a/src/Symfony/Component/Dotenv/README.md
+++ b/src/Symfony/Component/Dotenv/README.md
@@ -2,7 +2,7 @@ Dotenv Component
================
Symfony Dotenv parses `.env` files to make environment variables stored in them
-accessible via `$_SERVER`, `$_ENV` and optionally `getenv()`.
+accessible via `$_SERVER` or `$_ENV`.
Resources
---------
diff --git a/src/Symfony/Component/ErrorHandler/DebugClassLoader.php b/src/Symfony/Component/ErrorHandler/DebugClassLoader.php
index 024034c13a..e210acdf10 100644
--- a/src/Symfony/Component/ErrorHandler/DebugClassLoader.php
+++ b/src/Symfony/Component/ErrorHandler/DebugClassLoader.php
@@ -427,17 +427,17 @@ class DebugClassLoader
}
}
- if ($refl->isInterface() && false !== strpos($doc, 'method') && preg_match_all('#\n \* @method\s+(static\s+)?+(?:[\w\|&\[\]\\\]+\s+)?(\w+(?:\s*\([^\)]*\))?)+(.+?([[:punct:]]\s*)?)?(?=\r?\n \*(?: @|/$|\r?\n))#', $doc, $notice, PREG_SET_ORDER)) {
+ if ($refl->isInterface() && false !== strpos($doc, 'method') && preg_match_all('#\n \* @method\s+(static\s+)?+([\w\|&\[\]\\\]+\s+)?(\w+(?:\s*\([^\)]*\))?)+(.+?([[:punct:]]\s*)?)?(?=\r?\n \*(?: @|/$|\r?\n))#', $doc, $notice, PREG_SET_ORDER)) {
foreach ($notice as $method) {
- $static = '' !== $method[1];
- $name = $method[2];
- $description = $method[3] ?? null;
+ $static = '' !== $method[1] && !empty($method[2]);
+ $name = $method[3];
+ $description = $method[4] ?? null;
if (false === strpos($name, '(')) {
$name .= '()';
}
if (null !== $description) {
$description = trim($description);
- if (!isset($method[4])) {
+ if (!isset($method[5])) {
$description .= '.';
}
}
diff --git a/src/Symfony/Component/ErrorHandler/Tests/DebugClassLoaderTest.php b/src/Symfony/Component/ErrorHandler/Tests/DebugClassLoaderTest.php
index adf55432ee..d0ff0afba8 100644
--- a/src/Symfony/Component/ErrorHandler/Tests/DebugClassLoaderTest.php
+++ b/src/Symfony/Component/ErrorHandler/Tests/DebugClassLoaderTest.php
@@ -325,6 +325,7 @@ class DebugClassLoaderTest extends TestCase
restore_error_handler();
$this->assertSame([
+ 'Class "Test\Symfony\Component\ErrorHandler\Tests\ExtendsVirtualParent" should implement method "Symfony\Component\ErrorHandler\Tests\Fixtures\VirtualInterface::staticReturningMethod()".',
'Class "Test\Symfony\Component\ErrorHandler\Tests\ExtendsVirtualParent" should implement method "Symfony\Component\ErrorHandler\Tests\Fixtures\VirtualInterface::sameLineInterfaceMethodNoBraces()".',
'Class "Test\Symfony\Component\ErrorHandler\Tests\ExtendsVirtualParent" should implement method "Symfony\Component\ErrorHandler\Tests\Fixtures\VirtualInterface::newLineInterfaceMethod()": Some description!',
'Class "Test\Symfony\Component\ErrorHandler\Tests\ExtendsVirtualParent" should implement method "Symfony\Component\ErrorHandler\Tests\Fixtures\VirtualInterface::newLineInterfaceMethodNoBraces()": Description.',
diff --git a/src/Symfony/Component/ErrorHandler/Tests/Fixtures/VirtualInterface.php b/src/Symfony/Component/ErrorHandler/Tests/Fixtures/VirtualInterface.php
index fd1c8ba04e..5c9136081f 100644
--- a/src/Symfony/Component/ErrorHandler/Tests/Fixtures/VirtualInterface.php
+++ b/src/Symfony/Component/ErrorHandler/Tests/Fixtures/VirtualInterface.php
@@ -4,6 +4,7 @@ namespace Symfony\Component\ErrorHandler\Tests\Fixtures;
/**
* @method string interfaceMethod()
+ * @method static staticReturningMethod()
* @method sameLineInterfaceMethod($arg)
* @method sameLineInterfaceMethodNoBraces
*
@@ -25,7 +26,7 @@ namespace Symfony\Component\ErrorHandler\Tests\Fixtures;
*
* Static
* @method static Foo&Bar staticMethod()
- * @method static staticMethodNoBraces
+ * @method static mixed staticMethodNoBraces
* @method static \stdClass staticMethodTyped(int $arg) Description
* @method static \stdClass[] staticMethodTypedNoBraces
*/
diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/NumberToLocalizedStringTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/NumberToLocalizedStringTransformer.php
index 8e0e1454e0..59d59093e0 100644
--- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/NumberToLocalizedStringTransformer.php
+++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/NumberToLocalizedStringTransformer.php
@@ -279,7 +279,7 @@ class NumberToLocalizedStringTransformer implements DataTransformerInterface
break;
}
- $number /= $roundingCoef;
+ $number = 1 === $roundingCoef ? (int) $number : $number / $roundingCoef;
}
return $number;
diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/NumberToLocalizedStringTransformerTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/NumberToLocalizedStringTransformerTest.php
index cb3f5d890e..80da74ed56 100644
--- a/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/NumberToLocalizedStringTransformerTest.php
+++ b/src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/NumberToLocalizedStringTransformerTest.php
@@ -370,7 +370,7 @@ class NumberToLocalizedStringTransformerTest extends TestCase
{
$transformer = new NumberToLocalizedStringTransformer($scale, null, $roundingMode);
- $this->assertEquals($output, $transformer->reverseTransform($input));
+ $this->assertSame($output, $transformer->reverseTransform($input));
}
public function testReverseTransformDoesNotRoundIfNoScale()
diff --git a/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php b/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php
index 5620dc5c1e..33942d73fe 100644
--- a/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php
+++ b/src/Symfony/Component/Serializer/Encoder/XmlEncoder.php
@@ -11,6 +11,7 @@
namespace Symfony\Component\Serializer\Encoder;
+use Symfony\Component\Serializer\Exception\BadMethodCallException;
use Symfony\Component\Serializer\Exception\NotEncodableValueException;
use Symfony\Component\Serializer\SerializerAwareInterface;
use Symfony\Component\Serializer\SerializerAwareTrait;
@@ -368,7 +369,7 @@ class XmlEncoder implements EncoderInterface, DecoderInterface, NormalizationAwa
$removeEmptyTags = $this->context[self::REMOVE_EMPTY_TAGS] ?? $this->defaultContext[self::REMOVE_EMPTY_TAGS] ?? false;
$encoderIgnoredNodeTypes = $this->context[self::ENCODER_IGNORED_NODE_TYPES] ?? $this->defaultContext[self::ENCODER_IGNORED_NODE_TYPES];
- if (\is_array($data) || ($data instanceof \Traversable && !$this->serializer->supportsNormalization($data, $this->format))) {
+ if (\is_array($data) || ($data instanceof \Traversable && (null === $this->serializer || !$this->serializer->supportsNormalization($data, $this->format)))) {
foreach ($data as $key => $data) {
//Ah this is the magic @ attribute types.
if (0 === strpos($key, '@') && $this->isElementNameValid($attributeName = substr($key, 1))) {
@@ -407,6 +408,10 @@ class XmlEncoder implements EncoderInterface, DecoderInterface, NormalizationAwa
}
if (\is_object($data)) {
+ if (null === $this->serializer) {
+ throw new BadMethodCallException(sprintf('The serializer needs to be set to allow %s() to be used with object data.', __METHOD__));
+ }
+
$data = $this->serializer->normalize($data, $this->format, $this->context);
if (null !== $data && !is_scalar($data)) {
return $this->buildXml($parentNode, $data, $xmlRootNodeName);
@@ -469,6 +474,10 @@ class XmlEncoder implements EncoderInterface, DecoderInterface, NormalizationAwa
} elseif ($val instanceof \Traversable) {
$this->buildXml($node, $val);
} elseif (\is_object($val)) {
+ if (null === $this->serializer) {
+ throw new BadMethodCallException(sprintf('The serializer needs to be set to allow %s() to be used with object data.', __METHOD__));
+ }
+
return $this->selectNodeType($node, $this->serializer->normalize($val, $this->format, $this->context));
} elseif (is_numeric($val)) {
return $this->appendText($node, (string) $val);
diff --git a/src/Symfony/Component/Serializer/Normalizer/ArrayDenormalizer.php b/src/Symfony/Component/Serializer/Normalizer/ArrayDenormalizer.php
index 935e7a0323..ad5090faa5 100644
--- a/src/Symfony/Component/Serializer/Normalizer/ArrayDenormalizer.php
+++ b/src/Symfony/Component/Serializer/Normalizer/ArrayDenormalizer.php
@@ -68,6 +68,10 @@ class ArrayDenormalizer implements ContextAwareDenormalizerInterface, Serializer
*/
public function supportsDenormalization($data, string $type, string $format = null, array $context = []): bool
{
+ if (null === $this->serializer) {
+ throw new BadMethodCallException(sprintf('The serializer needs to be set to allow %s() to be used.', __METHOD__));
+ }
+
return '[]' === substr($type, -2)
&& $this->serializer->supportsDenormalization($data, substr($type, 0, -2), $format, $context);
}
diff --git a/src/Symfony/Component/Validator/ConstraintValidator.php b/src/Symfony/Component/Validator/ConstraintValidator.php
index 4d66776839..02a8261eff 100644
--- a/src/Symfony/Component/Validator/ConstraintValidator.php
+++ b/src/Symfony/Component/Validator/ConstraintValidator.php
@@ -21,8 +21,8 @@ use Symfony\Component\Validator\Context\ExecutionContextInterface;
abstract class ConstraintValidator implements ConstraintValidatorInterface
{
/**
- * Whether to format {@link \DateTime} objects as RFC-3339 dates
- * ("Y-m-d H:i:s").
+ * Whether to format {@link \DateTime} objects, either with the {@link \IntlDateFormatter}
+ * (if it is available) or as RFC-3339 dates ("Y-m-d H:i:s").
*/
const PRETTY_DATE = 1;
@@ -69,7 +69,8 @@ abstract class ConstraintValidator implements ConstraintValidatorInterface
* in double quotes ("). Objects, arrays and resources are formatted as
* "object", "array" and "resource". If the $format bitmask contains
* the PRETTY_DATE bit, then {@link \DateTime} objects will be formatted
- * as RFC-3339 dates ("Y-m-d H:i:s").
+ * with the {@link \IntlDateFormatter}. If it is not available, they will be
+ * formatted as RFC-3339 dates ("Y-m-d H:i:s").
*
* Be careful when passing message parameters to a constraint violation
* that (may) contain objects, arrays or resources. These parameters
diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.de.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.de.xlf
index 0702e8dfcd..a546b86c78 100644
--- a/src/Symfony/Component/Validator/Resources/translations/validators.de.xlf
+++ b/src/Symfony/Component/Validator/Resources/translations/validators.de.xlf
@@ -370,6 +370,10 @@
This value is not a valid hostname.
Dieser Wert ist kein gültiger Hostname.
+
+ The number of elements in this collection should be a multiple of {{ compared_value }}.
+ Die Anzahl an Elementen in dieser Sammlung sollte ein Vielfaches von {{ compared_value }} sein.
+