Issues (4069)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

include/nusoap/class.soapclient.php (18 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
/*
4
5
Modification information for LGPL compliance
6
7
r57813 - 2010-08-19 10:34:44 -0700 (Thu, 19 Aug 2010) - kjing - Author: John Mertic <[email protected]>
8
    Bug 39085 - When loading the opposite search panel via ajax on the ListViews, call the index action instead of the ListView action to avoid touching pre-MVC code by accident.
9
10
r56990 - 2010-06-16 13:05:36 -0700 (Wed, 16 Jun 2010) - kjing - snapshot "Mango" svn branch to a new one for GitHub sync
11
12
r56989 - 2010-06-16 13:01:33 -0700 (Wed, 16 Jun 2010) - kjing - defunt "Mango" svn dev branch before github cutover
13
14
r55980 - 2010-04-19 13:31:28 -0700 (Mon, 19 Apr 2010) - kjing - create Mango (6.1) based on windex
15
16
r51719 - 2009-10-22 10:18:00 -0700 (Thu, 22 Oct 2009) - mitani - Converted to Build 3  tags and updated the build system 
17
18
r51634 - 2009-10-19 13:32:22 -0700 (Mon, 19 Oct 2009) - mitani - Windex is the branch for Sugar Sales 1.0 development
19
20
r51443 - 2009-10-12 13:34:36 -0700 (Mon, 12 Oct 2009) - jmertic - Bug 33332 - Made application PHP 5.3 compliant with E_DEPRECATED warnings on by:
21
- Changing all ereg function to either preg or simple string based ones
22
- No more references to magic quotes.
23
- Change all the session_unregister() functions to just unset() the correct session variable instead.
24
25
r50375 - 2009-08-24 18:07:43 -0700 (Mon, 24 Aug 2009) - dwong - branch kobe2 from tokyo r50372
26
27
r42807 - 2008-12-29 11:16:59 -0800 (Mon, 29 Dec 2008) - dwong - Branch from trunk/sugarcrm r42806 to branches/tokyo/sugarcrm
28
29
r39619 - 2008-09-09 13:41:34 -0700 (Tue, 09 Sep 2008) - jmertic - Bug 24827 - Remove all instances where we return a new object and assign it by reference, since this is deprecated in PHP 5 and emits E_DEPRECATED errors in PHP 5.3.
30
Touched:
31
- data/SugarBean.php
32
- include/domit/php_http_client_generic.php
33
- include/domit/php_http_connector.php
34
- include/domit/testing_domit.php
35
- include/domit/xml_domit_getelementsbypath.php
36
- include/domit/xml_domit_lite_parser.php
37
- include/domit/xml_domit_nodemaps.php
38
- include/domit/xml_domit_parser.php
39
- include/domit/xml_domit_shared.php
40
- include/generic/SugarWidgets/SugarWidgetField.php
41
- include/generic/SugarWidgets/SugarWidgetReportField.php
42
- include/ListView/ProcessView.php
43
- include/nusoap/class.soapclient.php
44
- include/nusoap/nusoap.php
45
- include/nusoap/nusoapmime.php
46
- include/Pear/HTML_Safe/Safe.php
47
- include/Pear/XML_HTMLSax3/HTMLSax3.php
48
- modules/Administration/RebuildWorkFlow.php
49
- modules/Expressions/RelateSelector.php
50
- modules/Reports/templates/templates_reports.php
51
- modules/WorkFlow/Delete.php
52
- modules/WorkFlow/Save.php
53
- modules/WorkFlow/SaveSequence.php
54
- modules/WorkFlow/WorkFlow.php
55
- modules/WorkFlowActionShells/CreateStep1.php
56
- modules/WorkFlowActionShells/CreateStep2.php
57
- modules/WorkFlowActionShells/Save.php
58
- modules/WorkFlowActionShells/WorkFlowActionShell.php
59
- modules/WorkFlowAlerts/Save.php
60
- modules/WorkFlowAlerts/WorkFlowAlert.php
61
- modules/WorkFlowAlertShells/DetailView.php
62
- modules/WorkFlowAlertShells/WorkFlowAlertShell.php
63
- modules/WorkFlowTriggerShells/CreateStep1.php
64
- modules/WorkFlowTriggerShells/CreateStepFilter.php
65
- modules/WorkFlowTriggerShells/SaveFilter.php
66
- modules/WorkFlowTriggerShells/WorkFlowTriggerShell.php
67
- soap/SoapHelperFunctions.php
68
- test/modules/DynamicFields/DynamicFields_Bug24095_test.php
69
- test/simpletest/browser.php
70
- test/simpletest/default_reporter.php
71
- test/simpletest/detached.php
72
- test/simpletest/eclipse.php
73
- test/simpletest/expectation.php
74
- test/simpletest/extensions/pear_test_case.php
75
- test/simpletest/form.php
76
- test/simpletest/http.php
77
- test/simpletest/mock_objects.php
78
- test/simpletest/page.php
79
- test/simpletest/parser.php
80
- test/simpletest/remote.php
81
- test/simpletest/shell_tester.php
82
- test/simpletest/simple_test.php
83
- test/simpletest/simpletest.php
84
- test/simpletest/test/acceptance_test.php
85
- test/simpletest/test/adapter_test.php
86
- test/simpletest/test/authentication_test.php
87
- test/simpletest/test/browser_test.php
88
- test/simpletest/test/collector_test.php
89
- test/simpletest/test/compatibility_test.php
90
- test/simpletest/test/detached_test.php
91
- test/simpletest/test/eclipse_test.php
92
- test/simpletest/test/encoding_test.php
93
- test/simpletest/test/errors_test.php
94
- test/simpletest/test/expectation_test.php
95
- test/simpletest/test/form_test.php
96
- test/simpletest/test/frames_test.php
97
- test/simpletest/test/http_test.php
98
- test/simpletest/test/live_test.php
99
- test/simpletest/test/mock_objects_test.php
100
- test/simpletest/test/page_test.php
101
- test/simpletest/test/parse_error_test.php
102
- test/simpletest/test/parser_test.php
103
- test/simpletest/test/remote_test.php
104
- test/simpletest/test/shell_test.php
105
- test/simpletest/test/shell_tester_test.php
106
- test/simpletest/test/simpletest_test.php
107
- test/simpletest/test/site/page_request.php
108
- test/simpletest/test/tag_test.php
109
- test/simpletest/test/unit_tester_test.php
110
- test/simpletest/test/user_agent_test.php
111
- test/simpletest/test/visual_test.php
112
- test/simpletest/test/xml_test.php
113
- test/simpletest/test_case.php
114
- test/simpletest/ui/array_reporter/test.php
115
- test/simpletest/ui/recorder/test.php
116
- test/simpletest/unit_tester.php
117
- test/simpletest/url.php
118
- test/simpletest/user_agent.php
119
- test/simpletest/web_tester.php
120
- test/spikephpcoverage/src/PEAR.php
121
- test/spikephpcoverage/src/util/Utility.php
122
- test/spikephpcoverage/src/XML/Parser.php
123
- test/spikephpcoverage/src/XML/Parser/Simple.php
124
- test/test_utilities/SugarTest_SimpleBrowser.php
125
126
r13782 - 2006-06-06 10:58:55 -0700 (Tue, 06 Jun 2006) - majed - changes entry point code
127
128
r11115 - 2006-01-17 14:54:45 -0800 (Tue, 17 Jan 2006) - majed - add entry point validation
129
130
r8991 - 2005-11-03 19:07:25 -0800 (Thu, 03 Nov 2005) - majed - fixes nusoap issue
131
132
r8846 - 2005-10-31 11:01:12 -0800 (Mon, 31 Oct 2005) - majed - new version of nusoap
133
134
r7905 - 2005-09-21 19:12:57 -0700 (Wed, 21 Sep 2005) - majed - restores old nusoap pre & with a few fixes
135
136
r7861 - 2005-09-20 15:40:25 -0700 (Tue, 20 Sep 2005) - majed - & fix for 3.5.1
137
138
r5462 - 2005-05-25 13:50:11 -0700 (Wed, 25 May 2005) - majed - upgraded nusoap to .6.9
139
140
r573 - 2004-09-04 13:03:32 -0700 (Sat, 04 Sep 2004) - sugarclint - undoing copyrights added in inadvertantly.  --clint
141
142
r546 - 2004-09-03 11:49:38 -0700 (Fri, 03 Sep 2004) - sugarmsi - removed echo count
143
144
r354 - 2004-08-02 23:00:37 -0700 (Mon, 02 Aug 2004) - sugarjacob - Adding Soap
145
146
147
*/
148
149
150
if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
151
152
153
154
155
/**
156
*
157
* [nu]soapclient higher level class for easy usage.
158
*
159
* usage:
160
*
161
* // instantiate client with server info
162
* $soapclient = new nusoap_client( string path [ ,mixed wsdl] );
163
*
164
* // call method, get results
165
* echo $soapclient->call( string methodname [ ,array parameters] );
166
*
167
* // bye bye client
168
* unset($soapclient);
169
*
170
* @author   Dietrich Ayala <[email protected]>
171
* @author   Scott Nichol <[email protected]>
172
173
* @access   public
174
*/
175
class nusoap_client extends nusoap_base  {
176
177
	var $username = '';				// Username for HTTP authentication
178
	var $password = '';				// Password for HTTP authentication
179
	var $authtype = '';				// Type of HTTP authentication
180
	var $certRequest = array();		// Certificate for HTTP SSL authentication
181
	var $requestHeaders = false;	// SOAP headers in request (text)
182
	var $responseHeaders = '';		// SOAP headers from response (incomplete namespace resolution) (text)
183
	var $responseHeader = NULL;		// SOAP Header from response (parsed)
184
	var $document = '';				// SOAP body response portion (incomplete namespace resolution) (text)
185
	var $endpoint;
186
	var $forceEndpoint = '';		// overrides WSDL endpoint
187
    var $proxyhost = '';
188
    var $proxyport = '';
189
	var $proxyusername = '';
190
	var $proxypassword = '';
191
	var $portName = '';				// port name to use in WSDL
192
    var $xml_encoding = '';			// character set encoding of incoming (response) messages
193
	var $http_encoding = false;
194
	var $timeout = 0;				// HTTP connection timeout
195
	var $response_timeout = 30;		// HTTP response timeout
196
	var $endpointType = '';			// soap|wsdl, empty for WSDL initialization error
197
	var $persistentConnection = false;
198
	var $defaultRpcParams = false;	// This is no longer used
199
	var $request = '';				// HTTP request
200
	var $response = '';				// HTTP response
201
	var $responseData = '';			// SOAP payload of response
202
	var $cookies = array();			// Cookies from response or for request
203
    var $decode_utf8 = true;		// toggles whether the parser decodes element content w/ utf8_decode()
204
	var $operations = array();		// WSDL operations, empty for WSDL initialization error
205
	var $curl_options = array();	// User-specified cURL options
206
	var $bindingType = '';			// WSDL operation binding type
207
	var $use_curl = false;			// whether to always try to use cURL
208
209
	/*
210
	 * fault related variables
211
	 */
212
	/**
213
	 * @var      fault
214
	 * @access   public
215
	 */
216
	var $fault;
217
	/**
218
	 * @var      faultcode
219
	 * @access   public
220
	 */
221
	var $faultcode;
222
	/**
223
	 * @var      faultstring
224
	 * @access   public
225
	 */
226
	var $faultstring;
227
	/**
228
	 * @var      faultdetail
229
	 * @access   public
230
	 */
231
	var $faultdetail;
232
233
	/**
234
	* constructor
235
	*
236
	* @param    mixed $endpoint SOAP server or WSDL URL (string), or wsdl instance (object)
237
	* @param    mixed $wsdl optional, set to 'wsdl' or true if using WSDL
238
	* @param    string $proxyhost optional
239
	* @param    string $proxyport optional
240
	* @param	string $proxyusername optional
241
	* @param	string $proxypassword optional
242
	* @param	integer $timeout set the connection timeout
243
	* @param	integer $response_timeout set the response timeout
244
	* @param	string $portName optional portName in WSDL document
245
	* @access   public
246
	*/
247
	function nusoap_client($endpoint,$wsdl = false,$proxyhost = false,$proxyport = false,$proxyusername = false, $proxypassword = false, $timeout = 0, $response_timeout = 30, $portName = ''){
248
		parent::nusoap_base();
249
		$this->endpoint = $endpoint;
250
		$this->proxyhost = $proxyhost;
0 ignored issues
show
Documentation Bug introduced by
It seems like $proxyhost can also be of type false. However, the property $proxyhost is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
251
		$this->proxyport = $proxyport;
0 ignored issues
show
Documentation Bug introduced by
It seems like $proxyport can also be of type false. However, the property $proxyport is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
252
		$this->proxyusername = $proxyusername;
0 ignored issues
show
Documentation Bug introduced by
It seems like $proxyusername can also be of type false. However, the property $proxyusername is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
253
		$this->proxypassword = $proxypassword;
0 ignored issues
show
Documentation Bug introduced by
It seems like $proxypassword can also be of type false. However, the property $proxypassword is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
254
		$this->timeout = $timeout;
255
		$this->response_timeout = $response_timeout;
256
		$this->portName = $portName;
257
258
		$this->debug("ctor wsdl=$wsdl timeout=$timeout response_timeout=$response_timeout");
259
		$this->appendDebug('endpoint=' . $this->varDump($endpoint));
260
261
		// make values
262
		if($wsdl){
263
			if (is_object($endpoint) && (get_class($endpoint) == 'wsdl')) {
264
				$this->wsdl = $endpoint;
265
				$this->endpoint = $this->wsdl->wsdl;
266
				$this->wsdlFile = $this->endpoint;
267
				$this->debug('existing wsdl instance created from ' . $this->endpoint);
268
				$this->checkWSDL();
269
			} else {
270
				$this->wsdlFile = $this->endpoint;
271
				$this->wsdl = null;
272
				$this->debug('will use lazy evaluation of wsdl from ' . $this->endpoint);
273
			}
274
			$this->endpointType = 'wsdl';
275
		} else {
276
			$this->debug("instantiate SOAP with endpoint at $endpoint");
277
			$this->endpointType = 'soap';
278
		}
279
	}
280
281
	/**
282
	* calls method, returns PHP native type
283
	*
284
	* @param    string $operation SOAP server URL or path
285
	* @param    mixed $params An array, associative or simple, of the parameters
286
	*			              for the method call, or a string that is the XML
287
	*			              for the call.  For rpc style, this call will
288
	*			              wrap the XML in a tag named after the method, as
289
	*			              well as the SOAP Envelope and Body.  For document
290
	*			              style, this will only wrap with the Envelope and Body.
291
	*			              IMPORTANT: when using an array with document style,
292
	*			              in which case there
293
	*                         is really one parameter, the root of the fragment
294
	*                         used in the call, which encloses what programmers
295
	*                         normally think of parameters.  A parameter array
296
	*                         *must* include the wrapper.
297
	* @param	string $namespace optional method namespace (WSDL can override)
298
	* @param	string $soapAction optional SOAPAction value (WSDL can override)
299
	* @param	mixed $headers optional string of XML with SOAP header content, or array of soapval objects for SOAP headers, or associative array
300
	* @param	boolean $rpcParams optional (no longer used)
301
	* @param	string	$style optional (rpc|document) the style to use when serializing parameters (WSDL can override)
302
	* @param	string	$use optional (encoded|literal) the use when serializing parameters (WSDL can override)
303
	* @return	mixed	response from SOAP call, normally an associative array mirroring the structure of the XML response, false for certain fatal errors
304
	* @access   public
305
	*/
306
	function call($operation,$params=array(),$namespace='http://tempuri.org',$soapAction='',$headers=false,$rpcParams=null,$style='rpc',$use='encoded'){
307
		$this->operation = $operation;
308
		$this->fault = false;
309
		$this->setError('');
310
		$this->request = '';
311
		$this->response = '';
312
		$this->responseData = '';
313
		$this->faultstring = '';
314
		$this->faultcode = '';
315
		$this->opData = array();
316
		
317
		$this->debug("call: operation=$operation, namespace=$namespace, soapAction=$soapAction, rpcParams=$rpcParams, style=$style, use=$use, endpointType=$this->endpointType");
318
		$this->appendDebug('params=' . $this->varDump($params));
319
		$this->appendDebug('headers=' . $this->varDump($headers));
320
		if ($headers) {
321
			$this->requestHeaders = $headers;
322
		}
323
		if ($this->endpointType == 'wsdl' && is_null($this->wsdl)) {
324
			$this->loadWSDL();
325
			if ($this->getError())
326
				return false;
327
		}
328
		// serialize parameters
329
		if($this->endpointType == 'wsdl' && $opData = $this->getOperationData($operation)){
330
			// use WSDL for operation
331
			$this->opData = $opData;
332
			$this->debug("found operation");
333
			$this->appendDebug('opData=' . $this->varDump($opData));
334
			if (isset($opData['soapAction'])) {
335
				$soapAction = $opData['soapAction'];
336
			}
337
			if (! $this->forceEndpoint) {
338
				$this->endpoint = $opData['endpoint'];
339
			} else {
340
				$this->endpoint = $this->forceEndpoint;
341
			}
342
			$namespace = isset($opData['input']['namespace']) ? $opData['input']['namespace'] :	$namespace;
343
			$style = $opData['style'];
344
			$use = $opData['input']['use'];
345
			// add ns to ns array
346
			if($namespace != '' && !isset($this->wsdl->namespaces[$namespace])){
347
				$nsPrefix = 'ns' . rand(1000, 9999);
348
				$this->wsdl->namespaces[$nsPrefix] = $namespace;
349
			}
350
            $nsPrefix = $this->wsdl->getPrefixFromNamespace($namespace);
351
			// serialize payload
352
			if (is_string($params)) {
353
				$this->debug("serializing param string for WSDL operation $operation");
354
				$payload = $params;
355
			} elseif (is_array($params)) {
356
				$this->debug("serializing param array for WSDL operation $operation");
357
				$payload = $this->wsdl->serializeRPCParameters($operation,'input',$params,$this->bindingType);
358
			} else {
359
				$this->debug('params must be array or string');
360
				$this->setError('params must be array or string');
361
				return false;
362
			}
363
            $usedNamespaces = $this->wsdl->usedNamespaces;
364
			if (isset($opData['input']['encodingStyle'])) {
365
				$encodingStyle = $opData['input']['encodingStyle'];
366
			} else {
367
				$encodingStyle = '';
368
			}
369
			$this->appendDebug($this->wsdl->getDebug());
370
			$this->wsdl->clearDebug();
371
			if ($errstr = $this->wsdl->getError()) {
372
				$this->debug('got wsdl error: '.$errstr);
373
				$this->setError('wsdl error: '.$errstr);
374
				return false;
375
			}
376
		} elseif($this->endpointType == 'wsdl') {
377
			// operation not in WSDL
378
			$this->appendDebug($this->wsdl->getDebug());
379
			$this->wsdl->clearDebug();
380
			$this->setError('operation '.$operation.' not present in WSDL.');
381
			$this->debug("operation '$operation' not present in WSDL.");
382
			return false;
383
		} else {
384
			// no WSDL
385
			//$this->namespaces['ns1'] = $namespace;
386
			$nsPrefix = 'ns' . rand(1000, 9999);
387
			// serialize 
388
			$payload = '';
389
			if (is_string($params)) {
390
				$this->debug("serializing param string for operation $operation");
391
				$payload = $params;
392
			} elseif (is_array($params)) {
393
				$this->debug("serializing param array for operation $operation");
394
				foreach($params as $k => $v){
395
					$payload .= $this->serialize_val($v,$k,false,false,false,false,$use);
396
				}
397
			} else {
398
				$this->debug('params must be array or string');
399
				$this->setError('params must be array or string');
400
				return false;
401
			}
402
			$usedNamespaces = array();
403
			if ($use == 'encoded') {
404
				$encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
405
			} else {
406
				$encodingStyle = '';
407
			}
408
		}
409
		// wrap RPC calls with method element
410
		if ($style == 'rpc') {
411
			if ($use == 'literal') {
412
				$this->debug("wrapping RPC request with literal method element");
413
				if ($namespace) {
414
					// 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
415
					$payload = "<$nsPrefix:$operation xmlns:$nsPrefix=\"$namespace\">" .
416
								$payload .
417
								"</$nsPrefix:$operation>";
418
				} else {
419
					$payload = "<$operation>" . $payload . "</$operation>";
420
				}
421
			} else {
422
				$this->debug("wrapping RPC request with encoded method element");
423
				if ($namespace) {
424
					$payload = "<$nsPrefix:$operation xmlns:$nsPrefix=\"$namespace\">" .
425
								$payload .
426
								"</$nsPrefix:$operation>";
427
				} else {
428
					$payload = "<$operation>" .
429
								$payload .
430
								"</$operation>";
431
				}
432
			}
433
		}
434
		// serialize envelope
435
		$soapmsg = $this->serializeEnvelope($payload,$this->requestHeaders,$usedNamespaces,$style,$use,$encodingStyle);
436
		$this->debug("endpoint=$this->endpoint, soapAction=$soapAction, namespace=$namespace, style=$style, use=$use, encodingStyle=$encodingStyle");
437
		$this->debug('SOAP message length=' . strlen($soapmsg) . ' contents (max 1000 bytes)=' . substr($soapmsg, 0, 1000));
438
		// send
439
		$return = $this->send($this->getHTTPBody($soapmsg),$soapAction,$this->timeout,$this->response_timeout);
440
		if($errstr = $this->getError()){
441
			$this->debug('Error: '.$errstr);
442
			return false;
443
		} else {
444
			$this->return = $return;
445
			$this->debug('sent message successfully and got a(n) '.gettype($return));
446
           	$this->appendDebug('return=' . $this->varDump($return));
447
			
448
			// fault?
449
			if(is_array($return) && isset($return['faultcode'])){
450
				$this->debug('got fault');
451
				$this->setError($return['faultcode'].': '.$return['faultstring']);
452
				$this->fault = true;
453
				foreach($return as $k => $v){
454
					$this->$k = $v;
455
					$this->debug("$k = $v<br>");
456
				}
457
				return $return;
458
			} elseif ($style == 'document') {
459
				// NOTE: if the response is defined to have multiple parts (i.e. unwrapped),
460
				// we are only going to return the first part here...sorry about that
461
				return $return;
462
			} else {
463
				// array of return values
464
				if(is_array($return)){
465
					// multiple 'out' parameters, which we return wrapped up
466
					// in the array
467
					if(sizeof($return) > 1){
468
						return $return;
469
					}
470
					// single 'out' parameter (normally the return value)
471
					$return = array_shift($return);
472
					$this->debug('return shifted value: ');
473
					$this->appendDebug($this->varDump($return));
474
           			return $return;
475
				// nothing returned (ie, echoVoid)
476
				} else {
477
					return "";
478
				}
479
			}
480
		}
481
	}
482
483
	/**
484
	* check WSDL passed as an instance or pulled from an endpoint
485
	*
486
	* @access   private
487
	*/
488
	function checkWSDL() {
489
		$this->appendDebug($this->wsdl->getDebug());
490
		$this->wsdl->clearDebug();
491
		$this->debug('checkWSDL');
492
		// catch errors
493
		if ($errstr = $this->wsdl->getError()) {
494
			$this->appendDebug($this->wsdl->getDebug());
495
			$this->wsdl->clearDebug();
496
			$this->debug('got wsdl error: '.$errstr);
497
			$this->setError('wsdl error: '.$errstr);
498
		} elseif ($this->operations = $this->wsdl->getOperations($this->portName, 'soap')) {
499
			$this->appendDebug($this->wsdl->getDebug());
500
			$this->wsdl->clearDebug();
501
			$this->bindingType = 'soap';
502
			$this->debug('got '.count($this->operations).' operations from wsdl '.$this->wsdlFile.' for binding type '.$this->bindingType);
503
		} elseif ($this->operations = $this->wsdl->getOperations($this->portName, 'soap12')) {
504
			$this->appendDebug($this->wsdl->getDebug());
505
			$this->wsdl->clearDebug();
506
			$this->bindingType = 'soap12';
507
			$this->debug('got '.count($this->operations).' operations from wsdl '.$this->wsdlFile.' for binding type '.$this->bindingType);
508
			$this->debug('**************** WARNING: SOAP 1.2 BINDING *****************');
509
		} else {
510
			$this->appendDebug($this->wsdl->getDebug());
511
			$this->wsdl->clearDebug();
512
			$this->debug('getOperations returned false');
513
			$this->setError('no operations defined in the WSDL document!');
514
		}
515
	}
516
517
	/**
518
	 * instantiate wsdl object and parse wsdl file
519
	 *
520
	 * @access	public
521
	 */
522
	function loadWSDL() {
523
		$this->debug('instantiating wsdl class with doc: '.$this->wsdlFile);
524
		$this->wsdl = new wsdl('',$this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword,$this->timeout,$this->response_timeout,$this->curl_options,$this->use_curl);
525
		$this->wsdl->setCredentials($this->username, $this->password, $this->authtype, $this->certRequest);
526
		$this->wsdl->fetchWSDL($this->wsdlFile);
527
		$this->checkWSDL();
528
	}
529
530
	/**
531
	* get available data pertaining to an operation
532
	*
533
	* @param    string $operation operation name
534
	* @return	array array of data pertaining to the operation
535
	* @access   public
536
	*/
537
	function getOperationData($operation){
538
		if ($this->endpointType == 'wsdl' && is_null($this->wsdl)) {
539
			$this->loadWSDL();
540
			if ($this->getError())
541
				return false;
542
		}
543
		if(isset($this->operations[$operation])){
544
			return $this->operations[$operation];
545
		}
546
		$this->debug("No data for operation: $operation");
547
	}
548
549
    /**
550
    * send the SOAP message
551
    *
552
    * Note: if the operation has multiple return values
553
    * the return value of this method will be an array
554
    * of those values.
555
    *
556
	* @param    string $msg a SOAPx4 soapmsg object
557
	* @param    string $soapaction SOAPAction value
558
	* @param    integer $timeout set connection timeout in seconds
559
	* @param	integer $response_timeout set response timeout in seconds
560
	* @return	mixed native PHP types.
561
	* @access   private
562
	*/
563
	function send($msg, $soapaction = '', $timeout=0, $response_timeout=30) {
564
		$this->checkCookies();
565
		// detect transport
566
		switch(true){
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing preg_match('/^http/', $this->endpoint) of type integer to the boolean true. If you are specifically checking for non-zero, consider using something more explicit like > 0 or !== 0 instead.
Loading history...
567
			// http(s)
568
			case preg_match('/^http/',$this->endpoint):
569
				$this->debug('transporting via HTTP');
570
				if($this->persistentConnection == true && is_object($this->persistentConnection)){
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
571
					$http =& $this->persistentConnection;
572
				} else {
573
					$http = new soap_transport_http($this->endpoint, $this->curl_options, $this->use_curl);
574
					if ($this->persistentConnection) {
575
						$http->usePersistentConnection();
576
					}
577
				}
578
				$http->setContentType($this->getHTTPContentType(), $this->getHTTPContentTypeCharset());
579
				$http->setSOAPAction($soapaction);
580
				if($this->proxyhost && $this->proxyport){
581
					$http->setProxy($this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword);
582
				}
583
                if($this->authtype != '') {
584
					$http->setCredentials($this->username, $this->password, $this->authtype, array(), $this->certRequest);
585
				}
586
				if($this->http_encoding != ''){
587
					$http->setEncoding($this->http_encoding);
588
				}
589
				$this->debug('sending message, length='.strlen($msg));
590
				if(preg_match('/^http:/',$this->endpoint)){
591
				//if(strpos($this->endpoint,'http:')){
592
					$this->responseData = $http->send($msg,$timeout,$response_timeout,$this->cookies);
0 ignored issues
show
Documentation Bug introduced by
It seems like $http->send($msg, $timeo...imeout, $this->cookies) can also be of type false. However, the property $responseData is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
593
				} elseif(preg_match('/^https/',$this->endpoint)){
594
				//} elseif(strpos($this->endpoint,'https:')){
595
					//if(phpversion() == '4.3.0-dev'){
596
						//$response = $http->send($msg,$timeout,$response_timeout);
597
                   		//$this->request = $http->outgoing_payload;
598
						//$this->response = $http->incoming_payload;
599
					//} else
600
					$this->responseData = $http->sendHTTPS($msg,$timeout,$response_timeout,$this->cookies);
0 ignored issues
show
Documentation Bug introduced by
It seems like $http->sendHTTPS($msg, $...imeout, $this->cookies) can also be of type false. However, the property $responseData is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
Deprecated Code introduced by
The method soap_transport_http::sendHTTPS() has been deprecated.

This method has been deprecated.

Loading history...
601
				} else {
602
					$this->setError('no http/s in endpoint url');
603
				}
604
				$this->request = $http->outgoing_payload;
605
				$this->response = $http->incoming_payload;
606
				$this->appendDebug($http->getDebug());
607
				$this->UpdateCookies($http->incoming_cookies);
608
609
				// save transport object if using persistent connections
610
				if ($this->persistentConnection) {
611
					$http->clearDebug();
612
					if (!is_object($this->persistentConnection)) {
613
						$this->persistentConnection = $http;
614
					}
615
				}
616
				
617
				if($err = $http->getError()){
618
					$this->setError('HTTP Error: '.$err);
619
					return false;
620
				} elseif($this->getError()){
621
					return false;
622
				} else {
623
					$this->debug('got response, length='. strlen($this->responseData).' type='.$http->incoming_headers['content-type']);
624
					return $this->parseResponse($http->incoming_headers, $this->responseData);
0 ignored issues
show
It seems like $this->responseData can also be of type false; however, nusoap_client::parseResponse() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
625
				}
626
			break;
0 ignored issues
show
break; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
627
			default:
628
				$this->setError('no transport found, or selected transport is not yet supported!');
629
			return false;
630
			break;
0 ignored issues
show
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
631
		}
632
	}
633
634
	/**
635
	* processes SOAP message returned from server
636
	*
637
	* @param	array	$headers	The HTTP headers
638
	* @param	string	$data		unprocessed response data from server
639
	* @return	mixed	value of the message, decoded into a PHP type
640
	* @access   private
641
	*/
642
    function parseResponse($headers, $data) {
643
		$this->debug('Entering parseResponse() for data of length ' . strlen($data) . ' headers:');
644
		$this->appendDebug($this->varDump($headers));
645
    	if (!isset($headers['content-type'])) {
646
			$this->setError('Response not of type text/xml (no content-type header)');
647
			return false;
648
    	}
649
		if (!strstr($headers['content-type'], 'text/xml')) {
650
			$this->setError('Response not of type text/xml: ' . $headers['content-type']);
651
			return false;
652
		}
653
		if (strpos($headers['content-type'], '=')) {
654
			$enc = str_replace('"', '', substr(strstr($headers["content-type"], '='), 1));
655
			$this->debug('Got response encoding: ' . $enc);
656
			if(preg_match('/^(ISO-8859-1|US-ASCII|UTF-8)$/i',$enc)){
657
				$this->xml_encoding = strtoupper($enc);
658
			} else {
659
				$this->xml_encoding = 'US-ASCII';
660
			}
661
		} else {
662
			// should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
663
			$this->xml_encoding = 'ISO-8859-1';
664
		}
665
		$this->debug('Use encoding: ' . $this->xml_encoding . ' when creating nusoap_parser');
666
		$parser = new nusoap_parser($data,$this->xml_encoding,$this->operation,$this->decode_utf8);
667
		// add parser debug data to our debug
668
		$this->appendDebug($parser->getDebug());
669
		// if parse errors
670
		if($errstr = $parser->getError()){
671
			$this->setError( $errstr);
672
			// destroy the parser object
673
			unset($parser);
674
			return false;
675
		} else {
676
			// get SOAP headers
677
			$this->responseHeaders = $parser->getHeaders();
678
			// get SOAP headers
679
			$this->responseHeader = $parser->get_soapheader();
680
			// get decoded message
681
			$return = $parser->get_soapbody();
682
            // add document for doclit support
683
            $this->document = $parser->document;
684
			// destroy the parser object
685
			unset($parser);
686
			// return decode message
687
			return $return;
688
		}
689
	 }
690
691
	/**
692
	* sets user-specified cURL options
693
	*
694
	* @param	mixed $option The cURL option (always integer?)
695
	* @param	mixed $value The cURL option value
696
	* @access   public
697
	*/
698
	function setCurlOption($option, $value) {
699
		$this->debug("setCurlOption option=$option, value=");
700
		$this->appendDebug($this->varDump($value));
701
		$this->curl_options[$option] = $value;
702
	}
703
704
	/**
705
	* sets the SOAP endpoint, which can override WSDL
706
	*
707
	* @param	string $endpoint The endpoint URL to use, or empty string or false to prevent override
708
	* @access   public
709
	*/
710
	function setEndpoint($endpoint) {
711
		$this->debug("setEndpoint(\"$endpoint\")");
712
		$this->forceEndpoint = $endpoint;
713
	}
714
715
	/**
716
	* set the SOAP headers
717
	*
718
	* @param	mixed $headers String of XML with SOAP header content, or array of soapval objects for SOAP headers
719
	* @access   public
720
	*/
721
	function setHeaders($headers){
722
		$this->debug("setHeaders headers=");
723
		$this->appendDebug($this->varDump($headers));
724
		$this->requestHeaders = $headers;
725
	}
726
727
	/**
728
	* get the SOAP response headers (namespace resolution incomplete)
729
	*
730
	* @return	string
731
	* @access   public
732
	*/
733
	function getHeaders(){
734
		return $this->responseHeaders;
735
	}
736
737
	/**
738
	* get the SOAP response Header (parsed)
739
	*
740
	* @return	mixed
741
	* @access   public
742
	*/
743
	function getHeader(){
744
		return $this->responseHeader;
745
	}
746
747
	/**
748
	* set proxy info here
749
	*
750
	* @param    string $proxyhost
751
	* @param    string $proxyport
752
	* @param	string $proxyusername
753
	* @param	string $proxypassword
754
	* @access   public
755
	*/
756
	function setHTTPProxy($proxyhost, $proxyport, $proxyusername = '', $proxypassword = '') {
757
		$this->proxyhost = $proxyhost;
758
		$this->proxyport = $proxyport;
759
		$this->proxyusername = $proxyusername;
760
		$this->proxypassword = $proxypassword;
761
	}
762
763
	/**
764
	* if authenticating, set user credentials here
765
	*
766
	* @param    string $username
767
	* @param    string $password
768
	* @param	string $authtype (basic|digest|certificate|ntlm)
769
	* @param	array $certRequest (keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, verifypeer (optional), verifyhost (optional): see corresponding options in cURL docs)
770
	* @access   public
771
	*/
772
	function setCredentials($username, $password, $authtype = 'basic', $certRequest = array()) {
773
		$this->debug("setCredentials username=$username authtype=$authtype certRequest=");
774
		$this->appendDebug($this->varDump($certRequest));
775
		$this->username = $username;
776
		$this->password = $password;
777
		$this->authtype = $authtype;
778
		$this->certRequest = $certRequest;
779
	}
780
	
781
	/**
782
	* use HTTP encoding
783
	*
784
	* @param    string $enc HTTP encoding
785
	* @access   public
786
	*/
787
	function setHTTPEncoding($enc='gzip, deflate'){
788
		$this->debug("setHTTPEncoding(\"$enc\")");
789
		$this->http_encoding = $enc;
0 ignored issues
show
Documentation Bug introduced by
The property $http_encoding was declared of type boolean, but $enc is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
790
	}
791
	
792
	/**
793
	* Set whether to try to use cURL connections if possible
794
	*
795
	* @param	boolean $use Whether to try to use cURL
796
	* @access   public
797
	*/
798
	function setUseCURL($use) {
799
		$this->debug("setUseCURL($use)");
800
		$this->use_curl = $use;
801
	}
802
803
	/**
804
	* use HTTP persistent connections if possible
805
	*
806
	* @access   public
807
	*/
808
	function useHTTPPersistentConnection(){
809
		$this->debug("useHTTPPersistentConnection");
810
		$this->persistentConnection = true;
811
	}
812
	
813
	/**
814
	* gets the default RPC parameter setting.
815
	* If true, default is that call params are like RPC even for document style.
816
	* Each call() can override this value.
817
	*
818
	* This is no longer used.
819
	*
820
	* @return boolean
821
	* @access public
822
	* @deprecated
823
	*/
824
	function getDefaultRpcParams() {
825
		return $this->defaultRpcParams;
826
	}
827
828
	/**
829
	* sets the default RPC parameter setting.
830
	* If true, default is that call params are like RPC even for document style
831
	* Each call() can override this value.
832
	*
833
	* This is no longer used.
834
	*
835
	* @param    boolean $rpcParams
836
	* @access public
837
	* @deprecated
838
	*/
839
	function setDefaultRpcParams($rpcParams) {
840
		$this->defaultRpcParams = $rpcParams;
841
	}
842
	
843
	/**
844
	* dynamically creates an instance of a proxy class,
845
	* allowing user to directly call methods from wsdl
846
	*
847
	* @return   object soap_proxy object
848
	* @access   public
849
	*/
850
	function getProxy() {
851
		$r = rand();
852
		$evalStr = $this->_getProxyClassCode($r);
853
		//$this->debug("proxy class: $evalStr");
854
		if ($this->getError()) {
855
			$this->debug("Error from _getProxyClassCode, so return NULL");
856
			return null;
857
		}
858
		// eval the class
859
		eval($evalStr);
0 ignored issues
show
It is generally not recommended to use eval unless absolutely required.

On one hand, eval might be exploited by malicious users if they somehow manage to inject dynamic content. On the other hand, with the emergence of faster PHP runtimes like the HHVM, eval prevents some optimization that they perform.

Loading history...
860
		// instantiate proxy object
861
		eval("\$proxy = new nusoap_proxy_$r('');");
0 ignored issues
show
It is generally not recommended to use eval unless absolutely required.

On one hand, eval might be exploited by malicious users if they somehow manage to inject dynamic content. On the other hand, with the emergence of faster PHP runtimes like the HHVM, eval prevents some optimization that they perform.

Loading history...
862
		// transfer current wsdl data to the proxy thereby avoiding parsing the wsdl twice
863
		$proxy->endpointType = 'wsdl';
864
		$proxy->wsdlFile = $this->wsdlFile;
865
		$proxy->wsdl = $this->wsdl;
866
		$proxy->operations = $this->operations;
867
		$proxy->defaultRpcParams = $this->defaultRpcParams;
868
		// transfer other state
869
		$proxy->soap_defencoding = $this->soap_defencoding;
870
		$proxy->username = $this->username;
871
		$proxy->password = $this->password;
872
		$proxy->authtype = $this->authtype;
873
		$proxy->certRequest = $this->certRequest;
874
		$proxy->requestHeaders = $this->requestHeaders;
875
		$proxy->endpoint = $this->endpoint;
876
		$proxy->forceEndpoint = $this->forceEndpoint;
877
		$proxy->proxyhost = $this->proxyhost;
878
		$proxy->proxyport = $this->proxyport;
879
		$proxy->proxyusername = $this->proxyusername;
880
		$proxy->proxypassword = $this->proxypassword;
881
		$proxy->http_encoding = $this->http_encoding;
882
		$proxy->timeout = $this->timeout;
883
		$proxy->response_timeout = $this->response_timeout;
884
		$proxy->persistentConnection = &$this->persistentConnection;
885
		$proxy->decode_utf8 = $this->decode_utf8;
886
		$proxy->curl_options = $this->curl_options;
887
		$proxy->bindingType = $this->bindingType;
888
		$proxy->use_curl = $this->use_curl;
889
		return $proxy;
890
	}
891
892
	/**
893
	* dynamically creates proxy class code
894
	*
895
	* @return   string PHP/NuSOAP code for the proxy class
896
	* @access   private
897
	*/
898
	function _getProxyClassCode($r) {
899
		$this->debug("in getProxy endpointType=$this->endpointType");
900
		$this->appendDebug("wsdl=" . $this->varDump($this->wsdl));
901
		if ($this->endpointType != 'wsdl') {
902
			$evalStr = 'A proxy can only be created for a WSDL client';
903
			$this->setError($evalStr);
904
			$evalStr = "echo \"$evalStr\";";
905
			return $evalStr;
906
		}
907
		if ($this->endpointType == 'wsdl' && is_null($this->wsdl)) {
908
			$this->loadWSDL();
909
			if ($this->getError()) {
910
				return "echo \"" . $this->getError() . "\";";
911
			}
912
		}
913
		$evalStr = '';
914
		foreach ($this->operations as $operation => $opData) {
915
			if ($operation != '') {
916
				// create param string and param comment string
917
				if (sizeof($opData['input']['parts']) > 0) {
918
					$paramStr = '';
919
					$paramArrayStr = '';
920
					$paramCommentStr = '';
921
					foreach ($opData['input']['parts'] as $name => $type) {
922
						$paramStr .= "\$$name, ";
923
						$paramArrayStr .= "'$name' => \$$name, ";
924
						$paramCommentStr .= "$type \$$name, ";
925
					}
926
					$paramStr = substr($paramStr, 0, strlen($paramStr)-2);
927
					$paramArrayStr = substr($paramArrayStr, 0, strlen($paramArrayStr)-2);
928
					$paramCommentStr = substr($paramCommentStr, 0, strlen($paramCommentStr)-2);
929
				} else {
930
					$paramStr = '';
931
					$paramArrayStr = '';
932
					$paramCommentStr = 'void';
933
				}
934
				$opData['namespace'] = !isset($opData['namespace']) ? 'http://testuri.com' : $opData['namespace'];
935
				$evalStr .= "// $paramCommentStr
936
	function " . str_replace('.', '__', $operation) . "($paramStr) {
937
		\$params = array($paramArrayStr);
938
		return \$this->call('$operation', \$params, '".$opData['namespace']."', '".(isset($opData['soapAction']) ? $opData['soapAction'] : '')."');
939
	}
940
	";
941
				unset($paramStr);
942
				unset($paramCommentStr);
943
			}
944
		}
945
		$evalStr = 'class nusoap_proxy_'.$r.' extends nusoap_client {
946
	'.$evalStr.'
947
}';
948
		return $evalStr;
949
	}
950
951
	/**
952
	* dynamically creates proxy class code
953
	*
954
	* @return   string PHP/NuSOAP code for the proxy class
955
	* @access   public
956
	*/
957
	function getProxyClassCode() {
958
		$r = rand();
959
		return $this->_getProxyClassCode($r);
960
	}
961
962
	/**
963
	* gets the HTTP body for the current request.
964
	*
965
	* @param string $soapmsg The SOAP payload
966
	* @return string The HTTP body, which includes the SOAP payload
967
	* @access private
968
	*/
969
	function getHTTPBody($soapmsg) {
970
		return $soapmsg;
971
	}
972
	
973
	/**
974
	* gets the HTTP content type for the current request.
975
	*
976
	* Note: getHTTPBody must be called before this.
977
	*
978
	* @return string the HTTP content type for the current request.
979
	* @access private
980
	*/
981
	function getHTTPContentType() {
982
		return 'text/xml';
983
	}
984
	
985
	/**
986
	* gets the HTTP content type charset for the current request.
987
	* returns false for non-text content types.
988
	*
989
	* Note: getHTTPBody must be called before this.
990
	*
991
	* @return string the HTTP content type charset for the current request.
992
	* @access private
993
	*/
994
	function getHTTPContentTypeCharset() {
995
		return $this->soap_defencoding;
996
	}
997
998
	/*
999
	* whether or not parser should decode utf8 element content
1000
    *
1001
    * @return   always returns true
1002
    * @access   public
1003
    */
1004
    function decodeUTF8($bool){
1005
		$this->decode_utf8 = $bool;
1006
		return true;
1007
    }
1008
1009
	/**
1010
	 * adds a new Cookie into $this->cookies array
1011
	 *
1012
	 * @param	string $name Cookie Name
1013
	 * @param	string $value Cookie Value
1014
	 * @return	boolean if cookie-set was successful returns true, else false
1015
	 * @access	public
1016
	 */
1017
	function setCookie($name, $value) {
1018
		if (strlen($name) == 0) {
1019
			return false;
1020
		}
1021
		$this->cookies[] = array('name' => $name, 'value' => $value);
1022
		return true;
1023
	}
1024
1025
	/**
1026
	 * gets all Cookies
1027
	 *
1028
	 * @return   array with all internal cookies
1029
	 * @access   public
1030
	 */
1031
	function getCookies() {
1032
		return $this->cookies;
1033
	}
1034
1035
	/**
1036
	 * checks all Cookies and delete those which are expired
1037
	 *
1038
	 * @return   boolean always return true
1039
	 * @access   private
1040
	 */
1041
	function checkCookies() {
1042
		if (sizeof($this->cookies) == 0) {
1043
			return true;
1044
		}
1045
		$this->debug('checkCookie: check ' . sizeof($this->cookies) . ' cookies');
1046
		$curr_cookies = $this->cookies;
1047
		$this->cookies = array();
1048
		foreach ($curr_cookies as $cookie) {
1049
			if (! is_array($cookie)) {
1050
				$this->debug('Remove cookie that is not an array');
1051
				continue;
1052
			}
1053
			if ((isset($cookie['expires'])) && (! empty($cookie['expires']))) {
1054
				if (strtotime($cookie['expires']) > time()) {
1055
					$this->cookies[] = $cookie;
1056
				} else {
1057
					$this->debug('Remove expired cookie ' . $cookie['name']);
1058
				}
1059
			} else {
1060
				$this->cookies[] = $cookie;
1061
			}
1062
		}
1063
		$this->debug('checkCookie: '.sizeof($this->cookies).' cookies left in array');
1064
		return true;
1065
	}
1066
1067
	/**
1068
	 * updates the current cookies with a new set
1069
	 *
1070
	 * @param	array $cookies new cookies with which to update current ones
1071
	 * @return	boolean always return true
1072
	 * @access	private
1073
	 */
1074
	function UpdateCookies($cookies) {
1075
		if (sizeof($this->cookies) == 0) {
1076
			// no existing cookies: take whatever is new
1077
			if (sizeof($cookies) > 0) {
1078
				$this->debug('Setting new cookie(s)');
1079
				$this->cookies = $cookies;
1080
			}
1081
			return true;
1082
		}
1083
		if (sizeof($cookies) == 0) {
1084
			// no new cookies: keep what we've got
1085
			return true;
1086
		}
1087
		// merge
1088
		foreach ($cookies as $newCookie) {
1089
			if (!is_array($newCookie)) {
1090
				continue;
1091
			}
1092
			if ((!isset($newCookie['name'])) || (!isset($newCookie['value']))) {
1093
				continue;
1094
			}
1095
			$newName = $newCookie['name'];
1096
1097
			$found = false;
1098
			for ($i = 0; $i < count($this->cookies); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
1099
				$cookie = $this->cookies[$i];
1100
				if (!is_array($cookie)) {
1101
					continue;
1102
				}
1103
				if (!isset($cookie['name'])) {
1104
					continue;
1105
				}
1106
				if ($newName != $cookie['name']) {
1107
					continue;
1108
				}
1109
				$newDomain = isset($newCookie['domain']) ? $newCookie['domain'] : 'NODOMAIN';
1110
				$domain = isset($cookie['domain']) ? $cookie['domain'] : 'NODOMAIN';
1111
				if ($newDomain != $domain) {
1112
					continue;
1113
				}
1114
				$newPath = isset($newCookie['path']) ? $newCookie['path'] : 'NOPATH';
1115
				$path = isset($cookie['path']) ? $cookie['path'] : 'NOPATH';
1116
				if ($newPath != $path) {
1117
					continue;
1118
				}
1119
				$this->cookies[$i] = $newCookie;
1120
				$found = true;
1121
				$this->debug('Update cookie ' . $newName . '=' . $newCookie['value']);
1122
				break;
1123
			}
1124
			if (! $found) {
1125
				$this->debug('Add cookie ' . $newName . '=' . $newCookie['value']);
1126
				$this->cookies[] = $newCookie;
1127
			}
1128
		}
1129
		return true;
1130
	}
1131
}
1132
1133
if (!extension_loaded('soap')) {
1134
	/**
1135
	 *	For backwards compatiblity, define soapclient unless the PHP SOAP extension is loaded.
1136
	 */
1137
	class soapclient extends nusoap_client {
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
1138
	}
1139
}
1140
1141
/**
1142
 *	For backwards compatiblity, define nusoapclient unless the PHP SOAP extension is loaded.
1143
 */
1144
class nusoapclient extends nusoap_client {
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
1145
}
1146
?>
1147