mirror of
https://github.com/typemill/typemill.git
synced 2025-01-17 05:18:19 +01:00
329 lines
9.9 KiB
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'; |