2020-09-25 17:55:35 +00:00
|
|
|
<?php declare(strict_types=1);
|
|
|
|
|
|
|
|
namespace Lean;
|
|
|
|
|
|
|
|
use Dotenv\Dotenv;
|
|
|
|
|
|
|
|
use DI\ContainerBuilder,
|
|
|
|
DI\Container;
|
|
|
|
|
|
|
|
use League\Route\Strategy\ApplicationStrategy;
|
|
|
|
|
|
|
|
use Psr\Http\Message\ServerRequestInterface;
|
|
|
|
|
2021-02-16 03:10:04 +00:00
|
|
|
use Tell\I18n;
|
2020-10-20 13:55:48 +00:00
|
|
|
use Ulmus\Container\AdapterProxy;
|
|
|
|
|
2023-01-31 19:12:28 +00:00
|
|
|
use Laminas\Diactoros\ServerRequestFactory,
|
|
|
|
Laminas\HttpHandlerRunner\Emitter\EmitterInterface;
|
|
|
|
|
2023-01-26 13:28:36 +00:00
|
|
|
use Ulmus\Ulmus;
|
2020-09-25 17:55:35 +00:00
|
|
|
|
|
|
|
class Kernel {
|
|
|
|
|
|
|
|
protected Container $container;
|
|
|
|
|
|
|
|
protected string $locale;
|
|
|
|
|
|
|
|
public array $paths = [];
|
|
|
|
|
|
|
|
public int $errorReporting = E_ALL & ~E_USER_DEPRECATED & ~E_DEPRECATED & ~E_STRICT & ~E_NOTICE;
|
|
|
|
|
|
|
|
public string $definitionFilePath;
|
|
|
|
|
|
|
|
public string $errorLogPath;
|
|
|
|
|
|
|
|
public string $projectPath;
|
|
|
|
|
|
|
|
public string $routeDefinitionList = 'routes.list';
|
|
|
|
|
|
|
|
public function __construct(string $projectPath)
|
|
|
|
{
|
|
|
|
$this->projectPath = $projectPath;
|
|
|
|
|
|
|
|
$this->setEnvironment();
|
|
|
|
$this->initializeEngine();
|
|
|
|
$this->setupContainer();
|
|
|
|
$this->serviceContainer();
|
|
|
|
$this->handleRequest();
|
|
|
|
}
|
|
|
|
|
|
|
|
public static function putenv($var, $value)
|
|
|
|
{
|
|
|
|
putenv("$var=$value");
|
|
|
|
$_ENV[$var] = $value;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function setEnvironment() {
|
|
|
|
static::putenv('PROJECT_PATH', $this->projectPath);
|
|
|
|
|
|
|
|
// Environment vars (accessible from \DI\env(), getenv(), $_ENV and $_SERVER)
|
|
|
|
Dotenv::create(getenv("PROJECT_PATH"))->load();
|
|
|
|
|
|
|
|
// Override using headers
|
2023-04-05 17:42:46 +00:00
|
|
|
if ( ( $keys = getenv('KEYS') ) && ( $auth = $_SERVER["HTTP_X_DEV_AUTH"] ?? null ) && in_array($auth, explode(',', $keys)) ) {
|
2022-11-24 19:57:42 +00:00
|
|
|
foreach (['APP_ENV', 'DEBUG',] as $env) {
|
|
|
|
if (null !== $value = $_SERVER["HTTP_X_$env"] ?? null) {
|
|
|
|
static::putenv($env, $value);
|
|
|
|
}
|
2020-09-25 17:55:35 +00:00
|
|
|
}
|
|
|
|
}
|
2021-08-27 18:06:15 +00:00
|
|
|
|
|
|
|
// Paths and directories
|
|
|
|
foreach($this->paths as $name => $envkey) {
|
|
|
|
if ( ! getenv($name) ) {
|
|
|
|
$path = getenv("PROJECT_PATH") . DIRECTORY_SEPARATOR . getenv($envkey);
|
|
|
|
|
|
|
|
if (getenv('DEBUG') && ! file_exists($path)) {
|
|
|
|
mkdir($path, 0755, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
static::putenv($name, realpath($path));
|
|
|
|
}
|
|
|
|
}
|
2020-09-25 17:55:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
protected function initializeEngine() : self
|
|
|
|
{
|
|
|
|
# Defining default locale and timezone
|
|
|
|
date_default_timezone_set(getenv("DEFAULT_TIMEZONE"));
|
|
|
|
|
|
|
|
setlocale(LC_ALL, $this->locale = getenv("DEFAULT_LOCAL"));
|
|
|
|
setlocale(LC_TIME, getenv("DEFAULT_TIME"), getenv("DEFAULT_TIME_FALLBACK"));
|
|
|
|
|
2021-08-27 18:06:15 +00:00
|
|
|
if ( class_exists('Locale') ) {
|
|
|
|
\Locale::setDefault($this->locale);
|
|
|
|
}
|
|
|
|
|
2020-09-25 17:55:35 +00:00
|
|
|
ini_set("log_errors", "1");
|
|
|
|
ini_set("error_log", $this->errorLogPath);
|
2021-02-16 03:10:04 +00:00
|
|
|
ini_set('display_errors', getenv("DEBUG") ? 'on' : 'on');
|
2020-09-25 17:55:35 +00:00
|
|
|
|
|
|
|
error_reporting($this->errorReporting);
|
|
|
|
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function setupContainer() : self
|
|
|
|
{
|
|
|
|
$containerBuilder = new ContainerBuilder();
|
|
|
|
|
|
|
|
if (getenv("APP_ENV") === "prod") {
|
|
|
|
if (getenv("CACHE_PATH")) {
|
2023-10-16 17:58:51 +00:00
|
|
|
$containerBuilder->enableCompilation(getenv("CACHE_PATH") . "/di/");
|
|
|
|
$containerBuilder->writeProxiesToFile(true, getenv("CACHE_PATH") . "/di/proxies/");
|
2020-09-25 17:55:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-31 19:12:28 +00:00
|
|
|
# $containerBuilder->useAnnotations(false);
|
2020-09-25 17:55:35 +00:00
|
|
|
|
|
|
|
if ($this->definitionFilePath ?? false) {
|
|
|
|
$containerBuilder->addDefinitions(require($this->definitionFilePath));
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->container = $containerBuilder->build();
|
|
|
|
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function serviceContainer() : self
|
|
|
|
{
|
2020-10-20 13:55:48 +00:00
|
|
|
$this->container->has(AdapterProxy::class) and $this->container->get(AdapterProxy::class);
|
2023-01-26 13:28:36 +00:00
|
|
|
$this->container->has('ulmus.caching') and ( Ulmus::$cache = $this->container->get('ulmus.caching') );
|
2020-12-07 14:11:29 +00:00
|
|
|
$this->container->has(Lean::class) and $this->container->get(Lean::class);
|
2020-10-20 13:55:48 +00:00
|
|
|
|
2021-02-16 03:10:04 +00:00
|
|
|
if ($this->container->has(I18n::class)) {
|
|
|
|
$i18n = $this->container->get(I18n::class);
|
|
|
|
$i18n->locale($this->locale);
|
|
|
|
$i18n->initialize(!getenv("DEBUG"));
|
|
|
|
}
|
|
|
|
|
2020-09-25 17:55:35 +00:00
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function handleRequest() : self
|
|
|
|
{
|
|
|
|
ServerRequestFactory::fromGlobals($_SERVER, $_GET, $_POST, $_COOKIE, $_FILES);
|
|
|
|
|
|
|
|
// Router
|
|
|
|
$routeFactory = $this->container->get($this->routeDefinitionList);
|
|
|
|
|
|
|
|
$router = $routeFactory($this->container);
|
|
|
|
|
|
|
|
$router->setStrategy($this->container->get(ApplicationStrategy::class));
|
|
|
|
|
|
|
|
// Handle requests
|
|
|
|
$response = $router->dispatch($this->container->get(ServerRequestInterface::class));
|
|
|
|
|
|
|
|
// Reply to clients
|
|
|
|
$this->container->get(EmitterInterface::class)->emit($response);
|
|
|
|
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
};
|