/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'][