File indexing completed on 2025-03-02 05:29:42
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 }