6
6
use Soap \Encoding \Normalizer \PhpPropertyNameNormalizer ;
7
7
use Soap \Encoding \TypeInference \ComplexTypeBuilder ;
8
8
use Soap \Engine \Metadata \Model \Property ;
9
+ use Soap \Engine \Metadata \Model \Type ;
9
10
use Soap \Engine \Metadata \Model \TypeMeta ;
10
11
use VeeWee \Reflecta \Iso \Iso ;
11
12
use VeeWee \Reflecta \Lens \Lens ;
@@ -47,17 +48,21 @@ public static function forContext(Context $context): self
47
48
$ isAnyPropertyQualified = false ;
48
49
49
50
foreach ($ sortedProperties as $ property ) {
50
- $ typeMeta = $ property ->getType ()->getMeta ();
51
+ $ propertyType = $ property ->getType ();
52
+ $ propertyTypeMeta = $ propertyType ->getMeta ();
53
+ $ propertyContext = $ context ->withType ($ propertyType );
51
54
$ name = $ property ->getName ();
52
55
$ normalizedName = PhpPropertyNameNormalizer::normalize ($ name );
53
56
54
- $ shouldLensBeOptional = self ::shouldLensBeOptional ($ typeMeta );
57
+ $ encoder = $ context ->registry ->detectEncoderForContext ($ propertyContext );
58
+ $ shouldLensBeOptional = self ::shouldLensBeOptional ($ propertyTypeMeta );
55
59
$ normalizedProperties [$ normalizedName ] = $ property ;
56
- $ encoderLenses [$ normalizedName ] = $ shouldLensBeOptional ? optional (property ($ normalizedName )) : property ($ normalizedName );
57
- $ decoderLenses [$ normalizedName ] = $ shouldLensBeOptional ? optional (index ($ name )) : index ($ name );
58
- $ isos [$ normalizedName ] = self ::grabIsoForProperty ($ context , $ property );
59
60
60
- $ isAnyPropertyQualified = $ isAnyPropertyQualified || $ typeMeta ->isQualified ()->unwrapOr (false );
61
+ $ encoderLenses [$ normalizedName ] = self ::createEncoderLensForType ($ shouldLensBeOptional , $ normalizedName , $ encoder , $ type , $ property );
62
+ $ decoderLenses [$ normalizedName ] = self ::createDecoderLensForType ($ shouldLensBeOptional , $ name , $ encoder , $ type , $ property );
63
+ $ isos [$ normalizedName ] = $ encoder ->iso ($ propertyContext );
64
+
65
+ $ isAnyPropertyQualified = $ isAnyPropertyQualified || $ propertyTypeMeta ->isQualified ()->unwrapOr (false );
61
66
}
62
67
63
68
return new self (
@@ -69,6 +74,46 @@ public static function forContext(Context $context): self
69
74
);
70
75
}
71
76
77
+ /**
78
+ * @return Lens<object, mixed>
79
+ */
80
+ private static function createEncoderLensForType (
81
+ bool $ shouldLensBeOptional ,
82
+ string $ normalizedName ,
83
+ XmlEncoder $ encoder ,
84
+ Type $ type ,
85
+ Property $ property ,
86
+ ): Lens {
87
+ $ lens = match (true ) {
88
+ $ encoder instanceof Feature \DecoratingEncoder => self ::createEncoderLensForType ($ shouldLensBeOptional , $ normalizedName , $ encoder ->decoratedEncoder (), $ type , $ property ),
89
+ $ encoder instanceof Feature \ProvidesObjectEncoderLens => $ encoder ::createObjectEncoderLens ($ type , $ property ),
90
+ default => property ($ normalizedName )
91
+ };
92
+
93
+ /** @var Lens<object, mixed> */
94
+ return $ shouldLensBeOptional ? optional ($ lens ) : $ lens ;
95
+ }
96
+
97
+ /**
98
+ * @return Lens<array, mixed>
99
+ */
100
+ private static function createDecoderLensForType (
101
+ bool $ shouldLensBeOptional ,
102
+ string $ name ,
103
+ XmlEncoder $ encoder ,
104
+ Type $ type ,
105
+ Property $ property ,
106
+ ): Lens {
107
+ $ lens = match (true ) {
108
+ $ encoder instanceof Feature \DecoratingEncoder => self ::createDecoderLensForType ($ shouldLensBeOptional , $ name , $ encoder ->decoratedEncoder (), $ type , $ property ),
109
+ $ encoder instanceof Feature \ProvidesObjectDecoderLens => $ encoder ::createObjectDecoderLens ($ type , $ property ),
110
+ default => index ($ name ),
111
+ };
112
+
113
+ /** @var Lens<array, mixed> */
114
+ return $ shouldLensBeOptional ? optional ($ lens ) : $ lens ;
115
+ }
116
+
72
117
private static function shouldLensBeOptional (TypeMeta $ meta ): bool
73
118
{
74
119
if ($ meta ->isNullable ()->unwrapOr (false )) {
@@ -84,15 +129,4 @@ private static function shouldLensBeOptional(TypeMeta $meta): bool
84
129
85
130
return false ;
86
131
}
87
-
88
- /**
89
- * @return Iso<mixed, string>
90
- */
91
- private static function grabIsoForProperty (Context $ context , Property $ property ): Iso
92
- {
93
- $ propertyContext = $ context ->withType ($ property ->getType ());
94
-
95
- return $ context ->registry ->detectEncoderForContext ($ propertyContext )
96
- ->iso ($ propertyContext );
97
- }
98
132
}
0 commit comments