<?php
 
/**
 
 * @package genericarray
 
 */
 
 
/**
 
 * Generic array loader. Singleton.
 
 */
 
final class ArrayOfGenericLoader {
 
    private static $instance;
 
    
 
    const PREFIX = 'ArrayOf';
 
    
 
    public static function getInstance() {
 
        if (!self::$instance) {
 
            self::$instance = new ArrayOfGenericLoader();
 
        }
 
        return self::$instance;
 
    }
 
    
 
    public $cachedir;
 
    
 
    private function __construct() {
 
        $this->cachedir = dirname(__FILE__) . '/cache';
 
    }
 
    
 
    public function loadClass($classname) {
 
        if (substr($classname, 0, strlen(self::PREFIX)) != self::PREFIX) return false;
 
        if ($this->inCache($classname)) {
 
            $this->loadFromCache($classname);
 
            return true;
 
        }
 
        $this->createGeneric($classname);
 
        return true;
 
    }
 
    
 
    private function inCache($classname) {
 
        if (!file_exists($this->cachedir . '/check.' . $classname . '.php')) return false;
 
        if (!file_exists($this->cachedir . '/' . $classname . '.php')) return false;
 
        return require($this->cachedir . '/check.' . $classname . '.php');
 
    }
 
        
 
    private function loadFromCache($classname) {
 
        require_once $this->cachedir . '/' . $classname . '.php';
 
    }
 
            
 
    private function createGeneric($classname) {
 
        $genericClass = new ReflectionClass(self::PREFIX . 'GenericX');
 
        $genericFile = $genericClass->getFileName();
 
        $genericX = substr($classname, strlen(self::PREFIX));
 
        
 
        $tokens = token_get_all(file_get_contents($genericFile));
 
        $code = '';
 
        foreach ($tokens as $token) {
 
            if (is_array($token)) {
 
                if ($token[0] == T_STRING) {
 
                    $token[1] = str_replace('GenericX', $genericX, $token[1]);
 
                } else if ($token[0] == T_COMMENT || $token[0] == T_DOC_COMMENT) {
 
                    $token[1] = str_replace('GenericX', $genericX, $token[1]);
 
                }
 
                $code .= $token[1];
 
            } else {
 
                $code .= $token;
 
            }
 
        }
 
        
 
        $checkCode  = "<?php\n";
 
        $checkCode .= "if (filemtime('" . addcslashes($genericFile, "'\\") . "') > filemtime(__FILE__)) {\n";
 
        $checkCode .= "    return false;\n";
 
        $checkCode .= "}\n";
 
        $checkCode .= "return true;\n";
 
        
 
        file_put_contents($this->cachedir . '/check.' . $classname . '.php', $checkCode);
 
        if (file_put_contents($this->cachedir . '/' . $classname . '.php', $code)) {
 
            $this->loadFromCache($classname);
 
        } else {
 
            eval("?>$code");
 
        }
 
    }
 
}
 
?>
 
 |