Update to latest shlink-common and remove deprecation references

This commit is contained in:
Alejandro Celaya 2024-07-29 19:39:31 +02:00
parent 6b0b52853c
commit b52ceaff9a
20 changed files with 62 additions and 83 deletions

View file

@ -44,7 +44,7 @@
"pagerfanta/core": "^3.8", "pagerfanta/core": "^3.8",
"ramsey/uuid": "^4.7", "ramsey/uuid": "^4.7",
"shlinkio/doctrine-specification": "^2.1.1", "shlinkio/doctrine-specification": "^2.1.1",
"shlinkio/shlink-common": "^6.1", "shlinkio/shlink-common": "dev-main#144e5c1 as 6.2",
"shlinkio/shlink-config": "^3.0", "shlinkio/shlink-config": "^3.0",
"shlinkio/shlink-event-dispatcher": "^4.1", "shlinkio/shlink-event-dispatcher": "^4.1",
"shlinkio/shlink-importer": "^5.3.2", "shlinkio/shlink-importer": "^5.3.2",

View file

@ -77,7 +77,7 @@ services:
shlink_db_postgres: shlink_db_postgres:
container_name: shlink_db_postgres container_name: shlink_db_postgres
image: postgres:12.2-alpine image: postgres:16.3-alpine
ports: ports:
- "5434:5432" - "5434:5432"
volumes: volumes:

View file

