PageRenderTime 59ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/class.phpwsdlcomplex.php

http://php-wsdl-creator.googlecode.com/
PHP | 378 lines | 230 code | 11 blank | 137 comment | 37 complexity | abee30f01727dcf6c414f84fc2449643 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. PhpWsdl::RegisterHook('InterpretKeywordpw_complexHook','internal','PhpWsdlComplex::InterpretComplex');
  18. PhpWsdl::RegisterHook('CreateObjectHook','internalcomplex','PhpWsdlComplex::CreateComplexTypeObject');
  19. /**
  20. * This class creates complex types (classes or arrays)
  21. *
  22. * @author Andreas Müller-Saala, wan24.de
  23. */
  24. class PhpWsdlComplex extends PhpWsdlObject{
  25. /**
  26. * The array type
  27. *
  28. * @var string
  29. */
  30. public $Type=null;
  31. /**
  32. * Name of the complex type to inherit from
  33. *
  34. * @var string
  35. */
  36. public $Inherit=null;
  37. /**
  38. * A list of elements, if this type is a class
  39. *
  40. * @var PhpWsdlElement[]
  41. */
  42. public $Elements;
  43. /**
  44. * Is this type an array?
  45. *
  46. * @var boolean
  47. */
  48. public $IsArray;
  49. /**
  50. * Enable creating a PHP constructor that requires all parameters?
  51. *
  52. * @var boolean
  53. */
  54. public $EnablePhpConstructor=false;
  55. /**
  56. * Disable definition of arrays with the "Array" postfix in the type name?
  57. *
  58. * @var boolean
  59. */
  60. public static $DisableArrayPostfix=false;
  61. /**
  62. * Create a PHP constructor that requires all parameters per default?
  63. *
  64. * @var boolean
  65. */
  66. public static $DefaultEnablePhpConstructor=false;
  67. /**
  68. * Constructor
  69. *
  70. * @param string $name The name
  71. * @param PhpWsdlElement[] $el Optional a list of elements
  72. * @param array $settings Optional the settings hash array (default: NULL)
  73. */
  74. public function PhpWsdlComplex($name,$el=Array(),$settings=null){
  75. PhpWsdl::Debug('New complex type '.$name);
  76. parent::PhpWsdlObject($name,$settings);
  77. if(!self::$DisableArrayPostfix){
  78. $this->IsArray=substr($name,strlen($name)-5,5)=='Array';
  79. if($this->IsArray)
  80. $this->Type=substr($this->Name,0,strlen($this->Name)-5);
  81. }
  82. $this->Elements=$el;
  83. $this->EnablePhpConstructor=self::$DefaultEnablePhpConstructor;
  84. if(!is_null($settings)){
  85. if(isset($settings['isarray']))
  86. $this->IsArray=$settings['isarray'];
  87. if(isset($settings['phpconstructor']))
  88. $this->EnablePhpConstructor=$settings['phpconstructor']=='1'||$settings['phpconstructor']=='true';
  89. if(isset($settings['type']))
  90. $this->IsArray=$settings['type'];
  91. if(isset($settings['inherit']))
  92. $this->Inherit=$settings['inherit'];
  93. }
  94. }
  95. /**
  96. * Create WSDL for the type
  97. *
  98. * @param PhpWsdl $pw The PhpWsdl object
  99. * @return string The WSDL
  100. */
  101. public function CreateType($pw){
  102. $res=Array();
  103. $res[]='<s:complexType name="'.$this->Name.'">';
  104. if($pw->IncludeDocs&&!$pw->Optimize&&!is_null($this->Docs)){
  105. $res[]='<s:annotation>';
  106. $res[]='<s:documentation><![CDATA['.$this->Docs.']]></s:documentation>';
  107. $res[]='</s:annotation>';
  108. }
  109. if(!$this->IsArray){
  110. PhpWsdl::Debug('Create WSDL definition for type '.$this->Name.' as type');
  111. if(is_null($this->Inherit)){
  112. $res[]='<s:sequence>';
  113. $i=-1;
  114. $len=sizeof($this->Elements);
  115. while(++$i<$len)
  116. $res[]=$this->Elements[$i]->CreateElement($pw);
  117. $res[]='</s:sequence>';
  118. }else{
  119. PhpWsdl::Debug('Inherit from "'.$this->Inherit.'"');
  120. $res[]='<s:complexContent>';
  121. $res[]='<s:extension base="tns:'.$this->Inherit.'">';
  122. $res[]='<s:sequence>';
  123. $i=-1;
  124. $len=sizeof($this->Elements);
  125. while(++$i<$len)
  126. $res[]=$this->Elements[$i]->CreateElement($pw);
  127. $res[]='</s:sequence>';
  128. $res[]='</s:extension>';
  129. $res[]='</s:complexContent>';
  130. }
  131. }else{
  132. PhpWsdl::Debug('Create WSDL definition for type '.$this->Name.' as array');
  133. $res[]='<s:complexContent>';
  134. $res[]='<s:restriction base="soapenc:Array">';
  135. $res[]='<s:attribute ref="soapenc:arrayType" wsdl:arrayType="'.PhpWsdl::TranslateType($this->Type).'[]" />';
  136. $res[]='</s:restriction>';
  137. $res[]='</s:complexContent>';
  138. }
  139. $res[]='</s:complexType>';
  140. return implode('',$res);
  141. }
  142. /**
  143. * Find an element within this type
  144. *
  145. * @param string $name The name
  146. * @return PhpWsdlElement The element or NULL, if not found
  147. */
  148. public function GetElement($name){
  149. PhpWsdl::Debug('Find element '.$name);
  150. $i=-1;
  151. $len=sizeof($this->Elements);
  152. while(++$i<$len)
  153. if($this->Elements[$i]->Name==$name){
  154. PhpWsdl::Debug('Found element at index '.$i);
  155. return $this->Elements[$i];
  156. }
  157. return null;
  158. }
  159. /**
  160. * Create the HTML documentation for a complex type
  161. *
  162. * @param array $data
  163. */
  164. public function CreateTypeHtml($data){
  165. PhpWsdl::Debug('CreateTypeHtml for '.$data['type']->Name);
  166. $server=$data['server'];
  167. $res=&$data['res'];
  168. $t=&$data['type'];
  169. $res[]='<h3>'.$t->Name.'</h3>';
  170. $res[]='<a name="'.$t->Name.'"></a>';
  171. if(!is_null($t->Inherit))
  172. $res[]='<p>This type inherits all properties from <a href="#'.$t->Inherit.'"><span class="lightBlue">'.$t->Inherit.'</span></a>.</p>';
  173. $eLen=sizeof($t->Elements);
  174. if($t->IsArray){
  175. // Array type
  176. $res[]='<p>This is an array type of <span class="pre">';
  177. $o=sizeof($res)-1;
  178. if(in_array($t->Type,PhpWsdl::$BasicTypes)){
  179. $res[$o].='<span class="blue">'.$t->Type.'</span>';
  180. }else{
  181. $res[$o].='<a href="#'.$t->Type.'"><span class="lightBlue">'.$t->Type.'</span></a>';
  182. }
  183. $res[$o].='</span>.</p>';
  184. if(!is_null($t->Docs))
  185. $res[]='<p>'.nl2br(htmlentities($t->Docs)).'</p>';
  186. }else if($eLen>0){
  187. // Complex type with elements
  188. if(!is_null($t->Docs))
  189. $res[]='<p>'.nl2br(htmlentities($t->Docs)).'</p>';
  190. $res[]='<ul class="pre">';
  191. $j=-1;
  192. while(++$j<$eLen)
  193. $t->Elements[$j]->CreateElementHtml(array_merge(
  194. $data,
  195. Array(
  196. 'element' => $t->Elements[$j]
  197. )
  198. ));
  199. $res[]='</ul>';
  200. }else{
  201. // Complex type without elements
  202. $res[]='<p>This type has no elements.</p>';
  203. }
  204. PhpWsdl::CallHook(
  205. 'CreateTypeHtmlHook',
  206. $data
  207. );
  208. }
  209. /**
  210. * Create type PHP code
  211. *
  212. * @param array $data The event data
  213. */
  214. public function CreateTypePhp($data){
  215. if($this->IsArray)
  216. return;
  217. $server=$data['server'];
  218. $res=&$data['res'];
  219. $res[]="/**";
  220. if(!is_null($this->Docs)){
  221. $res[]=" * ".implode("\n * ",explode("\n",$this->Docs));
  222. $res[]=" *";
  223. }
  224. $temp=Array();
  225. $i=-1;
  226. $eLen=sizeof($this->Elements);
  227. while(++$i<$eLen){
  228. $e=$this->Elements[$i];
  229. $temp[]='$'.$e->Name;
  230. $res[]=" * @pw_element ".$e->Type." \$".$e->Name.((!is_null($e->Docs))?' '.$e->Docs:'');
  231. }
  232. $res[]=" * @pw_complex ".$this->Name;
  233. $res[]=" */";
  234. $res[]="class ".$this->Name.((is_null($this->Inherit))?'':' extends '.$this->Inherit)."{";
  235. if($eLen>0&&$this->EnablePhpConstructor){
  236. $res[]="\t/**";
  237. $res[]="\t * Constructor with parameters (all required!)";
  238. $res[]="\t *";
  239. $i=-1;
  240. while(++$i<$eLen){
  241. $e=$this->Elements[$i];
  242. $res[]="\t * @param ".$e->Type." ".$temp[$i].((!is_null($e->Docs))?' '.$e->Docs:'');
  243. }
  244. if(!is_null($this->Inherit)){
  245. $it=$server->GetType($this->Inherit);
  246. if($it->EnablePhpConstructor){
  247. $i=-1;
  248. $tLen=sizeof($it->Elements);
  249. while(++$i<$tLen){
  250. $e=$it->Elements[$i];
  251. $tempb[]='$'.$e->Name;
  252. $res[]=" * @param ".$e->Type." \$".$e->Name.((!is_null($e->Docs))?' '.$e->Docs:'');
  253. }
  254. }
  255. }
  256. $res[]="\t */";
  257. $res[]="\tpublic function ".$this->Name."(".implode(',',$temp)."){";
  258. if(!is_null($this->Inherit)&&$it->EnablePhpConstructor)
  259. $res[]="\t\tparent::".$this->Inherit."(".implode(',',$tempb).");";
  260. $i=-1;
  261. while(++$i<$eLen)
  262. $res[]="\t\t\$this->".$this->Elements[$i]->Name."=".$temp[$i];
  263. $res[]="\t}";
  264. }
  265. $i=-1;
  266. while(++$i<$eLen){
  267. $e=$this->Elements[$i];
  268. $res[]="\t/**";
  269. if(!is_null($e->Docs)){
  270. $res[]="\t * ".implode("\n\t * ",explode("\n",$e->Docs));
  271. $res[]="\t *";
  272. }
  273. $res[]="\t * @var ".$e->Type;
  274. $res[]="\t */";
  275. $res[]="\tpublic \$".$this->Elements[$i]->Name.";";
  276. }
  277. $res[]="}";
  278. }
  279. /**
  280. * Interpret a complex type
  281. *
  282. * @param array $data The parser data
  283. * @return boolean Response
  284. */
  285. public static function InterpretComplex($data){
  286. $info=explode(' ',$data['keyword'][1],3);
  287. if(sizeof($info)<1)
  288. return true;
  289. $server=$data['server'];
  290. $name=$info[0];
  291. PhpWsdl::Debug('Interpret complex type "'.$name.'"');
  292. $type=null;
  293. $docs=null;
  294. if(strpos($name,'[]')>-1){
  295. if(sizeof($info)<2){
  296. PhpWsdl::Debug('WARNING: Invalid array definition!');
  297. return true;
  298. }
  299. $name=substr($name,0,strlen($name)-2);
  300. if(!is_null($server->GetType($name))){
  301. PhpWsdl::Debug('WARNING: Double type detected!');
  302. return true;
  303. }
  304. $type=$info[1];
  305. if($server->ParseDocs)
  306. if(sizeof($info)>2)
  307. $docs=$info[2];
  308. PhpWsdl::Debug('Array "'.$name.'" type of "'.$type.'" definition');
  309. }else{
  310. if(!is_null($server->GetType($name))){
  311. PhpWsdl::Debug('WARNING: Double type detected!');
  312. return true;
  313. }
  314. if(!self::$DisableArrayPostfix&&substr($name,strlen($name)-5)=='Array'){
  315. $type=substr($name,0,strlen($name)-5);
  316. PhpWsdl::Debug('Array "'.$name.'" type of "'.$type.'" definition');
  317. }else{
  318. PhpWsdl::Debug('Complex type definition');
  319. }
  320. if($server->ParseDocs){
  321. $temp=sizeof($info);
  322. if($temp>1)
  323. $docs=($temp>2)?$info[1].' '.$info[2]:$info[1];
  324. }
  325. }
  326. $data['type']=Array(
  327. 'id' => 'complex',
  328. 'name' => $name,
  329. 'type' => $type,
  330. 'docs' => $docs
  331. );
  332. return false;
  333. }
  334. /**
  335. * Create complex type object
  336. *
  337. * @param array $data The parser data
  338. * @return boolean Response
  339. */
  340. public static function CreateComplexTypeObject($data){
  341. if($data['method']!='')
  342. return true;
  343. if(!is_null($data['obj']))
  344. return true;
  345. if(!is_array($data['type']))
  346. return true;
  347. if(!isset($data['type']['id']))
  348. return true;
  349. if($data['type']['id']!='complex')
  350. return true;
  351. if(!is_null($data['docs'])){
  352. $data['settings']['docs']=$data['docs'];
  353. }else{
  354. $data['settings']['docs']=$data['type']['docs'];
  355. }
  356. PhpWsdl::Debug('Add complex type '.$data['type']['name']);
  357. $data['settings']['isarray']=!is_null($data['type']['type']);
  358. $data['obj']=new PhpWsdlComplex($data['type']['name'],$data['elements'],$data['settings']);
  359. $data['obj']->Type=$data['type']['type'];
  360. $data['settings']=Array();
  361. $data['server']->Types[]=$data['obj'];
  362. return true;
  363. }
  364. }