mirror of
https://github.com/shlinkio/shlink.git
synced 2024-12-22 23:23:42 -06:00
Implemented methods to get paginated list of visits by tag, reusing methods used for short code filtering
This commit is contained in:
parent
5be882a31b
commit
baf77b6ffb
@ -12,6 +12,8 @@ use Shlinkio\Shlink\Core\Entity\ShortUrl;
|
||||
use Shlinkio\Shlink\Core\Entity\Visit;
|
||||
use Shlinkio\Shlink\Core\Entity\VisitLocation;
|
||||
|
||||
use function array_column;
|
||||
|
||||
use const PHP_INT_MAX;
|
||||
|
||||
class VisitRepository extends EntityRepository implements VisitRepositoryInterface
|
||||
@ -87,6 +89,90 @@ class VisitRepository extends EntityRepository implements VisitRepositoryInterfa
|
||||
?int $offset = null
|
||||
): array {
|
||||
$qb = $this->createVisitsByShortCodeQueryBuilder($shortCode, $domain, $dateRange);
|
||||
return $this->resolveVisitsWithNativeQuery($qb, $limit, $offset);
|
||||
}
|
||||
|
||||
public function countVisitsByShortCode(string $shortCode, ?string $domain = null, ?DateRange $dateRange = null): int
|
||||
{
|
||||
$qb = $this->createVisitsByShortCodeQueryBuilder($shortCode, $domain, $dateRange);
|
||||
$qb->select('COUNT(v.id)');
|
||||
|
||||
return (int) $qb->getQuery()->getSingleScalarResult();
|
||||
}
|
||||
|
||||
private function createVisitsByShortCodeQueryBuilder(
|
||||
string $shortCode,
|
||||
?string $domain,
|
||||
?DateRange $dateRange
|
||||
): QueryBuilder {
|
||||
/** @var ShortUrlRepositoryInterface $shortUrlRepo */
|
||||
$shortUrlRepo = $this->getEntityManager()->getRepository(ShortUrl::class);
|
||||
$shortUrl = $shortUrlRepo->findOne($shortCode, $domain);
|
||||
$shortUrlId = $shortUrl !== null ? $shortUrl->getId() : -1;
|
||||
|
||||
// Parameters in this query need to be part of the query itself, as we need to use it a sub-query later
|
||||
// Since they are not strictly provided by the caller, it's reasonably safe
|
||||
$qb = $this->getEntityManager()->createQueryBuilder();
|
||||
$qb->from(Visit::class, 'v')
|
||||
->where($qb->expr()->eq('v.shortUrl', $shortUrlId));
|
||||
|
||||
// Apply date range filtering
|
||||
$this->applyDatesInline($qb, $dateRange);
|
||||
|
||||
return $qb;
|
||||
}
|
||||
|
||||
public function findVisitsByTag(
|
||||
string $tag,
|
||||
?DateRange $dateRange = null,
|
||||
?int $limit = null,
|
||||
?int $offset = null
|
||||
): array {
|
||||
$qb = $this->createVisitsByTagQueryBuilder($tag, $dateRange);
|
||||
return $this->resolveVisitsWithNativeQuery($qb, $limit, $offset);
|
||||
}
|
||||
|
||||
public function countVisitsByTag(string $tag, ?DateRange $dateRange = null): int
|
||||
{
|
||||
$qb = $this->createVisitsByTagQueryBuilder($tag, $dateRange);
|
||||
$qb->select('COUNT(v.id)');
|
||||
|
||||
return (int) $qb->getQuery()->getSingleScalarResult();
|
||||
}
|
||||
|
||||
private function createVisitsByTagQueryBuilder(string $tag, ?DateRange $dateRange = null): QueryBuilder
|
||||
{
|
||||
$qb = $this->getEntityManager()->createQueryBuilder();
|
||||
$qb->select('s.id')
|
||||
->from(ShortUrl::class, 's')
|
||||
->join('s.tags', 't')
|
||||
->where($qb->expr()->eq('t.name', ':tag'))
|
||||
->setParameter('tag', $tag);
|
||||
|
||||
// Parameters in this query need to be part of the query itself, as we need to use it a sub-query later
|
||||
// Since they are not strictly provided by the caller, it's reasonably safe
|
||||
$qb2 = $this->getEntityManager()->createQueryBuilder();
|
||||
$qb2->from(Visit::class, 'v')
|
||||
->where($qb2->expr()->in('v.shortUrl', array_column($qb->getQuery()->getArrayResult(), 'id')));
|
||||
|
||||
// Apply date range filtering
|
||||
$this->applyDatesInline($qb2, $dateRange);
|
||||
|
||||
return $qb2;
|
||||
}
|
||||
|
||||
private function applyDatesInline(QueryBuilder $qb, ?DateRange $dateRange): void
|
||||
{
|
||||
if ($dateRange !== null && $dateRange->getStartDate() !== null) {
|
||||
$qb->andWhere($qb->expr()->gte('v.date', '\'' . $dateRange->getStartDate()->toDateTimeString() . '\''));
|
||||
}
|
||||
if ($dateRange !== null && $dateRange->getEndDate() !== null) {
|
||||
$qb->andWhere($qb->expr()->lte('v.date', '\'' . $dateRange->getEndDate()->toDateTimeString() . '\''));
|
||||
}
|
||||
}
|
||||
|
||||
private function resolveVisitsWithNativeQuery(QueryBuilder $qb, ?int $limit, ?int $offset): array
|
||||
{
|
||||
$qb->select('v.id')
|
||||
->orderBy('v.id', 'DESC')
|
||||
// Falling back to values that will behave as no limit/offset, but will workaround MS SQL not allowing
|
||||
@ -115,53 +201,4 @@ class VisitRepository extends EntityRepository implements VisitRepositoryInterfa
|
||||
|
||||
return $query->getResult();
|
||||
}
|
||||
|
||||
public function countVisitsByShortCode(string $shortCode, ?string $domain = null, ?DateRange $dateRange = null): int
|
||||
{
|
||||
$qb = $this->createVisitsByShortCodeQueryBuilder($shortCode, $domain, $dateRange);
|
||||
$qb->select('COUNT(v.id)');
|
||||
|
||||
return (int) $qb->getQuery()->getSingleScalarResult();
|
||||
}
|
||||
|
||||
private function createVisitsByShortCodeQueryBuilder(
|
||||
string $shortCode,
|
||||
?string $domain,
|
||||
?DateRange $dateRange
|
||||
): QueryBuilder {
|
||||
/** @var ShortUrlRepositoryInterface $shortUrlRepo */
|
||||
$shortUrlRepo = $this->getEntityManager()->getRepository(ShortUrl::class);
|
||||
$shortUrl = $shortUrlRepo->findOne($shortCode, $domain);
|
||||
$shortUrlId = $shortUrl !== null ? $shortUrl->getId() : -1;
|
||||
|
||||
// Parameters in this query need to be part of the query itself, as we need to use it a sub-query later
|
||||
// Since they are not strictly provided by the caller, it's reasonably safe
|
||||
$qb = $this->getEntityManager()->createQueryBuilder();
|
||||
$qb->from(Visit::class, 'v')
|
||||
->where($qb->expr()->eq('v.shortUrl', $shortUrlId));
|
||||
|
||||
// Apply date range filtering
|
||||
if ($dateRange !== null && $dateRange->getStartDate() !== null) {
|
||||
$qb->andWhere($qb->expr()->gte('v.date', '\'' . $dateRange->getStartDate()->toDateTimeString() . '\''));
|
||||
}
|
||||
if ($dateRange !== null && $dateRange->getEndDate() !== null) {
|
||||
$qb->andWhere($qb->expr()->lte('v.date', '\'' . $dateRange->getEndDate()->toDateTimeString() . '\''));
|
||||
}
|
||||
|
||||
return $qb;
|
||||
}
|
||||
|
||||
public function findVisitsByTag(
|
||||
string $tag,
|
||||
?DateRange $dateRange = null,
|
||||
?int $limit = null,
|
||||
?int $offset = null
|
||||
): array {
|
||||
return [];
|
||||
}
|
||||
|
||||
public function countVisitsByTag(string $tag, ?DateRange $dateRange = null): int
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user