Replaced laminas-paginator with pagerfanta

This commit is contained in:
Alejandro Celaya 2021-01-23 14:37:34 +01:00
parent 088e361228
commit 55ddc4ae75
25 changed files with 63 additions and 61 deletions

View File

@ -29,7 +29,6 @@
"laminas/laminas-config-aggregator": "^1.1",
"laminas/laminas-diactoros": "^2.1.3",
"laminas/laminas-inputfilter": "^2.10",
"laminas/laminas-paginator": "^2.8",
"laminas/laminas-servicemanager": "^3.6",
"laminas/laminas-stdlib": "^3.2",
"lcobucci/jwt": "^4.0",
@ -43,11 +42,12 @@
"monolog/monolog": "^2.0",
"nikolaposa/monolog-factory": "^3.1",
"ocramius/proxy-manager": "^2.11",
"pagerfanta/core": "^2.5",
"php-middleware/request-id": "^4.1",
"predis/predis": "^1.1",
"pugx/shortid-php": "^0.7",
"ramsey/uuid": "^3.9",
"shlinkio/shlink-common": "^3.4",
"shlinkio/shlink-common": "dev-main#cab9f39 as 3.5",
"shlinkio/shlink-config": "^1.0",
"shlinkio/shlink-event-dispatcher": "^2.0",
"shlinkio/shlink-importer": "^2.1",

View File

