Test Setup Failed
Push — master ( ec638a...cb9435 )
by Julito
51:10
created

nusoap_client::call()   F

Complexity

Conditions 32
Paths 9850

Size

Total Lines 176
Code Lines 132

Duplication

Lines 25
Ratio 14.2 %

Importance

Changes 0
Metric Value
cc 32
eloc 132
nc 9850
nop 8
dl 25
loc 176
rs 2
c 0
b 0
f 0

How to fix   Long Method    Complexity    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
/**
4
*
5
* [nu]soapclient higher level class for easy usage.
6
*
7
* usage:
8
*
9
* // instantiate client with server info
10
* $soapclient = new nusoap_client( string path [ ,mixed wsdl] );
11
*
12
* // call method, get results
13
* echo $soapclient->call( string methodname [ ,array parameters] );
14
*
15
* // bye bye client
16
* unset($soapclient);
17
*
18
* @author   Dietrich Ayala <[email protected]>
19
* @author   Scott Nichol <[email protected]>
20
* @version  $Id: class.soapclient.php,v 1.69 2010/04/26 20:15:08 snichol Exp $
21
* @access   public
22
*/
23
class nusoap_client extends nusoap_base
24
{
25
	var $username = '';				// Username for HTTP authentication
26
	var $password = '';				// Password for HTTP authentication
27
	var $authtype = '';				// Type of HTTP authentication
28
	var $certRequest = array();		// Certificate for HTTP SSL authentication
29
	var $requestHeaders = false;	// SOAP headers in request (text)
30
	var $responseHeaders = '';		// SOAP headers from response (incomplete namespace resolution) (text)
31
	var $responseHeader = NULL;		// SOAP Header from response (parsed)
32
	var $document = '';				// SOAP body response portion (incomplete namespace resolution) (text)
33
	var $endpoint;
34
	var $forceEndpoint = '';		// overrides WSDL endpoint
35
    var $proxyhost = '';
36
    var $proxyport = '';
37
	var $proxyusername = '';
38
	var $proxypassword = '';
39
	var $portName = '';				// port name to use in WSDL
40
    var $xml_encoding = '';			// character set encoding of incoming (response) messages
41
	var $http_encoding = false;
42
	var $timeout = 0;				// HTTP connection timeout
43
	var $response_timeout = 30;		// HTTP response timeout
44
	var $endpointType = '';			// soap|wsdl, empty for WSDL initialization error
45
	var $persistentConnection = false;
46
	var $defaultRpcParams = false;	// This is no longer used
47
	var $request = '';				// HTTP request
48
	var $response = '';				// HTTP response
49
	var $responseData = '';			// SOAP payload of response
50
	var $cookies = array();			// Cookies from response or for request
51
    var $decode_utf8 = true;		// toggles whether the parser decodes element content w/ utf8_decode()
52
	var $operations = array();		// WSDL operations, empty for WSDL initialization error
53
	var $curl_options = array();	// User-specified cURL options
54
	var $bindingType = '';			// WSDL operation binding type
55
	var $use_curl = false;			// whether to always try to use cURL
56
57
	/*
58
	 * fault related variables
59
	 */
60
	/**
61
	 * @var      fault
62
	 * @access   public
63
	 */
64
	var $fault;
65
	/**
66
	 * @var      faultcode
67
	 * @access   public
68
	 */
69
	var $faultcode;
70
	/**
71
	 * @var      faultstring
72
	 * @access   public
73
	 */
74
	var $faultstring;
75
	/**
76
	 * @var      faultdetail
77
	 * @access   public
78
	 */
79
	var $faultdetail;
80
81
	/**
82
	* constructor
83
	*
84
	* @param    mixed $endpoint SOAP server or WSDL URL (string), or wsdl instance (object)
85
	* @param    mixed $wsdl optional, set to 'wsdl' or true if using WSDL
86
	* @param    string $proxyhost optional
87
	* @param    string $proxyport optional
88
	* @param	string $proxyusername optional
89
	* @param	string $proxypassword optional
90
	* @param	integer $timeout set the connection timeout
91
	* @param	integer $response_timeout set the response timeout
92
	* @param	string $portName optional portName in WSDL document
93
	* @access   public
94
	*/
95
	function __construct($endpoint,$wsdl = false,$proxyhost = false,$proxyport = false,$proxyusername = false, $proxypassword = false, $timeout = 0, $response_timeout = 30, $portName = ''){
96
		parent::__construct();
97
		$this->endpoint = $endpoint;
98
		$this->proxyhost = $proxyhost;
99
		$this->proxyport = $proxyport;
100
		$this->proxyusername = $proxyusername;
101
		$this->proxypassword = $proxypassword;
102
		$this->timeout = $timeout;
103
		$this->response_timeout = $response_timeout;
104
		$this->portName = $portName;
105
106
		$this->debug("ctor wsdl=$wsdl timeout=$timeout response_timeout=$response_timeout");
107
		$this->appendDebug('endpoint=' . $this->varDump($endpoint));
108
109
		// make values
110
		if($wsdl){
111
			if (is_object($endpoint) && (get_class($endpoint) == 'wsdl')) {
112
				$this->wsdl = $endpoint;
113
				$this->endpoint = $this->wsdl->wsdl;
114
				$this->wsdlFile = $this->endpoint;
115
				$this->debug('existing wsdl instance created from ' . $this->endpoint);
116
				$this->checkWSDL();
117
			} else {
118
				$this->wsdlFile = $this->endpoint;
119
				$this->wsdl = null;
120
				$this->debug('will use lazy evaluation of wsdl from ' . $this->endpoint);
121
			}
122
			$this->endpointType = 'wsdl';
123
		} else {
124
			$this->debug("instantiate SOAP with endpoint at $endpoint");
125
			$this->endpointType = 'soap';
126
		}
127
	}
128
129
	/**
130
	* calls method, returns PHP native type
131
	*
132
	* @param    string $operation SOAP server URL or path
133
	* @param    mixed $params An array, associative or simple, of the parameters
134
	*			              for the method call, or a string that is the XML
135
	*			              for the call.  For rpc style, this call will
136
	*			              wrap the XML in a tag named after the method, as
137
	*			              well as the SOAP Envelope and Body.  For document
138
	*			              style, this will only wrap with the Envelope and Body.
139
	*			              IMPORTANT: when using an array with document style,
140
	*			              in which case there
141
	*                         is really one parameter, the root of the fragment
142
	*                         used in the call, which encloses what programmers
143
	*                         normally think of parameters.  A parameter array
144
	*                         *must* include the wrapper.
145
	* @param	string $namespace optional method namespace (WSDL can override)
146
	* @param	string $soapAction optional SOAPAction value (WSDL can override)
147
	* @param	mixed $headers optional string of XML with SOAP header content, or array of soapval objects for SOAP headers, or associative array
148
	* @param	boolean $rpcParams optional (no longer used)
149
	* @param	string	$style optional (rpc|document) the style to use when serializing parameters (WSDL can override)
150
	* @param	string	$use optional (encoded|literal) the use when serializing parameters (WSDL can override)
151
	* @return	mixed	response from SOAP call, normally an associative array mirroring the structure of the XML response, false for certain fatal errors
152
	* @access   public
153
	*/
154
	function call($operation,$params=array(),$namespace='http://tempuri.org',$soapAction='',$headers=false,$rpcParams=null,$style='rpc',$use='encoded'){
155
		$this->operation = $operation;
156
		$this->fault = false;
157
		$this->setError('');
158
		$this->request = '';
159
		$this->response = '';
160
		$this->responseData = '';
161
		$this->faultstring = '';
162
		$this->faultcode = '';
163
		$this->opData = array();
164
165
		$this->debug("call: operation=$operation, namespace=$namespace, soapAction=$soapAction, rpcParams=$rpcParams, style=$style, use=$use, endpointType=$this->endpointType");
166
		$this->appendDebug('params=' . $this->varDump($params));
167
		$this->appendDebug('headers=' . $this->varDump($headers));
168
		if ($headers) {
169
			$this->requestHeaders = $headers;
170
		}
171
		if ($this->endpointType == 'wsdl' && is_null($this->wsdl)) {
172
			$this->loadWSDL();
173
			if ($this->getError())
174
				return false;
175
		}
176
		// serialize parameters
177
		if($this->endpointType == 'wsdl' && $opData = $this->getOperationData($operation)){
178
			// use WSDL for operation
179
			$this->opData = $opData;
180
			$this->debug("found operation");
181
			$this->appendDebug('opData=' . $this->varDump($opData));
182
			if (isset($opData['soapAction'])) {
183
				$soapAction = $opData['soapAction'];
184
			}
185
			if (! $this->forceEndpoint) {
186
				$this->endpoint = $opData['endpoint'];
187
			} else {
188
				$this->endpoint = $this->forceEndpoint;
189
			}
190
			$namespace = isset($opData['input']['namespace']) ? $opData['input']['namespace'] :	$namespace;
191
			$style = $opData['style'];
192
			$use = $opData['input']['use'];
193
			// add ns to ns array
194
			if($namespace != '' && !isset($this->wsdl->namespaces[$namespace])){
195
				$nsPrefix = 'ns' . rand(1000, 9999);
196
				$this->wsdl->namespaces[$nsPrefix] = $namespace;
197
			}
198
            $nsPrefix = $this->wsdl->getPrefixFromNamespace($namespace);
199
			// serialize payload
200
			if (is_string($params)) {
201
				$this->debug("serializing param string for WSDL operation $operation");
202
				$payload = $params;
203
			} elseif (is_array($params)) {
204
				$this->debug("serializing param array for WSDL operation $operation");
205
				$payload = $this->wsdl->serializeRPCParameters($operation,'input',$params,$this->bindingType);
206
			} else {
207
				$this->debug('params must be array or string');
208
				$this->setError('params must be array or string');
209
				return false;
210
			}
211
            $usedNamespaces = $this->wsdl->usedNamespaces;
212
			if (isset($opData['input']['encodingStyle'])) {
213
				$encodingStyle = $opData['input']['encodingStyle'];
214
			} else {
215
				$encodingStyle = '';
216
			}
217
			$this->appendDebug($this->wsdl->getDebug());
218
			$this->wsdl->clearDebug();
219
			if ($errstr = $this->wsdl->getError()) {
220
				$this->debug('got wsdl error: '.$errstr);
221
				$this->setError('wsdl error: '.$errstr);
222
				return false;
223
			}
224
		} elseif($this->endpointType == 'wsdl') {
225
			// operation not in WSDL
226
			$this->appendDebug($this->wsdl->getDebug());
227
			$this->wsdl->clearDebug();
228
			$this->setError('operation '.$operation.' not present in WSDL.');
229
			$this->debug("operation '$operation' not present in WSDL.");
230
			return false;
231
		} else {
232
			// no WSDL
233
			//$this->namespaces['ns1'] = $namespace;
234
			$nsPrefix = 'ns' . rand(1000, 9999);
235
			// serialize
236
			$payload = '';
237
			if (is_string($params)) {
238
				$this->debug("serializing param string for operation $operation");
239
				$payload = $params;
240
			} elseif (is_array($params)) {
241
				$this->debug("serializing param array for operation $operation");
242
				foreach($params as $k => $v){
243
					$payload .= $this->serialize_val($v,$k,false,false,false,false,$use);
244
				}
245
			} else {
246
				$this->debug('params must be array or string');
247
				$this->setError('params must be array or string');
248
				return false;
249
			}
250
			$usedNamespaces = array();
251
			if ($use == 'encoded') {
252
				$encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
253
			} else {
254
				$encodingStyle = '';
255
			}
256
		}
257
		// wrap RPC calls with method element
258
		if ($style == 'rpc') {
259
			if ($use == 'literal') {
260
				$this->debug("wrapping RPC request with literal method element");
261
				if ($namespace) {
262
					// 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
263
					$payload = "<$nsPrefix:$operation xmlns:$nsPrefix=\"$namespace\">" .
264
								$payload .
265
								"</$nsPrefix:$operation>";
266
				} else {
267
					$payload = "<$operation>" . $payload . "</$operation>";
268
				}
269
			} else {
270
				$this->debug("wrapping RPC request with encoded method element");
271
				if ($namespace) {
272
					$payload = "<$nsPrefix:$operation xmlns:$nsPrefix=\"$namespace\">" .
273
								$payload .
274
								"</$nsPrefix:$operation>";
275
				} else {
276
					$payload = "<$operation>" .
277
								$payload .
278
								"</$operation>";
279
				}
280
			}
281
		}
282
		// serialize envelope
283
		$soapmsg = $this->serializeEnvelope($payload,$this->requestHeaders,$usedNamespaces,$style,$use,$encodingStyle);
284
		$this->debug("endpoint=$this->endpoint, soapAction=$soapAction, namespace=$namespace, style=$style, use=$use, encodingStyle=$encodingStyle");
285
		$this->debug('SOAP message length=' . strlen($soapmsg) . ' contents (max 1000 bytes)=' . substr($soapmsg, 0, 1000));
286
		// send
287
		$return = $this->send($this->getHTTPBody($soapmsg),$soapAction,$this->timeout,$this->response_timeout);
288
		if($errstr = $this->getError()){
289
			$this->debug('Error: '.$errstr);
290
			return false;
291
		} else {
292
			$this->return = $return;
293
			$this->debug('sent message successfully and got a(n) '.gettype($return));
294
           	$this->appendDebug('return=' . $this->varDump($return));
295
296
			// fault?
297
			if(is_array($return) && isset($return['faultcode'])){
298
				$this->debug('got fault');
299
				$this->setError($return['faultcode'].': '.$return['faultstring']);
300
				$this->fault = true;
301
				foreach($return as $k => $v){
302
					$this->$k = $v;
303
					$this->debug("$k = $v<br>");
304
				}
305
				return $return;
306
			} elseif ($style == 'document') {
307
				// NOTE: if the response is defined to have multiple parts (i.e. unwrapped),
308
				// we are only going to return the first part here...sorry about that
309
				return $return;
310
			} else {
311
				// array of return values
312
				if(is_array($return)){
313
					// multiple 'out' parameters, which we return wrapped up
314
					// in the array
315
					if(sizeof($return) > 1){
316
						return $return;
317
					}
318
					// single 'out' parameter (normally the return value)
319
					$return = array_shift($return);
320
					$this->debug('return shifted value: ');
321
					$this->appendDebug($this->varDump($return));
322
           			return $return;
323
				// nothing returned (ie, echoVoid)
324
				} else {
325
					return "";
326
				}
327
			}
328
		}
329
	}
330
331
	/**
332
	* check WSDL passed as an instance or pulled from an endpoint
333
	*
334
	* @access   private
335
	*/
336
	function checkWSDL() {
337
		$this->appendDebug($this->wsdl->getDebug());
338
		$this->wsdl->clearDebug();
339
		$this->debug('checkWSDL');
340
		// catch errors
341
		if ($errstr = $this->wsdl->getError()) {
342
			$this->appendDebug($this->wsdl->getDebug());
343
			$this->wsdl->clearDebug();
344
			$this->debug('got wsdl error: '.$errstr);
345
			$this->setError('wsdl error: '.$errstr);
346
		} elseif ($this->operations = $this->wsdl->getOperations($this->portName, 'soap')) {
347
			$this->appendDebug($this->wsdl->getDebug());
348
			$this->wsdl->clearDebug();
349
			$this->bindingType = 'soap';
350
			$this->debug('got '.count($this->operations).' operations from wsdl '.$this->wsdlFile.' for binding type '.$this->bindingType);
351
		} elseif ($this->operations = $this->wsdl->getOperations($this->portName, 'soap12')) {
352
			$this->appendDebug($this->wsdl->getDebug());
353
			$this->wsdl->clearDebug();
354
			$this->bindingType = 'soap12';
355
			$this->debug('got '.count($this->operations).' operations from wsdl '.$this->wsdlFile.' for binding type '.$this->bindingType);
356
			$this->debug('**************** WARNING: SOAP 1.2 BINDING *****************');
357
		} else {
358
			$this->appendDebug($this->wsdl->getDebug());
359
			$this->wsdl->clearDebug();
360
			$this->debug('getOperations returned false');
361
			$this->setError('no operations defined in the WSDL document!');
362
		}
363
	}
364
365
	/**
366
	 * instantiate wsdl object and parse wsdl file
367
	 *
368
	 * @access	public
369
	 */
370
	function loadWSDL() {
371
		$this->debug('instantiating wsdl class with doc: '.$this->wsdlFile);
372
		$this->wsdl = new wsdl('',$this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword,$this->timeout,$this->response_timeout,$this->curl_options,$this->use_curl);
373
		$this->wsdl->setCredentials($this->username, $this->password, $this->authtype, $this->certRequest);
374
		$this->wsdl->fetchWSDL($this->wsdlFile);
375
		$this->checkWSDL();
376
	}
377
378
	/**
379
	* get available data pertaining to an operation
380
	*
381
	* @param    string $operation operation name
382
	* @return	array array of data pertaining to the operation
383
	* @access   public
384
	*/
385
	function getOperationData($operation){
386
		if ($this->endpointType == 'wsdl' && is_null($this->wsdl)) {
387
			$this->loadWSDL();
388
			if ($this->getError())
389
				return false;
390
		}
391
		if(isset($this->operations[$operation])){
392
			return $this->operations[$operation];
393
		}
394
		$this->debug("No data for operation: $operation");
395
	}
396
397
    /**
398
    * send the SOAP message
399
    *
400
    * Note: if the operation has multiple return values
401
    * the return value of this method will be an array
402
    * of those values.
403
    *
404
	* @param    string $msg a SOAPx4 soapmsg object
405
	* @param    string $soapaction SOAPAction value
406
	* @param    integer $timeout set connection timeout in seconds
407
	* @param	integer $response_timeout set response timeout in seconds
408
	* @return	mixed native PHP types.
409
	* @access   private
410
	*/
411
	function send($msg, $soapaction = '', $timeout=0, $response_timeout=30) {
412
		$this->checkCookies();
413
		// detect transport
414
		switch(true){
415
			// http(s)
416
			case preg_match('/^http/',$this->endpoint):
417
				$this->debug('transporting via HTTP');
418
				if($this->persistentConnection == true && is_object($this->persistentConnection)){
419
					$http =& $this->persistentConnection;
420
				} else {
421
					$http = new soap_transport_http($this->endpoint, $this->curl_options, $this->use_curl);
422
					if ($this->persistentConnection) {
423
						$http->usePersistentConnection();
424
					}
425
				}
426
				$http->setContentType($this->getHTTPContentType(), $this->getHTTPContentTypeCharset());
427
				$http->setSOAPAction($soapaction);
428
				if($this->proxyhost && $this->proxyport){
429
					$http->setProxy($this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword);
430
				}
431
                if($this->authtype != '') {
432
					$http->setCredentials($this->username, $this->password, $this->authtype, array(), $this->certRequest);
433
				}
434
				if($this->http_encoding != ''){
435
					$http->setEncoding($this->http_encoding);
436
				}
437
				$this->debug('sending message, length='.strlen($msg));
438
				if(preg_match('/^http:/',$this->endpoint)){
439
				//if(strpos($this->endpoint,'http:')){
440
					$this->responseData = $http->send($msg,$timeout,$response_timeout,$this->cookies);
441
				} elseif(preg_match('/^https/',$this->endpoint)){
442
				//} elseif(strpos($this->endpoint,'https:')){
443
					//if(phpversion() == '4.3.0-dev'){
444
						//$response = $http->send($msg,$timeout,$response_timeout);
445
                   		//$this->request = $http->outgoing_payload;
446
						//$this->response = $http->incoming_payload;
447
					//} else
448
					$this->responseData = $http->sendHTTPS($msg,$timeout,$response_timeout,$this->cookies);
449
				} else {
450
					$this->setError('no http/s in endpoint url');
451
				}
452
				$this->request = $http->outgoing_payload;
453
				$this->response = $http->incoming_payload;
454
				$this->appendDebug($http->getDebug());
455
				$this->UpdateCookies($http->incoming_cookies);
456
457
				// save transport object if using persistent connections
458
				if ($this->persistentConnection) {
459
					$http->clearDebug();
460
					if (!is_object($this->persistentConnection)) {
461
						$this->persistentConnection = $http;
462
					}
463
				}
464
465
				if($err = $http->getError()){
466
					$this->setError('HTTP Error: '.$err);
467
					return false;
468
				} elseif($this->getError()){
469
					return false;
470
				} else {
471
					$this->debug('got response, length='. strlen($this->responseData).' type='.$http->incoming_headers['content-type']);
472
					return $this->parseResponse($http->incoming_headers, $this->responseData);
473
				}
474
			break;
475
			default:
476
				$this->setError('no transport found, or selected transport is not yet supported!');
477
			return false;
478
			break;
479
		}
480
	}
481
482
	/**
483
	* processes SOAP message returned from server
484
	*
485
	* @param	array	$headers	The HTTP headers
486
	* @param	string	$data		unprocessed response data from server
487
	* @return	mixed	value of the message, decoded into a PHP type
488
	* @access   private
489
	*/
490
    function parseResponse($headers, $data) {
491
		$this->debug('Entering parseResponse() for data of length ' . strlen($data) . ' headers:');
492
		$this->appendDebug($this->varDump($headers));
493
    	if (!isset($headers['content-type'])) {
494
			$this->setError('Response not of type text/xml (no content-type header)');
495
			return false;
496
    	}
497
		if (!strstr($headers['content-type'], 'text/xml')) {
498
			$this->setError('Response not of type text/xml: ' . $headers['content-type']);
499
			return false;
500
		}
501
		if (strpos($headers['content-type'], '=')) {
502
			$enc = str_replace('"', '', substr(strstr($headers["content-type"], '='), 1));
503
			$this->debug('Got response encoding: ' . $enc);
504
			if(preg_match('/^(ISO-8859-1|US-ASCII|UTF-8)$/i',$enc)){
505
				$this->xml_encoding = strtoupper($enc);
506
			} else {
507
				$this->xml_encoding = 'US-ASCII';
508
			}
509
		} else {
510
			// should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
511
			$this->xml_encoding = 'ISO-8859-1';
512
		}
513
		$this->debug('Use encoding: ' . $this->xml_encoding . ' when creating nusoap_parser');
514
		$parser = new nusoap_parser($data,$this->xml_encoding,$this->operation,$this->decode_utf8);
515
		// add parser debug data to our debug
516
		$this->appendDebug($parser->getDebug());
517
		// if parse errors
518
		if($errstr = $parser->getError()){
519
			$this->setError( $errstr);
520
			// destroy the parser object
521
			unset($parser);
522
			return false;
523
		} else {
524
			// get SOAP headers
525
			$this->responseHeaders = $parser->getHeaders();
526
			// get SOAP headers
527
			$this->responseHeader = $parser->get_soapheader();
528
			// get decoded message
529
			$return = $parser->get_soapbody();
530
            // add document for doclit support
531
            $this->document = $parser->document;
532
			// destroy the parser object
533
			unset($parser);
534
			// return decode message
535
			return $return;
536
		}
537
	 }
538
539
	/**
540
	* sets user-specified cURL options
541
	*
542
	* @param	mixed $option The cURL option (always integer?)
543
	* @param	mixed $value The cURL option value
544
	* @access   public
545
	*/
546
	function setCurlOption($option, $value) {
547
		$this->debug("setCurlOption option=$option, value=");
548
		$this->appendDebug($this->varDump($value));
549
		$this->curl_options[$option] = $value;
550
	}
551
552
	/**
553
	* sets the SOAP endpoint, which can override WSDL
554
	*
555
	* @param	string $endpoint The endpoint URL to use, or empty string or false to prevent override
556
	* @access   public
557
	*/
558
	function setEndpoint($endpoint) {
559
		$this->debug("setEndpoint(\"$endpoint\")");
560
		$this->forceEndpoint = $endpoint;
561
	}
562
563
	/**
564
	* set the SOAP headers
565
	*
566
	* @param	mixed $headers String of XML with SOAP header content, or array of soapval objects for SOAP headers
567
	* @access   public
568
	*/
569
	function setHeaders($headers){
570
		$this->debug("setHeaders headers=");
571
		$this->appendDebug($this->varDump($headers));
572
		$this->requestHeaders = $headers;
573
	}
574
575
	/**
576
	* get the SOAP response headers (namespace resolution incomplete)
577
	*
578
	* @return	string
579
	* @access   public
580
	*/
581
	function getHeaders(){
582
		return $this->responseHeaders;
583
	}
584
585
	/**
586
	* get the SOAP response Header (parsed)
587
	*
588
	* @return	mixed
589
	* @access   public
590
	*/
591
	function getHeader(){
592
		return $this->responseHeader;
593
	}
594
595
	/**
596
	* set proxy info here
597
	*
598
	* @param    string $proxyhost
599
	* @param    string $proxyport
600
	* @param	string $proxyusername
601
	* @param	string $proxypassword
602
	* @access   public
603
	*/
604
	function setHTTPProxy($proxyhost, $proxyport, $proxyusername = '', $proxypassword = '') {
605
		$this->proxyhost = $proxyhost;
606
		$this->proxyport = $proxyport;
607
		$this->proxyusername = $proxyusername;
608
		$this->proxypassword = $proxypassword;
609
	}
610
611
	/**
612
	* if authenticating, set user credentials here
613
	*
614
	* @param    string $username
615
	* @param    string $password
616
	* @param	string $authtype (basic|digest|certificate|ntlm)
617
	* @param	array $certRequest (keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, verifypeer (optional), verifyhost (optional): see corresponding options in cURL docs)
618
	* @access   public
619
	*/
620
	function setCredentials($username, $password, $authtype = 'basic', $certRequest = array()) {
621
		$this->debug("setCredentials username=$username authtype=$authtype certRequest=");
622
		$this->appendDebug($this->varDump($certRequest));
623
		$this->username = $username;
624
		$this->password = $password;
625
		$this->authtype = $authtype;
626
		$this->certRequest = $certRequest;
627
	}
628
629
	/**
630
	* use HTTP encoding
631
	*
632
	* @param    string $enc HTTP encoding
633
	* @access   public
634
	*/
635
	function setHTTPEncoding($enc='gzip, deflate'){
636
		$this->debug("setHTTPEncoding(\"$enc\")");
637
		$this->http_encoding = $enc;
638
	}
639
640
	/**
641
	* Set whether to try to use cURL connections if possible
642
	*
643
	* @param	boolean $use Whether to try to use cURL
644
	* @access   public
645
	*/
646
	function setUseCURL($use) {
647
		$this->debug("setUseCURL($use)");
648
		$this->use_curl = $use;
649
	}
650
651
	/**
652
	* use HTTP persistent connections if possible
653
	*
654
	* @access   public
655
	*/
656
	function useHTTPPersistentConnection(){
657
		$this->debug("useHTTPPersistentConnection");
658
		$this->persistentConnection = true;
659
	}
660
661
	/**
662
	* gets the default RPC parameter setting.
663
	* If true, default is that call params are like RPC even for document style.
664
	* Each call() can override this value.
665
	*
666
	* This is no longer used.
667
	*
668
	* @return boolean
669
	* @access public
670
	* @deprecated
671
	*/
672
	function getDefaultRpcParams() {
673
		return $this->defaultRpcParams;
674
	}
675
676
	/**
677
	* sets the default RPC parameter setting.
678
	* If true, default is that call params are like RPC even for document style
679
	* Each call() can override this value.
680
	*
681
	* This is no longer used.
682
	*
683
	* @param    boolean $rpcParams
684
	* @access public
685
	* @deprecated
686
	*/
687
	function setDefaultRpcParams($rpcParams) {
688
		$this->defaultRpcParams = $rpcParams;
689
	}
690
691
	/**
692
	* dynamically creates an instance of a proxy class,
693
	* allowing user to directly call methods from wsdl
694
	*
695
	* @return   object soap_proxy object
696
	* @access   public
697
	*/
698
	function getProxy() {
699
		$r = rand();
700
		$evalStr = $this->_getProxyClassCode($r);
701
		//$this->debug("proxy class: $evalStr");
702
		if ($this->getError()) {
703
			$this->debug("Error from _getProxyClassCode, so return NULL");
704
			return null;
705
		}
706
		// eval the class
707
		eval($evalStr);
708
		// instantiate proxy object
709
		eval("\$proxy = new nusoap_proxy_$r('');");
710
		// transfer current wsdl data to the proxy thereby avoiding parsing the wsdl twice
711
		$proxy->endpointType = 'wsdl';
712
		$proxy->wsdlFile = $this->wsdlFile;
713
		$proxy->wsdl = $this->wsdl;
714
		$proxy->operations = $this->operations;
715
		$proxy->defaultRpcParams = $this->defaultRpcParams;
716
		// transfer other state
717
		$proxy->soap_defencoding = $this->soap_defencoding;
718
		$proxy->username = $this->username;
719
		$proxy->password = $this->password;
720
		$proxy->authtype = $this->authtype;
721
		$proxy->certRequest = $this->certRequest;
722
		$proxy->requestHeaders = $this->requestHeaders;
723
		$proxy->endpoint = $this->endpoint;
724
		$proxy->forceEndpoint = $this->forceEndpoint;
725
		$proxy->proxyhost = $this->proxyhost;
726
		$proxy->proxyport = $this->proxyport;
727
		$proxy->proxyusername = $this->proxyusername;
728
		$proxy->proxypassword = $this->proxypassword;
729
		$proxy->http_encoding = $this->http_encoding;
730
		$proxy->timeout = $this->timeout;
731
		$proxy->response_timeout = $this->response_timeout;
732
		$proxy->persistentConnection = &$this->persistentConnection;
733
		$proxy->decode_utf8 = $this->decode_utf8;
734
		$proxy->curl_options = $this->curl_options;
735
		$proxy->bindingType = $this->bindingType;
736
		$proxy->use_curl = $this->use_curl;
737
		return $proxy;
738
	}
739
740
	/**
741
	* dynamically creates proxy class code
742
	*
743
	* @return   string PHP/NuSOAP code for the proxy class
744
	* @access   private
745
	*/
746
	function _getProxyClassCode($r) {
747
		$this->debug("in getProxy endpointType=$this->endpointType");
748
		$this->appendDebug("wsdl=" . $this->varDump($this->wsdl));
749
		if ($this->endpointType != 'wsdl') {
750
			$evalStr = 'A proxy can only be created for a WSDL client';
751
			$this->setError($evalStr);
752
			$evalStr = "echo \"$evalStr\";";
753
			return $evalStr;
754
		}
755
		if ($this->endpointType == 'wsdl' && is_null($this->wsdl)) {
756
			$this->loadWSDL();
757
			if ($this->getError()) {
758
				return "echo \"" . $this->getError() . "\";";
759
			}
760
		}
761
		$evalStr = '';
762
		foreach ($this->operations as $operation => $opData) {
763
			if ($operation != '') {
764
				// create param string and param comment string
765
				if (sizeof($opData['input']['parts']) > 0) {
766
					$paramStr = '';
767
					$paramArrayStr = '';
768
					$paramCommentStr = '';
769
					foreach ($opData['input']['parts'] as $name => $type) {
770
						$paramStr .= "\$$name, ";
771
						$paramArrayStr .= "'$name' => \$$name, ";
772
						$paramCommentStr .= "$type \$$name, ";
773
					}
774
					$paramStr = substr($paramStr, 0, strlen($paramStr)-2);
775
					$paramArrayStr = substr($paramArrayStr, 0, strlen($paramArrayStr)-2);
776
					$paramCommentStr = substr($paramCommentStr, 0, strlen($paramCommentStr)-2);
777
				} else {
778
					$paramStr = '';
779
					$paramArrayStr = '';
780
					$paramCommentStr = 'void';
781
				}
782
				$opData['namespace'] = !isset($opData['namespace']) ? 'http://testuri.com' : $opData['namespace'];
783
				$evalStr .= "// $paramCommentStr
784
	function " . str_replace('.', '__', $operation) . "($paramStr) {
785
		\$params = array($paramArrayStr);
786
		return \$this->call('$operation', \$params, '".$opData['namespace']."', '".(isset($opData['soapAction']) ? $opData['soapAction'] : '')."');
787
	}
788
	";
789
				unset($paramStr);
790
				unset($paramCommentStr);
791
			}
792
		}
793
		$evalStr = 'class nusoap_proxy_'.$r.' extends nusoap_client {
794
	'.$evalStr.'
795
}';
796
		return $evalStr;
797
	}
