/monica/monica/vendor/zendframework/zendframework/library/Zend/Loader/AutoloaderFactory.php

https://bitbucket.org/alexandretaz/maniac_divers · PHP · 222 lines · 113 code · 22 blank · 87 comment · 19 complexity · dbd96db561928fb53010c13a774a4a2e MD5 · raw file

  1. <?php
  2. /**
  3. * Zend Framework (http://framework.zend.com/)
  4. *
  5. * @link http://github.com/zendframework/zf2 for the canonical source repository
  6. * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
  7. * @license http://framework.zend.com/license/new-bsd New BSD License
  8. */
  9. namespace Zend\Loader;
  10. use ReflectionClass;
  11. use Traversable;
  12. require_once __DIR__ . '/SplAutoloader.php';
  13. if (class_exists('Zend\Loader\AutoloaderFactory')) {
  14. return;
  15. }
  16. abstract class AutoloaderFactory
  17. {
  18. const STANDARD_AUTOLOADER = 'Zend\Loader\StandardAutoloader';
  19. /**
  20. * @var array All autoloaders registered using the factory
  21. */
  22. protected static $loaders = array();
  23. /**
  24. * @var StandardAutoloader StandardAutoloader instance for resolving
  25. * autoloader classes via the include_path
  26. */
  27. protected static $standardAutoloader;
  28. /**
  29. * Factory for autoloaders
  30. *
  31. * Options should be an array or Traversable object of the following structure:
  32. * <code>
  33. * array(
  34. * '<autoloader class name>' => $autoloaderOptions,
  35. * )
  36. * </code>
  37. *
  38. * The factory will then loop through and instantiate each autoloader with
  39. * the specified options, and register each with the spl_autoloader.
  40. *
  41. * You may retrieve the concrete autoloader instances later using
  42. * {@link getRegisteredAutoloaders()}.
  43. *
  44. * Note that the class names must be resolvable on the include_path or via
  45. * the Zend library, using PSR-0 rules (unless the class has already been
  46. * loaded).
  47. *
  48. * @param array|Traversable $options (optional) options to use. Defaults to Zend\Loader\StandardAutoloader
  49. * @return void
  50. * @throws Exception\InvalidArgumentException for invalid options
  51. * @throws Exception\InvalidArgumentException for unloadable autoloader classes
  52. * @throws Exception\DomainException for autoloader classes not implementing SplAutoloader
  53. */
  54. public static function factory($options = null)
  55. {
  56. if (null === $options) {
  57. if (!isset(static::$loaders[static::STANDARD_AUTOLOADER])) {
  58. $autoloader = static::getStandardAutoloader();
  59. $autoloader->register();
  60. static::$loaders[static::STANDARD_AUTOLOADER] = $autoloader;
  61. }
  62. // Return so we don't hit the next check's exception (we're done here anyway)
  63. return;
  64. }
  65. if (!is_array($options) && !($options instanceof Traversable)) {
  66. require_once __DIR__ . '/Exception/InvalidArgumentException.php';
  67. throw new Exception\InvalidArgumentException(
  68. 'Options provided must be an array or Traversable'
  69. );
  70. }
  71. foreach ($options as $class => $autoloaderOptions) {
  72. if (!isset(static::$loaders[$class])) {
  73. $autoloader = static::getStandardAutoloader();
  74. if (!class_exists($class) && !$autoloader->autoload($class)) {
  75. require_once 'Exception/InvalidArgumentException.php';
  76. throw new Exception\InvalidArgumentException(
  77. sprintf('Autoloader class "%s" not loaded', $class)
  78. );
  79. }
  80. if (!static::isSubclassOf($class, 'Zend\Loader\SplAutoloader')) {
  81. require_once 'Exception/InvalidArgumentException.php';
  82. throw new Exception\InvalidArgumentException(
  83. sprintf('Autoloader class %s must implement Zend\\Loader\\SplAutoloader', $class)
  84. );
  85. }
  86. if ($class === static::STANDARD_AUTOLOADER) {
  87. $autoloader->setOptions($autoloaderOptions);
  88. } else {
  89. $autoloader = new $class($autoloaderOptions);
  90. }
  91. $autoloader->register();
  92. static::$loaders[$class] = $autoloader;
  93. } else {
  94. static::$loaders[$class]->setOptions($autoloaderOptions);
  95. }
  96. }
  97. }
  98. /**
  99. * Get an list of all autoloaders registered with the factory
  100. *
  101. * Returns an array of autoloader instances.
  102. *
  103. * @return array
  104. */
  105. public static function getRegisteredAutoloaders()
  106. {
  107. return static::$loaders;
  108. }
  109. /**
  110. * Retrieves an autoloader by class name
  111. *
  112. * @param string $class
  113. * @return SplAutoloader
  114. * @throws Exception\InvalidArgumentException for non-registered class
  115. */
  116. public static function getRegisteredAutoloader($class)
  117. {
  118. if (!isset(static::$loaders[$class])) {
  119. require_once 'Exception/InvalidArgumentException.php';
  120. throw new Exception\InvalidArgumentException(sprintf('Autoloader class "%s" not loaded', $class));
  121. }
  122. return static::$loaders[$class];
  123. }
  124. /**
  125. * Unregisters all autoloaders that have been registered via the factory.
  126. * This will NOT unregister autoloaders registered outside of the fctory.
  127. *
  128. * @return void
  129. */
  130. public static function unregisterAutoloaders()
  131. {
  132. foreach (static::getRegisteredAutoloaders() as $class => $autoloader) {
  133. spl_autoload_unregister(array($autoloader, 'autoload'));
  134. unset(static::$loaders[$class]);
  135. }
  136. }
  137. /**
  138. * Unregister a single autoloader by class name
  139. *
  140. * @param string $autoloaderClass
  141. * @return bool
  142. */
  143. public static function unregisterAutoloader($autoloaderClass)
  144. {
  145. if (!isset(static::$loaders[$autoloaderClass])) {
  146. return false;
  147. }
  148. $autoloader = static::$loaders[$autoloaderClass];
  149. spl_autoload_unregister(array($autoloader, 'autoload'));
  150. unset(static::$loaders[$autoloaderClass]);
  151. return true;
  152. }
  153. /**
  154. * Get an instance of the standard autoloader
  155. *
  156. * Used to attempt to resolve autoloader classes, using the
  157. * StandardAutoloader. The instance is marked as a fallback autoloader, to
  158. * allow resolving autoloaders not under the "Zend" namespace.
  159. *
  160. * @return SplAutoloader
  161. */
  162. protected static function getStandardAutoloader()
  163. {
  164. if (null !== static::$standardAutoloader) {
  165. return static::$standardAutoloader;
  166. }
  167. if (!class_exists(static::STANDARD_AUTOLOADER)) {
  168. // Extract the filename from the classname
  169. $stdAutoloader = substr(strrchr(static::STANDARD_AUTOLOADER, '\\'), 1);
  170. require_once __DIR__ . "/$stdAutoloader.php";
  171. }
  172. $loader = new StandardAutoloader();
  173. static::$standardAutoloader = $loader;
  174. return static::$standardAutoloader;
  175. }
  176. /**
  177. * Checks if the object has this class as one of its parents
  178. *
  179. * @see https://bugs.php.net/bug.php?id=53727
  180. * @see https://github.com/zendframework/zf2/pull/1807
  181. *
  182. * @param string $className
  183. * @param string $type
  184. * @return bool
  185. */
  186. protected static function isSubclassOf($className, $type)
  187. {
  188. if (is_subclass_of($className, $type)) {
  189. return true;
  190. }
  191. if (version_compare(PHP_VERSION, '5.3.7', '>=')) {
  192. return false;
  193. }
  194. if (!interface_exists($type)) {
  195. return false;
  196. }
  197. $r = new ReflectionClass($className);
  198. return $r->implementsInterface($type);
  199. }
  200. }