Autoload.php

<?php

namespace Lia\Addon;

class Autoload extends \Lia\Addon
{
    public string $fqn = 'lia:server.autoload';

    /**
     * an key=>value array
     * @key directory
     * @value array of namespaces in the directory
     */
    public $dirs;

    public function init_lia(){
        $this->lia->methods['autoload'] = [$this, 'addDir'];
    }

    public function enable(){
        spl_autoload_register([$this, 'loadClass']);
    }

    public function onAppEnabled(\Lia\AppInterface $app){
        // @TODO handle app being enabled.
        // @TODO probably add an AddonInterface
        // @TODO param type should be \Lia\AppInterface, unless I rename App to something else & AppInterface becomes App.
    }


    /**
     * add a directory to be autoloaded, psr4-ish
     * @param $dir the directory that contains classes
     * @param ...$baseNamespaces a list of namespaces that are found in the root of the dir
     *
     * @usage `$lia->autoload(__DIR__.'/class/');`
     * @usage `$autoload->addDir(__DIR__.'/class/', '\\Tlf');`. `\\Tlf` makes it so a class `\\Tlf\Something` can be autoloaded at `__DIR__.'/class/Something.php'`
     */
    public function addDir($dir,...$baseNamespaces){
        $this->dirs[$dir] = $baseNamespaces;
    }
    
    public function loadClass($class) {
        $this->psr4_autoload($class);
    }

    public function psr4_autoload($class){
        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";
                }
            }
        }
    }

}