shop.balmet.com

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

class.soap_server.php (39941B)


      1 <?php
      2 
      3 
      4 
      5 
      6 /**
      7 *
      8 * nusoap_server allows the user to create a SOAP server
      9 * that is capable of receiving messages and returning responses
     10 *
     11 * @author   Dietrich Ayala <dietrich@ganx4.com>
     12 * @author   Scott Nichol <snichol@users.sourceforge.net>
     13 * @version  $Id: class.soap_server.php,v 1.63 2010/04/26 20:15:08 snichol Exp $
     14 * @access   public
     15 */
     16 class nusoap_server extends nusoap_base {
     17 	/**
     18 	 * HTTP headers of request
     19 	 * @var array
     20 	 * @access private
     21 	 */
     22 	var $headers = array();
     23 	/**
     24 	 * HTTP request
     25 	 * @var string
     26 	 * @access private
     27 	 */
     28 	var $request = '';
     29 	/**
     30 	 * SOAP headers from request (incomplete namespace resolution; special characters not escaped) (text)
     31 	 * @var string
     32 	 * @access public
     33 	 */
     34 	var $requestHeaders = '';
     35 	/**
     36 	 * SOAP Headers from request (parsed)
     37 	 * @var mixed
     38 	 * @access public
     39 	 */
     40 	var $requestHeader = NULL;
     41 	/**
     42 	 * SOAP body request portion (incomplete namespace resolution; special characters not escaped) (text)
     43 	 * @var string
     44 	 * @access public
     45 	 */
     46 	var $document = '';
     47 	/**
     48 	 * SOAP payload for request (text)
     49 	 * @var string
     50 	 * @access public
     51 	 */
     52 	var $requestSOAP = '';
     53 	/**
     54 	 * requested method namespace URI
     55 	 * @var string
     56 	 * @access private
     57 	 */
     58 	var $methodURI = '';
     59 	/**
     60 	 * name of method requested
     61 	 * @var string
     62 	 * @access private
     63 	 */
     64 	var $methodname = '';
     65 	/**
     66 	 * method parameters from request
     67 	 * @var array
     68 	 * @access private
     69 	 */
     70 	var $methodparams = array();
     71 	/**
     72 	 * SOAP Action from request
     73 	 * @var string
     74 	 * @access private
     75 	 */
     76 	var $SOAPAction = '';
     77 	/**
     78 	 * character set encoding of incoming (request) messages
     79 	 * @var string
     80 	 * @access public
     81 	 */
     82 	var $xml_encoding = '';
     83 	/**
     84 	 * toggles whether the parser decodes element content w/ utf8_decode()
     85 	 * @var boolean
     86 	 * @access public
     87 	 */
     88     var $decode_utf8 = true;
     89 
     90 	/**
     91 	 * HTTP headers of response
     92 	 * @var array
     93 	 * @access public
     94 	 */
     95 	var $outgoing_headers = array();
     96 	/**
     97 	 * HTTP response
     98 	 * @var string
     99 	 * @access private
    100 	 */
    101 	var $response = '';
    102 	/**
    103 	 * SOAP headers for response (text or array of soapval or associative array)
    104 	 * @var mixed
    105 	 * @access public
    106 	 */
    107 	var $responseHeaders = '';
    108 	/**
    109 	 * SOAP payload for response (text)
    110 	 * @var string
    111 	 * @access private
    112 	 */
    113 	var $responseSOAP = '';
    114 	/**
    115 	 * method return value to place in response
    116 	 * @var mixed
    117 	 * @access private
    118 	 */
    119 	var $methodreturn = false;
    120 	/**
    121 	 * whether $methodreturn is a string of literal XML
    122 	 * @var boolean
    123 	 * @access public
    124 	 */
    125 	var $methodreturnisliteralxml = false;
    126 	/**
    127 	 * SOAP fault for response (or false)
    128 	 * @var mixed
    129 	 * @access private
    130 	 */
    131 	var $fault = false;
    132 	/**
    133 	 * text indication of result (for debugging)
    134 	 * @var string
    135 	 * @access private
    136 	 */
    137 	var $result = 'successful';
    138 
    139 	/**
    140 	 * assoc array of operations => opData; operations are added by the register()
    141 	 * method or by parsing an external WSDL definition
    142 	 * @var array
    143 	 * @access private
    144 	 */
    145 	var $operations = array();
    146 	/**
    147 	 * wsdl instance (if one)
    148 	 * @var mixed
    149 	 * @access private
    150 	 */
    151 	var $wsdl = false;
    152 	/**
    153 	 * URL for WSDL (if one)
    154 	 * @var mixed
    155 	 * @access private
    156 	 */
    157 	var $externalWSDLURL = false;
    158 	/**
    159 	 * whether to append debug to response as XML comment
    160 	 * @var boolean
    161 	 * @access public
    162 	 */
    163 	var $debug_flag = false;
    164 
    165 
    166 	/**
    167 	* constructor
    168     * the optional parameter is a path to a WSDL file that you'd like to bind the server instance to.
    169 	*
    170     * @param mixed $wsdl file path or URL (string), or wsdl instance (object)
    171 	* @access   public
    172 	*/
    173 	function nusoap_server($wsdl=false){
    174 		parent::nusoap_base();
    175 		// turn on debugging?
    176 		global $debug;
    177 		global $HTTP_SERVER_VARS;
    178 
    179 		if (isset($_SERVER)) {
    180 			$this->debug("_SERVER is defined:");
    181 			$this->appendDebug($this->varDump($_SERVER));
    182 		} elseif (isset($HTTP_SERVER_VARS)) {
    183 			$this->debug("HTTP_SERVER_VARS is defined:");
    184 			$this->appendDebug($this->varDump($HTTP_SERVER_VARS));
    185 		} else {
    186 			$this->debug("Neither _SERVER nor HTTP_SERVER_VARS is defined.");
    187 		}
    188 
    189 		if (isset($debug)) {
    190 			$this->debug("In nusoap_server, set debug_flag=$debug based on global flag");
    191 			$this->debug_flag = $debug;
    192 		} elseif (isset($_SERVER['QUERY_STRING'])) {
    193 			$qs = explode('&', $_SERVER['QUERY_STRING']);
    194 			foreach ($qs as $v) {
    195 				if (substr($v, 0, 6) == 'debug=') {
    196 					$this->debug("In nusoap_server, set debug_flag=" . substr($v, 6) . " based on query string #1");
    197 					$this->debug_flag = substr($v, 6);
    198 				}
    199 			}
    200 		} elseif (isset($HTTP_SERVER_VARS['QUERY_STRING'])) {
    201 			$qs = explode('&', $HTTP_SERVER_VARS['QUERY_STRING']);
    202 			foreach ($qs as $v) {
    203 				if (substr($v, 0, 6) == 'debug=') {
    204 					$this->debug("In nusoap_server, set debug_flag=" . substr($v, 6) . " based on query string #2");
    205 					$this->debug_flag = substr($v, 6);
    206 				}
    207 			}
    208 		}
    209 
    210 		// wsdl
    211 		if($wsdl){
    212 			$this->debug("In nusoap_server, WSDL is specified");
    213 			if (is_object($wsdl) && (get_class($wsdl) == 'wsdl')) {
    214 				$this->wsdl = $wsdl;
    215 				$this->externalWSDLURL = $this->wsdl->wsdl;
    216 				$this->debug('Use existing wsdl instance from ' . $this->externalWSDLURL);
    217 			} else {
    218 				$this->debug('Create wsdl from ' . $wsdl);
    219 				$this->wsdl = new wsdl($wsdl);
    220 				$this->externalWSDLURL = $wsdl;
    221 			}
    222 			$this->appendDebug($this->wsdl->getDebug());
    223 			$this->wsdl->clearDebug();
    224 			if($err = $this->wsdl->getError()){
    225 				die('WSDL ERROR: '.$err);
    226 			}
    227 		}
    228 	}
    229 
    230 	/**
    231 	* processes request and returns response
    232 	*
    233 	* @param    string $data usually is the value of $HTTP_RAW_POST_DATA
    234 	* @access   public
    235 	*/
    236 	function service($data){
    237 		global $HTTP_SERVER_VARS;
    238 
    239 		if (isset($_SERVER['REQUEST_METHOD'])) {
    240 			$rm = $_SERVER['REQUEST_METHOD'];
    241 		} elseif (isset($HTTP_SERVER_VARS['REQUEST_METHOD'])) {
    242 			$rm = $HTTP_SERVER_VARS['REQUEST_METHOD'];
    243 		} else {
    244 			$rm = '';
    245 		}
    246 
    247 		if (isset($_SERVER['QUERY_STRING'])) {
    248 			$qs = $_SERVER['QUERY_STRING'];
    249 		} elseif (isset($HTTP_SERVER_VARS['QUERY_STRING'])) {
    250 			$qs = $HTTP_SERVER_VARS['QUERY_STRING'];
    251 		} else {
    252 			$qs = '';
    253 		}
    254 		$this->debug("In service, request method=$rm query string=$qs strlen(\$data)=" . strlen($data));
    255 
    256 		if ($rm == 'POST') {
    257 			$this->debug("In service, invoke the request");
    258 			$this->parse_request($data);
    259 			if (! $this->fault) {
    260 				$this->invoke_method();
    261 			}
    262 			if (! $this->fault) {
    263 				$this->serialize_return();
    264 			}
    265 			$this->send_response();
    266 		} elseif (preg_match('/wsdl/', $qs) ){
    267 			$this->debug("In service, this is a request for WSDL");
    268 			if ($this->externalWSDLURL){
    269               if (strpos($this->externalWSDLURL, "http://") !== false) { // assume URL
    270 				$this->debug("In service, re-direct for WSDL");
    271 				header('Location: '.$this->externalWSDLURL);
    272               } else { // assume file
    273 				$this->debug("In service, use file passthru for WSDL");
    274                 header("Content-Type: text/xml\r\n");
    275 				$pos = strpos($this->externalWSDLURL, "file://");
    276 				if ($pos === false) {
    277 					$filename = $this->externalWSDLURL;
    278 				} else {
    279 					$filename = substr($this->externalWSDLURL, $pos + 7);
    280 				}
    281                 $fp = fopen($this->externalWSDLURL, 'r');
    282                 fpassthru($fp);
    283               }
    284 			} elseif ($this->wsdl) {
    285 				$this->debug("In service, serialize WSDL");
    286 				header("Content-Type: text/xml; charset=ISO-8859-1\r\n");
    287 				print $this->wsdl->serialize($this->debug_flag);
    288 				if ($this->debug_flag) {
    289 					$this->debug('wsdl:');
    290 					$this->appendDebug($this->varDump($this->wsdl));
    291 					print $this->getDebugAsXMLComment();
    292 				}
    293 			} else {
    294 				$this->debug("In service, there is no WSDL");
    295 				header("Content-Type: text/html; charset=ISO-8859-1\r\n");
    296 				print "This service does not provide WSDL";
    297 			}
    298 		} elseif ($this->wsdl) {
    299 			$this->debug("In service, return Web description");
    300 			print $this->wsdl->webDescription();
    301 		} else {
    302 			$this->debug("In service, no Web description");
    303 			header("Content-Type: text/html; charset=ISO-8859-1\r\n");
    304 			print "This service does not provide a Web description";
    305 		}
    306 	}
    307 
    308 	/**
    309 	* parses HTTP request headers.
    310 	*
    311 	* The following fields are set by this function (when successful)
    312 	*
    313 	* headers
    314 	* request
    315 	* xml_encoding
    316 	* SOAPAction
    317 	*
    318 	* @access   private
    319 	*/
    320 	function parse_http_headers() {
    321 		global $HTTP_SERVER_VARS;
    322 
    323 		$this->request = '';
    324 		$this->SOAPAction = '';
    325 		if(function_exists('getallheaders')){
    326 			$this->debug("In parse_http_headers, use getallheaders");
    327 			$headers = getallheaders();
    328 			foreach($headers as $k=>$v){
    329 				$k = strtolower($k);
    330 				$this->headers[$k] = $v;
    331 				$this->request .= "$k: $v\r\n";
    332 				$this->debug("$k: $v");
    333 			}
    334 			// get SOAPAction header
    335 			if(isset($this->headers['soapaction'])){
    336 				$this->SOAPAction = str_replace('"','',$this->headers['soapaction']);
    337 			}
    338 			// get the character encoding of the incoming request
    339 			if(isset($this->headers['content-type']) && strpos($this->headers['content-type'],'=')){
    340 				$enc = str_replace('"','',substr(strstr($this->headers["content-type"],'='),1));
    341 				if(preg_match('/^(ISO-8859-1|US-ASCII|UTF-8)$/i',$enc)){
    342 					$this->xml_encoding = strtoupper($enc);
    343 				} else {
    344 					$this->xml_encoding = 'US-ASCII';
    345 				}
    346 			} else {
    347 				// should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
    348 				$this->xml_encoding = 'ISO-8859-1';
    349 			}
    350 		} elseif(isset($_SERVER) && is_array($_SERVER)){
    351 			$this->debug("In parse_http_headers, use _SERVER");
    352 			foreach ($_SERVER as $k => $v) {
    353 				if (substr($k, 0, 5) == 'HTTP_') {
    354 					$k = str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($k, 5))));
    355 				} else {
    356 					$k = str_replace(' ', '-', strtolower(str_replace('_', ' ', $k)));
    357 				}
    358 				if ($k == 'soapaction') {
    359 					// get SOAPAction header
    360 					$k = 'SOAPAction';
    361 					$v = str_replace('"', '', $v);
    362 					$v = str_replace('\\', '', $v);
    363 					$this->SOAPAction = $v;
    364 				} else if ($k == 'content-type') {
    365 					// get the character encoding of the incoming request
    366 					if (strpos($v, '=')) {
    367 						$enc = substr(strstr($v, '='), 1);
    368 						$enc = str_replace('"', '', $enc);
    369 						$enc = str_replace('\\', '', $enc);
    370 						if (preg_match('/^(ISO-8859-1|US-ASCII|UTF-8)$/i',$enc)) {
    371 							$this->xml_encoding = strtoupper($enc);
    372 						} else {
    373 							$this->xml_encoding = 'US-ASCII';
    374 						}
    375 					} else {
    376 						// should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
    377 						$this->xml_encoding = 'ISO-8859-1';
    378 					}
    379 				}
    380 				$this->headers[$k] = $v;
    381 				$this->request .= "$k: $v\r\n";
    382 				$this->debug("$k: $v");
    383 			}
    384 		} elseif (is_array($HTTP_SERVER_VARS)) {
    385 			$this->debug("In parse_http_headers, use HTTP_SERVER_VARS");
    386 			foreach ($HTTP_SERVER_VARS as $k => $v) {
    387 				if (substr($k, 0, 5) == 'HTTP_') {
    388 					$k = str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($k, 5)))); 	                                         $k = strtolower(substr($k, 5));
    389 				} else {
    390 					$k = str_replace(' ', '-', strtolower(str_replace('_', ' ', $k))); 	                                         $k = strtolower($k);
    391 				}
    392 				if ($k == 'soapaction') {
    393 					// get SOAPAction header
    394 					$k = 'SOAPAction';
    395 					$v = str_replace('"', '', $v);
    396 					$v = str_replace('\\', '', $v);
    397 					$this->SOAPAction = $v;
    398 				} else if ($k == 'content-type') {
    399 					// get the character encoding of the incoming request
    400 					if (strpos($v, '=')) {
    401 						$enc = substr(strstr($v, '='), 1);
    402 						$enc = str_replace('"', '', $enc);
    403 						$enc = str_replace('\\', '', $enc);
    404 						if (preg_match('/^(ISO-8859-1|US-ASCII|UTF-8)$/i',$enc)) {
    405 							$this->xml_encoding = strtoupper($enc);
    406 						} else {
    407 							$this->xml_encoding = 'US-ASCII';
    408 						}
    409 					} else {
    410 						// should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
    411 						$this->xml_encoding = 'ISO-8859-1';
    412 					}
    413 				}
    414 				$this->headers[$k] = $v;
    415 				$this->request .= "$k: $v\r\n";
    416 				$this->debug("$k: $v");
    417 			}
    418 		} else {
    419 			$this->debug("In parse_http_headers, HTTP headers not accessible");
    420 			$this->setError("HTTP headers not accessible");
    421 		}
    422 	}
    423 
    424 	/**
    425 	* parses a request
    426 	*
    427 	* The following fields are set by this function (when successful)
    428 	*
    429 	* headers
    430 	* request
    431 	* xml_encoding
    432 	* SOAPAction
    433 	* request
    434 	* requestSOAP
    435 	* methodURI
    436 	* methodname
    437 	* methodparams
    438 	* requestHeaders
    439 	* document
    440 	*
    441 	* This sets the fault field on error
    442 	*
    443 	* @param    string $data XML string
    444 	* @access   private
    445 	*/
    446 	function parse_request($data='') {
    447 		$this->debug('entering parse_request()');
    448 		$this->parse_http_headers();
    449 		$this->debug('got character encoding: '.$this->xml_encoding);
    450 		// uncompress if necessary
    451 		if (isset($this->headers['content-encoding']) && $this->headers['content-encoding'] != '') {
    452 			$this->debug('got content encoding: ' . $this->headers['content-encoding']);
    453 			if ($this->headers['content-encoding'] == 'deflate' || $this->headers['content-encoding'] == 'gzip') {
    454 		    	// if decoding works, use it. else assume data wasn't gzencoded
    455 				if (function_exists('gzuncompress')) {
    456 					if ($this->headers['content-encoding'] == 'deflate' && $degzdata = @gzuncompress($data)) {
    457 						$data = $degzdata;
    458 					} elseif ($this->headers['content-encoding'] == 'gzip' && $degzdata = gzinflate(substr($data, 10))) {
    459 						$data = $degzdata;
    460 					} else {
    461 						$this->fault('SOAP-ENV:Client', 'Errors occurred when trying to decode the data');
    462 						return;
    463 					}
    464 				} else {
    465 					$this->fault('SOAP-ENV:Client', 'This Server does not support compressed data');
    466 					return;
    467 				}
    468 			}
    469 		}
    470 		$this->request .= "\r\n".$data;
    471 		$data = $this->parseRequest($this->headers, $data);
    472 		$this->requestSOAP = $data;
    473 		$this->debug('leaving parse_request');
    474 	}
    475 
    476 	/**
    477 	* invokes a PHP function for the requested SOAP method
    478 	*
    479 	* The following fields are set by this function (when successful)
    480 	*
    481 	* methodreturn
    482 	*
    483 	* Note that the PHP function that is called may also set the following
    484 	* fields to affect the response sent to the client
    485 	*
    486 	* responseHeaders
    487 	* outgoing_headers
    488 	*
    489 	* This sets the fault field on error
    490 	*
    491 	* @access   private
    492 	*/
    493 	function invoke_method() {
    494 		$this->debug('in invoke_method, methodname=' . $this->methodname . ' methodURI=' . $this->methodURI . ' SOAPAction=' . $this->SOAPAction);
    495 
    496 		//
    497 		// if you are debugging in this area of the code, your service uses a class to implement methods,
    498 		// you use SOAP RPC, and the client is .NET, please be aware of the following...
    499 		// when the .NET wsdl.exe utility generates a proxy, it will remove the '.' or '..' from the
    500 		// method name.  that is fine for naming the .NET methods.  it is not fine for properly constructing
    501 		// the XML request and reading the XML response.  you need to add the RequestElementName and
    502 		// ResponseElementName to the System.Web.Services.Protocols.SoapRpcMethodAttribute that wsdl.exe
    503 		// generates for the method.  these parameters are used to specify the correct XML element names
    504 		// for .NET to use, i.e. the names with the '.' in them.
    505 		//
    506 		$orig_methodname = $this->methodname;
    507 		if ($this->wsdl) {
    508 			if ($this->opData = $this->wsdl->getOperationData($this->methodname)) {
    509 				$this->debug('in invoke_method, found WSDL operation=' . $this->methodname);
    510 				$this->appendDebug('opData=' . $this->varDump($this->opData));
    511 			} elseif ($this->opData = $this->wsdl->getOperationDataForSoapAction($this->SOAPAction)) {
    512 				// Note: hopefully this case will only be used for doc/lit, since rpc services should have wrapper element
    513 				$this->debug('in invoke_method, found WSDL soapAction=' . $this->SOAPAction . ' for operation=' . $this->opData['name']);
    514 				$this->appendDebug('opData=' . $this->varDump($this->opData));
    515 				$this->methodname = $this->opData['name'];
    516 			} else {
    517 				$this->debug('in invoke_method, no WSDL for operation=' . $this->methodname);
    518 				$this->fault('SOAP-ENV:Client', "Operation '" . $this->methodname . "' is not defined in the WSDL for this service");
    519 				return;
    520 			}
    521 		} else {
    522 			$this->debug('in invoke_method, no WSDL to validate method');
    523 		}
    524 
    525 		// if a . is present in $this->methodname, we see if there is a class in scope,
    526 		// which could be referred to. We will also distinguish between two deliminators,
    527 		// to allow methods to be called a the class or an instance
    528 		if (strpos($this->methodname, '..') > 0) {
    529 			$delim = '..';
    530 		} else if (strpos($this->methodname, '.') > 0) {
    531 			$delim = '.';
    532 		} else {
    533 			$delim = '';
    534 		}
    535 		$this->debug("in invoke_method, delim=$delim");
    536 
    537 		$class = '';
    538 		$method = '';
    539 		if (strlen($delim) > 0 && substr_count($this->methodname, $delim) == 1) {
    540 			$try_class = substr($this->methodname, 0, strpos($this->methodname, $delim));
    541 			if (class_exists($try_class)) {
    542 				// get the class and method name
    543 				$class = $try_class;
    544 				$method = substr($this->methodname, strpos($this->methodname, $delim) + strlen($delim));
    545 				$this->debug("in invoke_method, class=$class method=$method delim=$delim");
    546 			} else {
    547 				$this->debug("in invoke_method, class=$try_class not found");
    548 			}
    549 		} else {
    550 			$try_class = '';
    551 			$this->debug("in invoke_method, no class to try");
    552 		}
    553 
    554 		// does method exist?
    555 		if ($class == '') {
    556 			if (!function_exists($this->methodname)) {
    557 				$this->debug("in invoke_method, function '$this->methodname' not found!");
    558 				$this->result = 'fault: method not found';
    559 				$this->fault('SOAP-ENV:Client',"method '$this->methodname'('$orig_methodname') not defined in service('$try_class' '$delim')");
    560 				return;
    561 			}
    562 		} else {
    563 			$method_to_compare = (substr(phpversion(), 0, 2) == '4.') ? strtolower($method) : $method;
    564 			if (!in_array($method_to_compare, get_class_methods($class))) {
    565 				$this->debug("in invoke_method, method '$this->methodname' not found in class '$class'!");
    566 				$this->result = 'fault: method not found';
    567 				$this->fault('SOAP-ENV:Client',"method '$this->methodname'/'$method_to_compare'('$orig_methodname') not defined in service/'$class'('$try_class' '$delim')");
    568 				return;
    569 			}
    570 		}
    571 
    572 		// evaluate message, getting back parameters
    573 		// verify that request parameters match the method's signature
    574 		if(! $this->verify_method($this->methodname,$this->methodparams)){
    575 			// debug
    576 			$this->debug('ERROR: request not verified against method signature');
    577 			$this->result = 'fault: request failed validation against method signature';
    578 			// return fault
    579 			$this->fault('SOAP-ENV:Client',"Operation '$this->methodname' not defined in service.");
    580 			return;
    581 		}
    582 
    583 		// if there are parameters to pass
    584 		$this->debug('in invoke_method, params:');
    585 		$this->appendDebug($this->varDump($this->methodparams));
    586 		$this->debug("in invoke_method, calling '$this->methodname'");
    587 		if (!function_exists('call_user_func_array')) {
    588 			if ($class == '') {
    589 				$this->debug('in invoke_method, calling function using eval()');
    590 				$funcCall = "\$this->methodreturn = $this->methodname(";
    591 			} else {
    592 				if ($delim == '..') {
    593 					$this->debug('in invoke_method, calling class method using eval()');
    594 					$funcCall = "\$this->methodreturn = ".$class."::".$method."(";
    595 				} else {
    596 					$this->debug('in invoke_method, calling instance method using eval()');
    597 					// generate unique instance name
    598 					$instname = "\$inst_".time();
    599 					$funcCall = $instname." = new ".$class."(); ";
    600 					$funcCall .= "\$this->methodreturn = ".$instname."->".$method."(";
    601 				}
    602 			}
    603 			if ($this->methodparams) {
    604 				foreach ($this->methodparams as $param) {
    605 					if (is_array($param) || is_object($param)) {
    606 						$this->fault('SOAP-ENV:Client', 'NuSOAP does not handle complexType parameters correctly when using eval; call_user_func_array must be available');
    607 						return;
    608 					}
    609 					$funcCall .= "\"$param\",";
    610 				}
    611 				$funcCall = substr($funcCall, 0, -1);
    612 			}
    613 			$funcCall .= ');';
    614 			$this->debug('in invoke_method, function call: '.$funcCall);
    615 			@eval($funcCall);
    616 		} else {
    617 			if ($class == '') {
    618 				$this->debug('in invoke_method, calling function using call_user_func_array()');
    619 				$call_arg = "$this->methodname";	// straight assignment changes $this->methodname to lower case after call_user_func_array()
    620 			} elseif ($delim == '..') {
    621 				$this->debug('in invoke_method, calling class method using call_user_func_array()');
    622 				$call_arg = array ($class, $method);
    623 			} else {
    624 				$this->debug('in invoke_method, calling instance method using call_user_func_array()');
    625 				$instance = new $class ();
    626 				$call_arg = array(&$instance, $method);
    627 			}
    628 			if (is_array($this->methodparams)) {
    629 				$this->methodreturn = call_user_func_array($call_arg, array_values($this->methodparams));
    630 			} else {
    631 				$this->methodreturn = call_user_func_array($call_arg, array());
    632 			}
    633 		}
    634         $this->debug('in invoke_method, methodreturn:');
    635         $this->appendDebug($this->varDump($this->methodreturn));
    636 		$this->debug("in invoke_method, called method $this->methodname, received data of type ".gettype($this->methodreturn));
    637 	}
    638 
    639 	/**
    640 	* serializes the return value from a PHP function into a full SOAP Envelope
    641 	*
    642 	* The following fields are set by this function (when successful)
    643 	*
    644 	* responseSOAP
    645 	*
    646 	* This sets the fault field on error
    647 	*
    648 	* @access   private
    649 	*/
    650 	function serialize_return() {
    651 		$this->debug('Entering serialize_return methodname: ' . $this->methodname . ' methodURI: ' . $this->methodURI);
    652 		// if fault
    653 		if (isset($this->methodreturn) && is_object($this->methodreturn) && ((get_class($this->methodreturn) == 'soap_fault') || (get_class($this->methodreturn) == 'nusoap_fault'))) {
    654 			$this->debug('got a fault object from method');
    655 			$this->fault = $this->methodreturn;
    656 			return;
    657 		} elseif ($this->methodreturnisliteralxml) {
    658 			$return_val = $this->methodreturn;
    659 		// returned value(s)
    660 		} else {
    661 			$this->debug('got a(n) '.gettype($this->methodreturn).' from method');
    662 			$this->debug('serializing return value');
    663 			if($this->wsdl){
    664 				if (sizeof($this->opData['output']['parts']) > 1) {
    665 					$this->debug('more than one output part, so use the method return unchanged');
    666 			    	$opParams = $this->methodreturn;
    667 			    } elseif (sizeof($this->opData['output']['parts']) == 1) {
    668 					$this->debug('exactly one output part, so wrap the method return in a simple array');
    669 					// TODO: verify that it is not already wrapped!
    670 			    	//foreach ($this->opData['output']['parts'] as $name => $type) {
    671 					//	$this->debug('wrap in element named ' . $name);
    672 			    	//}
    673 			    	$opParams = array($this->methodreturn);
    674 			    }
    675 			    $return_val = $this->wsdl->serializeRPCParameters($this->methodname,'output',$opParams);
    676 			    $this->appendDebug($this->wsdl->getDebug());
    677 			    $this->wsdl->clearDebug();
    678 				if($errstr = $this->wsdl->getError()){
    679 					$this->debug('got wsdl error: '.$errstr);
    680 					$this->fault('SOAP-ENV:Server', 'unable to serialize result');
    681 					return;
    682 				}
    683 			} else {
    684 				if (isset($this->methodreturn)) {
    685 					$return_val = $this->serialize_val($this->methodreturn, 'return');
    686 				} else {
    687 					$return_val = '';
    688 					$this->debug('in absence of WSDL, assume void return for backward compatibility');
    689 				}
    690 			}
    691 		}
    692 		$this->debug('return value:');
    693 		$this->appendDebug($this->varDump($return_val));
    694 
    695 		$this->debug('serializing response');
    696 		if ($this->wsdl) {
    697 			$this->debug('have WSDL for serialization: style is ' . $this->opData['style']);
    698 			if ($this->opData['style'] == 'rpc') {
    699 				$this->debug('style is rpc for serialization: use is ' . $this->opData['output']['use']);
    700 				if ($this->opData['output']['use'] == 'literal') {
    701 					// 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
    702 					if ($this->methodURI) {
    703 						$payload = '<ns1:'.$this->methodname.'Response xmlns:ns1="'.$this->methodURI.'">'.$return_val.'</ns1:'.$this->methodname."Response>";
    704 					} else {
    705 						$payload = '<'.$this->methodname.'Response>'.$return_val.'</'.$this->methodname.'Response>';
    706 					}
    707 				} else {
    708 					if ($this->methodURI) {
    709 						$payload = '<ns1:'.$this->methodname.'Response xmlns:ns1="'.$this->methodURI.'">'.$return_val.'</ns1:'.$this->methodname."Response>";
    710 					} else {
    711 						$payload = '<'.$this->methodname.'Response>'.$return_val.'</'.$this->methodname.'Response>';
    712 					}
    713 				}
    714 			} else {
    715 				$this->debug('style is not rpc for serialization: assume document');
    716 				$payload = $return_val;
    717 			}
    718 		} else {
    719 			$this->debug('do not have WSDL for serialization: assume rpc/encoded');
    720 			$payload = '<ns1:'.$this->methodname.'Response xmlns:ns1="'.$this->methodURI.'">'.$return_val.'</ns1:'.$this->methodname."Response>";
    721 		}
    722 		$this->result = 'successful';
    723 		if($this->wsdl){
    724 			//if($this->debug_flag){
    725             	$this->appendDebug($this->wsdl->getDebug());
    726             //	}
    727 			if (isset($this->opData['output']['encodingStyle'])) {
    728 				$encodingStyle = $this->opData['output']['encodingStyle'];
    729 			} else {
    730 				$encodingStyle = '';
    731 			}
    732 			// Added: In case we use a WSDL, return a serialized env. WITH the usedNamespaces.
    733 			$this->responseSOAP = $this->serializeEnvelope($payload,$this->responseHeaders,$this->wsdl->usedNamespaces,$this->opData['style'],$this->opData['output']['use'],$encodingStyle);
    734 		} else {
    735 			$this->responseSOAP = $this->serializeEnvelope($payload,$this->responseHeaders);
    736 		}
    737 		$this->debug("Leaving serialize_return");
    738 	}
    739 
    740 	/**
    741 	* sends an HTTP response
    742 	*
    743 	* The following fields are set by this function (when successful)
    744 	*
    745 	* outgoing_headers
    746 	* response
    747 	*
    748 	* @access   private
    749 	*/
    750 	function send_response() {
    751 		$this->debug('Enter send_response');
    752 		if ($this->fault) {
    753 			$payload = $this->fault->serialize();
    754 			$this->outgoing_headers[] = "HTTP/1.0 500 Internal Server Error";
    755 			$this->outgoing_headers[] = "Status: 500 Internal Server Error";
    756 		} else {
    757 			$payload = $this->responseSOAP;
    758 			// Some combinations of PHP+Web server allow the Status
    759 			// to come through as a header.  Since OK is the default
    760 			// just do nothing.
    761 			// $this->outgoing_headers[] = "HTTP/1.0 200 OK";
    762 			// $this->outgoing_headers[] = "Status: 200 OK";
    763 		}
    764         // add debug data if in debug mode
    765 		if(isset($this->debug_flag) && $this->debug_flag){
    766         	$payload .= $this->getDebugAsXMLComment();
    767         }
    768 		$this->outgoing_headers[] = "Server: $this->title Server v$this->version";
    769 		preg_match('/\$Revisio' . 'n: ([^ ]+)/', $this->revision, $rev);
    770 		$this->outgoing_headers[] = "X-SOAP-Server: $this->title/$this->version (".$rev[1].")";
    771 		// Let the Web server decide about this
    772 		//$this->outgoing_headers[] = "Connection: Close\r\n";
    773 		$payload = $this->getHTTPBody($payload);
    774 		$type = $this->getHTTPContentType();
    775 		$charset = $this->getHTTPContentTypeCharset();
    776 		$this->outgoing_headers[] = "Content-Type: $type" . ($charset ? '; charset=' . $charset : '');
    777 		//begin code to compress payload - by John
    778 		// NOTE: there is no way to know whether the Web server will also compress
    779 		// this data.
    780 		if (strlen($payload) > 1024 && isset($this->headers) && isset($this->headers['accept-encoding'])) {	
    781 			if (strstr($this->headers['accept-encoding'], 'gzip')) {
    782 				if (function_exists('gzencode')) {
    783 					if (isset($this->debug_flag) && $this->debug_flag) {
    784 						$payload .= "<!-- Content being gzipped -->";
    785 					}
    786 					$this->outgoing_headers[] = "Content-Encoding: gzip";
    787 					$payload = gzencode($payload);
    788 				} else {
    789 					if (isset($this->debug_flag) && $this->debug_flag) {
    790 						$payload .= "<!-- Content will not be gzipped: no gzencode -->";
    791 					}
    792 				}
    793 			} elseif (strstr($this->headers['accept-encoding'], 'deflate')) {
    794 				// Note: MSIE requires gzdeflate output (no Zlib header and checksum),
    795 				// instead of gzcompress output,
    796 				// which conflicts with HTTP 1.1 spec (http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.5)
    797 				if (function_exists('gzdeflate')) {
    798 					if (isset($this->debug_flag) && $this->debug_flag) {
    799 						$payload .= "<!-- Content being deflated -->";
    800 					}
    801 					$this->outgoing_headers[] = "Content-Encoding: deflate";
    802 					$payload = gzdeflate($payload);
    803 				} else {
    804 					if (isset($this->debug_flag) && $this->debug_flag) {
    805 						$payload .= "<!-- Content will not be deflated: no gzcompress -->";
    806 					}
    807 				}
    808 			}
    809 		}
    810 		//end code
    811 		$this->outgoing_headers[] = "Content-Length: ".strlen($payload);
    812 		reset($this->outgoing_headers);
    813 		foreach($this->outgoing_headers as $hdr){
    814 			header($hdr, false);
    815 		}
    816 		print $payload;
    817 		$this->response = join("\r\n",$this->outgoing_headers)."\r\n\r\n".$payload;
    818 	}
    819 
    820 	/**
    821 	* takes the value that was created by parsing the request
    822 	* and compares to the method's signature, if available.
    823 	*
    824 	* @param	string	$operation	The operation to be invoked
    825 	* @param	array	$request	The array of parameter values
    826 	* @return	boolean	Whether the operation was found
    827 	* @access   private
    828 	*/
    829 	function verify_method($operation,$request){
    830 		if(isset($this->wsdl) && is_object($this->wsdl)){
    831 			if($this->wsdl->getOperationData($operation)){
    832 				return true;
    833 			}
    834 	    } elseif(isset($this->operations[$operation])){
    835 			return true;
    836 		}
    837 		return false;
    838 	}
    839 
    840 	/**
    841 	* processes SOAP message received from client
    842 	*
    843 	* @param	array	$headers	The HTTP headers
    844 	* @param	string	$data		unprocessed request data from client
    845 	* @return	mixed	value of the message, decoded into a PHP type
    846 	* @access   private
    847 	*/
    848     function parseRequest($headers, $data) {
    849 		$this->debug('Entering parseRequest() for data of length ' . strlen($data) . ' headers:');
    850 		$this->appendDebug($this->varDump($headers));
    851     	if (!isset($headers['content-type'])) {
    852 			$this->setError('Request not of type text/xml (no content-type header)');
    853 			return false;
    854     	}
    855 		if (!strstr($headers['content-type'], 'text/xml')) {
    856 			$this->setError('Request not of type text/xml');
    857 			return false;
    858 		}
    859 		if (strpos($headers['content-type'], '=')) {
    860 			$enc = str_replace('"', '', substr(strstr($headers["content-type"], '='), 1));
    861 			$this->debug('Got response encoding: ' . $enc);
    862 			if(preg_match('/^(ISO-8859-1|US-ASCII|UTF-8)$/i',$enc)){
    863 				$this->xml_encoding = strtoupper($enc);
    864 			} else {
    865 				$this->xml_encoding = 'US-ASCII';
    866 			}
    867 		} else {
    868 			// should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
    869 			$this->xml_encoding = 'ISO-8859-1';
    870 		}
    871 		$this->debug('Use encoding: ' . $this->xml_encoding . ' when creating nusoap_parser');
    872 		// parse response, get soap parser obj
    873 		$parser = new nusoap_parser($data,$this->xml_encoding,'',$this->decode_utf8);
    874 		// parser debug
    875 		$this->debug("parser debug: \n".$parser->getDebug());
    876 		// if fault occurred during message parsing
    877 		if($err = $parser->getError()){
    878 			$this->result = 'fault: error in msg parsing: '.$err;
    879 			$this->fault('SOAP-ENV:Client',"error in msg parsing:\n".$err);
    880 		// else successfully parsed request into soapval object
    881 		} else {
    882 			// get/set methodname
    883 			$this->methodURI = $parser->root_struct_namespace;
    884 			$this->methodname = $parser->root_struct_name;
    885 			$this->debug('methodname: '.$this->methodname.' methodURI: '.$this->methodURI);
    886 			$this->debug('calling parser->get_soapbody()');
    887 			$this->methodparams = $parser->get_soapbody();
    888 			// get SOAP headers
    889 			$this->requestHeaders = $parser->getHeaders();
    890 			// get SOAP Header
    891 			$this->requestHeader = $parser->get_soapheader();
    892             // add document for doclit support
    893             $this->document = $parser->document;
    894 		}
    895 	 }
    896 
    897 	/**
    898 	* gets the HTTP body for the current response.
    899 	*
    900 	* @param string $soapmsg The SOAP payload
    901 	* @return string The HTTP body, which includes the SOAP payload
    902 	* @access private
    903 	*/
    904 	function getHTTPBody($soapmsg) {
    905 		return $soapmsg;
    906 	}
    907 	
    908 	/**
    909 	* gets the HTTP content type for the current response.
    910 	*
    911 	* Note: getHTTPBody must be called before this.
    912 	*
    913 	* @return string the HTTP content type for the current response.
    914 	* @access private
    915 	*/
    916 	function getHTTPContentType() {
    917 		return 'text/xml';
    918 	}
    919 	
    920 	/**
    921 	* gets the HTTP content type charset for the current response.
    922 	* returns false for non-text content types.
    923 	*
    924 	* Note: getHTTPBody must be called before this.
    925 	*
    926 	* @return string the HTTP content type charset for the current response.
    927 	* @access private
    928 	*/
    929 	function getHTTPContentTypeCharset() {
    930 		return $this->soap_defencoding;
    931 	}
    932 
    933 	/**
    934 	* add a method to the dispatch map (this has been replaced by the register method)
    935 	*
    936 	* @param    string $methodname
    937 	* @param    string $in array of input values
    938 	* @param    string $out array of output values
    939 	* @access   public
    940 	* @deprecated
    941 	*/
    942 	function add_to_map($methodname,$in,$out){
    943 			$this->operations[$methodname] = array('name' => $methodname,'in' => $in,'out' => $out);
    944 	}
    945 
    946 	/**
    947 	* register a service function with the server
    948 	*
    949 	* @param    string $name the name of the PHP function, class.method or class..method
    950 	* @param    array $in assoc array of input values: key = param name, value = param type
    951 	* @param    array $out assoc array of output values: key = param name, value = param type
    952 	* @param	mixed $namespace the element namespace for the method or false
    953 	* @param	mixed $soapaction the soapaction for the method or false
    954 	* @param	mixed $style optional (rpc|document) or false Note: when 'document' is specified, parameter and return wrappers are created for you automatically
    955 	* @param	mixed $use optional (encoded|literal) or false
    956 	* @param	string $documentation optional Description to include in WSDL
    957 	* @param	string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded)
    958 	* @access   public
    959 	*/
    960 	function register($name,$in=array(),$out=array(),$namespace=false,$soapaction=false,$style=false,$use=false,$documentation='',$encodingStyle=''){
    961 		global $HTTP_SERVER_VARS;
    962 
    963 		if($this->externalWSDLURL){
    964 			die('You cannot bind to an external WSDL file, and register methods outside of it! Please choose either WSDL or no WSDL.');
    965 		}
    966 		if (! $name) {
    967 			die('You must specify a name when you register an operation');
    968 		}
    969 		if (!is_array($in)) {
    970 			die('You must provide an array for operation inputs');
    971 		}
    972 		if (!is_array($out)) {
    973 			die('You must provide an array for operation outputs');
    974 		}
    975 		if(false == $namespace) {
    976 		}
    977 		if(false == $soapaction) {
    978 			if (isset($_SERVER)) {
    979 				$SERVER_NAME = $_SERVER['SERVER_NAME'];
    980 				$SCRIPT_NAME = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME'];
    981 				$HTTPS = isset($_SERVER['HTTPS']) ? $_SERVER['HTTPS'] : (isset($HTTP_SERVER_VARS['HTTPS']) ? $HTTP_SERVER_VARS['HTTPS'] : 'off');
    982 			} elseif (isset($HTTP_SERVER_VARS)) {
    983 				$SERVER_NAME = $HTTP_SERVER_VARS['SERVER_NAME'];
    984 				$SCRIPT_NAME = isset($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : $HTTP_SERVER_VARS['SCRIPT_NAME'];
    985 				$HTTPS = isset($HTTP_SERVER_VARS['HTTPS']) ? $HTTP_SERVER_VARS['HTTPS'] : 'off';
    986 			} else {
    987 				$this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available");
    988 			}
    989         	if ($HTTPS == '1' || $HTTPS == 'on') {
    990         		$SCHEME = 'https';
    991         	} else {
    992         		$SCHEME = 'http';
    993         	}
    994 			$soapaction = "$SCHEME://$SERVER_NAME$SCRIPT_NAME/$name";
    995 		}
    996 		if(false == $style) {
    997 			$style = "rpc";
    998 		}
    999 		if(false == $use) {
   1000 			$use = "encoded";
   1001 		}
   1002 		if ($use == 'encoded' && $encodingStyle == '') {
   1003 			$encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
   1004 		}
   1005 
   1006 		$this->operations[$name] = array(
   1007 	    'name' => $name,
   1008 	    'in' => $in,
   1009 	    'out' => $out,
   1010 	    'namespace' => $namespace,
   1011 	    'soapaction' => $soapaction,
   1012 	    'style' => $style);
   1013         if($this->wsdl){
   1014         	$this->wsdl->addOperation($name,$in,$out,$namespace,$soapaction,$style,$use,$documentation,$encodingStyle);
   1015 	    }
   1016 		return true;
   1017 	}
   1018 
   1019 	/**
   1020 	* Specify a fault to be returned to the client.
   1021 	* This also acts as a flag to the server that a fault has occured.
   1022 	*
   1023 	* @param	string $faultcode
   1024 	* @param	string $faultstring
   1025 	* @param	string $faultactor
   1026 	* @param	string $faultdetail
   1027 	* @access   public
   1028 	*/
   1029 	function fault($faultcode,$faultstring,$faultactor='',$faultdetail=''){
   1030 		if ($faultdetail == '' && $this->debug_flag) {
   1031 			$faultdetail = $this->getDebug();
   1032 		}
   1033 		$this->fault = new nusoap_fault($faultcode,$faultactor,$faultstring,$faultdetail);
   1034 		$this->fault->soap_defencoding = $this->soap_defencoding;
   1035 	}
   1036 
   1037     /**
   1038     * Sets up wsdl object.
   1039     * Acts as a flag to enable internal WSDL generation
   1040     *
   1041     * @param string $serviceName, name of the service
   1042     * @param mixed $namespace optional 'tns' service namespace or false
   1043     * @param mixed $endpoint optional URL of service endpoint or false
   1044     * @param string $style optional (rpc|document) WSDL style (also specified by operation)
   1045     * @param string $transport optional SOAP transport
   1046     * @param mixed $schemaTargetNamespace optional 'types' targetNamespace for service schema or false
   1047     */
   1048     function configureWSDL($serviceName,$namespace = false,$endpoint = false,$style='rpc', $transport = 'http://schemas.xmlsoap.org/soap/http', $schemaTargetNamespace = false)
   1049     {
   1050     	global $HTTP_SERVER_VARS;
   1051 
   1052 		if (isset($_SERVER)) {
   1053 			$SERVER_NAME = $_SERVER['SERVER_NAME'];
   1054 			$SERVER_PORT = $_SERVER['SERVER_PORT'];
   1055 			$SCRIPT_NAME = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME'];
   1056 			$HTTPS = isset($_SERVER['HTTPS']) ? $_SERVER['HTTPS'] : (isset($HTTP_SERVER_VARS['HTTPS']) ? $HTTP_SERVER_VARS['HTTPS'] : 'off');
   1057 		} elseif (isset($HTTP_SERVER_VARS)) {
   1058 			$SERVER_NAME = $HTTP_SERVER_VARS['SERVER_NAME'];
   1059 			$SERVER_PORT = $HTTP_SERVER_VARS['SERVER_PORT'];
   1060 			$SCRIPT_NAME = isset($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : $HTTP_SERVER_VARS['SCRIPT_NAME'];
   1061 			$HTTPS = isset($HTTP_SERVER_VARS['HTTPS']) ? $HTTP_SERVER_VARS['HTTPS'] : 'off';
   1062 		} else {
   1063 			$this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available");
   1064 		}
   1065 		// If server name has port number attached then strip it (else port number gets duplicated in WSDL output) (occurred using lighttpd and FastCGI)
   1066 		$colon = strpos($SERVER_NAME,":");
   1067 		if ($colon) {
   1068 		    $SERVER_NAME = substr($SERVER_NAME, 0, $colon);
   1069 		}
   1070 		if ($SERVER_PORT == 80) {
   1071 			$SERVER_PORT = '';
   1072 		} else {
   1073 			$SERVER_PORT = ':' . $SERVER_PORT;
   1074 		}
   1075         if(false == $namespace) {
   1076             $namespace = "http://$SERVER_NAME/soap/$serviceName";
   1077         }
   1078         
   1079         if(false == $endpoint) {
   1080         	if ($HTTPS == '1' || $HTTPS == 'on') {
   1081         		$SCHEME = 'https';
   1082         	} else {
   1083         		$SCHEME = 'http';
   1084         	}
   1085             $endpoint = "$SCHEME://$SERVER_NAME$SERVER_PORT$SCRIPT_NAME";
   1086         }
   1087         
   1088         if(false == $schemaTargetNamespace) {
   1089             $schemaTargetNamespace = $namespace;
   1090         }
   1091         
   1092 		$this->wsdl = new wsdl;
   1093 		$this->wsdl->serviceName = $serviceName;
   1094         $this->wsdl->endpoint = $endpoint;
   1095 		$this->wsdl->namespaces['tns'] = $namespace;
   1096 		$this->wsdl->namespaces['soap'] = 'http://schemas.xmlsoap.org/wsdl/soap/';
   1097 		$this->wsdl->namespaces['wsdl'] = 'http://schemas.xmlsoap.org/wsdl/';
   1098 		if ($schemaTargetNamespace != $namespace) {
   1099 			$this->wsdl->namespaces['types'] = $schemaTargetNamespace;
   1100 		}
   1101         $this->wsdl->schemas[$schemaTargetNamespace][0] = new nusoap_xmlschema('', '', $this->wsdl->namespaces);
   1102         if ($style == 'document') {
   1103 	        $this->wsdl->schemas[$schemaTargetNamespace][0]->schemaInfo['elementFormDefault'] = 'qualified';
   1104         }
   1105         $this->wsdl->schemas[$schemaTargetNamespace][0]->schemaTargetNamespace = $schemaTargetNamespace;
   1106         $this->wsdl->schemas[$schemaTargetNamespace][0]->imports['http://schemas.xmlsoap.org/soap/encoding/'][0] = array('location' => '', 'loaded' => true);
   1107         $this->wsdl->schemas[$schemaTargetNamespace][0]->imports['http://schemas.xmlsoap.org/wsdl/'][0] = array('location' => '', 'loaded' => true);
   1108         $this->wsdl->bindings[$serviceName.'Binding'] = array(
   1109         	'name'=>$serviceName.'Binding',
   1110             'style'=>$style,
   1111             'transport'=>$transport,
   1112             'portType'=>$serviceName.'PortType');
   1113         $this->wsdl->ports[$serviceName.'Port'] = array(
   1114         	'binding'=>$serviceName.'Binding',
   1115             'location'=>$endpoint,
   1116             'bindingType'=>'http://schemas.xmlsoap.org/wsdl/soap/');
   1117     }
   1118 }
   1119 
   1120 /**
   1121  * Backward compatibility
   1122  */
   1123 class soap_server extends nusoap_server {
   1124 }
   1125 
   1126 
   1127 ?>