diff --git a/common.php b/common.php index e5f37583..d9c79b8d 100644 --- a/common.php +++ b/common.php @@ -108,3 +108,4 @@ if(isset($_SERVER['HTTP_HOST'])) { } require SYSTEM . 'exception.php'; +require SYSTEM . 'autoload.php'; diff --git a/system/autoload.php b/system/autoload.php new file mode 100644 index 00000000..a13db1db --- /dev/null +++ b/system/autoload.php @@ -0,0 +1,206 @@ +register(); + +// register the base directories for the namespace prefix +$loader->addNamespace('Composer\Semver', LIBS . 'semver'); +$loader->addNamespace('Twig', LIBS . 'Twig'); +/** + * An example of a general-purpose implementation that includes the optional + * functionality of allowing multiple base directories for a single namespace + * prefix. + * + * Given a foo-bar package of classes in the file system at the following + * paths ... + * + * /path/to/packages/foo-bar/ + * src/ + * Baz.php # Foo\Bar\Baz + * Qux/ + * Quux.php # Foo\Bar\Qux\Quux + * tests/ + * BazTest.php # Foo\Bar\BazTest + * Qux/ + * QuuxTest.php # Foo\Bar\Qux\QuuxTest + * + * ... add the path to the class files for the \Foo\Bar\ namespace prefix + * as follows: + * + * register(); + * + * // register the base directories for the namespace prefix + * $loader->addNamespace('Foo\Bar', '/path/to/packages/foo-bar/src'); + * $loader->addNamespace('Foo\Bar', '/path/to/packages/foo-bar/tests'); + * + * The following line would cause the autoloader to attempt to load the + * \Foo\Bar\Qux\Quux class from /path/to/packages/foo-bar/src/Qux/Quux.php: + * + * prefixes[$prefix]) === false) { + $this->prefixes[$prefix] = array(); + } + + // retain the base directory for the namespace prefix + if ($prepend) { + array_unshift($this->prefixes[$prefix], $base_dir); + } else { + array_push($this->prefixes[$prefix], $base_dir); + } + } + + /** + * Loads the class file for a given class name. + * + * @param string $class The fully-qualified class name. + * @return mixed The mapped file name on success, or boolean false on + * failure. + */ + public function loadClass($class) + { + if (0 === strpos($class, 'Twig_')) { + $file = LIBS . 'Twig/' . str_replace(array('_', "\0"), array('/', ''), $class).'.php'; + + if((config('env') === 'dev') && !is_file($file)) { + return false; + } + + require $file; + return false; + } + + // the current namespace prefix + $prefix = $class; + + // work backwards through the namespace names of the fully-qualified + // class name to find a mapped file name + while (false !== $pos = strrpos($prefix, '\\')) { + + // retain the trailing namespace separator in the prefix + $prefix = substr($class, 0, $pos + 1); + + // the rest is the relative class name + $relative_class = substr($class, $pos + 1); + + // try to load a mapped file for the prefix and relative class + $mapped_file = $this->loadMappedFile($prefix, $relative_class); + if ($mapped_file) { + return $mapped_file; + } + + // remove the trailing namespace separator for the next iteration + // of strrpos() + $prefix = rtrim($prefix, '\\'); + } + + // never found a mapped file + return false; + } + + /** + * Load the mapped file for a namespace prefix and relative class. + * + * @param string $prefix The namespace prefix. + * @param string $relative_class The relative class name. + * @return mixed Boolean false if no mapped file can be loaded, or the + * name of the mapped file that was loaded. + */ + protected function loadMappedFile($prefix, $relative_class) + { + // are there any base directories for this namespace prefix? + if (isset($this->prefixes[$prefix]) === false) { + return false; + } + + // look through base directories for this namespace prefix + foreach ($this->prefixes[$prefix] as $base_dir) { + + // replace the namespace prefix with the base directory, + // replace namespace separators with directory separators + // in the relative class name, append with .php + $file = $base_dir + . str_replace('\\', '/', $relative_class) + . '.php'; + + // if the mapped file exists, require it + if ($this->requireFile($file)) { + // yes, we're done + return $file; + } + } + + // never found it + return false; + } + + /** + * If a file exists, require it from the file system. + * + * @param string $file The file to require. + * @return bool True if the file exists, false if not. + */ + protected function requireFile($file) + { + if (config('env') !== 'dev' || file_exists($file)) { + require $file; + return true; + } + return false; + } +} \ No newline at end of file