File indexing completed on 2024-05-12 06:02: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_Reflection
0017  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0018  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0019  * @version    $Id$
0020  */
0021 
0022 /**
0023  * @see Zend_Reflection_Docblock_Tag
0024  */
0025 // require_once 'Zend/Reflection/Docblock/Tag.php';
0026 
0027 /**
0028  * @category   Zend
0029  * @package    Zend_Reflection
0030  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0031  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0032  */
0033 class Zend_Reflection_Docblock implements Reflector
0034 {
0035     /**
0036      * @var Reflector
0037      */
0038     protected $_reflector = null;
0039 
0040     /**#@+
0041      * @var int
0042      */
0043     protected $_startLine = null;
0044     protected $_endLine   = null;
0045     /**#@-*/
0046 
0047     /**
0048      * @var string
0049      */
0050     protected $_docComment = null;
0051 
0052     /**
0053      * @var string
0054      */
0055     protected $_cleanDocComment = null;
0056 
0057     /**
0058      * @var string
0059      */
0060     protected $_longDescription = null;
0061 
0062     /**
0063      * @var string
0064      */
0065     protected $_shortDescription = null;
0066 
0067     /**
0068      * @var array
0069      */
0070     protected $_tags = array();
0071 
0072     /**
0073      * Export reflection
0074      *
0075      * Reqired by the Reflector interface.
0076      *
0077      * @todo   What should this do?
0078      * @return void
0079      */
0080     public static function export()
0081     {
0082 
0083     }
0084 
0085     /**
0086      * Serialize to string
0087      *
0088      * Required by the Reflector interface
0089      *
0090      * @todo   What should this return?
0091      * @return string
0092      */
0093     public function __toString()
0094     {
0095         $str = "Docblock [ /* Docblock */ ] {".PHP_EOL.PHP_EOL;
0096         $str .= "  - Tags [".count($this->_tags)."] {".PHP_EOL;
0097 
0098         foreach($this->_tags AS $tag) {
0099             $str .= "    ".$tag;
0100         }
0101 
0102         $str .= "  }".PHP_EOL;
0103         $str .= "}".PHP_EOL;
0104 
0105         return $str;
0106     }
0107 
0108     /**
0109      * Constructor
0110      *
0111      * @param Reflector|string $commentOrReflector
0112      */
0113     public function __construct($commentOrReflector)
0114     {
0115         if ($commentOrReflector instanceof Reflector) {
0116             $this->_reflector = $commentOrReflector;
0117             if (!method_exists($commentOrReflector, 'getDocComment')) {
0118                 // require_once 'Zend/Reflection/Exception.php';
0119                 throw new Zend_Reflection_Exception('Reflector must contain method "getDocComment"');
0120             }
0121             $docComment = $commentOrReflector->getDocComment();
0122 
0123             $lineCount = substr_count($docComment, "\n");
0124 
0125             $this->_startLine = $this->_reflector->getStartLine() - $lineCount - 1;
0126             $this->_endLine   = $this->_reflector->getStartLine() - 1;
0127 
0128         } elseif (is_string($commentOrReflector)) {
0129             $docComment = $commentOrReflector;
0130         } else {
0131             // require_once 'Zend/Reflection/Exception.php';
0132             throw new Zend_Reflection_Exception(get_class($this) . ' must have a (string) DocComment or a Reflector in the constructor');
0133         }
0134 
0135         if ($docComment == '') {
0136             // require_once 'Zend/Reflection/Exception.php';
0137             throw new Zend_Reflection_Exception('DocComment cannot be empty');
0138         }
0139 
0140         $this->_docComment = $docComment;
0141         $this->_parse();
0142     }
0143 
0144     /**
0145      * Retrieve contents of docblock
0146      *
0147      * @return string
0148      */
0149     public function getContents()
0150     {
0151         return $this->_cleanDocComment;
0152     }
0153 
0154     /**
0155      * Get start line (position) of docblock
0156      *
0157      * @return int
0158      */
0159     public function getStartLine()
0160     {
0161         return $this->_startLine;
0162     }
0163 
0164     /**
0165      * Get last line (position) of docblock
0166      *
0167      * @return int
0168      */
0169     public function getEndLine()
0170     {
0171         return $this->_endLine;
0172     }
0173 
0174     /**
0175      * Get docblock short description
0176      *
0177      * @return string
0178      */
0179     public function getShortDescription()
0180     {
0181         return $this->_shortDescription;
0182     }
0183 
0184     /**
0185      * Get docblock long description
0186      *
0187      * @return string
0188      */
0189     public function getLongDescription()
0190     {
0191         return $this->_longDescription;
0192     }
0193 
0194     /**
0195      * Does the docblock contain the given annotation tag?
0196      *
0197      * @param  string $name
0198      * @return bool
0199      */
0200     public function hasTag($name)
0201     {
0202         foreach ($this->_tags as $tag) {
0203             if ($tag->getName() == $name) {
0204                 return true;
0205             }
0206         }
0207         return false;
0208     }
0209 
0210     /**
0211      * Retrieve the given docblock tag
0212      *
0213      * @param  string $name
0214      * @return Zend_Reflection_Docblock_Tag|false
0215      */
0216     public function getTag($name)
0217     {
0218         foreach ($this->_tags as $tag) {
0219             if ($tag->getName() == $name) {
0220                 return $tag;
0221             }
0222         }
0223 
0224         return false;
0225     }
0226 
0227     /**
0228      * Get all docblock annotation tags
0229      *
0230      * @param string $filter
0231      * @return array Array of Zend_Reflection_Docblock_Tag
0232      */
0233     public function getTags($filter = null)
0234     {
0235         if ($filter === null || !is_string($filter)) {
0236             return $this->_tags;
0237         }
0238 
0239         $returnTags = array();
0240         foreach ($this->_tags as $tag) {
0241             if ($tag->getName() == $filter) {
0242                 $returnTags[] = $tag;
0243             }
0244         }
0245         return $returnTags;
0246     }
0247 
0248     /**
0249      * Parse the docblock
0250      *
0251      * @return void
0252      */
0253     protected function _parse()
0254     {
0255         $docComment = $this->_docComment;
0256 
0257         // First remove doc block line starters
0258         $docComment = preg_replace('#[ \t]*(?:\/\*\*|\*\/|\*)?[ ]{0,1}(.*)?#', '$1', $docComment);
0259         $docComment = ltrim($docComment, "\r\n"); // @todo should be changed to remove first and last empty line
0260 
0261         $this->_cleanDocComment = $docComment;
0262 
0263         // Next parse out the tags and descriptions
0264         $parsedDocComment = $docComment;
0265         $lineNumber = $firstBlandLineEncountered = 0;
0266         while (($newlinePos = strpos($parsedDocComment, "\n")) !== false) {
0267             $lineNumber++;
0268             $line = substr($parsedDocComment, 0, $newlinePos);
0269 
0270             $matches = array();
0271 
0272             if ((strpos($line, '@') === 0) && (preg_match('#^(@\w+.*?)(\n)(?:@|\r?\n|$)#s', $parsedDocComment, $matches))) {
0273                 $this->_tags[] = Zend_Reflection_Docblock_Tag::factory($matches[1]);
0274                 $parsedDocComment = str_replace($matches[1] . $matches[2], '', $parsedDocComment);
0275             } else {
0276                 if ($lineNumber < 3 && !$firstBlandLineEncountered) {
0277                     $this->_shortDescription .= $line . "\n";
0278                 } else {
0279                     $this->_longDescription .= $line . "\n";
0280                 }
0281 
0282                 if ($line == '') {
0283                     $firstBlandLineEncountered = true;
0284                 }
0285 
0286                 $parsedDocComment = substr($parsedDocComment, $newlinePos + 1);
0287             }
0288 
0289         }
0290 
0291         $this->_shortDescription = rtrim($this->_shortDescription);
0292         $this->_longDescription  = rtrim($this->_longDescription);
0293     }
0294 }