cvs: php-src /ext/soap php_encoding.c /ext/soap/tests classmap003.phpt classmap003.wsdl
| From: | Dmitry Stogov | Date: | Wed, 01 Feb 2006 17:18:38 +0000 |
| Subject: | cvs: php-src /ext/soap php_encoding.c /ext/soap/tests classmap003.phpt classmap003.wsdl | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-36717@lists.php.net to get a copy of this message | ||
dmitry Wed Feb 1 17:18:38 2006 UTC
Modified files:
/php-src/ext/soap php_encoding.c
/php-src/ext/soap/tests classmap003.phpt classmap003.wsdl
Log:
Fixed encoding of inhereted objects
http://cvs.php.net/viewcvs.cgi/php-src/ext/soap/php_encoding.c?r1=1.117&r2=1.118&diff_format=u Index: php-src/ext/soap/php_encoding.c diff -u php-src/ext/soap/php_encoding.c:1.117 php-src/ext/soap/php_encoding.c:1.118 --- php-src/ext/soap/php_encoding.c:1.117 Sun Jan 1 13:09:53 2006 +++ php-src/ext/soap/php_encoding.c Wed Feb 1 17:18:38 2006 @@ -17,7 +17,7 @@ | Dmitry Stogov <dmitry@zend.com> | +----------------------------------------------------------------------+ */ -/* $Id: php_encoding.c,v 1.117 2006/01/01 13:09:53 sniper Exp $ */ +/* $Id: php_encoding.c,v 1.118 2006/02/01 17:18:38 dmitry Exp $ */ #include <time.h> @@ -306,6 +306,34 @@ 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 @@ 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 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 @@ 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 @@ 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 @@ 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 @@ xmlParam = xmlNewNode(NULL,"BOGUS"); xmlAddChild(parent, xmlParam); } - FIND_ZVAL_NULL(data, xmlParam, style); if (prop != NULL) { sdlTypePtr array_el; @@ -1679,14 +1709,7 @@ } 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); http://cvs.php.net/viewcvs.cgi/php-src/ext/soap/tests/classmap003.phpt?r1=1.1&r2=1.2&diff_format=u Index: php-src/ext/soap/tests/classmap003.phpt diff -u /dev/null php-src/ext/soap/tests/classmap003.phpt:1.2 --- /dev/null Wed Feb 1 17:18:38 2006 +++ php-src/ext/soap/tests/classmap003.phpt Wed Feb 1 17:18:38 2006 @@ -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 +) http://cvs.php.net/viewcvs.cgi/php-src/ext/soap/tests/classmap003.wsdl?r1=1.1&r2=1.2&diff_format=u Index: php-src/ext/soap/tests/classmap003.wsdl diff -u /dev/null php-src/ext/soap/tests/classmap003.wsdl:1.2 --- /dev/null Wed Feb 1 17:18:38 2006 +++ php-src/ext/soap/tests/classmap003.wsdl Wed Feb 1 17:18:38 2006 @@ -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>
http://cvs.php.net/viewcvs.cgi/php-src/ext/soap/php_encoding.c?r1=1.117&r2=1.118&diff_format=u Index: php-src/ext/soap/php_encoding.c diff -u php-src/ext/soap/php_encoding.c:1.117 php-src/ext/soap/php_encoding.c:1.118 --- php-src/ext/soap/php_encoding.c:1.117 Sun Jan 1 13:09:53 2006 +++ php-src/ext/soap/php_encoding.c Wed Feb 1 17:18:38 2006 @@ -17,7 +17,7 @@ | Dmitry Stogov <dmitry@zend.com> | +----------------------------------------------------------------------+ */ -/* $Id: php_encoding.c,v 1.117 2006/01/01 13:09:53 sniper Exp $ */ +/* $Id: php_encoding.c,v 1.118 2006/02/01 17:18:38 dmitry Exp $ */ #include <time.h> @@ -306,6 +306,34 @@ 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 @@ 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 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 @@ 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 @@ 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 @@ 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 @@ xmlParam = xmlNewNode(NULL,"BOGUS"); xmlAddChild(parent, xmlParam); } - FIND_ZVAL_NULL(data, xmlParam, style); if (prop != NULL) { sdlTypePtr array_el; @@ -1679,14 +1709,7 @@ } 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); http://cvs.php.net/viewcvs.cgi/php-src/ext/soap/tests/classmap003.phpt?r1=1.1&r2=1.2&diff_format=u Index: php-src/ext/soap/tests/classmap003.phpt diff -u /dev/null php-src/ext/soap/tests/classmap003.phpt:1.2 --- /dev/null Wed Feb 1 17:18:38 2006 +++ php-src/ext/soap/tests/classmap003.phpt Wed Feb 1 17:18:38 2006 @@ -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 +) http://cvs.php.net/viewcvs.cgi/php-src/ext/soap/tests/classmap003.wsdl?r1=1.1&r2=1.2&diff_format=u Index: php-src/ext/soap/tests/classmap003.wsdl diff -u /dev/null php-src/ext/soap/tests/classmap003.wsdl:1.2 --- /dev/null Wed Feb 1 17:18:38 2006 +++ php-src/ext/soap/tests/classmap003.wsdl Wed Feb 1 17:18:38 2006 @@ -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>