Skip to content

Commit f116186

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

File tree

4 files changed

+212
-2
lines changed

4 files changed

+212
-2
lines changed

ext/soap/php_encoding.c

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,20 @@ static encodePtr find_encoder_by_type_name(sdlPtr sdl, const char *type)
274274
if (strcmp(enc->details.type_str, type) == 0) {
275275
return enc;
276276
}
277+
int ns_len = strlen(enc->details.ns);
278+
int type_len = strlen(enc->details.type_str);
279+
int len = ns_len + type_len + 2;
280+
char *nscat = emalloc(len+1);
281+
nscat[0] = '{';
282+
memcpy(nscat+1,enc->details.ns,ns_len);
283+
nscat[ns_len+1] = '}';
284+
memcpy(nscat+ns_len+2, enc->details.type_str, type_len);
285+
nscat[len] = '\0';
286+
if (strcmp(nscat, type) == 0) {
287+
efree(nscat);
288+
return enc;
289+
}
290+
efree(nscat);
277291
} ZEND_HASH_FOREACH_END();
278292
}
279293
return NULL;
@@ -1380,8 +1394,24 @@ static zval *to_zval_object_ex(zval *ret, encodeTypePtr type, xmlNodePtr data, z
13801394
} else if (SOAP_GLOBAL(class_map) && type->type_str) {
13811395
zval *classname;
13821396
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 &&
1397+
classname = zend_hash_str_find_deref(SOAP_GLOBAL(class_map), type->type_str, strlen(type->type_str));
1398+
if(classname == NULL){
1399+
if (type->ns) {
1400+
int ns_len = strlen(type->ns);
1401+
int type_len = strlen(type->type_str);
1402+
int len = ns_len + type_len + 2;
1403+
char *nscat = emalloc(len+1);
1404+
nscat[0] = '{';
1405+
memcpy(nscat+1,type->ns,ns_len);
1406+
nscat[ns_len+1] = '}';
1407+
memcpy(nscat+ns_len+2, type->type_str, type_len);
1408+
nscat[len] = '\0';
1409+
classname = zend_hash_str_find_deref(SOAP_GLOBAL(class_map), nscat, strlen(nscat));
1410+
1411+
efree(nscat);
1412+
}
1413+
}
1414+
if (classname != NULL &&
13851415
Z_TYPE_P(classname) == IS_STRING &&
13861416
(tmp = zend_fetch_class(Z_STR_P(classname), ZEND_FETCH_CLASS_AUTO)) != NULL) {
13871417
ce = tmp;

ext/soap/tests/classmap005.phpt

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
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+
class book{
29+
public $a="a";
30+
public $b="c";
31+
32+
}
33+
34+
$options=Array(
35+
'actor' =>'http://schema.nothing.com',
36+
'classmap' => array('{http://schemas.nothing.com}book'=>'bookNs', 'wsdltype2'=>'classname2')
37+
);
38+
39+
$client = new TestSoapClient(__DIR__."/classmap.wsdl",$options);
40+
$ret = $client->dotest2("???");
41+
var_dump($ret);
42+
echo "ok\n";
43+
?>
44+
--EXPECT--
45+
object(bookNs)#2 (2) {
46+
["a"]=>
47+
string(5) "Blaat"
48+
["b"]=>
49+
string(3) "aap"
50+
}
51+
ok

ext/soap/tests/classmap006.phpt

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
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+
35+
function __construct($wsdl, $options) {
36+
parent::__construct($wsdl, $options);
37+
$this->server = new SoapServer($wsdl, $options);
38+
$this->server->addFunction("f");
39+
}
40+
41+
function __doRequest($request, $location, $action, $version, $one_way = 0): ?string {
42+
ob_start();
43+
$this->server->handle($request);
44+
$response = ob_get_contents();
45+
ob_end_clean();
46+
return $response;
47+
}
48+
}
49+
50+
$client = new LocalSoapClient(__DIR__."/classmap006.wsdl",
51+
array('classmap'=>array('A'=>'A','{urn:abt}At'=>'Attest','B'=>'B')));
52+
print_r($client->f(new Attest('test')));
53+
?>
54+
--EXPECT--
55+
B Object
56+
(
57+
[x] => 5
58+
[y] => 6
59+
)

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)