From 7e6fcc2105f5a97f4b6fd6a010ce4ece2adf16ea Mon Sep 17 00:00:00 2001 From: HypeMC Date: Sun, 17 Dec 2023 21:48:18 +0100 Subject: [PATCH 1/7] [Serializer] Fix using deserialization path --- Normalizer/AbstractNormalizer.php | 2 +- Normalizer/AbstractObjectNormalizer.php | 2 +- Tests/SerializerTest.php | 81 +++++++++++++++++++++++-- composer.json | 2 +- 4 files changed, 78 insertions(+), 9 deletions(-) diff --git a/Normalizer/AbstractNormalizer.php b/Normalizer/AbstractNormalizer.php index 0d0181ae8..1a7c314b8 100644 --- a/Normalizer/AbstractNormalizer.php +++ b/Normalizer/AbstractNormalizer.php @@ -414,7 +414,7 @@ protected function instantiateObject(array &$data, string $class, array &$contex sprintf('Failed to create object because the class misses the "%s" property.', $constructorParameter->name), $data, ['unknown'], - $objectDeserializationPath, + $context['deserialization_path'], true ); $context['not_normalizable_value_exceptions'][] = $exception; diff --git a/Normalizer/AbstractObjectNormalizer.php b/Normalizer/AbstractObjectNormalizer.php index cd24de584..a51b69503 100644 --- a/Normalizer/AbstractObjectNormalizer.php +++ b/Normalizer/AbstractObjectNormalizer.php @@ -437,7 +437,7 @@ public function denormalize($data, string $type, string $format = null, array $c sprintf('Failed to denormalize attribute "%s" value for class "%s": '.$e->getMessage(), $attribute, $type), $data, ['unknown'], - $context['deserialization_path'] ?? null, + $attributeContext['deserialization_path'] ?? null, false, $e->getCode(), $e diff --git a/Tests/SerializerTest.php b/Tests/SerializerTest.php index 447e0f882..921d3fd01 100644 --- a/Tests/SerializerTest.php +++ b/Tests/SerializerTest.php @@ -1049,7 +1049,7 @@ public function testCollectDenormalizationErrors(?ClassMetadataFactory $classMet 'expectedTypes' => [ 'unknown', ], - 'path' => 'php74FullWithConstructor', + 'path' => 'php74FullWithConstructor.constructorArgument', 'useMessageForUser' => true, 'message' => 'Failed to create object because the class misses the "constructorArgument" property.', ], @@ -1186,6 +1186,75 @@ public function testCollectDenormalizationErrors2(?ClassMetadataFactory $classMe $this->assertSame($expected, $exceptionsAsArray); } + /** + * @requires PHP 7.4 + */ + public function testCollectDenormalizationErrorsWithoutTypeExtractor() + { + $json = ' + { + "string": [], + "int": [], + "float": [] + }'; + + $serializer = new Serializer([new ObjectNormalizer()], ['json' => new JsonEncoder()]); + + try { + $serializer->deserialize($json, Php74Full::class, 'json', [ + DenormalizerInterface::COLLECT_DENORMALIZATION_ERRORS => true, + ]); + + $this->fail(); + } catch (\Throwable $th) { + $this->assertInstanceOf(PartialDenormalizationException::class, $th); + } + + $this->assertInstanceOf(Php74Full::class, $th->getData()); + + $exceptionsAsArray = array_map(function (NotNormalizableValueException $e): array { + return [ + 'currentType' => $e->getCurrentType(), + 'expectedTypes' => $e->getExpectedTypes(), + 'path' => $e->getPath(), + 'useMessageForUser' => $e->canUseMessageForUser(), + 'message' => $e->getMessage(), + ]; + }, $th->getErrors()); + + $expected = [ + [ + 'currentType' => 'array', + 'expectedTypes' => [ + 'unknown', + ], + 'path' => 'string', + 'useMessageForUser' => false, + 'message' => 'Failed to denormalize attribute "string" value for class "Symfony\\Component\\Serializer\\Tests\\Fixtures\\Php74Full": Expected argument of type "string", "array" given at property path "string".', + ], + [ + 'currentType' => 'array', + 'expectedTypes' => [ + 'unknown', + ], + 'path' => 'int', + 'useMessageForUser' => false, + 'message' => 'Failed to denormalize attribute "int" value for class "Symfony\\Component\\Serializer\\Tests\\Fixtures\\Php74Full": Expected argument of type "int", "array" given at property path "int".', + ], + [ + 'currentType' => 'array', + 'expectedTypes' => [ + 'unknown', + ], + 'path' => 'float', + 'useMessageForUser' => false, + 'message' => 'Failed to denormalize attribute "float" value for class "Symfony\\Component\\Serializer\\Tests\\Fixtures\\Php74Full": Expected argument of type "float", "array" given at property path "float".', + ], + ]; + + $this->assertSame($expected, $exceptionsAsArray); + } + /** * @dataProvider provideCollectDenormalizationErrors * @@ -1241,7 +1310,7 @@ public function testCollectDenormalizationErrorsWithConstructor(?ClassMetadataFa 'expectedTypes' => [ 'unknown', ], - 'path' => null, + 'path' => 'string', 'useMessageForUser' => true, 'message' => 'Failed to create object because the class misses the "string" property.', ], @@ -1250,7 +1319,7 @@ public function testCollectDenormalizationErrorsWithConstructor(?ClassMetadataFa 'expectedTypes' => [ 'unknown', ], - 'path' => null, + 'path' => 'int', 'useMessageForUser' => true, 'message' => 'Failed to create object because the class misses the "int" property.', ], @@ -1300,7 +1369,7 @@ public function testCollectDenormalizationErrorsWithInvalidConstructorTypes() [ 'currentType' => 'string', 'expectedTypes' => [ - 0 => 'bool', + 'bool', ], 'path' => 'bool', 'useMessageForUser' => false, @@ -1309,7 +1378,7 @@ public function testCollectDenormalizationErrorsWithInvalidConstructorTypes() [ 'currentType' => 'bool', 'expectedTypes' => [ - 0 => 'int', + 'int', ], 'path' => 'int', 'useMessageForUser' => false, @@ -1481,7 +1550,7 @@ public function testPartialDenormalizationWithMissingConstructorTypes() 'expectedTypes' => [ 'unknown', ], - 'path' => null, + 'path' => 'two', 'useMessageForUser' => true, 'message' => 'Failed to create object because the class misses the "two" property.', ], diff --git a/composer.json b/composer.json index 3ec14ae0f..ec5e37a3f 100644 --- a/composer.json +++ b/composer.json @@ -33,7 +33,7 @@ "symfony/http-foundation": "^4.4|^5.0|^6.0", "symfony/http-kernel": "^4.4|^5.0|^6.0", "symfony/mime": "^4.4|^5.0|^6.0", - "symfony/property-access": "^5.4|^6.0", + "symfony/property-access": "^5.4.26|^6.3", "symfony/property-info": "^5.4.24|^6.2.11", "symfony/uid": "^5.3|^6.0", "symfony/validator": "^4.4|^5.0|^6.0", From 1ac9e8a73703534e54ac8ded5d493345b7690ab4 Mon Sep 17 00:00:00 2001 From: Thijs Reijgersberg Date: Tue, 2 Jan 2024 17:32:57 +0100 Subject: [PATCH 2/7] [Serializer] Take unnamed variadic parameters into account when denormalizing We shouldn't break when a constructor has variadic parameters without named keys in the array. --- Normalizer/AbstractNormalizer.php | 2 +- ...myWithWithVariadicParameterConstructor.php | 44 +++++++++++++++++++ Tests/Normalizer/AbstractNormalizerTest.php | 20 +++++++++ 3 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 Tests/Fixtures/DummyWithWithVariadicParameterConstructor.php diff --git a/Normalizer/AbstractNormalizer.php b/Normalizer/AbstractNormalizer.php index 1a7c314b8..27224f5b3 100644 --- a/Normalizer/AbstractNormalizer.php +++ b/Normalizer/AbstractNormalizer.php @@ -372,7 +372,7 @@ protected function instantiateObject(array &$data, string $class, array &$contex $variadicParameters[$parameterKey] = $this->denormalizeParameter($reflectionClass, $constructorParameter, $paramName, $parameterData, $context, $format); } - $params = array_merge($params, $variadicParameters); + $params = array_merge(array_values($params), $variadicParameters); $unsetKeys[] = $key; } } elseif ($allowed && !$ignored && (isset($data[$key]) || \array_key_exists($key, $data))) { diff --git a/Tests/Fixtures/DummyWithWithVariadicParameterConstructor.php b/Tests/Fixtures/DummyWithWithVariadicParameterConstructor.php new file mode 100644 index 000000000..7b3819ac9 --- /dev/null +++ b/Tests/Fixtures/DummyWithWithVariadicParameterConstructor.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Serializer\Tests\Fixtures; + +class DummyWithWithVariadicParameterConstructor +{ + private $foo; + + private $bar; + + private $baz; + + public function __construct(string $foo, int $bar = 1, Dummy ...$baz) + { + $this->foo = $foo; + $this->bar = $bar; + $this->baz = $baz; + } + + public function getFoo(): string + { + return $this->foo; + } + + public function getBar(): int + { + return $this->bar; + } + + /** @return Dummy[] */ + public function getBaz(): array + { + return $this->baz; + } +} diff --git a/Tests/Normalizer/AbstractNormalizerTest.php b/Tests/Normalizer/AbstractNormalizerTest.php index 250032781..ae627d96a 100644 --- a/Tests/Normalizer/AbstractNormalizerTest.php +++ b/Tests/Normalizer/AbstractNormalizerTest.php @@ -29,6 +29,7 @@ use Symfony\Component\Serializer\Tests\Fixtures\AbstractNormalizerDummy; use Symfony\Component\Serializer\Tests\Fixtures\Annotations\IgnoreDummy; use Symfony\Component\Serializer\Tests\Fixtures\Dummy; +use Symfony\Component\Serializer\Tests\Fixtures\DummyWithWithVariadicParameterConstructor; use Symfony\Component\Serializer\Tests\Fixtures\NullableConstructorArgumentDummy; use Symfony\Component\Serializer\Tests\Fixtures\NullableOptionalConstructorArgumentDummy; use Symfony\Component\Serializer\Tests\Fixtures\StaticConstructorDummy; @@ -247,6 +248,25 @@ public static function getNormalizer() yield [new ObjectNormalizer(null, null, null, $extractor)]; } + public function testVariadicConstructorDenormalization() + { + $data = [ + 'foo' => 'woo', + 'baz' => [ + ['foo' => null, 'bar' => null, 'baz' => null, 'qux' => null], + ['foo' => null, 'bar' => null, 'baz' => null, 'qux' => null], + ], + ]; + + $normalizer = new ObjectNormalizer(); + $normalizer->setSerializer(new Serializer([$normalizer])); + + $expected = new DummyWithWithVariadicParameterConstructor('woo', 1, new Dummy(), new Dummy()); + $actual = $normalizer->denormalize($data, DummyWithWithVariadicParameterConstructor::class); + + $this->assertEquals($expected, $actual); + } + public static function getNormalizerWithCustomNameConverter() { $extractor = new PhpDocExtractor(); From 3bda12fb521c328c57ea9043d912599ad4d24a83 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 23 Jan 2024 14:51:25 +0100 Subject: [PATCH 3/7] Apply php-cs-fixer fix --rules nullable_type_declaration_for_default_null_value --- Annotation/DiscriminatorMap.php | 2 +- Encoder/JsonEncoder.php | 2 +- Encoder/XmlEncoder.php | 4 +- Encoder/YamlEncoder.php | 2 +- Exception/ExtraAttributesException.php | 2 +- .../MissingConstructorArgumentsException.php | 2 +- Exception/NotNormalizableValueException.php | 2 +- Extractor/ObjectPropertyListExtractor.php | 2 +- Mapping/AttributeMetadata.php | 2 +- Mapping/AttributeMetadataInterface.php | 2 +- Mapping/ClassMetadata.php | 4 +- Mapping/ClassMetadataInterface.php | 2 +- Mapping/Loader/AnnotationLoader.php | 2 +- .../AdvancedNameConverterInterface.php | 4 +- .../CamelCaseToSnakeCaseNameConverter.php | 2 +- NameConverter/MetadataAwareNameConverter.php | 10 ++--- Normalizer/AbstractNormalizer.php | 10 ++--- Normalizer/AbstractObjectNormalizer.php | 20 +++++----- Normalizer/ArrayDenormalizer.php | 4 +- Normalizer/BackedEnumNormalizer.php | 8 ++-- .../ConstraintViolationListNormalizer.php | 6 +-- .../ContextAwareDenormalizerInterface.php | 2 +- .../ContextAwareNormalizerInterface.php | 2 +- Normalizer/CustomNormalizer.php | 8 ++-- Normalizer/DataUriNormalizer.php | 10 ++--- Normalizer/DateIntervalNormalizer.php | 8 ++-- Normalizer/DateTimeNormalizer.php | 8 ++-- Normalizer/DateTimeZoneNormalizer.php | 8 ++-- Normalizer/DenormalizableInterface.php | 2 +- Normalizer/DenormalizerInterface.php | 4 +- Normalizer/FormErrorNormalizer.php | 4 +- Normalizer/GetSetMethodNormalizer.php | 10 ++--- Normalizer/JsonSerializableNormalizer.php | 8 ++-- Normalizer/MimeMessageNormalizer.php | 8 ++-- Normalizer/NormalizableInterface.php | 2 +- Normalizer/NormalizerInterface.php | 4 +- Normalizer/ObjectNormalizer.php | 8 ++-- Normalizer/ObjectToPopulateTrait.php | 2 +- Normalizer/ProblemNormalizer.php | 4 +- Normalizer/PropertyNormalizer.php | 12 +++--- Normalizer/UidNormalizer.php | 8 ++-- Normalizer/UnwrappingDenormalizer.php | 6 +-- Serializer.php | 8 ++-- .../AbstractObjectNormalizerTest.php | 40 +++++++++---------- .../ConstraintViolationListNormalizerTest.php | 2 +- Tests/Normalizer/Features/CallbacksObject.php | 2 +- Tests/Normalizer/ObjectNormalizerTest.php | 10 ++--- Tests/Normalizer/TestDenormalizer.php | 4 +- Tests/Normalizer/TestNormalizer.php | 4 +- 49 files changed, 146 insertions(+), 146 deletions(-) diff --git a/Annotation/DiscriminatorMap.php b/Annotation/DiscriminatorMap.php index d01287bfd..6bf061833 100644 --- a/Annotation/DiscriminatorMap.php +++ b/Annotation/DiscriminatorMap.php @@ -40,7 +40,7 @@ class DiscriminatorMap * * @throws InvalidArgumentException */ - public function __construct($typeProperty, array $mapping = null) + public function __construct($typeProperty, ?array $mapping = null) { if (\is_array($typeProperty)) { trigger_deprecation('symfony/serializer', '5.3', 'Passing an array as first argument to "%s" is deprecated. Use named arguments instead.', __METHOD__); diff --git a/Encoder/JsonEncoder.php b/Encoder/JsonEncoder.php index d460331a3..288c44912 100644 --- a/Encoder/JsonEncoder.php +++ b/Encoder/JsonEncoder.php @@ -27,7 +27,7 @@ class JsonEncoder implements EncoderInterface, DecoderInterface JsonDecode::ASSOCIATIVE => true, ]; - public function __construct(JsonEncode $encodingImpl = null, JsonDecode $decodingImpl = null, array $defaultContext = []) + public function __construct(?JsonEncode $encodingImpl = null, ?JsonDecode $decodingImpl = null, array $defaultContext = []) { $this->defaultContext = array_merge($this->defaultContext, $defaultContext); $this->encodingImpl = $encodingImpl ?? new JsonEncode($this->defaultContext); diff --git a/Encoder/XmlEncoder.php b/Encoder/XmlEncoder.php index ef3f30ba0..86ab8a70b 100644 --- a/Encoder/XmlEncoder.php +++ b/Encoder/XmlEncoder.php @@ -360,7 +360,7 @@ private function addXmlNamespaces(array $data, \DOMNode $node, \DOMDocument $doc * * @throws NotEncodableValueException */ - private function buildXml(\DOMNode $parentNode, $data, string $format, array $context, string $xmlRootNodeName = null): bool + private function buildXml(\DOMNode $parentNode, $data, string $format, array $context, ?string $xmlRootNodeName = null): bool { $append = true; $removeEmptyTags = $context[self::REMOVE_EMPTY_TAGS] ?? $this->defaultContext[self::REMOVE_EMPTY_TAGS] ?? false; @@ -436,7 +436,7 @@ private function buildXml(\DOMNode $parentNode, $data, string $format, array $co * * @param array|object $data */ - private function appendNode(\DOMNode $parentNode, $data, string $format, array $context, string $nodeName, string $key = null): bool + private function appendNode(\DOMNode $parentNode, $data, string $format, array $context, string $nodeName, ?string $key = null): bool { $dom = $parentNode instanceof \DOMDocument ? $parentNode : $parentNode->ownerDocument; $node = $dom->createElement($nodeName); diff --git a/Encoder/YamlEncoder.php b/Encoder/YamlEncoder.php index c688c2283..7291c6278 100644 --- a/Encoder/YamlEncoder.php +++ b/Encoder/YamlEncoder.php @@ -40,7 +40,7 @@ class YamlEncoder implements EncoderInterface, DecoderInterface self::YAML_FLAGS => 0, ]; - public function __construct(Dumper $dumper = null, Parser $parser = null, array $defaultContext = []) + public function __construct(?Dumper $dumper = null, ?Parser $parser = null, array $defaultContext = []) { if (!class_exists(Dumper::class)) { throw new RuntimeException('The YamlEncoder class requires the "Yaml" component. Install "symfony/yaml" to use it.'); diff --git a/Exception/ExtraAttributesException.php b/Exception/ExtraAttributesException.php index 37cfb556f..cee352d49 100644 --- a/Exception/ExtraAttributesException.php +++ b/Exception/ExtraAttributesException.php @@ -20,7 +20,7 @@ class ExtraAttributesException extends RuntimeException { private $extraAttributes; - public function __construct(array $extraAttributes, \Throwable $previous = null) + public function __construct(array $extraAttributes, ?\Throwable $previous = null) { $msg = sprintf('Extra attributes are not allowed ("%s" %s unknown).', implode('", "', $extraAttributes), \count($extraAttributes) > 1 ? 'are' : 'is'); diff --git a/Exception/MissingConstructorArgumentsException.php b/Exception/MissingConstructorArgumentsException.php index fe984a291..2f6ca569c 100644 --- a/Exception/MissingConstructorArgumentsException.php +++ b/Exception/MissingConstructorArgumentsException.php @@ -21,7 +21,7 @@ class MissingConstructorArgumentsException extends RuntimeException */ private $missingArguments; - public function __construct(string $message, int $code = 0, \Throwable $previous = null, array $missingArguments = []) + public function __construct(string $message, int $code = 0, ?\Throwable $previous = null, array $missingArguments = []) { $this->missingArguments = $missingArguments; diff --git a/Exception/NotNormalizableValueException.php b/Exception/NotNormalizableValueException.php index e601e5043..7b2a1c7bc 100644 --- a/Exception/NotNormalizableValueException.php +++ b/Exception/NotNormalizableValueException.php @@ -26,7 +26,7 @@ class NotNormalizableValueException extends UnexpectedValueException * safely to your user. In other words, avoid catching other exceptions and * passing their message directly to this class. */ - public static function createForUnexpectedDataType(string $message, $data, array $expectedTypes, string $path = null, bool $useMessageForUser = false, int $code = 0, \Throwable $previous = null): self + public static function createForUnexpectedDataType(string $message, $data, array $expectedTypes, ?string $path = null, bool $useMessageForUser = false, int $code = 0, ?\Throwable $previous = null): self { $self = new self($message, $code, $previous); diff --git a/Extractor/ObjectPropertyListExtractor.php b/Extractor/ObjectPropertyListExtractor.php index 1f9fc6f7c..2e7bf4c05 100644 --- a/Extractor/ObjectPropertyListExtractor.php +++ b/Extractor/ObjectPropertyListExtractor.php @@ -21,7 +21,7 @@ final class ObjectPropertyListExtractor implements ObjectPropertyListExtractorIn private $propertyListExtractor; private $objectClassResolver; - public function __construct(PropertyListExtractorInterface $propertyListExtractor, callable $objectClassResolver = null) + public function __construct(PropertyListExtractorInterface $propertyListExtractor, ?callable $objectClassResolver = null) { $this->propertyListExtractor = $propertyListExtractor; $this->objectClassResolver = $objectClassResolver; diff --git a/Mapping/AttributeMetadata.php b/Mapping/AttributeMetadata.php index 36d1e92b6..0823a11b0 100644 --- a/Mapping/AttributeMetadata.php +++ b/Mapping/AttributeMetadata.php @@ -127,7 +127,7 @@ public function getMaxDepth() /** * {@inheritdoc} */ - public function setSerializedName(string $serializedName = null) + public function setSerializedName(?string $serializedName = null) { $this->serializedName = $serializedName; } diff --git a/Mapping/AttributeMetadataInterface.php b/Mapping/AttributeMetadataInterface.php index 9e5a1ae2d..57ce746db 100644 --- a/Mapping/AttributeMetadataInterface.php +++ b/Mapping/AttributeMetadataInterface.php @@ -54,7 +54,7 @@ public function getMaxDepth(); /** * Sets the serialization name for this attribute. */ - public function setSerializedName(string $serializedName = null); + public function setSerializedName(?string $serializedName = null); /** * Gets the serialization name for this attribute. diff --git a/Mapping/ClassMetadata.php b/Mapping/ClassMetadata.php index 65b42ceba..51c934742 100644 --- a/Mapping/ClassMetadata.php +++ b/Mapping/ClassMetadata.php @@ -51,7 +51,7 @@ class ClassMetadata implements ClassMetadataInterface /** * Constructs a metadata for the given class. */ - public function __construct(string $class, ClassDiscriminatorMapping $classDiscriminatorMapping = null) + public function __construct(string $class, ?ClassDiscriminatorMapping $classDiscriminatorMapping = null) { $this->name = $class; $this->classDiscriminatorMapping = $classDiscriminatorMapping; @@ -118,7 +118,7 @@ public function getClassDiscriminatorMapping(): ?ClassDiscriminatorMapping /** * {@inheritdoc} */ - public function setClassDiscriminatorMapping(ClassDiscriminatorMapping $mapping = null) + public function setClassDiscriminatorMapping(?ClassDiscriminatorMapping $mapping = null) { $this->classDiscriminatorMapping = $mapping; } diff --git a/Mapping/ClassMetadataInterface.php b/Mapping/ClassMetadataInterface.php index e0a445d6a..0c6b86900 100644 --- a/Mapping/ClassMetadataInterface.php +++ b/Mapping/ClassMetadataInterface.php @@ -53,5 +53,5 @@ public function getReflectionClass(): \ReflectionClass; public function getClassDiscriminatorMapping(): ?ClassDiscriminatorMapping; - public function setClassDiscriminatorMapping(ClassDiscriminatorMapping $mapping = null); + public function setClassDiscriminatorMapping(?ClassDiscriminatorMapping $mapping = null); } diff --git a/Mapping/Loader/AnnotationLoader.php b/Mapping/Loader/AnnotationLoader.php index d6bef3c42..4d0e1768d 100644 --- a/Mapping/Loader/AnnotationLoader.php +++ b/Mapping/Loader/AnnotationLoader.php @@ -43,7 +43,7 @@ class AnnotationLoader implements LoaderInterface private $reader; - public function __construct(Reader $reader = null) + public function __construct(?Reader $reader = null) { $this->reader = $reader; } diff --git a/NameConverter/AdvancedNameConverterInterface.php b/NameConverter/AdvancedNameConverterInterface.php index 0b277d40e..9e9ee2a37 100644 --- a/NameConverter/AdvancedNameConverterInterface.php +++ b/NameConverter/AdvancedNameConverterInterface.php @@ -21,10 +21,10 @@ interface AdvancedNameConverterInterface extends NameConverterInterface /** * {@inheritdoc} */ - public function normalize(string $propertyName, string $class = null, string $format = null, array $context = []); + public function normalize(string $propertyName, ?string $class = null, ?string $format = null, array $context = []); /** * {@inheritdoc} */ - public function denormalize(string $propertyName, string $class = null, string $format = null, array $context = []); + public function denormalize(string $propertyName, ?string $class = null, ?string $format = null, array $context = []); } diff --git a/NameConverter/CamelCaseToSnakeCaseNameConverter.php b/NameConverter/CamelCaseToSnakeCaseNameConverter.php index 4060e5ac3..8c9953c96 100644 --- a/NameConverter/CamelCaseToSnakeCaseNameConverter.php +++ b/NameConverter/CamelCaseToSnakeCaseNameConverter.php @@ -25,7 +25,7 @@ class CamelCaseToSnakeCaseNameConverter implements NameConverterInterface * @param array|null $attributes The list of attributes to rename or null for all attributes * @param bool $lowerCamelCase Use lowerCamelCase style */ - public function __construct(array $attributes = null, bool $lowerCamelCase = true) + public function __construct(?array $attributes = null, bool $lowerCamelCase = true) { $this->attributes = $attributes; $this->lowerCamelCase = $lowerCamelCase; diff --git a/NameConverter/MetadataAwareNameConverter.php b/NameConverter/MetadataAwareNameConverter.php index 7ce17cc39..a27c82756 100644 --- a/NameConverter/MetadataAwareNameConverter.php +++ b/NameConverter/MetadataAwareNameConverter.php @@ -32,7 +32,7 @@ final class MetadataAwareNameConverter implements AdvancedNameConverterInterface private static $attributesMetadataCache = []; - public function __construct(ClassMetadataFactoryInterface $metadataFactory, NameConverterInterface $fallbackNameConverter = null) + public function __construct(ClassMetadataFactoryInterface $metadataFactory, ?NameConverterInterface $fallbackNameConverter = null) { $this->metadataFactory = $metadataFactory; $this->fallbackNameConverter = $fallbackNameConverter; @@ -41,7 +41,7 @@ public function __construct(ClassMetadataFactoryInterface $metadataFactory, Name /** * {@inheritdoc} */ - public function normalize(string $propertyName, string $class = null, string $format = null, array $context = []): string + public function normalize(string $propertyName, ?string $class = null, ?string $format = null, array $context = []): string { if (null === $class) { return $this->normalizeFallback($propertyName, $class, $format, $context); @@ -57,7 +57,7 @@ public function normalize(string $propertyName, string $class = null, string $fo /** * {@inheritdoc} */ - public function denormalize(string $propertyName, string $class = null, string $format = null, array $context = []): string + public function denormalize(string $propertyName, ?string $class = null, ?string $format = null, array $context = []): string { if (null === $class) { return $this->denormalizeFallback($propertyName, $class, $format, $context); @@ -85,7 +85,7 @@ private function getCacheValueForNormalization(string $propertyName, string $cla return $attributesMetadata[$propertyName]->getSerializedName() ?? null; } - private function normalizeFallback(string $propertyName, string $class = null, string $format = null, array $context = []): string + private function normalizeFallback(string $propertyName, ?string $class = null, ?string $format = null, array $context = []): string { return $this->fallbackNameConverter ? $this->fallbackNameConverter->normalize($propertyName, $class, $format, $context) : $propertyName; } @@ -100,7 +100,7 @@ private function getCacheValueForDenormalization(string $propertyName, string $c return self::$attributesMetadataCache[$cacheKey][$propertyName] ?? null; } - private function denormalizeFallback(string $propertyName, string $class = null, string $format = null, array $context = []): string + private function denormalizeFallback(string $propertyName, ?string $class = null, ?string $format = null, array $context = []): string { return $this->fallbackNameConverter ? $this->fallbackNameConverter->denormalize($propertyName, $class, $format, $context) : $propertyName; } diff --git a/Normalizer/AbstractNormalizer.php b/Normalizer/AbstractNormalizer.php index 1a7c314b8..e75d40fe3 100644 --- a/Normalizer/AbstractNormalizer.php +++ b/Normalizer/AbstractNormalizer.php @@ -137,7 +137,7 @@ abstract class AbstractNormalizer implements NormalizerInterface, DenormalizerIn /** * Sets the {@link ClassMetadataFactoryInterface} to use. */ - public function __construct(ClassMetadataFactoryInterface $classMetadataFactory = null, NameConverterInterface $nameConverter = null, array $defaultContext = []) + public function __construct(?ClassMetadataFactoryInterface $classMetadataFactory = null, ?NameConverterInterface $nameConverter = null, array $defaultContext = []) { $this->classMetadataFactory = $classMetadataFactory; $this->nameConverter = $nameConverter; @@ -197,7 +197,7 @@ protected function isCircularReference(object $object, array &$context) * * @throws CircularReferenceException */ - protected function handleCircularReference(object $object, string $format = null, array $context = []) + protected function handleCircularReference(object $object, ?string $format = null, array $context = []) { $circularReferenceHandler = $context[self::CIRCULAR_REFERENCE_HANDLER] ?? $this->defaultContext[self::CIRCULAR_REFERENCE_HANDLER]; if ($circularReferenceHandler) { @@ -269,7 +269,7 @@ protected function getGroups(array $context): array * * @return bool */ - protected function isAllowedAttribute($classOrObject, string $attribute, string $format = null, array $context = []) + protected function isAllowedAttribute($classOrObject, string $attribute, ?string $format = null, array $context = []) { $ignoredAttributes = $context[self::IGNORED_ATTRIBUTES] ?? $this->defaultContext[self::IGNORED_ATTRIBUTES]; if (\in_array($attribute, $ignoredAttributes)) { @@ -330,7 +330,7 @@ protected function getConstructor(array &$data, string $class, array &$context, * @throws RuntimeException * @throws MissingConstructorArgumentsException */ - protected function instantiateObject(array &$data, string $class, array &$context, \ReflectionClass $reflectionClass, $allowedAttributes, string $format = null) + protected function instantiateObject(array &$data, string $class, array &$context, \ReflectionClass $reflectionClass, $allowedAttributes, ?string $format = null) { if (null !== $object = $this->extractObjectToPopulate($class, $context, self::OBJECT_TO_POPULATE)) { unset($context[self::OBJECT_TO_POPULATE]); @@ -473,7 +473,7 @@ protected function instantiateObject(array &$data, string $class, array &$contex /** * @internal */ - protected function denormalizeParameter(\ReflectionClass $class, \ReflectionParameter $parameter, string $parameterName, $parameterData, array $context, string $format = null) + protected function denormalizeParameter(\ReflectionClass $class, \ReflectionParameter $parameter, string $parameterName, $parameterData, array $context, ?string $format = null) { try { if (($parameterType = $parameter->getType()) instanceof \ReflectionNamedType && !$parameterType->isBuiltin()) { diff --git a/Normalizer/AbstractObjectNormalizer.php b/Normalizer/AbstractObjectNormalizer.php index a51b69503..89914f391 100644 --- a/Normalizer/AbstractObjectNormalizer.php +++ b/Normalizer/AbstractObjectNormalizer.php @@ -115,7 +115,7 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer */ protected $classDiscriminatorResolver; - public function __construct(ClassMetadataFactoryInterface $classMetadataFactory = null, NameConverterInterface $nameConverter = null, PropertyTypeExtractorInterface $propertyTypeExtractor = null, ClassDiscriminatorResolverInterface $classDiscriminatorResolver = null, callable $objectClassResolver = null, array $defaultContext = []) + public function __construct(?ClassMetadataFactoryInterface $classMetadataFactory = null, ?NameConverterInterface $nameConverter = null, ?PropertyTypeExtractorInterface $propertyTypeExtractor = null, ?ClassDiscriminatorResolverInterface $classDiscriminatorResolver = null, ?callable $objectClassResolver = null, array $defaultContext = []) { parent::__construct($classMetadataFactory, $nameConverter, $defaultContext); @@ -137,7 +137,7 @@ public function __construct(ClassMetadataFactoryInterface $classMetadataFactory /** * {@inheritdoc} */ - public function supportsNormalization($data, string $format = null) + public function supportsNormalization($data, ?string $format = null) { return \is_object($data) && !$data instanceof \Traversable; } @@ -145,7 +145,7 @@ public function supportsNormalization($data, string $format = null) /** * {@inheritdoc} */ - public function normalize($object, string $format = null, array $context = []) + public function normalize($object, ?string $format = null, array $context = []) { if (!isset($context['cache_key'])) { $context['cache_key'] = $this->getCacheKey($format, $context); @@ -269,7 +269,7 @@ private function getAttributeMetadata($objectOrClass, string $attribute): ?Attri /** * {@inheritdoc} */ - protected function instantiateObject(array &$data, string $class, array &$context, \ReflectionClass $reflectionClass, $allowedAttributes, string $format = null) + protected function instantiateObject(array &$data, string $class, array &$context, \ReflectionClass $reflectionClass, $allowedAttributes, ?string $format = null) { if (null !== $object = $this->extractObjectToPopulate($class, $context, self::OBJECT_TO_POPULATE)) { unset($context[self::OBJECT_TO_POPULATE]); @@ -337,19 +337,19 @@ protected function getAttributes(object $object, ?string $format, array $context * * @return string[] */ - abstract protected function extractAttributes(object $object, string $format = null, array $context = []); + abstract protected function extractAttributes(object $object, ?string $format = null, array $context = []); /** * Gets the attribute value. * * @return mixed */ - abstract protected function getAttributeValue(object $object, string $attribute, string $format = null, array $context = []); + abstract protected function getAttributeValue(object $object, string $attribute, ?string $format = null, array $context = []); /** * {@inheritdoc} */ - public function supportsDenormalization($data, string $type, string $format = null) + public function supportsDenormalization($data, string $type, ?string $format = null) { return class_exists($type) || (interface_exists($type, false) && $this->classDiscriminatorResolver && null !== $this->classDiscriminatorResolver->getMappingForClass($type)); } @@ -357,7 +357,7 @@ public function supportsDenormalization($data, string $type, string $format = nu /** * {@inheritdoc} */ - public function denormalize($data, string $type, string $format = null, array $context = []) + public function denormalize($data, string $type, ?string $format = null, array $context = []) { if (!isset($context['cache_key'])) { $context['cache_key'] = $this->getCacheKey($format, $context); @@ -460,7 +460,7 @@ public function denormalize($data, string $type, string $format = null, array $c /** * Sets attribute value. */ - abstract protected function setAttributeValue(object $object, string $attribute, $value, string $format = null, array $context = []); + abstract protected function setAttributeValue(object $object, string $attribute, $value, ?string $format = null, array $context = []); /** * Validates the submitted data and denormalizes it. @@ -669,7 +669,7 @@ private function validateAndDenormalize(array $types, string $currentClass, stri /** * @internal */ - protected function denormalizeParameter(\ReflectionClass $class, \ReflectionParameter $parameter, string $parameterName, $parameterData, array $context, string $format = null) + protected function denormalizeParameter(\ReflectionClass $class, \ReflectionParameter $parameter, string $parameterName, $parameterData, array $context, ?string $format = null) { if ($parameter->isVariadic() || null === $this->propertyTypeExtractor || null === $types = $this->getTypes($class->getName(), $parameterName)) { return parent::denormalizeParameter($class, $parameter, $parameterName, $parameterData, $context, $format); diff --git a/Normalizer/ArrayDenormalizer.php b/Normalizer/ArrayDenormalizer.php index 1420523c0..248a8bb66 100644 --- a/Normalizer/ArrayDenormalizer.php +++ b/Normalizer/ArrayDenormalizer.php @@ -35,7 +35,7 @@ class ArrayDenormalizer implements ContextAwareDenormalizerInterface, Denormaliz * * @throws NotNormalizableValueException */ - public function denormalize($data, string $type, string $format = null, array $context = []): array + public function denormalize($data, string $type, ?string $format = null, array $context = []): array { if (null === $this->denormalizer) { throw new BadMethodCallException('Please set a denormalizer before calling denormalize()!'); @@ -68,7 +68,7 @@ public function denormalize($data, string $type, string $format = null, array $c /** * {@inheritdoc} */ - public function supportsDenormalization($data, string $type, string $format = null, array $context = []): bool + public function supportsDenormalization($data, string $type, ?string $format = null, array $context = []): bool { if (null === $this->denormalizer) { throw new BadMethodCallException(sprintf('The nested denormalizer needs to be set to allow "%s()" to be used.', __METHOD__)); diff --git a/Normalizer/BackedEnumNormalizer.php b/Normalizer/BackedEnumNormalizer.php index 995033516..8f3e55a1f 100644 --- a/Normalizer/BackedEnumNormalizer.php +++ b/Normalizer/BackedEnumNormalizer.php @@ -29,7 +29,7 @@ final class BackedEnumNormalizer implements NormalizerInterface, DenormalizerInt * * @throws InvalidArgumentException */ - public function normalize($object, string $format = null, array $context = []) + public function normalize($object, ?string $format = null, array $context = []) { if (!$object instanceof \BackedEnum) { throw new InvalidArgumentException('The data must belong to a backed enumeration.'); @@ -41,7 +41,7 @@ public function normalize($object, string $format = null, array $context = []) /** * {@inheritdoc} */ - public function supportsNormalization($data, string $format = null): bool + public function supportsNormalization($data, ?string $format = null): bool { return $data instanceof \BackedEnum; } @@ -51,7 +51,7 @@ public function supportsNormalization($data, string $format = null): bool * * @throws NotNormalizableValueException */ - public function denormalize($data, string $type, string $format = null, array $context = []) + public function denormalize($data, string $type, ?string $format = null, array $context = []) { if (!is_subclass_of($type, \BackedEnum::class)) { throw new InvalidArgumentException('The data must belong to a backed enumeration.'); @@ -75,7 +75,7 @@ public function denormalize($data, string $type, string $format = null, array $c /** * {@inheritdoc} */ - public function supportsDenormalization($data, string $type, string $format = null): bool + public function supportsDenormalization($data, string $type, ?string $format = null): bool { return is_subclass_of($type, \BackedEnum::class); } diff --git a/Normalizer/ConstraintViolationListNormalizer.php b/Normalizer/ConstraintViolationListNormalizer.php index 923612690..dd9f859c2 100644 --- a/Normalizer/ConstraintViolationListNormalizer.php +++ b/Normalizer/ConstraintViolationListNormalizer.php @@ -33,7 +33,7 @@ class ConstraintViolationListNormalizer implements NormalizerInterface, Cacheabl private $defaultContext; private $nameConverter; - public function __construct(array $defaultContext = [], NameConverterInterface $nameConverter = null) + public function __construct(array $defaultContext = [], ?NameConverterInterface $nameConverter = null) { $this->defaultContext = $defaultContext; $this->nameConverter = $nameConverter; @@ -44,7 +44,7 @@ public function __construct(array $defaultContext = [], NameConverterInterface $ * * @return array */ - public function normalize($object, string $format = null, array $context = []) + public function normalize($object, ?string $format = null, array $context = []) { if (\array_key_exists(self::PAYLOAD_FIELDS, $context)) { $payloadFieldsToSerialize = $context[self::PAYLOAD_FIELDS]; @@ -109,7 +109,7 @@ public function normalize($object, string $format = null, array $context = []) /** * {@inheritdoc} */ - public function supportsNormalization($data, string $format = null) + public function supportsNormalization($data, ?string $format = null) { return $data instanceof ConstraintViolationListInterface; } diff --git a/Normalizer/ContextAwareDenormalizerInterface.php b/Normalizer/ContextAwareDenormalizerInterface.php index c875de1b5..9682cf5a4 100644 --- a/Normalizer/ContextAwareDenormalizerInterface.php +++ b/Normalizer/ContextAwareDenormalizerInterface.php @@ -23,5 +23,5 @@ interface ContextAwareDenormalizerInterface extends DenormalizerInterface * * @param array $context options that denormalizers have access to */ - public function supportsDenormalization($data, string $type, string $format = null, array $context = []); + public function supportsDenormalization($data, string $type, ?string $format = null, array $context = []); } diff --git a/Normalizer/ContextAwareNormalizerInterface.php b/Normalizer/ContextAwareNormalizerInterface.php index ff0bb3a21..f20d5c991 100644 --- a/Normalizer/ContextAwareNormalizerInterface.php +++ b/Normalizer/ContextAwareNormalizerInterface.php @@ -23,5 +23,5 @@ interface ContextAwareNormalizerInterface extends NormalizerInterface * * @param array $context options that normalizers have access to */ - public function supportsNormalization($data, string $format = null, array $context = []); + public function supportsNormalization($data, ?string $format = null, array $context = []); } diff --git a/Normalizer/CustomNormalizer.php b/Normalizer/CustomNormalizer.php index ebe2f0f69..ae37783c9 100644 --- a/Normalizer/CustomNormalizer.php +++ b/Normalizer/CustomNormalizer.php @@ -25,7 +25,7 @@ class CustomNormalizer implements NormalizerInterface, DenormalizerInterface, Se /** * {@inheritdoc} */ - public function normalize($object, string $format = null, array $context = []) + public function normalize($object, ?string $format = null, array $context = []) { return $object->normalize($this->serializer, $format, $context); } @@ -33,7 +33,7 @@ public function normalize($object, string $format = null, array $context = []) /** * {@inheritdoc} */ - public function denormalize($data, string $type, string $format = null, array $context = []) + public function denormalize($data, string $type, ?string $format = null, array $context = []) { $object = $this->extractObjectToPopulate($type, $context) ?? new $type(); $object->denormalize($this->serializer, $data, $format, $context); @@ -49,7 +49,7 @@ public function denormalize($data, string $type, string $format = null, array $c * * @return bool */ - public function supportsNormalization($data, string $format = null) + public function supportsNormalization($data, ?string $format = null) { return $data instanceof NormalizableInterface; } @@ -63,7 +63,7 @@ public function supportsNormalization($data, string $format = null) * * @return bool */ - public function supportsDenormalization($data, string $type, string $format = null) + public function supportsDenormalization($data, string $type, ?string $format = null) { return is_subclass_of($type, DenormalizableInterface::class); } diff --git a/Normalizer/DataUriNormalizer.php b/Normalizer/DataUriNormalizer.php index f338c49f8..79042c292 100644 --- a/Normalizer/DataUriNormalizer.php +++ b/Normalizer/DataUriNormalizer.php @@ -36,7 +36,7 @@ class DataUriNormalizer implements NormalizerInterface, DenormalizerInterface, C */ private $mimeTypeGuesser; - public function __construct(MimeTypeGuesserInterface $mimeTypeGuesser = null) + public function __construct(?MimeTypeGuesserInterface $mimeTypeGuesser = null) { if (!$mimeTypeGuesser && class_exists(MimeTypes::class)) { $mimeTypeGuesser = MimeTypes::getDefault(); @@ -50,7 +50,7 @@ public function __construct(MimeTypeGuesserInterface $mimeTypeGuesser = null) * * @return string */ - public function normalize($object, string $format = null, array $context = []) + public function normalize($object, ?string $format = null, array $context = []) { if (!$object instanceof \SplFileInfo) { throw new InvalidArgumentException('The object must be an instance of "\SplFileInfo".'); @@ -76,7 +76,7 @@ public function normalize($object, string $format = null, array $context = []) /** * {@inheritdoc} */ - public function supportsNormalization($data, string $format = null) + public function supportsNormalization($data, ?string $format = null) { return $data instanceof \SplFileInfo; } @@ -93,7 +93,7 @@ public function supportsNormalization($data, string $format = null) * @throws InvalidArgumentException * @throws NotNormalizableValueException */ - public function denormalize($data, string $type, string $format = null, array $context = []) + public function denormalize($data, string $type, ?string $format = null, array $context = []) { if (null === $data || !preg_match('/^data:([a-z0-9][a-z0-9\!\#\$\&\-\^\_\+\.]{0,126}\/[a-z0-9][a-z0-9\!\#\$\&\-\^\_\+\.]{0,126}(;[a-z0-9\-]+\=[a-z0-9\-]+)?)?(;base64)?,[a-z0-9\!\$\&\\\'\,\(\)\*\+\,\;\=\-\.\_\~\:\@\/\?\%\s]*\s*$/i', $data)) { throw NotNormalizableValueException::createForUnexpectedDataType('The provided "data:" URI is not valid.', $data, ['string'], $context['deserialization_path'] ?? null, true); @@ -122,7 +122,7 @@ public function denormalize($data, string $type, string $format = null, array $c /** * {@inheritdoc} */ - public function supportsDenormalization($data, string $type, string $format = null) + public function supportsDenormalization($data, string $type, ?string $format = null) { return isset(self::SUPPORTED_TYPES[$type]); } diff --git a/Normalizer/DateIntervalNormalizer.php b/Normalizer/DateIntervalNormalizer.php index 93128d35b..4a09f2e8b 100644 --- a/Normalizer/DateIntervalNormalizer.php +++ b/Normalizer/DateIntervalNormalizer.php @@ -40,7 +40,7 @@ public function __construct(array $defaultContext = []) * * @throws InvalidArgumentException */ - public function normalize($object, string $format = null, array $context = []) + public function normalize($object, ?string $format = null, array $context = []) { if (!$object instanceof \DateInterval) { throw new InvalidArgumentException('The object must be an instance of "\DateInterval".'); @@ -52,7 +52,7 @@ public function normalize($object, string $format = null, array $context = []) /** * {@inheritdoc} */ - public function supportsNormalization($data, string $format = null) + public function supportsNormalization($data, ?string $format = null) { return $data instanceof \DateInterval; } @@ -72,7 +72,7 @@ public function hasCacheableSupportsMethod(): bool * * @throws NotNormalizableValueException */ - public function denormalize($data, string $type, string $format = null, array $context = []) + public function denormalize($data, string $type, ?string $format = null, array $context = []) { if (!\is_string($data)) { throw NotNormalizableValueException::createForUnexpectedDataType('Data expected to be a string.', $data, ['string'], $context['deserialization_path'] ?? null, true); @@ -121,7 +121,7 @@ public function denormalize($data, string $type, string $format = null, array $c /** * {@inheritdoc} */ - public function supportsDenormalization($data, string $type, string $format = null) + public function supportsDenormalization($data, string $type, ?string $format = null) { return \DateInterval::class === $type; } diff --git a/Normalizer/DateTimeNormalizer.php b/Normalizer/DateTimeNormalizer.php index 3b8b7fe1f..b4357b566 100644 --- a/Normalizer/DateTimeNormalizer.php +++ b/Normalizer/DateTimeNormalizer.php @@ -54,7 +54,7 @@ public function setDefaultContext(array $defaultContext): void * * @throws InvalidArgumentException */ - public function normalize($object, string $format = null, array $context = []) + public function normalize($object, ?string $format = null, array $context = []) { if (!$object instanceof \DateTimeInterface) { throw new InvalidArgumentException('The object must implement the "\DateTimeInterface".'); @@ -74,7 +74,7 @@ public function normalize($object, string $format = null, array $context = []) /** * {@inheritdoc} */ - public function supportsNormalization($data, string $format = null) + public function supportsNormalization($data, ?string $format = null) { return $data instanceof \DateTimeInterface; } @@ -86,7 +86,7 @@ public function supportsNormalization($data, string $format = null) * * @throws NotNormalizableValueException */ - public function denormalize($data, string $type, string $format = null, array $context = []) + public function denormalize($data, string $type, ?string $format = null, array $context = []) { if (\is_int($data) || \is_float($data)) { switch ($context[self::FORMAT_KEY] ?? $this->defaultContext[self::FORMAT_KEY] ?? null) { @@ -136,7 +136,7 @@ public function denormalize($data, string $type, string $format = null, array $c /** * {@inheritdoc} */ - public function supportsDenormalization($data, string $type, string $format = null) + public function supportsDenormalization($data, string $type, ?string $format = null) { return isset(self::SUPPORTED_TYPES[$type]); } diff --git a/Normalizer/DateTimeZoneNormalizer.php b/Normalizer/DateTimeZoneNormalizer.php index 7d63b7609..497460369 100644 --- a/Normalizer/DateTimeZoneNormalizer.php +++ b/Normalizer/DateTimeZoneNormalizer.php @@ -29,7 +29,7 @@ class DateTimeZoneNormalizer implements NormalizerInterface, DenormalizerInterfa * * @throws InvalidArgumentException */ - public function normalize($object, string $format = null, array $context = []) + public function normalize($object, ?string $format = null, array $context = []) { if (!$object instanceof \DateTimeZone) { throw new InvalidArgumentException('The object must be an instance of "\DateTimeZone".'); @@ -41,7 +41,7 @@ public function normalize($object, string $format = null, array $context = []) /** * {@inheritdoc} */ - public function supportsNormalization($data, string $format = null) + public function supportsNormalization($data, ?string $format = null) { return $data instanceof \DateTimeZone; } @@ -53,7 +53,7 @@ public function supportsNormalization($data, string $format = null) * * @throws NotNormalizableValueException */ - public function denormalize($data, string $type, string $format = null, array $context = []) + public function denormalize($data, string $type, ?string $format = null, array $context = []) { if ('' === $data || null === $data) { throw NotNormalizableValueException::createForUnexpectedDataType('The data is either an empty string or null, you should pass a string that can be parsed as a DateTimeZone.', $data, [Type::BUILTIN_TYPE_STRING], $context['deserialization_path'] ?? null, true); @@ -69,7 +69,7 @@ public function denormalize($data, string $type, string $format = null, array $c /** * {@inheritdoc} */ - public function supportsDenormalization($data, string $type, string $format = null) + public function supportsDenormalization($data, string $type, ?string $format = null) { return \DateTimeZone::class === $type; } diff --git a/Normalizer/DenormalizableInterface.php b/Normalizer/DenormalizableInterface.php index 05c08112e..3cf07de92 100644 --- a/Normalizer/DenormalizableInterface.php +++ b/Normalizer/DenormalizableInterface.php @@ -34,5 +34,5 @@ interface DenormalizableInterface * differently based on different input formats * @param array $context Options for denormalizing */ - public function denormalize(DenormalizerInterface $denormalizer, $data, string $format = null, array $context = []); + public function denormalize(DenormalizerInterface $denormalizer, $data, ?string $format = null, array $context = []); } diff --git a/Normalizer/DenormalizerInterface.php b/Normalizer/DenormalizerInterface.php index e3f7113b1..4f8f49f7c 100644 --- a/Normalizer/DenormalizerInterface.php +++ b/Normalizer/DenormalizerInterface.php @@ -44,7 +44,7 @@ interface DenormalizerInterface * @throws RuntimeException Occurs if the class cannot be instantiated * @throws ExceptionInterface Occurs for all the other cases of errors */ - public function denormalize($data, string $type, string $format = null, array $context = []); + public function denormalize($data, string $type, ?string $format = null, array $context = []); /** * Checks whether the given class is supported for denormalization by this normalizer. @@ -55,5 +55,5 @@ public function denormalize($data, string $type, string $format = null, array $c * * @return bool */ - public function supportsDenormalization($data, string $type, string $format = null); + public function supportsDenormalization($data, string $type, ?string $format = null); } diff --git a/Normalizer/FormErrorNormalizer.php b/Normalizer/FormErrorNormalizer.php index c23507207..81ce6de3a 100644 --- a/Normalizer/FormErrorNormalizer.php +++ b/Normalizer/FormErrorNormalizer.php @@ -25,7 +25,7 @@ final class FormErrorNormalizer implements NormalizerInterface, CacheableSupport /** * {@inheritdoc} */ - public function normalize($object, string $format = null, array $context = []): array + public function normalize($object, ?string $format = null, array $context = []): array { $data = [ 'title' => $context[self::TITLE] ?? 'Validation Failed', @@ -44,7 +44,7 @@ public function normalize($object, string $format = null, array $context = []): /** * {@inheritdoc} */ - public function supportsNormalization($data, string $format = null): bool + public function supportsNormalization($data, ?string $format = null): bool { return $data instanceof FormInterface && $data->isSubmitted() && !$data->isValid(); } diff --git a/Normalizer/GetSetMethodNormalizer.php b/Normalizer/GetSetMethodNormalizer.php index 484a8fd4b..8d749b4e1 100644 --- a/Normalizer/GetSetMethodNormalizer.php +++ b/Normalizer/GetSetMethodNormalizer.php @@ -41,7 +41,7 @@ class GetSetMethodNormalizer extends AbstractObjectNormalizer /** * {@inheritdoc} */ - public function supportsNormalization($data, string $format = null) + public function supportsNormalization($data, ?string $format = null) { return parent::supportsNormalization($data, $format) && $this->supports(\get_class($data)); } @@ -49,7 +49,7 @@ public function supportsNormalization($data, string $format = null) /** * {@inheritdoc} */ - public function supportsDenormalization($data, string $type, string $format = null) + public function supportsDenormalization($data, string $type, ?string $format = null) { return parent::supportsDenormalization($data, $type, $format) && $this->supports($type); } @@ -98,7 +98,7 @@ private function isGetMethod(\ReflectionMethod $method): bool /** * {@inheritdoc} */ - protected function extractAttributes(object $object, string $format = null, array $context = []) + protected function extractAttributes(object $object, ?string $format = null, array $context = []) { $reflectionObject = new \ReflectionObject($object); $reflectionMethods = $reflectionObject->getMethods(\ReflectionMethod::IS_PUBLIC); @@ -122,7 +122,7 @@ protected function extractAttributes(object $object, string $format = null, arra /** * {@inheritdoc} */ - protected function getAttributeValue(object $object, string $attribute, string $format = null, array $context = []) + protected function getAttributeValue(object $object, string $attribute, ?string $format = null, array $context = []) { $ucfirsted = ucfirst($attribute); @@ -147,7 +147,7 @@ protected function getAttributeValue(object $object, string $attribute, string $ /** * {@inheritdoc} */ - protected function setAttributeValue(object $object, string $attribute, $value, string $format = null, array $context = []) + protected function setAttributeValue(object $object, string $attribute, $value, ?string $format = null, array $context = []) { $setter = 'set'.ucfirst($attribute); $key = \get_class($object).':'.$setter; diff --git a/Normalizer/JsonSerializableNormalizer.php b/Normalizer/JsonSerializableNormalizer.php index 5032dce47..74f23fde9 100644 --- a/Normalizer/JsonSerializableNormalizer.php +++ b/Normalizer/JsonSerializableNormalizer.php @@ -24,7 +24,7 @@ class JsonSerializableNormalizer extends AbstractNormalizer /** * {@inheritdoc} */ - public function normalize($object, string $format = null, array $context = []) + public function normalize($object, ?string $format = null, array $context = []) { if ($this->isCircularReference($object, $context)) { return $this->handleCircularReference($object, $format, $context); @@ -44,7 +44,7 @@ public function normalize($object, string $format = null, array $context = []) /** * {@inheritdoc} */ - public function supportsNormalization($data, string $format = null) + public function supportsNormalization($data, ?string $format = null) { return $data instanceof \JsonSerializable; } @@ -52,7 +52,7 @@ public function supportsNormalization($data, string $format = null) /** * {@inheritdoc} */ - public function supportsDenormalization($data, string $type, string $format = null) + public function supportsDenormalization($data, string $type, ?string $format = null) { return false; } @@ -60,7 +60,7 @@ public function supportsDenormalization($data, string $type, string $format = nu /** * {@inheritdoc} */ - public function denormalize($data, string $type, string $format = null, array $context = []) + public function denormalize($data, string $type, ?string $format = null, array $context = []) { throw new LogicException(sprintf('Cannot denormalize with "%s".', \JsonSerializable::class)); } diff --git a/Normalizer/MimeMessageNormalizer.php b/Normalizer/MimeMessageNormalizer.php index 9dd9605a7..7519ad69e 100644 --- a/Normalizer/MimeMessageNormalizer.php +++ b/Normalizer/MimeMessageNormalizer.php @@ -52,7 +52,7 @@ public function setSerializer(SerializerInterface $serializer) /** * {@inheritdoc} */ - public function normalize($object, string $format = null, array $context = []) + public function normalize($object, ?string $format = null, array $context = []) { if ($object instanceof Headers) { $ret = []; @@ -77,7 +77,7 @@ public function normalize($object, string $format = null, array $context = []) /** * {@inheritdoc} */ - public function denormalize($data, string $type, string $format = null, array $context = []) + public function denormalize($data, string $type, ?string $format = null, array $context = []) { if (Headers::class === $type) { $ret = []; @@ -102,7 +102,7 @@ public function denormalize($data, string $type, string $format = null, array $c /** * {@inheritdoc} */ - public function supportsNormalization($data, string $format = null): bool + public function supportsNormalization($data, ?string $format = null): bool { return $data instanceof Message || $data instanceof Headers || $data instanceof HeaderInterface || $data instanceof Address || $data instanceof AbstractPart; } @@ -110,7 +110,7 @@ public function supportsNormalization($data, string $format = null): bool /** * {@inheritdoc} */ - public function supportsDenormalization($data, string $type, string $format = null): bool + public function supportsDenormalization($data, string $type, ?string $format = null): bool { return is_a($type, Message::class, true) || Headers::class === $type || AbstractPart::class === $type; } diff --git a/Normalizer/NormalizableInterface.php b/Normalizer/NormalizableInterface.php index ce4af8be5..5a8dc2897 100644 --- a/Normalizer/NormalizableInterface.php +++ b/Normalizer/NormalizableInterface.php @@ -35,5 +35,5 @@ interface NormalizableInterface * * @return array|string|int|float|bool */ - public function normalize(NormalizerInterface $normalizer, string $format = null, array $context = []); + public function normalize(NormalizerInterface $normalizer, ?string $format = null, array $context = []); } diff --git a/Normalizer/NormalizerInterface.php b/Normalizer/NormalizerInterface.php index b282f1dd6..87f8f1d8b 100644 --- a/Normalizer/NormalizerInterface.php +++ b/Normalizer/NormalizerInterface.php @@ -36,7 +36,7 @@ interface NormalizerInterface * @throws LogicException Occurs when the normalizer is not called in an expected context * @throws ExceptionInterface Occurs for all the other cases of errors */ - public function normalize($object, string $format = null, array $context = []); + public function normalize($object, ?string $format = null, array $context = []); /** * Checks whether the given class is supported for normalization by this normalizer. @@ -46,5 +46,5 @@ public function normalize($object, string $format = null, array $context = []); * * @return bool */ - public function supportsNormalization($data, string $format = null); + public function supportsNormalization($data, ?string $format = null); } diff --git a/Normalizer/ObjectNormalizer.php b/Normalizer/ObjectNormalizer.php index eb3d9716a..cbbade546 100644 --- a/Normalizer/ObjectNormalizer.php +++ b/Normalizer/ObjectNormalizer.php @@ -32,7 +32,7 @@ class ObjectNormalizer extends AbstractObjectNormalizer private $objectClassResolver; - public function __construct(ClassMetadataFactoryInterface $classMetadataFactory = null, NameConverterInterface $nameConverter = null, PropertyAccessorInterface $propertyAccessor = null, PropertyTypeExtractorInterface $propertyTypeExtractor = null, ClassDiscriminatorResolverInterface $classDiscriminatorResolver = null, callable $objectClassResolver = null, array $defaultContext = []) + public function __construct(?ClassMetadataFactoryInterface $classMetadataFactory = null, ?NameConverterInterface $nameConverter = null, ?PropertyAccessorInterface $propertyAccessor = null, ?PropertyTypeExtractorInterface $propertyTypeExtractor = null, ?ClassDiscriminatorResolverInterface $classDiscriminatorResolver = null, ?callable $objectClassResolver = null, array $defaultContext = []) { if (!class_exists(PropertyAccess::class)) { throw new LogicException('The ObjectNormalizer class requires the "PropertyAccess" component. Install "symfony/property-access" to use it.'); @@ -58,7 +58,7 @@ public function hasCacheableSupportsMethod(): bool /** * {@inheritdoc} */ - protected function extractAttributes(object $object, string $format = null, array $context = []) + protected function extractAttributes(object $object, ?string $format = null, array $context = []) { if (\stdClass::class === \get_class($object)) { return array_keys((array) $object); @@ -124,7 +124,7 @@ protected function extractAttributes(object $object, string $format = null, arra /** * {@inheritdoc} */ - protected function getAttributeValue(object $object, string $attribute, string $format = null, array $context = []) + protected function getAttributeValue(object $object, string $attribute, ?string $format = null, array $context = []) { $discriminatorProperty = null; if (null !== $this->classDiscriminatorResolver && null !== $mapping = $this->classDiscriminatorResolver->getMappingForMappedObject($object)) { @@ -139,7 +139,7 @@ protected function getAttributeValue(object $object, string $attribute, string $ /** * {@inheritdoc} */ - protected function setAttributeValue(object $object, string $attribute, $value, string $format = null, array $context = []) + protected function setAttributeValue(object $object, string $attribute, $value, ?string $format = null, array $context = []) { try { $this->propertyAccessor->setValue($object, $attribute, $value); diff --git a/Normalizer/ObjectToPopulateTrait.php b/Normalizer/ObjectToPopulateTrait.php index 6a0d324ce..adb519f45 100644 --- a/Normalizer/ObjectToPopulateTrait.php +++ b/Normalizer/ObjectToPopulateTrait.php @@ -21,7 +21,7 @@ trait ObjectToPopulateTrait * @param string|null $key They in which to look for the object to populate. * Keeps backwards compatibility with `AbstractNormalizer`. */ - protected function extractObjectToPopulate(string $class, array $context, string $key = null): ?object + protected function extractObjectToPopulate(string $class, array $context, ?string $key = null): ?object { $key = $key ?? AbstractNormalizer::OBJECT_TO_POPULATE; diff --git a/Normalizer/ProblemNormalizer.php b/Normalizer/ProblemNormalizer.php index 6fdd2773a..0cc47cdf8 100644 --- a/Normalizer/ProblemNormalizer.php +++ b/Normalizer/ProblemNormalizer.php @@ -41,7 +41,7 @@ public function __construct(bool $debug = false, array $defaultContext = []) * * @return array */ - public function normalize($object, string $format = null, array $context = []) + public function normalize($object, ?string $format = null, array $context = []) { if (!$object instanceof FlattenException) { throw new InvalidArgumentException(sprintf('The object must implement "%s".', FlattenException::class)); @@ -67,7 +67,7 @@ public function normalize($object, string $format = null, array $context = []) /** * {@inheritdoc} */ - public function supportsNormalization($data, string $format = null): bool + public function supportsNormalization($data, ?string $format = null): bool { return $data instanceof FlattenException; } diff --git a/Normalizer/PropertyNormalizer.php b/Normalizer/PropertyNormalizer.php index 030603446..15e60a968 100644 --- a/Normalizer/PropertyNormalizer.php +++ b/Normalizer/PropertyNormalizer.php @@ -35,7 +35,7 @@ class PropertyNormalizer extends AbstractObjectNormalizer /** * {@inheritdoc} */ - public function supportsNormalization($data, string $format = null) + public function supportsNormalization($data, ?string $format = null) { return parent::supportsNormalization($data, $format) && $this->supports(\get_class($data)); } @@ -43,7 +43,7 @@ public function supportsNormalization($data, string $format = null) /** * {@inheritdoc} */ - public function supportsDenormalization($data, string $type, string $format = null) + public function supportsDenormalization($data, string $type, ?string $format = null) { return parent::supportsDenormalization($data, $type, $format) && $this->supports($type); } @@ -82,7 +82,7 @@ private function supports(string $class): bool /** * {@inheritdoc} */ - protected function isAllowedAttribute($classOrObject, string $attribute, string $format = null, array $context = []) + protected function isAllowedAttribute($classOrObject, string $attribute, ?string $format = null, array $context = []) { if (!parent::isAllowedAttribute($classOrObject, $attribute, $format, $context)) { return false; @@ -103,7 +103,7 @@ protected function isAllowedAttribute($classOrObject, string $attribute, string /** * {@inheritdoc} */ - protected function extractAttributes(object $object, string $format = null, array $context = []) + protected function extractAttributes(object $object, ?string $format = null, array $context = []) { $reflectionObject = new \ReflectionObject($object); $attributes = []; @@ -124,7 +124,7 @@ protected function extractAttributes(object $object, string $format = null, arra /** * {@inheritdoc} */ - protected function getAttributeValue(object $object, string $attribute, string $format = null, array $context = []) + protected function getAttributeValue(object $object, string $attribute, ?string $format = null, array $context = []) { try { $reflectionProperty = $this->getReflectionProperty($object, $attribute); @@ -158,7 +158,7 @@ protected function getAttributeValue(object $object, string $attribute, string $ /** * {@inheritdoc} */ - protected function setAttributeValue(object $object, string $attribute, $value, string $format = null, array $context = []) + protected function setAttributeValue(object $object, string $attribute, $value, ?string $format = null, array $context = []) { try { $reflectionProperty = $this->getReflectionProperty($object, $attribute); diff --git a/Normalizer/UidNormalizer.php b/Normalizer/UidNormalizer.php index 81e60a349..70b5e158d 100644 --- a/Normalizer/UidNormalizer.php +++ b/Normalizer/UidNormalizer.php @@ -40,7 +40,7 @@ public function __construct(array $defaultContext = []) * * @param AbstractUid $object */ - public function normalize($object, string $format = null, array $context = []) + public function normalize($object, ?string $format = null, array $context = []) { switch ($context[self::NORMALIZATION_FORMAT_KEY] ?? $this->defaultContext[self::NORMALIZATION_FORMAT_KEY]) { case self::NORMALIZATION_FORMAT_CANONICAL: @@ -59,7 +59,7 @@ public function normalize($object, string $format = null, array $context = []) /** * {@inheritdoc} */ - public function supportsNormalization($data, string $format = null): bool + public function supportsNormalization($data, ?string $format = null): bool { return $data instanceof AbstractUid; } @@ -67,7 +67,7 @@ public function supportsNormalization($data, string $format = null): bool /** * {@inheritdoc} */ - public function denormalize($data, string $type, string $format = null, array $context = []) + public function denormalize($data, string $type, ?string $format = null, array $context = []) { try { return AbstractUid::class !== $type ? $type::fromString($data) : Uuid::fromString($data); @@ -85,7 +85,7 @@ public function denormalize($data, string $type, string $format = null, array $c /** * {@inheritdoc} */ - public function supportsDenormalization($data, string $type, string $format = null): bool + public function supportsDenormalization($data, string $type, ?string $format = null): bool { return is_a($type, AbstractUid::class, true); } diff --git a/Normalizer/UnwrappingDenormalizer.php b/Normalizer/UnwrappingDenormalizer.php index 9e9880d90..8a38538f0 100644 --- a/Normalizer/UnwrappingDenormalizer.php +++ b/Normalizer/UnwrappingDenormalizer.php @@ -27,7 +27,7 @@ final class UnwrappingDenormalizer implements DenormalizerInterface, SerializerA private $propertyAccessor; - public function __construct(PropertyAccessorInterface $propertyAccessor = null) + public function __construct(?PropertyAccessorInterface $propertyAccessor = null) { $this->propertyAccessor = $propertyAccessor ?? PropertyAccess::createPropertyAccessor(); } @@ -35,7 +35,7 @@ public function __construct(PropertyAccessorInterface $propertyAccessor = null) /** * {@inheritdoc} */ - public function denormalize($data, $class, string $format = null, array $context = []) + public function denormalize($data, $class, ?string $format = null, array $context = []) { $propertyPath = $context[self::UNWRAP_PATH]; $context['unwrapped'] = true; @@ -54,7 +54,7 @@ public function denormalize($data, $class, string $format = null, array $context /** * {@inheritdoc} */ - public function supportsDenormalization($data, $type, string $format = null, array $context = []): bool + public function supportsDenormalization($data, $type, ?string $format = null, array $context = []): bool { return \array_key_exists(self::UNWRAP_PATH, $context) && !isset($context['unwrapped']); } diff --git a/Serializer.php b/Serializer.php index 607dc9963..d814a8aef 100644 --- a/Serializer.php +++ b/Serializer.php @@ -154,7 +154,7 @@ final public function deserialize($data, string $type, string $format, array $co /** * {@inheritdoc} */ - public function normalize($data, string $format = null, array $context = []) + public function normalize($data, ?string $format = null, array $context = []) { // If a normalizer supports the given data, use it if ($normalizer = $this->getNormalizer($data, $format, $context)) { @@ -199,7 +199,7 @@ public function normalize($data, string $format = null, array $context = []) * @throws NotNormalizableValueException * @throws PartialDenormalizationException Occurs when one or more properties of $type fails to denormalize */ - public function denormalize($data, string $type, string $format = null, array $context = []) + public function denormalize($data, string $type, ?string $format = null, array $context = []) { if (isset($context[DenormalizerInterface::COLLECT_DENORMALIZATION_ERRORS], $context['not_normalizable_value_exceptions'])) { throw new LogicException('Passing a value for "not_normalizable_value_exceptions" context key is not allowed.'); @@ -254,7 +254,7 @@ public function denormalize($data, string $type, string $format = null, array $c /** * {@inheritdoc} */ - public function supportsNormalization($data, string $format = null, array $context = []) + public function supportsNormalization($data, ?string $format = null, array $context = []) { return null !== $this->getNormalizer($data, $format, $context); } @@ -262,7 +262,7 @@ public function supportsNormalization($data, string $format = null, array $conte /** * {@inheritdoc} */ - public function supportsDenormalization($data, string $type, string $format = null, array $context = []) + public function supportsDenormalization($data, string $type, ?string $format = null, array $context = []) { return isset(self::SCALAR_TYPES[$type]) || null !== $this->getDenormalizer($data, $type, $format, $context); } diff --git a/Tests/Normalizer/AbstractObjectNormalizerTest.php b/Tests/Normalizer/AbstractObjectNormalizerTest.php index 4e781c5d8..62515c223 100644 --- a/Tests/Normalizer/AbstractObjectNormalizerTest.php +++ b/Tests/Normalizer/AbstractObjectNormalizerTest.php @@ -473,17 +473,17 @@ protected function getAllowedAttributes($classOrObject, array $context, bool $at return ['foo']; } - protected function extractAttributes(object $object, string $format = null, array $context = []): array + protected function extractAttributes(object $object, ?string $format = null, array $context = []): array { return []; } - protected function getAttributeValue(object $object, string $attribute, string $format = null, array $context = []) + protected function getAttributeValue(object $object, string $attribute, ?string $format = null, array $context = []) { return $object->$attribute; } - protected function setAttributeValue(object $object, string $attribute, $value, string $format = null, array $context = []) + protected function setAttributeValue(object $object, string $attribute, $value, ?string $format = null, array $context = []) { } }; @@ -552,26 +552,26 @@ public function testDenormalizeUntypedStringObject() class AbstractObjectNormalizerDummy extends AbstractObjectNormalizer { - protected function extractAttributes(object $object, string $format = null, array $context = []): array + protected function extractAttributes(object $object, ?string $format = null, array $context = []): array { return []; } - protected function getAttributeValue(object $object, string $attribute, string $format = null, array $context = []) + protected function getAttributeValue(object $object, string $attribute, ?string $format = null, array $context = []) { } - protected function setAttributeValue(object $object, string $attribute, $value, string $format = null, array $context = []) + protected function setAttributeValue(object $object, string $attribute, $value, ?string $format = null, array $context = []) { $object->$attribute = $value; } - protected function isAllowedAttribute($classOrObject, string $attribute, string $format = null, array $context = []): bool + protected function isAllowedAttribute($classOrObject, string $attribute, ?string $format = null, array $context = []): bool { return \in_array($attribute, ['foo', 'baz', 'quux', 'value']); } - public function instantiateObject(array &$data, string $class, array &$context, \ReflectionClass $reflectionClass, $allowedAttributes, string $format = null): object + public function instantiateObject(array &$data, string $class, array &$context, \ReflectionClass $reflectionClass, $allowedAttributes, ?string $format = null): object { return parent::instantiateObject($data, $class, $context, $reflectionClass, $allowedAttributes, $format); } @@ -595,15 +595,15 @@ public function __construct() parent::__construct(new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()))); } - protected function extractAttributes(object $object, string $format = null, array $context = []): array + protected function extractAttributes(object $object, ?string $format = null, array $context = []): array { } - protected function getAttributeValue(object $object, string $attribute, string $format = null, array $context = []) + protected function getAttributeValue(object $object, string $attribute, ?string $format = null, array $context = []) { } - protected function setAttributeValue(object $object, string $attribute, $value, string $format = null, array $context = []) + protected function setAttributeValue(object $object, string $attribute, $value, ?string $format = null, array $context = []) { $object->$attribute = $value; } @@ -691,7 +691,7 @@ public function deserialize($data, string $type, string $format, array $context { } - public function denormalize($data, string $type, string $format = null, array $context = []) + public function denormalize($data, string $type, ?string $format = null, array $context = []) { foreach ($this->normalizers as $normalizer) { if ($normalizer instanceof DenormalizerInterface && $normalizer->supportsDenormalization($data, $type, $format, $context)) { @@ -702,7 +702,7 @@ public function denormalize($data, string $type, string $format = null, array $c return null; } - public function supportsDenormalization($data, string $type, string $format = null): bool + public function supportsDenormalization($data, string $type, ?string $format = null): bool { return true; } @@ -710,25 +710,25 @@ public function supportsDenormalization($data, string $type, string $format = nu class AbstractObjectNormalizerCollectionDummy extends AbstractObjectNormalizer { - protected function extractAttributes(object $object, string $format = null, array $context = []): array + protected function extractAttributes(object $object, ?string $format = null, array $context = []): array { } - protected function getAttributeValue(object $object, string $attribute, string $format = null, array $context = []) + protected function getAttributeValue(object $object, string $attribute, ?string $format = null, array $context = []) { } - protected function setAttributeValue(object $object, string $attribute, $value, string $format = null, array $context = []) + protected function setAttributeValue(object $object, string $attribute, $value, ?string $format = null, array $context = []) { $object->$attribute = $value; } - protected function isAllowedAttribute($classOrObject, string $attribute, string $format = null, array $context = []): bool + protected function isAllowedAttribute($classOrObject, string $attribute, ?string $format = null, array $context = []): bool { return true; } - public function instantiateObject(array &$data, string $class, array &$context, \ReflectionClass $reflectionClass, $allowedAttributes, string $format = null): object + public function instantiateObject(array &$data, string $class, array &$context, \ReflectionClass $reflectionClass, $allowedAttributes, ?string $format = null): object { return parent::instantiateObject($data, $class, $context, $reflectionClass, $allowedAttributes, $format); } @@ -754,7 +754,7 @@ class ArrayDenormalizerDummy implements DenormalizerInterface, SerializerAwareIn * * @throws NotNormalizableValueException */ - public function denormalize($data, string $type, string $format = null, array $context = []) + public function denormalize($data, string $type, ?string $format = null, array $context = []) { $serializer = $this->serializer; $type = substr($type, 0, -2); @@ -769,7 +769,7 @@ public function denormalize($data, string $type, string $format = null, array $c /** * {@inheritdoc} */ - public function supportsDenormalization($data, string $type, string $format = null, array $context = []): bool + public function supportsDenormalization($data, string $type, ?string $format = null, array $context = []): bool { return str_ends_with($type, '[]') && $this->serializer->supportsDenormalization($data, substr($type, 0, -2), $format, $context); diff --git a/Tests/Normalizer/ConstraintViolationListNormalizerTest.php b/Tests/Normalizer/ConstraintViolationListNormalizerTest.php index 4dd177948..510451cc5 100644 --- a/Tests/Normalizer/ConstraintViolationListNormalizerTest.php +++ b/Tests/Normalizer/ConstraintViolationListNormalizerTest.php @@ -111,7 +111,7 @@ public function testNormalizeWithNameConverter() /** * @dataProvider payloadFieldsProvider */ - public function testNormalizePayloadFields($fields, array $expected = null) + public function testNormalizePayloadFields($fields, ?array $expected = null) { $constraint = new NotNull(); $constraint->payload = ['severity' => 'warning', 'anotherField2' => 'aValue']; diff --git a/Tests/Normalizer/Features/CallbacksObject.php b/Tests/Normalizer/Features/CallbacksObject.php index 19ad3f547..d484f8b8a 100644 --- a/Tests/Normalizer/Features/CallbacksObject.php +++ b/Tests/Normalizer/Features/CallbacksObject.php @@ -20,7 +20,7 @@ class CallbacksObject */ public $foo; - public function __construct($bar = null, string $foo = null) + public function __construct($bar = null, ?string $foo = null) { $this->bar = $bar; $this->foo = $foo; diff --git a/Tests/Normalizer/ObjectNormalizerTest.php b/Tests/Normalizer/ObjectNormalizerTest.php index a909274eb..36957ac5c 100644 --- a/Tests/Normalizer/ObjectNormalizerTest.php +++ b/Tests/Normalizer/ObjectNormalizerTest.php @@ -91,7 +91,7 @@ protected function setUp(): void $this->createNormalizer(); } - private function createNormalizer(array $defaultContext = [], ClassMetadataFactoryInterface $classMetadataFactory = null) + private function createNormalizer(array $defaultContext = [], ?ClassMetadataFactoryInterface $classMetadataFactory = null) { $this->serializer = $this->createMock(ObjectSerializerNormalizer::class); $this->normalizer = new ObjectNormalizer($classMetadataFactory, null, null, null, null, null, $defaultContext); @@ -789,12 +789,12 @@ public function testDenormalizeFalsePseudoType() public function testAdvancedNameConverter() { $nameConverter = new class() implements AdvancedNameConverterInterface { - public function normalize(string $propertyName, string $class = null, string $format = null, array $context = []): string + public function normalize(string $propertyName, ?string $class = null, ?string $format = null, array $context = []): string { return sprintf('%s-%s-%s-%s', $propertyName, $class, $format, $context['foo']); } - public function denormalize(string $propertyName, string $class = null, string $format = null, array $context = []): string + public function denormalize(string $propertyName, ?string $class = null, ?string $format = null, array $context = []): string { return sprintf('%s-%s-%s-%s', $propertyName, $class, $format, $context['foo']); } @@ -1047,7 +1047,7 @@ public function __get($name) class FormatAndContextAwareNormalizer extends ObjectNormalizer { - protected function isAllowedAttribute($classOrObject, string $attribute, string $format = null, array $context = []): bool + protected function isAllowedAttribute($classOrObject, string $attribute, ?string $format = null, array $context = []): bool { if (\in_array($attribute, ['foo', 'bar']) && 'foo_and_bar_included' === $format) { return true; @@ -1103,7 +1103,7 @@ class DummyWithConstructorObjectAndDefaultValue private $foo; private $inner; - public function __construct($foo = 'a', ObjectInner $inner = null) + public function __construct($foo = 'a', ?ObjectInner $inner = null) { $this->foo = $foo; $this->inner = $inner; diff --git a/Tests/Normalizer/TestDenormalizer.php b/Tests/Normalizer/TestDenormalizer.php index 68c8c532c..6639c76d6 100644 --- a/Tests/Normalizer/TestDenormalizer.php +++ b/Tests/Normalizer/TestDenormalizer.php @@ -23,14 +23,14 @@ class TestDenormalizer implements DenormalizerInterface /** * {@inheritdoc} */ - public function denormalize($data, string $type, string $format = null, array $context = []) + public function denormalize($data, string $type, ?string $format = null, array $context = []) { } /** * {@inheritdoc} */ - public function supportsDenormalization($data, string $type, string $format = null): bool + public function supportsDenormalization($data, string $type, ?string $format = null): bool { return true; } diff --git a/Tests/Normalizer/TestNormalizer.php b/Tests/Normalizer/TestNormalizer.php index 75a999485..84b806941 100644 --- a/Tests/Normalizer/TestNormalizer.php +++ b/Tests/Normalizer/TestNormalizer.php @@ -23,7 +23,7 @@ class TestNormalizer implements NormalizerInterface /** * {@inheritdoc} */ - public function normalize($object, string $format = null, array $context = []) + public function normalize($object, ?string $format = null, array $context = []) { return null; } @@ -31,7 +31,7 @@ public function normalize($object, string $format = null, array $context = []) /** * {@inheritdoc} */ - public function supportsNormalization($data, string $format = null): bool + public function supportsNormalization($data, ?string $format = null): bool { return true; } From b2ab3bff0a3ae122ec2a55798304d4cb244b9ac2 Mon Sep 17 00:00:00 2001 From: Cornel Cruceru Date: Fri, 12 Jan 2024 18:36:51 +0200 Subject: [PATCH 4/7] [Serializer] Rewrite `AbstractObjectNormalizer::createChildContext()` to use the provided `cache_key` from original context when creating child contexts --- Normalizer/AbstractObjectNormalizer.php | 6 +- .../AbstractObjectNormalizerTest.php | 125 ++++++++++++++++++ 2 files changed, 130 insertions(+), 1 deletion(-) diff --git a/Normalizer/AbstractObjectNormalizer.php b/Normalizer/AbstractObjectNormalizer.php index a51b69503..ee2af79f3 100644 --- a/Normalizer/AbstractObjectNormalizer.php +++ b/Normalizer/AbstractObjectNormalizer.php @@ -781,7 +781,11 @@ private function isMaxDepthReached(array $attributesMetadata, string $class, str protected function createChildContext(array $parentContext, string $attribute, ?string $format): array { $context = parent::createChildContext($parentContext, $attribute, $format); - $context['cache_key'] = $this->getCacheKey($format, $context); + if ($context['cache_key'] ?? false) { + $context['cache_key'] .= '-'.$attribute; + } else { + $context['cache_key'] = $this->getCacheKey($format, $context); + } return $context; } diff --git a/Tests/Normalizer/AbstractObjectNormalizerTest.php b/Tests/Normalizer/AbstractObjectNormalizerTest.php index 4e781c5d8..368a20032 100644 --- a/Tests/Normalizer/AbstractObjectNormalizerTest.php +++ b/Tests/Normalizer/AbstractObjectNormalizerTest.php @@ -548,6 +548,131 @@ public function testDenormalizeUntypedStringObject() $this->assertEquals(new DummyWithStringObject(new DummyString()), $actual); $this->assertEquals('', $actual->value->value); } + + public function testProvidingContextCacheKeyGeneratesSameChildContextCacheKey() + { + $foobar = new Dummy(); + $foobar->foo = new EmptyDummy(); + $foobar->bar = 'bar'; + $foobar->baz = 'baz'; + $data = [ + 'foo' => [], + 'bar' => 'bar', + 'baz' => 'baz', + ]; + + $normalizer = new class() extends AbstractObjectNormalizerDummy { + public $childContextCacheKey; + + protected function extractAttributes(object $object, string $format = null, array $context = []): array + { + return array_keys((array) $object); + } + + protected function getAttributeValue(object $object, string $attribute, string $format = null, array $context = []) + { + return $object->{$attribute}; + } + + protected function createChildContext(array $parentContext, string $attribute, ?string $format): array + { + $childContext = parent::createChildContext($parentContext, $attribute, $format); + $this->childContextCacheKey = $childContext['cache_key']; + + return $childContext; + } + }; + + $serializer = new Serializer([$normalizer]); + + $serializer->normalize($foobar, null, ['cache_key' => 'hardcoded', 'iri' => '/dummy/1']); + $firstChildContextCacheKey = $normalizer->childContextCacheKey; + + $serializer->normalize($foobar, null, ['cache_key' => 'hardcoded', 'iri' => '/dummy/2']); + $secondChildContextCacheKey = $normalizer->childContextCacheKey; + + $this->assertSame($firstChildContextCacheKey, $secondChildContextCacheKey); + } + + public function testChildContextKeepsOriginalContextCacheKey() + { + $foobar = new Dummy(); + $foobar->foo = new EmptyDummy(); + $foobar->bar = 'bar'; + $foobar->baz = 'baz'; + $data = [ + 'foo' => [], + 'bar' => 'bar', + 'baz' => 'baz', + ]; + + $normalizer = new class() extends AbstractObjectNormalizerDummy { + public $childContextCacheKey; + + protected function extractAttributes(object $object, string $format = null, array $context = []): array + { + return array_keys((array) $object); + } + + protected function getAttributeValue(object $object, string $attribute, string $format = null, array $context = []) + { + return $object->{$attribute}; + } + + protected function createChildContext(array $parentContext, string $attribute, ?string $format): array + { + $childContext = parent::createChildContext($parentContext, $attribute, $format); + $this->childContextCacheKey = $childContext['cache_key']; + + return $childContext; + } + }; + + $serializer = new Serializer([$normalizer]); + $serializer->normalize($foobar, null, ['cache_key' => 'hardcoded', 'iri' => '/dummy/1']); + + $this->assertSame('hardcoded-foo', $normalizer->childContextCacheKey); + } + + public function testChildContextCacheKeyStaysFalseWhenOriginalCacheKeyIsFalse() + { + $foobar = new Dummy(); + $foobar->foo = new EmptyDummy(); + $foobar->bar = 'bar'; + $foobar->baz = 'baz'; + $data = [ + 'foo' => [], + 'bar' => 'bar', + 'baz' => 'baz', + ]; + + $normalizer = new class() extends AbstractObjectNormalizerDummy { + public $childContextCacheKey; + + protected function extractAttributes(object $object, string $format = null, array $context = []): array + { + return array_keys((array) $object); + } + + protected function getAttributeValue(object $object, string $attribute, string $format = null, array $context = []) + { + return $object->{$attribute}; + } + + protected function createChildContext(array $parentContext, string $attribute, ?string $format): array + { + $childContext = parent::createChildContext($parentContext, $attribute, $format); + $this->childContextCacheKey = $childContext['cache_key']; + + return $childContext; + } + }; + + $serializer = new Serializer([$normalizer]); + $serializer->normalize($foobar, null, ['cache_key' => false]); + + $this->assertFalse($normalizer->childContextCacheKey); + } } class AbstractObjectNormalizerDummy extends AbstractObjectNormalizer From c2b504e08170edc10b34539ae4a78b375b41cd3d Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Mon, 29 Jan 2024 11:52:16 +0100 Subject: [PATCH 5/7] do not overwrite the cache key when it is false --- Normalizer/AbstractObjectNormalizer.php | 2 +- Tests/Normalizer/AbstractObjectNormalizerTest.php | 15 --------------- 2 files changed, 1 insertion(+), 16 deletions(-) diff --git a/Normalizer/AbstractObjectNormalizer.php b/Normalizer/AbstractObjectNormalizer.php index 25341e234..4b03fa9dd 100644 --- a/Normalizer/AbstractObjectNormalizer.php +++ b/Normalizer/AbstractObjectNormalizer.php @@ -783,7 +783,7 @@ protected function createChildContext(array $parentContext, string $attribute, ? $context = parent::createChildContext($parentContext, $attribute, $format); if ($context['cache_key'] ?? false) { $context['cache_key'] .= '-'.$attribute; - } else { + } elseif (false !== ($context['cache_key'] ?? null)) { $context['cache_key'] = $this->getCacheKey($format, $context); } diff --git a/Tests/Normalizer/AbstractObjectNormalizerTest.php b/Tests/Normalizer/AbstractObjectNormalizerTest.php index 5a1d1613a..5adc3d4ee 100644 --- a/Tests/Normalizer/AbstractObjectNormalizerTest.php +++ b/Tests/Normalizer/AbstractObjectNormalizerTest.php @@ -555,11 +555,6 @@ public function testProvidingContextCacheKeyGeneratesSameChildContextCacheKey() $foobar->foo = new EmptyDummy(); $foobar->bar = 'bar'; $foobar->baz = 'baz'; - $data = [ - 'foo' => [], - 'bar' => 'bar', - 'baz' => 'baz', - ]; $normalizer = new class() extends AbstractObjectNormalizerDummy { public $childContextCacheKey; @@ -600,11 +595,6 @@ public function testChildContextKeepsOriginalContextCacheKey() $foobar->foo = new EmptyDummy(); $foobar->bar = 'bar'; $foobar->baz = 'baz'; - $data = [ - 'foo' => [], - 'bar' => 'bar', - 'baz' => 'baz', - ]; $normalizer = new class() extends AbstractObjectNormalizerDummy { public $childContextCacheKey; @@ -640,11 +630,6 @@ public function testChildContextCacheKeyStaysFalseWhenOriginalCacheKeyIsFalse() $foobar->foo = new EmptyDummy(); $foobar->bar = 'bar'; $foobar->baz = 'baz'; - $data = [ - 'foo' => [], - 'bar' => 'bar', - 'baz' => 'baz', - ]; $normalizer = new class() extends AbstractObjectNormalizerDummy { public $childContextCacheKey; From 95767d59415e4f3cd1c06b81e2e72dda838711b7 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 29 Jan 2024 16:15:02 +0100 Subject: [PATCH 6/7] Fix merge (bis) --- Tests/Normalizer/AbstractObjectNormalizerTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Tests/Normalizer/AbstractObjectNormalizerTest.php b/Tests/Normalizer/AbstractObjectNormalizerTest.php index 853aadb8d..a07fcd54e 100644 --- a/Tests/Normalizer/AbstractObjectNormalizerTest.php +++ b/Tests/Normalizer/AbstractObjectNormalizerTest.php @@ -938,7 +938,7 @@ protected function extractAttributes(object $object, string $format = null, arra return array_keys((array) $object); } - protected function getAttributeValue(object $object, string $attribute, string $format = null, array $context = []) + protected function getAttributeValue(object $object, string $attribute, string $format = null, array $context = []): mixed { return $object->{$attribute}; } @@ -978,7 +978,7 @@ protected function extractAttributes(object $object, string $format = null, arra return array_keys((array) $object); } - protected function getAttributeValue(object $object, string $attribute, string $format = null, array $context = []) + protected function getAttributeValue(object $object, string $attribute, string $format = null, array $context = []): mixed { return $object->{$attribute}; } @@ -1013,7 +1013,7 @@ protected function extractAttributes(object $object, string $format = null, arra return array_keys((array) $object); } - protected function getAttributeValue(object $object, string $attribute, string $format = null, array $context = []) + protected function getAttributeValue(object $object, string $attribute, string $format = null, array $context = []): mixed { return $object->{$attribute}; } From 02acd86290077dab2f12ae91b3e9f141c079d84c Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 30 Jan 2024 08:55:07 +0100 Subject: [PATCH 7/7] [Mime] Fix serializing uninitialized RawMessage::$message to null --- Normalizer/MimeMessageNormalizer.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Normalizer/MimeMessageNormalizer.php b/Normalizer/MimeMessageNormalizer.php index 7519ad69e..a1e131835 100644 --- a/Normalizer/MimeMessageNormalizer.php +++ b/Normalizer/MimeMessageNormalizer.php @@ -17,6 +17,7 @@ use Symfony\Component\Mime\Header\UnstructuredHeader; use Symfony\Component\Mime\Message; use Symfony\Component\Mime\Part\AbstractPart; +use Symfony\Component\Mime\RawMessage; use Symfony\Component\Serializer\SerializerAwareInterface; use Symfony\Component\Serializer\SerializerInterface; @@ -63,15 +64,18 @@ public function normalize($object, ?string $format = null, array $context = []) return $ret; } + $ret = $this->normalizer->normalize($object, $format, $context); + if ($object instanceof AbstractPart) { - $ret = $this->normalizer->normalize($object, $format, $context); $ret['class'] = \get_class($object); unset($ret['seekable'], $ret['cid'], $ret['handle']); + } - return $ret; + if ($object instanceof RawMessage && \array_key_exists('message', $ret) && null === $ret['message']) { + unset($ret['message']); } - return $this->normalizer->normalize($object, $format, $context); + return $ret; } /**