8000 Add deep populate option #21669 · symfony/symfony@e8f290f · GitHub
[go: up one dir, main page]

Skip to content

Commit e8f290f

Browse files
committed
Add deep populate option #21669
1 parent 2ff8c19 commit e8f290f

File tree

6 files changed

+90
-1
lines changed

6 files changed

+90
-1
lines changed

src/Symfony/Component/Serializer/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ CHANGELOG
55
-----
66

77
* added the list of constraint violations' parameters in `ConstraintViolationListNormalizer`
8+
* added a `deep_object_to_populate` context option to recursive denormalize on `object_to_populate` object.
89

910
4.2.0
1011
-----

src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\Serializer\Normalizer;
1313

1414
use Symfony\Component\PropertyAccess\Exception\InvalidArgumentException;
15+
use Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException;
1516
use Symfony\Component\PropertyInfo\PropertyTypeExtractorInterface;
1617
use Symfony\Component\PropertyInfo\Type;
1718
use Symfony\Component\Serializer\Encoder\JsonEncoder;
@@ -38,6 +39,7 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
3839
const SKIP_NULL_VALUES = 'skip_null_values';
3940
const MAX_DEPTH_HANDLER = 'max_depth_handler';
4041
const EXCLUDE_FROM_CACHE_KEY = 'exclude_from_cache_key';
42+
const DEEP_OBJECT_TO_POPULATE = 'deep_object_to_populate';
4143

4244
private $propertyTypeExtractor;
4345
private $typesCache = [];
@@ -274,6 +276,13 @@ public function denormalize($data, $class, $format = null, array $context = [])
274276
continue;
275277
}
276278

279+
if ($context[self::DEEP_OBJECT_TO_POPULATE] ?? $this->defaultContext[self::DEEP_OBJECT_TO_POPULATE] ?? false) {
280+
try {
281+
$context[self::OBJECT_TO_POPULATE] = $this->getAttributeValue($object, $attribute, $format, $context);
282+
} catch (NoSuchPropertyException $e) {
283+
}
284+
}
285+
277286
$value = $this->validateAndDenormalize($class, $attribute, $value, $format, $context);
278287
try {
279288
$this->setAttributeValue($object, $attribute, $value, $format, $context);

src/Symfony/Component/Serializer/Normalizer/ObjectToPopulateTrait.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ trait ObjectToPopulateTrait
2626
*/
2727
protected function extractObjectToPopulate($class, array $context, $key = null)
2828
{
29-
$key = $key ?: 'object_to_populate';
29+
$key = $key ?: AbstractNormalizer::OBJECT_TO_POPULATE;
3030

3131
if (isset($context[$key]) && \is_object($context[$key]) && $context[$key] instanceof $class) {
3232
return $context[$key];
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Serializer\Tests\Fixtures;
13+
14+
/**
15+
* @author Jérôme Desjardin <jewome62@gmail.com>
16+
*/
17+
class DeepObjectPopulateChildDummy
18+
{
19+
public $foo;
20+
21+
public $bar;
22+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Serializer\Tests\Fixtures;
13+
14+
/**
15+
* @author Jérôme Desjardin <jewome62@gmail.com>
16+
*/
17+
class DeepObjectPopulateParentDummy
18+
{
19+
/**
20+
* @var DeepObjectPopulateChildDummy
21+
*/
22+
private $child;
23+
24+
public function setChild(DeepObjectPopulateChildDummy $child)
25+
{
26+
$this->child = $child;
27+
}
28+
29+
public function getChild()
30+
{
31+
return $this->child;
32+
}
33+
}

src/Symfony/Component/Serializer/Tests/Normalizer/AbstractObjectNormalizerTest.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
2424
use Symfony\Component\Serializer\SerializerAwareInterface;
2525
use Symfony\Component\Serializer\SerializerInterface;
26+
use Symfony\Component\Serializer\Tests\Fixtures\DeepObjectPopulateChildDummy;
27+
use Symfony\Component\Serializer\Tests\Fixtures\DeepObjectPopulateParentDummy;
2628

2729
class AbstractObjectNormalizerTest extends TestCase
2830
{
@@ -171,6 +173,28 @@ public function testSkipNullValues()
171173
$result = $normalizer->normalize($dummy, null, [AbstractObjectNormalizer::SKIP_NULL_VALUES => true]);
172174
$this->assertSame(['bar' => 'present'], $result);
173175
}
176+
177+
public function testDeepObjectToPopulate()
178+
{
179+
$child = new DeepObjectPopulateChildDummy();
180+
$child->bar = 'bar-old';
181+
$child->foo = 'foo-old';
182+
183+
$parent = new DeepObjectPopulateParentDummy();
184+
185+
$parent->setChild($child);
186+
187+
$context = [
188+
AbstractObjectNormalizer::OBJECT_TO_POPULATE => $parent,
189+
AbstractObjectNormalizer::DEEP_OBJECT_TO_POPULATE => true
190+
];
191+
192+
$normalizer = new ObjectNormalizer();
193+
$normalizer->denormalize(['child' => [ 'bar' => 'bar-new']], 'Symfony\Component\Serializer\Tests\Fixtures\DeepObjectPopulateParentDummy', null, $context);
194+
195+
$this->assertSame('bar-new', $parent->getChild()->bar);
196+
$this->assertSame('foo-old', $parent->getChild()->foo);
197+
}
174198
}
175199

176200
class AbstractObjectNormalizerDummy extends AbstractObjectNormalizer

0 commit comments

Comments
 (0)
0