feature #28661 [Serializer] Add an option to skip null values (dunglas)

This PR was squashed before being merged into the 4.2-dev branch (closes #28661).

Discussion
----------

[Serializer] Add an option to skip null values

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      |no
| New feature?  | yes <!-- don't forget to update src/**/CHANGELOG.md files -->
| BC breaks?    | no     <!-- see https://symfony.com/bc -->
| Deprecations? | no <!-- don't forget to update UPGRADE-*.md and src/**/CHANGELOG.md files -->
| Tests pass?   | yes    <!-- please add some, will be required by reviewers -->
| Fixed tickets | n/a   <!-- #-prefixed issue number(s), if any -->
| License       | MIT
| Doc PR        | todo

Adds a new option to not serialize `null` values:

```php
$dummy = new class {
    public $foo;
    public $bar = 'notNull';
};

$normalizer = new ObjectNormalizer();
$result = $normalizer->normalize($dummy, 'json', ['skip_null_values' => true]);
// ['bar' => 'notNull']
```

This feature is the only missing part to add [JSON Merge Patch](https://tools.ietf.org/html/rfc7386) support in [API Platform](https://api-platform.com).
It will also help supporting this RFC in all other projects using the Symfony Serializer.

Commits
-------

d3c5055f7b [Serializer] Add an option to skip null values
This commit is contained in:
Nicolas Grekas 2018-10-02 17:09:27 +02:00
commit c31c40d83e
3 changed files with 16 additions and 0 deletions

View File

@ -4,6 +4,7 @@ CHANGELOG
4.2.0
-----
* added a `skip_null_values` context option to not serialize properties with a `null` values
* `AbstractNormalizer::handleCircularReference` is now final and receives
two optional extra arguments: the format and the context
* added support for XML comment encoding (encoding `['#comment' => ' foo ']` results `<!-- foo -->`)

View File

@ -35,6 +35,7 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
const ENABLE_MAX_DEPTH = 'enable_max_depth';
const DEPTH_KEY_PATTERN = 'depth_%s::%s';
const DISABLE_TYPE_ENFORCEMENT = 'disable_type_enforcement';
const SKIP_NULL_VALUES = 'skip_null_values';
private $propertyTypeExtractor;
private $typesCache = array();
@ -402,6 +403,10 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
*/
private function updateData(array $data, string $attribute, $attributeValue, string $class, ?string $format, array $context): array
{
if (null === $attributeValue && ($context[self::SKIP_NULL_VALUES] ?? false)) {
return $data;
}
if ($this->nameConverter) {
$attribute = $this->nameConverter->normalize($attribute, $class, $format, $context);
}

View File

@ -161,6 +161,16 @@ class AbstractObjectNormalizerTest extends TestCase
'allow_extra_attributes' => false,
));
}
public function testSkipNullValues()
{
$dummy = new Dummy();
$dummy->bar = 'present';
$normalizer = new ObjectNormalizer();
$result = $normalizer->normalize($dummy, null, array(AbstractObjectNormalizer::SKIP_NULL_VALUES => true));
$this->assertSame(array('bar' => 'present'), $result);
}
}
class AbstractObjectNormalizerDummy extends AbstractObjectNormalizer