@ -9,14 +9,14 @@ use Shlinkio\Shlink\CLI\Input\StartDateOption;
use Shlinkio\Shlink\CLI\Util\ExitCode; use Shlinkio\Shlink\CLI\Util\ExitCode;
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\PagerfantaUtils;
use Shlinkio\Shlink\Common\Rest\DataTransformerInterface;
use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlsParams; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlsParams;
use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlWithVisitsSummary; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlWithVisitsSummary;
use Shlinkio\Shlink\Core\ShortUrl\Model\TagsMode; use Shlinkio\Shlink\Core\ShortUrl\Model\TagsMode;
use Shlinkio\Shlink\Core\ShortUrl\Model\Validation\ShortUrlsParamsInputFilter; use Shlinkio\Shlink\Core\ShortUrl\Model\Validation\ShortUrlsParamsInputFilter;
use Shlinkio\Shlink\Core\ShortUrl\ShortUrlListServiceInterface; use Shlinkio\Shlink\Core\ShortUrl\ShortUrlListServiceInterface;
use Shlinkio\Shlink\Core\ShortUrl\Transformer\ShortUrlDataTransformerInterface;
use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputOption;
@ -32,8 +32,6 @@ use function sprintf;
class ListShortUrlsCommand extends Command class ListShortUrlsCommand extends Command
{ {
use PagerfantaUtilsTrait;
public const NAME = 'short-url:list'; public const NAME = 'short-url:list';
private readonly StartDateOption $startDateOption; private readonly StartDateOption $startDateOption;
@ -41,7 +39,7 @@ class ListShortUrlsCommand extends Command
public function __construct( public function __construct(
private readonly ShortUrlListServiceInterface $shortUrlService, private readonly ShortUrlListServiceInterface $shortUrlService,
private readonly DataTransformerInterface $transformer, private readonly ShortUrlDataTransformerInterface $transformer,
) { ) {
parent::__construct(); parent::__construct();
$this->startDateOption = new StartDateOption($this, 'short URLs'); $this->startDateOption = new StartDateOption($this, 'short URLs');
@ -196,7 +194,7 @@ class ListShortUrlsCommand extends Command
ShlinkTable::default($output)->render( ShlinkTable::default($output)->render(
array_keys($columnsMap), array_keys($columnsMap),
$rows, $rows,
$all ? null : $this->formatCurrentPageMessage($shortUrls, 'Page %s of %s'), $all ? null : PagerfantaUtils::formatCurrentPageMessage($shortUrls, 'Page %s of %s'),
); );
return $shortUrls; return $shortUrls;

View file

@ -4,14 +4,14 @@ declare(strict_types=1);
namespace Shlinkio\Shlink\Core\EventDispatcher; namespace Shlinkio\Shlink\Core\EventDispatcher;
use Shlinkio\Shlink\Common\Rest\DataTransformerInterface;
use Shlinkio\Shlink\Common\UpdatePublishing\Update; use Shlinkio\Shlink\Common\UpdatePublishing\Update;
use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
use Shlinkio\Shlink\Core\ShortUrl\Transformer\ShortUrlDataTransformerInterface;
use Shlinkio\Shlink\Core\Visit\Entity\Visit; use Shlinkio\Shlink\Core\Visit\Entity\Visit;
final readonly class PublishingUpdatesGenerator implements PublishingUpdatesGeneratorInterface final readonly class PublishingUpdatesGenerator implements PublishingUpdatesGeneratorInterface
{ {
public function __construct(private DataTransformerInterface $shortUrlTransformer) public function __construct(private ShortUrlDataTransformerInterface $shortUrlTransformer)
{ {
} }

View file

@ -4,24 +4,17 @@ declare(strict_types=1);
namespace Shlinkio\Shlink\Core\ShortUrl\Transformer; namespace Shlinkio\Shlink\Core\ShortUrl\Transformer;
use Shlinkio\Shlink\Common\Rest\DataTransformerInterface;
use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortUrlStringifierInterface; use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortUrlStringifierInterface;
use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlWithVisitsSummary; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlWithVisitsSummary;
/** readonly class ShortUrlDataTransformer implements ShortUrlDataTransformerInterface
* @fixme Do not implement DataTransformerInterface, but a separate interface
*/
readonly class ShortUrlDataTransformer implements DataTransformerInterface
{ {
public function __construct(private ShortUrlStringifierInterface $stringifier) public function __construct(private ShortUrlStringifierInterface $stringifier)
{ {
} }
/** public function transform(ShortUrlWithVisitsSummary|ShortUrl $data): array
* @param ShortUrlWithVisitsSummary|ShortUrl $data
*/
public function transform($data): array // phpcs:ignore
{ {
$shortUrl = $data instanceof ShortUrlWithVisitsSummary ? $data->shortUrl : $data; $shortUrl = $data instanceof ShortUrlWithVisitsSummary ? $data->shortUrl : $data;
return [ return [

View file

@ -0,0 +1,13 @@
<?php
declare(strict_types=1);
namespace Shlinkio\Shlink\Core\ShortUrl\Transformer;
use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlWithVisitsSummary;
interface ShortUrlDataTransformerInterface
{
public function transform(ShortUrlWithVisitsSummary|ShortUrl $data): array;
}

View file

@ -7,10 +7,10 @@ namespace Shlinkio\Shlink\Rest\Action\ShortUrl;
use Laminas\Diactoros\Response\JsonResponse; use Laminas\Diactoros\Response\JsonResponse;
use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request; use Psr\Http\Message\ServerRequestInterface as Request;
use Shlinkio\Shlink\Common\Rest\DataTransformerInterface;
use Shlinkio\Shlink\Core\Exception\ValidationException; use Shlinkio\Shlink\Core\Exception\ValidationException;
use Shlinkio\Shlink\Core\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\Options\UrlShortenerOptions;
use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlCreation; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlCreation;
use Shlinkio\Shlink\Core\ShortUrl\Transformer\ShortUrlDataTransformerInterface;
use Shlinkio\Shlink\Core\ShortUrl\UrlShortenerInterface; use Shlinkio\Shlink\Core\ShortUrl\UrlShortenerInterface;
use Shlinkio\Shlink\Rest\Action\AbstractRestAction; use Shlinkio\Shlink\Rest\Action\AbstractRestAction;
@ -18,7 +18,7 @@ abstract class AbstractCreateShortUrlAction extends AbstractRestAction
{ {
public function __construct( public function __construct(
private readonly UrlShortenerInterface $urlShortener, private readonly UrlShortenerInterface $urlShortener,
private readonly DataTransformerInterface $transformer, private readonly ShortUrlDataTransformerInterface $transformer,
protected readonly UrlShortenerOptions $urlShortenerOptions, protected readonly UrlShortenerOptions $urlShortenerOptions,
) { ) {
} }

View file

@ -7,10 +7,10 @@ namespace Shlinkio\Shlink\Rest\Action\ShortUrl;
use Laminas\Diactoros\Response\JsonResponse; use Laminas\Diactoros\Response\JsonResponse;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
use Shlinkio\Shlink\Common\Rest\DataTransformerInterface;
use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlEdition; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlEdition;
use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlIdentifier; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlIdentifier;
use Shlinkio\Shlink\Core\ShortUrl\ShortUrlServiceInterface; use Shlinkio\Shlink\Core\ShortUrl\ShortUrlServiceInterface;
use Shlinkio\Shlink\Core\ShortUrl\Transformer\ShortUrlDataTransformerInterface;
use Shlinkio\Shlink\Rest\Action\AbstractRestAction; use Shlinkio\Shlink\Rest\Action\AbstractRestAction;
use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware; use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware;
@ -21,7 +21,7 @@ class EditShortUrlAction extends AbstractRestAction
public function __construct( public function __construct(
private readonly ShortUrlServiceInterface $shortUrlService, private readonly ShortUrlServiceInterface $shortUrlService,
private readonly DataTransformerInterface $transformer, private readonly ShortUrlDataTransformerInterface $transformer,
) { ) {
} }

View file

@ -7,23 +7,21 @@ namespace Shlinkio\Shlink\Rest\Action\ShortUrl;
use Laminas\Diactoros\Response\JsonResponse; use Laminas\Diactoros\Response\JsonResponse;
use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request; use Psr\Http\Message\ServerRequestInterface as Request;
use Shlinkio\Shlink\Common\Paginator\Util\PagerfantaUtilsTrait; use Shlinkio\Shlink\Common\Paginator\Util\PagerfantaUtils;
use Shlinkio\Shlink\Common\Rest\DataTransformerInterface;
use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlsParams; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlsParams;
use Shlinkio\Shlink\Core\ShortUrl\ShortUrlListServiceInterface; use Shlinkio\Shlink\Core\ShortUrl\ShortUrlListServiceInterface;
use Shlinkio\Shlink\Core\ShortUrl\Transformer\ShortUrlDataTransformerInterface;
use Shlinkio\Shlink\Rest\Action\AbstractRestAction; use Shlinkio\Shlink\Rest\Action\AbstractRestAction;
use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware; use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware;
class ListShortUrlsAction extends AbstractRestAction class ListShortUrlsAction extends AbstractRestAction
{ {
use PagerfantaUtilsTrait;
protected const ROUTE_PATH = '/short-urls'; protected const ROUTE_PATH = '/short-urls';
protected const ROUTE_ALLOWED_METHODS = [self::METHOD_GET]; protected const ROUTE_ALLOWED_METHODS = [self::METHOD_GET];
public function __construct( public function __construct(
private readonly ShortUrlListServiceInterface $shortUrlService, private readonly ShortUrlListServiceInterface $shortUrlService,
private readonly DataTransformerInterface $transformer, private readonly ShortUrlDataTransformerInterface $transformer,
) { ) {
} }
@ -33,6 +31,8 @@ class ListShortUrlsAction extends AbstractRestAction
ShortUrlsParams::fromRawData($request->getQueryParams()), ShortUrlsParams::fromRawData($request->getQueryParams()),
AuthenticationMiddleware::apiKeyFromRequest($request), AuthenticationMiddleware::apiKeyFromRequest($request),
); );
return new JsonResponse(['shortUrls' => $this->serializePaginator($shortUrls, $this->transformer)]); return new JsonResponse([
'shortUrls' => PagerfantaUtils::serializePaginator($shortUrls, $this->transformer->transform(...)),
]);
} }
} }

View file

@ -7,9 +7,9 @@ namespace Shlinkio\Shlink\Rest\Action\ShortUrl;
use Laminas\Diactoros\Response\JsonResponse; use Laminas\Diactoros\Response\JsonResponse;
use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request; use Psr\Http\Message\ServerRequestInterface as Request;
use Shlinkio\Shlink\Common\Rest\DataTransformerInterface;
use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlIdentifier; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlIdentifier;
use Shlinkio\Shlink\Core\ShortUrl\ShortUrlResolverInterface; use Shlinkio\Shlink\Core\ShortUrl\ShortUrlResolverInterface;
use Shlinkio\Shlink\Core\ShortUrl\Transformer\ShortUrlDataTransformerInterface;
use Shlinkio\Shlink\Rest\Action\AbstractRestAction; use Shlinkio\Shlink\Rest\Action\AbstractRestAction;
use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware; use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware;
@ -20,7 +20,7 @@ class ResolveShortUrlAction extends AbstractRestAction
public function __construct( public function __construct(
private readonly ShortUrlResolverInterface $urlResolver, private readonly ShortUrlResolverInterface $urlResolver,
private readonly DataTransformerInterface $transformer, private readonly ShortUrlDataTransformerInterface $transformer,
) { ) {
} }

View file

@ -7,7 +7,7 @@ namespace Shlinkio\Shlink\Rest\Action\Tag;
use Laminas\Diactoros\Response\JsonResponse; use Laminas\Diactoros\Response\JsonResponse;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
use Shlinkio\Shlink\Common\Paginator\Util\PagerfantaUtilsTrait; use Shlinkio\Shlink\Common\Paginator\Util\PagerfantaUtils;
use Shlinkio\Shlink\Core\Tag\Model\TagsParams; use Shlinkio\Shlink\Core\Tag\Model\TagsParams;
use Shlinkio\Shlink\Core\Tag\TagServiceInterface; use Shlinkio\Shlink\Core\Tag\TagServiceInterface;
use Shlinkio\Shlink\Rest\Action\AbstractRestAction; use Shlinkio\Shlink\Rest\Action\AbstractRestAction;
@ -15,12 +15,10 @@ use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware;
class ListTagsAction extends AbstractRestAction class ListTagsAction extends AbstractRestAction
{ {
use PagerfantaUtilsTrait;
protected const ROUTE_PATH = '/tags'; protected const ROUTE_PATH = '/tags';
protected const ROUTE_ALLOWED_METHODS = [self::METHOD_GET]; protected const ROUTE_ALLOWED_METHODS = [self::METHOD_GET];
public function __construct(private TagServiceInterface $tagService) public function __construct(private readonly TagServiceInterface $tagService)
{ {
} }
@ -30,7 +28,7 @@ class ListTagsAction extends AbstractRestAction
$apiKey = AuthenticationMiddleware::apiKeyFromRequest($request); $apiKey = AuthenticationMiddleware::apiKeyFromRequest($request);
return new JsonResponse([ return new JsonResponse([
'tags' => $this->serializePaginator($this->tagService->listTags($params, $apiKey)), 'tags' => PagerfantaUtils::serializePaginator($this->tagService->listTags($params, $apiKey)),
]); ]);
} }
} }

View file

@ -7,7 +7,7 @@ namespace Shlinkio\Shlink\Rest\Action\Tag;
use Laminas\Diactoros\Response\JsonResponse; use Laminas\Diactoros\Response\JsonResponse;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
use Shlinkio\Shlink\Common\Paginator\Util\PagerfantaUtilsTrait; use Shlinkio\Shlink\Common\Paginator\Util\PagerfantaUtils;
use Shlinkio\Shlink\Core\Tag\Model\TagsParams; use Shlinkio\Shlink\Core\Tag\Model\TagsParams;
use Shlinkio\Shlink\Core\Tag\TagServiceInterface; use Shlinkio\Shlink\Core\Tag\TagServiceInterface;
use Shlinkio\Shlink\Rest\Action\AbstractRestAction; use Shlinkio\Shlink\Rest\Action\AbstractRestAction;
@ -15,8 +15,6 @@ use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware;
class TagsStatsAction extends AbstractRestAction class TagsStatsAction extends AbstractRestAction
{ {
use PagerfantaUtilsTrait;
protected const ROUTE_PATH = '/tags/stats'; protected const ROUTE_PATH = '/tags/stats';
protected const ROUTE_ALLOWED_METHODS = [self::METHOD_GET]; protected const ROUTE_ALLOWED_METHODS = [self::METHOD_GET];
@ -30,6 +28,6 @@ class TagsStatsAction extends AbstractRestAction
$apiKey = AuthenticationMiddleware::apiKeyFromRequest($request); $apiKey = AuthenticationMiddleware::apiKeyFromRequest($request);
$tagsInfo = $this->tagService->tagsInfo($params, $apiKey); $tagsInfo = $this->tagService->tagsInfo($params, $apiKey);
return new JsonResponse(['tags' => $this->serializePaginator($tagsInfo)]); return new JsonResponse(['tags' => PagerfantaUtils::serializePaginator($tagsInfo)]);
} }
} }

View file

@ -7,15 +7,12 @@ namespace Shlinkio\Shlink\Rest\Action\Visit;
use Laminas\Diactoros\Response\JsonResponse; use Laminas\Diactoros\Response\JsonResponse;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
use Shlinkio\Shlink\Common\Paginator\Util\PagerfantaUtilsTrait;
use Shlinkio\Shlink\Core\Visit\VisitsDeleterInterface; use Shlinkio\Shlink\Core\Visit\VisitsDeleterInterface;
use Shlinkio\Shlink\Rest\Action\AbstractRestAction; use Shlinkio\Shlink\Rest\Action\AbstractRestAction;
use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware; use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware;
class DeleteOrphanVisitsAction extends AbstractRestAction class DeleteOrphanVisitsAction extends AbstractRestAction
{ {
use PagerfantaUtilsTrait;
protected const ROUTE_PATH = '/visits/orphan'; protected const ROUTE_PATH = '/visits/orphan';
protected const ROUTE_ALLOWED_METHODS = [self::METHOD_DELETE]; protected const ROUTE_ALLOWED_METHODS = [self::METHOD_DELETE];

View file

@ -7,7 +7,7 @@ namespace Shlinkio\Shlink\Rest\Action\Visit;
use Laminas\Diactoros\Response\JsonResponse; use Laminas\Diactoros\Response\JsonResponse;
use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request; use Psr\Http\Message\ServerRequestInterface as Request;
use Shlinkio\Shlink\Common\Paginator\Util\PagerfantaUtilsTrait; use Shlinkio\Shlink\Common\Paginator\Util\PagerfantaUtils;
use Shlinkio\Shlink\Core\Visit\Model\VisitsParams; use Shlinkio\Shlink\Core\Visit\Model\VisitsParams;
use Shlinkio\Shlink\Core\Visit\VisitsStatsHelperInterface; use Shlinkio\Shlink\Core\Visit\VisitsStatsHelperInterface;
use Shlinkio\Shlink\Rest\Action\AbstractRestAction; use Shlinkio\Shlink\Rest\Action\AbstractRestAction;
@ -15,13 +15,13 @@ use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware;
class DomainVisitsAction extends AbstractRestAction class DomainVisitsAction extends AbstractRestAction
{ {
use PagerfantaUtilsTrait;
protected const ROUTE_PATH = '/domains/{domain}/visits'; protected const ROUTE_PATH = '/domains/{domain}/visits';
protected const ROUTE_ALLOWED_METHODS = [self::METHOD_GET]; protected const ROUTE_ALLOWED_METHODS = [self::METHOD_GET];
public function __construct(private VisitsStatsHelperInterface $visitsHelper, private string $defaultDomain) public function __construct(
{ private readonly VisitsStatsHelperInterface $visitsHelper,
private readonly string $defaultDomain,
) {
} }
public function handle(Request $request): Response public function handle(Request $request): Response
@ -31,9 +31,7 @@ class DomainVisitsAction extends AbstractRestAction
$apiKey = AuthenticationMiddleware::apiKeyFromRequest($request); $apiKey = AuthenticationMiddleware::apiKeyFromRequest($request);
$visits = $this->visitsHelper->visitsForDomain($domain, $params, $apiKey); $visits = $this->visitsHelper->visitsForDomain($domain, $params, $apiKey);
return new JsonResponse([ return new JsonResponse(['visits' => PagerfantaUtils::serializePaginator($visits)]);
'visits' => $this->serializePaginator($visits),
]);
} }
private function resolveDomainParam(Request $request): string private function resolveDomainParam(Request $request): string

View file

@ -7,7 +7,7 @@ namespace Shlinkio\Shlink\Rest\Action\Visit;
use Laminas\Diactoros\Response\JsonResponse; use Laminas\Diactoros\Response\JsonResponse;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
use Shlinkio\Shlink\Common\Paginator\Util\PagerfantaUtilsTrait; use Shlinkio\Shlink\Common\Paginator\Util\PagerfantaUtils;
use Shlinkio\Shlink\Core\Visit\Model\VisitsParams; use Shlinkio\Shlink\Core\Visit\Model\VisitsParams;
use Shlinkio\Shlink\Core\Visit\VisitsStatsHelperInterface; use Shlinkio\Shlink\Core\Visit\VisitsStatsHelperInterface;
use Shlinkio\Shlink\Rest\Action\AbstractRestAction; use Shlinkio\Shlink\Rest\Action\AbstractRestAction;
@ -15,12 +15,10 @@ use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware;
class NonOrphanVisitsAction extends AbstractRestAction class NonOrphanVisitsAction extends AbstractRestAction
{ {
use PagerfantaUtilsTrait;
protected const ROUTE_PATH = '/visits/non-orphan'; protected const ROUTE_PATH = '/visits/non-orphan';
protected const ROUTE_ALLOWED_METHODS = [self::METHOD_GET]; protected const ROUTE_ALLOWED_METHODS = [self::METHOD_GET];
public function __construct(private VisitsStatsHelperInterface $visitsHelper) public function __construct(private readonly VisitsStatsHelperInterface $visitsHelper)
{ {
} }
@ -30,8 +28,6 @@ class NonOrphanVisitsAction extends AbstractRestAction
$apiKey = AuthenticationMiddleware::apiKeyFromRequest($request); $apiKey = AuthenticationMiddleware::apiKeyFromRequest($request);
$visits = $this->visitsHelper->nonOrphanVisits($params, $apiKey); $visits = $this->visitsHelper->nonOrphanVisits($params, $apiKey);
return new JsonResponse([ return new JsonResponse(['visits' => PagerfantaUtils::serializePaginator($visits)]);
'visits' => $this->serializePaginator($visits),
]);
} }
} }

View file

@ -7,7 +7,7 @@ namespace Shlinkio\Shlink\Rest\Action\Visit;
use Laminas\Diactoros\Response\JsonResponse; use Laminas\Diactoros\Response\JsonResponse;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
use Shlinkio\Shlink\Common\Paginator\Util\PagerfantaUtilsTrait; use Shlinkio\Shlink\Common\Paginator\Util\PagerfantaUtils;
use Shlinkio\Shlink\Core\Visit\Model\OrphanVisitsParams; use Shlinkio\Shlink\Core\Visit\Model\OrphanVisitsParams;
use Shlinkio\Shlink\Core\Visit\VisitsStatsHelperInterface; use Shlinkio\Shlink\Core\Visit\VisitsStatsHelperInterface;
use Shlinkio\Shlink\Rest\Action\AbstractRestAction; use Shlinkio\Shlink\Rest\Action\AbstractRestAction;
@ -15,8 +15,6 @@ use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware;
class OrphanVisitsAction extends AbstractRestAction class OrphanVisitsAction extends AbstractRestAction
{ {
use PagerfantaUtilsTrait;
protected const ROUTE_PATH = '/visits/orphan'; protected const ROUTE_PATH = '/visits/orphan';
protected const ROUTE_ALLOWED_METHODS = [self::METHOD_GET]; protected const ROUTE_ALLOWED_METHODS = [self::METHOD_GET];
@ -30,8 +28,6 @@ class OrphanVisitsAction extends AbstractRestAction
$apiKey = AuthenticationMiddleware::apiKeyFromRequest($request); $apiKey = AuthenticationMiddleware::apiKeyFromRequest($request);
$visits = $this->visitsHelper->orphanVisits($params, $apiKey); $visits = $this->visitsHelper->orphanVisits($params, $apiKey);
return new JsonResponse([ return new JsonResponse(['visits' => PagerfantaUtils::serializePaginator($visits)]);
'visits' => $this->serializePaginator($visits),
]);
} }
} }

View file

@ -7,7 +7,7 @@ namespace Shlinkio\Shlink\Rest\Action\Visit;
use Laminas\Diactoros\Response\JsonResponse; use Laminas\Diactoros\Response\JsonResponse;
use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request; use Psr\Http\Message\ServerRequestInterface as Request;
use Shlinkio\Shlink\Common\Paginator\Util\PagerfantaUtilsTrait; use Shlinkio\Shlink\Common\Paginator\Util\PagerfantaUtils;
use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlIdentifier; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlIdentifier;
use Shlinkio\Shlink\Core\Visit\Model\VisitsParams; use Shlinkio\Shlink\Core\Visit\Model\VisitsParams;
use Shlinkio\Shlink\Core\Visit\VisitsStatsHelperInterface; use Shlinkio\Shlink\Core\Visit\VisitsStatsHelperInterface;
@ -16,12 +16,10 @@ use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware;
class ShortUrlVisitsAction extends AbstractRestAction class ShortUrlVisitsAction extends AbstractRestAction
{ {
use PagerfantaUtilsTrait;
protected const ROUTE_PATH = '/short-urls/{shortCode}/visits'; protected const ROUTE_PATH = '/short-urls/{shortCode}/visits';
protected const ROUTE_ALLOWED_METHODS = [self::METHOD_GET]; protected const ROUTE_ALLOWED_METHODS = [self::METHOD_GET];
public function __construct(private VisitsStatsHelperInterface $visitsHelper) public function __construct(private readonly VisitsStatsHelperInterface $visitsHelper)
{ {
} }
@ -32,8 +30,6 @@ class ShortUrlVisitsAction extends AbstractRestAction
$apiKey = AuthenticationMiddleware::apiKeyFromRequest($request); $apiKey = AuthenticationMiddleware::apiKeyFromRequest($request);
$visits = $this->visitsHelper->visitsForShortUrl($identifier, $params, $apiKey); $visits = $this->visitsHelper->visitsForShortUrl($identifier, $params, $apiKey);
return new JsonResponse([ return new JsonResponse(['visits' => PagerfantaUtils::serializePaginator($visits)]);
'visits' => $this->serializePaginator($visits),
]);
} }
} }

View file

@ -7,7 +7,7 @@ namespace Shlinkio\Shlink\Rest\Action\Visit;
use Laminas\Diactoros\Response\JsonResponse; use Laminas\Diactoros\Response\JsonResponse;
use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request; use Psr\Http\Message\ServerRequestInterface as Request;
use Shlinkio\Shlink\Common\Paginator\Util\PagerfantaUtilsTrait; use Shlinkio\Shlink\Common\Paginator\Util\PagerfantaUtils;
use Shlinkio\Shlink\Core\Visit\Model\VisitsParams; use Shlinkio\Shlink\Core\Visit\Model\VisitsParams;
use Shlinkio\Shlink\Core\Visit\VisitsStatsHelperInterface; use Shlinkio\Shlink\Core\Visit\VisitsStatsHelperInterface;
use Shlinkio\Shlink\Rest\Action\AbstractRestAction; use Shlinkio\Shlink\Rest\Action\AbstractRestAction;
@ -15,12 +15,10 @@ use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware;
class TagVisitsAction extends AbstractRestAction class TagVisitsAction extends AbstractRestAction
{ {
use PagerfantaUtilsTrait;
protected const ROUTE_PATH = '/tags/{tag}/visits'; protected const ROUTE_PATH = '/tags/{tag}/visits';
protected const ROUTE_ALLOWED_METHODS = [self::METHOD_GET]; protected const ROUTE_ALLOWED_METHODS = [self::METHOD_GET];
public function __construct(private VisitsStatsHelperInterface $visitsHelper) public function __construct(private readonly VisitsStatsHelperInterface $visitsHelper)
{ {
} }
@ -31,8 +29,6 @@ class TagVisitsAction extends AbstractRestAction
$apiKey = AuthenticationMiddleware::apiKeyFromRequest($request); $apiKey = AuthenticationMiddleware::apiKeyFromRequest($request);
$visits = $this->visitsHelper->visitsForTag($tag, $params, $apiKey); $visits = $this->visitsHelper->visitsForTag($tag, $params, $apiKey);
return new JsonResponse([ return new JsonResponse(['visits' => PagerfantaUtils::serializePaginator($visits)]);
'visits' => $this->serializePaginator($visits),
]);
} }
} }

