5
5
6
6
use Closure ;
7
7
use DOMElement ;
8
- use Generator ;
9
8
use Soap \Encoding \Encoder \Context ;
10
9
use Soap \Encoding \Encoder \Feature \ListAware ;
11
- use Soap \Encoding \Encoder \SimpleType \ScalarTypeEncoder ;
12
10
use Soap \Encoding \Encoder \XmlEncoder ;
13
11
use Soap \Encoding \TypeInference \XsiTypeDetector ;
14
12
use Soap \Encoding \Xml \Node \Element ;
15
- use Soap \Encoding \Xml \Reader \ElementValueReader ;
16
13
use Soap \Encoding \Xml \Writer \XsdTypeXmlElementWriter ;
17
14
use Soap \Encoding \Xml \Writer \XsiAttributeBuilder ;
18
- use Soap \Engine \Metadata \Model \XsdType ;
19
15
use Soap \WsdlReader \Model \Definitions \BindingUse ;
20
- use Soap \WsdlReader \Parser \Xml \QnameParser ;
21
16
use VeeWee \Reflecta \Iso \Iso ;
22
- use XMLWriter ;
23
17
use function count ;
18
+ use function Psl \Fun \lazy ;
24
19
use function Psl \Vec \map ;
25
20
use function VeeWee \Xml \Dom \Locator \Element \children as readChildren ;
26
21
use function VeeWee \Xml \Writer \Builder \children ;
27
- use function VeeWee \Xml \Writer \Builder \element ;
28
- use function VeeWee \Xml \Writer \Builder \namespaced_element ;
29
22
use function VeeWee \Xml \Writer \Builder \prefixed_attribute ;
30
- use function VeeWee \Xml \Writer \Builder \value as buildValue ;
23
+ use function VeeWee \Xml \Writer \Builder \raw as buildRaw ;
31
24
32
25
/**
33
26
* @implements XmlEncoder<list<mixed>, non-empty-string>
@@ -39,39 +32,35 @@ final class SoapArrayEncoder implements ListAware, XmlEncoder
39
32
*/
40
33
public function iso (Context $ context ): Iso
41
34
{
35
+ $ arrayAccess = lazy (static fn (): SoapArrayAccess => SoapArrayAccess::forContext ($ context ));
36
+
42
37
return (new Iso (
43
38
/**
44
39
* @param list<mixed> $value
45
40
* @return non-empty-string
46
41
*/
47
- fn (array $ value ): string => $ this ->encodeArray ($ context , $ value ),
42
+ fn (array $ value ): string => $ this ->encodeArray ($ context , $ arrayAccess (), $ value ),
48
43
/**
49
44
* @param non-empty-string|Element $value
50
45
* @return list<mixed>
51
46
*/
52
47
fn (string |Element $ value ): array => $ this ->decodeArray (
53
48
$ context ,
49
+ $ arrayAccess (),
54
50
$ value instanceof Element ? $ value : Element::fromString ($ value )
55
51
),
56
52
));
57
53
}
58
54
55
+
59
56
/**
60
57
* @param list<mixed> $data
61
58
*
62
59
* @return non-empty-string
63
60
*/
64
- private function encodeArray (Context $ context , array $ data ): string
61
+ private function encodeArray (Context $ context , SoapArrayAccess $ arrayAccess , array $ data ): string
65
62
{
66
- $ type = $ context ->type ;
67
- $ meta = $ type ->getMeta ();
68
- $ itemNodeName = $ meta ->arrayNodeName ()->unwrapOr (null );
69
- $ itemType = $ meta ->arrayType ()
70
- ->map (static fn (array $ info ): string => $ info ['itemType ' ])
71
- ->unwrapOr (XsiTypeDetector::detectFromValue (
72
- $ context ->withType (XsdType::any ()),
73
- $ data [0 ] ?? null
74
- ));
63
+ $ iso = $ arrayAccess ->itemEncoder ->iso ($ arrayAccess ->itemContext );
75
64
76
65
return (new XsdTypeXmlElementWriter ())(
77
66
$ context ,
@@ -86,66 +75,35 @@ private function encodeArray(Context $context, array $data): string
86
75
prefixed_attribute (
87
76
'SOAP-ENC ' ,
88
77
'arrayType ' ,
89
- $ itemType . '[ ' .count ($ data ).'] '
78
+ $ arrayAccess -> xsiType . '[ ' .count ($ data ).'] '
90
79
),
91
80
]
92
81
: []
93
82
),
94
83
...map (
95
84
$ data ,
96
- fn (mixed $ value ): Closure => $ this -> itemElement ( $ context , $ itemNodeName , $ itemType , $ value )
85
+ static fn (mixed $ value ): Closure => buildRaw (( string ) $ iso -> to ( $ value) )
97
86
)
98
87
])
99
88
);
100
89
}
101
90
102
- /**
103
- * @psalm-param mixed $value
104
- * @return Closure(XMLWriter): Generator<bool>
105
- */
106
- private function itemElement (Context $ context , ?string $ itemNodeName , string $ itemType , mixed $ value ): Closure
107
- {
108
- $ buildValue = buildValue (ScalarTypeEncoder::default ()->iso ($ context )->to ($ value ));
109
-
110
- if ($ context ->bindingUse === BindingUse::ENCODED || $ itemNodeName !== null ) {
111
- return element (
112
- $ itemNodeName ?? 'item ' ,
113
- children ([
114
- (new XsiAttributeBuilder ($ context , $ itemType )),
115
- $ buildValue
116
- ])
117
- );
118
- }
119
-
120
- [$ prefix , $ localName ] = (new QnameParser ())($ itemType );
121
-
122
- return namespaced_element (
123
- $ context ->namespaces ->lookupNamespaceFromName ($ prefix )->unwrap (),
124
- $ prefix ,
125
- $ localName ,
126
- $ buildValue
127
- );
128
- }
129
-
130
91
/**
131
92
* @return list<mixed>
132
93
*/
133
- private function decodeArray (Context $ context , Element $ value ): array
94
+ private function decodeArray (Context $ context , SoapArrayAccess $ arrayAccess , Element $ value ): array
134
95
{
135
96
$ element = $ value ->element ();
97
+ $ iso = $ arrayAccess ->itemEncoder ->iso ($ arrayAccess ->itemContext );
136
98
137
99
return readChildren ($ element )->reduce (
138
100
/**
139
101
* @param list<mixed> $list
140
102
* @return list<mixed>
141
103
*/
142
- static function (array $ list , DOMElement $ item ) use ($ context ): array {
143
- /** @psalm-var mixed $value */
144
- $ value = (new ElementValueReader ())(
145
- $ context ->withType (XsdType::any ()),
146
- ScalarTypeEncoder::default (),
147
- $ item
148
- );
104
+ static function (array $ list , DOMElement $ item ) use ($ iso ): array {
105
+ /** @var mixed $value */
106
+ $ value = $ iso ->from (Element::fromDOMElement ($ item ));
149
107
150
108
return [...$ list , $ value ];
151
109
},
0 commit comments