Browse Source

Fixed encoding of inhereted objects

migration/RELEASE_1_0_0
Dmitry Stogov 21 years ago
parent
commit
d4a61bb8de
  1. 61
      ext/soap/php_encoding.c
  2. 54
      ext/soap/tests/classmap003.phpt
  3. 51
      ext/soap/tests/classmap003.wsdl

61
ext/soap/php_encoding.c

@ -306,6 +306,34 @@ xmlNodePtr master_to_xml(encodePtr encode, zval *data, int style, xmlNodePtr par
xmlSetNs(node, nsp);
}
} else {
if (SOAP_GLOBAL(class_map) && data &&
Z_TYPE_P(data) == IS_OBJECT &&
!Z_OBJPROP_P(data)->nApplyCount) {
zend_class_entry *ce = Z_OBJCE_P(data);
HashPosition pos;
zval **tmp;
char *type_name = NULL;
uint type_len;
ulong idx;
for (zend_hash_internal_pointer_reset_ex(SOAP_GLOBAL(class_map), &pos);
zend_hash_get_current_data_ex(SOAP_GLOBAL(class_map), (void **) &tmp, &pos) == SUCCESS;
zend_hash_move_forward_ex(SOAP_GLOBAL(class_map), &pos)) {
if (Z_TYPE_PP(tmp) == IS_STRING &&
ce->name_length == Z_STRLEN_PP(tmp) &&
zend_binary_strncasecmp(ce->name, ce->name_length, Z_STRVAL_PP(tmp), ce->name_length, ce->name_length) == 0 &&
zend_hash_get_current_key_ex(SOAP_GLOBAL(class_map), &type_name, &type_len, &idx, 0, &pos) == HASH_KEY_IS_STRING) {
/* TODO: namespace isn't stored */
encodePtr enc = get_encoder(SOAP_GLOBAL(sdl), SOAP_GLOBAL(sdl)->target_ns, type_name);
if (enc) {
encode = &enc->details;
}
break;
}
}
}
if (encode == NULL) {
encode = get_conversion(UNKNOWN_TYPE);
}
@ -1221,9 +1249,9 @@ static zval *to_zval_object(encodeTypePtr type, xmlNodePtr data)
ret = master_to_zval_int(sdlType->encode, data);
FIND_XML_NULL(data, ret);
if (get_zval_property(ret, "any" TSRMLS_CC) != NULL) {
unset_zval_property(ret, "any" TSRMLS_CC);
unset_zval_property(ret, "any" TSRMLS_CC);
redo_any = 1;
}
}
if (Z_TYPE_P(ret) == IS_OBJECT && ce != ZEND_STANDARD_CLASS_DEF_PTR) {
zend_object *zobj = zend_objects_get_address(ret TSRMLS_CC);
zobj->ce = ce;
@ -1527,7 +1555,7 @@ static sdlTypePtr model_array_element(sdlContentModelPtr model)
static xmlNodePtr to_xml_object(encodeTypePtr type, zval *data, int style, xmlNodePtr parent)
{
xmlNodePtr xmlParam;
HashTable *prop;
HashTable *prop = NULL;
int i;
sdlTypePtr sdlType = type->sdl_type;
TSRMLS_FETCH();
@ -1535,19 +1563,19 @@ static xmlNodePtr to_xml_object(encodeTypePtr type, zval *data, int style, xmlNo
if (!data || Z_TYPE_P(data) == IS_NULL) {
xmlParam = xmlNewNode(NULL,"BOGUS");
xmlAddChild(parent, xmlParam);
if (style == SOAP_ENCODED) {
if (style == SOAP_ENCODED) {
xmlSetProp(xmlParam, "xsi:nil", "true");
}
return xmlParam;
}
if (Z_TYPE_P(data) == IS_OBJECT) {
prop = Z_OBJPROP_P(data);
} else if (Z_TYPE_P(data) == IS_ARRAY) {
prop = Z_ARRVAL_P(data);
}
if (sdlType) {
prop = NULL;
if (Z_TYPE_P(data) == IS_OBJECT) {
prop = Z_OBJPROP_P(data);
} else if (Z_TYPE_P(data) == IS_ARRAY) {
prop = Z_ARRVAL_P(data);
}
if (sdlType->kind == XSD_TYPEKIND_RESTRICTION &&
sdlType->encode && type != &sdlType->encode->details) {
encodePtr enc;
@ -1563,7 +1591,7 @@ static xmlNodePtr to_xml_object(encodeTypePtr type, zval *data, int style, xmlNo
zval *tmp = get_zval_property(data, "_" TSRMLS_CC);
if (tmp) {
xmlParam = master_to_xml(enc, tmp, style, parent);
} else if (prop == NULL) {
} else if (prop == NULL) {
xmlParam = master_to_xml(enc, data, style, parent);
} else {
xmlParam = xmlNewNode(NULL,"BOGUS");
@ -1579,7 +1607,10 @@ static xmlNodePtr to_xml_object(encodeTypePtr type, zval *data, int style, xmlNo
sdlType->encode->details.sdl_type->kind != XSD_TYPEKIND_SIMPLE &&
sdlType->encode->details.sdl_type->kind != XSD_TYPEKIND_LIST &&
sdlType->encode->details.sdl_type->kind != XSD_TYPEKIND_UNION) {
if (prop) prop->nApplyCount++;
xmlParam = master_to_xml(sdlType->encode, data, style, parent);
if (prop) prop->nApplyCount--;
} else {
zval *tmp = get_zval_property(data, "_" TSRMLS_CC);
@ -1596,7 +1627,6 @@ static xmlNodePtr to_xml_object(encodeTypePtr type, zval *data, int style, xmlNo
xmlParam = xmlNewNode(NULL,"BOGUS");
xmlAddChild(parent, xmlParam);
}
FIND_ZVAL_NULL(data, xmlParam, style);
if (prop != NULL) {
sdlTypePtr array_el;
@ -1679,14 +1709,7 @@ static xmlNodePtr to_xml_object(encodeTypePtr type, zval *data, int style, xmlNo
} else {
xmlParam = xmlNewNode(NULL,"BOGUS");
xmlAddChild(parent, xmlParam);
FIND_ZVAL_NULL(data, xmlParam, style);
prop = NULL;
if (Z_TYPE_P(data) == IS_OBJECT) {
prop = Z_OBJPROP_P(data);
} else if (Z_TYPE_P(data) == IS_ARRAY) {
prop = Z_ARRVAL_P(data);
}
if (prop != NULL) {
i = zend_hash_num_elements(prop);
zend_hash_internal_pointer_reset(prop);

54
ext/soap/tests/classmap003.phpt

@ -0,0 +1,54 @@
--TEST--
SOAP Classmap 3: encoding of inherited objects
--SKIPIF--
<?php require_once('skipif.inc'); ?>
--FILE--
<?php
ini_set("soap.wsdl_cache_enabled",0);
class A {
public $x;
function __construct($a){
$this->x = $a;
}
}
class B extends A {
public $y;
function __construct($a){
parent::__construct($a);
$this->y = $a + 1;
}
}
function f(){
return new B(5);
}
class LocalSoapClient extends SoapClient {
function __construct($wsdl, $options) {
parent::__construct($wsdl, $options);
$this->server = new SoapServer($wsdl, $options);
$this->server->addFunction("f");
}
function __doRequest($request, $location, $action, $version) {
ob_start();
$this->server->handle($request);
$response = ob_get_contents();
ob_end_clean();
return $response;
}
}
$client = new LocalSoapClient(dirname(__FILE__)."/classmap003.wsdl",
array('classmap'=>array('A'=>'A','B'=>'B')));
print_r($client->f());
?>
--EXPECT--
B Object
(
[x] => 5
[y] => 6
)

51
ext/soap/tests/classmap003.wsdl

@ -0,0 +1,51 @@
<?xml version='1.0' encoding='UTF-8'?>
<!-- WSDL file generated by Zend Studio. -->
<definitions name="ab" targetNamespace="urn:ab" xmlns:typens="urn:ab" 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/">
<types>
<xsd:schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:ab">
<xsd:complexType name="A">
<xsd:sequence>
<xsd:element name="x" type="xsd:anyType"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="B">
<xsd:complexContent>
<xsd:extension base="typens:A">
<xsd:sequence>
<xsd:element name="y" type="xsd:anyType"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:schema>
</types>
<message name="f"/>
<message name="fResponse">
<part name="fReturn" type="typens:A"/>
</message>
<portType name="abServerPortType">
<operation name="f">
<input message="typens:f"/>
<output message="typens:fResponse"/>
</operation>
</portType>
<binding name="abServerBinding" type="typens:abServerPortType">
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="f">
<soap:operation soapAction="urn:abServerAction"/>
<input>
<soap:body namespace="urn:ab" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
</input>
<output>
<soap:body namespace="urn:ab" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
</output>
</operation>
</binding>
<service name="abService">
<port name="abServerPort" binding="typens:abServerBinding">
<soap:address location="http://localhost/abServer.php"/>
</port>
</service>
</definitions>
Loading…
Cancel
Save