diff options
-rw-r--r-- | ext/soap/TODO | 2 | ||||
-rw-r--r-- | ext/soap/php_encoding.c | 154 | ||||
-rw-r--r-- | ext/soap/php_encoding.h | 5 | ||||
-rw-r--r-- | ext/soap/soap.c | 22 |
4 files changed, 79 insertions, 104 deletions
diff --git a/ext/soap/TODO b/ext/soap/TODO index f8afb7bcb7..c195a97b70 100644 --- a/ext/soap/TODO +++ b/ext/soap/TODO @@ -57,7 +57,7 @@ Encoding + multidimensional arrays + arrays of arrays + SOAP 1.2 array encoding/decoding (itemType, arraySize) - - SOAP 1.1 - arrayType="xsd:ur-type[]", SOAP 1.2 - itemType="xsd:anyType" + + SOAP 1.1 - arrayType="xsd:ur-type[]", SOAP 1.2 - itemType="xsd:anyType" - SOAP 1.1 encoding of arrays with holes (partially transmitted and sparse arrays) SOAP 1.2 doesn't support partially transmitted and sparse arrays - full support for structures??? diff --git a/ext/soap/php_encoding.c b/ext/soap/php_encoding.c index 90acb5fa30..14e5e4fc9a 100644 --- a/ext/soap/php_encoding.c +++ b/ext/soap/php_encoding.c @@ -41,6 +41,13 @@ static xmlNodePtr to_xml_gday(encodeType type, zval *data, int style); static xmlNodePtr to_xml_gmonth(encodeType type, zval *data, int style); static xmlNodePtr to_xml_duration(encodeType type, zval *data, int style); +static int is_map(zval *array); +static void get_array_type(xmlNodePtr node, zval *array, smart_str *out_type TSRMLS_DC); + +static void get_type_str(xmlNodePtr node, const char* ns, const char* type, smart_str* ret); +static void set_ns_and_type(xmlNodePtr node, encodeType type); +static void set_ns_and_type_ex(xmlNodePtr node, char *ns, char *type); + encode defaultEncoding[] = { {{UNKNOWN_TYPE, NULL, NULL, NULL}, guess_zval_convert, guess_xml_convert}, @@ -960,25 +967,9 @@ xmlNodePtr to_xml_array(encodeType type, zval *data, int style) } if (myNs != NULL) { enc = get_encoder(SOAP_GLOBAL(sdl), myNs->href, value); - - if (strcmp(myNs->href,XSD_NAMESPACE) == 0) { - smart_str_appendl(&array_type, XSD_NS_PREFIX, sizeof(XSD_NS_PREFIX) - 1); - smart_str_appendc(&array_type, ':'); - } else { - smart_str *prefix = encode_new_ns(); - smart_str smart_ns = {0}; - - smart_str_appendl(&smart_ns, "xmlns:", sizeof("xmlns:") - 1); - smart_str_appendl(&smart_ns, prefix->c, prefix->len); - smart_str_0(&smart_ns); - xmlSetProp(xmlParam, smart_ns.c, myNs->href); - smart_str_free(&smart_ns); - - smart_str_appends(&array_type, prefix->c); - smart_str_appendc(&array_type, ':'); - smart_str_free(prefix); - efree(prefix); - } + get_type_str(xmlParam, myNs->href, value, &array_type); + } else { + smart_str_appends(&array_type, value); } dims = emalloc(sizeof(int)*dimension); @@ -995,8 +986,6 @@ xmlNodePtr to_xml_array(encodeType type, zval *data, int style) } } - smart_str_appends(&array_type, value); - smart_str_append_long(&array_size, dims[0]); for (i=1; i<dimension; i++) { smart_str_appendc(&array_size, ','); @@ -1010,37 +999,18 @@ xmlNodePtr to_xml_array(encodeType type, zval *data, int style) zend_hash_num_elements(sdl_type->elements) == 1 && (elementType = *(sdlTypePtr*)sdl_type->elements->pListHead->pData) != NULL && elementType->encode && elementType->encode->details.type_str) { - char* ns = elementType->encode->details.ns; - if (ns) { - if (strcmp(ns,XSD_NAMESPACE) == 0) { - smart_str_appendl(&array_type, XSD_NS_PREFIX, sizeof(XSD_NS_PREFIX) - 1); - smart_str_appendc(&array_type, ':'); - } else { - smart_str *prefix = encode_new_ns(); - smart_str smart_ns = {0}; - - smart_str_appendl(&smart_ns, "xmlns:", sizeof("xmlns:") - 1); - smart_str_appendl(&smart_ns, prefix->c, prefix->len); - smart_str_0(&smart_ns); - xmlSetProp(xmlParam, smart_ns.c, ns); - smart_str_free(&smart_ns); - - smart_str_appends(&array_type, prefix->c); - smart_str_appendc(&array_type, ':'); - smart_str_free(prefix); - efree(prefix); - } - } enc = elementType->encode; - smart_str_appends(&array_type, elementType->encode->details.type_str); + + get_type_str(xmlParam, elementType->encode->details.ns, elementType->encode->details.type_str, &array_type); + smart_str_append_long(&array_size, i); dims = emalloc(sizeof(int)*dimension); dims[0] = i; } else { - get_array_type(data, &array_type TSRMLS_CC); + get_array_type(xmlParam, data, &array_type TSRMLS_CC); enc = get_encoder_ex(SOAP_GLOBAL(sdl), array_type.c); smart_str_append_long(&array_size, i); dims = emalloc(sizeof(int)*dimension); @@ -1048,6 +1018,11 @@ xmlNodePtr to_xml_array(encodeType type, zval *data, int style) } if (soap_version == SOAP_1_1) { + smart_str_0(&array_type); + if (strcmp(array_type.c,"xsd:anyType") == 0) { + smart_str_0(&array_type); + smart_str_appendl(&array_type,"xsd:ur-type",sizeof("xsd:ur-type")-1); + } smart_str_appendc(&array_type, '['); smart_str_append(&array_type, &array_size); smart_str_appendc(&array_type, ']'); @@ -1587,45 +1562,17 @@ static xmlNodePtr to_xml_gmonth(encodeType type, zval *data, int style) return to_xml_datetime_ex(type, data, "--%m--", style); } -void set_ns_and_type(xmlNodePtr node, encodeType type) +static void set_ns_and_type(xmlNodePtr node, encodeType type) { set_ns_and_type_ex(node, type.ns, type.type_str); } -void set_ns_and_type_ex(xmlNodePtr node, char *ns, char *type) +static void set_ns_and_type_ex(xmlNodePtr node, char *ns, char *type) { - if (ns != NULL) { - char *sprefix; - smart_str *prefix; - smart_str xmlns = {0}, nstype = {0}; - - TSRMLS_FETCH(); - - if (zend_hash_find(SOAP_GLOBAL(defEncNs), ns, strlen(ns) + 1, (void **)&sprefix) == FAILURE) { - prefix = encode_new_ns(); - smart_str_appendl(&xmlns, "xmlns:", 6); - smart_str_append(&xmlns, prefix); - smart_str_0(&xmlns); - - xmlSetProp(node, xmlns.c, ns); - } else { - prefix = emalloc(sizeof(smart_str)); - memset(prefix, 0, sizeof(smart_str)); - smart_str_appends(prefix, sprefix); - } - - smart_str_append(&nstype, prefix); - smart_str_appendc(&nstype, ':'); - smart_str_appends(&nstype, type); - smart_str_0(&nstype); - xmlSetProp(node, "xsi:type", nstype.c); - smart_str_free(&nstype); - smart_str_free(&xmlns); - smart_str_free(prefix); - efree(prefix); - } else { - xmlSetProp(node, "xsi:type", type); - } + smart_str nstype = {0}; + get_type_str(node, ns, type, &nstype); + xmlSetProp(node, "xsi:type", nstype.c); + smart_str_free(&nstype); } smart_str *encode_new_ns() @@ -1728,7 +1675,7 @@ encodePtr get_conversion_from_type_ex(HashTable *encoding, xmlNodePtr node, cons } } -int is_map(zval *array) +static int is_map(zval *array) { int i, count = zend_hash_num_elements(Z_ARRVAL_P(array)); @@ -1742,7 +1689,7 @@ int is_map(zval *array) return FALSE; } -void get_array_type(zval *array, smart_str *type TSRMLS_DC) +static void get_array_type(xmlNodePtr node, zval *array, smart_str *type TSRMLS_DC) { HashTable *ht = HASH_OF(array); int i, count, cur_type, prev_type, different; @@ -1789,26 +1736,51 @@ void get_array_type(zval *array, smart_str *type TSRMLS_DC) smart_str_appendl(type, "xsd:anyType", 11); } else { encodePtr enc; - char *prefix; enc = get_conversion(cur_type); + get_type_str(node, enc->details.ns, enc->details.type_str, type); + } +} - if (enc->details.ns != NULL) { - if (zend_hash_find(SOAP_GLOBAL(defEncNs), enc->details.ns, strlen(enc->details.ns) + 1, (void **)&prefix) == FAILURE) { - php_error(E_ERROR, "Unknown namespace '%s'",enc->details.ns); - } +static void get_type_str(xmlNodePtr node, const char* ns, const char* type, smart_str* ret) +{ + char *prefix; + TSRMLS_FETCH(); + if (ns) { + if (SOAP_GLOBAL(soap_version) == SOAP_1_2 && + strcmp(ns,SOAP_1_1_ENC_NAMESPACE) == 0) { + ns = SOAP_1_2_ENC_NAMESPACE; + } else if (SOAP_GLOBAL(soap_version) == SOAP_1_1 && + strcmp(ns,SOAP_1_2_ENC_NAMESPACE) == 0) { + ns = SOAP_1_1_ENC_NAMESPACE; + } + if (zend_hash_find(SOAP_GLOBAL(defEncNs), (char*)ns, strlen(ns) + 1, (void **)&prefix) == SUCCESS) { + smart_str_appendl(ret, prefix, strlen(prefix)); + smart_str_appendc(ret, ':'); + } else if (node != NULL) { + smart_str* prefix = encode_new_ns(); + smart_str xmlns = {0}; + + smart_str_appendl(&xmlns, "xmlns:", 6); + smart_str_append(&xmlns, prefix); + smart_str_0(&xmlns); + + xmlSetProp(node, xmlns.c, ns); - smart_str_appendl(type, prefix, strlen(prefix)); - smart_str_appendc(type, ':'); - smart_str_appendl(type, enc->details.type_str, strlen(enc->details.type_str)); - smart_str_0(type); + smart_str_append(ret, prefix); + smart_str_appendc(ret, ':'); + + smart_str_free(&xmlns); + smart_str_free(prefix); + efree(prefix); } else { - smart_str_appendl(type, enc->details.type_str, strlen(enc->details.type_str)); + php_error(E_ERROR,"Unknown namespace '%s'",ns); } } + smart_str_appendl(ret, type, strlen(type)); + smart_str_0(ret); } - smart_str *build_soap_action(zval *this_ptr, char *soapaction) { zval **uri; diff --git a/ext/soap/php_encoding.h b/ext/soap/php_encoding.h index 061cd847d5..90cfd16fea 100644 --- a/ext/soap/php_encoding.h +++ b/ext/soap/php_encoding.h @@ -198,15 +198,10 @@ xmlNodePtr guess_xml_convert(encodeType type, zval *data, int style); void encode_reset_ns(); smart_str *encode_new_ns(); -void set_ns_and_type(xmlNodePtr node, encodeType type); -void set_ns_and_type_ex(xmlNodePtr node, char *ns, char *type); encodePtr get_conversion_ex(HashTable *encoding, int encode); encodePtr get_conversion_from_type_ex(HashTable *encoding, xmlNodePtr node, const char *type); encodePtr get_conversion_from_href_type_ex(HashTable *encoding, const char *type, int len); -int is_map(zval *array); -void get_array_type(zval *array, smart_str *out_type TSRMLS_DC); - void delete_encoder(void *handle); extern encode defaultEncoding[]; diff --git a/ext/soap/soap.c b/ext/soap/soap.c index ef248b4862..9722c8083d 100644 --- a/ext/soap/soap.c +++ b/ext/soap/soap.c @@ -279,7 +279,9 @@ static void php_soap_init_globals(zend_soap_globals *soap_globals) } } /* Index everything by number */ - zend_hash_index_update(soap_globals->defEncIndex, defaultEncoding[i].details.type, &enc, sizeof(encodePtr), NULL); + if (!zend_hash_index_exists(soap_globals->defEncIndex, defaultEncoding[i].details.type)) { + zend_hash_index_update(soap_globals->defEncIndex, defaultEncoding[i].details.type, &enc, sizeof(encodePtr), NULL); + } i++; } while (defaultEncoding[i].details.type != END_KNOWN_TYPES); @@ -1306,6 +1308,7 @@ PHP_METHOD(soapobject, soapobject) long use = SOAP_RPC; long style = SOAP_ENCODED; long version = SOAP_1_1; + long old_soap_version ; GET_THIS_OBJECT(thisObj); @@ -1315,12 +1318,6 @@ PHP_METHOD(soapobject, soapobject) sdlPtr sdl; int ret; - sdl = get_sdl(location); - ret = zend_list_insert(sdl, le_sdl); - - add_property_resource(thisObj, "sdl", ret); - zend_list_addref(ret); - if (arg2 != NULL) { version = Z_LVAL_P(arg2); } @@ -1329,6 +1326,17 @@ PHP_METHOD(soapobject, soapobject) } else { php_error(E_ERROR,"Can't create SoapObject. Wrong 'version' parameter."); } + old_soap_version = SOAP_GLOBAL(soap_version); + SOAP_GLOBAL(soap_version) = version; + + sdl = get_sdl(location); + ret = zend_list_insert(sdl, le_sdl); + + add_property_resource(thisObj, "sdl", ret); + zend_list_addref(ret); + + SOAP_GLOBAL(soap_version) = old_soap_version; + } else if (arg2 != NULL && Z_TYPE_P(arg2) == IS_STRING) { /* SoapObject($location, $uri, $style=SOAP_RPC, $use=SOAP_ENCODED, $version=SOAP_1_1) */ add_property_stringl(thisObj, "location", location, location_len, 1); |