From: Dmitry Stogov Date: Wed, 1 Feb 2006 17:18:38 +0000 (+0000) Subject: Fixed encoding of inhereted objects X-Git-Tag: RELEASE_1_2~321 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d4a61bb8de127ec81615576f108d71fa89068467;p=php Fixed encoding of inhereted objects --- diff --git a/ext/soap/php_encoding.c b/ext/soap/php_encoding.c index d03cdb2a93..20e0dab5cf 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); } @@ -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); 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-- + +--FILE-- +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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +