web/lib/Zend/CodeGenerator/Php/Class.php
changeset 64 162c1de6545a
parent 19 1c2f13fd785c
child 68 ecaf28ffe26e
equal deleted inserted replaced
63:5b37998e522e 64:162c1de6545a
       
     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 }