240 lines
4.5 KiB
PHP
Executable File
240 lines
4.5 KiB
PHP
Executable File
<?php
|
|
|
|
abstract class Provider extends Entity implements IteratorAggregate {
|
|
|
|
protected static
|
|
$type,
|
|
$subType,
|
|
$rootType,
|
|
$parentType,
|
|
$providers = array();
|
|
|
|
final public static function addProviderDir ( $dir, $cache = null ) {
|
|
|
|
static::checkDirectories($dir, $cache);
|
|
|
|
foreach ( scandir($dir) as $name )
|
|
if ( file_exists($dir . '/' . $name . '/provider.php') ) {
|
|
|
|
if ( $cache && !file_exists($cache . '/' . $name) )
|
|
mkdir($cache . '/' . $name, 0777, 1);
|
|
|
|
self::set($name, $dir . '/' . $name, $cache ? $cache . '/' . $name : null);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
final public static function set ( $name, $dir, $cache = '' ) {
|
|
|
|
if ( !empty(self::$providers[$name]) )
|
|
throw new Exception(sprintf(
|
|
'Provider "%1$s" already set !',
|
|
$name
|
|
));
|
|
|
|
static::checkDirectories($dir, $cache);
|
|
|
|
self::$providers[$name] = array($dir, $cache);
|
|
|
|
}
|
|
|
|
final public static function checkDirectories ( $folder, $cache = null ) {
|
|
|
|
if ( !( $exists = file_exists($folder) ) || !is_dir($folder) )
|
|
throw new Exception(sprintf(
|
|
$exists ?
|
|
'Directory "%1$s" doest not exists ! It is a file !' :
|
|
'Directory "%1$s" doest not exists !',
|
|
$folder
|
|
));
|
|
|
|
if ( $cache && ( !( $exists = file_exists($cache) ) || !is_dir($cache) ) )
|
|
throw new Exception(sprintf(
|
|
$exists ?
|
|
'Directory "%1$s" doest not exists ! It is a file !' :
|
|
'Directory "%1$s" doest not exists !',
|
|
$cache
|
|
));
|
|
|
|
}
|
|
|
|
protected static function getInstance ( $name ) {
|
|
|
|
//~ echo sprintf(
|
|
//~ '%1$s::%2$s(%3$s)' . "\n",
|
|
//~ get_called_class(),
|
|
//~ __METHOD__,
|
|
//~ $name
|
|
//~ );
|
|
|
|
if ( empty(self::$providers[$name]) )
|
|
throw new Exception(sprintf(
|
|
'Provider "%1$s" not registered !',
|
|
$name
|
|
));
|
|
|
|
$data = include(self::$providers[$name][0] . '/provider.php');
|
|
|
|
$data['name'] = $name;
|
|
$class = $data['type'];
|
|
|
|
return new $class($data);
|
|
|
|
}
|
|
|
|
abstract protected function build ();
|
|
|
|
protected function __construct ( $data, $parent = null ) {
|
|
|
|
parent::__construct($data, $parent);
|
|
|
|
$this->load();
|
|
|
|
}
|
|
|
|
public function getIterator () {
|
|
|
|
return $this->__get('Model');
|
|
|
|
}
|
|
|
|
protected function load () {
|
|
|
|
// if not in cache
|
|
if ( !$this->loadFromCache() ) {
|
|
|
|
// if no model structure found
|
|
$this->loadFromFiles();
|
|
$this->build();
|
|
|
|
$this->saveToFiles();
|
|
|
|
// merge data for faster access and cache
|
|
$this->saveToCache();
|
|
|
|
}
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
private function loadFromFiles () {
|
|
|
|
$loaded = false;
|
|
$name = $this->getName();
|
|
if ( $dir = self::$providers[$name][0] ) {
|
|
|
|
foreach ( scandir($dir) as $file )
|
|
if ( preg_match('!^([a-zA-Z0-9_]++)\.([a-zA-Z0-9_]++)\.php$!', $file, $m) ) {
|
|
|
|
$loaded = true;
|
|
$this->data['children'][$m[1]][$m[2]] = include($dir . '/' . $file);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/*#BEGIN debug#*/
|
|
return false;
|
|
/*#END debug#*/
|
|
return $loaded;
|
|
|
|
}
|
|
|
|
private function saveToFiles ( ) {
|
|
|
|
$name = $this->getName();
|
|
if ( $dir = self::$providers[$name][0] ) {
|
|
|
|
$dir .= '/auto';
|
|
if ( !file_exists($dir) )
|
|
mkdir($dir, 0777, 1);
|
|
|
|
$provider = $this->data;
|
|
unset($provider['children']);
|
|
phpize($provider, $dir . '/provider.php');
|
|
|
|
foreach ( $this->data['children'] as $type => $instances )
|
|
foreach ( $instances as $k => $instance )
|
|
phpize($instance, sprintf(
|
|
'%1$s/%2$s.%3$s.php',
|
|
$dir,
|
|
$type,
|
|
$k
|
|
));
|
|
|
|
}
|
|
|
|
//~ if ( $dir = self::$providers[$name][1] ) {
|
|
|
|
//~ if ( !file_exists($dir = dirname($this->cachePath) . '/' . $this->getName()) )
|
|
//~ mkdir($dir, 0770, 1);
|
|
|
|
//~ foreach ( $props as $f )
|
|
//~ phpize($this->$f, $dir . '/' . $f . '.php');
|
|
|
|
//~ }
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
private function loadFromCache ( ) {
|
|
|
|
if ( $cache = self::$providers[$name = $this->getName()][1] ) {
|
|
|
|
$cacheFile = sprintf(
|
|
'%1$s/provider.php',
|
|
$cache
|
|
);
|
|
|
|
/*#BEGIN debug#*/
|
|
//~ // clear the cache if it is.
|
|
if ( file_exists($cacheFile) )
|
|
unlink($cacheFile);
|
|
|
|
/*#END debug#*/
|
|
|
|
$cached = null;
|
|
if ( file_exists($cacheFile) )
|
|
$cached = include($cacheFile);
|
|
|
|
// restore the cache
|
|
if ( $cached ) {
|
|
|
|
$this->data = $cached;
|
|
|
|
$cached = null;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
private function saveToCache ( ) {
|
|
|
|
// Cache the merged model data
|
|
if ( $cache = self::$providers[$name = $this->getName()][1] ) {
|
|
|
|
$cacheFile = sprintf(
|
|
'%1$s/provider.php',
|
|
$cache
|
|
);
|
|
|
|
phpize($this->data, $cacheFile);
|
|
|
|
}
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
?>
|