diff --git a/classes/Autoload.php b/classes/Autoload.php new file mode 100644 index 000000000..520e8996e --- /dev/null +++ b/classes/Autoload.php @@ -0,0 +1,125 @@ + 'path/to/override', 'classnamecore' => 'path/to/class/core') + */ + public $index = array(); + + + protected function __construct() + { + $this->root_dir = dirname(dirname(__FILE__)).'/'; + } + + /** + * + */ + public static function getInstance() + { + if (!Autoload::$instance) + Autoload::$instance = new Autoload(); + + return Autoload::$instance; + } + + public function generateIndex() + { + $classes = array_merge( + $this->getClassesFromDir('classes/', true), + $this->getClassesFromDir('override/classes/', false) + ); + $content = 'root_dir.Autoload::INDEX_FILE; + + if ((file_exists($filename) && is_writable($filename)) || is_writable(dirname($filename))) + file_put_contents($filename, $content); + else + throw new Exception($filename.' is not writable!'); + + $this->index = include_once($this->root_dir.Autoload::INDEX_FILE); + } + + protected function getClassesFromDir($path, $is_core) + { + $classes = array(); + + foreach (scandir($this->root_dir.$path) as $file) + { + if ($file[0] != '.') + { + if (is_dir($this->root_dir.$path.$file)) + $classes = array_merge($classes, $this->getClassesFromDir($path.$file.'/', $is_core)); + else if (substr($file, -4) == '.php') + { + $content = file_get_contents($path.$file); + if (preg_match('#\W((abstract\s+)?class|interface)\s+(?P'.basename($file, '.php').'(Core)?)\s+((extends|implements)\s+[a-z][a-z0-9_]*)?\s*\{#i', $content, $m)) + { + $classes[$m['classname']] = $path.$file; + if (substr($m['classname'], -4) == 'Core') + $classes[substr($m['classname'], 0, -4)] = ''; + } + } + } + } + + return $classes; + } + + /** + * + * + * @param string $classname + */ + public function load($classname) + { + if (!isset($this->index[$classname])) + $this->generateIndex(); + + $is_core = (substr($classname, -4) == 'Core'); + + // If $classname has not core suffix (E.g. Shop, Product) + if (!$is_core) + { + // If requested class does not exist, load associated core class + if (isset($this->index[$classname]) && !$this->index[$classname]) + { + require_once($this->root_dir.$this->index[$classname.'Core']); + if (file_exists($this->root_dir.'override/'.$this->index[$classname.'Core'])) + { + $this->generateIndex(); + require_once($this->root_dir.$this->index[$classname]); + } + else + { + // Since the classname does not exists (we only have a classCore class), we have to emulate the declaration of this class + $class_infos = new ReflectionClass($classname.'Core'); + eval(($class_infos->isAbstract() ? 'abstract ' : '').'class '.$classname.' extends '.$classname.'Core {}'); + } + } + else + { + // request a non Core Class load the associated Core class if exists + if (isset($this->index[$classname.'Core'])) + require_once($this->root_dir.$this->index[$classname.'Core']); + + require_once($this->root_dir.$this->index[$classname]); + } + } + // Call directly ProductCore, ShopCore class + else + require_once($this->root_dir.$this->index[$classname]); + + if (!class_exists($classname, false) && !interface_exists($classname, false)) + throw new Exception('Class not found: '.$classname); + } + +} + diff --git a/config/autoload.php b/config/autoload.php index a18916322..94e14e701 100644 --- a/config/autoload.php +++ b/config/autoload.php @@ -1,6 +1,6 @@ isInterface() && substr($classInfos->name, -4) == 'Core') - eval(($classInfos->isAbstract() ? 'abstract ' : '').'class '.$className.' extends '.$className.'Core {}'); - } - elseif ($file_in_override && !$file_in_classes) - require_once($overrideDir.$className.'.php'); - } - } + Autoload::getInstance()->load($classname); +}