diff --git a/module/CLI/src/Command/Api/GenerateKeyCommand.php b/module/CLI/src/Command/Api/GenerateKeyCommand.php
index 2dc91c51..119fa020 100644
--- a/module/CLI/src/Command/Api/GenerateKeyCommand.php
+++ b/module/CLI/src/Command/Api/GenerateKeyCommand.php
@@ -6,11 +6,11 @@ namespace Shlinkio\Shlink\CLI\Command\Api;
use Cake\Chronos\Chronos;
use Shlinkio\Shlink\CLI\ApiKey\RoleResolverInterface;
+use Shlinkio\Shlink\CLI\Command\BaseCommand;
use Shlinkio\Shlink\CLI\Util\ExitCodes;
use Shlinkio\Shlink\CLI\Util\ShlinkTable;
use Shlinkio\Shlink\Rest\ApiKey\Role;
use Shlinkio\Shlink\Rest\Service\ApiKeyServiceInterface;
-use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
@@ -19,7 +19,7 @@ use Symfony\Component\Console\Style\SymfonyStyle;
use function Shlinkio\Shlink\Core\arrayToString;
use function sprintf;
-class GenerateKeyCommand extends Command
+class GenerateKeyCommand extends BaseCommand
{
public const NAME = 'api-key:generate';
@@ -42,9 +42,9 @@ class GenerateKeyCommand extends Command
%command.full_name%
- You can optionally set its expiration date with --expirationDate or -e:
+ You can optionally set its expiration date with --expiration-date or -e:
- %command.full_name% --expirationDate 2020-01-01
+ %command.full_name% --expiration-date 2020-01-01
You can also set roles to the API key:
@@ -56,8 +56,8 @@ class GenerateKeyCommand extends Command
$this
->setName(self::NAME)
->setDescription('Generates a new valid API key.')
- ->addOption(
- 'expirationDate',
+ ->addOptionWithDeprecatedFallback(
+ 'expiration-date',
'e',
InputOption::VALUE_REQUIRED,
'The date in which the API key should expire. Use any valid PHP format.',
@@ -79,7 +79,7 @@ class GenerateKeyCommand extends Command
protected function execute(InputInterface $input, OutputInterface $output): ?int
{
- $expirationDate = $input->getOption('expirationDate');
+ $expirationDate = $this->getOptionWithDeprecatedFallback($input, 'expiration-date');
$apiKey = $this->apiKeyService->create(
isset($expirationDate) ? Chronos::parse($expirationDate) : null,
...$this->roleResolver->determineRoles($input),
diff --git a/module/CLI/src/Command/Api/ListKeysCommand.php b/module/CLI/src/Command/Api/ListKeysCommand.php
index cf09e614..9243779b 100644
--- a/module/CLI/src/Command/Api/ListKeysCommand.php
+++ b/module/CLI/src/Command/Api/ListKeysCommand.php
@@ -4,12 +4,12 @@ declare(strict_types=1);
namespace Shlinkio\Shlink\CLI\Command\Api;
+use Shlinkio\Shlink\CLI\Command\BaseCommand;
use Shlinkio\Shlink\CLI\Util\ExitCodes;
use Shlinkio\Shlink\CLI\Util\ShlinkTable;
use Shlinkio\Shlink\Rest\ApiKey\Role;
use Shlinkio\Shlink\Rest\Entity\ApiKey;
use Shlinkio\Shlink\Rest\Service\ApiKeyServiceInterface;
-use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
@@ -19,7 +19,7 @@ use function Functional\map;
use function implode;
use function sprintf;
-class ListKeysCommand extends Command
+class ListKeysCommand extends BaseCommand
{
private const ERROR_STRING_PATTERN = '%s>';
private const SUCCESS_STRING_PATTERN = '%s';
@@ -40,8 +40,8 @@ class ListKeysCommand extends Command
$this
->setName(self::NAME)
->setDescription('Lists all the available API keys.')
- ->addOption(
- 'enabledOnly',
+ ->addOptionWithDeprecatedFallback(
+ 'enabled-only',
'e',
InputOption::VALUE_NONE,
'Tells if only enabled API keys should be returned.',
@@ -50,7 +50,7 @@ class ListKeysCommand extends Command
protected function execute(InputInterface $input, OutputInterface $output): ?int
{
- $enabledOnly = $input->getOption('enabledOnly');
+ $enabledOnly = $this->getOptionWithDeprecatedFallback($input, 'enabled-only');
$rows = map($this->apiKeyService->listKeys($enabledOnly), function (ApiKey $apiKey) use ($enabledOnly) {
$expiration = $apiKey->getExpirationDate();
diff --git a/module/CLI/src/Command/BaseCommand.php b/module/CLI/src/Command/BaseCommand.php
new file mode 100644
index 00000000..443b37ec
--- /dev/null
+++ b/module/CLI/src/Command/BaseCommand.php
@@ -0,0 +1,51 @@
+addOption($name, $shortcut, $mode, $description, $default);
+
+ if (str_contains($name, '-')) {
+ $camelCaseName = kebabCaseToCamelCase($name);
+ $this->addOption($camelCaseName, null, $mode, sprintf('[DEPRECATED] Same as "%s".', $name), $default);
+ }
+
+ return $this;
+ }
+
+ /**
+ * @return bool|string|string[]|null
+ */
+ protected function getOptionWithDeprecatedFallback(InputInterface $input, string $name)
+ {
+ $rawInput = method_exists($input, '__toString') ? $input->__toString() : '';
+ $camelCaseName = kebabCaseToCamelCase($name);
+
+ if (str_contains($rawInput, $camelCaseName)) {
+ return $input->getOption($camelCaseName);
+ }
+
+ return $input->getOption($name);
+ }
+}
diff --git a/module/CLI/src/Command/ShortUrl/GenerateShortUrlCommand.php b/module/CLI/src/Command/ShortUrl/GenerateShortUrlCommand.php
index 12bbb3fb..7ceb0435 100644
--- a/module/CLI/src/Command/ShortUrl/GenerateShortUrlCommand.php
+++ b/module/CLI/src/Command/ShortUrl/GenerateShortUrlCommand.php
@@ -4,13 +4,13 @@ declare(strict_types=1);
namespace Shlinkio\Shlink\CLI\Command\ShortUrl;
+use Shlinkio\Shlink\CLI\Command\BaseCommand;
use Shlinkio\Shlink\CLI\Util\ExitCodes;
use Shlinkio\Shlink\Core\Exception\InvalidUrlException;
use Shlinkio\Shlink\Core\Exception\NonUniqueSlugException;
use Shlinkio\Shlink\Core\Model\ShortUrlMeta;
use Shlinkio\Shlink\Core\Service\UrlShortenerInterface;
use Shlinkio\Shlink\Core\Validation\ShortUrlMetaInputFilter;
-use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
@@ -23,9 +23,9 @@ use function Functional\flatten;
use function Functional\unique;
use function method_exists;
use function sprintf;
-use function strpos;
+use function str_contains;
-class GenerateShortUrlCommand extends Command
+class GenerateShortUrlCommand extends BaseCommand
{
public const NAME = 'short-url:generate';
@@ -53,34 +53,34 @@ class GenerateShortUrlCommand extends Command
InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED,
'Tags to apply to the new short URL',
)
- ->addOption(
- 'validSince',
+ ->addOptionWithDeprecatedFallback(
+ 'valid-since',
's',
InputOption::VALUE_REQUIRED,
'The date from which this short URL will be valid. '
. 'If someone tries to access it before this date, it will not be found.',
)
- ->addOption(
- 'validUntil',
+ ->addOptionWithDeprecatedFallback(
+ 'valid-until',
'u',
InputOption::VALUE_REQUIRED,
'The date until which this short URL will be valid. '
. 'If someone tries to access it after this date, it will not be found.',
)
- ->addOption(
- 'customSlug',
+ ->addOptionWithDeprecatedFallback(
+ 'custom-slug',
'c',
InputOption::VALUE_REQUIRED,
'If provided, this slug will be used instead of generating a short code',
)
- ->addOption(
- 'maxVisits',
+ ->addOptionWithDeprecatedFallback(
+ 'max-visits',
'm',
InputOption::VALUE_REQUIRED,
'This will limit the number of visits for this short URL.',
)
- ->addOption(
- 'findIfExists',
+ ->addOptionWithDeprecatedFallback(
+ 'find-if-exists',
'f',
InputOption::VALUE_NONE,
'This will force existing matching URL to be returned if found, instead of creating a new one.',
@@ -91,11 +91,11 @@ class GenerateShortUrlCommand extends Command
InputOption::VALUE_REQUIRED,
'The domain to which this short URL will be attached.',
)
- ->addOption(
- 'shortCodeLength',
+ ->addOptionWithDeprecatedFallback(
+ 'short-code-length',
'l',
InputOption::VALUE_REQUIRED,
- 'The length for generated short code (it will be ignored if --customSlug was provided).',
+ 'The length for generated short code (it will be ignored if --custom-slug was provided).',
)
->addOption(
'validate-url',
@@ -136,18 +136,24 @@ class GenerateShortUrlCommand extends Command
$explodeWithComma = curry('explode')(',');
$tags = unique(flatten(array_map($explodeWithComma, $input->getOption('tags'))));
- $customSlug = $input->getOption('customSlug');
- $maxVisits = $input->getOption('maxVisits');
- $shortCodeLength = $input->getOption('shortCodeLength') ?? $this->defaultShortCodeLength;
+ $customSlug = $this->getOptionWithDeprecatedFallback($input, 'custom-slug');
+ $maxVisits = $this->getOptionWithDeprecatedFallback($input, 'max-visits');
+ $shortCodeLength = $this->getOptionWithDeprecatedFallback(
+ $input,
+ 'short-code-length',
+ ) ?? $this->defaultShortCodeLength;
$doValidateUrl = $this->doValidateUrl($input);
try {
$shortUrl = $this->urlShortener->shorten($longUrl, $tags, ShortUrlMeta::fromRawData([
- ShortUrlMetaInputFilter::VALID_SINCE => $input->getOption('validSince'),
- ShortUrlMetaInputFilter::VALID_UNTIL => $input->getOption('validUntil'),
+ ShortUrlMetaInputFilter::VALID_SINCE => $this->getOptionWithDeprecatedFallback($input, 'valid-since'),
+ ShortUrlMetaInputFilter::VALID_UNTIL => $this->getOptionWithDeprecatedFallback($input, 'valid-until'),
ShortUrlMetaInputFilter::CUSTOM_SLUG => $customSlug,
ShortUrlMetaInputFilter::MAX_VISITS => $maxVisits !== null ? (int) $maxVisits : null,
- ShortUrlMetaInputFilter::FIND_IF_EXISTS => $input->getOption('findIfExists'),
+ ShortUrlMetaInputFilter::FIND_IF_EXISTS => $this->getOptionWithDeprecatedFallback(
+ $input,
+ 'find-if-exists',
+ ),
ShortUrlMetaInputFilter::DOMAIN => $input->getOption('domain'),
ShortUrlMetaInputFilter::SHORT_CODE_LENGTH => $shortCodeLength,
ShortUrlMetaInputFilter::VALIDATE_URL => $doValidateUrl,
@@ -168,10 +174,10 @@ class GenerateShortUrlCommand extends Command
{
$rawInput = method_exists($input, '__toString') ? $input->__toString() : '';
- if (strpos($rawInput, '--no-validate-url') !== false) {
+ if (str_contains($rawInput, '--no-validate-url')) {
return false;
}
- if (strpos($rawInput, '--validate-url') !== false) {
+ if (str_contains($rawInput, '--validate-url')) {
return true;
}
diff --git a/module/Core/functions/functions.php b/module/Core/functions/functions.php
index 076de6a0..531f8038 100644
--- a/module/Core/functions/functions.php
+++ b/module/Core/functions/functions.php
@@ -12,9 +12,12 @@ use PUGX\Shortid\Factory as ShortIdFactory;
use function Functional\reduce_left;
use function is_array;
+use function lcfirst;
use function print_r;
use function sprintf;
use function str_repeat;
+use function str_replace;
+use function ucwords;
const DEFAULT_DELETE_SHORT_URL_THRESHOLD = 15;
const DEFAULT_SHORT_CODES_LENGTH = 5;
@@ -97,3 +100,8 @@ function arrayToString(array $array, int $indentSize = 4): string
);
}, '');
}
+
+function kebabCaseToCamelCase(string $name): string
+{
+ return lcfirst(str_replace(' ', '', ucwords(str_replace('-', ' ', $name))));
+}