PageRenderTime 92ms CodeModel.GetById 28ms RepoModel.GetById 3ms app.codeStats 0ms

/nusoap/class.phpwsdl.nusoap.php

http://php-wsdl-creator.googlecode.com/
PHP | 384 lines | 286 code | 14 blank | 84 comment | 22 complexity | 78d4a5f2ac7d73cbeb4c72381a2bbc7e 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. // The NuSOAP adapter was developed and tested with NuSOAP version 0.9.5
  18. //
  19. // Note: The NuSOAP adapter won't work with the PhpWsdlProxy!
  20. PhpWsdl::Debug('NuSOAP adapter loaded');
  21. PhpWsdl::RegisterHook('CreateWsdlHeaderHook','nusoap','PhpWsdlNuSOAP::CreateWsdl');
  22. PhpWsdl::RegisterHook('PrepareServerHook','nusoap','PhpWsdlNuSOAP::PrepareServer');
  23. PhpWsdl::RegisterHook('RunServerHook','nusoap','PhpWsdlNuSOAP::RunServer');
  24. // Disable the PhpWsdl WSDL Generator (we need to use the one from NuSOAP)
  25. PhpWsdl::UnregisterHook('CreateWsdlHeaderHook','internal');
  26. PhpWsdl::UnregisterHook('CreateWsdlTypeSchemaHook','internal');
  27. PhpWsdl::UnregisterHook('CreateWsdlMessagesHook','internal');
  28. PhpWsdl::UnregisterHook('CreateWsdlPortsHook','internal');
  29. PhpWsdl::UnregisterHook('CreateWsdlBindingsHook','internal');
  30. PhpWsdl::UnregisterHook('CreateWsdlServiceHook','internal');
  31. PhpWsdl::UnregisterHook('CreateWsdlFooterHook','internal');
  32. // Comment out this line to get rid of the NuSOAP information in the HTML output
  33. PhpWsdl::RegisterHook('CreateHtmlGeneralHook','nusoap','PhpWsdlNuSOAP::CreateHtmlGeneral');
  34. /**
  35. * This class will run a NuSOAP SOAP server with PhpWsdl
  36. *
  37. * @author Andreas Müller-Saala, wan24.de
  38. */
  39. class PhpWsdlNuSOAP{
  40. /**
  41. * The current server object
  42. *
  43. * @var nusoap_server
  44. */
  45. public static $Server=null;
  46. /**
  47. * Create WSDL
  48. *
  49. * @param array $data The server data
  50. * @return boolean Response
  51. */
  52. public static function CreateWsdl($data){
  53. if(!class_exists('soap_server')){
  54. PhpWsdl::Debug('NuSOAP not found');
  55. return true;// Use the default PHP SoapServer because NuSOAP is not available
  56. }
  57. if(is_null(self::$Server))
  58. self::CreateServer($data['server'],$data);
  59. $data['res'][]=self::$Server->wsdl->serialize();
  60. return false;
  61. }
  62. /**
  63. * Prepare the NuSOAP server
  64. *
  65. * @param array $data The server data
  66. * @return boolean Response
  67. */
  68. public static function PrepareServer($data){
  69. if(!class_exists('soap_server')){
  70. PhpWsdl::Debug('NuSOAP not found');
  71. return true;// Use the default PHP SoapServer because NuSOAP is not available
  72. }
  73. // Initialize the NuSOAP server object
  74. $server=$data['server'];
  75. $data['soapserver']=(is_null(self::$Server))?self::CreateServer($server):self::$Server;
  76. return false;
  77. }
  78. /**
  79. * Run the NuSOAP server
  80. *
  81. * @param array $data The server data
  82. * @return boolean Response
  83. */
  84. public static function RunServer($data){
  85. $server=$data['soapserver'];
  86. if($server!==self::$Server||!class_exists('soap_server')){
  87. PhpWsdl::Debug('NuSOAP not found or server object changed');
  88. return true;// We can't handle this server run!
  89. }
  90. $req=file_get_contents('php://input');
  91. $handled=false;
  92. if(!PhpWsdl::CallHook(
  93. 'NuSOAPRunHook',
  94. array_merge(
  95. $data,
  96. Array(
  97. 'req' => &$req,
  98. 'handled' => &$handled
  99. )
  100. )
  101. )
  102. )
  103. return $handled;
  104. self::$Server->service(utf8_encode($req));
  105. return false;
  106. }
  107. /**
  108. * Modify the HTML documentation output
  109. *
  110. * @param array $data
  111. * @return boolean Response
  112. */
  113. public static function CreateHtmlGeneral($data){
  114. $res=&$data['res'];
  115. $res[]='<p><i>Info: This SOAP webservice uses NuSOAP as SOAP server.</i></p>';
  116. return true;
  117. }
  118. /**
  119. * Create a NuSOAP soap_server object
  120. *
  121. * @param PhpWsdl $server The PhpWsdl object
  122. * @return nusoap_server The NuSOAP server object
  123. */
  124. public static function CreateServer($server){
  125. if(!is_null(self::$Server))
  126. return self::$Server;
  127. // Basic configuration
  128. self::$Server=new nusoap_server();
  129. self::$Server->debug_flag=false;
  130. self::$Server->soap_defencoding='UTF-8';
  131. self::$Server->decode_utf8=false;
  132. self::$Server->configureWSDL($server->Name,$server->NameSpace,$server->EndPoint);
  133. self::$Server->wsdl->schemaTargetNamespace=$server->NameSpace;
  134. if(!PhpWsdl::CallHook(
  135. 'NuSOAPConfigHook',
  136. Array(
  137. 'server' => self::$Server
  138. )
  139. )
  140. )
  141. return self::$Server;
  142. // Add types
  143. $i=-1;
  144. $len=sizeof($server->Types);
  145. while(++$i<$len){
  146. $t=$server->Types[$i];
  147. PhpWsdl::Debug('Add complex type '.$t->Name);
  148. if(!PhpWsdl::CallHook(
  149. 'NuSOAPTypeHook',
  150. array_merge(
  151. $data,
  152. Array(
  153. 'type' => &$t
  154. )
  155. )
  156. )
  157. )
  158. continue;
  159. if($t->IsArray){
  160. $type=$t->Type;
  161. self::$Server->wsdl->addComplexType(
  162. $t->Name,
  163. 'complexType',
  164. 'array',
  165. '',
  166. 'SOAP-ENC:Array',
  167. Array(),
  168. Array(
  169. Array(
  170. 'ref' => 'SOAP-ENC:arrayType',
  171. 'wsdl:arrayType'=> ((in_array($type,PhpWsdl::$BasicTypes))?'xsd:'.$type:'tns:'.$type).'[]'
  172. )
  173. ),
  174. (in_array($type,PhpWsdl::$BasicTypes))?'xsd:'.$type:'tns:'.$type
  175. );
  176. }else if(get_class($t)=='PhpWsdlEnum'){
  177. self::$Server->wsdl->addSimpleType(
  178. $t->Name,
  179. (in_array($t->Type,PhpWsdl::$BasicTypes))?'xsd:'.$t->Type:'tns:'.$t->Type,
  180. 'simpleType',
  181. 'scalar',
  182. $t->Elements
  183. );
  184. }else{
  185. $el=Array();
  186. $j=-1;
  187. $eLen=sizeof($t->Elements);
  188. while(++$j<$eLen){
  189. $e=$t->Elements[$j];
  190. $el[$e->Name]=Array(
  191. 'name' => $e->Name,
  192. 'type' => (in_array($e->Type,PhpWsdl::$BasicTypes))?'xsd:'.$e->Type:'tns:'.$e->Type
  193. );
  194. }
  195. self::$Server->wsdl->addComplexType(
  196. $t->Name,
  197. 'complexType',
  198. 'struct',
  199. 'sequence',
  200. '',
  201. $el
  202. );
  203. }
  204. }
  205. PhpWsdl::CallHook(
  206. 'NuSOAPTypesHook',
  207. $data
  208. );
  209. // Add methods
  210. $i=-1;
  211. $len=sizeof($server->Methods);
  212. while(++$i<$len){
  213. $m=$server->Methods[$i];
  214. PhpWsdl::Debug('Register method '.$m->Name);
  215. if(!PhpWsdl::CallHook(
  216. 'NuSOAPMethodHook',
  217. array_merge(
  218. $data,
  219. Array(
  220. 'method' => &$m
  221. )
  222. )
  223. )
  224. )
  225. continue;
  226. $param=Array();
  227. $j=-1;
  228. $pLen=sizeof($m->Param);
  229. while(++$j<$pLen){
  230. $p=$m->Param[$j];
  231. $param[$p->Name]=(in_array($p->Type,PhpWsdl::$BasicTypes))?'xsd:'.$p->Type:'tns:'.$p->Type;
  232. }
  233. $r=$m->Return;
  234. self::$Server->register(
  235. ($m->IsGlobal)?$m->Name:$server->Name.'.'.$m->Name,
  236. $param,
  237. (is_null($r))
  238. ?Array()
  239. :Array(
  240. 'return' => (in_array($r->Type,PhpWsdl::$BasicTypes))?'xsd:'.$r->Type:'tns:'.$r->Type
  241. ),
  242. $server->NameSpace,
  243. $server->NameSpace.$m->Name,
  244. 'rpc',
  245. 'encoded'
  246. );
  247. }
  248. PhpWsdl::CallHook(
  249. 'NuSOAPMethodsHook',
  250. $data
  251. );
  252. return self::$Server;
  253. }
  254. /**
  255. * Fill an PhpWsdl object with data from an NuSOAP object
  256. * Development status: Beta
  257. *
  258. * @param nusoap_server $nusoap NuSOAP server object
  259. * @param PhpWsdl $phpwsdl PhpWsdl object or NULL to create a new one (default: NULL)
  260. * @return PhpWsdl PhpWsdl object
  261. */
  262. public static function CreatePhpWsdl($nusoap,$phpwsdl=null){
  263. //TODO This has still to be tested with some real NuSOAP webservice objects!
  264. PhpWsdl::Debug('Create PhpWsdl from NuSOAP');
  265. if(is_null($phpwsdl))
  266. $phpwsdl=PhpWsdl::CreateInstance();
  267. // Basic configuration
  268. $phpwsdl->Name=$nusoap->wsdl->serviceName;
  269. $phpwsdl->EndPoint=$nusoap->wsdl->endpoint;
  270. $phpwsdl->NameSpace=$nusoap->wsdl->namespaces['tns'];
  271. // Types
  272. PhpWsdl::Debug('Add types');
  273. $ntl=$nusoap->wsdl->schemas[$phpwsdl->NameSpace][0]->complexTypes;
  274. $keys=array_keys($ntl);
  275. $i=-1;
  276. $len=sizeof($keys);
  277. while(++$i<$len){
  278. $nt=$ntl[$keys[$i]];
  279. $name=$nt['name'];
  280. PhpWsdl::Debug('Add type '.$name);
  281. if(!is_null($phpwsdl->GetType($name))){
  282. PhpWsdl::Debug('WARNING: Double type detected!');
  283. continue;
  284. }
  285. if($nt['typeClass']=='complexType'&&$nt['phpType']=='array'){
  286. // Array
  287. PhpWsdl::Debug('Array type');
  288. list($temp,$type)=explode(':',$nt['arrayType'],2);
  289. $t=new PhpWsdlComplex($name);
  290. $t->Type=$type;
  291. $t->IsArray=true;
  292. $phpwsdl->Types[]=$t;
  293. }else if($nt['typeClass']=='complexType'){
  294. // Complex type
  295. PhpWsdl::Debug('Complex type');
  296. if($nt['phpType']!='struct')
  297. PhpWsdl::Debug('WARNING: Not a PHP struct');
  298. if($nt['compositor']!='sequence')
  299. PhpWsdl::Debug('WARNING: Not sequenced elements');
  300. $el=Array();
  301. $ek=array_keys($nt['elements']);
  302. $j=-1;
  303. $eLen=sizeof($ek);
  304. while(++$j<$eLen){
  305. $n=$nt['elements'][$ek[$j]]['name'];
  306. list($temp,$type)=explode(':',$nt['elements'][$ek[$j]]['type']);
  307. PhpWsdl::Debug('Found element '.$n.' type of '.$type);
  308. $el[]=new PhpWsdlElement($n,$type);
  309. }
  310. $phpwsdl->Types[]=new PhpWsdlComplex($name,$el);
  311. }else if($nt['typeClass']=='simpleType'){
  312. // Enumeration
  313. PhpWsdl::Debug('Enumeration');
  314. list($temp,$type)=explode(':',$nt['type']);
  315. $phpwsdl->Types[]=new PhpWsdlEnum($name,$type,$nt['enumeration']);
  316. }else{
  317. PhpWsdl::Debug('WARNING: PHP type "'.$nt['phpType'].'" is not supported!');
  318. }
  319. }
  320. // Methods
  321. PhpWsdl::Debug('Add methods');
  322. $nml=$nusoap->operations;
  323. $keys=array_keys($nml);
  324. $i=-1;
  325. $len=sizeof($keys);
  326. while(++$i<$len){
  327. $nm=$nml[$keys[$i]];
  328. // Get the method name
  329. $name=$nml['name'];
  330. PhpWsdl::Debug('Add method '.$name);
  331. $glob=strpos($name,'.')<0;
  332. if(!$glob){
  333. list($temp,$name)=explode('.',$name,2);
  334. PhpWsdl::Debug('Class method '.$name);
  335. }else{
  336. PhpWsdl::Debug('Global method');
  337. }
  338. if(!is_null($phpwsdl->GetMethod($name))){
  339. PhpWsdl::Debug('WARNING: Double method detected!');
  340. continue;
  341. }
  342. // Get parameters
  343. $param=Array();
  344. $pk=array_keys($nm['in']);
  345. $j=-1;
  346. $pLen=sizeof($pk);
  347. while(++$j<$pLen){
  348. list($temp,$type)=explode(':',$nm['in'][$pk[$j]],2);
  349. PhpWsdl::Debug('Parameter '.$ok[$j].' type of '.$type);
  350. $param[]=new PhpWsdlParam($pk[$j],$type);
  351. }
  352. // Get return type
  353. $r=null;
  354. if(sizeof($nm['out'])>0){
  355. $pk=array_keys($nm['in']);
  356. list($temp,$type)=explode(':',$nm['out'][$pk[0]],2);
  357. PhpWsdl::Debug('Return '.$pk[0].' type of '.$type);
  358. $r=new PhpWsdlParam($pk[0],$type);
  359. }
  360. // Create method
  361. $m=new PhpWsdlMethod($name,$param,$r);
  362. $m->IsGlobal=$glob;
  363. $phpwsdl->Methods[]=$m;
  364. }
  365. return $phpwsdl;
  366. }
  367. }