File indexing completed on 2024-06-16 05:29:55

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 }