@ -75,7 +75,7 @@ class GetVisitsCommand extends AbstractWithDateRangeCommand
$paginator = $this->visitsTracker->info($identifier, new VisitsParams(new DateRange($startDate, $endDate)));
$rows = map($paginator->getCurrentItems(), function (Visit $visit) {
$rows = map($paginator->getCurrentPageResults(), function (Visit $visit) {
$rowData = $visit->jsonSerialize();
$rowData['country'] = ($visit->getVisitLocation() ?? new UnknownVisitLocation())->getCountryName();
return select_keys($rowData, ['referer', 'date', 'userAgent', 'country']);

View File

@ -4,11 +4,11 @@ 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\Core\Model\ShortUrlsOrdering;
use Shlinkio\Shlink\Core\Model\ShortUrlsParams;
use Shlinkio\Shlink\Core\Service\ShortUrlServiceInterface;
@ -29,7 +29,7 @@ use function sprintf;
class ListShortUrlsCommand extends AbstractWithDateRangeCommand
{
use PaginatorUtilsTrait;
use PagerfantaUtilsTrait;
public const NAME = 'short-url:list';
private const COLUMNS_WHITELIST = [
@ -132,7 +132,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,
);

View File

@ -5,13 +5,13 @@ declare(strict_types=1);
namespace ShlinkioTest\Shlink\CLI\Command\ShortUrl;
use Cake\Chronos\Chronos;
use Laminas\Paginator\Adapter\ArrayAdapter;
use Laminas\Paginator\Paginator;
use Pagerfanta\Adapter\ArrayAdapter;
use PHPUnit\Framework\TestCase;
use Prophecy\Argument;
use Prophecy\PhpUnit\ProphecyTrait;
use Prophecy\Prophecy\ObjectProphecy;
use Shlinkio\Shlink\CLI\Command\ShortUrl\GetVisitsCommand;
use Shlinkio\Shlink\Common\Paginator\Paginator;
use Shlinkio\Shlink\Common\Util\DateRange;
use Shlinkio\Shlink\Core\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Entity\Visit;

View File

@ -5,13 +5,13 @@ declare(strict_types=1);
namespace ShlinkioTest\Shlink\CLI\Command\ShortUrl;
use Cake\Chronos\Chronos;
use Laminas\Paginator\Adapter\ArrayAdapter;
use Laminas\Paginator\Paginator;
use Pagerfanta\Adapter\ArrayAdapter;
use PHPUnit\Framework\TestCase;
use Prophecy\Argument;
use Prophecy\PhpUnit\ProphecyTrait;
use Prophecy\Prophecy\ObjectProphecy;
use Shlinkio\Shlink\CLI\Command\ShortUrl\ListShortUrlsCommand;
use Shlinkio\Shlink\Common\Paginator\Paginator;
use Shlinkio\Shlink\Core\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Model\ShortUrlsParams;
use Shlinkio\Shlink\Core\Service\ShortUrlServiceInterface;
@ -89,7 +89,7 @@ class ListShortUrlsCommandTest extends TestCase
{
$page = 5;
$this->shortUrlService->listShortUrls(ShortUrlsParams::fromRawData(['page' => $page]))
->willReturn(new Paginator(new ArrayAdapter()))
->willReturn(new Paginator(new ArrayAdapter([])))
->shouldBeCalledOnce();
$this->commandTester->setInputs(['y']);
@ -100,7 +100,7 @@ class ListShortUrlsCommandTest extends TestCase
public function ifTagsFlagIsProvidedTagsColumnIsIncluded(): void
{
$this->shortUrlService->listShortUrls(ShortUrlsParams::emptyInstance())
->willReturn(new Paginator(new ArrayAdapter()))
->willReturn(new Paginator(new ArrayAdapter([])))
->shouldBeCalledOnce();
$this->commandTester->setInputs(['y']);
@ -127,7 +127,7 @@ class ListShortUrlsCommandTest extends TestCase
'tags' => $tags,
'startDate' => $startDate !== null ? Chronos::parse($startDate)->toAtomString() : null,
'endDate' => $endDate !== null ? Chronos::parse($endDate)->toAtomString() : null,
]))->willReturn(new Paginator(new ArrayAdapter()));
]))->willReturn(new Paginator(new ArrayAdapter([])));
$this->commandTester->setInputs(['n']);
$this->commandTester->execute($commandArgs);
@ -180,7 +180,7 @@ class ListShortUrlsCommandTest extends TestCase
{
$listShortUrls = $this->shortUrlService->listShortUrls(ShortUrlsParams::fromRawData([
'orderBy' => $expectedOrderBy,
]))->willReturn(new Paginator(new ArrayAdapter()));
]))->willReturn(new Paginator(new ArrayAdapter([])));
$this->commandTester->setInputs(['n']);
$this->commandTester->execute($commandArgs);
@ -207,7 +207,7 @@ class ListShortUrlsCommandTest extends TestCase
'endDate' => null,
'orderBy' => null,
'itemsPerPage' => -1,
]))->willReturn(new Paginator(new ArrayAdapter()));
]))->willReturn(new Paginator(new ArrayAdapter([])));
$this->commandTester->execute(['--all' => true]);

View File