798
799
	/**
800
	* dynamically creates proxy class code
801
	*
802
	* @return   string PHP/NuSOAP code for the proxy class
803
	* @access   public
804
	*/
805
	function getProxyClassCode() {
806
		$r = rand();
807
		return $this->_getProxyClassCode($r);
808
	}
809
810
	/**
811
	* gets the HTTP body for the current request.
812
	*
813
	* @param string $soapmsg The SOAP payload
814
	* @return string The HTTP body, which includes the SOAP payload
815
	* @access private
816
	*/
817
	function getHTTPBody($soapmsg) {
818
		return $soapmsg;
819
	}
820
821
	/**
822
	* gets the HTTP content type for the current request.
823
	*
824
	* Note: getHTTPBody must be called before this.
825
	*
826
	* @return string the HTTP content type for the current request.
827
	* @access private
828
	*/
829
	function getHTTPContentType() {
830
		return 'text/xml';
831
	}
832
833
	/**
834
	* gets the HTTP content type charset for the current request.
835
	* returns false for non-text content types.
836
	*
837
	* Note: getHTTPBody must be called before this.
838
	*
839
	* @return string the HTTP content type charset for the current request.
840
	* @access private
841
	*/
842
	function getHTTPContentTypeCharset() {
843
		return $this->soap_defencoding;
844
	}
