cvs: pear /SOAP Base.php Client.php Parser.php Server.php Transport.php Value.php WSDL.php package.xml /SOAP/Server Email.php Email_Gateway.php
/SOAP/Transport HTTP.php SMTP.php /SOAP/example client.php /SOAP/interop client_round2_run.php /SOAP/test 5.2.1.simpletypes.string.php
5.2.simpletypes.php test.utility.php /SOAP/tools genproxy.php
| From: | Shane Caraveo | Date: | Sun, 29 Sep 2002 01:06:14 +0000 |
| Subject: | cvs: pear /SOAP Base.php Client.php Parser.php Server.php Transport.php Value.php WSDL.php package.xml /SOAP/Server Email.php Email_Gateway.php /SOAP/Transport HTTP.php SMTP.php /SOAP/example client.php /SOAP/interop client_round2_run.php /SOAP/test 5.2.1.simpletypes.string.php 5.2.simpletypes.php test.utility.php /SOAP/tools genproxy.php |
||
| Groups: | php.pear.cvs | ||
| Request: | Send a blank email to pear-cvs+get-6740@lists.php.net to get a copy of this message | ||
shane Sat Sep 28 21:06:14 2002 EDT
Modified files:
/pear/SOAP Base.php Client.php Parser.php Server.php Transport.php
Value.php WSDL.php package.xml
/pear/SOAP/Server Email.php Email_Gateway.php
/pear/SOAP/Transport HTTP.php SMTP.php
/pear/SOAP/example client.php
/pear/SOAP/interop client_round2_run.php
/pear/SOAP/test 5.2.1.simpletypes.string.php 5.2.simpletypes.php
test.utility.php
/pear/SOAP/tools genproxy.php
Log:
Includes minor API changes from 0.6.2.
Supports HTTP Proxy (SOAP_Client constructor
takes 4th param of type array, SOAP_WSDL
constructor takes 2nd param of type array, see HTTP_Request
docs for proxy parameters).
Improved WSDL proxy generation.
Interop tests are moved to SOAP_Interop module, available
via CVS only.
Now additionaly requires PEAR modules Net_URL, Net_Socket, HTTP_Request
Index: pear/SOAP/Base.php diff -u pear/SOAP/Base.php:1.22 pear/SOAP/Base.php:1.23 --- pear/SOAP/Base.php:1.22 Sun Aug 18 14:45:48 2002 +++ pear/SOAP/Base.php Sat Sep 28 21:06:07 2002 @@ -17,7 +17,7 @@ // | Authors: Dietrich Ayala <dietrich@ganx4.com> Original Author | // +----------------------------------------------------------------------+ // -// $Id: Base.php,v 1.22 2002/08/18 18:45:48 shane Exp $ +// $Id: Base.php,v 1.23 2002/09/29 01:06:07 shane Exp $ // /* @@ -112,7 +112,7 @@ * Common base class of all Soap lclasses * * @access public -* @version $Id: Base.php,v 1.22 2002/08/18 18:45:48 shane Exp $ +* @version $Id: Base.php,v 1.23 2002/09/29 01:06:07 shane Exp $ * @package SOAP::Client * @author Shane Caraveo <shane@php.net> Conversion to PEAR and updates */ @@ -194,9 +194,9 @@ var $_xmlEntities = array ( '&' => '&', '<' => '<', '>' => '>', "'" => ''', '"' => '"' ); - var $doconversion = FALSE; + var $_doconversion = FALSE; - var $attachments = array(); + var $__attachments = array(); /** * Store debugging information in $debug_data? @@ -204,7 +204,7 @@ * @var boolean if true debugging informations will be store in $debug_data * @see $debug_data, SOAP_Base */ - var $debug_flag = false; + var $_debug_flag = false; /** * String containing debugging informations if $debug_flag is set to true @@ -213,14 +213,14 @@ * @see $debug_flag, SOAP_Base * @access public */ - var $debug_data = ''; + var $_debug_data = ''; /** * Fault code * * @var string */ - var $myfaultcode = ''; + var $_myfaultcode = ''; /** * Recent PEAR error object @@ -229,14 +229,14 @@ */ var $fault = NULL; - var $wsdl = NULL; + var $_wsdl = NULL; /** * section5 * * @var boolean defines if we use section 5 encoding, or false if this is literal */ - var $section5 = TRUE; + var $_section5 = TRUE; // handle type to class mapping var $_auto_translation = false; @@ -247,17 +247,17 @@ * Constructor * * @param string error code - * @see $debug_data, debug() + * @see $debug_data, _debug() */ function SOAP_Base($faultcode = 'Client') { - $this->myfaultcode = $faultcode; - $this->resetNamespaces(); - $this->debug_flag = $GLOBALS['SOAP_DEBUG']; - parent::PEAR('SOAP_Fault'); + $this->_myfaultcode = $faultcode; + $this->_resetNamespaces(); + $this->_debug_flag = $GLOBALS['SOAP_DEBUG']; + parent::PEAR('SOAPfault'); } - function resetNamespaces() + function _resetNamespaces() { $this->_namespaces = array( 'http://schemas.xmlsoap.org/soap/envelope/' => 'SOAP-ENV', @@ -267,7 +267,7 @@ } /** - * setSchemaVersion + * _setSchemaVersion * * sets the schema version used in the soap message * @@ -275,10 +275,10 @@ * * @access private */ - function setSchemaVersion($schemaVersion) + function _setSchemaVersion($schemaVersion) { if (!in_array($schemaVersion, $this->_XMLSchema)) { - return $this->raiseSoapFault("unsuported XMLSchema $schemaVersion"); + return $this->_raiseSoapFault("unsuported XMLSchema $schemaVersion"); } $this->_XMLSchemaVersion = $schemaVersion; $tmpNS = array_flip($this->_namespaces); @@ -304,13 +304,13 @@ * @param boolean * @see $debug_flag, $debug_data */ - function &raiseSoapFault($str, $detail = '', $actorURI = '', $code = null, $mode = null, $options = null, $skipmsg = false) + function &_raiseSoapFault($str, $detail = '', $actorURI = '', $code = null, $mode = null, $options = null, $skipmsg = false) { # pass through previous faults if (is_object($str)) { $this->fault = $str; } else { - if (!$code) $code = $this->myfaultcode; + if (!$code) $code = $this->_myfaultcode; $this->fault = new SOAP_Fault($str, $code, $actorURI, @@ -320,20 +320,30 @@ } return $this->fault; } + + function __isfault() + { + return $this->fault != NULL; + } + + function &__getfault() + { + return $this->fault; + } /** * maintains a string of debug data * * @param debugging message - sometimes an error message */ - function debug($string) + function _debug($string) { - if ($this->debug_flag) { - $this->debug_data .= get_class($this) . ': ' . preg_replace("/>/", ">\r\n", $string) . "\n"; + if ($this->_debug_flag) { + $this->_debug_data .= get_class($this) . ': ' . preg_replace("/>/", ">\r\n", $string) . "\n"; } } - function getNamespacePrefix($ns) + function _getNamespacePrefix($ns) { if (array_key_exists($ns,$this->_namespaces)) { return $this->_namespaces[$ns]; @@ -343,122 +353,141 @@ return $prefix; return NULL; } - - function serializeValue(&$value, $name = '', $type = false, $elNamespace = NULL, $typeNamespace=NULL, $options=array(), $attributes = array()) + + function _getNamespaceForPrefix($prefix) + { + $flipped = array_flip($this->_namespaces); + if (array_key_exists($prefix,$flipped)) { + return $flipped[$prefix]; + } + return NULL; + } + + function _isSoapValue(&$value) + { + return is_object($value) && + (get_class($value) == 'soap_value' || + is_subclass_of($value,'soap_value')); + } + + function _serializeValue(&$value, $name = '', $type = false, $elNamespace = NULL, $typeNamespace=NULL, $options=array(), $attributes = array(), $artype='') { $namespaces = array(); - $xmlout_value = NULL; + $arrayType = $xmlout_value = NULL; $typePrefix = $elPrefix = $xmlout_offset = $xmlout_arrayType = $xmlout_type = $xmlns = ''; + $ptype = $array_type_ns = ''; if (!$name || is_numeric($name)) { $name = 'item'; } - - if (!is_null($value)) { - $ptype = $arrayType = $array_type_ns = ''; - if ($this->wsdl) - list($ptype,$arrayType,$array_type_ns) = $this->wsdl->getSchemaType($type, $name, $typeNamespace); - if (!$ptype) $ptype = $this->_getType($value); - if (!$type) $type = $ptype; - - #if ($ptype == 'object') { - # return $value->serialize($this); - #} else - if (strcasecmp($ptype,'Struct')==0 || strcasecmp($type,'Struct')==0) { - // struct - if (is_object($value)) { - $vars = get_object_vars($value); - } else { - $vars = &$value; - } - if (is_array($vars)) { - foreach (array_keys($vars) as $k) { - if (is_object($vars[$k])) { - if (is_a($vars[$k],'soap_value')) { - $xmlout_value .= $vars[$k]->serialize($this); - } else { - // XXX get the members and serialize them instead - // converting to an array is more overhead than we - // should realy do, but php-soap is on it's way. - $xmlout_value .= $this->serializeValue(get_object_vars($vars[$k]), $k); - } + + if ($this->_wsdl) + list($ptype,$arrayType,$array_type_ns) = $this->_wsdl->getSchemaType($type, $name, $typeNamespace); + + if (!$arrayType) $arrayType = $artype; + if (!$ptype) $ptype = $this->_getType($value); + if (!$type) $type = $ptype; + + if (strcasecmp($ptype,'Struct')==0 || strcasecmp($type,'Struct')==0) { + // struct + $vars = NULL; + if (is_object($value)) { + $vars = get_object_vars($value); + } else { + $vars = &$value; + } + if (is_array($vars)) { + foreach (array_keys($vars) as $k) { + if ($k[0]=='_') continue; // hide private vars + if (is_object($vars[$k])) { + if (is_a($vars[$k],'soap_value')) { + $xmlout_value .= $vars[$k]->serialize($this); } else { - $xmlout_value .= $this->serializeValue($vars[$k],$k); + // XXX get the members and serialize them instead + // converting to an array is more overhead than we + // should realy do, but php-soap is on it's way. + $xmlout_value .= $this->_serializeValue(get_object_vars($vars[$k]), $k); } + } else { + $xmlout_value .= $this->_serializeValue($vars[$k],$k); } } - } else if (strcasecmp($ptype,'Array')==0 || strcasecmp($type,'Array')==0) { - // array - $typeNamespace = SOAP_SCHEMA_ENCODING; - $type = 'Array'; - $numtypes = 0; - // XXX this will be slow on larger array's. Basicly, it flattens array's to allow us - // to serialize multi-dimensional array's. We only do this if arrayType is set, - // which will typicaly only happen if we are using WSDL - if (isset($options['flatten']) || ($arrayType && (strchr($arrayType,',') || strstr($arrayType,'][')))) { - $numtypes = $this->_multiArrayType($value, $arrayType, $ar_size, $xmlout_value); - } + } + } else if (strcasecmp($ptype,'Array')==0 || strcasecmp($type,'Array')==0) { + // array + $typeNamespace = SOAP_SCHEMA_ENCODING; + $type = 'Array'; + $numtypes = 0; + // XXX this will be slow on larger array's. Basicly, it flattens array's to allow us + // to serialize multi-dimensional array's. We only do this if arrayType is set, + // which will typicaly only happen if we are using WSDL + if (isset($options['flatten']) || ($arrayType && (strchr($arrayType,',') || strstr($arrayType,'][')))) { + $numtypes = $this->_multiArrayType($value, $arrayType, $ar_size, $xmlout_value); + } + + $array_type = $array_type_prefix = ''; + if ($numtypes != 1) { + $arrayTypeQName = new QName($arrayType); + $arrayType = $arrayTypeQName->name; + $array_types = array(); + $array_val = NULL; - $array_type = $array_type_prefix = ''; - if ($numtypes != 1) { - $arrayTypeQName = new QName($arrayType); - $arrayType = $arrayTypeQName->name; - $array_types = array(); - $array_val = NULL; - - // serialize each array element - $ar_size = count($value); - for ($i=0; $i < $ar_size; $i++) { - $array_val =& $value[$i]; - if (is_object($array_val)) { - $array_type = $array_val->type; - $array_types[$array_type] = 1; - $array_type_ns = $array_val->type_namespace; - $xmlout_value .= $array_val->serialize($this); - } else { - $array_type = $this->_getType($array_val); - $array_types[$array_type] = 1; - $xmlout_value .= $this->serializeValue($array_val,'item', $array_type); - } - } - - $xmlout_offset = " SOAP-ENC:offset=\"[0]\""; - if (!$arrayType) { - $numtypes = count($array_types); - if ($numtypes == 1) $arrayType = $array_type; - // using anyType is more interoperable - if ($array_type == 'Struct') { - $array_type = ''; - } else if ($array_type == 'Array') { - $arrayType = 'anyType'; - $array_type_prefix = 'xsd'; - } else - if (!$arrayType) $arrayType = $array_type; + // serialize each array element + $ar_size = count($value); + for ($i=0; $i < $ar_size; $i++) { + $array_val =& $value[$i]; + if ($this->_isSoapValue($array_val)) { + $array_type = $array_val->type; + $array_types[$array_type] = 1; + $array_type_ns = $array_val->type_namespace; + $xmlout_value .= $array_val->serialize($this); + } else { + $array_type = $this->_getType($array_val); + $array_types[$array_type] = 1; + $xmlout_value .= $this->_serializeValue($array_val,'item', $array_type); } } - if (!isset($arrayType) || $numtypes > 1) { - $arrayType = 'xsd:anyType'; // should reference what schema we're using - } else { - if ($array_type_ns) { - $array_type_prefix = $this->getNamespacePrefix($array_type_ns); - } else if (array_key_exists($arrayType, $this->_typemap[$this->_XMLSchemaVersion])) { - $array_type_prefix = $this->_namespaces[$this->_XMLSchemaVersion]; - } - if ($array_type_prefix) - $arrayType = $array_type_prefix.':'.$arrayType; + + $xmlout_offset = " SOAP-ENC:offset=\"[0]\""; + if (!$arrayType) { + $numtypes = count($array_types); + if ($numtypes == 1) $arrayType = $array_type; + // using anyType is more interoperable + if ($array_type == 'Struct') { + $array_type = ''; + } else if ($array_type == 'Array') { + $arrayType = 'anyType'; + $array_type_prefix = 'xsd'; + } else + if (!$arrayType) $arrayType = $array_type; } - $xmlout_arrayType = " SOAP-ENC:arrayType=\"".$arrayType."[$ar_size]\""; - - } else if ($type == 'string') { - $xmlout_value = htmlspecialchars($value); + } + if (!isset($arrayType) || $numtypes > 1) { + $arrayType = 'xsd:anyType'; // should reference what schema we're using } else { - $xmlout_value = $value; + if ($array_type_ns) { + $array_type_prefix = $this->_getNamespacePrefix($array_type_ns); + } else if (array_key_exists($arrayType, $this->_typemap[$this->_XMLSchemaVersion])) { + $array_type_prefix = $this->_namespaces[$this->_XMLSchemaVersion]; + } + if ($array_type_prefix) + $arrayType = $array_type_prefix.':'.$arrayType; } + $xmlout_arrayType = " SOAP-ENC:arrayType=\"".$arrayType."[$ar_size]\""; + } else if ($this->_isSoapValue($value)) { + $xmlout_value = $value->serialize($this); + } else if ($type == 'string') { + $xmlout_value = htmlspecialchars($value); + } else if ($type == 'boolean') { + $xmlout_value = $value?'true':'false'; + } else { + $xmlout_value = $value; } + // add namespaces if ($elNamespace) { - if ($this->section5) { - $elPrefix = $this->getNamespacePrefix($elNamespace); + if ($this->_section5) { + $elPrefix = $this->_getNamespacePrefix($elNamespace); $xmlout_name = "$elPrefix:$name"; } else { $xmlns = " xmlns:ns1=\"$elNamespace\""; @@ -469,7 +498,7 @@ } if ($typeNamespace) { - $typePrefix = $this->getNamespacePrefix($typeNamespace); + $typePrefix = $this->_getNamespacePrefix($typeNamespace); $xmlout_type = "$typePrefix:$type"; } else if ($type && array_key_exists($type, $this->_typemap[$this->_XMLSchemaVersion])) { $typePrefix = $this->_namespaces[$this->_XMLSchemaVersion]; @@ -488,9 +517,9 @@ // store the attachement for mime encoding if (isset($options['attachment'])) - $this->attachments[] = $options['attachment']; + $this->__attachments[] = $options['attachment']; - if ($this->section5) { + if ($this->_section5) { if ($xmlout_type) $xmlout_type = " xsi:type=\"$xmlout_type\""; if (is_null($xmlout_value)) { $xml = "\r\n<$xmlout_name$xmlout_type$xmlns$xmlout_arrayType$xml_attr/>"; @@ -532,14 +561,14 @@ break; case 'array': // XXX hashes always get done as structs by pear::soap - $type = $this->isHash($value)?'Struct':'Array'; + $type = $this->_isHash($value)?'Struct':'Array'; break; case 'integer': case 'long': $type = 'int'; break; case 'boolean': - $value = $value?'true':'false'; + #$value = $value?'true':'false'; break; case 'double': $type = 'float'; // double is deprecated in 4.2 and later @@ -556,7 +585,7 @@ if (SOAP_Type_hexBinary::is_hexbin($value)) { $type = 'hexBinary'; } else - if ($this->isBase64($value)) { + if ($this->_isBase64($value)) { $type = 'base64Binary'; } else { $dt = new SOAP_Type_dateTime($value); @@ -594,7 +623,7 @@ $xml .= $value->serialize($this); } else { $type = $this->_getType($value); - $xml .= $this->serializeValue($value,'item',$type); + $xml .= $this->_serializeValue($value,'item',$type); } } $size = NULL; @@ -606,7 +635,7 @@ * @param string * @return string */ - function isBase64(&$value) + function _isBase64(&$value) { $l = strlen($value); if ($l > 0) @@ -619,7 +648,7 @@ * @param mixed * @return boolean */ - function isHash(&$a) { + function _isHash(&$a) { # XXX I realy dislike having to loop through this in php code, # realy large arrays will be slow. We need a C function to do this. $names = array(); @@ -629,7 +658,7 @@ $t = gettype($k); if ($t != 'integer') { return TRUE; - } else if (gettype($v) == 'object' && is_a($v,'soap_value')) { + } else if ($this->_isSoapValue($v)) { $names[$v->name] = 1; } // if someone has a large hash they should realy be defining the type @@ -638,7 +667,7 @@ return count($names)>1; } - function un_htmlentities($string) + function &_un_htmlentities($string) { $trans_tbl = get_html_translation_table (HTML_ENTITIES); $trans_tbl = array_flip($trans_tbl); @@ -649,11 +678,11 @@ * * @param mixed */ - function decode(&$soapval) + function &_decode(&$soapval) { global $SOAP_OBJECT_STRUCT; - if (!is_object($soapval)) { + if (!$this->_isSoapValue($soapval)) { return $soapval; } else if (is_array($soapval->value)) { if ($SOAP_OBJECT_STRUCT && $soapval->type != 'Array') { @@ -669,6 +698,9 @@ } else if ($this->_auto_translation) { if (class_exists($soapval->type)) { $classname = $soapval->type; + } else if ($this->_wsdl) { + $t = $this->_wsdl->getComplexTypeNameForElement($soapval->name, $soapval->namespace); + if ($t && class_exists($t)) $classname = $t; } } $return = new $classname; @@ -677,39 +709,55 @@ } $counter = 1; - $isstruct = TRUE; // assume it's a struct + $isstruct = !$SOAP_OBJECT_STRUCT || !is_array($return); foreach ($soapval->value as $item) { if (is_object($return)) { + if ($this->_wsdl) { + // get this childs wsdl information + // /$soapval->ns/$soapval->type/$item->ns/$item->name + $child_type = $this->_wsdl->getComplexTypeChildType( + $soapval->namespace, + $soapval->name, + $item->namespace, + $item->name); + if ($child_type) $item->type = $child_type; + } if (!$isstruct || $item->type == 'Array') { if (isset($return->{$item->name}) && is_object($return->{$item->name})) { - $return->{$item->name} = $this->decode($item); + $return->{$item->name} = $this->_decode($item); } else if (isset($return->{$item->name}) && is_array($return->{$item->name})) { - $return->{$item->name}[] = $this->decode($item); + $return->{$item->name}[] = $this->_decode($item); } else if (is_array($return)) { - $return[] = $this->decode($item); + $return[] = $this->_decode($item); } else { - $return->{$item->name} = $this->decode($item); + $return->{$item->name} = $this->_decode($item); } } else if (isset($return->{$item->name})) { $isstruct = FALSE; if (count(get_class_vars($return)) == 1) { - $return = array($return->{$item->name}, $this->decode($item)); + $return = array($return->{$item->name}, $this->_decode($item)); } else { - $return->{$item->name} = array($return->{$item->name}, $this->decode($item)); + $return->{$item->name} = array($return->{$item->name}, $this->_decode($item)); } } else { - $return->{$item->name} = $this->decode($item); + $return->{$item->name} = $this->_decode($item); + } + /* set the attributes as members in the class */ + if (method_exists($return,'__set_attribute')) { + foreach ($soapval->attributes as $key=>$value) { + call_user_func_array(array(&$return,'__set_attribute'),array($key,$value)); + } } } else { if (!$isstruct) { - $return[] = $this->decode($item); + $return[] = $this->_decode($item); } else if (isset($return[$item->name])) { $isstruct = FALSE; - $return = array($return[$item->name], $this->decode($item)); + $return = array($return[$item->name], $this->_decode($item)); } else { - $return[$item->name] = $this->decode($item); + $return[$item->name] = $this->_decode($item); } } } @@ -736,7 +784,7 @@ * @return associative array (headers,body) * @access private */ - function _makeEnvelope(&$method, &$headers, $encoding = SOAP_DEFAULT_ENCODING,$options = array()) + function &_makeEnvelope(&$method, &$headers, $encoding = SOAP_DEFAULT_ENCODING,$options = array()) { $smsg = $header_xml = $ns_string = ''; @@ -766,13 +814,13 @@ } /* if use='literal', we do not put in the encodingStyle. This is denoted by - $this->section5 being false. + $this->_section5 being false. XXX use can be defined at a more granular level than we are dealing with here, so this does not work for all services. */ $xml = "<?xml version=\"1.0\" encoding=\"$encoding\"?>\r\n\r\n". "<SOAP-ENV:Envelope $ns_string". - ($this->section5?" SOAP-ENV:encodingStyle=\"" . SOAP_SCHEMA_ENCODING . "\"":''). + ($this->_section5?" SOAP-ENV:encodingStyle=\"" . SOAP_SCHEMA_ENCODING . "\"":''). ">\r\n". "$header_xml$body</SOAP-ENV:Envelope>\r\n"; @@ -784,7 +832,7 @@ global $SOAP_options; if (!isset($SOAP_options['Mime'])) { - return $this->raiseSoapFault('Mime is not installed'); + return $this->_raiseSoapFault('Mime is not installed'); } // encode any attachments @@ -799,9 +847,9 @@ $msg->addSubPart($xml, $params); // add the attachements - $c = count($this->attachments); + $c = count($this->__attachments); for ($i=0; $i < $c; $i++) { - $attachment =& $this->attachments[$i]; + $attachment =& $this->__attachments[$i]; $msg->addSubPart($attachment['body'],$attachment); } return $msg->encode(); @@ -813,7 +861,7 @@ global $SOAP_options; if (!isset($SOAP_options['DIME'])) { - return $this->raiseSoapFault('DIME is not installed'); + return $this->_raiseSoapFault('DIME is not installed'); } // encode any attachments @@ -823,20 +871,20 @@ $msg = $dime->encodeData($xml,SOAP_ENVELOP,NULL,NET_DIME_TYPE_URI); // add the attachements - $c = count($this->attachments); + $c = count($this->__attachments); for ($i=0; $i < $c; $i++) { - $attachment =& $this->attachments[$i]; + $attachment =& $this->__attachments[$i]; $msg .= $dime->encodeData($attachment['body'],$attachment['content_type'],$attachment['cid'],NET_DIME_TYPE_MEDIA); } $msg .= $dime->endMessage(); return $msg; } - function decodeMimeMessage(&$data, &$headers, &$attachments) + function _decodeMimeMessage(&$data, &$headers, &$attachments) { global $SOAP_options; if (!isset($SOAP_options['Mime'])) { - $this->makeFault('Server','Mime Unsupported, install PEAR::Mail::Mime'); + $this->_raiseSoapFault('Mime Unsupported, install PEAR::Mail::Mime','','','Server'); return; } @@ -874,14 +922,14 @@ } return; } - $this->makeFault('Server','Mime parsing error'); + $this->_raiseSoapFault('Mime parsing error','','','Server'); } - function decodeDIMEMessage(&$data, &$headers, &$attachments) + function _decodeDIMEMessage(&$data, &$headers, &$attachments) { global $SOAP_options; if (!isset($SOAP_options['DIME'])) { - return $this->raiseSoapFault('DIME is not installed'); + $this->_raiseSoapFault('DIME Unsupported, install PEAR::Net::DIME','','','Server'); } // XXX this SHOULD be moved to the transport layer, e.g. PHP itself @@ -890,7 +938,7 @@ $dime->decodeData($data); if (strcasecmp($dime->parts[0]['type'],SOAP_ENVELOP) !=0 || strcasecmp($dime->parts[0]['type'],SOAP_ENVELOP) !=0) { - $this->makeFault('Server','Dime record 1 is not a SOAP envelop!'); + $this->_raiseSoapFault('Dime record 1 is not a SOAP envelop!','','','Server'); } else { $data = $dime->parts[0]['data']; $headers['content-type'] = 'text/xml'; // fake it for now @@ -918,7 +966,7 @@ * class used to handle QNAME values in XML * * @access public -* @version $Id: Base.php,v 1.22 2002/08/18 18:45:48 shane Exp $ +* @version $Id: Base.php,v 1.23 2002/09/29 01:06:07 shane Exp $ * @package SOAP::Client * @author Shane Caraveo <shane@php.net> Conversion to PEAR and updates */ Index: pear/SOAP/Client.php diff -u pear/SOAP/Client.php:1.40 pear/SOAP/Client.php:1.41 --- pear/SOAP/Client.php:1.40 Sun Aug 18 14:45:48 2002 +++ pear/SOAP/Client.php Sat Sep 28 21:06:07 2002 @@ -17,7 +17,7 @@ // | Authors: Dietrich Ayala <dietrich@ganx4.com> Original Author | // +----------------------------------------------------------------------+ // -// $Id: Client.php,v 1.40 2002/08/18 18:45:48 shane Exp $ +// $Id: Client.php,v 1.41 2002/09/29 01:06:07 shane Exp $ // require_once 'SOAP/Value.php'; @@ -37,7 +37,7 @@ * originaly based on SOAPx4 by Dietrich Ayala http://dietrich.ganx4.com/soapx4 * * @access public -* @version $Id: Client.php,v 1.40 2002/08/18 18:45:48 shane Exp $ +* @version $Id: Client.php,v 1.41 2002/09/29 01:06:07 shane Exp $ * @package SOAP::Client * @author Shane Caraveo <shane@php.net> Conversion to PEAR and updates * @author Stig Bakken <ssb@fast.no> Conversion to PEAR @@ -60,14 +60,14 @@ * @var string * @see SOAP_Client() */ - var $endpoint = ''; + var $_endpoint = ''; /** * portname * * @var string contains the SOAP PORT name that is used by the client */ - var $portName = ''; + var $_portName = ''; /** @@ -75,35 +75,23 @@ * * @var string e.g. wdsl */ - var $endpointType = ''; - - /** - * WDSL object - * - * @var object SOAP_WDSL - */ - var $wsdl = NULL; + var $__endpointType = ''; /** * wire * * @var string contains outoing and incoming data stream for debugging. */ - var $wire = NULL; - - /** - * soapmsg - * - * @var SOAP_Message The soap message class that is used for outgoing calls. - */ - var $soapmsg = NULL; - + var $wire; + var $__last_request = NULL; + var $__last_response = NULL; + var $__options = array('trace'=>0); /** * encoding * * @var string Contains the character encoding used for XML parser, etc. */ - var $encoding = SOAP_DEFAULT_ENCODING; + var $_encoding = SOAP_DEFAULT_ENCODING; /** @@ -120,26 +108,34 @@ var $headersIn = NULL; /** + * __proxy_params + * + * @var array contains options for HTTP_Request class (see HTTP/Request.php) + */ + var $__proxy_params = array(); + /** * SOAP_Client constructor * * @param string endpoint (URL) * @param boolean wsdl (true if endpoint is a wsdl file) * @param string portName + * @param array contains options for HTTP_Request class (see HTTP/Request.php) * @access public */ - function SOAP_Client($endpoint, $wsdl = false, $portName = false) + function SOAP_Client($endpoint, $wsdl = false, $portName = false, $proxy_params=array()) { parent::SOAP_Base('Client'); - $this->endpoint = $endpoint; - $this->portName = $portName; + $this->_endpoint = $endpoint; + $this->_portName = $portName; + $this->__proxy_params = $proxy_params; // make values if ($wsdl) { - $this->endpointType = 'wsdl'; + $this->__endpointType = 'wsdl'; // instantiate wsdl class - $this->wsdl = new SOAP_WSDL($this->endpoint); - if ($this->wsdl->fault) { - $this->raiseSoapFault($this->wsdl->fault); + $this->_wsdl = new SOAP_WSDL($this->_endpoint, $this->__proxy_params); + if ($this->_wsdl->fault) { + $this->_raiseSoapFault($this->_wsdl->fault); } } } @@ -157,10 +153,10 @@ function setEncoding($encoding) { if (in_array($encoding, $this->_encodings)) { - $this->encoding = $encoding; + $this->_encoding = $encoding; return NULL; } - return $this->raiseSoapFault('Invalid Encoding'); + return $this->_raiseSoapFault('Invalid Encoding'); } /** @@ -173,18 +169,17 @@ * * @access public */ - function addHeader($soap_value) + function addHeader(&$soap_value) { # add a new header to the message if (is_a($soap_value,'soap_header')) { - #$this->soapmsg->addHeader($soap_value); $this->headersOut[] = $soap_value; } else if (gettype($soap_value) == 'array') { // name, value, namespace, mustunderstand, actor $h = new SOAP_Header($soap_value[0], NULL, $soap_value[1], $soap_value[2], $soap_value[3]); $this->headersOut[] = $h; } else { - $this->raiseSoapFault("Don't understand the header info you provided. Must be array or SOAP_Header."); + $this->_raiseSoapFault("Don't understand the header info you provided. Must be array or SOAP_Header."); } } @@ -218,50 +213,132 @@ */ function call($method, $params = array(), $namespace = false, $soapAction = false) { + $soap_data = $this->__generate($method, $params, $namespace, $soapAction); + if (PEAR::isError($soap_data)) { + return $this->_raiseSoapFault($soap_data); + } + $soap_transport = new SOAP_Transport($this->_endpoint, $this->_encoding); + if ($soap_transport->fault) { + return $this->_raiseSoapFault($soap_transport->fault); + } + // send the message + $transport_options = array_merge($this->__proxy_params, $this->__options); + $this->xml = $soap_transport->send($soap_data, $this->__options); + + // save the wire information for debugging + if ($this->__options['trace'] > 0) { + $this->__last_request =& $soap_transport->transport->outgoing_payload; + $this->__last_response =& $soap_transport->transport->incoming_payload; + $this->wire = $this->__get_wire(); + } + if ($soap_transport->fault) { + return $this->_raiseSoapFault($this->xml); + } + + $this->__attachements =& $soap_transport->transport->attachments; + $this->__result_encoding = $soap_transport->result_encoding; + unset($soap_transport); + + if (isset($this->__options['result']) && $this->__options['result'] != 'parse') return $this->xml; + + return $this->__parse($this->xml, $this->__result_encoding,$this->__attachements); + } + + /** + * SOAP_Client::__call + * + * Overload extension support + * if the overload extension is loaded, you can call the client class + * with a soap method name + * $soap = new SOAP_Client(....); + * $value = $soap->getStockQuote('MSFT'); + * + * @param string method + * @param array args + * @param string retur_value + * + * @return boolean + * @access public + */ + function __call($method, $args, &$return_value) + { + if ($this->_wsdl) $this->_wsdl->matchMethod($method); + $return_value = $this->call($method, $args); + return TRUE; + } + + function &__getlastrequest() + { + return $this->__last_request; + } + + function &__getlastresponse() + { + return $this->__last_response; + } + + function __use($use) + { + $this->__options['use'] = $use; + } + + function __style($style) + { + $this->__options['style'] = $style; + } + + function __trace($level) + { + $this->__options['trace'] = $level; + } + + function &__generate($method, $params = array(), $namespace = false, $soapAction = false) + { $this->fault = null; - $options = array('input'=>'parse','result'=>'parse'); + $this->__options['input']='parse'; + $this->__options['result']='parse'; if ($params && gettype($params) != 'array') { $params = array($params); } if (gettype($namespace) == 'array') { - $options = array_merge($options,$namespace); - if (isset($options['namespace'])) $namespace = $options['namespace']; + $this->__options = array_merge($this->__options,$namespace); + if (isset($this->__options['namespace'])) $namespace = $this->__options['namespace']; else $namespace = false; } else { // we'll place soapaction into our array for usage in the transport - $options['soapaction'] = $soapAction; - $options['namespace'] = $namespace; + $this->__options['soapaction'] = $soapAction; + $this->__options['namespace'] = $namespace; } - if ($this->endpointType == 'wsdl') { - $this->setSchemaVersion($this->wsdl->xsd); + if ($this->__endpointType == 'wsdl') { + $this->_setSchemaVersion($this->_wsdl->xsd); // get portName - if (!$this->portName) { - $this->portName = $this->wsdl->getPortName($method); - if (PEAR::isError($this->portName)) { - return $this->raiseSoapFault($this->portName); - } + if (!$this->_portName) { + $this->_portName = $this->_wsdl->getPortName($method); } - $namespace = $this->wsdl->getNamespace($this->portName, $method); + if (PEAR::isError($this->_portName)) { + return $this->_raiseSoapFault($this->_portName); + } + $namespace = $this->_wsdl->getNamespace($this->_portName, $method); // get endpoint - $this->endpoint = $this->wsdl->getEndpoint($this->portName); - if (PEAR::isError($this->endpoint)) { - return $this->raiseSoapFault($this->endpoint); + $this->_endpoint = $this->_wsdl->getEndpoint($this->_portName); + if (PEAR::isError($this->_endpoint)) { + return $this->_raiseSoapFault($this->_endpoint); } // get operation data - $opData = $this->wsdl->getOperationData($this->portName, $method); + $opData = $this->_wsdl->getOperationData($this->_portName, $method); if (PEAR::isError($opData)) { - return $this->raiseSoapFault($opData); + return $this->_raiseSoapFault($opData); } - $options['style'] = $opData['style']; - $options['use'] = $opData['input']['use']; - $options['soapaction'] = $opData['soapAction']; + $this->__options['style'] = $opData['style']; + $this->__options['use'] = $opData['input']['use']; + $this->__options['soapaction'] = $opData['soapAction']; // set input params - if ($options['input'] == 'parse') { + if ($this->__options['input'] == 'parse') { $nparams = array(); if (isset($opData['input']['parts']) && count($opData['input']['parts']) > 0) { $i = 0; @@ -271,8 +348,8 @@ $attrs = array(); // is the name actually a complex type? if (isset($part['element'])) { - $xmlns = $this->wsdl->namespaces[$part['namespace']]; - $part = $this->wsdl->elements[$part['namespace']][$part['type']]; + $xmlns = $this->_wsdl->namespaces[$part['namespace']]; + $part = $this->_wsdl->elements[$part['namespace']][$part['type']]; $name = $part['name']; } if (isset($params[$name])) { @@ -290,9 +367,9 @@ // type is a qname likely, split it apart, and get the type namespace from wsdl $qname = new QName($part['type']); if ($qname->ns) - $type_namespace = $this->wsdl->namespaces[$qname->ns]; + $type_namespace = $this->_wsdl->namespaces[$qname->ns]; else if (isset($part['namespace'])) - $type_namespace = $this->wsdl->namespaces[$part['namespace']]; + $type_namespace = $this->_wsdl->namespaces[$part['namespace']]; else $type_namespace = NULL; $qname->namespace = $type_namespace; @@ -308,24 +385,24 @@ $params = $nparams; } } else { - $this->setSchemaVersion(SOAP_XML_SCHEMA_VERSION); + $this->_setSchemaVersion(SOAP_XML_SCHEMA_VERSION); } // serialize the message $this->section5 = TRUE; // assume we encode with section 5 - if (isset($options['use']) && $options['use']=='literal') $this->section5 = FALSE; + if (isset($this->__options['use']) && $this->__options['use']=='literal') $this->section5 = FALSE; - if (!isset($options['style']) || $options['style'] == 'rpc') { - $options['style'] = 'rpc'; + if (!isset($this->__options['style']) || $this->__options['style'] == 'rpc') { + $this->__options['style'] = 'rpc'; $this->docparams = true; $mqname = new QName($method, $namespace); $methodValue = new SOAP_Value($mqname->fqn(), 'Struct', $params); - $soap_msg = $this->_makeEnvelope($methodValue, $this->headersOut, $this->encoding,$options); + $soap_msg = $this->_makeEnvelope($methodValue, $this->headersOut, $this->_encoding,$this->__options); } else { if (!$params) { $mqname = new QName($method, $namespace); $params = new SOAP_Value($mqname->fqn(), 'Struct', NULL); - } elseif ($options['input'] == 'parse') { + } elseif ($this->__options['input'] == 'parse') { if (is_array($params)) { $nparams = array(); foreach ($params as $n => $v) { @@ -338,26 +415,26 @@ $params = $nparams; } } - $soap_msg = $this->_makeEnvelope($params, $this->headersOut, $this->encoding,$options); + $soap_msg = $this->_makeEnvelope($params, $this->headersOut, $this->_encoding,$this->__options); } if (PEAR::isError($soap_msg)) { - return $this->raiseSoapFault($soap_msg); + return $this->_raiseSoapFault($soap_msg); } // handle Mime or DIME encoding // XXX DIME Encoding should move to the transport, do it here for now // and for ease of getting it done - if (count($this->attachments)) { - if ((isset($options['Attachments']) && $options['Attachments'] == 'Mime') || isset($options['Mime'])) { - $soap_msg = $this->_makeMimeMessage($soap_msg, $this->encoding); + if (count($this->__attachments)) { + if ((isset($this->__options['Attachments']) && $this->__options['Attachments'] == 'Mime') || isset($this->__options['Mime'])) { + $soap_msg = $this->_makeMimeMessage($soap_msg, $this->_encoding); } else { // default is dime - $soap_msg = $this->_makeDIMEMessage($soap_msg, $this->encoding); - $options['headers']['Content-Type'] = 'application/dime'; + $soap_msg = $this->_makeDIMEMessage($soap_msg, $this->_encoding); + $this->__options['headers']['Content-Type'] = 'application/dime'; } if (PEAR::isError($soap_msg)) { - return $this->raiseSoapFault($soap_msg); + return $this->_raiseSoapFault($soap_msg); } } @@ -365,74 +442,52 @@ if (is_array($soap_msg)) { $soap_data = $soap_msg['body']; if (count($soap_msg['headers'])) { - if (isset($options['headers'])) { - $options['headers'] = array_merge($options['headers'],$soap_msg['headers']); + if (isset($this->__options['headers'])) { + $this->__options['headers'] = array_merge($this->__options['headers'],$soap_msg['headers']); } else { - $options['headers'] = $soap_msg['headers']; + $this->__options['headers'] = $soap_msg['headers']; } } } else { $soap_data = $soap_msg; } - #$f = fopen('/tmp/dime.data','wb+'); - #if ($f) { - # fwrite($f,$soap_data); - # fclose($f); - # return; - #} - $soap_transport = new SOAP_Transport($this->endpoint, $this->encoding); - - if ($soap_transport->fault) { - return $this->raiseSoapFault($soap_transport->fault); - } - - // send the message - $this->xml = $soap_transport->send($soap_data, $options); - - // save the wire information for debugging - $this->wire = "OUTGOING:\n\n". - $soap_transport->transport->outgoing_payload. - "\n\nINCOMING\n\n". - preg_replace("/></",">\r\n<",$soap_transport->transport->incoming_payload); - - if (isset($options['result']) && $options['result'] != 'parse') return $this->xml; - - if ($soap_transport->fault) { - return $this->raiseSoapFault($this->xml); - } - return $this->parseResponse($this->xml, $soap_transport->result_encoding,$soap_transport->transport->attachments); + return $soap_data; } - - function parseResponse($response, $encoding, $attachments) + + function &__parse($response, $encoding, $attachments) { // parse the response $this->response = new SOAP_Parser($response, $encoding, $attachments); if ($this->response->fault) { - return $this->raiseSoapFault($this->response->fault); + return $this->_raiseSoapFault($this->response->fault); } // return array of parameters $return = $this->response->getResponse(); $headers = $this->response->getHeaders(); if ($headers) { - $this->headersIn = $this->decode($headers); + $this->headersIn = $this->__decodeResponse($headers,false); } - #$this->soapmsg = NULL; - + return $this->__decodeResponse($return); + } + + function &__decodeResponse($response,$shift=true) + { + if (!$response) return NULL; // check for valid response - if (PEAR::isError($return)) { - return $this->raiseSoapFault($return); - } else if (!is_a($return,'soap_value')) { - return $this->raiseSoapFault("didn't get SOAP_Value object back from client"); + if (PEAR::isError($response)) { + return $this->_raiseSoapFault($response); + } else if (!is_a($response,'soap_value')) { + return $this->_raiseSoapFault("didn't get SOAP_Value object back from client"); } // decode to native php datatype - $returnArray = $this->decode($return); + $returnArray = $this->_decode($response); // fault? if (PEAR::isError($returnArray)) { - return $this->raiseSoapFault($returnArray); + return $this->_raiseSoapFault($returnArray); } - if (is_object($returnArray)) { + if (is_object($returnArray) && get_class($returnArray) == 'stdClass') { $returnArray = get_object_vars($returnArray); } @@ -445,40 +500,27 @@ if (stristr($k,'detail')) $faultdetail = $v; if (stristr($k,'faultactor')) $faultactor = $v; } - return $this->raiseSoapFault($faultstring, $faultdetail, $faultactor, $faultcode); + return $this->_raiseSoapFault($faultstring, $faultdetail, $faultactor, $faultcode); } // return array of return values - if (count($returnArray) == 1) { + if ($shift && count($returnArray) == 1) { return array_shift($returnArray); } return $returnArray; } return $returnArray; } - - /** - * SOAP_Client::__call - * - * Overload extension support - * if the overload extension is loaded, you can call the client class - * with a soap method name - * $soap = new SOAP_Client(....); - * $value = $soap->getStockQuote('MSFT'); - * - * @param string method - * @param array args - * @param string retur_value - * - * @return boolean - * @access public - */ - function __call($method, $args, &$return_value) + + function __get_wire() { - if ($this->wsdl) $this->wsdl->matchMethod($method); - $return_value = $this->call($method, $args); - return TRUE; + if ($this->__options['trace'] > 0) { + return "OUTGOING:\n\n". + $this->__last_request. + "\n\nINCOMING\n\n". + preg_replace("/></",">\r\n<",$this->__last_response); + } + return NULL; } - } if (extension_loaded('overload')) { Index: pear/SOAP/Parser.php diff -u pear/SOAP/Parser.php:1.24 pear/SOAP/Parser.php:1.25 --- pear/SOAP/Parser.php:1.24 Mon Jun 24 21:58:03 2002 +++ pear/SOAP/Parser.php Sat Sep 28 21:06:08 2002 @@ -17,7 +17,7 @@ // | Authors: Dietrich Ayala <dietrich@ganx4.com> Original Author | // +----------------------------------------------------------------------+ // -// $Id: Parser.php,v 1.24 2002/06/25 01:58:03 shane Exp $ +// $Id: Parser.php,v 1.25 2002/09/29 01:06:08 shane Exp $ // require_once 'SOAP/Base.php'; @@ -30,7 +30,7 @@ * originaly based on SOAPx4 by Dietrich Ayala http://dietrich.ganx4.com/soapx4 * * @access public -* @version $Id: Parser.php,v 1.24 2002/06/25 01:58:03 shane Exp $ +* @version $Id: Parser.php,v 1.25 2002/09/29 01:06:08 shane Exp $ * @package SOAP::Parser * @author Shane Caraveo <shane@php.net> Conversion to PEAR and updates * @author Dietrich Ayala <dietrich@ganx4.com> Original Author @@ -71,7 +71,7 @@ function SOAP_Parser($xml, $encoding = SOAP_DEFAULT_ENCODING, $attachments=NULL) { parent::SOAP_Base('Parser'); - $this->setSchemaVersion(SOAP_XML_SCHEMA_VERSION); + $this->_setSchemaVersion(SOAP_XML_SCHEMA_VERSION); $this->xml = $xml; $this->xml_encoding = $encoding; @@ -101,7 +101,7 @@ $err = sprintf('XML error on line %d: %s', xml_get_current_line_number($parser), xml_error_string(xml_get_error_code($parser))); - $this->raiseSoapFault($err,htmlspecialchars($this->xml)); + $this->_raiseSoapFault($err,htmlspecialchars($this->xml)); } else { // build the response if (count($this->root_struct)) @@ -299,17 +299,19 @@ $prefix = $kqn->name; if (in_array($value, $this->_XMLSchema)) { - $this->setSchemaVersion($value); + $this->_setSchemaVersion($value); } - - $this->_namespaces[$prefix] = $value; + + $this->_namespaces[$value] = $prefix; // set method namespace # XXX unused??? #if ($name == $this->curent_root_struct_name) { # $this->methodNamespace = $value; #} - + } elseif ($key == 'xmlns') { + $qname->ns = $this->_getNamespacePrefix($value); + $qname->namespace = $value; } elseif ($kqn->name == 'actor') { $this->message[$pos]['actor'] = $value; } elseif ($kqn->name == 'mustUnderstand') { @@ -319,7 +321,7 @@ } elseif ($kqn->name == 'type') { $vqn = new QName($value); $this->message[$pos]['type'] = $vqn->name; - $this->message[$pos]['type_namespace'] = $this->_namespaces[$vqn->ns]; + $this->message[$pos]['type_namespace'] = $this->_getNamespaceForPrefix($vqn->ns); #print "set type for {$this->message[$pos]['name']} to {$this->message[$pos]['type']}\n"; // should do something here with the namespace of specified type? @@ -367,9 +369,11 @@ // see if namespace is defined in tag if (array_key_exists('xmlns:'.$qname->ns,$attrs)) { $namespace = $attrs['xmlns:'.$qname->ns]; + } else if ($qname->ns && !$qname->namespace) { + $namespace = $this->_getNamespaceForPrefix($qname->ns); } else { // get namespace - $namespace = $qname->ns?$this->_namespaces[$qname->ns]:$this->default_namespace; + $namespace = $qname->namespace?$qname->namespace:$this->default_namespace; } $this->message[$pos]['namespace'] = $namespace; $this->default_namespace = $namespace; @@ -469,7 +473,7 @@ if ($this->soapresponse) { return $this->soapresponse; } - return $this->raiseSoapFault("couldn't build response"); + return $this->_raiseSoapFault("couldn't build response"); } /** Index: pear/SOAP/Server.php diff -u pear/SOAP/Server.php:1.24 pear/SOAP/Server.php:1.25 --- pear/SOAP/Server.php:1.24 Wed Jul 17 21:50:09 2002 +++ pear/SOAP/Server.php Sat Sep 28 21:06:08 2002 @@ -17,7 +17,7 @@ // | Authors: Dietrich Ayala <dietrich@ganx4.com> Original Author | // +----------------------------------------------------------------------+ // -// $Id: Server.php,v 1.24 2002/07/18 01:50:09 shane Exp $ +// $Id: Server.php,v 1.25 2002/09/29 01:06:08 shane Exp $ // require_once 'SOAP/Base.php'; @@ -40,7 +40,7 @@ * originaly based on SOAPx4 by Dietrich Ayala http://dietrich.ganx4.com/soapx4 * * @access public -* @version $Id: Server.php,v 1.24 2002/07/18 01:50:09 shane Exp $ +* @version $Id: Server.php,v 1.25 2002/09/29 01:06:08 shane Exp $ * @package SOAP::Client * @author Shane Caraveo <shane@php.net> Conversion to PEAR and updates * @author Dietrich Ayala <dietrich@ganx4.com> Original Author @@ -74,11 +74,6 @@ */ var $xml_encoding = SOAP_DEFAULT_ENCODING; var $response_encoding = 'UTF-8'; - /** - * - * @var boolean - */ - var $soapfault = false; var $result = 'successful'; // for logging interop results to db @@ -128,40 +123,40 @@ // treat incoming data as UTF-8 if no encoding set if (isset($_SERVER['CONTENT_TYPE'])) { if (strcasecmp($_SERVER['CONTENT_TYPE'],'application/dime')==0) { - $this->decodeDIMEMessage($data,$headers,$attachments); + $this->_decodeDIMEMessage($data,$headers,$attachments); $useEncoding = 'DIME'; } else if (stristr($_SERVER['CONTENT_TYPE'],'multipart/related')) { // this is a mime message, lets decode it. $data = 'Content-Type: '.stripslashes($_SERVER['CONTENT_TYPE'])."\r\n\r\n".$data; - $this->decodeMimeMessage($data,$headers,$attachments); + $this->_decodeMimeMessage($data,$headers,$attachments); $useEncoding = 'Mime'; } if (!isset($headers['content-type'])) { $headers['content-type'] = $_SERVER['CONTENT_TYPE']; } - if (!$this->soapfault && + if (!$this->fault && !$this->_getContentEncoding($headers['content-type'])) { $this->xml_encoding = SOAP_DEFAULT_ENCODING; // an encoding we don't understand, return a fault - $this->makeFault('Server','Unsupported encoding, use one of ISO-8859-1, US-ASCII, UTF-8'); + $this->_raiseSoapFault('Unsupported encoding, use one of ISO-8859-1, US-ASCII, UTF-8','','','Server'); } } // if this is not a POST with Content-Type text/xml, try to return a WSDL file - if (!$this->soapfault && !$test && ($_SERVER['REQUEST_METHOD'] != 'POST' || + if (!$this->fault && !$test && ($_SERVER['REQUEST_METHOD'] != 'POST' || strncmp($headers['content-type'],'text/xml',8) != 0)) { // this is not possibly a valid soap request, try to return a WSDL file - $this->makeFault('Server',"Invalid SOAP request, must be POST with content-type: text/xml, got: {$headers['content-type']}"); + $this->_raiseSoapFault("Invalid SOAP request, must be POST with content-type: text/xml, got: {$headers['content-type']}",'','','Server'); } - if (!$this->soapfault) { + if (!$this->fault) { // $response is a soap_msg object $soap_msg = $this->parseRequest($data, $attachments); // handle Mime or DIME encoding // XXX DIME Encoding should move to the transport, do it here for now // and for ease of getting it done - if (count($this->attachments)) { + if (count($this->__attachments)) { if ($useEncoding == 'Mime') { $soap_msg = $this->_makeMimeMessage($soap_msg); } else { @@ -184,9 +179,9 @@ } } - if ($this->soapfault) { + if ($this->fault) { $hdrs = "HTTP/1.1 500 Soap Fault\r\n"; - $response = $this->getFaultMessage(); + $response = $this->fault->message(); } else { $hdrs = "HTTP/1.1 200 OK\r\n"; } @@ -267,7 +262,7 @@ $parser = new SOAP_Parser($data,$this->xml_encoding,$attachments); // if fault occurred during message parsing if ($parser->fault) { - $this->soapfault = $parser->fault; + $this->fault = $parser->fault; return NULL; } @@ -279,7 +274,7 @@ if ($request_headers) { if (!is_a($request_headers,'soap_value')) { - $this->makeFault('Server',"parser did not return SOAP_Value object: $request_headers"); + $this->_raiseSoapFault("parser did not return SOAP_Value object: $request_headers",'','','Server'); return NULL; } if ($request_headers->value) { @@ -294,7 +289,7 @@ $header_val->actor == $this->endpoint); if (!$f_exists && $header_val->mustunderstand && $myactor) { - $this->makeFault('MustUnderstand',"I don't understand header $header_val->name."); + $this->_raiseSoapFault("I don't understand header $header_val->name.",'','','MustUnderstand'); return NULL; } @@ -327,7 +322,7 @@ $this->method_namespace = $parser->message[$parser->root_struct[0]]['namespace']; // does method exist? if (!$this->methodname || !$this->validateMethod($this->methodname,$this->method_namespace)) { - $this->makeFault('Server',"method '$this->methodname' not defined in service"); + $this->_raiseSoapFault("method '{$this->method_namespace}$this->methodname' not defined in service",'','','Server'); return NULL; } @@ -335,7 +330,7 @@ return NULL; } if (!is_a($request_val,'soap_value')) { - $this->makeFault('Server',"parser did not return SOAP_Value object: $request_val"); + $this->_raiseSoapFault("parser did not return SOAP_Value object: $request_val",'','','Server'); return NULL; } @@ -347,7 +342,7 @@ // need to set special error detection inside the value class // so as to differentiate between no params passed, and an error decoding - $request_data = $this->decode($request_val); + $request_data = $this->_decode($request_val); $method_response = $this->callMethod($this->methodname, $request_data); @@ -405,19 +400,19 @@ strcasecmp($this->_typemap[SOAP_XML_SCHEMA_VERSION][$sig_t[$i]],$this->_typemap[SOAP_XML_SCHEMA_VERSION][$p[$i]])!=0)) { $param = $params[$i]; - $this->makeFault('Client',"soap request contained mismatching parameters of name $param->name had type [{$p[$i]}], which did not match signature's type: [{$sig_t[$i]}], matched? ".(strcasecmp($sig_t[$i],$p[$i]))); + $this->_raiseSoapFault("soap request contained mismatching parameters of name $param->name had type [{$p[$i]}], which did not match signature's type: [{$sig_t[$i]}], matched? ".(strcasecmp($sig_t[$i],$p[$i])),'','','Client'); return false; } } return true; // oops, wrong number of paramss } else { - $this->makeFault('Client',"soap request contained incorrect number of parameters. method '$this->methodname' required ".count($sig).' and request provided '.count($params)); + $this->_raiseSoapFault("soap request contained incorrect number of parameters. method '$this->methodname' required ".count($sig).' and request provided '.count($params),'','','Client'); return false; } // oops, no params... } else { - $this->makeFault('Client',"soap request contained incorrect number of parameters. method '$this->methodname' requires ".count($sig).' parameters, and request provided none'); + $this->_raiseSoapFault("soap request contained incorrect number of parameters. method '$this->methodname' requires ".count($sig).' parameters, and request provided none','','','Client'); return false; } // no params @@ -478,7 +473,7 @@ // XXX a bit of backwards compatibility $namespace = $obj->namespace; } else { - $this->makeFault('Server','No namespace provided for class!'); + $this->_raiseSoapFault('No namespace provided for class!','','','Server'); return FALSE; } } @@ -493,27 +488,13 @@ function addToMap($methodname, $in, $out, $namespace = NULL) { if (!function_exists($methodname)) { - $this->makeFault('Server',"error mapping function\n"); + $this->_raiseSoapFault("error mapping function\n",'','','Server'); return FALSE; } $this->dispatch_map[$methodname]['in'] = $in; $this->dispatch_map[$methodname]['out'] = $out; if ($namespace) $this->dispatch_map[$methodname]['namespace'] = $namespace; return TRUE; - } - - // set up a fault - function getFaultMessage() - { - if (!$this->soapfault) { - $this->makeFault('Server','fault message requested, but no fault has occured!'); - } - return $this->soapfault->message(); - } - - function makeFault($fault_code, $fault_string) - { - $this->soapfault = new SOAP_Fault($fault_string, $fault_code); } } Index: pear/SOAP/Transport.php diff -u pear/SOAP/Transport.php:1.16 pear/SOAP/Transport.php:1.17 --- pear/SOAP/Transport.php:1.16 Wed Apr 24 03:41:18 2002 +++ pear/SOAP/Transport.php Sat Sep 28 21:06:08 2002 @@ -17,7 +17,7 @@ // | Authors: Dietrich Ayala <dietrich@ganx4.com> Original Author | // +----------------------------------------------------------------------+ // -// $Id: Transport.php,v 1.16 2002/04/24 07:41:18 shane Exp $ +// $Id: Transport.php,v 1.17 2002/09/29 01:06:08 shane Exp $ // require_once 'SOAP/Base.php'; @@ -30,7 +30,7 @@ * no knowlege of the transport protocols is available at this level * * @access public -* @version $Id: Transport.php,v 1.16 2002/04/24 07:41:18 shane Exp $ +* @version $Id: Transport.php,v 1.17 2002/09/29 01:06:08 shane Exp $ * @package SOAP::Transport * @author Shane Caraveo <shane@php.net> */ @@ -69,7 +69,7 @@ $this->transport = new SOAP_Transport_SMTP($url, $encoding); return; } - $this->raiseSoapFault("No Transport for {$urlparts['scheme']}"); + $this->_raiseSoapFault("No Transport for {$urlparts['scheme']}"); } /** @@ -90,7 +90,7 @@ $response = $this->transport->send($soap_data, $options); if (PEAR::isError($response)) { - return $this->raiseSoapFault($response); + return $this->_raiseSoapFault($response); } $this->result_encoding = $this->transport->result_encoding; #echo "\n OUTGOING: ".$this->transport->outgoing_payload."\n\n"; Index: pear/SOAP/Value.php diff -u pear/SOAP/Value.php:1.31 pear/SOAP/Value.php:1.32 --- pear/SOAP/Value.php:1.31 Sat Aug 17 14:55:29 2002 +++ pear/SOAP/Value.php Sat Sep 28 21:06:08 2002 @@ -17,7 +17,7 @@ // | Authors: Dietrich Ayala <dietrich@ganx4.com> Original Author | // +----------------------------------------------------------------------+ // -// $Id: Value.php,v 1.31 2002/08/17 18:55:29 shane Exp $ +// $Id: Value.php,v 1.32 2002/09/29 01:06:08 shane Exp $ // require_once 'SOAP/Base.php'; @@ -28,7 +28,7 @@ * originaly based on SOAPx4 by Dietrich Ayala http://dietrich.ganx4.com/soapx4 * * @access public -* @version $Id: Value.php,v 1.31 2002/08/17 18:55:29 shane Exp $ +* @version $Id: Value.php,v 1.32 2002/09/29 01:06:08 shane Exp $ * @package SOAP::Client * @author Shane Caraveo <shane@php.net> Conversion to PEAR and updates * @author Dietrich Ayala <dietrich@ganx4.com> Original Author @@ -101,9 +101,9 @@ * * @return string xml representation */ - function serialize(&$serializer) + function &serialize(&$serializer) { - return $serializer->serializeValue($this->value, $this->name, $this->type, $this->namespace, $this->type_namespace, $this->options, $this->attributes); + return $serializer->_serializeValue($this->value, $this->name, $this->type, $this->namespace, $this->type_namespace, $this->options, $this->attributes, $this->arrayType); } } @@ -117,7 +117,7 @@ * originaly based on SOAPx4 by Dietrich Ayala http://dietrich.ganx4.com/soapx4 * * @access public - * @version $Id: Value.php,v 1.31 2002/08/17 18:55:29 shane Exp $ + * @version $Id: Value.php,v 1.32 2002/09/29 01:06:08 shane Exp $ * @package SOAP::Header * @author Shane Caraveo <shane@php.net> Conversion to PEAR and updates * @author Dietrich Ayala <dietrich@ganx4.com> Original Author Index: pear/SOAP/WSDL.php diff -u pear/SOAP/WSDL.php:1.26 pear/SOAP/WSDL.php:1.27 --- pear/SOAP/WSDL.php:1.26 Thu Aug 22 03:14:27 2002 +++ pear/SOAP/WSDL.php Sat Sep 28 21:06:08 2002 @@ -17,10 +17,11 @@ // | Authors: Dietrich Ayala <dietrich@ganx4.com> Original Author | // +----------------------------------------------------------------------+ // -// $Id: WSDL.php,v 1.26 2002/08/22 07:14:27 shane Exp $ +// $Id: WSDL.php,v 1.27 2002/09/29 01:06:08 shane Exp $ // require_once 'SOAP/Base.php'; require_once 'SOAP/Fault.php'; +require_once 'HTTP/Request.php'; DEFINE("WSDL_CACHE_MAX_AGE",12*60*60); DEFINE("WSDL_CACHE_USE",0); // set to zero to turn off caching @@ -38,7 +39,7 @@ * implement IDL type syntax declaration so we can generate WSDL * * @access public -* @version $Id: WSDL.php,v 1.26 2002/08/22 07:14:27 shane Exp $ +* @version $Id: WSDL.php,v 1.27 2002/09/29 01:06:08 shane Exp $ * @package SOAP::Client * @author Shane Caraveo <shane@php.net> Conversion to PEAR and updates * @author Dietrich Ayala <dietrich@ganx4.com> Original Author @@ -59,10 +60,19 @@ var $services = array(); var $service = ''; var $uri = ''; + var $proxy = NULL; - function SOAP_WSDL($uri = false) { + /** + * SOAP_WSDL constructor + * + * @param string endpoint_uri (URL) + * @param array contains options for HTTP_Request class (see HTTP/Request.php) + * @access public + */ + function SOAP_WSDL($uri = false, $proxy=array()) { parent::SOAP_Base('WSDL'); $this->uri = $uri; + $this->proxy = $proxy; $this->parse($uri); reset($this->services); $this->service = key($this->services); @@ -74,10 +84,10 @@ } } - function parse($uri) { + function parse($uri, $proxy=array()) { $parser = new SOAP_WSDL_Parser($uri, $this); if ($parser->fault) { - $this->raiseSoapFault($parser->fault); + $this->_raiseSoapFault($parser->fault); } } @@ -85,7 +95,7 @@ { return (isset($this->services[$this->service]['ports'][$portName]['address']['location'])) ? $this->services[$this->service]['ports'][$portName]['address']['location'] - : $this->raiseSoapFault("no endpoint for port for $portName", $this->uri); + : $this->_raiseSoapFault("no endpoint for port for $portName", $this->uri); } // find the name of the first port that contains an operation of name $operation @@ -101,7 +111,7 @@ } } } - return $this->raiseSoapFault("no operation $operation in wsdl", $this->uri); + return $this->_raiseSoapFault("no operation $operation in wsdl", $this->uri); } function getOperationData($portName,$operation) @@ -115,7 +125,7 @@ // get operation data from porttype $portType = $this->bindings[$binding]['type']; if (!$portType) { - return $this->raiseSoapFault("no port type for binding $binding in wsdl " . $this->uri); + return $this->_raiseSoapFault("no port type for binding $binding in wsdl " . $this->uri); } if (is_array($this->portTypes[$portType][$operation])) { if (isset($this->portTypes[$portType][$operation]['parameterOrder'])) @@ -123,6 +133,8 @@ $opData['input'] = array_merge($opData['input'], $this->portTypes[$portType][$operation]['input']); $opData['output'] = array_merge($opData['output'], $this->portTypes[$portType][$operation]['output']); } + if (!$opData) + return $this->_raiseSoapFault("no operation $operation for port $portName, in wsdl", $this->uri); // message data from messages $inputMsg = $opData['input']['message']; foreach ($this->messages[$inputMsg] as $pname => $pattrs) { @@ -130,10 +142,11 @@ && $pname == 'parameters') { $el = $this->elements[$pattrs['namespace']][$pattrs['type']]; - foreach ($el['elements'] as $elname => $elattrs) { - $opData['input']['parts'][$elname] = $elattrs; + if ($el['elements']) { + foreach ($el['elements'] as $elname => $elattrs) { + $opData['input']['parts'][$elname] = $elattrs; + } } - } else { $opData['input']['parts'][$pname] = $pattrs; } @@ -144,8 +157,10 @@ && $pname == 'parameters') { $el = $this->elements[$pattrs['namespace']][$pattrs['type']]; - foreach ($el['elements'] as $elname => $elattrs) { - $opData['output']['parts'][$elname] = $elattrs; + if ($el['elements']) { + foreach ($el['elements'] as $elname => $elattrs) { + $opData['output']['parts'][$elname] = $elattrs; + } } } else { @@ -154,7 +169,7 @@ } return $opData; } - return $this->raiseSoapFault("no binding for port $portName in wsdl", $this->uri); + return $this->_raiseSoapFault("no binding for port $portName in wsdl", $this->uri); } function matchMethod(&$operation) { @@ -179,7 +194,8 @@ function getNamespace($portName, $operation) { - if (isset($this->bindings[$this->services[$this->service]['ports'][$portName]['binding']]['operations'][$operation]['input']['namespace']) && + if (isset($this->bindings[$this->services[$this->service]['ports'][$portName]['binding']]) && + isset($this->bindings[$this->services[$this->service]['ports'][$portName]['binding']]['operations'][$operation]['input']['namespace']) && $namespace = $this->bindings[$this->services[$this->service]['ports'][$portName]['binding']]['operations'][$operation]['input']['namespace']) { return $namespace; } @@ -424,6 +440,42 @@ return new $classname; } + function &_getComplexTypeForElement($name, $namespace) + { + $t = NULL; + if (isset($this->ns[$namespace]) && + isset($this->elements[$this->ns[$namespace]][$name]['type'])) { + + $type = $this->elements[$this->ns[$namespace]][$name]['type']; + $ns = $this->elements[$this->ns[$namespace]][$name]['namespace']; + + if (isset($this->complexTypes[$ns][$type])) { + $t = $this->complexTypes[$ns][$type]; + } + } + return $t; + } + + function getComplexTypeNameForElement($name, $namespace) + { + $t = $this->_getComplexTypeForElement($name, $namespace); + if ($t) { + return $t['name']; + } + return NULL; + } + + function getComplexTypeChildType($ns, $name, $child_ns, $child_name) { + // is the type an element? + $t = $this->_getComplexTypeForElement($name, $ns); + if ($t) { + // no, get it from complex types directly + if (isset($t['elements'][$child_name]['type'])) + return $t['elements'][$child_name]['type']; + } + return NULL; + } + function getSchemaType($type, $name, $type_namespace) { # see if it's a complex type so we can deal properly with SOAPENC:arrayType @@ -507,7 +559,7 @@ * retreives file from cache if it exists, otherwise retreive from net, * add to cache, and return from cache */ - function get($wsdl_fname, $cache=0) { + function get($wsdl_fname, $proxy_params=array(), $cache=0) { $cachename = SOAP_WSDL_Cache::_cacheDir() . "/" . md5($wsdl_fname); $cacheinfo = $cachename.".info"; $cachename .= ".wsdl"; @@ -522,7 +574,7 @@ } if ($cache) { if ($cache != $md5_wsdl) { - return $this->raiseSoapFault("WSDL Checksum error!", $wsdl_fname); + return $this->_raiseSoapFault("WSDL Checksum error!", $wsdl_fname); } } else { $fi = stat($cachename); @@ -535,11 +587,20 @@ } } if (!$md5_wsdl) { - $fd = @file($wsdl_fname); // time consumer - if (!$fd) { - return $this->raiseSoapFault("Unable to retrieve WSDL", $wsdl_fname); + $uri = explode('?',$wsdl_fname); + $rq = new HTTP_Request($uri[0], $proxy_params); + // the user agent HTTP_Request uses fouls things up + if (isset($uri[1])) { + $rq->addRawQueryString($uri[1]); + } + $result = $rq->sendRequest(); + if (PEAR::isError($result)) { + return $this->_raiseSoapFault("Unable to retrieve WSDL $wsdl_fname, ".$rq->getResponseCode(), $wsdl_fname); + } + $file_data = $rq->getResponseBody(); + if (!$file_data) { + return $this->_raiseSoapFault("Unable to retrieve WSDL $wsdl_fname, no http body", $wsdl_fname); } - $file_data = join('',$fd); $md5_wsdl = md5($file_data); @@ -550,7 +611,7 @@ } } if (WSDL_CACHE_USE && $cache && $cache != $md5_wsdl) { - return $this->raiseSoapFault("WSDL Checksum error!", $wsdl_fname); + return $this->_raiseSoapFault("WSDL Checksum error!", $wsdl_fname); } return $file_data; } @@ -597,9 +658,9 @@ function parse($uri) { // Check whether content has been read. - $fd = $this->cache->get($uri); + $fd = $this->cache->get($uri, $this->wsdl->proxy); if (PEAR::isError($fd)) { - return $this->raiseSoapFault($fd); + return $this->_raiseSoapFault($fd); } // Create an XML parser. @@ -613,7 +674,8 @@ $detail = sprintf('XML error on line %d: %s', xml_get_current_line_number($parser), xml_error_string(xml_get_error_code($parser))); - return $this->raiseSoapFault("Unable to parse WSDL file $uri", $detail); + print $fd; + return $this->_raiseSoapFault("Unable to parse WSDL file $uri\n$detail"); } xml_parser_free($parser); return TRUE; @@ -1033,9 +1095,10 @@ $base = parse_url($this->uri); $uri = $this->merge_url($base,$uri); } - $result = $this->parse($uri, $this->wsdl); - if (PEAR::isError($result)) { - return $result; + $import_parser = new SOAP_WSDL_Parser($uri, $this->wsdl); + #$result = $this->parse($uri, $this->wsdl); + if ($import_parser->fault) { + return FALSE; } $this->currentImport = $attrs['namespace']; $this->wsdl->imports[$this->currentImport] = $attrs; @@ -1101,7 +1164,7 @@ if (isset($ns) && $ns) { $namespace = 'xmlns:'.$ns; if (!$this->wsdl->definition[$namespace]) { - return $this->raiseSoapFault("parse error, no namespace for $namespace",$this->uri); + return $this->_raiseSoapFault("parse error, no namespace for $namespace",$this->uri); } $this->tns = $ns; } Index: pear/SOAP/package.xml diff -u pear/SOAP/package.xml:1.15 pear/SOAP/package.xml:1.16 --- pear/SOAP/package.xml:1.15 Sun Jul 7 17:49:14 2002 +++ pear/SOAP/package.xml Sat Sep 28 21:06:08 2002 @@ -19,10 +19,17 @@ <license>PHP License</license> <release> <state>beta</state> - <version>0.6.2</version> + <version>0.6.3</version> <date>2002-07-06</date> <notes> - This is the initial independent PEAR release. + Includes minor API changes from 0.6.2. + Supports HTTP Proxy (SOAP_Client constructor + takes 4th param of type array, SOAP_WSDL + constructor takes 2nd param of type array, see HTTP_Request + docs for proxy parameters). + Improved WSDL proxy generation. + Interop tests are moved to SOAP_Interop module, available + via CVS only. </notes> <filelist> <dir name="/" baseinstalldir="SOAP"> @@ -58,24 +65,6 @@ <file role="php" name="duration.php"/> <file role="php" name="hexBinary.php"/> </dir> - <dir name="interop" role="test"> - <file role="test" name="index.php"/> - <file role="test" name="client_round2.php"/> - <file role="test" name="client_round2_run.php"/> - <file role="test" name="client_round2_interop.php"/> - <file role="test" name="client_round2_params.php"/> - <file role="test" name="client_round2_results.php"/> - <file role="test" name="database_round2.sql"/> - <file role="test" name="echoheadersvc.wsdl"/> - <file role="test" name="interop.wsdl"/> - <file role="test" name="interopB.wsdl"/> - <file role="test" name="readme.txt"/> - <file role="test" name="server_round2.php"/> - <file role="test" name="server_round2_base.php"/> - <file role="test" name="server_round2_groupB.php"/> - <file role="test" name="server_round2_groupC.php"/> - <file role="test" name="server_round2_test.php"/> - </dir> <dir name="test" role="test"> <file role="test" name="5.2.simpletypes.php"/> <file role="test" name="5.2.1.simpletypes.string.php"/> @@ -92,7 +81,19 @@ <dep type="ext" rel="has">bcmath</dep> <dep type="ext" rel="has">pcre</dep> <dep type="pkg" rel="has">Mail_Mime</dep> + <dep type="pkg" rel="has">HTTP_Request</dep> + <dep type="pkg" rel="ge" version="1.0.5">Net_URL</dep> <dep type="pkg" rel="ge" version="0.1">Net_DIME</dep> </deps> </release> + <changelog> + <release> + <state>beta</state> + <version>0.6.2</version> + <date>2002-07-06</date> + <notes> + This is the initial independent PEAR release. + </notes> + </release> + </changelog> </package> Index: pear/SOAP/Server/Email.php diff -u pear/SOAP/Server/Email.php:1.5 pear/SOAP/Server/Email.php:1.6 --- pear/SOAP/Server/Email.php:1.5 Tue May 14 19:02:49 2002 +++ pear/SOAP/Server/Email.php Sat Sep 28 21:06:08 2002 @@ -16,7 +16,7 @@ // | Authors: Shane Caraveo <Shane@Caraveo.com> Port to PEAR and more | // +----------------------------------------------------------------------+ // -// $Id: Email.php,v 1.5 2002/05/14 23:02:49 shane Exp $ +// $Id: Email.php,v 1.6 2002/09/29 01:06:08 shane Exp $ // require_once 'SOAP/Server.php'; @@ -37,7 +37,7 @@ * function call * * @access public -* @version $Id: Email.php,v 1.5 2002/05/14 23:02:49 shane Exp $ +* @version $Id: Email.php,v 1.6 2002/09/29 01:06:08 shane Exp $ * @package SOAP::Server * @author Shane Caraveo <shane@php.net> */ @@ -70,7 +70,7 @@ } if (!stristr($this->headers['content-type'],'text/xml')) { - $this->makeFault('Client','Invalid Content Type'); + $this->_raiseSoapFault('Invalid Content Type','','','Client'); return FALSE; } @@ -81,7 +81,7 @@ #} else if (strcasecmp($this->headers['content-transfer-encoding'],'quoted-printable')==0) { # $data = $match[2]; #} else { - # $this->makeFault('Client','Invalid Content-Transfer-Encoding'); + # $this->_raiseSoapFault('Invalid Content-Transfer-Encoding','','','Client'); # return FALSE; #} } else { @@ -91,7 +91,7 @@ // if no content, return false return strlen($this->request) > 0; } - $this->makeFault('Client','Invalid Email Format'); + $this->_raiseSoapFault('Invalid Email Format','','','Client'); return FALSE; } @@ -101,12 +101,12 @@ # if neither matches, we'll just try it anyway if (stristr($data,'Content-Type: application/dime')) { - $this->decodeDIMEMessage($data,$this->headers,$attachments); + $this->_decodeDIMEMessage($data,$this->headers,$attachments); $useEncoding = 'DIME'; } else if (stristr($data,'MIME-Version:')) { // this is a mime message, lets decode it. #$data = 'Content-Type: '.stripslashes($_SERVER['CONTENT_TYPE'])."\r\n\r\n".$data; - $this->decodeMimeMessage($data,$this->headers,$attachments); + $this->_decodeMimeMessage($data,$this->headers,$attachments); $useEncoding = 'Mime'; } else { // the old fallback, but decodeMimeMessage handles things fine. @@ -118,7 +118,7 @@ if (!$this->soapfault && !$this->_getContentEncoding($this->headers['content-type'])) { $this->xml_encoding = SOAP_DEFAULT_ENCODING; // an encoding we don't understand, return a fault - $this->makeFault('Server','Unsupported encoding, use one of ISO-8859-1, US-ASCII, UTF-8'); + $this->_raiseSoapFault('Unsupported encoding, use one of ISO-8859-1, US-ASCII, UTF-8','','','Server'); } if ($this->soapfault) { @@ -153,7 +153,7 @@ if (!$response && !$this->_getContentEncoding($this->headers['content-type'])) { $this->xml_encoding = SOAP_DEFAULT_ENCODING; // an encoding we don't understand, return a fault - $this->makeFault('Server','Unsupported encoding, use one of ISO-8859-1, US-ASCII, UTF-8'); + $this->_raiseSoapFault('Unsupported encoding, use one of ISO-8859-1, US-ASCII, UTF-8','','','Server'); $response = $this->getFaultMessage(); } @@ -165,7 +165,7 @@ // handle Mime or DIME encoding // XXX DIME Encoding should move to the transport, do it here for now // and for ease of getting it done - if (count($this->attachments)) { + if (count($this->__attachments)) { if ($useEncoding == 'Mime') { $soap_msg = $this->_makeMimeMessage($soap_msg); } else { Index: pear/SOAP/Server/Email_Gateway.php diff -u pear/SOAP/Server/Email_Gateway.php:1.5 pear/SOAP/Server/Email_Gateway.php:1.6 --- pear/SOAP/Server/Email_Gateway.php:1.5 Tue May 14 19:02:49 2002 +++ pear/SOAP/Server/Email_Gateway.php Sat Sep 28 21:06:09 2002 @@ -16,7 +16,7 @@ // | Authors: Shane Caraveo <Shane@Caraveo.com> Port to PEAR and more | // +----------------------------------------------------------------------+ // -// $Id: Email_Gateway.php,v 1.5 2002/05/14 23:02:49 shane Exp $ +// $Id: Email_Gateway.php,v 1.6 2002/09/29 01:06:09 shane Exp $ // require_once 'SOAP/Server/Email.php'; @@ -40,7 +40,7 @@ * email * * @access public -* @version $Id: Email_Gateway.php,v 1.5 2002/05/14 23:02:49 shane Exp $ +* @version $Id: Email_Gateway.php,v 1.6 2002/09/29 01:06:09 shane Exp $ * @package SOAP::Server * @author Shane Caraveo <shane@php.net> */ @@ -67,8 +67,8 @@ // we have a full set of headers, need to find the first blank line $this->_parseEmail($data); - if ($this->soapfault) { - $response = $this->getFaultMessage(); + if ($this->fault) { + $response = $this->fault->message(); } if ($this->headers['content-type']=='application/dime') $useEncoding='DIME'; @@ -96,7 +96,7 @@ foreach ($soap_transport->transport->attachments as $cid=>$body) { $this->attachments[] = array('body' => $body, 'cid' => $cid, 'encoding' => 'base64'); } - if (count($this->attachments)) { + if (count($this->__attachments)) { if ($useEncoding == 'Mime') { $soap_msg = $this->_makeMimeMessage($response); $options['headers']['MIME-Version'] = '1.0'; @@ -106,7 +106,7 @@ $options['headers']['Content-Type'] = 'application/dime'; } if (PEAR::isError($soap_msg)) { - return $this->raiseSoapFault($soap_msg); + return $this->_raiseSoapFault($soap_msg); } if (is_array($soap_msg)) { $response = $soap_msg['body']; Index: pear/SOAP/Transport/HTTP.php diff -u pear/SOAP/Transport/HTTP.php:1.18 pear/SOAP/Transport/HTTP.php:1.19 --- pear/SOAP/Transport/HTTP.php:1.18 Mon May 13 02:56:03 2002 +++ pear/SOAP/Transport/HTTP.php Sat Sep 28 21:06:09 2002 @@ -16,7 +16,7 @@ // | Authors: Shane Caraveo <Shane@Caraveo.com> | // +----------------------------------------------------------------------+ // -// $Id: HTTP.php,v 1.18 2002/05/13 06:56:03 shane Exp $ +// $Id: HTTP.php,v 1.19 2002/09/29 01:06:09 shane Exp $ // require_once 'SOAP/Base.php'; @@ -25,7 +25,7 @@ * HTTP Transport for SOAP * * @access public -* @version $Id: HTTP.php,v 1.18 2002/05/13 06:56:03 shane Exp $ +* @version $Id: HTTP.php,v 1.19 2002/09/29 01:06:09 shane Exp $ * @package SOAP::Transport::HTTP * @author Shane Caraveo <shane@php.net> */ @@ -124,7 +124,7 @@ return $this->_sendHTTPS($msg, $options); } - return $this->raiseSoapFault('Invalid url scheme '.$this->url); + return $this->_raiseSoapFault('Invalid url scheme '.$this->url); } /** @@ -153,11 +153,11 @@ function _validateUrl() { if ( ! is_array($this->urlparts) ) { - $this->raiseSoapFault("Unable to parse URL $url"); + $this->_raiseSoapFault("Unable to parse URL $url"); return FALSE; } if (!isset($this->urlparts['host'])) { - $this->raiseSoapFault("No host in URL $url"); + $this->_raiseSoapFault("No host in URL $url"); return FALSE; } if (!isset($this->urlparts['port'])) { @@ -171,7 +171,8 @@ if (isset($this->urlparts['user'])) { $this->setCredentials($this->urlparts['user'], $this->urlparts['pass']); } - + if (!isset($this->urlparts['path']) || !$this->urlparts['path']) + $this->urlparts['path'] = '/'; return TRUE; } @@ -208,25 +209,25 @@ // find the response error, some servers response with 500 for soap faults if (preg_match("/^HTTP\/1\.. (\d+).*/s",$match[1],$status) && $status[1] >= 400 && $status[1] < 500) { - $this->raiseSoapFault("HTTP Response $status[1] Not Found"); + $this->_raiseSoapFault("HTTP Response $status[1] Not Found"); return FALSE; } $this->_parseEncoding($match[1]); if ($this->result_content_type == 'application/dime') { // XXX quick hack insertion of DIME - $this->decodeDIMEMessage($this->response,$this->headers,$this->attachments); + $this->_decodeDIMEMessage($this->response,$this->headers,$this->attachments); $this->result_content_type = $this->headers['content-type']; } else if (stristr($this->result_content_type,'multipart/related')) { $this->response = $this->incoming_payload; - $this->decodeMimeMessage($this->response,$this->headers,$this->attachments); + $this->_decodeMimeMessage($this->response,$this->headers,$this->attachments); } else if ($this->result_content_type != 'text/xml') { - $this->raiseSoapFault($this->response); + $this->_raiseSoapFault($this->response); return FALSE; } // if no content, return false return strlen($this->response) > 0; } - $this->raiseSoapFault('Invalid HTTP Response'); + $this->_raiseSoapFault('Invalid HTTP Response'); return FALSE; } @@ -242,6 +243,12 @@ $fullpath = $this->urlparts['path']. (isset($this->urlparts['query'])?'?'.$this->urlparts['query']:''). (isset($this->urlparts['fragment'])?'#'.$this->urlparts['fragment']:''); + if (isset($options['proxy_host'])) { + $fullpath = ($https?'https://':'http://').$this->urlparts['host'].':'.$this->urlparts['port'].$fullpath; + } + if (isset($options['proxy_user'])) { + $this->headers['Proxy-Authorization'] = 'Basic ' . base64_encode($options['proxy_user'].":".$options['proxy_pass']); + } $this->headers['User-Agent'] = $this->_userAgent; $this->headers['Host'] = $this->urlparts['host']; $this->headers['Content-Type'] = "text/xml; charset=$this->encoding"; @@ -273,18 +280,23 @@ function &_sendHTTP(&$msg, $options) { $this->_getRequest($msg, $options); - + $host = $this->urlparts['host']; + $port = $this->urlparts['port']; + if (isset($options['proxy_host'])) { + $host = $options['proxy_host']; + $port = isset($options['proxy_port'])?$options['proxy_port']:8080; + } // send if ($this->timeout > 0) { - $fp = fsockopen($this->urlparts['host'], $this->urlparts['port'], $this->errno, $this->errmsg, $this->timeout); + $fp = fsockopen($host, $port, $this->errno, $this->errmsg, $this->timeout); } else { - $fp = fsockopen($this->urlparts['host'], $this->urlparts['port'], $this->errno, $this->errmsg); + $fp = fsockopen($host, $port, $this->errno, $this->errmsg); } if (!$fp) { - return $this->raiseSoapFault("Connect Error to {$this->urlparts['host']}:{$this->urlparts['port']}"); + return $this->raiseSoapFault("Connect Error to $host:$port"); } if (!fputs($fp, $this->outgoing_payload, strlen($this->outgoing_payload))) { - return $this->raiseSoapFault("Error POSTing Data to {$this->urlparts['host']}"); + return $this->raiseSoapFault("Error POSTing Data to $host"); } // get reponse @@ -316,12 +328,25 @@ * Your php must be compiled with CURL */ if (!extension_loaded('curl')) { - return $this->raiseSoapFault('CURL Extension is required for HTTPS'); + return $this->_raiseSoapFault('CURL Extension is required for HTTPS'); } $this->_getRequest($msg, $options); $ch = curl_init(); + + // XXX don't know if this proxy stuff is right for CURL + if (isset($options['proxy_host'])) { + // $options['http_proxy'] == 'hostname:port' + $host = $options['proxy_host']; + $port = isset($options['proxy_port'])?$options['proxy_port']:8080; + curl_setopt($ch, CURLOPT_PROXY, $host.":".$port); + } + if (isset($options['proxy_user'])) { + // $options['http_proxy_userpw'] == 'username:password' + curl_setopt($ch, CURLOPT_PROXYUSERPWD, $options['proxy_user'].':'.$options['proxy_pass']); + } + if ($this->timeout) { curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout); //times out after 4s } Index: pear/SOAP/Transport/SMTP.php diff -u pear/SOAP/Transport/SMTP.php:1.13 pear/SOAP/Transport/SMTP.php:1.14 --- pear/SOAP/Transport/SMTP.php:1.13 Tue May 14 19:02:49 2002 +++ pear/SOAP/Transport/SMTP.php Sat Sep 28 21:06:09 2002 @@ -16,7 +16,7 @@ // | Authors: Shane Caraveo <Shane@Caraveo.com> | // +----------------------------------------------------------------------+ // -// $Id: SMTP.php,v 1.13 2002/05/14 23:02:49 shane Exp $ +// $Id: SMTP.php,v 1.14 2002/09/29 01:06:09 shane Exp $ // // Status: rough draft, untested // @@ -39,7 +39,7 @@ * TODO: use PEAR smtp and Mime classes * * @access public -* @version $Id: SMTP.php,v 1.13 2002/05/14 23:02:49 shane Exp $ +* @version $Id: SMTP.php,v 1.14 2002/09/29 01:06:09 shane Exp $ * @package SOAP::Transport::SMTP * @author Shane Caraveo <shane@php.net> */ @@ -87,7 +87,7 @@ return $this->fault; } if (!$options || !array_key_exists('from',$options)) { - return $this->raiseSoapFault("No FROM address to send message with"); + return $this->_raiseSoapFault("No FROM address to send message with"); } if (isset($options['host'])) $this->host = $options['host']; @@ -125,7 +125,7 @@ $headers['Content-Transfer-Encoding'] = 'base64'; $out = chunk_split(base64_encode($msg),76,"\n"); } else { - return $this->raiseSoapFault("Invalid Transfer Encoding: {$options['transfer-encoding']}"); + return $this->_raiseSoapFault("Invalid Transfer Encoding: {$options['transfer-encoding']}"); } } else { // default to base64 @@ -198,16 +198,16 @@ function _validateUrl() { if ( ! is_array($this->urlparts) ) { - $this->raiseSoapFault("Unable to parse URL $url"); + $this->_raiseSoapFault("Unable to parse URL $url"); return FALSE; } if (!isset($this->urlparts['scheme']) || strcasecmp($this->urlparts['scheme'], 'mailto') != 0) { - $this->raiseSoapFault("Unable to parse URL $url"); + $this->_raiseSoapFault("Unable to parse URL $url"); return FALSE; } if (!isset($this->urlparts['path'])) { - $this->raiseSoapFault("Unable to parse URL $url"); + $this->_raiseSoapFault("Unable to parse URL $url"); return FALSE; } return TRUE; Index: pear/SOAP/example/client.php diff -u pear/SOAP/example/client.php:1.2 pear/SOAP/example/client.php:1.3 --- pear/SOAP/example/client.php:1.2 Sun Jul 7 17:49:14 2002 +++ pear/SOAP/example/client.php Sat Sep 28 21:06:09 2002 @@ -16,7 +16,7 @@ // | Authors: Shane Caraveo <Shane@Caraveo.com> | // +----------------------------------------------------------------------+ // -// $Id: client.php,v 1.2 2002/07/07 21:49:14 shane Exp $ +// $Id: client.php,v 1.3 2002/09/29 01:06:09 shane Exp $ // include("SOAP/Client.php"); /** @@ -24,12 +24,14 @@ */ $soapclient = new SOAP_Client("http://localhost/SOAP/example/server.php"); // this namespace is the same as declared in server.php -$namespace = 'urn:SOAP_Example_Server'; +$options = array('namespace' => 'urn:SOAP_Example_Server', + 'trace' => 1); -$ret = $soapclient->call("echoStringSimple",array("inputString"=>"this is a test string"),$namespace); +$ret = $soapclient->call("echoStringSimple",array("inputString"=>"this is a test string"),$options); +print $soapclient->__get_wire(); print_r($ret);echo "<br>\n"; -$ret = $soapclient->call("echoString",array("inputString"=>"this is a test string"),$namespace); +$ret = $soapclient->call("echoString",array("inputString"=>"this is a test string"),$options); print_r($ret);echo "<br>\n"; class SOAPStruct { @@ -41,7 +43,7 @@ $SOAPStruct = new SOAPStruct; /* send an object, get an object back */ -$ret = $soapclient->call("echoStruct",array(new SOAP_Value('inputStruct','',$SOAPStruct)),$namespace); +$ret = $soapclient->call("echoStruct",array(new SOAP_Value('inputStruct','',$SOAPStruct)),$options); print_r($ret); /** @@ -49,7 +51,7 @@ * must do a little work to make it happen here. This requires knowledge on the * developers part to figure out how they want to deal with it. */ -list($string, $int, $float) = array_values($soapclient->call("echoStructAsSimpleTypes",$SOAPStruct,$namespace)); +list($string, $int, $float) = array_values($soapclient->call("echoStructAsSimpleTypes",$SOAPStruct,$options)); echo "varString: $string<br>\nvarInt: $int<br>\nvarFloat: $float<br>\n"; ?> Index: pear/SOAP/interop/client_round2_run.php diff -u pear/SOAP/interop/client_round2_run.php:1.6 pear/SOAP/interop/client_round2_run.php:1.7 --- pear/SOAP/interop/client_round2_run.php:1.6 Sat Jul 6 17:58:24 2002 +++ pear/SOAP/interop/client_round2_run.php Sat Sep 28 21:06:10 2002 @@ -17,11 +17,12 @@ // | Authors: Shane Caraveo <Shane@Caraveo.com> | // +----------------------------------------------------------------------+ // -// $Id: client_round2_run.php,v 1.6 2002/07/06 21:58:24 shane Exp $ +// $Id: client_round2_run.php,v 1.7 2002/09/29 01:06:10 shane Exp $ // set_time_limit(0); require_once 'SOAP/interop/client_round2_interop.php'; $SOAP_RAW_CONVERT = TRUE; +$SOAP_OBJECT_STRUCT = false; $iop = new Interop_Client(); // force a fetch of endpoints, this happens irregardless if no endpoints in database @@ -29,21 +30,21 @@ // set some options $iop->currentTest = 'base'; // see $tests above -$iop->paramType = 'php'; // 'php' or 'soapval' +$iop->paramType = 'soapval'; // 'php' or 'soapval' $iop->useWSDL = 0; // 1= do wsdl tests $iop->numServers = 0; // 0 = all -$iop->specificEndpoint = ''; // test only this endpoint -$iop->testMethod = ''; // test only this method +$iop->specificEndpoint = 'MS SOAP ToolKit 2.0'; // test only this endpoint +$iop->testMethod = 'echoString'; // test only this method $iop->skipEndpointList = array(); // endpoints to skip $this->nosave = 0; // 1= disable saving results to database // debug output $iop->show = 1; -$iop->debug = 0; +$iop->debug = 1; $iop->showFaults = 0; // used in result table output -#$iop->doTest(); // run a single set of tests using above options +$iop->doTest(); // run a single set of tests using above options #$iop->doGroupTests(); // run a group of tests set in $currentTest -$iop->doTests(); // run all tests, ignore above options +#$iop->doTests(); // run all tests, ignore above options #$iop->outputTables(); echo "done"; Index: pear/SOAP/test/5.2.1.simpletypes.string.php diff -u pear/SOAP/test/5.2.1.simpletypes.string.php:1.2 pear/SOAP/test/5.2.1.simpletypes.string.php:1.3 --- pear/SOAP/test/5.2.1.simpletypes.string.php:1.2 Mon May 13 02:47:10 2002 +++ pear/SOAP/test/5.2.1.simpletypes.string.php Sat Sep 28 21:06:10 2002 @@ -34,7 +34,7 @@ } # serialize a soap value with unknown type $expect = "hello world"; -$val = $soap_base->decode($v); +$val = $soap_base->_decode($v); if (string_compare($expect, $val)) { print "$prefix Deserialize known SOAP_Value OK\n"; } else { @@ -53,7 +53,7 @@ # serialize a soap value with unknown type $expect = "hello world"; -$val = $soap_base->decode($v); +$val = $soap_base->_decode($v); if (string_compare($expect, $val)) { print "$prefix Deserialize Unknown SOAP_Value OK\n"; } else { Index: pear/SOAP/test/5.2.simpletypes.php diff -u pear/SOAP/test/5.2.simpletypes.php:1.6 pear/SOAP/test/5.2.simpletypes.php:1.7 --- pear/SOAP/test/5.2.simpletypes.php:1.6 Mon May 13 02:47:10 2002 +++ pear/SOAP/test/5.2.simpletypes.php Sat Sep 28 21:06:10 2002 @@ -68,7 +68,7 @@ # deserialize a soap value $expect = array('age'=>45, 'height'=> 5.9, 'displacement' => -450, 'color' => 'Blue'); -$val = $soap_base->decode($v); +$val = $soap_base->_decode($v); if (string_compare($expect, $val)) { print "$prefix Deserialize known SOAP_Value OK\n"; } else { @@ -93,7 +93,7 @@ # serialize a soap value with unknown type $expect = array('age'=>45, 'height'=> 5.9, 'displacement' => -450, 'color' => 'Blue'); -$val = $soap_base->decode($v); +$val = $soap_base->_decode($v); if (array_compare($expect, $val)) { print "$prefix Deserialize Unknown SOAP_Value OK\n"; } else { Index: pear/SOAP/test/test.utility.php diff -u pear/SOAP/test/test.utility.php:1.5 pear/SOAP/test/test.utility.php:1.6 --- pear/SOAP/test/test.utility.php:1.5 Mon May 13 02:47:10 2002 +++ pear/SOAP/test/test.utility.php Sat Sep 28 21:06:10 2002 @@ -70,7 +70,7 @@ return $response->fault->getFault(); } $return = $response->getResponse(); - $v = $response->decode($return); + $v = $response->_decode($return); if (gettype($v) == 'array' && count($v)==1) { return array_shift($v); } Index: pear/SOAP/tools/genproxy.php diff -u pear/SOAP/tools/genproxy.php:1.3 pear/SOAP/tools/genproxy.php:1.4 --- pear/SOAP/tools/genproxy.php:1.3 Thu Aug 22 03:14:29 2002 +++ pear/SOAP/tools/genproxy.php Sat Sep 28 21:06:11 2002 @@ -12,7 +12,7 @@ function do_wsdl($uri) { $wsdl = new SOAP_WSDL($uri); - print $wsdl->generateAllProxies(); + #print $wsdl->generateAllProxies(); } echo "<?php\n\nrequire_once 'SOAP/Client.php';\n\n"; do_wsdl($_SERVER['argv'][1]);
Index: pear/SOAP/Base.php diff -u pear/SOAP/Base.php:1.22 pear/SOAP/Base.php:1.23 --- pear/SOAP/Base.php:1.22 Sun Aug 18 14:45:48 2002 +++ pear/SOAP/Base.php Sat Sep 28 21:06:07 2002 @@ -17,7 +17,7 @@ // | Authors: Dietrich Ayala <dietrich@ganx4.com> Original Author | // +----------------------------------------------------------------------+ // -// $Id: Base.php,v 1.22 2002/08/18 18:45:48 shane Exp $ +// $Id: Base.php,v 1.23 2002/09/29 01:06:07 shane Exp $ // /* @@ -112,7 +112,7 @@ * Common base class of all Soap lclasses * * @access public -* @version $Id: Base.php,v 1.22 2002/08/18 18:45:48 shane Exp $ +* @version $Id: Base.php,v 1.23 2002/09/29 01:06:07 shane Exp $ * @package SOAP::Client * @author Shane Caraveo <shane@php.net> Conversion to PEAR and updates */ @@ -194,9 +194,9 @@ var $_xmlEntities = array ( '&' => '&', '<' => '<', '>' => '>', "'" => ''', '"' => '"' ); - var $doconversion = FALSE; + var $_doconversion = FALSE; - var $attachments = array(); + var $__attachments = array(); /** * Store debugging information in $debug_data? @@ -204,7 +204,7 @@ * @var boolean if true debugging informations will be store in $debug_data * @see $debug_data, SOAP_Base */ - var $debug_flag = false; + var $_debug_flag = false; /** * String containing debugging informations if $debug_flag is set to true @@ -213,14 +213,14 @@ * @see $debug_flag, SOAP_Base * @access public */ - var $debug_data = ''; + var $_debug_data = ''; /** * Fault code * * @var string */ - var $myfaultcode = ''; + var $_myfaultcode = ''; /** * Recent PEAR error object @@ -229,14 +229,14 @@ */ var $fault = NULL; - var $wsdl = NULL; + var $_wsdl = NULL; /** * section5 * * @var boolean defines if we use section 5 encoding, or false if this is literal */ - var $section5 = TRUE; + var $_section5 = TRUE; // handle type to class mapping var $_auto_translation = false; @@ -247,17 +247,17 @@ * Constructor * * @param string error code - * @see $debug_data, debug() + * @see $debug_data, _debug() */ function SOAP_Base($faultcode = 'Client') { - $this->myfaultcode = $faultcode; - $this->resetNamespaces(); - $this->debug_flag = $GLOBALS['SOAP_DEBUG']; - parent::PEAR('SOAP_Fault'); + $this->_myfaultcode = $faultcode; + $this->_resetNamespaces(); + $this->_debug_flag = $GLOBALS['SOAP_DEBUG']; + parent::PEAR('SOAPfault'); } - function resetNamespaces() + function _resetNamespaces() { $this->_namespaces = array( 'http://schemas.xmlsoap.org/soap/envelope/' => 'SOAP-ENV', @@ -267,7 +267,7 @@ } /** - * setSchemaVersion + * _setSchemaVersion * * sets the schema version used in the soap message * @@ -275,10 +275,10 @@ * * @access private */ - function setSchemaVersion($schemaVersion) + function _setSchemaVersion($schemaVersion) { if (!in_array($schemaVersion, $this->_XMLSchema)) { - return $this->raiseSoapFault("unsuported XMLSchema $schemaVersion"); + return $this->_raiseSoapFault("unsuported XMLSchema $schemaVersion"); } $this->_XMLSchemaVersion = $schemaVersion; $tmpNS = array_flip($this->_namespaces); @@ -304,13 +304,13 @@ * @param boolean * @see $debug_flag, $debug_data */ - function &raiseSoapFault($str, $detail = '', $actorURI = '', $code = null, $mode = null, $options = null, $skipmsg = false) + function &_raiseSoapFault($str, $detail = '', $actorURI = '', $code = null, $mode = null, $options = null, $skipmsg = false) { # pass through previous faults if (is_object($str)) { $this->fault = $str; } else { - if (!$code) $code = $this->myfaultcode; + if (!$code) $code = $this->_myfaultcode; $this->fault = new SOAP_Fault($str, $code, $actorURI, @@ -320,20 +320,30 @@ } return $this->fault; } + + function __isfault() + { + return $this->fault != NULL; + } + + function &__getfault() + { + return $this->fault; + } /** * maintains a string of debug data * * @param debugging message - sometimes an error message */ - function debug($string) + function _debug($string) { - if ($this->debug_flag) { - $this->debug_data .= get_class($this) . ': ' . preg_replace("/>/", ">\r\n", $string) . "\n"; + if ($this->_debug_flag) { + $this->_debug_data .= get_class($this) . ': ' . preg_replace("/>/", ">\r\n", $string) . "\n"; } } - function getNamespacePrefix($ns) + function _getNamespacePrefix($ns) { if (array_key_exists($ns,$this->_namespaces)) { return $this->_namespaces[$ns]; @@ -343,122 +353,141 @@ return $prefix; return NULL; } - - function serializeValue(&$value, $name = '', $type = false, $elNamespace = NULL, $typeNamespace=NULL, $options=array(), $attributes = array()) + + function _getNamespaceForPrefix($prefix) + { + $flipped = array_flip($this->_namespaces); + if (array_key_exists($prefix,$flipped)) { + return $flipped[$prefix]; + } + return NULL; + } + + function _isSoapValue(&$value) + { + return is_object($value) && + (get_class($value) == 'soap_value' || + is_subclass_of($value,'soap_value')); + } + + function _serializeValue(&$value, $name = '', $type = false, $elNamespace = NULL, $typeNamespace=NULL, $options=array(), $attributes = array(), $artype='') { $namespaces = array(); - $xmlout_value = NULL; + $arrayType = $xmlout_value = NULL; $typePrefix = $elPrefix = $xmlout_offset = $xmlout_arrayType = $xmlout_type = $xmlns = ''; + $ptype = $array_type_ns = ''; if (!$name || is_numeric($name)) { $name = 'item'; } - - if (!is_null($value)) { - $ptype = $arrayType = $array_type_ns = ''; - if ($this->wsdl) - list($ptype,$arrayType,$array_type_ns) = $this->wsdl->getSchemaType($type, $name, $typeNamespace); - if (!$ptype) $ptype = $this->_getType($value); - if (!$type) $type = $ptype; - - #if ($ptype == 'object') { - # return $value->serialize($this); - #} else - if (strcasecmp($ptype,'Struct')==0 || strcasecmp($type,'Struct')==0) { - // struct - if (is_object($value)) { - $vars = get_object_vars($value); - } else { - $vars = &$value; - } - if (is_array($vars)) { - foreach (array_keys($vars) as $k) { - if (is_object($vars[$k])) { - if (is_a($vars[$k],'soap_value')) { - $xmlout_value .= $vars[$k]->serialize($this); - } else { - // XXX get the members and serialize them instead - // converting to an array is more overhead than we - // should realy do, but php-soap is on it's way. - $xmlout_value .= $this->serializeValue(get_object_vars($vars[$k]), $k); - } + + if ($this->_wsdl) + list($ptype,$arrayType,$array_type_ns) = $this->_wsdl->getSchemaType($type, $name, $typeNamespace); + + if (!$arrayType) $arrayType = $artype; + if (!$ptype) $ptype = $this->_getType($value); + if (!$type) $type = $ptype; + + if (strcasecmp($ptype,'Struct')==0 || strcasecmp($type,'Struct')==0) { + // struct + $vars = NULL; + if (is_object($value)) { + $vars = get_object_vars($value); + } else { + $vars = &$value; + } + if (is_array($vars)) { + foreach (array_keys($vars) as $k) { + if ($k[0]=='_') continue; // hide private vars + if (is_object($vars[$k])) { + if (is_a($vars[$k],'soap_value')) { + $xmlout_value .= $vars[$k]->serialize($this); } else { - $xmlout_value .= $this->serializeValue($vars[$k],$k); + // XXX get the members and serialize them instead + // converting to an array is more overhead than we + // should realy do, but php-soap is on it's way. + $xmlout_value .= $this->_serializeValue(get_object_vars($vars[$k]), $k); } + } else { + $xmlout_value .= $this->_serializeValue($vars[$k],$k); } } - } else if (strcasecmp($ptype,'Array')==0 || strcasecmp($type,'Array')==0) { - // array - $typeNamespace = SOAP_SCHEMA_ENCODING; - $type = 'Array'; - $numtypes = 0; - // XXX this will be slow on larger array's. Basicly, it flattens array's to allow us - // to serialize multi-dimensional array's. We only do this if arrayType is set, - // which will typicaly only happen if we are using WSDL - if (isset($options['flatten']) || ($arrayType && (strchr($arrayType,',') || strstr($arrayType,'][')))) { - $numtypes = $this->_multiArrayType($value, $arrayType, $ar_size, $xmlout_value); - } + } + } else if (strcasecmp($ptype,'Array')==0 || strcasecmp($type,'Array')==0) { + // array + $typeNamespace = SOAP_SCHEMA_ENCODING; + $type = 'Array'; + $numtypes = 0; + // XXX this will be slow on larger array's. Basicly, it flattens array's to allow us + // to serialize multi-dimensional array's. We only do this if arrayType is set, + // which will typicaly only happen if we are using WSDL + if (isset($options['flatten']) || ($arrayType && (strchr($arrayType,',') || strstr($arrayType,'][')))) { + $numtypes = $this->_multiArrayType($value, $arrayType, $ar_size, $xmlout_value); + } + + $array_type = $array_type_prefix = ''; + if ($numtypes != 1) { + $arrayTypeQName = new QName($arrayType); + $arrayType = $arrayTypeQName->name; + $array_types = array(); + $array_val = NULL; - $array_type = $array_type_prefix = ''; - if ($numtypes != 1) { - $arrayTypeQName = new QName($arrayType); - $arrayType = $arrayTypeQName->name; - $array_types = array(); - $array_val = NULL; - - // serialize each array element - $ar_size = count($value); - for ($i=0; $i < $ar_size; $i++) { - $array_val =& $value[$i]; - if (is_object($array_val)) { - $array_type = $array_val->type; - $array_types[$array_type] = 1; - $array_type_ns = $array_val->type_namespace; - $xmlout_value .= $array_val->serialize($this); - } else { - $array_type = $this->_getType($array_val); - $array_types[$array_type] = 1; - $xmlout_value .= $this->serializeValue($array_val,'item', $array_type); - } - } - - $xmlout_offset = " SOAP-ENC:offset=\"[0]\""; - if (!$arrayType) { - $numtypes = count($array_types); - if ($numtypes == 1) $arrayType = $array_type; - // using anyType is more interoperable - if ($array_type == 'Struct') { - $array_type = ''; - } else if ($array_type == 'Array') { - $arrayType = 'anyType'; - $array_type_prefix = 'xsd'; - } else - if (!$arrayType) $arrayType = $array_type; + // serialize each array element + $ar_size = count($value); + for ($i=0; $i < $ar_size; $i++) { + $array_val =& $value[$i]; + if ($this->_isSoapValue($array_val)) { + $array_type = $array_val->type; + $array_types[$array_type] = 1; + $array_type_ns = $array_val->type_namespace; + $xmlout_value .= $array_val->serialize($this); + } else { + $array_type = $this->_getType($array_val); + $array_types[$array_type] = 1; + $xmlout_value .= $this->_serializeValue($array_val,'item', $array_type); } } - if (!isset($arrayType) || $numtypes > 1) { - $arrayType = 'xsd:anyType'; // should reference what schema we're using - } else { - if ($array_type_ns) { - $array_type_prefix = $this->getNamespacePrefix($array_type_ns); - } else if (array_key_exists($arrayType, $this->_typemap[$this->_XMLSchemaVersion])) { - $array_type_prefix = $this->_namespaces[$this->_XMLSchemaVersion]; - } - if ($array_type_prefix) - $arrayType = $array_type_prefix.':'.$arrayType; + + $xmlout_offset = " SOAP-ENC:offset=\"[0]\""; + if (!$arrayType) { + $numtypes = count($array_types); + if ($numtypes == 1) $arrayType = $array_type; + // using anyType is more interoperable + if ($array_type == 'Struct') { + $array_type = ''; + } else if ($array_type == 'Array') { + $arrayType = 'anyType'; + $array_type_prefix = 'xsd'; + } else + if (!$arrayType) $arrayType = $array_type; } - $xmlout_arrayType = " SOAP-ENC:arrayType=\"".$arrayType."[$ar_size]\""; - - } else if ($type == 'string') { - $xmlout_value = htmlspecialchars($value); + } + if (!isset($arrayType) || $numtypes > 1) { + $arrayType = 'xsd:anyType'; // should reference what schema we're using } else { - $xmlout_value = $value; + if ($array_type_ns) { + $array_type_prefix = $this->_getNamespacePrefix($array_type_ns); + } else if (array_key_exists($arrayType, $this->_typemap[$this->_XMLSchemaVersion])) { + $array_type_prefix = $this->_namespaces[$this->_XMLSchemaVersion]; + } + if ($array_type_prefix) + $arrayType = $array_type_prefix.':'.$arrayType; } + $xmlout_arrayType = " SOAP-ENC:arrayType=\"".$arrayType."[$ar_size]\""; + } else if ($this->_isSoapValue($value)) { + $xmlout_value = $value->serialize($this); + } else if ($type == 'string') { + $xmlout_value = htmlspecialchars($value); + } else if ($type == 'boolean') { + $xmlout_value = $value?'true':'false'; + } else { + $xmlout_value = $value; } + // add namespaces if ($elNamespace) { - if ($this->section5) { - $elPrefix = $this->getNamespacePrefix($elNamespace); + if ($this->_section5) { + $elPrefix = $this->_getNamespacePrefix($elNamespace); $xmlout_name = "$elPrefix:$name"; } else { $xmlns = " xmlns:ns1=\"$elNamespace\""; @@ -469,7 +498,7 @@ } if ($typeNamespace) { - $typePrefix = $this->getNamespacePrefix($typeNamespace); + $typePrefix = $this->_getNamespacePrefix($typeNamespace); $xmlout_type = "$typePrefix:$type"; } else if ($type && array_key_exists($type, $this->_typemap[$this->_XMLSchemaVersion])) { $typePrefix = $this->_namespaces[$this->_XMLSchemaVersion]; @@ -488,9 +517,9 @@ // store the attachement for mime encoding if (isset($options['attachment'])) - $this->attachments[] = $options['attachment']; + $this->__attachments[] = $options['attachment']; - if ($this->section5) { + if ($this->_section5) { if ($xmlout_type) $xmlout_type = " xsi:type=\"$xmlout_type\""; if (is_null($xmlout_value)) { $xml = "\r\n<$xmlout_name$xmlout_type$xmlns$xmlout_arrayType$xml_attr/>"; @@ -532,14 +561,14 @@ break; case 'array': // XXX hashes always get done as structs by pear::soap - $type = $this->isHash($value)?'Struct':'Array'; + $type = $this->_isHash($value)?'Struct':'Array'; break; case 'integer': case 'long': $type = 'int'; break; case 'boolean': - $value = $value?'true':'false'; + #$value = $value?'true':'false'; break; case 'double': $type = 'float'; // double is deprecated in 4.2 and later @@ -556,7 +585,7 @@ if (SOAP_Type_hexBinary::is_hexbin($value)) { $type = 'hexBinary'; } else - if ($this->isBase64($value)) { + if ($this->_isBase64($value)) { $type = 'base64Binary'; } else { $dt = new SOAP_Type_dateTime($value); @@ -594,7 +623,7 @@ $xml .= $value->serialize($this); } else { $type = $this->_getType($value); - $xml .= $this->serializeValue($value,'item',$type); + $xml .= $this->_serializeValue($value,'item',$type); } } $size = NULL; @@ -606,7 +635,7 @@ * @param string * @return string */ - function isBase64(&$value) + function _isBase64(&$value) { $l = strlen($value); if ($l > 0) @@ -619,7 +648,7 @@ * @param mixed * @return boolean */ - function isHash(&$a) { + function _isHash(&$a) { # XXX I realy dislike having to loop through this in php code, # realy large arrays will be slow. We need a C function to do this. $names = array(); @@ -629,7 +658,7 @@ $t = gettype($k); if ($t != 'integer') { return TRUE; - } else if (gettype($v) == 'object' && is_a($v,'soap_value')) { + } else if ($this->_isSoapValue($v)) { $names[$v->name] = 1; } // if someone has a large hash they should realy be defining the type @@ -638,7 +667,7 @@ return count($names)>1; } - function un_htmlentities($string) + function &_un_htmlentities($string) { $trans_tbl = get_html_translation_table (HTML_ENTITIES); $trans_tbl = array_flip($trans_tbl); @@ -649,11 +678,11 @@ * * @param mixed */ - function decode(&$soapval) + function &_decode(&$soapval) { global $SOAP_OBJECT_STRUCT; - if (!is_object($soapval)) { + if (!$this->_isSoapValue($soapval)) { return $soapval; } else if (is_array($soapval->value)) { if ($SOAP_OBJECT_STRUCT && $soapval->type != 'Array') { @@ -669,6 +698,9 @@ } else if ($this->_auto_translation) { if (class_exists($soapval->type)) { $classname = $soapval->type; + } else if ($this->_wsdl) { + $t = $this->_wsdl->getComplexTypeNameForElement($soapval->name, $soapval->namespace); + if ($t && class_exists($t)) $classname = $t; } } $return = new $classname; @@ -677,39 +709,55 @@ } $counter = 1; - $isstruct = TRUE; // assume it's a struct + $isstruct = !$SOAP_OBJECT_STRUCT || !is_array($return); foreach ($soapval->value as $item) { if (is_object($return)) { + if ($this->_wsdl) { + // get this childs wsdl information + // /$soapval->ns/$soapval->type/$item->ns/$item->name + $child_type = $this->_wsdl->getComplexTypeChildType( + $soapval->namespace, + $soapval->name, + $item->namespace, + $item->name); + if ($child_type) $item->type = $child_type; + } if (!$isstruct || $item->type == 'Array') { if (isset($return->{$item->name}) && is_object($return->{$item->name})) { - $return->{$item->name} = $this->decode($item); + $return->{$item->name} = $this->_decode($item); } else if (isset($return->{$item->name}) && is_array($return->{$item->name})) { - $return->{$item->name}[] = $this->decode($item); + $return->{$item->name}[] = $this->_decode($item); } else if (is_array($return)) { - $return[] = $this->decode($item); + $return[] = $this->_decode($item); } else { - $return->{$item->name} = $this->decode($item); + $return->{$item->name} = $this->_decode($item); } } else if (isset($return->{$item->name})) { $isstruct = FALSE; if (count(get_class_vars($return)) == 1) { - $return = array($return->{$item->name}, $this->decode($item)); + $return = array($return->{$item->name}, $this->_decode($item)); } else { - $return->{$item->name} = array($return->{$item->name}, $this->decode($item)); + $return->{$item->name} = array($return->{$item->name}, $this->_decode($item)); } } else { - $return->{$item->name} = $this->decode($item); + $return->{$item->name} = $this->_decode($item); + } + /* set the attributes as members in the class */ + if (method_exists($return,'__set_attribute')) { + foreach ($soapval->attributes as $key=>$value) { + call_user_func_array(array(&$return,'__set_attribute'),array($key,$value)); + } } } else { if (!$isstruct) { - $return[] = $this->decode($item); + $return[] = $this->_decode($item); } else if (isset($return[$item->name])) { $isstruct = FALSE; - $return = array($return[$item->name], $this->decode($item)); + $return = array($return[$item->name], $this->_decode($item)); } else { - $return[$item->name] = $this->decode($item); + $return[$item->name] = $this->_decode($item); } } } @@ -736,7 +784,7 @@ * @return associative array (headers,body) * @access private */ - function _makeEnvelope(&$method, &$headers, $encoding = SOAP_DEFAULT_ENCODING,$options = array()) + function &_makeEnvelope(&$method, &$headers, $encoding = SOAP_DEFAULT_ENCODING,$options = array()) { $smsg = $header_xml = $ns_string = ''; @@ -766,13 +814,13 @@ } /* if use='literal', we do not put in the encodingStyle. This is denoted by - $this->section5 being false. + $this->_section5 being false. XXX use can be defined at a more granular level than we are dealing with here, so this does not work for all services. */ $xml = "<?xml version=\"1.0\" encoding=\"$encoding\"?>\r\n\r\n". "<SOAP-ENV:Envelope $ns_string". - ($this->section5?" SOAP-ENV:encodingStyle=\"" . SOAP_SCHEMA_ENCODING . "\"":''). + ($this->_section5?" SOAP-ENV:encodingStyle=\"" . SOAP_SCHEMA_ENCODING . "\"":''). ">\r\n". "$header_xml$body</SOAP-ENV:Envelope>\r\n"; @@ -784,7 +832,7 @@ global $SOAP_options; if (!isset($SOAP_options['Mime'])) { - return $this->raiseSoapFault('Mime is not installed'); + return $this->_raiseSoapFault('Mime is not installed'); } // encode any attachments @@ -799,9 +847,9 @@ $msg->addSubPart($xml, $params); // add the attachements - $c = count($this->attachments); + $c = count($this->__attachments); for ($i=0; $i < $c; $i++) { - $attachment =& $this->attachments[$i]; + $attachment =& $this->__attachments[$i]; $msg->addSubPart($attachment['body'],$attachment); } return $msg->encode(); @@ -813,7 +861,7 @@ global $SOAP_options; if (!isset($SOAP_options['DIME'])) { - return $this->raiseSoapFault('DIME is not installed'); + return $this->_raiseSoapFault('DIME is not installed'); } // encode any attachments @@ -823,20 +871,20 @@ $msg = $dime->encodeData($xml,SOAP_ENVELOP,NULL,NET_DIME_TYPE_URI); // add the attachements - $c = count($this->attachments); + $c = count($this->__attachments); for ($i=0; $i < $c; $i++) { - $attachment =& $this->attachments[$i]; + $attachment =& $this->__attachments[$i]; $msg .= $dime->encodeData($attachment['body'],$attachment['content_type'],$attachment['cid'],NET_DIME_TYPE_MEDIA); } $msg .= $dime->endMessage(); return $msg; } - function decodeMimeMessage(&$data, &$headers, &$attachments) + function _decodeMimeMessage(&$data, &$headers, &$attachments) { global $SOAP_options; if (!isset($SOAP_options['Mime'])) { - $this->makeFault('Server','Mime Unsupported, install PEAR::Mail::Mime'); + $this->_raiseSoapFault('Mime Unsupported, install PEAR::Mail::Mime','','','Server'); return; } @@ -874,14 +922,14 @@ } return; } - $this->makeFault('Server','Mime parsing error'); + $this->_raiseSoapFault('Mime parsing error','','','Server'); } - function decodeDIMEMessage(&$data, &$headers, &$attachments) + function _decodeDIMEMessage(&$data, &$headers, &$attachments) { global $SOAP_options; if (!isset($SOAP_options['DIME'])) { - return $this->raiseSoapFault('DIME is not installed'); + $this->_raiseSoapFault('DIME Unsupported, install PEAR::Net::DIME','','','Server'); } // XXX this SHOULD be moved to the transport layer, e.g. PHP itself @@ -890,7 +938,7 @@ $dime->decodeData($data); if (strcasecmp($dime->parts[0]['type'],SOAP_ENVELOP) !=0 || strcasecmp($dime->parts[0]['type'],SOAP_ENVELOP) !=0) { - $this->makeFault('Server','Dime record 1 is not a SOAP envelop!'); + $this->_raiseSoapFault('Dime record 1 is not a SOAP envelop!','','','Server'); } else { $data = $dime->parts[0]['data']; $headers['content-type'] = 'text/xml'; // fake it for now @@ -918,7 +966,7 @@ * class used to handle QNAME values in XML * * @access public -* @version $Id: Base.php,v 1.22 2002/08/18 18:45:48 shane Exp $ +* @version $Id: Base.php,v 1.23 2002/09/29 01:06:07 shane Exp $ * @package SOAP::Client * @author Shane Caraveo <shane@php.net> Conversion to PEAR and updates */ Index: pear/SOAP/Client.php diff -u pear/SOAP/Client.php:1.40 pear/SOAP/Client.php:1.41 --- pear/SOAP/Client.php:1.40 Sun Aug 18 14:45:48 2002 +++ pear/SOAP/Client.php Sat Sep 28 21:06:07 2002 @@ -17,7 +17,7 @@ // | Authors: Dietrich Ayala <dietrich@ganx4.com> Original Author | // +----------------------------------------------------------------------+ // -// $Id: Client.php,v 1.40 2002/08/18 18:45:48 shane Exp $ +// $Id: Client.php,v 1.41 2002/09/29 01:06:07 shane Exp $ // require_once 'SOAP/Value.php'; @@ -37,7 +37,7 @@ * originaly based on SOAPx4 by Dietrich Ayala http://dietrich.ganx4.com/soapx4 * * @access public -* @version $Id: Client.php,v 1.40 2002/08/18 18:45:48 shane Exp $ +* @version $Id: Client.php,v 1.41 2002/09/29 01:06:07 shane Exp $ * @package SOAP::Client * @author Shane Caraveo <shane@php.net> Conversion to PEAR and updates * @author Stig Bakken <ssb@fast.no> Conversion to PEAR @@ -60,14 +60,14 @@ * @var string * @see SOAP_Client() */ - var $endpoint = ''; + var $_endpoint = ''; /** * portname * * @var string contains the SOAP PORT name that is used by the client */ - var $portName = ''; + var $_portName = ''; /** @@ -75,35 +75,23 @@ * * @var string e.g. wdsl */ - var $endpointType = ''; - - /** - * WDSL object - * - * @var object SOAP_WDSL - */ - var $wsdl = NULL; + var $__endpointType = ''; /** * wire * * @var string contains outoing and incoming data stream for debugging. */ - var $wire = NULL; - - /** - * soapmsg - * - * @var SOAP_Message The soap message class that is used for outgoing calls. - */ - var $soapmsg = NULL; - + var $wire; + var $__last_request = NULL; + var $__last_response = NULL; + var $__options = array('trace'=>0); /** * encoding * * @var string Contains the character encoding used for XML parser, etc. */ - var $encoding = SOAP_DEFAULT_ENCODING; + var $_encoding = SOAP_DEFAULT_ENCODING; /** @@ -120,26 +108,34 @@ var $headersIn = NULL; /** + * __proxy_params + * + * @var array contains options for HTTP_Request class (see HTTP/Request.php) + */ + var $__proxy_params = array(); + /** * SOAP_Client constructor * * @param string endpoint (URL) * @param boolean wsdl (true if endpoint is a wsdl file) * @param string portName + * @param array contains options for HTTP_Request class (see HTTP/Request.php) * @access public */ - function SOAP_Client($endpoint, $wsdl = false, $portName = false) + function SOAP_Client($endpoint, $wsdl = false, $portName = false, $proxy_params=array()) { parent::SOAP_Base('Client'); - $this->endpoint = $endpoint; - $this->portName = $portName; + $this->_endpoint = $endpoint; + $this->_portName = $portName; + $this->__proxy_params = $proxy_params; // make values if ($wsdl) { - $this->endpointType = 'wsdl'; + $this->__endpointType = 'wsdl'; // instantiate wsdl class - $this->wsdl = new SOAP_WSDL($this->endpoint); - if ($this->wsdl->fault) { - $this->raiseSoapFault($this->wsdl->fault); + $this->_wsdl = new SOAP_WSDL($this->_endpoint, $this->__proxy_params); + if ($this->_wsdl->fault) { + $this->_raiseSoapFault($this->_wsdl->fault); } } } @@ -157,10 +153,10 @@ function setEncoding($encoding) { if (in_array($encoding, $this->_encodings)) { - $this->encoding = $encoding; + $this->_encoding = $encoding; return NULL; } - return $this->raiseSoapFault('Invalid Encoding'); + return $this->_raiseSoapFault('Invalid Encoding'); } /** @@ -173,18 +169,17 @@ * * @access public */ - function addHeader($soap_value) + function addHeader(&$soap_value) { # add a new header to the message if (is_a($soap_value,'soap_header')) { - #$this->soapmsg->addHeader($soap_value); $this->headersOut[] = $soap_value; } else if (gettype($soap_value) == 'array') { // name, value, namespace, mustunderstand, actor $h = new SOAP_Header($soap_value[0], NULL, $soap_value[1], $soap_value[2], $soap_value[3]); $this->headersOut[] = $h; } else { - $this->raiseSoapFault("Don't understand the header info you provided. Must be array or SOAP_Header."); + $this->_raiseSoapFault("Don't understand the header info you provided. Must be array or SOAP_Header."); } } @@ -218,50 +213,132 @@ */ function call($method, $params = array(), $namespace = false, $soapAction = false) { + $soap_data = $this->__generate($method, $params, $namespace, $soapAction); + if (PEAR::isError($soap_data)) { + return $this->_raiseSoapFault($soap_data); + } + $soap_transport = new SOAP_Transport($this->_endpoint, $this->_encoding); + if ($soap_transport->fault) { + return $this->_raiseSoapFault($soap_transport->fault); + } + // send the message + $transport_options = array_merge($this->__proxy_params, $this->__options); + $this->xml = $soap_transport->send($soap_data, $this->__options); + + // save the wire information for debugging + if ($this->__options['trace'] > 0) { + $this->__last_request =& $soap_transport->transport->outgoing_payload; + $this->__last_response =& $soap_transport->transport->incoming_payload; + $this->wire = $this->__get_wire(); + } + if ($soap_transport->fault) { + return $this->_raiseSoapFault($this->xml); + } + + $this->__attachements =& $soap_transport->transport->attachments; + $this->__result_encoding = $soap_transport->result_encoding; + unset($soap_transport); + + if (isset($this->__options['result']) && $this->__options['result'] != 'parse') return $this->xml; + + return $this->__parse($this->xml, $this->__result_encoding,$this->__attachements); + } + + /** + * SOAP_Client::__call + * + * Overload extension support + * if the overload extension is loaded, you can call the client class + * with a soap method name + * $soap = new SOAP_Client(....); + * $value = $soap->getStockQuote('MSFT'); + * + * @param string method + * @param array args + * @param string retur_value + * + * @return boolean + * @access public + */ + function __call($method, $args, &$return_value) + { + if ($this->_wsdl) $this->_wsdl->matchMethod($method); + $return_value = $this->call($method, $args); + return TRUE; + } + + function &__getlastrequest() + { + return $this->__last_request; + } + + function &__getlastresponse() + { + return $this->__last_response; + } + + function __use($use) + { + $this->__options['use'] = $use; + } + + function __style($style) + { + $this->__options['style'] = $style; + } + + function __trace($level) + { + $this->__options['trace'] = $level; + } + + function &__generate($method, $params = array(), $namespace = false, $soapAction = false) + { $this->fault = null; - $options = array('input'=>'parse','result'=>'parse'); + $this->__options['input']='parse'; + $this->__options['result']='parse'; if ($params && gettype($params) != 'array') { $params = array($params); } if (gettype($namespace) == 'array') { - $options = array_merge($options,$namespace); - if (isset($options['namespace'])) $namespace = $options['namespace']; + $this->__options = array_merge($this->__options,$namespace); + if (isset($this->__options['namespace'])) $namespace = $this->__options['namespace']; else $namespace = false; } else { // we'll place soapaction into our array for usage in the transport - $options['soapaction'] = $soapAction; - $options['namespace'] = $namespace; + $this->__options['soapaction'] = $soapAction; + $this->__options['namespace'] = $namespace; } - if ($this->endpointType == 'wsdl') { - $this->setSchemaVersion($this->wsdl->xsd); + if ($this->__endpointType == 'wsdl') { + $this->_setSchemaVersion($this->_wsdl->xsd); // get portName - if (!$this->portName) { - $this->portName = $this->wsdl->getPortName($method); - if (PEAR::isError($this->portName)) { - return $this->raiseSoapFault($this->portName); - } + if (!$this->_portName) { + $this->_portName = $this->_wsdl->getPortName($method); } - $namespace = $this->wsdl->getNamespace($this->portName, $method); + if (PEAR::isError($this->_portName)) { + return $this->_raiseSoapFault($this->_portName); + } + $namespace = $this->_wsdl->getNamespace($this->_portName, $method); // get endpoint - $this->endpoint = $this->wsdl->getEndpoint($this->portName); - if (PEAR::isError($this->endpoint)) { - return $this->raiseSoapFault($this->endpoint); + $this->_endpoint = $this->_wsdl->getEndpoint($this->_portName); + if (PEAR::isError($this->_endpoint)) { + return $this->_raiseSoapFault($this->_endpoint); } // get operation data - $opData = $this->wsdl->getOperationData($this->portName, $method); + $opData = $this->_wsdl->getOperationData($this->_portName, $method); if (PEAR::isError($opData)) { - return $this->raiseSoapFault($opData); + return $this->_raiseSoapFault($opData); } - $options['style'] = $opData['style']; - $options['use'] = $opData['input']['use']; - $options['soapaction'] = $opData['soapAction']; + $this->__options['style'] = $opData['style']; + $this->__options['use'] = $opData['input']['use']; + $this->__options['soapaction'] = $opData['soapAction']; // set input params - if ($options['input'] == 'parse') { + if ($this->__options['input'] == 'parse') { $nparams = array(); if (isset($opData['input']['parts']) && count($opData['input']['parts']) > 0) { $i = 0; @@ -271,8 +348,8 @@ $attrs = array(); // is the name actually a complex type? if (isset($part['element'])) { - $xmlns = $this->wsdl->namespaces[$part['namespace']]; - $part = $this->wsdl->elements[$part['namespace']][$part['type']]; + $xmlns = $this->_wsdl->namespaces[$part['namespace']]; + $part = $this->_wsdl->elements[$part['namespace']][$part['type']]; $name = $part['name']; } if (isset($params[$name])) { @@ -290,9 +367,9 @@ // type is a qname likely, split it apart, and get the type namespace from wsdl $qname = new QName($part['type']); if ($qname->ns) - $type_namespace = $this->wsdl->namespaces[$qname->ns]; + $type_namespace = $this->_wsdl->namespaces[$qname->ns]; else if (isset($part['namespace'])) - $type_namespace = $this->wsdl->namespaces[$part['namespace']]; + $type_namespace = $this->_wsdl->namespaces[$part['namespace']]; else $type_namespace = NULL; $qname->namespace = $type_namespace; @@ -308,24 +385,24 @@ $params = $nparams; } } else { - $this->setSchemaVersion(SOAP_XML_SCHEMA_VERSION); + $this->_setSchemaVersion(SOAP_XML_SCHEMA_VERSION); } // serialize the message $this->section5 = TRUE; // assume we encode with section 5 - if (isset($options['use']) && $options['use']=='literal') $this->section5 = FALSE; + if (isset($this->__options['use']) && $this->__options['use']=='literal') $this->section5 = FALSE; - if (!isset($options['style']) || $options['style'] == 'rpc') { - $options['style'] = 'rpc'; + if (!isset($this->__options['style']) || $this->__options['style'] == 'rpc') { + $this->__options['style'] = 'rpc'; $this->docparams = true; $mqname = new QName($method, $namespace); $methodValue = new SOAP_Value($mqname->fqn(), 'Struct', $params); - $soap_msg = $this->_makeEnvelope($methodValue, $this->headersOut, $this->encoding,$options); + $soap_msg = $this->_makeEnvelope($methodValue, $this->headersOut, $this->_encoding,$this->__options); } else { if (!$params) { $mqname = new QName($method, $namespace); $params = new SOAP_Value($mqname->fqn(), 'Struct', NULL); - } elseif ($options['input'] == 'parse') { + } elseif ($this->__options['input'] == 'parse') { if (is_array($params)) { $nparams = array(); foreach ($params as $n => $v) { @@ -338,26 +415,26 @@ $params = $nparams; } } - $soap_msg = $this->_makeEnvelope($params, $this->headersOut, $this->encoding,$options); + $soap_msg = $this->_makeEnvelope($params, $this->headersOut, $this->_encoding,$this->__options); } if (PEAR::isError($soap_msg)) { - return $this->raiseSoapFault($soap_msg); + return $this->_raiseSoapFault($soap_msg); } // handle Mime or DIME encoding // XXX DIME Encoding should move to the transport, do it here for now // and for ease of getting it done - if (count($this->attachments)) { - if ((isset($options['Attachments']) && $options['Attachments'] == 'Mime') || isset($options['Mime'])) { - $soap_msg = $this->_makeMimeMessage($soap_msg, $this->encoding); + if (count($this->__attachments)) { + if ((isset($this->__options['Attachments']) && $this->__options['Attachments'] == 'Mime') || isset($this->__options['Mime'])) { + $soap_msg = $this->_makeMimeMessage($soap_msg, $this->_encoding); } else { // default is dime - $soap_msg = $this->_makeDIMEMessage($soap_msg, $this->encoding); - $options['headers']['Content-Type'] = 'application/dime'; + $soap_msg = $this->_makeDIMEMessage($soap_msg, $this->_encoding); + $this->__options['headers']['Content-Type'] = 'application/dime'; } if (PEAR::isError($soap_msg)) { - return $this->raiseSoapFault($soap_msg); + return $this->_raiseSoapFault($soap_msg); } } @@ -365,74 +442,52 @@ if (is_array($soap_msg)) { $soap_data = $soap_msg['body']; if (count($soap_msg['headers'])) { - if (isset($options['headers'])) { - $options['headers'] = array_merge($options['headers'],$soap_msg['headers']); + if (isset($this->__options['headers'])) { + $this->__options['headers'] = array_merge($this->__options['headers'],$soap_msg['headers']); } else { - $options['headers'] = $soap_msg['headers']; + $this->__options['headers'] = $soap_msg['headers']; } } } else { $soap_data = $soap_msg; } - #$f = fopen('/tmp/dime.data','wb+'); - #if ($f) { - # fwrite($f,$soap_data); - # fclose($f); - # return; - #} - $soap_transport = new SOAP_Transport($this->endpoint, $this->encoding); - - if ($soap_transport->fault) { - return $this->raiseSoapFault($soap_transport->fault); - } - - // send the message - $this->xml = $soap_transport->send($soap_data, $options); - - // save the wire information for debugging - $this->wire = "OUTGOING:\n\n". - $soap_transport->transport->outgoing_payload. - "\n\nINCOMING\n\n". - preg_replace("/></",">\r\n<",$soap_transport->transport->incoming_payload); - - if (isset($options['result']) && $options['result'] != 'parse') return $this->xml; - - if ($soap_transport->fault) { - return $this->raiseSoapFault($this->xml); - } - return $this->parseResponse($this->xml, $soap_transport->result_encoding,$soap_transport->transport->attachments); + return $soap_data; } - - function parseResponse($response, $encoding, $attachments) + + function &__parse($response, $encoding, $attachments) { // parse the response $this->response = new SOAP_Parser($response, $encoding, $attachments); if ($this->response->fault) { - return $this->raiseSoapFault($this->response->fault); + return $this->_raiseSoapFault($this->response->fault); } // return array of parameters $return = $this->response->getResponse(); $headers = $this->response->getHeaders(); if ($headers) { - $this->headersIn = $this->decode($headers); + $this->headersIn = $this->__decodeResponse($headers,false); } - #$this->soapmsg = NULL; - + return $this->__decodeResponse($return); + } + + function &__decodeResponse($response,$shift=true) + { + if (!$response) return NULL; // check for valid response - if (PEAR::isError($return)) { - return $this->raiseSoapFault($return); - } else if (!is_a($return,'soap_value')) { - return $this->raiseSoapFault("didn't get SOAP_Value object back from client"); + if (PEAR::isError($response)) { + return $this->_raiseSoapFault($response); + } else if (!is_a($response,'soap_value')) { + return $this->_raiseSoapFault("didn't get SOAP_Value object back from client"); } // decode to native php datatype - $returnArray = $this->decode($return); + $returnArray = $this->_decode($response); // fault? if (PEAR::isError($returnArray)) { - return $this->raiseSoapFault($returnArray); + return $this->_raiseSoapFault($returnArray); } - if (is_object($returnArray)) { + if (is_object($returnArray) && get_class($returnArray) == 'stdClass') { $returnArray = get_object_vars($returnArray); } @@ -445,40 +500,27 @@ if (stristr($k,'detail')) $faultdetail = $v; if (stristr($k,'faultactor')) $faultactor = $v; } - return $this->raiseSoapFault($faultstring, $faultdetail, $faultactor, $faultcode); + return $this->_raiseSoapFault($faultstring, $faultdetail, $faultactor, $faultcode); } // return array of return values - if (count($returnArray) == 1) { + if ($shift && count($returnArray) == 1) { return array_shift($returnArray); } return $returnArray; } return $returnArray; } - - /** - * SOAP_Client::__call - * - * Overload extension support - * if the overload extension is loaded, you can call the client class - * with a soap method name - * $soap = new SOAP_Client(....); - * $value = $soap->getStockQuote('MSFT'); - * - * @param string method - * @param array args - * @param string retur_value - * - * @return boolean - * @access public - */ - function __call($method, $args, &$return_value) + + function __get_wire() { - if ($this->wsdl) $this->wsdl->matchMethod($method); - $return_value = $this->call($method, $args); - return TRUE; + if ($this->__options['trace'] > 0) { + return "OUTGOING:\n\n". + $this->__last_request. + "\n\nINCOMING\n\n". + preg_replace("/></",">\r\n<",$this->__last_response); + } + return NULL; } - } if (extension_loaded('overload')) { Index: pear/SOAP/Parser.php diff -u pear/SOAP/Parser.php:1.24 pear/SOAP/Parser.php:1.25 --- pear/SOAP/Parser.php:1.24 Mon Jun 24 21:58:03 2002 +++ pear/SOAP/Parser.php Sat Sep 28 21:06:08 2002 @@ -17,7 +17,7 @@ // | Authors: Dietrich Ayala <dietrich@ganx4.com> Original Author | // +----------------------------------------------------------------------+ // -// $Id: Parser.php,v 1.24 2002/06/25 01:58:03 shane Exp $ +// $Id: Parser.php,v 1.25 2002/09/29 01:06:08 shane Exp $ // require_once 'SOAP/Base.php'; @@ -30,7 +30,7 @@ * originaly based on SOAPx4 by Dietrich Ayala http://dietrich.ganx4.com/soapx4 * * @access public -* @version $Id: Parser.php,v 1.24 2002/06/25 01:58:03 shane Exp $ +* @version $Id: Parser.php,v 1.25 2002/09/29 01:06:08 shane Exp $ * @package SOAP::Parser * @author Shane Caraveo <shane@php.net> Conversion to PEAR and updates * @author Dietrich Ayala <dietrich@ganx4.com> Original Author @@ -71,7 +71,7 @@ function SOAP_Parser($xml, $encoding = SOAP_DEFAULT_ENCODING, $attachments=NULL) { parent::SOAP_Base('Parser'); - $this->setSchemaVersion(SOAP_XML_SCHEMA_VERSION); + $this->_setSchemaVersion(SOAP_XML_SCHEMA_VERSION); $this->xml = $xml; $this->xml_encoding = $encoding; @@ -101,7 +101,7 @@ $err = sprintf('XML error on line %d: %s', xml_get_current_line_number($parser), xml_error_string(xml_get_error_code($parser))); - $this->raiseSoapFault($err,htmlspecialchars($this->xml)); + $this->_raiseSoapFault($err,htmlspecialchars($this->xml)); } else { // build the response if (count($this->root_struct)) @@ -299,17 +299,19 @@ $prefix = $kqn->name; if (in_array($value, $this->_XMLSchema)) { - $this->setSchemaVersion($value); + $this->_setSchemaVersion($value); } - - $this->_namespaces[$prefix] = $value; + + $this->_namespaces[$value] = $prefix; // set method namespace # XXX unused??? #if ($name == $this->curent_root_struct_name) { # $this->methodNamespace = $value; #} - + } elseif ($key == 'xmlns') { + $qname->ns = $this->_getNamespacePrefix($value); + $qname->namespace = $value; } elseif ($kqn->name == 'actor') { $this->message[$pos]['actor'] = $value; } elseif ($kqn->name == 'mustUnderstand') { @@ -319,7 +321,7 @@ } elseif ($kqn->name == 'type') { $vqn = new QName($value); $this->message[$pos]['type'] = $vqn->name; - $this->message[$pos]['type_namespace'] = $this->_namespaces[$vqn->ns]; + $this->message[$pos]['type_namespace'] = $this->_getNamespaceForPrefix($vqn->ns); #print "set type for {$this->message[$pos]['name']} to {$this->message[$pos]['type']}\n"; // should do something here with the namespace of specified type? @@ -367,9 +369,11 @@ // see if namespace is defined in tag if (array_key_exists('xmlns:'.$qname->ns,$attrs)) { $namespace = $attrs['xmlns:'.$qname->ns]; + } else if ($qname->ns && !$qname->namespace) { + $namespace = $this->_getNamespaceForPrefix($qname->ns); } else { // get namespace - $namespace = $qname->ns?$this->_namespaces[$qname->ns]:$this->default_namespace; + $namespace = $qname->namespace?$qname->namespace:$this->default_namespace; } $this->message[$pos]['namespace'] = $namespace; $this->default_namespace = $namespace; @@ -469,7 +473,7 @@ if ($this->soapresponse) { return $this->soapresponse; } - return $this->raiseSoapFault("couldn't build response"); + return $this->_raiseSoapFault("couldn't build response"); } /** Index: pear/SOAP/Server.php diff -u pear/SOAP/Server.php:1.24 pear/SOAP/Server.php:1.25 --- pear/SOAP/Server.php:1.24 Wed Jul 17 21:50:09 2002 +++ pear/SOAP/Server.php Sat Sep 28 21:06:08 2002 @@ -17,7 +17,7 @@ // | Authors: Dietrich Ayala <dietrich@ganx4.com> Original Author | // +----------------------------------------------------------------------+ // -// $Id: Server.php,v 1.24 2002/07/18 01:50:09 shane Exp $ +// $Id: Server.php,v 1.25 2002/09/29 01:06:08 shane Exp $ // require_once 'SOAP/Base.php'; @@ -40,7 +40,7 @@ * originaly based on SOAPx4 by Dietrich Ayala http://dietrich.ganx4.com/soapx4 * * @access public -* @version $Id: Server.php,v 1.24 2002/07/18 01:50:09 shane Exp $ +* @version $Id: Server.php,v 1.25 2002/09/29 01:06:08 shane Exp $ * @package SOAP::Client * @author Shane Caraveo <shane@php.net> Conversion to PEAR and updates * @author Dietrich Ayala <dietrich@ganx4.com> Original Author @@ -74,11 +74,6 @@ */ var $xml_encoding = SOAP_DEFAULT_ENCODING; var $response_encoding = 'UTF-8'; - /** - * - * @var boolean - */ - var $soapfault = false; var $result = 'successful'; // for logging interop results to db @@ -128,40 +123,40 @@ // treat incoming data as UTF-8 if no encoding set if (isset($_SERVER['CONTENT_TYPE'])) { if (strcasecmp($_SERVER['CONTENT_TYPE'],'application/dime')==0) { - $this->decodeDIMEMessage($data,$headers,$attachments); + $this->_decodeDIMEMessage($data,$headers,$attachments); $useEncoding = 'DIME'; } else if (stristr($_SERVER['CONTENT_TYPE'],'multipart/related')) { // this is a mime message, lets decode it. $data = 'Content-Type: '.stripslashes($_SERVER['CONTENT_TYPE'])."\r\n\r\n".$data; - $this->decodeMimeMessage($data,$headers,$attachments); + $this->_decodeMimeMessage($data,$headers,$attachments); $useEncoding = 'Mime'; } if (!isset($headers['content-type'])) { $headers['content-type'] = $_SERVER['CONTENT_TYPE']; } - if (!$this->soapfault && + if (!$this->fault && !$this->_getContentEncoding($headers['content-type'])) { $this->xml_encoding = SOAP_DEFAULT_ENCODING; // an encoding we don't understand, return a fault - $this->makeFault('Server','Unsupported encoding, use one of ISO-8859-1, US-ASCII, UTF-8'); + $this->_raiseSoapFault('Unsupported encoding, use one of ISO-8859-1, US-ASCII, UTF-8','','','Server'); } } // if this is not a POST with Content-Type text/xml, try to return a WSDL file - if (!$this->soapfault && !$test && ($_SERVER['REQUEST_METHOD'] != 'POST' || + if (!$this->fault && !$test && ($_SERVER['REQUEST_METHOD'] != 'POST' || strncmp($headers['content-type'],'text/xml',8) != 0)) { // this is not possibly a valid soap request, try to return a WSDL file - $this->makeFault('Server',"Invalid SOAP request, must be POST with content-type: text/xml, got: {$headers['content-type']}"); + $this->_raiseSoapFault("Invalid SOAP request, must be POST with content-type: text/xml, got: {$headers['content-type']}",'','','Server'); } - if (!$this->soapfault) { + if (!$this->fault) { // $response is a soap_msg object $soap_msg = $this->parseRequest($data, $attachments); // handle Mime or DIME encoding // XXX DIME Encoding should move to the transport, do it here for now // and for ease of getting it done - if (count($this->attachments)) { + if (count($this->__attachments)) { if ($useEncoding == 'Mime') { $soap_msg = $this->_makeMimeMessage($soap_msg); } else { @@ -184,9 +179,9 @@ } } - if ($this->soapfault) { + if ($this->fault) { $hdrs = "HTTP/1.1 500 Soap Fault\r\n"; - $response = $this->getFaultMessage(); + $response = $this->fault->message(); } else { $hdrs = "HTTP/1.1 200 OK\r\n"; } @@ -267,7 +262,7 @@ $parser = new SOAP_Parser($data,$this->xml_encoding,$attachments); // if fault occurred during message parsing if ($parser->fault) { - $this->soapfault = $parser->fault; + $this->fault = $parser->fault; return NULL; } @@ -279,7 +274,7 @@ if ($request_headers) { if (!is_a($request_headers,'soap_value')) { - $this->makeFault('Server',"parser did not return SOAP_Value object: $request_headers"); + $this->_raiseSoapFault("parser did not return SOAP_Value object: $request_headers",'','','Server'); return NULL; } if ($request_headers->value) { @@ -294,7 +289,7 @@ $header_val->actor == $this->endpoint); if (!$f_exists && $header_val->mustunderstand && $myactor) { - $this->makeFault('MustUnderstand',"I don't understand header $header_val->name."); + $this->_raiseSoapFault("I don't understand header $header_val->name.",'','','MustUnderstand'); return NULL; } @@ -327,7 +322,7 @@ $this->method_namespace = $parser->message[$parser->root_struct[0]]['namespace']; // does method exist? if (!$this->methodname || !$this->validateMethod($this->methodname,$this->method_namespace)) { - $this->makeFault('Server',"method '$this->methodname' not defined in service"); + $this->_raiseSoapFault("method '{$this->method_namespace}$this->methodname' not defined in service",'','','Server'); return NULL; } @@ -335,7 +330,7 @@ return NULL; } if (!is_a($request_val,'soap_value')) { - $this->makeFault('Server',"parser did not return SOAP_Value object: $request_val"); + $this->_raiseSoapFault("parser did not return SOAP_Value object: $request_val",'','','Server'); return NULL; } @@ -347,7 +342,7 @@ // need to set special error detection inside the value class // so as to differentiate between no params passed, and an error decoding - $request_data = $this->decode($request_val); + $request_data = $this->_decode($request_val); $method_response = $this->callMethod($this->methodname, $request_data); @@ -405,19 +400,19 @@ strcasecmp($this->_typemap[SOAP_XML_SCHEMA_VERSION][$sig_t[$i]],$this->_typemap[SOAP_XML_SCHEMA_VERSION][$p[$i]])!=0)) { $param = $params[$i]; - $this->makeFault('Client',"soap request contained mismatching parameters of name $param->name had type [{$p[$i]}], which did not match signature's type: [{$sig_t[$i]}], matched? ".(strcasecmp($sig_t[$i],$p[$i]))); + $this->_raiseSoapFault("soap request contained mismatching parameters of name $param->name had type [{$p[$i]}], which did not match signature's type: [{$sig_t[$i]}], matched? ".(strcasecmp($sig_t[$i],$p[$i])),'','','Client'); return false; } } return true; // oops, wrong number of paramss } else { - $this->makeFault('Client',"soap request contained incorrect number of parameters. method '$this->methodname' required ".count($sig).' and request provided '.count($params)); + $this->_raiseSoapFault("soap request contained incorrect number of parameters. method '$this->methodname' required ".count($sig).' and request provided '.count($params),'','','Client'); return false; } // oops, no params... } else { - $this->makeFault('Client',"soap request contained incorrect number of parameters. method '$this->methodname' requires ".count($sig).' parameters, and request provided none'); + $this->_raiseSoapFault("soap request contained incorrect number of parameters. method '$this->methodname' requires ".count($sig).' parameters, and request provided none','','','Client'); return false; } // no params @@ -478,7 +473,7 @@ // XXX a bit of backwards compatibility $namespace = $obj->namespace; } else { - $this->makeFault('Server','No namespace provided for class!'); + $this->_raiseSoapFault('No namespace provided for class!','','','Server'); return FALSE; } } @@ -493,27 +488,13 @@ function addToMap($methodname, $in, $out, $namespace = NULL) { if (!function_exists($methodname)) { - $this->makeFault('Server',"error mapping function\n"); + $this->_raiseSoapFault("error mapping function\n",'','','Server'); return FALSE; } $this->dispatch_map[$methodname]['in'] = $in; $this->dispatch_map[$methodname]['out'] = $out; if ($namespace) $this->dispatch_map[$methodname]['namespace'] = $namespace; return TRUE; - } - - // set up a fault - function getFaultMessage() - { - if (!$this->soapfault) { - $this->makeFault('Server','fault message requested, but no fault has occured!'); - } - return $this->soapfault->message(); - } - - function makeFault($fault_code, $fault_string) - { - $this->soapfault = new SOAP_Fault($fault_string, $fault_code); } } Index: pear/SOAP/Transport.php diff -u pear/SOAP/Transport.php:1.16 pear/SOAP/Transport.php:1.17 --- pear/SOAP/Transport.php:1.16 Wed Apr 24 03:41:18 2002 +++ pear/SOAP/Transport.php Sat Sep 28 21:06:08 2002 @@ -17,7 +17,7 @@ // | Authors: Dietrich Ayala <dietrich@ganx4.com> Original Author | // +----------------------------------------------------------------------+ // -// $Id: Transport.php,v 1.16 2002/04/24 07:41:18 shane Exp $ +// $Id: Transport.php,v 1.17 2002/09/29 01:06:08 shane Exp $ // require_once 'SOAP/Base.php'; @@ -30,7 +30,7 @@ * no knowlege of the transport protocols is available at this level * * @access public -* @version $Id: Transport.php,v 1.16 2002/04/24 07:41:18 shane Exp $ +* @version $Id: Transport.php,v 1.17 2002/09/29 01:06:08 shane Exp $ * @package SOAP::Transport * @author Shane Caraveo <shane@php.net> */ @@ -69,7 +69,7 @@ $this->transport = new SOAP_Transport_SMTP($url, $encoding); return; } - $this->raiseSoapFault("No Transport for {$urlparts['scheme']}"); + $this->_raiseSoapFault("No Transport for {$urlparts['scheme']}"); } /** @@ -90,7 +90,7 @@ $response = $this->transport->send($soap_data, $options); if (PEAR::isError($response)) { - return $this->raiseSoapFault($response); + return $this->_raiseSoapFault($response); } $this->result_encoding = $this->transport->result_encoding; #echo "\n OUTGOING: ".$this->transport->outgoing_payload."\n\n"; Index: pear/SOAP/Value.php diff -u pear/SOAP/Value.php:1.31 pear/SOAP/Value.php:1.32 --- pear/SOAP/Value.php:1.31 Sat Aug 17 14:55:29 2002 +++ pear/SOAP/Value.php Sat Sep 28 21:06:08 2002 @@ -17,7 +17,7 @@ // | Authors: Dietrich Ayala <dietrich@ganx4.com> Original Author | // +----------------------------------------------------------------------+ // -// $Id: Value.php,v 1.31 2002/08/17 18:55:29 shane Exp $ +// $Id: Value.php,v 1.32 2002/09/29 01:06:08 shane Exp $ // require_once 'SOAP/Base.php'; @@ -28,7 +28,7 @@ * originaly based on SOAPx4 by Dietrich Ayala http://dietrich.ganx4.com/soapx4 * * @access public -* @version $Id: Value.php,v 1.31 2002/08/17 18:55:29 shane Exp $ +* @version $Id: Value.php,v 1.32 2002/09/29 01:06:08 shane Exp $ * @package SOAP::Client * @author Shane Caraveo <shane@php.net> Conversion to PEAR and updates * @author Dietrich Ayala <dietrich@ganx4.com> Original Author @@ -101,9 +101,9 @@ * * @return string xml representation */ - function serialize(&$serializer) + function &serialize(&$serializer) { - return $serializer->serializeValue($this->value, $this->name, $this->type, $this->namespace, $this->type_namespace, $this->options, $this->attributes); + return $serializer->_serializeValue($this->value, $this->name, $this->type, $this->namespace, $this->type_namespace, $this->options, $this->attributes, $this->arrayType); } } @@ -117,7 +117,7 @@ * originaly based on SOAPx4 by Dietrich Ayala http://dietrich.ganx4.com/soapx4 * * @access public - * @version $Id: Value.php,v 1.31 2002/08/17 18:55:29 shane Exp $ + * @version $Id: Value.php,v 1.32 2002/09/29 01:06:08 shane Exp $ * @package SOAP::Header * @author Shane Caraveo <shane@php.net> Conversion to PEAR and updates * @author Dietrich Ayala <dietrich@ganx4.com> Original Author Index: pear/SOAP/WSDL.php diff -u pear/SOAP/WSDL.php:1.26 pear/SOAP/WSDL.php:1.27 --- pear/SOAP/WSDL.php:1.26 Thu Aug 22 03:14:27 2002 +++ pear/SOAP/WSDL.php Sat Sep 28 21:06:08 2002 @@ -17,10 +17,11 @@ // | Authors: Dietrich Ayala <dietrich@ganx4.com> Original Author | // +----------------------------------------------------------------------+ // -// $Id: WSDL.php,v 1.26 2002/08/22 07:14:27 shane Exp $ +// $Id: WSDL.php,v 1.27 2002/09/29 01:06:08 shane Exp $ // require_once 'SOAP/Base.php'; require_once 'SOAP/Fault.php'; +require_once 'HTTP/Request.php'; DEFINE("WSDL_CACHE_MAX_AGE",12*60*60); DEFINE("WSDL_CACHE_USE",0); // set to zero to turn off caching @@ -38,7 +39,7 @@ * implement IDL type syntax declaration so we can generate WSDL * * @access public -* @version $Id: WSDL.php,v 1.26 2002/08/22 07:14:27 shane Exp $ +* @version $Id: WSDL.php,v 1.27 2002/09/29 01:06:08 shane Exp $ * @package SOAP::Client * @author Shane Caraveo <shane@php.net> Conversion to PEAR and updates * @author Dietrich Ayala <dietrich@ganx4.com> Original Author @@ -59,10 +60,19 @@ var $services = array(); var $service = ''; var $uri = ''; + var $proxy = NULL; - function SOAP_WSDL($uri = false) { + /** + * SOAP_WSDL constructor + * + * @param string endpoint_uri (URL) + * @param array contains options for HTTP_Request class (see HTTP/Request.php) + * @access public + */ + function SOAP_WSDL($uri = false, $proxy=array()) { parent::SOAP_Base('WSDL'); $this->uri = $uri; + $this->proxy = $proxy; $this->parse($uri); reset($this->services); $this->service = key($this->services); @@ -74,10 +84,10 @@ } } - function parse($uri) { + function parse($uri, $proxy=array()) { $parser = new SOAP_WSDL_Parser($uri, $this); if ($parser->fault) { - $this->raiseSoapFault($parser->fault); + $this->_raiseSoapFault($parser->fault); } } @@ -85,7 +95,7 @@ { return (isset($this->services[$this->service]['ports'][$portName]['address']['location'])) ? $this->services[$this->service]['ports'][$portName]['address']['location'] - : $this->raiseSoapFault("no endpoint for port for $portName", $this->uri); + : $this->_raiseSoapFault("no endpoint for port for $portName", $this->uri); } // find the name of the first port that contains an operation of name $operation @@ -101,7 +111,7 @@ } } } - return $this->raiseSoapFault("no operation $operation in wsdl", $this->uri); + return $this->_raiseSoapFault("no operation $operation in wsdl", $this->uri); } function getOperationData($portName,$operation) @@ -115,7 +125,7 @@ // get operation data from porttype $portType = $this->bindings[$binding]['type']; if (!$portType) { - return $this->raiseSoapFault("no port type for binding $binding in wsdl " . $this->uri); + return $this->_raiseSoapFault("no port type for binding $binding in wsdl " . $this->uri); } if (is_array($this->portTypes[$portType][$operation])) { if (isset($this->portTypes[$portType][$operation]['parameterOrder'])) @@ -123,6 +133,8 @@ $opData['input'] = array_merge($opData['input'], $this->portTypes[$portType][$operation]['input']); $opData['output'] = array_merge($opData['output'], $this->portTypes[$portType][$operation]['output']); } + if (!$opData) + return $this->_raiseSoapFault("no operation $operation for port $portName, in wsdl", $this->uri); // message data from messages $inputMsg = $opData['input']['message']; foreach ($this->messages[$inputMsg] as $pname => $pattrs) { @@ -130,10 +142,11 @@ && $pname == 'parameters') { $el = $this->elements[$pattrs['namespace']][$pattrs['type']]; - foreach ($el['elements'] as $elname => $elattrs) { - $opData['input']['parts'][$elname] = $elattrs; + if ($el['elements']) { + foreach ($el['elements'] as $elname => $elattrs) { + $opData['input']['parts'][$elname] = $elattrs; + } } - } else { $opData['input']['parts'][$pname] = $pattrs; } @@ -144,8 +157,10 @@ && $pname == 'parameters') { $el = $this->elements[$pattrs['namespace']][$pattrs['type']]; - foreach ($el['elements'] as $elname => $elattrs) { - $opData['output']['parts'][$elname] = $elattrs; + if ($el['elements']) { + foreach ($el['elements'] as $elname => $elattrs) { + $opData['output']['parts'][$elname] = $elattrs; + } } } else { @@ -154,7 +169,7 @@ } return $opData; } - return $this->raiseSoapFault("no binding for port $portName in wsdl", $this->uri); + return $this->_raiseSoapFault("no binding for port $portName in wsdl", $this->uri); } function matchMethod(&$operation) { @@ -179,7 +194,8 @@ function getNamespace($portName, $operation) { - if (isset($this->bindings[$this->services[$this->service]['ports'][$portName]['binding']]['operations'][$operation]['input']['namespace']) && + if (isset($this->bindings[$this->services[$this->service]['ports'][$portName]['binding']]) && + isset($this->bindings[$this->services[$this->service]['ports'][$portName]['binding']]['operations'][$operation]['input']['namespace']) && $namespace = $this->bindings[$this->services[$this->service]['ports'][$portName]['binding']]['operations'][$operation]['input']['namespace']) { return $namespace; } @@ -424,6 +440,42 @@ return new $classname; } + function &_getComplexTypeForElement($name, $namespace) + { + $t = NULL; + if (isset($this->ns[$namespace]) && + isset($this->elements[$this->ns[$namespace]][$name]['type'])) { + + $type = $this->elements[$this->ns[$namespace]][$name]['type']; + $ns = $this->elements[$this->ns[$namespace]][$name]['namespace']; + + if (isset($this->complexTypes[$ns][$type])) { + $t = $this->complexTypes[$ns][$type]; + } + } + return $t; + } + + function getComplexTypeNameForElement($name, $namespace) + { + $t = $this->_getComplexTypeForElement($name, $namespace); + if ($t) { + return $t['name']; + } + return NULL; + } + + function getComplexTypeChildType($ns, $name, $child_ns, $child_name) { + // is the type an element? + $t = $this->_getComplexTypeForElement($name, $ns); + if ($t) { + // no, get it from complex types directly + if (isset($t['elements'][$child_name]['type'])) + return $t['elements'][$child_name]['type']; + } + return NULL; + } + function getSchemaType($type, $name, $type_namespace) { # see if it's a complex type so we can deal properly with SOAPENC:arrayType @@ -507,7 +559,7 @@ * retreives file from cache if it exists, otherwise retreive from net, * add to cache, and return from cache */ - function get($wsdl_fname, $cache=0) { + function get($wsdl_fname, $proxy_params=array(), $cache=0) { $cachename = SOAP_WSDL_Cache::_cacheDir() . "/" . md5($wsdl_fname); $cacheinfo = $cachename.".info"; $cachename .= ".wsdl"; @@ -522,7 +574,7 @@ } if ($cache) { if ($cache != $md5_wsdl) { - return $this->raiseSoapFault("WSDL Checksum error!", $wsdl_fname); + return $this->_raiseSoapFault("WSDL Checksum error!", $wsdl_fname); } } else { $fi = stat($cachename); @@ -535,11 +587,20 @@ } } if (!$md5_wsdl) { - $fd = @file($wsdl_fname); // time consumer - if (!$fd) { - return $this->raiseSoapFault("Unable to retrieve WSDL", $wsdl_fname); + $uri = explode('?',$wsdl_fname); + $rq = new HTTP_Request($uri[0], $proxy_params); + // the user agent HTTP_Request uses fouls things up + if (isset($uri[1])) { + $rq->addRawQueryString($uri[1]); + } + $result = $rq->sendRequest(); + if (PEAR::isError($result)) { + return $this->_raiseSoapFault("Unable to retrieve WSDL $wsdl_fname, ".$rq->getResponseCode(), $wsdl_fname); + } + $file_data = $rq->getResponseBody(); + if (!$file_data) { + return $this->_raiseSoapFault("Unable to retrieve WSDL $wsdl_fname, no http body", $wsdl_fname); } - $file_data = join('',$fd); $md5_wsdl = md5($file_data); @@ -550,7 +611,7 @@ } } if (WSDL_CACHE_USE && $cache && $cache != $md5_wsdl) { - return $this->raiseSoapFault("WSDL Checksum error!", $wsdl_fname); + return $this->_raiseSoapFault("WSDL Checksum error!", $wsdl_fname); } return $file_data; } @@ -597,9 +658,9 @@ function parse($uri) { // Check whether content has been read. - $fd = $this->cache->get($uri); + $fd = $this->cache->get($uri, $this->wsdl->proxy); if (PEAR::isError($fd)) { - return $this->raiseSoapFault($fd); + return $this->_raiseSoapFault($fd); } // Create an XML parser. @@ -613,7 +674,8 @@ $detail = sprintf('XML error on line %d: %s', xml_get_current_line_number($parser), xml_error_string(xml_get_error_code($parser))); - return $this->raiseSoapFault("Unable to parse WSDL file $uri", $detail); + print $fd; + return $this->_raiseSoapFault("Unable to parse WSDL file $uri\n$detail"); } xml_parser_free($parser); return TRUE; @@ -1033,9 +1095,10 @@ $base = parse_url($this->uri); $uri = $this->merge_url($base,$uri); } - $result = $this->parse($uri, $this->wsdl); - if (PEAR::isError($result)) { - return $result; + $import_parser = new SOAP_WSDL_Parser($uri, $this->wsdl); + #$result = $this->parse($uri, $this->wsdl); + if ($import_parser->fault) { + return FALSE; } $this->currentImport = $attrs['namespace']; $this->wsdl->imports[$this->currentImport] = $attrs; @@ -1101,7 +1164,7 @@ if (isset($ns) && $ns) { $namespace = 'xmlns:'.$ns; if (!$this->wsdl->definition[$namespace]) { - return $this->raiseSoapFault("parse error, no namespace for $namespace",$this->uri); + return $this->_raiseSoapFault("parse error, no namespace for $namespace",$this->uri); } $this->tns = $ns; } Index: pear/SOAP/package.xml diff -u pear/SOAP/package.xml:1.15 pear/SOAP/package.xml:1.16 --- pear/SOAP/package.xml:1.15 Sun Jul 7 17:49:14 2002 +++ pear/SOAP/package.xml Sat Sep 28 21:06:08 2002 @@ -19,10 +19,17 @@ <license>PHP License</license> <release> <state>beta</state> - <version>0.6.2</version> + <version>0.6.3</version> <date>2002-07-06</date> <notes> - This is the initial independent PEAR release. + Includes minor API changes from 0.6.2. + Supports HTTP Proxy (SOAP_Client constructor + takes 4th param of type array, SOAP_WSDL + constructor takes 2nd param of type array, see HTTP_Request + docs for proxy parameters). + Improved WSDL proxy generation. + Interop tests are moved to SOAP_Interop module, available + via CVS only. </notes> <filelist> <dir name="/" baseinstalldir="SOAP"> @@ -58,24 +65,6 @@ <file role="php" name="duration.php"/> <file role="php" name="hexBinary.php"/> </dir> - <dir name="interop" role="test"> - <file role="test" name="index.php"/> - <file role="test" name="client_round2.php"/> - <file role="test" name="client_round2_run.php"/> - <file role="test" name="client_round2_interop.php"/> - <file role="test" name="client_round2_params.php"/> - <file role="test" name="client_round2_results.php"/> - <file role="test" name="database_round2.sql"/> - <file role="test" name="echoheadersvc.wsdl"/> - <file role="test" name="interop.wsdl"/> - <file role="test" name="interopB.wsdl"/> - <file role="test" name="readme.txt"/> - <file role="test" name="server_round2.php"/> - <file role="test" name="server_round2_base.php"/> - <file role="test" name="server_round2_groupB.php"/> - <file role="test" name="server_round2_groupC.php"/> - <file role="test" name="server_round2_test.php"/> - </dir> <dir name="test" role="test"> <file role="test" name="5.2.simpletypes.php"/> <file role="test" name="5.2.1.simpletypes.string.php"/> @@ -92,7 +81,19 @@ <dep type="ext" rel="has">bcmath</dep> <dep type="ext" rel="has">pcre</dep> <dep type="pkg" rel="has">Mail_Mime</dep> + <dep type="pkg" rel="has">HTTP_Request</dep> + <dep type="pkg" rel="ge" version="1.0.5">Net_URL</dep> <dep type="pkg" rel="ge" version="0.1">Net_DIME</dep> </deps> </release> + <changelog> + <release> + <state>beta</state> + <version>0.6.2</version> + <date>2002-07-06</date> + <notes> + This is the initial independent PEAR release. + </notes> + </release> + </changelog> </package> Index: pear/SOAP/Server/Email.php diff -u pear/SOAP/Server/Email.php:1.5 pear/SOAP/Server/Email.php:1.6 --- pear/SOAP/Server/Email.php:1.5 Tue May 14 19:02:49 2002 +++ pear/SOAP/Server/Email.php Sat Sep 28 21:06:08 2002 @@ -16,7 +16,7 @@ // | Authors: Shane Caraveo <Shane@Caraveo.com> Port to PEAR and more | // +----------------------------------------------------------------------+ // -// $Id: Email.php,v 1.5 2002/05/14 23:02:49 shane Exp $ +// $Id: Email.php,v 1.6 2002/09/29 01:06:08 shane Exp $ // require_once 'SOAP/Server.php'; @@ -37,7 +37,7 @@ * function call * * @access public -* @version $Id: Email.php,v 1.5 2002/05/14 23:02:49 shane Exp $ +* @version $Id: Email.php,v 1.6 2002/09/29 01:06:08 shane Exp $ * @package SOAP::Server * @author Shane Caraveo <shane@php.net> */ @@ -70,7 +70,7 @@ } if (!stristr($this->headers['content-type'],'text/xml')) { - $this->makeFault('Client','Invalid Content Type'); + $this->_raiseSoapFault('Invalid Content Type','','','Client'); return FALSE; } @@ -81,7 +81,7 @@ #} else if (strcasecmp($this->headers['content-transfer-encoding'],'quoted-printable')==0) { # $data = $match[2]; #} else { - # $this->makeFault('Client','Invalid Content-Transfer-Encoding'); + # $this->_raiseSoapFault('Invalid Content-Transfer-Encoding','','','Client'); # return FALSE; #} } else { @@ -91,7 +91,7 @@ // if no content, return false return strlen($this->request) > 0; } - $this->makeFault('Client','Invalid Email Format'); + $this->_raiseSoapFault('Invalid Email Format','','','Client'); return FALSE; } @@ -101,12 +101,12 @@ # if neither matches, we'll just try it anyway if (stristr($data,'Content-Type: application/dime')) { - $this->decodeDIMEMessage($data,$this->headers,$attachments); + $this->_decodeDIMEMessage($data,$this->headers,$attachments); $useEncoding = 'DIME'; } else if (stristr($data,'MIME-Version:')) { // this is a mime message, lets decode it. #$data = 'Content-Type: '.stripslashes($_SERVER['CONTENT_TYPE'])."\r\n\r\n".$data; - $this->decodeMimeMessage($data,$this->headers,$attachments); + $this->_decodeMimeMessage($data,$this->headers,$attachments); $useEncoding = 'Mime'; } else { // the old fallback, but decodeMimeMessage handles things fine. @@ -118,7 +118,7 @@ if (!$this->soapfault && !$this->_getContentEncoding($this->headers['content-type'])) { $this->xml_encoding = SOAP_DEFAULT_ENCODING; // an encoding we don't understand, return a fault - $this->makeFault('Server','Unsupported encoding, use one of ISO-8859-1, US-ASCII, UTF-8'); + $this->_raiseSoapFault('Unsupported encoding, use one of ISO-8859-1, US-ASCII, UTF-8','','','Server'); } if ($this->soapfault) { @@ -153,7 +153,7 @@ if (!$response && !$this->_getContentEncoding($this->headers['content-type'])) { $this->xml_encoding = SOAP_DEFAULT_ENCODING; // an encoding we don't understand, return a fault - $this->makeFault('Server','Unsupported encoding, use one of ISO-8859-1, US-ASCII, UTF-8'); + $this->_raiseSoapFault('Unsupported encoding, use one of ISO-8859-1, US-ASCII, UTF-8','','','Server'); $response = $this->getFaultMessage(); } @@ -165,7 +165,7 @@ // handle Mime or DIME encoding // XXX DIME Encoding should move to the transport, do it here for now // and for ease of getting it done - if (count($this->attachments)) { + if (count($this->__attachments)) { if ($useEncoding == 'Mime') { $soap_msg = $this->_makeMimeMessage($soap_msg); } else { Index: pear/SOAP/Server/Email_Gateway.php diff -u pear/SOAP/Server/Email_Gateway.php:1.5 pear/SOAP/Server/Email_Gateway.php:1.6 --- pear/SOAP/Server/Email_Gateway.php:1.5 Tue May 14 19:02:49 2002 +++ pear/SOAP/Server/Email_Gateway.php Sat Sep 28 21:06:09 2002 @@ -16,7 +16,7 @@ // | Authors: Shane Caraveo <Shane@Caraveo.com> Port to PEAR and more | // +----------------------------------------------------------------------+ // -// $Id: Email_Gateway.php,v 1.5 2002/05/14 23:02:49 shane Exp $ +// $Id: Email_Gateway.php,v 1.6 2002/09/29 01:06:09 shane Exp $ // require_once 'SOAP/Server/Email.php'; @@ -40,7 +40,7 @@ * email * * @access public -* @version $Id: Email_Gateway.php,v 1.5 2002/05/14 23:02:49 shane Exp $ +* @version $Id: Email_Gateway.php,v 1.6 2002/09/29 01:06:09 shane Exp $ * @package SOAP::Server * @author Shane Caraveo <shane@php.net> */ @@ -67,8 +67,8 @@ // we have a full set of headers, need to find the first blank line $this->_parseEmail($data); - if ($this->soapfault) { - $response = $this->getFaultMessage(); + if ($this->fault) { + $response = $this->fault->message(); } if ($this->headers['content-type']=='application/dime') $useEncoding='DIME'; @@ -96,7 +96,7 @@ foreach ($soap_transport->transport->attachments as $cid=>$body) { $this->attachments[] = array('body' => $body, 'cid' => $cid, 'encoding' => 'base64'); } - if (count($this->attachments)) { + if (count($this->__attachments)) { if ($useEncoding == 'Mime') { $soap_msg = $this->_makeMimeMessage($response); $options['headers']['MIME-Version'] = '1.0'; @@ -106,7 +106,7 @@ $options['headers']['Content-Type'] = 'application/dime'; } if (PEAR::isError($soap_msg)) { - return $this->raiseSoapFault($soap_msg); + return $this->_raiseSoapFault($soap_msg); } if (is_array($soap_msg)) { $response = $soap_msg['body']; Index: pear/SOAP/Transport/HTTP.php diff -u pear/SOAP/Transport/HTTP.php:1.18 pear/SOAP/Transport/HTTP.php:1.19 --- pear/SOAP/Transport/HTTP.php:1.18 Mon May 13 02:56:03 2002 +++ pear/SOAP/Transport/HTTP.php Sat Sep 28 21:06:09 2002 @@ -16,7 +16,7 @@ // | Authors: Shane Caraveo <Shane@Caraveo.com> | // +----------------------------------------------------------------------+ // -// $Id: HTTP.php,v 1.18 2002/05/13 06:56:03 shane Exp $ +// $Id: HTTP.php,v 1.19 2002/09/29 01:06:09 shane Exp $ // require_once 'SOAP/Base.php'; @@ -25,7 +25,7 @@ * HTTP Transport for SOAP * * @access public -* @version $Id: HTTP.php,v 1.18 2002/05/13 06:56:03 shane Exp $ +* @version $Id: HTTP.php,v 1.19 2002/09/29 01:06:09 shane Exp $ * @package SOAP::Transport::HTTP * @author Shane Caraveo <shane@php.net> */ @@ -124,7 +124,7 @@ return $this->_sendHTTPS($msg, $options); } - return $this->raiseSoapFault('Invalid url scheme '.$this->url); + return $this->_raiseSoapFault('Invalid url scheme '.$this->url); } /** @@ -153,11 +153,11 @@ function _validateUrl() { if ( ! is_array($this->urlparts) ) { - $this->raiseSoapFault("Unable to parse URL $url"); + $this->_raiseSoapFault("Unable to parse URL $url"); return FALSE; } if (!isset($this->urlparts['host'])) { - $this->raiseSoapFault("No host in URL $url"); + $this->_raiseSoapFault("No host in URL $url"); return FALSE; } if (!isset($this->urlparts['port'])) { @@ -171,7 +171,8 @@ if (isset($this->urlparts['user'])) { $this->setCredentials($this->urlparts['user'], $this->urlparts['pass']); } - + if (!isset($this->urlparts['path']) || !$this->urlparts['path']) + $this->urlparts['path'] = '/'; return TRUE; } @@ -208,25 +209,25 @@ // find the response error, some servers response with 500 for soap faults if (preg_match("/^HTTP\/1\.. (\d+).*/s",$match[1],$status) && $status[1] >= 400 && $status[1] < 500) { - $this->raiseSoapFault("HTTP Response $status[1] Not Found"); + $this->_raiseSoapFault("HTTP Response $status[1] Not Found"); return FALSE; } $this->_parseEncoding($match[1]); if ($this->result_content_type == 'application/dime') { // XXX quick hack insertion of DIME - $this->decodeDIMEMessage($this->response,$this->headers,$this->attachments); + $this->_decodeDIMEMessage($this->response,$this->headers,$this->attachments); $this->result_content_type = $this->headers['content-type']; } else if (stristr($this->result_content_type,'multipart/related')) { $this->response = $this->incoming_payload; - $this->decodeMimeMessage($this->response,$this->headers,$this->attachments); + $this->_decodeMimeMessage($this->response,$this->headers,$this->attachments); } else if ($this->result_content_type != 'text/xml') { - $this->raiseSoapFault($this->response); + $this->_raiseSoapFault($this->response); return FALSE; } // if no content, return false return strlen($this->response) > 0; } - $this->raiseSoapFault('Invalid HTTP Response'); + $this->_raiseSoapFault('Invalid HTTP Response'); return FALSE; } @@ -242,6 +243,12 @@ $fullpath = $this->urlparts['path']. (isset($this->urlparts['query'])?'?'.$this->urlparts['query']:''). (isset($this->urlparts['fragment'])?'#'.$this->urlparts['fragment']:''); + if (isset($options['proxy_host'])) { + $fullpath = ($https?'https://':'http://').$this->urlparts['host'].':'.$this->urlparts['port'].$fullpath; + } + if (isset($options['proxy_user'])) { + $this->headers['Proxy-Authorization'] = 'Basic ' . base64_encode($options['proxy_user'].":".$options['proxy_pass']); + } $this->headers['User-Agent'] = $this->_userAgent; $this->headers['Host'] = $this->urlparts['host']; $this->headers['Content-Type'] = "text/xml; charset=$this->encoding"; @@ -273,18 +280,23 @@ function &_sendHTTP(&$msg, $options) { $this->_getRequest($msg, $options); - + $host = $this->urlparts['host']; + $port = $this->urlparts['port']; + if (isset($options['proxy_host'])) { + $host = $options['proxy_host']; + $port = isset($options['proxy_port'])?$options['proxy_port']:8080; + } // send if ($this->timeout > 0) { - $fp = fsockopen($this->urlparts['host'], $this->urlparts['port'], $this->errno, $this->errmsg, $this->timeout); + $fp = fsockopen($host, $port, $this->errno, $this->errmsg, $this->timeout); } else { - $fp = fsockopen($this->urlparts['host'], $this->urlparts['port'], $this->errno, $this->errmsg); + $fp = fsockopen($host, $port, $this->errno, $this->errmsg); } if (!$fp) { - return $this->raiseSoapFault("Connect Error to {$this->urlparts['host']}:{$this->urlparts['port']}"); + return $this->raiseSoapFault("Connect Error to $host:$port"); } if (!fputs($fp, $this->outgoing_payload, strlen($this->outgoing_payload))) { - return $this->raiseSoapFault("Error POSTing Data to {$this->urlparts['host']}"); + return $this->raiseSoapFault("Error POSTing Data to $host"); } // get reponse @@ -316,12 +328,25 @@ * Your php must be compiled with CURL */ if (!extension_loaded('curl')) { - return $this->raiseSoapFault('CURL Extension is required for HTTPS'); + return $this->_raiseSoapFault('CURL Extension is required for HTTPS'); } $this->_getRequest($msg, $options); $ch = curl_init(); + + // XXX don't know if this proxy stuff is right for CURL + if (isset($options['proxy_host'])) { + // $options['http_proxy'] == 'hostname:port' + $host = $options['proxy_host']; + $port = isset($options['proxy_port'])?$options['proxy_port']:8080; + curl_setopt($ch, CURLOPT_PROXY, $host.":".$port); + } + if (isset($options['proxy_user'])) { + // $options['http_proxy_userpw'] == 'username:password' + curl_setopt($ch, CURLOPT_PROXYUSERPWD, $options['proxy_user'].':'.$options['proxy_pass']); + } + if ($this->timeout) { curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout); //times out after 4s } Index: pear/SOAP/Transport/SMTP.php diff -u pear/SOAP/Transport/SMTP.php:1.13 pear/SOAP/Transport/SMTP.php:1.14 --- pear/SOAP/Transport/SMTP.php:1.13 Tue May 14 19:02:49 2002 +++ pear/SOAP/Transport/SMTP.php Sat Sep 28 21:06:09 2002 @@ -16,7 +16,7 @@ // | Authors: Shane Caraveo <Shane@Caraveo.com> | // +----------------------------------------------------------------------+ // -// $Id: SMTP.php,v 1.13 2002/05/14 23:02:49 shane Exp $ +// $Id: SMTP.php,v 1.14 2002/09/29 01:06:09 shane Exp $ // // Status: rough draft, untested // @@ -39,7 +39,7 @@ * TODO: use PEAR smtp and Mime classes * * @access public -* @version $Id: SMTP.php,v 1.13 2002/05/14 23:02:49 shane Exp $ +* @version $Id: SMTP.php,v 1.14 2002/09/29 01:06:09 shane Exp $ * @package SOAP::Transport::SMTP * @author Shane Caraveo <shane@php.net> */ @@ -87,7 +87,7 @@ return $this->fault; } if (!$options || !array_key_exists('from',$options)) { - return $this->raiseSoapFault("No FROM address to send message with"); + return $this->_raiseSoapFault("No FROM address to send message with"); } if (isset($options['host'])) $this->host = $options['host']; @@ -125,7 +125,7 @@ $headers['Content-Transfer-Encoding'] = 'base64'; $out = chunk_split(base64_encode($msg),76,"\n"); } else { - return $this->raiseSoapFault("Invalid Transfer Encoding: {$options['transfer-encoding']}"); + return $this->_raiseSoapFault("Invalid Transfer Encoding: {$options['transfer-encoding']}"); } } else { // default to base64 @@ -198,16 +198,16 @@ function _validateUrl() { if ( ! is_array($this->urlparts) ) { - $this->raiseSoapFault("Unable to parse URL $url"); + $this->_raiseSoapFault("Unable to parse URL $url"); return FALSE; } if (!isset($this->urlparts['scheme']) || strcasecmp($this->urlparts['scheme'], 'mailto') != 0) { - $this->raiseSoapFault("Unable to parse URL $url"); + $this->_raiseSoapFault("Unable to parse URL $url"); return FALSE; } if (!isset($this->urlparts['path'])) { - $this->raiseSoapFault("Unable to parse URL $url"); + $this->_raiseSoapFault("Unable to parse URL $url"); return FALSE; } return TRUE; Index: pear/SOAP/example/client.php diff -u pear/SOAP/example/client.php:1.2 pear/SOAP/example/client.php:1.3 --- pear/SOAP/example/client.php:1.2 Sun Jul 7 17:49:14 2002 +++ pear/SOAP/example/client.php Sat Sep 28 21:06:09 2002 @@ -16,7 +16,7 @@ // | Authors: Shane Caraveo <Shane@Caraveo.com> | // +----------------------------------------------------------------------+ // -// $Id: client.php,v 1.2 2002/07/07 21:49:14 shane Exp $ +// $Id: client.php,v 1.3 2002/09/29 01:06:09 shane Exp $ // include("SOAP/Client.php"); /** @@ -24,12 +24,14 @@ */ $soapclient = new SOAP_Client("http://localhost/SOAP/example/server.php"); // this namespace is the same as declared in server.php -$namespace = 'urn:SOAP_Example_Server'; +$options = array('namespace' => 'urn:SOAP_Example_Server', + 'trace' => 1); -$ret = $soapclient->call("echoStringSimple",array("inputString"=>"this is a test string"),$namespace); +$ret = $soapclient->call("echoStringSimple",array("inputString"=>"this is a test string"),$options); +print $soapclient->__get_wire(); print_r($ret);echo "<br>\n"; -$ret = $soapclient->call("echoString",array("inputString"=>"this is a test string"),$namespace); +$ret = $soapclient->call("echoString",array("inputString"=>"this is a test string"),$options); print_r($ret);echo "<br>\n"; class SOAPStruct { @@ -41,7 +43,7 @@ $SOAPStruct = new SOAPStruct; /* send an object, get an object back */ -$ret = $soapclient->call("echoStruct",array(new SOAP_Value('inputStruct','',$SOAPStruct)),$namespace); +$ret = $soapclient->call("echoStruct",array(new SOAP_Value('inputStruct','',$SOAPStruct)),$options); print_r($ret); /** @@ -49,7 +51,7 @@ * must do a little work to make it happen here. This requires knowledge on the * developers part to figure out how they want to deal with it. */ -list($string, $int, $float) = array_values($soapclient->call("echoStructAsSimpleTypes",$SOAPStruct,$namespace)); +list($string, $int, $float) = array_values($soapclient->call("echoStructAsSimpleTypes",$SOAPStruct,$options)); echo "varString: $string<br>\nvarInt: $int<br>\nvarFloat: $float<br>\n"; ?> Index: pear/SOAP/interop/client_round2_run.php diff -u pear/SOAP/interop/client_round2_run.php:1.6 pear/SOAP/interop/client_round2_run.php:1.7 --- pear/SOAP/interop/client_round2_run.php:1.6 Sat Jul 6 17:58:24 2002 +++ pear/SOAP/interop/client_round2_run.php Sat Sep 28 21:06:10 2002 @@ -17,11 +17,12 @@ // | Authors: Shane Caraveo <Shane@Caraveo.com> | // +----------------------------------------------------------------------+ // -// $Id: client_round2_run.php,v 1.6 2002/07/06 21:58:24 shane Exp $ +// $Id: client_round2_run.php,v 1.7 2002/09/29 01:06:10 shane Exp $ // set_time_limit(0); require_once 'SOAP/interop/client_round2_interop.php'; $SOAP_RAW_CONVERT = TRUE; +$SOAP_OBJECT_STRUCT = false; $iop = new Interop_Client(); // force a fetch of endpoints, this happens irregardless if no endpoints in database @@ -29,21 +30,21 @@ // set some options $iop->currentTest = 'base'; // see $tests above -$iop->paramType = 'php'; // 'php' or 'soapval' +$iop->paramType = 'soapval'; // 'php' or 'soapval' $iop->useWSDL = 0; // 1= do wsdl tests $iop->numServers = 0; // 0 = all -$iop->specificEndpoint = ''; // test only this endpoint -$iop->testMethod = ''; // test only this method +$iop->specificEndpoint = 'MS SOAP ToolKit 2.0'; // test only this endpoint +$iop->testMethod = 'echoString'; // test only this method $iop->skipEndpointList = array(); // endpoints to skip $this->nosave = 0; // 1= disable saving results to database // debug output $iop->show = 1; -$iop->debug = 0; +$iop->debug = 1; $iop->showFaults = 0; // used in result table output -#$iop->doTest(); // run a single set of tests using above options +$iop->doTest(); // run a single set of tests using above options #$iop->doGroupTests(); // run a group of tests set in $currentTest -$iop->doTests(); // run all tests, ignore above options +#$iop->doTests(); // run all tests, ignore above options #$iop->outputTables(); echo "done"; Index: pear/SOAP/test/5.2.1.simpletypes.string.php diff -u pear/SOAP/test/5.2.1.simpletypes.string.php:1.2 pear/SOAP/test/5.2.1.simpletypes.string.php:1.3 --- pear/SOAP/test/5.2.1.simpletypes.string.php:1.2 Mon May 13 02:47:10 2002 +++ pear/SOAP/test/5.2.1.simpletypes.string.php Sat Sep 28 21:06:10 2002 @@ -34,7 +34,7 @@ } # serialize a soap value with unknown type $expect = "hello world"; -$val = $soap_base->decode($v); +$val = $soap_base->_decode($v); if (string_compare($expect, $val)) { print "$prefix Deserialize known SOAP_Value OK\n"; } else { @@ -53,7 +53,7 @@ # serialize a soap value with unknown type $expect = "hello world"; -$val = $soap_base->decode($v); +$val = $soap_base->_decode($v); if (string_compare($expect, $val)) { print "$prefix Deserialize Unknown SOAP_Value OK\n"; } else { Index: pear/SOAP/test/5.2.simpletypes.php diff -u pear/SOAP/test/5.2.simpletypes.php:1.6 pear/SOAP/test/5.2.simpletypes.php:1.7 --- pear/SOAP/test/5.2.simpletypes.php:1.6 Mon May 13 02:47:10 2002 +++ pear/SOAP/test/5.2.simpletypes.php Sat Sep 28 21:06:10 2002 @@ -68,7 +68,7 @@ # deserialize a soap value $expect = array('age'=>45, 'height'=> 5.9, 'displacement' => -450, 'color' => 'Blue'); -$val = $soap_base->decode($v); +$val = $soap_base->_decode($v); if (string_compare($expect, $val)) { print "$prefix Deserialize known SOAP_Value OK\n"; } else { @@ -93,7 +93,7 @@ # serialize a soap value with unknown type $expect = array('age'=>45, 'height'=> 5.9, 'displacement' => -450, 'color' => 'Blue'); -$val = $soap_base->decode($v); +$val = $soap_base->_decode($v); if (array_compare($expect, $val)) { print "$prefix Deserialize Unknown SOAP_Value OK\n"; } else { Index: pear/SOAP/test/test.utility.php diff -u pear/SOAP/test/test.utility.php:1.5 pear/SOAP/test/test.utility.php:1.6 --- pear/SOAP/test/test.utility.php:1.5 Mon May 13 02:47:10 2002 +++ pear/SOAP/test/test.utility.php Sat Sep 28 21:06:10 2002 @@ -70,7 +70,7 @@ return $response->fault->getFault(); } $return = $response->getResponse(); - $v = $response->decode($return); + $v = $response->_decode($return); if (gettype($v) == 'array' && count($v)==1) { return array_shift($v); } Index: pear/SOAP/tools/genproxy.php diff -u pear/SOAP/tools/genproxy.php:1.3 pear/SOAP/tools/genproxy.php:1.4 --- pear/SOAP/tools/genproxy.php:1.3 Thu Aug 22 03:14:29 2002 +++ pear/SOAP/tools/genproxy.php Sat Sep 28 21:06:11 2002 @@ -12,7 +12,7 @@ function do_wsdl($uri) { $wsdl = new SOAP_WSDL($uri); - print $wsdl->generateAllProxies(); + #print $wsdl->generateAllProxies(); } echo "<?php\n\nrequire_once 'SOAP/Client.php';\n\n"; do_wsdl($_SERVER['argv'][1]);