@ -4,13 +4,13 @@ declare(strict_types=1);
namespace Shlinkio\Shlink\Core\Paginator\Adapter;
use Laminas\Paginator\Adapter\AdapterInterface;
use Pagerfanta\Adapter\AdapterInterface;
abstract class AbstractCacheableCountPaginatorAdapter implements AdapterInterface
{
private ?int $count = null;
final public function count(): int
final public function getNbResults(): int
{
// Since a new adapter instance is created every time visits are fetched, it is reasonably safe to internally
// cache the count value.

View File

@ -5,7 +5,7 @@ declare(strict_types=1);
namespace Shlinkio\Shlink\Core\Paginator\Adapter;
use Happyr\DoctrineSpecification\Specification\Specification;
use Laminas\Paginator\Adapter\AdapterInterface;
use Pagerfanta\Adapter\AdapterInterface;
use Shlinkio\Shlink\Core\Model\ShortUrlsParams;
use Shlinkio\Shlink\Core\Repository\ShortUrlRepositoryInterface;
use Shlinkio\Shlink\Rest\Entity\ApiKey;
@ -23,10 +23,10 @@ class ShortUrlRepositoryAdapter implements AdapterInterface
$this->apiKey = $apiKey;
}
public function getItems($offset, $itemCountPerPage): array // phpcs:ignore
public function getSlice($offset, $length): array // phpcs:ignore
{
return $this->repository->findList(
$itemCountPerPage,
$length,
$offset,
$this->params->searchTerm(),
$this->params->tags(),
@ -36,7 +36,7 @@ class ShortUrlRepositoryAdapter implements AdapterInterface
);
}
public function count(): int
public function getNbResults(): int
{
return $this->repository->countList(
$this->params->searchTerm(),

View File

@ -28,12 +28,12 @@ class VisitsForTagPaginatorAdapter extends AbstractCacheableCountPaginatorAdapte
$this->apiKey = $apiKey;
}
public function getItems($offset, $itemCountPerPage): array // phpcs:ignore
public function getSlice($offset, $length): array // phpcs:ignore
{
return $this->visitRepository->findVisitsByTag(
$this->tag,
$this->params->getDateRange(),
$itemCountPerPage,
$length,
$offset,
$this->resolveSpec(),
);

View File

@ -28,13 +28,13 @@ class VisitsPaginatorAdapter extends AbstractCacheableCountPaginatorAdapter
$this->spec = $spec;
}
public function getItems($offset, $itemCountPerPage): array // phpcs:ignore
public function getSlice($offset, $length): array // phpcs:ignore
{
return $this->visitRepository->findVisitsByShortCode(
$this->identifier->shortCode(),
$this->identifier->domain(),
$this->params->getDateRange(),
$itemCountPerPage,
$length,
$offset,
$this->spec,
);

View File

@ -5,7 +5,7 @@ declare(strict_types=1);
namespace Shlinkio\Shlink\Core\Service;
use Doctrine\ORM;
use Laminas\Paginator\Paginator;
use Shlinkio\Shlink\Common\Paginator\Paginator;
use Shlinkio\Shlink\Core\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Exception\InvalidUrlException;
use Shlinkio\Shlink\Core\Exception\ShortUrlNotFoundException;
@ -45,8 +45,8 @@ class ShortUrlService implements ShortUrlServiceInterface
/** @var ShortUrlRepository $repo */
$repo = $this->em->getRepository(ShortUrl::class);
$paginator = new Paginator(new ShortUrlRepositoryAdapter($repo, $params, $apiKey));
$paginator->setItemCountPerPage($params->itemsPerPage())
->setCurrentPageNumber($params->page());
$paginator->setMaxPerPage($params->itemsPerPage())
->setCurrentPage($params->page());
return $paginator;
}

View File

@ -4,7 +4,7 @@ declare(strict_types=1);
namespace Shlinkio\Shlink\Core\Service;
use Laminas\Paginator\Paginator;
use Shlinkio\Shlink\Common\Paginator\Paginator;
use Shlinkio\Shlink\Core\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Exception\InvalidUrlException;
use Shlinkio\Shlink\Core\Exception\ShortUrlNotFoundException;

View File

@ -5,8 +5,8 @@ declare(strict_types=1);
namespace Shlinkio\Shlink\Core\Service;
use Doctrine\ORM;
use Laminas\Paginator\Paginator;
use Psr\EventDispatcher\EventDispatcherInterface;
use Shlinkio\Shlink\Common\Paginator\Paginator;
use Shlinkio\Shlink\Core\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Entity\Tag;
use Shlinkio\Shlink\Core\Entity\Visit;
@ -66,8 +66,8 @@ class VisitsTracker implements VisitsTrackerInterface
/** @var VisitRepositoryInterface $repo */
$repo = $this->em->getRepository(Visit::class);
$paginator = new Paginator(new VisitsPaginatorAdapter($repo, $identifier, $params, $spec));
$paginator->setItemCountPerPage($params->getItemsPerPage())
->setCurrentPageNumber($params->getPage());
$paginator->setMaxPerPage($params->getItemsPerPage())
->setCurrentPage($params->getPage());
return $paginator;
}
@ -87,8 +87,8 @@ class VisitsTracker implements VisitsTrackerInterface
/** @var VisitRepositoryInterface $repo */
$repo = $this->em->getRepository(Visit::class);
$paginator = new Paginator(new VisitsForTagPaginatorAdapter($repo, $tag, $params, $apiKey));
$paginator->setItemCountPerPage($params->getItemsPerPage())
->setCurrentPageNumber($params->getPage());
$paginator->setMaxPerPage($params->getItemsPerPage())
->setCurrentPage($params->getPage());
return $paginator;
}

