Skip to content

Commit

Permalink
feature #27819 [Serializer] deprecated normalizers and encoders who d…
Browse files Browse the repository at this point in the history
…ont implement the base interfaces (rodnaph)

This PR was merged into the 4.2-dev branch.

Discussion
----------

[Serializer] deprecated normalizers and encoders who dont implement the base interfaces

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | None
| License       | MIT
| Doc PR        | None

Currently the `Serializer` can be constructed with any object regardless of whether or not it implements `NormalizerInterface` or `DenormalizerInterface`. This object will then be ignored when getting a normalizer/denormalizer, so in effect silently ignored for serializer operations.

This change throws an exception on construct if a given normalizer object does not implement one of these interfaces - are there use cases where this would not be true?

Commits
-------

cbc2be8 [Serializer] deprecated normalizers and encoders who dont implement the base interfaces
  • Loading branch information
fabpot committed Sep 25, 2018
2 parents 3d2124e + cbc2be8 commit 9db435e
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 2 deletions.
6 changes: 6 additions & 0 deletions src/Symfony/Component/Serializer/CHANGELOG.md
Expand Up @@ -13,6 +13,12 @@ CHANGELOG
the format and the context in a name converter
* the `AbstractNormalizer::handleCircularReference()` method will have two new `$format`
and `$context` arguments in version 5.0, not defining them is deprecated
* deprecated creating a `Serializer` with normalizers which do not implement
either `NormalizerInterface` or `DenormalizerInterface`
* deprecated creating a `Serializer` with normalizers which do not implement
either `NormalizerInterface` or `DenormalizerInterface`
* deprecated creating a `Serializer` with encoders which do not implement
either `EncoderInterface` or `DecoderInterface`

4.1.0
-----
Expand Down
14 changes: 14 additions & 0 deletions src/Symfony/Component/Serializer/Serializer.php
Expand Up @@ -64,6 +64,10 @@ class Serializer implements SerializerInterface, ContextAwareNormalizerInterface
private $denormalizerCache = array();
private $normalizerCache = array();

/**
* @param (NormalizerInterface|DenormalizerInterface)[] $normalizers
* @param (EncoderInterface|DecoderInterface)[] $encoders
*/
public function __construct(array $normalizers = array(), array $encoders = array())
{
foreach ($normalizers as $normalizer) {
Expand All @@ -78,6 +82,11 @@ public function __construct(array $normalizers = array(), array $encoders = arra
if ($normalizer instanceof NormalizerAwareInterface) {
$normalizer->setNormalizer($this);
}

if (!($normalizer instanceof NormalizerInterface || $normalizer instanceof DenormalizerInterface)) {
@trigger_error(\sprintf('Passing normalizers ("%s") which do not implement either "%s" or "%s" has been deprecated since Symfony 4.2.', \get_class($normalizer), NormalizerInterface::class, DenormalizerInterface::class), E_USER_DEPRECATED);
// throw new \InvalidArgumentException(\sprintf('The class "%s" does not implement "%s" or "%s".', \get_class($normalizer), NormalizerInterface::class, DenormalizerInterface::class));
}
}
$this->normalizers = $normalizers;

Expand All @@ -93,6 +102,11 @@ public function __construct(array $normalizers = array(), array $encoders = arra
if ($encoder instanceof EncoderInterface) {
$realEncoders[] = $encoder;
}

if (!($encoder instanceof EncoderInterface || $encoder instanceof DecoderInterface)) {
@trigger_error(\sprintf('Passing encoders ("%s") which do not implement either "%s" or "%s" has been deprecated since Symfony 4.2.', \get_class($encoder), EncoderInterface::class, DecoderInterface::class), E_USER_DEPRECATED);
// throw new \InvalidArgumentException(\sprintf('The class "%s" does not implement "%s" or "%s".', \get_class($normalizer), EncoderInterface::class, DecoderInterface::class));
}
}
$this->encoder = new ChainEncoder($realEncoders);
$this->decoder = new ChainDecoder($decoders);
Expand Down
22 changes: 20 additions & 2 deletions src/Symfony/Component/Serializer/Tests/SerializerTest.php
Expand Up @@ -55,6 +55,24 @@ public function testInterface()
$this->assertInstanceOf('Symfony\Component\Serializer\Encoder\DecoderInterface', $serializer);
}

/**
* @expectedDeprecation Passing normalizers ("stdClass") which do not implement either "Symfony\Component\Serializer\Normalizer\NormalizerInterface" or "Symfony\Component\Serializer\Normalizer\DenormalizerInterface" has been deprecated since Symfony 4.2.
* @group legacy
*/
public function testDeprecationErrorOnInvalidNormalizer()
{
new Serializer(array(new \stdClass()));
}

/**
* @expectedDeprecation Passing encoders ("stdClass") which do not implement either "Symfony\Component\Serializer\Encoder\EncoderInterface" or "Symfony\Component\Serializer\Encoder\DecoderInterface" has been deprecated since Symfony 4.2.
* @group legacy
*/
public function testDeprecationErrorOnInvalidEncoder()
{
new Serializer(array(), array(new \stdClass()));
}

/**
* @expectedException \Symfony\Component\Serializer\Exception\UnexpectedValueException
*/
Expand Down Expand Up @@ -334,7 +352,7 @@ public function testDeserializeArray()

public function testNormalizerAware()
{
$normalizerAware = $this->getMockBuilder(NormalizerAwareInterface::class)->getMock();
$normalizerAware = $this->getMockBuilder(array(NormalizerAwareInterface::class, NormalizerInterface::class))->getMock();
$normalizerAware->expects($this->once())
->method('setNormalizer')
->with($this->isInstanceOf(NormalizerInterface::class));
Expand All @@ -344,7 +362,7 @@ public function testNormalizerAware()

public function testDenormalizerAware()
{
$denormalizerAware = $this->getMockBuilder(DenormalizerAwareInterface::class)->getMock();
$denormalizerAware = $this->getMockBuilder(array(DenormalizerAwareInterface::class, DenormalizerInterface::class))->getMock();
$denormalizerAware->expects($this->once())
->method('setDenormalizer')
->with($this->isInstanceOf(DenormalizerInterface::class));
Expand Down

0 comments on commit 9db435e

Please sign in to comment.