mirror of
https://github.com/shlinkio/shlink.git
synced 2025-02-25 18:45:27 -06:00
Ensured required config options cannot be left empty
This commit is contained in:
parent
48f01921e1
commit
8323b87076
@ -19,20 +19,14 @@ class ApplicationConfigCustomizer implements ConfigCustomizerInterface
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$validator = function ($value) {
|
|
||||||
return $value;
|
|
||||||
};
|
|
||||||
$appConfig->setApp([
|
$appConfig->setApp([
|
||||||
'SECRET' => $io->ask(
|
'SECRET' => $io->ask(
|
||||||
'Define a secret string that will be used to sign API tokens (leave empty to autogenerate one)',
|
'Define a secret string that will be used to sign API tokens (leave empty to autogenerate one) '
|
||||||
null,
|
. '<fg=red>[DEPRECATED. TO BE REMOVED]</>'
|
||||||
$validator
|
|
||||||
) ?: $this->generateRandomString(32),
|
) ?: $this->generateRandomString(32),
|
||||||
'DISABLE_TRACK_PARAM' => $io->ask(
|
'DISABLE_TRACK_PARAM' => $io->ask(
|
||||||
'Provide a parameter name that you will be able to use to disable tracking on specific request to '
|
'Provide a parameter name that you will be able to use to disable tracking on specific request to '
|
||||||
. 'short URLs (leave empty and this feature won\'t be enabled)',
|
. 'short URLs (leave empty and this feature won\'t be enabled)'
|
||||||
null,
|
|
||||||
$validator
|
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
@ -4,12 +4,15 @@ declare(strict_types=1);
|
|||||||
namespace Shlinkio\Shlink\Installer\Config\Plugin;
|
namespace Shlinkio\Shlink\Installer\Config\Plugin;
|
||||||
|
|
||||||
use Shlinkio\Shlink\Installer\Model\CustomizableAppConfig;
|
use Shlinkio\Shlink\Installer\Model\CustomizableAppConfig;
|
||||||
|
use Shlinkio\Shlink\Installer\Util\AskUtilsTrait;
|
||||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||||
use Symfony\Component\Filesystem\Exception\IOException;
|
use Symfony\Component\Filesystem\Exception\IOException;
|
||||||
use Symfony\Component\Filesystem\Filesystem;
|
use Symfony\Component\Filesystem\Filesystem;
|
||||||
|
|
||||||
class DatabaseConfigCustomizer implements ConfigCustomizerInterface
|
class DatabaseConfigCustomizer implements ConfigCustomizerInterface
|
||||||
{
|
{
|
||||||
|
use AskUtilsTrait;
|
||||||
|
|
||||||
private const DATABASE_DRIVERS = [
|
private const DATABASE_DRIVERS = [
|
||||||
'MySQL' => 'pdo_mysql',
|
'MySQL' => 'pdo_mysql',
|
||||||
'PostgreSQL' => 'pdo_pgsql',
|
'PostgreSQL' => 'pdo_pgsql',
|
||||||
@ -59,8 +62,8 @@ class DatabaseConfigCustomizer implements ConfigCustomizerInterface
|
|||||||
// Ask for connection params if database is not SQLite
|
// Ask for connection params if database is not SQLite
|
||||||
if ($params['DRIVER'] !== self::DATABASE_DRIVERS['SQLite']) {
|
if ($params['DRIVER'] !== self::DATABASE_DRIVERS['SQLite']) {
|
||||||
$params['NAME'] = $io->ask('Database name', 'shlink');
|
$params['NAME'] = $io->ask('Database name', 'shlink');
|
||||||
$params['USER'] = $io->ask('Database username');
|
$params['USER'] = $this->askRequired($io, 'username', 'Database username');
|
||||||
$params['PASSWORD'] = $io->ask('Database password');
|
$params['PASSWORD'] = $this->askRequired($io, 'password', 'Database password');
|
||||||
$params['HOST'] = $io->ask('Database host', 'localhost');
|
$params['HOST'] = $io->ask('Database host', 'localhost');
|
||||||
$params['PORT'] = $io->ask('Database port', $this->getDefaultDbPort($params['DRIVER']));
|
$params['PORT'] = $io->ask('Database port', $this->getDefaultDbPort($params['DRIVER']));
|
||||||
}
|
}
|
||||||
|
@ -19,12 +19,12 @@ class LanguageConfigCustomizer implements ConfigCustomizerInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
$appConfig->setLanguage([
|
$appConfig->setLanguage([
|
||||||
'DEFAULT' => $this->chooseLanguage('Select default language for the application in general', $io),
|
'DEFAULT' => $this->chooseLanguage($io, 'Select default language for the application in general'),
|
||||||
'CLI' => $this->chooseLanguage('Select default language for CLI executions', $io),
|
'CLI' => $this->chooseLanguage($io, 'Select default language for CLI executions'),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function chooseLanguage(string $message, SymfonyStyle $io): string
|
private function chooseLanguage(SymfonyStyle $io, string $message): string
|
||||||
{
|
{
|
||||||
return $io->choice($message, self::SUPPORTED_LANGUAGES, self::SUPPORTED_LANGUAGES[0]);
|
return $io->choice($message, self::SUPPORTED_LANGUAGES, self::SUPPORTED_LANGUAGES[0]);
|
||||||
}
|
}
|
||||||
|
@ -5,11 +5,14 @@ namespace Shlinkio\Shlink\Installer\Config\Plugin;
|
|||||||
|
|
||||||
use Shlinkio\Shlink\Core\Service\UrlShortener;
|
use Shlinkio\Shlink\Core\Service\UrlShortener;
|
||||||
use Shlinkio\Shlink\Installer\Model\CustomizableAppConfig;
|
use Shlinkio\Shlink\Installer\Model\CustomizableAppConfig;
|
||||||
|
use Shlinkio\Shlink\Installer\Util\AskUtilsTrait;
|
||||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||||
use function str_shuffle;
|
use function str_shuffle;
|
||||||
|
|
||||||
class UrlShortenerConfigCustomizer implements ConfigCustomizerInterface
|
class UrlShortenerConfigCustomizer implements ConfigCustomizerInterface
|
||||||
{
|
{
|
||||||
|
use AskUtilsTrait;
|
||||||
|
|
||||||
public function process(SymfonyStyle $io, CustomizableAppConfig $appConfig): void
|
public function process(SymfonyStyle $io, CustomizableAppConfig $appConfig): void
|
||||||
{
|
{
|
||||||
$io->title('URL SHORTENER');
|
$io->title('URL SHORTENER');
|
||||||
@ -25,14 +28,9 @@ class UrlShortenerConfigCustomizer implements ConfigCustomizerInterface
|
|||||||
['http', 'https'],
|
['http', 'https'],
|
||||||
'http'
|
'http'
|
||||||
),
|
),
|
||||||
'HOSTNAME' => $io->ask('Hostname for generated URLs'),
|
'HOSTNAME' => $this->askRequired($io, 'hostname', 'Hostname for generated URLs'),
|
||||||
'CHARS' => $io->ask(
|
'CHARS' => $io->ask('Character set for generated short codes (leave empty to autogenerate one)')
|
||||||
'Character set for generated short codes (leave empty to autogenerate one)',
|
?: str_shuffle(UrlShortener::DEFAULT_CHARS),
|
||||||
null,
|
|
||||||
function ($value) {
|
|
||||||
return $value;
|
|
||||||
}
|
|
||||||
) ?: str_shuffle(UrlShortener::DEFAULT_CHARS),
|
|
||||||
'VALIDATE_URL' => $io->confirm('Do you want to validate long urls by 200 HTTP status code on response'),
|
'VALIDATE_URL' => $io->confirm('Do you want to validate long urls by 200 HTTP status code on response'),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
10
module/Installer/src/Exception/ExceptionInterface.php
Normal file
10
module/Installer/src/Exception/ExceptionInterface.php
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Shlinkio\Shlink\Installer\Exception;
|
||||||
|
|
||||||
|
use Throwable;
|
||||||
|
|
||||||
|
interface ExceptionInterface extends Throwable
|
||||||
|
{
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Shlinkio\Shlink\Installer\Exception;
|
||||||
|
|
||||||
|
use RuntimeException;
|
||||||
|
use function sprintf;
|
||||||
|
|
||||||
|
class MissingRequiredOptionException extends RuntimeException implements ExceptionInterface
|
||||||
|
{
|
||||||
|
public static function fromOption(string $optionName): self
|
||||||
|
{
|
||||||
|
return new self(sprintf('The "%s" is required and can\'t be empty', $optionName));
|
||||||
|
}
|
||||||
|
}
|
22
module/Installer/src/Util/AskUtilsTrait.php
Normal file
22
module/Installer/src/Util/AskUtilsTrait.php
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Shlinkio\Shlink\Installer\Util;
|
||||||
|
|
||||||
|
use Shlinkio\Shlink\Installer\Exception\MissingRequiredOptionException;
|
||||||
|
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||||
|
|
||||||
|
trait AskUtilsTrait
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
private function askRequired(SymfonyStyle $io, string $optionName, string $question)
|
||||||
|
{
|
||||||
|
return $io->ask($question, null, function ($value) use ($optionName) {
|
||||||
|
if (empty($value)) {
|
||||||
|
throw MissingRequiredOptionException::fromOption($optionName);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace ShlinkioTest\Shlink\Installer\Exception;
|
||||||
|
|
||||||
|
use Shlinkio\Shlink\Installer\Exception\MissingRequiredOptionException;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
class MissingRequiredOptionExceptionTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function fromOptionsGeneratesExpectedMessage()
|
||||||
|
{
|
||||||
|
$e = MissingRequiredOptionException::fromOption('foo');
|
||||||
|
$this->assertEquals('The "foo" is required and can\'t be empty', $e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user