* @copyright 2019 WPTRT * @license https://www.gnu.org/licenses/gpl-2.0.html GPL-2.0-or-later * @link https://github.com/WPTRT/autoload */ namespace WPTRT\Autoload; class Loader { /** * Array of loaders. * * @since 1.0.0 * @access protected * @var array */ protected $loaders = []; /** * Adds a new prefix and path to load. * * @since 1.0.0 * @access public * @param string $prefix Namespace prefix. * @param array|string $paths Absolute path(s) where to look for classes. * @return void */ public function add( $prefix, $paths ) { foreach ( (array) $paths as $path ) { $this->loaders[ $prefix ][] = $path; } } /** * Removes a loader by prefix or prefix + path. * * @since 1.0.0 * @access public * @param string $prefix Namespace prefix. * @param string $path Absolute path. * @return void */ public function remove( $prefix, $path = '' ) { // Remove specific loader if both the prefix and path are provided. if ( $path ) { if ( $this->has( $prefix, $path ) ) { $key = array_search( $path, $this->loaders[ $prefix ], true ); unset( $this->loaders[ $prefix ][ $key ] ); } return; } // Remove all loaders for a prefix if no path is provided. if ( $this->has( $prefix ) ) { unset( $this->loaders[ $prefix ] ); } } /** * Checks if a loader is already added. * * @since 1.0.0 * @access public * @param string $prefix Namespace prefix. * @param string $path Absolute path. * @return bool */ public function has( $prefix, $path = '' ) { if ( $path ) { return isset( $this->loaders[ $prefix ] ) && in_array( $path, $this->loaders[ $prefix ], true ); } return isset( $this->loaders[ $prefix ] ); } /** * Registers all loaders. * * @since 1.0.0 * @access public * @return void */ public function register() { if ( $this->loaders ) { spl_autoload_register( function( $class ) { $this->load( $class ); }, true, true ); } } /** * Loads a class if it's within the given namespace. * * @since 1.0.0 * @access protected * @param string $class Fully-qualified class name. * @return void */ protected function load( $class ) { foreach ( $this->loaders as $prefix => $paths ) { // Continue if the class is not in our namespace. if ( 0 !== strpos( $class, $prefix ) ) { continue; } // Build a class filename to append to the path. $suffix = ltrim( str_replace( $prefix, '', $class ), '\\' ); $suffix = DIRECTORY_SEPARATOR . str_replace( '\\', DIRECTORY_SEPARATOR, $suffix ) . '.php'; // Loop through the paths to see if we can find the file // for the class. foreach ( $paths as $path ) { // Load the class file if it exists and return. if ( file_exists( $file = realpath( $path ) . $suffix ) ) { include $file; return; } } } } }