A super easy PHP Framework for web development! https://github.com/exacti/phacil-framework
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

571 lines
12 KiB

6 years ago
<?php
/*
* Copyright © 2021 ExacTI Technology Solutions. All rights reserved.
* GPLv3 General License.
* https://exacti.com.br
* Phacil PHP Framework - https://github.com/exacti/phacil-framework
*/
6 years ago
namespace Phacil\Framework;
/**
* Autoload class for Phacil Framework
*
* @package Phacil\Framework
* @since 2.0.0
*/
class AutoLoad {
/**
*
* @var array|null
*/
private static $namespace = null;
/**
*
* @var array|null
*/
private static $namespaceWithoutPrefix;
/**
*
* @var string
*/
private static $class = null;
private static $subCallClass = [];
/**
*
* @var string
*/
private static $classNative;
/**
* Config class
*/
const CONFIG_CLASS = "Phacil\Framework\Config";
/**
*
* @var \Phacil\Framework\AutoLoad
*/
private static $instance = null;
/**
*
* @var array
*/
protected $loadedClasses = array();
/**
*
* @var bool
*/
private static $composerLoaded = false;
/**
*
* @var array
*/
private static $allowed = [
'log',
'front',
'controller',
'loader',
'model',
'registry',
'document',
'response',
'classes',
'abstracthelper',
3 years ago
'interfaces\\front',
'interfaces\\loader',
'interfaces\\action',
'traits\\action',
'interfaces\\databases',
'interfaces\\serializer',
'exception',
'render',
'debug',
'restful'
];
/**
*
* @var string[]
*/
private static $legacy = [
'Controller',
'Model',
'Document',
'Captcha',
'Caches',
'Pagination',
'Request',
'Mail',
'Translate',
'Encryption'
];
function __construct() {
}
/**
* Load SPL Autoloader
*
* @return bool
* @throws \TypeError
*/
static public function run() {
return spl_autoload_register(['self', 'load']);
}
/**
*
* @return bool
*/
static public function checkComposerLoader() {
return self::$composerLoaded;
}
/**
* Resolve file path
*
* @param string $file
* @return false|\SplFileInfo
*/
static protected function fileResolver($file) {
$splFile = new \SplFileInfo($file);
if(!$splFile->isReadable()) return false;
return $splFile;
}
/**
*
* @param string|\SplFileInfo $file
* @return bool|void
*/
static protected function loadClassFile($file){
$file = ($file instanceof \SplFileInfo) ? $file : self::fileResolver($file);
if($file){
if(self::required($file)) {
self::getInstance()->loadedClasses[] = count(self::$subCallClass) > 1 ? self::$subCallClass : self::$class;
self::$subCallClass = [];
return true;
}
} else {
return false;
}
}
/**
*
* @param \SplFileInfo $file
* @return mixed
*/
static public function required(\SplFileInfo $file) {
return require_once($file->getPathname());
}
/**
*
* @return string[]
*/
static public function getAllowedSystemClasses() {
return self::$allowed;
}
/**
*
* @return \Phacil\Framework\AutoLoad
*/
static public function getInstance() {
if(!self::$instance)
self::$instance = new self();
return self::$instance;
}
/**
*
* @return bool
*/
private function loadConfigClass(){
if(self::$class != self::CONFIG_CLASS) return false;
$classNative = str_replace('phacil\\framework\\', '', strtolower(self::$class));
$value = DIR_SYSTEM . str_replace('\\', "/", $classNative) . '/autoload.php';
$value = self::fileResolver($value);
if (file_exists($value)) {
try {
if (($value)) {
self::loadClassFile($value);
return true;
} else {
throw new \Exception("I can't load '$value' file! Please check system permissions.");
}
} catch (\Exception $e) {
$log = new \Phacil\Framework\Log("exception.log");
$log->write(self::$class . ' not loaded!');
exit($e->getMessage());
}
}
return false;
}
/** @return bool */
public function checkConfigLoaded(){
return isset($this->loadedClasses[0]) && $this->loadedClasses[0] == self::CONFIG_CLASS;
}
/**
* @return true|void
* @throws \Exception
*/
protected function configIsFirst(){
try {
if(!$this->checkConfigLoaded()) throw new \Exception("Config need to be a first class loaded!");
return true;
} catch (\Exception $th) {
throw $th;
}
}
/**
*
* @return void
*/
private function prepareNamespaces() {
self::$namespace = explode("\\", self::$class);
self::$namespaceWithoutPrefix = (\Phacil\Framework\Config::NAMESPACE_PREFIX()) ? explode("\\", str_replace(\Phacil\Framework\Config::NAMESPACE_PREFIX() . "\\", "", self::$class)) : self::$namespace;
self::$classNative = (isset(self::$namespace[0]) && self::$namespace[0] == "Phacil") ? str_replace('phacil\\framework\\', '', strtolower(self::$class)) : self::$class;
}
/**
*
* @return bool
* @throws \Phacil\Framework\Exception
*/
private function legacyLoad() {
if (in_array(self::$class, self::$legacy)) {
try {
class_alias("\\Phacil\\Framework\\" . self::$class, self::$class);
return true;
} catch (\Exception $th) {
throw new \Phacil\Framework\Exception($th->getMessage());
}
return false;
}
return false;
}
/**
* Check if class is an Framework Class
*
* @return bool
*/
static private function isPhacil() {
return isset(self::$namespace[0]) && self::$namespace[0] == 'Phacil';
}
/**
* Load /system/engine classes
*
* @return bool
*/
private function loadEngineClasses() {
if (!self::isPhacil()) return false;
if (in_array(self::$classNative, self::$allowed)) {
$file = \Phacil\Framework\Config::DIR_SYSTEM() . 'engine/' . str_replace("\\", "/", self::$classNative) . '.php';
try {
if (!self::loadClassFile($file)) {
throw new \Exception("Class ".self::$class." not loaded.");
}
return true;
} catch (\Exception $th) {
$log = new \Phacil\Framework\Log("exception.log");
$log->write($th->getMessage());
}
}
return false;
}
/**
* Load \Phacil\Framework\Interfaces\Action implemented classes
*
* @return bool
*/
private function loadActionClasses() {
if (!self::isPhacil()) return false;
if(self::$class != 'Phacil\Framework\Action' && self::$class != 'Phacil\Framework\ActionSystem') return false;
$file = (\Phacil\Framework\Config::DIR_SYSTEM() . 'engine/action.php');
try {
if (!self::loadClassFile($file)) {
throw new \Exception("Action classes is not loaded.");
}
return true;
} catch (\Exception $th) {
$log = new \Phacil\Framework\Log("exception.log");
$log->write($th->getMessage());
}
return false;
}
/**
* Load database classes
*
* @return bool
* @throws \Phacil\Framework\Exception
*/
private function loadDatabase() {
if(!self::isPhacil()) return false;
if (isset(self::$namespace[2]) && self::$namespace[2] == 'Databases') {
$fileDB = \Phacil\Framework\Config::DIR_DATABASE(\Phacil\Framework\Config::DIR_SYSTEM() . "database/") . str_replace("\\", "/", self::$classNative) . '.php';
//$fileDB = self::fileResolver($fileDB);
try {
if (!self::loadClassFile($fileDB)) {
throw new \Phacil\Framework\Exception($fileDB . ' does not exist', 2);
}
return true;
} catch (Exception $th) {
throw new \Phacil\Framework\Exception($th->getMessage(), $th->getCode(), $th);
}
}
return false;
}
/**
* Try to load an framework class with autoload
*
* @return bool
*/
private function loadEngineAutoload() {
if (!self::isPhacil()) return false;
$value = \Phacil\Framework\Config::DIR_SYSTEM() . str_replace('\\', "/", self::$classNative) . '/autoload.php';
try {
if (self::loadClassFile($value)) {
return true;
}
} catch (\Exception $e) {
$log = new \Phacil\Framework\Log("exception.log");
$log->write(self::$class . ' not loaded!');
exit($e->getMessage());
}
return false;
}
/**
* Try to load an framework class without autoload
*
* @return bool
*/
private function loadEngineAutoload2() {
if (!self::isPhacil()) return false;
$value = \Phacil\Framework\Config::DIR_SYSTEM() . str_replace('\\', "/", self::$classNative) . '.php';
try {
if (self::loadClassFile($value)) {
return true;
}
} catch (\Exception $e) {
$log = new \Phacil\Framework\Log("exception.log");
$log->write(self::$class . ' not loaded!');
exit($e->getMessage());
}
return false;
}
/**
* Try load modular classes
*
* @return bool
*/
private function loadModularFiles() {
$tryMagicOne = \Phacil\Framework\Config::DIR_APP_MODULAR() . implode("/", self::$namespace) . ".php";
try {
if (self::loadClassFile($tryMagicOne)) {
return true;
}
} catch (\Exception $e) {
$log = new \Phacil\Framework\Log("exception.log");
$log->write($e->getMessage());
exit($e->getMessage());
}
return false;
}
/**
* Try load modular class without namespace
*
* @return bool
*/
private function loadModularWithoutNamespacesPrefix() {
$tryMagicOne = \Phacil\Framework\Config::DIR_APP_MODULAR() . implode("/", self::$namespaceWithoutPrefix) . ".php";
try {
if (self::loadClassFile($tryMagicOne)) {
return true;
}
} catch (\Exception $e) {
$log = new \Phacil\Framework\Log("exception.log");
$log->write($e->getMessage());
exit($e->getMessage());
}
return false;
}
/**
* Try load modular parent class
*
* @return bool
*/
private function loadModularNamespaceShift() {
$namespace = self::$namespace;
$prefix = array_shift($namespace);
$tryMagicOne = \Phacil\Framework\Config::DIR_APP_MODULAR() . implode("/", $namespace) . ".php" ;
try {
if (self::loadClassFile($tryMagicOne)) {
return true;
}
} catch (\Exception $e) {
$log = new \Phacil\Framework\Log("exception.log");
$log->write($e->getMessage());
exit($e->getMessage());
}
return false;
}
/**
* Load Composer
*
* @return bool
* @throws \Phacil\Framework\Exception
*/
static public function loadComposer() {
if (self::isPhacil() || self::checkComposerLoader()) return false;
$composer = \Phacil\Framework\Config::DIR_VENDOR() ?: \Phacil\Framework\Config::DIR_VENDOR(\Phacil\Framework\Config::DIR_SYSTEM() . 'vendor/autoload.php');
/**
* fix for Polyfill Mbstring in older PHP versions
*/
$cMbstring = false;
if (version_compare(phpversion(), '7.0.0', '>') == false || extension_loaded('mbstring')) {
$cMbstring = \Phacil\Framework\Compatibility\Polyfill\Mbstring::load();
$GLOBALS['__composer_autoload_files']['0e6d7bf4a5811bfa5cf40c5ccd6fae6a'] = 'noLoad';
}
/**
* End fix
*/
if ($autoloadComposer = self::loadClassFile($composer)) {
self::$composerLoaded = $autoloadComposer;
return true;
} else {
$log = new \Phacil\Framework\Log("exception.log");
$m = 'Composer load not found.';
$log->write($m);
throw new Exception($m);
}
}
protected function checkIsLoadedClass($class) {
return in_array($class, $this->loadedClasses);
}
/**
* Initite loaders process
*
* @param string $class
* @return void
* @throws \Exception
* @throws \Phacil\Framework\Exception
*/
static public function load($class) {
self::$class = $class;
self::$subCallClass[] = $class;
$autoload = self::getInstance();
//if($autoload->checkIsLoadedClass($class)) return;
if($autoload->loadConfigClass()) return;
$autoload->configIsFirst();
$autoload->prepareNamespaces();
if($autoload->legacyLoad()) return;
if($autoload->loadActionClasses()) return;
if($autoload->loadDatabase()) return;
if($autoload->loadEngineClasses()) return;
if($autoload->loadEngineAutoload()) return;
if($autoload->loadEngineAutoload2()) return;
if($autoload->loadModularFiles()) return;
if($autoload->loadModularWithoutNamespacesPrefix()) return;
if($autoload->loadModularNamespaceShift()) return;
//if($autoload->loadComposer()) return;
return;
}
}
AutoLoad::run();
$config = \Phacil\Framework\Config::INIT();
AutoLoad::loadComposer();