/**
* Gazelle Autoload System.
* @author Michael
*/
class Loader extends ReadOnlyArray implements FileLibrary {
/**
* When pulled from cache we relink with the PHP autoload service.
*/
public function unserialize($data) {
parent::unserialize($data);
spl_autoload_register(array($this, 'find'), true);
}
/**
* As we go to cache unlink from the autoload service.
*/
public function serialize() {
spl_autoload_unregister(array($this, 'find'));
return parent::serialize();
}
/**
* Determine if a class is available for loading.
*
* NOTE BENE -- This is NOT a replacement for class_exists.
* That function, if called, will hit this autoloader and
* run the find method below - loading the class if it is
* found unless false is passed as the second parameter, in
* which case none of the autoloaders will be invoked before
* class_exists returns its response. This method allows you
* to check if the class is *available* for loading, but
* doesn't load it. The core framework uses this as a sneaky
* way of setting an error flag - if the ErrorHandler class
* got loaded then there are errors, but if it wasn't then
* there where none - hence the load state of that class
* itself is a flag.
*
* @implements FileLibrary
* @param string $class
*/
public function exists( $class ) {
return $this->findClass($class, false);
}
/**
* Responder to the PHP Autoload service. While this can be called
* to load the class without using the autoload service,
* the only time this should be necessary is if several
* autoloaders are in use and their stack order is unknown;
* or more likely - by the test system.
*
* @implements FileLibrary
* @param string $class
*/
public function find( $class ) {
return $this->findClass($class, true);
}
/**
* Find a class and if instructed to do so load it.
*
* @param $path // Path of class to load.
* @param $load // Do we actually load it?
*/
protected function findClass( $path, $load ) {
$haystack = $this->getArrayCopy();
$needles = explode("\\", $path);
do {
$needle = array_shift($needles);
if (!isset($haystack[$needle])) {
break;
} else if (is_array($haystack[$needle])) {
$haystack = $haystack[$needle];
continue;
} else if (file_exists($haystack[$needle])) {
if ($load) {
require_once ( $haystack[$needle] );
}
return true;
}
} while (count($needles) > 0);
/*
* We failed find the requested class. We're in trouble.
* First, return false if not loading or if we're not
* the only registered autoloader.
*/
if ( $load == false || count(spl_autoload_functions()) > 1) {
return false;
}
// Uh oh... Well, is our FatalException object present, cause
// we'd rather use that.
if ( $this->exists("Gazelle\\FatalException")) {
throw new FatalException("Unable to load requested class {$path}");
}
// No? Well core exception it is then.
throw new \Exception("Unable to load requested class {$path}");
}
}
Bookmarks