8000 feature #21716 [Serializer] Add Support for `object_to_populate` in C… · symfony/symfony@94aef22 · GitHub
[go: up one dir, main page]

Skip to content

Commit 94aef22

Browse files
committed
feature #21716 [Serializer] Add Support for object_to_populate in CustomNormalizer (chrisguitarguy)
This PR was squashed before being merged into the 3.4 branch (closes #21716). Discussion ---------- [Serializer] Add Support for `object_to_populate` in CustomNormalizer | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #21715 | License | MIT | Doc PR | n/a This pulls a trait out of `AbstractNormalizer` with a method to extract the object to populate and adds some tests for it. Then uses that trait in both `AbstractNormalizer` and `CustomNormalizer` so both can support the `object_to_populate` key. Commits ------- ec9242d [Serializer] Add Support for in CustomNormalizer
2 parents f56f28b + ec9242d commit 94aef22

File tree

5 files changed

+107
-9
lines changed

5 files changed

+107
-9
lines changed

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

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
*/
2828
abstract class AbstractNormalizer extends SerializerAwareNormalizer implements NormalizerInterface, DenormalizerInterface, SerializerAwareInterface
2929
{
30+
use ObjectToPopulateTrait;
31+
3032
const CIRCULAR_REFERENCE_LIMIT = 'circular_reference_limit';
3133
const OBJECT_TO_POPULATE = 'object_to_populate';
3234
const GROUPS = 'groups';
@@ -317,12 +319,7 @@ protected function instantiateObject(array &$data, $class, array &$context, \Ref
317319
$format = null;
318320
}
319321

320-
if (
321-
isset($context[static::OBJECT_TO_POPULATE]) &&
322-
is_object($context[static::OBJECT_TO_POPULATE]) &&
323-
$context[static::OBJECT_TO_POPULATE] instanceof $class
324-
) {
325-
$object = $context[static::OBJECT_TO_POPULATE];
322+
if (null !== $object = $this->extractObjectToPopulate($class, $context, static::OBJECT_TO_POPULATE)) {
326323
unset($context[static::OBJECT_TO_POPULATE]);
327324

328325
return $object;

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,11 @@
1919
*/
2020
class CustomNormalizer implements NormalizerInterface, DenormalizerInterface, SerializerAwareInterface
2121
{
22-
private $cache = array();
23-
22+
use ObjectToPopulateTrait;
2423
use SerializerAwareTrait;
2524

25+
private $cache = array();
26+
2627
/**
2728
* {@inheritdoc}
2829
*/
@@ -36,7 +37,7 @@ public function normalize($object, $format = null, array $context = array())
3637
*/
3738
public function denormalize($data, $class, $format = null, array $context = array())
3839
{
39-
$object = new $class();
40+
$object = $this->extractObjectToPopulate($class, $context) ?: new $class();
4041
$object->denormalize($this->serializer, $data, $format, $context);
4142

4243
return $object;
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
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\Normalizer;
13+
14+
trait ObjectToPopulateTrait
15+
{
16+
/**
17+
* Extract the `object_to_populate` field from the context if it exists
18+
* and is an instance of the provided $class.
19+
*
20+
* @param string $class The class the object should be
21+
* @param $context The denormalization context
22+
* @param string $key They in which to look for the object to populate.
23+
* Keeps backwards compatibility with `AbstractNormalizer`.
24+
*
25+
* @return object|null an object if things check out, null otherwise
26+
*/
27+
protected function extractObjectToPopulate($class, array $context, $key = null)
28+
{
29+
$key = $key ?: 'object_to_populate';
30+
31+
if (
32+
isset($context[$key]) &&
33+
is_object($context[$key]) &&
34+
$context[$key] instanceof $class
35+
) {
36+
return $context[$key];
37+
}
38+
39+
return null;
40+
}
41+
}

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,18 @@ public function testDeserialize()
5656
$this->assertNull($obj->xmlFoo);
5757
}
5858

59+
public function testDenormalizeWithObjectToPopulateUsesProvidedObject()
60+
{
61+
$expected = new ScalarDummy();
62+
$obj = $this->normalizer->denormalize('foo', ScalarDummy::class, 'json', array(
63+
'object_to_populate' => $expected,
64+
));
65+
66+
$this->assertSame($expected, $obj);
67+
$this->assertEquals('foo', $obj->foo);
68+
$this->assertNull($obj->xmlFoo);
69+
}
70+
5971
public function testSupportsNormalization()
6072
{
6173
$this->assertTrue($this->normalizer->supportsNormalization(new ScalarDummy()));
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
namespace Symfony\Component\Serializer\Tests\Normalizer;
4+
5+
use PHPUnit\Framework\TestCase;
6+
use Symfony\Component\Serializer\Normalizer\ObjectToPopulateTrait;
7+
use Symfony\Component\Serializer\Tests\Fixtures\ProxyDummy;
8+
9+
class ObjectToPopulateTraitTest extends TestCase
10+
{
11+
use ObjectToPopulateTrait;
12+
13+
public function testExtractObjectToPopulateReturnsNullWhenKeyIsMissing()
14+
{
15+
$object = $this->extractObjectToPopulate(ProxyDummy::class, array());
16+
17+
$this->assertNull($object);
18+
}
19+
20+
public function testExtractObjectToPopulateReturnsNullWhenNonObjectIsProvided()
21+
{
22+
$object = $this->extractObjectToPopulate(ProxyDummy::class, array(
23+
'object_to_populate' => 'not an object',
24+
));
25+
26+
$this->assertNull($object);
27+
}
28+
29+
public function testExtractObjectToPopulateReturnsNullWhenTheClassIsNotAnInstanceOfTheProvidedClass()
30+
{
31+
$object = $this->extractObjectToPopulate(ProxyDummy::class, array(
32+
'object_to_populate' => new \stdClass(),
33+
));
34+
35+
$this->assertNull($object);
36+
}
37+
38+
public function testExtractObjectToPopulateReturnsObjectWhenEverythingChecksOut()
39+
{
40+
$expected = new ProxyDummy();
41+
$object = $this->extractObjectToPopulate(ProxyDummy::class, array(
42+
'object_to_populate' => $expected,
43+
));
44+
45+
$this->assertSame($expected, $object);
46+
}
47+
}

0 commit comments

Comments
 (0)
0