From 0714257de2cbd0358bac79b22880b18be2e95e13 Mon Sep 17 00:00:00 2001 From: Dariusz Gafka Date: Sun, 20 Feb 2022 17:25:56 +0100 Subject: [PATCH 01/10] Allow for contextual property naming strategy --- .../SerializationGraphNavigator.php | 10 ++++ src/SerializationContext.php | 19 +++++++ tests/SerializerBuilderTest.php | 55 +++++++++++++++++++ 3 files changed, 84 insertions(+) diff --git a/src/GraphNavigator/SerializationGraphNavigator.php b/src/GraphNavigator/SerializationGraphNavigator.php index 210de8648..e8a532e2d 100644 --- a/src/GraphNavigator/SerializationGraphNavigator.php +++ b/src/GraphNavigator/SerializationGraphNavigator.php @@ -24,6 +24,7 @@ use JMS\Serializer\GraphNavigatorInterface; use JMS\Serializer\Handler\HandlerRegistryInterface; use JMS\Serializer\Metadata\ClassMetadata; +use JMS\Serializer\Naming\PropertyNamingStrategyInterface; use JMS\Serializer\NullAwareVisitorInterface; use JMS\Serializer\SerializationContext; use JMS\Serializer\Visitor\SerializationVisitorInterface; @@ -80,6 +81,10 @@ final class SerializationGraphNavigator extends GraphNavigator * @var bool */ private $shouldSerializeNull; + /** + * @var PropertyNamingStrategyInterface|null + */ + private $contextPropertyNamingStrategy = null; public function __construct( MetadataFactoryInterface $metadataFactory, @@ -104,6 +109,7 @@ public function initialize(VisitorInterface $visitor, Context $context): void parent::initialize($visitor, $context); $this->shouldSerializeNull = $context->shouldSerializeNull(); + $this->contextPropertyNamingStrategy = $context->getPropertyNamingStrategy(); } /** @@ -255,6 +261,10 @@ public function accept($data, ?array $type = null) continue; } + if ($this->contextPropertyNamingStrategy) { + $propertyMetadata->serializedName = $this->contextPropertyNamingStrategy->translateName($propertyMetadata); + } + $v = $this->accessor->getValue($data, $propertyMetadata, $this->context); if (null === $v && true !== $this->shouldSerializeNull) { diff --git a/src/SerializationContext.php b/src/SerializationContext.php index 24073536b..d92123f5b 100644 --- a/src/SerializationContext.php +++ b/src/SerializationContext.php @@ -5,6 +5,7 @@ namespace JMS\Serializer; use JMS\Serializer\Exception\RuntimeException; +use JMS\Serializer\Naming\PropertyNamingStrategyInterface; use Metadata\MetadataFactoryInterface; class SerializationContext extends Context @@ -24,6 +25,10 @@ class SerializationContext extends Context * @var bool */ private $serializeNull = false; + /** + * @var PropertyNamingStrategyInterface|null + */ + private $propertyNamingStrategy = null; public static function create(): self { @@ -50,6 +55,15 @@ public function setSerializeNull(bool $bool): self return $this; } + public function setPropertyNamingStrategy(PropertyNamingStrategyInterface $propertyNamingStrategy): self + { + $this->assertMutable(); + + $this->propertyNamingStrategy = $propertyNamingStrategy; + + return $this; + } + /** * Returns TRUE when NULLs should be serialized * Returns FALSE when NULLs should not be serialized @@ -59,6 +73,11 @@ public function shouldSerializeNull(): bool return $this->serializeNull; } + public function getPropertyNamingStrategy(): ?PropertyNamingStrategyInterface + { + return $this->propertyNamingStrategy; + } + /** * @param mixed $object */ diff --git a/tests/SerializerBuilderTest.php b/tests/SerializerBuilderTest.php index 07e4f2186..e61890546 100644 --- a/tests/SerializerBuilderTest.php +++ b/tests/SerializerBuilderTest.php @@ -8,8 +8,11 @@ use JMS\Serializer\Exception\UnsupportedFormatException; use JMS\Serializer\Expression\ExpressionEvaluator; use JMS\Serializer\Handler\HandlerRegistry; +use JMS\Serializer\Naming\CamelCaseNamingStrategy; +use JMS\Serializer\Naming\IdenticalPropertyNamingStrategy; use JMS\Serializer\SerializationContext; use JMS\Serializer\SerializerBuilder; +use JMS\Serializer\Tests\Fixtures\CustomDeserializationObject; use JMS\Serializer\Tests\Fixtures\DocBlockType\Collection\Details\ProductDescription; use JMS\Serializer\Tests\Fixtures\DocBlockType\SingleClassFromDifferentNamespaceTypeHint; use JMS\Serializer\Tests\Fixtures\PersonSecret; @@ -201,6 +204,58 @@ public function testSetCallbackSerializationContextWithNotSerializeNull() self::assertEquals('{"not_null":"ok"}', $result); } + public function testSetCallbackSerializationContextWithIdenticalPropertyNamingStrategy() + { + $this->builder->setSerializationContextFactory(static function () { + return SerializationContext::create() + ->setPropertyNamingStrategy(new IdenticalPropertyNamingStrategy()); + }); + + $serializer = $this->builder + ->build(); + + $object = new CustomDeserializationObject('johny'); + $json = '{"someProperty":"johny"}'; + + self::assertEquals($json, $serializer->serialize($object, 'json')); + self::assertEquals($object, $serializer->deserialize($json, get_class($object), 'json')); + } + + public function testSetCallbackSerializationContextWithCamelCaseStrategy() + { + $this->builder->setSerializationContextFactory(static function () { + return SerializationContext::create() + ->setPropertyNamingStrategy(new CamelCaseNamingStrategy()); + }); + + $serializer = $this->builder + ->build(); + + $object = new CustomDeserializationObject('johny'); + $json = '{"some_property":"johny"}'; + + self::assertEquals($json, $serializer->serialize($object, 'json')); + self::assertEquals($object, $serializer->deserialize($json, get_class($object), 'json')); + } + + public function testSetCallbackSerializationContextOverridingDefaultStrategy() + { + $this->builder->setSerializationContextFactory(static function () { + return SerializationContext::create() + ->setPropertyNamingStrategy(new IdenticalPropertyNamingStrategy()); + }); + + $serializer = $this->builder + ->setPropertyNamingStrategy(new CamelCaseNamingStrategy()) + ->build(); + + $object = new CustomDeserializationObject('johny'); + $json = '{"someProperty":"johny"}'; + + self::assertEquals($json, $serializer->serialize($object, 'json')); + self::assertEquals($object, $serializer->deserialize($json, get_class($object), 'json')); + } + public function expressionFunctionProvider() { return [ From cc188fd25a32758012dbacb0750dd0f7fd6c28c5 Mon Sep 17 00:00:00 2001 From: Dariusz Gafka Date: Sun, 20 Feb 2022 17:32:11 +0100 Subject: [PATCH 02/10] Add test for inner child --- ...tomDeserializationObjectWithInnerClass.php | 21 +++++++++++++++++++ tests/SerializerBuilderTest.php | 18 ++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 tests/Fixtures/CustomDeserializationObjectWithInnerClass.php diff --git a/tests/Fixtures/CustomDeserializationObjectWithInnerClass.php b/tests/Fixtures/CustomDeserializationObjectWithInnerClass.php new file mode 100644 index 000000000..578314530 --- /dev/null +++ b/tests/Fixtures/CustomDeserializationObjectWithInnerClass.php @@ -0,0 +1,21 @@ +someProperty = $value; + } +} diff --git a/tests/SerializerBuilderTest.php b/tests/SerializerBuilderTest.php index e61890546..dab1d146d 100644 --- a/tests/SerializerBuilderTest.php +++ b/tests/SerializerBuilderTest.php @@ -13,6 +13,7 @@ use JMS\Serializer\SerializationContext; use JMS\Serializer\SerializerBuilder; use JMS\Serializer\Tests\Fixtures\CustomDeserializationObject; +use JMS\Serializer\Tests\Fixtures\CustomDeserializationObjectWithInnerClass; use JMS\Serializer\Tests\Fixtures\DocBlockType\Collection\Details\ProductDescription; use JMS\Serializer\Tests\Fixtures\DocBlockType\SingleClassFromDifferentNamespaceTypeHint; use JMS\Serializer\Tests\Fixtures\PersonSecret; @@ -256,6 +257,23 @@ public function testSetCallbackSerializationContextOverridingDefaultStrategy() self::assertEquals($object, $serializer->deserialize($json, get_class($object), 'json')); } + public function testSetCallbackSerializationContextWithIdenticalPropertyNamingForInnerClass() + { + $this->builder->setSerializationContextFactory(static function () { + return SerializationContext::create() + ->setPropertyNamingStrategy(new CamelCaseNamingStrategy()); + }); + + $serializer = $this->builder + ->build(); + + $object = new CustomDeserializationObjectWithInnerClass(new CustomDeserializationObject('johny')); + $json = '{"some_property":{"some_property":"johny"}}'; + + self::assertEquals($json, $serializer->serialize($object, 'json')); + self::assertEquals($object, $serializer->deserialize($json, get_class($object), 'json')); + } + public function expressionFunctionProvider() { return [ From 784ab9c8284cfbf2d64a51ce8398f178bb92c1ba Mon Sep 17 00:00:00 2001 From: Dariusz Gafka Date: Sun, 22 May 2022 21:03:15 +0200 Subject: [PATCH 03/10] Refactor Refactor --- src/SerializationContext.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/SerializationContext.php b/src/SerializationContext.php index d92123f5b..b0d16f327 100644 --- a/src/SerializationContext.php +++ b/src/SerializationContext.php @@ -58,7 +58,6 @@ public function setSerializeNull(bool $bool): self public function setPropertyNamingStrategy(PropertyNamingStrategyInterface $propertyNamingStrategy): self { $this->assertMutable(); - $this->propertyNamingStrategy = $propertyNamingStrategy; return $this; From 0e370a81ff598b274145ed99080b24818b316b32 Mon Sep 17 00:00:00 2001 From: Dariusz Gafka Date: Wed, 12 Oct 2022 20:26:07 +0200 Subject: [PATCH 04/10] Handle changing strategies --- src/Context.php | 20 +++++++++ .../DeserializationGraphNavigator.php | 17 +++++--- .../SerializationGraphNavigator.php | 19 ++++---- src/Metadata/PropertyMetadata.php | 5 +++ src/SerializationContext.php | 19 -------- .../Fixtures/CustomDeserializationObject.php | 6 +-- ...tomDeserializationObjectWithInnerClass.php | 6 +-- ...eserializationObjectWithSerializedName.php | 23 ++++++++++ tests/SerializerBuilderTest.php | 43 +++++++++++++++++++ 9 files changed, 117 insertions(+), 41 deletions(-) create mode 100644 tests/Fixtures/CustomDeserializationObjectWithSerializedName.php diff --git a/src/Context.php b/src/Context.php index 36adc2e69..03404b493 100644 --- a/src/Context.php +++ b/src/Context.php @@ -13,6 +13,7 @@ use JMS\Serializer\Exclusion\VersionExclusionStrategy; use JMS\Serializer\Metadata\ClassMetadata; use JMS\Serializer\Metadata\PropertyMetadata; +use JMS\Serializer\Naming\PropertyNamingStrategyInterface; use Metadata\MetadataFactory; use Metadata\MetadataFactoryInterface; @@ -54,6 +55,11 @@ abstract class Context /** @var \SplStack */ private $metadataStack; + /** + * @var PropertyNamingStrategyInterface|null + */ + private $propertyNamingStrategy = null; + public function __construct() { $this->metadataStack = new \SplStack(); @@ -228,6 +234,20 @@ public function popPropertyMetadata(): void } } + public function setPropertyNamingStrategy(PropertyNamingStrategyInterface $propertyNamingStrategy): self + { + $this->assertMutable(); + + $this->propertyNamingStrategy = $propertyNamingStrategy; + + return $this; + } + + public function getPropertyNamingStrategy(): ?PropertyNamingStrategyInterface + { + return $this->propertyNamingStrategy; + } + public function popClassMetadata(): void { $metadata = $this->metadataStack->pop(); diff --git a/src/GraphNavigator/DeserializationGraphNavigator.php b/src/GraphNavigator/DeserializationGraphNavigator.php index eaf236240..934d91ecf 100644 --- a/src/GraphNavigator/DeserializationGraphNavigator.php +++ b/src/GraphNavigator/DeserializationGraphNavigator.php @@ -209,13 +209,20 @@ public function accept($data, ?array $type = null) continue; } - $this->context->pushPropertyMetadata($propertyMetadata); + /** Metadata changes based on context, should not be cached */ + $contextSpecificMetadata = $propertyMetadata; + if (null !== $this->context->getPropertyNamingStrategy()) { + $contextSpecificMetadata = clone $propertyMetadata; + $contextSpecificMetadata->serializedName = $this->context->getPropertyNamingStrategy()->translateName($propertyMetadata); + } + + $this->context->pushPropertyMetadata($contextSpecificMetadata); try { - $v = $this->visitor->visitProperty($propertyMetadata, $data); - $this->accessor->setValue($object, $v, $propertyMetadata, $this->context); + $v = $this->visitor->visitProperty($contextSpecificMetadata, $data); + $this->accessor->setValue($object, $v, $contextSpecificMetadata, $this->context); } catch (NotAcceptableException $e) { - if (true === $propertyMetadata->hasDefault) { - $this->accessor->setValue($object, $propertyMetadata->defaultValue, $propertyMetadata, $this->context); + if (true === $contextSpecificMetadata->hasDefault) { + $this->accessor->setValue($object, $contextSpecificMetadata->defaultValue, $contextSpecificMetadata, $this->context); } } diff --git a/src/GraphNavigator/SerializationGraphNavigator.php b/src/GraphNavigator/SerializationGraphNavigator.php index 543c0bc50..c4c799cea 100644 --- a/src/GraphNavigator/SerializationGraphNavigator.php +++ b/src/GraphNavigator/SerializationGraphNavigator.php @@ -25,7 +25,6 @@ use JMS\Serializer\GraphNavigatorInterface; use JMS\Serializer\Handler\HandlerRegistryInterface; use JMS\Serializer\Metadata\ClassMetadata; -use JMS\Serializer\Naming\PropertyNamingStrategyInterface; use JMS\Serializer\NullAwareVisitorInterface; use JMS\Serializer\SerializationContext; use JMS\Serializer\Visitor\SerializationVisitorInterface; @@ -82,10 +81,6 @@ final class SerializationGraphNavigator extends GraphNavigator * @var bool */ private $shouldSerializeNull; - /** - * @var PropertyNamingStrategyInterface|null - */ - private $contextPropertyNamingStrategy = null; public function __construct( MetadataFactoryInterface $metadataFactory, @@ -110,7 +105,6 @@ public function initialize(VisitorInterface $visitor, Context $context): void parent::initialize($visitor, $context); $this->shouldSerializeNull = $context->shouldSerializeNull(); - $this->contextPropertyNamingStrategy = $context->getPropertyNamingStrategy(); } /** @@ -263,12 +257,15 @@ public function accept($data, ?array $type = null) continue; } - if ($this->contextPropertyNamingStrategy) { - $propertyMetadata->serializedName = $this->contextPropertyNamingStrategy->translateName($propertyMetadata); + /** Metadata changes based on context, should not be cached */ + $contextSpecificMetadata = $propertyMetadata; + if (null !== $this->context->getPropertyNamingStrategy()) { + $contextSpecificMetadata = clone $propertyMetadata; + $contextSpecificMetadata->serializedName = $this->context->getPropertyNamingStrategy()->translateName($propertyMetadata); } try { - $v = $this->accessor->getValue($data, $propertyMetadata, $this->context); + $v = $this->accessor->getValue($data, $contextSpecificMetadata, $this->context); } catch (UninitializedPropertyException $e) { continue; } @@ -277,8 +274,8 @@ public function accept($data, ?array $type = null) continue; } - $this->context->pushPropertyMetadata($propertyMetadata); - $this->visitor->visitProperty($propertyMetadata, $v); + $this->context->pushPropertyMetadata($contextSpecificMetadata); + $this->visitor->visitProperty($contextSpecificMetadata, $v); $this->context->popPropertyMetadata(); } diff --git a/src/Metadata/PropertyMetadata.php b/src/Metadata/PropertyMetadata.php index ff41c949f..377e41808 100644 --- a/src/Metadata/PropertyMetadata.php +++ b/src/Metadata/PropertyMetadata.php @@ -33,6 +33,11 @@ class PropertyMetadata extends BasePropertyMetadata */ public $serializedName; + /** + * @var string|null + */ + public $preContextSerializedName; + /** * @var array|null */ diff --git a/src/SerializationContext.php b/src/SerializationContext.php index d92123f5b..24073536b 100644 --- a/src/SerializationContext.php +++ b/src/SerializationContext.php @@ -5,7 +5,6 @@ namespace JMS\Serializer; use JMS\Serializer\Exception\RuntimeException; -use JMS\Serializer\Naming\PropertyNamingStrategyInterface; use Metadata\MetadataFactoryInterface; class SerializationContext extends Context @@ -25,10 +24,6 @@ class SerializationContext extends Context * @var bool */ private $serializeNull = false; - /** - * @var PropertyNamingStrategyInterface|null - */ - private $propertyNamingStrategy = null; public static function create(): self { @@ -55,15 +50,6 @@ public function setSerializeNull(bool $bool): self return $this; } - public function setPropertyNamingStrategy(PropertyNamingStrategyInterface $propertyNamingStrategy): self - { - $this->assertMutable(); - - $this->propertyNamingStrategy = $propertyNamingStrategy; - - return $this; - } - /** * Returns TRUE when NULLs should be serialized * Returns FALSE when NULLs should not be serialized @@ -73,11 +59,6 @@ public function shouldSerializeNull(): bool return $this->serializeNull; } - public function getPropertyNamingStrategy(): ?PropertyNamingStrategyInterface - { - return $this->propertyNamingStrategy; - } - /** * @param mixed $object */ diff --git a/tests/Fixtures/CustomDeserializationObject.php b/tests/Fixtures/CustomDeserializationObject.php index 5d8dbdfab..96766df84 100644 --- a/tests/Fixtures/CustomDeserializationObject.php +++ b/tests/Fixtures/CustomDeserializationObject.php @@ -4,14 +4,14 @@ namespace JMS\Serializer\Tests\Fixtures; -use JMS\Serializer\Annotation\Type; +use JMS\Serializer\Annotation as Serializer; class CustomDeserializationObject { /** - * @Type("string") + * @Serializer\Type("string") */ - #[Type(name: 'string')] + #[Serializer\Type(name: 'string')] public $someProperty; public function __construct($value) diff --git a/tests/Fixtures/CustomDeserializationObjectWithInnerClass.php b/tests/Fixtures/CustomDeserializationObjectWithInnerClass.php index 578314530..ec481fb52 100644 --- a/tests/Fixtures/CustomDeserializationObjectWithInnerClass.php +++ b/tests/Fixtures/CustomDeserializationObjectWithInnerClass.php @@ -4,14 +4,14 @@ namespace JMS\Serializer\Tests\Fixtures; -use JMS\Serializer\Annotation\Type; +use JMS\Serializer\Annotation as Serializer; class CustomDeserializationObjectWithInnerClass { /** - * @Type("JMS\Serializer\Tests\Fixtures\CustomDeserializationObject") + * @Serializer\Type("JMS\Serializer\Tests\Fixtures\CustomDeserializationObject") */ - #[Type(name: CustomDeserializationObject::class)] + #[Serializer\Type(name: CustomDeserializationObject::class)] private $someProperty; public function __construct(CustomDeserializationObject $value) diff --git a/tests/Fixtures/CustomDeserializationObjectWithSerializedName.php b/tests/Fixtures/CustomDeserializationObjectWithSerializedName.php new file mode 100644 index 000000000..5856c834d --- /dev/null +++ b/tests/Fixtures/CustomDeserializationObjectWithSerializedName.php @@ -0,0 +1,23 @@ +someProperty = $value; + } +} diff --git a/tests/SerializerBuilderTest.php b/tests/SerializerBuilderTest.php index dab1d146d..03fff05ce 100644 --- a/tests/SerializerBuilderTest.php +++ b/tests/SerializerBuilderTest.php @@ -10,10 +10,12 @@ use JMS\Serializer\Handler\HandlerRegistry; use JMS\Serializer\Naming\CamelCaseNamingStrategy; use JMS\Serializer\Naming\IdenticalPropertyNamingStrategy; +use JMS\Serializer\Naming\SerializedNameAnnotationStrategy; use JMS\Serializer\SerializationContext; use JMS\Serializer\SerializerBuilder; use JMS\Serializer\Tests\Fixtures\CustomDeserializationObject; use JMS\Serializer\Tests\Fixtures\CustomDeserializationObjectWithInnerClass; +use JMS\Serializer\Tests\Fixtures\CustomDeserializationObjectWithSerializedName; use JMS\Serializer\Tests\Fixtures\DocBlockType\Collection\Details\ProductDescription; use JMS\Serializer\Tests\Fixtures\DocBlockType\SingleClassFromDifferentNamespaceTypeHint; use JMS\Serializer\Tests\Fixtures\PersonSecret; @@ -211,6 +213,10 @@ public function testSetCallbackSerializationContextWithIdenticalPropertyNamingSt return SerializationContext::create() ->setPropertyNamingStrategy(new IdenticalPropertyNamingStrategy()); }); + $this->builder->setDeserializationContextFactory(static function () { + return DeserializationContext::create() + ->setPropertyNamingStrategy(new IdenticalPropertyNamingStrategy()); + }); $serializer = $this->builder ->build(); @@ -222,6 +228,39 @@ public function testSetCallbackSerializationContextWithIdenticalPropertyNamingSt self::assertEquals($object, $serializer->deserialize($json, get_class($object), 'json')); } + public function testUsingNoSerializationContextInSecondRun() + { + $serializer = $this->builder->build(); + $object = new CustomDeserializationObjectWithSerializedName('johny'); + + $jsonWithCamelCase = '{"someProperty":"johny"}'; + self::assertEquals($jsonWithCamelCase, $serializer->serialize($object, 'json', SerializationContext::create()->setPropertyNamingStrategy(new IdenticalPropertyNamingStrategy()))); + self::assertEquals($object, $serializer->deserialize($jsonWithCamelCase, get_class($object), 'json', DeserializationContext::create()->setPropertyNamingStrategy(new IdenticalPropertyNamingStrategy()))); + + $jsonWithUnderscores = '{"name":"johny"}'; + self::assertEquals($jsonWithUnderscores, $serializer->serialize($object, 'json')); + self::assertEquals($object, $serializer->deserialize($jsonWithUnderscores, get_class($object), 'json')); + } + + public function testUsingSerializedNameStrategyInContext() + { + $serializer = $this->builder->build(); + $object = new CustomDeserializationObjectWithSerializedName('johny'); + + $jsonWithUnderscores = '{"name":"johny"}'; + self::assertEquals($jsonWithUnderscores, $serializer->serialize( + $object, + 'json', + SerializationContext::create()->setPropertyNamingStrategy(new SerializedNameAnnotationStrategy(new IdenticalPropertyNamingStrategy())) + )); + self::assertEquals($object, $serializer->deserialize( + $jsonWithUnderscores, + get_class($object), + 'json', + DeserializationContext::create()->setPropertyNamingStrategy(new SerializedNameAnnotationStrategy(new IdenticalPropertyNamingStrategy())) + )); + } + public function testSetCallbackSerializationContextWithCamelCaseStrategy() { $this->builder->setSerializationContextFactory(static function () { @@ -245,6 +284,10 @@ public function testSetCallbackSerializationContextOverridingDefaultStrategy() return SerializationContext::create() ->setPropertyNamingStrategy(new IdenticalPropertyNamingStrategy()); }); + $this->builder->setDeserializationContextFactory(static function () { + return DeserializationContext::create() + ->setPropertyNamingStrategy(new IdenticalPropertyNamingStrategy()); + }); $serializer = $this->builder ->setPropertyNamingStrategy(new CamelCaseNamingStrategy()) From f42048f3fc892edea3fa9e5105720fd85823f827 Mon Sep 17 00:00:00 2001 From: Dariusz Gafka Date: Tue, 15 Nov 2022 08:18:08 +0100 Subject: [PATCH 05/10] Add docs --- doc/configuration.rst | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/doc/configuration.rst b/doc/configuration.rst index aabe95662..6030f1a90 100644 --- a/doc/configuration.rst +++ b/doc/configuration.rst @@ -77,6 +77,43 @@ The serializer would expect the metadata files to be named like the fully qualif replaced with ``.``. So, if you class would be named ``Vendor\Package\Foo``, the metadata file would need to be located at ``$someDir/Vendor.Package.Foo.(xml|yml)``. If not found, ``$someDir/Vendor.Package.(xml|yml)`` will be tried, then ``$someDir/Vendor.Package.(xml|yml)`` and so on. For more information, see the :doc:`reference `. +Context Strategy +---------------------------------------------- + +Context strategy allows you to change serialization configuration for specific serialization or deserialization. +This allow you to deviate from default configuration. + +### Serializing null values + + use JMS\Serializer\SerializationContext; + + $serializer->serialize( + $object, + 'json', + SerializationContext::create()->setSerializeNull(true) + ) + +### Serializing with different property naming strategy + + use JMS\Serializer\SerializationContext; + + $serializer->serialize( + $object, + 'json', + SerializationContext::create()->setPropertyNamingStrategy(new SerializedNameAnnotationStrategy(new IdenticalPropertyNamingStrategy())) + ) + +### Deserializing with different property naming strategy + + use JMS\Serializer\SerializationContext; + + $serializer->deserialize( + $jsonString, + Product:class, + 'json', + DeserializationContext::create()->setPropertyNamingStrategy(new SerializedNameAnnotationStrategy(new IdenticalPropertyNamingStrategy())) + ) + Setting a default SerializationContext factory ---------------------------------------------- To avoid to pass an instance of SerializationContext @@ -103,4 +140,4 @@ a serialization context from your callable and use it. You can also set a default DeserializationContextFactory with ``->setDeserializationContextFactory(function () { /* ... */ })`` - to be used with methods ``deserialize()`` and ``fromArray()``. + to be used with methods ``deserialize()`` and ``fromArray()``. \ No newline at end of file From 8c2eb6ffa4280c51e93c1be2f0e15a14949526af Mon Sep 17 00:00:00 2001 From: Dariusz Gafka Date: Tue, 15 Nov 2022 08:34:59 +0100 Subject: [PATCH 06/10] update docs --- doc/configuration.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/configuration.rst b/doc/configuration.rst index 6030f1a90..589c4741a 100644 --- a/doc/configuration.rst +++ b/doc/configuration.rst @@ -83,7 +83,7 @@ Context Strategy Context strategy allows you to change serialization configuration for specific serialization or deserialization. This allow you to deviate from default configuration. -### Serializing null values +### Serializing null values:: use JMS\Serializer\SerializationContext; @@ -93,7 +93,7 @@ This allow you to deviate from default configuration. SerializationContext::create()->setSerializeNull(true) ) -### Serializing with different property naming strategy +### Serializing with different property naming strategy:: use JMS\Serializer\SerializationContext; @@ -103,7 +103,7 @@ This allow you to deviate from default configuration. SerializationContext::create()->setPropertyNamingStrategy(new SerializedNameAnnotationStrategy(new IdenticalPropertyNamingStrategy())) ) -### Deserializing with different property naming strategy +### Deserializing with different property naming strategy:: use JMS\Serializer\SerializationContext; From d8a95ad6c3c796dd2eab22b735f48b5f42d4b594 Mon Sep 17 00:00:00 2001 From: Dariusz Gafka Date: Tue, 15 Nov 2022 08:42:46 +0100 Subject: [PATCH 07/10] add bench for naming serialization --- .../JsonContextNamingSerializationBench.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 tests/Benchmark/JsonContextNamingSerializationBench.php diff --git a/tests/Benchmark/JsonContextNamingSerializationBench.php b/tests/Benchmark/JsonContextNamingSerializationBench.php new file mode 100644 index 000000000..00ef9219a --- /dev/null +++ b/tests/Benchmark/JsonContextNamingSerializationBench.php @@ -0,0 +1,16 @@ +setPropertyNamingStrategy(new IdenticalPropertyNamingStrategy()); + } +} From 6f29e4259b1e8a676e67806acf3414b84b9099fa Mon Sep 17 00:00:00 2001 From: Dariusz Gafka Date: Tue, 26 Dec 2023 15:01:26 +0100 Subject: [PATCH 08/10] phpcs --- src/Context.php | 1 - tests/SerializerBuilderTest.php | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Context.php b/src/Context.php index 00c9821e9..4408ef4a1 100644 --- a/src/Context.php +++ b/src/Context.php @@ -14,7 +14,6 @@ use JMS\Serializer\Metadata\ClassMetadata; use JMS\Serializer\Metadata\PropertyMetadata; use JMS\Serializer\Naming\PropertyNamingStrategyInterface; -use Metadata\MetadataFactory; use Metadata\MetadataFactoryInterface; abstract class Context diff --git a/tests/SerializerBuilderTest.php b/tests/SerializerBuilderTest.php index 3d5689d4a..7b5a562bf 100644 --- a/tests/SerializerBuilderTest.php +++ b/tests/SerializerBuilderTest.php @@ -251,13 +251,13 @@ public function testUsingSerializedNameStrategyInContext() self::assertEquals($jsonWithUnderscores, $serializer->serialize( $object, 'json', - SerializationContext::create()->setPropertyNamingStrategy(new SerializedNameAnnotationStrategy(new IdenticalPropertyNamingStrategy())) + SerializationContext::create()->setPropertyNamingStrategy(new SerializedNameAnnotationStrategy(new IdenticalPropertyNamingStrategy())), )); self::assertEquals($object, $serializer->deserialize( $jsonWithUnderscores, get_class($object), 'json', - DeserializationContext::create()->setPropertyNamingStrategy(new SerializedNameAnnotationStrategy(new IdenticalPropertyNamingStrategy())) + DeserializationContext::create()->setPropertyNamingStrategy(new SerializedNameAnnotationStrategy(new IdenticalPropertyNamingStrategy())), )); } From 380f5294302534073db046e4383ef22212ed59bc Mon Sep 17 00:00:00 2001 From: Dariusz Gafka Date: Tue, 26 Dec 2023 15:04:04 +0100 Subject: [PATCH 09/10] phpcs --- src/Metadata/Driver/AnnotationOrAttributeDriver.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/Metadata/Driver/AnnotationOrAttributeDriver.php b/src/Metadata/Driver/AnnotationOrAttributeDriver.php index 8e1b52343..3642b973a 100644 --- a/src/Metadata/Driver/AnnotationOrAttributeDriver.php +++ b/src/Metadata/Driver/AnnotationOrAttributeDriver.php @@ -290,11 +290,6 @@ public function loadMetadataForClass(\ReflectionClass $class): ?BaseClassMetadat } } - if (!$configured) { - // return null; - // uncomment the above line afetr a couple of months - } - return $classMetadata; } From 8247a39a526a9e892430752fe6248d6a0da4eca3 Mon Sep 17 00:00:00 2001 From: Dariusz Gafka Date: Tue, 26 Dec 2023 15:09:28 +0100 Subject: [PATCH 10/10] phpstan --- tests/Benchmark/JsonContextNamingSerializationBench.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/Benchmark/JsonContextNamingSerializationBench.php b/tests/Benchmark/JsonContextNamingSerializationBench.php index 00ef9219a..1229e8fe6 100644 --- a/tests/Benchmark/JsonContextNamingSerializationBench.php +++ b/tests/Benchmark/JsonContextNamingSerializationBench.php @@ -6,11 +6,13 @@ use JMS\Serializer\Naming\IdenticalPropertyNamingStrategy; use JMS\Serializer\SerializationContext; +use JMS\Serializer\Tests\Benchmark\Performance\JsonSerializationBench; class JsonContextNamingSerializationBench extends JsonSerializationBench { protected function createContext(): SerializationContext { + /** @phpstan-ignore-next-line */ return parent::createContext()->setPropertyNamingStrategy(new IdenticalPropertyNamingStrategy()); } }