Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit a1c164d

Browse filesBrowse files
committed
[Serializer] Allow (de)normalization of empty objects in PropertyNormalizer and GetSetMethodNormalizer
1 parent a10071b commit a1c164d
Copy full SHA for a1c164d

File tree

4 files changed

+111
-0
lines changed
Filter options

4 files changed

+111
-0
lines changed

‎src/Symfony/Component/Serializer/Normalizer/GetSetMethodNormalizer.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Serializer/Normalizer/GetSetMethodNormalizer.php
+24Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@
1111

1212
namespace Symfony\Component\Serializer\Normalizer;
1313

14+
use Symfony\Component\PropertyInfo\PropertyTypeExtractorInterface;
15+
use Symfony\Component\Serializer\Mapping\ClassDiscriminatorResolverInterface;
16+
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface;
17+
use Symfony\Component\Serializer\NameConverter\NameConverterInterface;
18+
1419
/**
1520
* Converts between objects with getter and setter methods and arrays.
1621
*
@@ -36,6 +41,21 @@ class GetSetMethodNormalizer extends AbstractObjectNormalizer
3641
{
3742
private static $setterAccessibleCache = [];
3843

44+
private $allowNormalizationOfObjectsWithoutAnyGetters;
45+
46+
public function __construct(
47+
ClassMetadataFactoryInterface $classMetadataFactory = null,
48+
NameConverterInterface $nameConverter = null,
49+
PropertyTypeExtractorInterface $propertyTypeExtractor = null,
50+
ClassDiscriminatorResolverInterface $classDiscriminatorResolver = null,
51+
callable $objectClassResolver = null,
52+
array $defaultContext = [],
53+
bool $allowNormalizationOfObjectsWithoutAnyGetters = false,
54+
) {
55+
parent::__construct($classMetadataFactory, $nameConverter, $propertyTypeExtractor, $classDiscriminatorResolver, $objectClassResolver, $defaultContext);
56+
$this->allowNormalizationOfObjectsWithoutAnyGetters = $allowNormalizationOfObjectsWithoutAnyGetters;
57+
}
58+
3959
/**
4060
* {@inheritdoc}
4161
*
@@ -69,6 +89,10 @@ public function hasCacheableSupportsMethod(): bool
6989
*/
7090
private function supports(string $class): bool
7191
{
92+
if ($this->allowNormalizationOfObjectsWithoutAnyGetters) {
93+
return true;
94+
}
95+
7296
$class = new \ReflectionClass($class);
7397
$methods = $class->getMethods(\ReflectionMethod::IS_PUBLIC);
7498
foreach ($methods as $method) {

‎src/Symfony/Component/Serializer/Normalizer/PropertyNormalizer.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Serializer/Normalizer/PropertyNormalizer.php
+23Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@
1212
namespace Symfony\Component\Serializer\Normalizer;
1313

1414
use Symfony\Component\PropertyAccess\Exception\UninitializedPropertyException;
15+
use Symfony\Component\PropertyInfo\PropertyTypeExtractorInterface;
16+
use Symfony\Component\Serializer\Mapping\ClassDiscriminatorResolverInterface;
17+
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface;
18+
use Symfony\Component\Serializer\NameConverter\NameConverterInterface;
1519

1620
/**
1721
* Converts between objects and arrays by mapping properties.
@@ -32,6 +36,21 @@
3236
*/
3337
class PropertyNormalizer extends AbstractObjectNormalizer
3438
{
39+
private $allowNormalizationOfObjectsWithoutAnyProperties;
40+
41+
public function __construct(
42+
ClassMetadataFactoryInterface $classMetadataFactory = null,
43+
NameConverterInterface $nameConverter = null,
44+
PropertyTypeExtractorInterface $propertyTypeExtractor = null,
45+
ClassDiscriminatorResolverInterface $classDiscriminatorResolver = null,
46+
callable $objectClassResolver = null,
47+
array $defaultContext = [],
48+
bool $allowNormalizationOfObjectsWithoutAnyProperties = false,
49+
) {
50+
parent::__construct($classMetadataFactory, $nameConverter, $propertyTypeExtractor, $classDiscriminatorResolver, $objectClassResolver, $defaultContext);
51+
$this->allowNormalizationOfObjectsWithoutAnyProperties = $allowNormalizationOfObjectsWithoutAnyProperties;
52+
}
53+
3554
/**
3655
* {@inheritdoc}
3756
*
@@ -65,6 +84,10 @@ public function hasCacheableSupportsMethod(): bool
6584
*/
6685
private function supports(string $class): bool
6786
{
87+
if ($this->allowNormalizationOfObjectsWithoutAnyProperties) {
88+
return true;
89+
}
90+
6891
$class = new \ReflectionClass($class);
6992

7093
// We look for at least one non-static property

‎src/Symfony/Component/Serializer/Tests/Normalizer/GetSetMethodNormalizerTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Serializer/Tests/Normalizer/GetSetMethodNormalizerTest.php
+34Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,36 @@ public function testRejectInvalidKey()
357357
$this->markTestSkipped('This test makes no sense with the GetSetMethodNormalizer');
358358
}
359359

360+
protected function getNormalizerAllowingObjectsWithoutGetters(): GetSetMethodNormalizer
361+
{
362+
return new GetSetMethodNormalizer(null, null, null, null, null, [], true);
363+
}
364+
365+
public function testNormalizeObjectWithoutAnyProperties()
366+
{
367+
$normalizer = $this->getNormalizerAllowingObjectsWithoutGetters();
368+
$obj = new EmptyObjectDummy();
369+
370+
$this->assertTrue($normalizer->supportsNormalization($obj));
371+
372+
$this->assertEquals(
373+
[],
374+
$normalizer->normalize($obj),
375+
);
376+
}
377+
378+
public function testDenormalizeObjectWithoutAnyProperties()
379+
{
380+
$normalizer = $this->getNormalizerAllowingObjectsWithoutGetters();
381+
$obj = new EmptyObjectDummy();
382+
383+
$this->assertTrue($normalizer->supportsDenormalization($obj, \get_class($obj)));
384+
$this->assertEquals(
385+
$obj,
386+
$normalizer->denormalize([], \get_class($obj)),
387+
);
388+
}
389+
360390
protected function getNormalizerForIgnoredAttributes(): GetSetMethodNormalizer
361391
{
362392
$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
@@ -722,3 +752,7 @@ public function hasFoo()
722752
return $this->foo;
723753
}
724754
}
755+
756+
class EmptyObjectDummy
757+
{
758+
}

‎src/Symfony/Component/Serializer/Tests/Normalizer/PropertyNormalizerTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Serializer/Tests/Normalizer/PropertyNormalizerTest.php
+30Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,36 @@ protected function getDenormalizerForGroups(): PropertyNormalizer
246246
return new PropertyNormalizer($classMetadataFactory);
247247
}
248248

249+
protected function getNormalizerAllowingObjectsWithoutProperties(): PropertyNormalizer
250+
{
251+
return new PropertyNormalizer(null, null, null, null, null, [], true);
252+
}
253+
254+
public function testNormalizeObjectWithoutAnyProperties()
255+
{
256+
$normalizer = $this->getNormalizerAllowingObjectsWithoutProperties();
257+
$obj = new StaticPropertyDummy();
258+
259+
$this->assertTrue($normalizer->supportsNormalization($obj));
260+
261+
$this->assertEquals(
262+
[],
263+
$normalizer->normalize($obj),
264+
);
265+
}
266+
267+
public function testDenormalizeObjectWithoutAnyProperties()
268+
{
269+
$normalizer = $this->getNormalizerAllowingObjectsWithoutProperties();
270+
$obj = new StaticPropertyDummy();
271+
272+
$this->assertTrue($normalizer->supportsDenormalization($obj, \get_class($obj)));
273+
$this->assertEquals(
274+
$obj,
275+
$normalizer->denormalize([], \get_class($obj)),
276+
);
277+
}
278+
249279
public function testGroupsNormalizeWithNameConverter()
250280
{
251281
$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.