diff options
| author | Andreas Brachold <vdr07@deltab.de> | 2008-01-26 17:53:19 +0000 |
|---|---|---|
| committer | Andreas Brachold <vdr07@deltab.de> | 2008-01-26 17:53:19 +0000 |
| commit | 49baade6e8a2f26a88a2f2c6a5faac33293b1111 (patch) | |
| tree | 4d34e7201029bf587791e3830dbba28227db9562 /contrib | |
| parent | fb02e00134f2168cff914aad91308bc59b150dd2 (diff) | |
| download | xxv-49baade6e8a2f26a88a2f2c6a5faac33293b1111.tar.gz xxv-49baade6e8a2f26a88a2f2c6a5faac33293b1111.tar.bz2 | |
* Update to nusoap 0.7.3
* Enhance memory limit to 16M
Diffstat (limited to 'contrib')
| -rw-r--r-- | contrib/popularity/popularity/nusoap.php | 1684 | ||||
| -rw-r--r-- | contrib/popularity/t10.php | 449 |
2 files changed, 1442 insertions, 691 deletions
diff --git a/contrib/popularity/popularity/nusoap.php b/contrib/popularity/popularity/nusoap.php index 60d870d..1f1dde6 100644 --- a/contrib/popularity/popularity/nusoap.php +++ b/contrib/popularity/popularity/nusoap.php @@ -1,7 +1,7 @@ <?php
/*
-$Id: nusoap.php,v 1.94 2005/08/04 01:27:42 snichol Exp $
+$Id: nusoap.php,v 1.114 2007/11/06 15:17:46 snichol Exp $
NuSOAP - Web Services Toolkit for PHP
@@ -21,6 +21,12 @@ You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+The NuSOAP project home is:
+http://sourceforge.net/projects/nusoap/
+
+The primary support for NuSOAP is the mailing list:
+nusoap-general@lists.sourceforge.net
+
If you have any questions or comments, please email:
Dietrich Ayala
@@ -32,6 +38,20 @@ http://www.nusphere.com */
+/*
+ * Some of the standards implmented in whole or part by NuSOAP:
+ *
+ * SOAP 1.1 (http://www.w3.org/TR/2000/NOTE-SOAP-20000508/)
+ * WSDL 1.1 (http://www.w3.org/TR/2001/NOTE-wsdl-20010315)
+ * SOAP Messages With Attachments (http://www.w3.org/TR/SOAP-attachments)
+ * XML 1.0 (http://www.w3.org/TR/2006/REC-xml-20060816/)
+ * Namespaces in XML 1.0 (http://www.w3.org/TR/2006/REC-xml-names-20060816/)
+ * XML Schema 1.0 (http://www.w3.org/TR/xmlschema-0/)
+ * RFC 2045 Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies
+ * RFC 2068 Hypertext Transfer Protocol -- HTTP/1.1
+ * RFC 2617 HTTP Authentication: Basic and Digest Access Authentication
+ */
+
/* load classes
// necessary classes
@@ -59,7 +79,8 @@ $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel = 9; * nusoap_base
*
* @author Dietrich Ayala <dietrich@ganx4.com>
-* @version $Id: nusoap.php,v 1.94 2005/08/04 01:27:42 snichol Exp $
+* @author Scott Nichol <snichol@users.sourceforge.net>
+* @version $Id: nusoap.php,v 1.114 2007/11/06 15:17:46 snichol Exp $
* @access public
*/
class nusoap_base {
@@ -69,21 +90,21 @@ class nusoap_base { * @var string
* @access private
*/
- var $title = 'xxvSOAP';
+ var $title = 'NuSOAP';
/**
* Version for HTTP headers.
*
* @var string
* @access private
*/
- var $version = '0.7.2';
+ var $version = '0.7.3';
/**
* CVS revision for HTTP headers.
*
* @var string
* @access private
*/
- var $revision = '$Revision: 1.94 $';
+ var $revision = '$Revision: 1.114 $';
/**
* Current error string (manipulated by getError/setError)
*
@@ -157,7 +178,7 @@ class nusoap_base { /**
* XML Schema types in an array of uri => (array of xml type => php type)
* is this legacy yet?
- * no, this is used by the xmlschema class to verify type => namespace mappings.
+ * no, this is used by the nusoap_xmlschema class to verify type => namespace mappings.
* @var array
* @access public
*/
@@ -308,7 +329,8 @@ class nusoap_base { while (strpos($this->debug_str, '--')) {
$this->debug_str = str_replace('--', '- -', $this->debug_str);
}
- return "<!--\n" . $this->debug_str . "\n-->";
+ $ret = "<!--\n" . $this->debug_str . "\n-->";
+ return $ret;
}
/**
@@ -379,16 +401,22 @@ class nusoap_base { * @param string $type_ns The namespace for the type of the element
* @param array $attributes The attributes to serialize as name=>value pairs
* @param string $use The WSDL "use" (encoded|literal)
+ * @param boolean $soapval Whether this is called from soapval.
* @return string The serialized element, possibly with child elements
* @access public
*/
- function serialize_val($val,$name=false,$type=false,$name_ns=false,$type_ns=false,$attributes=false,$use='encoded'){
- $this->debug("in serialize_val: name=$name, type=$type, name_ns=$name_ns, type_ns=$type_ns, use=$use");
+ function serialize_val($val,$name=false,$type=false,$name_ns=false,$type_ns=false,$attributes=false,$use='encoded',$soapval=false) {
+ $this->debug("in serialize_val: name=$name, type=$type, name_ns=$name_ns, type_ns=$type_ns, use=$use, soapval=$soapval");
$this->appendDebug('value=' . $this->varDump($val));
$this->appendDebug('attributes=' . $this->varDump($attributes));
- if(is_object($val) && get_class($val) == 'soapval'){
- return $val->serialize($use);
+ if (is_object($val) && get_class($val) == 'soapval' && (! $soapval)) {
+ $this->debug("serialize_val: serialize soapval");
+ $xml = $val->serialize($use);
+ $this->appendDebug($val->getDebug());
+ $val->clearDebug();
+ $this->debug("serialize_val of soapval returning $xml");
+ return $xml;
}
// force valid name if necessary
if (is_numeric($name)) {
@@ -421,20 +449,26 @@ class nusoap_base { }
// serialize null value
if (is_null($val)) {
+ $this->debug("serialize_val: serialize null");
if ($use == 'literal') {
// TODO: depends on minOccurs
- return "<$name$xmlns $atts/>";
+ $xml = "<$name$xmlns$atts/>";
+ $this->debug("serialize_val returning $xml");
+ return $xml;
} else {
if (isset($type) && isset($type_prefix)) {
$type_str = " xsi:type=\"$type_prefix:$type\"";
} else {
$type_str = '';
}
- return "<$name$xmlns$type_str $atts xsi:nil=\"true\"/>";
+ $xml = "<$name$xmlns$type_str$atts xsi:nil=\"true\"/>";
+ $this->debug("serialize_val returning $xml");
+ return $xml;
}
}
// serialize if an xsd built-in primitive type
if($type != '' && isset($this->typemap[$this->XMLSchemaVersion][$type])){
+ $this->debug("serialize_val: serialize xsd built-in primitive type");
if (is_bool($val)) {
if ($type == 'boolean') {
$val = $val ? 'true' : 'false';
@@ -445,65 +479,91 @@ class nusoap_base { $val = $this->expandEntities($val);
}
if ($use == 'literal') {
- return "<$name$xmlns $atts>$val</$name>";
+ $xml = "<$name$xmlns$atts>$val</$name>";
+ $this->debug("serialize_val returning $xml");
+ return $xml;
} else {
- return "<$name$xmlns $atts xsi:type=\"xsd:$type\">$val</$name>";
+ $xml = "<$name$xmlns xsi:type=\"xsd:$type\"$atts>$val</$name>";
+ $this->debug("serialize_val returning $xml");
+ return $xml;
}
}
// detect type and serialize
$xml = '';
switch(true) {
case (is_bool($val) || $type == 'boolean'):
+ $this->debug("serialize_val: serialize boolean");
if ($type == 'boolean') {
$val = $val ? 'true' : 'false';
} elseif (! $val) {
$val = 0;
}
if ($use == 'literal') {
- $xml .= "<$name$xmlns $atts>$val</$name>";
+ $xml .= "<$name$xmlns$atts>$val</$name>";
} else {
$xml .= "<$name$xmlns xsi:type=\"xsd:boolean\"$atts>$val</$name>";
}
break;
case (is_int($val) || is_long($val) || $type == 'int'):
+ $this->debug("serialize_val: serialize int");
if ($use == 'literal') {
- $xml .= "<$name$xmlns $atts>$val</$name>";
+ $xml .= "<$name$xmlns$atts>$val</$name>";
} else {
$xml .= "<$name$xmlns xsi:type=\"xsd:int\"$atts>$val</$name>";
}
break;
case (is_float($val)|| is_double($val) || $type == 'float'):
+ $this->debug("serialize_val: serialize float");
if ($use == 'literal') {
- $xml .= "<$name$xmlns $atts>$val</$name>";
+ $xml .= "<$name$xmlns$atts>$val</$name>";
} else {
$xml .= "<$name$xmlns xsi:type=\"xsd:float\"$atts>$val</$name>";
}
break;
case (is_string($val) || $type == 'string'):
+ $this->debug("serialize_val: serialize string");
$val = $this->expandEntities($val);
if ($use == 'literal') {
- $xml .= "<$name$xmlns $atts>$val</$name>";
+ $xml .= "<$name$xmlns$atts>$val</$name>";
} else {
$xml .= "<$name$xmlns xsi:type=\"xsd:string\"$atts>$val</$name>";
}
break;
case is_object($val):
- if (! $name) {
- $name = get_class($val);
- $this->debug("In serialize_val, used class name $name as element name");
+ $this->debug("serialize_val: serialize object");
+ if (get_class($val) == 'soapval') {
+ $this->debug("serialize_val: serialize soapval object");
+ $pXml = $val->serialize($use);
+ $this->appendDebug($val->getDebug());
+ $val->clearDebug();
+ } else {
+ if (! $name) {
+ $name = get_class($val);
+ $this->debug("In serialize_val, used class name $name as element name");
+ } else {
+ $this->debug("In serialize_val, do not override name $name for element name for class " . get_class($val));
+ }
+ foreach(get_object_vars($val) as $k => $v){
+ $pXml = isset($pXml) ? $pXml.$this->serialize_val($v,$k,false,false,false,false,$use) : $this->serialize_val($v,$k,false,false,false,false,$use);
+ }
+ }
+ if(isset($type) && isset($type_prefix)){
+ $type_str = " xsi:type=\"$type_prefix:$type\"";
} else {
- $this->debug("In serialize_val, do not override name $name for element name for class " . get_class($val));
+ $type_str = '';
}
- foreach(get_object_vars($val) as $k => $v){
- $pXml = isset($pXml) ? $pXml.$this->serialize_val($v,$k,false,false,false,false,$use) : $this->serialize_val($v,$k,false,false,false,false,$use);
+ if ($use == 'literal') {
+ $xml .= "<$name$xmlns$atts>$pXml</$name>";
+ } else {
+ $xml .= "<$name$xmlns$type_str$atts>$pXml</$name>";
}
- $xml .= '<'.$name.'>'.$pXml.'</'.$name.'>';
break;
break;
case (is_array($val) || $type):
// detect if struct or array
$valueType = $this->isArraySimpleOrStruct($val);
if($valueType=='arraySimple' || ereg('^ArrayOf',$type)){
+ $this->debug("serialize_val: serialize array");
$i = 0;
if(is_array($val) && count($val)> 0){
foreach($val as $v){
@@ -565,13 +625,14 @@ class nusoap_base { $xml = "<$name$xmlns$type_str$atts>".$xml."</$name>";
} else {
// got a struct
+ $this->debug("serialize_val: serialize struct");
if(isset($type) && isset($type_prefix)){
$type_str = " xsi:type=\"$type_prefix:$type\"";
} else {
$type_str = '';
}
if ($use == 'literal') {
- $xml .= "<$name$xmlns $atts>";
+ $xml .= "<$name$xmlns$atts>";
} else {
$xml .= "<$name$xmlns$type_str$atts>";
}
@@ -590,9 +651,11 @@ class nusoap_base { }
break;
default:
+ $this->debug("serialize_val: serialize unknown");
$xml .= 'not detected, got '.gettype($val).' for '.$val;
break;
}
+ $this->debug("serialize_val returning $xml");
return $xml;
}
@@ -600,7 +663,7 @@ class nusoap_base { * serializes a message
*
* @param string $body the XML of the SOAP body
- * @param mixed $headers optional string of XML with SOAP header content, or array of soapval objects for SOAP headers
+ * @param mixed $headers optional string of XML with SOAP header content, or array of soapval objects for SOAP headers, or associative array
* @param array $namespaces optional the namespaces used in generating the body and headers
* @param string $style optional (rpc|document)
* @param string $use optional (encoded|literal)
@@ -632,11 +695,15 @@ class nusoap_base { if($headers){
if (is_array($headers)) {
$xml = '';
- foreach ($headers as $header) {
- $xml .= $this->serialize_val($header, false, false, false, false, false, $use);
+ foreach ($headers as $k => $v) {
+ if (is_object($v) && get_class($v) == 'soapval') {
+ $xml .= $this->serialize_val($v, false, false, false, false, false, $use);
+ } else {
+ $xml .= $this->serialize_val($v, $k, false, false, false, false, $use);
+ }
}
$headers = $xml;
- $this->debug("In serializeEnvelope, serialzied array of headers to $headers");
+ $this->debug("In serializeEnvelope, serialized array of headers to $headers");
}
$headers = "<SOAP-ENV:Header>".$headers."</SOAP-ENV:Header>";
}
@@ -692,7 +759,7 @@ class nusoap_base { /**
* expands (changes prefix to namespace) a qualified name
*
- * @param string $string qname
+ * @param string $qname qname
* @return string expanded qname
* @access private
*/
@@ -811,6 +878,16 @@ class nusoap_base { ob_end_clean();
return $ret_val;
}
+
+ /**
+ * represents the object as a string
+ *
+ * @return string
+ * @access public
+ */
+ function __toString() {
+ return $this->varDump($this);
+ }
}
// XML Schema Datatype Helper Functions
@@ -821,6 +898,7 @@ class nusoap_base { * convert unix timestamp to ISO 8601 compliant date string
*
* @param string $timestamp Unix time stamp
+* @param boolean $utc Whether the time stamp is UTC or local
* @access public
*/
function timestamp_to_iso8601($timestamp,$utc=true){
@@ -875,7 +953,8 @@ function iso8601_to_timestamp($datestr){ $regs[5] = $regs[5] - $m;
}
}
- return strtotime("$regs[1]-$regs[2]-$regs[3] $regs[4]:$regs[5]:$regs[6]Z");
+ return gmmktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
+// return strtotime("$regs[1]-$regs[2]-$regs[3] $regs[4]:$regs[5]:$regs[6]Z");
} else {
return false;
}
@@ -910,10 +989,10 @@ function usleepWindows($usec) * Mainly used for returning faults from deployed functions
* in a server instance.
* @author Dietrich Ayala <dietrich@ganx4.com>
-* @version $Id: nusoap.php,v 1.94 2005/08/04 01:27:42 snichol Exp $
+* @version $Id: nusoap.php,v 1.114 2007/11/06 15:17:46 snichol Exp $
* @access public
*/
-class soap_fault extends nusoap_base {
+class nusoap_fault extends nusoap_base {
/**
* The fault code (client|server)
* @var string
@@ -942,12 +1021,12 @@ class soap_fault extends nusoap_base { /**
* constructor
*
- * @param string $faultcode (client | server)
+ * @param string $faultcode (SOAP-ENV:Client | SOAP-ENV:Server)
* @param string $faultactor only used when msg routed between multiple actors
* @param string $faultstring human readable error message
* @param mixed $faultdetail detail, typically a string or array of string
*/
- function soap_fault($faultcode,$faultactor='',$faultstring='',$faultdetail=''){
+ function nusoap_fault($faultcode,$faultactor='',$faultstring='',$faultdetail=''){
parent::nusoap_base();
$this->faultcode = $faultcode;
$this->faultactor = $faultactor;
@@ -982,24 +1061,26 @@ class soap_fault extends nusoap_base { }
}
-
+/**
+ * Backward compatibility
+ */
+class soap_fault extends nusoap_fault {
+}
?><?php
/**
-* parses an XML Schema, allows access to it's data, other utility methods
-* no validation... yet.
-* very experimental and limited. As is discussed on XML-DEV, I'm one of the people
-* that just doesn't have time to read the spec(s) thoroughly, and just have a couple of trusty
-* tutorials I refer to :)
+* parses an XML Schema, allows access to it's data, other utility methods.
+* imperfect, no validation... yet, but quite functional.
*
* @author Dietrich Ayala <dietrich@ganx4.com>
-* @version $Id: nusoap.php,v 1.94 2005/08/04 01:27:42 snichol Exp $
+* @author Scott Nichol <snichol@users.sourceforge.net>
+* @version $Id: nusoap.php,v 1.114 2007/11/06 15:17:46 snichol Exp $
* @access public
*/
-class XMLSchema extends nusoap_base {
+class nusoap_xmlschema extends nusoap_base {
// files
var $schema = '';
@@ -1038,9 +1119,9 @@ class XMLSchema extends nusoap_base { * @param string $namespaces namespaces defined in enclosing XML
* @access public
*/
- function XMLSchema($schema='',$xml='',$namespaces=array()){
+ function nusoap_xmlschema($schema='',$xml='',$namespaces=array()){
parent::nusoap_base();
- $this->debug('xmlschema class instantiated, inside constructor');
+ $this->debug('nusoap_xmlschema class instantiated, inside constructor');
// files
$this->schema = $schema;
$this->xml = $xml;
@@ -1066,8 +1147,8 @@ class XMLSchema extends nusoap_base { /**
* parse an XML file
*
- * @param string $xml, path/URL to XML file
- * @param string $type, (schema | xml)
+ * @param string $xml path/URL to XML file
+ * @param string $type (schema | xml)
* @return boolean
* @access public
*/
@@ -1094,7 +1175,7 @@ class XMLSchema extends nusoap_base { * parse an XML string
*
* @param string $xml path or URL
- * @param string $type, (schema|xml)
+ * @param string $type (schema|xml)
* @access private
*/
function parseString($xml,$type){
@@ -1138,6 +1219,21 @@ class XMLSchema extends nusoap_base { }
/**
+ * gets a type name for an unnamed type
+ *
+ * @param string Element name
+ * @return string A type name for an unnamed type
+ * @access private
+ */
+ function CreateTypeName($ename) {
+ $scope = '';
+ for ($i = 0; $i < count($this->complexTypeStack); $i++) {
+ $scope .= $this->complexTypeStack[$i] . '_';
+ }
+ return $scope . $ename . '_ContainedType';
+ }
+
+ /**
* start-element handler
*
* @param string $parser XML parser object
@@ -1269,6 +1365,8 @@ class XMLSchema extends nusoap_base { case 'complexType':
array_push($this->complexTypeStack, $this->currentComplexType);
if(isset($attrs['name'])){
+ // TODO: what is the scope of named complexTypes that appear
+ // nested within other c complexTypes?
$this->xdebug('processing named complexType '.$attrs['name']);
//$this->currentElement = false;
$this->currentComplexType = $attrs['name'];
@@ -1287,9 +1385,10 @@ class XMLSchema extends nusoap_base { } else {
$this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
}
- }else{
- $this->xdebug('processing unnamed complexType for element '.$this->currentElement);
- $this->currentComplexType = $this->currentElement . '_ContainedType';
+ } else {
+ $name = $this->CreateTypeName($this->currentElement);
+ $this->xdebug('processing unnamed complexType for element ' . $this->currentElement . ' named ' . $name);
+ $this->currentComplexType = $name;
//$this->currentElement = false;
$this->complexTypes[$this->currentComplexType] = $attrs;
$this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType';
@@ -1310,9 +1409,6 @@ class XMLSchema extends nusoap_base { break;
case 'element':
array_push($this->elementStack, $this->currentElement);
- // elements defined as part of a complex type should
- // not really be added to $this->elements, but for some
- // reason, they are
if (!isset($attrs['form'])) {
$attrs['form'] = $this->schemaInfo['elementFormDefault'];
}
@@ -1336,24 +1432,25 @@ class XMLSchema extends nusoap_base { $this->complexTypes[$this->currentComplexType]['arrayType'] = $attrs['type'];
}
$this->currentElement = $attrs['name'];
- $this->elements[ $attrs['name'] ] = $attrs;
- $this->elements[ $attrs['name'] ]['typeClass'] = 'element';
$ename = $attrs['name'];
} elseif(isset($attrs['ref'])){
$this->xdebug("processing element as ref to ".$attrs['ref']);
$this->currentElement = "ref to ".$attrs['ref'];
$ename = $this->getLocalPart($attrs['ref']);
} else {
- $this->xdebug("processing untyped element ".$attrs['name']);
+ $type = $this->CreateTypeName($this->currentComplexType . '_' . $attrs['name']);
+ $this->xdebug("processing untyped element " . $attrs['name'] . ' type ' . $type);
$this->currentElement = $attrs['name'];
- $this->elements[ $attrs['name'] ] = $attrs;
- $this->elements[ $attrs['name'] ]['typeClass'] = 'element';
- $attrs['type'] = $this->schemaTargetNamespace . ':' . $attrs['name'] . '_ContainedType';
- $this->elements[ $attrs['name'] ]['type'] = $attrs['type'];
+ $attrs['type'] = $this->schemaTargetNamespace . ':' . $type;
$ename = $attrs['name'];
}
- if(isset($ename) && $this->currentComplexType){
+ if (isset($ename) && $this->currentComplexType) {
+ $this->xdebug("add element $ename to complexType $this->currentComplexType");
$this->complexTypes[$this->currentComplexType]['elements'][$ename] = $attrs;
+ } elseif (!isset($attrs['ref'])) {
+ $this->xdebug("add element $ename to elements array");
+ $this->elements[ $attrs['name'] ] = $attrs;
+ $this->elements[ $attrs['name'] ]['typeClass'] = 'element';
}
break;
case 'enumeration': // restriction value list member
@@ -1419,8 +1516,9 @@ class XMLSchema extends nusoap_base { $this->simpleTypes[ $attrs['name'] ]['typeClass'] = 'simpleType';
$this->simpleTypes[ $attrs['name'] ]['phpType'] = 'scalar';
} else {
- $this->xdebug('processing unnamed simpleType for element '.$this->currentElement);
- $this->currentSimpleType = $this->currentElement . '_ContainedType';
+ $name = $this->CreateTypeName($this->currentComplexType . '_' . $this->currentElement);
+ $this->xdebug('processing unnamed simpleType for element ' . $this->currentElement . ' named ' . $name);
+ $this->currentSimpleType = $name;
//$this->currentElement = false;
$this->simpleTypes[$this->currentSimpleType] = $attrs;
$this->simpleTypes[$this->currentSimpleType]['phpType'] = 'scalar';
@@ -1563,13 +1661,13 @@ class XMLSchema extends nusoap_base { // simple types
if(isset($this->simpleTypes) && count($this->simpleTypes) > 0){
foreach($this->simpleTypes as $typeName => $eParts){
- $xml .= " <$schemaPrefix:simpleType name=\"$typeName\">\n <$schemaPrefix:restriction base=\"".$this->contractQName($eParts['type'])."\"/>\n";
+ $xml .= " <$schemaPrefix:simpleType name=\"$typeName\">\n <$schemaPrefix:restriction base=\"".$this->contractQName($eParts['type'])."\">\n";
if (isset($eParts['enumeration'])) {
foreach ($eParts['enumeration'] as $e) {
$xml .= " <$schemaPrefix:enumeration value=\"$e\"/>\n";
}
}
- $xml .= " </$schemaPrefix:simpleType>";
+ $xml .= " </$schemaPrefix:restriction>\n </$schemaPrefix:simpleType>";
}
}
// elements
@@ -1585,9 +1683,15 @@ class XMLSchema extends nusoap_base { }
}
// finish 'er up
- $el = "<$schemaPrefix:schema targetNamespace=\"$this->schemaTargetNamespace\"\n";
+ $attr = '';
+ foreach ($this->schemaInfo as $k => $v) {
+ if ($k == 'elementFormDefault' || $k == 'attributeFormDefault') {
+ $attr .= " $k=\"$v\"";
+ }
+ }
+ $el = "<$schemaPrefix:schema$attr targetNamespace=\"$this->schemaTargetNamespace\"\n";
foreach (array_diff($this->usedNamespaces, $this->enclosingNamespaces) as $nsp => $ns) {
- $el .= " xmlns:$nsp=\"$ns\"\n";
+ $el .= " xmlns:$nsp=\"$ns\"";
}
$xml = $el . ">\n".$xml."</$schemaPrefix:schema>\n";
return $xml;
@@ -1609,8 +1713,8 @@ class XMLSchema extends nusoap_base { * returns false if no type exists, or not w/ the given namespace
* else returns a string that is either a native php type, or 'struct'
*
- * @param string $type, name of defined type
- * @param string $ns, namespace of type
+ * @param string $type name of defined type
+ * @param string $ns namespace of type
* @return mixed
* @access public
* @deprecated
@@ -1641,7 +1745,7 @@ class XMLSchema extends nusoap_base { *
* For simpleType or element, the array has different keys.
*
- * @param string
+ * @param string $type
* @return mixed
* @access public
* @see addComplexType
@@ -1650,10 +1754,17 @@ class XMLSchema extends nusoap_base { */
function getTypeDef($type){
//$this->debug("in getTypeDef for type $type");
- if(isset($this->complexTypes[$type])){
+ if (substr($type, -1) == '^') {
+ $is_element = 1;
+ $type = substr($type, 0, -1);
+ } else {
+ $is_element = 0;
+ }
+
+ if((! $is_element) && isset($this->complexTypes[$type])){
$this->xdebug("in getTypeDef, found complexType $type");
return $this->complexTypes[$type];
- } elseif(isset($this->simpleTypes[$type])){
+ } elseif((! $is_element) && isset($this->simpleTypes[$type])){
$this->xdebug("in getTypeDef, found simpleType $type");
if (!isset($this->simpleTypes[$type]['phpType'])) {
// get info for type to tack onto the simple type
@@ -1712,7 +1823,7 @@ class XMLSchema extends nusoap_base { /**
* returns a sample serialization of a given type, or false if no type by the given name
*
- * @param string $type, name of type
+ * @param string $type name of type
* @return mixed
* @access public
* @deprecated
@@ -1722,7 +1833,7 @@ class XMLSchema extends nusoap_base { if($typeDef = $this->getTypeDef($type)){
$str .= '<'.$type;
if(is_array($typeDef['attrs'])){
- foreach($attrs as $attName => $data){
+ foreach($typeDef['attrs'] as $attName => $data){
$str .= " $attName=\"{type = ".$data['type']."}\"";
}
}
@@ -1747,8 +1858,8 @@ class XMLSchema extends nusoap_base { * returns HTML form elements that allow a user
* to enter values for creating an instance of the given type.
*
- * @param string $name, name for type instance
- * @param string $type, name of type
+ * @param string $name name for type instance
+ * @param string $type name of type
* @return string
* @access public
* @deprecated
@@ -1850,7 +1961,7 @@ class XMLSchema extends nusoap_base { * @param string $phpType (should always be scalar)
* @param array $enumeration array of values
* @access public
- * @see xmlschema
+ * @see nusoap_xmlschema
* @see getTypeDef
*/
function addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array()) {
@@ -1870,7 +1981,7 @@ class XMLSchema extends nusoap_base { * adds an element to the schema
*
* @param array $attrs attributes that must include name and type
- * @see xmlschema
+ * @see nusoap_xmlschema
* @access public
*/
function addElement($attrs) {
@@ -1885,7 +1996,11 @@ class XMLSchema extends nusoap_base { }
}
-
+/**
+ * Backward compatibility
+ */
+class XMLSchema extends nusoap_xmlschema {
+}
?><?php
@@ -1899,7 +2014,7 @@ class XMLSchema extends nusoap_base { * xsd:anyType and user-defined types.
*
* @author Dietrich Ayala <dietrich@ganx4.com>
-* @version $Id: nusoap.php,v 1.94 2005/08/04 01:27:42 snichol Exp $
+* @version $Id: nusoap.php,v 1.114 2007/11/06 15:17:46 snichol Exp $
* @access public
*/
class soapval extends nusoap_base {
@@ -1975,7 +2090,7 @@ class soapval extends nusoap_base { * @access public
*/
function serialize($use='encoded') {
- return $this->serialize_val($this->value,$this->name,$this->type,$this->element_ns,$this->type_ns,$this->attributes,$use);
+ return $this->serialize_val($this->value, $this->name, $this->type, $this->element_ns, $this->type_ns, $this->attributes, $use, true);
}
/**
@@ -2000,7 +2115,8 @@ class soapval extends nusoap_base { * NOTE: PHP must be compiled with the CURL extension for HTTPS support
*
* @author Dietrich Ayala <dietrich@ganx4.com>
-* @version $Id: nusoap.php,v 1.94 2005/08/04 01:27:42 snichol Exp $
+* @author Scott Nichol <snichol@users.sourceforge.net>
+* @version $Id: nusoap.php,v 1.114 2007/11/06 15:17:46 snichol Exp $
* @access public
*/
class soap_transport_http extends nusoap_base {
@@ -2020,38 +2136,97 @@ class soap_transport_http extends nusoap_base { var $incoming_cookies = array();
var $outgoing_payload = '';
var $incoming_payload = '';
+ var $response_status_line; // HTTP response status line
var $useSOAPAction = true;
var $persistentConnection = false;
var $ch = false; // cURL handle
+ var $ch_options = array(); // cURL custom options
+ var $use_curl = false; // force cURL use
+ var $proxy = null; // proxy information (associative array)
var $username = '';
var $password = '';
var $authtype = '';
var $digestRequest = array();
- var $certRequest = array(); // keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, verifypeer (optional), verifyhost (optional)
+ var $certRequest = array(); // keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, certpassword (optional), verifypeer (optional), verifyhost (optional)
// cainfofile: certificate authority file, e.g. '$pathToPemFiles/rootca.pem'
// sslcertfile: SSL certificate file, e.g. '$pathToPemFiles/mycert.pem'
// sslkeyfile: SSL key file, e.g. '$pathToPemFiles/mykey.pem'
// passphrase: SSL key password/passphrase
+ // certpassword: SSL certificate password
// verifypeer: default is 1
// verifyhost: default is 1
/**
* constructor
+ *
+ * @param string $url The URL to which to connect
+ * @param array $curl_options User-specified cURL options
+ * @param boolean $use_curl Whether to try to force cURL use
+ * @access public
*/
- function soap_transport_http($url){
+ function soap_transport_http($url, $curl_options = NULL, $use_curl = false){
parent::nusoap_base();
+ $this->debug("ctor url=$url use_curl=$use_curl curl_options:");
+ $this->appendDebug($this->varDump($curl_options));
$this->setURL($url);
+ if (is_array($curl_options)) {
+ $this->ch_options = $curl_options;
+ }
+ $this->use_curl = $use_curl;
ereg('\$Revisio' . 'n: ([^ ]+)', $this->revision, $rev);
- $this->outgoing_headers['User-Agent'] = $this->title.'/'.$this->version.' ('.$rev[1].')';
- $this->debug('set User-Agent: ' . $this->outgoing_headers['User-Agent']);
+ $this->setHeader('User-Agent', $this->title.'/'.$this->version.' ('.$rev[1].')');
}
+ /**
+ * sets a cURL option
+ *
+ * @param mixed $option The cURL option (always integer?)
+ * @param mixed $value The cURL option value
+ * @access private
+ */
+ function setCurlOption($option, $value) {
+ $this->debug("setCurlOption option=$option, value=");
+ $this->appendDebug($this->varDump($value));
+ curl_setopt($this->ch, $option, $value);
+ }
+
+ /**
+ * sets an HTTP header
+ *
+ * @param string $name The name of the header
+ * @param string $value The value of the header
+ * @access private
+ */
+ function setHeader($name, $value) {
+ $this->outgoing_headers[$name] = $value;
+ $this->debug("set header $name: $value");
+ }
+
+ /**
+ * unsets an HTTP header
+ *
+ * @param string $name The name of the header
+ * @access private
+ */
+ function unsetHeader($name) {
+ if (isset($this->outgoing_headers[$name])) {
+ $this->debug("unset header $name");
+ unset($this->outgoing_headers[$name]);
+ }
+ }
+
+ /**
+ * sets the URL to which to connect
+ *
+ * @param string $url The URL to which to connect
+ * @access private
+ */
function setURL($url) {
$this->url = $url;
$u = parse_url($url);
foreach($u as $k => $v){
- $this->debug("$k = $v");
+ $this->debug("parsed URL $k = $v");
$this->$k = $v;
}
@@ -2074,17 +2249,38 @@ class soap_transport_http extends nusoap_base { // build headers
if (!isset($u['port'])) {
- $this->outgoing_headers['Host'] = $this->host;
+ $this->setHeader('Host', $this->host);
} else {
- $this->outgoing_headers['Host'] = $this->host.':'.$this->port;
+ $this->setHeader('Host', $this->host.':'.$this->port);
}
- $this->debug('set Host: ' . $this->outgoing_headers['Host']);
if (isset($u['user']) && $u['user'] != '') {
$this->setCredentials(urldecode($u['user']), isset($u['pass']) ? urldecode($u['pass']) : '');
}
}
-
+
+ /**
+ * gets the I/O method to use
+ *
+ * @return string I/O method to use (socket|curl|unknown)
+ * @access private
+ */
+ function io_method() {
+ if ($this->use_curl || ($this->scheme == 'https') || ($this->scheme == 'http' && $this->authtype == 'ntlm') || ($this->scheme == 'http' && is_array($this->proxy) && $this->proxy['authtype'] == 'ntlm'))
+ return 'curl';
+ if (($this->scheme == 'http' || $this->scheme == 'ssl') && $this->authtype != 'ntlm' && (!is_array($this->proxy) || $this->proxy['authtype'] != 'ntlm'))
+ return 'socket';
+ return 'unknown';
+ }
+
+ /**
+ * establish an HTTP connection
+ *
+ * @param integer $timeout set connection timeout in seconds
+ * @param integer $response_timeout set response timeout in seconds
+ * @return boolean true if connected, false if not
+ * @access private
+ */
function connect($connection_timeout=0,$response_timeout=30){
// For PHP 4.3 with OpenSSL, change https scheme to ssl, then treat like
// "regular" socket.
@@ -2099,7 +2295,15 @@ class soap_transport_http extends nusoap_base { // }
// }
$this->debug("connect connection_timeout $connection_timeout, response_timeout $response_timeout, scheme $this->scheme, host $this->host, port $this->port");
- if ($this->scheme == 'http' || $this->scheme == 'ssl') {
+ if ($this->io_method() == 'socket') {
+ if (!is_array($this->proxy)) {
+ $host = $this->host;
+ $port = $this->port;
+ } else {
+ $host = $this->proxy['host'];
+ $port = $this->proxy['port'];
+ }
+
// use persistent connection
if($this->persistentConnection && isset($this->fp) && is_resource($this->fp)){
if (!feof($this->fp)) {
@@ -2112,9 +2316,7 @@ class soap_transport_http extends nusoap_base { // munge host if using OpenSSL
if ($this->scheme == 'ssl') {
- $host = 'ssl://' . $this->host;
- } else {
- $host = $this->host;
+ $host = 'ssl://' . $host;
}
$this->debug('calling fsockopen with host ' . $host . ' connection_timeout ' . $connection_timeout);
@@ -2144,81 +2346,156 @@ class soap_transport_http extends nusoap_base { $this->debug('socket connected');
return true;
- } else if ($this->scheme == 'https') {
+ } else if ($this->io_method() == 'curl') {
if (!extension_loaded('curl')) {
- $this->setError('CURL Extension, or OpenSSL extension w/ PHP version >= 4.3 is required for HTTPS');
+// $this->setError('cURL Extension, or OpenSSL extension w/ PHP version >= 4.3 is required for HTTPS');
+ $this->setError('The PHP cURL Extension is required for HTTPS or NLTM. You will need to re-build or update your PHP to included cURL.');
return false;
}
- $this->debug('connect using https');
+ // Avoid warnings when PHP does not have these options
+ if (defined('CURLOPT_CONNECTIONTIMEOUT'))
+ $CURLOPT_CONNECTIONTIMEOUT = CURLOPT_CONNECTIONTIMEOUT;
+ else
+ $CURLOPT_CONNECTIONTIMEOUT = 78;
+ if (defined('CURLOPT_HTTPAUTH'))
+ $CURLOPT_HTTPAUTH = CURLOPT_HTTPAUTH;
+ else
+ $CURLOPT_HTTPAUTH = 107;
+ if (defined('CURLOPT_PROXYAUTH'))
+ $CURLOPT_PROXYAUTH = CURLOPT_PROXYAUTH;
+ else
+ $CURLOPT_PROXYAUTH = 111;
+ if (defined('CURLAUTH_BASIC'))
+ $CURLAUTH_BASIC = CURLAUTH_BASIC;
+ else
+ $CURLAUTH_BASIC = 1;
+ if (defined('CURLAUTH_DIGEST'))
+ $CURLAUTH_DIGEST = CURLAUTH_DIGEST;
+ else
+ $CURLAUTH_DIGEST = 2;
+ if (defined('CURLAUTH_NTLM'))
+ $CURLAUTH_NTLM = CURLAUTH_NTLM;
+ else
+ $CURLAUTH_NTLM = 8;
+
+ $this->debug('connect using cURL');
// init CURL
$this->ch = curl_init();
// set url
- $hostURL = ($this->port != '') ? "https://$this->host:$this->port" : "https://$this->host";
+ $hostURL = ($this->port != '') ? "$this->scheme://$this->host:$this->port" : "$this->scheme://$this->host";
// add path
$hostURL .= $this->path;
- curl_setopt($this->ch, CURLOPT_URL, $hostURL);
+ $this->setCurlOption(CURLOPT_URL, $hostURL);
// follow location headers (re-directs)
- curl_setopt($this->ch, CURLOPT_FOLLOWLOCATION, 1);
+ if (ini_get('safe_mode') || ini_get('open_basedir')) {
+ $this->debug('safe_mode or open_basedir set, so do not set CURLOPT_FOLLOWLOCATION');
+ $this->debug('safe_mode = ');
+ $this->appendDebug($this->varDump(ini_get('safe_mode')));
+ $this->debug('open_basedir = ');
+ $this->appendDebug($this->varDump(ini_get('open_basedir')));
+ } else {
+ $this->setCurlOption(CURLOPT_FOLLOWLOCATION, 1);
+ }
// ask for headers in the response output
- curl_setopt($this->ch, CURLOPT_HEADER, 1);
+ $this->setCurlOption(CURLOPT_HEADER, 1);
// ask for the response output as the return value
- curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, 1);
+ $this->setCurlOption(CURLOPT_RETURNTRANSFER, 1);
// encode
// We manage this ourselves through headers and encoding
// if(function_exists('gzuncompress')){
-// curl_setopt($this->ch, CURLOPT_ENCODING, 'deflate');
+// $this->setCurlOption(CURLOPT_ENCODING, 'deflate');
// }
// persistent connection
if ($this->persistentConnection) {
+ // I believe the following comment is now bogus, having applied to
+ // the code when it used CURLOPT_CUSTOMREQUEST to send the request.
// The way we send data, we cannot use persistent connections, since
// there will be some "junk" at the end of our request.
- //curl_setopt($this->ch, CURL_HTTP_VERSION_1_1, true);
+ //$this->setCurlOption(CURL_HTTP_VERSION_1_1, true);
$this->persistentConnection = false;
- $this->outgoing_headers['Connection'] = 'close';
- $this->debug('set Connection: ' . $this->outgoing_headers['Connection']);
+ $this->setHeader('Connection', 'close');
}
- // set timeout
+ // set timeouts
if ($connection_timeout != 0) {
- curl_setopt($this->ch, CURLOPT_TIMEOUT, $connection_timeout);
- }
- // TODO: cURL has added a connection timeout separate from the response timeout
- //if ($connection_timeout != 0) {
- // curl_setopt($this->ch, CURLOPT_CONNECTIONTIMEOUT, $connection_timeout);
- //}
- //if ($response_timeout != 0) {
- // curl_setopt($this->ch, CURLOPT_TIMEOUT, $response_timeout);
- //}
-
- // recent versions of cURL turn on peer/host checking by default,
- // while PHP binaries are not compiled with a default location for the
- // CA cert bundle, so disable peer/host checking.
-//curl_setopt($this->ch, CURLOPT_CAINFO, 'f:\php-4.3.2-win32\extensions\curl-ca-bundle.crt');
- curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, 0);
- curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, 0);
-
- // support client certificates (thanks Tobias Boes, Doug Anarino, Eryan Ariobowo)
- if ($this->authtype == 'certificate') {
- if (isset($this->certRequest['cainfofile'])) {
- curl_setopt($this->ch, CURLOPT_CAINFO, $this->certRequest['cainfofile']);
- }
- if (isset($this->certRequest['verifypeer'])) {
- curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, $this->certRequest['verifypeer']);
- } else {
- curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, 1);
+ $this->setCurlOption($CURLOPT_CONNECTIONTIMEOUT, $connection_timeout);
+ }
+ if ($response_timeout != 0) {
+ $this->setCurlOption(CURLOPT_TIMEOUT, $response_timeout);
+ }
+
+ if ($this->scheme == 'https') {
+ $this->debug('set cURL SSL verify options');
+ // recent versions of cURL turn on peer/host checking by default,
+ // while PHP binaries are not compiled with a default location for the
+ // CA cert bundle, so disable peer/host checking.
+ //$this->setCurlOption(CURLOPT_CAINFO, 'f:\php-4.3.2-win32\extensions\curl-ca-bundle.crt');
+ $this->setCurlOption(CURLOPT_SSL_VERIFYPEER, 0);
+ $this->setCurlOption(CURLOPT_SSL_VERIFYHOST, 0);
+
+ // support client certificates (thanks Tobias Boes, Doug Anarino, Eryan Ariobowo)
+ if ($this->authtype == 'certificate') {
+ $this->debug('set cURL certificate options');
+ if (isset($this->certRequest['cainfofile'])) {
+ $this->setCurlOption(CURLOPT_CAINFO, $this->certRequest['cainfofile']);
+ }
+ if (isset($this->certRequest['verifypeer'])) {
+ $this->setCurlOption(CURLOPT_SSL_VERIFYPEER, $this->certRequest['verifypeer']);
+ } else {
+ $this->setCurlOption(CURLOPT_SSL_VERIFYPEER, 1);
+ }
+ if (isset($this->certRequest['verifyhost'])) {
+ $this->setCurlOption(CURLOPT_SSL_VERIFYHOST, $this->certRequest['verifyhost']);
+ } else {
+ $this->setCurlOption(CURLOPT_SSL_VERIFYHOST, 1);
+ }
+ if (isset($this->certRequest['sslcertfile'])) {
+ $this->setCurlOption(CURLOPT_SSLCERT, $this->certRequest['sslcertfile']);
+ }
+ if (isset($this->certRequest['sslkeyfile'])) {
+ $this->setCurlOption(CURLOPT_SSLKEY, $this->certRequest['sslkeyfile']);
+ }
+ if (isset($this->certRequest['passphrase'])) {
+ $this->setCurlOption(CURLOPT_SSLKEYPASSWD, $this->certRequest['passphrase']);
+ }
+ if (isset($this->certRequest['certpassword'])) {
+ $this->setCurlOption(CURLOPT_SSLCERTPASSWD, $this->certRequest['certpassword']);
+ }
}
- if (isset($this->certRequest['verifyhost'])) {
- curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, $this->certRequest['verifyhost']);
- } else {
- curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, 1);
+ }
+ if ($this->authtype && ($this->authtype != 'certificate')) {
+ if ($this->username) {
+ $this->debug('set cURL username/password');
+ $this->setCurlOption(CURLOPT_USERPWD, "$this->username:$this->password");
}
- if (isset($this->certRequest['sslcertfile'])) {
- curl_setopt($this->ch, CURLOPT_SSLCERT, $this->certRequest['sslcertfile']);
+ if ($this->authtype == 'basic') {
+ $this->debug('set cURL for Basic authentication');
+ $this->setCurlOption($CURLOPT_HTTPAUTH, $CURLAUTH_BASIC);
}
- if (isset($this->certRequest['sslkeyfile'])) {
- curl_setopt($this->ch, CURLOPT_SSLKEY, $this->certRequest['sslkeyfile']);
+ if ($this->authtype == 'digest') {
+ $this->debug('set cURL for digest authentication');
+ $this->setCurlOption($CURLOPT_HTTPAUTH, $CURLAUTH_DIGEST);
}
- if (isset($this->certRequest['passphrase'])) {
- curl_setopt($this->ch, CURLOPT_SSLKEYPASSWD , $this->certRequest['passphrase']);
+ if ($this->authtype == 'ntlm') {
+ $this->debug('set cURL for NTLM authentication');
+ $this->setCurlOption($CURLOPT_HTTPAUTH, $CURLAUTH_NTLM);
+ }
+ }
+ if (is_array($this->proxy)) {
+ $this->debug('set cURL proxy options');
+ if ($this->proxy['port'] != '') {
+ $this->setCurlOption(CURLOPT_PROXY, $this->proxy['host'].':'.$this->proxy['port']);
+ } else {
+ $this->setCurlOption(CURLOPT_PROXY, $this->proxy['host']);
+ }
+ if ($this->proxy['username'] || $this->proxy['password']) {
+ $this->debug('set cURL proxy authentication options');
+ $this->setCurlOption(CURLOPT_PROXYUSERPWD, $this->proxy['username'].':'.$this->proxy['password']);
+ if ($this->proxy['authtype'] == 'basic') {
+ $this->setCurlOption($CURLOPT_PROXYAUTH, $CURLAUTH_BASIC);
+ }
+ if ($this->proxy['authtype'] == 'ntlm') {
+ $this->setCurlOption($CURLOPT_PROXYAUTH, $CURLAUTH_NTLM);
+ }
}
}
$this->debug('cURL connection set up');
@@ -2229,9 +2506,9 @@ class soap_transport_http extends nusoap_base { return false;
}
}
-
+
/**
- * send the SOAP message via HTTP
+ * sends the SOAP request and gets the SOAP response via HTTP[S]
*
* @param string $data message data
* @param integer $timeout set connection timeout in seconds
@@ -2262,7 +2539,7 @@ class soap_transport_http extends nusoap_base { // get response
$respdata = $this->getResponse();
} else {
- $this->setError('Too many tries to get an OK response');
+ $this->setError("Too many tries to get an OK response ($this->response_status_line)");
}
}
$this->debug('end of send()');
@@ -2271,14 +2548,15 @@ class soap_transport_http extends nusoap_base { /**
- * send the SOAP message via HTTPS 1.0 using CURL
+ * sends the SOAP request and gets the SOAP response via HTTPS using CURL
*
- * @param string $msg message data
+ * @param string $data message data
* @param integer $timeout set connection timeout in seconds
* @param integer $response_timeout set response timeout in seconds
* @param array $cookies cookies to send
* @return string data
* @access public
+ * @deprecated
*/
function sendHTTPS($data, $timeout=0, $response_timeout=30, $cookies) {
return $this->send($data, $timeout, $response_timeout, $cookies);
@@ -2289,16 +2567,19 @@ class soap_transport_http extends nusoap_base { *
* @param string $username
* @param string $password
- * @param string $authtype (basic, digest, certificate)
+ * @param string $authtype (basic|digest|certificate|ntlm)
* @param array $digestRequest (keys must be nonce, nc, realm, qop)
- * @param array $certRequest (keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, verifypeer (optional), verifyhost (optional): see corresponding options in cURL docs)
+ * @param array $certRequest (keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, certpassword (optional), verifypeer (optional), verifyhost (optional): see corresponding options in cURL docs)
* @access public
*/
function setCredentials($username, $password, $authtype = 'basic', $digestRequest = array(), $certRequest = array()) {
- $this->debug("Set credentials for authtype $authtype");
+ $this->debug("setCredentials username=$username authtype=$authtype digestRequest=");
+ $this->appendDebug($this->varDump($digestRequest));
+ $this->debug("certRequest=");
+ $this->appendDebug($this->varDump($certRequest));
// cf. RFC 2617
if ($authtype == 'basic') {
- $this->outgoing_headers['Authorization'] = 'Basic '.base64_encode(str_replace(':','',$username).':'.$password);
+ $this->setHeader('Authorization', 'Basic '.base64_encode(str_replace(':','',$username).':'.$password));
} elseif ($authtype == 'digest') {
if (isset($digestRequest['nonce'])) {
$digestRequest['nc'] = isset($digestRequest['nc']) ? $digestRequest['nc']++ : 1;
@@ -2312,7 +2593,7 @@ class soap_transport_http extends nusoap_base { $HA1 = md5($A1);
// A2 = Method ":" digest-uri-value
- $A2 = 'POST:' . $this->digest_uri;
+ $A2 = $this->request_method . ':' . $this->digest_uri;
// H(A2)
$HA2 = md5($A2);
@@ -2339,21 +2620,24 @@ class soap_transport_http extends nusoap_base { $hashedDigest = md5($unhashedDigest);
- $this->outgoing_headers['Authorization'] = 'Digest username="' . $username . '", realm="' . $digestRequest['realm'] . '", nonce="' . $nonce . '", uri="' . $this->digest_uri . '", cnonce="' . $cnonce . '", nc=' . sprintf("%08x", $digestRequest['nc']) . ', qop="' . $digestRequest['qop'] . '", response="' . $hashedDigest . '"';
+ $opaque = '';
+ if (isset($digestRequest['opaque'])) {
+ $opaque = ', opaque="' . $digestRequest['opaque'] . '"';
+ }
+
+ $this->setHeader('Authorization', 'Digest username="' . $username . '", realm="' . $digestRequest['realm'] . '", nonce="' . $nonce . '", uri="' . $this->digest_uri . $opaque . '", cnonce="' . $cnonce . '", nc=' . sprintf("%08x", $digestRequest['nc']) . ', qop="' . $digestRequest['qop'] . '", response="' . $hashedDigest . '"');
}
} elseif ($authtype == 'certificate') {
$this->certRequest = $certRequest;
+ $this->debug('Authorization header not set for certificate');
+ } elseif ($authtype == 'ntlm') {
+ // do nothing
+ $this->debug('Authorization header not set for ntlm');
}
$this->username = $username;
$this->password = $password;
$this->authtype = $authtype;
$this->digestRequest = $digestRequest;
-
- if (isset($this->outgoing_headers['Authorization'])) {
- $this->debug('set Authorization: ' . substr($this->outgoing_headers['Authorization'], 0, 12) . '...');
- } else {
- $this->debug('Authorization header not set');
- }
}
/**
@@ -2363,8 +2647,7 @@ class soap_transport_http extends nusoap_base { * @access public
*/
function setSOAPAction($soapaction) {
- $this->outgoing_headers['SOAPAction'] = '"' . $soapaction . '"';
- $this->debug('set SOAPAction: ' . $this->outgoing_headers['SOAPAction']);
+ $this->setHeader('SOAPAction', '"' . $soapaction . '"');
}
/**
@@ -2376,12 +2659,10 @@ class soap_transport_http extends nusoap_base { function setEncoding($enc='gzip, deflate') {
if (function_exists('gzdeflate')) {
$this->protocol_version = '1.1';
- $this->outgoing_headers['Accept-Encoding'] = $enc;
- $this->debug('set Accept-Encoding: ' . $this->outgoing_headers['Accept-Encoding']);
+ $this->setHeader('Accept-Encoding', $enc);
if (!isset($this->outgoing_headers['Connection'])) {
- $this->outgoing_headers['Connection'] = 'close';
+ $this->setHeader('Connection', 'close');
$this->persistentConnection = false;
- $this->debug('set Connection: ' . $this->outgoing_headers['Connection']);
}
set_magic_quotes_runtime(0);
// deprecated
@@ -2392,22 +2673,58 @@ class soap_transport_http extends nusoap_base { /**
* set proxy info here
*
- * @param string $proxyhost
+ * @param string $proxyhost use an empty string to remove proxy
* @param string $proxyport
* @param string $proxyusername
* @param string $proxypassword
+ * @param string $proxyauthtype (basic|ntlm)
* @access public
*/
- function setProxy($proxyhost, $proxyport, $proxyusername = '', $proxypassword = '') {
- $this->uri = $this->url;
- $this->host = $proxyhost;
- $this->port = $proxyport;
- if ($proxyusername != '' && $proxypassword != '') {
- $this->outgoing_headers['Proxy-Authorization'] = ' Basic '.base64_encode($proxyusername.':'.$proxypassword);
- $this->debug('set Proxy-Authorization: ' . $this->outgoing_headers['Proxy-Authorization']);
+ function setProxy($proxyhost, $proxyport, $proxyusername = '', $proxypassword = '', $proxyauthtype = 'basic') {
+ if ($proxyhost) {
+ $this->proxy = array(
+ 'host' => $proxyhost,
+ 'port' => $proxyport,
+ 'username' => $proxyusername,
+ 'password' => $proxypassword,
+ 'authtype' => $proxyauthtype
+ );
+ if ($proxyusername != '' && $proxypassword != '' && $proxyauthtype = 'basic') {
+ $this->setHeader('Proxy-Authorization', ' Basic '.base64_encode($proxyusername.':'.$proxypassword));
+ }
+ } else {
+ $this->debug('remove proxy');
+ $proxy = null;
+ unsetHeader('Proxy-Authorization');
}
}
+
+ /**
+ * Test if the given string starts with a header that is to be skipped.
+ * Skippable headers result from chunked transfer and proxy requests.
+ *
+ * @param string $data The string to check.
+ * @returns boolean Whether a skippable header was found.
+ * @access private
+ */
+ function isSkippableCurlHeader(&$data) {
+ $skipHeaders = array( 'HTTP/1.1 100',
+ 'HTTP/1.0 301',
+ 'HTTP/1.1 301',
+ 'HTTP/1.0 302',
+ 'HTTP/1.1 302',
+ 'HTTP/1.0 401',
+ 'HTTP/1.1 401',
+ 'HTTP/1.0 200 Connection established');
+ foreach ($skipHeaders as $hd) {
+ $prefix = substr($data, 0, strlen($hd));
+ if ($prefix == $hd) return true;
+ }
+
+ return false;
+ }
+
/**
* decode a string that is encoded w/ "chunked' transfer encoding
* as defined in RFC2068 19.4.6
@@ -2467,16 +2784,29 @@ class soap_transport_http extends nusoap_base { return $new;
}
- /*
- * Writes payload, including HTTP headers, to $this->outgoing_payload.
+ /**
+ * Writes the payload, including HTTP headers, to $this->outgoing_payload.
+ *
+ * @param string $data HTTP body
+ * @param string $cookie_str data for HTTP Cookie header
+ * @return void
+ * @access private
*/
function buildPayload($data, $cookie_str = '') {
+ // Note: for cURL connections, $this->outgoing_payload is ignored,
+ // as is the Content-Length header, but these are still created as
+ // debugging guides.
+
// add content-length header
- $this->outgoing_headers['Content-Length'] = strlen($data);
- $this->debug('set Content-Length: ' . $this->outgoing_headers['Content-Length']);
+ $this->setHeader('Content-Length', strlen($data));
// start building outgoing payload:
- $req = "$this->request_method $this->uri HTTP/$this->protocol_version";
+ if ($this->proxy) {
+ $uri = $this->url;
+ } else {
+ $uri = $this->uri;
+ }
+ $req = "$this->request_method $uri HTTP/$this->protocol_version";
$this->debug("HTTP request: $req");
$this->outgoing_payload = "$req\r\n";
@@ -2501,6 +2831,14 @@ class soap_transport_http extends nusoap_base { $this->outgoing_payload .= $data;
}
+ /**
+ * sends the SOAP request via HTTP[S]
+ *
+ * @param string $data message data
+ * @param array $cookies cookies to send
+ * @return boolean true if OK, false if problem
+ * @access private
+ */
function sendRequest($data, $cookies = NULL) {
// build cookie string
$cookie_str = $this->getCookiesForRequest($cookies, (($this->scheme == 'ssl') || ($this->scheme == 'https')));
@@ -2508,7 +2846,7 @@ class soap_transport_http extends nusoap_base { // build payload
$this->buildPayload($data, $cookie_str);
- if ($this->scheme == 'http' || $this->scheme == 'ssl') {
+ if ($this->io_method() == 'socket') {
// send payload
if(!fputs($this->fp, $this->outgoing_payload, strlen($this->outgoing_payload))) {
$this->setError('couldn\'t write message data to socket');
@@ -2517,33 +2855,51 @@ class soap_transport_http extends nusoap_base { }
$this->debug('wrote data to socket, length = ' . strlen($this->outgoing_payload));
return true;
- } else if ($this->scheme == 'https') {
+ } else if ($this->io_method() == 'curl') {
// set payload
- // TODO: cURL does say this should only be the verb, and in fact it
+ // cURL does say this should only be the verb, and in fact it
// turns out that the URI and HTTP version are appended to this, which
- // some servers refuse to work with
- //curl_setopt($this->ch, CURLOPT_CUSTOMREQUEST, $this->outgoing_payload);
+ // some servers refuse to work with (so we no longer use this method!)
+ //$this->setCurlOption(CURLOPT_CUSTOMREQUEST, $this->outgoing_payload);
+ $curl_headers = array();
foreach($this->outgoing_headers as $k => $v){
- $curl_headers[] = "$k: $v";
+ if ($k == 'Connection' || $k == 'Content-Length' || $k == 'Host' || $k == 'Authorization' || $k == 'Proxy-Authorization') {
+ $this->debug("Skip cURL header $k: $v");
+ } else {
+ $curl_headers[] = "$k: $v";
+ }
}
if ($cookie_str != '') {
$curl_headers[] = 'Cookie: ' . $cookie_str;
}
- curl_setopt($this->ch, CURLOPT_HTTPHEADER, $curl_headers);
+ $this->setCurlOption(CURLOPT_HTTPHEADER, $curl_headers);
+ $this->debug('set cURL HTTP headers');
if ($this->request_method == "POST") {
- curl_setopt($this->ch, CURLOPT_POST, 1);
- curl_setopt($this->ch, CURLOPT_POSTFIELDS, $data);
+ $this->setCurlOption(CURLOPT_POST, 1);
+ $this->setCurlOption(CURLOPT_POSTFIELDS, $data);
+ $this->debug('set cURL POST data');
} else {
}
+ // insert custom user-set cURL options
+ foreach ($this->ch_options as $key => $val) {
+ $this->setCurlOption($key, $val);
+ }
+
$this->debug('set cURL payload');
return true;
}
}
+ /**
+ * gets the SOAP response via HTTP[S]
+ *
+ * @return string the response (also sets member variables like incoming_payload)
+ * @access private
+ */
function getResponse(){
$this->incoming_payload = '';
- if ($this->scheme == 'http' || $this->scheme == 'ssl') {
+ if ($this->io_method() == 'socket') {
// loop until headers have been retrieved
$data = '';
while (!isset($lb)){
@@ -2579,8 +2935,8 @@ class soap_transport_http extends nusoap_base { $lb = "\n";
}
}
- // remove 100 header
- if(isset($lb) && ereg('^HTTP/1.1 100',$data)){
+ // remove 100 headers
+ if (isset($lb) && ereg('^HTTP/1.1 100',$data)) {
unset($lb);
$data = '';
}//
@@ -2706,7 +3062,7 @@ class soap_transport_http extends nusoap_base { // $this->incoming_payload = $header_data.$lb.$lb.$data;
// }
- } else if ($this->scheme == 'https') {
+ } else if ($this->io_method() == 'curl') {
// send and receive
$this->debug('send and receive with cURL');
$this->incoming_payload = curl_exec($this->ch);
@@ -2732,14 +3088,28 @@ class soap_transport_http extends nusoap_base { $this->debug('No cURL error, closing cURL');
curl_close($this->ch);
- // remove 100 header(s)
- while (ereg('^HTTP/1.1 100',$data)) {
+ // try removing skippable headers
+ $savedata = $data;
+ while ($this->isSkippableCurlHeader($data)) {
+ $this->debug("Found HTTP header to skip");
if ($pos = strpos($data,"\r\n\r\n")) {
$data = ltrim(substr($data,$pos));
} elseif($pos = strpos($data,"\n\n") ) {
$data = ltrim(substr($data,$pos));
}
}
+
+ if ($data == '') {
+ // have nothing left; just remove 100 header(s)
+ $data = $savedata;
+ while (ereg('^HTTP/1.1 100',$data)) {
+ if ($pos = strpos($data,"\r\n\r\n")) {
+ $data = ltrim(substr($data,$pos));
+ } elseif($pos = strpos($data,"\n\n") ) {
+ $data = ltrim(substr($data,$pos));
+ }
+ }
+ }
// separate content from HTTP headers
if ($pos = strpos($data,"\r\n\r\n")) {
@@ -2779,14 +3149,15 @@ class soap_transport_http extends nusoap_base { }
}
- $arr = explode(' ', $header_array[0], 3);
+ $this->response_status_line = $header_array[0];
+ $arr = explode(' ', $this->response_status_line, 3);
$http_version = $arr[0];
$http_status = intval($arr[1]);
$http_reason = count($arr) > 2 ? $arr[2] : '';
// see if we need to resend the request with http digest authentication
- if (isset($this->incoming_headers['location']) && $http_status == 301) {
- $this->debug("Got 301 $http_reason with Location: " . $this->incoming_headers['location']);
+ if (isset($this->incoming_headers['location']) && ($http_status == 301 || $http_status == 302)) {
+ $this->debug("Got $http_status $http_reason with Location: " . $this->incoming_headers['location']);
$this->setURL($this->incoming_headers['location']);
$this->tryagain = true;
return false;
@@ -2896,19 +3267,30 @@ class soap_transport_http extends nusoap_base { return $data;
}
+ /**
+ * sets the content-type for the SOAP message to be sent
+ *
+ * @param string $type the content type, MIME style
+ * @param mixed $charset character set used for encoding (or false)
+ * @access public
+ */
function setContentType($type, $charset = false) {
- $this->outgoing_headers['Content-Type'] = $type . ($charset ? '; charset=' . $charset : '');
- $this->debug('set Content-Type: ' . $this->outgoing_headers['Content-Type']);
+ $this->setHeader('Content-Type', $type . ($charset ? '; charset=' . $charset : ''));
}
+ /**
+ * specifies that an HTTP persistent connection should be used
+ *
+ * @return boolean whether the request was honored by this method.
+ * @access public
+ */
function usePersistentConnection(){
if (isset($this->outgoing_headers['Accept-Encoding'])) {
return false;
}
$this->protocol_version = '1.1';
$this->persistentConnection = true;
- $this->outgoing_headers['Connection'] = 'Keep-Alive';
- $this->debug('set Connection: ' . $this->outgoing_headers['Connection']);
+ $this->setHeader('Connection', 'Keep-Alive');
return true;
}
@@ -3032,16 +3414,15 @@ class soap_transport_http extends nusoap_base { /**
*
-* soap_server allows the user to create a SOAP server
+* nusoap_server allows the user to create a SOAP server
* that is capable of receiving messages and returning responses
*
-* NOTE: WSDL functionality is experimental
-*
* @author Dietrich Ayala <dietrich@ganx4.com>
-* @version $Id: nusoap.php,v 1.94 2005/08/04 01:27:42 snichol Exp $
+* @author Scott Nichol <snichol@users.sourceforge.net>
+* @version $Id: nusoap.php,v 1.114 2007/11/06 15:17:46 snichol Exp $
* @access public
*/
-class soap_server extends nusoap_base {
+class nusoap_server extends nusoap_base {
/**
* HTTP headers of request
* @var array
@@ -3061,6 +3442,12 @@ class soap_server extends nusoap_base { */
var $requestHeaders = '';
/**
+ * SOAP Headers from request (parsed)
+ * @var mixed
+ * @access public
+ */
+ var $requestHeader = NULL;
+ /**
* SOAP body request portion (incomplete namespace resolution; special characters not escaped) (text)
* @var string
* @access public
@@ -3122,8 +3509,8 @@ class soap_server extends nusoap_base { */
var $response = '';
/**
- * SOAP headers for response (text)
- * @var string
+ * SOAP headers for response (text or array of soapval or associative array)
+ * @var mixed
* @access public
*/
var $responseHeaders = '';
@@ -3192,7 +3579,7 @@ class soap_server extends nusoap_base { * @param mixed $wsdl file path or URL (string), or wsdl instance (object)
* @access public
*/
- function soap_server($wsdl=false){
+ function nusoap_server($wsdl=false){
parent::nusoap_base();
// turn on debugging?
global $debug;
@@ -3209,13 +3596,13 @@ class soap_server extends nusoap_base { }
if (isset($debug)) {
- $this->debug("In soap_server, set debug_flag=$debug based on global flag");
+ $this->debug("In nusoap_server, set debug_flag=$debug based on global flag");
$this->debug_flag = $debug;
} elseif (isset($_SERVER['QUERY_STRING'])) {
$qs = explode('&', $_SERVER['QUERY_STRING']);
foreach ($qs as $v) {
if (substr($v, 0, 6) == 'debug=') {
- $this->debug("In soap_server, set debug_flag=" . substr($v, 6) . " based on query string #1");
+ $this->debug("In nusoap_server, set debug_flag=" . substr($v, 6) . " based on query string #1");
$this->debug_flag = substr($v, 6);
}
}
@@ -3223,7 +3610,7 @@ class soap_server extends nusoap_base { $qs = explode('&', $HTTP_SERVER_VARS['QUERY_STRING']);
foreach ($qs as $v) {
if (substr($v, 0, 6) == 'debug=') {
- $this->debug("In soap_server, set debug_flag=" . substr($v, 6) . " based on query string #2");
+ $this->debug("In nusoap_server, set debug_flag=" . substr($v, 6) . " based on query string #2");
$this->debug_flag = substr($v, 6);
}
}
@@ -3231,7 +3618,7 @@ class soap_server extends nusoap_base { // wsdl
if($wsdl){
- $this->debug("In soap_server, WSDL is specified");
+ $this->debug("In nusoap_server, WSDL is specified");
if (is_object($wsdl) && (get_class($wsdl) == 'wsdl')) {
$this->wsdl = $wsdl;
$this->externalWSDLURL = $this->wsdl->wsdl;
@@ -3351,9 +3738,9 @@ class soap_server extends nusoap_base { $this->debug("In parse_http_headers, use _SERVER");
foreach ($_SERVER as $k => $v) {
if (substr($k, 0, 5) == 'HTTP_') {
- $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($k, 5)))); $k = strtolower(substr($k, 5));
+ $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($k, 5))));
} else {
- $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', $k))); $k = strtolower($k);
+ $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', $k)));
}
if ($k == 'soapaction') {
// get SOAPAction header
@@ -3458,11 +3845,11 @@ class soap_server extends nusoap_base { } elseif ($this->headers['content-encoding'] == 'gzip' && $degzdata = gzinflate(substr($data, 10))) {
$data = $degzdata;
} else {
- $this->fault('Client', 'Errors occurred when trying to decode the data');
+ $this->fault('SOAP-ENV:Client', 'Errors occurred when trying to decode the data');
return;
}
} else {
- $this->fault('Client', 'This Server does not support compressed data');
+ $this->fault('SOAP-ENV:Client', 'This Server does not support compressed data');
return;
}
}
@@ -3504,7 +3891,7 @@ class soap_server extends nusoap_base { $this->methodname = $this->opData['name'];
} else {
$this->debug('in invoke_method, no WSDL for operation=' . $this->methodname);
- $this->fault('Client', "Operation '" . $this->methodname . "' is not defined in the WSDL for this service");
+ $this->fault('SOAP-ENV:Client', "Operation '" . $this->methodname . "' is not defined in the WSDL for this service");
return;
}
} else {
@@ -3537,7 +3924,7 @@ class soap_server extends nusoap_base { if (!function_exists($this->methodname)) {
$this->debug("in invoke_method, function '$this->methodname' not found!");
$this->result = 'fault: method not found';
- $this->fault('Client',"method '$this->methodname' not defined in service");
+ $this->fault('SOAP-ENV:Client',"method '$this->methodname' not defined in service");
return;
}
} else {
@@ -3545,7 +3932,7 @@ class soap_server extends nusoap_base { if (!in_array($method_to_compare, get_class_methods($class))) {
$this->debug("in invoke_method, method '$this->methodname' not found in class '$class'!");
$this->result = 'fault: method not found';
- $this->fault('Client',"method '$this->methodname' not defined in service");
+ $this->fault('SOAP-ENV:Client',"method '$this->methodname' not defined in service");
return;
}
}
@@ -3557,7 +3944,7 @@ class soap_server extends nusoap_base { $this->debug('ERROR: request not verified against method signature');
$this->result = 'fault: request failed validation against method signature';
// return fault
- $this->fault('Client',"Operation '$this->methodname' not defined in service.");
+ $this->fault('SOAP-ENV:Client',"Operation '$this->methodname' not defined in service.");
return;
}
@@ -3583,8 +3970,8 @@ class soap_server extends nusoap_base { }
if ($this->methodparams) {
foreach ($this->methodparams as $param) {
- if (is_array($param)) {
- $this->fault('Client', 'NuSOAP does not handle complexType parameters correctly when using eval; call_user_func_array must be available');
+ if (is_array($param) || is_object($param)) {
+ $this->fault('SOAP-ENV:Client', 'NuSOAP does not handle complexType parameters correctly when using eval; call_user_func_array must be available');
return;
}
$funcCall .= "\"$param\",";
@@ -3606,11 +3993,15 @@ class soap_server extends nusoap_base { $instance = new $class ();
$call_arg = array(&$instance, $method);
}
- $this->methodreturn = call_user_func_array($call_arg, $this->methodparams);
+ if (is_array($this->methodparams)) {
+ $this->methodreturn = call_user_func_array($call_arg, array_values($this->methodparams));
+ } else {
+ $this->methodreturn = call_user_func_array($call_arg, array());
+ }
}
$this->debug('in invoke_method, methodreturn:');
$this->appendDebug($this->varDump($this->methodreturn));
- $this->debug("in invoke_method, called method $this->methodname, received $this->methodreturn of type ".gettype($this->methodreturn));
+ $this->debug("in invoke_method, called method $this->methodname, received data of type ".gettype($this->methodreturn));
}
/**
@@ -3627,7 +4018,7 @@ class soap_server extends nusoap_base { function serialize_return() {
$this->debug('Entering serialize_return methodname: ' . $this->methodname . ' methodURI: ' . $this->methodURI);
// if fault
- if (isset($this->methodreturn) && (get_class($this->methodreturn) == 'soap_fault')) {
+ if (isset($this->methodreturn) && ((get_class($this->methodreturn) == 'soap_fault') || (get_class($this->methodreturn) == 'nusoap_fault'))) {
$this->debug('got a fault object from method');
$this->fault = $this->methodreturn;
return;
@@ -3638,11 +4029,15 @@ class soap_server extends nusoap_base { $this->debug('got a(n) '.gettype($this->methodreturn).' from method');
$this->debug('serializing return value');
if($this->wsdl){
- // weak attempt at supporting multiple output params
- if(sizeof($this->opData['output']['parts']) > 1){
+ if (sizeof($this->opData['output']['parts']) > 1) {
+ $this->debug('more than one output part, so use the method return unchanged');
$opParams = $this->methodreturn;
- } else {
- // TODO: is this really necessary?
+ } elseif (sizeof($this->opData['output']['parts']) == 1) {
+ $this->debug('exactly one output part, so wrap the method return in a simple array');
+ // TODO: verify that it is not already wrapped!
+ //foreach ($this->opData['output']['parts'] as $name => $type) {
+ // $this->debug('wrap in element named ' . $name);
+ //}
$opParams = array($this->methodreturn);
}
$return_val = $this->wsdl->serializeRPCParameters($this->methodname,'output',$opParams);
@@ -3650,7 +4045,7 @@ class soap_server extends nusoap_base { $this->wsdl->clearDebug();
if($errstr = $this->wsdl->getError()){
$this->debug('got wsdl error: '.$errstr);
- $this->fault('Server', 'unable to serialize result');
+ $this->fault('SOAP-ENV:Server', 'unable to serialize result');
return;
}
} else {
@@ -3671,7 +4066,8 @@ class soap_server extends nusoap_base { if ($this->opData['style'] == 'rpc') {
$this->debug('style is rpc for serialization: use is ' . $this->opData['output']['use']);
if ($this->opData['output']['use'] == 'literal') {
- $payload = '<'.$this->methodname.'Response xmlns="'.$this->methodURI.'">'.$return_val.'</'.$this->methodname."Response>";
+ // http://www.ws-i.org/Profiles/BasicProfile-1.1-2004-08-24.html R2735 says rpc/literal accessor elements should not be in a namespace
+ $payload = '<ns1:'.$this->methodname.'Response xmlns:ns1="'.$this->methodURI.'">'.$return_val.'</ns1:'.$this->methodname."Response>";
} else {
$payload = '<ns1:'.$this->methodname.'Response xmlns:ns1="'.$this->methodURI.'">'.$return_val.'</ns1:'.$this->methodname."Response>";
}
@@ -3694,7 +4090,7 @@ class soap_server extends nusoap_base { $encodingStyle = '';
}
// Added: In case we use a WSDL, return a serialized env. WITH the usedNamespaces.
- $this->responseSOAP = $this->serializeEnvelope($payload,$this->responseHeaders,$this->wsdl->usedNamespaces,$this->opData['style'],$encodingStyle);
+ $this->responseSOAP = $this->serializeEnvelope($payload,$this->responseHeaders,$this->wsdl->usedNamespaces,$this->opData['style'],$this->opData['output']['use'],$encodingStyle);
} else {
$this->responseSOAP = $this->serializeEnvelope($payload,$this->responseHeaders);
}
@@ -3827,25 +4223,27 @@ class soap_server extends nusoap_base { // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
$this->xml_encoding = 'ISO-8859-1';
}
- $this->debug('Use encoding: ' . $this->xml_encoding . ' when creating soap_parser');
+ $this->debug('Use encoding: ' . $this->xml_encoding . ' when creating nusoap_parser');
// parse response, get soap parser obj
- $parser = new soap_parser($data,$this->xml_encoding,'',$this->decode_utf8);
+ $parser = new nusoap_parser($data,$this->xml_encoding,'',$this->decode_utf8);
// parser debug
$this->debug("parser debug: \n".$parser->getDebug());
// if fault occurred during message parsing
if($err = $parser->getError()){
$this->result = 'fault: error in msg parsing: '.$err;
- $this->fault('Client',"error in msg parsing:\n".$err);
+ $this->fault('SOAP-ENV:Client',"error in msg parsing:\n".$err);
// else successfully parsed request into soapval object
} else {
// get/set methodname
$this->methodURI = $parser->root_struct_namespace;
$this->methodname = $parser->root_struct_name;
$this->debug('methodname: '.$this->methodname.' methodURI: '.$this->methodURI);
- $this->debug('calling parser->get_response()');
- $this->methodparams = $parser->get_response();
+ $this->debug('calling parser->get_soapbody()');
+ $this->methodparams = $parser->get_soapbody();
// get SOAP headers
$this->requestHeaders = $parser->getHeaders();
+ // get SOAP Header
+ $this->requestHeader = $parser->get_soapheader();
// add document for doclit support
$this->document = $parser->document;
}
@@ -3935,13 +4333,20 @@ class soap_server extends nusoap_base { if (isset($_SERVER)) {
$SERVER_NAME = $_SERVER['SERVER_NAME'];
$SCRIPT_NAME = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME'];
+ $HTTPS = isset($_SERVER['HTTPS']) ? $_SERVER['HTTPS'] : (isset($HTTP_SERVER_VARS['HTTPS']) ? $HTTP_SERVER_VARS['HTTPS'] : 'off');
} elseif (isset($HTTP_SERVER_VARS)) {
$SERVER_NAME = $HTTP_SERVER_VARS['SERVER_NAME'];
$SCRIPT_NAME = isset($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : $HTTP_SERVER_VARS['SCRIPT_NAME'];
+ $HTTPS = isset($HTTP_SERVER_VARS['HTTPS']) ? $HTTP_SERVER_VARS['HTTPS'] : 'off';
} else {
$this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available");
}
- $soapaction = "http://$SERVER_NAME$SCRIPT_NAME/$name";
+ if ($HTTPS == '1' || $HTTPS == 'on') {
+ $SCHEME = 'https';
+ } else {
+ $SCHEME = 'http';
+ }
+ $soapaction = "$SCHEME://$SERVER_NAME$SCRIPT_NAME/$name";
}
if(false == $style) {
$style = "rpc";
@@ -3980,7 +4385,7 @@ class soap_server extends nusoap_base { if ($faultdetail == '' && $this->debug_flag) {
$faultdetail = $this->getDebug();
}
- $this->fault = new soap_fault($faultcode,$faultactor,$faultstring,$faultdetail);
+ $this->fault = new nusoap_fault($faultcode,$faultactor,$faultstring,$faultdetail);
$this->fault->soap_defencoding = $this->soap_defencoding;
}
@@ -4003,15 +4408,20 @@ class soap_server extends nusoap_base { $SERVER_NAME = $_SERVER['SERVER_NAME'];
$SERVER_PORT = $_SERVER['SERVER_PORT'];
$SCRIPT_NAME = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME'];
- $HTTPS = $_SERVER['HTTPS'];
+ $HTTPS = isset($_SERVER['HTTPS']) ? $_SERVER['HTTPS'] : (isset($HTTP_SERVER_VARS['HTTPS']) ? $HTTP_SERVER_VARS['HTTPS'] : 'off');
} elseif (isset($HTTP_SERVER_VARS)) {
$SERVER_NAME = $HTTP_SERVER_VARS['SERVER_NAME'];
$SERVER_PORT = $HTTP_SERVER_VARS['SERVER_PORT'];
$SCRIPT_NAME = isset($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : $HTTP_SERVER_VARS['SCRIPT_NAME'];
- $HTTPS = $HTTP_SERVER_VARS['HTTPS'];
+ $HTTPS = isset($HTTP_SERVER_VARS['HTTPS']) ? $HTTP_SERVER_VARS['HTTPS'] : 'off';
} else {
$this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available");
}
+ // If server name has port number attached then strip it (else port number gets duplicated in WSDL output) (occurred using lighttpd and FastCGI)
+ $colon = strpos($SERVER_NAME,":");
+ if ($colon) {
+ $SERVER_NAME = substr($SERVER_NAME, 0, $colon);
+ }
if ($SERVER_PORT == 80) {
$SERVER_PORT = '';
} else {
@@ -4043,7 +4453,10 @@ class soap_server extends nusoap_base { if ($schemaTargetNamespace != $namespace) {
$this->wsdl->namespaces['types'] = $schemaTargetNamespace;
}
- $this->wsdl->schemas[$schemaTargetNamespace][0] = new xmlschema('', '', $this->wsdl->namespaces);
+ $this->wsdl->schemas[$schemaTargetNamespace][0] = new nusoap_xmlschema('', '', $this->wsdl->namespaces);
+ if ($style == 'document') {
+ $this->wsdl->schemas[$schemaTargetNamespace][0]->schemaInfo['elementFormDefault'] = 'qualified';
+ }
$this->wsdl->schemas[$schemaTargetNamespace][0]->schemaTargetNamespace = $schemaTargetNamespace;
$this->wsdl->schemas[$schemaTargetNamespace][0]->imports['http://schemas.xmlsoap.org/soap/encoding/'][0] = array('location' => '', 'loaded' => true);
$this->wsdl->schemas[$schemaTargetNamespace][0]->imports['http://schemas.xmlsoap.org/wsdl/'][0] = array('location' => '', 'loaded' => true);
@@ -4059,17 +4472,23 @@ class soap_server extends nusoap_base { }
}
-
+/**
+ * Backward compatibility
+ */
+class soap_server extends nusoap_server {
+}
?><?php
/**
-* parses a WSDL file, allows access to it's data, other utility methods
+* parses a WSDL file, allows access to it's data, other utility methods.
+* also builds WSDL structures programmatically.
*
* @author Dietrich Ayala <dietrich@ganx4.com>
-* @version $Id: nusoap.php,v 1.94 2005/08/04 01:27:42 snichol Exp $
+* @author Scott Nichol <snichol@users.sourceforge.net>
+* @version $Id: nusoap.php,v 1.114 2007/11/06 15:17:46 snichol Exp $
* @access public
*/
class wsdl extends nusoap_base {
@@ -4107,6 +4526,13 @@ class wsdl extends nusoap_base { var $proxypassword = '';
var $timeout = 0;
var $response_timeout = 30;
+ var $curl_options = array(); // User-specified cURL options
+ var $use_curl = false; // whether to always try to use cURL
+ // for HTTP authentication
+ var $username = ''; // Username for HTTP authentication
+ var $password = ''; // Password for HTTP authentication
+ var $authtype = ''; // Type of HTTP authentication
+ var $certRequest = array(); // Certificate for HTTP SSL authentication
/**
* constructor
@@ -4118,82 +4544,96 @@ class wsdl extends nusoap_base { * @param string $proxypassword
* @param integer $timeout set the connection timeout
* @param integer $response_timeout set the response timeout
+ * @param array $curl_options user-specified cURL options
+ * @param boolean $use_curl try to use cURL
* @access public
*/
- function wsdl($wsdl = '',$proxyhost=false,$proxyport=false,$proxyusername=false,$proxypassword=false,$timeout=0,$response_timeout=30){
+ function wsdl($wsdl = '',$proxyhost=false,$proxyport=false,$proxyusername=false,$proxypassword=false,$timeout=0,$response_timeout=30,$curl_options=null,$use_curl=false){
parent::nusoap_base();
- $this->wsdl = $wsdl;
+ $this->debug("ctor wsdl=$wsdl timeout=$timeout response_timeout=$response_timeout");
$this->proxyhost = $proxyhost;
$this->proxyport = $proxyport;
$this->proxyusername = $proxyusername;
$this->proxypassword = $proxypassword;
$this->timeout = $timeout;
$this->response_timeout = $response_timeout;
-
+ if (is_array($curl_options))
+ $this->curl_options = $curl_options;
+ $this->use_curl = $use_curl;
+ $this->fetchWSDL($wsdl);
+ }
+
+ /**
+ * fetches the WSDL document and parses it
+ *
+ * @access public
+ */
+ function fetchWSDL($wsdl) {
+ $this->debug("parse and process WSDL path=$wsdl");
+ $this->wsdl = $wsdl;
// parse wsdl file
- if ($wsdl != "") {
- $this->debug('initial wsdl URL: ' . $wsdl);
- $this->parseWSDL($wsdl);
+ if ($this->wsdl != "") {
+ $this->parseWSDL($this->wsdl);
}
// imports
// TODO: handle imports more properly, grabbing them in-line and nesting them
- $imported_urls = array();
- $imported = 1;
- while ($imported > 0) {
- $imported = 0;
- // Schema imports
- foreach ($this->schemas as $ns => $list) {
- foreach ($list as $xs) {
- $wsdlparts = parse_url($this->wsdl); // this is bogusly simple!
- foreach ($xs->imports as $ns2 => $list2) {
- for ($ii = 0; $ii < count($list2); $ii++) {
- if (! $list2[$ii]['loaded']) {
- $this->schemas[$ns]->imports[$ns2][$ii]['loaded'] = true;
- $url = $list2[$ii]['location'];
- if ($url != '') {
- $urlparts = parse_url($url);
- if (!isset($urlparts['host'])) {
- $url = $wsdlparts['scheme'] . '://' . $wsdlparts['host'] . (isset($wsdlparts['port']) ? ':' .$wsdlparts['port'] : '') .
- substr($wsdlparts['path'],0,strrpos($wsdlparts['path'],'/') + 1) .$urlparts['path'];
- }
- if (! in_array($url, $imported_urls)) {
- $this->parseWSDL($url);
- $imported++;
- $imported_urls[] = $url;
- }
- } else {
- $this->debug("Unexpected scenario: empty URL for unloaded import");
+ $imported_urls = array();
+ $imported = 1;
+ while ($imported > 0) {
+ $imported = 0;
+ // Schema imports
+ foreach ($this->schemas as $ns => $list) {
+ foreach ($list as $xs) {
+ $wsdlparts = parse_url($this->wsdl); // this is bogusly simple!
+ foreach ($xs->imports as $ns2 => $list2) {
+ for ($ii = 0; $ii < count($list2); $ii++) {
+ if (! $list2[$ii]['loaded']) {
+ $this->schemas[$ns]->imports[$ns2][$ii]['loaded'] = true;
+ $url = $list2[$ii]['location'];
+ if ($url != '') {
+ $urlparts = parse_url($url);
+ if (!isset($urlparts['host'])) {
+ $url = $wsdlparts['scheme'] . '://' . $wsdlparts['host'] . (isset($wsdlparts['port']) ? ':' .$wsdlparts['port'] : '') .
+ substr($wsdlparts['path'],0,strrpos($wsdlparts['path'],'/') + 1) .$urlparts['path'];
}
+ if (! in_array($url, $imported_urls)) {
+ $this->parseWSDL($url);
+ $imported++;
+ $imported_urls[] = $url;
+ }
+ } else {
+ $this->debug("Unexpected scenario: empty URL for unloaded import");
}
}
- }
- }
- }
- // WSDL imports
- $wsdlparts = parse_url($this->wsdl); // this is bogusly simple!
- foreach ($this->import as $ns => $list) {
- for ($ii = 0; $ii < count($list); $ii++) {
- if (! $list[$ii]['loaded']) {
- $this->import[$ns][$ii]['loaded'] = true;
- $url = $list[$ii]['location'];
- if ($url != '') {
- $urlparts = parse_url($url);
- if (!isset($urlparts['host'])) {
- $url = $wsdlparts['scheme'] . '://' . $wsdlparts['host'] . (isset($wsdlparts['port']) ? ':' . $wsdlparts['port'] : '') .
- substr($wsdlparts['path'],0,strrpos($wsdlparts['path'],'/') + 1) .$urlparts['path'];
- }
- if (! in_array($url, $imported_urls)) {
- $this->parseWSDL($url);
- $imported++;
- $imported_urls[] = $url;
- }
- } else {
- $this->debug("Unexpected scenario: empty URL for unloaded import");
+ }
+ }
+ }
+ }
+ // WSDL imports
+ $wsdlparts = parse_url($this->wsdl); // this is bogusly simple!
+ foreach ($this->import as $ns => $list) {
+ for ($ii = 0; $ii < count($list); $ii++) {
+ if (! $list[$ii]['loaded']) {
+ $this->import[$ns][$ii]['loaded'] = true;
+ $url = $list[$ii]['location'];
+ if ($url != '') {
+ $urlparts = parse_url($url);
+ if (!isset($urlparts['host'])) {
+ $url = $wsdlparts['scheme'] . '://' . $wsdlparts['host'] . (isset($wsdlparts['port']) ? ':' . $wsdlparts['port'] : '') .
+ substr($wsdlparts['path'],0,strrpos($wsdlparts['path'],'/') + 1) .$urlparts['path'];
}
+ if (! in_array($url, $imported_urls)) {
+ $this->parseWSDL($url);
+ $imported++;
+ $imported_urls[] = $url;
+ }
+ } else {
+ $this->debug("Unexpected scenario: empty URL for unloaded import");
}
}
- }
- }
+ }
+ }
+ }
// add new data to operation data
foreach($this->bindings as $binding => $bindingData) {
if (isset($bindingData['operations']) && is_array($bindingData['operations'])) {
@@ -4213,7 +4653,8 @@ class wsdl extends nusoap_base { if(isset($this->messages[ $this->bindings[$binding]['operations'][$operation]['output']['message'] ])){
$this->bindings[$binding]['operations'][$operation]['output']['parts'] = $this->messages[ $this->bindings[$binding]['operations'][$operation]['output']['message'] ];
}
- if (isset($bindingData['style'])) {
+ // Set operation style if necessary, but do not override one already provided
+ if (isset($bindingData['style']) && !isset($this->bindings[$binding]['operations'][$operation]['style'])) {
$this->bindings[$binding]['operations'][$operation]['style'] = $bindingData['style'];
}
$this->bindings[$binding]['operations'][$operation]['transport'] = isset($bindingData['transport']) ? $bindingData['transport'] : '';
@@ -4222,7 +4663,7 @@ class wsdl extends nusoap_base { }
}
}
- }
+ }
/**
* parses the wsdl document
@@ -4230,8 +4671,9 @@ class wsdl extends nusoap_base { * @param string $wsdl path or URL
* @access private
*/
- function parseWSDL($wsdl = '')
- {
+ function parseWSDL($wsdl = '') {
+ $this->debug("parse WSDL at path=$wsdl");
+
if ($wsdl == '') {
$this->debug('no wsdl passed to parseWSDL()!!');
$this->setError('no wsdl passed to parseWSDL()!!');
@@ -4244,12 +4686,15 @@ class wsdl extends nusoap_base { if (isset($wsdl_props['scheme']) && ($wsdl_props['scheme'] == 'http' || $wsdl_props['scheme'] == 'https')) {
$this->debug('getting WSDL http(s) URL ' . $wsdl);
// get wsdl
- $tr = new soap_transport_http($wsdl);
+ $tr = new soap_transport_http($wsdl, $this->curl_options, $this->use_curl);
$tr->request_method = 'GET';
$tr->useSOAPAction = false;
if($this->proxyhost && $this->proxyport){
$tr->setProxy($this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword);
}
+ if ($this->authtype != '') {
+ $tr->setCredentials($this->username, $this->password, $this->authtype, array(), $this->certRequest);
+ }
$tr->setEncoding('gzip, deflate');
$wsdl_string = $tr->send('', $this->timeout, $this->response_timeout);
//$this->debug("WSDL request\n" . $tr->outgoing_payload);
@@ -4340,7 +4785,7 @@ class wsdl extends nusoap_base { $this->debug('Parsing WSDL schema');
// $this->debug("startElement for $name ($attrs[name]). status = $this->status (".$this->getLocalPart($name).")");
$this->status = 'schema';
- $this->currentSchema = new xmlschema('', '', $this->namespaces);
+ $this->currentSchema = new nusoap_xmlschema('', '', $this->namespaces);
$this->currentSchema->schemaStartElement($parser, $name, $attrs);
$this->appendDebug($this->currentSchema->getDebug());
$this->currentSchema->clearDebug();
@@ -4394,12 +4839,12 @@ class wsdl extends nusoap_base { case 'message':
if ($name == 'part') {
if (isset($attrs['type'])) {
- $this->debug("msg " . $this->currentMessage . ": found part $attrs[name]: " . implode(',', $attrs));
+ $this->debug("msg " . $this->currentMessage . ": found part (with type) $attrs[name]: " . implode(',', $attrs));
$this->messages[$this->currentMessage][$attrs['name']] = $attrs['type'];
}
if (isset($attrs['element'])) {
- $this->debug("msg " . $this->currentMessage . ": found part $attrs[name]: " . implode(',', $attrs));
- $this->messages[$this->currentMessage][$attrs['name']] = $attrs['element'];
+ $this->debug("msg " . $this->currentMessage . ": found part (with element) $attrs[name]: " . implode(',', $attrs));
+ $this->messages[$this->currentMessage][$attrs['name']] = $attrs['element'] . '^';
}
}
break;
@@ -4584,6 +5029,24 @@ class wsdl extends nusoap_base { }
}
+ /**
+ * if authenticating, set user credentials here
+ *
+ * @param string $username
+ * @param string $password
+ * @param string $authtype (basic|digest|certificate|ntlm)
+ * @param array $certRequest (keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, certpassword (optional), verifypeer (optional), verifyhost (optional): see corresponding options in cURL docs)
+ * @access public
+ */
+ function setCredentials($username, $password, $authtype = 'basic', $certRequest = array()) {
+ $this->debug("setCredentials username=$username authtype=$authtype certRequest=");
+ $this->appendDebug($this->varDump($certRequest));
+ $this->username = $username;
+ $this->password = $password;
+ $this->authtype = $authtype;
+ $this->certRequest = $certRequest;
+ }
+
function getBindingData($binding)
{
if (is_array($this->bindings[$binding])) {
@@ -4594,15 +5057,16 @@ class wsdl extends nusoap_base { /**
* returns an assoc array of operation names => operation data
*
- * @param string $bindingType eg: soap, smtp, dime (only soap is currently supported)
+ * @param string $bindingType eg: soap, smtp, dime (only soap and soap12 are currently supported)
* @return array
* @access public
*/
- function getOperations($bindingType = 'soap')
- {
+ function getOperations($bindingType = 'soap') {
$ops = array();
if ($bindingType == 'soap') {
$bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/';
+ } elseif ($bindingType == 'soap12') {
+ $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap12/';
}
// loop thru ports
foreach($this->ports as $port => $portData) {
@@ -4623,8 +5087,8 @@ class wsdl extends nusoap_base { /**
* returns an associative array of data necessary for calling an operation
*
- * @param string $operation , name of operation
- * @param string $bindingType , type of binding eg: soap
+ * @param string $operation name of operation
+ * @param string $bindingType type of binding eg: soap, soap12
* @return array
* @access public
*/
@@ -4632,6 +5096,8 @@ class wsdl extends nusoap_base { {
if ($bindingType == 'soap') {
$bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/';
+ } elseif ($bindingType == 'soap12') {
+ $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap12/';
}
// loop thru ports
foreach($this->ports as $port => $portData) {
@@ -4654,13 +5120,15 @@ class wsdl extends nusoap_base { * returns an associative array of data necessary for calling an operation
*
* @param string $soapAction soapAction for operation
- * @param string $bindingType type of binding eg: soap
+ * @param string $bindingType type of binding eg: soap, soap12
* @return array
* @access public
*/
function getOperationDataForSoapAction($soapAction, $bindingType = 'soap') {
if ($bindingType == 'soap') {
$bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/';
+ } elseif ($bindingType == 'soap12') {
+ $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap12/';
}
// loop thru ports
foreach($this->ports as $port => $portData) {
@@ -4688,11 +5156,11 @@ class wsdl extends nusoap_base { * 'attrs' => array() // refs to attributes array
* )
*
- * @param $type string the type
- * @param $ns string namespace (not prefix) of the type
+ * @param string $type the type
+ * @param string $ns namespace (not prefix) of the type
* @return mixed
* @access public
- * @see xmlschema
+ * @see nusoap_xmlschema
*/
function getTypeDef($type, $ns) {
$this->debug("in getTypeDef: type=$type, ns=$ns");
@@ -4700,13 +5168,22 @@ class wsdl extends nusoap_base { $ns = $this->namespaces['tns'];
$this->debug("in getTypeDef: type namespace forced to $ns");
}
+ if (!isset($this->schemas[$ns])) {
+ foreach ($this->schemas as $ns0 => $schema0) {
+ if (strcasecmp($ns, $ns0) == 0) {
+ $this->debug("in getTypeDef: replacing schema namespace $ns with $ns0");
+ $ns = $ns0;
+ break;
+ }
+ }
+ }
if (isset($this->schemas[$ns])) {
$this->debug("in getTypeDef: have schema for namespace $ns");
for ($i = 0; $i < count($this->schemas[$ns]); $i++) {
$xs = &$this->schemas[$ns][$i];
$t = $xs->getTypeDef($type);
- $this->appendDebug($xs->getDebug());
- $xs->clearDebug();
+ //$this->appendDebug($xs->getDebug());
+ //$xs->clearDebug();
if ($t) {
if (!isset($t['phpType'])) {
// get info for type to tack onto the element
@@ -4753,7 +5230,7 @@ class wsdl extends nusoap_base { }
$b = '
- <html><head><title>xxvSOAP: '.$this->serviceName.'</title>
+ <html><head><title>NuSOAP: '.$this->serviceName.'</title>
<style type="text/css">
body { font-family: arial; color: #000000; background-color: #ffffff; margin: 0px 0px 0px 0px; }
p { font-family: arial; color: #000000; margin-top: 0px; margin-bottom: 12px; }
@@ -4903,7 +5380,7 @@ class wsdl extends nusoap_base { }
// types
if (count($this->schemas)>=1) {
- $xml .= "\n<types>";
+ $xml .= "\n<types>\n";
foreach ($this->schemas as $ns => $list) {
foreach ($list as $xs) {
$xml .= $xs->serializeSchema();
@@ -4934,13 +5411,17 @@ class wsdl extends nusoap_base { }
}
$ns = $this->getNamespaceFromPrefix($typePrefix);
- $typeDef = $this->getTypeDef($this->getLocalPart($partType), $ns);
+ $localPart = $this->getLocalPart($partType);
+ $typeDef = $this->getTypeDef($localPart, $ns);
if ($typeDef['typeClass'] == 'element') {
$elementortype = 'element';
+ if (substr($localPart, -1) == '^') {
+ $localPart = substr($localPart, 0, -1);
+ }
} else {
$elementortype = 'type';
}
- $xml .= '<part name="' . $partName . '" ' . $elementortype . '="' . $typePrefix . ':' . $this->getLocalPart($partType) . '" />';
+ $xml .= "\n" . ' <part name="' . $partName . '" ' . $elementortype . '="' . $typePrefix . ':' . $localPart . '" />';
}
}
$xml .= '</message>';
@@ -4952,38 +5433,38 @@ class wsdl extends nusoap_base { $portType_xml = '';
foreach($this->bindings as $bindingName => $attrs) {
$binding_xml .= "\n<binding name=\"" . $bindingName . '" type="tns:' . $attrs['portType'] . '">';
- $binding_xml .= '<soap:binding style="' . $attrs['style'] . '" transport="' . $attrs['transport'] . '"/>';
+ $binding_xml .= "\n" . ' <soap:binding style="' . $attrs['style'] . '" transport="' . $attrs['transport'] . '"/>';
$portType_xml .= "\n<portType name=\"" . $attrs['portType'] . '">';
foreach($attrs['operations'] as $opName => $opParts) {
- $binding_xml .= '<operation name="' . $opName . '">';
- $binding_xml .= '<soap:operation soapAction="' . $opParts['soapAction'] . '" style="'. $opParts['style'] . '"/>';
+ $binding_xml .= "\n" . ' <operation name="' . $opName . '">';
+ $binding_xml .= "\n" . ' <soap:operation soapAction="' . $opParts['soapAction'] . '" style="'. $opParts['style'] . '"/>';
if (isset($opParts['input']['encodingStyle']) && $opParts['input']['encodingStyle'] != '') {
$enc_style = ' encodingStyle="' . $opParts['input']['encodingStyle'] . '"';
} else {
$enc_style = '';
}
- $binding_xml .= '<input><soap:body use="' . $opParts['input']['use'] . '" namespace="' . $opParts['input']['namespace'] . '"' . $enc_style . '/></input>';
+ $binding_xml .= "\n" . ' <input><soap:body use="' . $opParts['input']['use'] . '" namespace="' . $opParts['input']['namespace'] . '"' . $enc_style . '/></input>';
if (isset($opParts['output']['encodingStyle']) && $opParts['output']['encodingStyle'] != '') {
$enc_style = ' encodingStyle="' . $opParts['output']['encodingStyle'] . '"';
} else {
$enc_style = '';
}
- $binding_xml .= '<output><soap:body use="' . $opParts['output']['use'] . '" namespace="' . $opParts['output']['namespace'] . '"' . $enc_style . '/></output>';
- $binding_xml .= '</operation>';
- $portType_xml .= '<operation name="' . $opParts['name'] . '"';
+ $binding_xml .= "\n" . ' <output><soap:body use="' . $opParts['output']['use'] . '" namespace="' . $opParts['output']['namespace'] . '"' . $enc_style . '/></output>';
+ $binding_xml .= "\n" . ' </operation>';
+ $portType_xml .= "\n" . ' <operation name="' . $opParts['name'] . '"';
if (isset($opParts['parameterOrder'])) {
$portType_xml .= ' parameterOrder="' . $opParts['parameterOrder'] . '"';
}
$portType_xml .= '>';
if(isset($opParts['documentation']) && $opParts['documentation'] != '') {
- $portType_xml .= '<documentation>' . htmlspecialchars($opParts['documentation']) . '</documentation>';
+ $portType_xml .= "\n" . ' <documentation>' . htmlspecialchars($opParts['documentation']) . '</documentation>';
}
- $portType_xml .= '<input message="tns:' . $opParts['input']['message'] . '"/>';
- $portType_xml .= '<output message="tns:' . $opParts['output']['message'] . '"/>';
- $portType_xml .= '</operation>';
+ $portType_xml .= "\n" . ' <input message="tns:' . $opParts['input']['message'] . '"/>';
+ $portType_xml .= "\n" . ' <output message="tns:' . $opParts['output']['message'] . '"/>';
+ $portType_xml .= "\n" . ' </operation>';
}
- $portType_xml .= '</portType>';
- $binding_xml .= '</binding>';
+ $portType_xml .= "\n" . '</portType>';
+ $binding_xml .= "\n" . '</binding>';
}
$xml .= $portType_xml . $binding_xml;
}
@@ -4991,17 +5472,105 @@ class wsdl extends nusoap_base { $xml .= "\n<service name=\"" . $this->serviceName . '">';
if (count($this->ports) >= 1) {
foreach($this->ports as $pName => $attrs) {
- $xml .= '<port name="' . $pName . '" binding="tns:' . $attrs['binding'] . '">';
- $xml .= '<soap:address location="' . $attrs['location'] . ($debug ? '?debug=1' : '') . '"/>';
- $xml .= '</port>';
+ $xml .= "\n" . ' <port name="' . $pName . '" binding="tns:' . $attrs['binding'] . '">';
+ $xml .= "\n" . ' <soap:address location="' . $attrs['location'] . ($debug ? '?debug=1' : '') . '"/>';
+ $xml .= "\n" . ' </port>';
}
}
- $xml .= '</service>';
+ $xml .= "\n" . '</service>';
return $xml . "\n</definitions>";
}
-
+
+ /**
+ * determine whether a set of parameters are unwrapped
+ * when they are expect to be wrapped, Microsoft-style.
+ *
+ * @param string $type the type (element name) of the wrapper
+ * @param array $parameters the parameter values for the SOAP call
+ * @return boolean whether they parameters are unwrapped (and should be wrapped)
+ * @access private
+ */
+ function parametersMatchWrapped($type, &$parameters) {
+ $this->debug("in parametersMatchWrapped type=$type, parameters=");
+ $this->appendDebug($this->varDump($parameters));
+
+ // split type into namespace:unqualified-type
+ if (strpos($type, ':')) {
+ $uqType = substr($type, strrpos($type, ':') + 1);
+ $ns = substr($type, 0, strrpos($type, ':'));
+ $this->debug("in parametersMatchWrapped: got a prefixed type: $uqType, $ns");
+ if ($this->getNamespaceFromPrefix($ns)) {
+ $ns = $this->getNamespaceFromPrefix($ns);
+ $this->debug("in parametersMatchWrapped: expanded prefixed type: $uqType, $ns");
+ }
+ } else {
+ // TODO: should the type be compared to types in XSD, and the namespace
+ // set to XSD if the type matches?
+ $this->debug("in parametersMatchWrapped: No namespace for type $type");
+ $ns = '';
+ $uqType = $type;
+ }
+
+ // get the type information
+ if (!$typeDef = $this->getTypeDef($uqType, $ns)) {
+ $this->debug("in parametersMatchWrapped: $type ($uqType) is not a supported type.");
+ return false;
+ }
+ $this->debug("in parametersMatchWrapped: found typeDef=");
+ $this->appendDebug($this->varDump($typeDef));
+ if (substr($uqType, -1) == '^') {
+ $uqType = substr($uqType, 0, -1);
+ }
+ $phpType = $typeDef['phpType'];
+ $arrayType = (isset($typeDef['arrayType']) ? $typeDef['arrayType'] : '');
+ $this->debug("in parametersMatchWrapped: uqType: $uqType, ns: $ns, phptype: $phpType, arrayType: $arrayType");
+
+ // we expect a complexType or element of complexType
+ if ($phpType != 'struct') {
+ $this->debug("in parametersMatchWrapped: not a struct");
+ return false;
+ }
+
+ // see whether the parameter names match the elements
+ if (isset($typeDef['elements']) && is_array($typeDef['elements'])) {
+ $elements = 0;
+ $matches = 0;
+ $change = false;
+ if ($this->isArraySimpleOrStruct($parameters) == 'arraySimple' && count($parameters) == count($typeDef['elements'])) {
+ $this->debug("in parametersMatchWrapped: (wrapped return value kludge) correct number of elements in simple array, so change array and wrap");
+ $change = true;
+ }
+ foreach ($typeDef['elements'] as $name => $attrs) {
+ if ($change) {
+ $this->debug("in parametersMatchWrapped: change parameter $element to name $name");
+ $parameters[$name] = $parameters[$elements];
+ unset($parameters[$elements]);
+ $matches++;
+ } elseif (isset($parameters[$name])) {
+ $this->debug("in parametersMatchWrapped: have parameter named $name");
+ $matches++;
+ } else {
+ $this->debug("in parametersMatchWrapped: do not have parameter named $name");
+ }
+ $elements++;
+ }
+
+ $this->debug("in parametersMatchWrapped: $matches parameter names match $elements wrapped parameter names");
+ if ($matches == 0) {
+ return false;
+ }
+ return true;
+ }
+
+ // since there are no elements for the type, if the user passed no
+ // parameters, the parameters match wrapped.
+ $this->debug("in parametersMatchWrapped: no elements type $ns:$uqType");
+ return count($parameters) == 0;
+ }
+
/**
* serialize PHP values according to a WSDL message definition
+ * contrary to the method name, this is not limited to RPC
*
* TODO
* - multi-ref serialization
@@ -5010,12 +5579,12 @@ class wsdl extends nusoap_base { * @param string $operation operation name
* @param string $direction (input|output)
* @param mixed $parameters parameter value(s)
+ * @param string $bindingType (soap|soap12)
* @return mixed parameters serialized as XML or false on error (e.g. operation not found)
* @access public
*/
- function serializeRPCParameters($operation, $direction, $parameters)
- {
- $this->debug("in serializeRPCParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion");
+ function serializeRPCParameters($operation, $direction, $parameters, $bindingType = 'soap') {
+ $this->debug("in serializeRPCParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion, bindingType=$bindingType");
$this->appendDebug('parameters=' . $this->varDump($parameters));
if ($direction != 'input' && $direction != 'output') {
@@ -5023,12 +5592,12 @@ class wsdl extends nusoap_base { $this->setError('The value of the \$direction argument needs to be either "input" or "output"');
return false;
}
- if (!$opData = $this->getOperationData($operation)) {
- $this->debug('Unable to retrieve WSDL data for operation: ' . $operation);
- $this->setError('Unable to retrieve WSDL data for operation: ' . $operation);
+ if (!$opData = $this->getOperationData($operation, $bindingType)) {
+ $this->debug('Unable to retrieve WSDL data for operation: ' . $operation . ' bindingType: ' . $bindingType);
+ $this->setError('Unable to retrieve WSDL data for operation: ' . $operation . ' bindingType: ' . $bindingType);
return false;
}
- $this->debug('opData:');
+ $this->debug('in serializeRPCParameters: opData:');
$this->appendDebug($this->varDump($opData));
// Get encoding style for output and set to current
@@ -5041,14 +5610,29 @@ class wsdl extends nusoap_base { // set input params
$xml = '';
if (isset($opData[$direction]['parts']) && sizeof($opData[$direction]['parts']) > 0) {
-
+ $parts = &$opData[$direction]['parts'];
+ $part_count = sizeof($parts);
+ $style = $opData['style'];
$use = $opData[$direction]['use'];
- $this->debug('have ' . count($opData[$direction]['parts']) . ' part(s) to serialize');
+ $this->debug("have $part_count part(s) to serialize using $style/$use");
if (is_array($parameters)) {
$parametersArrayType = $this->isArraySimpleOrStruct($parameters);
- $this->debug('have ' . count($parameters) . ' parameter(s) provided as ' . $parametersArrayType . ' to serialize');
- foreach($opData[$direction]['parts'] as $name => $type) {
- $this->debug('serializing part "'.$name.'" of type "'.$type.'"');
+ $parameter_count = count($parameters);
+ $this->debug("have $parameter_count parameter(s) provided as $parametersArrayType to serialize");
+ // check for Microsoft-style wrapped parameters
+ if ($style == 'document' && $use == 'literal' && $part_count == 1 && isset($parts['parameters'])) {
+ $this->debug('check whether the caller has wrapped the parameters');
+ if ((($parametersArrayType == 'arrayStruct' || $parameter_count == 0) && !isset($parameters['parameters'])) || ($direction == 'output' && $parametersArrayType == 'arraySimple' && $parameter_count == 1)) {
+ $this->debug('check whether caller\'s parameters match the wrapped ones');
+ if ($this->parametersMatchWrapped($parts['parameters'], $parameters)) {
+ $this->debug('wrap the parameters for the caller');
+ $parameters = array('parameters' => $parameters);
+ $parameter_count = 1;
+ }
+ }
+ }
+ foreach ($parts as $name => $type) {
+ $this->debug("serializing part $name of type $type");
// Track encoding style
if (isset($opData[$direction]['encodingStyle']) && $encodingStyle != $opData[$direction]['encodingStyle']) {
$encodingStyle = $opData[$direction]['encodingStyle'];
@@ -5086,9 +5670,10 @@ class wsdl extends nusoap_base { * - multi-ref serialization
* - validate PHP values against type definitions, return errors if invalid
*
- * @param string $ type name
- * @param mixed $ param value
- * @return mixed new param or false if initial value didn't validate
+ * @param string $operation operation name
+ * @param string $direction (input|output)
+ * @param mixed $parameters parameter value(s)
+ * @return mixed parameters serialized as XML or false on error (e.g. operation not found)
* @access public
* @deprecated
*/
@@ -5221,7 +5806,7 @@ class wsdl extends nusoap_base { if($ns == $this->XMLSchemaVersion || $ns == 'http://schemas.xmlsoap.org/soap/encoding/'){
$this->debug('in serializeType: type namespace indicates XML Schema or SOAP Encoding type');
- if ($unqualified && $use == 'literal') {
+ if ($unqualified && $use == 'literal') {
$elementNS = " xmlns=\"\"";
} else {
$elementNS = '';
@@ -5237,6 +5822,10 @@ class wsdl extends nusoap_base { $this->debug("in serializeType: returning: $xml");
return $xml;
}
+ if ($uqType == 'Array') {
+ // JBoss/Axis does this sometimes
+ return $this->serialize_val($value, $name, false, false, false, false, $use);
+ }
if ($uqType == 'boolean') {
if ((is_string($value) && $value == 'false') || (! $value)) {
$value = 'false';
@@ -5314,6 +5903,9 @@ class wsdl extends nusoap_base { } else {
$this->debug("in serializeType: found typeDef");
$this->appendDebug('typeDef=' . $this->varDump($typeDef));
+ if (substr($uqType, -1) == '^') {
+ $uqType = substr($uqType, 0, -1);
+ }
}
$phpType = $typeDef['phpType'];
$this->debug("in serializeType: uqType: $uqType, ns: $ns, phptype: $phpType, arrayType: " . (isset($typeDef['arrayType']) ? $typeDef['arrayType'] : '') );
@@ -5621,21 +6213,23 @@ class wsdl extends nusoap_base { /**
* adds an XML Schema complex type to the WSDL types
*
- * @param string name
- * @param string typeClass (complexType|simpleType|attribute)
- * @param string phpType: currently supported are array and struct (php assoc array)
- * @param string compositor (all|sequence|choice)
- * @param string restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array)
- * @param array elements = array ( name => array(name=>'',type=>'') )
- * @param array attrs = array(array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'xsd:string[]'))
- * @param string arrayType: namespace:name (xsd:string)
- * @see xmlschema
+ * @param string $name
+ * @param string $typeClass (complexType|simpleType|attribute)
+ * @param string $phpType currently supported are array and struct (php assoc array)
+ * @param string $compositor (all|sequence|choice)
+ * @param string $restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array)
+ * @param array $elements e.g. array ( name => array(name=>'',type=>'') )
+ * @param array $attrs e.g. array(array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'xsd:string[]'))
+ * @param string $arrayType as namespace:name (xsd:string)
+ * @see nusoap_xmlschema
* @access public
*/
function addComplexType($name,$typeClass='complexType',$phpType='array',$compositor='',$restrictionBase='',$elements=array(),$attrs=array(),$arrayType='') {
if (count($elements) > 0) {
+ $eElements = array();
foreach($elements as $n => $e){
// expand each element
+ $ee = array();
foreach ($e as $k => $v) {
$k = strpos($k,':') ? $this->expandQname($k) : $k;
$v = strpos($v,':') ? $this->expandQname($v) : $v;
@@ -5674,7 +6268,7 @@ class wsdl extends nusoap_base { * @param string $typeClass (should always be simpleType)
* @param string $phpType (should always be scalar)
* @param array $enumeration array of values
- * @see xmlschema
+ * @see nusoap_xmlschema
* @access public
*/
function addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array()) {
@@ -5688,7 +6282,7 @@ class wsdl extends nusoap_base { * adds an element to the WSDL types
*
* @param array $attrs attributes that must include name and type
- * @see xmlschema
+ * @see nusoap_xmlschema
* @access public
*/
function addElement($attrs) {
@@ -5722,15 +6316,15 @@ class wsdl extends nusoap_base { }
$this->addComplexType($name . 'RequestType', 'complexType', 'struct', 'all', '', $elements);
$this->addElement(array('name' => $name, 'type' => $name . 'RequestType'));
- $in = array('parameters' => 'tns:' . $name);
+ $in = array('parameters' => 'tns:' . $name . '^');
$elements = array();
foreach ($out as $n => $t) {
$elements[$n] = array('name' => $n, 'type' => $t);
}
$this->addComplexType($name . 'ResponseType', 'complexType', 'struct', 'all', '', $elements);
- $this->addElement(array('name' => $name . 'Response', 'type' => $name . 'ResponseType'));
- $out = array('parameters' => 'tns:' . $name . 'Response');
+ $this->addElement(array('name' => $name . 'Response', 'type' => $name . 'ResponseType', 'form' => 'qualified'));
+ $out = array('parameters' => 'tns:' . $name . 'Response' . '^');
}
// get binding
@@ -5791,13 +6385,14 @@ class wsdl extends nusoap_base { /**
*
-* soap_parser class parses SOAP XML messages into native PHP values
+* nusoap_parser class parses SOAP XML messages into native PHP values
*
* @author Dietrich Ayala <dietrich@ganx4.com>
-* @version $Id: nusoap.php,v 1.94 2005/08/04 01:27:42 snichol Exp $
+* @author Scott Nichol <snichol@users.sourceforge.net>
+* @version $Id: nusoap.php,v 1.114 2007/11/06 15:17:46 snichol Exp $
* @access public
*/
-class soap_parser extends nusoap_base {
+class nusoap_parser extends nusoap_base {
var $xml = '';
var $xml_encoding = '';
@@ -5821,7 +6416,8 @@ class soap_parser extends nusoap_base { var $fault_detail = '';
var $depth_array = array();
var $debug_flag = true;
- var $soapresponse = NULL;
+ var $soapresponse = NULL; // parsed SOAP Body
+ var $soapheader = NULL; // parsed SOAP Header
var $responseHeaders = ''; // incoming SOAP headers (text)
var $body_position = 0;
// for multiref parsing:
@@ -5841,7 +6437,7 @@ class soap_parser extends nusoap_base { * @param string $decode_utf8 whether to decode UTF-8 to ISO-8859-1
* @access public
*/
- function soap_parser($xml,$encoding='UTF-8',$method='',$decode_utf8=true){
+ function nusoap_parser($xml,$encoding='UTF-8',$method='',$decode_utf8=true){
parent::nusoap_base();
$this->xml = $xml;
$this->xml_encoding = $encoding;
@@ -5873,7 +6469,7 @@ class soap_parser extends nusoap_base { } else {
$this->debug('No XML declaration');
}
- $this->debug('Entering soap_parser(), length='.strlen($xml).', encoding='.$encoding);
+ $this->debug('Entering nusoap_parser(), length='.strlen($xml).', encoding='.$encoding);
// Create an XML parser - why not xml_parser_create_ns?
$this->parser = xml_parser_create($this->xml_encoding);
// Set the options for parsing the XML data.
@@ -5899,10 +6495,10 @@ class soap_parser extends nusoap_base { $this->debug('parsed successfully, found root struct: '.$this->root_struct.' of name '.$this->root_struct_name);
// get final value
$this->soapresponse = $this->message[$this->root_struct]['result'];
- // get header value: no, because this is documented as XML string
-// if($this->root_header != '' && isset($this->message[$this->root_header]['result'])){
-// $this->responseHeaders = $this->message[$this->root_header]['result'];
-// }
+ // get header value
+ if($this->root_header != '' && isset($this->message[$this->root_header]['result'])){
+ $this->soapheader = $this->message[$this->root_header]['result'];
+ }
// resolve hrefs/ids
if(sizeof($this->multirefs) > 0){
foreach($this->multirefs as $id => $hrefs){
@@ -5963,10 +6559,10 @@ class soap_parser extends nusoap_base { // set status
if($name == 'Envelope'){
$this->status = 'envelope';
- } elseif($name == 'Header'){
+ } elseif($name == 'Header' && $this->status = 'envelope'){
$this->root_header = $pos;
$this->status = 'header';
- } elseif($name == 'Body'){
+ } elseif($name == 'Body' && $this->status = 'envelope'){
$this->status = 'body';
$this->body_position = $pos;
// set method
@@ -6002,17 +6598,21 @@ class soap_parser extends nusoap_base { $this->methodNamespace = $value;
}
// if it's a type declaration, set type
- } elseif($key_localpart == 'type'){
- $value_prefix = $this->getPrefix($value);
- $value_localpart = $this->getLocalPart($value);
- $this->message[$pos]['type'] = $value_localpart;
- $this->message[$pos]['typePrefix'] = $value_prefix;
- if(isset($this->namespaces[$value_prefix])){
- $this->message[$pos]['type_namespace'] = $this->namespaces[$value_prefix];
- } else if(isset($attrs['xmlns:'.$value_prefix])) {
- $this->message[$pos]['type_namespace'] = $attrs['xmlns:'.$value_prefix];
- }
- // should do something here with the namespace of specified type?
+ } elseif($key_localpart == 'type'){
+ if (isset($this->message[$pos]['type']) && $this->message[$pos]['type'] == 'array') {
+ // do nothing: already processed arrayType
+ } else {
+ $value_prefix = $this->getPrefix($value);
+ $value_localpart = $this->getLocalPart($value);
+ $this->message[$pos]['type'] = $value_localpart;
+ $this->message[$pos]['typePrefix'] = $value_prefix;
+ if(isset($this->namespaces[$value_prefix])){
+ $this->message[$pos]['type_namespace'] = $this->namespaces[$value_prefix];
+ } else if(isset($attrs['xmlns:'.$value_prefix])) {
+ $this->message[$pos]['type_namespace'] = $attrs['xmlns:'.$value_prefix];
+ }
+ // should do something here with the namespace of specified type?
+ }
} elseif($key_localpart == 'arrayType'){
$this->message[$pos]['type'] = 'array';
/* do arrayType ereg here
@@ -6208,19 +6808,40 @@ class soap_parser extends nusoap_base { }
/**
- * get the parsed message
+ * get the parsed message (SOAP Body)
*
* @return mixed
* @access public
+ * @deprecated use get_soapbody instead
*/
function get_response(){
return $this->soapresponse;
}
/**
- * get the parsed headers
+ * get the parsed SOAP Body (NULL if there was none)
*
- * @return string XML or empty if no headers
+ * @return mixed
+ * @access public
+ */
+ function get_soapbody(){
+ return $this->soapresponse;
+ }
+
+ /**
+ * get the parsed SOAP Header (NULL if there was none)
+ *
+ * @return mixed
+ * @access public
+ */
+ function get_soapheader(){
+ return $this->soapheader;
+ }
+
+ /**
+ * get the unparsed SOAP Header
+ *
+ * @return string XML or empty if no Header
* @access public
*/
function getHeaders(){
@@ -6320,7 +6941,7 @@ class soap_parser extends nusoap_base { //} elseif($this->message[$pos]['type'] == 'SOAPStruct' || $this->message[$pos]['type'] == 'struct') {
} else {
// Apache Vector type: treat as an array
- $this->debug('in buildVal, adding Java Vector '.$this->message[$pos]['name']);
+ $this->debug('in buildVal, adding Java Vector or generic compound type '.$this->message[$pos]['name']);
if ($this->message[$pos]['type'] == 'Vector' && $this->message[$pos]['type_namespace'] == 'http://xml.apache.org/xml-soap') {
$notstruct = 1;
} else {
@@ -6363,23 +6984,36 @@ class soap_parser extends nusoap_base { }
}
}
- return is_array($params) ? $params : array();
+ $ret = is_array($params) ? $params : array();
+ $this->debug('in buildVal, return:');
+ $this->appendDebug($this->varDump($ret));
+ return $ret;
} else {
$this->debug('in buildVal, no children, building scalar');
$cdata = isset($this->message[$pos]['cdata']) ? $this->message[$pos]['cdata'] : '';
if (isset($this->message[$pos]['type'])) {
- return $this->decodeSimple($cdata, $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : '');
+ $ret = $this->decodeSimple($cdata, $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : '');
+ $this->debug("in buildVal, return: $ret");
+ return $ret;
}
$parent = $this->message[$pos]['parent'];
if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
- return $this->decodeSimple($cdata, $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
+ $ret = $this->decodeSimple($cdata, $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
+ $this->debug("in buildVal, return: $ret");
+ return $ret;
}
- return $this->message[$pos]['cdata'];
+ $ret = $this->message[$pos]['cdata'];
+ $this->debug("in buildVal, return: $ret");
+ return $ret;
}
}
}
-
+/**
+ * Backward compatibility
+ */
+class soap_parser extends nusoap_parser {
+}
?><?php
@@ -6387,12 +7021,12 @@ class soap_parser extends nusoap_base { /**
*
-* soapclient higher level class for easy usage.
+* [nu]soapclient higher level class for easy usage.
*
* usage:
*
* // instantiate client with server info
-* $soapclient = new soapclient( string path [ ,boolean wsdl] );
+* $soapclient = new nusoap_client( string path [ ,mixed wsdl] );
*
* // call method, get results
* echo $soapclient->call( string methodname [ ,array parameters] );
@@ -6401,17 +7035,19 @@ class soap_parser extends nusoap_base { * unset($soapclient);
*
* @author Dietrich Ayala <dietrich@ganx4.com>
-* @version $Id: nusoap.php,v 1.94 2005/08/04 01:27:42 snichol Exp $
+* @author Scott Nichol <snichol@users.sourceforge.net>
+* @version $Id: nusoap.php,v 1.114 2007/11/06 15:17:46 snichol Exp $
* @access public
*/
-class soapclient extends nusoap_base {
+class nusoap_client extends nusoap_base {
- var $username = '';
- var $password = '';
- var $authtype = '';
- var $certRequest = array();
+ var $username = ''; // Username for HTTP authentication
+ var $password = ''; // Password for HTTP authentication
+ var $authtype = ''; // Type of HTTP authentication
+ var $certRequest = array(); // Certificate for HTTP SSL authentication
var $requestHeaders = false; // SOAP headers in request (text)
var $responseHeaders = ''; // SOAP headers from response (incomplete namespace resolution) (text)
+ var $responseHeader = NULL; // SOAP Header from response (parsed)
var $document = ''; // SOAP body response portion (incomplete namespace resolution) (text)
var $endpoint;
var $forceEndpoint = ''; // overrides WSDL endpoint
@@ -6432,7 +7068,10 @@ class soapclient extends nusoap_base { var $cookies = array(); // Cookies from response or for request
var $decode_utf8 = true; // toggles whether the parser decodes element content w/ utf8_decode()
var $operations = array(); // WSDL operations, empty for WSDL initialization error
-
+ var $curl_options = array(); // User-specified cURL options
+ var $bindingType = ''; // WSDL operation binding type
+ var $use_curl = false; // whether to always try to use cURL
+
/*
* fault related variables
*/
@@ -6471,7 +7110,7 @@ class soapclient extends nusoap_base { * @param integer $response_timeout set the response timeout
* @access public
*/
- function soapclient($endpoint,$wsdl = false,$proxyhost = false,$proxyport = false,$proxyusername = false, $proxypassword = false, $timeout = 0, $response_timeout = 30){
+ function nusoap_client($endpoint,$wsdl = false,$proxyhost = false,$proxyport = false,$proxyusername = false, $proxypassword = false, $timeout = 0, $response_timeout = 30){
parent::nusoap_base();
$this->endpoint = $endpoint;
$this->proxyhost = $proxyhost;
@@ -6481,6 +7120,9 @@ class soapclient extends nusoap_base { $this->timeout = $timeout;
$this->response_timeout = $response_timeout;
+ $this->debug("ctor wsdl=$wsdl timeout=$timeout response_timeout=$response_timeout");
+ $this->appendDebug('endpoint=' . $this->varDump($endpoint));
+
// make values
if($wsdl){
if (is_object($endpoint) && (get_class($endpoint) == 'wsdl')) {
@@ -6488,26 +7130,13 @@ class soapclient extends nusoap_base { $this->endpoint = $this->wsdl->wsdl;
$this->wsdlFile = $this->endpoint;
$this->debug('existing wsdl instance created from ' . $this->endpoint);
+ $this->checkWSDL();
} else {
$this->wsdlFile = $this->endpoint;
-
- // instantiate wsdl object and parse wsdl file
- $this->debug('instantiating wsdl class with doc: '.$endpoint);
- $this->wsdl =& new wsdl($this->wsdlFile,$this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword,$this->timeout,$this->response_timeout);
- }
- $this->appendDebug($this->wsdl->getDebug());
- $this->wsdl->clearDebug();
- // catch errors
- if($errstr = $this->wsdl->getError()){
- $this->debug('got wsdl error: '.$errstr);
- $this->setError('wsdl error: '.$errstr);
- } elseif($this->operations = $this->wsdl->getOperations()){
- $this->debug( 'got '.count($this->operations).' operations from wsdl '.$this->wsdlFile);
- $this->endpointType = 'wsdl';
- } else {
- $this->debug( 'getOperations returned false');
- $this->setError('no operations defined in the WSDL document!');
+ $this->wsdl = null;
+ $this->debug('will use lazy evaluation of wsdl from ' . $this->endpoint);
}
+ $this->endpointType = 'wsdl';
} else {
$this->debug("instantiate SOAP with endpoint at $endpoint");
$this->endpointType = 'soap';
@@ -6517,7 +7146,7 @@ class soapclient extends nusoap_base { /**
* calls method, returns PHP native type
*
- * @param string $method SOAP server URL or path
+ * @param string $operation SOAP server URL or path
* @param mixed $params An array, associative or simple, of the parameters
* for the method call, or a string that is the XML
* for the call. For rpc style, this call will
@@ -6532,7 +7161,7 @@ class soapclient extends nusoap_base { * *must* include the wrapper.
* @param string $namespace optional method namespace (WSDL can override)
* @param string $soapAction optional SOAPAction value (WSDL can override)
- * @param mixed $headers optional string of XML with SOAP header content, or array of soapval objects for SOAP headers
+ * @param mixed $headers optional string of XML with SOAP header content, or array of soapval objects for SOAP headers, or associative array
* @param boolean $rpcParams optional (no longer used)
* @param string $style optional (rpc|document) the style to use when serializing parameters (WSDL can override)
* @param string $use optional (encoded|literal) the use when serializing parameters (WSDL can override)
@@ -6556,6 +7185,11 @@ class soapclient extends nusoap_base { if ($headers) {
$this->requestHeaders = $headers;
}
+ if ($this->endpointType == 'wsdl' && is_null($this->wsdl)) {
+ $this->loadWSDL();
+ if ($this->getError())
+ return false;
+ }
// serialize parameters
if($this->endpointType == 'wsdl' && $opData = $this->getOperationData($operation)){
// use WSDL for operation
@@ -6585,7 +7219,7 @@ class soapclient extends nusoap_base { $payload = $params;
} elseif (is_array($params)) {
$this->debug("serializing param array for WSDL operation $operation");
- $payload = $this->wsdl->serializeRPCParameters($operation,'input',$params);
+ $payload = $this->wsdl->serializeRPCParameters($operation,'input',$params,$this->bindingType);
} else {
$this->debug('params must be array or string');
$this->setError('params must be array or string');
@@ -6642,7 +7276,10 @@ class soapclient extends nusoap_base { if ($use == 'literal') {
$this->debug("wrapping RPC request with literal method element");
if ($namespace) {
- $payload = "<$operation xmlns=\"$namespace\">" . $payload . "</$operation>";
+ // http://www.ws-i.org/Profiles/BasicProfile-1.1-2004-08-24.html R2735 says rpc/literal accessor elements should not be in a namespace
+ $payload = "<$nsPrefix:$operation xmlns:$nsPrefix=\"$namespace\">" .
+ $payload .
+ "</$nsPrefix:$operation>";
} else {
$payload = "<$operation>" . $payload . "</$operation>";
}
@@ -6709,6 +7346,45 @@ class soapclient extends nusoap_base { }
/**
+ * check WSDL passed as an instance or pulled from an endpoint
+ *
+ * @access private
+ */
+ function checkWSDL() {
+ $this->appendDebug($this->wsdl->getDebug());
+ $this->wsdl->clearDebug();
+ $this->debug('checkWSDL');
+ // catch errors
+ if ($errstr = $this->wsdl->getError()) {
+ $this->debug('got wsdl error: '.$errstr);
+ $this->setError('wsdl error: '.$errstr);
+ } elseif ($this->operations = $this->wsdl->getOperations('soap')) {
+ $this->bindingType = 'soap';
+ $this->debug('got '.count($this->operations).' operations from wsdl '.$this->wsdlFile.' for binding type '.$this->bindingType);
+ } elseif ($this->operations = $this->wsdl->getOperations('soap12')) {
+ $this->bindingType = 'soap12';
+ $this->debug('got '.count($this->operations).' operations from wsdl '.$this->wsdlFile.' for binding type '.$this->bindingType);
+ $this->debug('**************** WARNING: SOAP 1.2 BINDING *****************');
+ } else {
+ $this->debug('getOperations returned false');
+ $this->setError('no operations defined in the WSDL document!');
+ }
+ }
+
+ /**
+ * instantiate wsdl object and parse wsdl file
+ *
+ * @access public
+ */
+ function loadWSDL() {
+ $this->debug('instantiating wsdl class with doc: '.$this->wsdlFile);
+ $this->wsdl =& new wsdl('',$this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword,$this->timeout,$this->response_timeout,$this->curl_options,$this->use_curl);
+ $this->wsdl->setCredentials($this->username, $this->password, $this->authtype, $this->certRequest);
+ $this->wsdl->fetchWSDL($this->wsdlFile);
+ $this->checkWSDL();
+ }
+
+ /**
* get available data pertaining to an operation
*
* @param string $operation operation name
@@ -6716,6 +7392,11 @@ class soapclient extends nusoap_base { * @access public
*/
function getOperationData($operation){
+ if ($this->endpointType == 'wsdl' && is_null($this->wsdl)) {
+ $this->loadWSDL();
+ if ($this->getError())
+ return false;
+ }
if(isset($this->operations[$operation])){
return $this->operations[$operation];
}
@@ -6746,7 +7427,7 @@ class soapclient extends nusoap_base { if($this->persistentConnection == true && is_object($this->persistentConnection)){
$http =& $this->persistentConnection;
} else {
- $http = new soap_transport_http($this->endpoint);
+ $http = new soap_transport_http($this->endpoint, $this->curl_options, $this->use_curl);
if ($this->persistentConnection) {
$http->usePersistentConnection();
}
@@ -6816,9 +7497,10 @@ class soapclient extends nusoap_base { * @access private
*/
function parseResponse($headers, $data) {
- $this->debug('Entering parseResponse() for data of length ' . strlen($data) . ' and type ' . $headers['content-type']);
+ $this->debug('Entering parseResponse() for data of length ' . strlen($data) . ' headers:');
+ $this->appendDebug($this->varDump($headers));
if (!strstr($headers['content-type'], 'text/xml')) {
- $this->setError('Response not of type text/xml');
+ $this->setError('Response not of type text/xml: ' . $headers['content-type']);
return false;
}
if (strpos($headers['content-type'], '=')) {
@@ -6833,8 +7515,8 @@ class soapclient extends nusoap_base { // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
$this->xml_encoding = 'ISO-8859-1';
}
- $this->debug('Use encoding: ' . $this->xml_encoding . ' when creating soap_parser');
- $parser = new soap_parser($data,$this->xml_encoding,$this->operation,$this->decode_utf8);
+ $this->debug('Use encoding: ' . $this->xml_encoding . ' when creating nusoap_parser');
+ $parser = new nusoap_parser($data,$this->xml_encoding,$this->operation,$this->decode_utf8);
// add parser debug data to our debug
$this->appendDebug($parser->getDebug());
// if parse errors
@@ -6846,8 +7528,10 @@ class soapclient extends nusoap_base { } else {
// get SOAP headers
$this->responseHeaders = $parser->getHeaders();
+ // get SOAP headers
+ $this->responseHeader = $parser->get_soapheader();
// get decoded message
- $return = $parser->get_response();
+ $return = $parser->get_soapbody();
// add document for doclit support
$this->document = $parser->document;
// destroy the parser object
@@ -6858,22 +7542,38 @@ class soapclient extends nusoap_base { }
/**
+ * sets user-specified cURL options
+ *
+ * @param mixed $option The cURL option (always integer?)
+ * @param mixed $value The cURL option value
+ * @access public
+ */
+ function setCurlOption($option, $value) {
+ $this->debug("setCurlOption option=$option, value=");
+ $this->appendDebug($this->varDump($value));
+ $this->curl_options[$option] = $value;
+ }
+
+ /**
* sets the SOAP endpoint, which can override WSDL
*
- * @param $endpoint string The endpoint URL to use, or empty string or false to prevent override
+ * @param string $endpoint The endpoint URL to use, or empty string or false to prevent override
* @access public
*/
function setEndpoint($endpoint) {
+ $this->debug("setEndpoint(\"$endpoint\")");
$this->forceEndpoint = $endpoint;
}
/**
* set the SOAP headers
*
- * @param $headers mixed String of XML with SOAP header content, or array of soapval objects for SOAP headers
+ * @param mixed $headers String of XML with SOAP header content, or array of soapval objects for SOAP headers
* @access public
*/
function setHeaders($headers){
+ $this->debug("setHeaders headers=");
+ $this->appendDebug($this->varDump($headers));
$this->requestHeaders = $headers;
}
@@ -6888,6 +7588,16 @@ class soapclient extends nusoap_base { }
/**
+ * get the SOAP response Header (parsed)
+ *
+ * @return mixed
+ * @access public
+ */
+ function getHeader(){
+ return $this->responseHeader;
+ }
+
+ /**
* set proxy info here
*
* @param string $proxyhost
@@ -6908,11 +7618,13 @@ class soapclient extends nusoap_base { *
* @param string $username
* @param string $password
- * @param string $authtype (basic|digest|certificate)
+ * @param string $authtype (basic|digest|certificate|ntlm)
* @param array $certRequest (keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, verifypeer (optional), verifyhost (optional): see corresponding options in cURL docs)
* @access public
*/
function setCredentials($username, $password, $authtype = 'basic', $certRequest = array()) {
+ $this->debug("setCredentials username=$username authtype=$authtype certRequest=");
+ $this->appendDebug($this->varDump($certRequest));
$this->username = $username;
$this->password = $password;
$this->authtype = $authtype;
@@ -6922,19 +7634,32 @@ class soapclient extends nusoap_base { /**
* use HTTP encoding
*
- * @param string $enc
+ * @param string $enc HTTP encoding
* @access public
*/
function setHTTPEncoding($enc='gzip, deflate'){
+ $this->debug("setHTTPEncoding(\"$enc\")");
$this->http_encoding = $enc;
}
/**
+ * Set whether to try to use cURL connections if possible
+ *
+ * @param boolean $use Whether to try to use cURL
+ * @access public
+ */
+ function setUseCURL($use) {
+ $this->debug("setUseCURL($use)");
+ $this->use_curl = $use;
+ }
+
+ /**
* use HTTP persistent connections if possible
*
* @access public
*/
function useHTTPPersistentConnection(){
+ $this->debug("useHTTPPersistentConnection");
$this->persistentConnection = true;
}
@@ -6975,14 +7700,18 @@ class soapclient extends nusoap_base { * @return object soap_proxy object
* @access public
*/
- function getProxy(){
+ function getProxy() {
$r = rand();
$evalStr = $this->_getProxyClassCode($r);
- //$this->debug("proxy class: $evalStr";
+ //$this->debug("proxy class: $evalStr");
+ if ($this->getError()) {
+ $this->debug("Error from _getProxyClassCode, so return NULL");
+ return null;
+ }
// eval the class
eval($evalStr);
// instantiate proxy object
- eval("\$proxy = new soap_proxy_$r('');");
+ eval("\$proxy = new nusoap_proxy_$r('');");
// transfer current wsdl data to the proxy thereby avoiding parsing the wsdl twice
$proxy->endpointType = 'wsdl';
$proxy->wsdlFile = $this->wsdlFile;
@@ -6990,21 +7719,26 @@ class soapclient extends nusoap_base { $proxy->operations = $this->operations;
$proxy->defaultRpcParams = $this->defaultRpcParams;
// transfer other state
+ $proxy->soap_defencoding = $this->soap_defencoding;
$proxy->username = $this->username;
$proxy->password = $this->password;
$proxy->authtype = $this->authtype;
+ $proxy->certRequest = $this->certRequest;
+ $proxy->requestHeaders = $this->requestHeaders;
+ $proxy->endpoint = $this->endpoint;
+ $proxy->forceEndpoint = $this->forceEndpoint;
$proxy->proxyhost = $this->proxyhost;
$proxy->proxyport = $this->proxyport;
$proxy->proxyusername = $this->proxyusername;
$proxy->proxypassword = $this->proxypassword;
+ $proxy->http_encoding = $this->http_encoding;
$proxy->timeout = $this->timeout;
$proxy->response_timeout = $this->response_timeout;
- $proxy->http_encoding = $this->http_encoding;
- $proxy->persistentConnection = $this->persistentConnection;
- $proxy->requestHeaders = $this->requestHeaders;
- $proxy->soap_defencoding = $this->soap_defencoding;
- $proxy->endpoint = $this->endpoint;
- $proxy->forceEndpoint = $this->forceEndpoint;
+ $proxy->persistentConnection = &$this->persistentConnection;
+ $proxy->decode_utf8 = $this->decode_utf8;
+ $proxy->curl_options = $this->curl_options;
+ $proxy->bindingType = $this->bindingType;
+ $proxy->use_curl = $this->use_curl;
return $proxy;
}
@@ -7015,11 +7749,20 @@ class soapclient extends nusoap_base { * @access private
*/
function _getProxyClassCode($r) {
+ $this->debug("in getProxy endpointType=$this->endpointType");
+ $this->appendDebug("wsdl=" . $this->varDump($this->wsdl));
if ($this->endpointType != 'wsdl') {
$evalStr = 'A proxy can only be created for a WSDL client';
$this->setError($evalStr);
+ $evalStr = "echo \"$evalStr\";";
return $evalStr;
}
+ if ($this->endpointType == 'wsdl' && is_null($this->wsdl)) {
+ $this->loadWSDL();
+ if ($this->getError()) {
+ return "echo \"" . $this->getError() . "\";";
+ }
+ }
$evalStr = '';
foreach ($this->operations as $operation => $opData) {
if ($operation != '') {
@@ -7038,6 +7781,7 @@ class soapclient extends nusoap_base { $paramCommentStr = substr($paramCommentStr, 0, strlen($paramCommentStr)-2);
} else {
$paramStr = '';
+ $paramArrayStr = '';
$paramCommentStr = 'void';
}
$opData['namespace'] = !isset($opData['namespace']) ? 'http://testuri.com' : $opData['namespace'];
@@ -7051,7 +7795,7 @@ class soapclient extends nusoap_base { unset($paramCommentStr);
}
}
- $evalStr = 'class soap_proxy_'.$r.' extends soapclient {
+ $evalStr = 'class nusoap_proxy_'.$r.' extends nusoap_client {
'.$evalStr.'
}';
return $evalStr;
@@ -7120,7 +7864,7 @@ class soapclient extends nusoap_base { *
* @param string $name Cookie Name
* @param string $value Cookie Value
- * @return if cookie-set was successful returns true, else false
+ * @return boolean if cookie-set was successful returns true, else false
* @access public
*/
function setCookie($name, $value) {
@@ -7144,7 +7888,7 @@ class soapclient extends nusoap_base { /**
* checks all Cookies and delete those which are expired
*
- * @return always return true
+ * @return boolean always return true
* @access private
*/
function checkCookies() {
@@ -7177,7 +7921,7 @@ class soapclient extends nusoap_base { * updates the current cookies with a new set
*
* @param array $cookies new cookies with which to update current ones
- * @return always return true
+ * @return boolean always return true
* @access private
*/
function UpdateCookies($cookies) {
@@ -7238,4 +7982,12 @@ class soapclient extends nusoap_base { return true;
}
}
-?>
+
+if (!extension_loaded('soap')) {
+ /**
+ * For backwards compatiblity, define soapclient unless the PHP SOAP extension is loaded.
+ */
+ class soapclient extends nusoap_client {
+ }
+}
+?> diff --git a/contrib/popularity/t10.php b/contrib/popularity/t10.php index cf13983..fbce645 100644 --- a/contrib/popularity/t10.php +++ b/contrib/popularity/t10.php @@ -14,6 +14,8 @@ // Set flag that this is a parent file define( '_VALID_MOS', 1 ); +ini_set("memory_limit", "16M") ; + // Pull in the NuSOAP code require_once('popularity/nusoap.php'); @@ -45,159 +47,159 @@ function opendatabase() { //////////////////////////////////////////////////////////////////////////////// // Register the method to expose $server->register('getUsrKey', // method name - array('k' => 'xsd:string'), // user key - array('return' => 'xsd:string'), // output parameters - 'urn:t10', // namespace - 'urn:t10#getUsrKey', // soapaction - 'rpc', // style - 'encoded', // use - 'A connection test for clients.' // documentation + array('k' => 'xsd:string'), // user key + array('return' => 'xsd:string'), // output parameters + 'urn:t10', // namespace + 'urn:t10#getUsrKey', // soapaction + 'rpc', // style + 'encoded', // use + 'A connection test for clients.' // documentation ); // A connection test for clients. function getUsrKey($k) { - $usrkey = $k; - return $usrkey; + $usrkey = $k; + return $usrkey; } //////////////////////////////////////////////////////////////////////////////// // Register the method to expose -$server->register('getServerTime', // method name - array('k' => 'xsd:string'), // user key - array('return' => 'xsd:int'), // output parameters - 'urn:t10', // namespace - 'urn:t10#getServerTime', // soapaction - 'rpc', // style - 'encoded', // use - 'Return the time from server.' // documentation +$server->register('getServerTime', // method name + array('k' => 'xsd:string'), // user key + array('return' => 'xsd:int'), // output parameters + 'urn:t10', // namespace + 'urn:t10#getServerTime', // soapaction + 'rpc', // style + 'encoded', // use + 'Return the time from server.' // documentation ); // Return the time from server function getServerTime($k) { - $database = opendatabase(); + $database = opendatabase(); - $query = "SELECT UNIX_TIMESTAMP(NOW())"; - $database->setQuery( $query ); - $servertime = $database->loadResult(); + $query = "SELECT UNIX_TIMESTAMP(NOW())"; + $database->setQuery( $query ); + $servertime = $database->loadResult(); - return $servertime; + return $servertime; } //////////////////////////////////////////////////////////////////////////////// // Register the method to expose -$server->register('getEventLevel', // method name - array('k' => 'xsd:string', // user key - 'e' => 'xsd:int'), // eventid - array('return' => 'xsd:float'), // output parameters - 'urn:t10', // namespace - 'urn:t10#getEventLevel', // soapaction - 'rpc', // style - 'encoded', // use - 'Return the average level from event.' // documentation +$server->register('getEventLevel', // method name + array('k' => 'xsd:string', // user key + 'e' => 'xsd:int'), // eventid + array('return' => 'xsd:float'), // output parameters + 'urn:t10', // namespace + 'urn:t10#getEventLevel', // soapaction + 'rpc', // style + 'encoded', // use + 'Return the average level from event.' // documentation ); // Return the average level from Event function getEventLevel($k,$e) { - $database = opendatabase(); + $database = opendatabase(); - $query = "SELECT AVG(level)" - . " FROM #__popularity" - . " WHERE id = " . $database->Quote( (int) $e ) - ; - $database->setQuery( $query ); - $average = $database->loadResult(); + $query = "SELECT AVG(level)" + . " FROM #__popularity" + . " WHERE id = " . $database->Quote( (int) $e ) + ; + $database->setQuery( $query ); + $average = $database->loadResult(); - return $average; + return $average; } //////////////////////////////////////////////////////////////////////////////// // Register the method to expose $server->register('setEventLevel', // method name - array('k' => 'xsd:string', // user key - 'e' => 'xsd:int', // eventid - 'l' => 'xsd:int', // level - 's' => 'xsd:int'), // stoptime - array('return' => 'xsd:int'), // output parameters - 'urn:t10', // namespace - 'urn:t10#setEventLevel', // soapaction - 'rpc', // style - 'encoded', // use - 'Set a level to event.' // documentation + array('k' => 'xsd:string', // user key + 'e' => 'xsd:int', // eventid + 'l' => 'xsd:int', // level + 's' => 'xsd:int'), // stoptime + array('return' => 'xsd:int'), // output parameters + 'urn:t10', // namespace + 'urn:t10#setEventLevel', // soapaction + 'rpc', // style + 'encoded', // use + 'Set a level to event.' // documentation ); // Set a level to event. function setEventLevel($k,$e,$l,$s) { - if((int)$l <= 0) { - $l = 0; - } else { - if((int)$l >= 10) { - $l = 10; - } + if((int)$l <= 0) { + $l = 0; + } else { + if((int)$l >= 10) { + $l = 10; } + } - $database = opendatabase(); - - $query = "REPLACE INTO #__popularity" - . " (user, id, level, stoptime)" - . " VALUES ( " . $database->Quote( $k ) . ", " - . (int)$e . ", " - . (int)$l . ", " - . " FROM_UNIXTIME( " . (int)$s . " )" - . " )" - ; - $database->setQuery( $query ); - if (!$database->query()) { - die($database->stderr(true)); - return 1; - } + $database = opendatabase(); + + $query = "REPLACE INTO #__popularity" + . " (user, id, level, stoptime)" + . " VALUES ( " . $database->Quote( $k ) . ", " + . (int)$e . ", " + . (int)$l . ", " + . " FROM_UNIXTIME( " . (int)$s . " )" + . " )" + ; + $database->setQuery( $query ); + if (!$database->query()) { + die($database->stderr(true)); return 1; + } + return 1; } //////////////////////////////////////////////////////////////////////////////// // Register the method to expose -$server->register('deleteEvent', // method name - array('k' => 'xsd:string', // user key - 'e' => 'xsd:int'), // eventid - array('return' => 'xsd:int'), // output parameters - 'urn:t10', // namespace - 'urn:t10#deleteEvent', // soapaction - 'rpc', // style - 'encoded', // use - 'Delete an event from database.' // documentation +$server->register('deleteEvent', // method name + array('k' => 'xsd:string', // user key + 'e' => 'xsd:int'), // eventid + array('return' => 'xsd:int'), // output parameters + 'urn:t10', // namespace + 'urn:t10#deleteEvent', // soapaction + 'rpc', // style + 'encoded', // use + 'Delete an event from database.' // documentation ); // Delete an event from database. function deleteEvent($k,$e) { - $database = opendatabase(); + $database = opendatabase(); - $query = "DELETE" - . " FROM #__popularity" - . " WHERE id = " . $database->Quote( (int) $e ) - . " AND user = " . $database->Quote( $k ) - ; - $database->setQuery( $query ); - if (!$database->query()) { - die($database->stderr(true)); - return 0; - } + $query = "DELETE" + . " FROM #__popularity" + . " WHERE id = " . $database->Quote( (int) $e ) + . " AND user = " . $database->Quote( $k ) + ; + $database->setQuery( $query ); + if (!$database->query()) { + die($database->stderr(true)); + return 0; + } - return 1; + return 1; } // Delete expired events from selected database. function expired($database) { - $query = "DELETE" - . " FROM #__popularity" - . " WHERE stoptime < NOW()" - ; - $database->setQuery( $query ); - if (!$database->query()) { - die($database->stderr(true)); - return 0; - } + $query = "DELETE" + . " FROM #__popularity" + . " WHERE stoptime < NOW()" + ; + $database->setQuery( $query ); + if (!$database->query()) { + die($database->stderr(true)); + return 0; + } - return 1; + return 1; } /*//////////////////////////////////////////////////////////////////////////////// @@ -222,28 +224,28 @@ function clear($k) { //////////////////////////////////////////////////////////////////////////////// $server->wsdl->addComplexType( - 'v', //EventLevel - 'complexType', - 'struct', - 'all', - '', - array( - 'e' => array('name'=>'e','type'=>'xsd:int'), // eventid - 'l' => array('name'=>'l','type'=>'xsd:float') // level - ) + 'v', //EventLevel + 'complexType', + 'struct', + 'all', + '', + array( + 'e' => array('name'=>'e','type'=>'xsd:int'), // eventid + 'l' => array('name'=>'l','type'=>'xsd:float') // level + ) ); $server->wsdl->addComplexType( - 'a', //EventLevelArray - 'complexType', - 'array', - '', - 'SOAP-ENC:Array', - array(), - array( - array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'tns:v[]') - ), - 'tns:v' + 'a', //EventLevelArray + 'complexType', + 'array', + '', + 'SOAP-ENC:Array', + array(), + array( + array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'tns:v[]') + ), + 'tns:v' ); // Register the method to expose @@ -259,109 +261,106 @@ $server->register('getEventLevels', // method name // Return the average Levels from Events.
function getEventLevels($k) {
- $database = opendatabase(); + $database = opendatabase(); - if(!expired($database)) { - return 0; - } + if(!expired($database)) { + return 0; + } - $query = "SELECT id, AVG(level) as level" - . " FROM #__popularity" - . " GROUP BY id" - ; - $database->setQuery( $query ); - $rows = $database->loadObjectList(); - if(empty($rows)) { - return 0; - } - - $result = array(); - foreach ($rows as $row) { - $result[] = array( - 'e' => $row->id, - 'l' => $row->level - ); - } - return $result; + $result = array(); + $query = "SELECT id, AVG(level) as level" + . " FROM #__popularity" + . " GROUP BY id" + ; + $database->setQuery( $query ); + $rows = $database->loadObjectList(); + if(!empty($rows)) { + foreach ($rows as $row) { + $result[] = array( + 'e' => $row->id, + 'l' => $row->level + ); + } + } + return $result; }
//////////////////////////////////////////////////////////////////////////////// $server->wsdl->addComplexType( - 't', //topten - 'complexType', - 'struct', - 'all', - '', - array( - 'e' => array('name'=>'e','type'=>'xsd:int'), // eventid - 'l' => array('name'=>'l','type'=>'xsd:float'), // level - 'c' => array('name'=>'c','type'=>'xsd:int'), // count - 'r' => array('name'=>'r','type'=>'xsd:float') // rank - ) + 't', //topten + 'complexType', + 'struct', + 'all', + '', + array( + 'e' => array('name'=>'e','type'=>'xsd:int'), // eventid + 'l' => array('name'=>'l','type'=>'xsd:float'), // level + 'c' => array('name'=>'c','type'=>'xsd:int'), // count + 'r' => array('name'=>'r','type'=>'xsd:float') // rank + ) ); $server->wsdl->addComplexType( - 'b', - 'complexType', - 'array', - '', - 'SOAP-ENC:Array', - array(), - array( - array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'tns:t[]') - ), - 'tns:t' + 'b', + 'complexType', + 'array', + '', + 'SOAP-ENC:Array', + array(), + array( + array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'tns:t[]') + ), + 'tns:t' ); // Register the method to expose $server->register('getTopTen', // method name - array('k' => 'xsd:string', // user key - 'l' => 'xsd:int'), // level - array('return' => 'tns:b'), // output parameters - 'urn:t10', // namespace - 'urn:t10#getTopTen', // soapaction - 'rpc', // style - 'encoded', // use - 'Return the topten list.' // documentation + array('k' => 'xsd:string', // user key + 'l' => 'xsd:int'), // level + array('return' => 'tns:b'), // output parameters + 'urn:t10', // namespace + 'urn:t10#getTopTen', // soapaction + 'rpc', // style + 'encoded', // use + 'Return the topten list.' // documentation ); // Return the topten list. function getTopTen($k,$l) {
- $database = opendatabase(); + $database = opendatabase(); - if(!expired($database)) { - return 0; - } + if(!expired($database)) { + return 0; + } - if((int)$l <= 1) { - $l = 1; - } - if((int)$l >= 1000) { - $l = 1000; - } + if((int)$l <= 1) { + $l = 1; + } + if((int)$l >= 1000) { + $l = 1000; + } - $query = "SELECT id, AVG(level) as l, COUNT(*) as c, AVG(level)*COUNT(*) as r" - . " FROM #__popularity" - . " GROUP BY id ORDER by r DESC LIMIT " . (int) $l - ; - $database->setQuery( $query ); - $rows = $database->loadObjectList(); - if(empty($rows)) { - return 0; - } - - $result = array(); - foreach ($rows as $row) { - $result[] = array( - 'e' => $row->id, - 'l' => $row->l, - 'c' => $row->c, - 'r' => $row->r - ); - } - return $result;
+ $result = array(); + $query = "SELECT id as i, AVG(level) as l, COUNT(*) as c, AVG(level)*COUNT(*) as r" + . " FROM #__popularity" + . " GROUP BY id ORDER by r DESC" + ; + + $database->setQuery( $query, 0 , (int) $l); + $rows = $database->loadObjectList(); + if(!empty($rows)) { + foreach ($rows as $row) { + $result[] = array( + 'e' => $row->i, + 'l' => $row->l, + 'c' => $row->c, + 'r' => $row->r + ); + } + } + return $result;
} @@ -369,34 +368,34 @@ function getTopTen($k,$l) { // Register the method to expose /* $server->register('createtable', // method name - array('k' => 'xsd:string'), // user key - array('return' => 'xsd:int'), // output parameters - 'urn:t10', // namespace - 'urn:t10#createtable', // soapaction - 'rpc', // style - 'encoded', // use - 'create table into database.' // documentation + array('k' => 'xsd:string'), // user key + array('return' => 'xsd:int'), // output parameters + 'urn:t10', // namespace + 'urn:t10#createtable', // soapaction + 'rpc', // style + 'encoded', // use + 'create table into database.' // documentation ); // Delete an event from database. function createtable($k) { - $database = opendatabase(); - - $query = "CREATE TABLE IF NOT EXISTS #__popularity ("
- . " user varchar(16) NOT NULL default '',"
- . " id int unsigned NOT NULL default '0',"
- . " level int default NULL,"
- . " stoptime datetime NOT NULL,"
- . " UNIQUE KEY `event` (`user`,`id`)"
- . " )" - ; - $database->setQuery( $query ); - if (!$database->query()) { - die($database->stderr(true)); - return 0; - } - - return 1; + $database = opendatabase(); + + $query = "CREATE TABLE IF NOT EXISTS #__popularity ("
+ . " user varchar(16) NOT NULL default '',"
+ . " id int unsigned NOT NULL default '0',"
+ . " level int default NULL,"
+ . " stoptime datetime NOT NULL,"
+ . " UNIQUE KEY `event` (`user`,`id`)"
+ . " )" + ; + $database->setQuery( $query ); + if (!$database->query()) { + die($database->stderr(true)); + return 0; + } + + return 1; } */ //////////////////////////////////////////////////////////////////////////////// |
