You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openmeetings.apache.org by es...@apache.org on 2011/12/22 01:16:27 UTC
svn commit: r1221963 [2/3] - in
/incubator/openmeetings/trunk/plugins/sugarcrm/5.x.x: ./ SugarModules/
SugarModules/include/ SugarModules/include/language/ SugarModules/modules/
SugarModules/modules/Administration/ SugarModules/modules/Administration/E...
Added: incubator/openmeetings/trunk/plugins/sugarcrm/5.x.x/openmeetings_gateway/lib/nusoap.php
URL: http://svn.apache.org/viewvc/incubator/openmeetings/trunk/plugins/sugarcrm/5.x.x/openmeetings_gateway/lib/nusoap.php?rev=1221963&view=auto
==============================================================================
--- incubator/openmeetings/trunk/plugins/sugarcrm/5.x.x/openmeetings_gateway/lib/nusoap.php (added)
+++ incubator/openmeetings/trunk/plugins/sugarcrm/5.x.x/openmeetings_gateway/lib/nusoap.php Thu Dec 22 00:16:25 2011
@@ -0,0 +1,8079 @@
+<?php
+
+/*
+$Id: nusoap.php,v 1.114 2007/11/06 15:17:46 snichol Exp $
+
+NuSOAP - Web Services Toolkit for PHP
+
+Copyright (c) 2002 NuSphere Corporation
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+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
+dietrich@ganx4.com
+http://dietrich.ganx4.com/nusoap
+
+NuSphere Corporation
+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
+ */
+
+/*
+ *
+ * This is a modified version of nusoap for usage of Axis2
+ * for some reason it does not marshall the SOAP Body correct for Axis2 on Linux Platforms
+ *
+ */
+
+// class variable emulation
+// cf. http://www.webkreator.com/php/techniques/php-static-class-variables.html
+$GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel = 9;
+
+/**
+*
+* nusoap_base
+*
+* @author Dietrich Ayala <di...@ganx4.com>
+* @author Scott Nichol <sn...@users.sourceforge.net>
+* @version $Id: nusoap.php,v 1.114 2007/11/06 15:17:46 snichol Exp $
+* @access public
+*/
+class nusoap_base_om {
+ /**
+ * Identification for HTTP headers.
+ *
+ * @var string
+ * @access private
+ */
+ var $title = 'NuSOAP';
+ /**
+ * Version for HTTP headers.
+ *
+ * @var string
+ * @access private
+ */
+ var $version = '0.7.3';
+ /**
+ * CVS revision for HTTP headers.
+ *
+ * @var string
+ * @access private
+ */
+ var $revision = '$Revision: 1.114 $';
+ /**
+ * Current error string (manipulated by getError/setError)
+ *
+ * @var string
+ * @access private
+ */
+ var $error_str = '';
+ /**
+ * Current debug string (manipulated by debug/appendDebug/clearDebug/getDebug/getDebugAsXMLComment)
+ *
+ * @var string
+ * @access private
+ */
+ var $debug_str = '';
+ /**
+ * toggles automatic encoding of special characters as entities
+ * (should always be true, I think)
+ *
+ * @var boolean
+ * @access private
+ */
+ var $charencoding = true;
+ /**
+ * the debug level for this instance
+ *
+ * @var integer
+ * @access private
+ */
+ var $debugLevel;
+
+ /**
+ * set schema version
+ *
+ * @var string
+ * @access public
+ */
+ var $XMLSchemaVersion = 'http://www.w3.org/2001/XMLSchema';
+
+ /**
+ * charset encoding for outgoing messages
+ *
+ * @var string
+ * @access public
+ */
+ //var $soap_defencoding = 'ISO-8859-1';
+ var $soap_defencoding = 'UTF-8';
+
+ /**
+ * namespaces in an array of prefix => uri
+ *
+ * this is "seeded" by a set of constants, but it may be altered by code
+ *
+ * @var array
+ * @access public
+ */
+ var $namespaces = array(
+ 'SOAP-ENV' => 'http://schemas.xmlsoap.org/soap/envelope/',
+ 'xsd' => 'http://www.w3.org/2001/XMLSchema',
+ 'xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
+ 'SOAP-ENC' => 'http://schemas.xmlsoap.org/soap/encoding/'
+ );
+
+ /**
+ * namespaces used in the current context, e.g. during serialization
+ *
+ * @var array
+ * @access private
+ */
+ var $usedNamespaces = array();
+
+ /**
+ * XML Schema types in an array of uri => (array of xml type => php type)
+ * is this legacy yet?
+ * no, this is used by the nusoap_xmlschema class to verify type => namespace mappings.
+ * @var array
+ * @access public
+ */
+ var $typemap = array(
+ 'http://www.w3.org/2001/XMLSchema' => array(
+ 'string'=>'string','boolean'=>'boolean','float'=>'double','double'=>'double','decimal'=>'double',
+ 'duration'=>'','dateTime'=>'string','time'=>'string','date'=>'string','gYearMonth'=>'',
+ 'gYear'=>'','gMonthDay'=>'','gDay'=>'','gMonth'=>'','hexBinary'=>'string','base64Binary'=>'string',
+ // abstract "any" types
+ 'anyType'=>'string','anySimpleType'=>'string',
+ // derived datatypes
+ 'normalizedString'=>'string','token'=>'string','language'=>'','NMTOKEN'=>'','NMTOKENS'=>'','Name'=>'','NCName'=>'','ID'=>'',
+ 'IDREF'=>'','IDREFS'=>'','ENTITY'=>'','ENTITIES'=>'','integer'=>'integer','nonPositiveInteger'=>'integer',
+ 'negativeInteger'=>'integer','long'=>'integer','int'=>'integer','short'=>'integer','byte'=>'integer','nonNegativeInteger'=>'integer',
+ 'unsignedLong'=>'','unsignedInt'=>'','unsignedShort'=>'','unsignedByte'=>'','positiveInteger'=>''),
+ 'http://www.w3.org/2000/10/XMLSchema' => array(
+ 'i4'=>'','int'=>'integer','boolean'=>'boolean','string'=>'string','double'=>'double',
+ 'float'=>'double','dateTime'=>'string',
+ 'timeInstant'=>'string','base64Binary'=>'string','base64'=>'string','ur-type'=>'array'),
+ 'http://www.w3.org/1999/XMLSchema' => array(
+ 'i4'=>'','int'=>'integer','boolean'=>'boolean','string'=>'string','double'=>'double',
+ 'float'=>'double','dateTime'=>'string',
+ 'timeInstant'=>'string','base64Binary'=>'string','base64'=>'string','ur-type'=>'array'),
+ 'http://soapinterop.org/xsd' => array('SOAPStruct'=>'struct'),
+ 'http://schemas.xmlsoap.org/soap/encoding/' => array('base64'=>'string','array'=>'array','Array'=>'array'),
+ 'http://xml.apache.org/xml-soap' => array('Map')
+ );
+
+ /**
+ * XML entities to convert
+ *
+ * @var array
+ * @access public
+ * @deprecated
+ * @see expandEntities
+ */
+ var $xmlEntities = array('quot' => '"','amp' => '&',
+ 'lt' => '<','gt' => '>','apos' => "'");
+
+ /**
+ * constructor
+ *
+ * @access public
+ */
+ function nusoap_base_om() {
+ $this->debugLevel = $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel;
+ }
+
+ /**
+ * gets the global debug level, which applies to future instances
+ *
+ * @return integer Debug level 0-9, where 0 turns off
+ * @access public
+ */
+ function getGlobalDebugLevel() {
+ return $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel;
+ }
+
+ /**
+ * sets the global debug level, which applies to future instances
+ *
+ * @param int $level Debug level 0-9, where 0 turns off
+ * @access public
+ */
+ function setGlobalDebugLevel($level) {
+ $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel = $level;
+ }
+
+ /**
+ * gets the debug level for this instance
+ *
+ * @return int Debug level 0-9, where 0 turns off
+ * @access public
+ */
+ function getDebugLevel() {
+ return $this->debugLevel;
+ }
+
+ /**
+ * sets the debug level for this instance
+ *
+ * @param int $level Debug level 0-9, where 0 turns off
+ * @access public
+ */
+ function setDebugLevel($level) {
+ $this->debugLevel = $level;
+ }
+
+ /**
+ * adds debug data to the instance debug string with formatting
+ *
+ * @param string $string debug data
+ * @access private
+ */
+ function debug($string){
+ if ($this->debugLevel > 0) {
+ $this->appendDebug($this->getmicrotime().' '.get_class($this).": $string\n");
+ }
+ }
+
+ /**
+ * adds debug data to the instance debug string without formatting
+ *
+ * @param string $string debug data
+ * @access public
+ */
+ function appendDebug($string){
+ //echo "## appendDebug: ".$string."<br/>";
+ if ($this->debugLevel > 0) {
+ // it would be nice to use a memory stream here to use
+ // memory more efficiently
+ $this->debug_str .= $string;
+ }
+ }
+
+ /**
+ * clears the current debug data for this instance
+ *
+ * @access public
+ */
+ function clearDebug() {
+ // it would be nice to use a memory stream here to use
+ // memory more efficiently
+ $this->debug_str = '';
+ }
+
+ /**
+ * gets the current debug data for this instance
+ *
+ * @return debug data
+ * @access public
+ */
+ function &getDebug() {
+ // it would be nice to use a memory stream here to use
+ // memory more efficiently
+ return $this->debug_str;
+ }
+
+ /**
+ * gets the current debug data for this instance as an XML comment
+ * this may change the contents of the debug data
+ *
+ * @return debug data as an XML comment
+ * @access public
+ */
+ function &getDebugAsXMLComment() {
+ // it would be nice to use a memory stream here to use
+ // memory more efficiently
+ while (strpos($this->debug_str, '--')) {
+ $this->debug_str = str_replace('--', '- -', $this->debug_str);
+ }
+ $ret = "<!--\n" . $this->debug_str . "\n-->";
+ return $ret;
+ }
+
+ /**
+ * expands entities, e.g. changes '<' to '<'.
+ *
+ * @param string $val The string in which to expand entities.
+ * @access private
+ */
+ function expandEntities($val) {
+ if ($this->charencoding) {
+ $val = str_replace('&', '&', $val);
+ $val = str_replace("'", ''', $val);
+ $val = str_replace('"', '"', $val);
+ $val = str_replace('<', '<', $val);
+ $val = str_replace('>', '>', $val);
+ }
+ return $val;
+ }
+
+ /**
+ * returns error string if present
+ *
+ * @return mixed error string or false
+ * @access public
+ */
+ function getError(){
+ if($this->error_str != ''){
+ return $this->error_str;
+ }
+ return false;
+ }
+
+ /**
+ * sets error string
+ *
+ * @return boolean $string error string
+ * @access private
+ */
+ function setError($str){
+ $this->error_str = $str;
+ }
+
+ /**
+ * detect if array is a simple array or a struct (associative array)
+ *
+ * @param mixed $val The PHP array
+ * @return string (arraySimple|arrayStruct)
+ * @access private
+ */
+ function isArraySimpleOrStruct($val) {
+ $keyList = array_keys($val);
+ foreach ($keyList as $keyListValue) {
+ if (!is_int($keyListValue)) {
+ return 'arrayStruct';
+ }
+ }
+ return 'arraySimple';
+ }
+
+ /**
+ * serializes PHP values in accordance w/ section 5. Type information is
+ * not serialized if $use == 'literal'.
+ *
+ * @param mixed $val The value to serialize
+ * @param string $name The name (local part) of the XML element
+ * @param string $type The XML schema type (local part) for the element
+ * @param string $name_ns The namespace for the name of the XML element
+ * @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',$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' && (! $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)) {
+ $name = '__numeric_' . $name;
+ } elseif (! $name) {
+ $name = 'noname';
+ }
+ // if name has ns, add ns prefix to name
+ $xmlns = '';
+ if($name_ns){
+ $prefix = 'nu'.rand(1000,9999);
+ $name = $prefix.':'.$name;
+ $xmlns .= " xmlns:$prefix=\"$name_ns\"";
+ }
+ // if type is prefixed, create type prefix
+ if($type_ns != '' && $type_ns == $this->namespaces['xsd']){
+ // need to fix this. shouldn't default to xsd if no ns specified
+ // w/o checking against typemap
+ $type_prefix = 'xsd';
+ } elseif($type_ns){
+ $type_prefix = 'ns'.rand(1000,9999);
+ $xmlns .= " xmlns:$type_prefix=\"$type_ns\"";
+ }
+ // serialize attributes if present
+ $atts = '';
+ if($attributes){
+ foreach($attributes as $k => $v){
+ $atts .= " $k=\"".$this->expandEntities($v).'"';
+ }
+ }
+ // serialize null value
+ if (is_null($val)) {
+ $this->debug("serialize_val: serialize null");
+ if ($use == 'literal') {
+ // TODO: depends on minOccurs
+ $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 = '';
+ }
+ $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';
+ } elseif (! $val) {
+ $val = 0;
+ }
+ } else if (is_string($val)) {
+ $val = $this->expandEntities($val);
+ }
+ if ($use == 'literal') {
+ $xml = "<$name$xmlns$atts>$val</$name>";
+ $this->debug("serialize_val returning $xml");
+ return $xml;
+ } else {
+ $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>";
+ } 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>";
+ } 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>";
+ } 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>";
+ } else {
+ $xml .= "<$name$xmlns xsi:type=\"xsd:string\"$atts>$val</$name>";
+ }
+ break;
+ case is_object($val):
+ $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 {
+ $type_str = '';
+ }
+ if ($use == 'literal') {
+ $xml .= "<$name$xmlns$atts>$pXml</$name>";
+ } else {
+ $xml .= "<$name$xmlns$type_str$atts>$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){
+ if(is_object($v) && get_class($v) == 'soapval'){
+ $tt_ns = $v->type_ns;
+ $tt = $v->type;
+ } elseif (is_array($v)) {
+ $tt = $this->isArraySimpleOrStruct($v);
+ } else {
+ $tt = gettype($v);
+ }
+ $array_types[$tt] = 1;
+ // TODO: for literal, the name should be $name
+ $xml .= $this->serialize_val($v,'item',false,false,false,false,$use);
+ ++$i;
+ }
+ if(count($array_types) > 1){
+ $array_typename = 'xsd:anyType';
+ } elseif(isset($tt) && isset($this->typemap[$this->XMLSchemaVersion][$tt])) {
+ if ($tt == 'integer') {
+ $tt = 'int';
+ }
+ $array_typename = 'xsd:'.$tt;
+ } elseif(isset($tt) && $tt == 'arraySimple'){
+ $array_typename = 'SOAP-ENC:Array';
+ } elseif(isset($tt) && $tt == 'arrayStruct'){
+ $array_typename = 'unnamed_struct_use_soapval';
+ } else {
+ // if type is prefixed, create type prefix
+ if ($tt_ns != '' && $tt_ns == $this->namespaces['xsd']){
+ $array_typename = 'xsd:' . $tt;
+ } elseif ($tt_ns) {
+ $tt_prefix = 'ns' . rand(1000, 9999);
+ $array_typename = "$tt_prefix:$tt";
+ $xmlns .= " xmlns:$tt_prefix=\"$tt_ns\"";
+ } else {
+ $array_typename = $tt;
+ }
+ }
+ $array_type = $i;
+ if ($use == 'literal') {
+ $type_str = '';
+ } else if (isset($type) && isset($type_prefix)) {
+ $type_str = " xsi:type=\"$type_prefix:$type\"";
+ } else {
+ $type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"".$array_typename."[$array_type]\"";
+ }
+ // empty array
+ } else {
+ if ($use == 'literal') {
+ $type_str = '';
+ } else if (isset($type) && isset($type_prefix)) {
+ $type_str = " xsi:type=\"$type_prefix:$type\"";
+ } else {
+ $type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"xsd:anyType[0]\"";
+ }
+ }
+ // TODO: for array in literal, there is no wrapper here
+ $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>";
+ } else {
+ $xml .= "<$name$xmlns$type_str$atts>";
+ }
+ foreach($val as $k => $v){
+ // Apache Map
+ if ($type == 'Map' && $type_ns == 'http://xml.apache.org/xml-soap') {
+ $xml .= '<item>';
+ $xml .= $this->serialize_val($k,'key',false,false,false,false,$use);
+ $xml .= $this->serialize_val($v,'value',false,false,false,false,$use);
+ $xml .= '</item>';
+ } else {
+ $xml .= $this->serialize_val($v,$k,false,false,false,false,$use);
+ }
+ }
+ $xml .= "</$name>";
+ }
+ 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;
+ }
+
+ /**
+ * 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, 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)
+ * @param string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded)
+ * @return string the message
+ * @access public
+ */
+ function serializeEnvelope($body,$headers=false,$namespaces=array(),$style='rpc',$use='encoded',$encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'){
+ // TODO: add an option to automatically run utf8_encode on $body and $headers
+ // if $this->soap_defencoding is UTF-8. Not doing this automatically allows
+ // one to send arbitrary UTF-8 characters, not just characters that map to ISO-8859-1
+
+ $this->debug("In serializeEnvelope length=" . strlen($body) . " body (max 1000 characters)=" . substr($body, 0, 1000) . " style=$style use=$use encodingStyle=$encodingStyle");
+ $this->debug("headers:");
+ $this->appendDebug($this->varDump($headers));
+ $this->debug("namespaces:");
+ $this->appendDebug($this->varDump($namespaces));
+
+ // serialize namespaces
+ $ns_string = '';
+ foreach(array_merge($this->namespaces,$namespaces) as $k => $v){
+ $ns_string .= " xmlns:$k=\"$v\"";
+ }
+ if($encodingStyle) {
+ $ns_string = " SOAP-ENV:encodingStyle=\"$encodingStyle\"$ns_string";
+ }
+
+ // serialize headers
+ if($headers){
+ if (is_array($headers)) {
+ $xml = '';
+ 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, serialized array of headers to $headers");
+ }
+ $headers = "<SOAP-ENV:Header>".$headers."</SOAP-ENV:Header>";
+ }
+ //echo "####<br/>";
+ //echo $body;
+ //echo "<br/>####<br/>";
+ // serialize envelope
+ return
+ '<?xml version="1.0" encoding="'.$this->soap_defencoding .'"?'.">".
+ '<SOAP-ENV:Envelope'.$ns_string.">".
+ $headers.
+ "<SOAP-ENV:Body>".
+ $body.
+ "</SOAP-ENV:Body>".
+ "</SOAP-ENV:Envelope>";
+ }
+
+ /**
+ * formats a string to be inserted into an HTML stream
+ *
+ * @param string $str The string to format
+ * @return string The formatted string
+ * @access public
+ * @deprecated
+ */
+ function formatDump($str){
+ $str = htmlspecialchars($str);
+ return nl2br($str);
+ }
+
+ /**
+ * contracts (changes namespace to prefix) a qualified name
+ *
+ * @param string $qname qname
+ * @return string contracted qname
+ * @access private
+ */
+ function contractQname($qname){
+ // get element namespace
+ //$this->xdebug("Contract $qname");
+ if (strrpos($qname, ':')) {
+ // get unqualified name
+ $name = substr($qname, strrpos($qname, ':') + 1);
+ // get ns
+ $ns = substr($qname, 0, strrpos($qname, ':'));
+ $p = $this->getPrefixFromNamespace($ns);
+ if ($p) {
+ return $p . ':' . $name;
+ }
+ return $qname;
+ } else {
+ return $qname;
+ }
+ }
+
+ /**
+ * expands (changes prefix to namespace) a qualified name
+ *
+ * @param string $qname qname
+ * @return string expanded qname
+ * @access private
+ */
+ function expandQname($qname){
+ // get element prefix
+ if(strpos($qname,':') && !ereg('^http://',$qname)){
+ // get unqualified name
+ $name = substr(strstr($qname,':'),1);
+ // get ns prefix
+ $prefix = substr($qname,0,strpos($qname,':'));
+ if(isset($this->namespaces[$prefix])){
+ return $this->namespaces[$prefix].':'.$name;
+ } else {
+ return $qname;
+ }
+ } else {
+ return $qname;
+ }
+ }
+
+ /**
+ * returns the local part of a prefixed string
+ * returns the original string, if not prefixed
+ *
+ * @param string $str The prefixed string
+ * @return string The local part
+ * @access public
+ */
+ function getLocalPart($str){
+ if($sstr = strrchr($str,':')){
+ // get unqualified name
+ return substr( $sstr, 1 );
+ } else {
+ return $str;
+ }
+ }
+
+ /**
+ * returns the prefix part of a prefixed string
+ * returns false, if not prefixed
+ *
+ * @param string $str The prefixed string
+ * @return mixed The prefix or false if there is no prefix
+ * @access public
+ */
+ function getPrefix($str){
+ if($pos = strrpos($str,':')){
+ // get prefix
+ return substr($str,0,$pos);
+ }
+ return false;
+ }
+
+ /**
+ * pass it a prefix, it returns a namespace
+ *
+ * @param string $prefix The prefix
+ * @return mixed The namespace, false if no namespace has the specified prefix
+ * @access public
+ */
+ function getNamespaceFromPrefix($prefix){
+ if (isset($this->namespaces[$prefix])) {
+ return $this->namespaces[$prefix];
+ }
+ //$this->setError("No namespace registered for prefix '$prefix'");
+ return false;
+ }
+
+ /**
+ * returns the prefix for a given namespace (or prefix)
+ * or false if no prefixes registered for the given namespace
+ *
+ * @param string $ns The namespace
+ * @return mixed The prefix, false if the namespace has no prefixes
+ * @access public
+ */
+ function getPrefixFromNamespace($ns) {
+ foreach ($this->namespaces as $p => $n) {
+ if ($ns == $n || $ns == $p) {
+ $this->usedNamespaces[$p] = $n;
+ return $p;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * returns the time in ODBC canonical form with microseconds
+ *
+ * @return string The time in ODBC canonical form with microseconds
+ * @access public
+ */
+ function getmicrotime() {
+ if (function_exists('gettimeofday')) {
+ $tod = gettimeofday();
+ $sec = $tod['sec'];
+ $usec = $tod['usec'];
+ } else {
+ $sec = time();
+ $usec = 0;
+ }
+ return strftime('%Y-%m-%d %H:%M:%S', $sec) . '.' . sprintf('%06d', $usec);
+ }
+
+ /**
+ * Returns a string with the output of var_dump
+ *
+ * @param mixed $data The variable to var_dump
+ * @return string The output of var_dump
+ * @access public
+ */
+ function varDump($data) {
+ ob_start();
+ var_dump($data);
+ $ret_val = ob_get_contents();
+ 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
+
+//xsd:dateTime helpers
+
+/**
+* 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){
+ $datestr = date('Y-m-d\TH:i:sO',$timestamp);
+ if($utc){
+ $eregStr =
+ '([0-9]{4})-'. // centuries & years CCYY-
+ '([0-9]{2})-'. // months MM-
+ '([0-9]{2})'. // days DD
+ 'T'. // separator T
+ '([0-9]{2}):'. // hours hh:
+ '([0-9]{2}):'. // minutes mm:
+ '([0-9]{2})(\.[0-9]*)?'. // seconds ss.ss...
+ '(Z|[+\-][0-9]{2}:?[0-9]{2})?'; // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's
+
+ if(ereg($eregStr,$datestr,$regs)){
+ return sprintf('%04d-%02d-%02dT%02d:%02d:%02dZ',$regs[1],$regs[2],$regs[3],$regs[4],$regs[5],$regs[6]);
+ }
+ return false;
+ } else {
+ return $datestr;
+ }
+}*/
+
+/**
+* convert ISO 8601 compliant date string to unix timestamp
+*
+* @param string $datestr ISO 8601 compliant date string
+* @access public
+*/
+/*
+function iso8601_to_timestamp($datestr){
+ $eregStr =
+ '([0-9]{4})-'. // centuries & years CCYY-
+ '([0-9]{2})-'. // months MM-
+ '([0-9]{2})'. // days DD
+ 'T'. // separator T
+ '([0-9]{2}):'. // hours hh:
+ '([0-9]{2}):'. // minutes mm:
+ '([0-9]{2})(\.[0-9]+)?'. // seconds ss.ss...
+ '(Z|[+\-][0-9]{2}:?[0-9]{2})?'; // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's
+ if(ereg($eregStr,$datestr,$regs)){
+ // not utc
+ if($regs[8] != 'Z'){
+ $op = substr($regs[8],0,1);
+ $h = substr($regs[8],1,2);
+ $m = substr($regs[8],strlen($regs[8])-2,2);
+ if($op == '-'){
+ $regs[4] = $regs[4] + $h;
+ $regs[5] = $regs[5] + $m;
+ } elseif($op == '+'){
+ $regs[4] = $regs[4] - $h;
+ $regs[5] = $regs[5] - $m;
+ }
+ }
+ 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;
+ }
+}*/
+
+/**
+* sleeps some number of microseconds
+*
+* @param string $usec the number of microseconds to sleep
+* @access public
+* @deprecated
+*/
+/*
+function usleepWindows($usec)
+{
+ $start = gettimeofday();
+
+ do
+ {
+ $stop = gettimeofday();
+ $timePassed = 1000000 * ($stop['sec'] - $start['sec'])
+ + $stop['usec'] - $start['usec'];
+ }
+ while ($timePassed < $usec);
+}
+*/
+?><?php
+
+
+
+/**
+* Contains information for a SOAP fault.
+* Mainly used for returning faults from deployed functions
+* in a server instance.
+* @author Dietrich Ayala <di...@ganx4.com>
+* @version $Id: nusoap.php,v 1.114 2007/11/06 15:17:46 snichol Exp $
+* @access public
+*/
+class nusoap_fault_om extends nusoap_base_om {
+ /**
+ * The fault code (client|server)
+ * @var string
+ * @access private
+ */
+ var $faultcode;
+ /**
+ * The fault actor
+ * @var string
+ * @access private
+ */
+ var $faultactor;
+ /**
+ * The fault string, a description of the fault
+ * @var string
+ * @access private
+ */
+ var $faultstring;
+ /**
+ * The fault detail, typically a string or array of string
+ * @var mixed
+ * @access private
+ */
+ var $faultdetail;
+
+ /**
+ * constructor
+ *
+ * @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 nusoap_fault_om($faultcode,$faultactor='',$faultstring='',$faultdetail=''){
+ parent::nusoap_base_om();
+ $this->faultcode = $faultcode;
+ $this->faultactor = $faultactor;
+ $this->faultstring = $faultstring;
+ $this->faultdetail = $faultdetail;
+ }
+
+ /**
+ * serialize a fault
+ *
+ * @return string The serialization of the fault instance.
+ * @access public
+ */
+ function serialize(){
+ $ns_string = '';
+ foreach($this->namespaces as $k => $v){
+ $ns_string .= "\n xmlns:$k=\"$v\"";
+ }
+ $return_msg =
+ '<?xml version="1.0" encoding="'.$this->soap_defencoding.'"?>'.
+ '<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"'.$ns_string.">\n".
+ '<SOAP-ENV:Body>'.
+ '<SOAP-ENV:Fault>'.
+ $this->serialize_val($this->faultcode, 'faultcode').
+ $this->serialize_val($this->faultactor, 'faultactor').
+ $this->serialize_val($this->faultstring, 'faultstring').
+ $this->serialize_val($this->faultdetail, 'detail').
+ '</SOAP-ENV:Fault>'.
+ '</SOAP-ENV:Body>'.
+ '</SOAP-ENV:Envelope>';
+ return $return_msg;
+ }
+}
+
+/**
+ * Backward compatibility
+ */
+class soap_fault_om extends nusoap_fault_om {
+}
+
+?><?php
+
+
+
+/**
+* parses an XML Schema, allows access to it's data, other utility methods.
+* imperfect, no validation... yet, but quite functional.
+*
+* @author Dietrich Ayala <di...@ganx4.com>
+* @author Scott Nichol <sn...@users.sourceforge.net>
+* @version $Id: nusoap.php,v 1.114 2007/11/06 15:17:46 snichol Exp $
+* @access public
+*/
+class nusoap_xmlschema_om extends nusoap_base_om {
+
+ // files
+ var $schema = '';
+ var $xml = '';
+ // namespaces
+ var $enclosingNamespaces;
+ // schema info
+ var $schemaInfo = array();
+ var $schemaTargetNamespace = '';
+ // types, elements, attributes defined by the schema
+ var $attributes = array();
+ var $complexTypes = array();
+ var $complexTypeStack = array();
+ var $currentComplexType = null;
+ var $elements = array();
+ var $elementStack = array();
+ var $currentElement = null;
+ var $simpleTypes = array();
+ var $simpleTypeStack = array();
+ var $currentSimpleType = null;
+ // imports
+ var $imports = array();
+ // parser vars
+ var $parser;
+ var $position = 0;
+ var $depth = 0;
+ var $depth_array = array();
+ var $message = array();
+ var $defaultNamespace = array();
+
+ /**
+ * constructor
+ *
+ * @param string $schema schema document URI
+ * @param string $xml xml document URI
+ * @param string $namespaces namespaces defined in enclosing XML
+ * @access public
+ */
+ function nusoap_xmlschema_om($schema='',$xml='',$namespaces=array()){
+ parent::nusoap_base_om();
+ $this->debug('nusoap_xmlschema class instantiated, inside constructor');
+ // files
+ $this->schema = $schema;
+ $this->xml = $xml;
+
+ // namespaces
+ $this->enclosingNamespaces = $namespaces;
+ $this->namespaces = array_merge($this->namespaces, $namespaces);
+
+ // parse schema file
+ if($schema != ''){
+ $this->debug('initial schema file: '.$schema);
+ $this->parseFile($schema, 'schema');
+ }
+
+ // parse xml file
+ if($xml != ''){
+ $this->debug('initial xml file: '.$xml);
+ $this->parseFile($xml, 'xml');
+ }
+
+ }
+
+ /**
+ * parse an XML file
+ *
+ * @param string $xml path/URL to XML file
+ * @param string $type (schema | xml)
+ * @return boolean
+ * @access public
+ */
+ function parseFile($xml,$type){
+ // parse xml file
+ if($xml != ""){
+ $xmlStr = @join("",@file($xml));
+ if($xmlStr == ""){
+ $msg = 'Error reading XML from '.$xml;
+ $this->setError($msg);
+ $this->debug($msg);
+ return false;
+ } else {
+ $this->debug("parsing $xml");
+ $this->parseString($xmlStr,$type);
+ $this->debug("done parsing $xml");
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * parse an XML string
+ *
+ * @param string $xml path or URL
+ * @param string $type (schema|xml)
+ * @access private
+ */
+ function parseString($xml,$type){
+ // parse xml string
+ if($xml != ""){
+
+ // Create an XML parser.
+ $this->parser = xml_parser_create();
+ // Set the options for parsing the XML data.
+ xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
+
+ // Set the object for the parser.
+ xml_set_object($this->parser, $this);
+
+ // Set the element handlers for the parser.
+ if($type == "schema"){
+ xml_set_element_handler($this->parser, 'schemaStartElement','schemaEndElement');
+ xml_set_character_data_handler($this->parser,'schemaCharacterData');
+ } elseif($type == "xml"){
+ xml_set_element_handler($this->parser, 'xmlStartElement','xmlEndElement');
+ xml_set_character_data_handler($this->parser,'xmlCharacterData');
+ }
+
+ // Parse the XML file.
+ if(!xml_parse($this->parser,$xml,true)){
+ // Display an error message.
+ $errstr = sprintf('XML error parsing XML schema on line %d: %s',
+ xml_get_current_line_number($this->parser),
+ xml_error_string(xml_get_error_code($this->parser))
+ );
+ $this->debug($errstr);
+ $this->debug("XML payload:\n" . $xml);
+ $this->setError($errstr);
+ }
+
+ xml_parser_free($this->parser);
+ } else{
+ $this->debug('no xml passed to parseString()!!');
+ $this->setError('no xml passed to parseString()!!');
+ }
+ }
+
+ /**
+ * 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
+ * @param string $name element name
+ * @param string $attrs associative array of attributes
+ * @access private
+ */
+ function schemaStartElement($parser, $name, $attrs) {
+
+ // position in the total number of elements, starting from 0
+ $pos = $this->position++;
+ $depth = $this->depth++;
+ // set self as current value for this depth
+ $this->depth_array[$depth] = $pos;
+ $this->message[$pos] = array('cdata' => '');
+ if ($depth > 0) {
+ $this->defaultNamespace[$pos] = $this->defaultNamespace[$this->depth_array[$depth - 1]];
+ } else {
+ $this->defaultNamespace[$pos] = false;
+ }
+
+ // get element prefix
+ if($prefix = $this->getPrefix($name)){
+ // get unqualified name
+ $name = $this->getLocalPart($name);
+ } else {
+ $prefix = '';
+ }
+
+ // loop thru attributes, expanding, and registering namespace declarations
+ if(count($attrs) > 0){
+ foreach($attrs as $k => $v){
+ // if ns declarations, add to class level array of valid namespaces
+ if(ereg("^xmlns",$k)){
+ //$this->xdebug("$k: $v");
+ //$this->xdebug('ns_prefix: '.$this->getPrefix($k));
+ if($ns_prefix = substr(strrchr($k,':'),1)){
+ //$this->xdebug("Add namespace[$ns_prefix] = $v");
+ $this->namespaces[$ns_prefix] = $v;
+ } else {
+ $this->defaultNamespace[$pos] = $v;
+ if (! $this->getPrefixFromNamespace($v)) {
+ $this->namespaces['ns'.(count($this->namespaces)+1)] = $v;
+ }
+ }
+ if($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema'){
+ $this->XMLSchemaVersion = $v;
+ $this->namespaces['xsi'] = $v.'-instance';
+ }
+ }
+ }
+ foreach($attrs as $k => $v){
+ // expand each attribute
+ $k = strpos($k,':') ? $this->expandQname($k) : $k;
+ $v = strpos($v,':') ? $this->expandQname($v) : $v;
+ $eAttrs[$k] = $v;
+ }
+ $attrs = $eAttrs;
+ } else {
+ $attrs = array();
+ }
+ // find status, register data
+ switch($name){
+ case 'all': // (optional) compositor content for a complexType
+ case 'choice':
+ case 'group':
+ case 'sequence':
+ //$this->xdebug("compositor $name for currentComplexType: $this->currentComplexType and currentElement: $this->currentElement");
+ $this->complexTypes[$this->currentComplexType]['compositor'] = $name;
+ //if($name == 'all' || $name == 'sequence'){
+ // $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
+ //}
+ break;
+ case 'attribute': // complexType attribute
+ //$this->xdebug("parsing attribute $attrs[name] $attrs[ref] of value: ".$attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']);
+ $this->xdebug("parsing attribute:");
+ $this->appendDebug($this->varDump($attrs));
+ if (!isset($attrs['form'])) {
+ $attrs['form'] = $this->schemaInfo['attributeFormDefault'];
+ }
+ if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
+ $v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
+ if (!strpos($v, ':')) {
+ // no namespace in arrayType attribute value...
+ if ($this->defaultNamespace[$pos]) {
+ // ...so use the default
+ $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'] = $this->defaultNamespace[$pos] . ':' . $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
+ }
+ }
+ }
+ if(isset($attrs['name'])){
+ $this->attributes[$attrs['name']] = $attrs;
+ $aname = $attrs['name'];
+ } elseif(isset($attrs['ref']) && $attrs['ref'] == 'http://schemas.xmlsoap.org/soap/encoding/:arrayType'){
+ if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
+ $aname = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
+ } else {
+ $aname = '';
+ }
+ } elseif(isset($attrs['ref'])){
+ $aname = $attrs['ref'];
+ $this->attributes[$attrs['ref']] = $attrs;
+ }
+
+ if($this->currentComplexType){ // This should *always* be
+ $this->complexTypes[$this->currentComplexType]['attrs'][$aname] = $attrs;
+ }
+ // arrayType attribute
+ if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']) || $this->getLocalPart($aname) == 'arrayType'){
+ $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
+ $prefix = $this->getPrefix($aname);
+ if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])){
+ $v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
+ } else {
+ $v = '';
+ }
+ if(strpos($v,'[,]')){
+ $this->complexTypes[$this->currentComplexType]['multidimensional'] = true;
+ }
+ $v = substr($v,0,strpos($v,'[')); // clip the []
+ if(!strpos($v,':') && isset($this->typemap[$this->XMLSchemaVersion][$v])){
+ $v = $this->XMLSchemaVersion.':'.$v;
+ }
+ $this->complexTypes[$this->currentComplexType]['arrayType'] = $v;
+ }
+ break;
+ case 'complexContent': // (optional) content for a complexType
+ break;
+ 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'];
+ $this->complexTypes[$this->currentComplexType] = $attrs;
+ $this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType';
+ // This is for constructs like
+ // <complexType name="ListOfString" base="soap:Array">
+ // <sequence>
+ // <element name="string" type="xsd:string"
+ // minOccurs="0" maxOccurs="unbounded" />
+ // </sequence>
+ // </complexType>
+ if(isset($attrs['base']) && ereg(':Array$',$attrs['base'])){
+ $this->xdebug('complexType is unusual array');
+ $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
+ } else {
+ $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
+ }
+ } 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';
+ // This is for constructs like
+ // <complexType name="ListOfString" base="soap:Array">
+ // <sequence>
+ // <element name="string" type="xsd:string"
+ // minOccurs="0" maxOccurs="unbounded" />
+ // </sequence>
+ // </complexType>
+ if(isset($attrs['base']) && ereg(':Array$',$attrs['base'])){
+ $this->xdebug('complexType is unusual array');
+ $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
+ } else {
+ $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
+ }
+ }
+ break;
+ case 'element':
+ array_push($this->elementStack, $this->currentElement);
+ if (!isset($attrs['form'])) {
+ $attrs['form'] = $this->schemaInfo['elementFormDefault'];
+ }
+ if(isset($attrs['type'])){
+ $this->xdebug("processing typed element ".$attrs['name']." of type ".$attrs['type']);
+ if (! $this->getPrefix($attrs['type'])) {
+ if ($this->defaultNamespace[$pos]) {
+ $attrs['type'] = $this->defaultNamespace[$pos] . ':' . $attrs['type'];
+ $this->xdebug('used default namespace to make type ' . $attrs['type']);
+ }
+ }
+ // This is for constructs like
+ // <complexType name="ListOfString" base="soap:Array">
+ // <sequence>
+ // <element name="string" type="xsd:string"
+ // minOccurs="0" maxOccurs="unbounded" />
+ // </sequence>
+ // </complexType>
+ if ($this->currentComplexType && $this->complexTypes[$this->currentComplexType]['phpType'] == 'array') {
+ $this->xdebug('arrayType for unusual array is ' . $attrs['type']);
+ $this->complexTypes[$this->currentComplexType]['arrayType'] = $attrs['type'];
+ }
+ $this->currentElement = $attrs['name'];
+ $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 {
+ $type = $this->CreateTypeName($this->currentComplexType . '_' . $attrs['name']);
+ $this->xdebug("processing untyped element " . $attrs['name'] . ' type ' . $type);
+ $this->currentElement = $attrs['name'];
+ $attrs['type'] = $this->schemaTargetNamespace . ':' . $type;
+ $ename = $attrs['name'];
+ }
+ 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
+ $this->xdebug('enumeration ' . $attrs['value']);
+ if ($this->currentSimpleType) {
+ $this->simpleTypes[$this->currentSimpleType]['enumeration'][] = $attrs['value'];
+ } elseif ($this->currentComplexType) {
+ $this->complexTypes[$this->currentComplexType]['enumeration'][] = $attrs['value'];
+ }
+ break;
+ case 'extension': // simpleContent or complexContent type extension
+ $this->xdebug('extension ' . $attrs['base']);
+ if ($this->currentComplexType) {
+ $this->complexTypes[$this->currentComplexType]['extensionBase'] = $attrs['base'];
+ }
+ break;
+ case 'import':
+ if (isset($attrs['schemaLocation'])) {
+ //$this->xdebug('import namespace ' . $attrs['namespace'] . ' from ' . $attrs['schemaLocation']);
+ $this->imports[$attrs['namespace']][] = array('location' => $attrs['schemaLocation'], 'loaded' => false);
+ } else {
+ //$this->xdebug('import namespace ' . $attrs['namespace']);
+ $this->imports[$attrs['namespace']][] = array('location' => '', 'loaded' => true);
+ if (! $this->getPrefixFromNamespace($attrs['namespace'])) {
+ $this->namespaces['ns'.(count($this->namespaces)+1)] = $attrs['namespace'];
+ }
+ }
+ break;
+ case 'list': // simpleType value list
+ break;
+ case 'restriction': // simpleType, simpleContent or complexContent value restriction
+ $this->xdebug('restriction ' . $attrs['base']);
+ if($this->currentSimpleType){
+ $this->simpleTypes[$this->currentSimpleType]['type'] = $attrs['base'];
+ } elseif($this->currentComplexType){
+ $this->complexTypes[$this->currentComplexType]['restrictionBase'] = $attrs['base'];
+ if(strstr($attrs['base'],':') == ':Array'){
+ $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
+ }
+ }
+ break;
+ case 'schema':
+ $this->schemaInfo = $attrs;
+ $this->schemaInfo['schemaVersion'] = $this->getNamespaceFromPrefix($prefix);
+ if (isset($attrs['targetNamespace'])) {
+ $this->schemaTargetNamespace = $attrs['targetNamespace'];
+ }
+ if (!isset($attrs['elementFormDefault'])) {
+ $this->schemaInfo['elementFormDefault'] = 'unqualified';
+ }
+ if (!isset($attrs['attributeFormDefault'])) {
+ $this->schemaInfo['attributeFormDefault'] = 'unqualified';
+ }
+ break;
+ case 'simpleContent': // (optional) content for a complexType
+ break;
+ case 'simpleType':
+ array_push($this->simpleTypeStack, $this->currentSimpleType);
+ if(isset($attrs['name'])){
+ $this->xdebug("processing simpleType for name " . $attrs['name']);
+ $this->currentSimpleType = $attrs['name'];
+ $this->simpleTypes[ $attrs['name'] ] = $attrs;
+ $this->simpleTypes[ $attrs['name'] ]['typeClass'] = 'simpleType';
+ $this->simpleTypes[ $attrs['name'] ]['phpType'] = 'scalar';
+ } else {
+ $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';
+ }
+ break;
+ case 'union': // simpleType type list
+ break;
+ default:
+ //$this->xdebug("do not have anything to do for element $name");
+ }
+ }
+
+ /**
+ * end-element handler
+ *
+ * @param string $parser XML parser object
+ * @param string $name element name
+ * @access private
+ */
+ function schemaEndElement($parser, $name) {
+ // bring depth down a notch
+ $this->depth--;
+ // position of current element is equal to the last value left in depth_array for my depth
+ if(isset($this->depth_array[$this->depth])){
+ $pos = $this->depth_array[$this->depth];
+ }
+ // get element prefix
+ if ($prefix = $this->getPrefix($name)){
+ // get unqualified name
+ $name = $this->getLocalPart($name);
+ } else {
+ $prefix = '';
+ }
+ // move on...
+ if($name == 'complexType'){
+ $this->xdebug('done processing complexType ' . ($this->currentComplexType ? $this->currentComplexType : '(unknown)'));
+ $this->currentComplexType = array_pop($this->complexTypeStack);
+ //$this->currentElement = false;
+ }
+ if($name == 'element'){
+ $this->xdebug('done processing element ' . ($this->currentElement ? $this->currentElement : '(unknown)'));
+ $this->currentElement = array_pop($this->elementStack);
+ }
+ if($name == 'simpleType'){
+ $this->xdebug('done processing simpleType ' . ($this->currentSimpleType ? $this->currentSimpleType : '(unknown)'));
+ $this->currentSimpleType = array_pop($this->simpleTypeStack);
+ }
+ }
+
+ /**
+ * element content handler
+ *
+ * @param string $parser XML parser object
+ * @param string $data element content
+ * @access private
+ */
+ function schemaCharacterData($parser, $data){
+ $pos = $this->depth_array[$this->depth - 1];
+ $this->message[$pos]['cdata'] .= $data;
+ }
+
+ /**
+ * serialize the schema
+ *
+ * @access public
+ */
+ function serializeSchema(){
+
+ $schemaPrefix = $this->getPrefixFromNamespace($this->XMLSchemaVersion);
+ $xml = '';
+ // imports
+ if (sizeof($this->imports) > 0) {
+ foreach($this->imports as $ns => $list) {
+ foreach ($list as $ii) {
+ if ($ii['location'] != '') {
+ $xml .= " <$schemaPrefix:import location=\"" . $ii['location'] . '" namespace="' . $ns . "\" />\n";
+ } else {
+ $xml .= " <$schemaPrefix:import namespace=\"" . $ns . "\" />\n";
+ }
+ }
+ }
+ }
+ // complex types
+ foreach($this->complexTypes as $typeName => $attrs){
+ $contentStr = '';
+ // serialize child elements
+ if(isset($attrs['elements']) && (count($attrs['elements']) > 0)){
+ foreach($attrs['elements'] as $element => $eParts){
+ if(isset($eParts['ref'])){
+ $contentStr .= " <$schemaPrefix:element ref=\"$element\"/>\n";
+ } else {
+ $contentStr .= " <$schemaPrefix:element name=\"$element\" type=\"" . $this->contractQName($eParts['type']) . "\"";
+ foreach ($eParts as $aName => $aValue) {
+ // handle, e.g., abstract, default, form, minOccurs, maxOccurs, nillable
+ if ($aName != 'name' && $aName != 'type') {
+ $contentStr .= " $aName=\"$aValue\"";
+ }
+ }
+ $contentStr .= "/>\n";
+ }
+ }
+ // compositor wraps elements
+ if (isset($attrs['compositor']) && ($attrs['compositor'] != '')) {
+ $contentStr = " <$schemaPrefix:$attrs[compositor]>\n".$contentStr." </$schemaPrefix:$attrs[compositor]>\n";
+ }
+ }
+ // attributes
+ if(isset($attrs['attrs']) && (count($attrs['attrs']) >= 1)){
+ foreach($attrs['attrs'] as $attr => $aParts){
+ $contentStr .= " <$schemaPrefix:attribute";
+ foreach ($aParts as $a => $v) {
+ if ($a == 'ref' || $a == 'type') {
+ $contentStr .= " $a=\"".$this->contractQName($v).'"';
+ } elseif ($a == 'http://schemas.xmlsoap.org/wsdl/:arrayType') {
+ $this->usedNamespaces['wsdl'] = $this->namespaces['wsdl'];
+ $contentStr .= ' wsdl:arrayType="'.$this->contractQName($v).'"';
+ } else {
+ $contentStr .= " $a=\"$v\"";
+ }
+ }
+ $contentStr .= "/>\n";
+ }
+ }
+ // if restriction
+ if (isset($attrs['restrictionBase']) && $attrs['restrictionBase'] != ''){
+ $contentStr = " <$schemaPrefix:restriction base=\"".$this->contractQName($attrs['restrictionBase'])."\">\n".$contentStr." </$schemaPrefix:restriction>\n";
+ // complex or simple content
+ if ((isset($attrs['elements']) && count($attrs['elements']) > 0) || (isset($attrs['attrs']) && count($attrs['attrs']) > 0)){
+ $contentStr = " <$schemaPrefix:complexContent>\n".$contentStr." </$schemaPrefix:complexContent>\n";
+ }
+ }
+ // finalize complex type
+ if($contentStr != ''){
+ $contentStr = " <$schemaPrefix:complexType name=\"$typeName\">\n".$contentStr." </$schemaPrefix:complexType>\n";
+ } else {
+ $contentStr = " <$schemaPrefix:complexType name=\"$typeName\"/>\n";
+ }
+ $xml .= $contentStr;
+ }
+ // 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";
+ if (isset($eParts['enumeration'])) {
+ foreach ($eParts['enumeration'] as $e) {
+ $xml .= " <$schemaPrefix:enumeration value=\"$e\"/>\n";
+ }
+ }
+ $xml .= " </$schemaPrefix:restriction>\n </$schemaPrefix:simpleType>";
+ }
+ }
+ // elements
+ if(isset($this->elements) && count($this->elements) > 0){
+ foreach($this->elements as $element => $eParts){
+ $xml .= " <$schemaPrefix:element name=\"$element\" type=\"".$this->contractQName($eParts['type'])."\"/>\n";
+ }
+ }
+ // attributes
+ if(isset($this->attributes) && count($this->attributes) > 0){
+ foreach($this->attributes as $attr => $aParts){
+ $xml .= " <$schemaPrefix:attribute name=\"$attr\" type=\"".$this->contractQName($aParts['type'])."\"\n/>";
+ }
+ }
+ // finish 'er up
+ $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\"";
+ }
+ $xml = $el . ">\n".$xml."</$schemaPrefix:schema>\n";
+ return $xml;
+ }
+
+ /**
+ * adds debug data to the clas level debug string
+ *
+ * @param string $string debug data
+ * @access private
+ */
+ function xdebug($string){
+ $this->debug('<' . $this->schemaTargetNamespace . '> '.$string);
+ }
+
+ /**
+ * get the PHP type of a user defined type in the schema
+ * PHP type is kind of a misnomer since it actually returns 'struct' for assoc. arrays
+ * 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
+ * @return mixed
+ * @access public
+ * @deprecated
+ */
+ function getPHPType($type,$ns){
+ if(isset($this->typemap[$ns][$type])){
+ //print "found type '$type' and ns $ns in typemap<br>";
+ return $this->typemap[$ns][$type];
+ } elseif(isset($this->complexTypes[$type])){
+ //print "getting type '$type' and ns $ns from complexTypes array<br>";
+ return $this->complexTypes[$type]['phpType'];
+ }
+ return false;
+ }
+
+ /**
+ * returns an associative array of information about a given type
+ * returns false if no type exists by the given name
+ *
+ * For a complexType typeDef = array(
+ * 'restrictionBase' => '',
+ * 'phpType' => '',
+ * 'compositor' => '(sequence|all)',
+ * 'elements' => array(), // refs to elements array
+ * 'attrs' => array() // refs to attributes array
+ * ... and so on (see addComplexType)
+ * )
+ *
+ * For simpleType or element, the array has different keys.
+ *
+ * @param string $type
+ * @return mixed
+ * @access public
+ * @see addComplexType
+ * @see addSimpleType
+ * @see addElement
+ */
+ function getTypeDef($type){
+ //$this->debug("in getTypeDef for type $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((! $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
+ // TODO: can this ever really apply (i.e. what is a simpleType really?)
+ $uqType = substr($this->simpleTypes[$type]['type'], strrpos($this->simpleTypes[$type]['type'], ':') + 1);
+ $ns = substr($this->simpleTypes[$type]['type'], 0, strrpos($this->simpleTypes[$type]['type'], ':'));
+ $etype = $this->getTypeDef($uqType);
+ if ($etype) {
+ $this->xdebug("in getTypeDef, found type for simpleType $type:");
+ $this->xdebug($this->varDump($etype));
+ if (isset($etype['phpType'])) {
+ $this->simpleTypes[$type]['phpType'] = $etype['phpType'];
+ }
+ if (isset($etype['elements'])) {
+ $this->simpleTypes[$type]['elements'] = $etype['elements'];
+ }
+ }
+ }
+ return $this->simpleTypes[$type];
+ } elseif(isset($this->elements[$type])){
+ $this->xdebug("in getTypeDef, found element $type");
+ if (!isset($this->elements[$type]['phpType'])) {
+ // get info for type to tack onto the element
+ $uqType = substr($this->elements[$type]['type'], strrpos($this->elements[$type]['type'], ':') + 1);
+ $ns = substr($this->elements[$type]['type'], 0, strrpos($this->elements[$type]['type'], ':'));
+ $etype = $this->getTypeDef($uqType);
+ if ($etype) {
+ $this->xdebug("in getTypeDef, found type for element $type:");
+ $this->xdebug($this->varDump($etype));
+ if (isset($etype['phpType'])) {
+ $this->elements[$type]['phpType'] = $etype['phpType'];
+ }
+ if (isset($etype['elements'])) {
+ $this->elements[$type]['elements'] = $etype['elements'];
+ }
+ } elseif ($ns == 'http://www.w3.org/2001/XMLSchema') {
+ $this->xdebug("in getTypeDef, element $type is an XSD type");
+ $this->elements[$type]['phpType'] = 'scalar';
+ }
+ }
+ return $this->elements[$type];
+ } elseif(isset($this->attributes[$type])){
+ $this->xdebug("in getTypeDef, found attribute $type");
+ return $this->attributes[$type];
+ } elseif (ereg('_ContainedType$', $type)) {
+ $this->xdebug("in getTypeDef, have an untyped element $type");
+ $typeDef['typeClass'] = 'simpleType';
+ $typeDef['phpType'] = 'scalar';
+ $typeDef['type'] = 'http://www.w3.org/2001/XMLSchema:string';
+ return $typeDef;
+ }
+ $this->xdebug("in getTypeDef, did not find $type");
+ return false;
+ }
+
+ /**
+ * returns a sample serialization of a given type, or false if no type by the given name
+ *
+ * @param string $type name of type
+ * @return mixed
+ * @access public
+ * @deprecated
+ */
+ function serializeTypeDef($type){
+ //print "in sTD() for type $type<br>";
+ if($typeDef = $this->getTypeDef($type)){
+ $str .= '<'.$type;
+ if(is_array($typeDef['attrs'])){
+ foreach($typeDef['attrs'] as $attName => $data){
+ $str .= " $attName=\"{type = ".$data['type']."}\"";
+ }
+ }
+ $str .= " xmlns=\"".$this->schema['targetNamespace']."\"";
+ if(count($typeDef['elements']) > 0){
+ $str .= ">";
+ foreach($typeDef['elements'] as $element => $eData){
+ $str .= $this->serializeTypeDef($element);
+ }
+ $str .= "</$type>";
+ } elseif($typeDef['typeClass'] == 'element') {
+ $str .= "></$type>";
+ } else {
+ $str .= "/>";
+ }
+ return $str;
+ }
+ return false;
+ }
+
+ /**
+ * 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
+ * @return string
+ * @access public
+ * @deprecated
+ */
+ function typeToForm($name,$type){
+ // get typedef
+ if($typeDef = $this->getTypeDef($type)){
+ // if struct
+ if($typeDef['phpType'] == 'struct'){
+ $buffer .= '<table>';
+ foreach($typeDef['elements'] as $child => $childDef){
+ $buffer .= "
+ <tr><td align='right'>$childDef[name] (type: ".$this->getLocalPart($childDef['type'])."):</td>
+ <td><input type='text' name='parameters[".$name."][$childDef[name]]'></td></tr>";
+ }
+ $buffer .= '</table>';
+ // if array
+ } elseif($typeDef['phpType'] == 'array'){
+ $buffer .= '<table>';
+ for($i=0;$i < 3; $i++){
+ $buffer .= "
+ <tr><td align='right'>array item (type: $typeDef[arrayType]):</td>
+ <td><input type='text' name='parameters[".$name."][]'></td></tr>";
+ }
+ $buffer .= '</table>';
+ // if scalar
+ } else {
+ $buffer .= "<input type='text' name='parameters[$name]'>";
+ }
+ } else {
+ $buffer .= "<input type='text' name='parameters[$name]'>";
+ }
+ return $buffer;
+ }
+
+ /**
+ * adds a complex type to the schema
+ *
+ * example: array
+ *
+ * addType(
+ * 'ArrayOfstring',
+ * 'complexType',
+ * 'array',
+ * '',
+ * 'SOAP-ENC:Array',
+ * array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'string[]'),
+ * 'xsd:string'
+ * );
+ *
+ * example: PHP associative array ( SOAP Struct )
+ *
+ * addType(
+ * 'SOAPStruct',
+ * 'complexType',
+ * 'struct',
+ * 'all',
+ * array('myVar'=> array('name'=>'myVar','type'=>'string')
+ * );
+ *
+ * @param name
+ * @param typeClass (complexType|simpleType|attribute)
+ * @param phpType: currently supported are array and struct (php assoc array)
+ * @param compositor (all|sequence|choice)
+ * @param restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array)
+ * @param elements = array ( name = array(name=>'',type=>'') )
+ * @param attrs = array(
+ * array(
+ * 'ref' => "http://schemas.xmlsoap.org/soap/encoding/:arrayType",
+ * "http://schemas.xmlsoap.org/wsdl/:arrayType" => "string[]"
+ * )
+ * )
+ * @param arrayType: namespace:name (http://www.w3.org/2001/XMLSchema:string)
+ * @access public
+ * @see getTypeDef
+ */
+ function addComplexType($name,$typeClass='complexType',$phpType='array',$compositor='',$restrictionBase='',$elements=array(),$attrs=array(),$arrayType=''){
+ $this->complexTypes[$name] = array(
+ 'name' => $name,
+ 'typeClass' => $typeClass,
+ 'phpType' => $phpType,
+ 'compositor'=> $compositor,
+ 'restrictionBase' => $restrictionBase,
+ 'elements' => $elements,
+ 'attrs' => $attrs,
+ 'arrayType' => $arrayType
+ );
+
+ $this->xdebug("addComplexType $name:");
+ $this->appendDebug($this->varDump($this->complexTypes[$name]));
+ }
+
+ /**
+ * adds a simple type to the schema
+ *
+ * @param string $name
+ * @param string $restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array)
+ * @param string $typeClass (should always be simpleType)
+ * @param string $phpType (should always be scalar)
+ * @param array $enumeration array of values
+ * @access public
+ * @see nusoap_xmlschema
+ * @see getTypeDef
+ */
+ function addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array()) {
+ $this->simpleTypes[$name] = array(
+ 'name' => $name,
+ 'typeClass' => $typeClass,
+ 'phpType' => $phpType,
+ 'type' => $restrictionBase,
+ 'enumeration' => $enumeration
+ );
+
+ $this->xdebug("addSimpleType $name:");
+ $this->appendDebug($this->varDump($this->simpleTypes[$name]));
+ }
+
+ /**
+ * adds an element to the schema
+ *
+ * @param array $attrs attributes that must include name and type
+ * @see nusoap_xmlschema
+ * @access public
+ */
+ function addElement($attrs) {
+ if (! $this->getPrefix($attrs['type'])) {
+ $attrs['type'] = $this->schemaTargetNamespace . ':' . $attrs['type'];
+ }
+ $this->elements[ $attrs['name'] ] = $attrs;
+ $this->elements[ $attrs['name'] ]['typeClass'] = 'element';
+
+ $this->xdebug("addElement " . $attrs['name']);
+ $this->appendDebug($this->varDump($this->elements[ $attrs['name'] ]));
+ }
+}
+
+/**
+ * Backward compatibility
+ */
+class XMLSchema_om extends nusoap_xmlschema_om {
+}
+
+?><?php
+
+
+
+/**
+* For creating serializable abstractions of native PHP types. This class
+* allows element name/namespace, XSD type, and XML attributes to be
+* associated with a value. This is extremely useful when WSDL is not
+* used, but is also useful when WSDL is used with polymorphic types, including
+* xsd:anyType and user-defined types.
+*
+* @author Dietrich Ayala <di...@ganx4.com>
+* @version $Id: nusoap.php,v 1.114 2007/11/06 15:17:46 snichol Exp $
+* @access public
+*/
+class soapval_om extends nusoap_base_om {
+ /**
+ * The XML element name
+ *
+ * @var string
+ * @access private
+ */
+ var $name;
+ /**
+ * The XML type name (string or false)
+ *
+ * @var mixed
+ * @access private
+ */
+ var $type;
+ /**
+ * The PHP value
+ *
+ * @var mixed
+ * @access private
+ */
+ var $value;
+ /**
+ * The XML element namespace (string or false)
+ *
+ * @var mixed
+ * @access private
+ */
+ var $element_ns;
+ /**
+ * The XML type namespace (string or false)
+ *
+ * @var mixed
+ * @access private
+ */
+ var $type_ns;
+ /**
+ * The XML element attributes (array or false)
+ *
+ * @var mixed
+ * @access private
+ */
+ var $attributes;
+
+ /**
+ * constructor
+ *
+ * @param string $name optional name
+ * @param mixed $type optional type name
+ * @param mixed $value optional value
+ * @param mixed $element_ns optional namespace of value
+ * @param mixed $type_ns optional namespace of type
+ * @param mixed $attributes associative array of attributes to add to element serialization
+ * @access public
+ */
+ function soapval_om($name='soapval',$type=false,$value=-1,$element_ns=false,$type_ns=false,$attributes=false) {
+ parent::nusoap_base_om();
+ $this->name = $name;
+ $this->type = $type;
+ $this->value = $value;
+ $this->element_ns = $element_ns;
+ $this->type_ns = $type_ns;
+ $this->attributes = $attributes;
+ }
+
+ /**
+ * return serialized value
+ *
+ * @param string $use The WSDL use value (encoded|literal)
+ * @return string XML data
+ * @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, true);
+ }
+
+ /**
+ * decodes a soapval object into a PHP native type
+ *
+ * @return mixed
+ * @access public
+ */
+ function decode(){
+ return $this->value;
+ }
+}
+
+
+
+?><?php
+
+
+
+/**
+* transport class for sending/receiving data via HTTP and HTTPS
+* NOTE: PHP must be compiled with the CURL extension for HTTPS support
+*
+* @author Dietrich Ayala <di...@ganx4.com>
+* @author Scott Nichol <sn...@users.sourceforge.net>
+* @version $Id: nusoap.php,v 1.114 2007/11/06 15:17:46 snichol Exp $
+* @access public
+*/
+class soap_transport_http_om extends nusoap_base_om {
+
+ var $url = '';
+ var $uri = '';
+ var $digest_uri = '';
+ var $scheme = '';
+ var $host = '';
+ var $port = '';
+ var $path = '';
+ var $request_method = 'POST';
+ var $protocol_version = '1.0';
+ var $encoding = '';
+ var $outgoing_headers = array();
+ var $incoming_headers = array();
+ 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, 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_om($url, $curl_options = NULL, $use_curl = false){
+ parent::nusoap_base_om();
+ $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->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("parsed URL $k = $v");
+ $this->$k = $v;
+ }
+
+ // add any GET params to path
+ if(isset($u['query']) && $u['query'] != ''){
+ $this->path .= '?' . $u['query'];
+ }
+
+ // set default port
+ if(!isset($u['port'])){
+ if($u['scheme'] == 'https'){
+ $this->port = 443;
+ } else {
+ $this->port = 80;
+ }
+ }
+
+ $this->uri = $this->path;
+ $this->digest_uri = $this->uri;
+
+ // build headers
+ if (!isset($u['port'])) {
+ $this->setHeader('Host', $this->host);
+ } else {
+ $this->setHeader('Host', $this->host.':'.$this->port);
+ }
+
+ 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.
+ // TODO: disabled for now because OpenSSL must be *compiled* in (not just
+ // loaded), and until PHP5 stream_get_wrappers is not available.
+// if ($this->scheme == 'https') {
+// if (version_compare(phpversion(), '4.3.0') >= 0) {
+// if (extension_loaded('openssl')) {
+// $this->scheme = 'ssl';
+// $this->debug('Using SSL over OpenSSL');
+// }
+// }
+// }
+ $this->debug("connect connection_timeout $connection_timeout, response_timeout $response_timeout, scheme $this->scheme, host $this->host, port $this->port");
+ 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)) {
+ $this->debug('Re-use persistent connection');
+ return true;
+ }
+ fclose($this->fp);
+ $this->debug('Closed persistent connection at EOF');
+ }
+
+ // munge host if using OpenSSL
+ if ($this->scheme == 'ssl') {
+ $host = 'ssl://' . $host;
+ }
+ $this->debug('calling fsockopen with host ' . $host . ' connection_timeout ' . $connection_timeout);
+
+ // open socket
+ if($connection_timeout > 0){
+ $this->fp = @fsockopen( $host, $this->port, $this->errno, $this->error_str, $connection_timeout);
+ } else {
+ $this->fp = @fsockopen( $host, $this->port, $this->errno, $this->error_str);
+ }
+
+ // test pointer
+ if(!$this->fp) {
+ $msg = 'Couldn\'t open socket connection to server ' . $this->url;
+ if ($this->errno) {
+ $msg .= ', Error ('.$this->errno.'): '.$this->error_str;
+ } else {
+ $msg .= ' prior to connect(). This is often a problem looking up the host name.';
+ }
+ $this->debug($msg);
+ $this->setError($msg);
+ return false;
+ }
+
+ // set response timeout
+ $this->debug('set response timeout to ' . $response_timeout);
+ socket_set_timeout( $this->fp, $response_timeout);
+
+ $this->debug('socket connected');
+ return true;
+ } 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('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;
+ }
+ // 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 != '') ? "$this->scheme://$this->host:$this->port" : "$this->scheme://$this->host";
+ // add path
+ $hostURL .= $this->path;
+ $this->setCurlOption(CURLOPT_URL, $hostURL);
+ // follow location headers (re-directs)
+ 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
+ $this->setCurlOption(CURLOPT_HEADER, 1);
+ // ask for the response output as the return value
+ $this->setCurlOption(CURLOPT_RETURNTRANSFER, 1);
+ // encode
+ // We manage this ourselves through headers and encoding
+// if(function_exists('gzuncompress')){
+// $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.
+ //$this->setCurlOption(CURL_HTTP_VERSION_1_1, true);
+ $this->persistentConnection = false;
+ $this->setHeader('Connection', 'close');
+ }
+ // set timeouts
+ if ($connection_timeout != 0) {
+ $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 ($this->authtype && ($this->authtype != 'certificate')) {
+ if ($this->username) {
+ $this->debug('set cURL username/password');
+ $this->setCurlOption(CURLOPT_USERPWD, "$this->username:$this->password");
+ }
+ if ($this->authtype == 'basic') {
+ $this->debug('set cURL for Basic authentication');
+ $this->setCurlOption($CURLOPT_HTTPAUTH, $CURLAUTH_BASIC);
+ }
+ if ($this->authtype == 'digest') {
+ $this->debug('set cURL for digest authentication');
+ $this->setCurlOption($CURLOPT_HTTPAUTH, $CURLAUTH_DIGEST);
+ }
+ 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');
+ return true;
+ } else {
+ $this->setError('Unknown scheme ' . $this->scheme);
+ $this->debug('Unknown scheme ' . $this->scheme);
+ return false;
+ }
+ }
+
+ /**
+ * 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
+ * @param integer $response_timeout set response timeout in seconds
+ * @param array $cookies cookies to send
+ * @return string data
+ * @access public
+ */
+ function send($data, $timeout=0, $response_timeout=30, $cookies=NULL) {
+
+ $this->debug('entered send() with data of length: '.strlen($data));
+
+ $this->tryagain = true;
+ $tries = 0;
+ while ($this->tryagain) {
+ $this->tryagain = false;
+ if ($tries++ < 2) {
+ // make connnection
+ if (!$this->connect($timeout, $response_timeout)){
+ return false;
+ }
+
+ // send request
+ if (!$this->sendRequest($data, $cookies)){
+ return false;
+ }
+
+ // get response
+ $respdata = $this->getResponse();
+ } else {
+ $this->setError("Too many tries to get an OK response ($this->response_status_line)");
+ }
+ }
+ $this->debug('end of send()');
+ return $respdata;
+ }
+
+
+ /**
+ * sends the SOAP request and gets the SOAP response via HTTPS using CURL
+ *
+ * @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);
+ }
+
+ /**
+ * if authenticating, set user credentials here
+ *
+ * @param string $username
+ * @param string $password
+ * @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, 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("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->setHeader('Authorization', 'Basic '.base64_encode(str_replace(':','',$username).':'.$password));
+ } elseif ($authtype == 'digest') {
+ if (isset($digestRequest['nonce'])) {
+ $digestRequest['nc'] = isset($digestRequest['nc']) ? $digestRequest['nc']++ : 1;
+
+ // calculate the Digest hashes (calculate code based on digest implementation found at: http://www.rassoc.com/gregr/weblog/stories/2002/07/09/webServicesSecurityHttpDigestAuthenticationWithoutActiveDirectory.html)
+
+ // A1 = unq(username-value) ":" unq(realm-value) ":" passwd
+ $A1 = $username. ':' . (isset($digestRequest['realm']) ? $digestRequest['realm'] : '') . ':' . $password;
+
+ // H(A1) = MD5(A1)
+ $HA1 = md5($A1);
+
+ // A2 = Method ":" digest-uri-value
+ $A2 = $this->request_method . ':' . $this->digest_uri;
+
+ // H(A2)
+ $HA2 = md5($A2);
+
+ // KD(secret, data) = H(concat(secret, ":", data))
+ // if qop == auth:
+ // request-digest = <"> < KD ( H(A1), unq(nonce-value)
+ // ":" nc-value
+ // ":" unq(cnonce-value)
+ // ":" unq(qop-value)
+ // ":" H(A2)
+ // ) <">
+ // if qop is missing,
[... 5475 lines stripped ...]