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 ->
|
} elseif ($normalizer->supportsDenormalization(null, $class, $format, $context)) { |
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 ->
|
if (\in_array($supportedType, ['*', 'object'], true) |
|
|| $class !== $supportedType && ('object' !== $genericType || !is_subclass_of($class, $supportedType)) |
|
) { |
|
continue; |
|
} |
$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
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
getSupportedTypesmethod and in the serializer code path that handles thegetSupportedTypeslogic it no longer calls thesupportsDenormalizationmethod 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 { }The test that I expect to pass but currently does not with Serializer 6.3:
The test passes when using Serializer 5.4
Removing the
getSupportedTypesmethod from theFooBaseDummyDenormalizerwhen using Serializer 6.3 makes the test pass again (but with a deprecation). TheFooBaseDummyDenormalizeris a simplified equivalent of a class from a bundle we use in our app.When we use Serializer 5.4 the serializer calls
$normalizer->supportsDenormalizationwhich returns true and everything works fine ->symfony/src/Symfony/Component/Serializer/Serializer.php
Line 315 in b39fcef
When we use Serializer 6.3 it skips that code path as the denormalizer has the
getSupportedTypesmethod so it enters thisifstatement which just does acontinue->symfony/src/Symfony/Component/Serializer/Serializer.php
Lines 363 to 367 in bbb5f5c
$supportedTypehere isSymfony\Component\Serializer\Tests\Fixtures\FooBaseDummy[],$classisSymfony\Component\Serializer\Tests\Fixtures\FooDummy[]and$genericTypeis*Possible Solution
No response
Additional Context
No response