Files
hermes/classes/autoloader.php
Joey Kimsey 4dbea74e5f Cleanup
Improved readme
removed contributing and code of conduct as they are basically just fluff when no one knows this repo exists
removed composer.lock because this repo doesn't install anything to lock
update copywrite to 2025
composer update to description
comments
2025-02-02 07:14:21 -05:00

187 lines
5.7 KiB
PHP

<?php
/**
* classes/autoloader.php
*
* This should provide a simple way to add autoloading.
*
* @version 1.1
* @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;
}
}