Преглед изворни кода

add nullable option for json visitor

mattw пре 12 година
родитељ
комит
8cb1e3cf54

+ 1 - 0
DependencyInjection/Configuration.php

@@ -115,6 +115,7 @@ class Configuration implements ConfigurationInterface
                     ->arrayNode('json')
                         ->addDefaultsIfNotSet()
                         ->children()
+                            ->booleanNode('serialize_null')->defaultFalse()->end()
                             ->scalarNode('options')
                                 ->defaultValue(0)
                                 ->beforeNormalization()

+ 4 - 0
DependencyInjection/JMSSerializerExtension.php

@@ -149,6 +149,10 @@ class JMSSerializerExtension extends ConfigurableExtension
         $container
             ->setParameter('jms_serializer.json_serialization_visitor.options', $config['visitors']['json']['options'])
         ;
+
+        $container
+            ->setParameter('jms_serializer.json_serialization_visitor.serialize_null', $config['visitors']['json']['serialize_null'])
+        ;
     }
 
     public function getConfiguration(array $config, ContainerBuilder $container)

+ 3 - 0
Resources/config/services.xml

@@ -131,6 +131,9 @@
             <call method="setOptions">
                 <argument>%jms_serializer.json_serialization_visitor.options%</argument>
             </call>
+            <call method="setNullable">
+                <argument>%jms_serializer.json_serialization_visitor.serialize_null%</argument>
+            </call>
             <tag name="jms_serializer.serialization_visitor" format="json" />
         </service>
         <service id="jms_serializer.json_deserialization_visitor" class="%jms_serializer.json_deserialization_visitor.class%" public="false">

+ 2 - 2
Serializer/GenericSerializationVisitor.php

@@ -90,7 +90,7 @@ abstract class GenericSerializationVisitor extends AbstractSerializationVisitor
         foreach ($data as $k => $v) {
             $v = $this->navigator->accept($v, null, $this);
 
-            if (null === $v) {
+            if (null === $v && (!is_string($k) || !$this->isNullable())) {
                 continue;
             }
 
@@ -133,7 +133,7 @@ abstract class GenericSerializationVisitor extends AbstractSerializationVisitor
                 : $data->{$metadata->getter}());
 
         $v = $this->navigator->accept($v, null, $this);
-        if (null === $v) {
+        if (null === $v && !$this->isNullable()) {
             return;
         }
 

+ 11 - 0
Serializer/JsonSerializationVisitor.php

@@ -21,6 +21,7 @@ namespace JMS\SerializerBundle\Serializer;
 class JsonSerializationVisitor extends GenericSerializationVisitor
 {
     private $options = 0;
+    private $nullable = false;
 
     public function getResult()
     {
@@ -36,4 +37,14 @@ class JsonSerializationVisitor extends GenericSerializationVisitor
     {
         $this->options = (integer) $options;
     }
+
+    public function setNullable($allowNull)
+    {
+        $this->nullable = (bool) $allowNull;
+    }
+
+    public function isNullable()
+    {
+        return (bool) $this->nullable;
+    }
 }

+ 10 - 0
Tests/Fixtures/ObjectWithNullProperty.php

@@ -0,0 +1,10 @@
+<?php
+
+namespace JMS\SerializerBundle\Tests\Fixtures;
+
+use JMS\SerializerBundle\Tests\Fixtures\SimpleObject;
+
+class ObjectWithNullProperty extends SimpleObject
+{
+    private $nullProperty = null;
+}

+ 25 - 1
Tests/Serializer/BaseSerializationTest.php

@@ -60,6 +60,7 @@ use JMS\SerializerBundle\Tests\Fixtures\ObjectWithVirtualProperties;
 use JMS\SerializerBundle\Tests\Fixtures\Order;
 use JMS\SerializerBundle\Tests\Fixtures\Price;
 use JMS\SerializerBundle\Tests\Fixtures\SimpleObject;
+use JMS\SerializerBundle\Tests\Fixtures\ObjectWithNullProperty;
 use JMS\SerializerBundle\Tests\Fixtures\SimpleObjectProxy;
 use Metadata\MetadataFactory;
 use Symfony\Component\Form\Form;
@@ -70,6 +71,24 @@ use Symfony\Component\Yaml\Inline;
 
 abstract class BaseSerializationTest extends \PHPUnit_Framework_TestCase
 {
+    public function testNullableArray()
+    {
+        if ($this->getFormat() !== 'json') {
+            $this->markTestSkipped('nullable currently only supported by JSON');
+        }
+        $arr = array('foo' => 'bar', 'baz' => null, null);
+        $this->assertEquals($this->getContent('nullable'), $this->getSerializer(true)->serialize($arr, $this->getFormat()));
+    }
+
+    public function testNullableObject()
+    {
+        if ($this->getFormat() !== 'json') {
+            $this->markTestSkipped('nullable currently only supported by JSON');
+        }
+        $obj = new ObjectWithNullProperty('foo', 'bar');
+        $this->assertEquals($this->getContent('simple_object_nullable'), $this->getSerializer(true)->serialize($obj, $this->getFormat()));
+    }
+
     public function testString()
     {
         $this->assertEquals($this->getContent('string'), $this->serialize('foo'));
@@ -476,7 +495,7 @@ abstract class BaseSerializationTest extends \PHPUnit_Framework_TestCase
         return $this->getSerializer()->deserialize($content, $type, $this->getFormat());
     }
 
-    protected function getSerializer()
+    protected function getSerializer($serialize_null = false)
     {
         $factory = new MetadataFactory(new AnnotationDriver(new AnnotationReader()));
         $namingStrategy = new SerializedNameAnnotationStrategy(new CamelCaseNamingStrategy());
@@ -490,6 +509,11 @@ abstract class BaseSerializationTest extends \PHPUnit_Framework_TestCase
             'xml'  => new XmlSerializationVisitor($namingStrategy, $customSerializationHandlers),
             'yml'  => new YamlSerializationVisitor($namingStrategy, $customSerializationHandlers),
         );
+
+        if ($serialize_null) {
+            $serializationVisitors['json']->setNullable(true);
+        }
+
         $deserializationVisitors = array(
             'json' => new JsonDeserializationVisitor($namingStrategy, $customDeserializationHandlers, $objectConstructor),
             'xml'  => new XmlDeserializationVisitor($namingStrategy, $customDeserializationHandlers, $objectConstructor),

+ 2 - 0
Tests/Serializer/JsonSerializationTest.php

@@ -68,6 +68,8 @@ class JsonSerializationTest extends BaseSerializationTest
             $outputs['virtual_properties_low'] = '{"low":1}';
             $outputs['virtual_properties_high'] = '{"high":8}';
             $outputs['virtual_properties_all'] = '{"low":1,"high":8}';
+            $outputs['nullable'] = '{"foo":"bar","baz":null}';
+            $outputs['simple_object_nullable'] = '{"foo":"foo","moo":"bar","camel_case":"boo","null_property":null}';
         }
 
         if (!isset($outputs[$key])) {