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.
315 lines
9.4 KiB
315 lines
9.4 KiB
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
/**
|
|
* @author Robert Strutts
|
|
* @copyright Copyright (c) 2022, Robert Strutts.
|
|
* @license MIT
|
|
*/
|
|
|
|
namespace CodeHydrater\bootstrap;
|
|
|
|
// Polyfill for PHP 4 to 7
|
|
if (!function_exists('str_contains')) {
|
|
function str_contains($haystack, $needle) {
|
|
return $needle !== '' && mb_strpos($haystack, $needle) !== false;
|
|
}
|
|
}
|
|
|
|
$mem_baseline = memory_get_usage();
|
|
|
|
require_once CodeHydrater_FRAMEWORK . 'bootstrap/errors.php';
|
|
|
|
final class views {
|
|
public static function ob_start(): void {
|
|
if (extension_loaded('mbstring')) {
|
|
ob_start('mb_output_handler');
|
|
} else {
|
|
ob_start();
|
|
}
|
|
}
|
|
}
|
|
|
|
if (site_helper::get_testing() === false) {
|
|
views::ob_start();
|
|
}
|
|
|
|
final class errors {
|
|
private static $is_live = true; // Fall Back Value if Config Not Found
|
|
private static $handle_global_errors = true;
|
|
private static $handle_shutdown_errors = true;
|
|
private static $handle_exceptions = true;
|
|
|
|
public static function set_live_mode(bool $is_live): void {
|
|
self::$is_live = $is_live;
|
|
}
|
|
public static function get_live_mode(): bool {
|
|
return self::$is_live;
|
|
}
|
|
public static function set_handle_shutdown_errors(bool $do_handle_errors): void {
|
|
self::$handle_shutdown_errors = $do_handle_errors;
|
|
}
|
|
public static function get_handle_shutdown_errors(): bool {
|
|
return self::$handle_shutdown_errors;
|
|
}
|
|
public static function set_handle_exceptions(bool $do_handle_errors): void {
|
|
self::$handle_exceptions = $do_handle_errors;
|
|
}
|
|
public static function get_handle_exceptions(): bool {
|
|
return self::$handle_exceptions;
|
|
}
|
|
public static function set_handle_global_errors(bool $do_handle_errors): void {
|
|
self::$handle_global_errors = $do_handle_errors;
|
|
}
|
|
public static function get_handle_global_errors(): bool {
|
|
return self::$handle_global_errors;
|
|
}
|
|
}
|
|
|
|
final class configure {
|
|
|
|
private static $config = [];
|
|
|
|
protected function __construct() {
|
|
|
|
}
|
|
|
|
public static function exists() { // an Alias to has
|
|
return self::has(func_get_args());
|
|
}
|
|
|
|
public static function has(string $name, $key = false): bool {
|
|
if ($key === false) {
|
|
return (isset(self::$config[strtolower($name)])) ? true : false;
|
|
}
|
|
return (isset(self::$config[strtolower($name)][strtolower($key)])) ? true : false;
|
|
}
|
|
|
|
public static function get(string $name, $key = false) {
|
|
if (isset(self::$config[strtolower($name)])) {
|
|
$a = self::$config[strtolower($name)];
|
|
if ($key === false) {
|
|
return $a;
|
|
}
|
|
if (isset($a[$key])) {
|
|
return $a[$key];
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public static function update() { // an Alias to set
|
|
return self::set(func_get_args());
|
|
}
|
|
|
|
public static function set(string $name, $value): void {
|
|
self::$config[strtolower($name)] = $value;
|
|
}
|
|
|
|
public static function set_key(string $name, string $key, $value): void {
|
|
self::$config[strtolower($name)][strtolower($key)] = $value;
|
|
}
|
|
|
|
public static function add_to_key(string $name, string $key, $value): void {
|
|
self::$config[strtolower($name)][strtolower($key)][] = $value;
|
|
}
|
|
|
|
public static function wipe(string $name, $key = false): void {
|
|
if (! self::exists($name, $key)) {
|
|
return;
|
|
}
|
|
if ($key === false) {
|
|
common::wipe(self::$config[strtolower($name)]);
|
|
}
|
|
common::wipe(self::$config[strtolower($name)][strtolower($key)]);
|
|
}
|
|
|
|
public static function load_array(array $a): void {
|
|
if (isset($a) && is_array($a)) {
|
|
foreach ($a as $name => $value) {
|
|
self::$config[$name] = $value;
|
|
}
|
|
}
|
|
unset($a);
|
|
}
|
|
|
|
}
|
|
|
|
final class registry {
|
|
|
|
private static $registry = [];
|
|
|
|
protected function __construct() {
|
|
|
|
}
|
|
|
|
public static function get(string $name, $key = false) {
|
|
if (isset(self::$registry[strtolower($name)])) {
|
|
$a = self::$registry[strtolower($name)];
|
|
if ($key === false) {
|
|
return $a;
|
|
}
|
|
if (isset($a[$key])) {
|
|
return $a[$key];
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public static function set(string $name, $value): bool {
|
|
if (array_key_exists(strtolower($name), self::$registry)) {
|
|
return false;
|
|
}
|
|
self::$registry[strtolower($name)] = $value;
|
|
return true;
|
|
}
|
|
|
|
}
|
|
|
|
final class di {
|
|
|
|
protected $services = [];
|
|
|
|
public function register(string $service_name, callable $callable): void {
|
|
$this->services[$service_name] = $callable;
|
|
}
|
|
|
|
public function has(string $service_name): bool {
|
|
return (array_key_exists($service_name, $this->services));
|
|
}
|
|
|
|
public function exists(string $service_name) { // an Alias to has
|
|
return $this->has($service_name);
|
|
}
|
|
|
|
/* Note args may be an object or an array maybe more...!
|
|
* This will Call/Execute the service
|
|
*/
|
|
public function get_service(
|
|
string $service_name,
|
|
$args = [],
|
|
...$more
|
|
) {
|
|
if ($this->has($service_name) ) {
|
|
return $this->services[$service_name]($args, $more);
|
|
}
|
|
return $this->resolve($service_name); // Try to Auto-Wire
|
|
}
|
|
|
|
public function get_auto(string $service_name) {
|
|
if ($this->has($service_name) ) {
|
|
return $this->services[$service_name]($this);
|
|
}
|
|
return $this->resolve($service_name); // Try to Auto-Wire
|
|
}
|
|
|
|
public function __set(string $service_name, callable $callable): void {
|
|
$this->register($service_name, $callable);
|
|
}
|
|
|
|
public function __get(string $service_name) {
|
|
return $this->get_service($service_name);
|
|
}
|
|
|
|
public function list_services_as_array(): array {
|
|
return array_keys($this->services);
|
|
}
|
|
|
|
public function list_services_as_string(): string {
|
|
return implode(',', array_keys($this->services));
|
|
}
|
|
|
|
public function resolve(string $service_name) {
|
|
try {
|
|
$reflection_class = new \ReflectionClass($service_name);
|
|
} catch (\ReflectionException $e) {
|
|
if (! is_live()) {
|
|
var_dump($e->getTrace());
|
|
echo $e->getMessage();
|
|
exit;
|
|
} else {
|
|
throw new \Exception("Failed to resolve resource: {$service_name}!");
|
|
}
|
|
}
|
|
if (! $reflection_class->isInstantiable()) {
|
|
throw new \Exception("The Service class: {$service_name} is not instantiable.");
|
|
}
|
|
$constructor = $reflection_class->getConstructor();
|
|
if (! $constructor) {
|
|
return new $service_name;
|
|
}
|
|
$parameters = $constructor->getParameters();
|
|
if (! $parameters) {
|
|
return new $service_name;
|
|
}
|
|
$dependencies = array_map(
|
|
function(\ReflectionParameter $param) {
|
|
$name = $param->getName();
|
|
$type = $param->getType();
|
|
if (! $type) {
|
|
throw new \Exception("Failed to resolve class: {$service_name} becasue param {$name} is missing a type hint.");
|
|
}
|
|
if ($type instanceof \ReflectionUnionType) {
|
|
throw new \Exception("Failed to resolve class: {$service_name} because of union type for param {$name}.");
|
|
}
|
|
if ($type instanceof \ReflectionNamedType && ! $type->isBuiltin()) {
|
|
return $this->get_auto($type->getName());
|
|
}
|
|
|
|
throw new \Exception("Failed to resolve class {$service_name} because of invalid param {$param}.");
|
|
}, $parameters
|
|
);
|
|
return $reflection_class->newInstanceArgs($dependencies);
|
|
}
|
|
|
|
}
|
|
|
|
// Initialize our Dependency Injector
|
|
registry::set('di', new di());
|
|
|
|
// Setup php for working with Unicode data, if possible
|
|
if (extension_loaded('mbstring')) {
|
|
mb_internal_encoding('UTF-8');
|
|
mb_http_output('UTF-8');
|
|
mb_language('uni');
|
|
mb_regex_encoding('UTF-8');
|
|
setlocale(LC_ALL, "en_US.UTF-8");
|
|
}
|
|
|
|
require_once CodeHydrater_FRAMEWORK . 'bootstrap/common.php';
|
|
require_once CodeHydrater_FRAMEWORK . 'bootstrap/requires.php';
|
|
require_once CodeHydrater_FRAMEWORK . 'bootstrap/auto_loader.php';
|
|
|
|
registry::set('loader', new Psr4AutoloaderClass);
|
|
registry::get('loader')->register();
|
|
registry::get('loader')->add_namespace("CodeHydrater\bootstrap", CodeHydrater_FRAMEWORK . "bootstrap");
|
|
registry::get('loader')->add_namespace("CodeHydrater", CodeHydrater_FRAMEWORK . "classes");
|
|
registry::get('loader')->add_namespace("Project", CodeHydrater_PROJECT);
|
|
|
|
load_all::init(CodeHydrater_PROJECT);
|
|
|
|
// Keep these blocks of code here not anywhere before it...
|
|
if (! defined('ENVIRONMENT')) {
|
|
if (is_live() === false) {
|
|
define('ENVIRONMENT', 'development');
|
|
} else {
|
|
define('ENVIRONMENT', 'production');
|
|
}
|
|
}
|
|
|
|
function is_live(): bool {
|
|
if (configure::has('CodeHydrater', 'live')) {
|
|
$live = configure::get('CodeHydrater', 'live');
|
|
}
|
|
if ($live === null) {
|
|
$live = errors::get_live_mode();
|
|
}
|
|
return (bool) $live;
|
|
}
|
|
|
|
$returned_route = \CodeHydrater\router::execute();
|
|
if ($returned_route["found"] === false) {
|
|
$app = new \CodeHydrater\app();
|
|
$app->load_controller();
|
|
}
|
|
|