187 lines
5.7 KiB
PHP
187 lines
5.7 KiB
PHP
<?php
|
|
/**
|
|
* classes/autoloader.php
|
|
*
|
|
* This should provide a simple way to add autoloading.
|
|
*
|
|
* @version 1.0.5
|
|
* @author Joey Kimsey <Joey@thetempusproject.com>
|
|
* @link https://TheTempusProject.com/libraries/Hermes
|
|
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
|
|
*/
|
|
namespace TheTempusProject\Hermes\Classes;
|
|
|
|
class Autoloader {
|
|
protected static $namespaces = [];
|
|
protected $rootFolder = '';
|
|
|
|
/**
|
|
* Automatically requires all the files within a given directory.
|
|
*
|
|
* @param {string} [$directory]
|
|
* @param {bool} [$includeRoot]
|
|
*/
|
|
public function includeFolder( $directory = '', $includeRoot = true ) {
|
|
$base_dir = str_replace( '\\', DIRECTORY_SEPARATOR, $directory );
|
|
$base_dir = str_replace( '/', DIRECTORY_SEPARATOR, $base_dir );
|
|
$base_dir = rtrim( $base_dir, DIRECTORY_SEPARATOR ) . DIRECTORY_SEPARATOR;
|
|
// should require all the files in the specific folder
|
|
if ( $includeRoot ) {
|
|
$base_dir = $this->rootFolder . $base_dir;
|
|
}
|
|
if ( !is_dir( $base_dir ) ) {
|
|
return false;
|
|
}
|
|
$files = scandir( $base_dir );
|
|
array_shift( $files );
|
|
array_shift( $files );
|
|
foreach ( $files as $key => $value ) {
|
|
if ( stripos( $value, '.php' ) ) {
|
|
include_once $base_dir . $value;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Adds a namespace and corresponding directory to the autoload list.
|
|
*
|
|
* @param {string} [$namespace]
|
|
* @param {string} [$directory]
|
|
* @param {bool} [$includeRoot]
|
|
*/
|
|
public function addNamespace( $namespace, $directory = '', $includeRoot = true ) {
|
|
// normalize namespace prefix
|
|
$prefix = trim( $namespace, '\\' ) . '\\';
|
|
|
|
// normalize directory
|
|
$base_dir = str_replace( '\\', DIRECTORY_SEPARATOR, $directory );
|
|
$base_dir = str_replace( '/', DIRECTORY_SEPARATOR, $base_dir );
|
|
$base_dir = rtrim( $base_dir, DIRECTORY_SEPARATOR ) . DIRECTORY_SEPARATOR;
|
|
|
|
if ( $base_dir === DIRECTORY_SEPARATOR ) {
|
|
$base_dir = '';
|
|
}
|
|
|
|
if ( empty( self::$namespaces[ $prefix ] ) ) {
|
|
self::$namespaces[ $prefix ] = [];
|
|
}
|
|
|
|
// retain the base directory for the namespace prefix
|
|
if ( $includeRoot ) {
|
|
$base_dir = $this->rootFolder . $base_dir;
|
|
}
|
|
array_push( self::$namespaces[ $prefix ], $base_dir );
|
|
}
|
|
|
|
/**
|
|
* This is the main method for the autoloader. It will cycle through
|
|
* possible locations and load the first available file.
|
|
*
|
|
* @param {string} [$class]
|
|
*/
|
|
public function loadClass( $class ) {
|
|
$class = trim( $class, '\\' );
|
|
$namespace_array = explode( '\\', $class );
|
|
$class_name = array_pop( $namespace_array );
|
|
$namespace = implode( '\\', $namespace_array ) . '\\';
|
|
|
|
if ( empty( self::$namespaces[ $namespace ] ) ) {
|
|
return false;
|
|
}
|
|
|
|
$file = convertClassNameToFileName( $class_name );
|
|
|
|
$possible_locations = [];
|
|
foreach ( self::$namespaces[ $namespace ] as $key => $folder ) {
|
|
if ( file_exists( $folder . $file ) ) {
|
|
$possible_locations[] = $folder . $file;
|
|
break;
|
|
} elseif ( file_exists( $folder . ucfirst( $file ) ) ) {
|
|
$possible_locations[] = $folder . ucfirst( $file );
|
|
break;
|
|
}
|
|
$newFile = '';
|
|
$exploded = explode( '_', $file );
|
|
foreach ( $exploded as &$value ) {
|
|
$newFile .= ucfirst( $value );
|
|
}
|
|
if ( file_exists( $folder . $newFile ) ) {
|
|
$possible_locations[] = $folder . $newFile;
|
|
break;
|
|
} elseif ( file_exists( $folder . ucfirst( $newFile ) ) ) {
|
|
$possible_locations[] = $folder . ucfirst( $newFile );
|
|
break;
|
|
}
|
|
}
|
|
if ( !empty( $possible_locations ) ) {
|
|
require_once $possible_locations[0];
|
|
return;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Tests the class to see if it can be loaded.
|
|
*
|
|
* @param {string} [$class]
|
|
*/
|
|
public static function testLoad( $class ) {
|
|
$class = trim( $class, '\\' );
|
|
$namespace_array = explode( '\\', $class );
|
|
$class_name = array_pop( $namespace_array );
|
|
$namespace = implode( '\\', $namespace_array ) . '\\';
|
|
|
|
if ( class_exists( $class ) ) {
|
|
return true;
|
|
}
|
|
|
|
if ( empty( self::$namespaces[ $namespace ] ) ) {
|
|
return false;
|
|
}
|
|
|
|
$file = convertClassNameToFileName( $class_name );
|
|
|
|
$possible_locations = [];
|
|
foreach ( self::$namespaces[ $namespace ] as $key => $folder ) {
|
|
if ( file_exists( $folder . $file ) ) {
|
|
$possible_locations[] = $folder . $file;
|
|
}
|
|
}
|
|
|
|
if ( !empty( $possible_locations ) ) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Sets the root folder for file paths.
|
|
*
|
|
* @param {string} [$folder]
|
|
*/
|
|
public function setRootFolder( $folder ) {
|
|
$this->rootFolder = rtrim( $folder, DIRECTORY_SEPARATOR ) . DIRECTORY_SEPARATOR;
|
|
}
|
|
|
|
/**
|
|
* Registers a new autoloader that should serve the currently defined namespaces.
|
|
*/
|
|
public function register() {
|
|
spl_autoload_register( [ $this, 'loadClass' ] );
|
|
}
|
|
|
|
/**
|
|
* Retrieves the currently defined namespaces.
|
|
*/
|
|
public function getNamespaces() {
|
|
return self::$namespaces;
|
|
}
|
|
|
|
/**
|
|
* Retrieves the currently defined root folder.
|
|
*/
|
|
public function getRootFolder() {
|
|
return $this->rootFolder;
|
|
}
|
|
}
|