sfAutoload.class.php 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. <?php
  2. /*
  3. * This file is part of the symfony package.
  4. * (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
  5. *
  6. * For the full copyright and license information, please view the LICENSE
  7. * file that was distributed with this source code.
  8. */
  9. /**
  10. * sfAutoload class.
  11. *
  12. * This class is a singleton as PHP seems to be unable to register 2 autoloaders that are instances
  13. * of the same class (why?).
  14. *
  15. * @package symfony
  16. * @subpackage autoload
  17. * @author Fabien Potencier <fabien.potencier@symfony-project.com>
  18. * @version SVN: $Id: sfAutoload.class.php 17858 2009-05-01 21:22:50Z FabianLange $
  19. */
  20. class sfAutoload
  21. {
  22. static protected
  23. $freshCache = false,
  24. $instance = null;
  25. protected
  26. $overriden = array(),
  27. $classes = array();
  28. protected function __construct()
  29. {
  30. }
  31. /**
  32. * Retrieves the singleton instance of this class.
  33. *
  34. * @return sfCoreAutoload A sfCoreAutoload implementation instance.
  35. */
  36. static public function getInstance()
  37. {
  38. if (!isset(self::$instance))
  39. {
  40. self::$instance = new sfAutoload();
  41. }
  42. return self::$instance;
  43. }
  44. /**
  45. * Register sfAutoload in spl autoloader.
  46. *
  47. * @return void
  48. */
  49. static public function register()
  50. {
  51. ini_set('unserialize_callback_func', 'spl_autoload_call');
  52. if (false === spl_autoload_register(array(self::getInstance(), 'autoload')))
  53. {
  54. throw new sfException(sprintf('Unable to register %s::autoload as an autoloading method.', get_class(self::getInstance())));
  55. }
  56. }
  57. /**
  58. * Unregister sfAutoload from spl autoloader.
  59. *
  60. * @return void
  61. */
  62. static public function unregister()
  63. {
  64. spl_autoload_unregister(array(self::getInstance(), 'autoload'));
  65. }
  66. public function setClassPath($class, $path)
  67. {
  68. $this->overriden[$class] = $path;
  69. $this->classes[$class] = $path;
  70. }
  71. public function getClassPath($class)
  72. {
  73. return isset($this->classes[$class]) ? $this->classes[$class] : null;
  74. }
  75. public function reloadClasses($force = false)
  76. {
  77. // only (re)load the autoloading cache once per request
  78. if (self::$freshCache)
  79. {
  80. return;
  81. }
  82. $configuration = sfProjectConfiguration::getActive();
  83. if (!$configuration || !$configuration instanceof sfApplicationConfiguration)
  84. {
  85. return;
  86. }
  87. self::$freshCache = true;
  88. if (file_exists($configuration->getConfigCache()->getCacheName('config/autoload.yml')))
  89. {
  90. self::$freshCache = false;
  91. if ($force)
  92. {
  93. unlink($configuration->getConfigCache()->getCacheName('config/autoload.yml'));
  94. }
  95. }
  96. $file = $configuration->getConfigCache()->checkConfig('config/autoload.yml');
  97. $this->classes = include($file);
  98. foreach ($this->overriden as $class => $path)
  99. {
  100. $this->classes[$class] = $path;
  101. }
  102. }
  103. /**
  104. * Handles autoloading of classes that have been specified in autoload.yml.
  105. *
  106. * @param string $class A class name.
  107. *
  108. * @return boolean Returns true if the class has been loaded
  109. */
  110. public function autoload($class)
  111. {
  112. // load the list of autoload classes
  113. if (!$this->classes)
  114. {
  115. self::reloadClasses();
  116. }
  117. return self::loadClass($class);
  118. }
  119. public function autoloadAgain($class)
  120. {
  121. self::reloadClasses(true);
  122. return self::loadClass($class);
  123. }
  124. /**
  125. * Tries to load a class that has been specified in autoload.yml.
  126. *
  127. * @param string $class A class name.
  128. *
  129. * @return boolean Returns true if the class has been loaded
  130. */
  131. public function loadClass($class)
  132. {
  133. // class already exists
  134. if (class_exists($class, false) || interface_exists($class, false))
  135. {
  136. return true;
  137. }
  138. // we have a class path, let's include it
  139. if (isset($this->classes[$class]))
  140. {
  141. require($this->classes[$class]);
  142. return true;
  143. }
  144. // see if the file exists in the current module lib directory
  145. // must be in a module context
  146. if (sfContext::hasInstance() && ($module = sfContext::getInstance()->getModuleName()) && isset($this->classes[$module.'/'.$class]))
  147. {
  148. require($this->classes[$module.'/'.$class]);
  149. return true;
  150. }
  151. return false;
  152. }
  153. }