These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
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-2017 Mike van Riel<[email protected]> |
||
9 | * @license http://www.opensource.org/licenses/mit-license.php MIT |
||
10 | * @link http://phpdoc.org |
||
11 | */ |
||
12 | |||
13 | namespace phpDocumentor\Application\Stage; |
||
14 | |||
15 | use phpDocumentor\Descriptor\Cache\ProjectDescriptorMapper; |
||
16 | use phpDocumentor\Descriptor\ProjectDescriptor; |
||
17 | use phpDocumentor\Descriptor\ProjectDescriptorBuilder; |
||
18 | use phpDocumentor\DomainModel\Parser\FileCollector; |
||
19 | use phpDocumentor\Event\LogEvent; |
||
20 | use phpDocumentor\Parser\Parser as DocParser; |
||
21 | use phpDocumentor\Partials\Collection as PartialsCollection; |
||
22 | use phpDocumentor\Reflection\DocBlock\ExampleFinder; |
||
23 | use Psr\Log\LogLevel; |
||
24 | use Symfony\Component\EventDispatcher\EventDispatcherInterface; |
||
25 | use Symfony\Component\Filesystem\Filesystem; |
||
26 | use Zend\Cache\Storage\StorageInterface; |
||
27 | |||
28 | /** |
||
29 | * Parses the given source code and creates a structure file. |
||
30 | * |
||
31 | * The parse task uses the source files defined either by -f or -d options and |
||
32 | * generates a structure file (structure.xml) at the target location (which is |
||
33 | * the folder 'output' unless the option -t is provided). |
||
34 | */ |
||
35 | final class Parser |
||
36 | { |
||
37 | /** @var ProjectDescriptorBuilder $builder */ |
||
38 | private $builder; |
||
39 | |||
40 | /** @var DocParser $parser */ |
||
41 | private $parser; |
||
42 | |||
43 | /** @var StorageInterface */ |
||
44 | private $cache; |
||
45 | |||
46 | /** |
||
47 | * @var ExampleFinder |
||
48 | */ |
||
49 | private $exampleFinder; |
||
50 | |||
51 | /** |
||
52 | * @var PartialsCollection |
||
53 | */ |
||
54 | private $partials; |
||
55 | |||
56 | /** |
||
57 | * @var FileCollector |
||
58 | */ |
||
59 | private $fileCollector; |
||
60 | |||
61 | /** |
||
62 | * @var EventDispatcherInterface |
||
63 | */ |
||
64 | private $eventDispatcher; |
||
65 | |||
66 | /** |
||
67 | * ParseCommand constructor. |
||
68 | */ |
||
69 | public function __construct( |
||
70 | ProjectDescriptorBuilder $builder, |
||
71 | DocParser $parser, |
||
72 | FileCollector $fileCollector, |
||
73 | StorageInterface $cache, |
||
74 | ExampleFinder $exampleFinder, |
||
75 | PartialsCollection $partials, |
||
76 | EventDispatcherInterface $eventDispatcher |
||
77 | ) { |
||
78 | $this->builder = $builder; |
||
79 | $this->parser = $parser; |
||
80 | $this->cache = $cache; |
||
81 | $this->exampleFinder = $exampleFinder; |
||
82 | $this->partials = $partials; |
||
83 | $this->fileCollector = $fileCollector; |
||
84 | $this->eventDispatcher = $eventDispatcher; |
||
85 | } |
||
86 | |||
87 | private function getBuilder(): ProjectDescriptorBuilder |
||
88 | { |
||
89 | return $this->builder; |
||
90 | } |
||
91 | |||
92 | private function getParser(): DocParser |
||
93 | { |
||
94 | return $this->parser; |
||
95 | } |
||
96 | |||
97 | /** |
||
98 | * Returns the Cache. |
||
99 | * |
||
100 | * @throws \InvalidArgumentException |
||
101 | */ |
||
102 | private function getCache(): StorageInterface |
||
103 | { |
||
104 | return $this->cache; |
||
105 | } |
||
106 | |||
107 | /** |
||
108 | * Executes the business logic involved with this command. |
||
109 | * |
||
110 | * @return array |
||
111 | * @throws \Exception if the target location is not a folder. |
||
112 | */ |
||
113 | public function __invoke(array $configuration) |
||
114 | { |
||
115 | $target = $configuration['phpdocumentor']['paths']['cache']; |
||
116 | |||
117 | //Grep only the first version for now. Multi version support will be added later |
||
118 | $version = current($configuration['phpdocumentor']['versions']); |
||
119 | |||
120 | //We are currently in the parser stage so grep the api config. |
||
121 | //And for now we support a single api definition. Could be more in the future. |
||
122 | $apiConfig = $version['api'][0]; |
||
123 | |||
124 | //Process cache setup |
||
125 | $fileSystem = new Filesystem(); |
||
126 | if (!$fileSystem->isAbsolutePath($target)) { |
||
127 | $target = getcwd() . DIRECTORY_SEPARATOR . $target; |
||
128 | } |
||
129 | if (!file_exists($target)) { |
||
130 | if (!mkdir($target) && !is_dir($target)) { |
||
131 | throw new \RuntimeException('PPCPP:EXC-BADTARGET'); |
||
132 | } |
||
133 | } |
||
134 | |||
135 | $this->getCache()->getOptions()->setCacheDir($target); |
||
136 | |||
137 | $parser = $this->getParser(); |
||
138 | $parser->setForced(!$configuration['phpdocumentor']['use-cache']); |
||
139 | $parser->setEncoding($apiConfig['encoding']); |
||
140 | $parser->setMarkers($apiConfig['markers']); |
||
141 | $parser->setIgnoredTags($apiConfig['ignore-tags']); |
||
142 | $parser->setValidate($apiConfig['validate']); |
||
143 | $parser->setDefaultPackageName($apiConfig['default-package-name']); |
||
144 | |||
145 | $builder = $this->getBuilder(); |
||
146 | $builder->createProjectDescriptor(); |
||
147 | $projectDescriptor = $builder->getProjectDescriptor(); |
||
148 | $projectDescriptor->setName($configuration['phpdocumentor']['title']); |
||
149 | $projectDescriptor->setPartials($this->partials); |
||
150 | |||
151 | $visibility = $this->getVisibility($apiConfig); |
||
152 | $projectDescriptor->getSettings()->setVisibility($visibility); |
||
153 | |||
154 | $mapper = new ProjectDescriptorMapper($this->getCache()); |
||
155 | |||
156 | if ($configuration['phpdocumentor']['use-cache']) { |
||
157 | //TODO: Re-enable garbage collection here. |
||
158 | //$mapper->garbageCollect($files); |
||
159 | $mapper->populate($projectDescriptor); |
||
160 | } |
||
161 | |||
162 | //TODO: Should determine root based on filesystems. Could be an issue for multiple. |
||
163 | // Need some config update here. |
||
164 | $this->exampleFinder->setSourceDirectory(getcwd()); |
||
165 | $this->exampleFinder->setExampleDirectories(['.']); |
||
166 | |||
167 | $this->log('PPCPP:LOG-COLLECTING'); |
||
168 | $files = $this->getFileCollection($apiConfig); |
||
169 | $this->log('PPCPP:LOG-OK'); |
||
170 | $this->log('PPCPP:LOG-INITIALIZING'); |
||
171 | |||
172 | $this->log('PPCPP:LOG-OK'); |
||
173 | $this->log('PPCPP:LOG-PARSING'); |
||
174 | |||
175 | $parser->parse($builder, $files); |
||
176 | |||
177 | $this->log('PPCPP:LOG-STORECACHE', LogLevel::INFO, ['cacheDir' => $target]); |
||
178 | $projectDescriptor->getSettings()->clearModifiedFlag(); |
||
179 | $mapper->save($projectDescriptor); |
||
180 | $this->log('PPCPP:LOG-OK'); |
||
181 | |||
182 | return $configuration; |
||
183 | } |
||
184 | |||
185 | /** |
||
186 | * Returns the collection of files based on the input and configuration. |
||
187 | */ |
||
188 | private function getFileCollection(array $apiConfig): array |
||
189 | { |
||
190 | $ignorePaths = array_map( |
||
191 | function ($value) { |
||
192 | if (substr($value, -1) === '*') { |
||
193 | return substr($value, 0, -1); |
||
194 | } |
||
195 | |||
196 | return $value; |
||
197 | }, |
||
198 | $apiConfig['ignore']['paths'] |
||
199 | ); |
||
200 | |||
201 | return $this->fileCollector->getFiles( |
||
202 | $apiConfig['source']['dsn'], |
||
203 | $apiConfig['source']['paths'], |
||
204 | [ |
||
205 | 'paths' => $ignorePaths, |
||
206 | 'hidden' => $apiConfig['ignore']['hidden'], |
||
207 | ], |
||
208 | $apiConfig['extensions'] |
||
209 | ); |
||
210 | } |
||
211 | |||
212 | private function getVisibility(array $apiConfig): ?int |
||
213 | { |
||
214 | $visibilities = $apiConfig['visibility']; |
||
215 | $visibility = null; |
||
216 | foreach ($visibilities as $item) { |
||
217 | switch ($item) { |
||
218 | case 'public': |
||
0 ignored issues
–
show
|
|||
219 | $visibility |= ProjectDescriptor\Settings::VISIBILITY_PUBLIC; |
||
220 | break; |
||
221 | case 'protected': |
||
222 | $visibility |= ProjectDescriptor\Settings::VISIBILITY_PROTECTED; |
||
223 | break; |
||
224 | case 'private': |
||
225 | $visibility |= ProjectDescriptor\Settings::VISIBILITY_PRIVATE; |
||
226 | break; |
||
227 | } |
||
228 | } |
||
229 | return $visibility; |
||
230 | } |
||
231 | |||
232 | /** |
||
233 | * Dispatches a logging request. |
||
234 | * |
||
235 | * @param string $message The message to log. |
||
236 | * @param string $priority The logging priority as declared in the LogLevel PSR-3 class. |
||
237 | * @param string[] $parameters |
||
238 | */ |
||
239 | private function log($message, $priority = LogLevel::INFO, $parameters = []) |
||
240 | { |
||
241 | $this->eventDispatcher->dispatch( |
||
242 | 'system.log', |
||
243 | LogEvent::createInstance($this) |
||
244 | ->setContext($parameters) |
||
245 | ->setMessage($message) |
||
246 | ->setPriority($priority) |
||
247 | ); |
||
248 | } |
||
249 | } |
||
250 |
As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next
break
.There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.
To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.