File indexing completed on 2025-01-19 05:20:59
0001 <?php 0002 /** 0003 * Zend Framework 0004 * 0005 * LICENSE 0006 * 0007 * This source file is subject to the new BSD license that is bundled 0008 * with this package in the file LICENSE.txt. 0009 * It is also available through the world-wide-web at this URL: 0010 * http://framework.zend.com/license/new-bsd 0011 * If you did not receive a copy of the license and are unable to 0012 * obtain it through the world-wide-web, please send an email 0013 * to license@zend.com so we can send you a copy immediately. 0014 * 0015 * @category Zend 0016 * @package Zend_CodeGenerator 0017 * @subpackage PHP 0018 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0019 * @license http://framework.zend.com/license/new-bsd New BSD License 0020 * @version $Id$ 0021 */ 0022 0023 /** 0024 * @see Zend_CodeGenerator_Php_Abstract 0025 */ 0026 // require_once 'Zend/CodeGenerator/Php/Abstract.php'; 0027 0028 /** 0029 * @see Zend_CodeGenerator_Php_Member_Container 0030 */ 0031 // require_once 'Zend/CodeGenerator/Php/Member/Container.php'; 0032 0033 /** 0034 * @see Zend_CodeGenerator_Php_Method 0035 */ 0036 // require_once 'Zend/CodeGenerator/Php/Method.php'; 0037 0038 /** 0039 * @see Zend_CodeGenerator_Php_Property 0040 */ 0041 // require_once 'Zend/CodeGenerator/Php/Property.php'; 0042 0043 /** 0044 * @see Zend_CodeGenerator_Php_Docblock 0045 */ 0046 // require_once 'Zend/CodeGenerator/Php/Docblock.php'; 0047 0048 /** 0049 * @category Zend 0050 * @package Zend_CodeGenerator 0051 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0052 * @license http://framework.zend.com/license/new-bsd New BSD License 0053 */ 0054 class Zend_CodeGenerator_Php_Class extends Zend_CodeGenerator_Php_Abstract 0055 { 0056 0057 /** 0058 * @var Zend_CodeGenerator_Php_Docblock 0059 */ 0060 protected $_docblock = null; 0061 0062 /** 0063 * @var string 0064 */ 0065 protected $_name = null; 0066 0067 /** 0068 * @var bool 0069 */ 0070 protected $_isAbstract = false; 0071 0072 /** 0073 * @var string 0074 */ 0075 protected $_extendedClass = null; 0076 0077 /** 0078 * @var array Array of string names 0079 */ 0080 protected $_implementedInterfaces = array(); 0081 0082 /** 0083 * @var array Array of properties 0084 */ 0085 protected $_properties = null; 0086 0087 /** 0088 * @var array Array of constants 0089 */ 0090 protected $_constants = null; 0091 0092 /** 0093 * @var array Array of methods 0094 */ 0095 protected $_methods = null; 0096 0097 /** 0098 * fromReflection() - build a Code Generation PHP Object from a Class Reflection 0099 * 0100 * @param Zend_Reflection_Class $reflectionClass 0101 * @return Zend_CodeGenerator_Php_Class 0102 */ 0103 public static function fromReflection(Zend_Reflection_Class $reflectionClass) 0104 { 0105 $class = new self(); 0106 0107 $class->setSourceContent($class->getSourceContent()); 0108 $class->setSourceDirty(false); 0109 0110 if ($reflectionClass->getDocComment() != '') { 0111 $class->setDocblock(Zend_CodeGenerator_Php_Docblock::fromReflection($reflectionClass->getDocblock())); 0112 } 0113 0114 $class->setAbstract($reflectionClass->isAbstract()); 0115 $class->setName($reflectionClass->getName()); 0116 0117 if ($parentClass = $reflectionClass->getParentClass()) { 0118 $class->setExtendedClass($parentClass->getName()); 0119 $interfaces = array_diff($reflectionClass->getInterfaces(), $parentClass->getInterfaces()); 0120 } else { 0121 $interfaces = $reflectionClass->getInterfaces(); 0122 } 0123 0124 $interfaceNames = array(); 0125 foreach($interfaces AS $interface) { 0126 $interfaceNames[] = $interface->getName(); 0127 } 0128 0129 $class->setImplementedInterfaces($interfaceNames); 0130 0131 $properties = array(); 0132 foreach ($reflectionClass->getProperties() as $reflectionProperty) { 0133 if ($reflectionProperty->getDeclaringClass()->getName() == $class->getName()) { 0134 $properties[] = Zend_CodeGenerator_Php_Property::fromReflection($reflectionProperty); 0135 } 0136 } 0137 $class->setProperties($properties); 0138 0139 $methods = array(); 0140 foreach ($reflectionClass->getMethods() as $reflectionMethod) { 0141 if ($reflectionMethod->getDeclaringClass()->getName() == $class->getName()) { 0142 $methods[] = Zend_CodeGenerator_Php_Method::fromReflection($reflectionMethod); 0143 } 0144 } 0145 $class->setMethods($methods); 0146 0147 return $class; 0148 } 0149 0150 /** 0151 * setDocblock() Set the docblock 0152 * 0153 * @param Zend_CodeGenerator_Php_Docblock|array|string $docblock 0154 * @return Zend_CodeGenerator_Php_File 0155 */ 0156 public function setDocblock($docblock) 0157 { 0158 if (is_string($docblock)) { 0159 $docblock = array('shortDescription' => $docblock); 0160 } 0161 0162 if (is_array($docblock)) { 0163 $docblock = new Zend_CodeGenerator_Php_Docblock($docblock); 0164 } elseif ((!is_null($docblock)) && (!$docblock instanceof Zend_CodeGenerator_Php_Docblock)) { 0165 // require_once 'Zend/CodeGenerator/Php/Exception.php'; 0166 throw new Zend_CodeGenerator_Php_Exception('setDocblock() is expecting either a string, array or an instance of Zend_CodeGenerator_Php_Docblock'); 0167 } 0168 0169 $this->_docblock = $docblock; 0170 return $this; 0171 } 0172 0173 /** 0174 * getDocblock() 0175 * 0176 * @return Zend_CodeGenerator_Php_Docblock 0177 */ 0178 public function getDocblock() 0179 { 0180 return $this->_docblock; 0181 } 0182 0183 /** 0184 * setName() 0185 * 0186 * @param string $name 0187 * @return Zend_CodeGenerator_Php_Class 0188 */ 0189 public function setName($name) 0190 { 0191 $this->_name = $name; 0192 return $this; 0193 } 0194 0195 /** 0196 * getName() 0197 * 0198 * @return string 0199 */ 0200 public function getName() 0201 { 0202 return $this->_name; 0203 } 0204 0205 /** 0206 * setAbstract() 0207 * 0208 * @param bool $isAbstract 0209 * @return Zend_CodeGenerator_Php_Class 0210 */ 0211 public function setAbstract($isAbstract) 0212 { 0213 $this->_isAbstract = ($isAbstract) ? true : false; 0214 return $this; 0215 } 0216 0217 /** 0218 * isAbstract() 0219 * 0220 * @return bool 0221 */ 0222 public function isAbstract() 0223 { 0224 return $this->_isAbstract; 0225 } 0226 0227 /** 0228 * setExtendedClass() 0229 * 0230 * @param string $extendedClass 0231 * @return Zend_CodeGenerator_Php_Class 0232 */ 0233 public function setExtendedClass($extendedClass) 0234 { 0235 $this->_extendedClass = $extendedClass; 0236 return $this; 0237 } 0238 0239 /** 0240 * getExtendedClass() 0241 * 0242 * @return string 0243 */ 0244 public function getExtendedClass() 0245 { 0246 return $this->_extendedClass; 0247 } 0248 0249 /** 0250 * setImplementedInterfaces() 0251 * 0252 * @param array $implementedInterfaces 0253 * @return Zend_CodeGenerator_Php_Class 0254 */ 0255 public function setImplementedInterfaces(Array $implementedInterfaces) 0256 { 0257 $this->_implementedInterfaces = $implementedInterfaces; 0258 return $this; 0259 } 0260 0261 /** 0262 * getImplementedInterfaces 0263 * 0264 * @return array 0265 */ 0266 public function getImplementedInterfaces() 0267 { 0268 return $this->_implementedInterfaces; 0269 } 0270 0271 /** 0272 * setProperties() 0273 * 0274 * @param array $properties 0275 * @return Zend_CodeGenerator_Php_Class 0276 */ 0277 public function setProperties(Array $properties) 0278 { 0279 foreach ($properties as $property) { 0280 $this->setProperty($property); 0281 } 0282 0283 return $this; 0284 } 0285 0286 /** 0287 * setConstants() 0288 * 0289 * @param array $constants 0290 * @return Zend_CodeGenerator_Php_Class 0291 */ 0292 public function setConstants(Array $constants) 0293 { 0294 foreach ($constants as $const) { 0295 $this->setConstant($const); 0296 } 0297 0298 return $this; 0299 } 0300 0301 /** 0302 * setProperty() 0303 * 0304 * @param array|Zend_CodeGenerator_Php_Property $property 0305 * @return Zend_CodeGenerator_Php_Class 0306 */ 0307 public function setProperty($property) 0308 { 0309 if (is_array($property)) { 0310 $property = new Zend_CodeGenerator_Php_Property($property); 0311 $propertyName = $property->getName(); 0312 } elseif ($property instanceof Zend_CodeGenerator_Php_Property) { 0313 $propertyName = $property->getName(); 0314 } else { 0315 // require_once 'Zend/CodeGenerator/Php/Exception.php'; 0316 throw new Zend_CodeGenerator_Php_Exception('setProperty() expects either an array of property options or an instance of Zend_CodeGenerator_Php_Property'); 0317 } 0318 0319 if ($property->isConst()) { 0320 return $this->setConstant($property); 0321 } 0322 if (isset($this->_properties[$propertyName])) { 0323 // require_once 'Zend/CodeGenerator/Php/Exception.php'; 0324 throw new Zend_CodeGenerator_Php_Exception('A property by name ' . $propertyName . ' already exists in this class.'); 0325 } 0326 0327 $this->_properties[$propertyName] = $property; 0328 return $this; 0329 } 0330 0331 /** 0332 * setConstant() 0333 * 0334 * @param array|Zend_CodeGenerator_Php_Property $const 0335 * @return Zend_CodeGenerator_Php_Class 0336 */ 0337 public function setConstant($const) 0338 { 0339 if (is_array($const)) { 0340 $const = new Zend_CodeGenerator_Php_Property($const); 0341 $constName = $const->getName(); 0342 } elseif ($const instanceof Zend_CodeGenerator_Php_Property) { 0343 $constName = $const->getName(); 0344 } else { 0345 // require_once 'Zend/CodeGenerator/Php/Exception.php'; 0346 throw new Zend_CodeGenerator_Php_Exception('setConstant() expects either an array of property options or an instance of Zend_CodeGenerator_Php_Property'); 0347 } 0348 0349 if (!$const->isConst()) { 0350 // require_once 'Zend/CodeGenerator/Php/Exception.php'; 0351 throw new Zend_CodeGenerator_Php_Exception('setProperty() expects argument to define a constant'); 0352 } 0353 if (isset($this->_constants[$constName])) { 0354 // require_once 'Zend/CodeGenerator/Php/Exception.php'; 0355 throw new Zend_CodeGenerator_Php_Exception('A constant by name ' . $constName . ' already exists in this class.'); 0356 } 0357 0358 $this->_constants[$constName] = $const; 0359 return $this; 0360 } 0361 0362 /** 0363 * getProperties() 0364 * 0365 * @return array 0366 */ 0367 public function getProperties() 0368 { 0369 return $this->_properties; 0370 } 0371 0372 /** 0373 * getConstants() 0374 * 0375 * @return array 0376 */ 0377 public function getConstants() 0378 { 0379 return $this->_constants; 0380 } 0381 0382 /** 0383 * getProperty() 0384 * 0385 * @param string $propertyName 0386 * @return Zend_CodeGenerator_Php_Property 0387 */ 0388 public function getProperty($propertyName) 0389 { 0390 foreach ($this->_properties as $property) { 0391 if ($property->getName() == $propertyName) { 0392 return $property; 0393 } 0394 } 0395 return false; 0396 } 0397 0398 /** 0399 * getConstant() 0400 * 0401 * @param string $constName 0402 * @return Zend_CodeGenerator_Php_Property 0403 */ 0404 public function getConstant($constName) 0405 { 0406 foreach ($this->_constants as $const) { 0407 if ($const->getName() == $constName) { 0408 return $const; 0409 } 0410 } 0411 return false; 0412 } 0413 0414 /** 0415 * hasProperty() 0416 * 0417 * @param string $propertyName 0418 * @return bool 0419 */ 0420 public function hasProperty($propertyName) 0421 { 0422 return isset($this->_properties[$propertyName]); 0423 } 0424 0425 /** 0426 * hasConstant() 0427 * 0428 * @param string $constName 0429 * @return bool 0430 */ 0431 public function hasConstant($constName) 0432 { 0433 return isset($this->_constants[$constName]); 0434 } 0435 0436 /** 0437 * setMethods() 0438 * 0439 * @param array $methods 0440 * @return Zend_CodeGenerator_Php_Class 0441 */ 0442 public function setMethods(Array $methods) 0443 { 0444 foreach ($methods as $method) { 0445 $this->setMethod($method); 0446 } 0447 return $this; 0448 } 0449 0450 /** 0451 * setMethod() 0452 * 0453 * @param array|Zend_CodeGenerator_Php_Method $method 0454 * @return Zend_CodeGenerator_Php_Class 0455 */ 0456 public function setMethod($method) 0457 { 0458 if (is_array($method)) { 0459 $method = new Zend_CodeGenerator_Php_Method($method); 0460 $methodName = $method->getName(); 0461 } elseif ($method instanceof Zend_CodeGenerator_Php_Method) { 0462 $methodName = $method->getName(); 0463 } else { 0464 // require_once 'Zend/CodeGenerator/Php/Exception.php'; 0465 throw new Zend_CodeGenerator_Php_Exception('setMethod() expects either an array of method options or an instance of Zend_CodeGenerator_Php_Method'); 0466 } 0467 0468 if (isset($this->_methods[$methodName])) { 0469 // require_once 'Zend/CodeGenerator/Php/Exception.php'; 0470 throw new Zend_CodeGenerator_Php_Exception('A method by name ' . $methodName . ' already exists in this class.'); 0471 } 0472 0473 $this->_methods[$methodName] = $method; 0474 return $this; 0475 } 0476 0477 /** 0478 * getMethods() 0479 * 0480 * @return array 0481 */ 0482 public function getMethods() 0483 { 0484 return $this->_methods; 0485 } 0486 0487 /** 0488 * getMethod() 0489 * 0490 * @param string $methodName 0491 * @return Zend_CodeGenerator_Php_Method 0492 */ 0493 public function getMethod($methodName) 0494 { 0495 foreach ($this->_methods as $method) { 0496 if ($method->getName() == $methodName) { 0497 return $method; 0498 } 0499 } 0500 return false; 0501 } 0502 0503 /** 0504 * hasMethod() 0505 * 0506 * @param string $methodName 0507 * @return bool 0508 */ 0509 public function hasMethod($methodName) 0510 { 0511 return isset($this->_methods[$methodName]); 0512 } 0513 0514 /** 0515 * isSourceDirty() 0516 * 0517 * @return bool 0518 */ 0519 public function isSourceDirty() 0520 { 0521 if (($docblock = $this->getDocblock()) && $docblock->isSourceDirty()) { 0522 return true; 0523 } 0524 0525 foreach ($this->_properties as $property) { 0526 if ($property->isSourceDirty()) { 0527 return true; 0528 } 0529 } 0530 0531 foreach ($this->_constants as $constant) { 0532 if ($constant->isSourceDirty()) { 0533 return true; 0534 } 0535 } 0536 0537 foreach ($this->_methods as $method) { 0538 if ($method->isSourceDirty()) { 0539 return true; 0540 } 0541 } 0542 0543 return parent::isSourceDirty(); 0544 } 0545 0546 /** 0547 * generate() 0548 * 0549 * @return string 0550 */ 0551 public function generate() 0552 { 0553 if (!$this->isSourceDirty()) { 0554 return $this->getSourceContent(); 0555 } 0556 0557 $output = ''; 0558 0559 if (null !== ($docblock = $this->getDocblock())) { 0560 $docblock->setIndentation(''); 0561 $output .= $docblock->generate(); 0562 } 0563 0564 if ($this->isAbstract()) { 0565 $output .= 'abstract '; 0566 } 0567 0568 $output .= 'class ' . $this->getName(); 0569 0570 if ( !empty( $this->_extendedClass) ) { 0571 $output .= ' extends ' . $this->_extendedClass; 0572 } 0573 0574 $implemented = $this->getImplementedInterfaces(); 0575 if (!empty($implemented)) { 0576 $output .= ' implements ' . implode(', ', $implemented); 0577 } 0578 0579 $output .= self::LINE_FEED . '{' . self::LINE_FEED . self::LINE_FEED; 0580 0581 $constants = $this->getConstants(); 0582 if (!empty($constants)) { 0583 foreach ($constants as $const) { 0584 $output .= $const->generate() . self::LINE_FEED . self::LINE_FEED; 0585 } 0586 } 0587 0588 $properties = $this->getProperties(); 0589 if (!empty($properties)) { 0590 foreach ($properties as $property) { 0591 $output .= $property->generate() . self::LINE_FEED . self::LINE_FEED; 0592 } 0593 } 0594 0595 $methods = $this->getMethods(); 0596 if (!empty($methods)) { 0597 foreach ($methods as $method) { 0598 $output .= $method->generate() . self::LINE_FEED; 0599 } 0600 } 0601 0602 $output .= self::LINE_FEED . '}' . self::LINE_FEED; 0603 0604 return $output; 0605 } 0606 0607 /** 0608 * _init() - is called at construction time 0609 * 0610 */ 0611 protected function _init() 0612 { 0613 $this->_properties = new Zend_CodeGenerator_Php_Member_Container(Zend_CodeGenerator_Php_Member_Container::TYPE_PROPERTY); 0614 $this->_constants = new Zend_CodeGenerator_Php_Member_Container(Zend_CodeGenerator_Php_Member_Container::TYPE_PROPERTY); 0615 $this->_methods = new Zend_CodeGenerator_Php_Member_Container(Zend_CodeGenerator_Php_Member_Container::TYPE_METHOD); 0616 } 0617 0618 }