1<?php 2 3declare(strict_types=1); 4 5/** 6 * This file is part of phpDocumentor. 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 * 11 * @link http://phpdoc.org 12 */ 13 14namespace phpDocumentor\Reflection\DocBlock\Tags; 15 16use phpDocumentor\Reflection\DocBlock\Description; 17use phpDocumentor\Reflection\DocBlock\DescriptionFactory; 18use phpDocumentor\Reflection\Types\Context as TypeContext; 19use Webmozart\Assert\Assert; 20use function preg_match; 21 22/** 23 * Reflection class for a {@}version tag in a Docblock. 24 */ 25final class Version extends BaseTag implements Factory\StaticMethod 26{ 27 /** @var string */ 28 protected $name = 'version'; 29 30 /** 31 * PCRE regular expression matching a version vector. 32 * Assumes the "x" modifier. 33 */ 34 public const REGEX_VECTOR = '(?: 35 # Normal release vectors. 36 \d\S* 37 | 38 # VCS version vectors. Per PHPCS, they are expected to 39 # follow the form of the VCS name, followed by ":", followed 40 # by the version vector itself. 41 # By convention, popular VCSes like CVS, SVN and GIT use "$" 42 # around the actual version vector. 43 [^\s\:]+\:\s*\$[^\$]+\$ 44 )'; 45 46 /** @var string|null The version vector. */ 47 private $version; 48 49 public function __construct(?string $version = null, ?Description $description = null) 50 { 51 Assert::nullOrStringNotEmpty($version); 52 53 $this->version = $version; 54 $this->description = $description; 55 } 56 57 public static function create( 58 ?string $body, 59 ?DescriptionFactory $descriptionFactory = null, 60 ?TypeContext $context = null 61 ) : ?self { 62 if (empty($body)) { 63 return new static(); 64 } 65 66 $matches = []; 67 if (!preg_match('/^(' . self::REGEX_VECTOR . ')\s*(.+)?$/sux', $body, $matches)) { 68 return null; 69 } 70 71 $description = null; 72 if ($descriptionFactory !== null) { 73 $description = $descriptionFactory->create($matches[2] ?? '', $context); 74 } 75 76 return new static( 77 $matches[1], 78 $description 79 ); 80 } 81 82 /** 83 * Gets the version section of the tag. 84 */ 85 public function getVersion() : ?string 86 { 87 return $this->version; 88 } 89 90 /** 91 * Returns a string representation for this tag. 92 */ 93 public function __toString() : string 94 { 95 if ($this->description) { 96 $description = $this->description->render(); 97 } else { 98 $description = ''; 99 } 100 101 $version = (string) $this->version; 102 103 return $version . ($description !== '' ? ($version !== '' ? ' ' : '') . $description : ''); 104 } 105} 106