/nusoap/lib/nusoap.php-Dateireferenz

gehe zum Quellcode dieser Datei

Klassen

class  nusoap_base
class  nusoap_fault
class  soap_fault
class  nusoap_xmlschema
class  XMLSchema
class  soapval
class  soap_transport_http
class  nusoap_server
class  soap_server
class  wsdl
class  nusoap_parser
class  soap_parser
class  nusoap_client

Funktionen

 timestamp_to_iso8601 ($timestamp, $utc=true)
 iso8601_to_timestamp ($datestr)
 usleepWindows ($usec)

Variablen

 $GLOBALS ['_transient']['static']['nusoap_base']['globalDebugLevel'] = 9


Dokumentation der Funktionen

iso8601_to_timestamp ( datestr  ) 

convert ISO 8601 compliant date string to unix timestamp

Parameter:
string $datestr ISO 8601 compliant date string
Rückgabe:
mixed Unix timestamp (int) or false public

Definiert in Zeile 942 der Datei nusoap.php.

00942                                        {
00943         $eregStr =
00944         '([0-9]{4})-'.  // centuries & years CCYY-
00945         '([0-9]{2})-'.  // months MM-
00946         '([0-9]{2})'.   // days DD
00947         'T'.                    // separator T
00948         '([0-9]{2}):'.  // hours hh:
00949         '([0-9]{2}):'.  // minutes mm:
00950         '([0-9]{2})(\.[0-9]+)?'. // seconds ss.ss...
00951         '(Z|[+\-][0-9]{2}:?[0-9]{2})?'; // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's
00952         if(ereg($eregStr,$datestr,$regs)){
00953                 // not utc
00954                 if($regs[8] != 'Z'){
00955                         $op = substr($regs[8],0,1);
00956                         $h = substr($regs[8],1,2);
00957                         $m = substr($regs[8],strlen($regs[8])-2,2);
00958                         if($op == '-'){
00959                                 $regs[4] = $regs[4] + $h;
00960                                 $regs[5] = $regs[5] + $m;
00961                         } elseif($op == '+'){
00962                                 $regs[4] = $regs[4] - $h;
00963                                 $regs[5] = $regs[5] - $m;
00964                         }
00965                 }
00966                 return gmmktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
00967 //              return strtotime("$regs[1]-$regs[2]-$regs[3] $regs[4]:$regs[5]:$regs[6]Z");
00968         } else {
00969                 return false;
00970         }
00971 }

timestamp_to_iso8601 ( timestamp,
utc = true 
)

convert unix timestamp to ISO 8601 compliant date string

Parameter:
int $timestamp Unix time stamp
boolean $utc Whether the time stamp is UTC or local
Rückgabe:
mixed ISO 8601 date string or false public

Definiert in Zeile 904 der Datei nusoap.php.

00904                                                    {
00905         $datestr = date('Y-m-d\TH:i:sO',$timestamp);
00906         $pos = strrpos($datestr, "+");
00907         if ($pos === FALSE) {
00908                 $pos = strrpos($datestr, "-");
00909         }
00910         if ($pos !== FALSE) {
00911                 if (strlen($datestr) == $pos + 5) {
00912                         $datestr = substr($datestr, 0, $pos + 3) . ':' . substr($datestr, -2);
00913                 }
00914         }
00915         if($utc){
00916                 $eregStr =
00917                 '([0-9]{4})-'.  // centuries & years CCYY-
00918                 '([0-9]{2})-'.  // months MM-
00919                 '([0-9]{2})'.   // days DD
00920                 'T'.                    // separator T
00921                 '([0-9]{2}):'.  // hours hh:
00922                 '([0-9]{2}):'.  // minutes mm:
00923                 '([0-9]{2})(\.[0-9]*)?'. // seconds ss.ss...
00924                 '(Z|[+\-][0-9]{2}:?[0-9]{2})?'; // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's
00925 
00926                 if(ereg($eregStr,$datestr,$regs)){
00927                         return sprintf('%04d-%02d-%02dT%02d:%02d:%02dZ',$regs[1],$regs[2],$regs[3],$regs[4],$regs[5],$regs[6]);
00928                 }
00929                 return false;
00930         } else {
00931                 return $datestr;
00932         }
00933 }

usleepWindows ( usec  ) 

sleeps some number of microseconds

Parameter:
string $usec the number of microseconds to sleep public
Veraltet:

For backwards compatiblity, define soapclient unless the PHP SOAP extension is loaded.

Definiert in Zeile 980 der Datei nusoap.php.

