Skip to content

Commit 3bc3728

Browse files
committed
ext/soap: setting xml namespace in classmap
1 parent 90f2e76 commit 3bc3728

File tree

4 files changed

+199
-5
lines changed

4 files changed

+199
-5
lines changed

ext/soap/php_encoding.c

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -271,9 +271,20 @@ static encodePtr find_encoder_by_type_name(sdlPtr sdl, const char *type)
271271
encodePtr enc;
272272

273273
ZEND_HASH_FOREACH_PTR(sdl->encoders, enc) {
274-
if (strcmp(enc->details.type_str, type) == 0) {
275-
return enc;
276-
}
274+
275+
if (type[0] == '{') {
276+
size_t ns_len = strlen(enc->details.ns);
277+
if (strncmp(enc->details.ns, type + 1, ns_len) == 0
278+
&& type[ns_len + 1] == '}'
279+
&& strcmp(enc->details.type_str, type + ns_len + 2) == 0) {
280+
return enc;
281+
}
282+
} else {
283+
if (strcmp(enc->details.type_str, type) == 0) {
284+
return enc;
285+
}
286+
}
287+
277288
} ZEND_HASH_FOREACH_END();
278289
}
279290
return NULL;
@@ -1380,8 +1391,15 @@ static zval *to_zval_object_ex(zval *ret, encodeTypePtr type, xmlNodePtr data, z
13801391
} else if (SOAP_GLOBAL(class_map) && type->type_str) {
13811392
zval *classname;
13821393
zend_class_entry *tmp;
1383-
1384-
if ((classname = zend_hash_str_find_deref(SOAP_GLOBAL(class_map), type->type_str, strlen(type->type_str))) != NULL &&
1394+
classname = zend_hash_str_find_deref(SOAP_GLOBAL(class_map), type->type_str, strlen(type->type_str));
1395+
if(classname == NULL){
1396+
if (type->ns) {
1397+
zend_string *nscat =zend_strpprintf(0, "{%s}%s", type->ns, type->type_str);
1398+
classname = zend_hash_find_deref(SOAP_GLOBAL(class_map),nscat);
1399+
zend_string_release_ex(nscat, 0);
1400+
}
1401+
}
1402+
if (classname != NULL &&
13851403
Z_TYPE_P(classname) == IS_STRING &&
13861404
(tmp = zend_fetch_class(Z_STR_P(classname), ZEND_FETCH_CLASS_AUTO)) != NULL) {
13871405
ce = tmp;

ext/soap/tests/classmap005.phpt

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
--TEST--
2+
SOAP Classmap 5: SoapClient support for classmap with namespace
3+
--EXTENSIONS--
4+
soap
5+
--INI--
6+
soap.wsdl_cache_enabled=0
7+
--FILE--
8+
<?php
9+
class TestSoapClient extends SoapClient{
10+
function __doRequest($request, $location, $action, $version, $one_way = 0): ?string {
11+
return <<<EOF
12+
<?xml version="1.0" encoding="UTF-8"?>
13+
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://schemas.nothing.com" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body>
14+
<ns1:dotest2Response><res xsi:type="ns1:book">
15+
<a xsi:type="xsd:string">Blaat</a>
16+
<b xsi:type="xsd:string">aap</b>
17+
</res>
18+
</ns1:dotest2Response></SOAP-ENV:Body></SOAP-ENV:Envelope>
19+
EOF;
20+
}
21+
}
22+
23+
class bookNs{
24+
public $a="a";
25+
public $b="c";
26+
27+
}
28+
29+
$options=Array(
30+
'actor' =>'http://schema.nothing.com',
31+
'classmap' => array('{http://schemas.nothing.com}book'=>'bookNs', 'wsdltype2'=>'classname2')
32+
);
33+
34+
$client = new TestSoapClient(__DIR__."/classmap.wsdl",$options);
35+
$ret = $client->dotest2("???");
36+
var_dump($ret);
37+
echo "ok\n";
38+
?>
39+
--EXPECT--
40+
object(bookNs)#2 (2) {
41+
["a"]=>
42+
string(5) "Blaat"
43+
["b"]=>
44+
string(3) "aap"
45+
}
46+
ok

ext/soap/tests/classmap006.phpt

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
--TEST--
2+
SOAP Classmap 6: encoding of inherited objects with namespace
3+
--EXTENSIONS--
4+
soap
5+
--FILE--
6+
<?php
7+
ini_set("soap.wsdl_cache_enabled",0);
8+
9+
class A {
10+
public $x;
11+
function __construct($a){
12+
$this->x = $a;
13+
}
14+
}
15+
class Attest {
16+
public $x;
17+
function __construct($a){
18+
$this->x = $a;
19+
}
20+
}
21+
class B extends A {
22+
public $y;
23+
function __construct($a){
24+
parent::__construct($a);
25+
$this->y = $a + 1;
26+
}
27+
}
28+
29+
function f($input){
30+
return new B(5);
31+
}
32+
33+
class LocalSoapClient extends SoapClient {
34+
private $server;
35+
36+
function __construct($wsdl, $options) {
37+
parent::__construct($wsdl, $options);
38+
$this->server = new SoapServer($wsdl, $options);
39+
$this->server->addFunction("f");
40+
}
41+
42+
function __doRequest($request, $location, $action, $version, $one_way = 0): ?string {
43+
ob_start();
44+
$this->server->handle($request);
45+
$response = ob_get_contents();
46+
ob_end_clean();
47+
return $response;
48+
}
49+
}
50+
51+
$client = new LocalSoapClient(__DIR__."/classmap006.wsdl",
52+
array('classmap'=>array('A'=>'A','{urn:abt}At'=>'Attest','B'=>'B')));
53+
print_r($client->f(new Attest('test')));
54+
?>
55+
--EXPECT--
56+
B Object
57+
(
58+
[x] => 5
59+
[y] => 6
60+
)

ext/soap/tests/classmap006.wsdl

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<?xml version='1.0' encoding='UTF-8'?>
2+
3+
<!-- WSDL file generated by Zend Studio. -->
4+
5+
<definitions name="ab" targetNamespace="urn:ab" xmlns:typens="urn:ab" xmlns:typenst="urn:abt" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/">
6+
<types>
7+
<xsd:schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:ab">
8+
<xsd:complexType name="A">
9+
<xsd:sequence>
10+
<xsd:element name="x" type="xsd:anyType"/>
11+
</xsd:sequence>
12+
</xsd:complexType>
13+
<xsd:complexType name="B">
14+
<xsd:complexContent>
15+
<xsd:extension base="typens:A">
16+
<xsd:sequence>
17+
<xsd:element name="y" type="xsd:anyType"/>
18+
</xsd:sequence>
19+
</xsd:extension>
20+
</xsd:complexContent>
21+
</xsd:complexType>
22+
</xsd:schema>
23+
<xsd:schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:abt">
24+
<xsd:complexType name="At">
25+
<xsd:sequence>
26+
<xsd:element name="x" type="xsd:anyType"/>
27+
</xsd:sequence>
28+
</xsd:complexType>
29+
<xsd:complexType name="Bt">
30+
<xsd:complexContent>
31+
<xsd:extension base="typens:A">
32+
<xsd:sequence>
33+
<xsd:element name="y" type="xsd:anyType"/>
34+
</xsd:sequence>
35+
</xsd:extension>
36+
</xsd:complexContent>
37+
</xsd:complexType>
38+
</xsd:schema>
39+
40+
</types>
41+
<message name="f">
42+
<part name="fInput" type="xsd:anyType"/>
43+
</message>
44+
<message name="fResponse">
45+
<part name="fReturn" type="typens:A"/>
46+
</message>
47+
<portType name="abServerPortType">
48+
<operation name="f">
49+
<input message="typens:f"/>
50+
<output message="typens:fResponse"/>
51+
</operation>
52+
</portType>
53+
<binding name="abServerBinding" type="typens:abServerPortType">
54+
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
55+
<operation name="f">
56+
<soap:operation soapAction="urn:abServerAction"/>
57+
<input>
58+
<soap:body namespace="urn:ab" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
59+
</input>
60+
<output>
61+
<soap:body namespace="urn:ab" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
62+
</output>
63+
</operation>
64+
</binding>
65+
<service name="abService">
66+
<port name="abServerPort" binding="typens:abServerBinding">
67+
<soap:address location="http://localhost/abServer.php"/>
68+
</port>
69+
</service>
70+
</definitions>

0 commit comments

Comments
 (0)