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\DocBlock; 14 15use phpDocumentor\Reflection\DocBlock\Tags\Formatter; 16use phpDocumentor\Reflection\DocBlock\Tags\Formatter\PassthroughFormatter; 17use Webmozart\Assert\Assert; 18 19/** 20 * Object representing to description for a DocBlock. 21 * 22 * A Description object can consist of plain text but can also include tags. A Description Formatter can then combine 23 * a body template with sprintf-style placeholders together with formatted tags in order to reconstitute a complete 24 * description text using the format that you would prefer. 25 * 26 * Because parsing a Description text can be a verbose process this is handled by the {@see DescriptionFactory}. It is 27 * thus recommended to use that to create a Description object, like this: 28 * 29 * $description = $descriptionFactory->create('This is a {@see Description}', $context); 30 * 31 * The description factory will interpret the given body and create a body template and list of tags from them, and pass 32 * that onto the constructor if this class. 33 * 34 * > The $context variable is a class of type {@see \phpDocumentor\Reflection\Types\Context} and contains the namespace 35 * > and the namespace aliases that apply to this DocBlock. These are used by the Factory to resolve and expand partial 36 * > type names and FQSENs. 37 * 38 * If you do not want to use the DescriptionFactory you can pass a body template and tag listing like this: 39 * 40 * $description = new Description( 41 * 'This is a %1$s', 42 * [ new See(new Fqsen('\phpDocumentor\Reflection\DocBlock\Description')) ] 43 * ); 44 * 45 * It is generally recommended to use the Factory as that will also apply escaping rules, while the Description object 46 * is mainly responsible for rendering. 47 * 48 * @see DescriptionFactory to create a new Description. 49 * @see Description\Formatter for the formatting of the body and tags. 50 */ 51class Description 52{ 53 /** @var string */ 54 private $bodyTemplate; 55 56 /** @var Tag[] */ 57 private $tags; 58 59 /** 60 * Initializes a Description with its body (template) and a listing of the tags used in the body template. 61 * 62 * @param string $bodyTemplate 63 * @param Tag[] $tags 64 */ 65 public function __construct($bodyTemplate, array $tags = []) 66 { 67 Assert::string($bodyTemplate); 68 69 $this->bodyTemplate = $bodyTemplate; 70 $this->tags = $tags; 71 } 72 73 /** 74 * Returns the tags for this DocBlock. 75 * 76 * @return Tag[] 77 */ 78 public function getTags() 79 { 80 return $this->tags; 81 } 82 83 /** 84 * Renders this description as a string where the provided formatter will format the tags in the expected string 85 * format. 86 * 87 * @param Formatter|null $formatter 88 * 89 * @return string 90 */ 91 public function render(Formatter $formatter = null) 92 { 93 if ($formatter === null) { 94 $formatter = new PassthroughFormatter(); 95 } 96 97 $tags = []; 98 foreach ($this->tags as $tag) { 99 $tags[] = '{' . $formatter->format($tag) . '}'; 100 } 101 102 return vsprintf($this->bodyTemplate, $tags); 103 } 104 105 /** 106 * Returns a plain string representation of this description. 107 * 108 * @return string 109 */ 110 public function __toString() 111 { 112 return $this->render(); 113 } 114} 115