1<?php 2/** 3 * This file is part of phpDocumentor. 4 * 5 * For the full copyright and license information, please view the LICENSE 6 * file that was distributed with this source code. 7 * 8 * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org> 9 * @license http://www.opensource.org/licenses/mit-license.php MIT 10 * @link http://phpdoc.org 11 */ 12 13namespace phpDocumentor\Reflection; 14 15use phpDocumentor\Reflection\DocBlock\Tag; 16use Webmozart\Assert\Assert; 17 18final class DocBlock 19{ 20 /** @var string The opening line for this docblock. */ 21 private $summary = ''; 22 23 /** @var DocBlock\Description The actual description for this docblock. */ 24 private $description = null; 25 26 /** @var Tag[] An array containing all the tags in this docblock; except inline. */ 27 private $tags = []; 28 29 /** @var Types\Context Information about the context of this DocBlock. */ 30 private $context = null; 31 32 /** @var Location Information about the location of this DocBlock. */ 33 private $location = null; 34 35 /** @var bool Is this DocBlock (the start of) a template? */ 36 private $isTemplateStart = false; 37 38 /** @var bool Does this DocBlock signify the end of a DocBlock template? */ 39 private $isTemplateEnd = false; 40 41 /** 42 * @param string $summary 43 * @param DocBlock\Description $description 44 * @param DocBlock\Tag[] $tags 45 * @param Types\Context $context The context in which the DocBlock occurs. 46 * @param Location $location The location within the file that this DocBlock occurs in. 47 * @param bool $isTemplateStart 48 * @param bool $isTemplateEnd 49 */ 50 public function __construct( 51 $summary = '', 52 DocBlock\Description $description = null, 53 array $tags = [], 54 Types\Context $context = null, 55 Location $location = null, 56 $isTemplateStart = false, 57 $isTemplateEnd = false 58 ) { 59 Assert::string($summary); 60 Assert::boolean($isTemplateStart); 61 Assert::boolean($isTemplateEnd); 62 Assert::allIsInstanceOf($tags, Tag::class); 63 64 $this->summary = $summary; 65 $this->description = $description ?: new DocBlock\Description(''); 66 foreach ($tags as $tag) { 67 $this->addTag($tag); 68 } 69 70 $this->context = $context; 71 $this->location = $location; 72 73 $this->isTemplateEnd = $isTemplateEnd; 74 $this->isTemplateStart = $isTemplateStart; 75 } 76 77 /** 78 * @return string 79 */ 80 public function getSummary() 81 { 82 return $this->summary; 83 } 84 85 /** 86 * @return DocBlock\Description 87 */ 88 public function getDescription() 89 { 90 return $this->description; 91 } 92 93 /** 94 * Returns the current context. 95 * 96 * @return Types\Context 97 */ 98 public function getContext() 99 { 100 return $this->context; 101 } 102 103 /** 104 * Returns the current location. 105 * 106 * @return Location 107 */ 108 public function getLocation() 109 { 110 return $this->location; 111 } 112 113 /** 114 * Returns whether this DocBlock is the start of a Template section. 115 * 116 * A Docblock may serve as template for a series of subsequent DocBlocks. This is indicated by a special marker 117 * (`#@+`) that is appended directly after the opening `/**` of a DocBlock. 118 * 119 * An example of such an opening is: 120 * 121 * ``` 122 * /**#@+ 123 * * My DocBlock 124 * * / 125 * ``` 126 * 127 * The description and tags (not the summary!) are copied onto all subsequent DocBlocks and also applied to all 128 * elements that follow until another DocBlock is found that contains the closing marker (`#@-`). 129 * 130 * @see self::isTemplateEnd() for the check whether a closing marker was provided. 131 * 132 * @return boolean 133 */ 134 public function isTemplateStart() 135 { 136 return $this->isTemplateStart; 137 } 138 139 /** 140 * Returns whether this DocBlock is the end of a Template section. 141 * 142 * @see self::isTemplateStart() for a more complete description of the Docblock Template functionality. 143 * 144 * @return boolean 145 */ 146 public function isTemplateEnd() 147 { 148 return $this->isTemplateEnd; 149 } 150 151 /** 152 * Returns the tags for this DocBlock. 153 * 154 * @return Tag[] 155 */ 156 public function getTags() 157 { 158 return $this->tags; 159 } 160 161 /** 162 * Returns an array of tags matching the given name. If no tags are found 163 * an empty array is returned. 164 * 165 * @param string $name String to search by. 166 * 167 * @return Tag[] 168 */ 169 public function getTagsByName($name) 170 { 171 Assert::string($name); 172 173 $result = []; 174 175 /** @var Tag $tag */ 176 foreach ($this->getTags() as $tag) { 177 if ($tag->getName() !== $name) { 178 continue; 179 } 180 181 $result[] = $tag; 182 } 183 184 return $result; 185 } 186 187 /** 188 * Checks if a tag of a certain type is present in this DocBlock. 189 * 190 * @param string $name Tag name to check for. 191 * 192 * @return bool 193 */ 194 public function hasTag($name) 195 { 196 Assert::string($name); 197 198 /** @var Tag $tag */ 199 foreach ($this->getTags() as $tag) { 200 if ($tag->getName() === $name) { 201 return true; 202 } 203 } 204 205 return false; 206 } 207 208 /** 209 * Remove a tag from this DocBlock. 210 * 211 * @param Tag $tag The tag to remove. 212 * 213 * @return void 214 */ 215 public function removeTag(Tag $tagToRemove) 216 { 217 foreach ($this->tags as $key => $tag) { 218 if ($tag === $tagToRemove) { 219 unset($this->tags[$key]); 220 break; 221 } 222 } 223 } 224 225 /** 226 * Adds a tag to this DocBlock. 227 * 228 * @param Tag $tag The tag to add. 229 * 230 * @return void 231 */ 232 private function addTag(Tag $tag) 233 { 234 $this->tags[] = $tag; 235 } 236} 237