845
846
	/*
847
	* whether or not parser should decode utf8 element content
848
    *
849
    * @return   always returns true
850
    * @access   public
851
    */
852
    function decodeUTF8($bool){
853
		$this->decode_utf8 = $bool;
854
		return true;
855
    }
856
857
	/**
858
	 * adds a new Cookie into $this->cookies array
859
	 *
860
	 * @param	string $name Cookie Name
861
	 * @param	string $value Cookie Value
862
	 * @return	boolean if cookie-set was successful returns true, else false
863
	 * @access	public
864
	 */
865
	function setCookie($name, $value) {
866
		if (strlen($name) == 0) {
867
			return false;
868
		}
869
		$this->cookies[] = array('name' => $name, 'value' => $value);
870
		return true;
871
	}
872
873
	/**
874
	 * gets all Cookies
875
	 *
876
	 * @return   array with all internal cookies
877
	 * @access   public
878
	 */
879
	function getCookies() {
880
		return $this->cookies;
881
	}
882
883
	/**
884
	 * checks all Cookies and delete those which are expired
885
	 *
886
	 * @return   boolean always return true
887
	 * @access   private
888
	 */
889
	function checkCookies() {
890
		if (sizeof($this->cookies) == 0) {
891
			return true;
892
		}
893
		$this->debug('checkCookie: check ' . sizeof($this->cookies) . ' cookies');
894
		$curr_cookies = $this->cookies;
895
		$this->cookies = array();
896
		foreach ($curr_cookies as $cookie) {
897
			if (! is_array($cookie)) {
898
				$this->debug('Remove cookie that is not an array');
899
				continue;
900
			}
901
			if ((isset($cookie['expires'])) && (! empty($cookie['expires']))) {
902
				if (strtotime($cookie['expires']) > time()) {
903
					$this->cookies[] = $cookie;
904
				} else {
905
					$this->debug('Remove expired cookie ' . $cookie['name']);
906
				}
907
			} else {
908
				$this->cookies[] = $cookie;
909
			}
910
		}
911
		$this->debug('checkCookie: '.sizeof($this->cookies).' cookies left in array');
912
		return true;
913
	}
