Refactored Databa config customizer so that it uses new structure

This commit is contained in:
Alejandro Celaya 2018-10-05 18:43:39 +02:00
parent 1b5081ae21
commit ebf2e459e8
5 changed files with 90 additions and 31 deletions

View File

@ -40,3 +40,8 @@ function env($key, $default = null)
return trim($value);
}
function contains($needle, array $haystack)
{
return \in_array($needle, $haystack, true);
}

View File

@ -146,7 +146,7 @@ class InstallCommand extends Command
$this->io->writeln(['<info>Custom configuration properly generated!</info>', '']);
// If current command is not update, generate database
if (! $this->isUpdate) {
if (! $this->isUpdate) {
$this->io->write('Initializing database...');
if (! $this->runPhpCommand(
'vendor/doctrine/orm/bin/doctrine.php orm:schema-tool:create',

View File

@ -8,12 +8,30 @@ use Shlinkio\Shlink\Installer\Util\AskUtilsTrait;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Filesystem\Exception\IOException;
use Symfony\Component\Filesystem\Filesystem;
use function array_diff;
use function array_keys;
use function Shlinkio\Shlink\Common\contains;
class DatabaseConfigCustomizer implements ConfigCustomizerInterface
{
use AskUtilsTrait;
private const DRIVER = 'DRIVER';
private const NAME = 'NAME';
private const USER = 'USER';
private const PASSWORD = 'PASSWORD';
private const HOST = 'HOST';
private const PORT = 'PORT';
private const DRIVER_DEPENDANT_OPTIONS = [
self::DRIVER,
self::NAME,
self::USER,
self::PASSWORD,
self::HOST,
self::PORT,
];
private const EXPECTED_KEYS = self::DRIVER_DEPENDANT_OPTIONS; // Same now, but could change in the future
private const DATABASE_DRIVERS = [
'MySQL' => 'pdo_mysql',
'PostgreSQL' => 'pdo_pgsql',
@ -37,39 +55,74 @@ class DatabaseConfigCustomizer implements ConfigCustomizerInterface
{
$io->title('DATABASE');
if ($appConfig->hasDatabase() && $io->confirm('Do you want to keep imported database config?')) {
// If the user selected to keep DB config and is configured to use sqlite, copy DB file
if ($appConfig->getDatabase()['DRIVER'] === self::DATABASE_DRIVERS['SQLite']) {
try {
$this->filesystem->copy(
$appConfig->getImportedInstallationPath() . '/' . CustomizableAppConfig::SQLITE_DB_PATH,
CustomizableAppConfig::SQLITE_DB_PATH
);
} catch (IOException $e) {
$io->error('It wasn\'t possible to import the SQLite database');
throw $e;
}
}
$db = $appConfig->getDatabase();
$doImport = $appConfig->hasDatabase() && $io->confirm('Do you want to keep imported database config?');
$keysToAskFor = $doImport ? array_diff(self::EXPECTED_KEYS, array_keys($db)) : self::EXPECTED_KEYS;
// If the user selected to keep DB, try to import SQLite database
if ($doImport) {
$this->importSqliteDbFile($io, $appConfig);
}
if (empty($keysToAskFor)) {
return;
}
// Select database type
$params = [];
$databases = array_keys(self::DATABASE_DRIVERS);
$dbType = $io->choice('Select database type', $databases, $databases[0]);
$params['DRIVER'] = self::DATABASE_DRIVERS[$dbType];
// Ask for connection params if database is not SQLite
if ($params['DRIVER'] !== self::DATABASE_DRIVERS['SQLite']) {
$params['NAME'] = $io->ask('Database name', 'shlink');
$params['USER'] = $this->askRequired($io, 'username', 'Database username');
$params['PASSWORD'] = $this->askRequired($io, 'password', 'Database password');
$params['HOST'] = $io->ask('Database host', 'localhost');
$params['PORT'] = $io->ask('Database port', $this->getDefaultDbPort($params['DRIVER']));
// If the driver is one of the params to ask for, ask for it first
if (contains(self::DRIVER, $keysToAskFor)) {
$db[self::DRIVER] = $this->ask($io, self::DRIVER);
$keysToAskFor = array_diff($keysToAskFor, [self::DRIVER]);
}
$appConfig->setDatabase($params);
// If driver is SQLite, do not ask any driver-dependant option
if ($db[self::DRIVER] === self::DATABASE_DRIVERS['SQLite']) {
$keysToAskFor = array_diff($keysToAskFor, self::DRIVER_DEPENDANT_OPTIONS);
}
// Iterate any remaining option and ask for it
foreach ($keysToAskFor as $key) {
$db[$key] = $this->ask($io, $key, $db);
}
$appConfig->setDatabase($db);
}
private function importSqliteDbFile(SymfonyStyle $io, CustomizableAppConfig $appConfig): void
{
if ($appConfig->getDatabase()[self::DRIVER] !== self::DATABASE_DRIVERS['SQLite']) {
return;
}
try {
$this->filesystem->copy(
$appConfig->getImportedInstallationPath() . '/' . CustomizableAppConfig::SQLITE_DB_PATH,
CustomizableAppConfig::SQLITE_DB_PATH
);
} catch (IOException $e) {
$io->error('It wasn\'t possible to import the SQLite database');
throw $e;
}
}
private function ask(SymfonyStyle $io, string $key, array $params = [])
{
switch ($key) {
case self::DRIVER:
$databases = array_keys(self::DATABASE_DRIVERS);
$dbType = $io->choice('Select database type', $databases, $databases[0]);
return self::DATABASE_DRIVERS[$dbType];
case self::NAME:
return $io->ask('Database name', 'shlink');
case self::USER:
return $this->askRequired($io, 'username', 'Database username');
case self::PASSWORD:
return $this->askRequired($io, 'password', 'Database password');
case self::HOST:
return $io->ask('Database host', 'localhost');
case self::PORT:
return $io->ask('Database port', $this->getDefaultDbPort($params[self::DRIVER]));
}
return '';
}
private function getDefaultDbPort(string $driver): string

View File

@ -10,7 +10,6 @@ use function array_keys;
class LanguageConfigCustomizer implements ConfigCustomizerInterface
{
private const SUPPORTED_LANGUAGES = ['en', 'es'];
private const DEFAULT_LANG = 'DEFAULT';
private const CLI_LANG = 'CLI';
private const EXPECTED_KEYS = [
@ -18,6 +17,8 @@ class LanguageConfigCustomizer implements ConfigCustomizerInterface
self::CLI_LANG,
];
private const SUPPORTED_LANGUAGES = ['en', 'es'];
public function process(SymfonyStyle $io, CustomizableAppConfig $appConfig): void
{
$io->title('LANGUAGE');

View File

@ -31,8 +31,8 @@ class UrlShortenerConfigCustomizer implements ConfigCustomizerInterface
$io->title('URL SHORTENER');
$urlShortener = $appConfig->getUrlShortener();
$diffKeys = $appConfig->hasUrlShortener() && $io->confirm('Do you want to keep imported URL shortener config?');
$keysToAskFor = $diffKeys ? array_diff(self::EXPECTED_KEYS, array_keys($urlShortener)) : self::EXPECTED_KEYS;
$doImport = $appConfig->hasUrlShortener() && $io->confirm('Do you want to keep imported URL shortener config?');
$keysToAskFor = $doImport ? array_diff(self::EXPECTED_KEYS, array_keys($urlShortener)) : self::EXPECTED_KEYS;
if (empty($keysToAskFor)) {
return;