diff --git a/module/CLI/src/Command/ShortUrl/ListShortUrlsCommand.php b/module/CLI/src/Command/ShortUrl/ListShortUrlsCommand.php index d7243dfba..72a92fe85 100644 --- a/module/CLI/src/Command/ShortUrl/ListShortUrlsCommand.php +++ b/module/CLI/src/Command/ShortUrl/ListShortUrlsCommand.php @@ -13,7 +13,7 @@ use Shlinkio\Shlink\Core\Domain\Entity\Domain; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlsParams; -use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlWithVisitsSummary; +use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlWithDeps; use Shlinkio\Shlink\Core\ShortUrl\Model\TagsMode; use Shlinkio\Shlink\Core\ShortUrl\Model\Validation\ShortUrlsParamsInputFilter; use Shlinkio\Shlink\Core\ShortUrl\ShortUrlListServiceInterface; @@ -186,7 +186,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int /** * @param array $columnsMap - * @return Paginator + * @return Paginator */ private function renderPage( OutputInterface $output, @@ -196,7 +196,7 @@ private function renderPage( ): Paginator { $shortUrls = $this->shortUrlService->listShortUrls($params); - $rows = map([...$shortUrls], function (ShortUrlWithVisitsSummary $shortUrl) use ($columnsMap) { + $rows = map([...$shortUrls], function (ShortUrlWithDeps $shortUrl) use ($columnsMap) { $serializedShortUrl = $this->transformer->transform($shortUrl); return map($columnsMap, fn (callable $call) => $call($serializedShortUrl, $shortUrl->shortUrl)); }); diff --git a/module/CLI/test/Command/ShortUrl/ListShortUrlsCommandTest.php b/module/CLI/test/Command/ShortUrl/ListShortUrlsCommandTest.php index ccdab8854..41b3fe88d 100644 --- a/module/CLI/test/Command/ShortUrl/ListShortUrlsCommandTest.php +++ b/module/CLI/test/Command/ShortUrl/ListShortUrlsCommandTest.php @@ -16,7 +16,7 @@ use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortUrlStringifier; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlCreation; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlsParams; -use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlWithVisitsSummary; +use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlWithDeps; use Shlinkio\Shlink\Core\ShortUrl\Model\TagsMode; use Shlinkio\Shlink\Core\ShortUrl\ShortUrlListServiceInterface; use Shlinkio\Shlink\Core\ShortUrl\Transformer\ShortUrlDataTransformer; @@ -48,7 +48,7 @@ public function loadingMorePagesCallsListMoreTimes(): void // The paginator will return more than one page $data = []; for ($i = 0; $i < 50; $i++) { - $data[] = ShortUrlWithVisitsSummary::fromShortUrl(ShortUrl::withLongUrl('https://url_' . $i)); + $data[] = ShortUrlWithDeps::fromShortUrl(ShortUrl::withLongUrl('https://url_' . $i)); } $this->shortUrlService->expects($this->exactly(3))->method('listShortUrls')->withAnyParameters() @@ -70,7 +70,7 @@ public function havingMorePagesButAnsweringNoCallsListJustOnce(): void // The paginator will return more than one page $data = []; for ($i = 0; $i < 30; $i++) { - $data[] = ShortUrlWithVisitsSummary::fromShortUrl(ShortUrl::withLongUrl('https://url_' . $i)); + $data[] = ShortUrlWithDeps::fromShortUrl(ShortUrl::withLongUrl('https://url_' . $i)); } $this->shortUrlService->expects($this->once())->method('listShortUrls')->with( @@ -112,7 +112,7 @@ public function provideOptionalFlagsMakesNewColumnsToBeIncluded( $this->shortUrlService->expects($this->once())->method('listShortUrls')->with( ShortUrlsParams::empty(), )->willReturn(new Paginator(new ArrayAdapter([ - ShortUrlWithVisitsSummary::fromShortUrl( + ShortUrlWithDeps::fromShortUrl( ShortUrl::create(ShortUrlCreation::fromRawData([ 'longUrl' => 'https://foo.com', 'tags' => ['foo', 'bar', 'baz'], diff --git a/module/Core/src/ShortUrl/Helper/ShortUrlStringifier.php b/module/Core/src/ShortUrl/Helper/ShortUrlStringifier.php index 6659bc0c0..36dd9a604 100644 --- a/module/Core/src/ShortUrl/Helper/ShortUrlStringifier.php +++ b/module/Core/src/ShortUrl/Helper/ShortUrlStringifier.php @@ -7,6 +7,7 @@ use Laminas\Diactoros\Uri; use Shlinkio\Shlink\Core\Config\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl; +use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlIdentifier; use function sprintf; @@ -18,19 +19,20 @@ public function __construct( ) { } - public function stringify(ShortUrl $shortUrl): string + public function stringify(ShortUrl|ShortUrlIdentifier $shortUrl): string { + $shortUrlIdentifier = $shortUrl instanceof ShortUrl ? ShortUrlIdentifier::fromShortUrl($shortUrl) : $shortUrl; $uriWithoutShortCode = (new Uri())->withScheme($this->urlShortenerOptions->schema) - ->withHost($this->resolveDomain($shortUrl)) + ->withHost($this->resolveDomain($shortUrlIdentifier)) ->withPath($this->basePath) ->__toString(); // The short code needs to be appended to avoid it from being URL-encoded - return sprintf('%s/%s', $uriWithoutShortCode, $shortUrl->getShortCode()); + return sprintf('%s/%s', $uriWithoutShortCode, $shortUrlIdentifier->shortCode); } - private function resolveDomain(ShortUrl $shortUrl): string + private function resolveDomain(ShortUrlIdentifier $shortUrlIdentifier): string { - return $shortUrl->getDomain()?->authority ?? $this->urlShortenerOptions->defaultDomain; + return $shortUrlIdentifier->domain ?? $this->urlShortenerOptions->defaultDomain; } } diff --git a/module/Core/src/ShortUrl/Helper/ShortUrlStringifierInterface.php b/module/Core/src/ShortUrl/Helper/ShortUrlStringifierInterface.php index 0505a6942..0a6f69755 100644 --- a/module/Core/src/ShortUrl/Helper/ShortUrlStringifierInterface.php +++ b/module/Core/src/ShortUrl/Helper/ShortUrlStringifierInterface.php @@ -5,8 +5,9 @@ namespace Shlinkio\Shlink\Core\ShortUrl\Helper; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl; +use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlIdentifier; interface ShortUrlStringifierInterface { - public function stringify(ShortUrl $shortUrl): string; + public function stringify(ShortUrl|ShortUrlIdentifier $shortUrl): string; } diff --git a/module/Core/src/ShortUrl/Model/ShortUrlIdentifier.php b/module/Core/src/ShortUrl/Model/ShortUrlIdentifier.php index ff44ed7fc..9b3014f81 100644 --- a/module/Core/src/ShortUrl/Model/ShortUrlIdentifier.php +++ b/module/Core/src/ShortUrl/Model/ShortUrlIdentifier.php @@ -33,10 +33,8 @@ public static function fromRedirectRequest(ServerRequestInterface $request): sel public static function fromShortUrl(ShortUrl $shortUrl): self { - $domain = $shortUrl->getDomain(); - $domainAuthority = $domain?->authority; - - return new self($shortUrl->getShortCode(), $domainAuthority); + $domain = $shortUrl->getDomain()?->authority; + return new self($shortUrl->getShortCode(), $domain); } public static function fromShortCodeAndDomain(string $shortCode, string|null $domain = null): self diff --git a/module/Core/src/ShortUrl/Model/ShortUrlWithVisitsSummary.php b/module/Core/src/ShortUrl/Model/ShortUrlWithDeps.php similarity index 75% rename from module/Core/src/ShortUrl/Model/ShortUrlWithVisitsSummary.php rename to module/Core/src/ShortUrl/Model/ShortUrlWithDeps.php index d5c34b8b2..4b9b5a705 100644 --- a/module/Core/src/ShortUrl/Model/ShortUrlWithVisitsSummary.php +++ b/module/Core/src/ShortUrl/Model/ShortUrlWithDeps.php @@ -7,12 +7,12 @@ use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl; use Shlinkio\Shlink\Core\Visit\Model\VisitsSummary; -final readonly class ShortUrlWithVisitsSummary +final readonly class ShortUrlWithDeps { private function __construct( public ShortUrl $shortUrl, + private string|null $authority, private VisitsSummary|null $visitsSummary = null, - private string|null $authority = null, ) { } @@ -23,17 +23,22 @@ public static function fromArray(array $data): self { return new self( shortUrl: $data['shortUrl'], + authority: $data['authority'] ?? null, visitsSummary: VisitsSummary::fromTotalAndNonBots( total: (int) $data['visits'], nonBots: (int) $data['nonBotVisits'], ), - authority: $data['authority'] ?? null, ); } public static function fromShortUrl(ShortUrl $shortUrl): self { - return new self($shortUrl); + return new self($shortUrl, authority: $shortUrl->getDomain()?->authority); + } + + public function toIdentifier(): ShortUrlIdentifier + { + return ShortUrlIdentifier::fromShortCodeAndDomain($this->shortUrl->getShortCode(), $this->authority); } public function toArray(): array diff --git a/module/Core/src/ShortUrl/Paginator/Adapter/ShortUrlRepositoryAdapter.php b/module/Core/src/ShortUrl/Paginator/Adapter/ShortUrlRepositoryAdapter.php index 1a7b97de5..4daa5cb96 100644 --- a/module/Core/src/ShortUrl/Paginator/Adapter/ShortUrlRepositoryAdapter.php +++ b/module/Core/src/ShortUrl/Paginator/Adapter/ShortUrlRepositoryAdapter.php @@ -6,13 +6,13 @@ use Pagerfanta\Adapter\AdapterInterface; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlsParams; -use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlWithVisitsSummary; +use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlWithDeps; use Shlinkio\Shlink\Core\ShortUrl\Persistence\ShortUrlsCountFiltering; use Shlinkio\Shlink\Core\ShortUrl\Persistence\ShortUrlsListFiltering; use Shlinkio\Shlink\Core\ShortUrl\Repository\ShortUrlListRepositoryInterface; use Shlinkio\Shlink\Rest\Entity\ApiKey; -/** @implements AdapterInterface */ +/** @implements AdapterInterface */ readonly class ShortUrlRepositoryAdapter implements AdapterInterface { public function __construct( diff --git a/module/Core/src/ShortUrl/Repository/ShortUrlListRepository.php b/module/Core/src/ShortUrl/Repository/ShortUrlListRepository.php index 6749a03f7..c18b31eff 100644 --- a/module/Core/src/ShortUrl/Repository/ShortUrlListRepository.php +++ b/module/Core/src/ShortUrl/Repository/ShortUrlListRepository.php @@ -12,7 +12,7 @@ use Shlinkio\Shlink\Core\Domain\Entity\Domain; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl; use Shlinkio\Shlink\Core\ShortUrl\Model\OrderableField; -use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlWithVisitsSummary; +use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlWithDeps; use Shlinkio\Shlink\Core\ShortUrl\Model\TagsMode; use Shlinkio\Shlink\Core\ShortUrl\Persistence\ShortUrlsCountFiltering; use Shlinkio\Shlink\Core\ShortUrl\Persistence\ShortUrlsListFiltering; @@ -25,7 +25,7 @@ class ShortUrlListRepository extends EntitySpecificationRepository implements ShortUrlListRepositoryInterface { /** - * @return ShortUrlWithVisitsSummary[] + * @return ShortUrlWithDeps[] */ public function findList(ShortUrlsListFiltering $filtering): array { @@ -59,7 +59,7 @@ public function findList(ShortUrlsListFiltering $filtering): array /** @var array{shortUrl: ShortUrl, visits: string, nonBotVisits: string, authority: string|null}[] $result */ $result = $qb->getQuery()->getResult(); - return map($result, static fn (array $s) => ShortUrlWithVisitsSummary::fromArray($s)); + return map($result, static fn (array $s) => ShortUrlWithDeps::fromArray($s)); } private function processOrderByForList(QueryBuilder $qb, ShortUrlsListFiltering $filtering): void diff --git a/module/Core/src/ShortUrl/Repository/ShortUrlListRepositoryInterface.php b/module/Core/src/ShortUrl/Repository/ShortUrlListRepositoryInterface.php index db3f8017d..d71f6297b 100644 --- a/module/Core/src/ShortUrl/Repository/ShortUrlListRepositoryInterface.php +++ b/module/Core/src/ShortUrl/Repository/ShortUrlListRepositoryInterface.php @@ -4,14 +4,14 @@ namespace Shlinkio\Shlink\Core\ShortUrl\Repository; -use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlWithVisitsSummary; +use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlWithDeps; use Shlinkio\Shlink\Core\ShortUrl\Persistence\ShortUrlsCountFiltering; use Shlinkio\Shlink\Core\ShortUrl\Persistence\ShortUrlsListFiltering; interface ShortUrlListRepositoryInterface { /** - * @return ShortUrlWithVisitsSummary[] + * @return ShortUrlWithDeps[] */ public function findList(ShortUrlsListFiltering $filtering): array; diff --git a/module/Core/src/ShortUrl/ShortUrlListServiceInterface.php b/module/Core/src/ShortUrl/ShortUrlListServiceInterface.php index a8b8b2cc8..9ece5cada 100644 --- a/module/Core/src/ShortUrl/ShortUrlListServiceInterface.php +++ b/module/Core/src/ShortUrl/ShortUrlListServiceInterface.php @@ -6,13 +6,13 @@ use Shlinkio\Shlink\Common\Paginator\Paginator; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlsParams; -use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlWithVisitsSummary; +use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlWithDeps; use Shlinkio\Shlink\Rest\Entity\ApiKey; interface ShortUrlListServiceInterface { /** - * @return Paginator + * @return Paginator */ public function listShortUrls(ShortUrlsParams $params, ApiKey|null $apiKey = null): Paginator; } diff --git a/module/Core/src/ShortUrl/Transformer/ShortUrlDataTransformer.php b/module/Core/src/ShortUrl/Transformer/ShortUrlDataTransformer.php index d2bdb73a9..2692f76bb 100644 --- a/module/Core/src/ShortUrl/Transformer/ShortUrlDataTransformer.php +++ b/module/Core/src/ShortUrl/Transformer/ShortUrlDataTransformer.php @@ -6,7 +6,8 @@ use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl; use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortUrlStringifierInterface; -use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlWithVisitsSummary; +use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlIdentifier; +use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlWithDeps; readonly class ShortUrlDataTransformer implements ShortUrlDataTransformerInterface { @@ -14,12 +15,14 @@ public function __construct(private ShortUrlStringifierInterface $stringifier) { } - public function transform(ShortUrlWithVisitsSummary|ShortUrl $data): array + public function transform(ShortUrlWithDeps|ShortUrl $shortUrl): array { - $shortUrl = $data instanceof ShortUrlWithVisitsSummary ? $data->shortUrl : $data; + $shortUrlIdentifier = $shortUrl instanceof ShortUrl + ? ShortUrlIdentifier::fromShortUrl($shortUrl) + : $shortUrl->toIdentifier(); return [ - 'shortUrl' => $this->stringifier->stringify($shortUrl), - ...$data->toArray(), + 'shortUrl' => $this->stringifier->stringify($shortUrlIdentifier), + ...$shortUrl->toArray(), ]; } } diff --git a/module/Core/src/ShortUrl/Transformer/ShortUrlDataTransformerInterface.php b/module/Core/src/ShortUrl/Transformer/ShortUrlDataTransformerInterface.php index e1101f701..cd8aeb370 100644 --- a/module/Core/src/ShortUrl/Transformer/ShortUrlDataTransformerInterface.php +++ b/module/Core/src/ShortUrl/Transformer/ShortUrlDataTransformerInterface.php @@ -5,9 +5,9 @@ namespace Shlinkio\Shlink\Core\ShortUrl\Transformer; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl; -use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlWithVisitsSummary; +use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlWithDeps; interface ShortUrlDataTransformerInterface { - public function transform(ShortUrlWithVisitsSummary|ShortUrl $data): array; + public function transform(ShortUrlWithDeps|ShortUrl $shortUrl): array; } diff --git a/module/Core/test-db/ShortUrl/Repository/ShortUrlListRepositoryTest.php b/module/Core/test-db/ShortUrl/Repository/ShortUrlListRepositoryTest.php index 995f7218a..051093656 100644 --- a/module/Core/test-db/ShortUrl/Repository/ShortUrlListRepositoryTest.php +++ b/module/Core/test-db/ShortUrl/Repository/ShortUrlListRepositoryTest.php @@ -14,7 +14,7 @@ use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl; use Shlinkio\Shlink\Core\ShortUrl\Model\OrderableField; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlCreation; -use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlWithVisitsSummary; +use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlWithDeps; use Shlinkio\Shlink\Core\ShortUrl\Model\TagsMode; use Shlinkio\Shlink\Core\ShortUrl\Persistence\ShortUrlsCountFiltering; use Shlinkio\Shlink\Core\ShortUrl\Persistence\ShortUrlsListFiltering; @@ -97,7 +97,7 @@ public function findListProperlyFiltersResult(): void $result = $this->repo->findList(new ShortUrlsListFiltering(searchTerm: 'bar')); self::assertCount(2, $result); self::assertEquals(2, $this->repo->countList(new ShortUrlsCountFiltering('bar'))); - self::assertContains($foo, map($result, fn (ShortUrlWithVisitsSummary $s) => $s->shortUrl)); + self::assertContains($foo, map($result, fn (ShortUrlWithDeps $s) => $s->shortUrl)); $result = $this->repo->findList(new ShortUrlsListFiltering()); self::assertCount(3, $result);