Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
138 / 138 |
|
100.00% |
11 / 11 |
CRAP | |
100.00% |
1 / 1 |
AutoloadCollector | |
100.00% |
138 / 138 |
|
100.00% |
11 / 11 |
41 | |
100.00% |
1 / 1 |
setAutoloader | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
getActivities | |
100.00% |
11 / 11 |
|
100.00% |
1 / 1 |
3 | |||
getContents | |
100.00% |
40 / 40 |
|
100.00% |
1 / 1 |
10 | |||
getDataByFile | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
3 | |||
getDataByDeclaration | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
3 | |||
renderAutoloader | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
2 | |||
renderNamespaces | |
100.00% |
26 / 26 |
|
100.00% |
1 / 1 |
4 | |||
renderClasses | |
100.00% |
21 / 21 |
|
100.00% |
1 / 1 |
3 | |||
renderPreload | |
100.00% |
11 / 11 |
|
100.00% |
1 / 1 |
5 | |||
getOpcacheConfiguration | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
getDeclarationType | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
5 |
1 | <?php declare(strict_types=1); |
2 | /* |
3 | * This file is part of Aplus Framework Autoload Library. |
4 | * |
5 | * (c) Natan Felles <natanfelles@gmail.com> |
6 | * |
7 | * For the full copyright and license information, please view the LICENSE |
8 | * file that was distributed with this source code. |
9 | */ |
10 | namespace Framework\Autoload\Debug; |
11 | |
12 | use Framework\Autoload\Autoloader; |
13 | use Framework\Autoload\Preloader; |
14 | use Framework\Debug\Collector; |
15 | use UnitEnum; |
16 | |
17 | /** |
18 | * Class AutoloadCollector. |
19 | * |
20 | * @package autoload |
21 | */ |
22 | class AutoloadCollector extends Collector |
23 | { |
24 | protected Autoloader $autoloader; |
25 | |
26 | public function setAutoloader(Autoloader $autoloader) : static |
27 | { |
28 | $this->autoloader = $autoloader; |
29 | return $this; |
30 | } |
31 | |
32 | public function getActivities() : array |
33 | { |
34 | $activities = []; |
35 | foreach ($this->getData() as $data) { |
36 | if ($data['loaded']) { |
37 | $activities[] = [ |
38 | 'collector' => $this->getName(), |
39 | 'class' => static::class, |
40 | 'description' => 'Load class ' . $data['class'], |
41 | 'start' => $data['start'], |
42 | 'end' => $data['end'], |
43 | ]; |
44 | } |
45 | } |
46 | return $activities; |
47 | } |
48 | |
49 | public function getContents() : string |
50 | { |
51 | \ob_start(); ?> |
52 | <h1>Autoloader</h1> |
53 | <?= $this->renderAutoloader() ?> |
54 | <h1>Included Files</h1> |
55 | <?php |
56 | $includedFiles = Preloader::getIncludedFiles(); ?> |
57 | <p>Total of <?= \count($includedFiles) ?> included files.</p> |
58 | <table> |
59 | <thead> |
60 | <tr> |
61 | <th>#</th> |
62 | <th>File</th> |
63 | <th title="Seconds">Time</th> |
64 | </tr> |
65 | </thead> |
66 | <tbody> |
67 | <?php foreach ($includedFiles as $index => $file): ?> |
68 | <?php |
69 | $data = $this->getDataByFile($file); ?> |
70 | <tr<?= $data |
71 | ? ' class="active" title="Included with the current Autoloader"' |
72 | : '' ?>> |
73 | <td><?= $index + 1 ?></td> |
74 | <td><?= \htmlentities($file) ?></td> |
75 | <td><?= $data ? \round($data['end'] - $data['start'], 6) : '' ?></td> |
76 | </tr> |
77 | <?php endforeach ?> |
78 | </tbody> |
79 | </table> |
80 | <h1>Preload</h1> |
81 | <?= $this->renderPreload() ?> |
82 | <h1>Declarations</h1> |
83 | <?php |
84 | $declarations = Preloader::getAllDeclarations(); ?> |
85 | <p>Total of <?= \count($declarations) ?> declarations.</p> |
86 | <table> |
87 | <thead> |
88 | <tr> |
89 | <th>#</th> |
90 | <th>Type</th> |
91 | <th>Declaration</th> |
92 | <th title="Loaded with the current Autoloader">Loaded</th> |
93 | <th title="Seconds">Time</th> |
94 | </tr> |
95 | </thead> |
96 | <tbody> |
97 | <?php foreach ($declarations as $index => $declaration): ?> |
98 | <?php |
99 | $data = $this->getDataByDeclaration($declaration); ?> |
100 | <tr<?= $data ? ' class="active" title="Searched with the current Autoloader"' |
101 | : '' ?>> |
102 | <td><?= $index + 1 ?></td> |
103 | <td><?= $this->getDeclarationType($declaration) ?></td> |
104 | <td><?= $declaration ?></td> |
105 | <td><?php |
106 | if ($data && isset($data['loaded'])) { |
107 | echo $data['loaded'] ? 'Yes' : 'No'; |
108 | } ?></td> |
109 | <td><?= $data ? \round($data['end'] - $data['start'], 6) : '' ?></td> |
110 | </tr> |
111 | <?php endforeach ?> |
112 | </tbody> |
113 | </table> |
114 | <?php |
115 | return \ob_get_clean(); // @phpstan-ignore-line |
116 | } |
117 | |
118 | /** |
119 | * @param string $file |
120 | * |
121 | * @return array<string,mixed>|false |
122 | */ |
123 | protected function getDataByFile(string $file) : array | false |
124 | { |
125 | foreach ($this->getData() as $data) { |
126 | if ($data['file'] === $file) { |
127 | return $data; |
128 | } |
129 | } |
130 | return false; |
131 | } |
132 | |
133 | /** |
134 | * @param string $declaration |
135 | * |
136 | * @return array<string,mixed>|false |
137 | */ |
138 | protected function getDataByDeclaration(string $declaration) : array | false |
139 | { |
140 | foreach ($this->getData() as $data) { |
141 | if ($data['class'] === $declaration) { |
142 | return $data; |
143 | } |
144 | } |
145 | return false; |
146 | } |
147 | |
148 | protected function renderAutoloader() : string |
149 | { |
150 | if ( ! isset($this->autoloader)) { |
151 | return '<p>An Autoloader instance has not been set on this collector.</p>'; |
152 | } |
153 | \ob_start(); ?> |
154 | <h2>Namespaces</h2> |
155 | <?= $this->renderNamespaces() ?> |
156 | <h2>Classes</h2> |
157 | <?php |
158 | echo $this->renderClasses(); |
159 | return \ob_get_clean(); // @phpstan-ignore-line |
160 | } |
161 | |
162 | protected function renderNamespaces() : string |
163 | { |
164 | $namespaces = $this->autoloader->getNamespaces(); |
165 | if (empty($namespaces)) { |
166 | return '<p>No namespace directory has been set on this Autoloader instance.</p>'; |
167 | } |
168 | \ksort($namespaces); |
169 | \ob_start(); ?> |
170 | <table> |
171 | <thead> |
172 | <tr> |
173 | <th>Namespace</th> |
174 | <th>Directories</th> |
175 | </tr> |
176 | </thead> |
177 | <tbody> |
178 | <?php foreach ($namespaces as $namespace => $directories): ?> |
179 | <?php $count = \count($directories); ?> |
180 | <tr> |
181 | <td rowspan="<?= $count ?>"><?= \htmlentities($namespace) ?></td> |
182 | <td><?= \htmlentities($directories[0]) ?></td> |
183 | </tr> |
184 | <?php for ($i = 1; $i < $count; $i++): ?> |
185 | <tr> |
186 | <td><?= \htmlentities($directories[$i]) ?></td> |
187 | </tr> |
188 | <?php endfor ?> |
189 | <?php endforeach ?> |
190 | </tbody> |
191 | </table> |
192 | <?php |
193 | return \ob_get_clean(); // @phpstan-ignore-line |
194 | } |
195 | |
196 | protected function renderClasses() : string |
197 | { |
198 | $classes = $this->autoloader->getClasses(); |
199 | if (empty($classes)) { |
200 | return '<p>No class file has been set on this Autoloader instance.</p>'; |
201 | } |
202 | \ksort($classes); |
203 | \ob_start(); ?> |
204 | <table> |
205 | <thead> |
206 | <tr> |
207 | <th>Class</th> |
208 | <th>File</th> |
209 | </tr> |
210 | </thead> |
211 | <tbody> |
212 | <?php foreach ($classes as $class => $file): ?> |
213 | <tr> |
214 | <td><?= \htmlentities($class) ?></td> |
215 | <td><?= \htmlentities($file) ?></td> |
216 | </tr> |
217 | <?php endforeach ?> |
218 | </tbody> |
219 | </table> |
220 | <?php |
221 | return \ob_get_clean(); // @phpstan-ignore-line |
222 | } |
223 | |
224 | protected function renderPreload() : string |
225 | { |
226 | $conf = $this->getOpcacheConfiguration(); |
227 | if ($conf === null) { |
228 | return '<p>Preload is not available.</p>'; |
229 | } |
230 | if ($conf && ! empty($conf['directives']['opcache.preload'])) { |
231 | $result = '<p><strong>File:</strong> ' |
232 | . \htmlentities($conf['directives']['opcache.preload']) . '</p>'; |
233 | if ( ! empty($conf['directives']['opcache.preload_user'])) { |
234 | $result .= '<p><strong>User:</strong> ' |
235 | . \htmlentities($conf['directives']['opcache.preload_user']) . '</p>'; |
236 | } |
237 | return $result; |
238 | } |
239 | return '<p>Preload file has not been set.</p>'; |
240 | } |
241 | |
242 | /** |
243 | * @return array<string,mixed>|null |
244 | */ |
245 | protected function getOpcacheConfiguration() : array | null |
246 | { |
247 | return \function_exists('opcache_get_configuration') |
248 | ? (array) \opcache_get_configuration() |
249 | : null; |
250 | } |
251 | |
252 | protected function getDeclarationType(string $declaration) : string |
253 | { |
254 | if (\in_array($declaration, \get_declared_classes(), true)) { |
255 | return \is_subclass_of($declaration, UnitEnum::class) ? 'enum' : 'class'; |
256 | } |
257 | if (\in_array($declaration, \get_declared_interfaces(), true)) { |
258 | return 'interface'; |
259 | } |
260 | if (\in_array($declaration, \get_declared_traits(), true)) { |
261 | return 'trait'; |
262 | } |
263 | return ''; |
264 | } |
265 | } |