Getter.php

<?php

namespace Tiny;

trait Getter {

    static protected function getRails($appDir){
        $rails = [];
        $railDir = $appDir.'/tiny';
        if (is_dir($railDir)){
            $files = scandir($railDir);
            foreach ($files as $file){
                if ($file=='.'||$file=='..'){
                    continue;
                } 
                $path = $railDir.'/'.$file;
                $ext = pathinfo($path,PATHINFO_EXTENSION);
                if ($ext!='php')continue;
                include_once($path);
                $class = self::getClassFromFile($path);
                $interfaces = self::getInterfacesFromClass($class);
                $interfaces = array_combine($interfaces,$interfaces);
                foreach ($interfaces as $interface){
                    $rails[$interface] = $class;
                }
            }
        }
        return $rails;
    }

    static protected function getClassFromFile($file){
        $fp = fopen($file, 'r');
        $class = $namespace = $buffer = '';
        $i = 0;
        while (!$class) {
            if (feof($fp)) break;

            $buffer .= fread($fp, 512);
            $tokens = token_get_all($buffer);

            if (strpos($buffer, '{') === false) continue;

            for (;$i<count($tokens);$i++) {
                if ($tokens[$i][0] === T_NAMESPACE) {
                    for ($j=$i+1;$j<count($tokens); $j++) {
                        if ($tokens[$j][0] === T_STRING) {
                            $namespace .= '\\'.$tokens[$j][1];
                        } else if ($tokens[$j] === '{' || $tokens[$j] === ';') {
                            break;
                        }
                    }
                }

                if ($tokens[$i][0] === T_CLASS) {
                    for ($j=$i+1;$j<count($tokens);$j++) {
                        if ($tokens[$j] === '{') {
                            $class = $tokens[$i+2][1];
                        }
                    }
                }
            }
        }
        if ($class=='')return '';
        return $namespace.'\\'.$class;
        
    }
    static protected function getInterfacesFromClass($class){
        if ($class=='')return [];
        $ref = new \ReflectionClass($class);
        return $ref->getInterfaceNames();
    }

    /**
     * 'getRail' is an old naming idea I came up with and decided not to use. Not sure of new name yet. Note on Dec 10, 2019
     */
    protected function getRail($name,$cargo=NULL){
        $railInterface = 'Tiny\\IFace\\'.$name;
        if (isset($this->rails[$railInterface])){
            $class = $this->rails[$railInterface];
            if ($cargo===NULL)return new $class();
            else return new $class($cargo);
        } 
        $class = '\\Tiny\\'.$name;

        if ($cargo===NULL)return new $class();
        else return new $class($cargo);
    }

}