From dd35808c87609710a64cc94948fb0879dad1e14b Mon Sep 17 00:00:00 2001 From: Asmir Mustafic Date: Thu, 7 Jun 2018 10:00:30 +0200 Subject: [PATCH 1/3] make access strategies aware of the context --- src/Accessor/AccessorStrategyInterface.php | 6 ++++-- src/Accessor/DefaultAccessorStrategy.php | 8 +++++--- src/GraphNavigator/DeserializationGraphNavigator.php | 2 +- src/GraphNavigator/SerializationGraphNavigator.php | 2 +- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/Accessor/AccessorStrategyInterface.php b/src/Accessor/AccessorStrategyInterface.php index 8f77af0f4..f53264258 100644 --- a/src/Accessor/AccessorStrategyInterface.php +++ b/src/Accessor/AccessorStrategyInterface.php @@ -4,7 +4,9 @@ namespace JMS\Serializer\Accessor; +use JMS\Serializer\DeserializationContext; use JMS\Serializer\Metadata\PropertyMetadata; +use JMS\Serializer\SerializationContext; /** * @author Asmir Mustafic @@ -16,7 +18,7 @@ interface AccessorStrategyInterface * @param PropertyMetadata $metadata * @return mixed */ - public function getValue(object $object, PropertyMetadata $metadata); + public function getValue(object $object, PropertyMetadata $metadata, SerializationContext $context); /** * @param object $object @@ -24,5 +26,5 @@ public function getValue(object $object, PropertyMetadata $metadata); * @param PropertyMetadata $metadata * @return void */ - public function setValue(object $object, $value, PropertyMetadata $metadata): void; + public function setValue(object $object, $value, PropertyMetadata $metadata, DeserializationContext $context): void; } diff --git a/src/Accessor/DefaultAccessorStrategy.php b/src/Accessor/DefaultAccessorStrategy.php index 805cdba6d..776f17e54 100644 --- a/src/Accessor/DefaultAccessorStrategy.php +++ b/src/Accessor/DefaultAccessorStrategy.php @@ -4,12 +4,14 @@ namespace JMS\Serializer\Accessor; +use JMS\Serializer\DeserializationContext; use JMS\Serializer\Exception\ExpressionLanguageRequiredException; use JMS\Serializer\Exception\LogicException; use JMS\Serializer\Expression\ExpressionEvaluatorInterface; use JMS\Serializer\Metadata\ExpressionPropertyMetadata; use JMS\Serializer\Metadata\PropertyMetadata; use JMS\Serializer\Metadata\StaticPropertyMetadata; +use JMS\Serializer\SerializationContext; /** * @author Asmir Mustafic @@ -30,7 +32,7 @@ public function __construct(ExpressionEvaluatorInterface $evaluator = null) $this->evaluator = $evaluator; } - public function getValue(object $object, PropertyMetadata $metadata) + public function getValue(object $object, PropertyMetadata $metadata, SerializationContext $context) { if ($metadata instanceof StaticPropertyMetadata) { return $metadata->getValue(null); @@ -41,7 +43,7 @@ public function getValue(object $object, PropertyMetadata $metadata) throw new ExpressionLanguageRequiredException(sprintf('The property %s on %s requires the expression accessor strategy to be enabled.', $metadata->name, $metadata->class)); } - return $this->evaluator->evaluate($metadata->expression, ['object' => $object]); + return $this->evaluator->evaluate($metadata->expression, ['object' => $object, 'context' => $context]); } if (null === $metadata->getter) { @@ -71,7 +73,7 @@ public function getValue(object $object, PropertyMetadata $metadata) return $object->{$metadata->getter}(); } - public function setValue(object $object, $value, PropertyMetadata $metadata): void + public function setValue(object $object, $value, PropertyMetadata $metadata, DeserializationContext $context): void { if ($metadata->readOnly) { throw new LogicException(sprintf('%s on %s is read only.', $metadata->name, $metadata->class)); diff --git a/src/GraphNavigator/DeserializationGraphNavigator.php b/src/GraphNavigator/DeserializationGraphNavigator.php index 39ee36bee..0150967e7 100644 --- a/src/GraphNavigator/DeserializationGraphNavigator.php +++ b/src/GraphNavigator/DeserializationGraphNavigator.php @@ -182,7 +182,7 @@ public function accept($data, array $type = null) $this->context->pushPropertyMetadata($propertyMetadata); try { $v = $this->visitor->visitProperty($propertyMetadata, $data); - $this->accessor->setValue($object, $v, $propertyMetadata); + $this->accessor->setValue($object, $v, $propertyMetadata, $this->context); } catch (NotAcceptableException $e) { } diff --git a/src/GraphNavigator/SerializationGraphNavigator.php b/src/GraphNavigator/SerializationGraphNavigator.php index bc7f22124..47765e59e 100644 --- a/src/GraphNavigator/SerializationGraphNavigator.php +++ b/src/GraphNavigator/SerializationGraphNavigator.php @@ -215,7 +215,7 @@ public function accept($data, array $type = null) continue; } - $v = $this->accessor->getValue($data, $propertyMetadata); + $v = $this->accessor->getValue($data, $propertyMetadata, $this->context); if (null === $v && $this->shouldSerializeNull !== true) { continue; From 19f3ade85dbc49b76c5ad19d43b2a1a9abce4500 Mon Sep 17 00:00:00 2001 From: Asmir Mustafic Date: Fri, 8 Jun 2018 16:55:16 +0200 Subject: [PATCH 2/3] add property metadata in the expression variables --- src/Accessor/DefaultAccessorStrategy.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Accessor/DefaultAccessorStrategy.php b/src/Accessor/DefaultAccessorStrategy.php index 776f17e54..1ceccedba 100644 --- a/src/Accessor/DefaultAccessorStrategy.php +++ b/src/Accessor/DefaultAccessorStrategy.php @@ -42,8 +42,7 @@ public function getValue(object $object, PropertyMetadata $metadata, Serializati if ($this->evaluator === null) { throw new ExpressionLanguageRequiredException(sprintf('The property %s on %s requires the expression accessor strategy to be enabled.', $metadata->name, $metadata->class)); } - - return $this->evaluator->evaluate($metadata->expression, ['object' => $object, 'context' => $context]); + return $this->evaluator->evaluate($metadata->expression, ['object' => $object, 'context' => $context, 'property_metadata' => $metadata ]); } if (null === $metadata->getter) { From c1f9d139b7b74e36620bd585f0a7d1caa60cf4d8 Mon Sep 17 00:00:00 2001 From: Asmir Mustafic Date: Tue, 12 Jun 2018 22:27:22 +0200 Subject: [PATCH 3/3] test context vars in prop accessor --- .../AuthorExpressionAccessContext.php | 30 +++++++++++++++++++ tests/Serializer/BaseSerializationTest.php | 14 +++++++++ tests/Serializer/JsonSerializationTest.php | 1 + .../xml/author_expression_context.xml | 6 ++++ 4 files changed, 51 insertions(+) create mode 100644 tests/Fixtures/AuthorExpressionAccessContext.php create mode 100644 tests/Serializer/xml/author_expression_context.xml diff --git a/tests/Fixtures/AuthorExpressionAccessContext.php b/tests/Fixtures/AuthorExpressionAccessContext.php new file mode 100644 index 000000000..73790cc3b --- /dev/null +++ b/tests/Fixtures/AuthorExpressionAccessContext.php @@ -0,0 +1,30 @@ +firstName = $firstName; + } + + public function getFirstName() + { + return $this->firstName; + } +} diff --git a/tests/Serializer/BaseSerializationTest.php b/tests/Serializer/BaseSerializationTest.php index 5f9df0712..f376e150c 100644 --- a/tests/Serializer/BaseSerializationTest.php +++ b/tests/Serializer/BaseSerializationTest.php @@ -30,6 +30,7 @@ use JMS\Serializer\Tests\Fixtures\Article; use JMS\Serializer\Tests\Fixtures\Author; use JMS\Serializer\Tests\Fixtures\AuthorExpressionAccess; +use JMS\Serializer\Tests\Fixtures\AuthorExpressionAccessContext; use JMS\Serializer\Tests\Fixtures\AuthorList; use JMS\Serializer\Tests\Fixtures\AuthorReadOnly; use JMS\Serializer\Tests\Fixtures\AuthorReadOnlyPerClass; @@ -741,6 +742,19 @@ public function testExpressionAuthor() self::assertEquals($this->getContent('author_expression'), $serializer->serialize($author, $this->getFormat())); } + public function testExpressionAuthorWithContextVars() + { + $evaluator = new ExpressionEvaluator(new ExpressionLanguage()); + + $builder = SerializerBuilder::create(); + $builder->setExpressionEvaluator($evaluator); + $serializer = $builder->build(); + + $author = new AuthorExpressionAccessContext("Ruud"); + self::assertEquals($this->getContent('author_expression_context'), $serializer->serialize($author, $this->getFormat())); + } + + /** * @expectedException \JMS\Serializer\Exception\ExpressionLanguageRequiredException * @expectedExceptionMessage The property firstName on JMS\Serializer\Tests\Fixtures\AuthorExpressionAccess requires the expression accessor strategy to be enabled. diff --git a/tests/Serializer/JsonSerializationTest.php b/tests/Serializer/JsonSerializationTest.php index fe1ac1827..8c93bad21 100644 --- a/tests/Serializer/JsonSerializationTest.php +++ b/tests/Serializer/JsonSerializationTest.php @@ -107,6 +107,7 @@ protected function getContent($key) $outputs['object_with_object_property_no_array_to_author'] = '{"foo": "bar", "author": "baz"}'; $outputs['object_with_object_property'] = '{"foo": "bar", "author": {"full_name": "baz"}}'; $outputs['author_expression'] = '{"my_first_name":"Ruud","last_name":"Kamphuis","id":123}'; + $outputs['author_expression_context'] = '{"first_name":"Ruud","direction":1,"name":"name"}'; $outputs['maxdepth_skippabe_object'] = '{"a":{"xxx":"yyy"}}'; $outputs['array_objects_nullable'] = '[]'; $outputs['type_casting'] = '{"as_string":"8"}'; diff --git a/tests/Serializer/xml/author_expression_context.xml b/tests/Serializer/xml/author_expression_context.xml new file mode 100644 index 000000000..5f7ae9b6b --- /dev/null +++ b/tests/Serializer/xml/author_expression_context.xml @@ -0,0 +1,6 @@ + + + + 1 + +