slovocast/app/src/Bootstrap.php

215 lines
6.2 KiB
PHP

<?php
namespace Slovocast;
use Slim\App;
use Slim\Factory\AppFactory;
use League\Config\Configuration;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseFactoryInterface;
use DI\Container;
use DI\ContainerBuilder;
use Slim\Views\Twig;
use Slim\Views\TwigMiddleware;
use Slim\Psr7\Factory\ResponseFactory;
use Slovocast\Routes;
use Slovocast\Configuration\{
SiteInformationSchema,
DatabaseConnectionSchema,
SessionSchema
};
use Slovocast\Domain\Repository\{
UserRepositoryInterface,
UserRepository
};
use Slovocast\Infrastructure\{
DatabaseConnectionInterface,
User\UserAuthorizationInterface,
User\BasicUserAuthorization
};
use Psr\Log\LoggerInterface;
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Monolog\Level;
use Odan\Session\PhpSession;
use Odan\Session\SessionInterface;
use Odan\Session\SessionManagerInterface;
/**
* Defines here are used globally
*/
define('APP_ROOT_DIR', __DIR__ . '/..');
define('APP_SRC_DIR', __DIR__);
define('APP_PUBLIC_DIR', __DIR__ . '/../public');
define('APP_TEMPLATES_DIR', __DIR__ . '/../templates');
define('APP_LOGS_DIR', __DIR__ . '/../var/logs');
define('APP_TEMP_DIR', __DIR__ . '/../var/temp');
class Bootstrap
{
/**
* Pulls out all the configuration schemas and configuration values.
*
* @return Configuration
*/
protected static function initConfig(): Configuration
{
$config = new Configuration();
$dotenv = \DotenvVault\DotenvVault::createImmutable(APP_ROOT_DIR);
// set all configuration details
$config->addSchema('site', SiteInformationSchema::getSchema());
$config->addSchema('database', DatabaseConnectionSchema::getSchema());
$config->addSchema('session', SessionSchema::getSchema());
$config->merge([
'site' => [
'name' => "Slovocast",
'description' => "A no-bullshit podcast hosting platform.",
'tags' => [
'podcast', 'hosting', 'indie', 'independent', 'easy'
]
],
'session' => [
'name' => 'slovocast'
]
]);
return $config;
}
/**
* Set up the Container with all of its definitions, as well as
* initialization of configuration.
*
* @return Container
*/
protected static function initContainer(): Container
{
$containerBuilder = new ContainerBuilder();
$config = self::initConfig();
$containerBuilder->addDefinitions([
'config' => $config,
LoggerInterface::class => function() {
$logger = new Logger();
$logger->pushHandler(
new StreamHandler(APP_LOG_DIR, Level::Warning)
);
return $logger;
},
/**
* Session and Flash classes here
*/
SessionManagerInterface::class => function (ContainerInterface $container) {
return $container->get(SessionInterface::class);
},
SessionInterface::class => function (ContainerInterface $container) {
$options = $container->get('config')->get('session');
return new PhpSession($options);
},
'flash' => function (ContainerInterface $container) {
return $container->get(SessionInterface::class)->getFlash();
},
/**
* Application DI
*/
ResponseFactoryInterface::class => function (ContainerInterface $container) {
return new ResponseFactory();
},
/**
* Database Connections
*/
/**
* Utility classes
*/
UserAuthorizationInterface::class => function(ContainerInterface $container) {
return new BasicUserAuthorization();
},
/**
* Add the Domain Repositories Here
*/
UserRepositoryInterface::class => function (ContainerInterface $container) {
return new UserRepository(
$container->get(DatabaseConnectionInterface::class),
$container->get(UserAuthorizationInterface::class)
);
}
]);
return $containerBuilder->build();
}
/**
* Tasking the instaniated Application, sets up all the routes for the
* application.
*
* @param App $app
* @return void
*/
protected static function establishRoutes(App $app): void
{
Routes::init($app);
}
/**
* Taking an instantiated application, sets up all the middleware required
* for the application to run. This appends Middleware in a Global sense,
* not per-route. Per-route middleware will be set in the `establishRoutes`
* method.
*
* @param App $app
*/
protected static function establishMiddleware(App $app): void
{
/** @var ContainerInterface $container */
$container = $app->getContainer();
/**
* @var Configuration
*/
$config = $container->get('config');
// Twig
$templateCache = false;
$twig = Twig::create(APP_TEMPLATES_DIR, [ 'cache' => $templateCache ]);
// Add the global variables
$twig->getEnvironment()
->addGlobal('site_name', $config->get('site.name'));
$twig->getEnvironment()
->addGlobal('site_description', $config->get('site.description'));
$flash = $container->get(SessionInterface::class)->getFlash();
$twig->getEnvironment()
->addGlobal('flash', $flash);
$app->add(TwigMiddleware::create($app, $twig));
// Add the error handling middleware
$app->addErrorMiddleware(true, true, true);
}
/**
* Instantiates the application.
*
* @return App
*/
public static function init(): App
{
$container = self::initContainer();
$app = AppFactory::createFromContainer($container);
self::establishMiddleware($app);
self::establishRoutes($app);
return $app;
}
}