diff --git a/app/core/class/di.php b/app/core/class/di.php new file mode 100644 index 0000000..bbabae5 --- /dev/null +++ b/app/core/class/di.php @@ -0,0 +1,125 @@ +, Joe Mottershaw + * @source https://github.com/elyzin/elyzin Base repository + * @link http://elyz.in + * @copyright 2018 Elyzin + * @license MIT + * + * @todo Namespace + * @todo Interface + */ +class DI +{ + /** + * @var array + */ + protected $instances = []; + + /** + * @param $abstract + * @param null $concrete + */ + public function push($abstract, $concrete = null) + { + if ($concrete === null) { + $concrete = $abstract; + } + $this->instances[$abstract] = $concrete; + } + + /** + * @param $abstract + * @param array $values + * + * @return mixed|null|object + * @throws Exception + */ + public function pull($abstract, $values = []) + { + // if we don't have it, just register it + if (!isset($this->instances[$abstract])) { + $this->set($abstract); + } + + return $this->resolve($this->instances[$abstract], $values); + } + + /** + * resolve single + * + * @param $concrete + * @param $values + * + * @return mixed|object + * @throws Exception + */ + public function resolve($concrete, $values = []) + { + if ($concrete instanceof Closure) { + return $concrete($this, $values); + } + + $reflector = new ReflectionClass($concrete); + // check if class is instantiable + if (!$reflector->isInstantiable()) { + throw new Exception("Class {$concrete} is not instantiable"); + } + + // get class constructor + $constructor = $reflector->getConstructor(); + if (is_null($constructor)) { + // get new instance from class + return $reflector->newInstance(); + } + + // get constructor params + $parameters = $constructor->getParameters(); + $dependencies = $this->getDependencies($parameters, $values); + + // get new instance with dependencies resolved + return $reflector->newInstanceArgs($dependencies); + } + + /** + * get all dependencies resolved + * + * @param $parameters + * + * @return array + * @throws Exception + */ + public function getDependencies($parameters, $values) + { + $dependencies = []; + foreach ($parameters as $parameter) { + // get the type hinted class + $dependency = $parameter->getClass(); + if ($dependency === null) { + // check if the constructor parameter name exists as a key in the values array + if (array_key_exists($parameter->getName(), $values)) { + // get default value of parameter + $dependencies[] = $values[$parameter->getName()]; + } else { + // check if default value for a parameter is available + if ($parameter->isDefaultValueAvailable()) { + // get default value of parameter + $dependencies[] = $parameter->getDefaultValue(); + } else { + throw new Exception("Can not resolve class dependency {$parameter->name}"); + } + } + } else { + // get dependency resolved + $dependencies[] = $this->get($dependency->name); + } + } + + return $dependencies; + } +} \ No newline at end of file diff --git a/app/core/func/site.php b/app/core/func/site.php index 7dc65f5..e0be642 100644 --- a/app/core/func/site.php +++ b/app/core/func/site.php @@ -14,8 +14,15 @@ if (!defined("APP")) die(); // Deny direct access -// Return preconfigured system paths -// ========================================================================================================= +// Class autoloader +spl_autoload_register(function($c){@include syspath('class').preg_replace('#\\\|_(?!.+\\\)#','/',$c).'.php';}); + +/** + * Return preconfigured system paths + * + * @param [type] $target + * @return string + */ function syspath($target){ $path = parse_ini_file(dirname(__DIR__).'/conf/syspath.ini',true); foreach ($path as $key => $group) { @@ -27,9 +34,15 @@ function syspath($target){ return false; } -// Fetch Settings << Fetch user settings as well, avoid hardcoded ini path -// ========================================================================================================= -function conf($node, $group = 'site'){ +/** + * Return Settings Values + * + * @param [type] $node // Settings name + * @param string $group // Settings Group Name + * @return mixed + * @todo Fetch user settings as well, avoid hardcoded ini path + */ +function conf(string $node, string $group = 'site'){ $settings = parse_ini_file(syspath('config').'basefact.ini',true); if(!empty($settings[$group][$node])) return $settings[$group][$node]; return false; diff --git a/public/index.php b/public/index.php index d6c0b45..e880831 100644 --- a/public/index.php +++ b/public/index.php @@ -41,16 +41,10 @@ // Start a new or resume existing session session_start(); - -// Class autoloader -spl_autoload_register(function($c){@include syspath('class').preg_replace('#\\\|_(?!.+\\\)#','/',$c).'.php';}); -$db = new db(); -$me = new user(); -$clock = new clock(); -$file = new file(); -$log = new log(); -$page = new page($pgen); +$di = new DI(); +$me = $di->pull['user']; +$page = $di->pull['page']; // Set timezone as per user preference if(!empty($me->pref('timezone'))){ @@ -84,4 +78,4 @@ $page->render('page_underdev', $msg)->flush(); } // Template code gathered through script. Display final page -$page->out(); \ No newline at end of file +$page->out($pgen); \ No newline at end of file