@@ -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,43 @@ 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
+ * Gets the discriminator property name by object.
306
+ *
307
+ * @param object $object
308
+ *
309
+ * @return string|null
310
+ */
311
+ private function getDiscriminatorProperty ($ object ): ?string
312
+ {
313
+ $ cacheKey = \get_class ($ object );
314
+ if (!\array_key_exists ($ cacheKey , $ this ->discriminatorCache )) {
315
+ $ this ->discriminatorCache [$ cacheKey ] = null ;
316
+ if ($ this ->classDiscriminatorResolver ) {
317
+ $ mapping = $ this ->classDiscriminatorResolver ->getMappingForMappedObject ($ object );
318
+ $ this ->discriminatorCache [$ cacheKey ] = $ mapping === null ? null : $ mapping ->getTypeProperty ();
319
+ }
320
+ }
321
+ return $ this ->discriminatorCache [$ cacheKey ];
322
+ }
323
+
280
324
/**
281
325
* Extracts attributes to normalize from the class of the given object, format and context.
282
326
*
@@ -350,7 +394,7 @@ public function denormalize($data, $type, $format = null, array $context = [])
350
394
351
395
if ($ context [self ::DEEP_OBJECT_TO_POPULATE ] ?? $ this ->defaultContext [self ::DEEP_OBJECT_TO_POPULATE ] ?? false ) {
352
396
try {
353
- $ context [self ::OBJECT_TO_POPULATE ] = $ this ->getAttributeValue ($ object , $ attribute , $ format , $ context );
397
+ $ context [self ::OBJECT_TO_POPULATE ] = $ this ->getValue ($ object , $ attribute , $ format , $ context );
354
398
} catch (NoSuchPropertyException $ e ) {
355
399
}
356
400
}
0 commit comments