914
915
	/**
916
	 * updates the current cookies with a new set
917
	 *
918
	 * @param	array $cookies new cookies with which to update current ones
919
	 * @return	boolean always return true
920
	 * @access	private
921
	 */
922
	function UpdateCookies($cookies) {
923
		if (sizeof($this->cookies) == 0) {
924
			// no existing cookies: take whatever is new
925
			if (sizeof($cookies) > 0) {
926
				$this->debug('Setting new cookie(s)');
927
				$this->cookies = $cookies;
928
			}
929
			return true;
930
		}
931
		if (sizeof($cookies) == 0) {
932
			// no new cookies: keep what we've got
933
			return true;
934
		}
935
		// merge
936
		foreach ($cookies as $newCookie) {
937
			if (!is_array($newCookie)) {
938
				continue;
939
			}
940
			if ((!isset($newCookie['name'])) || (!isset($newCookie['value']))) {
941
				continue;
942
			}
943
			$newName = $newCookie['name'];
944
945
			$found = false;
946
			for ($i = 0; $i < count($this->cookies); $i++) {
947
				$cookie = $this->cookies[$i];
948
				if (!is_array($cookie)) {
949
					continue;
950
				}
951
				if (!isset($cookie['name'])) {
952
					continue;
953
				}
954
				if ($newName != $cookie['name']) {
955
					continue;
956
				}
957
				$newDomain = isset($newCookie['domain']) ? $newCookie['domain'] : 'NODOMAIN';
958
				$domain = isset($cookie['domain']) ? $cookie['domain'] : 'NODOMAIN';
959
				if ($newDomain != $domain) {
960
					continue;
961
				}
962
				$newPath = isset($newCookie['path']) ? $newCookie['path'] : 'NOPATH';
963
				$path = isset($cookie['path']) ? $cookie['path'] : 'NOPATH';
964
				if ($newPath != $path) {
965
					continue;
966
				}
967
				$this->cookies[$i] = $newCookie;
968
				$found = true;
969
				$this->debug('Update cookie ' . $newName . '=' . $newCookie['value']);
970
				break;
971
			}
972
			if (! $found) {
973
				$this->debug('Add cookie ' . $newName . '=' . $newCookie['value']);
974
				$this->cookies[] = $newCookie;
975
			}
976
		}
977
		return true;
978
	}
979
}
980
981
if (!extension_loaded('soap')) {
982
	/**
983
	 *	For backwards compatiblity, define soapclient unless the PHP SOAP extension is loaded.
984
	 */
985
	class soapclient extends nusoap_client {
986
	}
987
}
988
?>
989