View File

@ -4,7 +4,7 @@ declare(strict_types=1);
namespace Shlinkio\Shlink\Core\Service;
use Laminas\Paginator\Paginator;
use Shlinkio\Shlink\Common\Paginator\Paginator;
use Shlinkio\Shlink\Core\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Entity\Visit;
use Shlinkio\Shlink\Core\Exception\ShortUrlNotFoundException;

View File

@ -47,7 +47,7 @@ class ShortUrlRepositoryAdapterTest extends TestCase
$dateRange = $params->dateRange();
$this->repo->findList(10, 5, $searchTerm, $tags, $orderBy, $dateRange, null)->shouldBeCalledOnce();
$adapter->getItems(5, 10);
$adapter->getSlice(5, 10);
}
/**
@ -71,7 +71,7 @@ class ShortUrlRepositoryAdapterTest extends TestCase
$dateRange = $params->dateRange();
$this->repo->countList($searchTerm, $tags, $dateRange, $apiKey->spec())->shouldBeCalledOnce();
$adapter->count();
$adapter->getNbResults();
}
public function provideFilteringArgs(): iterable

View File

@ -34,7 +34,7 @@ class VisitsForTagPaginatorAdapterTest extends TestCase
$findVisits = $this->repo->findVisitsByTag('foo', new DateRange(), $limit, $offset, null)->willReturn([]);
for ($i = 0; $i < $count; $i++) {
$adapter->getItems($offset, $limit);
$adapter->getSlice($offset, $limit);
}
$findVisits->shouldHaveBeenCalledTimes($count);
@ -49,7 +49,7 @@ class VisitsForTagPaginatorAdapterTest extends TestCase
$countVisits = $this->repo->countVisitsByTag('foo', new DateRange(), $apiKey->spec())->willReturn(3);
for ($i = 0; $i < $count; $i++) {
$adapter->count();
$adapter->getNbResults();
}
$countVisits->shouldHaveBeenCalledOnce();

View File

@ -37,7 +37,7 @@ class VisitsPaginatorAdapterTest extends TestCase
);
for ($i = 0; $i < $count; $i++) {
$adapter->getItems($offset, $limit);
$adapter->getSlice($offset, $limit);
}
$findVisits->shouldHaveBeenCalledTimes($count);
@ -52,7 +52,7 @@ class VisitsPaginatorAdapterTest extends TestCase
$countVisits = $this->repo->countVisitsByShortCode('', null, new DateRange(), $apiKey->spec())->willReturn(3);
for ($i = 0; $i < $count; $i++) {
$adapter->count();
$adapter->getNbResults();
}
$countVisits->shouldHaveBeenCalledOnce();

View File

@ -69,8 +69,10 @@ class ShortUrlServiceTest extends TestCase
$repo->countList(Argument::cetera())->willReturn(count($list))->shouldBeCalledOnce();
$this->em->getRepository(ShortUrl::class)->willReturn($repo->reveal());
$list = $this->service->listShortUrls(ShortUrlsParams::emptyInstance(), $apiKey);
self::assertEquals(4, $list->getCurrentItemCount());
$paginator = $this->service->listShortUrls(ShortUrlsParams::emptyInstance(), $apiKey);
self::assertCount(4, $paginator);
self::assertCount(4, $paginator->getCurrentPageResults());
}
/**

View File

@ -83,7 +83,7 @@ class VisitsTrackerTest extends TestCase
$paginator = $this->visitsTracker->info(new ShortUrlIdentifier($shortCode), new VisitsParams(), $apiKey);
self::assertEquals($list, ArrayUtils::iteratorToArray($paginator->getCurrentItems()));
self::assertEquals($list, ArrayUtils::iteratorToArray($paginator->getCurrentPageResults()));
$count->shouldHaveBeenCalledOnce();
}
@ -137,7 +137,7 @@ class VisitsTrackerTest extends TestCase
$paginator = $this->visitsTracker->visitsForTag($tag, new VisitsParams(), $apiKey);
self::assertEquals($list, ArrayUtils::iteratorToArray($paginator->getCurrentItems()));
self::assertEquals($list, ArrayUtils::iteratorToArray($paginator->getCurrentPageResults()));
$tagExists->shouldHaveBeenCalledOnce();
$getRepo->shouldHaveBeenCalledOnce();
}

View File

@ -7,7 +7,7 @@ namespace Shlinkio\Shlink\Rest\Action\ShortUrl;
use Laminas\Diactoros\Response\JsonResponse;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Shlinkio\Shlink\Common\Paginator\Util\PaginatorUtilsTrait;
use Shlinkio\Shlink\Common\Paginator\Util\PagerfantaUtilsTrait;
use Shlinkio\Shlink\Core\Model\ShortUrlsParams;
use Shlinkio\Shlink\Core\Service\ShortUrlServiceInterface;
use Shlinkio\Shlink\Core\Transformer\ShortUrlDataTransformer;
@ -16,7 +16,7 @@ use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware;
class ListShortUrlsAction extends AbstractRestAction
{
use PaginatorUtilsTrait;
use PagerfantaUtilsTrait;
protected const ROUTE_PATH = '/short-urls';
protected const ROUTE_ALLOWED_METHODS = [self::METHOD_GET];

View File

@ -7,7 +7,7 @@ namespace Shlinkio\Shlink\Rest\Action\Visit;
use Laminas\Diactoros\Response\JsonResponse;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Shlinkio\Shlink\Common\Paginator\Util\PaginatorUtilsTrait;
use Shlinkio\Shlink\Common\Paginator\Util\PagerfantaUtilsTrait;
use Shlinkio\Shlink\Core\Model\ShortUrlIdentifier;
use Shlinkio\Shlink\Core\Model\VisitsParams;
use Shlinkio\Shlink\Core\Service\VisitsTrackerInterface;
@ -16,7 +16,7 @@ use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware;
class ShortUrlVisitsAction extends AbstractRestAction
{
use PaginatorUtilsTrait;
use PagerfantaUtilsTrait;
protected const ROUTE_PATH = '/short-urls/{shortCode}/visits';
protected const ROUTE_ALLOWED_METHODS = [self::METHOD_GET];

View File

@ -7,7 +7,7 @@ namespace Shlinkio\Shlink\Rest\Action\Visit;
use Laminas\Diactoros\Response\JsonResponse;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Shlinkio\Shlink\Common\Paginator\Util\PaginatorUtilsTrait;
use Shlinkio\Shlink\Common\Paginator\Util\PagerfantaUtilsTrait;
use Shlinkio\Shlink\Core\Model\VisitsParams;
use Shlinkio\Shlink\Core\Service\VisitsTrackerInterface;
use Shlinkio\Shlink\Rest\Action\AbstractRestAction;
@ -15,7 +15,7 @@ use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware;
class TagVisitsAction extends AbstractRestAction
{
use PaginatorUtilsTrait;
use PagerfantaUtilsTrait;
protected const ROUTE_PATH = '/tags/{tag}/visits';
protected const ROUTE_ALLOWED_METHODS = [self::METHOD_GET];

View File

@ -4,11 +4,11 @@ declare(strict_types=1);
namespace ShlinkioApiTest\Shlink\Rest\Action;
use GuzzleHttp\Psr7\Query;
use Laminas\Diactoros\Uri;
use Shlinkio\Shlink\TestUtils\ApiTest\ApiTestCase;
use ShlinkioApiTest\Shlink\Rest\Utils\NotFoundUrlHelpersTrait;
use function GuzzleHttp\Psr7\build_query;
use function sprintf;
class ShortUrlVisitsActionTest extends ApiTestCase
@ -52,7 +52,7 @@ class ShortUrlVisitsActionTest extends ApiTestCase
$url = new Uri(sprintf('/short-urls/%s/visits', $shortCode));
if ($domain !== null) {
$url = $url->withQuery(build_query(['domain' => $domain]));
$url = $url->withQuery(Query::build(['domain' => $domain]));
}
$resp = $this->callApiWithKey(self::METHOD_GET, (string) $url);

View File

@ -7,11 +7,11 @@ namespace ShlinkioTest\Shlink\Rest\Action\ShortUrl;
use Cake\Chronos\Chronos;
use Laminas\Diactoros\Response\JsonResponse;
use Laminas\Diactoros\ServerRequest;
use Laminas\Paginator\Adapter\ArrayAdapter;
use Laminas\Paginator\Paginator;
use Pagerfanta\Adapter\ArrayAdapter;
use PHPUnit\Framework\TestCase;
use Prophecy\PhpUnit\ProphecyTrait;
use Prophecy\Prophecy\ObjectProphecy;
use Shlinkio\Shlink\Common\Paginator\Paginator;
use Shlinkio\Shlink\Core\Model\ShortUrlsParams;
use Shlinkio\Shlink\Core\Service\ShortUrlService;
use Shlinkio\Shlink\Rest\Action\ShortUrl\ListShortUrlsAction;
@ -56,7 +56,7 @@ class ListShortUrlsActionTest extends TestCase
'orderBy' => $expectedOrderBy,
'startDate' => $startDate,
'endDate' => $endDate,
]), $apiKey)->willReturn(new Paginator(new ArrayAdapter()));
]), $apiKey)->willReturn(new Paginator(new ArrayAdapter([])));
/** @var JsonResponse $response */
$response = $this->action->handle($request);

