|
1 <?php |
|
2 /** |
|
3 * Zend Framework |
|
4 * |
|
5 * LICENSE |
|
6 * |
|
7 * This source file is subject to the new BSD license that is bundled |
|
8 * with this package in the file LICENSE.txt. |
|
9 * It is also available through the world-wide-web at this URL: |
|
10 * http://framework.zend.com/license/new-bsd |
|
11 * If you did not receive a copy of the license and are unable to |
|
12 * obtain it through the world-wide-web, please send an email |
|
13 * to license@zend.com so we can send you a copy immediately. |
|
14 * |
|
15 * @category Zend |
|
16 * @package Zend_CodeGenerator |
|
17 * @subpackage PHP |
|
18 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) |
|
19 * @license http://framework.zend.com/license/new-bsd New BSD License |
|
20 * @version $Id: Class.php 21915 2010-04-16 20:40:15Z matthew $ |
|
21 */ |
|
22 |
|
23 /** |
|
24 * @see Zend_CodeGenerator_Php_Abstract |
|
25 */ |
|
26 require_once 'Zend/CodeGenerator/Php/Abstract.php'; |
|
27 |
|
28 /** |
|
29 * @see Zend_CodeGenerator_Php_Member_Container |
|
30 */ |
|
31 require_once 'Zend/CodeGenerator/Php/Member/Container.php'; |
|
32 |
|
33 /** |
|
34 * @see Zend_CodeGenerator_Php_Method |
|
35 */ |
|
36 require_once 'Zend/CodeGenerator/Php/Method.php'; |
|
37 |
|
38 /** |
|
39 * @see Zend_CodeGenerator_Php_Property |
|
40 */ |
|
41 require_once 'Zend/CodeGenerator/Php/Property.php'; |
|
42 |
|
43 /** |
|
44 * @see Zend_CodeGenerator_Php_Docblock |
|
45 */ |
|
46 require_once 'Zend/CodeGenerator/Php/Docblock.php'; |
|
47 |
|
48 /** |
|
49 * @category Zend |
|
50 * @package Zend_CodeGenerator |
|
51 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) |
|
52 * @license http://framework.zend.com/license/new-bsd New BSD License |
|
53 */ |
|
54 class Zend_CodeGenerator_Php_Class extends Zend_CodeGenerator_Php_Abstract |
|
55 { |
|
56 |
|
57 /** |
|
58 * @var Zend_CodeGenerator_Php_Docblock |
|
59 */ |
|
60 protected $_docblock = null; |
|
61 |
|
62 /** |
|
63 * @var string |
|
64 */ |
|
65 protected $_name = null; |
|
66 |
|
67 /** |
|
68 * @var bool |
|
69 */ |
|
70 protected $_isAbstract = false; |
|
71 |
|
72 /** |
|
73 * @var string |
|
74 */ |
|
75 protected $_extendedClass = null; |
|
76 |
|
77 /** |
|
78 * @var array Array of string names |
|
79 */ |
|
80 protected $_implementedInterfaces = array(); |
|
81 |
|
82 /** |
|
83 * @var array Array of properties |
|
84 */ |
|
85 protected $_properties = null; |
|
86 |
|
87 /** |
|
88 * @var array Array of methods |
|
89 */ |
|
90 protected $_methods = null; |
|
91 |
|
92 /** |
|
93 * fromReflection() - build a Code Generation PHP Object from a Class Reflection |
|
94 * |
|
95 * @param Zend_Reflection_Class $reflectionClass |
|
96 * @return Zend_CodeGenerator_Php_Class |
|
97 */ |
|
98 public static function fromReflection(Zend_Reflection_Class $reflectionClass) |
|
99 { |
|
100 $class = new self(); |
|
101 |
|
102 $class->setSourceContent($class->getSourceContent()); |
|
103 $class->setSourceDirty(false); |
|
104 |
|
105 if ($reflectionClass->getDocComment() != '') { |
|
106 $class->setDocblock(Zend_CodeGenerator_Php_Docblock::fromReflection($reflectionClass->getDocblock())); |
|
107 } |
|
108 |
|
109 $class->setAbstract($reflectionClass->isAbstract()); |
|
110 $class->setName($reflectionClass->getName()); |
|
111 |
|
112 if ($parentClass = $reflectionClass->getParentClass()) { |
|
113 $class->setExtendedClass($parentClass->getName()); |
|
114 $interfaces = array_diff($reflectionClass->getInterfaces(), $parentClass->getInterfaces()); |
|
115 } else { |
|
116 $interfaces = $reflectionClass->getInterfaces(); |
|
117 } |
|
118 |
|
119 $interfaceNames = array(); |
|
120 foreach($interfaces AS $interface) { |
|
121 $interfaceNames[] = $interface->getName(); |
|
122 } |
|
123 |
|
124 $class->setImplementedInterfaces($interfaceNames); |
|
125 |
|
126 $properties = array(); |
|
127 foreach ($reflectionClass->getProperties() as $reflectionProperty) { |
|
128 if ($reflectionProperty->getDeclaringClass()->getName() == $class->getName()) { |
|
129 $properties[] = Zend_CodeGenerator_Php_Property::fromReflection($reflectionProperty); |
|
130 } |
|
131 } |
|
132 $class->setProperties($properties); |
|
133 |
|
134 $methods = array(); |
|
135 foreach ($reflectionClass->getMethods() as $reflectionMethod) { |
|
136 if ($reflectionMethod->getDeclaringClass()->getName() == $class->getName()) { |
|
137 $methods[] = Zend_CodeGenerator_Php_Method::fromReflection($reflectionMethod); |
|
138 } |
|
139 } |
|
140 $class->setMethods($methods); |
|
141 |
|
142 return $class; |
|
143 } |
|
144 |
|
145 /** |
|
146 * setDocblock() Set the docblock |
|
147 * |
|
148 * @param Zend_CodeGenerator_Php_Docblock|array|string $docblock |
|
149 * @return Zend_CodeGenerator_Php_File |
|
150 */ |
|
151 public function setDocblock($docblock) |
|
152 { |
|
153 if (is_string($docblock)) { |
|
154 $docblock = array('shortDescription' => $docblock); |
|
155 } |
|
156 |
|
157 if (is_array($docblock)) { |
|
158 $docblock = new Zend_CodeGenerator_Php_Docblock($docblock); |
|
159 } elseif (!$docblock instanceof Zend_CodeGenerator_Php_Docblock) { |
|
160 require_once 'Zend/CodeGenerator/Php/Exception.php'; |
|
161 throw new Zend_CodeGenerator_Php_Exception('setDocblock() is expecting either a string, array or an instance of Zend_CodeGenerator_Php_Docblock'); |
|
162 } |
|
163 |
|
164 $this->_docblock = $docblock; |
|
165 return $this; |
|
166 } |
|
167 |
|
168 /** |
|
169 * getDocblock() |
|
170 * |
|
171 * @return Zend_CodeGenerator_Php_Docblock |
|
172 */ |
|
173 public function getDocblock() |
|
174 { |
|
175 return $this->_docblock; |
|
176 } |
|
177 |
|
178 /** |
|
179 * setName() |
|
180 * |
|
181 * @param string $name |
|
182 * @return Zend_CodeGenerator_Php_Class |
|
183 */ |
|
184 public function setName($name) |
|
185 { |
|
186 $this->_name = $name; |
|
187 return $this; |
|
188 } |
|
189 |
|
190 /** |
|
191 * getName() |
|
192 * |
|
193 * @return string |
|
194 */ |
|
195 public function getName() |
|
196 { |
|
197 return $this->_name; |
|
198 } |
|
199 |
|
200 /** |
|
201 * setAbstract() |
|
202 * |
|
203 * @param bool $isAbstract |
|
204 * @return Zend_CodeGenerator_Php_Class |
|
205 */ |
|
206 public function setAbstract($isAbstract) |
|
207 { |
|
208 $this->_isAbstract = ($isAbstract) ? true : false; |
|
209 return $this; |
|
210 } |
|
211 |
|
212 /** |
|
213 * isAbstract() |
|
214 * |
|
215 * @return bool |
|
216 */ |
|
217 public function isAbstract() |
|
218 { |
|
219 return $this->_isAbstract; |
|
220 } |
|
221 |
|
222 /** |
|
223 * setExtendedClass() |
|
224 * |
|
225 * @param string $extendedClass |
|
226 * @return Zend_CodeGenerator_Php_Class |
|
227 */ |
|
228 public function setExtendedClass($extendedClass) |
|
229 { |
|
230 $this->_extendedClass = $extendedClass; |
|
231 return $this; |
|
232 } |
|
233 |
|
234 /** |
|
235 * getExtendedClass() |
|
236 * |
|
237 * @return string |
|
238 */ |
|
239 public function getExtendedClass() |
|
240 { |
|
241 return $this->_extendedClass; |
|
242 } |
|
243 |
|
244 /** |
|
245 * setImplementedInterfaces() |
|
246 * |
|
247 * @param array $implementedInterfaces |
|
248 * @return Zend_CodeGenerator_Php_Class |
|
249 */ |
|
250 public function setImplementedInterfaces(Array $implementedInterfaces) |
|
251 { |
|
252 $this->_implementedInterfaces = $implementedInterfaces; |
|
253 return $this; |
|
254 } |
|
255 |
|
256 /** |
|
257 * getImplementedInterfaces |
|
258 * |
|
259 * @return array |
|
260 */ |
|
261 public function getImplementedInterfaces() |
|
262 { |
|
263 return $this->_implementedInterfaces; |
|
264 } |
|
265 |
|
266 /** |
|
267 * setProperties() |
|
268 * |
|
269 * @param array $properties |
|
270 * @return Zend_CodeGenerator_Php_Class |
|
271 */ |
|
272 public function setProperties(Array $properties) |
|
273 { |
|
274 foreach ($properties as $property) { |
|
275 $this->setProperty($property); |
|
276 } |
|
277 |
|
278 return $this; |
|
279 } |
|
280 |
|
281 /** |
|
282 * setProperty() |
|
283 * |
|
284 * @param array|Zend_CodeGenerator_Php_Property $property |
|
285 * @return Zend_CodeGenerator_Php_Class |
|
286 */ |
|
287 public function setProperty($property) |
|
288 { |
|
289 if (is_array($property)) { |
|
290 $property = new Zend_CodeGenerator_Php_Property($property); |
|
291 $propertyName = $property->getName(); |
|
292 } elseif ($property instanceof Zend_CodeGenerator_Php_Property) { |
|
293 $propertyName = $property->getName(); |
|
294 } else { |
|
295 require_once 'Zend/CodeGenerator/Php/Exception.php'; |
|
296 throw new Zend_CodeGenerator_Php_Exception('setProperty() expects either an array of property options or an instance of Zend_CodeGenerator_Php_Property'); |
|
297 } |
|
298 |
|
299 if (isset($this->_properties[$propertyName])) { |
|
300 require_once 'Zend/CodeGenerator/Php/Exception.php'; |
|
301 throw new Zend_CodeGenerator_Php_Exception('A property by name ' . $propertyName . ' already exists in this class.'); |
|
302 } |
|
303 |
|
304 $this->_properties[$propertyName] = $property; |
|
305 return $this; |
|
306 } |
|
307 |
|
308 /** |
|
309 * getProperties() |
|
310 * |
|
311 * @return array |
|
312 */ |
|
313 public function getProperties() |
|
314 { |
|
315 return $this->_properties; |
|
316 } |
|
317 |
|
318 /** |
|
319 * getProperty() |
|
320 * |
|
321 * @param string $propertyName |
|
322 * @return Zend_CodeGenerator_Php_Property |
|
323 */ |
|
324 public function getProperty($propertyName) |
|
325 { |
|
326 foreach ($this->_properties as $property) { |
|
327 if ($property->getName() == $propertyName) { |
|
328 return $property; |
|
329 } |
|
330 } |
|
331 return false; |
|
332 } |
|
333 |
|
334 /** |
|
335 * hasProperty() |
|
336 * |
|
337 * @param string $propertyName |
|
338 * @return bool |
|
339 */ |
|
340 public function hasProperty($propertyName) |
|
341 { |
|
342 return isset($this->_properties[$propertyName]); |
|
343 } |
|
344 |
|
345 /** |
|
346 * setMethods() |
|
347 * |
|
348 * @param array $methods |
|
349 * @return Zend_CodeGenerator_Php_Class |
|
350 */ |
|
351 public function setMethods(Array $methods) |
|
352 { |
|
353 foreach ($methods as $method) { |
|
354 $this->setMethod($method); |
|
355 } |
|
356 return $this; |
|
357 } |
|
358 |
|
359 /** |
|
360 * setMethod() |
|
361 * |
|
362 * @param array|Zend_CodeGenerator_Php_Method $method |
|
363 * @return Zend_CodeGenerator_Php_Class |
|
364 */ |
|
365 public function setMethod($method) |
|
366 { |
|
367 if (is_array($method)) { |
|
368 $method = new Zend_CodeGenerator_Php_Method($method); |
|
369 $methodName = $method->getName(); |
|
370 } elseif ($method instanceof Zend_CodeGenerator_Php_Method) { |
|
371 $methodName = $method->getName(); |
|
372 } else { |
|
373 require_once 'Zend/CodeGenerator/Php/Exception.php'; |
|
374 throw new Zend_CodeGenerator_Php_Exception('setMethod() expects either an array of method options or an instance of Zend_CodeGenerator_Php_Method'); |
|
375 } |
|
376 |
|
377 if (isset($this->_methods[$methodName])) { |
|
378 require_once 'Zend/CodeGenerator/Php/Exception.php'; |
|
379 throw new Zend_CodeGenerator_Php_Exception('A method by name ' . $methodName . ' already exists in this class.'); |
|
380 } |
|
381 |
|
382 $this->_methods[$methodName] = $method; |
|
383 return $this; |
|
384 } |
|
385 |
|
386 /** |
|
387 * getMethods() |
|
388 * |
|
389 * @return array |
|
390 */ |
|
391 public function getMethods() |
|
392 { |
|
393 return $this->_methods; |
|
394 } |
|
395 |
|
396 /** |
|
397 * getMethod() |
|
398 * |
|
399 * @param string $methodName |
|
400 * @return Zend_CodeGenerator_Php_Method |
|
401 */ |
|
402 public function getMethod($methodName) |
|
403 { |
|
404 foreach ($this->_methods as $method) { |
|
405 if ($method->getName() == $methodName) { |
|
406 return $method; |
|
407 } |
|
408 } |
|
409 return false; |
|
410 } |
|
411 |
|
412 /** |
|
413 * hasMethod() |
|
414 * |
|
415 * @param string $methodName |
|
416 * @return bool |
|
417 */ |
|
418 public function hasMethod($methodName) |
|
419 { |
|
420 return isset($this->_methods[$methodName]); |
|
421 } |
|
422 |
|
423 /** |
|
424 * isSourceDirty() |
|
425 * |
|
426 * @return bool |
|
427 */ |
|
428 public function isSourceDirty() |
|
429 { |
|
430 if (($docblock = $this->getDocblock()) && $docblock->isSourceDirty()) { |
|
431 return true; |
|
432 } |
|
433 |
|
434 foreach ($this->_properties as $property) { |
|
435 if ($property->isSourceDirty()) { |
|
436 return true; |
|
437 } |
|
438 } |
|
439 |
|
440 foreach ($this->_methods as $method) { |
|
441 if ($method->isSourceDirty()) { |
|
442 return true; |
|
443 } |
|
444 } |
|
445 |
|
446 return parent::isSourceDirty(); |
|
447 } |
|
448 |
|
449 /** |
|
450 * generate() |
|
451 * |
|
452 * @return string |
|
453 */ |
|
454 public function generate() |
|
455 { |
|
456 if (!$this->isSourceDirty()) { |
|
457 return $this->getSourceContent(); |
|
458 } |
|
459 |
|
460 $output = ''; |
|
461 |
|
462 if (null !== ($docblock = $this->getDocblock())) { |
|
463 $docblock->setIndentation(''); |
|
464 $output .= $docblock->generate(); |
|
465 } |
|
466 |
|
467 if ($this->isAbstract()) { |
|
468 $output .= 'abstract '; |
|
469 } |
|
470 |
|
471 $output .= 'class ' . $this->getName(); |
|
472 |
|
473 if ( !empty( $this->_extendedClass) ) { |
|
474 $output .= ' extends ' . $this->_extendedClass; |
|
475 } |
|
476 |
|
477 $implemented = $this->getImplementedInterfaces(); |
|
478 if (!empty($implemented)) { |
|
479 $output .= ' implements ' . implode(', ', $implemented); |
|
480 } |
|
481 |
|
482 $output .= self::LINE_FEED . '{' . self::LINE_FEED . self::LINE_FEED; |
|
483 |
|
484 $properties = $this->getProperties(); |
|
485 if (!empty($properties)) { |
|
486 foreach ($properties as $property) { |
|
487 $output .= $property->generate() . self::LINE_FEED . self::LINE_FEED; |
|
488 } |
|
489 } |
|
490 |
|
491 $methods = $this->getMethods(); |
|
492 if (!empty($methods)) { |
|
493 foreach ($methods as $method) { |
|
494 $output .= $method->generate() . self::LINE_FEED; |
|
495 } |
|
496 } |
|
497 |
|
498 $output .= self::LINE_FEED . '}' . self::LINE_FEED; |
|
499 |
|
500 return $output; |
|
501 } |
|
502 |
|
503 /** |
|
504 * _init() - is called at construction time |
|
505 * |
|
506 */ |
|
507 protected function _init() |
|
508 { |
|
509 $this->_properties = new Zend_CodeGenerator_Php_Member_Container(Zend_CodeGenerator_Php_Member_Container::TYPE_PROPERTY); |
|
510 $this->_methods = new Zend_CodeGenerator_Php_Member_Container(Zend_CodeGenerator_Php_Member_Container::TYPE_METHOD); |
|
511 } |
|
512 |
|
513 } |