diff --git a/composer.json b/composer.json index 112705dd2..a91b9d46e 100644 --- a/composer.json +++ b/composer.json @@ -20,7 +20,8 @@ "jms/metadata": "~1.1", "doctrine/annotations": "^1.0", "doctrine/instantiator": "^1.0.3", - "hoa/compiler": "^3.17.08.08" + "hoa/compiler": "^3.17.08.08", + "ocramius/generated-hydrator": "^2.2" }, "suggest": { "symfony/yaml": "Required if you'd like to use the YAML metadata format.", diff --git a/src/Accessor/AccessorStrategyInterface.php b/src/Accessor/AccessorStrategyInterface.php index 2225f8063..0bab2a6fb 100644 --- a/src/Accessor/AccessorStrategyInterface.php +++ b/src/Accessor/AccessorStrategyInterface.php @@ -32,7 +32,7 @@ interface AccessorStrategyInterface * @param PropertyMetadata $metadata * @return mixed */ - public function getValue(object $object, PropertyMetadata $metadata); + public function getValue(object $object, PropertyMetadata $metadata, $context); /** * @param object $object diff --git a/src/Accessor/DefaultAccessorStrategy.php b/src/Accessor/DefaultAccessorStrategy.php index a23f2239e..a362c8c95 100644 --- a/src/Accessor/DefaultAccessorStrategy.php +++ b/src/Accessor/DefaultAccessorStrategy.php @@ -20,6 +20,8 @@ namespace JMS\Serializer\Accessor; +use GeneratedHydrator\Configuration; +use JMS\Serializer\Metadata\ClassMetadata; use JMS\Serializer\Metadata\PropertyMetadata; /** @@ -27,9 +29,15 @@ */ final class DefaultAccessorStrategy implements AccessorStrategyInterface { + private $gen = array(); - public function getValue(object $object, PropertyMetadata $metadata) + public function getValue(object $object, PropertyMetadata $metadata, $context) { + + if (!$metadata->getter && array_key_exists($metadata->name, $context)) { + return $context[$metadata->name]; + } + return $metadata->getValue($object); } @@ -37,4 +45,22 @@ public function setValue(object $object, $value, PropertyMetadata $metadata): vo { $metadata->setValue($object, $value); } + + public function startAccessing(object $object, ClassMetadata $metadata) + { + $class = get_class($object); + + if (!isset($this->gen[$class])) { + $config = new Configuration($class); + $hydratorClass = $config->createFactory()->getHydratorClass(); + $this->gen[$class] = new $hydratorClass(); + } + + return $this->gen[$class]->extract($object); + } + + public function endAccessing(object $object, ClassMetadata $metadata, $context) + { + + } } diff --git a/src/Accessor/ExpressionAccessorStrategy.php b/src/Accessor/ExpressionAccessorStrategy.php index ec9dd00ab..5ad7cc345 100644 --- a/src/Accessor/ExpressionAccessorStrategy.php +++ b/src/Accessor/ExpressionAccessorStrategy.php @@ -44,7 +44,7 @@ public function __construct(ExpressionEvaluatorInterface $evaluator, AccessorStr $this->evaluator = $evaluator; } - public function getValue(object $object, PropertyMetadata $metadata) + public function getValue(object $object, PropertyMetadata $metadata, $context) { if ($metadata instanceof ExpressionPropertyMetadata) { return $this->evaluator->evaluate($metadata->expression, ['object' => $object]); diff --git a/src/GraphNavigator/SerializationGraphNavigator.php b/src/GraphNavigator/SerializationGraphNavigator.php index 122cfc148..d1d231a8e 100644 --- a/src/GraphNavigator/SerializationGraphNavigator.php +++ b/src/GraphNavigator/SerializationGraphNavigator.php @@ -222,6 +222,9 @@ public function accept($data, array $type = null) } $this->visitor->startVisitingObject($metadata, $data, $type); + + $context = $this->accessor->startAccessing($data, $metadata); + foreach ($metadata->propertyMetadata as $propertyMetadata) { if ($this->exclusionStrategy->shouldSkipProperty($propertyMetadata, $this->context)) { continue; @@ -231,7 +234,7 @@ public function accept($data, array $type = null) continue; } - $v = $this->accessor->getValue($data, $propertyMetadata); + $v = $this->accessor->getValue($data, $propertyMetadata, $context); if (null === $v && $this->shouldSerializeNull !== true) { continue; @@ -242,6 +245,8 @@ public function accept($data, array $type = null) $this->context->popPropertyMetadata(); } + $this->accessor->endAccessing($data, $metadata, $context); + $this->afterVisitingObject($metadata, $data, $type); return $this->visitor->endVisitingObject($metadata, $data, $type);