Skip to content

Commit 363bd0a

Browse files
Merge branch '6.4' into 7.3
* 6.4: [Console] Ensure terminal is usable after termination signal bug #61887 [Serializer] Fix discriminator class mapping with allow_extra_attributes=false
2 parents 0df5af2 + a7d76a1 commit 363bd0a

File tree

6 files changed

+84
-0
lines changed

6 files changed

+84
-0
lines changed

Normalizer/GetSetMethodNormalizer.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,10 @@ protected function isAllowedAttribute($classOrObject, string $attribute, ?string
169169

170170
$class = \is_object($classOrObject) ? $classOrObject::class : $classOrObject;
171171

172+
if ($this->classDiscriminatorResolver?->getMappingForMappedObject($classOrObject)?->getTypeProperty() === $attribute) {
173+
return true;
174+
}
175+
172176
if (!isset(self::$reflectionCache[$class])) {
173177
self::$reflectionCache[$class] = new \ReflectionClass($class);
174178
}

Normalizer/ObjectNormalizer.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,10 @@ protected function isAllowedAttribute($classOrObject, string $attribute, ?string
153153

154154
$class = \is_object($classOrObject) ? $classOrObject::class : $classOrObject;
155155

156+
if ($this->classDiscriminatorResolver?->getMappingForMappedObject($classOrObject)?->getTypeProperty() === $attribute) {
157+
return true;
158+
}
159+
156160
if ($context['_read_attributes'] ?? true) {
157161
if (!isset(self::$isReadableCache[$class.$attribute])) {
158162
self::$isReadableCache[$class.$attribute] = $this->propertyInfoExtractor->isReadable($class, $attribute) || $this->hasAttributeAccessorMethod($class, $attribute) || (\is_object($classOrObject) && $this->propertyAccessor->isReadable($classOrObject, $attribute));

Normalizer/PropertyNormalizer.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@ protected function isAllowedAttribute(object|string $classOrObject, string $attr
9999
return false;
100100
}
101101

102+
if ($this->classDiscriminatorResolver?->getMappingForMappedObject($classOrObject)?->getTypeProperty() === $attribute) {
103+
return true;
104+
}
105+
102106
try {
103107
$reflectionProperty = $this->getReflectionProperty($classOrObject, $attribute);
104108
} catch (\ReflectionException) {

Tests/Normalizer/GetSetMethodNormalizerTest.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,23 @@ public function testSupportsAndDenormalizeWithOptionalSetterArgument(array $data
569569
$obj = $this->normalizer->denormalize($data, GetSetDummyWithOptionalAndMultipleSetterArgs::class);
570570
$this->assertSame($expected, $obj->$method());
571571
}
572+
573+
public function testDiscriminatorWithAllowExtraAttributesFalse()
574+
{
575+
// Discriminator type property should be allowed with allow_extra_attributes=false
576+
$classMetadataFactory = new ClassMetadataFactory(new AttributeLoader());
577+
$discriminator = new ClassDiscriminatorFromClassMetadata($classMetadataFactory);
578+
$normalizer = new GetSetMethodNormalizer($classMetadataFactory, null, null, $discriminator);
579+
580+
$obj = $normalizer->denormalize(
581+
['type' => 'one'],
582+
GetSetMethodDummyInterface::class,
583+
null,
584+
[AbstractNormalizer::ALLOW_EXTRA_ATTRIBUTES => false]
585+
);
586+
587+
$this->assertInstanceOf(GetSetMethodDiscriminatedDummyOne::class, $obj);
588+
}
572589
}
573590

574591
class GetSetDummy

Tests/Normalizer/ObjectNormalizerTest.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
use Symfony\Component\Serializer\Exception\NotNormalizableValueException;
2626
use Symfony\Component\Serializer\Exception\RuntimeException;
2727
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
28+
use Symfony\Component\Serializer\Mapping\ClassDiscriminatorFromClassMetadata;
2829
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
2930
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface;
3031
use Symfony\Component\Serializer\Mapping\Loader\AttributeLoader;
@@ -1086,6 +1087,23 @@ public function testPrecedenceOfAccessorMethods()
10861087
'foo' => 'hasFoo',
10871088
], $normalizedSwappedHasserIsser);
10881089
}
1090+
1091+
public function testDiscriminatorWithAllowExtraAttributesFalse()
1092+
{
1093+
// Discriminator type property should be allowed with allow_extra_attributes=false
1094+
$classMetadataFactory = new ClassMetadataFactory(new AttributeLoader());
1095+
$discriminator = new ClassDiscriminatorFromClassMetadata($classMetadataFactory);
1096+
$normalizer = new ObjectNormalizer($classMetadataFactory, null, null, null, $discriminator);
1097+
1098+
$obj = $normalizer->denormalize(
1099+
['type' => 'type_a'],
1100+
DiscriminatorDummyInterface::class,
1101+
null,
1102+
[AbstractNormalizer::ALLOW_EXTRA_ATTRIBUTES => false]
1103+
);
1104+
1105+
$this->assertInstanceOf(DiscriminatorDummyTypeA::class, $obj);
1106+
}
10891107
}
10901108

10911109
class ProxyObjectDummy extends ObjectDummy
@@ -1429,6 +1447,25 @@ public function isolate()
14291447
}
14301448
}
14311449

1450+
#[\Symfony\Component\Serializer\Attribute\DiscriminatorMap(
1451+
typeProperty: 'type',
1452+
mapping: [
1453+
'type_a' => DiscriminatorDummyTypeA::class,
1454+
'type_b' => DiscriminatorDummyTypeB::class,
1455+
]
1456+
)]
1457+
interface DiscriminatorDummyInterface
1458+
{
1459+
}
1460+
1461+
class DiscriminatorDummyTypeA implements DiscriminatorDummyInterface
1462+
{
1463+
}
1464+
1465+
class DiscriminatorDummyTypeB implements DiscriminatorDummyInterface
1466+
{
1467+
}
1468+
14321469
class ObjectWithPropertyAndAllAccessorMethods
14331470
{
14341471
public function __construct(

Tests/Normalizer/PropertyNormalizerTest.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
use Symfony\Component\Serializer\Mapping\Loader\AttributeLoader;
2323
use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter;
2424
use Symfony\Component\Serializer\NameConverter\MetadataAwareNameConverter;
25+
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
2526
use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer;
2627
use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer;
2728
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
@@ -585,6 +586,23 @@ public function testDenormalizeWithDiscriminator()
585586
)
586587
);
587588
}
589+
590+
public function testDiscriminatorWithAllowExtraAttributesFalse()
591+
{
592+
// Discriminator type property should be allowed with allow_extra_attributes=false
593+
$classMetadataFactory = new ClassMetadataFactory(new AttributeLoader());
594+
$discriminator = new ClassDiscriminatorFromClassMetadata($classMetadataFactory);
595+
$normalizer = new PropertyNormalizer($classMetadataFactory, null, null, $discriminator);
596+
597+
$obj = $normalizer->denormalize(
598+
['type' => 'one'],
599+
PropertyDummyInterface::class,
600+
null,
601+
[AbstractNormalizer::ALLOW_EXTRA_ATTRIBUTES => false]
602+
);
603+
604+
$this->assertInstanceOf(PropertyDiscriminatedDummyOne::class, $obj);
605+
}
588606
}
589607

590608
class PropertyDummy

0 commit comments

Comments
 (0)