diff --git a/composer.json b/composer.json index ce688a63..0a7bd6c2 100644 --- a/composer.json +++ b/composer.json @@ -30,10 +30,10 @@ "mikehaertl/phpwkhtmltopdf": "^2.2", "monolog/monolog": "^1.21", "roave/security-advisories": "dev-master", - "symfony/console": "^4.1", - "symfony/filesystem": "^4.1", - "symfony/lock": "^4.1", - "symfony/process": "^4.1", + "symfony/console": "^4.2", + "symfony/filesystem": "^4.2", + "symfony/lock": "^4.2", + "symfony/process": "^4.2", "theorchard/monolog-cascade": "^0.4", "zendframework/zend-config": "^3.0", "zendframework/zend-config-aggregator": "^1.0", @@ -57,8 +57,8 @@ "phpunit/phpcov": "^5.0", "phpunit/phpunit": "^7.3", "shlinkio/php-coding-standard": "~1.0.0", - "symfony/dotenv": "^4.0", - "symfony/var-dumper": "^4.0", + "symfony/dotenv": "^4.2", + "symfony/var-dumper": "^4.2", "zendframework/zend-component-installer": "^2.1", "zendframework/zend-expressive-tooling": "^1.0" }, diff --git a/module/CLI/src/Command/ShortUrl/ListShortUrlsCommand.php b/module/CLI/src/Command/ShortUrl/ListShortUrlsCommand.php index 2bef076d..f1362cd8 100644 --- a/module/CLI/src/Command/ShortUrl/ListShortUrlsCommand.php +++ b/module/CLI/src/Command/ShortUrl/ListShortUrlsCommand.php @@ -3,8 +3,10 @@ declare(strict_types=1); namespace Shlinkio\Shlink\CLI\Command\ShortUrl; +use Shlinkio\Shlink\Common\Console\ShlinkTable; use Shlinkio\Shlink\Common\Paginator\Adapter\PaginableRepositoryAdapter; use Shlinkio\Shlink\Common\Paginator\Util\PaginatorUtilsTrait; +use Shlinkio\Shlink\Common\Rest\DataTransformerInterface; use Shlinkio\Shlink\Core\Service\ShortUrlServiceInterface; use Shlinkio\Shlink\Core\Transformer\ShortUrlDataTransformer; use Symfony\Component\Console\Command\Command; @@ -12,6 +14,7 @@ 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 Zend\Paginator\Paginator; use function array_values; use function count; use function explode; @@ -78,39 +81,53 @@ class ListShortUrlsCommand extends Command $searchTerm = $input->getOption('searchTerm'); $tags = $input->getOption('tags'); $tags = ! empty($tags) ? explode(',', $tags) : []; - $showTags = $input->getOption('showTags'); + $showTags = (bool) $input->getOption('showTags'); $transformer = new ShortUrlDataTransformer($this->domainConfig); do { - $result = $this->shortUrlService->listShortUrls($page, $searchTerm, $tags, $this->processOrderBy($input)); + $result = $this->renderPage($input, $output, $page, $searchTerm, $tags, $showTags, $transformer); $page++; - $headers = ['Short code', 'Short URL', 'Long URL', 'Date created', 'Visits count']; - if ($showTags) { - $headers[] = 'Tags'; - } - - $rows = []; - foreach ($result as $row) { - $shortUrl = $transformer->transform($row); - if ($showTags) { - $shortUrl['tags'] = implode(', ', $shortUrl['tags']); - } else { - unset($shortUrl['tags']); - } - - unset($shortUrl['originalUrl']); - $rows[] = array_values($shortUrl); - } - $io->table($headers, $rows); - - if ($this->isLastPage($result)) { - $continue = false; - $io->success('Short URLs properly listed'); - } else { - $continue = $io->confirm(sprintf('Continue with page %s?', $page), false); - } + $continue = $this->isLastPage($result) + ? false + : $io->confirm(sprintf('Continue with page %s?', $page), false); } while ($continue); + + $io->newLine(); + $io->success('Short URLs properly listed'); + } + + private function renderPage( + InputInterface $input, + OutputInterface $output, + int $page, + ?string $searchTerm, + array $tags, + bool $showTags, + DataTransformerInterface $transformer + ): Paginator { + $result = $this->shortUrlService->listShortUrls($page, $searchTerm, $tags, $this->processOrderBy($input)); + + $headers = ['Short code', 'Short URL', 'Long URL', 'Date created', 'Visits count']; + if ($showTags) { + $headers[] = 'Tags'; + } + + $rows = []; + foreach ($result as $row) { + $shortUrl = $transformer->transform($row); + if ($showTags) { + $shortUrl['tags'] = implode(', ', $shortUrl['tags']); + } else { + unset($shortUrl['tags']); + } + + unset($shortUrl['originalUrl']); + $rows[] = array_values($shortUrl); + } + + ShlinkTable::fromOutput($output)->render($headers, $rows); + return $result; } private function processOrderBy(InputInterface $input) diff --git a/module/Common/src/Console/ShlinkTable.php b/module/Common/src/Console/ShlinkTable.php new file mode 100644 index 00000000..6530b99a --- /dev/null +++ b/module/Common/src/Console/ShlinkTable.php @@ -0,0 +1,41 @@ + %s '; + + /** @var Table|null */ + private $baseTable; + + public function __construct(Table $baseTable) + { + $this->baseTable = $baseTable; + } + + public static function fromOutput(OutputInterface $output): self + { + return new self(new Table($output)); + } + + public function render(array $headers, array $rows, ?string $headerTitle = null, ?string $footerTitle = null): void + { + $style = Table::getStyleDefinition(self::DEFAULT_STYLE_NAME); + $style->setFooterTitleFormat(self::TABLE_TITLE_STYLE) + ->setHeaderTitleFormat(self::TABLE_TITLE_STYLE); + + $table = clone $this->baseTable; + $table->setStyle($style) + ->setHeaders($headers) + ->setRows($rows) + ->setHeaderTitle($headerTitle) + ->setFooterTitle($footerTitle) + ->render(); + } +}