Feature/show API key info in short-url CLI

This commit is contained in:
KetchupBomb 2021-04-10 06:50:34 +00:00
parent f30e922074
commit 5d0f306bcc
2 changed files with 72 additions and 38 deletions

View file

@ -4,12 +4,15 @@ declare(strict_types=1);
namespace Shlinkio\Shlink\CLI\Command\ShortUrl; namespace Shlinkio\Shlink\CLI\Command\ShortUrl;
use closure;
use Shlinkio\Shlink\CLI\Command\Util\AbstractWithDateRangeCommand; use Shlinkio\Shlink\CLI\Command\Util\AbstractWithDateRangeCommand;
use Shlinkio\Shlink\CLI\Util\ExitCodes; use Shlinkio\Shlink\CLI\Util\ExitCodes;
use Shlinkio\Shlink\CLI\Util\ShlinkTable; use Shlinkio\Shlink\CLI\Util\ShlinkTable;
use Shlinkio\Shlink\Common\Paginator\Paginator; use Shlinkio\Shlink\Common\Paginator\Paginator;
use Shlinkio\Shlink\Common\Paginator\Util\PagerfantaUtilsTrait; use Shlinkio\Shlink\Common\Paginator\Util\PagerfantaUtilsTrait;
use Shlinkio\Shlink\Common\Rest\DataTransformerInterface; use Shlinkio\Shlink\Common\Rest\DataTransformerInterface;
use Shlinkio\Shlink\Core\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Entity\Tag;
use Shlinkio\Shlink\Core\Model\ShortUrlsOrdering; use Shlinkio\Shlink\Core\Model\ShortUrlsOrdering;
use Shlinkio\Shlink\Core\Model\ShortUrlsParams; use Shlinkio\Shlink\Core\Model\ShortUrlsParams;
use Shlinkio\Shlink\Core\Service\ShortUrlServiceInterface; use Shlinkio\Shlink\Core\Service\ShortUrlServiceInterface;
@ -19,10 +22,13 @@ use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Component\Console\Style\SymfonyStyle;
use function array_keys;
use function array_pad; use function array_pad;
use function count;
use function explode; use function explode;
use function Functional\map; use function Functional\map;
use function implode; use function is_null;
use function join;
use function sprintf; use function sprintf;
class ListShortUrlsCommand extends AbstractWithDateRangeCommand class ListShortUrlsCommand extends AbstractWithDateRangeCommand
@ -30,18 +36,6 @@ class ListShortUrlsCommand extends AbstractWithDateRangeCommand
use PagerfantaUtilsTrait; use PagerfantaUtilsTrait;
public const NAME = 'short-url:list'; public const NAME = 'short-url:list';
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 ShortUrlServiceInterface $shortUrlService;
private DataTransformerInterface $transformer; private DataTransformerInterface $transformer;
@ -90,6 +84,18 @@ class ListShortUrlsCommand extends AbstractWithDateRangeCommand
InputOption::VALUE_NONE, InputOption::VALUE_NONE,
'Whether to display the tags or not.', 'Whether to display the tags or not.',
) )
->addOption(
'show-api-key',
'k',
InputOption::VALUE_NONE,
'Whether to display the API key from which the URL was generated or not.',
)
->addOption(
'show-api-key-name',
'm',
InputOption::VALUE_NONE,
'Whether to display the API key name from which the URL was generated or not.',
)
->addOption( ->addOption(
'all', 'all',
'a', 'a',
@ -117,12 +123,38 @@ class ListShortUrlsCommand extends AbstractWithDateRangeCommand
$searchTerm = $this->getOptionWithDeprecatedFallback($input, 'search-term'); $searchTerm = $this->getOptionWithDeprecatedFallback($input, 'search-term');
$tags = $input->getOption('tags'); $tags = $input->getOption('tags');
$tags = ! empty($tags) ? explode(',', $tags) : []; $tags = ! empty($tags) ? explode(',', $tags) : [];
$showTags = $this->getOptionWithDeprecatedFallback($input, 'show-tags');
$all = $input->getOption('all'); $all = $input->getOption('all');
$startDate = $this->getStartDateOption($input, $output); $startDate = $this->getStartDateOption($input, $output);
$endDate = $this->getEndDateOption($input, $output); $endDate = $this->getEndDateOption($input, $output);
$orderBy = $this->processOrderBy($input); $orderBy = $this->processOrderBy($input);
$transformerLookup = fn (string $key): closure
=> fn (ShortUrl $shortUrl)
=> $this->transformer->transform($shortUrl)[$key];
$columnMap = [
'Short Code' => $transformerLookup('shortCode'),
'Title' => $transformerLookup('title'),
'Short URL' => $transformerLookup('shortUrl'),
'Long URL' => $transformerLookup('longUrl'),
'Date created' => $transformerLookup('dateCreated'),
'Visits count' => $transformerLookup('visitsCount'),
];
if ($this->getOptionWithDeprecatedFallback($input, 'show-tags')) {
$columnMap['Tags'] = fn (ShortUrl $shortUrl): string
=> join(', ', map($shortUrl->getTags(), fn (Tag $tag): string => (string) $tag));
}
if ($input->getOption('show-api-key')) {
$columnMap['API Key'] = fn (ShortUrl $shortUrl): string => (string) $shortUrl->authorApiKey();
}
if ($input->getOption('show-api-key-name')) {
$columnMap['API Key Name'] = fn (ShortUrl $shortUrl): ?string => ! is_null($shortUrl->authorApiKey())
? $shortUrl->authorApiKey()->name()
: null;
}
$data = [ $data = [
ShortUrlsParamsInputFilter::SEARCH_TERM => $searchTerm, ShortUrlsParamsInputFilter::SEARCH_TERM => $searchTerm,
ShortUrlsParamsInputFilter::TAGS => $tags, ShortUrlsParamsInputFilter::TAGS => $tags,
@ -137,7 +169,7 @@ class ListShortUrlsCommand extends AbstractWithDateRangeCommand
do { do {
$data[ShortUrlsParamsInputFilter::PAGE] = $page; $data[ShortUrlsParamsInputFilter::PAGE] = $page;
$result = $this->renderPage($output, $showTags, ShortUrlsParams::fromRawData($data), $all); $result = $this->renderPage($output, $columnMap, ShortUrlsParams::fromRawData($data), $all);
$page++; $page++;
$continue = $result->hasNextPage() && $io->confirm( $continue = $result->hasNextPage() && $io->confirm(
@ -152,32 +184,29 @@ class ListShortUrlsCommand extends AbstractWithDateRangeCommand
return ExitCodes::EXIT_SUCCESS; return ExitCodes::EXIT_SUCCESS;
} }
private function renderPage(OutputInterface $output, bool $showTags, ShortUrlsParams $params, bool $all): Paginator private function renderPage(
{ OutputInterface $output,
$result = $this->shortUrlService->listShortUrls($params); array $columnMap,
ShortUrlsParams $params,
bool $all
): Paginator {
$shortUrls = $this->shortUrlService->listShortUrls($params);
$headers = ['Short code', 'Title', 'Short URL', 'Long URL', 'Date created', 'Visits count']; $rows = map($shortUrls, fn (ShortUrl $shortUrl)
if ($showTags) { => map($columnMap, fn (callable $call)
$headers[] = 'Tags'; => $call($shortUrl)));
}
$rows = []; ShlinkTable::fromOutput($output)
foreach ($result as $row) { ->render(
$columnsToShow = $showTags ? self::COLUMNS_TO_SHOW_WITH_TAGS : self::COLUMNS_TO_SHOW; array_keys($columnMap),
$shortUrl = $this->transformer->transform($row); $rows,
if ($showTags) { $all ? null : $this->formatCurrentPageMessage(
$shortUrl['tags'] = implode(', ', $shortUrl['tags']); $shortUrls,
} 'Page %s of %s',
),
);
$rows[] = map($columnsToShow, fn (string $prop) => $shortUrl[$prop]); return $shortUrls;
}
ShlinkTable::fromOutput($output)->render($headers, $rows, $all ? null : $this->formatCurrentPageMessage(
$result,
'Page %s of %s',
));
return $result;
} }
private function processOrderBy(InputInterface $input): ?string private function processOrderBy(InputInterface $input): ?string

View file

@ -132,6 +132,11 @@ class ShortUrl extends AbstractEntity
return $this->tags; return $this->tags;
} }
public function authorApiKey(): ?ApiKey
{
return $this->authorApiKey;
}
public function getValidSince(): ?Chronos public function getValidSince(): ?Chronos
{ {
return $this->validSince; return $this->validSince;