00981 {
00982         $start = gettimeofday();
00983         
00984         do
00985         {
00986                 $stop = gettimeofday();
00987                 $timePassed = 1000000 * ($stop['sec'] - $start['sec'])
00988                 + $stop['usec'] - $start['usec'];
00989         }
00990         while ($timePassed < $usec);
00991 }
00992 
00993 ?><?php
00994 
00995 
00996 
01005 class nusoap_fault extends nusoap_base {
01011         var $faultcode;
01017         var $faultactor;
01023         var $faultstring;
01029         var $faultdetail;
01030 
01039         function nusoap_fault($faultcode,$faultactor='',$faultstring='',$faultdetail=''){
01040                 parent::nusoap_base();
01041                 $this->faultcode = $faultcode;
01042                 $this->faultactor = $faultactor;
01043                 $this->faultstring = $faultstring;
01044                 $this->faultdetail = $faultdetail;
01045         }
01046 
01053         function serialize(){
01054                 $ns_string = '';
01055                 foreach($this->namespaces as $k => $v){
01056                         $ns_string .= "\n  xmlns:$k=\"$v\"";
01057                 }
01058                 $return_msg =
01059                         '<?xml version="1.0" encoding="'.$this->soap_defencoding.'"?>'.
01060                         '<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"'.$ns_string.">\n".
01061                                 '<SOAP-ENV:Body>'.
01062                                 '<SOAP-ENV:Fault>'.
01063                                         $this->serialize_val($this->faultcode, 'faultcode').
01064                                         $this->serialize_val($this->faultactor, 'faultactor').
01065                                         $this->serialize_val($this->faultstring, 'faultstring').
01066                                         $this->serialize_val($this->faultdetail, 'detail').
01067                                 '</SOAP-ENV:Fault>'.
01068                                 '</SOAP-ENV:Body>'.
01069                         '</SOAP-ENV:Envelope>';
01070                 return $return_msg;
01071         }
01072 }
01073 
01077 class soap_fault extends nusoap_fault {
01078 }
01079 
01080 ?><?php
01081 
01082 
01083 
01093 class nusoap_xmlschema extends nusoap_base  {
01094         
01095         // files
01096         var $schema = '';
01097         var $xml = '';
01098         // namespaces
01099         var $enclosingNamespaces;
01100         // schema info
01101         var $schemaInfo = array();
01102         var $schemaTargetNamespace = '';
01103         // types, elements, attributes defined by the schema
01104         var $attributes = array();
01105         var $complexTypes = array();
01106         var $complexTypeStack = array();
01107         var $currentComplexType = null;
01108         var $elements = array();
01109         var $elementStack = array();
01110         var $currentElement = null;
01111         var $simpleTypes = array();
01112         var $simpleTypeStack = array();
01113         var $currentSimpleType = null;
01114         // imports
01115         var $imports = array();
01116         // parser vars
01117         var $parser;
01118         var $position = 0;
01119         var $depth = 0;
01120         var $depth_array = array();
01121         var $message = array();
01122         var $defaultNamespace = array();
01123     
01132         function nusoap_xmlschema($schema='',$xml='',$namespaces=array()){
01133                 parent::nusoap_base();
01134                 $this->debug('nusoap_xmlschema class instantiated, inside constructor');
01135                 // files
01136                 $this->schema = $schema;
01137                 $this->xml = $xml;
01138 
01139                 // namespaces
01140                 $this->enclosingNamespaces = $namespaces;
01141                 $this->namespaces = array_merge($this->namespaces, $namespaces);
01142 
01143                 // parse schema file
01144                 if($schema != ''){
01145                         $this->debug('initial schema file: '.$schema);
01146                         $this->parseFile($schema, 'schema');
01147                 }
01148 
01149                 // parse xml file
01150                 if($xml != ''){
01151                         $this->debug('initial xml file: '.$xml);
01152                         $this->parseFile($xml, 'xml');
01153                 }
01154 
01155         }
01156 
01165         function parseFile($xml,$type){
01166                 // parse xml file
01167                 if($xml != ""){
01168                         $xmlStr = @join("",@file($xml));
01169                         if($xmlStr == ""){
01170                                 $msg = 'Error reading XML from '.$xml;
01171                                 $this->setError($msg);
01172                                 $this->debug($msg);
01173                         return false;
01174                         } else {
01175                                 $this->debug("parsing $xml");
01176                                 $this->parseString($xmlStr,$type);
01177                                 $this->debug("done parsing $xml");
01178                         return true;
01179                         }
01180                 }
01181                 return false;
01182         }
01183 
01191         function parseString($xml,$type){
01192                 // parse xml string
01193                 if($xml != ""){
01194 
01195                 // Create an XML parser.
01196                 $this->parser = xml_parser_create();
01197                 // Set the options for parsing the XML data.
01198                 xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
01199 
01200                 // Set the object for the parser.
01201                 xml_set_object($this->parser, $this);
01202 
01203                 // Set the element handlers for the parser.
01204                         if($type == "schema"){
01205                         xml_set_element_handler($this->parser, 'schemaStartElement','schemaEndElement');
01206                         xml_set_character_data_handler($this->parser,'schemaCharacterData');
01207                         } elseif($type == "xml"){
01208                                 xml_set_element_handler($this->parser, 'xmlStartElement','xmlEndElement');
01209                         xml_set_character_data_handler($this->parser,'xmlCharacterData');
01210                         }
01211 
01212                     // Parse the XML file.
01213                     if(!xml_parse($this->parser,$xml,true)){
01214                         // Display an error message.
01215                                 $errstr = sprintf('XML error parsing XML schema on line %d: %s',
01216                                 xml_get_current_line_number($this->parser),
01217                                 xml_error_string(xml_get_error_code($this->parser))
01218                                 );
01219                                 $this->debug($errstr);
01220                                 $this->debug("XML payload:\n" . $xml);
01221                                 $this->setError($errstr);
01222                 }
01223             
01224                         xml_parser_free($this->parser);
01225                 } else{
01226                         $this->debug('no xml passed to parseString()!!');
01227                         $this->setError('no xml passed to parseString()!!');
01228                 }
01229         }
01230 
01238         function CreateTypeName($ename) {
01239                 $scope = '';
01240                 for ($i = 0; $i < count($this->complexTypeStack); $i++) {
01241                         $scope .= $this->complexTypeStack[$i] . '_';
01242                 }
01243                 return $scope . $ename . '_ContainedType';
01244         }
01245         
01254         function schemaStartElement($parser, $name, $attrs) {
01255                 
01256                 // position in the total number of elements, starting from 0
01257                 $pos = $this->position++;
01258                 $depth = $this->depth++;
01259                 // set self as current value for this depth
01260                 $this->depth_array[$depth] = $pos;
01261                 $this->message[$pos] = array('cdata' => ''); 
01262                 if ($depth > 0) {
01263                         $this->defaultNamespace[$pos] = $this->defaultNamespace[$this->depth_array[$depth - 1]];
01264                 } else {
01265                         $this->defaultNamespace[$pos] = false;
01266                 }
01267 
01268                 // get element prefix
01269                 if($prefix = $this->getPrefix($name)){
01270                         // get unqualified name
01271                         $name = $this->getLocalPart($name);
01272                 } else {
01273                 $prefix = '';
01274         }
01275                 
01276         // loop thru attributes, expanding, and registering namespace declarations
01277         if(count($attrs) > 0){
01278                 foreach($attrs as $k => $v){
01279                 // if ns declarations, add to class level array of valid namespaces
01280                                 if(ereg("^xmlns",$k)){
01281                         //$this->xdebug("$k: $v");
01282                         //$this->xdebug('ns_prefix: '.$this->getPrefix($k));
01283                         if($ns_prefix = substr(strrchr($k,':'),1)){
01284                                 //$this->xdebug("Add namespace[$ns_prefix] = $v");
01285                                                 $this->namespaces[$ns_prefix] = $v;
01286                                         } else {
01287                                                 $this->defaultNamespace[$pos] = $v;
01288                                                 if (! $this->getPrefixFromNamespace($v)) {
01289                                                         $this->namespaces['ns'.(count($this->namespaces)+1)] = $v;
01290                                                 }
01291                                         }
01292                                         if($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema'){
01293                                                 $this->XMLSchemaVersion = $v;
01294                                                 $this->namespaces['xsi'] = $v.'-instance';
01295                                         }
01296                                 }
01297                 }
01298                 foreach($attrs as $k => $v){
01299                 // expand each attribute
01300                 $k = strpos($k,':') ? $this->expandQname($k) : $k;
01301                 $v = strpos($v,':') ? $this->expandQname($v) : $v;
01302                         $eAttrs[$k] = $v;
01303                 }
01304                 $attrs = $eAttrs;
01305         } else {
01306                 $attrs = array();
01307         }
01308                 // find status, register data
01309                 switch($name){
01310                         case 'all':                     // (optional) compositor content for a complexType
01311                         case 'choice':
01312                         case 'group':
01313                         case 'sequence':
01314                                 //$this->xdebug("compositor $name for currentComplexType: $this->currentComplexType and currentElement: $this->currentElement");
01315                                 $this->complexTypes[$this->currentComplexType]['compositor'] = $name;
01316                                 //if($name == 'all' || $name == 'sequence'){
01317                                 //      $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
01318                                 //}
01319                         break;
01320                         case 'attribute':       // complexType attribute
01321                 //$this->xdebug("parsing attribute $attrs[name] $attrs[ref] of value: ".$attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']);
01322                 $this->xdebug("parsing attribute:");
01323                 $this->appendDebug($this->varDump($attrs));
01324                                 if (!isset($attrs['form'])) {
01325                                         // TODO: handle globals
01326                                         $attrs['form'] = $this->schemaInfo['attributeFormDefault'];
01327                                 }
01328                 if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
01329                                         $v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
01330                                         if (!strpos($v, ':')) {
01331                                                 // no namespace in arrayType attribute value...
01332                                                 if ($this->defaultNamespace[$pos]) {
01333                                                         // ...so use the default
01334                                                         $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'] = $this->defaultNamespace[$pos] . ':' . $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
01335                                                 }
01336                                         }
01337                 }
01338                 if(isset($attrs['name'])){
01339                                         $this->attributes[$attrs['name']] = $attrs;
01340                                         $aname = $attrs['name'];
01341                                 } elseif(isset($attrs['ref']) && $attrs['ref'] == 'http://schemas.xmlsoap.org/soap/encoding/:arrayType'){
01342                                         if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
01343                                 $aname = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
01344                         } else {
01345                                 $aname = '';
01346                         }
01347                                 } elseif(isset($attrs['ref'])){
01348                                         $aname = $attrs['ref'];
01349                     $this->attributes[$attrs['ref']] = $attrs;
01350                                 }
01351                 
01352                                 if($this->currentComplexType){  // This should *always* be
01353                                         $this->complexTypes[$this->currentComplexType]['attrs'][$aname] = $attrs;
01354                                 }
01355                                 // arrayType attribute
01356                                 if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']) || $this->getLocalPart($aname) == 'arrayType'){
01357                                         $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
01358                         $prefix = $this->getPrefix($aname);
01359                                         if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])){
01360                                                 $v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
01361                                         } else {
01362                                                 $v = '';
01363                                         }
01364                     if(strpos($v,'[,]')){
01365                         $this->complexTypes[$this->currentComplexType]['multidimensional'] = true;
01366                     }
01367                     $v = substr($v,0,strpos($v,'[')); // clip the []
01368                     if(!strpos($v,':') && isset($this->typemap[$this->XMLSchemaVersion][$v])){
01369                         $v = $this->XMLSchemaVersion.':'.$v;
01370                     }
01371                     $this->complexTypes[$this->currentComplexType]['arrayType'] = $v;
01372                                 }
01373                         break;
01374                         case 'complexContent':  // (optional) content for a complexType
01375                                 $this->xdebug("do nothing for element $name");
01376                         break;
01377                         case 'complexType':
01378                                 array_push($this->complexTypeStack, $this->currentComplexType);
01379                                 if(isset($attrs['name'])){
01380                                         // TODO: what is the scope of named complexTypes that appear
01381                                         //       nested within other c complexTypes?
01382                                         $this->xdebug('processing named complexType '.$attrs['name']);
01383                                         //$this->currentElement = false;
01384                                         $this->currentComplexType = $attrs['name'];
01385                                         $this->complexTypes[$this->currentComplexType] = $attrs;
01386                                         $this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType';
01387                                         // This is for constructs like
01388                                         //           <complexType name="ListOfString" base="soap:Array">
01389                                         //                <sequence>
01390                                         //                    <element name="string" type="xsd:string"
01391                                         //                        minOccurs="0" maxOccurs="unbounded" />
01392                                         //                </sequence>
01393                                         //            </complexType>
01394                                         if(isset($attrs['base']) && ereg(':Array$',$attrs['base'])){
01395                                                 $this->xdebug('complexType is unusual array');
01396                                                 $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
01397                                         } else {
01398                                                 $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
01399                                         }
01400                                 } else {
01401                                         $name = $this->CreateTypeName($this->currentElement);
01402                                         $this->xdebug('processing unnamed complexType for element ' . $this->currentElement . ' named ' . $name);
01403                                         $this->currentComplexType = $name;
01404                                         //$this->currentElement = false;
01405                                         $this->complexTypes[$this->currentComplexType] = $attrs;
01406                                         $this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType';
01407                                         // This is for constructs like
01408                                         //           <complexType name="ListOfString" base="soap:Array">
01409                                         //                <sequence>
01410                                         //                    <element name="string" type="xsd:string"
01411                                         //                        minOccurs="0" maxOccurs="unbounded" />
01412                                         //                </sequence>
01413                                         //            </complexType>
01414                                         if(isset($attrs['base']) && ereg(':Array$',$attrs['base'])){
01415                                                 $this->xdebug('complexType is unusual array');
01416                                                 $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
01417                                         } else {
01418                                                 $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
01419                                         }
01420                                 }
01421                         break;
01422                         case 'element':
01423                                 array_push($this->elementStack, $this->currentElement);
01424                                 if (!isset($attrs['form'])) {
01425                                         if ($this->currentComplexType) {
01426                                                 $attrs['form'] = $this->schemaInfo['elementFormDefault'];
01427                                         } else {
01428                                                 // global
01429                                                 $attrs['form'] = 'qualified';
01430                                         }
01431                                 }
01432                                 if(isset($attrs['type'])){
01433                                         $this->xdebug("processing typed element ".$attrs['name']." of type ".$attrs['type']);
01434                                         if (! $this->getPrefix($attrs['type'])) {
01435                                                 if ($this->defaultNamespace[$pos]) {
01436                                                         $attrs['type'] = $this->defaultNamespace[$pos] . ':' . $attrs['type'];
01437                                                         $this->xdebug('used default namespace to make type ' . $attrs['type']);
01438                                                 }
01439                                         }
01440                                         // This is for constructs like
01441                                         //           <complexType name="ListOfString" base="soap:Array">
01442                                         //                <sequence>
01443                                         //                    <element name="string" type="xsd:string"
01444                                         //                        minOccurs="0" maxOccurs="unbounded" />
01445                                         //                </sequence>
01446                                         //            </complexType>
01447                                         if ($this->currentComplexType && $this->complexTypes[$this->currentComplexType]['phpType'] == 'array') {
01448                                                 $this->xdebug('arrayType for unusual array is ' . $attrs['type']);
01449                                                 $this->complexTypes[$this->currentComplexType]['arrayType'] = $attrs['type'];
01450                                         }
01451                                         $this->currentElement = $attrs['name'];
01452                                         $ename = $attrs['name'];
01453                                 } elseif(isset($attrs['ref'])){
01454                                         $this->xdebug("processing element as ref to ".$attrs['ref']);
01455                                         $this->currentElement = "ref to ".$attrs['ref'];
01456                                         $ename = $this->getLocalPart($attrs['ref']);
01457                                 } else {
01458                                         $type = $this->CreateTypeName($this->currentComplexType . '_' . $attrs['name']);
01459                                         $this->xdebug("processing untyped element " . $attrs['name'] . ' type ' . $type);
01460                                         $this->currentElement = $attrs['name'];
01461                                         $attrs['type'] = $this->schemaTargetNamespace . ':' . $type;
01462                                         $ename = $attrs['name'];
01463                                 }
01464                                 if (isset($ename) && $this->currentComplexType) {
01465                                         $this->xdebug("add element $ename to complexType $this->currentComplexType");
01466                                         $this->complexTypes[$this->currentComplexType]['elements'][$ename] = $attrs;
01467                                 } elseif (!isset($attrs['ref'])) {
01468                                         $this->xdebug("add element $ename to elements array");
01469                                         $this->elements[ $attrs['name'] ] = $attrs;
01470                                         $this->elements[ $attrs['name'] ]['typeClass'] = 'element';
01471                                 }
01472                         break;
01473                         case 'enumeration':     //      restriction value list member
01474                                 $this->xdebug('enumeration ' . $attrs['value']);
01475                                 if ($this->currentSimpleType) {
01476                                         $this->simpleTypes[$this->currentSimpleType]['enumeration'][] = $attrs['value'];
01477                                 } elseif ($this->currentComplexType) {
01478                                         $this->complexTypes[$this->currentComplexType]['enumeration'][] = $attrs['value'];
01479                                 }
01480                         break;
01481                         case 'extension':       // simpleContent or complexContent type extension
01482                                 $this->xdebug('extension ' . $attrs['base']);
01483                                 if ($this->currentComplexType) {
01484                                         $ns = $this->getPrefix($attrs['base']);
01485                                         if ($ns == '') {
01486                                                 $this->complexTypes[$this->currentComplexType]['extensionBase'] = $this->schemaTargetNamespace . ':' . $attrs['base'];
01487                                         } elseif ($this->getNamespaceFromPrefix($ns)) {
01488                                                 $this->complexTypes[$this->currentComplexType]['extensionBase'] = $attrs['base'];
01489                                         }
01490                                 }
01491                         break;
01492                         case 'import':
01493                             if (isset($attrs['schemaLocation'])) {
01494                                         $this->xdebug('import namespace ' . $attrs['namespace'] . ' from ' . $attrs['schemaLocation']);
01495                     $this->imports[$attrs['namespace']][] = array('location' => $attrs['schemaLocation'], 'loaded' => false);
01496                                 } else {
01497                                         $this->xdebug('import namespace ' . $attrs['namespace']);
01498                     $this->imports[$attrs['namespace']][] = array('location' => '', 'loaded' => true);
01499                                         if (! $this->getPrefixFromNamespace($attrs['namespace'])) {
01500                                                 $this->namespaces['ns'.(count($this->namespaces)+1)] = $attrs['namespace'];
01501                                         }
01502                                 }
01503                         break;
01504                         case 'include':
01505                             if (isset($attrs['schemaLocation'])) {
01506                                         $this->xdebug('include into namespace ' . $this->schemaTargetNamespace . ' from ' . $attrs['schemaLocation']);
01507                     $this->imports[$this->schemaTargetNamespace][] = array('location' => $attrs['schemaLocation'], 'loaded' => false);
01508                                 } else {
01509                                         $this->xdebug('ignoring invalid XML Schema construct: include without schemaLocation attribute');
01510                                 }
01511                         break;
01512                         case 'list':    // simpleType value list
01513                                 $this->xdebug("do nothing for element $name");
01514                         break;
01515                         case 'restriction':     // simpleType, simpleContent or complexContent value restriction
01516                                 $this->xdebug('restriction ' . $attrs['base']);
01517                                 if($this->currentSimpleType){
01518                                         $this->simpleTypes[$this->currentSimpleType]['type'] = $attrs['base'];
01519                                 } elseif($this->currentComplexType){
01520                                         $this->complexTypes[$this->currentComplexType]['restrictionBase'] = $attrs['base'];
01521                                         if(strstr($attrs['base'],':') == ':Array'){
01522                                                 $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
01523                                         }
01524                                 }
01525                         break;
01526                         case 'schema':
01527                                 $this->schemaInfo = $attrs;
01528                                 $this->schemaInfo['schemaVersion'] = $this->getNamespaceFromPrefix($prefix);
01529                                 if (isset($attrs['targetNamespace'])) {
01530                                         $this->schemaTargetNamespace = $attrs['targetNamespace'];
01531                                 }
01532                                 if (!isset($attrs['elementFormDefault'])) {
01533                                         $this->schemaInfo['elementFormDefault'] = 'unqualified';
01534                                 }
01535                                 if (!isset($attrs['attributeFormDefault'])) {
01536                                         $this->schemaInfo['attributeFormDefault'] = 'unqualified';
01537                                 }
01538                         break;
01539                         case 'simpleContent':   // (optional) content for a complexType
01540                                 $this->xdebug("do nothing for element $name");
01541                         break;
01542                         case 'simpleType':
01543                                 array_push($this->simpleTypeStack, $this->currentSimpleType);
01544                                 if(isset($attrs['name'])){
01545                                         $this->xdebug("processing simpleType for name " . $attrs['name']);
01546                                         $this->currentSimpleType = $attrs['name'];
01547                                         $this->simpleTypes[ $attrs['name'] ] = $attrs;
01548                                         $this->simpleTypes[ $attrs['name'] ]['typeClass'] = 'simpleType';
01549                                         $this->simpleTypes[ $attrs['name'] ]['phpType'] = 'scalar';
01550                                 } else {
01551                                         $name = $this->CreateTypeName($this->currentComplexType . '_' . $this->currentElement);
01552                                         $this->xdebug('processing unnamed simpleType for element ' . $this->currentElement . ' named ' . $name);
01553                                         $this->currentSimpleType = $name;
01554                                         //$this->currentElement = false;
01555                                         $this->simpleTypes[$this->currentSimpleType] = $attrs;
01556                                         $this->simpleTypes[$this->currentSimpleType]['phpType'] = 'scalar';
01557                                 }
01558                         break;
01559                         case 'union':   // simpleType type list
01560                                 $this->xdebug("do nothing for element $name");
01561                         break;
01562                         default:
01563                                 $this->xdebug("do not have any logic to process element $name");
01564                 }
01565         }
01566 
01574         function schemaEndElement($parser, $name) {
01575                 // bring depth down a notch
01576                 $this->depth--;
01577                 // position of current element is equal to the last value left in depth_array for my depth
01578                 if(isset($this->depth_array[$this->depth])){
01579                 $pos = $this->depth_array[$this->depth];
01580         }
01581                 // get element prefix
01582                 if ($prefix = $this->getPrefix($name)){
01583                         // get unqualified name
01584                         $name = $this->getLocalPart($name);
01585                 } else {
01586                 $prefix = '';
01587         }
01588                 // move on...
01589                 if($name == 'complexType'){
01590                         $this->xdebug('done processing complexType ' . ($this->currentComplexType ? $this->currentComplexType : '(unknown)'));
01591                         $this->currentComplexType = array_pop($this->complexTypeStack);
01592                         //$this->currentElement = false;
01593                 }
01594                 if($name == 'element'){
01595                         $this->xdebug('done processing element ' . ($this->currentElement ? $this->currentElement : '(unknown)'));
01596                         $this->currentElement = array_pop($this->elementStack);
01597                 }
01598                 if($name == 'simpleType'){
01599                         $this->xdebug('done processing simpleType ' . ($this->currentSimpleType ? $this->currentSimpleType : '(unknown)'));
01600                         $this->currentSimpleType = array_pop($this->simpleTypeStack);
01601                 }
01602         }
01603 
01611         function schemaCharacterData($parser, $data){
01612                 $pos = $this->depth_array[$this->depth - 1];
01613                 $this->message[$pos]['cdata'] .= $data;
01614         }
01615 
01621         function serializeSchema(){
01622 
01623                 $schemaPrefix = $this->getPrefixFromNamespace($this->XMLSchemaVersion);
01624                 $xml = '';
01625                 // imports
01626                 if (sizeof($this->imports) > 0) {
01627                         foreach($this->imports as $ns => $list) {
01628                                 foreach ($list as $ii) {
01629                                         if ($ii['location'] != '') {
01630                                                 $xml .= " <$schemaPrefix:import location=\"" . $ii['location'] . '" namespace="' . $ns . "\" />\n";
01631                                         } else {
01632                                                 $xml .= " <$schemaPrefix:import namespace=\"" . $ns . "\" />\n";
01633                                         }
01634                                 }
01635                         } 
01636                 } 
01637                 // complex types
01638                 foreach($this->complexTypes as $typeName => $attrs){
01639                         $contentStr = '';
01640                         // serialize child elements
01641                         if(isset($attrs['elements']) && (count($attrs['elements']) > 0)){
01642                                 foreach($attrs['elements'] as $element => $eParts){
01643                                         if(isset($eParts['ref'])){
01644                                                 $contentStr .= "   <$schemaPrefix:element ref=\"$element\"/>\n";
01645                                         } else {
01646                                                 $contentStr .= "   <$schemaPrefix:element name=\"$element\" type=\"" . $this->contractQName($eParts['type']) . "\"";
01647                                                 foreach ($eParts as $aName => $aValue) {
01648                                                         // handle, e.g., abstract, default, form, minOccurs, maxOccurs, nillable
01649                                                         if ($aName != 'name' && $aName != 'type') {
01650                                                                 $contentStr .= " $aName=\"$aValue\"";
01651                                                         }
01652                                                 }
01653                                                 $contentStr .= "/>\n";
01654                                         }
01655                                 }
01656                                 // compositor wraps elements
01657                                 if (isset($attrs['compositor']) && ($attrs['compositor'] != '')) {
01658                                         $contentStr = "  <$schemaPrefix:$attrs[compositor]>\n".$contentStr."  </$schemaPrefix:$attrs[compositor]>\n";
01659                                 }
01660                         }
01661                         // attributes
01662                         if(isset($attrs['attrs']) && (count($attrs['attrs']) >= 1)){
01663                                 foreach($attrs['attrs'] as $attr => $aParts){
01664                                         $contentStr .= "    <$schemaPrefix:attribute";
01665                                         foreach ($aParts as $a => $v) {
01666                                                 if ($a == 'ref' || $a == 'type') {
01667                                                         $contentStr .= " $a=\"".$this->contractQName($v).'"';
01668                                                 } elseif ($a == 'http://schemas.xmlsoap.org/wsdl/:arrayType') {
01669                                                         $this->usedNamespaces['wsdl'] = $this->namespaces['wsdl'];
01670                                                         $contentStr .= ' wsdl:arrayType="'.$this->contractQName($v).'"';
01671                                                 } else {
01672                                                         $contentStr .= " $a=\"$v\"";
01673                                                 }
01674                                         }
01675                                         $contentStr .= "/>\n";
01676                                 }
01677                         }
01678                         // if restriction
01679                         if (isset($attrs['restrictionBase']) && $attrs['restrictionBase'] != ''){
01680                                 $contentStr = "   <$schemaPrefix:restriction base=\"".$this->contractQName($attrs['restrictionBase'])."\">\n".$contentStr."   </$schemaPrefix:restriction>\n";
01681                                 // complex or simple content
01682                                 if ((isset($attrs['elements']) && count($attrs['elements']) > 0) || (isset($attrs['attrs']) && count($attrs['attrs']) > 0)){
01683                                         $contentStr = "  <$schemaPrefix:complexContent>\n".$contentStr."  </$schemaPrefix:complexContent>\n";
01684                                 }
01685                         }
01686                         // finalize complex type
01687                         if($contentStr != ''){
01688                                 $contentStr = " <$schemaPrefix:complexType name=\"$typeName\">\n".$contentStr." </$schemaPrefix:complexType>\n";
01689                         } else {
01690                                 $contentStr = " <$schemaPrefix:complexType name=\"$typeName\"/>\n";
01691                         }
01692                         $xml .= $contentStr;
01693                 }
01694                 // simple types
01695                 if(isset($this->simpleTypes) && count($this->simpleTypes) > 0){
01696                         foreach($this->simpleTypes as $typeName => $eParts){
01697                                 $xml .= " <$schemaPrefix:simpleType name=\"$typeName\">\n  <$schemaPrefix:restriction base=\"".$this->contractQName($eParts['type'])."\">\n";
01698                                 if (isset($eParts['enumeration'])) {
01699                                         foreach ($eParts['enumeration'] as $e) {
01700                                                 $xml .= "  <$schemaPrefix:enumeration value=\"$e\"/>\n";
01701                                         }
01702                                 }
01703                                 $xml .= "  </$schemaPrefix:restriction>\n </$schemaPrefix:simpleType>";
01704                         }
01705                 }
01706                 // elements
01707                 if(isset($this->elements) && count($this->elements) > 0){
01708                         foreach($this->elements as $element => $eParts){
01709                                 $xml .= " <$schemaPrefix:element name=\"$element\" type=\"".$this->contractQName($eParts['type'])."\"/>\n";
01710                         }
01711                 }
01712                 // attributes
01713                 if(isset($this->attributes) && count($this->attributes) > 0){
01714                         foreach($this->attributes as $attr => $aParts){
01715                                 $xml .= " <$schemaPrefix:attribute name=\"$attr\" type=\"".$this->contractQName($aParts['type'])."\"\n/>";
01716                         }
01717                 }
01718                 // finish 'er up
01719                 $attr = '';
01720                 foreach ($this->schemaInfo as $k => $v) {
01721                         if ($k == 'elementFormDefault' || $k == 'attributeFormDefault') {
01722                                 $attr .= " $k=\"$v\"";
01723                         }
01724                 }
01725                 $el = "<$schemaPrefix:schema$attr targetNamespace=\"$this->schemaTargetNamespace\"\n";
01726                 foreach (array_diff($this->usedNamespaces, $this->enclosingNamespaces) as $nsp => $ns) {
01727                         $el .= " xmlns:$nsp=\"$ns\"";
01728                 }
01729                 $xml = $el . ">\n".$xml."</$schemaPrefix:schema>\n";
01730                 return $xml;
01731         }
01732 
01739         function xdebug($string){
01740                 $this->debug('<' . $this->schemaTargetNamespace . '> '.$string);
01741         }
01742 
01755         function getPHPType($type,$ns){
01756                 if(isset($this->typemap[$ns][$type])){
01757                         //print "found type '$type' and ns $ns in typemap<br>";
01758                         return $this->typemap[$ns][$type];
01759                 } elseif(isset($this->complexTypes[$type])){
01760                         //print "getting type '$type' and ns $ns from complexTypes array<br>";
01761                         return $this->complexTypes[$type]['phpType'];
01762                 }
01763                 return false;
01764         }
01765 
01788         function getTypeDef($type){
01789                 //$this->debug("in getTypeDef for type $type");
01790                 if (substr($type, -1) == '^') {
01791                         $is_element = 1;
01792                         $type = substr($type, 0, -1);
01793                 } else {
01794                         $is_element = 0;
01795                 }
01796 
01797                 if((! $is_element) && isset($this->complexTypes[$type])){
01798                         $this->xdebug("in getTypeDef, found complexType $type");
01799                         return $this->complexTypes[$type];
01800                 } elseif((! $is_element) && isset($this->simpleTypes[$type])){
01801                         $this->xdebug("in getTypeDef, found simpleType $type");
01802                         if (!isset($this->simpleTypes[$type]['phpType'])) {
01803                                 // get info for type to tack onto the simple type
01804                                 // TODO: can this ever really apply (i.e. what is a simpleType really?)
01805                                 $uqType = substr($this->simpleTypes[$type]['type'], strrpos($this->simpleTypes[$type]['type'], ':') + 1);
01806                                 $ns = substr($this->simpleTypes[$type]['type'], 0, strrpos($this->simpleTypes[$type]['type'], ':'));
01807                                 $etype = $this->getTypeDef($uqType);
01808                                 if ($etype) {
01809                                         $this->xdebug("in getTypeDef, found type for simpleType $type:");
01810                                         $this->xdebug($this->varDump($etype));
01811                                         if (isset($etype['phpType'])) {
01812                                                 $this->simpleTypes[$type]['phpType'] = $etype['phpType'];
01813                                         }
01814                                         if (isset($etype['elements'])) {
01815                                                 $this->simpleTypes[$type]['elements'] = $etype['elements'];
01816                                         }
01817                                 }
01818                         }
01819                         return $this->simpleTypes[$type];
01820                 } elseif(isset($this->elements[$type])){
01821                         $this->xdebug("in getTypeDef, found element $type");
01822                         if (!isset($this->elements[$type]['phpType'])) {
01823                                 // get info for type to tack onto the element
01824                                 $uqType = substr($this->elements[$type]['type'], strrpos($this->elements[$type]['type'], ':') + 1);
01825                                 $ns = substr($this->elements[$type]['type'], 0, strrpos($this->elements[$type]['type'], ':'));
01826                                 $etype = $this->getTypeDef($uqType);
01827                                 if ($etype) {
01828                                         $this->xdebug("in getTypeDef, found type for element $type:");
01829                                         $this->xdebug($this->varDump($etype));
01830                                         if (isset($etype['phpType'])) {
01831                                                 $this->elements[$type]['phpType'] = $etype['phpType'];
01832                                         }
01833                                         if (isset($etype['elements'])) {
01834                                                 $this->elements[$type]['elements'] = $etype['elements'];
01835                                         }
01836                                         if (isset($etype['extensionBase'])) {
01837                                                 $this->elements[$type]['extensionBase'] = $etype['extensionBase'];
01838                                         }
01839                                 } elseif ($ns == 'http://www.w3.org/2001/XMLSchema') {
01840                                         $this->xdebug("in getTypeDef, element $type is an XSD type");
01841                                         $this->elements[$type]['phpType'] = 'scalar';
01842                                 }
01843                         }
01844                         return $this->elements[$type];
01845                 } elseif(isset($this->attributes[$type])){
01846                         $this->xdebug("in getTypeDef, found attribute $type");
01847                         return $this->attributes[$type];
01848                 } elseif (ereg('_ContainedType$', $type)) {
01849                         $this->xdebug("in getTypeDef, have an untyped element $type");
01850                         $typeDef['typeClass'] = 'simpleType';
01851                         $typeDef['phpType'] = 'scalar';
01852                         $typeDef['type'] = 'http://www.w3.org/2001/XMLSchema:string';
01853                         return $typeDef;
01854                 }
01855                 $this->xdebug("in getTypeDef, did not find $type");
01856                 return false;
01857         }
01858 
01867     function serializeTypeDef($type){
01868         //print "in sTD() for type $type<br>";
01869         if($typeDef = $this->getTypeDef($type)){
01870                 $str .= '<'.$type;
01871             if(is_array($typeDef['attrs'])){
01872                 foreach($typeDef['attrs'] as $attName => $data){
01873                     $str .= " $attName=\"{type = ".$data['type']."}\"";
01874                 }
01875             }
01876             $str .= " xmlns=\"".$this->schema['targetNamespace']."\"";
01877             if(count($typeDef['elements']) > 0){
01878                 $str .= ">";
01879                 foreach($typeDef['elements'] as $element => $eData){
01880                     $str .= $this->serializeTypeDef($element);
01881                 }
01882                 $str .= "</$type>";
01883             } elseif($typeDef['typeClass'] == 'element') {
01884                 $str .= "></$type>";
01885             } else {
01886                 $str .= "/>";
01887             }
01888                         return $str;
01889         }
01890         return false;
01891     }
01892 
01903         function typeToForm($name,$type){
01904                 // get typedef
01905                 if($typeDef = $this->getTypeDef($type)){
01906                         // if struct
01907                         if($typeDef['phpType'] == 'struct'){
01908                                 $buffer .= '<table>';
01909                                 foreach($typeDef['elements'] as $child => $childDef){
01910                                         $buffer .= "
01911                                         <tr><td align='right'>$childDef[name] (type: ".$this->getLocalPart($childDef['type'])."):</td>
01912                                         <td><input type='text' name='parameters[".$name."][$childDef[name]]'></td></tr>";
01913                                 }
01914                                 $buffer .= '</table>';
01915                         // if array
01916                         } elseif($typeDef['phpType'] == 'array'){
01917                                 $buffer .= '<table>';
01918                                 for($i=0;$i < 3; $i++){
01919                                         $buffer .= "
01920                                         <tr><td align='right'>array item (type: $typeDef[arrayType]):</td>
01921                                         <td><input type='text' name='parameters[".$name."][]'></td></tr>";
01922                                 }
01923                                 $buffer .= '</table>';
01924                         // if scalar
01925                         } else {
01926                                 $buffer .= "<input type='text' name='parameters[$name]'>";
01927                         }
01928                 } else {
01929                         $buffer .= "<input type='text' name='parameters[$name]'>";
01930                 }
01931                 return $buffer;
01932         }
01933         
01975         function addComplexType($name,$typeClass='complexType',$phpType='array',$compositor='',$restrictionBase='',$elements=array(),$attrs=array(),$arrayType=''){
01976                 $this->complexTypes[$name] = array(
01977             'name'              => $name,
01978             'typeClass' => $typeClass,
01979             'phpType'   => $phpType,
01980                 'compositor'=> $compositor,
01981             'restrictionBase' => $restrictionBase,
01982                 'elements'      => $elements,
01983             'attrs'             => $attrs,
01984             'arrayType' => $arrayType
01985                 );
01986                 
01987                 $this->xdebug("addComplexType $name:");
01988                 $this->appendDebug($this->varDump($this->complexTypes[$name]));
01989         }
01990         
02003         function addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array()) {
02004                 $this->simpleTypes[$name] = array(
02005             'name'                      => $name,
02006             'typeClass'         => $typeClass,
02007             'phpType'           => $phpType,
02008             'type'                      => $restrictionBase,
02009             'enumeration'       => $enumeration
02010                 );
02011                 
02012                 $this->xdebug("addSimpleType $name:");
02013                 $this->appendDebug($this->varDump($this->simpleTypes[$name]));
02014         }
02015 
02023         function addElement($attrs) {
02024                 if (! $this->getPrefix($attrs['type'])) {
02025                         $attrs['type'] = $this->schemaTargetNamespace . ':' . $attrs['type'];
02026                 }
02027                 $this->elements[ $attrs['name'] ] = $attrs;
02028                 $this->elements[ $attrs['name'] ]['typeClass'] = 'element';
02029                 
02030                 $this->xdebug("addElement " . $attrs['name']);
02031                 $this->appendDebug($this->varDump($this->elements[ $attrs['name'] ]));
02032         }
02033 }
02034 
02038 class XMLSchema extends nusoap_xmlschema {
02039 }
02040 
02041 ?><?php
02042 
02043 
02044 
02056 class soapval extends nusoap_base {
02063         var $name;
02070         var $type;
02077         var $value;
02084         var $element_ns;
02091         var $type_ns;
02098         var $attributes;
02099 
02111         function soapval($name='soapval',$type=false,$value=-1,$element_ns=false,$type_ns=false,$attributes=false) {
02112                 parent::nusoap_base();
02113                 $this->name = $name;
02114                 $this->type = $type;
02115                 $this->value = $value;
02116                 $this->element_ns = $element_ns;
02117                 $this->type_ns = $type_ns;
02118                 $this->attributes = $attributes;
02119     }
02120 
02128         function serialize($use='encoded') {
02129                 return $this->serialize_val($this->value, $this->name, $this->type, $this->element_ns, $this->type_ns, $this->attributes, $use, true);
02130     }
02131 
02138         function decode(){
02139                 return $this->value;
02140         }
02141 }
02142 
02143 
02144 
02145 ?><?php
02146 
02147 
02148 
02158 class soap_transport_http extends nusoap_base {
02159 
02160         var $url = '';
02161         var $uri = '';
02162         var $digest_uri = '';
02163         var $scheme = '';
02164         var $host = '';
02165         var $port = '';
02166         var $path = '';
02167         var $request_method = 'POST';
02168         var $protocol_version = '1.0';
02169         var $encoding = '';
02170         var $outgoing_headers = array();
02171         var $incoming_headers = array();
02172         var $incoming_cookies = array();
02173         var $outgoing_payload = '';
02174         var $incoming_payload = '';
02175         var $response_status_line;      // HTTP response status line
02176         var $useSOAPAction = true;
02177         var $persistentConnection = false;
02178         var $ch = false;        // cURL handle
02179         var $ch_options = array();      // cURL custom options
02180         var $use_curl = false;          // force cURL use
02181         var $proxy = null;                      // proxy information (associative array)
02182         var $username = '';
02183         var $password = '';
02184         var $authtype = '';
02185         var $digestRequest = array();
02186         var $certRequest = array();     // keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, certpassword (optional), verifypeer (optional), verifyhost (optional)
02187                                                                 // cainfofile: certificate authority file, e.g. '$pathToPemFiles/rootca.pem'
02188                                                                 // sslcertfile: SSL certificate file, e.g. '$pathToPemFiles/mycert.pem'
02189                                                                 // sslkeyfile: SSL key file, e.g. '$pathToPemFiles/mykey.pem'
02190                                                                 // passphrase: SSL key password/passphrase
02191                                                                 // certpassword: SSL certificate password
02192                                                                 // verifypeer: default is 1
02193                                                                 // verifyhost: default is 1
02194 
02203         function soap_transport_http($url, $curl_options = NULL, $use_curl = false){
02204                 parent::nusoap_base();
02205                 $this->debug("ctor url=$url use_curl=$use_curl curl_options:");
02206                 $this->appendDebug($this->varDump($curl_options));
02207                 $this->setURL($url);
02208                 if (is_array($curl_options)) {
02209                         $this->ch_options = $curl_options;
02210                 }
02211                 $this->use_curl = $use_curl;
02212                 ereg('\$Revisio' . 'n: ([^ ]+)', $this->revision, $rev);
02213                 $this->setHeader('User-Agent', $this->title.'/'.$this->version.' ('.$rev[1].')');
02214         }
02215 
02223         function setCurlOption($option, $value) {
02224                 $this->debug("setCurlOption option=$option, value=");
02225                 $this->appendDebug($this->varDump($value));
02226                 curl_setopt($this->ch, $option, $value);
02227         }
02228 
02236         function setHeader($name, $value) {
02237                 $this->outgoing_headers[$name] = $value;
02238                 $this->debug("set header $name: $value");
02239         }
02240 
02247         function unsetHeader($name) {
02248                 if (isset($this->outgoing_headers[$name])) {
02249                         $this->debug("unset header $name");
02250                         unset($this->outgoing_headers[$name]);
02251                 }
02252         }
02253 
02260         function setURL($url) {
02261                 $this->url = $url;
02262 
02263                 $u = parse_url($url);
02264                 foreach($u as $k => $v){
02265                         $this->debug("parsed URL $k = $v");
02266                         $this->$k = $v;
02267                 }
02268                 
02269                 // add any GET params to path
02270                 if(isset($u['query']) && $u['query'] != ''){
02271             $this->path .= '?' . $u['query'];
02272                 }
02273                 
02274                 // set default port
02275                 if(!isset($u['port'])){
02276                         if($u['scheme'] == 'https'){
02277                                 $this->port = 443;
02278                         } else {
02279                                 $this->port = 80;
02280                         }
02281                 }
02282                 
02283                 $this->uri = $this->path;
02284                 $this->digest_uri = $this->uri;
02285                 
02286                 // build headers
02287                 if (!isset($u['port'])) {
02288                         $this->setHeader('Host', $this->host);
02289                 } else {
02290                         $this->setHeader('Host', $this->host.':'.$this->port);
02291                 }
02292 
02293                 if (isset($u['user']) && $u['user'] != '') {
02294                         $this->setCredentials(urldecode($u['user']), isset($u['pass']) ? urldecode($u['pass']) : '');
02295                 }
02296         }
02297 
02304         function io_method() {
02305                 if ($this->use_curl || ($this->scheme == 'https') || ($this->scheme == 'http' && $this->authtype == 'ntlm') || ($this->scheme == 'http' && is_array($this->proxy) && $this->proxy['authtype'] == 'ntlm'))
02306                         return 'curl';
02307                 if (($this->scheme == 'http' || $this->scheme == 'ssl') && $this->authtype != 'ntlm' && (!is_array($this->proxy) || $this->proxy['authtype'] != 'ntlm'))
02308                         return 'socket';
02309                 return 'unknown';
02310         }
02311 
02320         function connect($connection_timeout=0,$response_timeout=30){
02321                 // For PHP 4.3 with OpenSSL, change https scheme to ssl, then treat like
02322                 // "regular" socket.
02323                 // TODO: disabled for now because OpenSSL must be *compiled* in (not just
02324                 //       loaded), and until PHP5 stream_get_wrappers is not available.
02325 //              if ($this->scheme == 'https') {
02326 //                      if (version_compare(phpversion(), '4.3.0') >= 0) {
02327 //                              if (extension_loaded('openssl')) {
02328 //                                      $this->scheme = 'ssl';
02329 //                                      $this->debug('Using SSL over OpenSSL');
02330 //                              }
02331 //                      }
02332 //              }
02333                 $this->debug("connect connection_timeout $connection_timeout, response_timeout $response_timeout, scheme $this->scheme, host $this->host, port $this->port");
02334           if ($this->io_method() == 'socket') {
02335                 if (!is_array($this->proxy)) {
02336                         $host = $this->host;
02337                         $port = $this->port;
02338                 } else {
02339                         $host = $this->proxy['host'];
02340                         $port = $this->proxy['port'];
02341                 }
02342 
02343                 // use persistent connection
02344                 if($this->persistentConnection && isset($this->fp) && is_resource($this->fp)){
02345                         if (!feof($this->fp)) {
02346                                 $this->debug('Re-use persistent connection');
02347                                 return true;
02348                         }
02349                         fclose($this->fp);
02350                         $this->debug('Closed persistent connection at EOF');
02351                 }
02352 
02353                 // munge host if using OpenSSL
02354                 if ($this->scheme == 'ssl') {
02355                         $host = 'ssl://' . $host;
02356                 }
02357                 $this->debug('calling fsockopen with host ' . $host . ' connection_timeout ' . $connection_timeout);
02358 
02359                 // open socket
02360                 if($connection_timeout > 0){
02361                         $this->fp = @fsockopen( $host, $this->port, $this->errno, $this->error_str, $connection_timeout);
02362                 } else {
02363                         $this->fp = @fsockopen( $host, $this->port, $this->errno, $this->error_str);
02364                 }
02365                 
02366                 // test pointer
02367                 if(!$this->fp) {
02368                         $msg = 'Couldn\'t open socket connection to server ' . $this->url;
02369                         if ($this->errno) {
02370                                 $msg .= ', Error ('.$this->errno.'): '.$this->error_str;
02371                         } else {
02372                                 $msg .= ' prior to connect().  This is often a problem looking up the host name.';
02373                         }
02374                         $this->debug($msg);
02375                         $this->setError($msg);
02376                         return false;
02377                 }
02378                 
02379                 // set response timeout
02380                 $this->debug('set response timeout to ' . $response_timeout);
02381                 socket_set_timeout( $this->fp, $response_timeout);
02382 
02383                 $this->debug('socket connected');
02384                 return true;
02385           } else if ($this->io_method() == 'curl') {
02386                 if (!extension_loaded('curl')) {
02387 //                      $this->setError('cURL Extension, or OpenSSL extension w/ PHP version >= 4.3 is required for HTTPS');
02388                         $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.');
02389                         return false;
02390                 }
02391                 // Avoid warnings when PHP does not have these options
02392                 if (defined('CURLOPT_CONNECTIONTIMEOUT'))
02393                         $CURLOPT_CONNECTIONTIMEOUT = CURLOPT_CONNECTIONTIMEOUT;
02394                 else
02395                         $CURLOPT_CONNECTIONTIMEOUT = 78;
02396                 if (defined('CURLOPT_HTTPAUTH'))
02397                         $CURLOPT_HTTPAUTH = CURLOPT_HTTPAUTH;
02398                 else
02399                         $CURLOPT_HTTPAUTH = 107;
02400                 if (defined('CURLOPT_PROXYAUTH'))
02401                         $CURLOPT_PROXYAUTH = CURLOPT_PROXYAUTH;
02402                 else
02403                         $CURLOPT_PROXYAUTH = 111;
02404                 if (defined('CURLAUTH_BASIC'))
02405                         $CURLAUTH_BASIC = CURLAUTH_BASIC;
02406                 else
02407                         $CURLAUTH_BASIC = 1;
02408                 if (defined('CURLAUTH_DIGEST'))
02409                         $CURLAUTH_DIGEST = CURLAUTH_DIGEST;
02410                 else
02411                         $CURLAUTH_DIGEST = 2;
02412                 if (defined('CURLAUTH_NTLM'))
02413                         $CURLAUTH_NTLM = CURLAUTH_NTLM;
02414                 else
02415                         $CURLAUTH_NTLM = 8;
02416 
02417                 $this->debug('connect using cURL');
02418                 // init CURL
02419                 $this->ch = curl_init();
02420                 // set url
02421                 $hostURL = ($this->port != '') ? "$this->scheme://$this->host:$this->port" : "$this->scheme://$this->host";
02422                 // add path
02423                 $hostURL .= $this->path;
02424                 $this->setCurlOption(CURLOPT_URL, $hostURL);
02425                 // follow location headers (re-directs)
02426                 if (ini_get('safe_mode') || ini_get('open_basedir')) {
02427                         $this->debug('safe_mode or open_basedir set, so do not set CURLOPT_FOLLOWLOCATION');
02428                         $this->debug('safe_mode = ');
02429                         $this->appendDebug($this->varDump(ini_get('safe_mode')));
02430                         $this->debug('open_basedir = ');
02431                         $this->appendDebug($this->varDump(ini_get('open_basedir')));
02432                 } else {
02433                         $this->setCurlOption(CURLOPT_FOLLOWLOCATION, 1);
02434                 }
02435                 // ask for headers in the response output
02436                 $this->setCurlOption(CURLOPT_HEADER, 1);
02437                 // ask for the response output as the return value
02438                 $this->setCurlOption(CURLOPT_RETURNTRANSFER, 1);
02439                 // encode
02440                 // We manage this ourselves through headers and encoding
02441 //              if(function_exists('gzuncompress')){
02442 //                      $this->setCurlOption(CURLOPT_ENCODING, 'deflate');
02443 //              }
02444                 // persistent connection
02445                 if ($this->persistentConnection) {
02446                         // I believe the following comment is now bogus, having applied to
02447                         // the code when it used CURLOPT_CUSTOMREQUEST to send the request.
02448                         // The way we send data, we cannot use persistent connections, since
02449                         // there will be some "junk" at the end of our request.
02450                         //$this->setCurlOption(CURL_HTTP_VERSION_1_1, true);
02451                         $this->persistentConnection = false;
02452                         $this->setHeader('Connection', 'close');
02453                 }
02454                 // set timeouts
02455                 if ($connection_timeout != 0) {
02456                         $this->setCurlOption($CURLOPT_CONNECTIONTIMEOUT, $connection_timeout);
02457                 }
02458                 if ($response_timeout != 0) {
02459                         $this->setCurlOption(CURLOPT_TIMEOUT, $response_timeout);
02460                 }
02461 
02462                 if ($this->scheme == 'https') {
02463                         $this->debug('set cURL SSL verify options');
02464                         // recent versions of cURL turn on peer/host checking by default,
02465                         // while PHP binaries are not compiled with a default location for the
02466                         // CA cert bundle, so disable peer/host checking.
02467                         //$this->setCurlOption(CURLOPT_CAINFO, 'f:\php-4.3.2-win32\extensions\curl-ca-bundle.crt');             
02468                         $this->setCurlOption(CURLOPT_SSL_VERIFYPEER, 0);
02469                         $this->setCurlOption(CURLOPT_SSL_VERIFYHOST, 0);
02470         
02471                         // support client certificates (thanks Tobias Boes, Doug Anarino, Eryan Ariobowo)
02472                         if ($this->authtype == 'certificate') {
02473                                 $this->debug('set cURL certificate options');
02474                                 if (isset($this->certRequest['cainfofile'])) {
02475                                         $this->setCurlOption(CURLOPT_CAINFO, $this->certRequest['cainfofile']);
02476                                 }
02477                                 if (isset($this->certRequest['verifypeer'])) {
02478                                         $this->setCurlOption(CURLOPT_SSL_VERIFYPEER, $this->certRequest['verifypeer']);
02479                                 } else {
02480                                         $this->setCurlOption(CURLOPT_SSL_VERIFYPEER, 1);
02481                                 }
02482                                 if (isset($this->certRequest['verifyhost'])) {
02483                                         $this->setCurlOption(CURLOPT_SSL_VERIFYHOST, $this->certRequest['verifyhost']);
02484                                 } else {
02485                                         $this->setCurlOption(CURLOPT_SSL_VERIFYHOST, 1);
02486                                 }
02487                                 if (isset($this->certRequest['sslcertfile'])) {
02488                                         $this->setCurlOption(CURLOPT_SSLCERT, $this->certRequest['sslcertfile']);
02489                                 }
02490                                 if (isset($this->certRequest['sslkeyfile'])) {
02491                                         $this->setCurlOption(CURLOPT_SSLKEY, $this->certRequest['sslkeyfile']);
02492                                 }
02493                                 if (isset($this->certRequest['passphrase'])) {
02494                                         $this->setCurlOption(CURLOPT_SSLKEYPASSWD, $this->certRequest['passphrase']);
02495                                 }
02496                                 if (isset($this->certRequest['certpassword'])) {
02497                                         $this->setCurlOption(CURLOPT_SSLCERTPASSWD, $this->certRequest['certpassword']);
02498                                 }
02499                         }
02500                 }
02501                 if ($this->authtype && ($this->authtype != 'certificate')) {
02502                         if ($this->username) {
02503                                 $this->debug('set cURL username/password');
02504                                 $this->setCurlOption(CURLOPT_USERPWD, "$this->username:$this->password");
02505                         }
02506                         if ($this->authtype == 'basic') {
02507                                 $this->debug('set cURL for Basic authentication');
02508                                 $this->setCurlOption($CURLOPT_HTTPAUTH, $CURLAUTH_BASIC);
02509                         }
02510                         if ($this->authtype == 'digest') {
02511                                 $this->debug('set cURL for digest authentication');
02512                                 $this->setCurlOption($CURLOPT_HTTPAUTH, $CURLAUTH_DIGEST);
02513                         }
02514                         if ($this->authtype == 'ntlm') {
02515                                 $this->debug('set cURL for NTLM authentication');
02516                                 $this->setCurlOption($CURLOPT_HTTPAUTH, $CURLAUTH_NTLM);
02517                         }
02518                 }
02519                 if (is_array($this->proxy)) {
02520                         $this->debug('set cURL proxy options');
02521                         if ($this->proxy['port'] != '') {
02522                                 $this->setCurlOption(CURLOPT_PROXY, $this->proxy['host'].':'.$this->proxy['port']);
02523                         } else {
02524                                 $this->setCurlOption(CURLOPT_PROXY, $this->proxy['host']);
02525                         }
02526                         if ($this->proxy['username'] || $this->proxy['password']) {
02527                                 $this->debug('set cURL proxy authentication options');
02528                                 $this->setCurlOption(CURLOPT_PROXYUSERPWD, $this->proxy['username'].':'.$this->proxy['password']);
02529                                 if ($this->proxy['authtype'] == 'basic') {
02530                                         $this->setCurlOption($CURLOPT_PROXYAUTH, $CURLAUTH_BASIC);
02531                                 }
02532                                 if ($this->proxy['authtype'] == 'ntlm') {
02533                                         $this->setCurlOption($CURLOPT_PROXYAUTH, $CURLAUTH_NTLM);
02534                                 }
02535                         }
02536                 }
02537                 $this->debug('cURL connection set up');
02538                 return true;
02539           } else {
02540                 $this->setError('Unknown scheme ' . $this->scheme);
02541                 $this->debug('Unknown scheme ' . $this->scheme);
02542                 return false;
02543           }
02544         }
02545 
02556         function send($data, $timeout=0, $response_timeout=30, $cookies=NULL) {
02557                 
02558                 $this->debug('entered send() with data of length: '.strlen($data));
02559 
02560                 $this->tryagain = true;
02561                 $tries = 0;
02562                 while ($this->tryagain) {
02563                         $this->tryagain = false;
02564                         if ($tries++ < 2) {
02565                                 // make connnection
02566                                 if (!$this->connect($timeout, $response_timeout)){
02567                                         return false;
02568                                 }
02569                                 
02570                                 // send request
02571                                 if (!$this->sendRequest($data, $cookies)){
02572                                         return false;
02573                                 }
02574                                 
02575                                 // get response
02576                                 $respdata = $this->getResponse();
02577                         } else {
02578                                 $this->setError("Too many tries to get an OK response ($this->response_status_line)");
02579                         }
02580                 }               
02581                 $this->debug('end of send()');
02582                 return $respdata;
02583         }
02584 
02585 
02597         function sendHTTPS($data, $timeout=0, $response_timeout=30, $cookies) {
02598                 return $this->send($data, $timeout, $response_timeout, $cookies);
02599         }
02600         
02611         function setCredentials($username, $password, $authtype = 'basic', $digestRequest = array(), $certRequest = array()) {
02612                 $this->debug("setCredentials username=$username authtype=$authtype digestRequest=");
02613                 $this->appendDebug($this->varDump($digestRequest));
02614                 $this->debug("certRequest=");
02615                 $this->appendDebug($this->varDump($certRequest));
02616                 // cf. RFC 2617
02617                 if ($authtype == 'basic') {
02618                         $this->setHeader('Authorization', 'Basic '.base64_encode(str_replace(':','',$username).':'.$password));
02619                 } elseif ($authtype == 'digest') {
02620                         if (isset($digestRequest['nonce'])) {
02621                                 $digestRequest['nc'] = isset($digestRequest['nc']) ? $digestRequest['nc']++ : 1;
02622                                 
02623                                 // calculate the Digest hashes (calculate code based on digest implementation found at: http://www.rassoc.com/gregr/weblog/stories/2002/07/09/webServicesSecurityHttpDigestAuthenticationWithoutActiveDirectory.html)
02624         
02625                                 // A1 = unq(username-value) ":" unq(realm-value) ":" passwd
02626                                 $A1 = $username. ':' . (isset($digestRequest['realm']) ? $digestRequest['realm'] : '') . ':' . $password;
02627         
02628                                 // H(A1) = MD5(A1)
02629                                 $HA1 = md5($A1);
02630         
02631                                 // A2 = Method ":" digest-uri-value
02632                                 $A2 = $this->request_method . ':' . $this->digest_uri;
02633         
02634                                 // H(A2)
02635                                 $HA2 =  md5($A2);
02636         
02637                                 // KD(secret, data) = H(concat(secret, ":", data))
02638                                 // if qop == auth:
02639                                 // request-digest  = <"> < KD ( H(A1),     unq(nonce-value)
02640                                 //                              ":" nc-value
02641                                 //                              ":" unq(cnonce-value)
02642                                 //                              ":" unq(qop-value)
02643                                 //                              ":" H(A2)
02644                                 //                            ) <">
02645                                 // if qop is missing,
02646                                 // request-digest  = <"> < KD ( H(A1), unq(nonce-value) ":" H(A2) ) > <">
02647         
02648                                 $unhashedDigest = '';
02649                                 $nonce = isset($digestRequest['nonce']) ? $digestRequest['nonce'] : '';
02650                                 $cnonce = $nonce;
02651                                 if ($digestRequest['qop'] != '') {
02652                                         $unhashedDigest = $HA1 . ':' . $nonce . ':' . sprintf("%08d", $digestRequest['nc']) . ':' . $cnonce . ':' . $digestRequest['qop'] . ':' . $HA2;
02653                                 } else {
02654                                         $unhashedDigest = $HA1 . ':' . $nonce . ':' . $HA2;
02655                                 }
02656         
02657                                 $hashedDigest = md5($unhashedDigest);
02658         
02659                                 $opaque = '';   
02660                                 if (isset($digestRequest['opaque'])) {
02661                                         $opaque = ', opaque="' . $digestRequest['opaque'] . '"';
02662                                 }
02663 
02664                                 $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 . '"');
02665                         }
02666                 } elseif ($authtype == 'certificate') {
02667                         $this->certRequest = $certRequest;
02668                         $this->debug('Authorization header not set for certificate');
02669                 } elseif ($authtype == 'ntlm') {
02670                         // do nothing
02671                         $this->debug('Authorization header not set for ntlm');
02672                 }
02673                 $this->username = $username;
02674                 $this->password = $password;
02675                 $this->authtype = $authtype;
02676                 $this->digestRequest = $digestRequest;
02677         }
02678         
02685         function setSOAPAction($soapaction) {
02686                 $this->setHeader('SOAPAction', '"' . $soapaction . '"');
02687         }
02688         
02695         function setEncoding($enc='gzip, deflate') {
02696                 if (function_exists('gzdeflate')) {
02697                         $this->protocol_version = '1.1';
02698                         $this->setHeader('Accept-Encoding', $enc);
02699                         if (!isset($this->outgoing_headers['Connection'])) {
02700                                 $this->setHeader('Connection', 'close');
02701                                 $this->persistentConnection = false;
02702                         }
02703                         set_magic_quotes_runtime(0);
02704                         // deprecated
02705                         $this->encoding = $enc;
02706                 }
02707         }
02708         
02719         function setProxy($proxyhost, $proxyport, $proxyusername = '', $proxypassword = '', $proxyauthtype = 'basic') {
02720                 if ($proxyhost) {
02721                         $this->proxy = array(
02722                                 'host' => $proxyhost,
02723                                 'port' => $proxyport,
02724                                 'username' => $proxyusername,
02725                                 'password' => $proxypassword,
02726                                 'authtype' => $proxyauthtype
02727                         );
02728                         if ($proxyusername != '' && $proxypassword != '' && $proxyauthtype = 'basic') {
02729                                 $this->setHeader('Proxy-Authorization', ' Basic '.base64_encode($proxyusername.':'.$proxypassword));
02730                         }
02731                 } else {
02732                         $this->debug('remove proxy');
02733                         $proxy = null;
02734                         unsetHeader('Proxy-Authorization');
02735                 }
02736         }
02737         
02738 
02747         function isSkippableCurlHeader(&$data) {
02748                 $skipHeaders = array(   'HTTP/1.1 100',
02749                                                                 'HTTP/1.0 301',
02750                                                                 'HTTP/1.1 301',
02751                                                                 'HTTP/1.0 302',
02752                                                                 'HTTP/1.1 302',
02753                                                                 'HTTP/1.0 401',
02754                                                                 'HTTP/1.1 401',
02755                                                                 'HTTP/1.0 200 Connection established');
02756                 foreach ($skipHeaders as $hd) {
02757                         $prefix = substr($data, 0, strlen($hd));
02758                         if ($prefix == $hd) return true;
02759                 }
02760 
02761                 return false;
02762         }
02763 
02774         function decodeChunked($buffer, $lb){
02775                 // length := 0
02776                 $length = 0;
02777                 $new = '';
02778                 
02779                 // read chunk-size, chunk-extension (if any) and CRLF
02780                 // get the position of the linebreak
02781                 $chunkend = strpos($buffer, $lb);
02782                 if ($chunkend == FALSE) {
02783                         $this->debug('no linebreak found in decodeChunked');
02784                         return $new;
02785                 }
02786                 $temp = substr($buffer,0,$chunkend);
02787                 $chunk_size = hexdec( trim($temp) );
02788                 $chunkstart = $chunkend + strlen($lb);
02789                 // while (chunk-size > 0) {
02790                 while ($chunk_size > 0) {
02791                         $this->debug("chunkstart: $chunkstart chunk_size: $chunk_size");
02792                         $chunkend = strpos( $buffer, $lb, $chunkstart + $chunk_size);
02793                         
02794                         // Just in case we got a broken connection
02795                         if ($chunkend == FALSE) {
02796                             $chunk = substr($buffer,$chunkstart);
02797                                 // append chunk-data to entity-body
02798                         $new .= $chunk;
02799                             $length += strlen($chunk);
02800                             break;
02801                         }
02802                         
02803                         // read chunk-data and CRLF
02804                         $chunk = substr($buffer,$chunkstart,$chunkend-$chunkstart);
02805                         // append chunk-data to entity-body
02806                         $new .= $chunk;
02807                         // length := length + chunk-size
02808                         $length += strlen($chunk);
02809                         // read chunk-size and CRLF
02810                         $chunkstart = $chunkend + strlen($lb);
02811                         
02812                         $chunkend = strpos($buffer, $lb, $chunkstart) + strlen($lb);
02813                         if ($chunkend == FALSE) {
02814                                 break; //Just in case we got a broken connection
02815                         }
02816                         $temp = substr($buffer,$chunkstart,$chunkend-$chunkstart);
02817                         $chunk_size = hexdec( trim($temp) );
02818                         $chunkstart = $chunkend;
02819                 }
02820                 return $new;
02821         }
02822         
02831         function buildPayload($data, $cookie_str = '') {
02832                 // Note: for cURL connections, $this->outgoing_payload is ignored,
02833                 // as is the Content-Length header, but these are still created as
02834                 // debugging guides.
02835 
02836                 // add content-length header
02837                 if ($this->request_method != 'GET') {
02838                         $this->setHeader('Content-Length', strlen($data));
02839                 }
02840 
02841                 // start building outgoing payload:
02842                 if ($this->proxy) {
02843                         $uri = $this->url;
02844                 } else {
02845                         $uri = $this->uri;
02846                 }
02847                 $req = "$this->request_method $uri HTTP/$this->protocol_version";
02848                 $this->debug("HTTP request: $req");
02849                 $this->outgoing_payload = "$req\r\n";
02850 
02851                 // loop thru headers, serializing
02852                 foreach($this->outgoing_headers as $k => $v){
02853                         $hdr = $k.': '.$v;
02854                         $this->debug("HTTP header: $hdr");
02855                         $this->outgoing_payload .= "$hdr\r\n";
02856                 }
02857 
02858                 // add any cookies
02859                 if ($cookie_str != '') {
02860                         $hdr = 'Cookie: '.$cookie_str;
02861                         $this->debug("HTTP header: $hdr");
02862                         $this->outgoing_payload .= "$hdr\r\n";
02863                 }
02864 
02865                 // header/body separator
02866                 $this->outgoing_payload .= "\r\n";
02867                 
02868                 // add data
02869                 $this->outgoing_payload .= $data;
02870         }
02871 
02880         function sendRequest($data, $cookies = NULL) {
02881                 // build cookie string
02882                 $cookie_str = $this->getCookiesForRequest($cookies, (($this->scheme == 'ssl') || ($this->scheme == 'https')));
02883 
02884                 // build payload
02885                 $this->buildPayload($data, $cookie_str);
02886 
02887           if ($this->io_method() == 'socket') {
02888                 // send payload
02889                 if(!fputs($this->fp, $this->outgoing_payload, strlen($this->outgoing_payload))) {
02890                         $this->setError('couldn\'t write message data to socket');
02891                         $this->debug('couldn\'t write message data to socket');
02892                         return false;
02893                 }
02894                 $this->debug('wrote data to socket, length = ' . strlen($this->outgoing_payload));
02895                 return true;
02896           } else if ($this->io_method() == 'curl') {
02897                 // set payload
02898                 // cURL does say this should only be the verb, and in fact it
02899                 // turns out that the URI and HTTP version are appended to this, which
02900                 // some servers refuse to work with (so we no longer use this method!)
02901                 //$this->setCurlOption(CURLOPT_CUSTOMREQUEST, $this->outgoing_payload);
02902                 $curl_headers = array();
02903                 foreach($this->outgoing_headers as $k => $v){
02904                         if ($k == 'Connection' || $k == 'Content-Length' || $k == 'Host' || $k == 'Authorization' || $k == 'Proxy-Authorization') {
02905                                 $this->debug("Skip cURL header $k: $v");
02906                         } else {
02907                                 $curl_headers[] = "$k: $v";
02908                         }
02909                 }
02910                 if ($cookie_str != '') {
02911                         $curl_headers[] = 'Cookie: ' . $cookie_str;
02912                 }
02913                 $this->setCurlOption(CURLOPT_HTTPHEADER, $curl_headers);
02914                 $this->debug('set cURL HTTP headers');
02915                 if ($this->request_method == "POST") {
02916                         $this->setCurlOption(CURLOPT_POST, 1);
02917                         $this->setCurlOption(CURLOPT_POSTFIELDS, $data);
02918                         $this->debug('set cURL POST data');
02919                 } else {
02920                 }
02921                 // insert custom user-set cURL options
02922                 foreach ($this->ch_options as $key => $val) {
02923                         $this->setCurlOption($key, $val);
02924                 }
02925 
02926                 $this->debug('set cURL payload');
02927                 return true;
02928           }
02929         }
02930 
02937         function getResponse(){
02938                 $this->incoming_payload = '';
02939             
02940           if ($this->io_method() == 'socket') {
02941             // loop until headers have been retrieved
02942             $data = '';
02943             while (!isset($lb)){
02944 
02945                         // We might EOF during header read.
02946                         if(feof($this->fp)) {
02947                                 $this->incoming_payload = $data;
02948                                 $this->debug('found no headers before EOF after length ' . strlen($data));
02949                                 $this->debug("received before EOF:\n" . $data);
02950                                 $this->setError('server failed to send headers');
02951                                 return false;
02952                         }
02953 
02954                         $tmp = fgets($this->fp, 256);
02955                         $tmplen = strlen($tmp);
02956                         $this->debug("read line of $tmplen bytes: " . trim($tmp));
02957 
02958                         if ($tmplen == 0) {
02959                                 $this->incoming_payload = $data;
02960                                 $this->debug('socket read of headers timed out after length ' . strlen($data));
02961                                 $this->debug("read before timeout: " . $data);
02962                                 $this->setError('socket read of headers timed out');
02963                                 return false;
02964                         }
02965 
02966                         $data .= $tmp;
02967                         $pos = strpos($data,"\r\n\r\n");
02968                         if($pos > 1){
02969                                 $lb = "\r\n";
02970                         } else {
02971                                 $pos = strpos($data,"\n\n");
02972                                 if($pos > 1){
02973                                         $lb = "\n";
02974                                 }
02975                         }
02976                         // remove 100 headers
02977                         if (isset($lb) && ereg('^HTTP/1.1 100',$data)) {
02978                                 unset($lb);
02979                                 $data = '';
02980                         }//
02981                 }
02982                 // store header data
02983                 $this->incoming_payload .= $data;
02984                 $this->debug('found end of headers after length ' . strlen($data));
02985                 // process headers
02986                 $header_data = trim(substr($data,0,$pos));
02987                 $header_array = explode($lb,$header_data);
02988                 $this->incoming_headers = array();
02989                 $this->incoming_cookies = array();
02990                 foreach($header_array as $header_line){
02991                         $arr = explode(':',$header_line, 2);
02992                         if(count($arr) > 1){
02993                                 $header_name = strtolower(trim($arr[0]));
02994                                 $this->incoming_headers[$header_name] = trim($arr[1]);
02995                                 if ($header_name == 'set-cookie') {
02996                                         // TODO: allow multiple cookies from parseCookie
02997                                         $cookie = $this->parseCookie(trim($arr[1]));
02998                                         if ($cookie) {
02999                                                 $this->incoming_cookies[] = $cookie;
03000                                                 $this->debug('found cookie: ' . $cookie['name'] . ' = ' . $cookie['value']);
03001                                         } else {
03002                                                 $this->debug('did not find cookie in ' . trim($arr[1]));
03003                                         }
03004                         }
03005                         } else if (isset($header_name)) {
03006                                 // append continuation line to previous header
03007                                 $this->incoming_headers[$header_name] .= $lb . ' ' . $header_line;
03008                         }
03009                 }
03010                 
03011                 // loop until msg has been received
03012                 if (isset($this->incoming_headers['transfer-encoding']) && strtolower($this->incoming_headers['transfer-encoding']) == 'chunked') {
03013                         $content_length =  2147483647;  // ignore any content-length header
03014                         $chunked = true;
03015                         $this->debug("want to read chunked content");
03016                 } elseif (isset($this->incoming_headers['content-length'])) {
03017                         $content_length = $this->incoming_headers['content-length'];
03018                         $chunked = false;
03019                         $this->debug("want to read content of length $content_length");
03020                 } else {
03021                         $content_length =  2147483647;
03022                         $chunked = false;
03023                         $this->debug("want to read content to EOF");
03024                 }
03025                 $data = '';
03026                 do {
03027                         if ($chunked) {
03028                                 $tmp = fgets($this->fp, 256);
03029                                 $tmplen = strlen($tmp);
03030                                 $this->debug("read chunk line of $tmplen bytes");
03031                                 if ($tmplen == 0) {
03032                                         $this->incoming_payload = $data;
03033                                         $this->debug('socket read of chunk length timed out after length ' . strlen($data));
03034                                         $this->debug("read before timeout:\n" . $data);
03035                                         $this->setError('socket read of chunk length timed out');
03036                                         return false;
03037                                 }
03038                                 $content_length = hexdec(trim($tmp));
03039                                 $this->debug("chunk length $content_length");
03040                         }
03041                         $strlen = 0;
03042                     while (($strlen < $content_length) && (!feof($this->fp))) {
03043                         $readlen = min(8192, $content_length - $strlen);
03044                                 $tmp = fread($this->fp, $readlen);
03045                                 $tmplen = strlen($tmp);
03046                                 $this->debug("read buffer of $tmplen bytes");
03047                                 if (($tmplen == 0) && (!feof($this->fp))) {
03048                                         $this->incoming_payload = $data;
03049                                         $this->debug('socket read of body timed out after length ' . strlen($data));
03050                                         $this->debug("read before timeout:\n" . $data);
03051                                         $this->setError('socket read of body timed out');
03052                                         return false;
03053                                 }
03054                                 $strlen += $tmplen;
03055                                 $data .= $tmp;
03056                         }
03057                         if ($chunked && ($content_length > 0)) {
03058                                 $tmp = fgets($this->fp, 256);
03059                                 $tmplen = strlen($tmp);
03060                                 $this->debug("read chunk terminator of $tmplen bytes");
03061                                 if ($tmplen == 0) {
03062                                         $this->incoming_payload = $data;
03063                                         $this->debug('socket read of chunk terminator timed out after length ' . strlen($data));
03064                                         $this->debug("read before timeout:\n" . $data);
03065                                         $this->setError('socket read of chunk terminator timed out');
03066                                         return false;
03067                                 }
03068                         }
03069                 } while ($chunked && ($content_length > 0) && (!feof($this->fp)));
03070                 if (feof($this->fp)) {
03071                         $this->debug('read to EOF');
03072                 }
03073                 $this->debug('read body of length ' . strlen($data));
03074                 $this->incoming_payload .= $data;
03075                 $this->debug('received a total of '.strlen($this->incoming_payload).' bytes of data from server');
03076                 
03077                 // close filepointer
03078                 if(
03079                         (isset($this->incoming_headers['connection']) && strtolower($this->incoming_headers['connection']) == 'close') || 
03080                         (! $this->persistentConnection) || feof($this->fp)){
03081                         fclose($this->fp);
03082                         $this->fp = false;
03083                         $this->debug('closed socket');
03084                 }
03085                 
03086                 // connection was closed unexpectedly
03087                 if($this->incoming_payload == ''){
03088                         $this->setError('no response from server');
03089                         return false;
03090                 }
03091                 
03092                 // decode transfer-encoding
03093 //              if(isset($this->incoming_headers['transfer-encoding']) && strtolower($this->incoming_headers['transfer-encoding']) == 'chunked'){
03094 //                      if(!$data = $this->decodeChunked($data, $lb)){
03095 //                              $this->setError('Decoding of chunked data failed');
03096 //                              return false;
03097 //                      }
03098                         //print "<pre>\nde-chunked:\n---------------\n$data\n\n---------------\n</pre>";
03099                         // set decoded payload
03100 //                      $this->incoming_payload = $header_data.$lb.$lb.$data;
03101 //              }
03102         
03103           } else if ($this->io_method() == 'curl') {
03104                 // send and receive
03105                 $this->debug('send and receive with cURL');
03106                 $this->incoming_payload = curl_exec($this->ch);
03107                 $data = $this->incoming_payload;
03108 
03109         $cErr = curl_error($this->ch);
03110                 if ($cErr != '') {
03111                 $err = 'cURL ERROR: '.curl_errno($this->ch).': '.$cErr.'<br>';
03112                 // TODO: there is a PHP bug that can cause this to SEGV for CURLINFO_CONTENT_TYPE
03113                         foreach(curl_getinfo($this->ch) as $k => $v){
03114                                 $err .= "$k: $v<br>";
03115                         }
03116                         $this->debug($err);
03117                         $this->setError($err);
03118                         curl_close($this->ch);
03119                 return false;
03120                 } else {
03121                         //echo '<pre>';
03122                         //var_dump(curl_getinfo($this->ch));
03123                         //echo '</pre>';
03124                 }
03125                 // close curl
03126                 $this->debug('No cURL error, closing cURL');
03127                 curl_close($this->ch);
03128                 
03129                 // try removing skippable headers
03130                 $savedata = $data;
03131                 while ($this->isSkippableCurlHeader($data)) {
03132                         $this->debug("Found HTTP header to skip");
03133                         if ($pos = strpos($data,"\r\n\r\n")) {
03134                                 $data = ltrim(substr($data,$pos));
03135                         } elseif($pos = strpos($data,"\n\n") ) {
03136                                 $data = ltrim(substr($data,$pos));
03137                         }
03138                 }
03139 
03140                 if ($data == '') {
03141                         // have nothing left; just remove 100 header(s)
03142                         $data = $savedata;
03143                         while (ereg('^HTTP/1.1 100',$data)) {
03144                                 if ($pos = strpos($data,"\r\n\r\n")) {
03145                                         $data = ltrim(substr($data,$pos));
03146                                 } elseif($pos = strpos($data,"\n\n") ) {
03147                                         $data = ltrim(substr($data,$pos));
03148                                 }
03149                         }
03150                 }
03151                 
03152                 // separate content from HTTP headers
03153                 if ($pos = strpos($data,"\r\n\r\n")) {
03154                         $lb = "\r\n";
03155                 } elseif( $pos = strpos($data,"\n\n")) {
03156                         $lb = "\n";
03157                 } else {
03158                         $this->debug('no proper separation of headers and document');
03159                         $this->setError('no proper separation of headers and document');
03160                         return false;
03161                 }
03162                 $header_data = trim(substr($data,0,$pos));
03163                 $header_array = explode($lb,$header_data);
03164                 $data = ltrim(substr($data,$pos));
03165                 $this->debug('found proper separation of headers and document');
03166                 $this->debug('cleaned data, stringlen: '.strlen($data));
03167                 // clean headers
03168                 foreach ($header_array as $header_line) {
03169                         $arr = explode(':',$header_line,2);
03170                         if(count($arr) > 1){
03171                                 $header_name = strtolower(trim($arr[0]));
03172                                 $this->incoming_headers[$header_name] = trim($arr[1]);
03173                                 if ($header_name == 'set-cookie') {
03174                                         // TODO: allow multiple cookies from parseCookie
03175                                         $cookie = $this->parseCookie(trim($arr[1]));
03176                                         if ($cookie) {
03177                                                 $this->incoming_cookies[] = $cookie;
03178                                                 $this->debug('found cookie: ' . $cookie['name'] . ' = ' . $cookie['value']);
03179                                         } else {
03180                                                 $this->debug('did not find cookie in ' . trim($arr[1]));
03181                                         }
03182                         }
03183                         } else if (isset($header_name)) {
03184                                 // append continuation line to previous header
03185                                 $this->incoming_headers[$header_name] .= $lb . ' ' . $header_line;
03186                         }
03187                 }
03188           }
03189 
03190                 $this->response_status_line = $header_array[0];
03191                 $arr = explode(' ', $this->response_status_line, 3);
03192                 $http_version = $arr[0];
03193                 $http_status = intval($arr[1]);
03194                 $http_reason = count($arr) > 2 ? $arr[2] : '';
03195 
03196                 // see if we need to resend the request with http digest authentication
03197                 if (isset($this->incoming_headers['location']) && ($http_status == 301 || $http_status == 302)) {
03198                         $this->debug("Got $http_status $http_reason with Location: " . $this->incoming_headers['location']);
03199                         $this->setURL($this->incoming_headers['location']);
03200                         $this->tryagain = true;
03201                         return false;
03202                 }
03203 
03204                 // see if we need to resend the request with http digest authentication
03205                 if (isset($this->incoming_headers['www-authenticate']) && $http_status == 401) {
03206                         $this->debug("Got 401 $http_reason with WWW-Authenticate: " . $this->incoming_headers['www-authenticate']);
03207                         if (strstr($this->incoming_headers['www-authenticate'], "Digest ")) {
03208                                 $this->debug('Server wants digest authentication');
03209                                 // remove "Digest " from our elements
03210                                 $digestString = str_replace('Digest ', '', $this->incoming_headers['www-authenticate']);
03211                                 
03212                                 // parse elements into array
03213                                 $digestElements = explode(',', $digestString);
03214                                 foreach ($digestElements as $val) {
03215                                         $tempElement = explode('=', trim($val), 2);
03216                                         $digestRequest[$tempElement[0]] = str_replace("\"", '', $tempElement[1]);
03217                                 }
03218 
03219                                 // should have (at least) qop, realm, nonce
03220                                 if (isset($digestRequest['nonce'])) {
03221                                         $this->setCredentials($this->username, $this->password, 'digest', $digestRequest);
03222                                         $this->tryagain = true;
03223                                         return false;
03224                                 }
03225                         }
03226                         $this->debug('HTTP authentication failed');
03227                         $this->setError('HTTP authentication failed');
03228                         return false;
03229                 }
03230                 
03231                 if (
03232                         ($http_status >= 300 && $http_status <= 307) ||
03233                         ($http_status >= 400 && $http_status <= 417) ||
03234                         ($http_status >= 501 && $http_status <= 505)
03235                    ) {
03236                         $this->setError("Unsupported HTTP response status $http_status $http_reason (soapclient->response has contents of the response)");
03237                         return false;
03238                 }
03239 
03240                 // decode content-encoding
03241                 if(isset($this->incoming_headers['content-encoding']) && $this->incoming_headers['content-encoding'] != ''){
03242                         if(strtolower($this->incoming_headers['content-encoding']) == 'deflate' || strtolower($this->incoming_headers['content-encoding']) == 'gzip'){
03243                         // if decoding works, use it. else assume data wasn't gzencoded
03244                         if(function_exists('gzinflate')){
03245                                         //$timer->setMarker('starting decoding of gzip/deflated content');
03246                                         // IIS 5 requires gzinflate instead of gzuncompress (similar to IE 5 and gzdeflate v. gzcompress)
03247                                         // this means there are no Zlib headers, although there should be
03248                                         $this->debug('The gzinflate function exists');
03249                                         $datalen = strlen($data);
03250                                         if ($this->incoming_headers['content-encoding'] == 'deflate') {
03251                                                 if ($degzdata = @gzinflate($data)) {
03252                                                 $data = $degzdata;
03253                                                 $this->debug('The payload has been inflated to ' . strlen($data) . ' bytes');
03254                                                 if (strlen($data) < $datalen) {
03255                                                         // test for the case that the payload has been compressed twice
03256                                                         $this->debug('The inflated payload is smaller than the gzipped one; try again');
03257                                                                 if ($degzdata = @gzinflate($data)) {
03258                                                                 $data = $degzdata;
03259                                                                 $this->debug('The payload has been inflated again to ' . strlen($data) . ' bytes');
03260                                                                 }
03261                                                 }
03262                                         } else {
03263                                                 $this->debug('Error using gzinflate to inflate the payload');
03264                                                 $this->setError('Error using gzinflate to inflate the payload');
03265                                         }
03266                                         } elseif ($this->incoming_headers['content-encoding'] == 'gzip') {
03267                                                 if ($degzdata = @gzinflate(substr($data, 10))) {        // do our best
03268                                                         $data = $degzdata;
03269                                                 $this->debug('The payload has been un-gzipped to ' . strlen($data) . ' bytes');
03270                                                 if (strlen($data) < $datalen) {
03271                                                         // test for the case that the payload has been compressed twice
03272                                                         $this->debug('The un-gzipped payload is smaller than the gzipped one; try again');
03273                                                                 if ($degzdata = @gzinflate(substr($data, 10))) {
03274                                                                 $data = $degzdata;
03275                                                                 $this->debug('The payload has been un-gzipped again to ' . strlen($data) . ' bytes');
03276                                                                 }
03277                                                 }
03278                                         } else {
03279                                                 $this->debug('Error using gzinflate to un-gzip the payload');
03280                                                         $this->setError('Error using gzinflate to un-gzip the payload');
03281                                         }
03282                                         }
03283                                         //$timer->setMarker('finished decoding of gzip/deflated content');
03284                                         //print "<xmp>\nde-inflated:\n---------------\n$data\n-------------\n</xmp>";
03285                                         // set decoded payload
03286                                         $this->incoming_payload = $header_data.$lb.$lb.$data;
03287                         } else {
03288                                         $this->debug('The server sent compressed data. Your php install must have the Zlib extension compiled in to support this.');
03289                                         $this->setError('The server sent compressed data. Your php install must have the Zlib extension compiled in to support this.');
03290                                 }
03291                         } else {
03292                                 $this->debug('Unsupported Content-Encoding ' . $this->incoming_headers['content-encoding']);
03293                                 $this->setError('Unsupported Content-Encoding ' . $this->incoming_headers['content-encoding']);
03294                         }
03295                 } else {
03296                         $this->debug('No Content-Encoding header');
03297                 }
03298                 
03299                 if(strlen($data) == 0){
03300                         $this->debug('no data after headers!');
03301                         $this->setError('no data present after HTTP headers');
03302                         return false;
03303                 }
03304                 
03305                 return $data;
03306         }
03307 
03315         function setContentType($type, $charset = false) {
03316                 $this->setHeader('Content-Type', $type . ($charset ? '; charset=' . $charset : ''));
03317         }
03318 
03325         function usePersistentConnection(){
03326                 if (isset($this->outgoing_headers['Accept-Encoding'])) {
03327                         return false;
03328                 }
03329                 $this->protocol_version = '1.1';
03330                 $this->persistentConnection = true;
03331                 $this->setHeader('Connection', 'Keep-Alive');
03332                 return true;
03333         }
03334 
03342         /*
03343          * TODO: allow a Set-Cookie string to be parsed into multiple cookies
03344          */
03345         function parseCookie($cookie_str) {
03346                 $cookie_str = str_replace('; ', ';', $cookie_str) . ';';
03347                 $data = split(';', $cookie_str);
03348                 $value_str = $data[0];
03349 
03350                 $cookie_param = 'domain=';
03351                 $start = strpos($cookie_str, $cookie_param);
03352                 if ($start > 0) {
03353                         $domain = substr($cookie_str, $start + strlen($cookie_param));
03354                         $domain = substr($domain, 0, strpos($domain, ';'));
03355                 } else {
03356                         $domain = '';
03357                 }
03358 
03359                 $cookie_param = 'expires=';
03360                 $start = strpos($cookie_str, $cookie_param);
03361                 if ($start > 0) {
03362                         $expires = substr($cookie_str, $start + strlen($cookie_param));
03363                         $expires = substr($expires, 0, strpos($expires, ';'));
03364                 } else {
03365                         $expires = '';
03366                 }
03367 
03368                 $cookie_param = 'path=';
03369                 $start = strpos($cookie_str, $cookie_param);
03370                 if ( $start > 0 ) {
03371                         $path = substr($cookie_str, $start + strlen($cookie_param));
03372                         $path = substr($path, 0, strpos($path, ';'));
03373                 } else {
03374                         $path = '/';
03375                 }
03376                                                 
03377                 $cookie_param = ';secure;';
03378                 if (strpos($cookie_str, $cookie_param) !== FALSE) {
03379                         $secure = true;
03380                 } else {
03381                         $secure = false;
03382                 }
03383 
03384                 $sep_pos = strpos($value_str, '=');
03385 
03386                 if ($sep_pos) {
03387                         $name = substr($value_str, 0, $sep_pos);
03388                         $value = substr($value_str, $sep_pos + 1);
03389                         $cookie= array( 'name' => $name,
03390                                         'value' => $value,
03391                                                         'domain' => $domain,
03392                                                         'path' => $path,
03393                                                         'expires' => $expires,
03394                                                         'secure' => $secure
03395                                                         );              
03396                         return $cookie;
03397                 }
03398                 return false;
03399         }
03400   
03409         function getCookiesForRequest($cookies, $secure=false) {
03410                 $cookie_str = '';
03411                 if ((! is_null($cookies)) && (is_array($cookies))) {
03412                         foreach ($cookies as $cookie) {
03413                                 if (! is_array($cookie)) {
03414                                         continue;
03415                                 }
03416                         $this->debug("check cookie for validity: ".$cookie['name'].'='.$cookie['value']);
03417                                 if ((isset($cookie['expires'])) && (! empty($cookie['expires']))) {
03418                                         if (strtotime($cookie['expires']) <= time()) {
03419                                                 $this->debug('cookie has expired');
03420                                                 continue;
03421                                         }
03422                                 }
03423                                 if ((isset($cookie['domain'])) && (! empty($cookie['domain']))) {
03424                                         $domain = preg_quote($cookie['domain']);
03425                                         if (! preg_match("'.*$domain$'i", $this->host)) {
03426                                                 $this->debug('cookie has different domain');
03427                                                 continue;
03428                                         }
03429                                 }
03430                                 if ((isset($cookie['path'])) && (! empty($cookie['path']))) {
03431                                         $path = preg_quote($cookie['path']);
03432                                         if (! preg_match("'^$path.*'i", $this->path)) {
03433                                                 $this->debug('cookie is for a different path');
03434                                                 continue;
03435                                         }
03436                                 }
03437                                 if ((! $secure) && (isset($cookie['secure'])) && ($cookie['secure'])) {
03438                                         $this->debug('cookie is secure, transport is not');
03439                                         continue;
03440                                 }
03441                                 $cookie_str .= $cookie['name'] . '=' . $cookie['value'] . '; ';
03442                         $this->debug('add cookie to Cookie-String: ' . $cookie['name'] . '=' . $cookie['value']);
03443                         }
03444                 }
03445                 return $cookie_str;
03446   }
03447 }
03448 
03449 ?><?php
03450 
03451 
03452 
03463 class nusoap_server extends nusoap_base {
03469         var $headers = array();
03475         var $request = '';
03481         var $requestHeaders = '';
03487         var $requestHeader = NULL;
03493         var $document = '';
03499         var $requestSOAP = '';
03505         var $methodURI = '';
03511         var $methodname = '';
03517         var $methodparams = array();
03523         var $SOAPAction = '';
03529         var $xml_encoding = '';
03535     var $decode_utf8 = true;
03536 
03542         var $outgoing_headers = array();
03548         var $response = '';
03554         var $responseHeaders = '';
03560         var $responseSOAP = '';
03566         var $methodreturn = false;
03572         var $methodreturnisliteralxml = false;
03578         var $fault = false;
03584         var $result = 'successful';
03585 
03592         var $operations = array();
03598         var $wsdl = false;
03604         var $externalWSDLURL = false;
03610         var $debug_flag = false;
03611 
03612 
03620         function nusoap_server($wsdl=false){
03621                 parent::nusoap_base();
03622                 // turn on debugging?
03623                 global $debug;
03624                 global $HTTP_SERVER_VARS;
03625 
03626                 if (isset($_SERVER)) {
03627                         $this->debug("_SERVER is defined:");
03628                         $this->appendDebug($this->varDump($_SERVER));
03629                 } elseif (isset($HTTP_SERVER_VARS)) {
03630                         $this->debug("HTTP_SERVER_VARS is defined:");
03631                         $this->appendDebug($this->varDump($HTTP_SERVER_VARS));
03632                 } else {
03633                         $this->debug("Neither _SERVER nor HTTP_SERVER_VARS is defined.");
03634                 }
03635 
03636                 if (isset($debug)) {
03637                         $this->debug("In nusoap_server, set debug_flag=$debug based on global flag");
03638                         $this->debug_flag = $debug;
03639                 } elseif (isset($_SERVER['QUERY_STRING'])) {
03640                         $qs = explode('&', $_SERVER['QUERY_STRING']);
03641                         foreach ($qs as $v) {
03642                                 if (substr($v, 0, 6) == 'debug=') {
03643                                         $this->debug("In nusoap_server, set debug_flag=" . substr($v, 6) . " based on query string #1");
03644                                         $this->debug_flag = substr($v, 6);
03645                                 }
03646                         }
03647                 } elseif (isset($HTTP_SERVER_VARS['QUERY_STRING'])) {
03648                         $qs = explode('&', $HTTP_SERVER_VARS['QUERY_STRING']);
03649                         foreach ($qs as $v) {
03650                                 if (substr($v, 0, 6) == 'debug=') {
03651                                         $this->debug("In nusoap_server, set debug_flag=" . substr($v, 6) . " based on query string #2");
03652                                         $this->debug_flag = substr($v, 6);
03653                                 }
03654                         }
03655                 }
03656 
03657                 // wsdl
03658                 if($wsdl){
03659                         $this->debug("In nusoap_server, WSDL is specified");
03660                         if (is_object($wsdl) && (get_class($wsdl) == 'wsdl')) {
03661                                 $this->wsdl = $wsdl;
03662                                 $this->externalWSDLURL = $this->wsdl->wsdl;
03663                                 $this->debug('Use existing wsdl instance from ' . $this->externalWSDLURL);
03664                         } else {
03665                                 $this->debug('Create wsdl from ' . $wsdl);
03666                                 $this->wsdl = new wsdl($wsdl);
03667                                 $this->externalWSDLURL = $wsdl;
03668                         }
03669                         $this->appendDebug($this->wsdl->getDebug());
03670                         $this->wsdl->clearDebug();
03671                         if($err = $this->wsdl->getError()){
03672                                 die('WSDL ERROR: '.$err);
03673                         }
03674                 }
03675         }
03676 
03683         function service($data){
03684                 global $HTTP_SERVER_VARS;
03685 
03686                 if (isset($_SERVER['REQUEST_METHOD'])) {
03687                         $rm = $_SERVER['REQUEST_METHOD'];
03688                 } elseif (isset($HTTP_SERVER_VARS['REQUEST_METHOD'])) {
03689                         $rm = $HTTP_SERVER_VARS['REQUEST_METHOD'];
03690                 } else {
03691                         $rm = '';
03692                 }
03693 
03694                 if (isset($_SERVER['QUERY_STRING'])) {
03695                         $qs = $_SERVER['QUERY_STRING'];
03696                 } elseif (isset($HTTP_SERVER_VARS['QUERY_STRING'])) {
03697                         $qs = $HTTP_SERVER_VARS['QUERY_STRING'];
03698                 } else {
03699                         $qs = '';
03700                 }
03701                 $this->debug("In service, request method=$rm query string=$qs strlen(\$data)=" . strlen($data));
03702 
03703                 if ($rm == 'POST') {
03704                         $this->debug("In service, invoke the request");
03705                         $this->parse_request($data);
03706                         if (! $this->fault) {
03707                                 $this->invoke_method();
03708                         }
03709                         if (! $this->fault) {
03710                                 $this->serialize_return();
03711                         }
03712                         $this->send_response();
03713                 } elseif (ereg('wsdl', $qs) ){
03714                         $this->debug("In service, this is a request for WSDL");
03715                         if ($this->externalWSDLURL){
03716               if (strpos($this->externalWSDLURL, "http://") !== false) { // assume URL
03717                                 $this->debug("In service, re-direct for WSDL");
03718                                 header('Location: '.$this->externalWSDLURL);
03719               } else { // assume file
03720                                 $this->debug("In service, use file passthru for WSDL");
03721                 header("Content-Type: text/xml\r\n");
03722                                 $pos = strpos($this->externalWSDLURL, "file://");
03723                                 if ($pos === false) {
03724                                         $filename = $this->externalWSDLURL;
03725                                 } else {
03726                                         $filename = substr($this->externalWSDLURL, $pos + 7);
03727                                 }
03728                 $fp = fopen($this->externalWSDLURL, 'r');
03729                 fpassthru($fp);
03730               }
03731                         } elseif ($this->wsdl) {
03732                                 $this->debug("In service, serialize WSDL");
03733                                 header("Content-Type: text/xml; charset=ISO-8859-1\r\n");
03734                                 print $this->wsdl->serialize($this->debug_flag);
03735                                 if ($this->debug_flag) {
03736                                         $this->debug('wsdl:');
03737                                         $this->appendDebug($this->varDump($this->wsdl));
03738                                         print $this->getDebugAsXMLComment();
03739                                 }
03740                         } else {
03741                                 $this->debug("In service, there is no WSDL");
03742                                 header("Content-Type: text/html; charset=ISO-8859-1\r\n");
03743                                 print "This service does not provide WSDL";
03744                         }
03745                 } elseif ($this->wsdl) {
03746                         $this->debug("In service, return Web description");
03747                         print $this->wsdl->webDescription();
03748                 } else {
03749                         $this->debug("In service, no Web description");
03750                         header("Content-Type: text/html; charset=ISO-8859-1\r\n");
03751                         print "This service does not provide a Web description";
03752                 }
03753         }
03754 
03767         function parse_http_headers() {
03768                 global $HTTP_SERVER_VARS;
03769 
03770                 $this->request = '';
03771                 $this->SOAPAction = '';
03772                 if(function_exists('getallheaders')){
03773                         $this->debug("In parse_http_headers, use getallheaders");
03774                         $headers = getallheaders();
03775                         foreach($headers as $k=>$v){
03776                                 $k = strtolower($k);
03777                                 $this->headers[$k] = $v;
03778                                 $this->request .= "$k: $v\r\n";
03779                                 $this->debug("$k: $v");
03780                         }
03781                         // get SOAPAction header
03782                         if(isset($this->headers['soapaction'])){
03783                                 $this->SOAPAction = str_replace('"','',$this->headers['soapaction']);
03784                         }
03785                         // get the character encoding of the incoming request
03786                         if(isset($this->headers['content-type']) && strpos($this->headers['content-type'],'=')){
03787                                 $enc = str_replace('"','',substr(strstr($this->headers["content-type"],'='),1));
03788                                 if(eregi('^(ISO-8859-1|US-ASCII|UTF-8)$',$enc)){
03789                                         $this->xml_encoding = strtoupper($enc);
03790                                 } else {
03791                                         $this->xml_encoding = 'US-ASCII';
03792                                 }
03793                         } else {
03794                                 // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
03795                                 $this->xml_encoding = 'ISO-8859-1';
03796                         }
03797                 } elseif(isset($_SERVER) && is_array($_SERVER)){
03798                         $this->debug("In parse_http_headers, use _SERVER");
03799                         foreach ($_SERVER as $k => $v) {
03800                                 if (substr($k, 0, 5) == 'HTTP_') {
03801                                         $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($k, 5))));
03802                                 } else {
03803                                         $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', $k)));
03804                                 }
03805                                 if ($k == 'soapaction') {
03806                                         // get SOAPAction header
03807                                         $k = 'SOAPAction';
03808                                         $v = str_replace('"', '', $v);
03809                                         $v = str_replace('\\', '', $v);
03810                                         $this->SOAPAction = $v;
03811                                 } else if ($k == 'content-type') {
03812                                         // get the character encoding of the incoming request
03813                                         if (strpos($v, '=')) {
03814                                                 $enc = substr(strstr($v, '='), 1);
03815                                                 $enc = str_replace('"', '', $enc);
03816                                                 $enc = str_replace('\\', '', $enc);
03817                                                 if (eregi('^(ISO-8859-1|US-ASCII|UTF-8)$', $enc)) {
03818                                                         $this->xml_encoding = strtoupper($enc);
03819                                                 } else {
03820                                                         $this->xml_encoding = 'US-ASCII';
03821                                                 }
03822                                         } else {
03823                                                 // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
03824                                                 $this->xml_encoding = 'ISO-8859-1';
03825                                         }
03826                                 }
03827                                 $this->headers[$k] = $v;
03828                                 $this->request .= "$k: $v\r\n";
03829                                 $this->debug("$k: $v");
03830                         }
03831                 } elseif (is_array($HTTP_SERVER_VARS)) {
03832                         $this->debug("In parse_http_headers, use HTTP_SERVER_VARS");
03833                         foreach ($HTTP_SERVER_VARS as $k => $v) {
03834                                 if (substr($k, 0, 5) == 'HTTP_') {
03835                                         $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($k, 5))));                                            $k = strtolower(substr($k, 5));
03836                                 } else {
03837                                         $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', $k)));                                               $k = strtolower($k);
03838                                 }
03839                                 if ($k == 'soapaction') {
03840                                         // get SOAPAction header
03841                                         $k = 'SOAPAction';
03842                                         $v = str_replace('"', '', $v);
03843                                         $v = str_replace('\\', '', $v);
03844                                         $this->SOAPAction = $v;
03845                                 } else if ($k == 'content-type') {
03846                                         // get the character encoding of the incoming request
03847                                         if (strpos($v, '=')) {
03848                                                 $enc = substr(strstr($v, '='), 1);
03849                                                 $enc = str_replace('"', '', $enc);
03850                                                 $enc = str_replace('\\', '', $enc);
03851                                                 if (eregi('^(ISO-8859-1|US-ASCII|UTF-8)$', $enc)) {
03852                                                         $this->xml_encoding = strtoupper($enc);
03853                                                 } else {
03854                                                         $this->xml_encoding = 'US-ASCII';
03855                                                 }
03856                                         } else {
03857                                                 // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
03858                                                 $this->xml_encoding = 'ISO-8859-1';
03859                                         }
03860                                 }
03861                                 $this->headers[$k] = $v;
03862                                 $this->request .= "$k: $v\r\n";
03863                                 $this->debug("$k: $v");
03864                         }
03865                 } else {
03866                         $this->debug("In parse_http_headers, HTTP headers not accessible");
03867                         $this->setError("HTTP headers not accessible");
03868                 }
03869         }
03870 
03893         function parse_request($data='') {
03894                 $this->debug('entering parse_request()');
03895                 $this->parse_http_headers();
03896                 $this->debug('got character encoding: '.$this->xml_encoding);
03897                 // uncompress if necessary
03898                 if (isset($this->headers['content-encoding']) && $this->headers['content-encoding'] != '') {
03899                         $this->debug('got content encoding: ' . $this->headers['content-encoding']);
03900                         if ($this->headers['content-encoding'] == 'deflate' || $this->headers['content-encoding'] == 'gzip') {
03901                         // if decoding works, use it. else assume data wasn't gzencoded
03902                                 if (function_exists('gzuncompress')) {
03903                                         if ($this->headers['content-encoding'] == 'deflate' && $degzdata = @gzuncompress($data)) {
03904                                                 $data = $degzdata;
03905                                         } elseif ($this->headers['content-encoding'] == 'gzip' && $degzdata = gzinflate(substr($data, 10))) {
03906                                                 $data = $degzdata;
03907                                         } else {
03908                                                 $this->fault('SOAP-ENV:Client', 'Errors occurred when trying to decode the data');
03909                                                 return;
03910                                         }
03911                                 } else {
03912                                         $this->fault('SOAP-ENV:Client', 'This Server does not support compressed data');
03913                                         return;
03914                                 }
03915                         }
03916                 }
03917                 $this->request .= "\r\n".$data;
03918                 $data = $this->parseRequest($this->headers, $data);
03919                 $this->requestSOAP = $data;
03920                 $this->debug('leaving parse_request');
03921         }
03922 
03940         function invoke_method() {
03941                 $this->debug('in invoke_method, methodname=' . $this->methodname . ' methodURI=' . $this->methodURI . ' SOAPAction=' . $this->SOAPAction);
03942 
03943                 if ($this->wsdl) {
03944                         if ($this->opData = $this->wsdl->getOperationData($this->methodname)) {
03945                                 $this->debug('in invoke_method, found WSDL operation=' . $this->methodname);
03946                                 $this->appendDebug('opData=' . $this->varDump($this->opData));
03947                         } elseif ($this->opData = $this->wsdl->getOperationDataForSoapAction($this->SOAPAction)) {
03948                                 // Note: hopefully this case will only be used for doc/lit, since rpc services should have wrapper element
03949                                 $this->debug('in invoke_method, found WSDL soapAction=' . $this->SOAPAction . ' for operation=' . $this->opData['name']);
03950                                 $this->appendDebug('opData=' . $this->varDump($this->opData));
03951                                 $this->methodname = $this->opData['name'];
03952                         } else {
03953                                 $this->debug('in invoke_method, no WSDL for operation=' . $this->methodname);
03954                                 $this->fault('SOAP-ENV:Client', "Operation '" . $this->methodname . "' is not defined in the WSDL for this service");
03955                                 return;
03956                         }
03957                 } else {
03958                         $this->debug('in invoke_method, no WSDL to validate method');
03959                 }
03960 
03961                 // if a . is present in $this->methodname, we see if there is a class in scope,
03962                 // which could be referred to. We will also distinguish between two deliminators,
03963                 // to allow methods to be called a the class or an instance
03964                 $class = '';
03965                 $method = '';
03966                 if (strpos($this->methodname, '..') > 0) {
03967                         $delim = '..';
03968                 } else if (strpos($this->methodname, '.') > 0) {
03969                         $delim = '.';
03970                 } else {
03971                         $delim = '';
03972                 }
03973 
03974                 if (strlen($delim) > 0 && substr_count($this->methodname, $delim) == 1 &&
03975                         class_exists(substr($this->methodname, 0, strpos($this->methodname, $delim)))) {
03976                         // get the class and method name
03977                         $class = substr($this->methodname, 0, strpos($this->methodname, $delim));
03978                         $method = substr($this->methodname, strpos($this->methodname, $delim) + strlen($delim));
03979                         $this->debug("in invoke_method, class=$class method=$method delim=$delim");
03980                 }
03981 
03982                 // does method exist?
03983                 if ($class == '') {
03984                         if (!function_exists($this->methodname)) {
03985                                 $this->debug("in invoke_method, function '$this->methodname' not found!");
03986                                 $this->result = 'fault: method not found';
03987                                 $this->fault('SOAP-ENV:Client',"method '$this->methodname' not defined in service");
03988                                 return;
03989                         }
03990                 } else {
03991                         $method_to_compare = (substr(phpversion(), 0, 2) == '4.') ? strtolower($method) : $method;
03992                         if (!in_array($method_to_compare, get_class_methods($class))) {
03993                                 $this->debug("in invoke_method, method '$this->methodname' not found in class '$class'!");
03994                                 $this->result = 'fault: method not found';
03995                                 $this->fault('SOAP-ENV:Client',"method '$this->methodname' not defined in service");
03996                                 return;
03997                         }
03998                 }
03999 
04000                 // evaluate message, getting back parameters
04001                 // verify that request parameters match the method's signature
04002                 if(! $this->verify_method($this->methodname,$this->methodparams)){
04003                         // debug
04004                         $this->debug('ERROR: request not verified against method signature');
04005                         $this->result = 'fault: request failed validation against method signature';
04006                         // return fault
04007                         $this->fault('SOAP-ENV:Client',"Operation '$this->methodname' not defined in service.");
04008                         return;
04009                 }
04010 
04011                 // if there are parameters to pass
04012                 $this->debug('in invoke_method, params:');
04013                 $this->appendDebug($this->varDump($this->methodparams));
04014                 $this->debug("in invoke_method, calling '$this->methodname'");
04015                 if (!function_exists('call_user_func_array')) {
04016                         if ($class == '') {
04017                                 $this->debug('in invoke_method, calling function using eval()');
04018                                 $funcCall = "\$this->methodreturn = $this->methodname(";
04019                         } else {
04020                                 if ($delim == '..') {
04021                                         $this->debug('in invoke_method, calling class method using eval()');
04022                                         $funcCall = "\$this->methodreturn = ".$class."::".$method."(";
04023                                 } else {
04024                                         $this->debug('in invoke_method, calling instance method using eval()');
04025                                         // generate unique instance name
04026                                         $instname = "\$inst_".time();
04027                                         $funcCall = $instname." = new ".$class."(); ";
04028                                         $funcCall .= "\$this->methodreturn = ".$instname."->".$method."(";
04029                                 }
04030                         }
04031                         if ($this->methodparams) {
04032                                 foreach ($this->methodparams as $param) {
04033                                         if (is_array($param) || is_object($param)) {
04034                                                 $this->fault('SOAP-ENV:Client', 'NuSOAP does not handle complexType parameters correctly when using eval; call_user_func_array must be available');
04035                                                 return;
04036                                         }
04037                                         $funcCall .= "\"$param\",";
04038                                 }
04039                                 $funcCall = substr($funcCall, 0, -1);
04040                         }
04041                         $funcCall .= ');';
04042                         $this->debug('in invoke_method, function call: '.$funcCall);
04043                         @eval($funcCall);
04044                 } else {
04045                         if ($class == '') {
04046                                 $this->debug('in invoke_method, calling function using call_user_func_array()');
04047                                 $call_arg = "$this->methodname";        // straight assignment changes $this->methodname to lower case after call_user_func_array()
04048                         } elseif ($delim == '..') {
04049                                 $this->debug('in invoke_method, calling class method using call_user_func_array()');
04050                                 $call_arg = array ($class, $method);
04051                         } else {
04052                                 $this->debug('in invoke_method, calling instance method using call_user_func_array()');
04053                                 $instance = new $class ();
04054                                 $call_arg = array(&$instance, $method);
04055                         }
04056                         if (is_array($this->methodparams)) {
04057                                 $this->methodreturn = call_user_func_array($call_arg, array_values($this->methodparams));
04058                         } else {
04059                                 $this->methodreturn = call_user_func_array($call_arg, array());
04060                         }
04061                 }
04062         $this->debug('in invoke_method, methodreturn:');
04063         $this->appendDebug($this->varDump($this->methodreturn));
04064                 $this->debug("in invoke_method, called method $this->methodname, received data of type ".gettype($this->methodreturn));
04065         }
04066 
04078         function serialize_return() {
04079                 $this->debug('Entering serialize_return methodname: ' . $this->methodname . ' methodURI: ' . $this->methodURI);
04080                 // if fault
04081                 if (isset($this->methodreturn) && ((get_class($this->methodreturn) == 'soap_fault') || (get_class($this->methodreturn) == 'nusoap_fault'))) {
04082                         $this->debug('got a fault object from method');
04083                         $this->fault = $this->methodreturn;
04084                         return;
04085                 } elseif ($this->methodreturnisliteralxml) {
04086                         $return_val = $this->methodreturn;
04087                 // returned value(s)
04088                 } else {
04089                         $this->debug('got a(n) '.gettype($this->methodreturn).' from method');
04090                         $this->debug('serializing return value');
04091                         if($this->wsdl){
04092                                 if (sizeof($this->opData['output']['parts']) > 1) {
04093                                         $this->debug('more than one output part, so use the method return unchanged');
04094                                 $opParams = $this->methodreturn;
04095                             } elseif (sizeof($this->opData['output']['parts']) == 1) {
04096                                         $this->debug('exactly one output part, so wrap the method return in a simple array');
04097                                         // TODO: verify that it is not already wrapped!
04098                                 //foreach ($this->opData['output']['parts'] as $name => $type) {
04099                                         //      $this->debug('wrap in element named ' . $name);
04100                                 //}
04101                                 $opParams = array($this->methodreturn);
04102                             }
04103                             $return_val = $this->wsdl->serializeRPCParameters($this->methodname,'output',$opParams);
04104                             $this->appendDebug($this->wsdl->getDebug());
04105                             $this->wsdl->clearDebug();
04106                                 if($errstr = $this->wsdl->getError()){
04107                                         $this->debug('got wsdl error: '.$errstr);
04108                                         $this->fault('SOAP-ENV:Server', 'unable to serialize result');
04109                                         return;
04110                                 }
04111                         } else {
04112                                 if (isset($this->methodreturn)) {
04113                                         $return_val = $this->serialize_val($this->methodreturn, 'return');
04114                                 } else {
04115                                         $return_val = '';
04116                                         $this->debug('in absence of WSDL, assume void return for backward compatibility');
04117                                 }
04118                         }
04119                 }
04120                 $this->debug('return value:');
04121                 $this->appendDebug($this->varDump($return_val));
04122 
04123                 $this->debug('serializing response');
04124                 if ($this->wsdl) {
04125                         $this->debug('have WSDL for serialization: style is ' . $this->opData['style']);
04126                         if ($this->opData['style'] == 'rpc') {
04127                                 $this->debug('style is rpc for serialization: use is ' . $this->opData['output']['use']);
04128                                 if ($this->opData['output']['use'] == 'literal') {
04129                                         // 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
04130                                         if ($this->methodURI) {
04131                                                 $payload = '<ns1:'.$this->methodname.'Response xmlns:ns1="'.$this->methodURI.'">'.$return_val.'</ns1:'.$this->methodname."Response>";
04132                                         } else {
04133                                                 $payload = '<'.$this->methodname.'Response>'.$return_val.'</'.$this->methodname.'Response>';
04134                                         }
04135                                 } else {
04136                                         if ($this->methodURI) {
04137                                                 $payload = '<ns1:'.$this->methodname.'Response xmlns:ns1="'.$this->methodURI.'">'.$return_val.'</ns1:'.$this->methodname."Response>";
04138                                         } else {
04139                                                 $payload = '<'.$this->methodname.'Response>'.$return_val.'</'.$this->methodname.'Response>';
04140                                         }
04141                                 }
04142                         } else {
04143                                 $this->debug('style is not rpc for serialization: assume document');
04144                                 $payload = $return_val;
04145                         }
04146                 } else {
04147                         $this->debug('do not have WSDL for serialization: assume rpc/encoded');
04148                         $payload = '<ns1:'.$this->methodname.'Response xmlns:ns1="'.$this->methodURI.'">'.$return_val.'</ns1:'.$this->methodname."Response>";
04149                 }
04150                 $this->result = 'successful';
04151                 if($this->wsdl){
04152                         //if($this->debug_flag){
04153                 $this->appendDebug($this->wsdl->getDebug());
04154             //  }
04155                         if (isset($opData['output']['encodingStyle'])) {
04156                                 $encodingStyle = $opData['output']['encodingStyle'];
04157                         } else {
04158                                 $encodingStyle = '';
04159                         }
04160                         // Added: In case we use a WSDL, return a serialized env. WITH the usedNamespaces.
04161                         $this->responseSOAP = $this->serializeEnvelope($payload,$this->responseHeaders,$this->wsdl->usedNamespaces,$this->opData['style'],$this->opData['output']['use'],$encodingStyle);
04162                 } else {
04163                         $this->responseSOAP = $this->serializeEnvelope($payload,$this->responseHeaders);
04164                 }
04165                 $this->debug("Leaving serialize_return");
04166         }
04167 
04178         function send_response() {
04179                 $this->debug('Enter send_response');
04180                 if ($this->fault) {
04181                         $payload = $this->fault->serialize();
04182                         $this->outgoing_headers[] = "HTTP/1.0 500 Internal Server Error";
04183                         $this->outgoing_headers[] = "Status: 500 Internal Server Error";
04184                 } else {
04185                         $payload = $this->responseSOAP;
04186                         // Some combinations of PHP+Web server allow the Status
04187                         // to come through as a header.  Since OK is the default
04188                         // just do nothing.
04189                         // $this->outgoing_headers[] = "HTTP/1.0 200 OK";
04190                         // $this->outgoing_headers[] = "Status: 200 OK";
04191                 }
04192         // add debug data if in debug mode
04193                 if(isset($this->debug_flag) && $this->debug_flag){
04194                 $payload .= $this->getDebugAsXMLComment();
04195         }
04196                 $this->outgoing_headers[] = "Server: $this->title Server v$this->version";
04197                 ereg('\$Revisio' . 'n: ([^ ]+)', $this->revision, $rev);
04198                 $this->outgoing_headers[] = "X-SOAP-Server: $this->title/$this->version (".$rev[1].")";
04199                 // Let the Web server decide about this
04200                 //$this->outgoing_headers[] = "Connection: Close\r\n";
04201                 $payload = $this->getHTTPBody($payload);
04202                 $type = $this->getHTTPContentType();
04203                 $charset = $this->getHTTPContentTypeCharset();
04204                 $this->outgoing_headers[] = "Content-Type: $type" . ($charset ? '; charset=' . $charset : '');
04205                 //begin code to compress payload - by John
04206                 // NOTE: there is no way to know whether the Web server will also compress
04207                 // this data.
04208                 if (strlen($payload) > 1024 && isset($this->headers) && isset($this->headers['accept-encoding'])) {     
04209                         if (strstr($this->headers['accept-encoding'], 'gzip')) {
04210                                 if (function_exists('gzencode')) {
04211                                         if (isset($this->debug_flag) && $this->debug_flag) {
04212                                                 $payload .= "<!-- Content being gzipped -->";
04213                                         }
04214                                         $this->outgoing_headers[] = "Content-Encoding: gzip";
04215                                         $payload = gzencode($payload);
04216                                 } else {
04217                                         if (isset($this->debug_flag) && $this->debug_flag) {
04218                                                 $payload .= "<!-- Content will not be gzipped: no gzencode -->";
04219                                         }
04220                                 }
04221                         } elseif (strstr($this->headers['accept-encoding'], 'deflate')) {
04222                                 // Note: MSIE requires gzdeflate output (no Zlib header and checksum),
04223                                 // instead of gzcompress output,
04224                                 // which conflicts with HTTP 1.1 spec (http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.5)
04225                                 if (function_exists('gzdeflate')) {
04226                                         if (isset($this->debug_flag) && $this->debug_flag) {
04227                                                 $payload .= "<!-- Content being deflated -->";
04228                                         }
04229                                         $this->outgoing_headers[] = "Content-Encoding: deflate";
04230                                         $payload = gzdeflate($payload);
04231                                 } else {
04232                                         if (isset($this->debug_flag) && $this->debug_flag) {
04233                                                 $payload .= "<!-- Content will not be deflated: no gzcompress -->";
04234                                         }
04235                                 }
04236                         }
04237                 }
04238                 //end code
04239                 $this->outgoing_headers[] = "Content-Length: ".strlen($payload);
04240                 reset($this->outgoing_headers);
04241                 foreach($this->outgoing_headers as $hdr){
04242                         header($hdr, false);
04243                 }
04244                 print $payload;
04245                 $this->response = join("\r\n",$this->outgoing_headers)."\r\n\r\n".$payload;
04246         }
04247 
04257         function verify_method($operation,$request){
04258                 if(isset($this->wsdl) && is_object($this->wsdl)){
04259                         if($this->wsdl->getOperationData($operation)){
04260                                 return true;
04261                         }
04262             } elseif(isset($this->operations[$operation])){
04263                         return true;
04264                 }
04265                 return false;
04266         }
04267 
04276     function parseRequest($headers, $data) {
04277                 $this->debug('Entering parseRequest() for data of length ' . strlen($data) . ' headers:');
04278                 $this->appendDebug($this->varDump($headers));
04279         if (!isset($headers['content-type'])) {
04280                         $this->setError('Request not of type text/xml (no content-type header)');
04281                         return false;
04282         }
04283                 if (!strstr($headers['content-type'], 'text/xml')) {
04284                         $this->setError('Request not of type text/xml');
04285                         return false;
04286                 }
04287                 if (strpos($headers['content-type'], '=')) {
04288                         $enc = str_replace('"', '', substr(strstr($headers["content-type"], '='), 1));
04289                         $this->debug('Got response encoding: ' . $enc);
04290                         if(eregi('^(ISO-8859-1|US-ASCII|UTF-8)$',$enc)){
04291                                 $this->xml_encoding = strtoupper($enc);
04292                         } else {
04293                                 $this->xml_encoding = 'US-ASCII';
04294                         }
04295                 } else {
04296                         // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
04297                         $this->xml_encoding = 'ISO-8859-1';
04298                 }
04299                 $this->debug('Use encoding: ' . $this->xml_encoding . ' when creating nusoap_parser');
04300                 // parse response, get soap parser obj
04301                 $parser = new nusoap_parser($data,$this->xml_encoding,'',$this->decode_utf8);
04302                 // parser debug
04303                 $this->debug("parser debug: \n".$parser->getDebug());
04304                 // if fault occurred during message parsing
04305                 if($err = $parser->getError()){
04306                         $this->result = 'fault: error in msg parsing: '.$err;
04307                         $this->fault('SOAP-ENV:Client',"error in msg parsing:\n".$err);
04308                 // else successfully parsed request into soapval object
04309                 } else {
04310                         // get/set methodname
04311                         $this->methodURI = $parser->root_struct_namespace;
04312                         $this->methodname = $parser->root_struct_name;
04313                         $this->debug('methodname: '.$this->methodname.' methodURI: '.$this->methodURI);
04314                         $this->debug('calling parser->get_soapbody()');
04315                         $this->methodparams = $parser->get_soapbody();
04316                         // get SOAP headers
04317                         $this->requestHeaders = $parser->getHeaders();
04318                         // get SOAP Header
04319                         $this->requestHeader = $parser->get_soapheader();
04320             // add document for doclit support
04321             $this->document = $parser->document;
04322                 }
04323          }
04324 
04332         function getHTTPBody($soapmsg) {
04333                 return $soapmsg;
04334         }
04335         
04344         function getHTTPContentType() {
04345                 return 'text/xml';
04346         }
04347         
04357         function getHTTPContentTypeCharset() {
04358                 return $this->soap_defencoding;
04359         }
04360 
04370         function add_to_map($methodname,$in,$out){
04371                         $this->operations[$methodname] = array('name' => $methodname,'in' => $in,'out' => $out);
04372         }
04373 
04388         function register($name,$in=array(),$out=array(),$namespace=false,$soapaction=false,$style=false,$use=false,$documentation='',$encodingStyle=''){
04389                 global $HTTP_SERVER_VARS;
04390 
04391                 if($this->externalWSDLURL){
04392                         die('You cannot bind to an external WSDL file, and register methods outside of it! Please choose either WSDL or no WSDL.');
04393                 }
04394                 if (! $name) {
04395                         die('You must specify a name when you register an operation');
04396                 }
04397                 if (!is_array($in)) {
04398                         die('You must provide an array for operation inputs');
04399                 }
04400                 if (!is_array($out)) {
04401                         die('You must provide an array for operation outputs');
04402                 }
04403                 if(false == $namespace) {
04404                 }
04405                 if(false == $soapaction) {
04406                         if (isset($_SERVER)) {
04407                                 $SERVER_NAME = $_SERVER['SERVER_NAME'];
04408                                 $SCRIPT_NAME = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME'];
04409                                 $HTTPS = isset($_SERVER['HTTPS']) ? $_SERVER['HTTPS'] : (isset($HTTP_SERVER_VARS['HTTPS']) ? $HTTP_SERVER_VARS['HTTPS'] : 'off');
04410                         } elseif (isset($HTTP_SERVER_VARS)) {
04411                                 $SERVER_NAME = $HTTP_SERVER_VARS['SERVER_NAME'];
04412                                 $SCRIPT_NAME = isset($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : $HTTP_SERVER_VARS['SCRIPT_NAME'];
04413                                 $HTTPS = isset($HTTP_SERVER_VARS['HTTPS']) ? $HTTP_SERVER_VARS['HTTPS'] : 'off';
04414                         } else {
04415                                 $this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available");
04416                         }
04417                 if ($HTTPS == '1' || $HTTPS == 'on') {
04418                         $SCHEME = 'https';
04419                 } else {
04420                         $SCHEME = 'http';
04421                 }
04422                         $soapaction = "$SCHEME://$SERVER_NAME$SCRIPT_NAME/$name";
04423                 }
04424                 if(false == $style) {
04425                         $style = "rpc";
04426                 }
04427                 if(false == $use) {
04428                         $use = "encoded";
04429                 }
04430                 if ($use == 'encoded' && $encodingStyle == '') {
04431                         $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
04432                 }
04433 
04434                 $this->operations[$name] = array(
04435             'name' => $name,
04436             'in' => $in,
04437             'out' => $out,
04438             'namespace' => $namespace,
04439             'soapaction' => $soapaction,
04440             'style' => $style);
04441         if($this->wsdl){
04442                 $this->wsdl->addOperation($name,$in,$out,$namespace,$soapaction,$style,$use,$documentation,$encodingStyle);
04443             }
04444                 return true;
04445         }
04446 
04457         function fault($faultcode,$faultstring,$faultactor='',$faultdetail=''){
04458                 if ($faultdetail == '' && $this->debug_flag) {
04459                         $faultdetail = $this->getDebug();
04460                 }
04461                 $this->fault = new nusoap_fault($faultcode,$faultactor,$faultstring,$faultdetail);
04462                 $this->fault->soap_defencoding = $this->soap_defencoding;
04463         }
04464 
04476     function configureWSDL($serviceName,$namespace = false,$endpoint = false,$style='rpc', $transport = 'http://schemas.xmlsoap.org/soap/http', $schemaTargetNamespace = false)
04477     {
04478         global $HTTP_SERVER_VARS;
04479 
04480                 if (isset($_SERVER)) {
04481                         $SERVER_NAME = $_SERVER['SERVER_NAME'];
04482                         $SERVER_PORT = $_SERVER['SERVER_PORT'];
04483                         $SCRIPT_NAME = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME'];
04484                         $HTTPS = isset($_SERVER['HTTPS']) ? $_SERVER['HTTPS'] : (isset($HTTP_SERVER_VARS['HTTPS']) ? $HTTP_SERVER_VARS['HTTPS'] : 'off');
04485                 } elseif (isset($HTTP_SERVER_VARS)) {
04486                         $SERVER_NAME = $HTTP_SERVER_VARS['SERVER_NAME'];
04487                         $SERVER_PORT = $HTTP_SERVER_VARS['SERVER_PORT'];
04488                         $SCRIPT_NAME = isset($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : $HTTP_SERVER_VARS['SCRIPT_NAME'];
04489                         $HTTPS = isset($HTTP_SERVER_VARS['HTTPS']) ? $HTTP_SERVER_VARS['HTTPS'] : 'off';
04490                 } else {
04491                         $this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available");
04492                 }
04493                 // If server name has port number attached then strip it (else port number gets duplicated in WSDL output) (occurred using lighttpd and FastCGI)
04494                 $colon = strpos($SERVER_NAME,":");
04495                 if ($colon) {
04496                     $SERVER_NAME = substr($SERVER_NAME, 0, $colon);
04497                 }
04498                 if ($SERVER_PORT == 80) {
04499                         $SERVER_PORT = '';
04500                 } else {
04501                         $SERVER_PORT = ':' . $SERVER_PORT;
04502                 }
04503         if(false == $namespace) {
04504             $namespace = "http://$SERVER_NAME/soap/$serviceName";
04505         }
04506         
04507         if(false == $endpoint) {
04508                 if ($HTTPS == '1' || $HTTPS == 'on') {
04509                         $SCHEME = 'https';
04510                 } else {
04511                         $SCHEME = 'http';
04512                 }
04513             $endpoint = "$SCHEME://$SERVER_NAME$SERVER_PORT$SCRIPT_NAME";
04514         }
04515         
04516         if(false == $schemaTargetNamespace) {
04517             $schemaTargetNamespace = $namespace;
04518         }
04519         
04520                 $this->wsdl = new wsdl;
04521                 $this->wsdl->serviceName = $serviceName;
04522         $this->wsdl->endpoint = $endpoint;
04523                 $this->wsdl->namespaces['tns'] = $namespace;
04524                 $this->wsdl->namespaces['soap'] = 'http://schemas.xmlsoap.org/wsdl/soap/';
04525                 $this->wsdl->namespaces['wsdl'] = 'http://schemas.xmlsoap.org/wsdl/';
04526                 if ($schemaTargetNamespace != $namespace) {
04527                         $this->wsdl->namespaces['types'] = $schemaTargetNamespace;
04528                 }
04529         $this->wsdl->schemas[$schemaTargetNamespace][0] = new nusoap_xmlschema('', '', $this->wsdl->namespaces);
04530         if ($style == 'document') {
04531                 $this->wsdl->schemas[$schemaTargetNamespace][0]->schemaInfo['elementFormDefault'] = 'qualified';
04532         }
04533         $this->wsdl->schemas[$schemaTargetNamespace][0]->schemaTargetNamespace = $schemaTargetNamespace;
04534         $this->wsdl->schemas[$schemaTargetNamespace][0]->imports['http://schemas.xmlsoap.org/soap/encoding/'][0] = array('location' => '', 'loaded' => true);
04535         $this->wsdl->schemas[$schemaTargetNamespace][0]->imports['http://schemas.xmlsoap.org/wsdl/'][0] = array('location' => '', 'loaded' => true);
04536         $this->wsdl->bindings[$serviceName.'Binding'] = array(
04537                 'name'=>$serviceName.'Binding',
04538             'style'=>$style,
04539             'transport'=>$transport,
04540             'portType'=>$serviceName.'PortType');
04541         $this->wsdl->ports[$serviceName.'Port'] = array(
04542                 'binding'=>$serviceName.'Binding',
04543             'location'=>$endpoint,
04544             'bindingType'=>'http://schemas.xmlsoap.org/wsdl/soap/');
04545     }
04546 }
04547 
04551 class soap_server extends nusoap_server {
04552 }
04553 
04554 ?><?php
04555 
04556 
04557 
04567 class wsdl extends nusoap_base {
04568         // URL or filename of the root of this WSDL
04569     var $wsdl; 
04570     // define internal arrays of bindings, ports, operations, messages, etc.
04571     var $schemas = array();
04572     var $currentSchema;
04573     var $message = array();
04574     var $complexTypes = array();
04575     var $messages = array();
04576     var $currentMessage;
04577     var $currentOperation;
04578     var $portTypes = array();
04579     var $currentPortType;
04580     var $bindings = array();
04581     var $currentBinding;
04582     var $ports = array();
04583     var $currentPort;
04584     var $opData = array();
04585     var $status = '';
04586     var $documentation = false;
04587     var $endpoint = ''; 
04588     // array of wsdl docs to import
04589     var $import = array(); 
04590     // parser vars
04591     var $parser;
04592     var $position = 0;
04593     var $depth = 0;
04594     var $depth_array = array();
04595         // for getting wsdl
04596         var $proxyhost = '';
04597     var $proxyport = '';
04598         var $proxyusername = '';
04599         var $proxypassword = '';
04600         var $timeout = 0;
04601         var $response_timeout = 30;
04602         var $curl_options = array();    // User-specified cURL options
04603         var $use_curl = false;                  // whether to always try to use cURL
04604         // for HTTP authentication
04605         var $username = '';                             // Username for HTTP authentication
04606         var $password = '';                             // Password for HTTP authentication
04607         var $authtype = '';                             // Type of HTTP authentication
04608         var $certRequest = array();             // Certificate for HTTP SSL authentication
04609 
04624     function wsdl($wsdl = '',$proxyhost=false,$proxyport=false,$proxyusername=false,$proxypassword=false,$timeout=0,$response_timeout=30,$curl_options=null,$use_curl=false){
04625                 parent::nusoap_base();
04626                 $this->debug("ctor wsdl=$wsdl timeout=$timeout response_timeout=$response_timeout");
04627         $this->proxyhost = $proxyhost;
04628         $this->proxyport = $proxyport;
04629                 $this->proxyusername = $proxyusername;
04630                 $this->proxypassword = $proxypassword;
04631                 $this->timeout = $timeout;
04632                 $this->response_timeout = $response_timeout;
04633                 if (is_array($curl_options))
04634                         $this->curl_options = $curl_options;
04635                 $this->use_curl = $use_curl;
04636                 $this->fetchWSDL($wsdl);
04637     }
04638 
04644         function fetchWSDL($wsdl) {
04645                 $this->debug("parse and process WSDL path=$wsdl");
04646                 $this->wsdl = $wsdl;
04647         // parse wsdl file
04648         if ($this->wsdl != "") {
04649             $this->parseWSDL($this->wsdl);
04650         }
04651         // imports
04652         // TODO: handle imports more properly, grabbing them in-line and nesting them
04653         $imported_urls = array();
04654         $imported = 1;
04655         while ($imported > 0) {
04656                 $imported = 0;
04657                 // Schema imports
04658                 foreach ($this->schemas as $ns => $list) {
04659                         foreach ($list as $xs) {
04660                                         $wsdlparts = parse_url($this->wsdl);    // this is bogusly simple!
04661                             foreach ($xs->imports as $ns2 => $list2) {
04662                                 for ($ii = 0; $ii < count($list2); $ii++) {
04663                                         if (! $list2[$ii]['loaded']) {
04664                                                 $this->schemas[$ns]->imports[$ns2][$ii]['loaded'] = true;
04665                                                 $url = $list2[$ii]['location'];
04666                                                                 if ($url != '') {
04667                                                                         $urlparts = parse_url($url);
04668                                                                         if (!isset($urlparts['host'])) {
04669                                                                                 $url = $wsdlparts['scheme'] . '://' . $wsdlparts['host'] . (isset($wsdlparts['port']) ? ':' .$wsdlparts['port'] : '') .
04670                                                                                                 substr($wsdlparts['path'],0,strrpos($wsdlparts['path'],'/') + 1) .$urlparts['path'];
04671                                                                         }
04672                                                                         if (! in_array($url, $imported_urls)) {
04673                                                                 $this->parseWSDL($url);
04674                                                                 $imported++;
04675                                                                 $imported_urls[] = $url;
04676                                                         }
04677                                                                 } else {
04678                                                                         $this->debug("Unexpected scenario: empty URL for unloaded import");
04679                                                                 }
04680                                                         }
04681                                                 }
04682                             } 
04683                         }
04684                 }
04685                 // WSDL imports
04686                         $wsdlparts = parse_url($this->wsdl);    // this is bogusly simple!
04687             foreach ($this->import as $ns => $list) {
04688                 for ($ii = 0; $ii < count($list); $ii++) {
04689                         if (! $list[$ii]['loaded']) {
04690                                 $this->import[$ns][$ii]['loaded'] = true;
04691                                 $url = $list[$ii]['location'];
04692                                                 if ($url != '') {
04693                                                         $urlparts = parse_url($url);
04694                                                         if (!isset($urlparts['host'])) {
04695                                                                 $url = $wsdlparts['scheme'] . '://' . $wsdlparts['host'] . (isset($wsdlparts['port']) ? ':' . $wsdlparts['port'] : '') .
04696                                                                                 substr($wsdlparts['path'],0,strrpos($wsdlparts['path'],'/') + 1) .$urlparts['path'];
04697                                                         }
04698                                                         if (! in_array($url, $imported_urls)) {
04699                                                 $this->parseWSDL($url);
04700                                                 $imported++;
04701                                                 $imported_urls[] = $url;
04702                                         }
04703                                                 } else {
04704                                                         $this->debug("Unexpected scenario: empty URL for unloaded import");
04705                                                 }
04706                                         }
04707                                 }
04708             } 
04709                 }
04710         // add new data to operation data
04711         foreach($this->bindings as $binding => $bindingData) {
04712             if (isset($bindingData['operations']) && is_array($bindingData['operations'])) {
04713                 foreach($bindingData['operations'] as $operation => $data) {
04714                     $this->debug('post-parse data gathering for ' . $operation);
04715                     $this->bindings[$binding]['operations'][$operation]['input'] = 
04716                                                 isset($this->bindings[$binding]['operations'][$operation]['input']) ? 
04717                                                 array_merge($this->bindings[$binding]['operations'][$operation]['input'], $this->portTypes[ $bindingData['portType'] ][$operation]['input']) :
04718                                                 $this->portTypes[ $bindingData['portType'] ][$operation]['input'];
04719                     $this->bindings[$binding]['operations'][$operation]['output'] = 
04720                                                 isset($this->bindings[$binding]['operations'][$operation]['output']) ?
04721                                                 array_merge($this->bindings[$binding]['operations'][$operation]['output'], $this->portTypes[ $bindingData['portType'] ][$operation]['output']) :
04722                                                 $this->portTypes[ $bindingData['portType'] ][$operation]['output'];
04723                     if(isset($this->messages[ $this->bindings[$binding]['operations'][$operation]['input']['message'] ])){
04724                                                 $this->bindings[$binding]['operations'][$operation]['input']['parts'] = $this->messages[ $this->bindings[$binding]['operations'][$operation]['input']['message'] ];
04725                                         }
04726                                         if(isset($this->messages[ $this->bindings[$binding]['operations'][$operation]['output']['message'] ])){
04727                                 $this->bindings[$binding]['operations'][$operation]['output']['parts'] = $this->messages[ $this->bindings[$binding]['operations'][$operation]['output']['message'] ];
04728                     }
04729                     // Set operation style if necessary, but do not override one already provided
04730                                         if (isset($bindingData['style']) && !isset($this->bindings[$binding]['operations'][$operation]['style'])) {
04731                         $this->bindings[$binding]['operations'][$operation]['style'] = $bindingData['style'];
04732                     }
04733                     $this->bindings[$binding]['operations'][$operation]['transport'] = isset($bindingData['transport']) ? $bindingData['transport'] : '';
04734                     $this->bindings[$binding]['operations'][$operation]['documentation'] = isset($this->portTypes[ $bindingData['portType'] ][$operation]['documentation']) ? $this->portTypes[ $bindingData['portType'] ][$operation]['documentation'] : '';
04735                     $this->bindings[$binding]['operations'][$operation]['endpoint'] = isset($bindingData['endpoint']) ? $bindingData['endpoint'] : '';
04736                 } 
04737             } 
04738         }
04739         }
04740 
04747     function parseWSDL($wsdl = '') {
04748                 $this->debug("parse WSDL at path=$wsdl");
04749 
04750         if ($wsdl == '') {
04751             $this->debug('no wsdl passed to parseWSDL()!!');
04752             $this->setError('no wsdl passed to parseWSDL()!!');
04753             return false;
04754         }
04755         
04756         // parse $wsdl for url format
04757         $wsdl_props = parse_url($wsdl);
04758 
04759         if (isset($wsdl_props['scheme']) && ($wsdl_props['scheme'] == 'http' || $wsdl_props['scheme'] == 'https')) {
04760             $this->debug('getting WSDL http(s) URL ' . $wsdl);
04761                 // get wsdl
04762                 $tr = new soap_transport_http($wsdl, $this->curl_options, $this->use_curl);
04763                         $tr->request_method = 'GET';
04764                         $tr->useSOAPAction = false;
04765                         if($this->proxyhost && $this->proxyport){
04766                                 $tr->setProxy($this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword);
04767                         }
04768                         if ($this->authtype != '') {
04769                                 $tr->setCredentials($this->username, $this->password, $this->authtype, array(), $this->certRequest);
04770                         }
04771                         $tr->setEncoding('gzip, deflate');
04772                         $wsdl_string = $tr->send('', $this->timeout, $this->response_timeout);
04773                         //$this->debug("WSDL request\n" . $tr->outgoing_payload);
04774                         //$this->debug("WSDL response\n" . $tr->incoming_payload);
04775                         $this->appendDebug($tr->getDebug());
04776                         // catch errors
04777                         if($err = $tr->getError() ){
04778                                 $errstr = 'Getting ' . $wsdl . ' - HTTP ERROR: '.$err;
04779                                 $this->debug($errstr);
04780                     $this->setError($errstr);
04781                                 unset($tr);
04782                     return false;
04783                         }
04784                         unset($tr);
04785                         $this->debug("got WSDL URL");
04786         } else {
04787             // $wsdl is not http(s), so treat it as a file URL or plain file path
04788                 if (isset($wsdl_props['scheme']) && ($wsdl_props['scheme'] == 'file') && isset($wsdl_props['path'])) {
04789                         $path = isset($wsdl_props['host']) ? ($wsdl_props['host'] . ':' . $wsdl_props['path']) : $wsdl_props['path'];
04790                 } else {
04791                         $path = $wsdl;
04792                 }
04793             $this->debug('getting WSDL file ' . $path);
04794             if ($fp = @fopen($path, 'r')) {
04795                 $wsdl_string = '';
04796                 while ($data = fread($fp, 32768)) {
04797                     $wsdl_string .= $data;
04798                 } 
04799                 fclose($fp);
04800             } else {
04801                 $errstr = "Bad path to WSDL file $path";
04802                 $this->debug($errstr);
04803                 $this->setError($errstr);
04804                 return false;
04805             } 
04806         }
04807         $this->debug('Parse WSDL');
04808         // end new code added
04809         // Create an XML parser.
04810         $this->parser = xml_parser_create(); 
04811         // Set the options for parsing the XML data.
04812         // xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
04813         xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0); 
04814         // Set the object for the parser.
04815         xml_set_object($this->parser, $this); 
04816         // Set the element handlers for the parser.
04817         xml_set_element_handler($this->parser, 'start_element', 'end_element');
04818         xml_set_character_data_handler($this->parser, 'character_data');
04819         // Parse the XML file.
04820         if (!xml_parse($this->parser, $wsdl_string, true)) {
04821             // Display an error message.
04822             $errstr = sprintf(
04823                                 'XML error parsing WSDL from %s on line %d: %s',
04824                                 $wsdl,
04825                 xml_get_current_line_number($this->parser),
04826                 xml_error_string(xml_get_error_code($this->parser))
04827                 );
04828             $this->debug($errstr);
04829                         $this->debug("XML payload:\n" . $wsdl_string);
04830             $this->setError($errstr);
04831             return false;
04832         } 
04833                 // free the parser
04834         xml_parser_free($this->parser);
04835         $this->debug('Parsing WSDL done');
04836                 // catch wsdl parse errors
04837                 if($this->getError()){
04838                         return false;
04839                 }
04840         return true;
04841     } 
04842 
04851     function start_element($parser, $name, $attrs)
04852     {
04853         if ($this->status == 'schema') {
04854             $this->currentSchema->schemaStartElement($parser, $name, $attrs);
04855             $this->appendDebug($this->currentSchema->getDebug());
04856             $this->currentSchema->clearDebug();
04857         } elseif (ereg('schema$', $name)) {
04858                 $this->debug('Parsing WSDL schema');
04859             // $this->debug("startElement for $name ($attrs[name]). status = $this->status (".$this->getLocalPart($name).")");
04860             $this->status = 'schema';
04861             $this->currentSchema = new nusoap_xmlschema('', '', $this->namespaces);
04862             $this->currentSchema->schemaStartElement($parser, $name, $attrs);
04863             $this->appendDebug($this->currentSchema->getDebug());
04864             $this->currentSchema->clearDebug();
04865         } else {
04866             // position in the total number of elements, starting from 0
04867             $pos = $this->position++;
04868             $depth = $this->depth++; 
04869             // set self as current value for this depth
04870             $this->depth_array[$depth] = $pos;
04871             $this->message[$pos] = array('cdata' => ''); 
04872             // process attributes
04873             if (count($attrs) > 0) {
04874                                 // register namespace declarations
04875                 foreach($attrs as $k => $v) {
04876                     if (ereg("^xmlns", $k)) {
04877                         if ($ns_prefix = substr(strrchr($k, ':'), 1)) {
04878                             $this->namespaces[$ns_prefix] = $v;
04879                         } else {
04880                             $this->namespaces['ns' . (count($this->namespaces) + 1)] = $v;
04881                         } 
04882                         if ($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema') {
04883                             $this->XMLSchemaVersion = $v;
04884                             $this->namespaces['xsi'] = $v . '-instance';
04885                         } 
04886                     }
04887                 }
04888                 // expand each attribute prefix to its namespace
04889                 foreach($attrs as $k => $v) {
04890                     $k = strpos($k, ':') ? $this->expandQname($k) : $k;
04891                     if ($k != 'location' && $k != 'soapAction' && $k != 'namespace') {
04892                         $v = strpos($v, ':') ? $this->expandQname($v) : $v;
04893                     } 
04894                     $eAttrs[$k] = $v;
04895                 } 
04896                 $attrs = $eAttrs;
04897             } else {
04898                 $attrs = array();
04899             } 
04900             // get element prefix, namespace and name
04901             if (ereg(':', $name)) {
04902                 // get ns prefix
04903                 $prefix = substr($name, 0, strpos($name, ':')); 
04904                 // get ns
04905                 $namespace = isset($this->namespaces[$prefix]) ? $this->namespaces[$prefix] : ''; 
04906                 // get unqualified name
04907                 $name = substr(strstr($name, ':'), 1);
04908             } 
04909                         // process attributes, expanding any prefixes to namespaces
04910             // find status, register data
04911             switch ($this->status) {
04912                 case 'message':
04913                     if ($name == 'part') {
04914                                     if (isset($attrs['type'])) {
04915                                     $this->debug("msg " . $this->currentMessage . ": found part (with type) $attrs[name]: " . implode(',', $attrs));
04916                                     $this->messages[$this->currentMessage][$attrs['name']] = $attrs['type'];
04917                                 } 
04918                                     if (isset($attrs['element'])) {
04919                                     $this->debug("msg " . $this->currentMessage . ": found part (with element) $attrs[name]: " . implode(',', $attrs));
04920                                         $this->messages[$this->currentMessage][$attrs['name']] = $attrs['element'] . '^';
04921                                     } 
04922                                 } 
04923                                 break;
04924                             case 'portType':
04925                                 switch ($name) {
04926                                     case 'operation':
04927                                         $this->currentPortOperation = $attrs['name'];
04928                                         $this->debug("portType $this->currentPortType operation: $this->currentPortOperation");
04929                                         if (isset($attrs['parameterOrder'])) {
04930                                                 $this->portTypes[$this->currentPortType][$attrs['name']]['parameterOrder'] = $attrs['parameterOrder'];
04931                                                 } 
04932                                                 break;
04933                                             case 'documentation':
04934                                                 $this->documentation = true;
04935                                                 break; 
04936                                             // merge input/output data
04937                                             default:
04938                                                 $m = isset($attrs['message']) ? $this->getLocalPart($attrs['message']) : '';
04939                                                 $this->portTypes[$this->currentPortType][$this->currentPortOperation][$name]['message'] = $m;
04940                                                 break;
04941                                         } 
04942                                 break;
04943                                 case 'binding':
04944                                     switch ($name) {
04945                                         case 'binding': 
04946                                             // get ns prefix
04947                                             if (isset($attrs['style'])) {
04948                                             $this->bindings[$this->currentBinding]['prefix'] = $prefix;
04949                                                 } 
04950                                                 $this->bindings[$this->currentBinding] = array_merge($this->bindings[$this->currentBinding], $attrs);
04951                                                 break;
04952                                                 case 'header':
04953                                                     $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus]['headers'][] = $attrs;
04954                                                     break;
04955                                                 case 'operation':
04956                                                     if (isset($attrs['soapAction'])) {
04957                                                         $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['soapAction'] = $attrs['soapAction'];
04958                                                     } 
04959                                                     if (isset($attrs['style'])) {
04960                                                         $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['style'] = $attrs['style'];
04961                                                     } 
04962                                                     if (isset($attrs['name'])) {
04963                                                         $this->currentOperation = $attrs['name'];
04964                                                         $this->debug("current binding operation: $this->currentOperation");
04965                                                         $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['name'] = $attrs['name'];
04966                                                         $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['binding'] = $this->currentBinding;
04967                                                         $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['endpoint'] = isset($this->bindings[$this->currentBinding]['endpoint']) ? $this->bindings[$this->currentBinding]['endpoint'] : '';
04968                                                     } 
04969                                                     break;
04970                                                 case 'input':
04971                                                     $this->opStatus = 'input';
04972                                                     break;
04973                                                 case 'output':
04974                                                     $this->opStatus = 'output';
04975                                                     break;
04976                                                 case 'body':
04977                                                     if (isset($this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus])) {
04978                                                         $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus] = array_merge($this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus], $attrs);
04979                                                     } else {
04980                                                         $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus] = $attrs;
04981                                                     } 
04982                                                     break;
04983                                         } 
04984                                         break;
04985                                 case 'service':
04986                                         switch ($name) {
04987                                             case 'port':
04988                                                 $this->currentPort = $attrs['name'];
04989                                                 $this->debug('current port: ' . $this->currentPort);
04990                                                 $this->ports[$this->currentPort]['binding'] = $this->getLocalPart($attrs['binding']);
04991                                         
04992                                                 break;
04993                                             case 'address':
04994                                                 $this->ports[$this->currentPort]['location'] = $attrs['location'];
04995                                                 $this->ports[$this->currentPort]['bindingType'] = $namespace;
04996                                                 $this->bindings[ $this->ports[$this->currentPort]['binding'] ]['bindingType'] = $namespace;
04997                                                 $this->bindings[ $this->ports[$this->currentPort]['binding'] ]['endpoint'] = $attrs['location'];
04998                                                 break;
04999                                         } 
05000                                         break;
05001                         } 
05002                 // set status
05003                 switch ($name) {
05004                         case 'import':
05005                             if (isset($attrs['location'])) {
05006                     $this->import[$attrs['namespace']][] = array('location' => $attrs['location'], 'loaded' => false);
05007                     $this->debug('parsing import ' . $attrs['namespace']. ' - ' . $attrs['location'] . ' (' . count($this->import[$attrs['namespace']]).')');
05008                                 } else {
05009                     $this->import[$attrs['namespace']][] = array('location' => '', 'loaded' => true);
05010                                         if (! $this->getPrefixFromNamespace($attrs['namespace'])) {
05011                                                 $this->namespaces['ns'.(count($this->namespaces)+1)] = $attrs['namespace'];
05012                                         }
05013                     $this->debug('parsing import ' . $attrs['namespace']. ' - [no location] (' . count($this->import[$attrs['namespace']]).')');
05014                                 }
05015                                 break;
05016                         //wait for schema
05017                         //case 'types':
05018                         //      $this->status = 'schema';
05019                         //      break;
05020                         case 'message':
05021                                 $this->status = 'message';
05022                                 $this->messages[$attrs['name']] = array();
05023                                 $this->currentMessage = $attrs['name'];
05024                                 break;
05025                         case 'portType':
05026                                 $this->status = 'portType';
05027                                 $this->portTypes[$attrs['name']] = array();
05028                                 $this->currentPortType = $attrs['name'];
05029                                 break;
05030                         case "binding":
05031                                 if (isset($attrs['name'])) {
05032                                 // get binding name
05033                                         if (strpos($attrs['name'], ':')) {
05034                                         $this->currentBinding = $this->getLocalPart($attrs['name']);
05035                                         } else {
05036                                         $this->currentBinding = $attrs['name'];
05037                                         } 
05038                                         $this->status = 'binding';
05039                                         $this->bindings[$this->currentBinding]['portType'] = $this->getLocalPart($attrs['type']);
05040                                         $this->debug("current binding: $this->currentBinding of portType: " . $attrs['type']);
05041                                 } 
05042                                 break;
05043                         case 'service':
05044                                 $this->serviceName = $attrs['name'];
05045                                 $this->status = 'service';
05046                                 $this->debug('current service: ' . $this->serviceName);
05047                                 break;
05048                         case 'definitions':
05049                                 foreach ($attrs as $name => $value) {
05050                                         $this->wsdl_info[$name] = $value;
05051                                 } 
05052                                 break;
05053                         } 
05054                 } 
05055         } 
05056 
05064         function end_element($parser, $name){ 
05065                 // unset schema status
05066                 if (/*ereg('types$', $name) ||*/ ereg('schema$', $name)) {
05067                         $this->status = "";
05068             $this->appendDebug($this->currentSchema->getDebug());
05069             $this->currentSchema->clearDebug();
05070                         $this->schemas[$this->currentSchema->schemaTargetNamespace][] = $this->currentSchema;
05071                 $this->debug('Parsing WSDL schema done');
05072                 } 
05073                 if ($this->status == 'schema') {
05074                         $this->currentSchema->schemaEndElement($parser, $name);
05075                 } else {
05076                         // bring depth down a notch
05077                         $this->depth--;
05078                 } 
05079                 // end documentation
05080                 if ($this->documentation) {
05081                         //TODO: track the node to which documentation should be assigned; it can be a part, message, etc.
05082                         //$this->portTypes[$this->currentPortType][$this->currentPortOperation]['documentation'] = $this->documentation;
05083                         $this->documentation = false;
05084                 } 
05085         } 
05086 
05094         function character_data($parser, $data)
05095         {
05096                 $pos = isset($this->depth_array[$this->depth]) ? $this->depth_array[$this->depth] : 0;
05097                 if (isset($this->message[$pos]['cdata'])) {
05098                         $this->message[$pos]['cdata'] .= $data;
05099                 } 
05100                 if ($this->documentation) {
05101                         $this->documentation .= $data;
05102                 } 
05103         } 
05104 
05114         function setCredentials($username, $password, $authtype = 'basic', $certRequest = array()) {
05115                 $this->debug("setCredentials username=$username authtype=$authtype certRequest=");
05116                 $this->appendDebug($this->varDump($certRequest));
05117                 $this->username = $username;
05118                 $this->password = $password;
05119                 $this->authtype = $authtype;
05120                 $this->certRequest = $certRequest;
05121         }
05122         
05123         function getBindingData($binding)
05124         {
05125                 if (is_array($this->bindings[$binding])) {
05126                         return $this->bindings[$binding];
05127                 } 
05128         }
05129         
05138         function getOperations($portName = '', $bindingType = 'soap') {
05139                 $ops = array();
05140                 if ($bindingType == 'soap') {
05141                         $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/';
05142                 } elseif ($bindingType == 'soap12') {
05143                         $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap12/';
05144                 } else {
05145                         $this->debug("getOperations bindingType $bindingType may not be supported");
05146                 }
05147                 $this->debug("getOperations for port '$portName' bindingType $bindingType");
05148                 // loop thru ports
05149                 foreach($this->ports as $port => $portData) {
05150                         $this->debug("getOperations checking port $port bindingType " . $portData['bindingType']);
05151                         if ($portName == '' || $port == $portName) {
05152                                 // binding type of port matches parameter
05153                                 if ($portData['bindingType'] == $bindingType) {
05154                                         $this->debug("getOperations found port $port bindingType $bindingType");
05155                                         //$this->debug("port data: " . $this->varDump($portData));
05156                                         //$this->debug("bindings: " . $this->varDump($this->bindings[ $portData['binding'] ]));
05157                                         // merge bindings
05158                                         if (isset($this->bindings[ $portData['binding'] ]['operations'])) {
05159                                                 $ops = array_merge ($ops, $this->bindings[ $portData['binding'] ]['operations']);
05160                                         }
05161                                 }
05162                         }
05163                 }
05164                 if (count($ops) == 0) {
05165                         $this->debug("getOperations found no operations for port '$portName' bindingType $bindingType");
05166                 }
05167                 return $ops;
05168         } 
05169         
05178         function getOperationData($operation, $bindingType = 'soap')
05179         {
05180                 if ($bindingType == 'soap') {
05181                         $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/';
05182                 } elseif ($bindingType == 'soap12') {
05183                         $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap12/';
05184                 }
05185                 // loop thru ports
05186                 foreach($this->ports as $port => $portData) {
05187                         // binding type of port matches parameter
05188                         if ($portData['bindingType'] == $bindingType) {
05189                                 // get binding
05190                                 //foreach($this->bindings[ $portData['binding'] ]['operations'] as $bOperation => $opData) {
05191                                 foreach(array_keys($this->bindings[ $portData['binding'] ]['operations']) as $bOperation) {
05192                                         // note that we could/should also check the namespace here
05193                                         if ($operation == $bOperation) {
05194                                                 $opData = $this->bindings[ $portData['binding'] ]['operations'][$operation];
05195                                             return $opData;
05196                                         } 
05197                                 } 
05198                         }
05199                 } 
05200         }
05201         
05210         function getOperationDataForSoapAction($soapAction, $bindingType = 'soap') {
05211                 if ($bindingType == 'soap') {
05212                         $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/';
05213                 } elseif ($bindingType == 'soap12') {
05214                         $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap12/';
05215                 }
05216                 // loop thru ports
05217                 foreach($this->ports as $port => $portData) {
05218                         // binding type of port matches parameter
05219                         if ($portData['bindingType'] == $bindingType) {
05220                                 // loop through operations for the binding
05221                                 foreach ($this->bindings[ $portData['binding'] ]['operations'] as $bOperation => $opData) {
05222                                         if ($opData['soapAction'] == $soapAction) {
05223                                             return $opData;
05224                                         } 
05225                                 } 
05226                         }
05227                 } 
05228         }
05229         
05248         function getTypeDef($type, $ns) {
05249                 $this->debug("in getTypeDef: type=$type, ns=$ns");
05250                 if ((! $ns) && isset($this->namespaces['tns'])) {
05251                         $ns = $this->namespaces['tns'];
05252                         $this->debug("in getTypeDef: type namespace forced to $ns");
05253                 }
05254                 if (!isset($this->schemas[$ns])) {
05255                         foreach ($this->schemas as $ns0 => $schema0) {
05256                                 if (strcasecmp($ns, $ns0) == 0) {
05257                                         $this->debug("in getTypeDef: replacing schema namespace $ns with $ns0");
05258                                         $ns = $ns0;
05259                                         break;
05260                                 }
05261                         }
05262                 }
05263                 if (isset($this->schemas[$ns])) {
05264                         $this->debug("in getTypeDef: have schema for namespace $ns");
05265                         for ($i = 0; $i < count($this->schemas[$ns]); $i++) {
05266                                 $xs = &$this->schemas[$ns][$i];
05267                                 $t = $xs->getTypeDef($type);
05268                                 $this->appendDebug($xs->getDebug());
05269                                 $xs->clearDebug();
05270                                 if ($t) {
05271                                         $this->debug("in getTypeDef: found type $type");
05272                                         if (!isset($t['phpType'])) {
05273                                                 // get info for type to tack onto the element
05274                                                 $uqType = substr($t['type'], strrpos($t['type'], ':') + 1);
05275                                                 $ns = substr($t['type'], 0, strrpos($t['type'], ':'));
05276                                                 $etype = $this->getTypeDef($uqType, $ns);
05277                                                 if ($etype) {
05278                                                         $this->debug("found type for [element] $type:");
05279                                                         $this->debug($this->varDump($etype));
05280                                                         if (isset($etype['phpType'])) {
05281                                                                 $t['phpType'] = $etype['phpType'];
05282                                                         }
05283                                                         if (isset($etype['elements'])) {
05284                                                                 $t['elements'] = $etype['elements'];
05285                                                         }
05286                                                         if (isset($etype['attrs'])) {
05287                                                                 $t['attrs'] = $etype['attrs'];
05288                                                         }
05289                                                 } else {
05290                                                         $this->debug("did not find type for [element] $type");
05291                                                 }
05292                                         }
05293                                         return $t;
05294                                 }
05295                         }
05296                         $this->debug("in getTypeDef: did not find type $type");
05297                 } else {
05298                         $this->debug("in getTypeDef: do not have schema for namespace $ns");
05299                 }
05300                 return false;
05301         }
05302 
05308     function webDescription(){
05309         global $HTTP_SERVER_VARS;
05310 
05311                 if (isset($_SERVER)) {
05312                         $PHP_SELF = $_SERVER['PHP_SELF'];
05313                 } elseif (isset($HTTP_SERVER_VARS)) {
05314                         $PHP_SELF = $HTTP_SERVER_VARS['PHP_SELF'];
05315                 } else {
05316                         $this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available");
05317                 }
05318 
05319                 $b = '
05320                 <html><head><title>NuSOAP: '.$this->serviceName.'</title>
05321                 <style type="text/css">
05322                     body    { font-family: arial; color: #000000; background-color: #ffffff; margin: 0px 0px 0px 0px; }
05323                     p       { font-family: arial; color: #000000; margin-top: 0px; margin-bottom: 12px; }
05324                     pre { background-color: silver; padding: 5px; font-family: Courier New; font-size: x-small; color: #000000;}
05325                     ul      { margin-top: 10px; margin-left: 20px; }
05326                     li      { list-style-type: none; margin-top: 10px; color: #000000; }
05327                     .content{
05328                         margin-left: 0px; padding-bottom: 2em; }
05329                     .nav {
05330                         padding-top: 10px; padding-bottom: 10px; padding-left: 15px; font-size: .70em;
05331                         margin-top: 10px; margin-left: 0px; color: #000000;
05332                         background-color: #ccccff; width: 20%; margin-left: 20px; margin-top: 20px; }
05333                     .title {
05334                         font-family: arial; font-size: 26px; color: #ffffff;
05335                         background-color: #999999; width: 100%;
05336                         margin-left: 0px; margin-right: 0px;
05337                         padding-top: 10px; padding-bottom: 10px;}
05338                     .hidden {
05339                         position: absolute; visibility: hidden; z-index: 200; left: 250px; top: 100px;
05340                         font-family: arial; overflow: hidden; width: 600;
05341                         padding: 20px; font-size: 10px; background-color: #999999;
05342                         layer-background-color:#FFFFFF; }
05343                     a,a:active  { color: charcoal; font-weight: bold; }
05344                     a:visited   { color: #666666; font-weight: bold; }
05345                     a:hover     { color: cc3300; font-weight: bold; }
05346                 </style>
05347                 <script language="JavaScript" type="text/javascript">
05348                 <!--
05349                 // POP-UP CAPTIONS...
05350                 function lib_bwcheck(){ //Browsercheck (needed)
05351                     this.ver=navigator.appVersion
05352                     this.agent=navigator.userAgent
05353                     this.dom=document.getElementById?1:0
05354                     this.opera5=this.agent.indexOf("Opera 5")>-1
05355                     this.ie5=(this.ver.indexOf("MSIE 5")>-1 && this.dom && !this.opera5)?1:0;
05356                     this.ie6=(this.ver.indexOf("MSIE 6")>-1 && this.dom && !this.opera5)?1:0;
05357                     this.ie4=(document.all && !this.dom && !this.opera5)?1:0;
05358                     this.ie=this.ie4||this.ie5||this.ie6
05359                     this.mac=this.agent.indexOf("Mac")>-1
05360                     this.ns6=(this.dom && parseInt(this.ver) >= 5) ?1:0;
05361                     this.ns4=(document.layers && !this.dom)?1:0;
05362                     this.bw=(this.ie6 || this.ie5 || this.ie4 || this.ns4 || this.ns6 || this.opera5)
05363                     return this
05364                 }
05365                 var bw = new lib_bwcheck()
05366                 //Makes crossbrowser object.
05367                 function makeObj(obj){
05368                     this.evnt=bw.dom? document.getElementById(obj):bw.ie4?document.all[obj]:bw.ns4?document.layers[obj]:0;
05369                     if(!this.evnt) return false
05370                     this.css=bw.dom||bw.ie4?this.evnt.style:bw.ns4?this.evnt:0;
05371                     this.wref=bw.dom||bw.ie4?this.evnt:bw.ns4?this.css.document:0;
05372                     this.writeIt=b_writeIt;
05373                     return this
05374                 }
05375                 // A unit of measure that will be added when setting the position of a layer.
05376                 //var px = bw.ns4||window.opera?"":"px";
05377                 function b_writeIt(text){
05378                     if (bw.ns4){this.wref.write(text);this.wref.close()}
05379                     else this.wref.innerHTML = text
05380                 }
05381                 //Shows the messages
05382                 var oDesc;
05383                 function popup(divid){
05384                     if(oDesc = new makeObj(divid)){
05385                         oDesc.css.visibility = "visible"
05386                     }
05387                 }
05388                 function popout(){ // Hides message
05389                     if(oDesc) oDesc.css.visibility = "hidden"
05390                 }
05391                 //-->
05392                 </script>
05393                 </head>
05394                 <body>
05395                 <div class=content>
05396                         <br><br>
05397                         <div class=title>'.$this->serviceName.'</div>
05398                         <div class=nav>
05399                                 <p>View the <a href="'.$PHP_SELF.'?wsdl">WSDL</a> for the service.
05400                                 Click on an operation name to view it&apos;s details.</p>
05401                                 <ul>';
05402                                 foreach($this->getOperations() as $op => $data){
05403                                     $b .= "<li><a href='#' onclick=\"popout();popup('$op')\">$op</a></li>";
05404                                     // create hidden div
05405                                     $b .= "<div id='$op' class='hidden'>
05406                                     <a href='#' onclick='popout()'><font color='#ffffff'>Close</font></a><br><br>";
05407                                     foreach($data as $donnie => $marie){ // loop through opdata
05408                                                 if($donnie == 'input' || $donnie == 'output'){ // show input/output data
05409                                                     $b .= "<font color='white'>".ucfirst($donnie).':</font><br>';
05410                                                     foreach($marie as $captain => $tenille){ // loop through data
05411                                                                 if($captain == 'parts'){ // loop thru parts
05412                                                                     $b .= "&nbsp;&nbsp;$captain:<br>";
05413                                                         //if(is_array($tenille)){
05414                                                                         foreach($tenille as $joanie => $chachi){
05415                                                                                         $b .= "&nbsp;&nbsp;&nbsp;&nbsp;$joanie: $chachi<br>";
05416                                                                         }
05417                                                                 //}
05418                                                                 } else {
05419                                                                     $b .= "&nbsp;&nbsp;$captain: $tenille<br>";
05420                                                                 }
05421                                                     }
05422                                                 } else {
05423                                                     $b .= "<font color='white'>".ucfirst($donnie).":</font> $marie<br>";
05424                                                 }
05425                                     }
05426                                         $b .= '</div>';
05427                                 }
05428                                 $b .= '
05429                                 <ul>
05430                         </div>
05431                 </div></body></html>';
05432                 return $b;
05433     }
05434 
05442         function serialize($debug = 0)
05443         {
05444                 $xml = '<?xml version="1.0" encoding="ISO-8859-1"?>';
05445                 $xml .= "\n<definitions";
05446                 foreach($this->namespaces as $k => $v) {
05447                         $xml .= " xmlns:$k=\"$v\"";
05448                 } 
05449                 // 10.9.02 - add poulter fix for wsdl and tns declarations
05450                 if (isset($this->namespaces['wsdl'])) {
05451                         $xml .= " xmlns=\"" . $this->namespaces['wsdl'] . "\"";
05452                 } 
05453                 if (isset($this->namespaces['tns'])) {
05454                         $xml .= " targetNamespace=\"" . $this->namespaces['tns'] . "\"";
05455                 } 
05456                 $xml .= '>'; 
05457                 // imports
05458                 if (sizeof($this->import) > 0) {
05459                         foreach($this->import as $ns => $list) {
05460                                 foreach ($list as $ii) {
05461                                         if ($ii['location'] != '') {
05462                                                 $xml .= '<import location="' . $ii['location'] . '" namespace="' . $ns . '" />';
05463                                         } else {
05464                                                 $xml .= '<import namespace="' . $ns . '" />';
05465                                         }
05466                                 }
05467                         } 
05468                 } 
05469                 // types
05470                 if (count($this->schemas)>=1) {
05471                         $xml .= "\n<types>\n";
05472                         foreach ($this->schemas as $ns => $list) {
05473                                 foreach ($list as $xs) {
05474                                         $xml .= $xs->serializeSchema();
05475                                 }
05476                         }
05477                         $xml .= '</types>';
05478                 } 
05479                 // messages
05480                 if (count($this->messages) >= 1) {
05481                         foreach($this->messages as $msgName => $msgParts) {
05482                                 $xml .= "\n<message name=\"" . $msgName . '">';
05483                                 if(is_array($msgParts)){
05484                                         foreach($msgParts as $partName => $partType) {
05485                                                 // print 'serializing '.$partType.', sv: '.$this->XMLSchemaVersion.'<br>';
05486                                                 if (strpos($partType, ':')) {
05487                                                     $typePrefix = $this->getPrefixFromNamespace($this->getPrefix($partType));
05488                                                 } elseif (isset($this->typemap[$this->namespaces['xsd']][$partType])) {
05489                                                     // print 'checking typemap: '.$this->XMLSchemaVersion.'<br>';
05490                                                     $typePrefix = 'xsd';
05491                                                 } else {
05492                                                     foreach($this->typemap as $ns => $types) {
05493                                                         if (isset($types[$partType])) {
05494                                                             $typePrefix = $this->getPrefixFromNamespace($ns);
05495                                                         } 
05496                                                     } 
05497                                                     if (!isset($typePrefix)) {
05498                                                         die("$partType has no namespace!");
05499                                                     } 
05500                                                 }
05501                                                 $ns = $this->getNamespaceFromPrefix($typePrefix);
05502                                                 $localPart = $this->getLocalPart($partType);
05503                                                 $typeDef = $this->getTypeDef($localPart, $ns);
05504                                                 if ($typeDef['typeClass'] == 'element') {
05505                                                         $elementortype = 'element';
05506                                                         if (substr($localPart, -1) == '^') {
05507                                                                 $localPart = substr($localPart, 0, -1);
05508                                                         }
05509                                                 } else {
05510                                                         $elementortype = 'type';
05511                                                 }
05512                                                 $xml .= "\n" . '  <part name="' . $partName . '" ' . $elementortype . '="' . $typePrefix . ':' . $localPart . '" />';
05513                                         }
05514                                 }
05515                                 $xml .= '</message>';
05516                         } 
05517                 } 
05518                 // bindings & porttypes
05519                 if (count($this->bindings) >= 1) {
05520                         $binding_xml = '';
05521                         $portType_xml = '';
05522                         foreach($this->bindings as $bindingName => $attrs) {
05523                                 $binding_xml .= "\n<binding name=\"" . $bindingName . '" type="tns:' . $attrs['portType'] . '">';
05524                                 $binding_xml .= "\n" . '  <soap:binding style="' . $attrs['style'] . '" transport="' . $attrs['transport'] . '"/>';
05525                                 $portType_xml .= "\n<portType name=\"" . $attrs['portType'] . '">';
05526                                 foreach($attrs['operations'] as $opName => $opParts) {
05527                                         $binding_xml .= "\n" . '  <operation name="' . $opName . '">';
05528                                         $binding_xml .= "\n" . '    <soap:operation soapAction="' . $opParts['soapAction'] . '" style="'. $opParts['style'] . '"/>';
05529                                         if (isset($opParts['input']['encodingStyle']) && $opParts['input']['encodingStyle'] != '') {
05530                                                 $enc_style = ' encodingStyle="' . $opParts['input']['encodingStyle'] . '"';
05531                                         } else {
05532                                                 $enc_style = '';
05533                                         }
05534                                         $binding_xml .= "\n" . '    <input><soap:body use="' . $opParts['input']['use'] . '" namespace="' . $opParts['input']['namespace'] . '"' . $enc_style . '/></input>';
05535                                         if (isset($opParts['output']['encodingStyle']) && $opParts['output']['encodingStyle'] != '') {
05536                                                 $enc_style = ' encodingStyle="' . $opParts['output']['encodingStyle'] . '"';
05537                                         } else {
05538                                                 $enc_style = '';
05539                                         }
05540                                         $binding_xml .= "\n" . '    <output><soap:body use="' . $opParts['output']['use'] . '" namespace="' . $opParts['output']['namespace'] . '"' . $enc_style . '/></output>';
05541                                         $binding_xml .= "\n" . '  </operation>';
05542                                         $portType_xml .= "\n" . '  <operation name="' . $opParts['name'] . '"';
05543                                         if (isset($opParts['parameterOrder'])) {
05544                                             $portType_xml .= ' parameterOrder="' . $opParts['parameterOrder'] . '"';
05545                                         } 
05546                                         $portType_xml .= '>';
05547                                         if(isset($opParts['documentation']) && $opParts['documentation'] != '') {
05548                                                 $portType_xml .= "\n" . '    <documentation>' . htmlspecialchars($opParts['documentation']) . '</documentation>';
05549                                         }
05550                                         $portType_xml .= "\n" . '    <input message="tns:' . $opParts['input']['message'] . '"/>';
05551                                         $portType_xml .= "\n" . '    <output message="tns:' . $opParts['output']['message'] . '"/>';
05552                                         $portType_xml .= "\n" . '  </operation>';
05553                                 } 
05554                                 $portType_xml .= "\n" . '</portType>';
05555                                 $binding_xml .= "\n" . '</binding>';
05556                         } 
05557                         $xml .= $portType_xml . $binding_xml;
05558                 } 
05559                 // services
05560                 $xml .= "\n<service name=\"" . $this->serviceName . '">';
05561                 if (count($this->ports) >= 1) {
05562                         foreach($this->ports as $pName => $attrs) {
05563                                 $xml .= "\n" . '  <port name="' . $pName . '" binding="tns:' . $attrs['binding'] . '">';
05564                                 $xml .= "\n" . '    <soap:address location="' . $attrs['location'] . ($debug ? '?debug=1' : '') . '"/>';
05565                                 $xml .= "\n" . '  </port>';
05566                         } 
05567                 } 
05568                 $xml .= "\n" . '</service>';
05569                 return $xml . "\n</definitions>";
05570         } 
05571 
05581         function parametersMatchWrapped($type, &$parameters) {
05582                 $this->debug("in parametersMatchWrapped type=$type, parameters=");
05583                 $this->appendDebug($this->varDump($parameters));
05584 
05585                 // split type into namespace:unqualified-type
05586                 if (strpos($type, ':')) {
05587                         $uqType = substr($type, strrpos($type, ':') + 1);
05588                         $ns = substr($type, 0, strrpos($type, ':'));
05589                         $this->debug("in parametersMatchWrapped: got a prefixed type: $uqType, $ns");
05590                         if ($this->getNamespaceFromPrefix($ns)) {
05591                                 $ns = $this->getNamespaceFromPrefix($ns);
05592                                 $this->debug("in parametersMatchWrapped: expanded prefixed type: $uqType, $ns");
05593                         }
05594                 } else {
05595                         // TODO: should the type be compared to types in XSD, and the namespace
05596                         // set to XSD if the type matches?
05597                         $this->debug("in parametersMatchWrapped: No namespace for type $type");
05598                         $ns = '';
05599                         $uqType = $type;
05600                 }
05601 
05602                 // get the type information
05603                 if (!$typeDef = $this->getTypeDef($uqType, $ns)) {
05604                         $this->debug("in parametersMatchWrapped: $type ($uqType) is not a supported type.");
05605                         return false;
05606                 }
05607                 $this->debug("in parametersMatchWrapped: found typeDef=");
05608                 $this->appendDebug($this->varDump($typeDef));
05609                 if (substr($uqType, -1) == '^') {
05610                         $uqType = substr($uqType, 0, -1);
05611                 }
05612                 $phpType = $typeDef['phpType'];
05613                 $arrayType = (isset($typeDef['arrayType']) ? $typeDef['arrayType'] : '');
05614                 $this->debug("in parametersMatchWrapped: uqType: $uqType, ns: $ns, phptype: $phpType, arrayType: $arrayType");
05615                 
05616                 // we expect a complexType or element of complexType
05617                 if ($phpType != 'struct') {
05618                         $this->debug("in parametersMatchWrapped: not a struct");
05619                         return false;
05620                 }
05621 
05622                 // see whether the parameter names match the elements
05623                 if (isset($typeDef['elements']) && is_array($typeDef['elements'])) {
05624                         $elements = 0;
05625                         $matches = 0;
05626                         foreach ($typeDef['elements'] as $name => $attrs) {
05627                                 if (isset($parameters[$name])) {
05628                                         $this->debug("in parametersMatchWrapped: have parameter named $name");
05629                                         $matches++;
05630                                 } else {
05631                                         $this->debug("in parametersMatchWrapped: do not have parameter named $name");
05632                                 }
05633                                 $elements++;
05634                         }
05635 
05636                         $this->debug("in parametersMatchWrapped: $matches parameter names match $elements wrapped parameter names");
05637                         if ($matches == 0) {
05638                                 return false;
05639                         }
05640                         return true;
05641                 }
05642 
05643                 // since there are no elements for the type, if the user passed no
05644                 // parameters, the parameters match wrapped.
05645                 $this->debug("in parametersMatchWrapped: no elements type $ns:$uqType");
05646                 return count($parameters) == 0;
05647         }
05648 
05664         function serializeRPCParameters($operation, $direction, $parameters, $bindingType = 'soap') {
05665                 $this->debug("in serializeRPCParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion, bindingType=$bindingType");
05666                 $this->appendDebug('parameters=' . $this->varDump($parameters));
05667                 
05668                 if ($direction != 'input' && $direction != 'output') {
05669                         $this->debug('The value of the \$direction argument needs to be either "input" or "output"');
05670                         $this->setError('The value of the \$direction argument needs to be either "input" or "output"');
05671                         return false;
05672                 } 
05673                 if (!$opData = $this->getOperationData($operation, $bindingType)) {
05674                         $this->debug('Unable to retrieve WSDL data for operation: ' . $operation . ' bindingType: ' . $bindingType);
05675                         $this->setError('Unable to retrieve WSDL data for operation: ' . $operation . ' bindingType: ' . $bindingType);
05676                         return false;
05677                 }
05678                 $this->debug('in serializeRPCParameters: opData:');
05679                 $this->appendDebug($this->varDump($opData));
05680 
05681                 // Get encoding style for output and set to current
05682                 $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
05683                 if(($direction == 'input') && isset($opData['output']['encodingStyle']) && ($opData['output']['encodingStyle'] != $encodingStyle)) {
05684                         $encodingStyle = $opData['output']['encodingStyle'];
05685                         $enc_style = $encodingStyle;
05686                 }
05687 
05688                 // set input params
05689                 $xml = '';
05690                 if (isset($opData[$direction]['parts']) && sizeof($opData[$direction]['parts']) > 0) {
05691                         $parts = &$opData[$direction]['parts'];
05692                         $part_count = sizeof($parts);
05693                         $style = $opData['style'];
05694                         $use = $opData[$direction]['use'];
05695                         $this->debug("have $part_count part(s) to serialize using $style/$use");
05696                         if (is_array($parameters)) {
05697                                 $parametersArrayType = $this->isArraySimpleOrStruct($parameters);
05698                                 $parameter_count = count($parameters);
05699                                 $this->debug("have $parameter_count parameter(s) provided as $parametersArrayType to serialize");
05700                                 // check for Microsoft-style wrapped parameters
05701                                 if ($style == 'document' && $use == 'literal' && $part_count == 1 && isset($parts['parameters'])) {
05702                                         $this->debug('check whether the caller has wrapped the parameters');
05703                                         if ($direction == 'output' && $parametersArrayType == 'arraySimple' && $parameter_count == 1) {
05704                                                 // TODO: consider checking here for double-wrapping, when
05705                                                 // service function wraps, then NuSOAP wraps again
05706                                                 $this->debug("change simple array to associative with 'parameters' element");
05707                                                 $parameters['parameters'] = $parameters[0];
05708                                                 unset($parameters[0]);
05709                                         }
05710                                         if (($parametersArrayType == 'arrayStruct' || $parameter_count == 0) && !isset($parameters['parameters'])) {
05711                                                 $this->debug('check whether caller\'s parameters match the wrapped ones');
05712                                                 if ($this->parametersMatchWrapped($parts['parameters'], $parameters)) {
05713                                                         $this->debug('wrap the parameters for the caller');
05714                                                         $parameters = array('parameters' => $parameters);
05715                                                         $parameter_count = 1;
05716                                                 }
05717                                         }
05718                                 }
05719                                 foreach ($parts as $name => $type) {
05720                                         $this->debug("serializing part $name of type $type");
05721                                         // Track encoding style
05722                                         if (isset($opData[$direction]['encodingStyle']) && $encodingStyle != $opData[$direction]['encodingStyle']) {
05723                                                 $encodingStyle = $opData[$direction]['encodingStyle'];                  
05724                                                 $enc_style = $encodingStyle;
05725                                         } else {
05726                                                 $enc_style = false;
05727                                         }
05728                                         // NOTE: add error handling here
05729                                         // if serializeType returns false, then catch global error and fault
05730                                         if ($parametersArrayType == 'arraySimple') {
05731                                                 $p = array_shift($parameters);
05732                                                 $this->debug('calling serializeType w/indexed param');
05733                                                 $xml .= $this->serializeType($name, $type, $p, $use, $enc_style);
05734                                         } elseif (isset($parameters[$name])) {
05735                                                 $this->debug('calling serializeType w/named param');
05736                                                 $xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style);
05737                                         } else {
05738                                                 // TODO: only send nillable
05739                                                 $this->debug('calling serializeType w/null param');
05740                                                 $xml .= $this->serializeType($name, $type, null, $use, $enc_style);
05741                                         }
05742                                 }
05743                         } else {
05744                                 $this->debug('no parameters passed.');
05745                         }
05746                 }
05747                 $this->debug("serializeRPCParameters returning: $xml");
05748                 return $xml;
05749         } 
05750         
05765         function serializeParameters($operation, $direction, $parameters)
05766         {
05767                 $this->debug("in serializeParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion"); 
05768                 $this->appendDebug('parameters=' . $this->varDump($parameters));
05769                 
05770                 if ($direction != 'input' && $direction != 'output') {
05771                         $this->debug('The value of the \$direction argument needs to be either "input" or "output"');
05772                         $this->setError('The value of the \$direction argument needs to be either "input" or "output"');
05773                         return false;
05774                 } 
05775                 if (!$opData = $this->getOperationData($operation)) {
05776                         $this->debug('Unable to retrieve WSDL data for operation: ' . $operation);
05777                         $this->setError('Unable to retrieve WSDL data for operation: ' . $operation);
05778                         return false;
05779                 }
05780                 $this->debug('opData:');
05781                 $this->appendDebug($this->varDump($opData));
05782                 
05783                 // Get encoding style for output and set to current
05784                 $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
05785                 if(($direction == 'input') && isset($opData['output']['encodingStyle']) && ($opData['output']['encodingStyle'] != $encodingStyle)) {
05786                         $encodingStyle = $opData['output']['encodingStyle'];
05787                         $enc_style = $encodingStyle;
05788                 }
05789                 
05790                 // set input params
05791                 $xml = '';
05792                 if (isset($opData[$direction]['parts']) && sizeof($opData[$direction]['parts']) > 0) {
05793                         
05794                         $use = $opData[$direction]['use'];
05795                         $this->debug("use=$use");
05796                         $this->debug('got ' . count($opData[$direction]['parts']) . ' part(s)');
05797                         if (is_array($parameters)) {
05798                                 $parametersArrayType = $this->isArraySimpleOrStruct($parameters);
05799                                 $this->debug('have ' . $parametersArrayType . ' parameters');
05800                                 foreach($opData[$direction]['parts'] as $name => $type) {
05801                                         $this->debug('serializing part "'.$name.'" of type "'.$type.'"');
05802                                         // Track encoding style
05803                                         if(isset($opData[$direction]['encodingStyle']) && $encodingStyle != $opData[$direction]['encodingStyle']) {
05804                                                 $encodingStyle = $opData[$direction]['encodingStyle'];                  
05805                                                 $enc_style = $encodingStyle;
05806                                         } else {
05807                                                 $enc_style = false;
05808                                         }
05809                                         // NOTE: add error handling here
05810                                         // if serializeType returns false, then catch global error and fault
05811                                         if ($parametersArrayType == 'arraySimple') {
05812                                                 $p = array_shift($parameters);
05813                                                 $this->debug('calling serializeType w/indexed param');
05814                                                 $xml .= $this->serializeType($name, $type, $p, $use, $enc_style);
05815                                         } elseif (isset($parameters[$name])) {
05816                                                 $this->debug('calling serializeType w/named param');
05817                                                 $xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style);
05818                                         } else {
05819                                                 // TODO: only send nillable
05820                                                 $this->debug('calling serializeType w/null param');
05821                                                 $xml .= $this->serializeType($name, $type, null, $use, $enc_style);
05822                                         }
05823                                 }
05824                         } else {
05825                                 $this->debug('no parameters passed.');
05826                         }
05827                 }
05828                 $this->debug("serializeParameters returning: $xml");
05829                 return $xml;
05830         } 
05831         
05844         function serializeType($name, $type, $value, $use='encoded', $encodingStyle=false, $unqualified=false)
05845         {
05846                 $this->debug("in serializeType: name=$name, type=$type, use=$use, encodingStyle=$encodingStyle, unqualified=" . ($unqualified ? "unqualified" : "qualified"));
05847                 $this->appendDebug("value=" . $this->varDump($value));
05848                 if($use == 'encoded' && $encodingStyle) {
05849                         $encodingStyle = ' SOAP-ENV:encodingStyle="' . $encodingStyle . '"';
05850                 }
05851 
05852                 // if a soapval has been supplied, let its type override the WSDL
05853         if (is_object($value) && get_class($value) == 'soapval') {
05854                 if ($value->type_ns) {
05855                         $type = $value->type_ns . ':' . $value->type;
05856                         $forceType = true;
05857                         $this->debug("in serializeType: soapval overrides type to $type");
05858                 } elseif ($value->type) {
05859                         $type = $value->type;
05860                         $forceType = true;
05861                         $this->debug("in serializeType: soapval overrides type to $type");
05862                 } else {
05863                         $forceType = false;
05864                         $this->debug("in serializeType: soapval does not override type");
05865                 }
05866                 $attrs = $value->attributes;
05867                 $value = $value->value;
05868                 $this->debug("in serializeType: soapval overrides value to $value");
05869                 if ($attrs) {
05870                         if (!is_array($value)) {
05871                                 $value['!'] = $value;
05872                         }
05873                         foreach ($attrs as $n => $v) {
05874                                 $value['!' . $n] = $v;
05875                         }
05876                         $this->debug("in serializeType: soapval provides attributes");
05877                     }
05878         } else {
05879                 $forceType = false;
05880         }
05881 
05882                 $xml = '';
05883                 if (strpos($type, ':')) {
05884                         $uqType = substr($type, strrpos($type, ':') + 1);
05885                         $ns = substr($type, 0, strrpos($type, ':'));
05886                         $this->debug("in serializeType: got a prefixed type: $uqType, $ns");
05887                         if ($this->getNamespaceFromPrefix($ns)) {
05888                                 $ns = $this->getNamespaceFromPrefix($ns);
05889                                 $this->debug("in serializeType: expanded prefixed type: $uqType, $ns");
05890                         }
05891 
05892                         if($ns == $this->XMLSchemaVersion || $ns == 'http://schemas.xmlsoap.org/soap/encoding/'){
05893                                 $this->debug('in serializeType: type namespace indicates XML Schema or SOAP Encoding type');
05894                                 if ($unqualified && $use == 'literal') {
05895                                         $elementNS = " xmlns=\"\"";
05896                                 } else {
05897                                         $elementNS = '';
05898                                 }
05899                                 if (is_null($value)) {
05900                                         if ($use == 'literal') {
05901                                                 // TODO: depends on minOccurs
05902                                                 $xml = "<$name$elementNS/>";
05903                                         } else {
05904                                                 // TODO: depends on nillable, which should be checked before calling this method
05905                                                 $xml = "<$name$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"/>";
05906                                         }
05907                                         $this->debug("in serializeType: returning: $xml");
05908                                         return $xml;
05909                                 }
05910                                 if ($uqType == 'Array') {
05911                                         // JBoss/Axis does this sometimes
05912                                         return $this->serialize_val($value, $name, false, false, false, false, $use);
05913                                 }
05914                         if ($uqType == 'boolean') {
05915                                 if ((is_string($value) && $value == 'false') || (! $value)) {
05916                                                 $value = 'false';
05917                                         } else {
05918                                                 $value = 'true';
05919                                         }
05920                                 } 
05921                                 if ($uqType == 'string' && gettype($value) == 'string') {
05922                                         $value = $this->expandEntities($value);
05923                                 }
05924                                 if (($uqType == 'long' || $uqType == 'unsignedLong') && gettype($value) == 'double') {
05925                                         $value = sprintf("%.0lf", $value);
05926                                 }
05927                                 // it's a scalar
05928                                 // TODO: what about null/nil values?
05929                                 // check type isn't a custom type extending xmlschema namespace
05930                                 if (!$this->getTypeDef($uqType, $ns)) {
05931                                         if ($use == 'literal') {
05932                                                 if ($forceType) {
05933                                                         $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">$value</$name>";
05934                                                 } else {
05935                                                         $xml = "<$name$elementNS>$value</$name>";
05936                                                 }
05937                                         } else {
05938                                                 $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>$value</$name>";
05939                                         }
05940                                         $this->debug("in serializeType: returning: $xml");
05941                                         return $xml;
05942                                 }
05943                                 $this->debug('custom type extends XML Schema or SOAP Encoding namespace (yuck)');
05944                         } else if ($ns == 'http://xml.apache.org/xml-soap') {
05945                                 $this->debug('in serializeType: appears to be Apache SOAP type');
05946                                 if ($uqType == 'Map') {
05947                                         $tt_prefix = $this->getPrefixFromNamespace('http://xml.apache.org/xml-soap');
05948                                         if (! $tt_prefix) {
05949                                                 $this->debug('in serializeType: Add namespace for Apache SOAP type');
05950                                                 $tt_prefix = 'ns' . rand(1000, 9999);
05951                                                 $this->namespaces[$tt_prefix] = 'http://xml.apache.org/xml-soap';
05952                                                 // force this to be added to usedNamespaces
05953                                                 $tt_prefix = $this->getPrefixFromNamespace('http://xml.apache.org/xml-soap');
05954                                         }
05955                                         $contents = '';
05956                                         foreach($value as $k => $v) {
05957                                                 $this->debug("serializing map element: key $k, value $v");
05958                                                 $contents .= '<item>';
05959                                                 $contents .= $this->serialize_val($k,'key',false,false,false,false,$use);
05960                                                 $contents .= $this->serialize_val($v,'value',false,false,false,false,$use);
05961                                                 $contents .= '</item>';
05962                                         }
05963                                         if ($use == 'literal') {
05964                                                 if ($forceType) {
05965                                                         $xml = "<$name xsi:type=\"" . $tt_prefix . ":$uqType\">$contents</$name>";
05966                                                 } else {
05967                                                         $xml = "<$name>$contents</$name>";
05968                                                 }
05969                                         } else {
05970                                                 $xml = "<$name xsi:type=\"" . $tt_prefix . ":$uqType\"$encodingStyle>$contents</$name>";
05971                                         }
05972                                         $this->debug("in serializeType: returning: $xml");
05973                                         return $xml;
05974                                 }
05975                                 $this->debug('in serializeType: Apache SOAP type, but only support Map');
05976                         }
05977                 } else {
05978                         // TODO: should the type be compared to types in XSD, and the namespace
05979                         // set to XSD if the type matches?
05980                         $this->debug("in serializeType: No namespace for type $type");
05981                         $ns = '';
05982                         $uqType = $type;
05983                 }
05984                 if(!$typeDef = $this->getTypeDef($uqType, $ns)){
05985                         $this->setError("$type ($uqType) is not a supported type.");
05986                         $this->debug("in serializeType: $type ($uqType) is not a supported type.");
05987                         return false;
05988                 } else {
05989                         $this->debug("in serializeType: found typeDef");
05990                         $this->appendDebug('typeDef=' . $this->varDump($typeDef));
05991                         if (substr($uqType, -1) == '^') {
05992                                 $uqType = substr($uqType, 0, -1);
05993                         }
05994                 }
05995                 if (!isset($typeDef['phpType'])) {
05996                         $this->setError("$type ($uqType) has no phpType.");
05997                         $this->debug("in serializeType: $type ($uqType) has no phpType.");
05998                         return false;
05999                 }
06000                 $phpType = $typeDef['phpType'];
06001                 $this->debug("in serializeType: uqType: $uqType, ns: $ns, phptype: $phpType, arrayType: " . (isset($typeDef['arrayType']) ? $typeDef['arrayType'] : '') ); 
06002                 // if php type == struct, map value to the <all> element names
06003                 if ($phpType == 'struct') {
06004                         if (isset($typeDef['typeClass']) && $typeDef['typeClass'] == 'element') {
06005                                 $elementName = $uqType;
06006                                 if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) {
06007                                         $elementNS = " xmlns=\"$ns\"";
06008                                 } else {
06009                                         $elementNS = " xmlns=\"\"";
06010                                 }
06011                         } else {
06012                                 $elementName = $name;
06013                                 if ($unqualified) {
06014                                         $elementNS = " xmlns=\"\"";
06015                                 } else {
06016                                         $elementNS = '';
06017                                 }
06018                         }
06019                         if (is_null($value)) {
06020                                 if ($use == 'literal') {
06021                                         // TODO: depends on minOccurs
06022                                         $xml = "<$elementName$elementNS/>";
06023                                 } else {
06024                                         $xml = "<$elementName$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"/>";
06025                                 }
06026                                 $this->debug("in serializeType: returning: $xml");
06027                                 return $xml;
06028                         }
06029                         if (is_object($value)) {
06030                                 $value = get_object_vars($value);
06031                         }
06032                         if (is_array($value)) {
06033                                 $elementAttrs = $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType);
06034                                 if ($use == 'literal') {
06035                                         if ($forceType) {
06036                                                 $xml = "<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">";
06037                                         } else {
06038                                                 $xml = "<$elementName$elementNS$elementAttrs>";
06039                                         }
06040                                 } else {
06041                                         $xml = "<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>";
06042                                 }
06043         
06044                                 $xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle);
06045                                 $xml .= "</$elementName>";
06046                         } else {
06047                                 $this->debug("in serializeType: phpType is struct, but value is not an array");
06048                                 $this->setError("phpType is struct, but value is not an array: see debug output for details");
06049                                 $xml = '';
06050                         }
06051                 } elseif ($phpType == 'array') {
06052                         if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) {
06053                                 $elementNS = " xmlns=\"$ns\"";
06054                         } else {
06055                                 if ($unqualified) {
06056                                         $elementNS = " xmlns=\"\"";
06057                                 } else {
06058                                         $elementNS = '';
06059                                 }
06060                         }
06061                         if (is_null($value)) {
06062                                 if ($use == 'literal') {
06063                                         // TODO: depends on minOccurs
06064                                         $xml = "<$name$elementNS/>";
06065                                 } else {
06066                                         $xml = "<$name$elementNS xsi:nil=\"true\" xsi:type=\"" .
06067                                                 $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') .
06068                                                 ":Array\" " .
06069                                                 $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') .
06070                                                 ':arrayType="' .
06071                                                 $this->getPrefixFromNamespace($this->getPrefix($typeDef['arrayType'])) .
06072                                                 ':' .
06073                                                 $this->getLocalPart($typeDef['arrayType'])."[0]\"/>";
06074                                 }
06075                                 $this->debug("in serializeType: returning: $xml");
06076                                 return $xml;
06077                         }
06078                         if (isset($typeDef['multidimensional'])) {
06079                                 $nv = array();
06080                                 foreach($value as $v) {
06081                                         $cols = ',' . sizeof($v);
06082                                         $nv = array_merge($nv, $v);
06083                                 } 
06084                                 $value = $nv;
06085                         } else {
06086                                 $cols = '';
06087                         } 
06088                         if (is_array($value) && sizeof($value) >= 1) {
06089                                 $rows = sizeof($value);
06090                                 $contents = '';
06091                                 foreach($value as $k => $v) {
06092                                         $this->debug("serializing array element: $k, $v of type: $typeDef[arrayType]");
06093                                         //if (strpos($typeDef['arrayType'], ':') ) {
06094                                         if (!in_array($typeDef['arrayType'],$this->typemap['http://www.w3.org/2001/XMLSchema'])) {
06095                                             $contents .= $this->serializeType('item', $typeDef['arrayType'], $v, $use);
06096                                         } else {
06097                                             $contents .= $this->serialize_val($v, 'item', $typeDef['arrayType'], null, $this->XMLSchemaVersion, false, $use);
06098                                         } 
06099                                 }
06100                         } else {
06101                                 $rows = 0;
06102                                 $contents = null;
06103                         }
06104                         // TODO: for now, an empty value will be serialized as a zero element
06105                         // array.  Revisit this when coding the handling of null/nil values.
06106                         if ($use == 'literal') {
06107                                 $xml = "<$name$elementNS>"
06108                                         .$contents
06109                                         ."</$name>";
06110                         } else {
06111                                 $xml = "<$name$elementNS xsi:type=\"".$this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/').':Array" '.
06112                                         $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/')
06113                                         .':arrayType="'
06114                                         .$this->getPrefixFromNamespace($this->getPrefix($typeDef['arrayType']))
06115                                         .":".$this->getLocalPart($typeDef['arrayType'])."[$rows$cols]\">"
06116                                         .$contents
06117                                         ."</$name>";
06118                         }
06119                 } elseif ($phpType == 'scalar') {
06120                         if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) {
06121                                 $elementNS = " xmlns=\"$ns\"";
06122                         } else {
06123                                 if ($unqualified) {
06124                                         $elementNS = " xmlns=\"\"";
06125                                 } else {
06126                                         $elementNS = '';
06127                                 }
06128                         }
06129                         if ($use == 'literal') {
06130                                 if ($forceType) {
06131                                         $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">$value</$name>";
06132                                 } else {
06133                                         $xml = "<$name$elementNS>$value</$name>";
06134                                 }
06135                         } else {
06136                                 $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>$value</$name>";
06137                         }
06138                 }
06139                 $this->debug("in serializeType: returning: $xml");
06140                 return $xml;
06141         }
06142         
06153         function serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType) {
06154                 $this->debug("serializeComplexTypeAttributes for XML Schema type $ns:$uqType");
06155                 $xml = '';
06156                 if (isset($typeDef['extensionBase'])) {
06157                         $nsx = $this->getPrefix($typeDef['extensionBase']);
06158                         $uqTypex = $this->getLocalPart($typeDef['extensionBase']);
06159                         if ($this->getNamespaceFromPrefix($nsx)) {
06160                                 $nsx = $this->getNamespaceFromPrefix($nsx);
06161                         }
06162                         if ($typeDefx = $this->getTypeDef($uqTypex, $nsx)) {
06163                                 $this->debug("serialize attributes for extension base $nsx:$uqTypex");
06164                                 $xml .= $this->serializeComplexTypeAttributes($typeDefx, $value, $nsx, $uqTypex);
06165                         } else {
06166                                 $this->debug("extension base $nsx:$uqTypex is not a supported type");
06167                         }
06168                 }
06169                 if (isset($typeDef['attrs']) && is_array($typeDef['attrs'])) {
06170                         $this->debug("serialize attributes for XML Schema type $ns:$uqType");
06171                         if (is_array($value)) {
06172                                 $xvalue = $value;
06173                         } elseif (is_object($value)) {
06174                                 $xvalue = get_object_vars($value);
06175                         } else {
06176                                 $this->debug("value is neither an array nor an object for XML Schema type $ns:$uqType");
06177                                 $xvalue = array();
06178                         }
06179                         foreach ($typeDef['attrs'] as $aName => $attrs) {
06180                                 if (isset($xvalue['!' . $aName])) {
06181                                         $xname = '!' . $aName;
06182                                         $this->debug("value provided for attribute $aName with key $xname");
06183                                 } elseif (isset($xvalue[$aName])) {
06184                                         $xname = $aName;
06185                                         $this->debug("value provided for attribute $aName with key $xname");
06186                                 } elseif (isset($attrs['default'])) {
06187                                         $xname = '!' . $aName;
06188                                         $xvalue[$xname] = $attrs['default'];
06189                                         $this->debug('use default value of ' . $xvalue[$aName] . ' for attribute ' . $aName);
06190                                 } else {
06191                                         $xname = '';
06192                                         $this->debug("no value provided for attribute $aName");
06193                                 }
06194                                 if ($xname) {
06195                                         $xml .=  " $aName=\"" . $this->expandEntities($xvalue[$xname]) . "\"";
06196                                 }
06197                         } 
06198                 } else {
06199                         $this->debug("no attributes to serialize for XML Schema type $ns:$uqType");
06200                 }
06201                 return $xml;
06202         }
06203 
06216         function serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use='encoded', $encodingStyle=false) {
06217                 $this->debug("in serializeComplexTypeElements for XML Schema type $ns:$uqType");
06218                 $xml = '';
06219                 if (isset($typeDef['extensionBase'])) {
06220                         $nsx = $this->getPrefix($typeDef['extensionBase']);
06221                         $uqTypex = $this->getLocalPart($typeDef['extensionBase']);
06222                         if ($this->getNamespaceFromPrefix($nsx)) {
06223                                 $nsx = $this->getNamespaceFromPrefix($nsx);
06224                         }
06225                         if ($typeDefx = $this->getTypeDef($uqTypex, $nsx)) {
06226                                 $this->debug("serialize elements for extension base $nsx:$uqTypex");
06227                                 $xml .= $this->serializeComplexTypeElements($typeDefx, $value, $nsx, $uqTypex, $use, $encodingStyle);
06228                         } else {
06229                                 $this->debug("extension base $nsx:$uqTypex is not a supported type");
06230                         }
06231                 }
06232                 if (isset($typeDef['elements']) && is_array($typeDef['elements'])) {
06233                         $this->debug("in serializeComplexTypeElements, serialize elements for XML Schema type $ns:$uqType");
06234                         if (is_array($value)) {
06235                                 $xvalue = $value;
06236                         } elseif (is_object($value)) {
06237                                 $xvalue = get_object_vars($value);
06238                         } else {
06239                                 $this->debug("value is neither an array nor an object for XML Schema type $ns:$uqType");
06240                                 $xvalue = array();
06241                         }
06242                         // toggle whether all elements are present - ideally should validate against schema
06243                         if (count($typeDef['elements']) != count($xvalue)){
06244                                 $optionals = true;
06245                         }
06246                         foreach ($typeDef['elements'] as $eName => $attrs) {
06247                                 if (!isset($xvalue[$eName])) {
06248                                         if (isset($attrs['default'])) {
06249                                                 $xvalue[$eName] = $attrs['default'];
06250                                                 $this->debug('use default value of ' . $xvalue[$eName] . ' for element ' . $eName);
06251                                         }
06252                                 }
06253                                 // if user took advantage of a minOccurs=0, then only serialize named parameters
06254                                 if (isset($optionals)
06255                                     && (!isset($xvalue[$eName])) 
06256                                         && ( (!isset($attrs['nillable'])) || $attrs['nillable'] != 'true')
06257                                         ){
06258                                         if (isset($attrs['minOccurs']) && $attrs['minOccurs'] <> '0') {
06259                                                 $this->debug("apparent error: no value provided for element $eName with minOccurs=" . $attrs['minOccurs']);
06260                                         }
06261                                         // do nothing
06262                                         $this->debug("no value provided for complexType element $eName and element is not nillable, so serialize nothing");
06263                                 } else {
06264                                         // get value
06265                                         if (isset($xvalue[$eName])) {
06266                                             $v = $xvalue[$eName];
06267                                         } else {
06268                                             $v = null;
06269                                         }
06270                                         if (isset($attrs['form'])) {
06271                                                 $unqualified = ($attrs['form'] == 'unqualified');
06272                                         } else {
06273                                                 $unqualified = false;
06274                                         }
06275                                         if (isset($attrs['maxOccurs']) && ($attrs['maxOccurs'] == 'unbounded' || $attrs['maxOccurs'] > 1) && isset($v) && is_array($v) && $this->isArraySimpleOrStruct($v) == 'arraySimple') {
06276                                                 $vv = $v;
06277                                                 foreach ($vv as $k => $v) {
06278                                                         if (isset($attrs['type']) || isset($attrs['ref'])) {
06279                                                                 // serialize schema-defined type
06280                                                             $xml .= $this->serializeType($eName, isset($attrs['type']) ? $attrs['type'] : $attrs['ref'], $v, $use, $encodingStyle, $unqualified);
06281                                                         } else {
06282                                                                 // serialize generic type (can this ever really happen?)
06283                                                             $this->debug("calling serialize_val() for $v, $eName, false, false, false, false, $use");
06284                                                             $xml .= $this->serialize_val($v, $eName, false, false, false, false, $use);
06285                                                         }
06286                                                 }
06287                                         } else {
06288                                                 if (isset($attrs['type']) || isset($attrs['ref'])) {
06289                                                         // serialize schema-defined type
06290                                                     $xml .= $this->serializeType($eName, isset($attrs['type']) ? $attrs['type'] : $attrs['ref'], $v, $use, $encodingStyle, $unqualified);
06291                                                 } else {
06292                                                         // serialize generic type (can this ever really happen?)
06293                                                     $this->debug("calling serialize_val() for $v, $eName, false, false, false, false, $use");
06294                                                     $xml .= $this->serialize_val($v, $eName, false, false, false, false, $use);
06295                                                 }
06296                                         }
06297                                 }
06298                         } 
06299                 } else {
06300                         $this->debug("no elements to serialize for XML Schema type $ns:$uqType");
06301                 }
06302                 return $xml;
06303         }
06304 
06319         function addComplexType($name,$typeClass='complexType',$phpType='array',$compositor='',$restrictionBase='',$elements=array(),$attrs=array(),$arrayType='') {
06320                 if (count($elements) > 0) {
06321                         $eElements = array();
06322                 foreach($elements as $n => $e){
06323                     // expand each element
06324                     $ee = array();
06325                     foreach ($e as $k => $v) {
06326                             $k = strpos($k,':') ? $this->expandQname($k) : $k;
06327                             $v = strpos($v,':') ? $this->expandQname($v) : $v;
06328                             $ee[$k] = $v;
06329                         }
06330                         $eElements[$n] = $ee;
06331                 }
06332                 $elements = $eElements;
06333                 }
06334                 
06335                 if (count($attrs) > 0) {
06336                 foreach($attrs as $n => $a){
06337                     // expand each attribute
06338                     foreach ($a as $k => $v) {
06339                             $k = strpos($k,':') ? $this->expandQname($k) : $k;
06340                             $v = strpos($v,':') ? $this->expandQname($v) : $v;
06341                             $aa[$k] = $v;
06342                         }
06343                         $eAttrs[$n] = $aa;
06344                 }
06345                 $attrs = $eAttrs;
06346                 }
06347 
06348                 $restrictionBase = strpos($restrictionBase,':') ? $this->expandQname($restrictionBase) : $restrictionBase;
06349                 $arrayType = strpos($arrayType,':') ? $this->expandQname($arrayType) : $arrayType;
06350 
06351                 $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns'];
06352                 $this->schemas[$typens][0]->addComplexType($name,$typeClass,$phpType,$compositor,$restrictionBase,$elements,$attrs,$arrayType);
06353         }
06354 
06366         function addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array()) {
06367                 $restrictionBase = strpos($restrictionBase,':') ? $this->expandQname($restrictionBase) : $restrictionBase;
06368 
06369                 $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns'];
06370                 $this->schemas[$typens][0]->addSimpleType($name, $restrictionBase, $typeClass, $phpType, $enumeration);
06371         }
06372 
06380         function addElement($attrs) {
06381                 $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns'];
06382                 $this->schemas[$typens][0]->addElement($attrs);
06383         }
06384 
06399         function addOperation($name, $in = false, $out = false, $namespace = false, $soapaction = false, $style = 'rpc', $use = 'encoded', $documentation = '', $encodingStyle = ''){
06400                 if ($use == 'encoded' && $encodingStyle == '') {
06401                         $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
06402                 }
06403 
06404                 if ($style == 'document') {
06405                         $elements = array();
06406                         foreach ($in as $n => $t) {
06407                                 $elements[$n] = array('name' => $n, 'type' => $t, 'form' => 'unqualified');
06408                         }
06409                         $this->addComplexType($name . 'RequestType', 'complexType', 'struct', 'all', '', $elements);
06410                         $this->addElement(array('name' => $name, 'type' => $name . 'RequestType'));
06411                         $in = array('parameters' => 'tns:' . $name . '^');
06412 
06413                         $elements = array();
06414                         foreach ($out as $n => $t) {
06415                                 $elements[$n] = array('name' => $n, 'type' => $t, 'form' => 'unqualified');
06416                         }
06417                         $this->addComplexType($name . 'ResponseType', 'complexType', 'struct', 'all', '', $elements);
06418                         $this->addElement(array('name' => $name . 'Response', 'type' => $name . 'ResponseType', 'form' => 'qualified'));
06419                         $out = array('parameters' => 'tns:' . $name . 'Response' . '^');
06420                 }
06421 
06422                 // get binding
06423                 $this->bindings[ $this->serviceName . 'Binding' ]['operations'][$name] =
06424                 array(
06425                 'name' => $name,
06426                 'binding' => $this->serviceName . 'Binding',
06427                 'endpoint' => $this->endpoint,
06428                 'soapAction' => $soapaction,
06429                 'style' => $style,
06430                 'input' => array(
06431                         'use' => $use,
06432                         'namespace' => $namespace,
06433                         'encodingStyle' => $encodingStyle,
06434                         'message' => $name . 'Request',
06435                         'parts' => $in),
06436                 'output' => array(
06437                         'use' => $use,
06438                         'namespace' => $namespace,
06439                         'encodingStyle' => $encodingStyle,
06440                         'message' => $name . 'Response',
06441                         'parts' => $out),
06442                 'namespace' => $namespace,
06443                 'transport' => 'http://schemas.xmlsoap.org/soap/http',
06444                 'documentation' => $documentation); 
06445                 // add portTypes
06446                 // add messages
06447                 if($in)
06448                 {
06449                         foreach($in as $pName => $pType)
06450                         {
06451                                 if(strpos($pType,':')) {
06452                                         $pType = $this->getNamespaceFromPrefix($this->getPrefix($pType)).":".$this->getLocalPart($pType);
06453                                 }
06454                                 $this->messages[$name.'Request'][$pName] = $pType;
06455                         }
06456                 } else {
06457             $this->messages[$name.'Request']= '0';
06458         }
06459                 if($out)
06460                 {
06461                         foreach($out as $pName => $pType)
06462                         {
06463                                 if(strpos($pType,':')) {
06464                                         $pType = $this->getNamespaceFromPrefix($this->getPrefix($pType)).":".$this->getLocalPart($pType);
06465                                 }
06466                                 $this->messages[$name.'Response'][$pName] = $pType;
06467                         }
06468                 } else {
06469             $this->messages[$name.'Response']= '0';
06470         }
06471                 return true;
06472         } 
06473 }
06474 ?><?php
06475 
06476 
06477 
06487 class nusoap_parser extends nusoap_base {
06488 
06489         var $xml = '';
06490         var $xml_encoding = '';
06491         var $method = '';
06492         var $root_struct = '';
06493         var $root_struct_name = '';
06494         var $root_struct_namespace = '';
06495         var $root_header = '';
06496     var $document = '';                 // incoming SOAP body (text)
06497         // determines where in the message we are (envelope,header,body,method)
06498         var $status = '';
06499         var $position = 0;
06500         var $depth = 0;
06501         var $default_namespace = '';
06502         var $namespaces = array();
06503         var $message = array();
06504     var $parent = '';
06505         var $fault = false;
06506         var $fault_code = '';
06507         var $fault_str = '';
06508         var $fault_detail = '';
06509         var $depth_array = array();
06510         var $debug_flag = true;
06511         var $soapresponse = NULL;       // parsed SOAP Body
06512         var $soapheader = NULL;         // parsed SOAP Header
06513         var $responseHeaders = '';      // incoming SOAP headers (text)
06514         var $body_position = 0;
06515         // for multiref parsing:
06516         // array of id => pos
06517         var $ids = array();
06518         // array of id => hrefs => pos
06519         var $multirefs = array();
06520         // toggle for auto-decoding element content
06521         var $decode_utf8 = true;
06522 
06532         function nusoap_parser($xml,$encoding='UTF-8',$method='',$decode_utf8=true){
06533                 parent::nusoap_base();
06534                 $this->xml = $xml;
06535                 $this->xml_encoding = $encoding;
06536                 $this->method = $method;
06537                 $this->decode_utf8 = $decode_utf8;
06538 
06539                 // Check whether content has been read.
06540                 if(!empty($xml)){
06541                         // Check XML encoding
06542                         $pos_xml = strpos($xml, '<?xml');
06543                         if ($pos_xml !== FALSE) {
06544                                 $xml_decl = substr($xml, $pos_xml, strpos($xml, '?>', $pos_xml + 2) - $pos_xml + 1);
06545                                 if (preg_match("/encoding=[\"']([^\"']*)[\"']/", $xml_decl, $res)) {
06546                                         $xml_encoding = $res[1];
06547                                         if (strtoupper($xml_encoding) != $encoding) {
06548                                                 $err = "Charset from HTTP Content-Type '" . $encoding . "' does not match encoding from XML declaration '" . $xml_encoding . "'";
06549                                                 $this->debug($err);
06550                                                 if ($encoding != 'ISO-8859-1' || strtoupper($xml_encoding) != 'UTF-8') {
06551                                                         $this->setError($err);
06552                                                         return;
06553                                                 }
06554                                                 // when HTTP says ISO-8859-1 (the default) and XML says UTF-8 (the typical), assume the other endpoint is just sloppy and proceed
06555                                         } else {
06556                                                 $this->debug('Charset from HTTP Content-Type matches encoding from XML declaration');
06557                                         }
06558                                 } else {
06559                                         $this->debug('No encoding specified in XML declaration');
06560                                 }
06561                         } else {
06562                                 $this->debug('No XML declaration');
06563                         }
06564                         $this->debug('Entering nusoap_parser(), length='.strlen($xml).', encoding='.$encoding);
06565                         // Create an XML parser - why not xml_parser_create_ns?
06566                         $this->parser = xml_parser_create($this->xml_encoding);
06567                         // Set the options for parsing the XML data.
06568                         //xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
06569                         xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
06570                         xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, $this->xml_encoding);
06571                         // Set the object for the parser.
06572                         xml_set_object($this->parser, $this);
06573                         // Set the element handlers for the parser.
06574                         xml_set_element_handler($this->parser, 'start_element','end_element');
06575                         xml_set_character_data_handler($this->parser,'character_data');
06576 
06577                         // Parse the XML file.
06578                         if(!xml_parse($this->parser,$xml,true)){
06579                             // Display an error message.
06580                             $err = sprintf('XML error parsing SOAP payload on line %d: %s',
06581                             xml_get_current_line_number($this->parser),
06582                             xml_error_string(xml_get_error_code($this->parser)));
06583                                 $this->debug($err);
06584                                 $this->debug("XML payload:\n" . $xml);
06585                                 $this->setError($err);
06586                         } else {
06587                                 $this->debug('parsed successfully, found root struct: '.$this->root_struct.' of name '.$this->root_struct_name);
06588                                 // get final value
06589                                 $this->soapresponse = $this->message[$this->root_struct]['result'];
06590                                 // get header value
06591                                 if($this->root_header != '' && isset($this->message[$this->root_header]['result'])){
06592                                         $this->soapheader = $this->message[$this->root_header]['result'];
06593                                 }
06594                                 // resolve hrefs/ids
06595                                 if(sizeof($this->multirefs) > 0){
06596                                         foreach($this->multirefs as $id => $hrefs){
06597                                                 $this->debug('resolving multirefs for id: '.$id);
06598                                                 $idVal = $this->buildVal($this->ids[$id]);
06599                                                 if (is_array($idVal) && isset($idVal['!id'])) {
06600                                                         unset($idVal['!id']);
06601                                                 }
06602                                                 foreach($hrefs as $refPos => $ref){
06603                                                         $this->debug('resolving href at pos '.$refPos);
06604                                                         $this->multirefs[$id][$refPos] = $idVal;
06605                                                 }
06606                                         }
06607                                 }
06608                         }
06609                         xml_parser_free($this->parser);
06610                 } else {
06611                         $this->debug('xml was empty, didn\'t parse!');
06612                         $this->setError('xml was empty, didn\'t parse!');
06613                 }
06614         }
06615 
06624         function start_element($parser, $name, $attrs) {
06625                 // position in a total number of elements, starting from 0
06626                 // update class level pos
06627                 $pos = $this->position++;
06628                 // and set mine
06629                 $this->message[$pos] = array('pos' => $pos,'children'=>'','cdata'=>'');
06630                 // depth = how many levels removed from root?
06631                 // set mine as current global depth and increment global depth value
06632                 $this->message[$pos]['depth'] = $this->depth++;
06633 
06634                 // else add self as child to whoever the current parent is
06635                 if($pos != 0){
06636                         $this->message[$this->parent]['children'] .= '|'.$pos;
06637                 }
06638                 // set my parent
06639                 $this->message[$pos]['parent'] = $this->parent;
06640                 // set self as current parent
06641                 $this->parent = $pos;
06642                 // set self as current value for this depth
06643                 $this->depth_array[$this->depth] = $pos;
06644                 // get element prefix
06645                 if(strpos($name,':')){
06646                         // get ns prefix
06647                         $prefix = substr($name,0,strpos($name,':'));
06648                         // get unqualified name
06649                         $name = substr(strstr($name,':'),1);
06650                 }
06651                 // set status
06652                 if($name == 'Envelope'){
06653                         $this->status = 'envelope';
06654                 } elseif($name == 'Header' && $this->status = 'envelope'){
06655                         $this->root_header = $pos;
06656                         $this->status = 'header';
06657                 } elseif($name == 'Body' && $this->status = 'envelope'){
06658                         $this->status = 'body';
06659                         $this->body_position = $pos;
06660                 // set method
06661                 } elseif($this->status == 'body' && $pos == ($this->body_position+1)){
06662                         $this->status = 'method';
06663                         $this->root_struct_name = $name;
06664                         $this->root_struct = $pos;
06665                         $this->message[$pos]['type'] = 'struct';
06666                         $this->debug("found root struct $this->root_struct_name, pos $this->root_struct");
06667                 }
06668                 // set my status
06669                 $this->message[$pos]['status'] = $this->status;
06670                 // set name
06671                 $this->message[$pos]['name'] = htmlspecialchars($name);
06672                 // set attrs
06673                 $this->message[$pos]['attrs'] = $attrs;
06674 
06675                 // loop through atts, logging ns and type declarations
06676         $attstr = '';
06677                 foreach($attrs as $key => $value){
06678                 $key_prefix = $this->getPrefix($key);
06679                         $key_localpart = $this->getLocalPart($key);
06680                         // if ns declarations, add to class level array of valid namespaces
06681             if($key_prefix == 'xmlns'){
06682                                 if(ereg('^http://www.w3.org/[0-9]{4}/XMLSchema$',$value)){
06683                                         $this->XMLSchemaVersion = $value;
06684                                         $this->namespaces['xsd'] = $this->XMLSchemaVersion;
06685                                         $this->namespaces['xsi'] = $this->XMLSchemaVersion.'-instance';
06686                                 }
06687                 $this->namespaces[$key_localpart] = $value;
06688                                 // set method namespace
06689                                 if($name == $this->root_struct_name){
06690                                         $this->methodNamespace = $value;
06691                                 }
06692                         // if it's a type declaration, set type
06693         } elseif($key_localpart == 'type'){
06694                         if (isset($this->message[$pos]['type']) && $this->message[$pos]['type'] == 'array') {
06695                                 // do nothing: already processed arrayType
06696                         } else {
06697                         $value_prefix = $this->getPrefix($value);
06698                         $value_localpart = $this->getLocalPart($value);
06699                                         $this->message[$pos]['type'] = $value_localpart;
06700                                         $this->message[$pos]['typePrefix'] = $value_prefix;
06701                         if(isset($this->namespaces[$value_prefix])){
06702                                 $this->message[$pos]['type_namespace'] = $this->namespaces[$value_prefix];
06703                         } else if(isset($attrs['xmlns:'.$value_prefix])) {
06704                                                 $this->message[$pos]['type_namespace'] = $attrs['xmlns:'.$value_prefix];
06705                         }
06706                                         // should do something here with the namespace of specified type?
06707                                 }
06708                         } elseif($key_localpart == 'arrayType'){
06709                                 $this->message[$pos]['type'] = 'array';
06710                                 /* do arrayType ereg here
06711                                 [1]    arrayTypeValue    ::=    atype asize
06712                                 [2]    atype    ::=    QName rank*
06713                                 [3]    rank    ::=    '[' (',')* ']'
06714                                 [4]    asize    ::=    '[' length~ ']'
06715                                 [5]    length    ::=    nextDimension* Digit+
06716                                 [6]    nextDimension    ::=    Digit+ ','
06717                                 */
06718                                 $expr = '([A-Za-z0-9_]+):([A-Za-z]+[A-Za-z0-9_]+)\[([0-9]+),?([0-9]*)\]';
06719                                 if(ereg($expr,$value,$regs)){
06720                                         $this->message[$pos]['typePrefix'] = $regs[1];
06721                                         $this->message[$pos]['arrayTypePrefix'] = $regs[1];
06722                         if (isset($this->namespaces[$regs[1]])) {
06723                                 $this->message[$pos]['arrayTypeNamespace'] = $this->namespaces[$regs[1]];
06724                         } else if (isset($attrs['xmlns:'.$regs[1]])) {
06725                                                 $this->message[$pos]['arrayTypeNamespace'] = $attrs['xmlns:'.$regs[1]];
06726                         }
06727                                         $this->message[$pos]['arrayType'] = $regs[2];
06728                                         $this->message[$pos]['arraySize'] = $regs[3];
06729                                         $this->message[$pos]['arrayCols'] = $regs[4];
06730                                 }
06731                         // specifies nil value (or not)
06732                         } elseif ($key_localpart == 'nil'){
06733                                 $this->message[$pos]['nil'] = ($value == 'true' || $value == '1');
06734                         // some other attribute
06735                         } elseif ($key != 'href' && $key != 'xmlns' && $key_localpart != 'encodingStyle' && $key_localpart != 'root') {
06736                                 $this->message[$pos]['xattrs']['!' . $key] = $value;
06737                         }
06738 
06739                         if ($key == 'xmlns') {
06740                                 $this->default_namespace = $value;
06741                         }
06742                         // log id
06743                         if($key == 'id'){
06744                                 $this->ids[$value] = $pos;
06745                         }
06746                         // root
06747                         if($key_localpart == 'root' && $value == 1){
06748                                 $this->status = 'method';
06749                                 $this->root_struct_name = $name;
06750                                 $this->root_struct = $pos;
06751                                 $this->debug("found root struct $this->root_struct_name, pos $pos");
06752                         }
06753             // for doclit
06754             $attstr .= " $key=\"$value\"";
06755                 }
06756         // get namespace - must be done after namespace atts are processed
06757                 if(isset($prefix)){
06758                         $this->message[$pos]['namespace'] = $this->namespaces[$prefix];
06759                         $this->default_namespace = $this->namespaces[$prefix];
06760                 } else {
06761                         $this->message[$pos]['namespace'] = $this->default_namespace;
06762                 }
06763         if($this->status == 'header'){
06764                 if ($this->root_header != $pos) {
06765                         $this->responseHeaders .= "<" . (isset($prefix) ? $prefix . ':' : '') . "$name$attstr>";
06766                 }
06767         } elseif($this->root_struct_name != ''){
06768                 $this->document .= "<" . (isset($prefix) ? $prefix . ':' : '') . "$name$attstr>";
06769         }
06770         }
06771 
06779         function end_element($parser, $name) {
06780                 // position of current element is equal to the last value left in depth_array for my depth
06781                 $pos = $this->depth_array[$this->depth--];
06782 
06783         // get element prefix
06784                 if(strpos($name,':')){
06785                         // get ns prefix
06786                         $prefix = substr($name,0,strpos($name,':'));
06787                         // get unqualified name
06788                         $name = substr(strstr($name,':'),1);
06789                 }
06790                 
06791                 // build to native type
06792                 if(isset($this->body_position) && $pos > $this->body_position){
06793                         // deal w/ multirefs
06794                         if(isset($this->message[$pos]['attrs']['href'])){
06795                                 // get id
06796                                 $id = substr($this->message[$pos]['attrs']['href'],1);
06797                                 // add placeholder to href array
06798                                 $this->multirefs[$id][$pos] = 'placeholder';
06799                                 // add set a reference to it as the result value
06800                                 $this->message[$pos]['result'] =& $this->multirefs[$id][$pos];
06801             // build complexType values
06802                         } elseif($this->message[$pos]['children'] != ''){
06803                                 // if result has already been generated (struct/array)
06804                                 if(!isset($this->message[$pos]['result'])){
06805                                         $this->message[$pos]['result'] = $this->buildVal($pos);
06806                                 }
06807                         // build complexType values of attributes and possibly simpleContent
06808                         } elseif (isset($this->message[$pos]['xattrs'])) {
06809                                 if (isset($this->message[$pos]['nil']) && $this->message[$pos]['nil']) {
06810                                         $this->message[$pos]['xattrs']['!'] = null;
06811                                 } elseif (isset($this->message[$pos]['cdata']) && trim($this->message[$pos]['cdata']) != '') {
06812                         if (isset($this->message[$pos]['type'])) {
06813                                                 $this->message[$pos]['xattrs']['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : '');
06814                                         } else {
06815                                                 $parent = $this->message[$pos]['parent'];
06816                                                 if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
06817                                                         $this->message[$pos]['xattrs']['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
06818                                                 } else {
06819                                                         $this->message[$pos]['xattrs']['!'] = $this->message[$pos]['cdata'];
06820                                                 }
06821                                         }
06822                                 }
06823                                 $this->message[$pos]['result'] = $this->message[$pos]['xattrs'];
06824                         // set value of simpleType (or nil complexType)
06825                         } else {
06826                 //$this->debug('adding data for scalar value '.$this->message[$pos]['name'].' of value '.$this->message[$pos]['cdata']);
06827                                 if (isset($this->message[$pos]['nil']) && $this->message[$pos]['nil']) {
06828                                         $this->message[$pos]['xattrs']['!'] = null;
06829                                 } elseif (isset($this->message[$pos]['type'])) {
06830                                         $this->message[$pos]['result'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : '');
06831                                 } else {
06832                                         $parent = $this->message[$pos]['parent'];
06833                                         if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
06834                                                 $this->message[$pos]['result'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
06835                                         } else {
06836                                                 $this->message[$pos]['result'] = $this->message[$pos]['cdata'];
06837                                         }
06838                                 }
06839 
06840                                 /* add value to parent's result, if parent is struct/array
06841                                 $parent = $this->message[$pos]['parent'];
06842                                 if($this->message[$parent]['type'] != 'map'){
06843                                         if(strtolower($this->message[$parent]['type']) == 'array'){
06844                                                 $this->message[$parent]['result'][] = $this->message[$pos]['result'];
06845                                         } else {
06846                                                 $this->message[$parent]['result'][$this->message[$pos]['name']] = $this->message[$pos]['result'];
06847                                         }
06848                                 }
06849                                 */
06850                         }
06851                 }
06852                 
06853         // for doclit
06854         if($this->status == 'header'){
06855                 if ($this->root_header != $pos) {
06856                         $this->responseHeaders .= "</" . (isset($prefix) ? $prefix . ':' : '') . "$name>";
06857                 }
06858         } elseif($pos >= $this->root_struct){
06859                 $this->document .= "</" . (isset($prefix) ? $prefix . ':' : '') . "$name>";
06860         }
06861                 // switch status
06862                 if($pos == $this->root_struct){
06863                         $this->status = 'body';
06864                         $this->root_struct_namespace = $this->message[$pos]['namespace'];
06865                 } elseif($name == 'Body'){
06866                         $this->status = 'envelope';
06867                  } elseif($name == 'Header'){
06868                         $this->status = 'envelope';
06869                 } elseif($name == 'Envelope'){
06870                         //
06871                 }
06872                 // set parent back to my parent
06873                 $this->parent = $this->message[$pos]['parent'];
06874         }
06875 
06883         function character_data($parser, $data){
06884                 $pos = $this->depth_array[$this->depth];
06885                 if ($this->xml_encoding=='UTF-8'){
06886                         // TODO: add an option to disable this for folks who want
06887                         // raw UTF-8 that, e.g., might not map to iso-8859-1
06888                         // TODO: this can also be handled with xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, "ISO-8859-1");
06889                         if($this->decode_utf8){
06890                                 $data = utf8_decode($data);
06891                         }
06892                 }
06893         $this->message[$pos]['cdata'] .= $data;
06894         // for doclit
06895         if($this->status == 'header'){
06896                 $this->responseHeaders .= $data;
06897         } else {
06898                 $this->document .= $data;
06899         }
06900         }
06901 
06909         function get_response(){
06910                 return $this->soapresponse;
06911         }
06912 
06919         function get_soapbody(){
06920                 return $this->soapresponse;
06921         }
06922 
06929         function get_soapheader(){
06930                 return $this->soapheader;
06931         }
06932 
06939         function getHeaders(){
06940             return $this->responseHeaders;
06941         }
06942 
06952         function decodeSimple($value, $type, $typens) {
06953                 // TODO: use the namespace!
06954                 if ((!isset($type)) || $type == 'string' || $type == 'long' || $type == 'unsignedLong') {
06955                         return (string) $value;
06956                 }
06957                 if ($type == 'int' || $type == 'integer' || $type == 'short' || $type == 'byte') {
06958                         return (int) $value;
06959                 }
06960                 if ($type == 'float' || $type == 'double' || $type == 'decimal') {
06961                         return (double) $value;
06962                 }
06963                 if ($type == 'boolean') {
06964                         if (strtolower($value) == 'false' || strtolower($value) == 'f') {
06965                                 return false;
06966                         }
06967                         return (boolean) $value;
06968                 }
06969                 if ($type == 'base64' || $type == 'base64Binary') {
06970                         $this->debug('Decode base64 value');
06971                         return base64_decode($value);
06972                 }
06973                 // obscure numeric types
06974                 if ($type == 'nonPositiveInteger' || $type == 'negativeInteger'
06975                         || $type == 'nonNegativeInteger' || $type == 'positiveInteger'
06976                         || $type == 'unsignedInt'
06977                         || $type == 'unsignedShort' || $type == 'unsignedByte') {
06978                         return (int) $value;
06979                 }
06980                 // bogus: parser treats array with no elements as a simple type
06981                 if ($type == 'array') {
06982                         return array();
06983                 }
06984                 // everything else
06985                 return (string) $value;
06986         }
06987 
06996         function buildVal($pos){
06997                 if(!isset($this->message[$pos]['type'])){
06998                         $this->message[$pos]['type'] = '';
06999                 }
07000                 $this->debug('in buildVal() for '.$this->message[$pos]['name']."(pos $pos) of type ".$this->message[$pos]['type']);
07001                 // if there are children...
07002                 if($this->message[$pos]['children'] != ''){
07003                         $this->debug('in buildVal, there are children');
07004                         $children = explode('|',$this->message[$pos]['children']);
07005                         array_shift($children); // knock off empty
07006                         // md array
07007                         if(isset($this->message[$pos]['arrayCols']) && $this->message[$pos]['arrayCols'] != ''){
07008                 $r=0; // rowcount
07009                 $c=0; // colcount
07010                 foreach($children as $child_pos){
07011                                         $this->debug("in buildVal, got an MD array element: $r, $c");
07012                                         $params[$r][] = $this->message[$child_pos]['result'];
07013                                     $c++;
07014                                     if($c == $this->message[$pos]['arrayCols']){
07015                                         $c = 0;
07016                                                 $r++;
07017                                     }
07018                 }
07019             // array
07020                         } elseif($this->message[$pos]['type'] == 'array' || $this->message[$pos]['type'] == 'Array'){
07021                 $this->debug('in buildVal, adding array '.$this->message[$pos]['name']);
07022                 foreach($children as $child_pos){
07023                         $params[] = &$this->message[$child_pos]['result'];
07024                 }
07025             // apache Map type: java hashtable
07026             } elseif($this->message[$pos]['type'] == 'Map' && $this->message[$pos]['type_namespace'] == 'http://xml.apache.org/xml-soap'){
07027                 $this->debug('in buildVal, Java Map '.$this->message[$pos]['name']);
07028                 foreach($children as $child_pos){
07029                         $kv = explode("|",$this->message[$child_pos]['children']);
07030                         $params[$this->message[$kv[1]]['result']] = &$this->message[$kv[2]]['result'];
07031                 }
07032             // generic compound type
07033             //} elseif($this->message[$pos]['type'] == 'SOAPStruct' || $this->message[$pos]['type'] == 'struct') {
07034                     } else {
07035                         // Apache Vector type: treat as an array
07036                 $this->debug('in buildVal, adding Java Vector or generic compound type '.$this->message[$pos]['name']);
07037                                 if ($this->message[$pos]['type'] == 'Vector' && $this->message[$pos]['type_namespace'] == 'http://xml.apache.org/xml-soap') {
07038                                         $notstruct = 1;
07039                                 } else {
07040                                         $notstruct = 0;
07041                     }
07042                 //
07043                 foreach($children as $child_pos){
07044                         if($notstruct){
07045                                 $params[] = &$this->message[$child_pos]['result'];
07046                         } else {
07047                                 if (isset($params[$this->message[$child_pos]['name']])) {
07048                                         // de-serialize repeated element name into an array
07049                                         if ((!is_array($params[$this->message[$child_pos]['name']])) || (!isset($params[$this->message[$child_pos]['name']][0]))) {
07050                                                 $params[$this->message[$child_pos]['name']] = array($params[$this->message[$child_pos]['name']]);
07051                                         }
07052                                         $params[$this->message[$child_pos]['name']][] = &$this->message[$child_pos]['result'];
07053                                 } else {
07054                                                 $params[$this->message[$child_pos]['name']] = &$this->message[$child_pos]['result'];
07055                                             }
07056                         }
07057                 }
07058                         }
07059                         if (isset($this->message[$pos]['xattrs'])) {
07060                 $this->debug('in buildVal, handling attributes');
07061                                 foreach ($this->message[$pos]['xattrs'] as $n => $v) {
07062                                         $params[$n] = $v;
07063                                 }
07064                         }
07065                         // handle simpleContent
07066                         if (isset($this->message[$pos]['cdata']) && trim($this->message[$pos]['cdata']) != '') {
07067                 $this->debug('in buildVal, handling simpleContent');
07068                 if (isset($this->message[$pos]['type'])) {
07069                                         $params['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : '');
07070                                 } else {
07071                                         $parent = $this->message[$pos]['parent'];
07072                                         if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
07073                                                 $params['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
07074                                         } else {
07075                                                 $params['!'] = $this->message[$pos]['cdata'];
07076                                         }
07077                                 }
07078                         }
07079                         $ret = is_array($params) ? $params : array();
07080                         $this->debug('in buildVal, return:');
07081                         $this->appendDebug($this->varDump($ret));
07082                         return $ret;
07083                 } else {
07084                 $this->debug('in buildVal, no children, building scalar');
07085                         $cdata = isset($this->message[$pos]['cdata']) ? $this->message[$pos]['cdata'] : '';
07086                 if (isset($this->message[$pos]['type'])) {
07087                                 $ret = $this->decodeSimple($cdata, $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : '');
07088                                 $this->debug("in buildVal, return: $ret");
07089                                 return $ret;
07090                         }
07091                         $parent = $this->message[$pos]['parent'];
07092                         if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
07093                                 $ret = $this->decodeSimple($cdata, $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
07094                                 $this->debug("in buildVal, return: $ret");
07095                                 return $ret;
07096                         }
07097                 $ret = $this->message[$pos]['cdata'];
07098                         $this->debug("in buildVal, return: $ret");
07099                 return $ret;
07100                 }
07101         }
07102 }
07103 
07107 class soap_parser extends nusoap_parser {
07108 }
07109 
07110 ?><?php
07111 
07112 
07113 
07134 class nusoap_client extends nusoap_base  {
07135 
07136         var $username = '';                             // Username for HTTP authentication
07137         var $password = '';                             // Password for HTTP authentication
07138         var $authtype = '';                             // Type of HTTP authentication
07139         var $certRequest = array();             // Certificate for HTTP SSL authentication
07140         var $requestHeaders = false;    // SOAP headers in request (text)
07141         var $responseHeaders = '';              // SOAP headers from response (incomplete namespace resolution) (text)
07142         var $responseHeader = NULL;             // SOAP Header from response (parsed)
07143         var $document = '';                             // SOAP body response portion (incomplete namespace resolution) (text)
07144         var $endpoint;
07145         var $forceEndpoint = '';                // overrides WSDL endpoint
07146     var $proxyhost = '';
07147     var $proxyport = '';
07148         var $proxyusername = '';
07149         var $proxypassword = '';
07150         var $portName = '';                             // port name to use in WSDL
07151     var $xml_encoding = '';                     // character set encoding of incoming (response) messages
07152         var $http_encoding = false;
07153         var $timeout = 0;                               // HTTP connection timeout
07154         var $response_timeout = 30;             // HTTP response timeout
07155         var $endpointType = '';                 // soap|wsdl, empty for WSDL initialization error
07156         var $persistentConnection = false;
07157         var $defaultRpcParams = false;  // This is no longer used
07158         var $request = '';                              // HTTP request
07159         var $response = '';                             // HTTP response
07160         var $responseData = '';                 // SOAP payload of response
07161         var $cookies = array();                 // Cookies from response or for request
07162     var $decode_utf8 = true;            // toggles whether the parser decodes element content w/ utf8_decode()
07163         var $operations = array();              // WSDL operations, empty for WSDL initialization error
07164         var $curl_options = array();    // User-specified cURL options
07165         var $bindingType = '';                  // WSDL operation binding type
07166         var $use_curl = false;                  // whether to always try to use cURL
07167 
07168         /*
07169          * fault related variables
07170          */
07175         var $fault;
07180         var $faultcode;
07185         var $faultstring;
07190         var $faultdetail;
07191 
07206         function nusoap_client($endpoint,$wsdl = false,$proxyhost = false,$proxyport = false,$proxyusername = false, $proxypassword = false, $timeout = 0, $response_timeout = 30, $portName = ''){
07207                 parent::nusoap_base();
07208                 $this->endpoint = $endpoint;
07209                 $this->proxyhost = $proxyhost;
07210                 $this->proxyport = $proxyport;
07211                 $this->proxyusername = $proxyusername;
07212                 $this->proxypassword = $proxypassword;
07213                 $this->timeout = $timeout;
07214                 $this->response_timeout = $response_timeout;
07215                 $this->portName = $portName;
07216 
07217                 $this->debug("ctor wsdl=$wsdl timeout=$timeout response_timeout=$response_timeout");
07218                 $this->appendDebug('endpoint=' . $this->varDump($endpoint));
07219 
07220                 // make values
07221                 if($wsdl){
07222                         if (is_object($endpoint) && (get_class($endpoint) == 'wsdl')) {
07223                                 $this->wsdl = $endpoint;
07224                                 $this->endpoint = $this->wsdl->wsdl;
07225                                 $this->wsdlFile = $this->endpoint;
07226                                 $this->debug('existing wsdl instance created from ' . $this->endpoint);
07227                                 $this->checkWSDL();
07228                         } else {
07229                                 $this->wsdlFile = $this->endpoint;
07230                                 $this->wsdl = null;
07231                                 $this->debug('will use lazy evaluation of wsdl from ' . $this->endpoint);
07232                         }
07233                         $this->endpointType = 'wsdl';
07234                 } else {
07235                         $this->debug("instantiate SOAP with endpoint at $endpoint");
07236                         $this->endpointType = 'soap';
07237                 }
07238         }
07239 
07265         function call($operation,$params=array(),$namespace='http://tempuri.org',$soapAction='',$headers=false,$rpcParams=null,$style='rpc',$use='encoded'){
07266                 $this->operation = $operation;
07267                 $this->fault = false;
07268                 $this->setError('');
07269                 $this->request = '';
07270                 $this->response = '';
07271                 $this->responseData = '';
07272                 $this->faultstring = '';
07273                 $this->faultcode = '';
07274                 $this->opData = array();
07275                 
07276                 $this->debug("call: operation=$operation, namespace=$namespace, soapAction=$soapAction, rpcParams=$rpcParams, style=$style, use=$use, endpointType=$this->endpointType");
07277                 $this->appendDebug('params=' . $this->varDump($params));
07278                 $this->appendDebug('headers=' . $this->varDump($headers));
07279                 if ($headers) {
07280                         $this->requestHeaders = $headers;
07281                 }
07282                 if ($this->endpointType == 'wsdl' && is_null($this->wsdl)) {
07283                         $this->loadWSDL();
07284                         if ($this->getError())
07285                                 return false;
07286                 }
07287                 // serialize parameters
07288                 if($this->endpointType == 'wsdl' && $opData = $this->getOperationData($operation)){
07289                         // use WSDL for operation
07290                         $this->opData = $opData;
07291                         $this->debug("found operation");
07292                         $this->appendDebug('opData=' . $this->varDump($opData));
07293                         if (isset($opData['soapAction'])) {
07294                                 $soapAction = $opData['soapAction'];
07295                         }
07296                         if (! $this->forceEndpoint) {
07297                                 $this->endpoint = $opData['endpoint'];
07298                         } else {
07299                                 $this->endpoint = $this->forceEndpoint;
07300                         }
07301                         $namespace = isset($opData['input']['namespace']) ? $opData['input']['namespace'] :     $namespace;
07302                         $style = $opData['style'];
07303                         $use = $opData['input']['use'];
07304                         // add ns to ns array
07305                         if($namespace != '' && !isset($this->wsdl->namespaces[$namespace])){
07306                                 $nsPrefix = 'ns' . rand(1000, 9999);
07307                                 $this->wsdl->namespaces[$nsPrefix] = $namespace;
07308                         }
07309             $nsPrefix = $this->wsdl->getPrefixFromNamespace($namespace);
07310                         // serialize payload
07311                         if (is_string($params)) {
07312                                 $this->debug("serializing param string for WSDL operation $operation");
07313                                 $payload = $params;
07314                         } elseif (is_array($params)) {
07315                                 $this->debug("serializing param array for WSDL operation $operation");
07316                                 $payload = $this->wsdl->serializeRPCParameters($operation,'input',$params,$this->bindingType);
07317                         } else {
07318                                 $this->debug('params must be array or string');
07319                                 $this->setError('params must be array or string');
07320                                 return false;
07321                         }
07322             $usedNamespaces = $this->wsdl->usedNamespaces;
07323                         if (isset($opData['input']['encodingStyle'])) {
07324                                 $encodingStyle = $opData['input']['encodingStyle'];
07325                         } else {
07326                                 $encodingStyle = '';
07327                         }
07328                         $this->appendDebug($this->wsdl->getDebug());
07329                         $this->wsdl->clearDebug();
07330                         if ($errstr = $this->wsdl->getError()) {
07331                                 $this->debug('got wsdl error: '.$errstr);
07332                                 $this->setError('wsdl error: '.$errstr);
07333                                 return false;
07334                         }
07335                 } elseif($this->endpointType == 'wsdl') {
07336                         // operation not in WSDL
07337                         $this->appendDebug($this->wsdl->getDebug());
07338                         $this->wsdl->clearDebug();
07339                         $this->setError( 'operation '.$operation.' not present.');
07340                         $this->debug("operation '$operation' not present.");
07341                         return false;
07342                 } else {
07343                         // no WSDL
07344                         //$this->namespaces['ns1'] = $namespace;
07345                         $nsPrefix = 'ns' . rand(1000, 9999);
07346                         // serialize 
07347                         $payload = '';
07348                         if (is_string($params)) {
07349                                 $this->debug("serializing param string for operation $operation");
07350                                 $payload = $params;
07351                         } elseif (is_array($params)) {
07352                                 $this->debug("serializing param array for operation $operation");
07353                                 foreach($params as $k => $v){
07354                                         $payload .= $this->serialize_val($v,$k,false,false,false,false,$use);
07355                                 }
07356                         } else {
07357                                 $this->debug('params must be array or string');
07358                                 $this->setError('params must be array or string');
07359                                 return false;
07360                         }
07361                         $usedNamespaces = array();
07362                         if ($use == 'encoded') {
07363                                 $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
07364                         } else {
07365                                 $encodingStyle = '';
07366                         }
07367                 }
07368                 // wrap RPC calls with method element
07369                 if ($style == 'rpc') {
07370                         if ($use == 'literal') {
07371                                 $this->debug("wrapping RPC request with literal method element");
07372                                 if ($namespace) {
07373                                         // 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
07374                                         $payload = "<$nsPrefix:$operation xmlns:$nsPrefix=\"$namespace\">" .
07375                                                                 $payload .
07376                                                                 "</$nsPrefix:$operation>";
07377                                 } else {
07378                                         $payload = "<$operation>" . $payload . "</$operation>";
07379                                 }
07380                         } else {
07381                                 $this->debug("wrapping RPC request with encoded method element");
07382                                 if ($namespace) {
07383                                         $payload = "<$nsPrefix:$operation xmlns:$nsPrefix=\"$namespace\">" .
07384                                                                 $payload .
07385                                                                 "</$nsPrefix:$operation>";
07386                                 } else {
07387                                         $payload = "<$operation>" .
07388                                                                 $payload .
07389                                                                 "</$operation>";
07390                                 }
07391                         }
07392                 }
07393                 // serialize envelope
07394                 $soapmsg = $this->serializeEnvelope($payload,$this->requestHeaders,$usedNamespaces,$style,$use,$encodingStyle);
07395                 $this->debug("endpoint=$this->endpoint, soapAction=$soapAction, namespace=$namespace, style=$style, use=$use, encodingStyle=$encodingStyle");
07396                 $this->debug('SOAP message length=' . strlen($soapmsg) . ' contents (max 1000 bytes)=' . substr($soapmsg, 0, 1000));
07397                 // send
07398                 $return = $this->send($this->getHTTPBody($soapmsg),$soapAction,$this->timeout,$this->response_timeout);
07399                 if($errstr = $this->getError()){
07400                         $this->debug('Error: '.$errstr);
07401                         return false;
07402                 } else {
07403                         $this->return = $return;
07404                         $this->debug('sent message successfully and got a(n) '.gettype($return));
07405                 $this->appendDebug('return=' . $this->varDump($return));
07406                         
07407                         // fault?
07408                         if(is_array($return) && isset($return['faultcode'])){
07409                                 $this->debug('got fault');
07410                                 $this->setError($return['faultcode'].': '.$return['faultstring']);
07411                                 $this->fault = true;
07412                                 foreach($return as $k => $v){
07413                                         $this->$k = $v;
07414                                         $this->debug("$k = $v<br>");
07415                                 }
07416                                 return $return;
07417                         } elseif ($style == 'document') {
07418                                 // NOTE: if the response is defined to have multiple parts (i.e. unwrapped),
07419                                 // we are only going to return the first part here...sorry about that
07420                                 return $return;
07421                         } else {
07422                                 // array of return values
07423                                 if(is_array($return)){
07424                                         // multiple 'out' parameters, which we return wrapped up
07425                                         // in the array
07426                                         if(sizeof($return) > 1){
07427                                                 return $return;
07428                                         }
07429                                         // single 'out' parameter (normally the return value)
07430                                         $return = array_shift($return);
07431                                         $this->debug('return shifted value: ');
07432                                         $this->appendDebug($this->varDump($return));
07433                                 return $return;
07434                                 // nothing returned (ie, echoVoid)
07435                                 } else {
07436                                         return "";
07437                                 }
07438                         }
07439                 }
07440         }
07441 
07447         function checkWSDL() {
07448                 $this->appendDebug($this->wsdl->getDebug());
07449                 $this->wsdl->clearDebug();
07450                 $this->debug('checkWSDL');
07451                 // catch errors
07452                 if ($errstr = $this->wsdl->getError()) {
07453                         $this->appendDebug($this->wsdl->getDebug());
07454                         $this->wsdl->clearDebug();
07455                         $this->debug('got wsdl error: '.$errstr);
07456                         $this->setError('wsdl error: '.$errstr);
07457                 } elseif ($this->operations = $this->wsdl->getOperations($this->portName, 'soap')) {
07458                         $this->appendDebug($this->wsdl->getDebug());
07459                         $this->wsdl->clearDebug();
07460                         $this->bindingType = 'soap';
07461                         $this->debug('got '.count($this->operations).' operations from wsdl '.$this->wsdlFile.' for binding type '.$this->bindingType);
07462                 } elseif ($this->operations = $this->wsdl->getOperations($this->portName, 'soap12')) {
07463                         $this->appendDebug($this->wsdl->getDebug());
07464                         $this->wsdl->clearDebug();
07465                         $this->bindingType = 'soap12';
07466                         $this->debug('got '.count($this->operations).' operations from wsdl '.$this->wsdlFile.' for binding type '.$this->bindingType);
07467                         $this->debug('**************** WARNING: SOAP 1.2 BINDING *****************');
07468                 } else {
07469                         $this->appendDebug($this->wsdl->getDebug());
07470                         $this->wsdl->clearDebug();
07471                         $this->debug('getOperations returned false');
07472                         $this->setError('no operations defined in the WSDL document!');
07473                 }
07474         }
07475 
07481         function loadWSDL() {
07482                 $this->debug('instantiating wsdl class with doc: '.$this->wsdlFile);
07483                 $this->wsdl =& new wsdl('',$this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword,$this->timeout,$this->response_timeout,$this->curl_options,$this->use_curl);
07484                 $this->wsdl->setCredentials($this->username, $this->password, $this->authtype, $this->certRequest);
07485                 $this->wsdl->fetchWSDL($this->wsdlFile);
07486                 $this->checkWSDL();
07487         }
07488 
07496         function getOperationData($operation){
07497                 if ($this->endpointType == 'wsdl' && is_null($this->wsdl)) {
07498                         $this->loadWSDL();
07499                         if ($this->getError())
07500                                 return false;
07501                 }
07502                 if(isset($this->operations[$operation])){
07503                         return $this->operations[$operation];
07504                 }
07505                 $this->debug("No data for operation: $operation");
07506         }
07507 
07522         function send($msg, $soapaction = '', $timeout=0, $response_timeout=30) {
07523                 $this->checkCookies();
07524                 // detect transport
07525                 switch(true){
07526                         // http(s)
07527                         case ereg('^http',$this->endpoint):
07528                                 $this->debug('transporting via HTTP');
07529                                 if($this->persistentConnection == true && is_object($this->persistentConnection)){
07530                                         $http =& $this->persistentConnection;
07531                                 } else {
07532                                         $http = new soap_transport_http($this->endpoint, $this->curl_options, $this->use_curl);
07533                                         if ($this->persistentConnection) {
07534                                                 $http->usePersistentConnection();
07535                                         }
07536                                 }
07537                                 $http->setContentType($this->getHTTPContentType(), $this->getHTTPContentTypeCharset());
07538                                 $http->setSOAPAction($soapaction);
07539                                 if($this->proxyhost && $this->proxyport){
07540                                         $http->setProxy($this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword);
07541                                 }
07542                 if($this->authtype != '') {
07543                                         $http->setCredentials($this->username, $this->password, $this->authtype, array(), $this->certRequest);
07544                                 }
07545                                 if($this->http_encoding != ''){
07546                                         $http->setEncoding($this->http_encoding);
07547                                 }
07548                                 $this->debug('sending message, length='.strlen($msg));
07549                                 if(ereg('^http:',$this->endpoint)){
07550                                 //if(strpos($this->endpoint,'http:')){
07551                                         $this->responseData = $http->send($msg,$timeout,$response_timeout,$this->cookies);
07552                                 } elseif(ereg('^https',$this->endpoint)){
07553                                 //} elseif(strpos($this->endpoint,'https:')){
07554                                         //if(phpversion() == '4.3.0-dev'){
07555                                                 //$response = $http->send($msg,$timeout,$response_timeout);
07556                                 //$this->request = $http->outgoing_payload;
07557                                                 //$this->response = $http->incoming_payload;
07558                                         //} else
07559                                         $this->responseData = $http->sendHTTPS($msg,$timeout,$response_timeout,$this->cookies);
07560                                 } else {
07561                                         $this->setError('no http/s in endpoint url');
07562                                 }
07563                                 $this->request = $http->outgoing_payload;
07564                                 $this->response = $http->incoming_payload;
07565                                 $this->appendDebug($http->getDebug());
07566                                 $this->UpdateCookies($http->incoming_cookies);
07567 
07568                                 // save transport object if using persistent connections
07569                                 if ($this->persistentConnection) {
07570                                         $http->clearDebug();
07571                                         if (!is_object($this->persistentConnection)) {
07572                                                 $this->persistentConnection = $http;
07573                                         }
07574                                 }
07575                                 
07576                                 if($err = $http->getError()){
07577                                         $this->setError('HTTP Error: '.$err);
07578                                         return false;
07579                                 } elseif($this->getError()){
07580                                         return false;
07581                                 } else {
07582                                         $this->debug('got response, length='. strlen($this->responseData).' type='.$http->incoming_headers['content-type']);
07583                                         return $this->parseResponse($http->incoming_headers, $this->responseData);
07584                                 }
07585                         break;
07586                         default:
07587                                 $this->setError('no transport found, or selected transport is not yet supported!');
07588                         return false;
07589                         break;
07590                 }
07591         }
07592 
07601     function parseResponse($headers, $data) {
07602                 $this->debug('Entering parseResponse() for data of length ' . strlen($data) . ' headers:');
07603                 $this->appendDebug($this->varDump($headers));
07604         if (!isset($headers['content-type'])) {
07605                         $this->setError('Response not of type text/xml (no content-type header)');
07606                         return false;
07607         }
07608                 if (!strstr($headers['content-type'], 'text/xml')) {
07609                         $this->setError('Response not of type text/xml: ' . $headers['content-type']);
07610                         return false;
07611                 }
07612                 if (strpos($headers['content-type'], '=')) {
07613                         $enc = str_replace('"', '', substr(strstr($headers["content-type"], '='), 1));
07614                         $this->debug('Got response encoding: ' . $enc);
07615                         if(eregi('^(ISO-8859-1|US-ASCII|UTF-8)$',$enc)){
07616                                 $this->xml_encoding = strtoupper($enc);
07617                         } else {
07618                                 $this->xml_encoding = 'US-ASCII';
07619                         }
07620                 } else {
07621                         // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
07622                         $this->xml_encoding = 'ISO-8859-1';
07623                 }
07624                 $this->debug('Use encoding: ' . $this->xml_encoding . ' when creating nusoap_parser');
07625                 $parser = new nusoap_parser($data,$this->xml_encoding,$this->operation,$this->decode_utf8);
07626                 // add parser debug data to our debug
07627                 $this->appendDebug($parser->getDebug());
07628                 // if parse errors
07629                 if($errstr = $parser->getError()){
07630                         $this->setError( $errstr);
07631                         // destroy the parser object
07632                         unset($parser);
07633                         return false;
07634                 } else {
07635                         // get SOAP headers
07636                         $this->responseHeaders = $parser->getHeaders();
07637                         // get SOAP headers
07638                         $this->responseHeader = $parser->get_soapheader();
07639                         // get decoded message
07640                         $return = $parser->get_soapbody();
07641             // add document for doclit support
07642             $this->document = $parser->document;
07643                         // destroy the parser object
07644                         unset($parser);
07645                         // return decode message
07646                         return $return;
07647                 }
07648          }
07649 
07657         function setCurlOption($option, $value) {
07658                 $this->debug("setCurlOption option=$option, value=");
07659                 $this->appendDebug($this->varDump($value));
07660                 $this->curl_options[$option] = $value;
07661         }
07662 
07669         function setEndpoint($endpoint) {
07670                 $this->debug("setEndpoint(\"$endpoint\")");
07671                 $this->forceEndpoint = $endpoint;
07672         }
07673 
07680         function setHeaders($headers){
07681                 $this->debug("setHeaders headers=");
07682                 $this->appendDebug($this->varDump($headers));
07683                 $this->requestHeaders = $headers;
07684         }
07685 
07692         function getHeaders(){
07693                 return $this->responseHeaders;
07694         }
07695 
07702         function getHeader(){
07703                 return $this->responseHeader;
07704         }
07705 
07715         function setHTTPProxy($proxyhost, $proxyport, $proxyusername = '', $proxypassword = '') {
07716                 $this->proxyhost = $proxyhost;
07717                 $this->proxyport = $proxyport;
07718                 $this->proxyusername = $proxyusername;
07719                 $this->proxypassword = $proxypassword;
07720         }
07721 
07731         function setCredentials($username, $password, $authtype = 'basic', $certRequest = array()) {
07732                 $this->debug("setCredentials username=$username authtype=$authtype certRequest=");
07733                 $this->appendDebug($this->varDump($certRequest));
07734                 $this->username = $username;
07735                 $this->password = $password;
07736                 $this->authtype = $authtype;
07737                 $this->certRequest = $certRequest;
07738         }
07739         
07746         function setHTTPEncoding($enc='gzip, deflate'){
07747                 $this->debug("setHTTPEncoding(\"$enc\")");
07748                 $this->http_encoding = $enc;
07749         }
07750         
07757         function setUseCURL($use) {
07758                 $this->debug("setUseCURL($use)");
07759                 $this->use_curl = $use;
07760         }
07761 
07767         function useHTTPPersistentConnection(){
07768                 $this->debug("useHTTPPersistentConnection");
07769                 $this->persistentConnection = true;
07770         }
07771         
07783         function getDefaultRpcParams() {
07784                 return $this->defaultRpcParams;
07785         }
07786 
07798         function setDefaultRpcParams($rpcParams) {
07799                 $this->defaultRpcParams = $rpcParams;
07800         }
07801         
07809         function getProxy() {
07810                 $r = rand();
07811                 $evalStr = $this->_getProxyClassCode($r);
07812                 //$this->debug("proxy class: $evalStr");
07813                 if ($this->getError()) {
07814                         $this->debug("Error from _getProxyClassCode, so return NULL");
07815                         return null;
07816                 }
07817                 // eval the class
07818                 eval($evalStr);
07819                 // instantiate proxy object
07820                 eval("\$proxy = new nusoap_proxy_$r('');");
07821                 // transfer current wsdl data to the proxy thereby avoiding parsing the wsdl twice
07822                 $proxy->endpointType = 'wsdl';
07823                 $proxy->wsdlFile = $this->wsdlFile;
07824                 $proxy->wsdl = $this->wsdl;
07825                 $proxy->operations = $this->operations;
07826                 $proxy->defaultRpcParams = $this->defaultRpcParams;
07827                 // transfer other state
07828                 $proxy->soap_defencoding = $this->soap_defencoding;
07829                 $proxy->username = $this->username;
07830                 $proxy->password = $this->password;
07831                 $proxy->authtype = $this->authtype;
07832                 $proxy->certRequest = $this->certRequest;
07833                 $proxy->requestHeaders = $this->requestHeaders;
07834                 $proxy->endpoint = $this->endpoint;
07835                 $proxy->forceEndpoint = $this->forceEndpoint;
07836                 $proxy->proxyhost = $this->proxyhost;
07837                 $proxy->proxyport = $this->proxyport;
07838                 $proxy->proxyusername = $this->proxyusername;
07839                 $proxy->proxypassword = $this->proxypassword;
07840                 $proxy->http_encoding = $this->http_encoding;
07841                 $proxy->timeout = $this->timeout;
07842                 $proxy->response_timeout = $this->response_timeout;
07843                 $proxy->persistentConnection = &$this->persistentConnection;
07844                 $proxy->decode_utf8 = $this->decode_utf8;
07845                 $proxy->curl_options = $this->curl_options;
07846                 $proxy->bindingType = $this->bindingType;
07847                 $proxy->use_curl = $this->use_curl;
07848                 return $proxy;
07849         }
07850 
07857         function _getProxyClassCode($r) {
07858                 $this->debug("in getProxy endpointType=$this->endpointType");
07859                 $this->appendDebug("wsdl=" . $this->varDump($this->wsdl));
07860                 if ($this->endpointType != 'wsdl') {
07861                         $evalStr = 'A proxy can only be created for a WSDL client';
07862                         $this->setError($evalStr);
07863                         $evalStr = "echo \"$evalStr\";";
07864                         return $evalStr;
07865                 }
07866                 if ($this->endpointType == 'wsdl' && is_null($this->wsdl)) {
07867                         $this->loadWSDL();
07868                         if ($this->getError()) {
07869                                 return "echo \"" . $this->getError() . "\";";
07870                         }
07871                 }
07872                 $evalStr = '';
07873                 foreach ($this->operations as $operation => $opData) {
07874                         if ($operation != '') {
07875                                 // create param string and param comment string
07876                                 if (sizeof($opData['input']['parts']) > 0) {
07877                                         $paramStr = '';
07878                                         $paramArrayStr = '';
07879                                         $paramCommentStr = '';
07880                                         foreach ($opData['input']['parts'] as $name => $type) {
07881                                                 $paramStr .= "\$$name, ";
07882                                                 $paramArrayStr .= "'$name' => \$$name, ";
07883                                                 $paramCommentStr .= "$type \$$name, ";
07884                                         }
07885                                         $paramStr = substr($paramStr, 0, strlen($paramStr)-2);
07886                                         $paramArrayStr = substr($paramArrayStr, 0, strlen($paramArrayStr)-2);
07887                                         $paramCommentStr = substr($paramCommentStr, 0, strlen($paramCommentStr)-2);
07888                                 } else {
07889                                         $paramStr = '';
07890                                         $paramArrayStr = '';
07891                                         $paramCommentStr = 'void';
07892                                 }
07893                                 $opData['namespace'] = !isset($opData['namespace']) ? 'http://testuri.com' : $opData['namespace'];
07894                                 $evalStr .= "// $paramCommentStr
07895         function " . str_replace('.', '__', $operation) . "($paramStr) {
07896                 \$params = array($paramArrayStr);
07897                 return \$this->call('$operation', \$params, '".$opData['namespace']."', '".(isset($opData['soapAction']) ? $opData['soapAction'] : '')."');
07898         }
07899         ";
07900                                 unset($paramStr);
07901                                 unset($paramCommentStr);
07902                         }
07903                 }
07904                 $evalStr = 'class nusoap_proxy_'.$r.' extends nusoap_client {
07905         '.$evalStr.'
07906 }';
07907                 return $evalStr;
07908         }
07909 
07916         function getProxyClassCode() {
07917                 $r = rand();
07918                 return $this->_getProxyClassCode($r);
07919         }
07920 
07928         function getHTTPBody($soapmsg) {
07929                 return $soapmsg;
07930         }
07931         
07940         function getHTTPContentType() {
07941                 return 'text/xml';
07942         }
07943         
07953         function getHTTPContentTypeCharset() {
07954                 return $this->soap_defencoding;
07955         }
07956 
07957         /*
07958         * whether or not parser should decode utf8 element content
07959     *
07960     * @return   always returns true
07961     * @access   public
07962     */
07963     function decodeUTF8($bool){
07964                 $this->decode_utf8 = $bool;
07965                 return true;
07966     }
07967 
07976         function setCookie($name, $value) {
07977                 if (strlen($name) == 0) {
07978                         return false;
07979                 }
07980                 $this->cookies[] = array('name' => $name, 'value' => $value);
07981                 return true;
07982         }
07983 
07990         function getCookies() {
07991                 return $this->cookies;
07992         }
07993 
08000         function checkCookies() {
08001                 if (sizeof($this->cookies) == 0) {
08002                         return true;
08003                 }
08004                 $this->debug('checkCookie: check ' . sizeof($this->cookies) . ' cookies');
08005                 $curr_cookies = $this->cookies;
08006                 $this->cookies = array();
08007                 foreach ($curr_cookies as $cookie) {
08008                         if (! is_array($cookie)) {
08009                                 $this->debug('Remove cookie that is not an array');
08010                                 continue;
08011                         }
08012                         if ((isset($cookie['expires'])) && (! empty($cookie['expires']))) {
08013                                 if (strtotime($cookie['expires']) > time()) {
08014                                         $this->cookies[] = $cookie;
08015                                 } else {
08016                                         $this->debug('Remove expired cookie ' . $cookie['name']);
08017                                 }
08018                         } else {
08019                                 $this->cookies[] = $cookie;
08020                         }
08021                 }
08022                 $this->debug('checkCookie: '.sizeof($this->cookies).' cookies left in array');
08023                 return true;
08024         }
08025 
08033         function UpdateCookies($cookies) {
08034                 if (sizeof($this->cookies) == 0) {
08035                         // no existing cookies: take whatever is new
08036                         if (sizeof($cookies) > 0) {
08037                                 $this->debug('Setting new cookie(s)');
08038                                 $this->cookies = $cookies;
08039                         }
08040                         return true;
08041                 }
08042                 if (sizeof($cookies) == 0) {
08043                         // no new cookies: keep what we've got
08044                         return true;
08045                 }
08046                 // merge
08047                 foreach ($cookies as $newCookie) {
08048                         if (!is_array($newCookie)) {
08049                                 continue;
08050                         }
08051                         if ((!isset($newCookie['name'])) || (!isset($newCookie['value']))) {
08052                                 continue;
08053                         }
08054                         $newName = $newCookie['name'];
08055 
08056                         $found = false;
08057                         for ($i = 0; $i < count($this->cookies); $i++) {
08058                                 $cookie = $this->cookies[$i];
08059                                 if (!is_array($cookie)) {
08060                                         continue;
08061                                 }
08062                                 if (!isset($cookie['name'])) {
08063                                         continue;
08064                                 }
08065                                 if ($newName != $cookie['name']) {
08066                                         continue;
08067                                 }
08068                                 $newDomain = isset($newCookie['domain']) ? $newCookie['domain'] : 'NODOMAIN';
08069                                 $domain = isset($cookie['domain']) ? $cookie['domain'] : 'NODOMAIN';
08070                                 if ($newDomain != $domain) {
08071                                         continue;
08072                                 }
08073                                 $newPath = isset($newCookie['path']) ? $newCookie['path'] : 'NOPATH';
08074                                 $path = isset($cookie['path']) ? $cookie['path'] : 'NOPATH';
08075                                 if ($newPath != $path) {
08076                                         continue;
08077                                 }
08078                                 $this->cookies[$i] = $newCookie;
08079                                 $found = true;
08080                                 $this->debug('Update cookie ' . $newName . '=' . $newCookie['value']);
08081                                 break;
08082                         }
08083                         if (! $found) {
08084                                 $this->debug('Add cookie ' . $newName . '=' . $newCookie['value']);
08085                                 $this->cookies[] = $newCookie;
08086                         }
08087                 }
08088                 return true;
08089         }
08090 }
08091 
08092 if (!extension_loaded('soap')) {
08096         class soapclient extends nusoap_client {
08097         }
08098 }


Variablen-Dokumentation

$GLOBALS['_transient']['static']['nusoap_base']['globalDebugLevel'] = 9

Definiert in Zeile 74 der Datei nusoap.php.

Copyright © 2003 - 2009 MyOOS [Shopsystem]. All rights reserved.
MyOOS [Shopsystem] is Free Software released under the GNU/GPL License.

Webmaster: info@r23.de (Impressum)
doxygen