oms-OnlineResourceWatcher/app/web/WebApplication.php
2022-11-06 18:13:52 +01:00

231 lines
8.5 KiB
PHP
Executable File

<?php
declare(strict_types=1);
use phpOMS\Autoloader;
use phpOMS\Application\ApplicationAbstract;
use phpOMS\Localization\ISO639x1Enum;
use phpOMS\Localization\Localization;
use phpOMS\Log\FileLogger;
use phpOMS\Message\Http\HttpRequest;
use phpOMS\Message\Http\HttpResponse;
use phpOMS\System\File\PathException;
use phpOMS\Uri\HttpUri;
use phpOMS\Uri\UriFactory;
class WebApplication extends ApplicationAbstract
{
public function __construct(array $config)
{
$response = null;
$sub = null;
try {
$this->setupHandlers();
$this->logger = FileLogger::getInstance($config['log']['file']['path'], false);
UriFactory::setQuery('/prefix', '', true);
UriFactory::setQuery('/backend', 'backend/', true);
UriFactory::setQuery('/api', 'api/', true);
$applicationName = $this->getApplicationName(HttpUri::fromCurrent(), $config['app'], $config['page']['root']);
$request = $this->initRequest($config['page']['root'], $config['app']);
$response = $this->initResponse($request, $config);
$this->theme = $this->getApplicationTheme($request, $config['app']['domains']);
$app = '\Applications\\' . $applicationName . '\Application';
$sub = new $app($this, $config);
} catch (\Throwable $e) {
$this->logger->critical(FileLogger::MSG_FULL, [
'message' => $e->getMessage(),
'line' => __LINE__, ]);
$sub = new \Applications\E500\Application($this, $config);
} finally {
if ($sub === null) {
$sub = new \Applications\E500\Application($this, $config);
}
if ($response === null) {
$response = new HttpResponse();
}
$request ??= HttpRequest::createFromSuperglobals();
$sub->run($request, $response);
$body = $response->getBody(true);
if (isset($this->sessionManager)) {
$this->sessionManager->save();
}
if (!$response->header->isLocked()) {
$response->header->push();
}
if (isset($this->sessionManager)) {
$this->sessionManager->lock();
}
echo $body;
}
}
private function setupHandlers() : void
{
\set_exception_handler(['\phpOMS\UnhandledHandler', 'exceptionHandler']);
\set_error_handler(['\phpOMS\UnhandledHandler', 'errorHandler']);
\register_shutdown_function(['\phpOMS\UnhandledHandler', 'shutdownHandler']);
\mb_internal_encoding('UTF-8');
}
private function initRequest(string $rootPath, array $config) : HttpRequest
{
$request = HttpRequest::createFromSuperglobals();
$subDirDepth = \substr_count($rootPath, '/') - 1;
$defaultLang = $config['domains'][$request->uri->host]['lang'] ?? $config['default']['lang'];
$uriLang = \strtolower($request->uri->getPathElement($subDirDepth + 0));
$requestLang = $request->getRequestLanguage();
$langCode = ISO639x1Enum::isValidValue($uriLang)
? $uriLang
: (ISO639x1Enum::isValidValue($requestLang)
? $requestLang
: $defaultLang
);
$pathOffset = $subDirDepth
+ (ISO639x1Enum::isValidValue($uriLang)
? 1 + ($this->getApplicationNameFromString($request->uri->getPathElement($subDirDepth + 1)) !== 'E500' ? 1 : 0)
: 0 + ($this->getApplicationNameFromString($request->uri->getPathElement($subDirDepth + 0)) !== 'E500' ? 1 : 0)
);
$request->createRequestHashs($pathOffset);
$request->uri->setRootPath($rootPath);
$request->uri->setPathOffset($pathOffset);
UriFactory::setupUriBuilder($request->uri);
$request->header->l11n->loadFromLanguage($langCode, \explode('_', $request->getLocale())[1] ?? '*');
return $request;
}
private function initResponse(HttpRequest $request, array $config) : HttpResponse
{
$response = new HttpResponse(new Localization());
$response->header->set('content-type', 'text/html; charset=utf-8');
$response->header->set('x-xss-protection', '1; mode=block');
$response->header->set('x-content-type-options', 'nosniff');
$response->header->set('x-frame-options', 'SAMEORIGIN');
$response->header->set('referrer-policy', 'same-origin');
if ($request->isHttps()) {
$response->header->set('strict-transport-security', 'max-age=31536000');
}
$defaultLang = $config['app']['domains'][$request->uri->host]['lang'] ?? $config['app']['default']['lang'];
$uriLang = \strtolower($request->uri->getPathElement(0));
$uriLang = ISO639x1Enum::isValidValue($uriLang) && \in_array($uriLang, $config['language'])
? $uriLang
: \strtolower($request->uri->getPathElement(0, false));
$requestLang = $request->getLanguage();
$langCode = ISO639x1Enum::isValidValue($uriLang) && \in_array($uriLang, $config['language'])
? $uriLang
: (ISO639x1Enum::isValidValue($requestLang) && \in_array($requestLang, $config['language'])
? $requestLang
: $defaultLang
);
$response->header->l11n->loadFromLanguage($langCode, \explode('_', $request->getLocale())[1] ?? '*');
UriFactory::setQuery('/lang', $request->getLanguage(), true);
if (ISO639x1Enum::isValidValue($uriLang)) {
UriFactory::setQuery('/prefix', $uriLang . '/' . (empty(UriFactory::getQuery('/prefix')) ? '' : UriFactory::getQuery('/prefix')), true);
UriFactory::setQuery('/api', $uriLang . '/' . (empty(UriFactory::getQuery('/api')) ? '' : UriFactory::getQuery('/api')), true);
}
return $response;
}
private function getApplicationName(HttpUri $uri, array $config, string $rootPath) : string
{
$subDirDepth = \substr_count($rootPath, '/') - 1;
// check subdomain
$appName = $uri->getSubdomain();
$appName = $this->getApplicationNameFromString($appName);
if ($appName !== 'E500') {
return $appName;
}
// check uri path 0 (no language is defined)
$appName = $uri->getPathElement($subDirDepth + 0);
$appName = $this->getApplicationNameFromString($appName);
if ($appName !== 'E500') {
UriFactory::setQuery(
'/prefix',
empty(UriFactory::getQuery('/prefix')
? ''
: UriFactory::getQuery('/prefix') . '/') . $uri->getPathElement($subDirDepth + 1) . '/',
true
);
return $appName;
}
// check uri path 1 (language is defined)
if (ISO639x1Enum::isValidValue($uri->getPathElement($subDirDepth + 0))) {
$appName = $uri->getPathElement($subDirDepth + 1);
$appName = $this->getApplicationNameFromString($appName);
if ($appName !== 'E500') {
UriFactory::setQuery(
'/prefix',
empty(UriFactory::getQuery('/prefix')
? ''
: UriFactory::getQuery('/prefix') . '/') . $uri->getPathElement($subDirDepth + 1) . '/',
true
);
return $appName;
}
}
// check config
$appName = $config['domains'][$uri->host]['app'] ?? $config['default']['app'];
return $this->getApplicationNameFromString($appName);
}
private function getApplicationNameFromString(string $app) : string
{
$applicationName = \ucfirst(\strtolower($app));
if (empty($applicationName) || !Autoloader::exists('\\Applications\\' . $applicationName . '\\Application')) {
$applicationName = 'E500';
}
return $applicationName;
}
private function getApplicationTheme(HttpRequest $request, array $config) : string
{
return $config[$request->uri->host]['theme'] ?? 'Backend';
}
public function loadLanguageFromPath(string $language, string $path) : void
{
/* Load theme language */
if (($absPath = \realpath($path)) === false) {
throw new PathException($path);
}
/** @noinspection PhpIncludeInspection */
$themeLanguage = include $absPath;
$this->l11nManager->loadLanguage($language, '0', $themeLanguage);
}
}