From: Dmitry Stogov Date: Thu, 27 Sep 2007 10:01:43 +0000 (+0000) Subject: Improved ext/soap to support element names in context of XMLShema's X-Git-Tag: BEFORE_IMPORT_OF_MYSQLND_IN_5_3~87 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=10150ea755337832ab186ac66c87066344b76ddd;p=php Improved ext/soap to support element names in context of XMLShema's --- diff --git a/NEWS b/NEWS index 0d339e74a4..4f190ffe00 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,8 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? 20??, PHP 5.3.0 +- Improved ext/soap to support element names in context of XMLShema's . + (Dmitry) - Improved ext/openssl (Dmitry) . Added support for OpenSSL digest functions . Added support for OpenSSL cipher functions diff --git a/ext/soap/php_encoding.c b/ext/soap/php_encoding.c index 8354f87ace..2f7008b5b2 100644 --- a/ext/soap/php_encoding.c +++ b/ext/soap/php_encoding.c @@ -1254,44 +1254,82 @@ static void unset_zval_property(zval* object, char* name TSRMLS_DC) static void model_to_zval_any(zval *ret, xmlNodePtr node TSRMLS_DC) { zval* any = NULL; + char* name = NULL; while (node != NULL) { if (get_zval_property(ret, (char*)node->name TSRMLS_CC) == NULL) { zval* val = master_to_zval(get_conversion(XSD_ANYXML), node); - if (get_attribute_ex(node->properties,"type", XSI_NAMESPACE) == NULL && - Z_TYPE_P(val) == IS_STRING) { - while (node->next != NULL && - get_zval_property(ret, (char*)node->next->name TSRMLS_CC) == NULL && - get_attribute_ex(node->next->properties,"type", XSI_NAMESPACE) == NULL) { + + if (any && Z_TYPE_P(any) != IS_ARRAY) { + /* Convert into array */ + zval *arr; + + MAKE_STD_ZVAL(arr); + array_init(arr); + if (name) { + add_assoc_zval(arr, name, any); + } else { + add_next_index_zval(arr, any); + } + any = arr; + } + + if (Z_TYPE_P(val) == IS_STRING && *Z_STRVAL_P(val) == '<') { + name = NULL; + while (node->next != NULL) { zval* val2 = master_to_zval(get_conversion(XSD_ANYXML), node->next); - if (Z_TYPE_P(val2) != IS_STRING) { + if (Z_TYPE_P(val2) != IS_STRING || *Z_STRVAL_P(val) != '<') { break; } add_string_to_string(val, val, val2); zval_ptr_dtor(&val2); node = node->next; } + } else { + name = (char*)node->name; } + if (any == NULL) { - any = val; - } else { - if (Z_TYPE_P(any) != IS_ARRAY) { + if (name) { /* Convert into array */ zval *arr; MAKE_STD_ZVAL(arr); array_init(arr); - add_next_index_zval(arr, any); + add_assoc_zval(arr, name, val); any = arr; + name = NULL; + } else { + any = val; } + } else { /* Add array element */ - add_next_index_zval(any, val); + if (name) { + zval **el; + if (zend_hash_find(Z_ARRVAL_P(any), name, strlen(name)+1, (void**)&el) == SUCCESS) { + if (Z_TYPE_PP(el) != IS_ARRAY) { + /* Convert into array */ + zval *arr; + + MAKE_STD_ZVAL(arr); + array_init(arr); + add_next_index_zval(arr, *el); + *el = arr; + } + add_next_index_zval(*el, val); + } else { + add_assoc_zval(any, name, val); + } + } else { + add_next_index_zval(any, val); + } + name = NULL; } } node = node->next; } if (any) { - set_zval_property(ret, "any", any TSRMLS_CC); + set_zval_property(ret, name ? name : "any", any TSRMLS_CC); } } @@ -3039,6 +3077,26 @@ static zval *to_zval_any(encodeTypePtr type, xmlNodePtr data) { xmlBufferPtr buf; zval *ret; + TSRMLS_FETCH(); + + if (SOAP_GLOBAL(sdl) && SOAP_GLOBAL(sdl)->elements && data->name) { + smart_str nscat = {0}; + sdlTypePtr *sdl_type; + + if (data->ns && data->ns->href) { + smart_str_appends(&nscat, (char*)data->ns->href); + smart_str_appendc(&nscat, ':'); + } + smart_str_appends(&nscat, (char*)data->name); + smart_str_0(&nscat); + + if (zend_hash_find(SOAP_GLOBAL(sdl)->elements, nscat.c, nscat.len+1, (void **)&sdl_type) == SUCCESS && + (*sdl_type)->encode) { + smart_str_free(&nscat); + return master_to_zval_int((*sdl_type)->encode, data); + } + smart_str_free(&nscat); + } buf = xmlBufferCreate(); xmlNodeDump(buf, NULL, data, 0, 0); @@ -3050,8 +3108,28 @@ static zval *to_zval_any(encodeTypePtr type, xmlNodePtr data) static xmlNodePtr to_xml_any(encodeTypePtr type, zval *data, int style, xmlNodePtr parent) { - xmlNodePtr ret; + xmlNodePtr ret = NULL; + if (Z_TYPE_P(data) == IS_ARRAY) { + HashPosition pos; + zval **el; + encodePtr enc = get_conversion(XSD_ANYXML); + char *name; + uint name_len; + ulong idx; + + for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(data), &pos); + zend_hash_get_current_data_ex(Z_ARRVAL_P(data), (void **) &el, &pos) == SUCCESS; + zend_hash_move_forward_ex(Z_ARRVAL_P(data), &pos)) { + ret = master_to_xml(enc, *el, style, parent); + if (ret && + ret->name != xmlStringTextNoenc && + zend_hash_get_current_key_ex(Z_ARRVAL_P(data), &name, &name_len, &idx, 0, &pos) == HASH_KEY_IS_STRING) { + xmlNodeSetName(ret, BAD_CAST(name)); + } + } + return ret; + } if (Z_TYPE_P(data) == IS_STRING) { ret = xmlNewTextLen(BAD_CAST(Z_STRVAL_P(data)), Z_STRLEN_P(data)); } else { diff --git a/ext/soap/tests/any.phpt b/ext/soap/tests/any.phpt index b6f42c9313..ef4ff08db9 100755 --- a/ext/soap/tests/any.phpt +++ b/ext/soap/tests/any.phpt @@ -19,9 +19,9 @@ function echoAnyElement($x) { global $g; $g = $x; - $struct = $x->inputAny->any; + $struct = $x->inputAny->any["SOAPComplexType"]; if ($struct instanceof SOAPComplexType) { - return array("return" => array("any" => new SoapVar($struct, SOAP_ENC_OBJECT, "SOAPComplexType", "http://soapinterop.org/xsd", "SOAPComplexType", "http://soapinterop.org/"))); + return array("return" => array("any" => array("SOAPComplexType"=>new SoapVar($struct, SOAP_ENC_OBJECT, "SOAPComplexType", "http://soapinterop.org/xsd", "SOAPComplexType", "http://soapinterop.org/")))); } else { return "?"; } @@ -59,13 +59,16 @@ object(stdClass)#5 (1) { ["inputAny"]=> object(stdClass)#6 (1) { ["any"]=> - object(SOAPComplexType)#7 (3) { - ["varInt"]=> - int(34) - ["varString"]=> - string(3) "arg" - ["varFloat"]=> - float(325.325) + array(1) { + ["SOAPComplexType"]=> + object(SOAPComplexType)#7 (3) { + ["varInt"]=> + int(34) + ["varString"]=> + string(3) "arg" + ["varFloat"]=> + float(325.325) + } } } } @@ -73,13 +76,16 @@ object(stdClass)#8 (1) { ["return"]=> object(stdClass)#9 (1) { ["any"]=> - object(SOAPComplexType)#10 (3) { - ["varInt"]=> - int(34) - ["varString"]=> - string(3) "arg" - ["varFloat"]=> - float(325.325) + array(1) { + ["SOAPComplexType"]=> + object(SOAPComplexType)#10 (3) { + ["varInt"]=> + int(34) + ["varString"]=> + string(3) "arg" + ["varFloat"]=> + float(325.325) + } } } }