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