1
0
mirror of https://github.com/typemill/typemill.git synced 2025-01-17 05:18:19 +01:00
php-typemill/system/system.php

329 lines
9.9 KiB
PHP

<?php
use Typemill\Events\OnSettingsLoaded;
use Typemill\Events\OnPluginsLoaded;
use Typemill\Events\OnSessionSegmentsLoaded;
use Typemill\Events\OnRolesPermissionsLoaded;
use Typemill\Events\OnResourcesLoaded;
/****************************
* HIDE ERRORS BY DEFAULT *
****************************/
ini_set('display_errors', 0);
ini_set('display_startup_errors', 0);
error_reporting(E_ALL);
/****************************
* CREATE EVENT DISPATCHER *
****************************/
$dispatcher = new \Symfony\Component\EventDispatcher\EventDispatcher();
/************************
* LOAD SETTINGS *
************************/
$settings = Typemill\Settings::loadSettings();
/****************************
* HANDLE DISPLAY ERRORS *
****************************/
if(isset($settings['settings']['displayErrorDetails']) && $settings['settings']['displayErrorDetails'])
{
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
}
/************************
* INITIATE SLIM *
************************/
$app = new \Slim\App($settings);
/************************
* GET SLIM CONTAINER *
************************/
$container = $app->getContainer();
/************************
* Create URI *
************************/
# get uri and delete username and password from uri
$uri = \Slim\Http\Uri::createFromEnvironment(new \Slim\Http\Environment($_SERVER))->withUserInfo('');
/************************
* LOAD & UPDATE PLUGINS *
************************/
$plugins = new Typemill\Plugins();
$pluginNames = $plugins->load();
$pluginSettings = $routes = $middleware = array();
foreach($pluginNames as $pluginName)
{
$className = $pluginName['className'];
$name = $pluginName['name'];
# check if plugin is in the settings already
if(isset($settings['settings']['plugins'][$name]))
{
# if so, add the settings to temporary plugin settings
$pluginSettings[$name] = $settings['settings']['plugins'][$name];
# and delete them from original settings
unset($settings['settings']['plugins'][$name]);
}
else
{
# if not, it is a new plugin. Add it and set active to false
$pluginSettings[$name] = ['active' => false];
# and set flag to refresh the settings
$refreshSettings = true;
}
# if the plugin is activated, add routes/middleware and add plugin as event subscriber
if($pluginSettings[$name]['active'])
{
$routes = $plugins->getNewRoutes($className, $routes);
$middleware = $plugins->getNewMiddleware($className, $middleware);
$dispatcher->addSubscriber(new $className($container));
}
}
# if plugins in original settings are not empty now, then a plugin has been removed
if(!empty($settings['settings']['plugins'])){ $refreshSettings = true; }
# update the settings in all cases
$settings['settings']['plugins'] = $pluginSettings;
# if plugins have been added or removed
if(isset($refreshSettings))
{
# update the settings in the container
$container->get('settings')->replace($settings['settings']);
# update stored settings file
$refreshSettings = Typemill\settings::updateSettings($settings['settings']);
}
# dispatch the event onPluginsLoaded
$dispatcher->dispatch('onPluginsLoaded', new OnPluginsLoaded($pluginNames));
# dispatch settings event and get all setting-updates from plugins
$dispatcher->dispatch('onSettingsLoaded', new OnSettingsLoaded($settings))->getData();
/**********************************
* LOAD ROLES AND PERMISSIONS *
**********************************/
# load roles and permissions
$rolesAndPermissions = Typemill\Settings::loadRolesAndPermissions();
# dispatch roles so plugins can enhance them
$rolesAndPermissions = $dispatcher->dispatch('onRolesPermissionsLoaded', new OnRolesPermissionsLoaded($rolesAndPermissions))->getData();
# load resources
$resources = Typemill\Settings::loadResources();
# dispatch roles so plugins can enhance them
$resources = $dispatcher->dispatch('onResourcesLoaded', new OnResourcesLoaded($resources))->getData();
# create acl-object
$acl = Typemill\Settings::createAcl($rolesAndPermissions, $resources);
# add acl to container
$container['acl'] = function($c) use ($acl)
{
return $acl;
};
/******************************
* ADD DISPATCHER TO CONTAINER *
******************************/
$container['dispatcher'] = function($container) use ($dispatcher)
{
return $dispatcher;
};
/************************
* DECIDE FOR SESSION *
************************/
$session_segments = array('setup', 'tm/', 'api/', '/setup', '/tm/', '/api/');
# let plugins add own segments for session, eg. to enable csrf for forms
$client_segments = $dispatcher->dispatch('onSessionSegmentsLoaded', new OnSessionSegmentsLoaded([]))->getData();
$session_segments = array_merge($session_segments, $client_segments);
$container['flash'] = false;
$container['csrf'] = false;
/************************************
* ADD ASSET-FUNCTION FOR PLUGINS *
************************************/
$container['assets'] = function($c) use ($uri)
{
return new \Typemill\Assets($uri->getBaseUrl());
};
/********************************
* MOVE TO MIDDLEWARE NEXT TIME *
********************************/
# if website is restricted to registered user
if( ( isset($settings['settings']['access']) && $settings['settings']['access'] ) || ( isset($settings['settings']['pageaccess']) && $settings['settings']['pageaccess'] ) )
{
# activate session for all routes
$session_segments = [$uri->getPath()];
}
foreach($session_segments as $segment)
{
if(substr( $uri->getPath(), 0, strlen($segment) ) === $segment)
{
// configure session
ini_set('session.cookie_httponly', 1 );
ini_set('session.use_strict_mode', 1);
ini_set('session.cookie_samesite', 'lax');
if($uri->getScheme() == 'https')
{
ini_set('session.cookie_secure', 1);
session_name('__Secure-typemill-session');
}
else
{
session_name('typemill-session');
}
// add csrf-protection
$container['csrf'] = function ($c)
{
$guard = new \Slim\Csrf\Guard();
$guard->setPersistentTokenMode(true);
$guard->setfailurecallable(function ($request, $response, $next)
{
$request = $request->withattribute("csrf_result", false);
return $next($request, $response);
});
return $guard;
};
// add flash to container
$container['flash'] = function ()
{
return new \Slim\Flash\Messages();
};
// start session
session_start();
}
}
/************************
* LOAD TWIG VIEW *
************************/
$container['view'] = function ($container) use ($uri)
{
$path = array($container->get('settings')['themePath'], $container->get('settings')['authorPath']);
$cache = ( isset($container->get('settings')['twigcache']) && $container->get('settings')['twigcache'] ) ? $container->get('settings')['rootPath'] . '/cache/twig' : false;
$view = new \Slim\Views\Twig( $path, [
'cache' => $cache,
'autoescape' => false,
'debug' => true
]);
# Instantiate and add Slim specific extension
$router = $container->get('router');
$view->addExtension(new Slim\Views\TwigExtension($router, $uri));
$view->addExtension(new Twig_Extension_Debug());
$view->addExtension(new Typemill\Extensions\TwigUserExtension());
$view->addExtension(new Typemill\Extensions\TwigMarkdownExtension());
$view->addExtension(new Typemill\Extensions\TwigMetaExtension());
$view->addExtension(new Typemill\Extensions\TwigPagelistExtension());
# if session route, add flash messages and csrf-protection
if($container['flash'])
{
$view->getEnvironment()->addGlobal('flash', $container->flash);
$view->addExtension(new Typemill\Extensions\TwigCsrfExtension($container['csrf']));
$view->addExtension(new Typemill\Extensions\TwigCaptchaExtension());
}
/******************************
* LOAD TRANSLATIONS *
******************************/
$pieces = explode('/',trim($uri->getPath(),'/'));
if( ($pieces[0] === 'tm' OR $pieces[0] === 'setup') )
{
# Admin environment labels
$labels = Typemill\Translations::loadTranslations('admin');
} else {
# User environment labels
# For now it is useless, but it will prove useful in the future
$labels = Typemill\Translations::loadTranslations('user');
}
$view['translations'] = $labels;
$view->addExtension(new Typemill\Extensions\TwigLanguageExtension( $labels ));
return $view;
};
/************************
* ADD MIDDLEWARE *
************************/
foreach($middleware as $pluginMiddleware)
{
$middlewareClass = $pluginMiddleware['classname'];
$middlewareParams = $pluginMiddleware['params'];
if(class_exists($middlewareClass))
{
$app->add(new $middlewareClass($middlewareParams));
}
}
if($container['flash'])
{
$app->add(new \Typemill\Middleware\ValidationErrorsMiddleware($container['view']));
$app->add(new \Typemill\Middleware\SecurityMiddleware($container['router'], $container['settings'], $container['flash']));
$app->add(new \Typemill\Middleware\OldInputMiddleware($container['view']));
$app->add($container->get('csrf'));
}
/********************************
* ASSET MIDDLEWARE FOR TWIG *
********************************/
$app->add(new \Typemill\Middleware\assetMiddleware($container));
/********************************
* PROXY DETECTION FOR REQUEST *
********************************/
if(isset($settings['settings']['proxy']) && $settings['settings']['proxy'])
{
$trustedProxies = ( isset($settings['settings']['trustedproxies']) && !empty($settings['settings']['trustedproxies']) ) ? explode(",", $settings['settings']['trustedproxies']) : [];
$app->add(new RKA\Middleware\ProxyDetection($trustedProxies));
}
/************************
* ADD ROUTES *
************************/
require __DIR__ . '/Routes/Api.php';
require __DIR__ . '/Routes/Web.php';