Add layout components and middlewares.

This commit is contained in:
Dave Smith-Hayes 2024-07-17 21:32:25 -04:00
parent 9d0cd8787d
commit 982d348a34
8 changed files with 76 additions and 97 deletions

View File

@ -1,3 +1,4 @@
DEPLOYMENT_ENV="development"
DATABASE_HOST="localhost" DATABASE_HOST="localhost"
DATABASE_USER="slovocast" DATABASE_USER="slovocast"
DATABASE_PASSWORD="Password01" DATABASE_PASSWORD="Password01"

View File

@ -2,6 +2,7 @@
namespace Slovocast; namespace Slovocast;
use Exception;
use Psr\Container\ContainerExceptionInterface; use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface; use Psr\Container\NotFoundExceptionInterface;
use Slim\App; use Slim\App;
@ -14,11 +15,8 @@ use Psr\Http\Message\ResponseFactoryInterface;
use DI\Container; use DI\Container;
use DI\ContainerBuilder; use DI\ContainerBuilder;
use Slim\Views\Twig;
use Slim\Views\TwigMiddleware;
use Slim\Psr7\Factory\ResponseFactory; use Slim\Psr7\Factory\ResponseFactory;
use Slovocast\Routes;
use Slovocast\Configuration\SiteInformationSchema; use Slovocast\Configuration\SiteInformationSchema;
use Slovocast\Configuration\DatabaseConnectionSchema; use Slovocast\Configuration\DatabaseConnectionSchema;
use Slovocast\Configuration\SessionSchema; use Slovocast\Configuration\SessionSchema;
@ -90,11 +88,10 @@ class Bootstrap
} }
/** /**
* Set up the Container with all of its definitions, as well as * Set up the Container with all of its definitions, as well as initialization of configuration.
* initialization of configuration.
* *
* @return Container * @return Container
* @throws \Exception * @throws Exception
*/ */
protected static function initContainer(): Container protected static function initContainer(): Container
{ {
@ -105,9 +102,7 @@ class Bootstrap
'config' => $config, 'config' => $config,
LoggerInterface::class => function() { LoggerInterface::class => function() {
$logger = new Logger(); $logger = new Logger();
$logger->pushHandler( $logger->pushHandler(new StreamHandler(APP_LOGS_DIR, Level::Warning));
new StreamHandler(APP_LOG_DIR, Level::Warning)
);
return $logger; return $logger;
}, },
@ -177,14 +172,12 @@ class Bootstrap
*/ */
protected static function establishRoutes(App $app): void protected static function establishRoutes(App $app): void
{ {
Routes::init($app); Routes::setup($app);
} }
/** /**
* Taking an instantiated application, sets up all the middleware required * Taking an instantiated application, sets up all the middleware required for the application to run. This appends
* for the application to run. This appends Middleware in a Global sense, * Middleware in a Global sense not per-route. Per-route middleware will be set in the `establishRoutes` method.
* not per-route. Per-route middleware will be set in the `establishRoutes`
* method.
* *
* @param App $app * @param App $app
* @throws ContainerExceptionInterface * @throws ContainerExceptionInterface
@ -193,30 +186,7 @@ class Bootstrap
*/ */
protected static function establishMiddleware(App $app): void protected static function establishMiddleware(App $app): void
{ {
/** @var ContainerInterface $container */ Middlewares::setup($app);
$container = $app->getContainer();
/**
* @var Configuration $config
*/
$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);
} }
/** /**
@ -226,7 +196,7 @@ class Bootstrap
* @throws ContainerExceptionInterface * @throws ContainerExceptionInterface
* @throws LoaderError * @throws LoaderError
* @throws NotFoundExceptionInterface * @throws NotFoundExceptionInterface
* @throws \Exception * @throws Exception
*/ */
public static function init(): App public static function init(): App
{ {

View File

@ -34,9 +34,6 @@ class UserRepository implements UserRepositoryInterface
/** /**
* Get a single instance of the User Entity. * Get a single instance of the User Entity.
*
* @param int $id
* @return User
*/ */
public function get(int $id): User public function get(int $id): User
{ {
@ -63,10 +60,6 @@ class UserRepository implements UserRepositoryInterface
return $this->userFromQueryResults($results->resultRows[0]); return $this->userFromQueryResults($results->resultRows[0]);
} }
/**
* @param User $user
* @return bool True if the User is saved.
*/
public function create(User $user): bool public function create(User $user): bool
{ {
$query = "INSERT INTO users (email, password, name) $query = "INSERT INTO users (email, password, name)
@ -99,11 +92,6 @@ class UserRepository implements UserRepositoryInterface
return (bool) $results->affectedRows; return (bool) $results->affectedRows;
} }
/**
* @param string $email
* @param string $password
* @return bool
*/
public function verifyPassword(string $email, string $password): bool public function verifyPassword(string $email, string $password): bool
{ {
try { try {

View File

@ -1,38 +0,0 @@
<?php
namespace Slovocast\Infrastructure;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
abstract class Middleware
{
/**
* @param Request $request
* @param Response $response
* @param callable $next
* @return Response
*/
public function __invoke(
Request $request,
Response $response,
callable $next
): Response {
return $this->invoke($request, $response, $next);
}
/**
* To write Middleware, we need to implement this concrete method, and set
* the child class as the Middleware in the Application bootstrapping.
*
* @param Request $request
* @param Response $response
* @param callable $next
* @return Response
*/
abstract public function invoke(
Request $request,
Response $response,
callable $next
): Response;
}

46
app/src/Middlewares.php Normal file
View File

@ -0,0 +1,46 @@
<?php
namespace Slovocast;
use League\Config\Configuration;
use Odan\Session\SessionInterface;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\ContainerInterface;
use Psr\Container\NotFoundExceptionInterface;
use Slim\App;
use Slim\Views\Twig;
use Slim\Views\TwigMiddleware;
use Twig\Error\LoaderError;
class Middlewares
{
/**
* @throws NotFoundExceptionInterface
* @throws ContainerExceptionInterface
* @throws LoaderError
*/
public static function setup(App $app): void
{
/** @var ContainerInterface $container */
$container = $app->getContainer();
/**
* @var Configuration $config
*/
$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);
}
}

View File

@ -19,7 +19,7 @@ class Routes
* @param App $app Instantiated Application * @param App $app Instantiated Application
* @return void * @return void
*/ */
public static function init(App $app): void public static function setup(App $app): void
{ {
$app->get('/', HomePage::class); $app->get('/', HomePage::class);
$app->get('/healthcheck', HealthCheck::class); $app->get('/healthcheck', HealthCheck::class);

View File

@ -0,0 +1,11 @@
{% for message in flash.get('notice') %}
<div class="flash notice">
{{ message }}
</div>
{% endfor %}
{% for message in flash.get('error') %}
<div class="flash error">
{{ message }}
</div>
{% endfor %}

View File

@ -2,7 +2,10 @@
<html lang="en"> <html lang="en">
<head> <head>
<title>{% block page_title %}{% endblock %}{{ site_name }}</title> <title>{% block page_title %}{% endblock %}{{ site_name }}</title>
{% block meta_tags %}
<meta name="description" value="{{ site_description }}"> <meta name="description" value="{{ site_description }}">
<meta name="keywords" value="{{ page_tags }}">
{% endblock %}
</head> </head>
<body> <body>
<div class="container"> <div class="container">
@ -11,11 +14,9 @@
</header> </header>
<main> <main>
{% for message in flash.get('error') %} {% include 'components/flash.twig' %}
<div class="flash error">
{{ message }}
</div>
{% endfor %}
{% block content %}{% endblock %} {% block content %}{% endblock %}
</main> </main>