mirror of
https://github.com/shlinkio/shlink.git
synced 2025-02-25 18:45:27 -06:00
Added support to print all short URLs at once from CLI
This commit is contained in:
@@ -11,7 +11,6 @@ use Shlinkio\Shlink\CLI\Util\ShlinkTable;
|
|||||||
use Shlinkio\Shlink\Common\Paginator\Util\PaginatorUtilsTrait;
|
use Shlinkio\Shlink\Common\Paginator\Util\PaginatorUtilsTrait;
|
||||||
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\Paginator\Adapter\ShortUrlRepositoryAdapter;
|
|
||||||
use Shlinkio\Shlink\Core\Service\ShortUrlServiceInterface;
|
use Shlinkio\Shlink\Core\Service\ShortUrlServiceInterface;
|
||||||
use Shlinkio\Shlink\Core\Transformer\ShortUrlDataTransformer;
|
use Shlinkio\Shlink\Core\Transformer\ShortUrlDataTransformer;
|
||||||
use Shlinkio\Shlink\Core\Validation\ShortUrlsParamsInputFilter;
|
use Shlinkio\Shlink\Core\Validation\ShortUrlsParamsInputFilter;
|
||||||
@@ -61,7 +60,7 @@ class ListShortUrlsCommand extends AbstractWithDateRangeCommand
|
|||||||
'page',
|
'page',
|
||||||
'p',
|
'p',
|
||||||
InputOption::VALUE_REQUIRED,
|
InputOption::VALUE_REQUIRED,
|
||||||
sprintf('The first page to list (%s items per page)', ShortUrlRepositoryAdapter::ITEMS_PER_PAGE),
|
'The first page to list (10 items per page unless "--all" is provided)',
|
||||||
'1',
|
'1',
|
||||||
)
|
)
|
||||||
->addOption(
|
->addOption(
|
||||||
@@ -82,7 +81,8 @@ class ListShortUrlsCommand extends AbstractWithDateRangeCommand
|
|||||||
InputOption::VALUE_REQUIRED,
|
InputOption::VALUE_REQUIRED,
|
||||||
'The field from which we want to order by. Pass ASC or DESC separated by a comma',
|
'The field from which we want to order by. Pass ASC or DESC separated by a comma',
|
||||||
)
|
)
|
||||||
->addOption('showTags', 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', InputOption::VALUE_NONE, 'Disables pagination and just displays all existing URLs');
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getStartDateDesc(): string
|
protected function getStartDateDesc(): string
|
||||||
@@ -104,24 +104,32 @@ class ListShortUrlsCommand extends AbstractWithDateRangeCommand
|
|||||||
$tags = $input->getOption('tags');
|
$tags = $input->getOption('tags');
|
||||||
$tags = ! empty($tags) ? explode(',', $tags) : [];
|
$tags = ! empty($tags) ? explode(',', $tags) : [];
|
||||||
$showTags = (bool) $input->getOption('showTags');
|
$showTags = (bool) $input->getOption('showTags');
|
||||||
|
$all = (bool) $input->getOption('all');
|
||||||
$startDate = $this->getDateOption($input, $output, 'startDate');
|
$startDate = $this->getDateOption($input, $output, 'startDate');
|
||||||
$endDate = $this->getDateOption($input, $output, 'endDate');
|
$endDate = $this->getDateOption($input, $output, 'endDate');
|
||||||
$orderBy = $this->processOrderBy($input);
|
$orderBy = $this->processOrderBy($input);
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
ShortUrlsParamsInputFilter::PAGE => $page,
|
||||||
|
ShortUrlsParamsInputFilter::SEARCH_TERM => $searchTerm,
|
||||||
|
ShortUrlsParamsInputFilter::TAGS => $tags,
|
||||||
|
ShortUrlsOrdering::ORDER_BY => $orderBy,
|
||||||
|
ShortUrlsParamsInputFilter::START_DATE => $startDate !== null ? $startDate->toAtomString() : null,
|
||||||
|
ShortUrlsParamsInputFilter::END_DATE => $endDate !== null ? $endDate->toAtomString() : null,
|
||||||
|
];
|
||||||
|
|
||||||
|
if ($all) {
|
||||||
|
$data[ShortUrlsParamsInputFilter::ITEMS_PER_PAGE] = -1;
|
||||||
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
$result = $this->renderPage($output, $showTags, ShortUrlsParams::fromRawData([
|
$result = $this->renderPage($output, $showTags, ShortUrlsParams::fromRawData($data));
|
||||||
ShortUrlsParamsInputFilter::PAGE => $page,
|
|
||||||
ShortUrlsParamsInputFilter::SEARCH_TERM => $searchTerm,
|
|
||||||
ShortUrlsParamsInputFilter::TAGS => $tags,
|
|
||||||
ShortUrlsOrdering::ORDER_BY => $orderBy,
|
|
||||||
ShortUrlsParamsInputFilter::START_DATE => $startDate !== null ? $startDate->toAtomString() : null,
|
|
||||||
ShortUrlsParamsInputFilter::END_DATE => $endDate !== null ? $endDate->toAtomString() : null,
|
|
||||||
]));
|
|
||||||
$page++;
|
$page++;
|
||||||
|
|
||||||
$continue = $this->isLastPage($result)
|
$continue = ! $this->isLastPage($result) && $io->confirm(
|
||||||
? false
|
sprintf('Continue with page <options=bold>%s</>?', $page),
|
||||||
: $io->confirm(sprintf('Continue with page <options=bold>%s</>?', $page), false);
|
false,
|
||||||
|
);
|
||||||
} while ($continue);
|
} while ($continue);
|
||||||
|
|
||||||
$io->newLine();
|
$io->newLine();
|
||||||
|
|||||||
@@ -12,11 +12,14 @@ use function Shlinkio\Shlink\Core\parseDateField;
|
|||||||
|
|
||||||
final class ShortUrlsParams
|
final class ShortUrlsParams
|
||||||
{
|
{
|
||||||
|
public const DEFAULT_ITEMS_PER_PAGE = 10;
|
||||||
|
|
||||||
private int $page;
|
private int $page;
|
||||||
private ?string $searchTerm;
|
private ?string $searchTerm;
|
||||||
private array $tags;
|
private array $tags;
|
||||||
private ShortUrlsOrdering $orderBy;
|
private ShortUrlsOrdering $orderBy;
|
||||||
private ?DateRange $dateRange;
|
private ?DateRange $dateRange;
|
||||||
|
private ?int $itemsPerPage = null;
|
||||||
|
|
||||||
private function __construct()
|
private function __construct()
|
||||||
{
|
{
|
||||||
@@ -56,6 +59,9 @@ final class ShortUrlsParams
|
|||||||
parseDateField($inputFilter->getValue(ShortUrlsParamsInputFilter::END_DATE)),
|
parseDateField($inputFilter->getValue(ShortUrlsParamsInputFilter::END_DATE)),
|
||||||
);
|
);
|
||||||
$this->orderBy = ShortUrlsOrdering::fromRawData($query);
|
$this->orderBy = ShortUrlsOrdering::fromRawData($query);
|
||||||
|
$this->itemsPerPage = (int) (
|
||||||
|
$inputFilter->getValue(ShortUrlsParamsInputFilter::ITEMS_PER_PAGE) ?? self::DEFAULT_ITEMS_PER_PAGE
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function page(): int
|
public function page(): int
|
||||||
@@ -63,6 +69,11 @@ final class ShortUrlsParams
|
|||||||
return $this->page;
|
return $this->page;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function itemsPerPage(): int
|
||||||
|
{
|
||||||
|
return $this->itemsPerPage;
|
||||||
|
}
|
||||||
|
|
||||||
public function searchTerm(): ?string
|
public function searchTerm(): ?string
|
||||||
{
|
{
|
||||||
return $this->searchTerm;
|
return $this->searchTerm;
|
||||||
|
|||||||
@@ -10,8 +10,6 @@ use Shlinkio\Shlink\Core\Repository\ShortUrlRepositoryInterface;
|
|||||||
|
|
||||||
class ShortUrlRepositoryAdapter implements AdapterInterface
|
class ShortUrlRepositoryAdapter implements AdapterInterface
|
||||||
{
|
{
|
||||||
public const ITEMS_PER_PAGE = 10;
|
|
||||||
|
|
||||||
private ShortUrlRepositoryInterface $repository;
|
private ShortUrlRepositoryInterface $repository;
|
||||||
private ShortUrlsParams $params;
|
private ShortUrlsParams $params;
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ class ShortUrlService implements ShortUrlServiceInterface
|
|||||||
/** @var ShortUrlRepository $repo */
|
/** @var ShortUrlRepository $repo */
|
||||||
$repo = $this->em->getRepository(ShortUrl::class);
|
$repo = $this->em->getRepository(ShortUrl::class);
|
||||||
$paginator = new Paginator(new ShortUrlRepositoryAdapter($repo, $params));
|
$paginator = new Paginator(new ShortUrlRepositoryAdapter($repo, $params));
|
||||||
$paginator->setItemCountPerPage(ShortUrlRepositoryAdapter::ITEMS_PER_PAGE)
|
$paginator->setItemCountPerPage($params->itemsPerPage())
|
||||||
->setCurrentPageNumber($params->page());
|
->setCurrentPageNumber($params->page());
|
||||||
|
|
||||||
return $paginator;
|
return $paginator;
|
||||||
|
|||||||
@@ -5,10 +5,13 @@ declare(strict_types=1);
|
|||||||
namespace Shlinkio\Shlink\Core\Validation;
|
namespace Shlinkio\Shlink\Core\Validation;
|
||||||
|
|
||||||
use Laminas\Filter;
|
use Laminas\Filter;
|
||||||
|
use Laminas\InputFilter\Input;
|
||||||
use Laminas\InputFilter\InputFilter;
|
use Laminas\InputFilter\InputFilter;
|
||||||
use Laminas\Validator;
|
use Laminas\Validator;
|
||||||
use Shlinkio\Shlink\Common\Validation;
|
use Shlinkio\Shlink\Common\Validation;
|
||||||
|
|
||||||
|
use function is_numeric;
|
||||||
|
|
||||||
class ShortUrlsParamsInputFilter extends InputFilter
|
class ShortUrlsParamsInputFilter extends InputFilter
|
||||||
{
|
{
|
||||||
use Validation\InputFactoryTrait;
|
use Validation\InputFactoryTrait;
|
||||||
@@ -18,6 +21,7 @@ class ShortUrlsParamsInputFilter extends InputFilter
|
|||||||
public const TAGS = 'tags';
|
public const TAGS = 'tags';
|
||||||
public const START_DATE = 'startDate';
|
public const START_DATE = 'startDate';
|
||||||
public const END_DATE = 'endDate';
|
public const END_DATE = 'endDate';
|
||||||
|
public const ITEMS_PER_PAGE = 'itemsPerPage';
|
||||||
|
|
||||||
public function __construct(array $data)
|
public function __construct(array $data)
|
||||||
{
|
{
|
||||||
@@ -32,14 +36,22 @@ class ShortUrlsParamsInputFilter extends InputFilter
|
|||||||
|
|
||||||
$this->add($this->createInput(self::SEARCH_TERM, false));
|
$this->add($this->createInput(self::SEARCH_TERM, false));
|
||||||
|
|
||||||
$page = $this->createInput(self::PAGE, false);
|
$this->add($this->createNumericInput(self::PAGE, 1));
|
||||||
$page->getValidatorChain()->attach(new Validator\Digits())
|
|
||||||
->attach(new Validator\GreaterThan(['min' => 1, 'inclusive' => true]));
|
|
||||||
$this->add($page);
|
|
||||||
|
|
||||||
$tags = $this->createArrayInput(self::TAGS, false);
|
$tags = $this->createArrayInput(self::TAGS, false);
|
||||||
$tags->getFilterChain()->attach(new Filter\StringToLower())
|
$tags->getFilterChain()->attach(new Filter\StringToLower())
|
||||||
->attach(new Filter\PregReplace(['pattern' => '/ /', 'replacement' => '-']));
|
->attach(new Filter\PregReplace(['pattern' => '/ /', 'replacement' => '-']));
|
||||||
$this->add($tags);
|
$this->add($tags);
|
||||||
|
|
||||||
|
$this->add($this->createNumericInput(self::ITEMS_PER_PAGE, -1));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function createNumericInput(string $name, int $min): Input
|
||||||
|
{
|
||||||
|
$input = $this->createInput($name, false);
|
||||||
|
$input->getValidatorChain()->attach(new Validator\Callback(fn ($value) => is_numeric($value)))
|
||||||
|
->attach(new Validator\GreaterThan(['min' => $min, 'inclusive' => true]));
|
||||||
|
|
||||||
|
return $input;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user