diff --git a/module/CLI/src/Command/ShortUrl/ListShortUrlsCommand.php b/module/CLI/src/Command/ShortUrl/ListShortUrlsCommand.php index b7bbaf3a..cea263f6 100644 --- a/module/CLI/src/Command/ShortUrl/ListShortUrlsCommand.php +++ b/module/CLI/src/Command/ShortUrl/ListShortUrlsCommand.php @@ -6,6 +6,7 @@ namespace Shlinkio\Shlink\CLI\Command\ShortUrl; use Shlinkio\Shlink\CLI\Input\EndDateOption; use Shlinkio\Shlink\CLI\Input\StartDateOption; +use Shlinkio\Shlink\CLI\Input\TagsOption; use Shlinkio\Shlink\CLI\Util\ShlinkTable; use Shlinkio\Shlink\Common\Paginator\Paginator; use Shlinkio\Shlink\Common\Paginator\Util\PagerfantaUtils; @@ -27,7 +28,6 @@ use function array_keys; use function array_pad; use function explode; use function implode; -use function Shlinkio\Shlink\Core\ArrayUtils\flatten; use function Shlinkio\Shlink\Core\ArrayUtils\map; use function sprintf; @@ -37,6 +37,7 @@ class ListShortUrlsCommand extends Command private readonly StartDateOption $startDateOption; private readonly EndDateOption $endDateOption; + private readonly TagsOption $tagsOption; public function __construct( private readonly ShortUrlListServiceInterface $shortUrlService, @@ -45,6 +46,7 @@ class ListShortUrlsCommand extends Command parent::__construct(); $this->startDateOption = new StartDateOption($this, 'short URLs'); $this->endDateOption = new EndDateOption($this, 'short URLs'); + $this->tagsOption = new TagsOption($this, 'A list of tags that short URLs need to include.'); } protected function configure(): void @@ -71,17 +73,6 @@ class ListShortUrlsCommand extends Command InputOption::VALUE_REQUIRED, 'Used to filter results by domain. Use DEFAULT keyword to filter by default domain', ) - ->addOption( - 'tags', - mode: InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, - description: '[DEPRECATED] Use --tag instead', - ) - ->addOption( - 'tag', - 't', - InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, - 'A list of tags that short URLs need to include.', - ) ->addOption('including-all-tags', 'i', InputOption::VALUE_NONE, '[DEPRECATED] Use --tags-all instead') ->addOption( 'tags-all', @@ -154,9 +145,7 @@ class ListShortUrlsCommand extends Command $searchTerm = $input->getOption('search-term'); $domain = $input->getOption('domain'); - // FIXME DEPRECATED Remove support for comma-separated tags in next major release - $tags = [...$input->getOption('tag'), ...$input->getOption('tags')]; - $tags = flatten(map($tags, static fn (string $tag) => explode(',', $tag))); + $tags = $this->tagsOption->get($input); $tagsMode = $input->getOption('tags-all') === true || $input->getOption('including-all-tags') === true ? TagsMode::ALL->value : TagsMode::ANY->value; diff --git a/module/CLI/src/Input/ShortUrlDataInput.php b/module/CLI/src/Input/ShortUrlDataInput.php index 1ff1de3f..908e6536 100644 --- a/module/CLI/src/Input/ShortUrlDataInput.php +++ b/module/CLI/src/Input/ShortUrlDataInput.php @@ -13,13 +13,10 @@ use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; -use function array_map; -use function array_unique; -use function Shlinkio\Shlink\Core\ArrayUtils\flatten; -use function Shlinkio\Shlink\Core\splitByComma; - final readonly class ShortUrlDataInput { + private readonly TagsOption $tagsOption; + public function __construct(Command $command, private bool $longUrlAsOption = false) { if ($longUrlAsOption) { @@ -28,13 +25,9 @@ final readonly class ShortUrlDataInput $command->addArgument('longUrl', InputArgument::REQUIRED, 'The long URL to set'); } + $this->tagsOption = new TagsOption($command, 'Tags to apply to the short URL'); + $command - ->addOption( - ShortUrlDataOption::TAGS->value, - ShortUrlDataOption::TAGS->shortcut(), - InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, - 'Tags to apply to the short URL', - ) ->addOption( ShortUrlDataOption::VALID_SINCE->value, ShortUrlDataOption::VALID_SINCE->shortcut(), @@ -117,9 +110,8 @@ final readonly class ShortUrlDataInput $maxVisits = $input->getOption('max-visits'); $data[ShortUrlInputFilter::MAX_VISITS] = $maxVisits !== null ? (int) $maxVisits : null; } - if (ShortUrlDataOption::TAGS->wasProvided($input)) { - $tags = array_unique(flatten(array_map(splitByComma(...), $input->getOption('tags')))); - $data[ShortUrlInputFilter::TAGS] = $tags; + if ($this->tagsOption->exists($input)) { + $data[ShortUrlInputFilter::TAGS] = $this->tagsOption->get($input); } if (ShortUrlDataOption::TITLE->wasProvided($input)) { $data[ShortUrlInputFilter::TITLE] = $input->getOption('title'); diff --git a/module/CLI/src/Input/ShortUrlDataOption.php b/module/CLI/src/Input/ShortUrlDataOption.php index 29c41407..4d8b582e 100644 --- a/module/CLI/src/Input/ShortUrlDataOption.php +++ b/module/CLI/src/Input/ShortUrlDataOption.php @@ -10,7 +10,6 @@ use function sprintf; enum ShortUrlDataOption: string { - case TAGS = 'tags'; case VALID_SINCE = 'valid-since'; case VALID_UNTIL = 'valid-until'; case MAX_VISITS = 'max-visits'; @@ -21,7 +20,6 @@ enum ShortUrlDataOption: string public function shortcut(): string|null { return match ($this) { - self::TAGS => 't', self::VALID_SINCE => 's', self::VALID_UNTIL => 'u', self::MAX_VISITS => 'm', diff --git a/module/CLI/src/Input/TagsOption.php b/module/CLI/src/Input/TagsOption.php new file mode 100644 index 00000000..ff02a735 --- /dev/null +++ b/module/CLI/src/Input/TagsOption.php @@ -0,0 +1,51 @@ +addOption( + 'tag', + 't', + InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, + $description, + ) + ->addOption( + 'tags', + mode: InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, + description: '[DEPRECATED] Use --tag instead', + ); + } + + /** + * Whether tags have been set or not, via `--tag`, `-t` or the deprecated `--tags` + */ + public function exists(InputInterface $input): bool + { + return $input->hasParameterOption(['--tag', '-t']) || $input->hasParameterOption('--tags'); + } + + /** + * @return string[] + */ + public function get(InputInterface $input): array + { + // FIXME DEPRECATED Remove support for comma-separated tags in next major release + $tags = [...$input->getOption('tag'), ...$input->getOption('tags')]; + return array_unique(flatten(array_map(splitByComma(...), $tags))); + } +}