@odan Please let me know, if any file is missing.
config/middleware.php:
<?php
declare(strict_types=1);
use Slim\App;
use Slim\Middleware\ErrorMiddleware;
use App\Middleware\UrlGeneratorMiddleware;
use Selective\BasePath\BasePathMiddleware;
use Slim\Views\TwigMiddleware;
use \Slim\HttpCache\Cache;
// use Middlewares;
return function (App $app) {
// Parse json, form data and xml
$app->addBodyParsingMiddleware();
$app->add(UrlGeneratorMiddleware::class);
// Add the Slim built-in routing middleware
$app->addRoutingMiddleware();
// Catch exceptions and errors
$app->add(ErrorMiddleware::class);
$app->add(TwigMiddleware::class);
$app->add(BasePathMiddleware::class);
// Register the http cache middleware.
$app->add(new Cache('public', 600));
// Middlewares::TrailingSlash(true) //(optional) set true to add the trailing slash instead remove
// ->redirect(301);
};
config/routes.php:
<?php
declare(strict_types=1);
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Slim\App;
return function (App $app) {
$app->get('/', \App\Action\HomeAction::class)->setName('home');
$app->get('/en', \App\Action\HomeEnAction::class)->setName('en');
$app->redirect('/en/', '/en', 301);
// listening on both with/withour trailing slash
// $app->get('/en[/]', \App\Action\HomeEnAction::class)->setName('en');
// redirects
$app->redirect('/sk[/]', '/', 301);
$app-> get('/download', \App\Action\DownloadAction::class)->setName('download');
};
src/Middleware/UrlGeneratorMiddleware.php:
<?php
namespace App\Middleware;
use App\Routing\UrlGenerator;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
/**
* Middleware.
*/
final class UrlGeneratorMiddleware implements MiddlewareInterface
{
/**
* @var UrlGenerator
*/
private $urlGenerator;
/**
* The constructor.
*
* @param UrlGenerator $urlGenerator The url generator
*/
public function __construct(UrlGenerator $urlGenerator)
{
$this->urlGenerator = $urlGenerator;
}
/**
* Invoke middleware.
*
* @param ServerRequestInterface $request The request
* @param RequestHandlerInterface $handler The handler
*
* @return ResponseInterface The response
*/
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
$this->urlGenerator->setRequest($request);
return $handler->handle($request);
}
}
config/settings.php:
<?php
declare(strict_types=1);
// Error reporting for production
error_reporting(0);
// error_reporting(E_ALL);
ini_set('display_errors', '0');
// Timezone
date_default_timezone_set('Europe/Bratislava');
// Settings
$settings = [];
// Path settings
$settings['root'] = dirname(__DIR__);
//echo $settings['root'];
$settings['temp'] = $settings['root'] . '/tmp';
$settings['public'] = $settings['root'] . '/public';
// Error Handling Middleware settings
$settings['error'] = [
// Should be set to false in production
'display_error_details' => false,
// Parameter is passed to the default ErrorHandler
// View in rendered output by enabling the "displayErrorDetails" setting.
// For the console and unit tests we also disable it
'log_errors' => true,
// Display error details in error log
'log_error_details' => true,
];
// Application settings
$settings['app'] = [
'secret' => '{{app_secret}}',
];
// Logger settings
$settings['logger'] = [
'name' => 'app',
'path' => $settings['root'] . '/app_logs',
'filename' => 'app.log',
'level' => \Monolog\Logger::DEBUG,
'file_permission' => 0775,
];
// Twig settings
// Configuration reference: https://symfony.com/doc/current/reference/configuration/twig.html
$settings['twig'] = [
// Template paths
'paths' => [
__DIR__ . '/../templates',
__DIR__ . '/../public',
],
// Twig environment options
'options' => [
'debug' => false,
// Should be set to true in production
'cache_enabled' => true,
'cache_path' => $settings['temp'] . '/twig',
],
];
// Assets
$settings['assets'] = [
// Public assets cache directory
'path' => $settings['public'] . '/cache',
'url_base_path' => 'cache/',
// Cache settings
'cache_enabled' => true,
'cache_path' => $settings['temp'],
'cache_name' => 'assets-cache',
// Should be set to 1 (enabled) in production
'minify' => 1,
];
// Session
$settings['session'] = [
'name' => 'dubakcv',
'cache_expire' => 0,
];
// Console commands
$settings['commands'] = [
\App\Console\TwigCompilerCommand::class
];
return $settings;
config/container.php:
<?php
declare(strict_types=1);
use App\Factory\LoggerFactory;
use App\Handler\DefaultErrorHandler;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseFactoryInterface;
use Fullpipe\TwigWebpackExtension\WebpackExtension;
use Selective\BasePath\BasePathMiddleware;
use Selective\Validation\Encoder\JsonEncoder;
use Selective\Validation\Middleware\ValidationExceptionMiddleware;
use Selective\Validation\Transformer\ErrorDetailsResultTransformer;
use Slim\App;
use Slim\Factory\AppFactory;
use Slim\Http\Environment;
use Slim\Interfaces\RouteParserInterface;
use Slim\Middleware\ErrorMiddleware;
use Slim\Psr7\Factory\UriFactory;
use Slim\Views\Twig;
use Slim\Views\TwigExtension;
use Slim\Views\TwigMiddleware;
use Slim\Views\TwigRuntimeLoader;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;
use Twig\Loader\FilesystemLoader;
use Twig\TwigFunction;
use Odan\Twig\TwigAssetsExtension;
use \Slim\HttpCache\CacheProvider;
return [
'settings' => function () {
return require __DIR__ . '/settings.php';
},
'environment' => function() {
// $_SERVER["SERVER_NAME"] = "cv.dubak.sk";
return new Environment($_SERVER);
},
App::class => function (ContainerInterface $container) {
AppFactory::setContainer($container);
return AppFactory::create();
},
// For the responder
ResponseFactoryInterface::class => function (ContainerInterface $container) {
return $container->get(App::class)->getResponseFactory();
},
// The Slim RouterParser
RouteParserInterface::class => function (ContainerInterface $container) {
return $container->get(App::class)->getRouteCollector()->getRouteParser();
},
// The logger factory
LoggerFactory::class => function (ContainerInterface $container) {
return new LoggerFactory($container->get('settings')['logger']);
},
TwigMiddleware::class => function (ContainerInterface $container) {
return TwigMiddleware::createFromContainer($container->get(App::class), Twig::class);
},
Twig::class => function (ContainerInterface $container) {
// $settings = $container->get('settings')['twig'];
$config = (array)$container->get('settings');
$settings = $config['twig'];
$twig = Twig::create($settings['paths'], $settings['options']);
$loader = $twig->getLoader();
$publicPath = (string)$config['public'];
if ($loader instanceof FilesystemLoader) {
$loader->addPath($publicPath, 'public');
}
// Add extensions
$twig->addExtension(new WebpackExtension($publicPath . '/assets/manifest.json', $publicPath));
$environment = $twig->getEnvironment();
// Add Twig extensions
$twig->addExtension(new TwigAssetsExtension($environment, (array)$config['assets']));
// $view = new Twig(__DIR__ . '/../templates', [
// 'cache' => false,
// ]);
// extension for path_for and base_url
// $twig->addExtension(new TwigExtension($container->router, $container->request->getUri()));
return $twig;
},
ErrorMiddleware::class => function (ContainerInterface $container) {
$settings = $container->get('settings')['error'];
$app = $container->get(App::class);
$logger = $container->get(LoggerFactory::class)
->addFileHandler('error.log')
->createInstance('default_error_handler');
$errorMiddleware = new ErrorMiddleware(
$app->getCallableResolver(),
$app->getResponseFactory(),
(bool)$settings['display_error_details'],
(bool)$settings['log_errors'],
(bool)$settings['log_error_details'],
$logger
);
$errorMiddleware->setDefaultErrorHandler($container->get(DefaultErrorHandler::class));
return $errorMiddleware;
},
BasePathMiddleware::class => function (ContainerInterface $container) {
$app = $container->get(App::class);
return new BasePathMiddleware($app);
},
CacheProvider::class => function (ContainerInterface $container) {
$app = $container->get(App::class);
return new CacheProvider($app);
}
];
Also, worthy to note, that website routing worked before the upgrade from Slim 4.7 onto 4.14.