diff --git a/src/JMS/Serializer/GenericSerializationVisitor.php b/src/JMS/Serializer/GenericSerializationVisitor.php index a704d23bc..4999a1129 100644 --- a/src/JMS/Serializer/GenericSerializationVisitor.php +++ b/src/JMS/Serializer/GenericSerializationVisitor.php @@ -24,13 +24,27 @@ abstract class GenericSerializationVisitor extends AbstractVisitor { + private $navigatorStack; private $navigator; + private $rootStack; private $root; + private $dataStackStack; private $dataStack; private $data; + public function __construct($namingStrategy) + { + parent::__construct($namingStrategy); + $this->navigatorStack = new \SplStack; + $this->dataStackStack = new \SplStack; + $this->rootStack = new \SplStack; + } + public function setNavigator(GraphNavigator $navigator) { + $this->navigatorStack->push($this->navigator); + $this->dataStackStack->push($this->dataStack); + $this->rootStack->push($this->root); $this->navigator = $navigator; $this->root = null; $this->dataStack = new \SplStack; @@ -44,6 +58,13 @@ public function getNavigator() return $this->navigator; } + public function endNavigator() + { + $this->navigator = $this->navigatorStack->pop(); + $this->dataStack = $this->dataStackStack->pop(); + $this->root = $this->rootStack->pop(); + } + public function visitNull($data, array $type, Context $context) { return null; @@ -169,6 +190,56 @@ public function addData($key, $value) $this->data[$key] = $value; } + + /** + * Allows you to remove data from the current object based on name. + * + * @param string $key + * @throws Exception\InvalidArgumentException + */ + public function removeDataPropertyName($propertyName) + { + $std = new \stdClass(); + $std->temp = 'temp'; + + $propMetadata = new PropertyMetadata($std, "temp"); + $propMetadata->name = $propertyName; + $key = $this->namingStrategy->translateName($propMetadata); + + if (!array_key_exists($key, $this->data)) { + throw new InvalidArgumentException(sprintf('There is no data for "%s".', $key)); + } + + unset($propMetadata); + unset($std); + unset($this->data[$key]); + } + + /** + * Allows you to remove data from the current object/root element. + * + * @param string $key + * @throws Exception\InvalidArgumentException + */ + public function removeData($key) + { + if (!array_key_exists($key, $this->data)) { + throw new InvalidArgumentException(sprintf('There is no data for "%s".', $key)); + } + + unset($this->data[$key]); + } + + /** + * Returns the current object + * + * @return mixed + */ + public function getData() + { + return $this->data; + } + public function getRoot() { return $this->root; diff --git a/src/JMS/Serializer/Serializer.php b/src/JMS/Serializer/Serializer.php index 70ea85c8a..f4b992ae7 100644 --- a/src/JMS/Serializer/Serializer.php +++ b/src/JMS/Serializer/Serializer.php @@ -80,8 +80,10 @@ public function serialize($data, $format, SerializationContext $context = null) return $this->serializationVisitors->get($format) ->map(function(VisitorInterface $visitor) use ($context, $data, $format) { $this->visit($visitor, $context, $visitor->prepare($data), $format); + $result = $visitor->getResult(); + $visitor->endNavigator(); - return $visitor->getResult(); + return $result; }) ->getOrThrow(new UnsupportedFormatException(sprintf('The format "%s" is not supported for serialization.', $format))) ; diff --git a/src/JMS/Serializer/XmlSerializationVisitor.php b/src/JMS/Serializer/XmlSerializationVisitor.php index 6a4850fff..28a0669b3 100644 --- a/src/JMS/Serializer/XmlSerializationVisitor.php +++ b/src/JMS/Serializer/XmlSerializationVisitor.php @@ -31,18 +31,31 @@ class XmlSerializationVisitor extends AbstractVisitor { public $document; + private $documentStack; private $navigator; + private $navigatorStack; private $defaultRootName = 'result'; private $defaultRootNamespace; private $defaultVersion = '1.0'; private $defaultEncoding = 'UTF-8'; private $stack; + private $stackStack; private $metadataStack; + private $metadataStackStack; private $currentNode; private $currentMetadata; private $hasValue; private $nullWasVisited; + public function __construct($namingStrategy) + { + parent::__construct($namingStrategy); + $this->navigatorStack = new \SplStack; + $this->documentStack = new \SplStack; + $this->stackStack = new \SplStack; + $this->metadataStackStack = new \SplStack; + } + public function setDefaultRootName($name, $namespace = null) { $this->defaultRootName = $name; @@ -69,6 +82,10 @@ public function setDefaultEncoding($encoding) public function setNavigator(GraphNavigator $navigator) { + $this->navigatorStack->push($this->navigator); + $this->documentStack->push($this->document); + $this->stackStack->push($this->stack); + $this->metadataStackStack->push($this->metadataStack); $this->navigator = $navigator; $this->document = null; $this->stack = new \SplStack; @@ -80,6 +97,14 @@ public function getNavigator() return $this->navigator; } + public function endNavigator() + { + $this->navigator = $this->navigatorStack->pop(); + $this->document = $this->documentStack->pop(); + $this->stack = $this->stackStack->pop(); + $this->metadataStack = $this->metadataStackStack->pop(); + } + public function visitNull($data, array $type, Context $context) { if (null === $this->document) { diff --git a/src/JMS/Serializer/YamlSerializationVisitor.php b/src/JMS/Serializer/YamlSerializationVisitor.php index 933aa9f80..d5d711e79 100644 --- a/src/JMS/Serializer/YamlSerializationVisitor.php +++ b/src/JMS/Serializer/YamlSerializationVisitor.php @@ -35,8 +35,11 @@ class YamlSerializationVisitor extends AbstractVisitor public $writer; private $navigator; + private $navigatorStack; private $stack; + private $stackStack; private $metadataStack; + private $metadataStackStack; private $currentMetadata; public function __construct(PropertyNamingStrategyInterface $namingStrategy) @@ -44,6 +47,10 @@ public function __construct(PropertyNamingStrategyInterface $namingStrategy) parent::__construct($namingStrategy); $this->writer = new Writer(); + + $this->navigatorStack = new \SplStack; + $this->stackStack = new \SplStack; + $this->metadataStackStack = new \SplStack; } public function setNavigator(GraphNavigator $navigator) @@ -52,6 +59,16 @@ public function setNavigator(GraphNavigator $navigator) $this->writer->reset(); $this->stack = new \SplStack; $this->metadataStack = new \SplStack; + $this->navigatorStack->push($this->navigator); + $this->stackStack->push($this->stack); + $this->metadataStackStack->push($this->metadataStack); + } + + public function endNavigator() + { + $this->navigator = $this->navigatorStack->pop(); + $this->stack = $this->stackStack->pop(); + $this->metadataStack = $this->metadataStackStack->pop(); } public function visitNull($data, array $type, Context $context)