. * * The copright holder may be reached by emailing john@johnkleijn.nl */ require_once 'Phreamp/Controller/Loader/Exception.php'; /** * Singleton Loader class * * WARNING: If the class you are trying to load contains parse errors, * execution will stop without error feedback. * */ class Phreamp_Loader { /** * Static instance * * @var Phreamp_Loader */ private static $_self; /** * Queue of directories to search when includepath doesn't resolve * * @var array */ private $_dirs = array(); /** * Get Singleton Instance * * @return Phreamp_Loader */ public static function getInstance() { if(!self::$_self) { self::$_self = new self(); } return self::$_self; } /** * Singleton constructor * */ private function __construct() {} /** * Cloning not allowed * */ private function __clone() {} /** * Load a class unless loaded * * @param string $className * @return void */ public static function load($className) { if(!class_exists($className, false)) { self::getInstance()->_doLoad($className); } } /** * Load a class that wasn't loaded yet * * @param string $className * @return void */ public static function autoload($className) { self::getInstance()->_doLoad($className); } /** * Set directories to use besides includepath * * @param array $dirs */ public function setDirectories(array $dirs) { foreach($dirs as $dir) { if(!is_dir($dir)) { throw new Phreamp_Loader_Exception("Directory $dir does not exist"); } } $this->_dirs = $dirs; } /** * Register autoload * */ public static function registerAutoload() { spl_autoload_register(array('Phreamp_Loader', 'autoload')); } /** * Load a class * * @param string $className * * @throws Phreamp_Loader_Exception */ private function _doLoad($className) { /** * Try simply including the file */ $relativePath = $this->_getRelativePath($className); @include_once $relativePath; /** * Class not found? */ if(!class_exists($className, false)) { try { $absolutePath = $this->_findAbsolutePath($relativePath); /** * Try again */ include_once $absolutePath; if(!class_exists($className, false)) { throw new Phreamp_Loader_Exception("File '$absolutePath' was loaded, class '$className' not found"); } } catch (Phreamp_Loader_Exception $e) { throw new Phreamp_Loader_Exception("Class '$className'' not found: {$e->getMessage()}"); } } } /** * Translate class name to path * * @param string $className * @return string */ private function _getRelativePath($className) { return str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php'; } /** * Try to find pathn in directories set * * @param string $relativePath * @throws Phreamp_Loader_Exception * @return string */ private function _findAbsolutePath($relativePath) { if(!is_readable($relativePath)) { foreach($this->_dirs as $dir) { if(is_readable($dir . DIRECTORY_SEPARATOR . $relativePath)) { return $dir . DIRECTORY_SEPARATOR . $relativePath; } } } else { return $relativePath; } throw new Phreamp_Loader_Exception("Relative path '$relativePath'' could not be resolved"); } }