55
66use Generator ;
77use Soap \Encoding \Encoder \Context ;
8- use Soap \Encoding \Encoder \Feature \ CData ;
8+ use Soap \Encoding \Encoder \Feature ;
99use Soap \Encoding \Encoder \XmlEncoder ;
1010use Soap \Encoding \TypeInference \XsiTypeDetector ;
1111use Soap \WsdlReader \Model \Definitions \BindingUse ;
@@ -48,16 +48,45 @@ private function buildXsiType(XMLWriter $writer): Generator
4848 }
4949
5050 $ context = $ this ->context ;
51- $ type = $ context ->type ;
51+ [$ xsiType , $ includeXsiTargetNamespace ] = match (true ) {
52+ $ this ->encoder instanceof Feature \XsiTypeCalculator => [
53+ $ this ->encoder ->resolveXsiTypeForValue ($ context , $ this ->value ),
54+ $ this ->encoder ->shouldIncludeXsiTargetNamespace ($ context ),
55+ ],
56+ default => [
57+ self ::resolveXsiTypeForValue ($ context , $ this ->value ),
58+ self ::shouldIncludeXsiTargetNamespace ($ context ),
59+ ],
60+ };
5261
5362 yield from (new XsiAttributeBuilder (
5463 $ this ->context ,
55- XsiTypeDetector::detectFromValue ($ context , $ this ->value ),
56- includeXsiTargetNamespace: $ type ->getXmlTargetNamespace () !== $ type ->getXmlNamespace ()
57- || !$ type ->getMeta ()->isQualified ()->unwrapOr (false )
64+ $ xsiType ,
65+ $ includeXsiTargetNamespace ,
5866 ))($ writer );
5967 }
6068
69+ /**
70+ * Can be used as a default fallback function when implementing the XsiTypeCalculator interface.
71+ * Tells the XsiAttributeBuilder what xsi:type attribute should be set to for a given value.
72+ */
73+ public static function resolveXsiTypeForValue (Context $ context , mixed $ value ): string
74+ {
75+ return XsiTypeDetector::detectFromValue ($ context , $ value );
76+ }
77+
78+ /**
79+ * Can be used as a default fallback function when implementing the XsiTypeCalculator interface.
80+ * Tells the XsiAttributeBuilder that the prefix of the xsi:type should be imported as a xmlns namespace.
81+ */
82+ public static function shouldIncludeXsiTargetNamespace (Context $ context ): bool
83+ {
84+ $ type = $ context ->type ;
85+
86+ return $ type ->getXmlTargetNamespace () !== $ type ->getXmlNamespace ()
87+ || !$ type ->getMeta ()->isQualified ()->unwrapOr (false );
88+ }
89+
6190 /**
6291 * @return Generator<bool>
6392 */
@@ -66,7 +95,7 @@ private function buildValue(XMLWriter $writer): Generator
6695 $ encoded = $ this ->encoder ->iso ($ this ->context )->to ($ this ->value );
6796
6897 $ builder = match (true ) {
69- $ this ->encoder instanceof CData => cdata (value ($ encoded )),
98+ $ this ->encoder instanceof Feature \ CData => cdata (value ($ encoded )),
7099 default => value ($ encoded )
71100 };
72101
0 commit comments