173 lines
3.9 KiB
PHP
Executable File
173 lines
3.9 KiB
PHP
Executable File
<?php
|
|
|
|
abstract class Engine {
|
|
|
|
abstract function run ( $data = array() );
|
|
|
|
protected static $instances = array();
|
|
|
|
public static function fromFile ( $file, $root = '', $cache = '', $content = '' ) {
|
|
|
|
if ( !$file )
|
|
throw new Exception('No file provided !');
|
|
|
|
// if specified, $root must be an actual directory
|
|
if ( $root && !( $root = realpath($root[0] === DIRECTORY_SEPARATOR ? $root : realpath('.') . DIRECTORY_SEPARATOR . $root) ) )
|
|
throw new Exception(sprintf('Directory "%1$s" for root not found !', $root));
|
|
|
|
// if specified, $cache must be an actual directory
|
|
if ( $cache && !( $cache = realpath($cache[0] === DIRECTORY_SEPARATOR ? $cache : realpath('.') . DIRECTORY_SEPARATOR . $cache) ) )
|
|
throw new Exception(sprintf('Directory "%1$s" for cache not found !', $cache));
|
|
|
|
// if $cache is set, then $root too !!
|
|
if ( $cache && !$root )
|
|
throw new Exception(sprintf('Directory cache "%1$" set but empty root directory provided !', $cache));
|
|
|
|
$file = Path::get($file);
|
|
$filepath = $file->prepend('/', $root);
|
|
$filemirror = $file->prepend($cache);
|
|
$cachepath = Path::get($file . '.php')->prepend($cache);
|
|
$basename = basename($file);
|
|
$dirname = dirname($file);
|
|
|
|
// Process Level cache : not instantiate the same file twice
|
|
if ( !empty(static::$instances[get_called_class()][$filepath->__toString()]) )
|
|
return static::$instances[get_called_class()][$filepath->__toString()];
|
|
|
|
// prepare cache dirctories
|
|
if ( $cache ) {
|
|
$cacheDir = dirname($cachepath);
|
|
if ( !file_exists($cacheDir) )
|
|
mkdir($cacheDir, 0777, 1);
|
|
}
|
|
|
|
/*#BEGIN debug#*/
|
|
if ( file_exists($filepath) )
|
|
$m = filemtime($filepath);
|
|
elseif ( $content && ( !file_exists($filemirror) || $content === file_get_contents($filemirror) ) )
|
|
$m = -1;
|
|
else $m = time();
|
|
if ( $cache && !file_exists($cachepath . $m) ) {
|
|
|
|
if ( file_exists($filemirror) )
|
|
unlink($filemirror);
|
|
if ( file_exists($cachepath) )
|
|
unlink($cachepath);
|
|
|
|
}
|
|
if ( $cache ) file_put_contents($cachepath . $m, $m);
|
|
/*#END debug#*/
|
|
|
|
if ( $cache && file_exists($cachepath) ) {
|
|
|
|
$instance = new static($dirname, $root, $cache, $basename);
|
|
$instance->file = $filemirror;
|
|
$instance->include = $cachepath;
|
|
|
|
} else {
|
|
|
|
if ( file_exists($filepath) )
|
|
$content = file_get_contents($filepath);
|
|
|
|
elseif ( !$content )
|
|
throw new Exception(sprintf('File "%1$s" not found and no content provided !', $filepath));
|
|
|
|
if ( $cache )
|
|
file_put_contents($filemirror, $content);
|
|
|
|
try {
|
|
|
|
$instance = static::fromString($content, $dirname, $root, $cache, $basename);
|
|
|
|
} catch ( Exception $e ) {
|
|
|
|
throw new Exception(sprintf(
|
|
'Error during compilation of file "%1$s" !',
|
|
$filepath
|
|
), 0, $e);
|
|
|
|
}
|
|
|
|
if ( $cache ) {
|
|
|
|
file_put_contents($cachepath, "<?php\n" . $instance->code . "\n?>");
|
|
|
|
$instance->include = $cachepath;
|
|
$instance->code = '';
|
|
$instance->file = $filemirror;
|
|
$instance->source = '';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return static::$instances[get_called_class()][$filepath->__toString()] = $instance;
|
|
|
|
}
|
|
|
|
protected
|
|
// Source code
|
|
$source = '',
|
|
$file = '',
|
|
// Compiled code
|
|
$code = '',
|
|
$include = '',
|
|
// Env
|
|
$dir = '',
|
|
$root = '',
|
|
$cache = '',
|
|
$basename = '';
|
|
|
|
protected function __construct ( $dir, $root = '', $cache = '', $basename = '') {
|
|
|
|
$this->dir = $dir;
|
|
$this->root = $root;
|
|
$this->cache = $cache;
|
|
$this->basename = $basename;
|
|
|
|
}
|
|
|
|
public function getSource () {
|
|
|
|
if ( $this->file )
|
|
return file_get_contents($this->file);
|
|
|
|
return $this->source;
|
|
|
|
}
|
|
|
|
/*** Runtime API ***/
|
|
|
|
public function getDir () {
|
|
|
|
return $this->dir;
|
|
|
|
}
|
|
|
|
public function getRoot () {
|
|
|
|
return $this->root;
|
|
|
|
}
|
|
|
|
public function getCache () {
|
|
|
|
return $this->cache;
|
|
|
|
}
|
|
|
|
public function getFile () {
|
|
|
|
return $this->dir . '/' . $this->basename;
|
|
|
|
}
|
|
|
|
public function getBasename () {
|
|
|
|
return $this->basename;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
?>
|