View file

@ -12,12 +12,12 @@ use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
use Shlinkio\Shlink\Common\Rest\DataTransformerInterface;
use Shlinkio\Shlink\Core\Exception\ValidationException; use Shlinkio\Shlink\Core\Exception\ValidationException;
use Shlinkio\Shlink\Core\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\Options\UrlShortenerOptions;
use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlCreation; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlCreation;
use Shlinkio\Shlink\Core\ShortUrl\Model\UrlShorteningResult; use Shlinkio\Shlink\Core\ShortUrl\Model\UrlShorteningResult;
use Shlinkio\Shlink\Core\ShortUrl\Transformer\ShortUrlDataTransformerInterface;
use Shlinkio\Shlink\Core\ShortUrl\UrlShortener; use Shlinkio\Shlink\Core\ShortUrl\UrlShortener;
use Shlinkio\Shlink\Rest\Action\ShortUrl\CreateShortUrlAction; use Shlinkio\Shlink\Rest\Action\ShortUrl\CreateShortUrlAction;
use Shlinkio\Shlink\Rest\Entity\ApiKey; use Shlinkio\Shlink\Rest\Entity\ApiKey;
@ -26,12 +26,12 @@ class CreateShortUrlActionTest extends TestCase
{ {
private CreateShortUrlAction $action; private CreateShortUrlAction $action;
private MockObject & UrlShortener $urlShortener; private MockObject & UrlShortener $urlShortener;
private MockObject & DataTransformerInterface $transformer; private MockObject & ShortUrlDataTransformerInterface $transformer;
protected function setUp(): void protected function setUp(): void
{ {
$this->urlShortener = $this->createMock(UrlShortener::class); $this->urlShortener = $this->createMock(UrlShortener::class);
$this->transformer = $this->createMock(DataTransformerInterface::class); $this->transformer = $this->createMock(ShortUrlDataTransformerInterface::class);
$this->action = new CreateShortUrlAction($this->urlShortener, $this->transformer, new UrlShortenerOptions()); $this->action = new CreateShortUrlAction($this->urlShortener, $this->transformer, new UrlShortenerOptions());
} }

View file

@ -8,11 +8,11 @@ use Laminas\Diactoros\ServerRequest;
use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
use Shlinkio\Shlink\Common\Rest\DataTransformerInterface;
use Shlinkio\Shlink\Core\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\Options\UrlShortenerOptions;
use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlCreation; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlCreation;
use Shlinkio\Shlink\Core\ShortUrl\Model\UrlShorteningResult; use Shlinkio\Shlink\Core\ShortUrl\Model\UrlShorteningResult;
use Shlinkio\Shlink\Core\ShortUrl\Transformer\ShortUrlDataTransformerInterface;
use Shlinkio\Shlink\Core\ShortUrl\UrlShortenerInterface; use Shlinkio\Shlink\Core\ShortUrl\UrlShortenerInterface;
use Shlinkio\Shlink\Rest\Action\ShortUrl\SingleStepCreateShortUrlAction; use Shlinkio\Shlink\Rest\Action\ShortUrl\SingleStepCreateShortUrlAction;
use Shlinkio\Shlink\Rest\Entity\ApiKey; use Shlinkio\Shlink\Rest\Entity\ApiKey;
@ -25,7 +25,7 @@ class SingleStepCreateShortUrlActionTest extends TestCase
protected function setUp(): void protected function setUp(): void
{ {
$this->urlShortener = $this->createMock(UrlShortenerInterface::class); $this->urlShortener = $this->createMock(UrlShortenerInterface::class);
$transformer = $this->createMock(DataTransformerInterface::class); $transformer = $this->createMock(ShortUrlDataTransformerInterface::class);
$transformer->method('transform')->willReturn([]); $transformer->method('transform')->willReturn([]);
$this->action = new SingleStepCreateShortUrlAction( $this->action = new SingleStepCreateShortUrlAction(