Description
Symfony version(s) affected
6.3
Description
Updating from Serializer 5.4 to 6.3 breaks our testsuite as the denormalizer which is supposed to denormalize an array property does not get executed anymore as it does implement the getSupportedTypes
method and in the serializer code path that handles the getSupportedTypes
logic it no longer calls the supportsDenormalization
method on that denormalizer (the concrete example can be seen under the steps to reproduce). I'm not entirely familiar with the Serializer component so maybe I'm just doing something wrong.
How to reproduce
The interfaces/classes needed to reproduce this:
interface FooBaseDummy
{
}
class FooDummy implements FooBaseDummy
{
/**
* @var string
*/
public $name;
}
class ArrayPropertyDummy
{
/**
* @var FooDummy[]
*/
public $foo;
public function getFoo(): array
{
return $this->foo;
}
}
final class FooBaseDummyDenormalizer implements DenormalizerInterface
{
public function denormalize(mixed $data, string $type, string $format = null, array $context = [])
{
$result = [];
foreach ($data as $foo) {
$fooDummy = new FooDummy();
$fooDummy->name = $foo['name'];
$result[] = $fooDummy;
}
return $result;
}
public function supportsDenormalization(mixed $data, string $type, string $format = null)
{
if (mb_substr($type, -2) === '[]') {
$className = mb_substr($type, 0, -2);
$classImplements = class_implements($className);
\assert(\is_array($classImplements));
return class_exists($className) && \in_array(FooBaseDummy::class, $classImplements, true);
}
return false;
}
/**
* @return array<string, bool>
*/
public function getSupportedTypes(?string $format): array
{
return [FooBaseDummy::class.'[]' => false];
}
}
The test that I expect to pass but currently does not with Serializer 6.3:
public function testDeserializeOnObjectWithArrayProperty()
{
$serializer = new Serializer([new FooBaseDummyDenormalizer(), new ObjectNormalizer(null, null, null, new PhpDocExtractor())], [new JsonEncoder()]);
$obj = $serializer->deserialize('{"foo":[{"name":"bar"}]}', ArrayPropertyDummy::class, 'json');
$this->assertInstanceOf(ArrayPropertyDummy::class, $obj);
$this->assertInstanceOf(FooDummy::class, $obj->getFoo()[0]);
}
The test passes when using Serializer 5.4
Removing the getSupportedTypes
method from the FooBaseDummyDenormalizer
when using Serializer 6.3 makes the test pass again (but with a deprecation). The FooBaseDummyDenormalizer
is a simplified equivalent of a class from a bundle we use in our app.
When we use Serializer 5.4 the serializer calls $normalizer->supportsDenormalization
which returns true and everything works fine ->
When we use Serializer 6.3 it skips that code path as the denormalizer has the
getSupportedTypes
method so it enters this if
statement which just does a continue
-> symfony/src/Symfony/Component/Serializer/Serializer.php
Lines 363 to 367 in bbb5f5c
$supportedType
here is Symfony\Component\Serializer\Tests\Fixtures\FooBaseDummy[]
, $class
is Symfony\Component\Serializer\Tests\Fixtures\FooDummy[]
and $genericType
is *
Possible Solution
No response
Additional Context
No response