From: Dmitry Stogov Date: Wed, 20 Sep 2006 13:42:52 +0000 (+0000) Subject: Added ability to make SOAP call userspace PHP<->XML converters X-Git-Tag: php-5.2.0RC5~121 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f5d7dac35d3e5bf653f275f86ab11f6b93874062;p=php Added ability to make SOAP call userspace PHP<->XML converters --- diff --git a/NEWS b/NEWS index 052be56a5b..541bafa14d 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,8 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? Sep 2006, PHP 5.2.0 +- Added ability to make SOAP call userspace PHP<->XML converters. (Dmitry) + - Fixed mess with CGI/CLI -d option (now it works with cgi; constants are working exactly like in php.ini; with FastCGI -d affects all requests). (Dmitry) diff --git a/ext/soap/php_encoding.c b/ext/soap/php_encoding.c index 2c92e5dd0f..b0ecba3467 100644 --- a/ext/soap/php_encoding.c +++ b/ext/soap/php_encoding.c @@ -287,13 +287,27 @@ xmlNodePtr master_to_xml(encodePtr encode, zval *data, int style, xmlNodePtr par soap_error0(E_ERROR, "Encoding: SoapVar hasn't 'enc_type' propery"); } - if (SOAP_GLOBAL(sdl)) { - if (zend_hash_find(ht, "enc_stype", sizeof("enc_stype"), (void **)&zstype) == SUCCESS) { - if (zend_hash_find(ht, "enc_ns", sizeof("enc_ns"), (void **)&zns) == SUCCESS) { - enc = get_encoder(SOAP_GLOBAL(sdl), Z_STRVAL_PP(zns), Z_STRVAL_PP(zstype)); - } else { - enc = get_encoder_ex(SOAP_GLOBAL(sdl), Z_STRVAL_PP(zstype), Z_STRLEN_PP(zstype)); + if (zend_hash_find(ht, "enc_stype", sizeof("enc_stype"), (void **)&zstype) == SUCCESS) { + if (zend_hash_find(ht, "enc_ns", sizeof("enc_ns"), (void **)&zns) == SUCCESS) { + enc = get_encoder(SOAP_GLOBAL(sdl), Z_STRVAL_PP(zns), Z_STRVAL_PP(zstype)); + } else { + zns = NULL; + enc = get_encoder_ex(SOAP_GLOBAL(sdl), Z_STRVAL_PP(zstype), Z_STRLEN_PP(zstype)); + } + if (enc == NULL && SOAP_GLOBAL(typemap)) { + encodePtr *new_enc; + smart_str nscat = {0}; + + if (zns != NULL) { + smart_str_appendl(&nscat, Z_STRVAL_PP(zns), Z_STRLEN_PP(zns)); + smart_str_appendc(&nscat, ':'); } + smart_str_appendl(&nscat, Z_STRVAL_PP(zstype), Z_STRLEN_PP(zstype)); + smart_str_0(&nscat); + if (zend_hash_find(SOAP_GLOBAL(typemap), nscat.c, nscat.len + 1, (void**)&new_enc) == SUCCESS) { + enc = *new_enc; + } + smart_str_free(&nscat); } } if (enc == NULL) { @@ -363,15 +377,24 @@ xmlNodePtr master_to_xml(encodePtr encode, zval *data, int style, xmlNodePtr par if (encode == NULL) { encode = get_conversion(UNKNOWN_TYPE); } - if (encode->to_xml_before) { - data = encode->to_xml_before(&encode->details, data); + if (SOAP_GLOBAL(typemap) && encode->details.type_str) { + smart_str nscat = {0}; + encodePtr *new_enc; + + if (encode->details.ns) { + smart_str_appends(&nscat, encode->details.ns); + smart_str_appendc(&nscat, ':'); + } + smart_str_appends(&nscat, encode->details.type_str); + smart_str_0(&nscat); + if (zend_hash_find(SOAP_GLOBAL(typemap), nscat.c, nscat.len + 1, (void**)&new_enc) == SUCCESS) { + encode = *new_enc; + } + smart_str_free(&nscat); } if (encode->to_xml) { node = encode->to_xml(&encode->details, data, style, parent); } - if (encode->to_xml_after) { - node = encode->to_xml_after(&encode->details, node, style); - } } return node; } @@ -379,16 +402,52 @@ xmlNodePtr master_to_xml(encodePtr encode, zval *data, int style, xmlNodePtr par static zval *master_to_zval_int(encodePtr encode, xmlNodePtr data) { zval *ret = NULL; + TSRMLS_FETCH(); + + if (SOAP_GLOBAL(typemap)) { + if (encode->details.type_str) { + smart_str nscat = {0}; + encodePtr *new_enc; - if (encode->to_zval_before) { - data = encode->to_zval_before(&encode->details, data, 0); + if (encode->details.ns) { + smart_str_appends(&nscat, encode->details.ns); + smart_str_appendc(&nscat, ':'); + } + smart_str_appends(&nscat, encode->details.type_str); + smart_str_0(&nscat); + if (zend_hash_find(SOAP_GLOBAL(typemap), nscat.c, nscat.len + 1, (void**)&new_enc) == SUCCESS) { + encode = *new_enc; + } + smart_str_free(&nscat); + } else { + xmlAttrPtr type_attr = get_attribute_ex(data->properties,"type", XSI_NAMESPACE); + + if (type_attr != NULL) { + encodePtr *new_enc; + xmlNsPtr nsptr; + char *ns, *cptype; + smart_str nscat = {0}; + + parse_namespace(type_attr->children->content, &cptype, &ns); + nsptr = xmlSearchNs(data->doc, data, BAD_CAST(ns)); + if (nsptr != NULL) { + smart_str_appends(&nscat, (char*)nsptr->href); + smart_str_appendc(&nscat, ':'); + } + smart_str_appends(&nscat, cptype); + smart_str_0(&nscat); + efree(cptype); + if (ns) {efree(ns);} + if (zend_hash_find(SOAP_GLOBAL(typemap), nscat.c, nscat.len + 1, (void**)&new_enc) == SUCCESS) { + encode = *new_enc; + } + smart_str_free(&nscat); + } + } } if (encode->to_zval) { ret = encode->to_zval(&encode->details, data); } - if (encode->to_zval_after) { - ret = encode->to_zval_after(&encode->details, ret); - } return ret; } @@ -400,7 +459,7 @@ zval *master_to_zval(encodePtr encode, xmlNodePtr data) if (encode == NULL) { encode = get_conversion(UNKNOWN_TYPE); } else { - /* Use xsi:type if it is defined */ + /* Use xsi:type if it is defined */ xmlAttrPtr type_attr = get_attribute_ex(data->properties,"type", XSI_NAMESPACE); if (type_attr != NULL) { @@ -427,125 +486,67 @@ zval *master_to_zval(encodePtr encode, xmlNodePtr data) return master_to_zval_int(encode, data); } -#ifdef HAVE_PHP_DOMXML -zval *to_xml_before_user(encodeTypePtr type, zval *data) -{ - TSRMLS_FETCH(); - - if (type.map->map_functions.to_xml_before) { - if (call_user_function(EG(function_table), NULL, type.map->map_functions.to_xml_before, data, 1, &data TSRMLS_CC) == FAILURE) { - soap_error0(E_ERROR, "Encoding: Error calling to_xml_before"); - } - } - return data; -} - xmlNodePtr to_xml_user(encodeTypePtr type, zval *data, int style, xmlNodePtr parent) { - zval *ret, **addr; - xmlNodePtr node; + xmlNodePtr ret = NULL; + zval *return_value; TSRMLS_FETCH(); - if (type.map->map_functions.to_xml) { - MAKE_STD_ZVAL(ret); - if (call_user_function(EG(function_table), NULL, type.map->map_functions.to_xml, ret, 1, &data TSRMLS_CC) == FAILURE) { - soap_error0(E_ERROR, "Encoding: Error calling to_xml"); - } + if (type && type->map && type->map->to_xml) { + MAKE_STD_ZVAL(return_value); - if (Z_TYPE_P(ret) != IS_OBJECT) { - soap_error0(E_ERROR, "Encoding: Error serializing object from to_xml_user"); + if (call_user_function(EG(function_table), NULL, type->map->to_xml, return_value, 1, &data TSRMLS_CC) == FAILURE) { + soap_error0(E_ERROR, "Encoding: Error calling to_xml callback"); } - - if (zend_hash_index_find(Z_OBJPROP_P(ret), 1, (void **)&addr) == SUCCESS) { - node = (xmlNodePtr)Z_LVAL_PP(addr); - node = xmlCopyNode(node, 1); - set_ns_and_type(node, type); + if (Z_TYPE_P(return_value) == IS_STRING) { + xmlDocPtr doc = soap_xmlParseMemory(Z_STRVAL_P(return_value), Z_STRLEN_P(return_value)); + if (doc && doc->children) { + ret = xmlDocCopyNode(doc->children, parent->doc, 1); + } + xmlFreeDoc(doc); } - zval_ptr_dtor(&ret); - } - return node; -} - -xmlNodePtr to_xml_after_user(encodeTypePtr type, xmlNodePtr node, int style) -{ - zval *ret, *param, **addr; - int found; - TSRMLS_FETCH(); - - if (type.map->map_functions.to_xml_after) { - MAKE_STD_ZVAL(ret); - MAKE_STD_ZVAL(param); - param = php_domobject_new(node, &found, NULL TSRMLS_CC); - if (call_user_function(EG(function_table), NULL, type.map->map_functions.to_xml_after, ret, 1, ¶m TSRMLS_CC) == FAILURE) { - soap_error0(E_ERROR, "Encoding: Error calling to_xml_after"); - } - if (zend_hash_index_find(Z_OBJPROP_P(ret), 1, (void **)&addr) == SUCCESS) { - node = (xmlNodePtr)Z_LVAL_PP(addr); - set_ns_and_type(node, type); - } - zval_ptr_dtor(&ret); - zval_ptr_dtor(¶m); + zval_ptr_dtor(&return_value); } - return node; -} - -xmlNodePtr to_zval_before_user(encodeTypePtr type, xmlNodePtr node, int style) -{ - zval *ret, *param, **addr; - int found; - TSRMLS_FETCH(); - - if (type.map->map_functions.to_zval_before) { - MAKE_STD_ZVAL(ret); - MAKE_STD_ZVAL(param); - param = php_domobject_new(node, &found, NULL TSRMLS_CC); - - if (call_user_function(EG(function_table), NULL, type.map->map_functions.to_zval_before, ret, 1, ¶m TSRMLS_CC) == FAILURE) { - soap_error0(E_ERROR, "Encoding: Error calling to_zval_before"); - } - if (zend_hash_index_find(Z_OBJPROP_P(ret), 1, (void **)&addr) == SUCCESS) { - node = (xmlNodePtr)Z_LVAL_PP(addr); - set_ns_and_type(node, type); - } - zval_ptr_dtor(&ret); - zval_ptr_dtor(¶m); + if (!ret) { + ret = xmlNewNode(NULL, BAD_CAST("BOGUS")); } - return node; -} - -zval *to_zval_user(encodeTypePtr type, xmlNodePtr node) -{ - zval *ret, *param; - int found; - TSRMLS_FETCH(); - - if (type.map->map_functions.to_zval) { - MAKE_STD_ZVAL(ret); - MAKE_STD_ZVAL(param); - param = php_domobject_new(node, &found, NULL TSRMLS_CC); - - if (call_user_function(EG(function_table), NULL, type.map->map_functions.to_zval, ret, 1, ¶m TSRMLS_CC) == FAILURE) { - soap_error0(E_ERROR, "Encoding: Error calling to_zval"); - } - zval_ptr_dtor(¶m); - efree(param); + xmlAddChild(parent, ret); + if (style == SOAP_ENCODED) { + set_ns_and_type(ret, type); } return ret; } -zval *to_zval_after_user(encodeTypePtr type, zval *data) +zval *to_zval_user(encodeTypePtr type, xmlNodePtr node) { + zval *return_value; TSRMLS_FETCH(); - if (type.map->map_functions.to_zval_after) { - if (call_user_function(EG(function_table), NULL, type.map->map_functions.to_zval_after, data, 1, &data TSRMLS_CC) == FAILURE) { - soap_error0(E_ERROR, "Encoding: Error calling to_zval_after"); - } + if (type && type->map && type->map->to_zval) { + xmlBufferPtr buf; + zval *data; + xmlNodePtr copy; + + copy = xmlCopyNode(node, 1); + buf = xmlBufferCreate(); + xmlNodeDump(buf, NULL, copy, 0, 0); + MAKE_STD_ZVAL(data); + ZVAL_STRING(data, (char*)xmlBufferContent(buf), 1); + xmlBufferFree(buf); + xmlFreeNode(copy); + + ALLOC_INIT_ZVAL(return_value); + + if (call_user_function(EG(function_table), NULL, type->map->to_zval, return_value, 1, &data TSRMLS_CC) == FAILURE) { + soap_error0(E_ERROR, "Encoding: Error calling from_xml callback"); + } + zval_ptr_dtor(&data); + } else { + ALLOC_INIT_ZVAL(return_value); } - return data; + return return_value; } -#endif /* TODO: get rid of "bogus".. ither by passing in the already created xmlnode or passing in the node name */ /* String encode/decode */ @@ -3090,26 +3091,8 @@ encodePtr get_conversion(int encode) TSRMLS_FETCH(); if (zend_hash_index_find(&SOAP_GLOBAL(defEncIndex), encode, (void **)&enc) == FAILURE) { - if (SOAP_GLOBAL(overrides)) { - smart_str nscat = {0}; - - smart_str_appendl(&nscat, (*enc)->details.ns, strlen((*enc)->details.ns)); - smart_str_appendc(&nscat, ':'); - smart_str_appendl(&nscat, (*enc)->details.type_str, strlen((*enc)->details.type_str)); - smart_str_0(&nscat); - - if (zend_hash_find(SOAP_GLOBAL(overrides), nscat.c, nscat.len + 1, (void **)&enc) == FAILURE) { - smart_str_free(&nscat); - soap_error0(E_ERROR, "Encoding: Cannot find encoding"); - return NULL; - } else { - smart_str_free(&nscat); - return *enc; - } - } else { - soap_error0(E_ERROR, "Encoding: Cannot find encoding"); - return NULL; - } + soap_error0(E_ERROR, "Encoding: Cannot find encoding"); + return NULL; } else { return *enc; } @@ -3256,32 +3239,11 @@ static void delete_mapping(void *data) { soapMappingPtr map = (soapMappingPtr)data; - if (map->ns) { - efree(map->ns); + if (map->to_xml) { + zval_ptr_dtor(&map->to_xml); } - if (map->ctype) { - efree(map->ctype); - } - - if (map->type == SOAP_MAP_FUNCTION) { - if (map->map_functions.to_xml_before) { - zval_ptr_dtor(&map->map_functions.to_xml_before); - } - if (map->map_functions.to_xml) { - zval_ptr_dtor(&map->map_functions.to_xml); - } - if (map->map_functions.to_xml_after) { - zval_ptr_dtor(&map->map_functions.to_xml_after); - } - if (map->map_functions.to_zval_before) { - zval_ptr_dtor(&map->map_functions.to_zval_before); - } - if (map->map_functions.to_zval) { - zval_ptr_dtor(&map->map_functions.to_zval); - } - if (map->map_functions.to_zval_after) { - zval_ptr_dtor(&map->map_functions.to_zval_after); - } + if (map->to_zval) { + zval_ptr_dtor(&map->to_zval); } efree(map); } diff --git a/ext/soap/php_encoding.h b/ext/soap/php_encoding.h index 2e92ec3757..c007925dd0 100644 --- a/ext/soap/php_encoding.h +++ b/ext/soap/php_encoding.h @@ -185,27 +185,15 @@ struct _encode { encodeType details; zval *(*to_zval)(encodeTypePtr type, xmlNodePtr data); xmlNodePtr (*to_xml)(encodeTypePtr type, zval *data, int style, xmlNodePtr parent); - - xmlNodePtr (*to_zval_before)(encodeTypePtr type, xmlNodePtr data, int style); - zval *(*to_zval_after)(encodeTypePtr type, zval *data); - - zval *(*to_xml_before)(encodeTypePtr type, zval *data); - xmlNodePtr (*to_xml_after)(encodeTypePtr type, xmlNodePtr data, int style); }; /* Master functions all encode/decode should be called thur these functions */ xmlNodePtr master_to_xml(encodePtr encode, zval *data, int style, xmlNodePtr parent); zval *master_to_zval(encodePtr encode, xmlNodePtr data); -#ifdef HAVE_PHP_DOMXML /* user defined mapping */ -zval *to_xml_before_user(encodeTypePtr type, zval *data); xmlNodePtr to_xml_user(encodeTypePtr type, zval *data, int style, xmlNodePtr parent); -xmlNodePtr to_xml_after_user(encodeTypePtr type, xmlNodePtr node, int style); -xmlNodePtr to_zval_before_user(encodeTypePtr type, xmlNodePtr node, int style); zval *to_zval_user(encodeTypePtr type, xmlNodePtr node); -zval *to_zval_after_user(encodeTypePtr type, zval *data); -#endif void whiteSpace_replace(xmlChar* str); void whiteSpace_collapse(xmlChar* str); diff --git a/ext/soap/php_sdl.c b/ext/soap/php_sdl.c index c36444e37c..53c9a1a5a0 100644 --- a/ext/soap/php_sdl.c +++ b/ext/soap/php_sdl.c @@ -1326,10 +1326,6 @@ static void sdl_deserialize_encoder(encodePtr enc, sdlTypePtr *types, char **in) if (real_enc) { enc->to_zval = real_enc->to_zval; enc->to_xml = real_enc->to_xml; - enc->to_zval_before = real_enc->to_zval_before; - enc->to_xml_before = real_enc->to_xml_before; - enc->to_zval_after = real_enc->to_zval_after; - enc->to_xml_after = real_enc->to_xml_after; } } } diff --git a/ext/soap/php_soap.h b/ext/soap/php_soap.h index 39dbe3e5d3..776381a5c7 100644 --- a/ext/soap/php_soap.h +++ b/ext/soap/php_soap.h @@ -35,10 +35,6 @@ #include #include -#ifdef HAVE_PHP_DOMXML -# include "ext/domxml/php_domxml.h" -#endif - #ifndef PHP_HAVE_STREAMS # error You lose - must be compiled against PHP 4.3.0 or later #endif @@ -78,23 +74,8 @@ typedef struct _soapService soapService, *soapServicePtr; #include "php_packet_soap.h" struct _soapMapping { - char *ns; - char *ctype; - int type; - - struct _map_functions { - zval *to_xml_before; - zval *to_xml; - zval *to_xml_after; - zval *to_zval_before; - zval *to_zval; - zval *to_zval_after; - } map_functions; - - struct _map_class { - int type; - zend_class_entry *ce; - } map_class; + zval *to_xml; + zval *to_zval; }; struct _soapHeader; @@ -116,7 +97,7 @@ struct _soapService { zval *soap_object; - HashTable *mapping; + HashTable *typemap; int version; int type; char *actor; @@ -170,7 +151,7 @@ ZEND_BEGIN_MODULE_GLOBALS(soap) HashTable defEncNs; /* mapping of default namespaces to prefixes */ HashTable defEnc; HashTable defEncIndex; - HashTable *overrides; + HashTable *typemap; int cur_uniq_ns; int soap_version; sdlPtr sdl; diff --git a/ext/soap/soap.c b/ext/soap/soap.c index e7f1999cea..3bb48defd3 100644 --- a/ext/soap/soap.c +++ b/ext/soap/soap.c @@ -33,6 +33,7 @@ static int le_sdl = 0; int le_url = 0; static int le_service = 0; +static int le_typemap = 0; typedef struct _soapHeader { sdlFunctionPtr function; @@ -66,6 +67,7 @@ static xmlNodePtr serialize_zval(zval *val, sdlParamPtr param, char *paramName, static void delete_service(void *service); static void delete_url(void *handle); +static void delete_hashtable(void *hashtable); #ifndef ZEND_ENGINE_2 static void soap_call_function_handler(INTERNAL_FUNCTION_PARAMETERS, zend_property_reference *property_reference); @@ -157,6 +159,9 @@ static void soap_error_handler(int error_num, const char *error_filename, const #define FIND_SDL_PROPERTY(ss,tmp) zend_hash_find(Z_OBJPROP_P(ss), "sdl", sizeof("sdl"), (void **)&tmp) #define FETCH_SDL_RES(ss,tmp) ss = (sdlPtr) zend_fetch_resource(tmp TSRMLS_CC, -1, "sdl", NULL, 1, le_sdl) +#define FIND_TYPEMAP_PROPERTY(ss,tmp) zend_hash_find(Z_OBJPROP_P(ss), "typemap", sizeof("typemap"), (void **)&tmp) +#define FETCH_TYPEMAP_RES(ss,tmp) ss = (HashTable*) zend_fetch_resource(tmp TSRMLS_CC, -1, "typemap", NULL, 1, le_typemap) + #define FETCH_THIS_SERVICE(ss) \ { \ zval **tmp; \ @@ -246,9 +251,6 @@ PHP_METHOD(SoapServer, handle); PHP_METHOD(SoapServer, setPersistence); PHP_METHOD(SoapServer, fault); PHP_METHOD(SoapServer, addSoapHeader); -#ifdef HAVE_PHP_DOMXML -PHP_METHOD(PHP_SOAP_SERVER_CLASS, map); -#endif /* Client Functions */ PHP_METHOD(SoapClient, SoapClient); @@ -282,10 +284,6 @@ PHP_METHOD(SoapHeader, SoapHeader); #define SOAP_CTOR(class_name, func_name, arginfo, flags) PHP_ME(class_name, func_name, arginfo, flags) static zend_function_entry soap_functions[] = { -#ifdef HAVE_PHP_DOMXML - PHP_FE(soap_encode_to_xml, NULL) - PHP_FE(soap_encode_to_zval, NULL) -#endif PHP_FE(use_soap_error_handler, NULL) PHP_FE(is_soap_fault, NULL) {NULL, NULL, NULL} @@ -309,9 +307,6 @@ static zend_function_entry soap_server_functions[] = { PHP_ME(SoapServer, handle, NULL, 0) PHP_ME(SoapServer, fault, NULL, 0) PHP_ME(SoapServer, addSoapHeader, NULL, 0) -#ifdef HAVE_PHP_DOMXML - PHP_ME(SoapServer, map, NULL, 0) -#endif {NULL, NULL, NULL} }; @@ -478,7 +473,7 @@ static void php_soap_init_globals(zend_soap_globals *soap_globals TSRMLS_DC) soap_globals->defEnc = defEnc; soap_globals->defEncIndex = defEncIndex; soap_globals->defEncNs = defEncNs; - soap_globals->overrides = NULL; + soap_globals->typemap = NULL; soap_globals->use_soap_error_handler = 0; soap_globals->error_code = NULL; soap_globals->error_object = NULL; @@ -503,7 +498,7 @@ PHP_MSHUTDOWN_FUNCTION(soap) PHP_RINIT_FUNCTION(soap) { - SOAP_GLOBAL(overrides) = NULL; + SOAP_GLOBAL(typemap) = NULL; SOAP_GLOBAL(use_soap_error_handler) = 0; SOAP_GLOBAL(error_code) = NULL; SOAP_GLOBAL(error_object) = NULL; @@ -584,6 +579,7 @@ PHP_MINIT_FUNCTION(soap) le_sdl = register_list_destructors(delete_sdl, NULL); le_url = register_list_destructors(delete_url, NULL); le_service = register_list_destructors(delete_service, NULL); + le_typemap = register_list_destructors(delete_hashtable, NULL); REGISTER_LONG_CONSTANT("SOAP_1_1", SOAP_1_1, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SOAP_1_2", SOAP_1_2, CONST_CS | CONST_PERSISTENT); @@ -689,42 +685,6 @@ PHP_MINFO_FUNCTION(soap) DISPLAY_INI_ENTRIES(); } -#ifdef HAVE_PHP_DOMXML -PHP_FUNCTION(soap_encode_to_xml) -{ - zval *pzval, *ret; - encodePtr enc; - char *name; - int found, name_len; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &name, &name_len, &pzval) == FAILURE) { - php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid parameters"); - } - - enc = get_conversion(Z_TYPE_P(pzval)); - ret = php_domobject_new(serialize_zval(pzval, NULL, name, SOAP_ENCODED), &found, NULL TSRMLS_CC); - *return_value = *ret; - zval_copy_ctor(return_value); - zval_ptr_dtor(&ret); -} - -PHP_FUNCTION(soap_encode_to_zval) -{ - zval *dom, **addr, *ret; - xmlNodePtr node; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &dom) == FAILURE) { - php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid parameters"); - } - - if (zend_hash_index_find(Z_OBJPROP_P(dom), 1, (void **)&addr) == FAILURE) { - } - - node = (xmlNodePtr)Z_LVAL_PP(addr); - ret = master_to_zval(NULL, node); - *return_value = *ret; -} -#endif /* {{{ proto object SoapParam::SoapParam ( mixed data, string name) SoapParam constructor */ @@ -932,6 +892,122 @@ PHP_METHOD(SoapVar, SoapVar) /* }}} */ +static HashTable* soap_create_typemap(sdlPtr sdl, HashTable *ht TSRMLS_DC) +{ + zval **tmp; + HashTable *ht2; + HashPosition pos1, pos2; + HashTable *typemap = NULL; + + zend_hash_internal_pointer_reset_ex(ht, &pos1); + while (zend_hash_get_current_data_ex(ht, (void**)&tmp, &pos1) == SUCCESS) { + char *type_name = NULL; + char *type_ns = NULL; + zval *to_xml = NULL; + zval *to_zval = NULL; + encodePtr enc, new_enc; + + if (Z_TYPE_PP(tmp) != IS_ARRAY) { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Wrong 'typemap' option"); + } + ht2 = Z_ARRVAL_PP(tmp); + + zend_hash_internal_pointer_reset_ex(ht2, &pos2); + while (zend_hash_get_current_data_ex(ht2, (void**)&tmp, &pos2) == SUCCESS) { + char *name = NULL; + unsigned int name_len; + ulong index; + + zend_hash_get_current_key_ex(ht2, &name, &name_len, &index, 0, &pos2); + if (name) { + if (name_len == sizeof("type_name") && + strncmp(name, "type_name", sizeof("type_name")-1) == 0) { + if (Z_TYPE_PP(tmp) == IS_STRING) { + type_name = Z_STRVAL_PP(tmp); + } else if (Z_TYPE_PP(tmp) != IS_NULL) { + } + } else if (name_len == sizeof("type_ns") && + strncmp(name, "type_ns", sizeof("type_ns")-1) == 0) { + if (Z_TYPE_PP(tmp) == IS_STRING) { + type_ns = Z_STRVAL_PP(tmp); + } else if (Z_TYPE_PP(tmp) != IS_NULL) { + } + } else if (name_len == sizeof("to_xml") && + strncmp(name, "to_xml", sizeof("to_xml")-1) == 0) { + to_xml = *tmp; + } else if (name_len == sizeof("from_xml") && + strncmp(name, "from_xml", sizeof("from_xml")-1) == 0) { + to_zval = *tmp; + } + } + zend_hash_move_forward_ex(ht2, &pos2); + } + + if (type_name) { + smart_str nscat = {0}; + + if (type_ns) { + enc = get_encoder(sdl, type_ns, type_name); + } else { + enc = get_encoder_ex(sdl, type_name, strlen(type_name)); + } + + new_enc = emalloc(sizeof(encode)); + memset(new_enc, 0, sizeof(encode)); + + if (enc) { + new_enc->details.type = enc->details.type; + new_enc->details.ns = estrdup(enc->details.ns); + new_enc->details.type_str = estrdup(enc->details.type_str); + new_enc->details.sdl_type = enc->details.sdl_type; + } else { + enc = get_conversion(UNKNOWN_TYPE); + new_enc->details.type = enc->details.type; + if (type_ns) { + new_enc->details.ns = estrdup(type_ns); + } + new_enc->details.type_str = estrdup(type_name); + } + new_enc->to_xml = enc->to_xml; + new_enc->to_zval = enc->to_zval; + new_enc->details.map = emalloc(sizeof(soapMapping)); + memset(new_enc->details.map, 0, sizeof(soapMapping)); + if (to_xml) { + zval_add_ref(&to_xml); + new_enc->details.map->to_xml = to_xml; + new_enc->to_xml = to_xml_user; + } else if (enc->details.map && enc->details.map->to_xml) { + zval_add_ref(&enc->details.map->to_xml); + new_enc->details.map->to_xml = enc->details.map->to_xml; + } + if (to_zval) { + zval_add_ref(&to_zval); + new_enc->details.map->to_zval = to_zval; + new_enc->to_zval = to_zval_user; + } else if (enc->details.map && enc->details.map->to_zval) { + zval_add_ref(&enc->details.map->to_zval); + new_enc->details.map->to_zval = enc->details.map->to_zval; + } + if (!typemap) { + typemap = emalloc(sizeof(HashTable)); + zend_hash_init(typemap, 0, NULL, delete_encoder, 0); + } + + if (type_ns) { + smart_str_appends(&nscat, type_ns); + smart_str_appendc(&nscat, ':'); + } + smart_str_appends(&nscat, type_name); + smart_str_0(&nscat); + zend_hash_update(typemap, nscat.c, nscat.len + 1, &new_enc, sizeof(encodePtr), NULL); + smart_str_free(&nscat); + } + zend_hash_move_forward_ex(ht, &pos1); + } + return typemap; +} + + /* {{{ proto object SoapServer::SoapServer ( mixed wsdl [, array options]) SoapServer constructor */ PHP_METHOD(SoapServer, SoapServer) @@ -941,6 +1017,7 @@ PHP_METHOD(SoapServer, SoapServer) int ret; int version = SOAP_1_1; long cache_wsdl; + HashTable *typemap_ht = NULL; SOAP_SERVER_BEGIN_CODE(); @@ -1005,6 +1082,12 @@ PHP_METHOD(SoapServer, SoapServer) zend_hash_copy(service->class_map, (*tmp)->value.ht, (copy_ctor_func_t) zval_add_ref, (void *) &ztmp, sizeof(zval *)); } + if (zend_hash_find(ht, "typemap", sizeof("typemap"), (void**)&tmp) == SUCCESS && + Z_TYPE_PP(tmp) == IS_ARRAY && + zend_hash_num_elements(Z_ARRVAL_PP(tmp)) > 0) { + typemap_ht = Z_ARRVAL_PP(tmp); + } + if (zend_hash_find(ht, "features", sizeof("features"), (void**)&tmp) == SUCCESS && Z_TYPE_PP(tmp) == IS_LONG) { service->features = Z_LVAL_PP(tmp); @@ -1036,6 +1119,10 @@ PHP_METHOD(SoapServer, SoapServer) } } } + + if (typemap_ht) { + service->typemap = soap_create_typemap(service->sdl, typemap_ht TSRMLS_CC); + } ret = zend_list_insert(service, le_service); add_property_resource(this_ptr, "service", ret); @@ -1045,127 +1132,6 @@ PHP_METHOD(SoapServer, SoapServer) /* }}} */ -#define NULL_OR_STRING(zval) \ - (!zval || Z_TYPE_P(zval) == IS_NULL || Z_TYPE_P(zval) == IS_STRING) - -#define IS_VALID_FUNCTION(zval) \ - (zval && Z_TYPE_P(zval) != IS_NULL) - -#ifdef HAVE_PHP_DOMXML -PHP_FUNCTION(PHP_SOAP_SERVER_CLASS, map) -{ - char *type, *class_name; - zval *to_xml_before = NULL, *to_xml = NULL, *to_xml_after = NULL, - *to_zval_before = NULL, *to_zval = NULL, *to_zval_after = NULL; - int type_len, class_name_len; - char *ns, *ctype; - soapServicePtr service; - - SOAP_SERVER_BEGIN_CODE(); - - if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "sz|zzzzz", - &type, &type_len, &to_xml_before, &to_xml, &to_xml_after, &to_zval_before, &to_zval, - &to_zval_after) == SUCCESS && NULL_OR_STRING(to_xml_before) && NULL_OR_STRING(to_xml) && - NULL_OR_STRING(to_xml_after) && NULL_OR_STRING(to_zval_before) && NULL_OR_STRING(to_zval) && - NULL_OR_STRING(to_zval_after)) { - - soapMappingPtr map; - encodePtr enc, new_enc; - smart_str resloved_ns = {0}; - - FETCH_THIS_SERVICE(service); - - new_enc = emalloc(sizeof(encode)); - memset(new_enc, 0, sizeof(encode)); - - ctype = strrchr(type, ':'); - if (ctype) { - smart_str_appendl(&resloved_ns, type, ctype - type); - smart_str_0(&resloved_ns); - ctype++; - } else { - ns = NULL; - } - - if (ns) { - if (zend_hash_find(SOAP_GLOBAL(defEncPrefix), resloved_ns.c, resloved_ns.len + 1, &ns) == SUCCESS) { - enc = get_encoder(service->sdl, ns, ctype); - smart_str_free(&resloved_ns); - smart_str_appendl(&resloved_ns, ns, strlen(ns)); - smart_str_appendc(&resloved_ns, ':'); - smart_str_appendl(&resloved_ns, ctype, strlen(ctype)); - smart_str_0(&resloved_ns); - type = resloved_ns.c; - type_len = resloved_ns.len; - } else { - enc = get_encoder_ex(service->sdl, type); - } - } else { - enc = get_encoder_ex(service->sdl, type); - } - - new_enc->details.type = enc->details.type; - new_enc->details.ns = estrdup(enc->details.ns); - new_enc->details.type_str = estrdup(enc->details.type_str); - new_enc->details.sdl_type = enc->details.sdl_type; - new_enc->to_xml = enc->to_xml; - new_enc->to_zval = enc->to_zval; - new_enc->to_xml_before = enc->to_xml_before; - new_enc->to_zval_before = enc->to_zval_before; - new_enc->to_xml_after = enc->to_xml_after; - new_enc->to_zval_after = enc->to_zval_after; - - map = emalloc(sizeof(soapMapping)); - memset(map, 0, sizeof(soapMapping)); - - map->type = SOAP_MAP_FUNCTION; - if (IS_VALID_FUNCTION(to_xml_before)) { - zval_add_ref(&to_xml_before); - map->map_functions.to_xml_before = to_xml_before; - new_enc->to_xml_before = to_xml_before_user; - } - if (IS_VALID_FUNCTION(to_xml)) { - zval_add_ref(&to_xml); - map->map_functions.to_xml = to_xml; - new_enc->to_xml = to_xml_user; - } - if (IS_VALID_FUNCTION(to_xml_after)) { - zval_add_ref(&to_xml_after); - map->map_functions.to_xml_after = to_xml_after; - new_enc->to_xml_after = to_xml_after_user; - } - if (IS_VALID_FUNCTION(to_zval_before)) { - zval_add_ref(&to_zval_before); - map->map_functions.to_zval_before = to_zval_before; - new_enc->to_zval_before = to_zval_before_user; - } - if (IS_VALID_FUNCTION(to_zval)) { - zval_add_ref(&to_zval); - map->map_functions.to_zval = to_zval; - new_enc->to_zval = to_zval_user; - } - if (IS_VALID_FUNCTION(to_zval_after)) { - zval_add_ref(&to_zval_after); - map->map_functions.to_zval_after = to_zval_after; - new_enc->to_zval_after = to_zval_after_user; - } - - new_enc->details.map = map; - - if (!service->mapping) { - service->mapping = emalloc(sizeof(HashTable)); - zend_hash_init(service->mapping, 0, NULL, delete_encoder, 0); - } - zend_hash_update(service->mapping, type, type_len + 1, &new_enc, sizeof(encodePtr), NULL); - smart_str_free(&resloved_ns); - } else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "ss|l", &type, &type_len, &class_name, &class_name_len, &type) == SUCCESS) { - } else { - php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid parameters"); - } -} -#endif - - /* {{{ proto object SoapServer::setPersistence ( int mode ) Sets persistence mode of SoapServer */ PHP_METHOD(SoapServer, setPersistence) @@ -1444,7 +1410,7 @@ PHP_METHOD(SoapServer, handle) char *arg = NULL; int arg_len; xmlCharEncodingHandlerPtr old_encoding; - HashTable *old_class_map; + HashTable *old_class_map, *old_typemap; int old_features; SOAP_SERVER_BEGIN_CODE(); @@ -1585,12 +1551,25 @@ PHP_METHOD(SoapServer, handle) SOAP_GLOBAL(encoding) = service->encoding; old_class_map = SOAP_GLOBAL(class_map); SOAP_GLOBAL(class_map) = service->class_map; + old_typemap = SOAP_GLOBAL(typemap); + SOAP_GLOBAL(typemap) = service->typemap; old_features = SOAP_GLOBAL(features); SOAP_GLOBAL(features) = service->features; old_soap_version = SOAP_GLOBAL(soap_version); function = deserialize_function_call(service->sdl, doc_request, service->actor, &function_name, &num_params, ¶ms, &soap_version, &soap_headers TSRMLS_CC); xmlFreeDoc(doc_request); +#ifdef ZEND_ENGINE_2 + if (EG(exception)) { + php_end_ob_buffer(0, 0 TSRMLS_CC); + if (Z_TYPE_P(EG(exception)) == IS_OBJECT && + instanceof_function(Z_OBJCE_P(EG(exception)), soap_fault_class_entry TSRMLS_CC)) { + soap_server_fault_ex(function, EG(exception), NULL TSRMLS_CC); + } + goto fail; + } +#endif + service->soap_headers_ptr = &soap_headers; soap_obj = NULL; @@ -1835,14 +1814,32 @@ PHP_METHOD(SoapServer, handle) memcpy(response_name,Z_STRVAL(function_name),Z_STRLEN(function_name)); memcpy(response_name+Z_STRLEN(function_name),"Response",sizeof("Response")); } - SOAP_GLOBAL(overrides) = service->mapping; doc_return = serialize_response_call(function, response_name, service->uri, &retval, soap_headers, soap_version TSRMLS_CC); - SOAP_GLOBAL(overrides) = NULL; efree(response_name); } else { php_error_docref(NULL TSRMLS_CC, E_ERROR, "Function '%s' call failed", Z_STRVAL(function_name)); } +#ifdef ZEND_ENGINE_2 + if (EG(exception)) { + php_end_ob_buffer(0, 0 TSRMLS_CC); + if (Z_TYPE_P(EG(exception)) == IS_OBJECT && + instanceof_function(Z_OBJCE_P(EG(exception)), soap_fault_class_entry TSRMLS_CC)) { + soap_server_fault_ex(function, EG(exception), NULL TSRMLS_CC); + } + if (service->type == SOAP_CLASS) { +#if HAVE_PHP_SESSION && !defined(COMPILE_DL_SESSION) + if (soap_obj && service->soap_class.persistance != SOAP_PERSISTENCE_SESSION) { +#else + if (soap_obj) { +#endif + zval_ptr_dtor(&soap_obj); + } + } + goto fail; + } +#endif + /* Flush buffer */ php_end_ob_buffer(0, 0 TSRMLS_CC); @@ -1875,6 +1872,7 @@ fail: SOAP_GLOBAL(encoding) = old_encoding; SOAP_GLOBAL(sdl) = old_sdl; SOAP_GLOBAL(class_map) = old_class_map; + SOAP_GLOBAL(typemap) = old_typemap; SOAP_GLOBAL(features) = old_features; /* Free soap headers */ @@ -2182,6 +2180,8 @@ PHP_METHOD(SoapClient, SoapClient) int soap_version = SOAP_1_1; php_stream_context *context = NULL; long cache_wsdl; + sdlPtr sdl = NULL; + HashTable *typemap_ht = NULL; SOAP_CLIENT_BEGIN_CODE(); @@ -2333,6 +2333,12 @@ PHP_METHOD(SoapClient, SoapClient) add_property_zval(this_ptr, "_classmap", class_map); } + if (zend_hash_find(ht, "typemap", sizeof("typemap"), (void**)&tmp) == SUCCESS && + Z_TYPE_PP(tmp) == IS_ARRAY && + zend_hash_num_elements(Z_ARRVAL_PP(tmp)) > 0) { + typemap_ht = Z_ARRVAL_PP(tmp); + } + if (zend_hash_find(ht, "features", sizeof("features"), (void**)&tmp) == SUCCESS && Z_TYPE_PP(tmp) == IS_LONG) { add_property_long(this_ptr, "_features", Z_LVAL_PP(tmp)); @@ -2366,7 +2372,6 @@ PHP_METHOD(SoapClient, SoapClient) if (wsdl) { int old_soap_version, ret; - sdlPtr sdl; old_soap_version = SOAP_GLOBAL(soap_version); SOAP_GLOBAL(soap_version) = soap_version; @@ -2379,6 +2384,15 @@ PHP_METHOD(SoapClient, SoapClient) SOAP_GLOBAL(soap_version) = old_soap_version; } + if (typemap_ht) { + HashTable *typemap = soap_create_typemap(sdl, typemap_ht TSRMLS_CC); + if (typemap) { + int ret; + + ret = zend_list_insert(typemap, le_typemap); + add_property_resource(this_ptr, "typemap", ret); + } + } SOAP_CLIENT_END_CODE(); } /* }}} */ @@ -2477,6 +2491,7 @@ static void do_soap_call(zval* this_ptr, xmlCharEncodingHandlerPtr old_encoding; HashTable *old_class_map; int old_features; + HashTable *old_typemap, *typemap = NULL; SOAP_CLIENT_BEGIN_CODE(); @@ -2502,6 +2517,9 @@ static void do_soap_call(zval* this_ptr, if (FIND_SDL_PROPERTY(this_ptr,tmp) != FAILURE) { FETCH_SDL_RES(sdl,tmp); } + if (FIND_TYPEMAP_PROPERTY(this_ptr,tmp) != FAILURE) { + FETCH_TYPEMAP_RES(typemap,tmp); + } clear_soap_fault(this_ptr TSRMLS_CC); @@ -2522,6 +2540,8 @@ static void do_soap_call(zval* this_ptr, } else { SOAP_GLOBAL(class_map) = NULL; } + old_typemap = SOAP_GLOBAL(typemap); + SOAP_GLOBAL(typemap) = typemap; old_features = SOAP_GLOBAL(features); if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_features", sizeof("_features"), (void **) &tmp) == SUCCESS && Z_TYPE_PP(tmp) == IS_LONG) { @@ -2624,7 +2644,8 @@ static void do_soap_call(zval* this_ptr, } } #ifdef ZEND_ENGINE_2 - if (Z_TYPE_P(return_value) == IS_OBJECT && + if (!EG(exception) && + Z_TYPE_P(return_value) == IS_OBJECT && instanceof_function(Z_OBJCE_P(return_value), soap_fault_class_entry TSRMLS_CC) && (zend_hash_find(Z_OBJPROP_P(this_ptr), "_exceptions", sizeof("_exceptions"), (void **) &tmp) != SUCCESS || Z_TYPE_PP(tmp) != IS_BOOL || Z_LVAL_PP(tmp) != 0)) { @@ -2641,6 +2662,7 @@ static void do_soap_call(zval* this_ptr, xmlCharEncCloseFunc(SOAP_GLOBAL(encoding)); } SOAP_GLOBAL(features) = old_features; + SOAP_GLOBAL(typemap) = old_typemap; SOAP_GLOBAL(class_map) = old_class_map; SOAP_GLOBAL(encoding) = old_encoding; SOAP_GLOBAL(sdl) = old_sdl; @@ -4606,9 +4628,9 @@ static void delete_service(void *data) efree(service->soap_functions.ft); } - if (service->mapping) { - zend_hash_destroy(service->mapping); - efree(service->mapping); + if (service->typemap) { + zend_hash_destroy(service->typemap); + efree(service->typemap); } if (service->soap_class.argc) { @@ -4640,3 +4662,10 @@ static void delete_service(void *data) } efree(service); } + +static void delete_hashtable(void *data) +{ + HashTable *ht = (HashTable*)data; + zend_hash_destroy(ht); + efree(ht); +} diff --git a/ext/soap/tests/typemap001.phpt b/ext/soap/tests/typemap001.phpt new file mode 100755 index 0000000000..d76170a748 --- /dev/null +++ b/ext/soap/tests/typemap001.phpt @@ -0,0 +1,60 @@ +--TEST-- +SOAP typemap 1: SoapServer support for typemap's from_xml() +--SKIPIF-- + +--FILE-- + + + + + foo + bar + + + + +"; + +function book_from_xml($xml) { + $sxe = simplexml_load_string($xml); + $obj = new book; + $obj->a = (string)$sxe->a; + $obj->b = (string)$sxe->b; + return $obj; +} + +class test{ + function dotest($book){ + $classname=get_class($book); + return "Object: ".$classname. "(".$book->a.",".$book->b.")"; + } +} + +class book{ + public $a="a"; + public $b="c"; + +} +$options=Array( + 'actor' =>'http://schemas.nothing.com', + 'typemap' => array(array("type_ns" => "http://schemas.nothing.com", + "type_name" => "book", + "from_xml" => "book_from_xml")) + ); + +$server = new SoapServer(dirname(__FILE__)."/classmap.wsdl",$options); +$server->setClass("test"); +$server->handle(); +echo "ok\n"; +?> +--EXPECT-- + +Object: book(foo,bar) +ok diff --git a/ext/soap/tests/typemap002.phpt b/ext/soap/tests/typemap002.phpt new file mode 100755 index 0000000000..ee80c5981c --- /dev/null +++ b/ext/soap/tests/typemap002.phpt @@ -0,0 +1,56 @@ +--TEST-- +SOAP typemap 2: SoapServer support for typemap's to_xml() +--SKIPIF-- + +--FILE-- + + + +??? + + + +"; + +function book_to_xml($book) { + return ''.$book->a.'!'.$book->b.'!'; +} + +class test{ + function dotest2($str){ + $book = new book; + $book->a = "foo"; + $book->b = "bar"; + return $book; + } +} + +class book{ + public $a="a"; + public $b="c"; + +} + +$options=Array( + 'actor' =>'http://schemas.nothing.com', + 'typemap' => array(array("type_ns" => "http://schemas.nothing.com", + "type_name" => "book", + "to_xml" => "book_to_xml")) + ); + +$server = new SoapServer(dirname(__FILE__)."/classmap.wsdl",$options); +$server->setClass("test"); +$server->handle(); +echo "ok\n"; +?> +--EXPECT-- + +foo!bar! +ok diff --git a/ext/soap/tests/typemap003.phpt b/ext/soap/tests/typemap003.phpt new file mode 100755 index 0000000000..17bd6c16e3 --- /dev/null +++ b/ext/soap/tests/typemap003.phpt @@ -0,0 +1,54 @@ +--TEST-- +SOAP Typemap 3: SoapClient support for typemap's from_xml() +--SKIPIF-- + +--FILE-- + + + + foo + bar + + +EOF; + } +} + +class book{ + public $a="a"; + public $b="c"; + +} + +function book_from_xml($xml) { + $sxe = simplexml_load_string($xml); + $obj = new book; + $obj->a = (string)$sxe->a; + $obj->b = (string)$sxe->b; + return $obj; +} + +$options=Array( + 'actor' =>'http://schemas.nothing.com', + 'typemap' => array(array("type_ns" => "http://schemas.nothing.com", + "type_name" => "book", + "from_xml" => "book_from_xml")) + ); + +$client = new TestSoapClient(dirname(__FILE__)."/classmap.wsdl",$options); +$ret = $client->dotest2("???"); +var_dump($ret); +echo "ok\n"; +?> +--EXPECTF-- +object(book)#%d (2) { + ["a"]=> + string(3) "foo" + ["b"]=> + string(3) "bar" +} +ok diff --git a/ext/soap/tests/typemap004.phpt b/ext/soap/tests/typemap004.phpt new file mode 100755 index 0000000000..f94af49900 --- /dev/null +++ b/ext/soap/tests/typemap004.phpt @@ -0,0 +1,41 @@ +--TEST-- +SOAP Typemap 4: SoapClient support for typemap's to_xml() +--SKIPIF-- + +--FILE-- +'.$book->a.'!'.$book->b.'!'; +} + +$options=Array( + 'actor' =>'http://schemas.nothing.com', + 'typemap' => array(array("type_ns" => "http://schemas.nothing.com", + "type_name" => "book", + "to_xml" => "book_to_xml")) + ); + +$client = new TestSoapClient(dirname(__FILE__)."/classmap.wsdl",$options); +$book = new book(); +$book->a = "foo"; +$book->b = "bar"; +$ret = $client->dotest($book); +var_dump($ret); +echo "ok\n"; +?> +--EXPECT-- + +foo!bar! diff --git a/ext/soap/tests/typemap005.phpt b/ext/soap/tests/typemap005.phpt new file mode 100755 index 0000000000..b016519a75 --- /dev/null +++ b/ext/soap/tests/typemap005.phpt @@ -0,0 +1,61 @@ +--TEST-- +SOAP typemap 5: SoapServer support for typemap's from_xml() (without WSDL) +--SKIPIF-- + +--FILE-- + + + + + foo + bar + + + + +"; + +function book_from_xml($xml) { + $sxe = simplexml_load_string($xml); + $obj = new book; + $obj->a = (string)$sxe->a; + $obj->b = (string)$sxe->b; + return $obj; +} + +class test{ + function dotest($book){ + $classname=get_class($book); + return "Object: ".$classname. "(".$book->a.",".$book->b.")"; + } +} + +class book{ + public $a="a"; + public $b="c"; + +} +$options=Array( + 'uri' => "http://schemas.nothing.com", + 'actor' => 'http://schemas.nothing.com', + 'typemap' => array(array("type_ns" => "http://schemas.nothing.com", + "type_name" => "book", + "from_xml" => "book_from_xml")) + ); + +$server = new SoapServer(NULL,$options); +$server->setClass("test"); +$server->handle(); +echo "ok\n"; +?> +--EXPECT-- + +Object: book(foo,bar) +ok diff --git a/ext/soap/tests/typemap006.phpt b/ext/soap/tests/typemap006.phpt new file mode 100755 index 0000000000..1e3609a8bc --- /dev/null +++ b/ext/soap/tests/typemap006.phpt @@ -0,0 +1,57 @@ +--TEST-- +SOAP typemap 6: SoapServer support for typemap's to_xml() (without WSDL, using SoapVar) +--SKIPIF-- + +--FILE-- + + + +??? + + + +"; + +function book_to_xml($book) { + return ''.$book->a.'!'.$book->b.'!'; +} + +class test{ + function dotest2($str){ + $book = new book; + $book->a = "foo"; + $book->b = "bar"; + return new SoapVar($book, null, "book", "http://schemas.nothing.com"); + } +} + +class book{ + public $a="a"; + public $b="c"; + +} + +$options=Array( + 'uri' => "http://schemas.nothing.com", + 'actor' => 'http://schemas.nothing.com', + 'typemap' => array(array("type_ns" => "http://schemas.nothing.com", + "type_name" => "book", + "to_xml" => "book_to_xml")) + ); + +$server = new SoapServer(NULL,$options); +$server->setClass("test"); +$server->handle(); +echo "ok\n"; +?> +--EXPECT-- + +foo!bar! +ok diff --git a/ext/soap/tests/typemap007.phpt b/ext/soap/tests/typemap007.phpt new file mode 100755 index 0000000000..8e2880b58e --- /dev/null +++ b/ext/soap/tests/typemap007.phpt @@ -0,0 +1,56 @@ +--TEST-- +SOAP Typemap 7: SoapClient support for typemap's from_xml() (without WSDL) +--SKIPIF-- + +--FILE-- + + + + foo + bar + + +EOF; + } +} + +class book{ + public $a="a"; + public $b="c"; + +} + +function book_from_xml($xml) { + $sxe = simplexml_load_string($xml); + $obj = new book; + $obj->a = (string)$sxe->a; + $obj->b = (string)$sxe->b; + return $obj; +} + +$options=Array( + 'uri' => 'http://schemas.nothing.com', + 'location' => 'test://', + 'actor' => 'http://schemas.nothing.com', + 'typemap' => array(array("type_ns" => "http://schemas.nothing.com", + "type_name" => "book", + "from_xml" => "book_from_xml")) + ); + +$client = new TestSoapClient(NULL, $options); +$ret = $client->dotest2("???"); +var_dump($ret); +echo "ok\n"; +?> +--EXPECTF-- +object(book)#%d (2) { + ["a"]=> + string(3) "foo" + ["b"]=> + string(3) "bar" +} +ok diff --git a/ext/soap/tests/typemap008.phpt b/ext/soap/tests/typemap008.phpt new file mode 100755 index 0000000000..aaaa715d67 --- /dev/null +++ b/ext/soap/tests/typemap008.phpt @@ -0,0 +1,43 @@ +--TEST-- +SOAP Typemap 8: SoapClient support for typemap's to_xml() (without WSDL, using SoapVar) +--SKIPIF-- + +--FILE-- +'.$book->a.'!'.$book->b.'!'; +} + +$options=Array( + 'uri' => 'http://schemas.nothing.com', + 'location' => 'test://', + 'actor' => 'http://schemas.nothing.com', + 'typemap' => array(array("type_ns" => "http://schemas.nothing.com", + "type_name" => "book", + "to_xml" => "book_to_xml")) + ); + +$client = new TestSoapClient(NULL, $options); +$book = new book(); +$book->a = "foo"; +$book->b = "bar"; +$ret = $client->dotest(new SoapVar($book, null, "book", "http://schemas.nothing.com")); +var_dump($ret); +echo "ok\n"; +?> +--EXPECT-- + +foo!bar! diff --git a/ext/soap/tests/typemap009.phpt b/ext/soap/tests/typemap009.phpt new file mode 100755 index 0000000000..337aea65cc --- /dev/null +++ b/ext/soap/tests/typemap009.phpt @@ -0,0 +1,56 @@ +--TEST-- +SOAP typemap 9: SoapServer support for typemap's from_xml() (SoapFault) +--SKIPIF-- + +--FILE-- + + + + + foo + bar + + + + +"; + +function book_from_xml($xml) { + throw new SoapFault("Server", "Conversion Failed"); +} + +class test{ + function dotest($book){ + $classname=get_class($book); + return "Object: ".$classname. "(".$book->a.",".$book->b.")"; + } +} + +class book{ + public $a="a"; + public $b="c"; + +} +$options=Array( + 'actor' =>'http://schemas.nothing.com', + 'typemap' => array(array("type_ns" => "http://schemas.nothing.com", + "type_name" => "book", + "from_xml" => "book_from_xml")) + ); + +$server = new SoapServer(dirname(__FILE__)."/classmap.wsdl",$options); +$server->setClass("test"); +$server->handle(); +echo "ok\n"; +?> +--EXPECT-- + +SOAP-ENV:ServerConversion Failed +ok diff --git a/ext/soap/tests/typemap010.phpt b/ext/soap/tests/typemap010.phpt new file mode 100755 index 0000000000..44d2746bdd --- /dev/null +++ b/ext/soap/tests/typemap010.phpt @@ -0,0 +1,56 @@ +--TEST-- +SOAP typemap 10: SoapServer support for typemap's to_xml() (SoapFault) +--SKIPIF-- + +--FILE-- + + + +??? + + + +"; + +function book_to_xml($book) { + throw new SoapFault("Server", "Conversion Fault"); +} + +class test{ + function dotest2($str){ + $book = new book; + $book->a = "foo"; + $book->b = "bar"; + return $book; + } +} + +class book{ + public $a="a"; + public $b="c"; + +} + +$options=Array( + 'actor' =>'http://schemas.nothing.com', + 'typemap' => array(array("type_ns" => "http://schemas.nothing.com", + "type_name" => "book", + "to_xml" => "book_to_xml")) + ); + +$server = new SoapServer(dirname(__FILE__)."/classmap.wsdl",$options); +$server->setClass("test"); +$server->handle(); +echo "ok\n"; +?> +--EXPECT-- + +SOAP-ENV:ServerConversion Fault +ok diff --git a/ext/soap/tests/typemap011.phpt b/ext/soap/tests/typemap011.phpt new file mode 100755 index 0000000000..52acde28d9 --- /dev/null +++ b/ext/soap/tests/typemap011.phpt @@ -0,0 +1,49 @@ +--TEST-- +SOAP Typemap 11: SoapClient support for typemap's from_xml() (SoapFault) +--SKIPIF-- + +--FILE-- + + + + foo + bar + + +EOF; + } +} + +class book{ + public $a="a"; + public $b="c"; + +} + +function book_from_xml($xml) { + throw new SoapFault("Client", "Conversion Error"); +} + +$options=Array( + 'actor' =>'http://schemas.nothing.com', + 'typemap' => array(array("type_ns" => "http://schemas.nothing.com", + "type_name" => "book", + "from_xml" => "book_from_xml")) + ); + +$client = new TestSoapClient(dirname(__FILE__)."/classmap.wsdl",$options); +try { + $ret = $client->dotest2("???"); +} catch (SoapFault $e) { + $ret = "SoapFault = " . $e->faultcode . " - " . $e->faultstring; +} +var_dump($ret); +echo "ok\n"; +?> +--EXPECT-- +string(37) "SoapFault = Client - Conversion Error" +ok diff --git a/ext/soap/tests/typemap012.phpt b/ext/soap/tests/typemap012.phpt new file mode 100755 index 0000000000..aa06215fe3 --- /dev/null +++ b/ext/soap/tests/typemap012.phpt @@ -0,0 +1,45 @@ +--TEST-- +SOAP Typemap 12: SoapClient support for typemap's to_xml() (SoapFault) +--SKIPIF-- + +--FILE-- +'http://schemas.nothing.com', + 'typemap' => array(array("type_ns" => "http://schemas.nothing.com", + "type_name" => "book", + "to_xml" => "book_to_xml")) + ); + +$client = new TestSoapClient(dirname(__FILE__)."/classmap.wsdl",$options); +$book = new book(); +$book->a = "foo"; +$book->b = "bar"; +try { + $ret = $client->dotest($book); +} catch (SoapFault $e) { + $ret = "SoapFault = " . $e->faultcode . " - " . $e->faultstring; +} +var_dump($ret); +echo "ok\n"; +?> +--EXPECT-- +string(37) "SoapFault = Client - Conversion Error" +ok