PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.9.2
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.9.2
4.0.8 4.0.7 4.0.6 4.0.5 4.0.4 4.0.3 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 3.1.2 3.1.3 3.10.0 3.10.1 3.10.10 3.10.11 3.10.12 3.10.13 3.10.14 3.10.15 3.10.2 3.10.3 All 149 releases
← All changes | vendor/composer/ClassLoader.php +187 -28 3.0.53.9.2 View file →
@@ -36,51 +36,122 @@
36 36 * This class is loosely based on the Symfony UniversalClassLoader.
37 37 *
38 38 * @author Fabien Potencier <fabien@symfony.com>
39 39 * @author Jordi Boggiano <j.boggiano@seld.be>
40 - * @see http://www.php-fig.org/psr/psr-0/
41 - * @see http://www.php-fig.org/psr/psr-4/
40 + * @see https://www.php-fig.org/psr/psr-0/
41 + * @see https://www.php-fig.org/psr/psr-4/
42 42 */
43 43 class ClassLoader
44 44 {
45 + /** @var ?string */
46 + private $vendorDir;
47 +
45 48 // PSR-4
49 + /**
50 + * @var array[]
51 + * @psalm-var array<string, array<string, int>>
52 + */
46 53 private $prefixLengthsPsr4 = array();
54 + /**
55 + * @var array[]
56 + * @psalm-var array<string, array<int, string>>
57 + */
47 58 private $prefixDirsPsr4 = array();
59 + /**
60 + * @var array[]
61 + * @psalm-var array<string, string>
62 + */
48 63 private $fallbackDirsPsr4 = array();
49 64
50 65 // PSR-0
66 + /**
67 + * @var array[]
68 + * @psalm-var array<string, array<string, string[]>>
69 + */
51 70 private $prefixesPsr0 = array();
71 + /**
72 + * @var array[]
73 + * @psalm-var array<string, string>
74 + */
52 75 private $fallbackDirsPsr0 = array();
53 76
77 + /** @var bool */
54 78 private $useIncludePath = false;
79 +
80 + /**
81 + * @var string[]
82 + * @psalm-var array<string, string>
83 + */
55 84 private $classMap = array();
56 85
86 + /** @var bool */
57 87 private $classMapAuthoritative = false;
58 88
89 + /**
90 + * @var bool[]
91 + * @psalm-var array<string, bool>
92 + */
93 + private $missingClasses = array();
94 +
95 + /** @var ?string */
96 + private $apcuPrefix;
97 +
98 + /**
99 + * @var self[]
100 + */
101 + private static $registeredLoaders = array();
102 +
103 + /**
104 + * @param ?string $vendorDir
105 + */
106 + public function __construct($vendorDir = null)
107 + {
108 + $this->vendorDir = $vendorDir;
109 + }
110 +
111 + /**
112 + * @return string[]
113 + */
59 114 public function getPrefixes()
60 115 {
61 116 if (!empty($this->prefixesPsr0)) {
62 - return call_user_func_array('array_merge', $this->prefixesPsr0);
117 + return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
63 118 }
64 119
65 120 return array();
66 121 }
67 122
123 + /**
124 + * @return array[]
125 + * @psalm-return array<string, array<int, string>>
126 + */
68 127 public function getPrefixesPsr4()
69 128 {
70 129 return $this->prefixDirsPsr4;
71 130 }
72 131
132 + /**
133 + * @return array[]
134 + * @psalm-return array<string, string>
135 + */
73 136 public function getFallbackDirs()
74 137 {
75 138 return $this->fallbackDirsPsr0;
76 139 }
77 140
141 + /**
142 + * @return array[]
143 + * @psalm-return array<string, string>
144 + */
78 145 public function getFallbackDirsPsr4()
79 146 {
80 147 return $this->fallbackDirsPsr4;
81 148 }
82 149
150 + /**
151 + * @return string[] Array of classname => path
152 + * @psalm-return array<string, string>
153 + */
83 154 public function getClassMap()
84 155 {
85 156 return $this->classMap;
86 157 }
@@ -85,9 +156,12 @@
85 156 return $this->classMap;
86 157 }
87 158
88 159 /**
89 - * @param array $classMap Class to filename map
160 + * @param string[] $classMap Class to filename map
161 + * @psalm-param array<string, string> $classMap
162 + *
163 + * @return void
90 164 */
91 165 public function addClassMap(array $classMap)
92 166 {
93 167 if ($this->classMap) {
@@ -100,11 +174,13 @@
100 174 /**
101 175 * Registers a set of PSR-0 directories for a given prefix, either
102 176 * appending or prepending to the ones previously set for this prefix.
103 177 *
104 - * @param string $prefix The prefix
105 - * @param array|string $paths The PSR-0 root directories
106 - * @param bool $prepend Whether to prepend the directories
178 + * @param string $prefix The prefix
179 + * @param string[]|string $paths The PSR-0 root directories
180 + * @param bool $prepend Whether to prepend the directories
181 + *
182 + * @return void
107 183 */
108 184 public function add($prefix, $paths, $prepend = false)
109 185 {
110 186 if (!$prefix) {
@@ -145,13 +221,15 @@
145 221 /**
146 222 * Registers a set of PSR-4 directories for a given namespace, either
147 223 * appending or prepending to the ones previously set for this namespace.
148 224 *
149 - * @param string $prefix The prefix/namespace, with trailing '\\'
150 - * @param array|string $paths The PSR-4 base directories
151 - * @param bool $prepend Whether to prepend the directories
225 + * @param string $prefix The prefix/namespace, with trailing '\\'
226 + * @param string[]|string $paths The PSR-4 base directories
227 + * @param bool $prepend Whether to prepend the directories
152 228 *
153 229 * @throws \InvalidArgumentException
230 + *
231 + * @return void
154 232 */
155 233 public function addPsr4($prefix, $paths, $prepend = false)
156 234 {
157 235 if (!$prefix) {
@@ -193,10 +271,12 @@
193 271 /**
194 272 * Registers a set of PSR-0 directories for a given prefix,
195 273 * replacing any others previously set for this prefix.
196 274 *
197 - * @param string $prefix The prefix
198 - * @param array|string $paths The PSR-0 base directories
275 + * @param string $prefix The prefix
276 + * @param string[]|string $paths The PSR-0 base directories
277 + *
278 + * @return void
199 279 */
200 280 public function set($prefix, $paths)
201 281 {
202 282 if (!$prefix) {
@@ -209,12 +289,14 @@
209 289 /**
210 290 * Registers a set of PSR-4 directories for a given namespace,
211 291 * replacing any others previously set for this namespace.
212 292 *
213 - * @param string $prefix The prefix/namespace, with trailing '\\'
214 - * @param array|string $paths The PSR-4 base directories
293 + * @param string $prefix The prefix/namespace, with trailing '\\'
294 + * @param string[]|string $paths The PSR-4 base directories
215 295 *
216 296 * @throws \InvalidArgumentException
297 + *
298 + * @return void
217 299 */
218 300 public function setPsr4($prefix, $paths)
219 301 {
220 302 if (!$prefix) {
@@ -232,8 +314,10 @@
232 314 /**
233 315 * Turns on searching the include path for class files.
234 316 *
235 317 * @param bool $useIncludePath
318 + *
319 + * @return void
236 320 */
237 321 public function setUseIncludePath($useIncludePath)
238 322 {
239 323 $this->useIncludePath = $useIncludePath;
@@ -254,8 +338,10 @@
254 338 * Turns off searching the prefix and fallback directories for classes
255 339 * that have not been registered with the class map.
256 340 *
257 341 * @param bool $classMapAuthoritative
342 + *
343 + * @return void
258 344 */
259 345 public function setClassMapAuthoritative($classMapAuthoritative)
260 346 {
261 347 $this->classMapAuthoritative = $classMapAuthoritative;
@@ -271,23 +357,64 @@
271 357 return $this->classMapAuthoritative;
272 358 }
273 359
274 360 /**
361 + * APCu prefix to use to cache found/not-found classes, if the extension is enabled.
362 + *
363 + * @param string|null $apcuPrefix
364 + *
365 + * @return void
366 + */
367 + public function setApcuPrefix($apcuPrefix)
368 + {
369 + $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
370 + }
371 +
372 + /**
373 + * The APCu prefix in use, or null if APCu caching is not enabled.
374 + *
375 + * @return string|null
376 + */
377 + public function getApcuPrefix()
378 + {
379 + return $this->apcuPrefix;
380 + }
381 +
382 + /**
275 383 * Registers this instance as an autoloader.
276 384 *
277 385 * @param bool $prepend Whether to prepend the autoloader or not
386 + *
387 + * @return void
278 388 */
279 389 public function register($prepend = false)
280 390 {
281 391 spl_autoload_register(array($this, 'loadClass'), true, $prepend);
392 +
393 + if (null === $this->vendorDir) {
394 + return;
395 + }
396 +
397 + if ($prepend) {
398 + self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
399 + } else {
400 + unset(self::$registeredLoaders[$this->vendorDir]);
401 + self::$registeredLoaders[$this->vendorDir] = $this;
402 + }
282 403 }
283 404
284 405 /**
285 406 * Unregisters this instance as an autoloader.
407 + *
408 + * @return void
286 409 */
287 410 public function unregister()
288 411 {
289 412 spl_autoload_unregister(array($this, 'loadClass'));
413 +
414 + if (null !== $this->vendorDir) {
415 + unset(self::$registeredLoaders[$this->vendorDir]);
416 + }
290 417 }
291 418
292 419 /**
293 420 * Loads the given class or interface.
@@ -292,9 +419,9 @@
292 419 /**
293 420 * Loads the given class or interface.
294 421 *
295 422 * @param string $class The name of the class
296 - * @return bool|null True if loaded, null otherwise
423 + * @return true|null True if loaded, null otherwise
297 424 */
298 425 public function loadClass($class)
299 426 {
300 427 if ($file = $this->findFile($class)) {
@@ -301,8 +428,10 @@
301 428 includeFile($file);
302 429
303 430 return true;
304 431 }
432 +
433 + return null;
305 434 }
306 435
307 436 /**
308 437 * Finds the path to the file where the class is defined.
@@ -312,36 +441,56 @@
312 441 * @return string|false The path if found, false otherwise
313 442 */
314 443 public function findFile($class)
315 444 {
316 - // work around for PHP 5.3.0 - 5.3.2 https://bugs.php.net/50731
317 - if ('\\' == $class[0]) {
318 - $class = substr($class, 1);
319 - }
320 -
321 445 // class map lookup
322 446 if (isset($this->classMap[$class])) {
323 447 return $this->classMap[$class];
324 448 }
325 - if ($this->classMapAuthoritative) {
449 + if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
326 450 return false;
327 451 }
452 + if (null !== $this->apcuPrefix) {
453 + $file = apcu_fetch($this->apcuPrefix.$class, $hit);
454 + if ($hit) {
455 + return $file;
456 + }
457 + }
328 458
329 459 $file = $this->findFileWithExtension($class, '.php');
330 460
331 461 // Search for Hack files if we are running on HHVM
332 - if ($file === null && defined('HHVM_VERSION')) {
462 + if (false === $file && defined('HHVM_VERSION')) {
333 463 $file = $this->findFileWithExtension($class, '.hh');
334 464 }
335 465
336 - if ($file === null) {
466 + if (null !== $this->apcuPrefix) {
467 + apcu_add($this->apcuPrefix.$class, $file);
468 + }
469 +
470 + if (false === $file) {
337 471 // Remember that this class does not exist.
338 - return $this->classMap[$class] = false;
472 + $this->missingClasses[$class] = true;
339 473 }
340 474
341 475 return $file;
342 476 }
343 477
478 + /**
479 + * Returns the currently registered loaders indexed by their corresponding vendor directories.
480 + *
481 + * @return self[]
482 + */
483 + public static function getRegisteredLoaders()
484 + {
485 + return self::$registeredLoaders;
486 + }
487 +
488 + /**
489 + * @param string $class
490 + * @param string $ext
491 + * @return string|false
492 + */
344 493 private function findFileWithExtension($class, $ext)
345 494 {
346 495 // PSR-4 lookup
347 496 $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
@@ -347,12 +496,16 @@
347 496 $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
348 497
349 498 $first = $class[0];
350 499 if (isset($this->prefixLengthsPsr4[$first])) {
351 - foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) {
352 - if (0 === strpos($class, $prefix)) {
353 - foreach ($this->prefixDirsPsr4[$prefix] as $dir) {
354 - if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
500 + $subPath = $class;
501 + while (false !== $lastPos = strrpos($subPath, '\\')) {
502 + $subPath = substr($subPath, 0, $lastPos);
503 + $search = $subPath . '\\';
504 + if (isset($this->prefixDirsPsr4[$search])) {
505 + $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
506 + foreach ($this->prefixDirsPsr4[$search] as $dir) {
507 + if (file_exists($file = $dir . $pathEnd)) {
355 508 return $file;
356 509 }
357 510 }
358 511 }
@@ -398,8 +551,10 @@
398 551 // PSR-0 include paths.
399 552 if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
400 553 return $file;
401 554 }
555 +
556 + return false;
402 557 }
403 558 }
404 559
405 560 /**
@@ -405,8 +560,12 @@
405 560 /**
406 561 * Scope isolated include.
407 562 *
408 563 * Prevents access to $this/self from included files.
564 + *
565 + * @param string $file
566 + * @return void
567 + * @private
409 568 */
410 569 function includeFile($file)
411 570 {
412 571 include $file;