|
@@ -4,51 +4,53 @@ declare(strict_types=1);
|
|
|
|
|
|
namespace Shlinkio\Shlink\CLI\Command\ShortUrl;
|
|
|
|
|
|
-use Laminas\Paginator\Paginator;
|
|
|
use Shlinkio\Shlink\CLI\Command\Util\AbstractWithDateRangeCommand;
|
|
|
use Shlinkio\Shlink\CLI\Util\ExitCodes;
|
|
|
use Shlinkio\Shlink\CLI\Util\ShlinkTable;
|
|
|
-use Shlinkio\Shlink\Common\Paginator\Util\PaginatorUtilsTrait;
|
|
|
+use Shlinkio\Shlink\Common\Paginator\Paginator;
|
|
|
+use Shlinkio\Shlink\Common\Paginator\Util\PagerfantaUtilsTrait;
|
|
|
+use Shlinkio\Shlink\Common\Rest\DataTransformerInterface;
|
|
|
use Shlinkio\Shlink\Core\Model\ShortUrlsOrdering;
|
|
|
use Shlinkio\Shlink\Core\Model\ShortUrlsParams;
|
|
|
use Shlinkio\Shlink\Core\Service\ShortUrlServiceInterface;
|
|
|
-use Shlinkio\Shlink\Core\Transformer\ShortUrlDataTransformer;
|
|
|
use Shlinkio\Shlink\Core\Validation\ShortUrlsParamsInputFilter;
|
|
|
use Symfony\Component\Console\Input\InputInterface;
|
|
|
use Symfony\Component\Console\Input\InputOption;
|
|
|
use Symfony\Component\Console\Output\OutputInterface;
|
|
|
use Symfony\Component\Console\Style\SymfonyStyle;
|
|
|
|
|
|
-use function array_flip;
|
|
|
-use function array_intersect_key;
|
|
|
-use function array_values;
|
|
|
-use function count;
|
|
|
+use function array_pad;
|
|
|
use function explode;
|
|
|
+use function Functional\map;
|
|
|
use function implode;
|
|
|
use function sprintf;
|
|
|
|
|
|
class ListShortUrlsCommand extends AbstractWithDateRangeCommand
|
|
|
{
|
|
|
- use PaginatorUtilsTrait;
|
|
|
+ use PagerfantaUtilsTrait;
|
|
|
|
|
|
public const NAME = 'short-url:list';
|
|
|
- private const COLUMNS_WHITELIST = [
|
|
|
+ private const COLUMNS_TO_SHOW = [
|
|
|
'shortCode',
|
|
|
+ 'title',
|
|
|
'shortUrl',
|
|
|
'longUrl',
|
|
|
'dateCreated',
|
|
|
'visitsCount',
|
|
|
+ ];
|
|
|
+ private const COLUMNS_TO_SHOW_WITH_TAGS = [
|
|
|
+ ...self::COLUMNS_TO_SHOW,
|
|
|
'tags',
|
|
|
];
|
|
|
|
|
|
private ShortUrlServiceInterface $shortUrlService;
|
|
|
- private ShortUrlDataTransformer $transformer;
|
|
|
+ private DataTransformerInterface $transformer;
|
|
|
|
|
|
- public function __construct(ShortUrlServiceInterface $shortUrlService, array $domainConfig)
|
|
|
+ public function __construct(ShortUrlServiceInterface $shortUrlService, DataTransformerInterface $transformer)
|
|
|
{
|
|
|
parent::__construct();
|
|
|
$this->shortUrlService = $shortUrlService;
|
|
|
- $this->transformer = new ShortUrlDataTransformer($domainConfig);
|
|
|
+ $this->transformer = $transformer;
|
|
|
}
|
|
|
|
|
|
protected function doConfigure(): void
|
|
@@ -60,28 +62,34 @@ 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 you want to order by. '
|
|
|
+ . 'Define ordering dir by passing ASC or DESC after "," or "-".',
|
|
|
+ )
|
|
|
+ ->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 +99,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 +114,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 = [
|
|
@@ -132,7 +140,7 @@ class ListShortUrlsCommand extends AbstractWithDateRangeCommand
|
|
|
$result = $this->renderPage($output, $showTags, ShortUrlsParams::fromRawData($data), $all);
|
|
|
$page++;
|
|
|
|
|
|
- $continue = ! $this->isLastPage($result) && $io->confirm(
|
|
|
+ $continue = $result->hasNextPage() && $io->confirm(
|
|
|
sprintf('Continue with page <options=bold>%s</>?', $page),
|
|
|
false,
|
|
|
);
|
|
@@ -148,21 +156,20 @@ class ListShortUrlsCommand extends AbstractWithDateRangeCommand
|
|
|
{
|
|
|
$result = $this->shortUrlService->listShortUrls($params);
|
|
|
|
|
|
- $headers = ['Short code', 'Short URL', 'Long URL', 'Date created', 'Visits count'];
|
|
|
+ $headers = ['Short code', 'Title', 'Short URL', 'Long URL', 'Date created', 'Visits count'];
|
|
|
if ($showTags) {
|
|
|
$headers[] = 'Tags';
|
|
|
}
|
|
|
|
|
|
$rows = [];
|
|
|
foreach ($result as $row) {
|
|
|
+ $columnsToShow = $showTags ? self::COLUMNS_TO_SHOW_WITH_TAGS : self::COLUMNS_TO_SHOW;
|
|
|
$shortUrl = $this->transformer->transform($row);
|
|
|
if ($showTags) {
|
|
|
$shortUrl['tags'] = implode(', ', $shortUrl['tags']);
|
|
|
- } else {
|
|
|
- unset($shortUrl['tags']);
|
|
|
}
|
|
|
|
|
|
- $rows[] = array_values(array_intersect_key($shortUrl, array_flip(self::COLUMNS_WHITELIST)));
|
|
|
+ $rows[] = map($columnsToShow, fn (string $prop) => $shortUrl[$prop]);
|
|
|
}
|
|
|
|
|
|
ShlinkTable::fromOutput($output)->render($headers, $rows, $all ? null : $this->formatCurrentPageMessage(
|
|
@@ -173,17 +180,14 @@ class ListShortUrlsCommand extends AbstractWithDateRangeCommand
|
|
|
return $result;
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * @return array|string|null
|
|
|
- */
|
|
|
- private function processOrderBy(InputInterface $input)
|
|
|
+ private function processOrderBy(InputInterface $input): ?string
|
|
|
{
|
|
|
- $orderBy = $input->getOption('orderBy');
|
|
|
+ $orderBy = $this->getOptionWithDeprecatedFallback($input, 'order-by');
|
|
|
if (empty($orderBy)) {
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
- $orderBy = explode(',', $orderBy);
|
|
|
- return count($orderBy) === 1 ? $orderBy[0] : [$orderBy[0] => $orderBy[1]];
|
|
|
+ [$field, $dir] = array_pad(explode(',', $orderBy), 2, null);
|
|
|
+ return $dir === null ? $field : sprintf('%s-%s', $field, $dir);
|
|
|
}
|
|
|
}
|