23
23
use Symfony \Component \Serializer \Exception \NotNormalizableValueException ;
24
24
use Symfony \Component \Serializer \Exception \PartialDenormalizationException ;
25
25
use Symfony \Component \Serializer \Normalizer \AbstractObjectNormalizer ;
26
+ use Symfony \Component \Serializer \Normalizer \CacheableSupport ;
26
27
use Symfony \Component \Serializer \Normalizer \CacheableSupportsMethodInterface ;
27
28
use Symfony \Component \Serializer \Normalizer \ContextAwareDenormalizerInterface ;
28
29
use Symfony \Component \Serializer \Normalizer \ContextAwareNormalizerInterface ;
@@ -247,34 +248,56 @@ public function supportsDenormalization(mixed $data, string $type, string $forma
247
248
private function getNormalizer (mixed $ data , ?string $ format , array $ context ): ?NormalizerInterface
248
249
{
249
250
$ type = \is_object ($ data ) ? $ data ::class : 'native- ' .\gettype ($ data );
250
-
251
+ $ minCached = CacheableSupport::SupportAlways;
252
+ $ minUncached = CacheableSupport::SupportNever;
251
253
if (!isset ($ this ->normalizerCache [$ format ][$ type ])) {
254
+ $ minCached = CacheableSupport::Support;
255
+ $ minUncached = CacheableSupport::SupportNot;
252
256
$ this ->normalizerCache [$ format ][$ type ] = [];
253
-
254
257
foreach ($ this ->normalizers as $ k => $ normalizer ) {
255
258
if (!$ normalizer instanceof NormalizerInterface) {
256
259
continue ;
257
260
}
258
261
259
- if (!$ normalizer instanceof CacheableSupportsMethodInterface || !$ normalizer ->hasCacheableSupportsMethod ()) {
260
- $ this ->normalizerCache [$ format ][$ type ][$ k ] = false ;
261
- } elseif ($ normalizer ->supportsNormalization ($ data , $ format , $ context )) {
262
- $ this ->normalizerCache [$ format ][$ type ][$ k ] = true ;
262
+ $ support = $ this ->supportsNormalizationWrapper ($ normalizer , $ data , $ format , $ context );
263
+ if (CacheableSupport::SupportNever === $ support ) {
264
+ continue ;
265
+ }
266
+
267
+ $ this ->normalizerCache [$ format ][$ type ][$ k ] = $ support ;
268
+ if (CacheableSupport::SupportAlways === $ support ) {
263
269
break ;
264
270
}
265
271
}
266
272
}
267
273
268
274
foreach ($ this ->normalizerCache [$ format ][$ type ] as $ k => $ cached ) {
269
275
$ normalizer = $ this ->normalizers [$ k ];
270
- if ($ cached || $ normalizer -> supportsNormalization ( $ data , $ format , $ context )) {
276
+ if ($ cached-> value >= $ minCached -> value || ( $ cached -> value > $ minUncached -> value && $ this -> supportsNormalizationWrapper ( $ normalizer , $ data , $ format , $ context)-> value > CacheableSupport::SupportNot-> value )) {
271
277
return $ normalizer ;
272
278
}
273
279
}
274
280
275
281
return null ;
276
282
}
277
283
284
+ /**
285
+ * Backwards-Compatibility layer for CacheableSupportsMethodInterface -> CacheableSupport.
286
+ */
287
+ private function supportsNormalizationWrapper (NormalizerInterface $ normalizer , mixed $ data , ?string $ format , array $ context ): CacheableSupport
288
+ {
289
+ $ value = $ normalizer ->supportsNormalization ($ data , $ format , $ context );
290
+ if (\is_bool ($ value )) {
291
+ trigger_deprecation ('symfony/serializer ' , '6.2 ' , 'Returning boolean from "%s::%s" is deprecated, return "%s" instead. ' , NormalizerInterface::class, 'supports() ' , CacheableSupport::class);
292
+ }
293
+
294
+ return match ($ value ) {
295
+ true => $ normalizer instanceof CacheableSupportsMethodInterface && $ normalizer ->hasCacheableSupportsMethod () ? CacheableSupport::SupportAlways : CacheableSupport::Support,
296
+ false => $ normalizer instanceof CacheableSupportsMethodInterface && $ normalizer ->hasCacheableSupportsMethod () ? CacheableSupport::SupportNever : CacheableSupport::SupportNot,
297
+ default => $ value
298
+ };
299
+ }
300
+
278
301
/**
279
302
* Returns a matching denormalizer.
280
303
*
@@ -285,33 +308,57 @@ private function getNormalizer(mixed $data, ?string $format, array $context): ?N
285
308
*/
286
309
private function getDenormalizer (mixed $ data , string $ class , ?string $ format , array $ context ): ?DenormalizerInterface
287
310
{
311
+ $ minCached = CacheableSupport::SupportAlways;
312
+ $ minUncached = CacheableSupport::SupportNever;
288
313
if (!isset ($ this ->denormalizerCache [$ format ][$ class ])) {
314
+ $ minCached = CacheableSupport::Support;
315
+ $ minUncached = CacheableSupport::SupportNot;
289
316
$ this ->denormalizerCache [$ format ][$ class ] = [];
290
317
291
318
foreach ($ this ->normalizers as $ k => $ normalizer ) {
292
319
if (!$ normalizer instanceof DenormalizerInterface) {
293
320
continue ;
294
321
}
295
322
296
- if (!$ normalizer instanceof CacheableSupportsMethodInterface || !$ normalizer ->hasCacheableSupportsMethod ()) {
297
- $ this ->denormalizerCache [$ format ][$ class ][$ k ] = false ;
298
- } elseif ($ normalizer ->supportsDenormalization (null , $ class , $ format , $ context )) {
299
- $ this ->denormalizerCache [$ format ][$ class ][$ k ] = true ;
323
+ $ support = $ this ->supportsDenormalizationWrapper ($ normalizer , $ data , $ class , $ format , $ context );
324
+ if (CacheableSupport::SupportNever === $ support ) {
325
+ continue ;
326
+ }
327
+
328
+ $ this ->denormalizerCache [$ format ][$ class ][$ k ] = $ support ;
329
+ if (CacheableSupport::SupportAlways === $ support ) {
300
330
break ;
301
331
}
302
332
}
303
333
}
304
334
305
335
foreach ($ this ->denormalizerCache [$ format ][$ class ] as $ k => $ cached ) {
306
336
$ normalizer = $ this ->normalizers [$ k ];
307
- if ($ cached || $ normalizer -> supportsDenormalization ( $ data , $ class , $ format , $ context )) {
337
+ if ($ cached-> value >= $ minCached -> value || ( $ cached -> value > $ minUncached -> value && $ this -> supportsDenormalizationWrapper ( $ normalizer , $ data , $ class , $ format , $ context)-> value > CacheableSupport::SupportNot-> value )) {
308
338
return $ normalizer ;
309
339
}
310
340
}
311
341
312
342
return null ;
313
343
}
314
344
345
+ /**
346
+ * Backwards-Compatibility layer for CacheableSupportsMethodInterface -> CacheableSupport.
347
+ */
348
+ private function supportsDenormalizationWrapper (DenormalizerInterface $ normalizer , mixed $ data , string $ class , ?string $ format , array $ context ): CacheableSupport
349
+ {
350
+ $ value = $ normalizer ->supportsDenormalization ($ data , $ class , $ format , $ context );
351
+ if (\is_bool ($ value )) {
352
+ trigger_deprecation ('symfony/serializer ' , '6.2 ' , 'Returning boolean from "%s::%s" is deprecated, return "%s" instead. ' , DenormalizerInterface::class, 'supports() ' , CacheableSupport::class);
353
+ }
354
+
355
+ return match ($ value ) {
356
+ true => $ normalizer instanceof CacheableSupportsMethodInterface && $ normalizer ->hasCacheableSupportsMethod () ? CacheableSupport::SupportAlways : CacheableSupport::Support,
357
+ false => $ normalizer instanceof CacheableSupportsMethodInterface && $ normalizer ->hasCacheableSupportsMethod () ? CacheableSupport::SupportNever : CacheableSupport::SupportNot,
358
+ default => $ value
359
+ };
360
+ }
361
+
315
362
final public function encode (mixed $ data , string $ format , array $ context = []): string
316
363
{
317
364
return $ this ->encoder ->encode ($ data , $ format , $ context );
0 commit comments