Browse Source

Merge pull request #187 from Seldaek/exclusion-strat

Pass object to each exclusion strategy class
Johannes 12 years ago
parent
commit
b6a247fd90

+ 6 - 3
Serializer/Exclusion/ExclusionStrategyInterface.php

@@ -32,16 +32,19 @@ interface ExclusionStrategyInterface
      * Whether the class should be skipped.
      *
      * @param ClassMetadata $metadata
+     * @param object        $object instance, provided during serialization but not deserialization
+     *
      * @return boolean
      */
-    function shouldSkipClass(ClassMetadata $metadata);
+    function shouldSkipClass(ClassMetadata $metadata, $object = null);
 
     /**
      * Whether the property should be skipped.
      *
      * @param PropertyMetadata $property
+     * @param object           $object instance, provided during serialization but not deserialization
      *
      * @return boolean
      */
-    function shouldSkipProperty(PropertyMetadata $property);
-}
+    function shouldSkipProperty(PropertyMetadata $property, $object = null);
+}

+ 2 - 2
Serializer/Exclusion/GroupsExclusionStrategy.php

@@ -37,7 +37,7 @@ class GroupsExclusionStrategy implements ExclusionStrategyInterface
         }
     }
 
-    public function shouldSkipClass(ClassMetadata $metadata)
+    public function shouldSkipClass(ClassMetadata $metadata, $object = null)
     {
         return false;
     }
@@ -45,7 +45,7 @@ class GroupsExclusionStrategy implements ExclusionStrategyInterface
     /**
      * {@inheritDoc}
      */
-    public function shouldSkipProperty(PropertyMetadata $property)
+    public function shouldSkipProperty(PropertyMetadata $property, $object = null)
     {
         if (!$property->groups) {
             return true;

+ 3 - 3
Serializer/Exclusion/VersionExclusionStrategy.php

@@ -30,7 +30,7 @@ class VersionExclusionStrategy implements ExclusionStrategyInterface
         $this->version = $version;
     }
 
-    public function shouldSkipClass(ClassMetadata $metadata)
+    public function shouldSkipClass(ClassMetadata $metadata, $object = null)
     {
         return false;
     }
@@ -38,7 +38,7 @@ class VersionExclusionStrategy implements ExclusionStrategyInterface
     /**
      * {@inheritDoc}
      */
-    public function shouldSkipProperty(PropertyMetadata $property)
+    public function shouldSkipProperty(PropertyMetadata $property, $object = null)
     {
         if ((null !== $version = $property->sinceVersion) && version_compare($this->version, $version, '<')) {
             return true;
@@ -50,4 +50,4 @@ class VersionExclusionStrategy implements ExclusionStrategyInterface
 
         return false;
     }
-}
+}

+ 2 - 2
Serializer/GraphNavigator.php

@@ -97,7 +97,7 @@ final class GraphNavigator
             }
 
             $metadata = $this->metadataFactory->getMetadataForClass($type);
-            if (null !== $this->exclusionStrategy && $this->exclusionStrategy->shouldSkipClass($metadata)) {
+            if (null !== $this->exclusionStrategy && $this->exclusionStrategy->shouldSkipClass($metadata, self::DIRECTION_SERIALIZATION === $this->direction ? $data : null)) {
                 if (self::DIRECTION_SERIALIZATION === $this->direction) {
                     $this->visiting->detach($data);
                 }
@@ -122,7 +122,7 @@ final class GraphNavigator
 
             $visitor->startVisitingObject($metadata, $data, $type);
             foreach ($metadata->propertyMetadata as $propertyMetadata) {
-                if (null !== $this->exclusionStrategy && $this->exclusionStrategy->shouldSkipProperty($propertyMetadata)) {
+                if (null !== $this->exclusionStrategy && $this->exclusionStrategy->shouldSkipProperty($propertyMetadata, self::DIRECTION_SERIALIZATION === $this->direction ? $data : null)) {
                     continue;
                 }
 

+ 1 - 1
Serializer/XmlDeserializationVisitor.php

@@ -68,7 +68,7 @@ class XmlDeserializationVisitor extends AbstractDeserializationVisitor
         $dom->loadXML($data);
         foreach ($dom->childNodes as $child) {
             if ($child->nodeType === XML_DOCUMENT_TYPE_NODE) {
-                $internalSubset = str_replace(PHP_EOL, '', $child->internalSubset);
+                $internalSubset = str_replace(array("\n", "\r"), '', $child->internalSubset);
                 if (!in_array($internalSubset, $this->doctypeWhitelist, true)) {
                     throw new \InvalidArgumentException(sprintf(
                         'The document type "%s" is not allowed. If it is safe, you may add it to the whitelist configuration.',

+ 41 - 1
Tests/Serializer/GraphNavigatorTest.php

@@ -5,7 +5,7 @@ namespace JMS\SerializerBundle\Tests\Serializer;
 use Doctrine\Common\Annotations\AnnotationReader;
 use JMS\SerializerBundle\Metadata\Driver\AnnotationDriver;
 use JMS\SerializerBundle\Serializer\GraphNavigator;
-use Metadata\MetadataFactory;
+use Metadata\MetadataFactory;
 
 class GraphNavigatorTest extends \PHPUnit_Framework_TestCase
 {
@@ -22,6 +22,41 @@ class GraphNavigatorTest extends \PHPUnit_Framework_TestCase
         $this->navigator->accept(STDIN, null, $this->visitor);
     }
 
+    public function testNavigatorPassesInstanceOnSerialization()
+    {
+        $object = new SerializableClass;
+        $metadata = $this->metadataFactory->getMetadataForClass(get_class($object));
+
+        $exclusionStrategy = $this->getMock('JMS\SerializerBundle\Serializer\Exclusion\ExclusionStrategyInterface');
+        $exclusionStrategy->expects($this->once())
+            ->method('shouldSkipClass')
+            ->with($metadata, $object);
+        $exclusionStrategy->expects($this->once())
+            ->method('shouldSkipProperty')
+            ->with($metadata->propertyMetadata['foo'], $object);
+
+        $this->navigator = new GraphNavigator(GraphNavigator::DIRECTION_SERIALIZATION, $this->metadataFactory, $exclusionStrategy);
+        $this->navigator->accept($object, null, $this->visitor);
+    }
+
+    public function testNavigatorPassesNullOnDeserialization()
+    {
+        $class = __NAMESPACE__.'\SerializableClass';
+        $metadata = $this->metadataFactory->getMetadataForClass($class);
+
+        $exclusionStrategy = $this->getMock('JMS\SerializerBundle\Serializer\Exclusion\ExclusionStrategyInterface');
+        $exclusionStrategy->expects($this->once())
+            ->method('shouldSkipClass')
+            ->with($metadata, null);
+
+        $exclusionStrategy->expects($this->once())
+            ->method('shouldSkipProperty')
+            ->with($metadata->propertyMetadata['foo'], null);
+
+        $this->navigator = new GraphNavigator(GraphNavigator::DIRECTION_DESERIALIZATION, $this->metadataFactory, $exclusionStrategy);
+        $this->navigator->accept('random', $class, $this->visitor);
+    }
+
     protected function setUp()
     {
         $this->visitor = $this->getMock('JMS\SerializerBundle\Serializer\VisitorInterface');
@@ -30,3 +65,8 @@ class GraphNavigatorTest extends \PHPUnit_Framework_TestCase
         $this->navigator = new GraphNavigator(GraphNavigator::DIRECTION_SERIALIZATION, $this->metadataFactory);
     }
 }
+
+class SerializableClass
+{
+    public $foo = 'bar';
+}