From 6c41f0610526dec16148a5e128a4a1b3301409cd Mon Sep 17 00:00:00 2001 From: binaryDiv Date: Sat, 25 Sep 2021 23:56:04 +0200 Subject: [PATCH] Implement YAML config loader --- .env.develop | 1 + .gitignore | 4 ++ Dockerfile | 6 ++- TODO.md | 2 +- composer.json | 1 + config/app.develop.yml | 19 ++++++++ config/app.example.yml | 23 ++++++++++ public/index.php | 10 +++- src/Config/AppConfig.php | 15 +++++- src/Config/Loaders/AutoConfigLoader.php | 28 ++++++++++++ src/Config/Loaders/ConfigLoaderInterface.php | 11 +++++ src/Config/Loaders/EnvConfigLoader.php | 4 +- src/Config/Loaders/YamlConfigLoader.php | 48 ++++++++++++++++++++ templates/base.html.twig | 6 ++- 14 files changed, 169 insertions(+), 9 deletions(-) create mode 100644 config/app.develop.yml create mode 100644 config/app.example.yml create mode 100644 src/Config/Loaders/AutoConfigLoader.php create mode 100644 src/Config/Loaders/ConfigLoaderInterface.php create mode 100644 src/Config/Loaders/YamlConfigLoader.php diff --git a/.env.develop b/.env.develop index 07b491f..f6a431d 100644 --- a/.env.develop +++ b/.env.develop @@ -10,6 +10,7 @@ MYSQL_USER=mailaccountadmin MYSQL_PASSWORD=mailaccountadmin # App settings +APP_TITLE="MailAccountAdmin [dev]" APP_ENV=development APP_DEBUG=true APP_TIMEZONE=Europe/Berlin diff --git a/.gitignore b/.gitignore index 646c542..37cecc0 100644 --- a/.gitignore +++ b/.gitignore @@ -10,5 +10,9 @@ # PHP /.composer /.phpunit.cache +/.twig.cache /coverage /vendor + +# Production settings +/config/app.yml diff --git a/Dockerfile b/Dockerfile index 9f9d176..89effb8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,8 +3,10 @@ FROM php:7.4-apache AS base WORKDIR /var/www RUN apt-get update && \ - apt-get install -y libzip-dev unzip git && \ - docker-php-ext-install pdo pdo_mysql zip + apt-get install -y git unzip libyaml-dev libzip-dev && \ + docker-php-ext-install pdo pdo_mysql zip && \ + pecl install yaml && \ + docker-php-ext-enable yaml RUN a2enmod rewrite && \ sed -ri -e 's!/var/www/html!/var/www/public!g' /etc/apache2/sites-available/*.conf diff --git a/TODO.md b/TODO.md index 2226cf1..4697f74 100644 --- a/TODO.md +++ b/TODO.md @@ -4,7 +4,6 @@ ## General -- Settings from a config file - Database migrations - Documentation - App deployment @@ -12,6 +11,7 @@ - Refactor auth and session handling ## Admin user management + - Create/edit/delete admins - Change own password diff --git a/composer.json b/composer.json index 93dcd53..aa59362 100644 --- a/composer.json +++ b/composer.json @@ -14,6 +14,7 @@ "require": { "php": "^7.4", "ext-pdo": "*", + "ext-yaml": "*", "slim/slim": "^4.8", "slim/psr7": "^1.3", "php-di/php-di": "^6.3", diff --git a/config/app.develop.yml b/config/app.develop.yml new file mode 100644 index 0000000..923ceb4 --- /dev/null +++ b/config/app.develop.yml @@ -0,0 +1,19 @@ +# Config file for local development (same settings as .env.develop) + +# -- App settings +appTitle: "MailAccountAdmin [dev]" +environment: development +debug: true +timezone: Europe/Berlin + +# -- Twig settings +twig: + cacheDir: + +# -- Database settings +database: + host: db + port: 3306 + name: mailusers + username: mailaccountadmin + password: mailaccountadmin diff --git a/config/app.example.yml b/config/app.example.yml new file mode 100644 index 0000000..2683c29 --- /dev/null +++ b/config/app.example.yml @@ -0,0 +1,23 @@ +# This is an example config file for MailAccountAdmin. +# Copy this file to /config/app.yml and change as needed. +# Settings that are commented out represent the default values. + +# -- App settings +# appTitle: MailAccountAdmin +# environment: production +# debug: false +# timezone: UTC +# dateTimeFormat: r + +# -- Twig settings +twig: + # Cache directory for Twig templates (default: unset, which means no cache is used) + cacheDir: .twig.cache + +# -- Database settings +database: + host: localhost + port: 3306 + name: mailusers + username: mailaccountadmin + password: very_secret_password diff --git a/public/index.php b/public/index.php index 10628de..c918330 100644 --- a/public/index.php +++ b/public/index.php @@ -3,15 +3,21 @@ declare(strict_types=1); require_once __DIR__ . '/../vendor/autoload.php'; -use MailAccountAdmin\Config\Loaders\EnvConfigLoader; +use MailAccountAdmin\Config\Loaders\AutoConfigLoader; use MailAccountAdmin\Dependencies; use MailAccountAdmin\Middlewares; use MailAccountAdmin\Routes; use Slim\Factory\AppFactory; +const ROOT_DIR = __DIR__ . '/..'; + session_start(); -$config = EnvConfigLoader::loadFromEnv(); +// Load application config (from config file or environment variables) +$configLoader = new AutoConfigLoader(); +$config = $configLoader->loadConfig(); + +// Create application $container = Dependencies::createContainer($config); $app = AppFactory::createFromContainer($container); diff --git a/src/Config/AppConfig.php b/src/Config/AppConfig.php index 4735a10..ce94e39 100644 --- a/src/Config/AppConfig.php +++ b/src/Config/AppConfig.php @@ -70,10 +70,23 @@ class AppConfig return $this->dateTimeFormat; } + public function getTwigCacheDir(): ?string + { + if (empty($this->twigCacheDir)) { + return null; + } elseif (substr($this->twigCacheDir, 0, 1) === '/') { + // Absolute path + return $this->twigCacheDir; + } else { + // Relative path + return ROOT_DIR . '/' . $this->twigCacheDir; + } + } + public function getTwigSettings(): array { return [ - 'cache' => $this->twigCacheDir ?: false, + 'cache' => $this->getTwigCacheDir() ?: false, 'debug' => $this->isDebugMode(), 'strict_variables' => $this->isDebugMode(), ]; diff --git a/src/Config/Loaders/AutoConfigLoader.php b/src/Config/Loaders/AutoConfigLoader.php new file mode 100644 index 0000000..6ba336c --- /dev/null +++ b/src/Config/Loaders/AutoConfigLoader.php @@ -0,0 +1,28 @@ +configLoader = new YamlConfigLoader($yamlFilePath); + } else { + $this->configLoader = new EnvConfigLoader(); + } + } + + public function loadConfig(): AppConfig + { + return $this->configLoader->loadConfig(); + } +} diff --git a/src/Config/Loaders/ConfigLoaderInterface.php b/src/Config/Loaders/ConfigLoaderInterface.php new file mode 100644 index 0000000..ed8ebe6 --- /dev/null +++ b/src/Config/Loaders/ConfigLoaderInterface.php @@ -0,0 +1,11 @@ +filePath = $filePath; + } + + public function loadConfig(): AppConfig + { + // Parse yml config file + $parsedConfig = yaml_parse_file($this->filePath); + + // Check datatypes + assert(is_array($parsedConfig)); + assert(!isset($parsedConfig['twig']) || is_array($parsedConfig['twig'])); + assert(!isset($parsedConfig['database']) || is_array($parsedConfig['database'])); + + return AppConfig::createFromArray([ + // App settings + 'appTitle' => $parsedConfig['appTitle'] ?? null, + 'environment' => $parsedConfig['environment'] ?? null, + 'debug' => (bool)$parsedConfig['debug'] ?? null, + 'timezone' => $parsedConfig['timezone'] ?? null, + 'dateTimeFormat' => $parsedConfig['dateTimeFormat'] ?? null, + + // Twig settings + 'twigCacheDir' => $parsedConfig['twig']['cacheDir'] ?? null, + + // Database settings + 'databaseHost' => $parsedConfig['database']['host'] ?? null, + 'databasePort' => (int)$parsedConfig['database']['port'] ?? null, + 'databaseName' => $parsedConfig['database']['name'] ?? null, + 'databaseUsername' => $parsedConfig['database']['username'] ?? null, + 'databasePassword' => $parsedConfig['database']['password'] ?? null, + ]); + } +} diff --git a/templates/base.html.twig b/templates/base.html.twig index c364b6d..bd0d091 100644 --- a/templates/base.html.twig +++ b/templates/base.html.twig @@ -12,7 +12,11 @@

{{ app_info.getTitle() }}

- {{ app_info.getVersion() }} + {% if logged_in | default() %} + {{ app_info.getVersion() }} + {% else %} + {{ app_info.getVersion() }} + {% endif %}