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