PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 2.24.0
GiveWP – Donation Plugin and Fundraising Platform v2.24.0
4.16.3 4.16.2 4.16.1 4.16.0 4.15.5 4.15.4 4.15.3 4.15.2 4.15.1 4.15.0 2.3.0 2.3.1 2.3.2 2.30.0 2.31.0 2.31.1 2.32.0 2.33.0 2.33.1 2.33.2 2.33.3 2.33.4 2.33.5 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.4.7 2.5.0 2.5.1 2.5.10 2.5.11 2.5.12 2.5.13 2.5.2 2.5.3 2.5.4 2.5.5 2.5.6 2.5.7 2.5.8 2.5.9 2.6.0 2.6.1 2.6.2 2.6.3 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.8.0 2.8.1 2.9.0 2.9.1 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.1.2 3.10.0 3.11.0 3.12.0 3.12.1 3.12.2 3.12.3 3.13.0 3.14.0 3.14.1 3.14.2 3.15.0 3.15.1 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.16.5 3.17.0 3.17.1 3.17.2 3.18.0 3.19.0 3.19.1 3.19.2 3.19.3 3.19.4 3.2.0 3.2.1 3.2.2 3.20.0 3.21.0 3.21.1 3.22.0 3.22.1 3.22.2 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.5.1 3.6.0 3.6.1 3.6.2 3.7.0 3.8.0 3.9.0 4.0.0 4.1.0 4.1.1 4.10.0 4.10.1 4.11.0 4.12.0 4.13.0 4.13.1 4.13.2 4.14.0 4.14.1 4.14.2 4.14.3 4.14.4 4.14.5 4.14.6 4.2.0 4.2.1 4.3.0 4.3.1 4.3.2 4.4.0 4.5.0 4.6.1 4.7.0 4.7.1 4.8.0 4.8.1 4.9.0 trunk 1.9.0 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.10.0 2.10.1 2.10.2 2.10.3 2.10.4 2.11.0 2.11.1 2.11.2 2.11.3 2.12.0 2.12.1 2.12.2 2.12.3 2.13.0 2.13.1 2.13.2 2.13.3 2.13.4 2.14.0 2.15.0 2.16.0 2.16.1 2.17.0 2.17.1 2.17.3 2.18.0 2.18.1 2.19.1 2.19.2 2.19.3 2.19.4 2.19.5 2.19.6 2.19.7 2.19.8 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.20.0 2.20.1 2.20.2 2.21.0 2.21.1 2.21.2 2.21.3 2.21.4 2.22.0 2.22.1 2.22.2 2.22.3 2.23.0 2.23.1 2.23.2 2.24.0 2.24.1 2.24.2 2.25.0 2.25.1 2.25.2 2.25.3 2.26.0 2.27.0 2.27.1 2.27.2 2.27.3 2.28.0 2.29.0 2.29.1 2.29.2
give / vendor / composer / ClassLoader.php
give / vendor / composer Last commit date
ClassLoader.php 3 years ago InstalledVersions.php 4 years ago LICENSE 7 years ago autoload_classmap.php 4 years ago autoload_files.php 4 years ago autoload_namespaces.php 4 years ago autoload_psr4.php 3 years ago autoload_real.php 3 years ago autoload_static.php 3 years ago installed.json 3 years ago installed.php 3 years ago platform_check.php 3 years ago
ClassLoader.php
582 lines
1 <?php
2
3 /*
4 * This file is part of Composer.
5 *
6 * (c) Nils Adermann <naderman@naderman.de>
7 * Jordi Boggiano <j.boggiano@seld.be>
8 *
9 * For the full copyright and license information, please view the LICENSE
10 * file that was distributed with this source code.
11 */
12
13 namespace Composer\Autoload;
14
15 /**
16 * ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
17 *
18 * $loader = new \Composer\Autoload\ClassLoader();
19 *
20 * // register classes with namespaces
21 * $loader->add('Symfony\Component', __DIR__.'/component');
22 * $loader->add('Symfony', __DIR__.'/framework');
23 *
24 * // activate the autoloader
25 * $loader->register();
26 *
27 * // to enable searching the include path (eg. for PEAR packages)
28 * $loader->setUseIncludePath(true);
29 *
30 * In this example, if you try to use a class in the Symfony\Component
31 * namespace or one of its children (Symfony\Component\Console for instance),
32 * the autoloader will first look for the class under the component/
33 * directory, and it will then fallback to the framework/ directory if not
34 * found before giving up.
35 *
36 * This class is loosely based on the Symfony UniversalClassLoader.
37 *
38 * @author Fabien Potencier <fabien@symfony.com>
39 * @author Jordi Boggiano <j.boggiano@seld.be>
40 * @see https://www.php-fig.org/psr/psr-0/
41 * @see https://www.php-fig.org/psr/psr-4/
42 */
43 class ClassLoader
44 {
45 /** @var \Closure(string):void */
46 private static $includeFile;
47
48 /** @var ?string */
49 private $vendorDir;
50
51 // PSR-4
52 /**
53 * @var array[]
54 * @psalm-var array<string, array<string, int>>
55 */
56 private $prefixLengthsPsr4 = array();
57 /**
58 * @var array[]
59 * @psalm-var array<string, array<int, string>>
60 */
61 private $prefixDirsPsr4 = array();
62 /**
63 * @var array[]
64 * @psalm-var array<string, string>
65 */
66 private $fallbackDirsPsr4 = array();
67
68 // PSR-0
69 /**
70 * @var array[]
71 * @psalm-var array<string, array<string, string[]>>
72 */
73 private $prefixesPsr0 = array();
74 /**
75 * @var array[]
76 * @psalm-var array<string, string>
77 */
78 private $fallbackDirsPsr0 = array();
79
80 /** @var bool */
81 private $useIncludePath = false;
82
83 /**
84 * @var string[]
85 * @psalm-var array<string, string>
86 */
87 private $classMap = array();
88
89 /** @var bool */
90 private $classMapAuthoritative = false;
91
92 /**
93 * @var bool[]
94 * @psalm-var array<string, bool>
95 */
96 private $missingClasses = array();
97
98 /** @var ?string */
99 private $apcuPrefix;
100
101 /**
102 * @var self[]
103 */
104 private static $registeredLoaders = array();
105
106 /**
107 * @param ?string $vendorDir
108 */
109 public function __construct($vendorDir = null)
110 {
111 $this->vendorDir = $vendorDir;
112 self::initializeIncludeClosure();
113 }
114
115 /**
116 * @return string[]
117 */
118 public function getPrefixes()
119 {
120 if (!empty($this->prefixesPsr0)) {
121 return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
122 }
123
124 return array();
125 }
126
127 /**
128 * @return array[]
129 * @psalm-return array<string, array<int, string>>
130 */
131 public function getPrefixesPsr4()
132 {
133 return $this->prefixDirsPsr4;
134 }
135
136 /**
137 * @return array[]
138 * @psalm-return array<string, string>
139 */
140 public function getFallbackDirs()
141 {
142 return $this->fallbackDirsPsr0;
143 }
144
145 /**
146 * @return array[]
147 * @psalm-return array<string, string>
148 */
149 public function getFallbackDirsPsr4()
150 {
151 return $this->fallbackDirsPsr4;
152 }
153
154 /**
155 * @return string[] Array of classname => path
156 * @psalm-return array<string, string>
157 */
158 public function getClassMap()
159 {
160 return $this->classMap;
161 }
162
163 /**
164 * @param string[] $classMap Class to filename map
165 * @psalm-param array<string, string> $classMap
166 *
167 * @return void
168 */
169 public function addClassMap(array $classMap)
170 {
171 if ($this->classMap) {
172 $this->classMap = array_merge($this->classMap, $classMap);
173 } else {
174 $this->classMap = $classMap;
175 }
176 }
177
178 /**
179 * Registers a set of PSR-0 directories for a given prefix, either
180 * appending or prepending to the ones previously set for this prefix.
181 *
182 * @param string $prefix The prefix
183 * @param string[]|string $paths The PSR-0 root directories
184 * @param bool $prepend Whether to prepend the directories
185 *
186 * @return void
187 */
188 public function add($prefix, $paths, $prepend = false)
189 {
190 if (!$prefix) {
191 if ($prepend) {
192 $this->fallbackDirsPsr0 = array_merge(
193 (array) $paths,
194 $this->fallbackDirsPsr0
195 );
196 } else {
197 $this->fallbackDirsPsr0 = array_merge(
198 $this->fallbackDirsPsr0,
199 (array) $paths
200 );
201 }
202
203 return;
204 }
205
206 $first = $prefix[0];
207 if (!isset($this->prefixesPsr0[$first][$prefix])) {
208 $this->prefixesPsr0[$first][$prefix] = (array) $paths;
209
210 return;
211 }
212 if ($prepend) {
213 $this->prefixesPsr0[$first][$prefix] = array_merge(
214 (array) $paths,
215 $this->prefixesPsr0[$first][$prefix]
216 );
217 } else {
218 $this->prefixesPsr0[$first][$prefix] = array_merge(
219 $this->prefixesPsr0[$first][$prefix],
220 (array) $paths
221 );
222 }
223 }
224
225 /**
226 * Registers a set of PSR-4 directories for a given namespace, either
227 * appending or prepending to the ones previously set for this namespace.
228 *
229 * @param string $prefix The prefix/namespace, with trailing '\\'
230 * @param string[]|string $paths The PSR-4 base directories
231 * @param bool $prepend Whether to prepend the directories
232 *
233 * @throws \InvalidArgumentException
234 *
235 * @return void
236 */
237 public function addPsr4($prefix, $paths, $prepend = false)
238 {
239 if (!$prefix) {
240 // Register directories for the root namespace.
241 if ($prepend) {
242 $this->fallbackDirsPsr4 = array_merge(
243 (array) $paths,
244 $this->fallbackDirsPsr4
245 );
246 } else {
247 $this->fallbackDirsPsr4 = array_merge(
248 $this->fallbackDirsPsr4,
249 (array) $paths
250 );
251 }
252 } elseif (!isset($this->prefixDirsPsr4[$prefix])) {
253 // Register directories for a new namespace.
254 $length = strlen($prefix);
255 if ('\\' !== $prefix[$length - 1]) {
256 throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
257 }
258 $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
259 $this->prefixDirsPsr4[$prefix] = (array) $paths;
260 } elseif ($prepend) {
261 // Prepend directories for an already registered namespace.
262 $this->prefixDirsPsr4[$prefix] = array_merge(
263 (array) $paths,
264 $this->prefixDirsPsr4[$prefix]
265 );
266 } else {
267 // Append directories for an already registered namespace.
268 $this->prefixDirsPsr4[$prefix] = array_merge(
269 $this->prefixDirsPsr4[$prefix],
270 (array) $paths
271 );
272 }
273 }
274
275 /**
276 * Registers a set of PSR-0 directories for a given prefix,
277 * replacing any others previously set for this prefix.
278 *
279 * @param string $prefix The prefix
280 * @param string[]|string $paths The PSR-0 base directories
281 *
282 * @return void
283 */
284 public function set($prefix, $paths)
285 {
286 if (!$prefix) {
287 $this->fallbackDirsPsr0 = (array) $paths;
288 } else {
289 $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
290 }
291 }
292
293 /**
294 * Registers a set of PSR-4 directories for a given namespace,
295 * replacing any others previously set for this namespace.
296 *
297 * @param string $prefix The prefix/namespace, with trailing '\\'
298 * @param string[]|string $paths The PSR-4 base directories
299 *
300 * @throws \InvalidArgumentException
301 *
302 * @return void
303 */
304 public function setPsr4($prefix, $paths)
305 {
306 if (!$prefix) {
307 $this->fallbackDirsPsr4 = (array) $paths;
308 } else {
309 $length = strlen($prefix);
310 if ('\\' !== $prefix[$length - 1]) {
311 throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
312 }
313 $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
314 $this->prefixDirsPsr4[$prefix] = (array) $paths;
315 }
316 }
317
318 /**
319 * Turns on searching the include path for class files.
320 *
321 * @param bool $useIncludePath
322 *
323 * @return void
324 */
325 public function setUseIncludePath($useIncludePath)
326 {
327 $this->useIncludePath = $useIncludePath;
328 }
329
330 /**
331 * Can be used to check if the autoloader uses the include path to check
332 * for classes.
333 *
334 * @return bool
335 */
336 public function getUseIncludePath()
337 {
338 return $this->useIncludePath;
339 }
340
341 /**
342 * Turns off searching the prefix and fallback directories for classes
343 * that have not been registered with the class map.
344 *
345 * @param bool $classMapAuthoritative
346 *
347 * @return void
348 */
349 public function setClassMapAuthoritative($classMapAuthoritative)
350 {
351 $this->classMapAuthoritative = $classMapAuthoritative;
352 }
353
354 /**
355 * Should class lookup fail if not found in the current class map?
356 *
357 * @return bool
358 */
359 public function isClassMapAuthoritative()
360 {
361 return $this->classMapAuthoritative;
362 }
363
364 /**
365 * APCu prefix to use to cache found/not-found classes, if the extension is enabled.
366 *
367 * @param string|null $apcuPrefix
368 *
369 * @return void
370 */
371 public function setApcuPrefix($apcuPrefix)
372 {
373 $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
374 }
375
376 /**
377 * The APCu prefix in use, or null if APCu caching is not enabled.
378 *
379 * @return string|null
380 */
381 public function getApcuPrefix()
382 {
383 return $this->apcuPrefix;
384 }
385
386 /**
387 * Registers this instance as an autoloader.
388 *
389 * @param bool $prepend Whether to prepend the autoloader or not
390 *
391 * @return void
392 */
393 public function register($prepend = false)
394 {
395 spl_autoload_register(array($this, 'loadClass'), true, $prepend);
396
397 if (null === $this->vendorDir) {
398 return;
399 }
400
401 if ($prepend) {
402 self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
403 } else {
404 unset(self::$registeredLoaders[$this->vendorDir]);
405 self::$registeredLoaders[$this->vendorDir] = $this;
406 }
407 }
408
409 /**
410 * Unregisters this instance as an autoloader.
411 *
412 * @return void
413 */
414 public function unregister()
415 {
416 spl_autoload_unregister(array($this, 'loadClass'));
417
418 if (null !== $this->vendorDir) {
419 unset(self::$registeredLoaders[$this->vendorDir]);
420 }
421 }
422
423 /**
424 * Loads the given class or interface.
425 *
426 * @param string $class The name of the class
427 * @return true|null True if loaded, null otherwise
428 */
429 public function loadClass($class)
430 {
431 if ($file = $this->findFile($class)) {
432 (self::$includeFile)($file);
433
434 return true;
435 }
436
437 return null;
438 }
439
440 /**
441 * Finds the path to the file where the class is defined.
442 *
443 * @param string $class The name of the class
444 *
445 * @return string|false The path if found, false otherwise
446 */
447 public function findFile($class)
448 {
449 // class map lookup
450 if (isset($this->classMap[$class])) {
451 return $this->classMap[$class];
452 }
453 if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
454 return false;
455 }
456 if (null !== $this->apcuPrefix) {
457 $file = apcu_fetch($this->apcuPrefix.$class, $hit);
458 if ($hit) {
459 return $file;
460 }
461 }
462
463 $file = $this->findFileWithExtension($class, '.php');
464
465 // Search for Hack files if we are running on HHVM
466 if (false === $file && defined('HHVM_VERSION')) {
467 $file = $this->findFileWithExtension($class, '.hh');
468 }
469
470 if (null !== $this->apcuPrefix) {
471 apcu_add($this->apcuPrefix.$class, $file);
472 }
473
474 if (false === $file) {
475 // Remember that this class does not exist.
476 $this->missingClasses[$class] = true;
477 }
478
479 return $file;
480 }
481
482 /**
483 * Returns the currently registered loaders indexed by their corresponding vendor directories.
484 *
485 * @return self[]
486 */
487 public static function getRegisteredLoaders()
488 {
489 return self::$registeredLoaders;
490 }
491
492 /**
493 * @param string $class
494 * @param string $ext
495 * @return string|false
496 */
497 private function findFileWithExtension($class, $ext)
498 {
499 // PSR-4 lookup
500 $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
501
502 $first = $class[0];
503 if (isset($this->prefixLengthsPsr4[$first])) {
504 $subPath = $class;
505 while (false !== $lastPos = strrpos($subPath, '\\')) {
506 $subPath = substr($subPath, 0, $lastPos);
507 $search = $subPath . '\\';
508 if (isset($this->prefixDirsPsr4[$search])) {
509 $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
510 foreach ($this->prefixDirsPsr4[$search] as $dir) {
511 if (file_exists($file = $dir . $pathEnd)) {
512 return $file;
513 }
514 }
515 }
516 }
517 }
518
519 // PSR-4 fallback dirs
520 foreach ($this->fallbackDirsPsr4 as $dir) {
521 if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
522 return $file;
523 }
524 }
525
526 // PSR-0 lookup
527 if (false !== $pos = strrpos($class, '\\')) {
528 // namespaced class name
529 $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
530 . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
531 } else {
532 // PEAR-like class name
533 $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
534 }
535
536 if (isset($this->prefixesPsr0[$first])) {
537 foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
538 if (0 === strpos($class, $prefix)) {
539 foreach ($dirs as $dir) {
540 if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
541 return $file;
542 }
543 }
544 }
545 }
546 }
547
548 // PSR-0 fallback dirs
549 foreach ($this->fallbackDirsPsr0 as $dir) {
550 if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
551 return $file;
552 }
553 }
554
555 // PSR-0 include paths.
556 if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
557 return $file;
558 }
559
560 return false;
561 }
562
563 private static function initializeIncludeClosure(): void
564 {
565 if (self::$includeFile !== null) {
566 return;
567 }
568
569 /**
570 * Scope isolated include.
571 *
572 * Prevents access to $this/self from included files.
573 *
574 * @param string $file
575 * @return void
576 */
577 self::$includeFile = static function($file) {
578 include $file;
579 };
580 }
581 }
582