feature #13500 [Serializer] Normalizers can serialize collections and scalars (dunglas)
This PR was squashed before being merged into the 2.7 branch (closes #13500).
Discussion
----------
[Serializer] Normalizers can serialize collections and scalars
| Q | A
| ------------- | ---
| Bug fix? | yes
| New feature? | yes
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| License | MIT
| Doc PR | n/a
Currently, the logic for serializing `array` and scalars is hardcoded in the serializer. This is not possible to have a custom serializer normalizing collections. This a big limitation, for instance it's not possible to create an normalizer creating [Hydra collections](http://www.hydra-cg.com/spec/latest/core/#h-collections) for a PHP array.
This PR fix that.
Commits
-------
1cf8eb2
[Serializer] Normalizers can serialize collections and scalars
This commit is contained in:
commit
7af0196d89
@ -33,6 +33,7 @@ use Symfony\Component\Serializer\Exception\UnexpectedValueException;
|
|||||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||||
* @author Lukas Kahwe Smith <smith@pooteeweet.org>
|
* @author Lukas Kahwe Smith <smith@pooteeweet.org>
|
||||||
|
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||||
*/
|
*/
|
||||||
class Serializer implements SerializerInterface, NormalizerInterface, DenormalizerInterface, EncoderInterface, DecoderInterface
|
class Serializer implements SerializerInterface, NormalizerInterface, DenormalizerInterface, EncoderInterface, DecoderInterface
|
||||||
{
|
{
|
||||||
@ -118,6 +119,11 @@ class Serializer implements SerializerInterface, NormalizerInterface, Denormaliz
|
|||||||
*/
|
*/
|
||||||
public function normalize($data, $format = null, array $context = array())
|
public function normalize($data, $format = null, array $context = array())
|
||||||
{
|
{
|
||||||
|
// If a normalizer supports the given data, use it
|
||||||
|
if ($normalizer = $this->getNormalizer($data, $format)) {
|
||||||
|
return $normalizer->normalize($data, $format, $context);
|
||||||
|
}
|
||||||
|
|
||||||
if (null === $data || is_scalar($data)) {
|
if (null === $data || is_scalar($data)) {
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
@ -172,21 +178,25 @@ class Serializer implements SerializerInterface, NormalizerInterface, Denormaliz
|
|||||||
/**
|
/**
|
||||||
* Returns a matching normalizer.
|
* Returns a matching normalizer.
|
||||||
*
|
*
|
||||||
* @param object $data The object to get the serializer for
|
* @param mixed $data Data to get the serializer for
|
||||||
* @param string $format format name, present to give the option to normalizers to act differently based on formats
|
* @param string $format format name, present to give the option to normalizers to act differently based on formats
|
||||||
*
|
*
|
||||||
* @return NormalizerInterface|null
|
* @return NormalizerInterface|null
|
||||||
*/
|
*/
|
||||||
private function getNormalizer($data, $format)
|
private function getNormalizer($data, $format)
|
||||||
{
|
{
|
||||||
$class = get_class($data);
|
if ($isObject = is_object($data)) {
|
||||||
if (isset($this->normalizerCache[$class][$format])) {
|
$class = get_class($data);
|
||||||
return $this->normalizerCache[$class][$format];
|
if (isset($this->normalizerCache[$class][$format])) {
|
||||||
|
return $this->normalizerCache[$class][$format];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($this->normalizers as $normalizer) {
|
foreach ($this->normalizers as $normalizer) {
|
||||||
if ($normalizer instanceof NormalizerInterface && $normalizer->supportsNormalization($data, $format)) {
|
if ($normalizer instanceof NormalizerInterface && $normalizer->supportsNormalization($data, $format)) {
|
||||||
$this->normalizerCache[$class][$format] = $normalizer;
|
if ($isObject) {
|
||||||
|
$this->normalizerCache[$class][$format] = $normalizer;
|
||||||
|
}
|
||||||
|
|
||||||
return $normalizer;
|
return $normalizer;
|
||||||
}
|
}
|
||||||
|
@ -73,6 +73,15 @@ class SerializerTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->assertTrue($this->serializer->denormalize(json_encode($data), 'stdClass', 'json'));
|
$this->assertTrue($this->serializer->denormalize(json_encode($data), 'stdClass', 'json'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testCustomNormalizerCanNormalizeCollectionsAndScalar()
|
||||||
|
{
|
||||||
|
$this->serializer = new Serializer(array(new TestNormalizer()), array());
|
||||||
|
$this->assertNull($this->serializer->normalize(array('a', 'b')));
|
||||||
|
$this->assertNull($this->serializer->normalize(new \ArrayObject(array('c', 'd'))));
|
||||||
|
$this->assertNull($this->serializer->normalize(array()));
|
||||||
|
$this->assertNull($this->serializer->normalize('test'));
|
||||||
|
}
|
||||||
|
|
||||||
public function testSerialize()
|
public function testSerialize()
|
||||||
{
|
{
|
||||||
$this->serializer = new Serializer(array(new GetSetMethodNormalizer()), array('json' => new JsonEncoder()));
|
$this->serializer = new Serializer(array(new GetSetMethodNormalizer()), array('json' => new JsonEncoder()));
|
||||||
|
Reference in New Issue
Block a user