General
-------
- rename soapobject to soapclient
-- make sure soapvar and soapparam are really need
- make sure soapserver.map(), soap_encode_to_xml() and soap_encode_to_zval() are really need
- reimplement SoapObject::__getfunctions() and SoapObject::__gettypes()
to return structures instead of strings
$this->_getEndpoints($test, 1);
// retreive endpoints from the endpoint server
- $endpointArray = $soapclient->__call("GetEndpointInfo",array("groupName"=>$test),"http://soapinterop.org/info/","http://soapinterop.org/info/");
+ $endpointArray = $soapclient->__call("GetEndpointInfo",array("groupName"=>$test),"http://soapinterop.org/","http://soapinterop.org/");
if ($soapclient->__isfault() || PEAR::isError($endpointArray)) {
print "<pre>".$soapclient->wire."\n";
print_r($endpointArray);
return $a;
}
-function soap_value($name, $value, $type) {
- return new soapparam(new soapvar($value,$type),$name);
+function soap_value($name, $value, $type, $type_name=NULL, $type_ns=NULL) {
+ return new soapparam(new soapvar($value,$type,$type_name,$type_ns),$name);
}
class SOAPStruct {
array('inputStringArray' => array('good','bad')));
$soap_tests['base'][] = new SOAP_Test('echoStringArray',
array('inputStringArray' =>
- soap_value('inputStringArray',array('good','bad'),SOAP_ENC_ARRAY)));
+ soap_value('inputStringArray',array('good','bad'),SOAP_ENC_ARRAY,"ArrayOfstring","http://soapinterop.org/xsd")));
$soap_tests['base'][] = new SOAP_Test('echoStringArray(one)',
array('inputStringArray' => array('good')));
$soap_tests['base'][] = new SOAP_Test('echoStringArray(one)',
array('inputStringArray' =>
- soap_value('inputStringArray',array('good'),SOAP_ENC_ARRAY)));
+ soap_value('inputStringArray',array('good'),SOAP_ENC_ARRAY,"ArrayOfstring","http://soapinterop.org/xsd")));
// empty array test
$soap_tests['base'][] = new SOAP_Test('echoStringArray(empty)', array('inputStringArray' => array()));
-$soap_tests['base'][] = new SOAP_Test('echoStringArray(empty)', array('inputStringArray' => soap_value('inputStringArray',array(),SOAP_ENC_ARRAY)));
+$soap_tests['base'][] = new SOAP_Test('echoStringArray(empty)', array('inputStringArray' => soap_value('inputStringArray',array(),SOAP_ENC_ARRAY,"ArrayOfstring","http://soapinterop.org/xsd")));
# XXX NULL Arrays not supported
// null array test
$soap_tests['base'][] = new SOAP_Test('echoStringArray(null)', array('inputStringArray' => NULL));
-$soap_tests['base'][] = new SOAP_Test('echoStringArray(null)', array('inputStringArray' => soap_value('inputStringArray',NULL,SOAP_ENC_ARRAY)));
+$soap_tests['base'][] = new SOAP_Test('echoStringArray(null)', array('inputStringArray' => soap_value('inputStringArray',NULL,SOAP_ENC_ARRAY,"ArrayOfstring","http://soapinterop.org/xsd")));
//***********************************************************
// Base echoInteger
array('inputIntegerArray' =>
soap_value('inputIntegerArray',
array(new soapvar(12345,XSD_INT),new soapvar(654321,XSD_INT)),
- SOAP_ENC_ARRAY)));
+ SOAP_ENC_ARRAY,"ArrayOfint","http://soapinterop.org/xsd")));
//***********************************************************
// Base echoFloat
array('inputFloatArray' =>
soap_value('inputFloatArray',
array(new soapvar(123.45,XSD_FLOAT),new soapvar(654.321,XSD_FLOAT)),
- SOAP_ENC_ARRAY)));
+ SOAP_ENC_ARRAY,"ArrayOffloat","http://soapinterop.org/xsd")));
//***********************************************************
// Base echoStruct
$soapstruct = new SOAPStruct('arg',34,325.325);
# XXX no way to set a namespace!!!
-$soapsoapstruct = soap_value('inputStruct',$soapstruct,SOAP_ENC_OBJECT);
+$soapsoapstruct = soap_value('inputStruct',$soapstruct,SOAP_ENC_OBJECT,"SOAPStruct","http://soapinterop.org/xsd");
$soap_tests['base'][] = new SOAP_Test('echoStruct', array('inputStruct' =>$soapstruct));
$soap_tests['base'][] = new SOAP_Test('echoStruct', array('inputStruct' =>$soapsoapstruct));
$soap_tests['base'][] = new SOAP_Test('echoStructArray', array('inputStructArray' => array(
$soapstruct,$soapstruct,$soapstruct)));
$soap_tests['base'][] = new SOAP_Test('echoStructArray', array('inputStructArray' =>
- soap_value('inputStructArray',array($soapstruct,$soapstruct,$soapstruct),SOAP_ENC_ARRAY)));
+ soap_value('inputStructArray',array(
+ new soapvar($soapstruct,SOAP_ENC_OBJECT,"SOAPStruct","http://soapinterop.org/xsd"),
+ new soapvar($soapstruct,SOAP_ENC_OBJECT,"SOAPStruct","http://soapinterop.org/xsd"),
+ new soapvar($soapstruct,SOAP_ENC_OBJECT,"SOAPStruct","http://soapinterop.org/xsd")),
+ SOAP_ENC_ARRAY,"ArrayOfSOAPStruct","http://soapinterop.org/xsd")));
//***********************************************************
(object)array('varString' => 'arg',
'varInt' => 34,
'varFloat' => 325.325
- ), SOAP_ENC_OBJECT)), $expect);
+ ), SOAP_ENC_OBJECT, "SOAPStruct","http://soapinterop.org/xsd")), $expect);
//***********************************************************
// GroupB echoSimpleTypesAsStruct
//***********************************************************
// GroupB echoNestedStruct
-$soap_tests['GroupB'][] = new SOAP_Test('echoNestedStruct',
- array('inputStruct' => (object)array(
+$strstr = (object)array(
'varString'=>'arg',
'varInt'=>34,
'varFloat'=>325.325,
'varString'=>'arg',
'varInt'=>34,
'varFloat'=>325.325
- )
- )));
+ ));
+$soap_tests['GroupB'][] = new SOAP_Test('echoNestedStruct',
+ array('inputStruct' => $strstr));
$soap_tests['GroupB'][] = new SOAP_Test('echoNestedStruct',
array('inputStruct' =>
soap_value('inputStruct',
'varString'=>'arg',
'varInt'=>34,
'varFloat'=>325.325,
- 'varStruct' => (object)array(
+ 'varStruct' => new SoapVar((object)array(
'varString'=>'arg',
'varInt'=>34,
'varFloat'=>325.325
- )
-// array( #push struct elements into one soap value
-// soap_value('varString','arg', XSD_STRING),
-// soap_value('varInt',34, XSD_INT),
-// soap_value('varFloat',325.325,XSD_FLOAT),
-// soap_value('varStruct',
-// (object)array('varString' => 'arg',
-// 'varInt' => 34,
-// 'varFloat' => 325.325
-// ), SOAP_ENC_OBJECT
- ), SOAP_ENC_OBJECT
- )));
+ ), SOAP_ENC_OBJECT, "SOAPStruct","http://soapinterop.org/xsd")
+ ), SOAP_ENC_OBJECT, "SOAPStructStruct","http://soapinterop.org/xsd"
+ )),$strstr);
//***********************************************************
// GroupB echoNestedArray
-$soap_tests['GroupB'][] = new SOAP_Test('echoNestedArray',
- array('inputStruct' => (object)array(
+$arrstr = (object)array(
'varString'=>'arg',
'varInt'=>34,
'varFloat'=>325.325,
'varArray' => array('red','blue','green')
- )));
+ );
+$soap_tests['GroupB'][] = new SOAP_Test('echoNestedArray',
+ array('inputStruct' => $arrstr));
$soap_tests['GroupB'][] = new SOAP_Test('echoNestedArray',
array('inputStruct' =>
soap_value('inputStruct',
'varInt' => 34,
'varFloat' => 325.325,
'varArray' =>
- array("red", "blue", "green")
-// soap_value('item','red', XSD_STRING),
-// soap_value('item','blue', XSD_STRING),
-// soap_value('item','green', XSD_STRING)
-// )
- ), SOAP_ENC_OBJECT
- )));
+ new SoapVar(array("red", "blue", "green"), SOAP_ENC_ARRAY, "ArrayOfstring","http://soapinterop.org/xsd")
+ ), SOAP_ENC_OBJECT, "SOAPArrayStruct","http://soapinterop.org/xsd"
+ )),$arrstr);
#//***********************************************************
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:tns="http://soapinterop.org/"
+ xmlns:s="http://soapinterop.org/xsd"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns="http://schemas.xmlsoap.org/wsdl/"
targetNamespace="http://soapinterop.org/">
<types>
- <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://soapinterop.org/">
+ <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://soapinterop.org/xsd">
<xsd:import namespace="http://schemas.xmlsoap.org/soap/encoding/" />
<xsd:import namespace="http://schemas.xmlsoap.org/wsdl/" />
<xsd:complexType name="ArrayOfstring">
<xsd:complexType name="ArrayOfSOAPStruct">
<xsd:complexContent>
<xsd:restriction base="SOAP-ENC:Array">
- <xsd:attribute ref="SOAP-ENC:arrayType" wsdl:arrayType="tns:SOAPStruct[]"/>
+ <xsd:attribute ref="SOAP-ENC:arrayType" wsdl:arrayType="s:SOAPStruct[]"/>
</xsd:restriction>
</xsd:complexContent>
</xsd:complexType>
<part name="outputString" type="xsd:string" />
</message>
<message name="echoStringArrayRequest">
- <part name="inputStringArray" type="tns:ArrayOfstring" />
+ <part name="inputStringArray" type="s:ArrayOfstring" />
</message>
<message name="echoStringArrayResponse">
- <part name="outputStringArray" type="tns:ArrayOfstring" />
+ <part name="outputStringArray" type="s:ArrayOfstring" />
</message>
<message name="echoIntegerRequest">
<part name="inputInteger" type="xsd:int" />
<part name="outputInteger" type="xsd:int" />
</message>
<message name="echoIntegerArrayRequest">
- <part name="inputIntegerArray" type="tns:ArrayOfint" />
+ <part name="inputIntegerArray" type="s:ArrayOfint" />
</message>
<message name="echoIntegerArrayResponse">
- <part name="outputIntegerArray" type="tns:ArrayOfint" />
+ <part name="outputIntegerArray" type="s:ArrayOfint" />
</message>
<message name="echoFloatRequest">
<part name="inputFloat" type="xsd:float" />
<part name="outputFloat" type="xsd:float" />
</message>
<message name="echoFloatArrayRequest">
- <part name="inputFloatArray" type="tns:ArrayOffloat" />
+ <part name="inputFloatArray" type="s:ArrayOffloat" />
</message>
<message name="echoFloatArrayResponse">
- <part name="outputFloatArray" type="tns:ArrayOffloat" />
+ <part name="outputFloatArray" type="s:ArrayOffloat" />
</message>
<message name="echoStructRequest">
- <part name="inputStruct" type="tns:SOAPStruct" />
+ <part name="inputStruct" type="s:SOAPStruct" />
</message>
<message name="echoStructResponse">
- <part name="outputStruct" type="tns:SOAPStruct" />
+ <part name="outputStruct" type="s:SOAPStruct" />
</message>
<message name="echoStructArrayRequest">
- <part name="inputStructArray" type="tns:ArrayOfSOAPStruct" />
+ <part name="inputStructArray" type="s:ArrayOfSOAPStruct" />
</message>
<message name="echoStructArrayResponse">
- <part name="outputStructArray" type="tns:ArrayOfSOAPStruct" />
+ <part name="outputStructArray" type="s:ArrayOfSOAPStruct" />
</message>
<message name="echoVoidRequest">
</message>
xmlNodePtr node = NULL;
TSRMLS_FETCH();
- if (encode == NULL) {
- encode = get_conversion(UNKNOWN_TYPE);
- }
- if (encode->to_xml_before) {
- data = encode->to_xml_before(&encode->details, data);
- }
- 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);
+ /* Special handling of class SoapVar */
+ if (data &&
+ Z_TYPE_P(data) == IS_OBJECT &&
+ Z_OBJCE_P(data) == soap_var_class_entry) {
+ zval **ztype, **zdata, **zns, **zstype, **zname, **znamens;
+ encodePtr enc;
+
+ if (zend_hash_find(Z_OBJPROP_P(data), "enc_type", sizeof("enc_type"), (void **)&ztype) == FAILURE) {
+ php_error(E_ERROR, "SOAP-ERROR: Encoding: SoapVar hasn't 'enc_type' propery");
+ }
+
+ enc = get_conversion(Z_LVAL_P(*ztype));
+
+ if (zend_hash_find(Z_OBJPROP_P(data), "enc_value", sizeof("enc_value"), (void **)&zdata) == FAILURE) {
+ node = master_to_xml(enc, NULL, style, parent);
+ } else {
+ node = master_to_xml(enc, *zdata, style, parent);
+ }
+
+ if (zend_hash_find(Z_OBJPROP_P(data), "enc_stype", sizeof("enc_stype"), (void **)&zstype) == SUCCESS) {
+ if (zend_hash_find(Z_OBJPROP_P(data), "enc_ns", sizeof("enc_ns"), (void **)&zns) == SUCCESS) {
+ set_ns_and_type_ex(node, Z_STRVAL_PP(zns), Z_STRVAL_PP(zstype));
+ } else {
+ set_ns_and_type_ex(node, NULL, Z_STRVAL_PP(zstype));
+ }
+ }
+
+ if (zend_hash_find(Z_OBJPROP_P(data), "enc_name", sizeof("enc_name"), (void **)&zname) == SUCCESS) {
+ xmlNodeSetName(node, Z_STRVAL_PP(zname));
+ }
+ if (zend_hash_find(Z_OBJPROP_P(data), "enc_namens", sizeof("enc_namens"), (void **)&znamens) == SUCCESS) {
+ xmlNsPtr nsp = encode_add_ns(node, Z_STRVAL_PP(znamens));
+ xmlSetNs(node, nsp);
+ }
+ } else {
+ if (encode == NULL) {
+ encode = get_conversion(UNKNOWN_TYPE);
+ }
+ if (encode->to_xml_before) {
+ data = encode->to_xml_before(&encode->details, data);
+ }
+ 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;
}
sdlTypePtr sdlType = type->sdl_type;
TSRMLS_FETCH();
- /* Special handling of class SoapVar */
- if (data &&
- Z_TYPE_P(data) == IS_OBJECT &&
- Z_OBJCE_P(data) == soap_var_class_entry) {
- zval **ztype, **zdata, **zns, **zstype, **zname, **znamens;
- encodePtr enc;
-
- if (zend_hash_find(Z_OBJPROP_P(data), "enc_type", sizeof("enc_type"), (void **)&ztype) == FAILURE) {
- php_error(E_ERROR, "SOAP-ERROR: Encoding: SoapVar hasn't 'enc_type' propery");
- }
-
- enc = get_conversion(Z_LVAL_P(*ztype));
-
- if (zend_hash_find(Z_OBJPROP_P(data), "enc_value", sizeof("enc_value"), (void **)&zdata) == FAILURE) {
- xmlParam = master_to_xml(enc, NULL, style, parent);
- } else {
- xmlParam = master_to_xml(enc, *zdata, style, parent);
- }
-
- if (zend_hash_find(Z_OBJPROP_P(data), "enc_stype", sizeof("enc_stype"), (void **)&zstype) == SUCCESS) {
- if (zend_hash_find(Z_OBJPROP_P(data), "enc_ns", sizeof("enc_ns"), (void **)&zns) == SUCCESS) {
- set_ns_and_type_ex(xmlParam, Z_STRVAL_PP(zns), Z_STRVAL_PP(zstype));
- } else {
- set_ns_and_type_ex(xmlParam, NULL, Z_STRVAL_PP(zstype));
- }
- }
-
- if (zend_hash_find(Z_OBJPROP_P(data), "enc_name", sizeof("enc_name"), (void **)&zname) == SUCCESS) {
- xmlNodeSetName(xmlParam, Z_STRVAL_PP(zname));
- }
- if (zend_hash_find(Z_OBJPROP_P(data), "enc_namens", sizeof("enc_namens"), (void **)&znamens) == SUCCESS) {
- xmlNsPtr nsp = encode_add_ns(xmlParam, Z_STRVAL_PP(znamens));
- xmlSetNs(xmlParam, nsp);
- }
- } else if (sdlType) {
+ if (sdlType) {
prop = NULL;
if (Z_TYPE_P(data) == IS_OBJECT) {
prop = Z_OBJPROP_P(data);
HashTable *ht = HASH_OF(array);
int i, count, cur_type, prev_type, different;
zval **tmp;
+ char *prev_stype, *cur_stype, *prev_ns, *cur_ns;
if (!array || Z_TYPE_P(array) != IS_ARRAY) {
smart_str_appendl(type, "xsd:anyType", 11);
if (zend_hash_find(Z_OBJPROP_PP(tmp), "enc_type", sizeof("enc_type"), (void **)&ztype) == FAILURE) {
php_error(E_ERROR, "SOAP-ERROR: Encoding: SoapVar hasn't 'enc_type' property");
}
- cur_type = Z_LVAL_P(*ztype);
+ cur_type = Z_LVAL_PP(ztype);
+
+ if (zend_hash_find(Z_OBJPROP_PP(tmp), "enc_stype", sizeof("enc_stype"), (void **)&ztype) == SUCCESS) {
+ cur_stype = Z_STRVAL_PP(ztype);
+ } else {
+ cur_stype = NULL;
+ }
+
+ if (zend_hash_find(Z_OBJPROP_PP(tmp), "enc_ns", sizeof("enc_ns"), (void **)&ztype) == SUCCESS) {
+ cur_ns = Z_STRVAL_PP(ztype);
+ } else {
+ cur_ns = NULL;
+ }
+
} else if (Z_TYPE_PP(tmp) == IS_ARRAY && is_map(*tmp)) {
cur_type = APACHE_MAP;
+ cur_stype = NULL;
+ cur_ns = NULL;
} else {
cur_type = Z_TYPE_PP(tmp);
+ cur_stype = NULL;
+ cur_ns = NULL;
}
if (i > 0) {
- if (cur_type != prev_type) {
+ if ((cur_type != prev_type) ||
+ (cur_stype != NULL && prev_stype != NULL && strcmp(cur_stype,prev_stype) != 0) ||
+ (cur_stype == NULL && cur_stype != prev_stype) ||
+ (cur_ns != NULL && prev_ns != NULL && strcmp(cur_ns,prev_ns) != 0) ||
+ (cur_ns == NULL && cur_ns != prev_ns)) {
different = TRUE;
break;
}
}
prev_type = cur_type;
+ prev_stype = cur_stype;
+ prev_ns = cur_ns;
zend_hash_move_forward(ht);
}
if (different || count == 0) {
smart_str_appendl(type, "xsd:anyType", 11);
} else {
- encodePtr enc;
+ if (cur_stype != NULL) {
+ if (cur_ns) {
+ xmlNsPtr ns = encode_add_ns(node,cur_ns);
+ smart_str_appends(type,ns->prefix);
+ smart_str_appendc(type,':');
+ }
+ smart_str_appends(type,cur_stype);
+ smart_str_0(type);
+ } else {
+ encodePtr enc;
- enc = get_conversion(cur_type);
- get_type_str(node, enc->details.ns, enc->details.type_str, type);
+ enc = get_conversion(cur_type);
+ get_type_str(node, enc->details.ns, enc->details.type_str, type);
+ }
}
}
int function_len,
int arg_count,
zval** real_args,
- zval* return_value
- TSRMLS_DC)
+ zval* return_value,
+ char* soap_action,
+ char* call_uri
+ TSRMLS_DC)
{
zval **tmp;
zval **trace;
} else if (zend_hash_find(Z_OBJPROP_P(thisObj), "location", sizeof("location"),(void **) &location) == FAILURE) {
add_soap_fault(thisObj, "Client", "Error could not find \"location\" property", NULL, NULL TSRMLS_CC);
} else {
- request = seralize_function_call(thisObj, NULL, function, Z_STRVAL_PP(uri), real_args, arg_count, soap_version TSRMLS_CC);
+ if (call_uri == NULL) {
+ call_uri = Z_STRVAL_PP(uri);
+ }
+ request = seralize_function_call(thisObj, NULL, function, call_uri, real_args, arg_count, soap_version TSRMLS_CC);
- smart_str_appendl(&action, Z_STRVAL_PP(uri), Z_STRLEN_PP(uri));
- smart_str_appendc(&action, '#');
- smart_str_appends(&action, function);
+ if (soap_action == NULL) {
+ smart_str_appendl(&action, Z_STRVAL_PP(uri), Z_STRLEN_PP(uri));
+ smart_str_appendc(&action, '#');
+ smart_str_appends(&action, function);
+ } else {
+ smart_str_appends(&action, soap_action);
+ }
smart_str_0(&action);
ret = send_http_soap_request(thisObj, request, Z_STRVAL_PP(location), action.c, soap_version TSRMLS_CC);
PHP_METHOD(soapobject, __call)
{
- char *function, *soap_action, *uri;
+ char *function, *soap_action = NULL, *uri = NULL;
int function_len, soap_action_len, uri_len, i = 0;
zval *args;
zval **real_args;
/*zval_add_ref(param);*/
real_args[i++] = *param;
}
- do_soap_call(this_ptr, function, function_len, arg_count, real_args, return_value TSRMLS_CC);
+ do_soap_call(this_ptr, function, function_len, arg_count, real_args, return_value, soap_action, uri TSRMLS_CC);
efree(real_args);
}
zval **arguments = (zval **) emalloc(sizeof(zval *) * arg_count);
zend_get_parameters_array(ht, arg_count, arguments);
- do_soap_call(this_ptr, function, Z_STRLEN(function_name->element) + 1, arg_count, arguments, return_value TSRMLS_CC);
+ do_soap_call(this_ptr, function, Z_STRLEN(function_name->element) + 1, arg_count, arguments, return_value, NULL, NULL TSRMLS_CC);
efree(arguments);
}
zval_dtor(&function_name->element);