Chris@12
|
1 <?php
|
Chris@12
|
2 /**
|
Chris@12
|
3 * This file is part of phpDocumentor.
|
Chris@12
|
4 *
|
Chris@12
|
5 * For the full copyright and license information, please view the LICENSE
|
Chris@12
|
6 * file that was distributed with this source code.
|
Chris@12
|
7 *
|
Chris@12
|
8 * @copyright 2010-2015 Mike van Riel<mike@phpdoc.org>
|
Chris@12
|
9 * @license http://www.opensource.org/licenses/mit-license.php MIT
|
Chris@12
|
10 * @link http://phpdoc.org
|
Chris@12
|
11 */
|
Chris@12
|
12
|
Chris@12
|
13 namespace phpDocumentor\Reflection\DocBlock;
|
Chris@12
|
14
|
Chris@12
|
15 use phpDocumentor\Reflection\DocBlock\Tags\Example;
|
Chris@12
|
16
|
Chris@12
|
17 /**
|
Chris@12
|
18 * Class used to find an example file's location based on a given ExampleDescriptor.
|
Chris@12
|
19 */
|
Chris@12
|
20 class ExampleFinder
|
Chris@12
|
21 {
|
Chris@12
|
22 /** @var string */
|
Chris@12
|
23 private $sourceDirectory = '';
|
Chris@12
|
24
|
Chris@12
|
25 /** @var string[] */
|
Chris@12
|
26 private $exampleDirectories = [];
|
Chris@12
|
27
|
Chris@12
|
28 /**
|
Chris@12
|
29 * Attempts to find the example contents for the given descriptor.
|
Chris@12
|
30 *
|
Chris@12
|
31 * @param Example $example
|
Chris@12
|
32 *
|
Chris@12
|
33 * @return string
|
Chris@12
|
34 */
|
Chris@12
|
35 public function find(Example $example)
|
Chris@12
|
36 {
|
Chris@12
|
37 $filename = $example->getFilePath();
|
Chris@12
|
38
|
Chris@12
|
39 $file = $this->getExampleFileContents($filename);
|
Chris@12
|
40 if (!$file) {
|
Chris@12
|
41 return "** File not found : {$filename} **";
|
Chris@12
|
42 }
|
Chris@12
|
43
|
Chris@12
|
44 return implode('', array_slice($file, $example->getStartingLine() - 1, $example->getLineCount()));
|
Chris@12
|
45 }
|
Chris@12
|
46
|
Chris@12
|
47 /**
|
Chris@12
|
48 * Registers the project's root directory where an 'examples' folder can be expected.
|
Chris@12
|
49 *
|
Chris@12
|
50 * @param string $directory
|
Chris@12
|
51 *
|
Chris@12
|
52 * @return void
|
Chris@12
|
53 */
|
Chris@12
|
54 public function setSourceDirectory($directory = '')
|
Chris@12
|
55 {
|
Chris@12
|
56 $this->sourceDirectory = $directory;
|
Chris@12
|
57 }
|
Chris@12
|
58
|
Chris@12
|
59 /**
|
Chris@12
|
60 * Returns the project's root directory where an 'examples' folder can be expected.
|
Chris@12
|
61 *
|
Chris@12
|
62 * @return string
|
Chris@12
|
63 */
|
Chris@12
|
64 public function getSourceDirectory()
|
Chris@12
|
65 {
|
Chris@12
|
66 return $this->sourceDirectory;
|
Chris@12
|
67 }
|
Chris@12
|
68
|
Chris@12
|
69 /**
|
Chris@12
|
70 * Registers a series of directories that may contain examples.
|
Chris@12
|
71 *
|
Chris@12
|
72 * @param string[] $directories
|
Chris@12
|
73 */
|
Chris@12
|
74 public function setExampleDirectories(array $directories)
|
Chris@12
|
75 {
|
Chris@12
|
76 $this->exampleDirectories = $directories;
|
Chris@12
|
77 }
|
Chris@12
|
78
|
Chris@12
|
79 /**
|
Chris@12
|
80 * Returns a series of directories that may contain examples.
|
Chris@12
|
81 *
|
Chris@12
|
82 * @return string[]
|
Chris@12
|
83 */
|
Chris@12
|
84 public function getExampleDirectories()
|
Chris@12
|
85 {
|
Chris@12
|
86 return $this->exampleDirectories;
|
Chris@12
|
87 }
|
Chris@12
|
88
|
Chris@12
|
89 /**
|
Chris@12
|
90 * Attempts to find the requested example file and returns its contents or null if no file was found.
|
Chris@12
|
91 *
|
Chris@12
|
92 * This method will try several methods in search of the given example file, the first one it encounters is
|
Chris@12
|
93 * returned:
|
Chris@12
|
94 *
|
Chris@12
|
95 * 1. Iterates through all examples folders for the given filename
|
Chris@12
|
96 * 2. Checks the source folder for the given filename
|
Chris@12
|
97 * 3. Checks the 'examples' folder in the current working directory for examples
|
Chris@12
|
98 * 4. Checks the path relative to the current working directory for the given filename
|
Chris@12
|
99 *
|
Chris@12
|
100 * @param string $filename
|
Chris@12
|
101 *
|
Chris@12
|
102 * @return string|null
|
Chris@12
|
103 */
|
Chris@12
|
104 private function getExampleFileContents($filename)
|
Chris@12
|
105 {
|
Chris@12
|
106 $normalizedPath = null;
|
Chris@12
|
107
|
Chris@12
|
108 foreach ($this->exampleDirectories as $directory) {
|
Chris@12
|
109 $exampleFileFromConfig = $this->constructExamplePath($directory, $filename);
|
Chris@12
|
110 if (is_readable($exampleFileFromConfig)) {
|
Chris@12
|
111 $normalizedPath = $exampleFileFromConfig;
|
Chris@12
|
112 break;
|
Chris@12
|
113 }
|
Chris@12
|
114 }
|
Chris@12
|
115
|
Chris@12
|
116 if (!$normalizedPath) {
|
Chris@12
|
117 if (is_readable($this->getExamplePathFromSource($filename))) {
|
Chris@12
|
118 $normalizedPath = $this->getExamplePathFromSource($filename);
|
Chris@12
|
119 } elseif (is_readable($this->getExamplePathFromExampleDirectory($filename))) {
|
Chris@12
|
120 $normalizedPath = $this->getExamplePathFromExampleDirectory($filename);
|
Chris@12
|
121 } elseif (is_readable($filename)) {
|
Chris@12
|
122 $normalizedPath = $filename;
|
Chris@12
|
123 }
|
Chris@12
|
124 }
|
Chris@12
|
125
|
Chris@12
|
126 return $normalizedPath && is_readable($normalizedPath) ? file($normalizedPath) : null;
|
Chris@12
|
127 }
|
Chris@12
|
128
|
Chris@12
|
129 /**
|
Chris@12
|
130 * Get example filepath based on the example directory inside your project.
|
Chris@12
|
131 *
|
Chris@12
|
132 * @param string $file
|
Chris@12
|
133 *
|
Chris@12
|
134 * @return string
|
Chris@12
|
135 */
|
Chris@12
|
136 private function getExamplePathFromExampleDirectory($file)
|
Chris@12
|
137 {
|
Chris@12
|
138 return getcwd() . DIRECTORY_SEPARATOR . 'examples' . DIRECTORY_SEPARATOR . $file;
|
Chris@12
|
139 }
|
Chris@12
|
140
|
Chris@12
|
141 /**
|
Chris@12
|
142 * Returns a path to the example file in the given directory..
|
Chris@12
|
143 *
|
Chris@12
|
144 * @param string $directory
|
Chris@12
|
145 * @param string $file
|
Chris@12
|
146 *
|
Chris@12
|
147 * @return string
|
Chris@12
|
148 */
|
Chris@12
|
149 private function constructExamplePath($directory, $file)
|
Chris@12
|
150 {
|
Chris@12
|
151 return rtrim($directory, '\\/') . DIRECTORY_SEPARATOR . $file;
|
Chris@12
|
152 }
|
Chris@12
|
153
|
Chris@12
|
154 /**
|
Chris@12
|
155 * Get example filepath based on sourcecode.
|
Chris@12
|
156 *
|
Chris@12
|
157 * @param string $file
|
Chris@12
|
158 *
|
Chris@12
|
159 * @return string
|
Chris@12
|
160 */
|
Chris@12
|
161 private function getExamplePathFromSource($file)
|
Chris@12
|
162 {
|
Chris@12
|
163 return sprintf(
|
Chris@12
|
164 '%s%s%s',
|
Chris@12
|
165 trim($this->getSourceDirectory(), '\\/'),
|
Chris@12
|
166 DIRECTORY_SEPARATOR,
|
Chris@12
|
167 trim($file, '"')
|
Chris@12
|
168 );
|
Chris@12
|
169 }
|
Chris@12
|
170 }
|