<?php
namespace Lia\Compo;
class Autoloader extends \Lia\Compo
{
/**
* Directories from which to PSR-4 style load
*/
protected $dirs = [];
/**
* Callables to use as autoloaders
*/
protected $loaders = [];
public function onCreate(){
spl_autoload_register([$this, 'loadClass']);
}
public function onReady(){
$lia = $this->lia;
$lia->addApi('lia:autoload.addDir', [$this, 'autoload']);
$lia->addApiMethod('lia:autoload.addDir', 'autoload');
$lia->addApi('lia:autoload.addCallback',[$this,'addAutoloader']);
$lia->addApiMethod('lia:autoload.addCallback', 'addAutoloader');
$lia->addApi('lia:autoload.addFromPrefixFunc', [$this, 'addAutoloaderFromPrefix']);
$lia->addApiPrefix('lia:autoload.addFromPrefixFunc', 'autoload');
}
public function autoload($directory, $baseNamespaces=[]){
$this->addDir($directory, ...$baseNamespaces);
}
public function addAutoloader($callback){
//@TODO Consider adding check to see if autoloader is callable. Small performance hit, but better feedback to Liaison users
$this->loaders[] = $callback;
}
public function addAutoloaderFromPrefix($key, $callback){
return $this->lia->api('lia:autoload.addCallback', $callback);
}
public function addDir($dir,...$baseNamespaces){
$this->dirs[$dir] = $baseNamespaces;
}
public function loadClass($class) {
// @TODO provide a classmap style loader that doesn't require proper namespacing
foreach ($this->loaders as $loader){
$loader($class);
if (class_exists($class, false))return;
}
foreach ($this->dirs as $dir=>$namespaces){
$namespaces[] = '';
foreach ($namespaces as $ns){
//@TODO maybe improve the performance of namespace checking??
if (substr($ns,0,1)=='\\')$ns = substr($ns,1);
if ($ns!=''&&strpos($class,$ns)!==0)continue;
$classPath = str_replace('\\','/',substr($class,strlen($ns))).'.php';
if (file_exists($file = $dir.'/'.$classPath)){
require_once($file);
return;
} else {
//DEBUG
// echo $file."\n";
}
}
}
}
}