diff options
| author | Dmitry Stogov <dmitry@php.net> | 2006-02-01 17:18:24 +0000 |
|---|---|---|
| committer | Dmitry Stogov <dmitry@php.net> | 2006-02-01 17:18:24 +0000 |
| commit | 9774b6d3e63526f61ba98d0f53b3dd2304473980 (patch) | |
| tree | ceb797c3d0832e1c7ef9ce8f5f6dc4999ccbc3c3 | |
| parent | d115747a247c29165cc8fc7158e8429a97791f95 (diff) | |
| download | php-git-9774b6d3e63526f61ba98d0f53b3dd2304473980.tar.gz | |
Fixed encoding of inhereted objects
| -rw-r--r-- | ext/soap/php_encoding.c | 61 | ||||
| -rwxr-xr-x | ext/soap/tests/classmap003.phpt | 54 | ||||
| -rwxr-xr-x | ext/soap/tests/classmap003.wsdl | 51 |
3 files changed, 147 insertions, 19 deletions
diff --git a/ext/soap/php_encoding.c b/ext/soap/php_encoding.c index b4d4a49ff2..b9c663298d 100644 --- a/ext/soap/php_encoding.c +++ b/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); } @@ -1220,9 +1248,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; @@ -1526,7 +1554,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(); @@ -1534,19 +1562,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; @@ -1562,7 +1590,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"); @@ -1578,7 +1606,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); @@ -1595,7 +1626,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; @@ -1678,14 +1708,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); diff --git a/ext/soap/tests/classmap003.phpt b/ext/soap/tests/classmap003.phpt new file mode 100755 index 0000000000..c126709054 --- /dev/null +++ b/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 +) diff --git a/ext/soap/tests/classmap003.wsdl b/ext/soap/tests/classmap003.wsdl new file mode 100755 index 0000000000..494c41864e --- /dev/null +++ b/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>
|
