Merge pull request #2495 from acelaya-forks/tags-option

Extract tags option to its own Option class
This commit is contained in:
Alejandro Celaya 2025-10-20 09:02:15 +02:00 committed by GitHub
commit cae18ccfb3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 61 additions and 31 deletions

View File

@ -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;

View File

@ -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');

View File

@ -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',

View File

@ -0,0 +1,51 @@
<?php
declare(strict_types=1);
namespace Shlinkio\Shlink\CLI\Input;
use Symfony\Component\Console\Command\Command;
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;
readonly class TagsOption
{
public function __construct(Command $command, string $description)
{
$command
->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)));
}
}