@@ -93,6 +93,7 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
93
93
private $ propertyTypeExtractor ;
94
94
private $ typesCache = [];
95
95
private $ attributesCache = [];
96
+ private $ discriminatorCache = [];
96
97
97
98
/**
98
99
* @deprecated since Symfony 4.2
@@ -107,8 +108,14 @@ abstract class AbstractObjectNormalizer extends AbstractNormalizer
107
108
*/
108
109
protected $ classDiscriminatorResolver ;
109
110
110
- public function __construct (ClassMetadataFactoryInterface $ classMetadataFactory = null , NameConverterInterface $ nameConverter = null , PropertyTypeExtractorInterface $ propertyTypeExtractor = null , ClassDiscriminatorResolverInterface $ classDiscriminatorResolver = null , callable $ objectClassResolver = null , array $ defaultContext = [])
111
- {
111
+ public function __construct (
112
+ ClassMetadataFactoryInterface $ classMetadataFactory = null ,
113
+ NameConverterInterface $ nameConverter = null ,
114
+ PropertyTypeExtractorInterface $ propertyTypeExtractor = null ,
115
+ ClassDiscriminatorResolverInterface $ classDiscriminatorResolver = null ,
116
+ callable $ objectClassResolver = null ,
117
+ array $ defaultContext = []
118
+ ) {
112
119
parent ::__construct ($ classMetadataFactory , $ nameConverter , $ defaultContext );
113
120
114
121
if (isset ($ this ->defaultContext [self ::MAX_DEPTH_HANDLER ]) && !\is_callable ($ this ->defaultContext [self ::MAX_DEPTH_HANDLER ])) {
@@ -180,7 +187,7 @@ public function normalize($object, $format = null, array $context = [])
180
187
continue ;
181
188
}
182
189
183
- $ attributeValue = $ this ->getAttributeValue ($ object , $ attribute , $ format , $ context );
190
+ $ attributeValue = $ this ->getValue ($ object , $ attribute , $ format , $ context );
184
191
if ($ maxDepthReached ) {
185
192
$ attributeValue = $ maxDepthHandler ($ attributeValue , $ object , $ attribute , $ format , $ context );
186
193
}
@@ -277,6 +284,42 @@ protected function getAttributes($object, $format = null, array $context)
277
284
return $ attributes ;
278
285
}
279
286
287
+ /**
288
+ * @internal this method is wrapper
289
+ * Gets the attribute value
290
+ *
291
+ * @param object $object
292
+ * @param string $attribute
293
+ * @param string|null $format
294
+ * @param array $context
295
+ *
296
+ * @return mixed
297
+ */
298
+ private function getValue ($ object , $ attribute , $ format = null , array $ context = [])
299
+ {
300
+ return $ attribute === $ this ->getDiscriminatorProperty ($ object )
301
+ ? $ this ->classDiscriminatorResolver ->getTypeForMappedObject ($ object )
302
+ : $ this ->getAttributeValue ($ object , $ attribute , $ format , $ context );
303
+ }
304
+
305
+ /**
306
+ * Gets the discriminator property name by object.
307
+ *
308
+ * @param object $object
309
+ */
310
+ private function getDiscriminatorProperty ($ object ): ?string
311
+ {
312
+ $ cacheKey = \get_class ($ object );
313
+ if (!\array_key_exists ($ cacheKey , $ this ->discriminatorCache )) {
314
+ $ this ->discriminatorCache [$ cacheKey ] = null ;
315
+ if ($ this ->classDiscriminatorResolver ) {
316
+ $ mapping = $ this ->classDiscriminatorResolver ->getMappingForMappedObject ($ object );
317
+ $ this ->discriminatorCache [$ cacheKey ] = null === $ mapping ? null : $ mapping ->getTypeProperty ();
318
+ }
319
+ }
320
+ return $ this ->discriminatorCache [$ cacheKey ];
321
+ }
322
+
280
323
/**
281
324
* Extracts attributes to normalize from the class of the given object, format and context.
282
325
*
@@ -350,7 +393,7 @@ public function denormalize($data, $type, $format = null, array $context = [])
350
393
351
394
if ($ context [self ::DEEP_OBJECT_TO_POPULATE ] ?? $ this ->defaultContext [self ::DEEP_OBJECT_TO_POPULATE ] ?? false ) {
352
395
try {
353
- $ context [self ::OBJECT_TO_POPULATE ] = $ this ->getAttributeValue ($ object , $ attribute , $ format , $ context );
396
+ $ context [self ::OBJECT_TO_POPULATE ] = $ this ->getValue ($ object , $ attribute , $ format , $ context );
354
397
} catch (NoSuchPropertyException $ e ) {
355
398
}
356
399
}
0 commit comments