View File

@ -6,13 +6,13 @@ namespace ShlinkioTest\Shlink\Rest\Action\Visit;
use Cake\Chronos\Chronos;
use Laminas\Diactoros\ServerRequestFactory;
use Laminas\Paginator\Adapter\ArrayAdapter;
use Laminas\Paginator\Paginator;
use Pagerfanta\Adapter\ArrayAdapter;
use PHPUnit\Framework\TestCase;
use Prophecy\Argument;
use Prophecy\PhpUnit\ProphecyTrait;
use Prophecy\Prophecy\ObjectProphecy;
use Psr\Http\Message\ServerRequestInterface;
use Shlinkio\Shlink\Common\Paginator\Paginator;
use Shlinkio\Shlink\Common\Util\DateRange;
use Shlinkio\Shlink\Core\Model\ShortUrlIdentifier;
use Shlinkio\Shlink\Core\Model\VisitsParams;

View File

@ -5,12 +5,12 @@ declare(strict_types=1);
namespace ShlinkioTest\Shlink\Rest\Action\Visit;
use Laminas\Diactoros\ServerRequest;
use Laminas\Paginator\Adapter\ArrayAdapter;
use Laminas\Paginator\Paginator;
use Pagerfanta\Adapter\ArrayAdapter;
use PHPUnit\Framework\TestCase;
use Prophecy\Argument;
use Prophecy\PhpUnit\ProphecyTrait;
use Prophecy\Prophecy\ObjectProphecy;
use Shlinkio\Shlink\Common\Paginator\Paginator;
use Shlinkio\Shlink\Core\Model\VisitsParams;
use Shlinkio\Shlink\Core\Service\VisitsTracker;
use Shlinkio\Shlink\Rest\Action\Visit\TagVisitsAction;