191 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			PHP
		
	
	
			
		
		
	
	
			191 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			PHP
		
	
	
| <?php
 | |
| 
 | |
| namespace Doctrine\Common\Annotations;
 | |
| 
 | |
| use function array_key_exists;
 | |
| use function array_merge;
 | |
| use function class_exists;
 | |
| use function in_array;
 | |
| use function is_file;
 | |
| use function str_replace;
 | |
| use function stream_resolve_include_path;
 | |
| use function strpos;
 | |
| 
 | |
| use const DIRECTORY_SEPARATOR;
 | |
| 
 | |
| final class AnnotationRegistry
 | |
| {
 | |
|     /**
 | |
|      * A map of namespaces to use for autoloading purposes based on a PSR-0 convention.
 | |
|      *
 | |
|      * Contains the namespace as key and an array of directories as value. If the value is NULL
 | |
|      * the include path is used for checking for the corresponding file.
 | |
|      *
 | |
|      * This autoloading mechanism does not utilize the PHP autoloading but implements autoloading on its own.
 | |
|      *
 | |
|      * @var string[][]|string[]|null[]
 | |
|      */
 | |
|     private static $autoloadNamespaces = [];
 | |
| 
 | |
|     /**
 | |
|      * A map of autoloader callables.
 | |
|      *
 | |
|      * @var callable[]
 | |
|      */
 | |
|     private static $loaders = [];
 | |
| 
 | |
|     /**
 | |
|      * An array of classes which cannot be found
 | |
|      *
 | |
|      * @var null[] indexed by class name
 | |
|      */
 | |
|     private static $failedToAutoload = [];
 | |
| 
 | |
|     /**
 | |
|      * Whenever registerFile() was used. Disables use of standard autoloader.
 | |
|      *
 | |
|      * @var bool
 | |
|      */
 | |
|     private static $registerFileUsed = false;
 | |
| 
 | |
|     public static function reset(): void
 | |
|     {
 | |
|         self::$autoloadNamespaces = [];
 | |
|         self::$loaders            = [];
 | |
|         self::$failedToAutoload   = [];
 | |
|         self::$registerFileUsed   = false;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Registers file.
 | |
|      *
 | |
|      * @deprecated This method is deprecated and will be removed in
 | |
|      *             doctrine/annotations 2.0. Annotations will be autoloaded in 2.0.
 | |
|      */
 | |
|     public static function registerFile(string $file): void
 | |
|     {
 | |
|         self::$registerFileUsed = true;
 | |
| 
 | |
|         require_once $file;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Adds a namespace with one or many directories to look for files or null for the include path.
 | |
|      *
 | |
|      * Loading of this namespaces will be done with a PSR-0 namespace loading algorithm.
 | |
|      *
 | |
|      * @deprecated This method is deprecated and will be removed in
 | |
|      *             doctrine/annotations 2.0. Annotations will be autoloaded in 2.0.
 | |
|      *
 | |
|      * @phpstan-param string|list<string>|null $dirs
 | |
|      */
 | |
|     public static function registerAutoloadNamespace(string $namespace, $dirs = null): void
 | |
|     {
 | |
|         self::$autoloadNamespaces[$namespace] = $dirs;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Registers multiple namespaces.
 | |
|      *
 | |
|      * Loading of this namespaces will be done with a PSR-0 namespace loading algorithm.
 | |
|      *
 | |
|      * @deprecated This method is deprecated and will be removed in
 | |
|      *             doctrine/annotations 2.0. Annotations will be autoloaded in 2.0.
 | |
|      *
 | |
|      * @param string[][]|string[]|null[] $namespaces indexed by namespace name
 | |
|      */
 | |
|     public static function registerAutoloadNamespaces(array $namespaces): void
 | |
|     {
 | |
|         self::$autoloadNamespaces = array_merge(self::$autoloadNamespaces, $namespaces);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Registers an autoloading callable for annotations, much like spl_autoload_register().
 | |
|      *
 | |
|      * NOTE: These class loaders HAVE to be silent when a class was not found!
 | |
|      * IMPORTANT: Loaders have to return true if they loaded a class that could contain the searched annotation class.
 | |
|      *
 | |
|      * @deprecated This method is deprecated and will be removed in
 | |
|      *             doctrine/annotations 2.0. Annotations will be autoloaded in 2.0.
 | |
|      */
 | |
|     public static function registerLoader(callable $callable): void
 | |
|     {
 | |
|         // Reset our static cache now that we have a new loader to work with
 | |
|         self::$failedToAutoload = [];
 | |
|         self::$loaders[]        = $callable;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Registers an autoloading callable for annotations, if it is not already registered
 | |
|      *
 | |
|      * @deprecated This method is deprecated and will be removed in
 | |
|      *             doctrine/annotations 2.0. Annotations will be autoloaded in 2.0.
 | |
|      */
 | |
|     public static function registerUniqueLoader(callable $callable): void
 | |
|     {
 | |
|         if (in_array($callable, self::$loaders, true)) {
 | |
|             return;
 | |
|         }
 | |
| 
 | |
|         self::registerLoader($callable);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Autoloads an annotation class silently.
 | |
|      */
 | |
|     public static function loadAnnotationClass(string $class): bool
 | |
|     {
 | |
|         if (class_exists($class, false)) {
 | |
|             return true;
 | |
|         }
 | |
| 
 | |
|         if (array_key_exists($class, self::$failedToAutoload)) {
 | |
|             return false;
 | |
|         }
 | |
| 
 | |
|         foreach (self::$autoloadNamespaces as $namespace => $dirs) {
 | |
|             if (strpos($class, $namespace) !== 0) {
 | |
|                 continue;
 | |
|             }
 | |
| 
 | |
|             $file = str_replace('\\', DIRECTORY_SEPARATOR, $class) . '.php';
 | |
| 
 | |
|             if ($dirs === null) {
 | |
|                 $path = stream_resolve_include_path($file);
 | |
|                 if ($path) {
 | |
|                     require $path;
 | |
| 
 | |
|                     return true;
 | |
|                 }
 | |
|             } else {
 | |
|                 foreach ((array) $dirs as $dir) {
 | |
|                     if (is_file($dir . DIRECTORY_SEPARATOR . $file)) {
 | |
|                         require $dir . DIRECTORY_SEPARATOR . $file;
 | |
| 
 | |
|                         return true;
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         foreach (self::$loaders as $loader) {
 | |
|             if ($loader($class) === true) {
 | |
|                 return true;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         if (
 | |
|             self::$loaders === [] &&
 | |
|             self::$autoloadNamespaces === [] &&
 | |
|             self::$registerFileUsed === false &&
 | |
|             class_exists($class)
 | |
|         ) {
 | |
|             return true;
 | |
|         }
 | |
| 
 | |
|         self::$failedToAutoload[$class] = null;
 | |
| 
 | |
|         return false;
 | |
|     }
 | |
| }
 |