web/lib/Zend/Reflection/Docblock.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_Reflection
       
    17  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
       
    18  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    19  * @version    $Id: Docblock.php 20096 2010-01-06 02:05:09Z bkarwin $
       
    20  */
       
    21 
       
    22 /**
       
    23  * @see Zend_Reflection_Docblock_Tag
       
    24  */
       
    25 require_once 'Zend/Reflection/Docblock/Tag.php';
       
    26 
       
    27 /**
       
    28  * @category   Zend
       
    29  * @package    Zend_Reflection
       
    30  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
       
    31  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    32  */
       
    33 class Zend_Reflection_Docblock implements Reflector
       
    34 {
       
    35     /**
       
    36      * @var Reflector
       
    37      */
       
    38     protected $_reflector = null;
       
    39 
       
    40     /**#@+
       
    41      * @var int
       
    42      */
       
    43     protected $_startLine = null;
       
    44     protected $_endLine   = null;
       
    45     /**#@-*/
       
    46 
       
    47     /**
       
    48      * @var string
       
    49      */
       
    50     protected $_docComment = null;
       
    51 
       
    52     /**
       
    53      * @var string
       
    54      */
       
    55     protected $_cleanDocComment = null;
       
    56 
       
    57     /**
       
    58      * @var string
       
    59      */
       
    60     protected $_longDescription = null;
       
    61 
       
    62     /**
       
    63      * @var string
       
    64      */
       
    65     protected $_shortDescription = null;
       
    66 
       
    67     /**
       
    68      * @var array
       
    69      */
       
    70     protected $_tags = array();
       
    71 
       
    72     /**
       
    73      * Export reflection
       
    74      *
       
    75      * Reqired by the Reflector interface.
       
    76      *
       
    77      * @todo   What should this do?
       
    78      * @return void
       
    79      */
       
    80     public static function export()
       
    81     {
       
    82 
       
    83     }
       
    84 
       
    85     /**
       
    86      * Serialize to string
       
    87      *
       
    88      * Required by the Reflector interface
       
    89      *
       
    90      * @todo   What should this return?
       
    91      * @return string
       
    92      */
       
    93     public function __toString()
       
    94     {
       
    95         $str = "Docblock [ /* Docblock */ ] {".PHP_EOL.PHP_EOL;
       
    96         $str .= "  - Tags [".count($this->_tags)."] {".PHP_EOL;
       
    97 
       
    98         foreach($this->_tags AS $tag) {
       
    99             $str .= "    ".$tag;
       
   100         }
       
   101 
       
   102         $str .= "  }".PHP_EOL;
       
   103         $str .= "}".PHP_EOL;
       
   104 
       
   105         return $str;
       
   106     }
       
   107 
       
   108     /**
       
   109      * Constructor
       
   110      *
       
   111      * @param Reflector|string $commentOrReflector
       
   112      */
       
   113     public function __construct($commentOrReflector)
       
   114     {
       
   115         if ($commentOrReflector instanceof Reflector) {
       
   116             $this->_reflector = $commentOrReflector;
       
   117             if (!method_exists($commentOrReflector, 'getDocComment')) {
       
   118                 require_once 'Zend/Reflection/Exception.php';
       
   119                 throw new Zend_Reflection_Exception('Reflector must contain method "getDocComment"');
       
   120             }
       
   121             $docComment = $commentOrReflector->getDocComment();
       
   122 
       
   123             $lineCount = substr_count($docComment, "\n");
       
   124 
       
   125             $this->_startLine = $this->_reflector->getStartLine() - $lineCount - 1;
       
   126             $this->_endLine   = $this->_reflector->getStartLine() - 1;
       
   127 
       
   128         } elseif (is_string($commentOrReflector)) {
       
   129             $docComment = $commentOrReflector;
       
   130         } else {
       
   131             require_once 'Zend/Reflection/Exception.php';
       
   132             throw new Zend_Reflection_Exception(get_class($this) . ' must have a (string) DocComment or a Reflector in the constructor');
       
   133         }
       
   134 
       
   135         if ($docComment == '') {
       
   136             require_once 'Zend/Reflection/Exception.php';
       
   137             throw new Zend_Reflection_Exception('DocComment cannot be empty');
       
   138         }
       
   139 
       
   140         $this->_docComment = $docComment;
       
   141         $this->_parse();
       
   142     }
       
   143 
       
   144     /**
       
   145      * Retrieve contents of docblock
       
   146      *
       
   147      * @return string
       
   148      */
       
   149     public function getContents()
       
   150     {
       
   151         return $this->_cleanDocComment;
       
   152     }
       
   153 
       
   154     /**
       
   155      * Get start line (position) of docblock
       
   156      *
       
   157      * @return int
       
   158      */
       
   159     public function getStartLine()
       
   160     {
       
   161         return $this->_startLine;
       
   162     }
       
   163 
       
   164     /**
       
   165      * Get last line (position) of docblock
       
   166      *
       
   167      * @return int
       
   168      */
       
   169     public function getEndLine()
       
   170     {
       
   171         return $this->_endLine;
       
   172     }
       
   173 
       
   174     /**
       
   175      * Get docblock short description
       
   176      *
       
   177      * @return string
       
   178      */
       
   179     public function getShortDescription()
       
   180     {
       
   181         return $this->_shortDescription;
       
   182     }
       
   183 
       
   184     /**
       
   185      * Get docblock long description
       
   186      *
       
   187      * @return string
       
   188      */
       
   189     public function getLongDescription()
       
   190     {
       
   191         return $this->_longDescription;
       
   192     }
       
   193 
       
   194     /**
       
   195      * Does the docblock contain the given annotation tag?
       
   196      *
       
   197      * @param  string $name
       
   198      * @return bool
       
   199      */
       
   200     public function hasTag($name)
       
   201     {
       
   202         foreach ($this->_tags as $tag) {
       
   203             if ($tag->getName() == $name) {
       
   204                 return true;
       
   205             }
       
   206         }
       
   207         return false;
       
   208     }
       
   209 
       
   210     /**
       
   211      * Retrieve the given docblock tag
       
   212      *
       
   213      * @param  string $name
       
   214      * @return Zend_Reflection_Docblock_Tag|false
       
   215      */
       
   216     public function getTag($name)
       
   217     {
       
   218         foreach ($this->_tags as $tag) {
       
   219             if ($tag->getName() == $name) {
       
   220                 return $tag;
       
   221             }
       
   222         }
       
   223 
       
   224         return false;
       
   225     }
       
   226 
       
   227     /**
       
   228      * Get all docblock annotation tags
       
   229      *
       
   230      * @param string $filter
       
   231      * @return array Array of Zend_Reflection_Docblock_Tag
       
   232      */
       
   233     public function getTags($filter = null)
       
   234     {
       
   235         if ($filter === null || !is_string($filter)) {
       
   236             return $this->_tags;
       
   237         }
       
   238 
       
   239         $returnTags = array();
       
   240         foreach ($this->_tags as $tag) {
       
   241             if ($tag->getName() == $filter) {
       
   242                 $returnTags[] = $tag;
       
   243             }
       
   244         }
       
   245         return $returnTags;
       
   246     }
       
   247 
       
   248     /**
       
   249      * Parse the docblock
       
   250      *
       
   251      * @return void
       
   252      */
       
   253     protected function _parse()
       
   254     {
       
   255         $docComment = $this->_docComment;
       
   256 
       
   257         // First remove doc block line starters
       
   258         $docComment = preg_replace('#[ \t]*(?:\/\*\*|\*\/|\*)?[ ]{0,1}(.*)?#', '$1', $docComment);
       
   259         $docComment = ltrim($docComment, "\r\n"); // @todo should be changed to remove first and last empty line
       
   260 
       
   261         $this->_cleanDocComment = $docComment;
       
   262 
       
   263         // Next parse out the tags and descriptions
       
   264         $parsedDocComment = $docComment;
       
   265         $lineNumber = $firstBlandLineEncountered = 0;
       
   266         while (($newlinePos = strpos($parsedDocComment, "\n")) !== false) {
       
   267             $lineNumber++;
       
   268             $line = substr($parsedDocComment, 0, $newlinePos);
       
   269 
       
   270             $matches = array();
       
   271 
       
   272             if ((strpos($line, '@') === 0) && (preg_match('#^(@\w+.*?)(\n)(?:@|\r?\n|$)#s', $parsedDocComment, $matches))) {
       
   273                 $this->_tags[] = Zend_Reflection_Docblock_Tag::factory($matches[1]);
       
   274                 $parsedDocComment = str_replace($matches[1] . $matches[2], '', $parsedDocComment);
       
   275             } else {
       
   276                 if ($lineNumber < 3 && !$firstBlandLineEncountered) {
       
   277                     $this->_shortDescription .= $line . "\n";
       
   278                 } else {
       
   279                     $this->_longDescription .= $line . "\n";
       
   280                 }
       
   281 
       
   282                 if ($line == '') {
       
   283                     $firstBlandLineEncountered = true;
       
   284                 }
       
   285 
       
   286                 $parsedDocComment = substr($parsedDocComment, $newlinePos + 1);
       
   287             }
       
   288 
       
   289         }
       
   290 
       
   291         $this->_shortDescription = rtrim($this->_shortDescription);
       
   292         $this->_longDescription  = rtrim($this->_longDescription);
       
   293     }
       
   294 }