34
34
use Symfony \Component \Serializer \NameConverter \NameConverterInterface ;
35
35
use Symfony \Component \TypeInfo \Exception \LogicException as TypeInfoLogicException ;
36
36
use Symfony \Component \TypeInfo \Type ;
37
+ use Symfony \Component \TypeInfo \Type \BuiltinType ;
37
38
use Symfony \Component \TypeInfo \Type \CollectionType ;
38
39
use Symfony \Component \TypeInfo \Type \IntersectionType ;
40
+ use Symfony \Component \TypeInfo \Type \NullableType ;
39
41
use Symfony \Component \TypeInfo \Type \ObjectType ;
40
42
use Symfony \Component \TypeInfo \Type \UnionType ;
43
+ use Symfony \Component \TypeInfo \Type \WrappingTypeInterface ;
41
44
use Symfony \Component \TypeInfo \TypeIdentifier ;
42
45
43
46
/**
@@ -644,7 +647,14 @@ private function validateAndDenormalizeLegacy(array $types, string $currentClass
644
647
private function validateAndDenormalize (Type $ type , string $ currentClass , string $ attribute , mixed $ data , ?string $ format , array $ context ): mixed
645
648
{
646
649
$ expectedTypes = [];
647
- $ isUnionType = $ type ->asNonNullable () instanceof UnionType;
650
+
651
+ // BC layer for type-info < 7.2
652
+ if (method_exists (Type::class, 'asNonNullable ' )) {
653
+ $ isUnionType = $ type ->asNonNullable () instanceof UnionType;
654
+ } else {
655
+ $ isUnionType = $ type instanceof UnionType;
656
+ }
657
+
648
658
$ e = null ;
649
659
$ extraAttributesException = null ;
650
660
$ missingConstructorArgumentsException = null ;
@@ -667,12 +677,23 @@ private function validateAndDenormalize(Type $type, string $currentClass, string
667
677
$ collectionValueType = $ t ->getCollectionValueType ();
668
678
}
669
679
670
- $ t = $ t ->getBaseType ();
680
+ // BC layer for type-info < 7.2
681
+ if (method_exists (Type::class, 'getBaseType ' )) {
682
+ $ t = $ t ->getBaseType ();
683
+ } else {
684
+ while ($ t instanceof WrappingTypeInterface) {
685
+ $ t = $ t ->getWrappedType ();
686
+ }
687
+ }
671
688
672
689
// Fix a collection that contains the only one element
673
690
// This is special to xml format only
674
- if ('xml ' === $ format && $ collectionValueType && !$ collectionValueType ->isA (TypeIdentifier::MIXED ) && (!\is_array ($ data ) || !\is_int (key ($ data )))) {
675
- $ data = [$ data ];
691
+ if ('xml ' === $ format && $ collectionValueType && (!\is_array ($ data ) || !\is_int (key ($ data )))) {
692
+ // BC layer for type-info < 7.2
693
+ $ isMixedType = method_exists (Type::class, 'isA ' ) ? $ collectionValueType ->isA (TypeIdentifier::MIXED ) : $ collectionValueType ->isIdentifiedBy (TypeIdentifier::MIXED );
694
+ if (!$ isMixedType ) {
695
+ $ data = [$ data ];
696
+ }
676
697
}
677
698
678
699
// This try-catch should cover all NotNormalizableValueException (and all return branches after the first
@@ -695,7 +716,10 @@ private function validateAndDenormalize(Type $type, string $currentClass, string
695
716
return '' ;
696
717
}
697
718
698
- $ isNullable = $ isNullable ?: $ type ->isNullable ();
719
+ // BC layer for type-info < 7.2
720
+ if (method_exists (Type::class, 'isNullable ' )) {
721
+ $ isNullable = $ isNullable ?: $ type ->isNullable ();
722
+ }
699
723
}
700
724
701
725
switch ($ typeIdentifier ) {
@@ -732,7 +756,16 @@ private function validateAndDenormalize(Type $type, string $currentClass, string
732
756
733
757
if ($ collectionValueType ) {
734
758
try {
735
- $ collectionValueBaseType = $ collectionValueType ->getBaseType ();
759
+ $ collectionValueBaseType = $ collectionValueType ;
760
+
761
+ // BC layer for type-info < 7.2
762
+ if (!interface_exists (WrappingTypeInterface::class)) {
763
+ $ collectionValueBaseType = $ collectionValueType ->getBaseType ();
764
+ } else {
765
+ while ($ collectionValueBaseType instanceof WrappingTypeInterface) {
766
+ $ collectionValueBaseType = $ collectionValueBaseType ->getWrappedType ();
767
+ }
768
+ }
736
769
} catch (TypeInfoLogicException ) {
737
770
$ collectionValueBaseType = Type::mixed ();
738
771
}
@@ -742,15 +775,29 @@ private function validateAndDenormalize(Type $type, string $currentClass, string
742
775
$ class = $ collectionValueBaseType ->getClassName ().'[] ' ;
743
776
$ context ['key_type ' ] = $ collectionKeyType ;
744
777
$ context ['value_type ' ] = $ collectionValueType ;
745
- } elseif (TypeIdentifier::ARRAY === $ collectionValueBaseType ->getTypeIdentifier ()) {
778
+ } elseif (
779
+ // BC layer for type-info < 7.2
780
+ !class_exists (NullableType::class) && TypeIdentifier::ARRAY === $ collectionValueBaseType ->getTypeIdentifier ()
781
+ || $ collectionValueBaseType instanceof BuiltinType && TypeIdentifier::ARRAY === $ collectionValueBaseType ->getTypeIdentifier ()
782
+ ) {
746
783
// get inner type for any nested array
747
784
$ innerType = $ collectionValueType ;
785
+ if ($ innerType instanceof NullableType) {
786
+ $ innerType = $ innerType ->getWrappedType ();
787
+ }
748
788
749
789
// note that it will break for any other builtinType
750
790
$ dimensions = '[] ' ;
751
791
while ($ innerType instanceof CollectionType) {
752
792
$ dimensions .= '[] ' ;
753
793
$ innerType = $ innerType ->getCollectionValueType ();
794
+ if ($ innerType instanceof NullableType) {
795
+ $ innerType = $ innerType ->getWrappedType ();
796
+ }
797
+ }
798
+
799
+ while ($ innerType instanceof WrappingTypeInterface) {
800
+ $ innerType = $ innerType ->getWrappedType ();
754
801
}
755
802
756
803
if ($ innerType instanceof ObjectType) {
@@ -862,8 +909,15 @@ private function validateAndDenormalize(Type $type, string $currentClass, string
862
909
throw $ missingConstructorArgumentsException ;
863
910
}
864
911
865
- if (!$ isUnionType && $ e ) {
866
- throw $ e ;
912
+ // BC layer for type-info < 7.2
913
+ if (!class_exists (NullableType::class)) {
914
+ if (!$ isUnionType && $ e ) {
915
+ throw $ e ;
916
+ }
917
+ } else {
918
+ if ($ e && !($ type instanceof UnionType && !$ type instanceof NullableType)) {
919
+ throw $ e ;
920
+ }
867
921
}
868
922
869
923
if ($ context [self ::DISABLE_TYPE_ENFORCEMENT ] ?? $ this ->defaultContext [self ::DISABLE_TYPE_ENFORCEMENT ] ?? false ) {
0 commit comments