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\Tags; 14 15use phpDocumentor\Reflection\DocBlock\Description; 16use phpDocumentor\Reflection\DocBlock\Tag; 17use Webmozart\Assert\Assert; 18 19/** 20 * Reflection class for a {@}example tag in a Docblock. 21 */ 22final class Example extends BaseTag 23{ 24 /** 25 * @var string Path to a file to use as an example. May also be an absolute URI. 26 */ 27 private $filePath; 28 29 /** 30 * @var bool Whether the file path component represents an URI. This determines how the file portion 31 * appears at {@link getContent()}. 32 */ 33 private $isURI = false; 34 35 /** 36 * @var int 37 */ 38 private $startingLine; 39 40 /** 41 * @var int 42 */ 43 private $lineCount; 44 45 public function __construct($filePath, $isURI, $startingLine, $lineCount, $description) 46 { 47 Assert::notEmpty($filePath); 48 Assert::integer($startingLine); 49 Assert::greaterThanEq($startingLine, 0); 50 51 $this->filePath = $filePath; 52 $this->startingLine = $startingLine; 53 $this->lineCount = $lineCount; 54 $this->name = 'example'; 55 if ($description !== null) { 56 $this->description = trim($description); 57 } 58 59 $this->isURI = $isURI; 60 } 61 62 /** 63 * {@inheritdoc} 64 */ 65 public function getContent() 66 { 67 if (null === $this->description) { 68 $filePath = '"' . $this->filePath . '"'; 69 if ($this->isURI) { 70 $filePath = $this->isUriRelative($this->filePath) 71 ? str_replace('%2F', '/', rawurlencode($this->filePath)) 72 :$this->filePath; 73 } 74 75 return trim($filePath . ' ' . parent::getDescription()); 76 } 77 78 return $this->description; 79 } 80 81 /** 82 * {@inheritdoc} 83 */ 84 public static function create($body) 85 { 86 // File component: File path in quotes or File URI / Source information 87 if (! preg_match('/^(?:\"([^\"]+)\"|(\S+))(?:\s+(.*))?$/sux', $body, $matches)) { 88 return null; 89 } 90 91 $filePath = null; 92 $fileUri = null; 93 if ('' !== $matches[1]) { 94 $filePath = $matches[1]; 95 } else { 96 $fileUri = $matches[2]; 97 } 98 99 $startingLine = 1; 100 $lineCount = null; 101 $description = null; 102 103 if (array_key_exists(3, $matches)) { 104 $description = $matches[3]; 105 106 // Starting line / Number of lines / Description 107 if (preg_match('/^([1-9]\d*)(?:\s+((?1))\s*)?(.*)$/sux', $matches[3], $contentMatches)) { 108 $startingLine = (int)$contentMatches[1]; 109 if (isset($contentMatches[2]) && $contentMatches[2] !== '') { 110 $lineCount = (int)$contentMatches[2]; 111 } 112 113 if (array_key_exists(3, $contentMatches)) { 114 $description = $contentMatches[3]; 115 } 116 } 117 } 118 119 return new static( 120 $filePath !== null?$filePath:$fileUri, 121 $fileUri !== null, 122 $startingLine, 123 $lineCount, 124 $description 125 ); 126 } 127 128 /** 129 * Returns the file path. 130 * 131 * @return string Path to a file to use as an example. 132 * May also be an absolute URI. 133 */ 134 public function getFilePath() 135 { 136 return $this->filePath; 137 } 138 139 /** 140 * Returns a string representation for this tag. 141 * 142 * @return string 143 */ 144 public function __toString() 145 { 146 return $this->filePath . ($this->description ? ' ' . $this->description : ''); 147 } 148 149 /** 150 * Returns true if the provided URI is relative or contains a complete scheme (and thus is absolute). 151 * 152 * @param string $uri 153 * 154 * @return bool 155 */ 156 private function isUriRelative($uri) 157 { 158 return false === strpos($uri, ':'); 159 } 160 161 /** 162 * @return int 163 */ 164 public function getStartingLine() 165 { 166 return $this->startingLine; 167 } 168 169 /** 170 * @return int 171 */ 172 public function getLineCount() 173 { 174 return $this->lineCount; 175 } 176} 177