diff --git a/CHANGELOG.md b/CHANGELOG.md
index 86dacaa0..baf1f824 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -13,7 +13,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com), and this
* [#986](https://github.com/shlinkio/shlink/issues/986) Updated official docker image to use PHP 8.
### Deprecated
-* *Nothing*
+* [#959](https://github.com/shlinkio/shlink/issues/959) Deprecated all command flags using camelCase format (like `--expirationDate`), adding kebab-case replacements for all of them (like `--expiration-date`).
+
+ All the existing camelCase flags will continue working for now, but will be removed in Shlink 3.0.0
### Removed
* *Nothing*
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/CLI/src/Command/ShortUrl/GetVisitsCommand.php b/module/CLI/src/Command/ShortUrl/GetVisitsCommand.php
index b58ea3ac..0b7de663 100644
--- a/module/CLI/src/Command/ShortUrl/GetVisitsCommand.php
+++ b/module/CLI/src/Command/ShortUrl/GetVisitsCommand.php
@@ -21,6 +21,7 @@ use Symfony\Component\Console\Style\SymfonyStyle;
use function Functional\map;
use function Functional\select_keys;
+use function sprintf;
class GetVisitsCommand extends AbstractWithDateRangeCommand
{
@@ -39,18 +40,18 @@ class GetVisitsCommand extends AbstractWithDateRangeCommand
$this
->setName(self::NAME)
->setDescription('Returns the detailed visits information for provided short code')
- ->addArgument('shortCode', InputArgument::REQUIRED, 'The short code which visits we want to get')
- ->addOption('domain', 'd', InputOption::VALUE_REQUIRED, 'The domain for the short code');
+ ->addArgument('shortCode', InputArgument::REQUIRED, 'The short code which visits we want to get.')
+ ->addOption('domain', 'd', InputOption::VALUE_REQUIRED, 'The domain for the short code.');
}
- protected function getStartDateDesc(): string
+ protected function getStartDateDesc(string $optionName): string
{
- return 'Allows to filter visits, returning only those older than start date';
+ return sprintf('Allows to filter visits, returning only those older than "%s".', $optionName);
}
- protected function getEndDateDesc(): string
+ protected function getEndDateDesc(string $optionName): string
{
- return 'Allows to filter visits, returning only those newer than end date';
+ return sprintf('Allows to filter visits, returning only those newer than "%s".', $optionName);
}
protected function interact(InputInterface $input, OutputInterface $output): void
@@ -70,8 +71,8 @@ class GetVisitsCommand extends AbstractWithDateRangeCommand
protected function execute(InputInterface $input, OutputInterface $output): ?int
{
$identifier = ShortUrlIdentifier::fromCli($input);
- $startDate = $this->getDateOption($input, $output, 'startDate');
- $endDate = $this->getDateOption($input, $output, 'endDate');
+ $startDate = $this->getStartDateOption($input, $output);
+ $endDate = $this->getEndDateOption($input, $output);
$paginator = $this->visitsTracker->info($identifier, new VisitsParams(new DateRange($startDate, $endDate)));
diff --git a/module/CLI/src/Command/ShortUrl/ListShortUrlsCommand.php b/module/CLI/src/Command/ShortUrl/ListShortUrlsCommand.php
index 3f539e27..cf20e328 100644
--- a/module/CLI/src/Command/ShortUrl/ListShortUrlsCommand.php
+++ b/module/CLI/src/Command/ShortUrl/ListShortUrlsCommand.php
@@ -60,28 +60,33 @@ class ListShortUrlsCommand extends AbstractWithDateRangeCommand
'page',
'p',
InputOption::VALUE_REQUIRED,
- 'The first page to list (10 items per page unless "--all" is provided)',
+ 'The first page to list (10 items per page unless "--all" is provided).',
'1',
)
- ->addOption(
- 'searchTerm',
+ ->addOptionWithDeprecatedFallback(
+ 'search-term',
'st',
InputOption::VALUE_REQUIRED,
- 'A query used to filter results by searching for it on the longUrl and shortCode fields',
+ 'A query used to filter results by searching for it on the longUrl and shortCode fields.',
)
->addOption(
'tags',
't',
InputOption::VALUE_REQUIRED,
- 'A comma-separated list of tags to filter results',
+ 'A comma-separated list of tags to filter results.',
)
- ->addOption(
- 'orderBy',
+ ->addOptionWithDeprecatedFallback(
+ 'order-by',
'o',
InputOption::VALUE_REQUIRED,
- 'The field from which we want to order by. Pass ASC or DESC separated by a comma',
+ 'The field from which we want to order by. Pass ASC or DESC separated by a comma.',
+ )
+ ->addOptionWithDeprecatedFallback(
+ 'show-tags',
+ null,
+ InputOption::VALUE_NONE,
+ 'Whether to display the tags or not.',
)
- ->addOption('showTags', null, InputOption::VALUE_NONE, 'Whether to display the tags or not')
->addOption(
'all',
'a',
@@ -91,14 +96,14 @@ class ListShortUrlsCommand extends AbstractWithDateRangeCommand
);
}
- protected function getStartDateDesc(): string
+ protected function getStartDateDesc(string $optionName): string
{
- return 'Allows to filter short URLs, returning only those created after "startDate"';
+ return sprintf('Allows to filter short URLs, returning only those created after "%s".', $optionName);
}
- protected function getEndDateDesc(): string
+ protected function getEndDateDesc(string $optionName): string
{
- return 'Allows to filter short URLs, returning only those created before "endDate"';
+ return sprintf('Allows to filter short URLs, returning only those created before "%s".', $optionName);
}
protected function execute(InputInterface $input, OutputInterface $output): ?int
@@ -106,13 +111,13 @@ class ListShortUrlsCommand extends AbstractWithDateRangeCommand
$io = new SymfonyStyle($input, $output);
$page = (int) $input->getOption('page');
- $searchTerm = $input->getOption('searchTerm');
+ $searchTerm = $this->getOptionWithDeprecatedFallback($input, 'search-term');
$tags = $input->getOption('tags');
$tags = ! empty($tags) ? explode(',', $tags) : [];
- $showTags = (bool) $input->getOption('showTags');
- $all = (bool) $input->getOption('all');
- $startDate = $this->getDateOption($input, $output, 'startDate');
- $endDate = $this->getDateOption($input, $output, 'endDate');
+ $showTags = $this->getOptionWithDeprecatedFallback($input, 'show-tags');
+ $all = $input->getOption('all');
+ $startDate = $this->getStartDateOption($input, $output);
+ $endDate = $this->getEndDateOption($input, $output);
$orderBy = $this->processOrderBy($input);
$data = [
@@ -178,7 +183,7 @@ class ListShortUrlsCommand extends AbstractWithDateRangeCommand
*/
private function processOrderBy(InputInterface $input)
{
- $orderBy = $input->getOption('orderBy');
+ $orderBy = $this->getOptionWithDeprecatedFallback($input, 'order-by');
if (empty($orderBy)) {
return null;
}
diff --git a/module/CLI/src/Command/Util/AbstractWithDateRangeCommand.php b/module/CLI/src/Command/Util/AbstractWithDateRangeCommand.php
index bd64701a..39e60c9a 100644
--- a/module/CLI/src/Command/Util/AbstractWithDateRangeCommand.php
+++ b/module/CLI/src/Command/Util/AbstractWithDateRangeCommand.php
@@ -5,7 +5,7 @@ declare(strict_types=1);
namespace Shlinkio\Shlink\CLI\Command\Util;
use Cake\Chronos\Chronos;
-use Symfony\Component\Console\Command\Command;
+use Shlinkio\Shlink\CLI\Command\BaseCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
@@ -13,19 +13,42 @@ use Throwable;
use function sprintf;
-abstract class AbstractWithDateRangeCommand extends Command
+abstract class AbstractWithDateRangeCommand extends BaseCommand
{
+ private const START_DATE = 'start-date';
+ private const END_DATE = 'end-date';
+
final protected function configure(): void
{
$this->doConfigure();
$this
- ->addOption('startDate', 's', InputOption::VALUE_REQUIRED, $this->getStartDateDesc())
- ->addOption('endDate', 'e', InputOption::VALUE_REQUIRED, $this->getEndDateDesc());
+ ->addOptionWithDeprecatedFallback(
+ self::START_DATE,
+ 's',
+ InputOption::VALUE_REQUIRED,
+ $this->getStartDateDesc(self::START_DATE),
+ )
+ ->addOptionWithDeprecatedFallback(
+ self::END_DATE,
+ 'e',
+ InputOption::VALUE_REQUIRED,
+ $this->getEndDateDesc(self::END_DATE),
+ );
}
- protected function getDateOption(InputInterface $input, OutputInterface $output, string $key): ?Chronos
+ protected function getStartDateOption(InputInterface $input, OutputInterface $output): ?Chronos
{
- $value = $input->getOption($key);
+ return $this->getDateOption($input, $output, self::START_DATE);
+ }
+
+ protected function getEndDateOption(InputInterface $input, OutputInterface $output): ?Chronos
+ {
+ return $this->getDateOption($input, $output, self::END_DATE);
+ }
+
+ private function getDateOption(InputInterface $input, OutputInterface $output, string $key): ?Chronos
+ {
+ $value = $this->getOptionWithDeprecatedFallback($input, $key);
if (empty($value)) {
return null;
}
@@ -49,6 +72,7 @@ abstract class AbstractWithDateRangeCommand extends Command
abstract protected function doConfigure(): void;
- abstract protected function getStartDateDesc(): string;
- abstract protected function getEndDateDesc(): string;
+ abstract protected function getStartDateDesc(string $optionName): string;
+
+ abstract protected function getEndDateDesc(string $optionName): string;
}
diff --git a/module/CLI/test/Command/Api/GenerateKeyCommandTest.php b/module/CLI/test/Command/Api/GenerateKeyCommandTest.php
index 744fb482..00548f17 100644
--- a/module/CLI/test/Command/Api/GenerateKeyCommandTest.php
+++ b/module/CLI/test/Command/Api/GenerateKeyCommandTest.php
@@ -55,7 +55,7 @@ class GenerateKeyCommandTest extends TestCase
$this->apiKeyService->create(Argument::type(Chronos::class))->shouldBeCalledOnce()
->willReturn(new ApiKey());
$this->commandTester->execute([
- '--expirationDate' => '2016-01-01',
+ '--expiration-date' => '2016-01-01',
]);
}
}
diff --git a/module/CLI/test/Command/Api/ListKeysCommandTest.php b/module/CLI/test/Command/Api/ListKeysCommandTest.php
index 116f979d..e0cada5d 100644
--- a/module/CLI/test/Command/Api/ListKeysCommandTest.php
+++ b/module/CLI/test/Command/Api/ListKeysCommandTest.php
@@ -39,7 +39,7 @@ class ListKeysCommandTest extends TestCase
{
$listKeys = $this->apiKeyService->listKeys($enabledOnly)->willReturn($keys);
- $this->commandTester->execute(['--enabledOnly' => $enabledOnly]);
+ $this->commandTester->execute(['--enabled-only' => $enabledOnly]);
$output = $this->commandTester->getDisplay();
self::assertEquals($expected, $output);
diff --git a/module/CLI/test/Command/ShortUrl/GenerateShortUrlCommandTest.php b/module/CLI/test/Command/ShortUrl/GenerateShortUrlCommandTest.php
index 82f38713..3283dced 100644
--- a/module/CLI/test/Command/ShortUrl/GenerateShortUrlCommandTest.php
+++ b/module/CLI/test/Command/ShortUrl/GenerateShortUrlCommandTest.php
@@ -48,7 +48,7 @@ class GenerateShortUrlCommandTest extends TestCase
$this->commandTester->execute([
'longUrl' => 'http://domain.com/foo/bar',
- '--maxVisits' => '3',
+ '--max-visits' => '3',
]);
$output = $this->commandTester->getDisplay();
@@ -78,7 +78,7 @@ class GenerateShortUrlCommandTest extends TestCase
NonUniqueSlugException::fromSlug('my-slug'),
);
- $this->commandTester->execute(['longUrl' => 'http://domain.com/invalid', '--customSlug' => 'my-slug']);
+ $this->commandTester->execute(['longUrl' => 'http://domain.com/invalid', '--custom-slug' => 'my-slug']);
$output = $this->commandTester->getDisplay();
self::assertEquals(ExitCodes::EXIT_FAILURE, $this->commandTester->getStatusCode());
diff --git a/module/CLI/test/Command/ShortUrl/GetVisitsCommandTest.php b/module/CLI/test/Command/ShortUrl/GetVisitsCommandTest.php
index 50c1751f..51394414 100644
--- a/module/CLI/test/Command/ShortUrl/GetVisitsCommandTest.php
+++ b/module/CLI/test/Command/ShortUrl/GetVisitsCommandTest.php
@@ -71,8 +71,8 @@ class GetVisitsCommandTest extends TestCase
$this->commandTester->execute([
'shortCode' => $shortCode,
- '--startDate' => $startDate,
- '--endDate' => $endDate,
+ '--start-date' => $startDate,
+ '--end-date' => $endDate,
]);
}
@@ -86,13 +86,13 @@ class GetVisitsCommandTest extends TestCase
$this->commandTester->execute([
'shortCode' => $shortCode,
- '--startDate' => $startDate,
+ '--start-date' => $startDate,
]);
$output = $this->commandTester->getDisplay();
$info->shouldHaveBeenCalledOnce();
self::assertStringContainsString(
- sprintf('Ignored provided "startDate" since its value "%s" is not a valid date', $startDate),
+ sprintf('Ignored provided "start-date" since its value "%s" is not a valid date', $startDate),
$output,
);
}
diff --git a/module/CLI/test/Command/ShortUrl/ListShortUrlsCommandTest.php b/module/CLI/test/Command/ShortUrl/ListShortUrlsCommandTest.php
index aca72e06..43047bbf 100644
--- a/module/CLI/test/Command/ShortUrl/ListShortUrlsCommandTest.php
+++ b/module/CLI/test/Command/ShortUrl/ListShortUrlsCommandTest.php
@@ -104,7 +104,7 @@ class ListShortUrlsCommandTest extends TestCase
->shouldBeCalledOnce();
$this->commandTester->setInputs(['y']);
- $this->commandTester->execute(['--showTags' => true]);
+ $this->commandTester->execute(['--show-tags' => true]);
$output = $this->commandTester->getDisplay();
self::assertStringContainsString('Tags', $output);
}
@@ -139,22 +139,22 @@ class ListShortUrlsCommandTest extends TestCase
{
yield [[], 1, null, []];
yield [['--page' => $page = 3], $page, null, []];
- yield [['--searchTerm' => $searchTerm = 'search this'], 1, $searchTerm, []];
+ yield [['--search-term' => $searchTerm = 'search this'], 1, $searchTerm, []];
yield [
- ['--page' => $page = 3, '--searchTerm' => $searchTerm = 'search this', '--tags' => $tags = 'foo,bar'],
+ ['--page' => $page = 3, '--search-term' => $searchTerm = 'search this', '--tags' => $tags = 'foo,bar'],
$page,
$searchTerm,
explode(',', $tags),
];
yield [
- ['--startDate' => $startDate = '2019-01-01'],
+ ['--start-date' => $startDate = '2019-01-01'],
1,
null,
[],
$startDate,
];
yield [
- ['--endDate' => $endDate = '2020-05-23'],
+ ['--end-date' => $endDate = '2020-05-23'],
1,
null,
[],
@@ -162,7 +162,7 @@ class ListShortUrlsCommandTest extends TestCase
$endDate,
];
yield [
- ['--startDate' => $startDate = '2019-01-01', '--endDate' => $endDate = '2020-05-23'],
+ ['--start-date' => $startDate = '2019-01-01', '--end-date' => $endDate = '2020-05-23'],
1,
null,
[],
@@ -191,9 +191,9 @@ class ListShortUrlsCommandTest extends TestCase
public function provideOrderBy(): iterable
{
yield [[], null];
- yield [['--orderBy' => 'foo'], 'foo'];
- yield [['--orderBy' => 'foo,ASC'], ['foo' => 'ASC']];
- yield [['--orderBy' => 'bar,DESC'], ['bar' => 'DESC']];
+ yield [['--order-by' => 'foo'], 'foo'];
+ yield [['--order-by' => 'foo,ASC'], ['foo' => 'ASC']];
+ yield [['--order-by' => 'bar,DESC'], ['bar' => 'DESC']];
}
/** @test */
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))));
+}