Created class to wrap CLI table rendering behavior

This commit is contained in:
Alejandro Celaya 2018-12-08 11:32:16 +01:00
parent 080943e810
commit 46a35c553e
3 changed files with 91 additions and 33 deletions

View file

@ -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"
},

View file

@ -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 <options=bold>%s</>?', $page), false);
}
$continue = $this->isLastPage($result)
? false
: $io->confirm(sprintf('Continue with page <options=bold>%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)

View file

@ -0,0 +1,41 @@
<?php
declare(strict_types=1);
namespace Shlinkio\Shlink\Common\Console;
use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Output\OutputInterface;
final class ShlinkTable
{
private const DEFAULT_STYLE_NAME = 'default';
private const TABLE_TITLE_STYLE = '<options=bold> %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();
}
}