PageRenderTime 57ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/class.phpwsdlclient.php

http://php-wsdl-creator.googlecode.com/
PHP | 692 lines | 410 code | 18 blank | 264 comment | 59 complexity | 899e3aab9528f04b00e6e9449b1cbb58 MD5 | raw file
Possible License(s): GPL-3.0
  1. <?php
  2. /*
  3. PhpWsdl - Generate WSDL from PHP
  4. Copyright (C) 2011 Andreas Müller-Saala, wan24.de
  5. This program is free software; you can redistribute it and/or modify it under
  6. the terms of the GNU General Public License as published by the Free Software
  7. Foundation; either version 3 of the License, or (at your option) any later
  8. version.
  9. This program is distributed in the hope that it will be useful, but WITHOUT
  10. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  11. FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License along with
  13. this program; if not, see <http://www.gnu.org/licenses/>.
  14. */
  15. if(basename($_SERVER['SCRIPT_FILENAME'])==basename(__FILE__))
  16. exit;
  17. // To use PhpWsdlClient, you need to load it seperatly from PhpWsdl. Or you
  18. // just load this class and let it autoload PhpWsdl
  19. require_once(dirname(__FILE__).'/class.phpwsdl.php');
  20. /**
  21. * A SOAP client class for PhpWsdl
  22. *
  23. * @author Andreas Müller-Saala, wan24.de
  24. * @version 2.4
  25. */
  26. class PhpWsdlClient{
  27. /**
  28. * The version number
  29. *
  30. * @var string
  31. */
  32. public static $VERSION='2.4';
  33. /**
  34. * Parse a method
  35. * 1: Type
  36. * 2: Method
  37. * 3: Parameters
  38. *
  39. * @var string
  40. */
  41. public static $methodRx='/^([^\s]+)\s+([^\(]+)\(([^\)]+)?\).*$/';
  42. /**
  43. * Parse a type
  44. * 1: Type
  45. * 2: Name
  46. *
  47. * @var string
  48. */
  49. public static $typeRx='/^([^\s]+)\s([^\[|\{|\s]+)([\[|\{|\s].*$)?/s';
  50. /**
  51. * Parse an element
  52. * 1: Type
  53. * 2: Name
  54. *
  55. * @var string
  56. */
  57. public static $elementRx='/^\s*([^\s]+)\s+([^\s|;]+);.*$/';
  58. /**
  59. * The WSDL URI
  60. *
  61. * @var string
  62. */
  63. public $WsdlUri;
  64. /**
  65. * The PHP SoapClient object
  66. *
  67. * @var SoapClient
  68. */
  69. public $Client=null;
  70. /**
  71. * SOAP call options
  72. *
  73. * @var array
  74. */
  75. public $Options;
  76. /**
  77. * SOAP call request headers
  78. *
  79. * @var array
  80. */
  81. public $RequestHeaders;
  82. /**
  83. * PHP SoapClient options array
  84. *
  85. * @var array
  86. */
  87. public $ClientOptions;
  88. /**
  89. * The webservice name
  90. *
  91. * @var string
  92. */
  93. public $ServiceName=null;
  94. /**
  95. * The SOAP endpoint
  96. *
  97. * @var string
  98. */
  99. public $EndPoint=null;
  100. /**
  101. * The SOAP namespace
  102. *
  103. * @var string
  104. */
  105. public $NameSpace=null;
  106. /**
  107. * A PhpWsdl object
  108. *
  109. * @var PhpWsdl
  110. */
  111. public $Server=null;
  112. /**
  113. * The WSDL
  114. *
  115. * @var string
  116. */
  117. public $WSDL=null;
  118. /**
  119. * A list of warnings
  120. *
  121. * @var string[]
  122. */
  123. public $Warnings=Array();
  124. /**
  125. * The http Auth username for fetching the WSDL (and sending SOAP requests, if PhpWsdlClient->UseSoapHttpAuth is TRUE)
  126. * If you need a different login for SOAP requests, use the PhpWsdlClient->ClientOptions array for the SOAP request
  127. * authentification values (login/password)
  128. *
  129. * @var string
  130. */
  131. public $HttpUser=null;
  132. /**
  133. * The http Auth password
  134. *
  135. * @var string
  136. */
  137. public $HttpPassword=null;
  138. /**
  139. * Use http Auth for SOAP requests, too? If FALSE, the login will only be used to fetch the WSDL from the given URI
  140. *
  141. * @var boolean
  142. */
  143. public $UseSoapHttpAuth=true;
  144. /**
  145. * Enable debugging of the RAW request/response?
  146. *
  147. * @var boolean
  148. */
  149. public $Debugging=false;
  150. /**
  151. * Encode parameters?
  152. * Note: This will only work if it's possible to build a PhpWsdl object from the target webservice WSDL
  153. *
  154. * @var boolean
  155. */
  156. public $EncodeParameters=false;
  157. /**
  158. * Constructor
  159. *
  160. * @param string $wsdlUri The WSDL URI
  161. * @param array $options SOAP call options (default: NULL)
  162. * @param array $requestHeaders SOAP call request headers (default: NULL)
  163. */
  164. public function PhpWsdlClient($wsdlUri,$options=null,$requestHeaders=null,$clientOptions=Array()){
  165. PhpWsdl::Debug('New PhpWsdlClient '.$wsdlUri);
  166. $this->WsdlUri=$wsdlUri;
  167. $this->Options=$options;
  168. $this->RequestHeaders=$requestHeaders;
  169. $this->ClientOptions=array_merge(
  170. Array(
  171. 'soap_version' => SOAP_1_1|SOAP_1_2,
  172. 'encoding' => 'UTF-8',
  173. 'compression' => SOAP_COMPRESSION_ACCEPT|SOAP_COMPRESSION_GZIP|9,
  174. 'connection_timeout'=>5
  175. ),
  176. $clientOptions
  177. );
  178. $this->GetWsdlFromCache();
  179. }
  180. /**
  181. * Fetch the WSDL (supports http Auth if CURL is enabled)
  182. *
  183. * @param string $wsdlUri The WSDL URI or NULL to use the PhpWsdlClient->WaslUri property (default: NULL)
  184. * @param array $options The CURL options (default: array)
  185. * @return string The WSDL XML
  186. */
  187. public function FetchWsdl($wsdlUri=null,$options=Array()){
  188. if(is_null($wsdlUri))
  189. $wsdlUri=$this->WsdlUri;
  190. PhpWsdl::Debug('Fetch WSDL from '.$wsdlUri);
  191. if(!is_file($wsdlUri)&&function_exists('curl_init')&&!is_null($this->HttpUser)){
  192. // Fetch with http Auth (credits to faebu :)
  193. PhpWsdl::Debug('Try CURL for http Auth');
  194. $ch=curl_init();
  195. $credit=$this->HttpUser.':'.$this->HttpPassword;
  196. curl_setopt_array($ch,array_merge(
  197. Array(
  198. CURLOPT_URL => $wsdlUri,
  199. CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
  200. CURLOPT_USERPWD => $credit,
  201. CURLOPT_TIMEOUT => 10,
  202. CURLOPT_RETURNTRANSFER => 1
  203. ),
  204. $options
  205. ));
  206. $wsdl=curl_exec($ch);
  207. if($wsdl===false){
  208. PhpWsdl::Debug('WARNING: Could not fetch WSDL with CURL: '.curl_error($ch));
  209. @curl_close($ch);
  210. }else{
  211. curl_close($ch);
  212. return $wsdl;
  213. }
  214. }
  215. // Fetch without authentification
  216. return file_get_contents($wsdlUri);
  217. }
  218. /**
  219. * Do a SOAP request
  220. *
  221. * @param string $method The method name
  222. * @param array $param The method parameters
  223. * @param array $options The call options (default: array)
  224. * @param array $requestHeaders The request headers (default: array)
  225. * @return mixed The server response
  226. */
  227. public function DoRequest($method,$param,$options=Array(),$requestHeaders=Array()){
  228. PhpWsdl::Debug('Sending request '.$method);
  229. $options=array_merge($this->Options,$options);
  230. $requestHeaders=array_merge($this->RequestHeaders,$requestHeaders);
  231. $client=$this->GetClient();
  232. if($this->EncodeParameters){
  233. $server=$this->CreateServerFromWsdl();
  234. $m=$server->GetMethod($method);
  235. if(!is_null($m)){
  236. PhpWsdl::Debug('Encode parameters');
  237. $temp=Array();
  238. $i=-1;
  239. $len=sizeof($param);
  240. while(++$i<$len)
  241. $temp[]=PhpWsdl::DoEncoding($m->Param[$i]->Type,$param[$i],true,$server);
  242. $param=$temp;
  243. }else{
  244. PhpWsdl::Debug('Can not encode parameters because the method was not found');
  245. }
  246. }
  247. $res=$client->__soapCall($method,$param,$options,$requestHeaders);
  248. if(is_soap_fault($res))
  249. PhpWsdl::Debug('SOAP error #'.$res->faultcode.': '.$res->faultstring);
  250. if($this->Debugging){
  251. PhpWsdl::Debug('Parameters: '.print_r($param,true));
  252. PhpWsdl::Debug('Options: '.print_r($options,true));
  253. PhpWsdl::Debug('Headers: '.print_r($requestHeaders,true));
  254. PhpWsdl::Debug('Result: '.print_r($res,true));
  255. PhpWsdl::Debug('Request: '.$client->__getLastRequest());
  256. PhpWsdl::Debug('Request headers: '.$client->__getLastRequestHeaders());
  257. PhpWsdl::Debug('Response: '.$client->__getLastResponse());
  258. PhpWsdl::Debug('Response headers: '.$client->__getLastResponseHeaders());
  259. }
  260. return $res;
  261. }
  262. /**
  263. * Get the PHP SoapClient object
  264. *
  265. * @param string $uri The WSDL URI or NULL to use the PhpWsdlClient->WsdlUri property (default: NULL)
  266. * @param array $options The additional PHP SoapClient options (default: array)
  267. * @return SoapClient The PHP SoapClient object
  268. */
  269. public function GetClient($uri=null,$options=Array()){
  270. if(is_null($this->Client)){
  271. if(is_null($uri))
  272. $uri=$this->WsdlUri;
  273. PhpWsdl::Debug('Create a PHP SoapClient object in PhpWsdlClient from '.$uri);
  274. if(!is_null(PhpWsdl::$CacheFolder)){
  275. $wsdlFile=$this->GetCacheFileName($uri);
  276. if(!is_null($this->GetWsdlFromCache($wsdlFile))){
  277. PhpWsdl::Debug('Use cached WSDL from '.$wsdlFile);
  278. $uri=$wsdlFile;
  279. }else{
  280. $wsdl=$this->FetchWsdl($uri);
  281. if($wsdl!==false)
  282. if($this->WriteWsdlToCache($wsdl,$uri,$wsdlFile,true)){
  283. PhpWsdl::Debug('Using cached WSDL from '.$wsdlFile);
  284. $uri=$wsdlFile;
  285. }
  286. }
  287. }
  288. if(
  289. !is_null($this->HttpUser)&&
  290. !isset($this->ClientOptions['login'])&&
  291. !isset($options['login'])&&
  292. $this->UseSoapHttpAuth
  293. ){
  294. PhpWsdl::Debug('Using http Auth options');
  295. $options['login']=$this->HttpUser;
  296. $options['password']=$this->HttpPassword;
  297. }
  298. if($this->Debugging){
  299. PhpWsdl::Debug('Debugging enabled');
  300. $options['trace']=true;
  301. }
  302. $this->Client=new SoapClient($uri,array_merge(
  303. $this->ClientOptions,
  304. $options
  305. ));
  306. }
  307. return $this->Client;
  308. }
  309. /**
  310. * Create/Fill a PhpWsdl object from WSDL
  311. *
  312. * @param PhpWsdl An existing PhpWsdl object (default: NULL)
  313. * @return PhpWsdl The PhpWsdl object
  314. */
  315. public function CreateServerFromWsdl($soap=null){
  316. PhpWsdl::Debug('Create/Fill a PhpWsdl object from WSDL');
  317. if(is_null($soap)){
  318. if(!is_null($this->Server)){
  319. PhpWsdl::Debug('Return existing object');
  320. return $this->Server;
  321. }
  322. $soap=PhpWsdl::CreateInstance();
  323. }else{
  324. PhpWsdl::Debug('Use existing object');
  325. }
  326. if(!is_null($soap->GetWsdlFromCache())){
  327. PhpWsdl::Debug('Server created from cached values');
  328. if(is_null($this->Server))
  329. $this->Server=$soap;
  330. return $soap;
  331. }
  332. // Configuration
  333. $soap->WsdlUri=$this->WsdlUri;
  334. $this->ParseWsdl();
  335. if(!is_null($this->ServiceName))
  336. $soap->Name=$this->ServiceName;
  337. if(!is_null($this->NameSpace))
  338. $soap->NameSpace=$this->NameSpace;
  339. $client=$this->GetClient();
  340. // Methods
  341. $fnc=$client->__getFunctions();
  342. $i=-1;
  343. $len=sizeof($fnc);
  344. while(++$i<$len){
  345. $f=$fnc[$i];
  346. list(
  347. $type,
  348. $method,
  349. $temp
  350. )=explode("\t",preg_replace(self::$methodRx,"$1\t$2\t$3",$f));
  351. PhpWsdl::Debug('Found method #'.$i.' '.$method);
  352. if(!is_null($soap->GetMethod($method))){
  353. $this->Warn('WARNING: Double method detected!');
  354. continue;
  355. }
  356. $m=new PhpWsdlMethod($method);
  357. $temp=explode(' ',$temp);
  358. $pLen=sizeof($temp);
  359. for($j=0;$j<$pLen-1;$j++){
  360. list(
  361. $t,
  362. $n
  363. )=Array(
  364. $temp[$j],
  365. $temp[$j+1]
  366. );
  367. PhpWsdl::Debug('Found parameter #'.$j.' '.$n.' type of '.$t);
  368. $m->Param[]=new PhpWsdlParam(substr($n,1),$t);
  369. }
  370. if($type!='void')
  371. $m->Return=new PhpWsdlParam('return',$type);
  372. $soap->Methods[]=$m;
  373. }
  374. // Types
  375. $typ=$client->__getTypes();
  376. $i=-1;
  377. $len=sizeof($typ);
  378. while(++$i<$len){
  379. $t=$typ[$i];
  380. list(
  381. $type,
  382. $name
  383. )=explode("\t",preg_replace(self::$typeRx,"$1\t$2",$t));
  384. PhpWsdl::Debug('Found type #'.$i.' '.$name.' type of '.$type);
  385. if(!is_null($soap->GetType($name))){
  386. $this->Warn('WARNING: Double type detected!');
  387. continue;
  388. }
  389. $arr=strpos($t,'[]')>-1;
  390. $enum=!$arr&&strpos($t,'{')<0;
  391. if($arr){
  392. PhpWsdl::Debug('Array type');
  393. $y=new PhpWsdlComplex($name);
  394. $y->Type=$type;
  395. $y->IsArray=true;
  396. $soap->Types[]=$y;
  397. }else if(!$enum&&$type=='struct'){
  398. PhpWsdl::Debug('Complex type');
  399. // Note: Inherited types are not supported since the PHP SoapClient object doesn't provide parent class
  400. // informations of a complex type, so PhpWsdlClient doesn't support inherited complex types at all!
  401. $el=Array();
  402. $temp=explode("\n",$t);
  403. $j=0;
  404. $eLen=sizeof($temp)-1;
  405. while(++$j<$eLen){
  406. list(
  407. $p,
  408. $n
  409. )=explode("\t",preg_replace(self::$elementRx,"$1\t$2",$temp[$j]),2);
  410. PhpWsdl::Debug('Found element #'.$j.' '.$n.' type of '.$p);
  411. $el[]=new PhpWsdlElement($n,$p);
  412. }
  413. $y=new PhpWsdlComplex($name,$el);
  414. $y->IsArray=false;
  415. $soap->Types[]=$y;
  416. }else if($enum){
  417. PhpWsdl::Debug('Enumeration');
  418. PhpWsdl::Debug('WARNING: Enumeration values are unknown!');
  419. $y=new PhpWsdlEnum($name,$type);
  420. $soap->Types[]=$y;
  421. }else{
  422. $this->Warn('WARNING: Could not create type '.$t);
  423. }
  424. }
  425. if(is_null($this->Server))
  426. $this->Server=$soap;
  427. return $soap;
  428. }
  429. /**
  430. * Parse the WSDL for webservice name, namespace and endpoint URI
  431. */
  432. public function ParseWsdl(){
  433. if(!is_null($this->ServiceName)&&!is_null($this->EndPoint)&&!is_null($this->NameSpace))
  434. return;
  435. PhpWsdl::Debug('Parse WSDL');
  436. $wsdl=$this->WSDL;
  437. $writeCache=false;
  438. if(is_null($wsdl)){
  439. $wsdl=$this->FetchWsdl();
  440. if($wsdl===false)
  441. throw(new Exception('Could not fetch WSDL'));
  442. $writeCache=true;
  443. }
  444. $xml=new DOMDocument();
  445. if(!$xml->loadXML($wsdl))
  446. throw(new Exception('Invalid WSDL'));
  447. $x=new DOMXPath($xml);
  448. // Namespace
  449. $temp=$x->query("/*[local-name()='definitions']/@targetNamespace");
  450. if($temp->length>0){
  451. $temp=$temp->item(0);
  452. PhpWsdl::Debug('Namespace '.$temp->value);
  453. $this->NameSpace=$temp->value;
  454. }else{
  455. $this->Warn('WARNING: No namespace found');
  456. }
  457. // Webservice name
  458. $temp=$x->query("/*[local-name()='definitions']/*[local-name()='service']/@name");
  459. if($temp->length>0){
  460. $temp=$temp->item(0);
  461. PhpWsdl::Debug('Name '.$temp->value);
  462. $this->ServiceName=$temp->value;
  463. }else{
  464. $this->Warn('WARNING: No name found');
  465. }
  466. // Endpoint URI
  467. $temp=$x->query("/*[local-name()='definitions']/*[local-name()='service']/*[local-name()='port']/*[local-name()='address']/@location");
  468. if($temp->length>0){
  469. $temp=$temp->item(0);
  470. PhpWsdl::Debug('Endpoint '.$temp->value);
  471. $this->EndPoint=$temp->value;
  472. }else{
  473. $this->Warn('WARNING: No endpoint found');
  474. }
  475. // Caching
  476. $this->WriteWsdlToCache($wsdl,null,null,$writeCache);
  477. }
  478. /**
  479. * Create a PHP SOAP client for this webservice
  480. *
  481. * @param string $filename Name of the file to save the PHP code (default: NULL)
  482. * @param array $options The options array for the PhpWsdl->OutputPhp method (default: array)
  483. * @return string The UTF-8 encoded PHP code of the SOAP client
  484. */
  485. public function CreatePhpSoapClient($filename=null,$options=Array()){
  486. $php=$this->CreateServerFromWsdl()->OutputPhp(false,false,$options);
  487. if(!is_null($filename))
  488. if(file_put_contents($filename,$php)===false)
  489. PhpWsdl::Debug('Could not write file '.$filename);
  490. return $php;
  491. }
  492. /**
  493. * Add a warning message
  494. *
  495. * @param string $str The message
  496. */
  497. private function Warn($str){
  498. $this->Warnings[]=$str;
  499. PhpWsdl::Debug($str);
  500. }
  501. /**
  502. * Get the cache filename
  503. *
  504. * @param string $wsdluri The WSDL URI or NULL to use the PhpWsdlAjax->WsdlUri property (default: NULL)
  505. * @return string The cache filename or NULL, if caching is disabled
  506. */
  507. public function GetCacheFileName($wsdluri=null){
  508. $data=Array(
  509. 'client' => $this,
  510. 'wsdluri' => $wsdluri,
  511. 'filename' => (is_null(PhpWsdl::$CacheFolder))?null:PhpWsdl::$CacheFolder.'/client-'.sha1((is_null($wsdluri))?$this->WsdlUri:$wsdluri).'.wsdl'
  512. );
  513. PhpWsdl::CallHook(
  514. 'ClientCacheFileNameHook',
  515. $data
  516. );
  517. return $data['filename'];
  518. }
  519. /**
  520. * Determine if the cache file exists
  521. *
  522. * @param string $file The WSDL cache filename or NULL to use the default (default: NULL)
  523. * @return boolean Are the cache files present?
  524. */
  525. public function CacheFileExists($file=null){
  526. if(is_null($file))
  527. $file=$this->GetCacheFileName();
  528. PhpWsdl::Debug('Check cache file exists '.$file);
  529. return file_exists($file)&&file_exists($file.'.cache');
  530. }
  531. /**
  532. * Determine if the existing cache files are still valid
  533. *
  534. * @param string $file The WSDL cache filename or NULL to use the default (default: NULL)
  535. * @return boolean Valid?
  536. */
  537. public function IsCacheValid($file=null){
  538. PhpWsdl::Debug('Check cache valid');
  539. if(is_null($file))
  540. $file=$this->GetCacheFileName();
  541. if(!$this->CacheFileExists($file))
  542. return false;
  543. return PhpWsdl::$CacheTime<0||time()-file_get_contents($file.'.cache')<=PhpWsdl::$CacheTime;
  544. }
  545. /**
  546. * Get the WSDL from the cache
  547. *
  548. * @param string $file The WSDL cache filename or NULL to use the default (default: NULL)
  549. * @param boolean $force Force this even if the cache is timed out? (default: FALSE)
  550. * @param boolean $nounserialize Don't unserialize the PhpWsdl* objects? (default: FALSE)
  551. * @return string The cached WSDL
  552. */
  553. public function GetWsdlFromCache($file=null,$force=false,$nounserialize=false){
  554. PhpWsdl::Debug('Get WSDL from cache');
  555. if(!is_null($this->WSDL))
  556. return $this->WSDL;
  557. if(is_null($file))
  558. $file=$this->GetCacheFileName();
  559. if(!$force){
  560. if(!$this->IsCacheValid($file))
  561. return null;
  562. }else if(!$this->CacheFileExists($file)){
  563. return null;
  564. }
  565. $this->WSDL=file_get_contents($file);
  566. if(!$nounserialize){
  567. PhpWsdl::Debug('Unserialize data');
  568. $data=unserialize(file_get_contents($file.'.obj'));
  569. $this->ServiceName=$data['servicename'];
  570. $this->EndPoint=$data['endpoint'];
  571. $this->NameSpace=$data['namespace'];
  572. PhpWsdl::CallHook(
  573. 'ClientReadCacheHook',
  574. Array(
  575. 'client' => $this,
  576. 'data' => &$data
  577. )
  578. );
  579. if($data['version']!=self::$VERSION){
  580. PhpWsdl::Debug('Could not use cache from version '.$data['version']);
  581. $this->ServiceName=null;
  582. $this->EndPoint=null;
  583. $this->NameSpace=null;
  584. $this->WSDL=null;
  585. return null;
  586. }
  587. }
  588. return $this->WSDL;
  589. }
  590. /**
  591. * Write WSDL to cache
  592. *
  593. * @param string $wsdl The UTF-8 encoded WSDL string (default: NULL)
  594. * @param string $wsdluri The SOAP WSDL URI or NULL to use the default (default: NULL)
  595. * @param string $file The target filename or NULL to use the default (default: NULL)
  596. * @param boolean $force Force refresh (default: FALSE)
  597. * @return boolean Succeed?
  598. */
  599. public function WriteWsdlToCache($wsdl=null,$wsdluri=null,$file=null,$force=false){
  600. PhpWsdl::Debug('Write WSDL to the cache');
  601. if(is_null($wsdluri))
  602. $wsdluri=$this->WsdlUri;
  603. if($wsdluri==$this->WsdlUri&&!is_null($wsdl))
  604. $this->WSDL=$wsdl;
  605. if(is_null($wsdl)){
  606. if(is_null($this->WSDL)){
  607. PhpWsdl::Debug('No WSDL');
  608. return false;// WSDL not defined
  609. }
  610. $wsdl=$this->WSDL;
  611. }
  612. if(is_null($file)){
  613. $file=$this->GetCacheFileName($wsdluri);
  614. if(is_null($file)){
  615. PhpWsdl::Debug('No cache file');
  616. return false;// No cache file
  617. }
  618. }
  619. $temp=substr($file,0,1);
  620. if($temp!='/'&&$temp!='.'){
  621. if(is_null(PhpWsdl::$CacheFolder)){
  622. PhpWsdl::Debug('No cache folder');
  623. return false;// No cache folder
  624. }
  625. $file=PhpWsdl::$CacheFolder.'/'.$file;
  626. }
  627. if(!$force)
  628. if($this->IsCacheValid($file)){
  629. PhpWsdl::Debug('Cache is still valid');
  630. return true;// Existing cache is still valid
  631. }
  632. PhpWsdl::Debug('Write to '.$file);
  633. if(file_put_contents($file,$wsdl)===false){
  634. PhpWsdl::Debug('Could not write to cache');
  635. return false;// Error writing to cache
  636. }
  637. if(file_put_contents($file.'.cache',time())===false){
  638. PhpWsdl::Debug('Could not write cache time file');
  639. return false;// Error writing to cache
  640. }
  641. $data=Array(
  642. 'version' => self::$VERSION,
  643. 'servicename' => $this->ServiceName,
  644. 'endpoint' => $this->EndPoint,
  645. 'namespace' => $this->NameSpace
  646. );
  647. PhpWsdl::CallHook(
  648. 'ClientWriteCacheHook',
  649. Array(
  650. 'client' => $this,
  651. 'data' => &$data
  652. )
  653. );
  654. if(file_put_contents($file.'.obj',serialize($data))===false){
  655. PhpWsdl::Debug('Could not write serialized cache');
  656. return false;
  657. }
  658. return true;
  659. }
  660. /**
  661. * SOAP method call proxy method
  662. *
  663. * @param string $method The method name
  664. * @param array $param The method parameters
  665. * @return mixed The server response
  666. */
  667. public function __call($method,$param){
  668. return $this->DoRequest($method,$param);
  669. }
  670. }