Skip to content

Commit

Permalink
Reduce duplication in actions listing visits
Browse files Browse the repository at this point in the history
  • Loading branch information
acelaya committed Nov 20, 2024
1 parent 0c75202 commit d5de747
Show file tree
Hide file tree
Showing 9 changed files with 87 additions and 87 deletions.
8 changes: 6 additions & 2 deletions module/Core/src/Visit/Model/OrphanVisitsParams.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,13 @@ public function __construct(
parent::__construct($dateRange, $page, $itemsPerPage, $excludeBots);
}

public static function fromRawData(array $query): self
public static function empty(): self
{
return new self();
}

public static function fromVisitsParamsAndRawData(VisitsParams $visitsParams, array $query): self
{
$visitsParams = parent::fromRawData($query);
$type = $query['type'] ?? null;

return new self(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class OrphanVisitsPaginatorAdapterTest extends TestCase
protected function setUp(): void
{
$this->repo = $this->createMock(VisitRepositoryInterface::class);
$this->params = OrphanVisitsParams::fromRawData([]);
$this->params = OrphanVisitsParams::empty();
$this->apiKey = ApiKey::create();

$this->adapter = new OrphanVisitsPaginatorAdapter($this->repo, $this->params, $this->apiKey);
Expand Down
2 changes: 1 addition & 1 deletion module/Core/test/Visit/VisitsStatsHelperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ public function orphanVisitsAreReturnedAsExpected(): void
)->willReturn($list);
$this->em->expects($this->once())->method('getRepository')->with(Visit::class)->willReturn($repo);

$paginator = $this->helper->orphanVisits(new OrphanVisitsParams());
$paginator = $this->helper->orphanVisits(OrphanVisitsParams::empty());

self::assertEquals($list, ArrayUtils::iteratorToArray($paginator->getCurrentPageResults()));
}
Expand Down
42 changes: 42 additions & 0 deletions module/Rest/src/Action/Visit/AbstractListVisitsAction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

declare(strict_types=1);

namespace Shlinkio\Shlink\Rest\Action\Visit;

use Laminas\Diactoros\Response\JsonResponse;
use Pagerfanta\Pagerfanta;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Shlinkio\Shlink\Common\Paginator\Util\PagerfantaUtils;
use Shlinkio\Shlink\Core\Visit\Entity\Visit;
use Shlinkio\Shlink\Core\Visit\Model\VisitsParams;
use Shlinkio\Shlink\Core\Visit\VisitsStatsHelperInterface;
use Shlinkio\Shlink\Rest\Action\AbstractRestAction;
use Shlinkio\Shlink\Rest\Entity\ApiKey;
use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware;

abstract class AbstractListVisitsAction extends AbstractRestAction
{
public function __construct(protected readonly VisitsStatsHelperInterface $visitsHelper)
{
}

public function handle(ServerRequestInterface $request): ResponseInterface
{
$params = VisitsParams::fromRawData($request->getQueryParams());
$apiKey = AuthenticationMiddleware::apiKeyFromRequest($request);
$visits = $this->getVisitsPaginator($request, $params, $apiKey);

return new JsonResponse(['visits' => PagerfantaUtils::serializePaginator($visits)]);
}

/**
* @return Pagerfanta<Visit>
*/
abstract protected function getVisitsPaginator(
ServerRequestInterface $request,
VisitsParams $params,
ApiKey $apiKey,
): Pagerfanta;
}
20 changes: 7 additions & 13 deletions module/Rest/src/Action/Visit/DomainVisitsAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,30 @@

namespace Shlinkio\Shlink\Rest\Action\Visit;

use Laminas\Diactoros\Response\JsonResponse;
use Psr\Http\Message\ResponseInterface as Response;
use Pagerfanta\Pagerfanta;
use Psr\Http\Message\ServerRequestInterface as Request;
use Shlinkio\Shlink\Common\Paginator\Util\PagerfantaUtils;
use Shlinkio\Shlink\Core\Config\Options\UrlShortenerOptions;
use Shlinkio\Shlink\Core\Domain\Entity\Domain;
use Shlinkio\Shlink\Core\Visit\Model\VisitsParams;
use Shlinkio\Shlink\Core\Visit\VisitsStatsHelperInterface;
use Shlinkio\Shlink\Rest\Action\AbstractRestAction;
use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware;
use Shlinkio\Shlink\Rest\Entity\ApiKey;

class DomainVisitsAction extends AbstractRestAction
class DomainVisitsAction extends AbstractListVisitsAction
{
protected const ROUTE_PATH = '/domains/{domain}/visits';
protected const ROUTE_ALLOWED_METHODS = [self::METHOD_GET];

public function __construct(
private readonly VisitsStatsHelperInterface $visitsHelper,
VisitsStatsHelperInterface $visitsHelper,
private readonly UrlShortenerOptions $urlShortenerOptions,
) {
parent::__construct($visitsHelper);
}

public function handle(Request $request): Response
protected function getVisitsPaginator(Request $request, VisitsParams $params, ApiKey $apiKey): Pagerfanta
{
$domain = $this->resolveDomainParam($request);
$params = VisitsParams::fromRawData($request->getQueryParams());
$apiKey = AuthenticationMiddleware::apiKeyFromRequest($request);
$visits = $this->visitsHelper->visitsForDomain($domain, $params, $apiKey);

return new JsonResponse(['visits' => PagerfantaUtils::serializePaginator($visits)]);
return $this->visitsHelper->visitsForDomain($domain, $params, $apiKey);
}

private function resolveDomainParam(Request $request): string
Expand Down
27 changes: 9 additions & 18 deletions module/Rest/src/Action/Visit/NonOrphanVisitsAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,21 @@

namespace Shlinkio\Shlink\Rest\Action\Visit;

use Laminas\Diactoros\Response\JsonResponse;
use Psr\Http\Message\ResponseInterface;
use Pagerfanta\Pagerfanta;
use Psr\Http\Message\ServerRequestInterface;
use Shlinkio\Shlink\Common\Paginator\Util\PagerfantaUtils;
use Shlinkio\Shlink\Core\Visit\Model\VisitsParams;
use Shlinkio\Shlink\Core\Visit\VisitsStatsHelperInterface;
use Shlinkio\Shlink\Rest\Action\AbstractRestAction;
use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware;
use Shlinkio\Shlink\Rest\Entity\ApiKey;

class NonOrphanVisitsAction extends AbstractRestAction
class NonOrphanVisitsAction extends AbstractListVisitsAction
{
protected const ROUTE_PATH = '/visits/non-orphan';
protected const ROUTE_ALLOWED_METHODS = [self::METHOD_GET];

public function __construct(private readonly VisitsStatsHelperInterface $visitsHelper)
{
}

public function handle(ServerRequestInterface $request): ResponseInterface
{
$params = VisitsParams::fromRawData($request->getQueryParams());
$apiKey = AuthenticationMiddleware::apiKeyFromRequest($request);
$visits = $this->visitsHelper->nonOrphanVisits($params, $apiKey);

return new JsonResponse(['visits' => PagerfantaUtils::serializePaginator($visits)]);
protected function getVisitsPaginator(
ServerRequestInterface $request,
VisitsParams $params,
ApiKey $apiKey,
): Pagerfanta {
return $this->visitsHelper->nonOrphanVisits($params, $apiKey);
}
}
29 changes: 11 additions & 18 deletions module/Rest/src/Action/Visit/OrphanVisitsAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,23 @@

namespace Shlinkio\Shlink\Rest\Action\Visit;

use Laminas\Diactoros\Response\JsonResponse;
use Psr\Http\Message\ResponseInterface;
use Pagerfanta\Pagerfanta;
use Psr\Http\Message\ServerRequestInterface;
use Shlinkio\Shlink\Common\Paginator\Util\PagerfantaUtils;
use Shlinkio\Shlink\Core\Visit\Model\OrphanVisitsParams;
use Shlinkio\Shlink\Core\Visit\VisitsStatsHelperInterface;
use Shlinkio\Shlink\Rest\Action\AbstractRestAction;
use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware;
use Shlinkio\Shlink\Core\Visit\Model\VisitsParams;
use Shlinkio\Shlink\Rest\Entity\ApiKey;

class OrphanVisitsAction extends AbstractRestAction
class OrphanVisitsAction extends AbstractListVisitsAction
{
protected const ROUTE_PATH = '/visits/orphan';
protected const ROUTE_ALLOWED_METHODS = [self::METHOD_GET];

public function __construct(private readonly VisitsStatsHelperInterface $visitsHelper)
{
}

public function handle(ServerRequestInterface $request): ResponseInterface
{
$params = OrphanVisitsParams::fromRawData($request->getQueryParams());
$apiKey = AuthenticationMiddleware::apiKeyFromRequest($request);
$visits = $this->visitsHelper->orphanVisits($params, $apiKey);

return new JsonResponse(['visits' => PagerfantaUtils::serializePaginator($visits)]);
protected function getVisitsPaginator(
ServerRequestInterface $request,
VisitsParams $params,
ApiKey $apiKey,
): Pagerfanta {
$orphanParams = OrphanVisitsParams::fromVisitsParamsAndRawData($params, $request->getQueryParams());
return $this->visitsHelper->orphanVisits($orphanParams, $apiKey);
}
}
22 changes: 5 additions & 17 deletions module/Rest/src/Action/Visit/ShortUrlVisitsAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,20 @@

namespace Shlinkio\Shlink\Rest\Action\Visit;

use Laminas\Diactoros\Response\JsonResponse;
use Psr\Http\Message\ResponseInterface as Response;
use Pagerfanta\Pagerfanta;
use Psr\Http\Message\ServerRequestInterface as Request;
use Shlinkio\Shlink\Common\Paginator\Util\PagerfantaUtils;
use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlIdentifier;
use Shlinkio\Shlink\Core\Visit\Model\VisitsParams;
use Shlinkio\Shlink\Core\Visit\VisitsStatsHelperInterface;
use Shlinkio\Shlink\Rest\Action\AbstractRestAction;
use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware;
use Shlinkio\Shlink\Rest\Entity\ApiKey;

class ShortUrlVisitsAction extends AbstractRestAction
class ShortUrlVisitsAction extends AbstractListVisitsAction
{
protected const ROUTE_PATH = '/short-urls/{shortCode}/visits';
protected const ROUTE_ALLOWED_METHODS = [self::METHOD_GET];

public function __construct(private readonly VisitsStatsHelperInterface $visitsHelper)
{
}

public function handle(Request $request): Response
protected function getVisitsPaginator(Request $request, VisitsParams $params, ApiKey $apiKey): Pagerfanta
{
$identifier = ShortUrlIdentifier::fromApiRequest($request);
$params = VisitsParams::fromRawData($request->getQueryParams());
$apiKey = AuthenticationMiddleware::apiKeyFromRequest($request);
$visits = $this->visitsHelper->visitsForShortUrl($identifier, $params, $apiKey);

return new JsonResponse(['visits' => PagerfantaUtils::serializePaginator($visits)]);
return $this->visitsHelper->visitsForShortUrl($identifier, $params, $apiKey);
}
}
22 changes: 5 additions & 17 deletions module/Rest/src/Action/Visit/TagVisitsAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,19 @@

namespace Shlinkio\Shlink\Rest\Action\Visit;

use Laminas\Diactoros\Response\JsonResponse;
use Psr\Http\Message\ResponseInterface as Response;
use Pagerfanta\Pagerfanta;
use Psr\Http\Message\ServerRequestInterface as Request;
use Shlinkio\Shlink\Common\Paginator\Util\PagerfantaUtils;
use Shlinkio\Shlink\Core\Visit\Model\VisitsParams;
use Shlinkio\Shlink\Core\Visit\VisitsStatsHelperInterface;
use Shlinkio\Shlink\Rest\Action\AbstractRestAction;
use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware;
use Shlinkio\Shlink\Rest\Entity\ApiKey;

class TagVisitsAction extends AbstractRestAction
class TagVisitsAction extends AbstractListVisitsAction
{
protected const ROUTE_PATH = '/tags/{tag}/visits';
protected const ROUTE_ALLOWED_METHODS = [self::METHOD_GET];

public function __construct(private readonly VisitsStatsHelperInterface $visitsHelper)
{
}

public function handle(Request $request): Response
protected function getVisitsPaginator(Request $request, VisitsParams $params, ApiKey $apiKey): Pagerfanta
{
$tag = $request->getAttribute('tag', '');
$params = VisitsParams::fromRawData($request->getQueryParams());
$apiKey = AuthenticationMiddleware::apiKeyFromRequest($request);
$visits = $this->visitsHelper->visitsForTag($tag, $params, $apiKey);

return new JsonResponse(['visits' => PagerfantaUtils::serializePaginator($visits)]);
return $this->visitsHelper->visitsForTag($tag, $params, $apiKey);
}
}

0 comments on commit d5de747

Please sign in to comment.