5 Modification information for LGPL compliance
7 r57813 - 2010-08-19 10:34:44 -0700 (Thu, 19 Aug 2010) - kjing - Author: John Mertic <jmertic@sugarcrm.com>
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.
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
12 r56989 - 2010-06-16 13:01:33 -0700 (Wed, 16 Jun 2010) - kjing - defunt "Mango" svn dev branch before github cutover
14 r55980 - 2010-04-19 13:31:28 -0700 (Mon, 19 Apr 2010) - kjing - create Mango (6.1) based on windex
16 r51719 - 2009-10-22 10:18:00 -0700 (Thu, 22 Oct 2009) - mitani - Converted to Build 3 tags and updated the build system
18 r51634 - 2009-10-19 13:32:22 -0700 (Mon, 19 Oct 2009) - mitani - Windex is the branch for Sugar Sales 1.0 development
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.
25 r50375 - 2009-08-24 18:07:43 -0700 (Mon, 24 Aug 2009) - dwong - branch kobe2 from tokyo r50372
27 r42807 - 2008-12-29 11:16:59 -0800 (Mon, 29 Dec 2008) - dwong - Branch from trunk/sugarcrm r42806 to branches/tokyo/sugarcrm
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.
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
126 r13782 - 2006-06-06 10:58:55 -0700 (Tue, 06 Jun 2006) - majed - changes entry point code
128 r11115 - 2006-01-17 14:54:45 -0800 (Tue, 17 Jan 2006) - majed - add entry point validation
130 r8991 - 2005-11-03 19:07:25 -0800 (Thu, 03 Nov 2005) - majed - fixes nusoap issue
132 r8846 - 2005-10-31 11:01:12 -0800 (Mon, 31 Oct 2005) - majed - new version of nusoap
134 r7905 - 2005-09-21 19:12:57 -0700 (Wed, 21 Sep 2005) - majed - restores old nusoap pre & with a few fixes
136 r7861 - 2005-09-20 15:40:25 -0700 (Tue, 20 Sep 2005) - majed - & fix for 3.5.1
138 r5462 - 2005-05-25 13:50:11 -0700 (Wed, 25 May 2005) - majed - upgraded nusoap to .6.9
140 r573 - 2004-09-04 13:03:32 -0700 (Sat, 04 Sep 2004) - sugarclint - undoing copyrights added in inadvertantly. --clint
142 r546 - 2004-09-03 11:49:38 -0700 (Fri, 03 Sep 2004) - sugarmsi - removed echo count
144 r354 - 2004-08-02 23:00:37 -0700 (Mon, 02 Aug 2004) - sugarjacob - Adding Soap
150 if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
157 * [nu]soapclient higher level class for easy usage.
161 * // instantiate client with server info
162 * $soapclient = new nusoap_client( string path [ ,mixed wsdl] );
164 * // call method, get results
165 * echo $soapclient->call( string methodname [ ,array parameters] );
168 * unset($soapclient);
170 * @author Dietrich Ayala <dietrich@ganx4.com>
171 * @author Scott Nichol <snichol@users.sourceforge.net>
175 class nusoap_client extends nusoap_base {
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)
186 var $forceEndpoint = ''; // overrides WSDL endpoint
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
210 * fault related variables
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
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;
251 $this->proxyport = $proxyport;
252 $this->proxyusername = $proxyusername;
253 $this->proxypassword = $proxypassword;
254 $this->timeout = $timeout;
255 $this->response_timeout = $response_timeout;
256 $this->portName = $portName;
258 $this->debug("ctor wsdl=$wsdl timeout=$timeout response_timeout=$response_timeout");
259 $this->appendDebug('endpoint=' . $this->varDump($endpoint));
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);
270 $this->wsdlFile = $this->endpoint;
272 $this->debug('will use lazy evaluation of wsdl from ' . $this->endpoint);
274 $this->endpointType = 'wsdl';
276 $this->debug("instantiate SOAP with endpoint at $endpoint");
277 $this->endpointType = 'soap';
282 * calls method, returns PHP native type
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
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;
311 $this->response = '';
312 $this->responseData = '';
313 $this->faultstring = '';
314 $this->faultcode = '';
315 $this->opData = array();
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));
321 $this->requestHeaders = $headers;
323 if ($this->endpointType == 'wsdl' && is_null($this->wsdl)) {
325 if ($this->getError())
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'];
337 if (! $this->forceEndpoint) {
338 $this->endpoint = $opData['endpoint'];
340 $this->endpoint = $this->forceEndpoint;
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;
350 $nsPrefix = $this->wsdl->getPrefixFromNamespace($namespace);
352 if (is_string($params)) {
353 $this->debug("serializing param string for WSDL operation $operation");
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);
359 $this->debug('params must be array or string');
360 $this->setError('params must be array or string');
363 $usedNamespaces = $this->wsdl->usedNamespaces;
364 if (isset($opData['input']['encodingStyle'])) {
365 $encodingStyle = $opData['input']['encodingStyle'];
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);
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.");
385 //$this->namespaces['ns1'] = $namespace;
386 $nsPrefix = 'ns' . rand(1000, 9999);
389 if (is_string($params)) {
390 $this->debug("serializing param string for operation $operation");
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);
398 $this->debug('params must be array or string');
399 $this->setError('params must be array or string');
402 $usedNamespaces = array();
403 if ($use == 'encoded') {
404 $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
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");
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\">" .
417 "</$nsPrefix:$operation>";
419 $payload = "<$operation>" . $payload . "</$operation>";
422 $this->debug("wrapping RPC request with encoded method element");
424 $payload = "<$nsPrefix:$operation xmlns:$nsPrefix=\"$namespace\">" .
426 "</$nsPrefix:$operation>";
428 $payload = "<$operation>" .
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));
439 $return = $this->send($this->getHTTPBody($soapmsg),$soapAction,$this->timeout,$this->response_timeout);
440 if($errstr = $this->getError()){
441 $this->debug('Error: '.$errstr);
444 $this->return = $return;
445 $this->debug('sent message successfully and got a(n) '.gettype($return));
446 $this->appendDebug('return=' . $this->varDump($return));
449 if(is_array($return) && isset($return['faultcode'])){
450 $this->debug('got fault');
451 $this->setError($return['faultcode'].': '.$return['faultstring']);
453 foreach($return as $k => $v){
455 $this->debug("$k = $v<br>");
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
463 // array of return values
464 if(is_array($return)){
465 // multiple 'out' parameters, which we return wrapped up
467 if(sizeof($return) > 1){
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));
475 // nothing returned (ie, echoVoid)
484 * check WSDL passed as an instance or pulled from an endpoint
488 function checkWSDL() {
489 $this->appendDebug($this->wsdl->getDebug());
490 $this->wsdl->clearDebug();
491 $this->debug('checkWSDL');
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 *****************');
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!');
518 * instantiate wsdl object and parse wsdl file
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);
531 * get available data pertaining to an operation
533 * @param string $operation operation name
534 * @return array array of data pertaining to the operation
537 function getOperationData($operation){
538 if ($this->endpointType == 'wsdl' && is_null($this->wsdl)) {
540 if ($this->getError())
543 if(isset($this->operations[$operation])){
544 return $this->operations[$operation];
546 $this->debug("No data for operation: $operation");
550 * send the SOAP message
552 * Note: if the operation has multiple return values
553 * the return value of this method will be an array
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.
563 function send($msg, $soapaction = '', $timeout=0, $response_timeout=30) {
564 $this->checkCookies();
568 case preg_match('/^http/',$this->endpoint):
569 $this->debug('transporting via HTTP');
570 if($this->persistentConnection == true && is_object($this->persistentConnection)){
571 $http =& $this->persistentConnection;
573 $http = new soap_transport_http($this->endpoint, $this->curl_options, $this->use_curl);
574 if ($this->persistentConnection) {
575 $http->usePersistentConnection();
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);
583 if($this->authtype != '') {
584 $http->setCredentials($this->username, $this->password, $this->authtype, array(), $this->certRequest);
586 if($this->http_encoding != ''){
587 $http->setEncoding($this->http_encoding);
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);
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;
600 $this->responseData = $http->sendHTTPS($msg,$timeout,$response_timeout,$this->cookies);
602 $this->setError('no http/s in endpoint url');
604 $this->request = $http->outgoing_payload;
605 $this->response = $http->incoming_payload;
606 $this->appendDebug($http->getDebug());
607 $this->UpdateCookies($http->incoming_cookies);
609 // save transport object if using persistent connections
610 if ($this->persistentConnection) {
612 if (!is_object($this->persistentConnection)) {
613 $this->persistentConnection = $http;
617 if($err = $http->getError()){
618 $this->setError('HTTP Error: '.$err);
620 } elseif($this->getError()){
623 $this->debug('got response, length='. strlen($this->responseData).' type='.$http->incoming_headers['content-type']);
624 return $this->parseResponse($http->incoming_headers, $this->responseData);
628 $this->setError('no transport found, or selected transport is not yet supported!');
635 * processes SOAP message returned from server
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
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)');
649 if (!strstr($headers['content-type'], 'text/xml')) {
650 $this->setError('Response not of type text/xml: ' . $headers['content-type']);
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);
659 $this->xml_encoding = 'US-ASCII';
662 // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
663 $this->xml_encoding = 'ISO-8859-1';
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());
670 if($errstr = $parser->getError()){
671 $this->setError( $errstr);
672 // destroy the parser object
677 $this->responseHeaders = $parser->getHeaders();
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
686 // return decode message
692 * sets user-specified cURL options
694 * @param mixed $option The cURL option (always integer?)
695 * @param mixed $value The cURL option value
698 function setCurlOption($option, $value) {
699 $this->debug("setCurlOption option=$option, value=");
700 $this->appendDebug($this->varDump($value));
701 $this->curl_options[$option] = $value;
705 * sets the SOAP endpoint, which can override WSDL
707 * @param string $endpoint The endpoint URL to use, or empty string or false to prevent override
710 function setEndpoint($endpoint) {
711 $this->debug("setEndpoint(\"$endpoint\")");
712 $this->forceEndpoint = $endpoint;
716 * set the SOAP headers
718 * @param mixed $headers String of XML with SOAP header content, or array of soapval objects for SOAP headers
721 function setHeaders($headers){
722 $this->debug("setHeaders headers=");
723 $this->appendDebug($this->varDump($headers));
724 $this->requestHeaders = $headers;
728 * get the SOAP response headers (namespace resolution incomplete)
733 function getHeaders(){
734 return $this->responseHeaders;
738 * get the SOAP response Header (parsed)
743 function getHeader(){
744 return $this->responseHeader;
748 * set proxy info here
750 * @param string $proxyhost
751 * @param string $proxyport
752 * @param string $proxyusername
753 * @param string $proxypassword
756 function setHTTPProxy($proxyhost, $proxyport, $proxyusername = '', $proxypassword = '') {
757 $this->proxyhost = $proxyhost;
758 $this->proxyport = $proxyport;
759 $this->proxyusername = $proxyusername;
760 $this->proxypassword = $proxypassword;
764 * if authenticating, set user credentials here
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)
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;
784 * @param string $enc HTTP encoding
787 function setHTTPEncoding($enc='gzip, deflate'){
788 $this->debug("setHTTPEncoding(\"$enc\")");
789 $this->http_encoding = $enc;
793 * Set whether to try to use cURL connections if possible
795 * @param boolean $use Whether to try to use cURL
798 function setUseCURL($use) {
799 $this->debug("setUseCURL($use)");
800 $this->use_curl = $use;
804 * use HTTP persistent connections if possible
808 function useHTTPPersistentConnection(){
809 $this->debug("useHTTPPersistentConnection");
810 $this->persistentConnection = true;
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.
818 * This is no longer used.
824 function getDefaultRpcParams() {
825 return $this->defaultRpcParams;
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.
833 * This is no longer used.
835 * @param boolean $rpcParams
839 function setDefaultRpcParams($rpcParams) {
840 $this->defaultRpcParams = $rpcParams;
844 * dynamically creates an instance of a proxy class,
845 * allowing user to directly call methods from wsdl
847 * @return object soap_proxy object
850 function getProxy() {
852 $evalStr = $this->_getProxyClassCode($r);
853 //$this->debug("proxy class: $evalStr");
854 if ($this->getError()) {
855 $this->debug("Error from _getProxyClassCode, so return NULL");
860 // instantiate proxy object
861 eval("\$proxy = new nusoap_proxy_$r('');");
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;
893 * dynamically creates proxy class code
895 * @return string PHP/NuSOAP code for the proxy class
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\";";
907 if ($this->endpointType == 'wsdl' && is_null($this->wsdl)) {
909 if ($this->getError()) {
910 return "echo \"" . $this->getError() . "\";";
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) {
920 $paramCommentStr = '';
921 foreach ($opData['input']['parts'] as $name => $type) {
922 $paramStr .= "\$$name, ";
923 $paramArrayStr .= "'$name' => \$$name, ";
924 $paramCommentStr .= "$type \$$name, ";
926 $paramStr = substr($paramStr, 0, strlen($paramStr)-2);
927 $paramArrayStr = substr($paramArrayStr, 0, strlen($paramArrayStr)-2);
928 $paramCommentStr = substr($paramCommentStr, 0, strlen($paramCommentStr)-2);
932 $paramCommentStr = 'void';
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'] : '')."');
942 unset($paramCommentStr);
945 $evalStr = 'class nusoap_proxy_'.$r.' extends nusoap_client {
952 * dynamically creates proxy class code
954 * @return string PHP/NuSOAP code for the proxy class
957 function getProxyClassCode() {
959 return $this->_getProxyClassCode($r);
963 * gets the HTTP body for the current request.
965 * @param string $soapmsg The SOAP payload
966 * @return string The HTTP body, which includes the SOAP payload
969 function getHTTPBody($soapmsg) {
974 * gets the HTTP content type for the current request.
976 * Note: getHTTPBody must be called before this.
978 * @return string the HTTP content type for the current request.
981 function getHTTPContentType() {
986 * gets the HTTP content type charset for the current request.
987 * returns false for non-text content types.
989 * Note: getHTTPBody must be called before this.
991 * @return string the HTTP content type charset for the current request.
994 function getHTTPContentTypeCharset() {
995 return $this->soap_defencoding;
999 * whether or not parser should decode utf8 element content
1001 * @return always returns true
1004 function decodeUTF8($bool){
1005 $this->decode_utf8 = $bool;
1010 * adds a new Cookie into $this->cookies array
1012 * @param string $name Cookie Name
1013 * @param string $value Cookie Value
1014 * @return boolean if cookie-set was successful returns true, else false
1017 function setCookie($name, $value) {
1018 if (strlen($name) == 0) {
1021 $this->cookies[] = array('name' => $name, 'value' => $value);
1028 * @return array with all internal cookies
1031 function getCookies() {
1032 return $this->cookies;
1036 * checks all Cookies and delete those which are expired
1038 * @return boolean always return true
1041 function checkCookies() {
1042 if (sizeof($this->cookies) == 0) {
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');
1053 if ((isset($cookie['expires'])) && (! empty($cookie['expires']))) {
1054 if (strtotime($cookie['expires']) > time()) {
1055 $this->cookies[] = $cookie;
1057 $this->debug('Remove expired cookie ' . $cookie['name']);
1060 $this->cookies[] = $cookie;
1063 $this->debug('checkCookie: '.sizeof($this->cookies).' cookies left in array');
1068 * updates the current cookies with a new set
1070 * @param array $cookies new cookies with which to update current ones
1071 * @return boolean always return true
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;
1083 if (sizeof($cookies) == 0) {
1084 // no new cookies: keep what we've got
1088 foreach ($cookies as $newCookie) {
1089 if (!is_array($newCookie)) {
1092 if ((!isset($newCookie['name'])) || (!isset($newCookie['value']))) {
1095 $newName = $newCookie['name'];
1098 for ($i = 0; $i < count($this->cookies); $i++) {
1099 $cookie = $this->cookies[$i];
1100 if (!is_array($cookie)) {
1103 if (!isset($cookie['name'])) {
1106 if ($newName != $cookie['name']) {
1109 $newDomain = isset($newCookie['domain']) ? $newCookie['domain'] : 'NODOMAIN';
1110 $domain = isset($cookie['domain']) ? $cookie['domain'] : 'NODOMAIN';
1111 if ($newDomain != $domain) {
1114 $newPath = isset($newCookie['path']) ? $newCookie['path'] : 'NOPATH';
1115 $path = isset($cookie['path']) ? $cookie['path'] : 'NOPATH';
1116 if ($newPath != $path) {
1119 $this->cookies[$i] = $newCookie;
1121 $this->debug('Update cookie ' . $newName . '=' . $newCookie['value']);
1125 $this->debug('Add cookie ' . $newName . '=' . $newCookie['value']);
1126 $this->cookies[] = $newCookie;
1133 if (!extension_loaded('soap')) {
1135 * For backwards compatiblity, define soapclient unless the PHP SOAP extension is loaded.
1137 class soapclient extends nusoap_client {
1142 * For backwards compatiblity, define nusoapclient unless the PHP SOAP extension is loaded.
1144 class nusoapclient extends nusoap_client {