Add new table to track short URL visits counts

This commit is contained in:
Alejandro Celaya
2024-03-20 08:33:52 +01:00
parent 14702063f2
commit 17d37a062a
8 changed files with 216 additions and 16 deletions

View File

@@ -19,6 +19,7 @@ use Shlinkio\Shlink\Core\ShortUrl\Model\Validation\ShortUrlInputFilter;
use Shlinkio\Shlink\Core\ShortUrl\Resolver\ShortUrlRelationResolverInterface;
use Shlinkio\Shlink\Core\ShortUrl\Resolver\SimpleShortUrlRelationResolver;
use Shlinkio\Shlink\Core\Tag\Entity\Tag;
use Shlinkio\Shlink\Core\Visit\Entity\ShortUrlVisitsCount;
use Shlinkio\Shlink\Core\Visit\Entity\Visit;
use Shlinkio\Shlink\Core\Visit\Model\VisitsSummary;
use Shlinkio\Shlink\Core\Visit\Model\VisitType;
@@ -37,6 +38,7 @@ class ShortUrl extends AbstractEntity
/**
* @param Collection<int, Tag> $tags
* @param Collection<int, Visit> & Selectable $visits
* @param Collection<int, ShortUrlVisitsCount> & Selectable $visitsCounts
*/
private function __construct(
private string $longUrl,
@@ -44,6 +46,7 @@ class ShortUrl extends AbstractEntity
private Chronos $dateCreated = new Chronos(),
private Collection $tags = new ArrayCollection(),
private Collection & Selectable $visits = new ArrayCollection(),
private Collection & Selectable $visitsCounts = new ArrayCollection(),
private ?Chronos $validSince = null,
private ?Chronos $validUntil = null,
private ?int $maxVisits = null,
@@ -179,16 +182,16 @@ class ShortUrl extends AbstractEntity
return $this->shortCode;
}
public function getDateCreated(): Chronos
{
return $this->dateCreated;
}
public function getDomain(): ?Domain
{
return $this->domain;
}
public function forwardQuery(): bool
{
return $this->forwardQuery;
}
public function reachedVisits(int $visitsAmount): bool
{
return count($this->visits) >= $visitsAmount;
@@ -214,11 +217,6 @@ class ShortUrl extends AbstractEntity
return $this;
}
public function forwardQuery(): bool
{
return $this->forwardQuery;
}
/**
* @throws ShortCodeCannotBeRegeneratedException
*/

View File

@@ -60,12 +60,17 @@ class ShortUrlListRepository extends EntitySpecificationRepository implements Sh
$leftJoinConditions[] = $qb->expr()->eq('v.potentialBot', 'false');
}
$qb->addSelect('SUM(v.count)')
->leftJoin('s.visitsCounts', 'v', Join::WITH, $qb->expr()->andX(...$leftJoinConditions))
->groupBy('s')
->orderBy('SUM(v.count)', $order);
// FIXME This query is inefficient.
// Diagnostic: It might need to use a sub-query, as done with the tags list query.
$qb->addSelect('COUNT(DISTINCT v)')
->leftJoin('s.visits', 'v', Join::WITH, $qb->expr()->andX(...$leftJoinConditions))
->groupBy('s')
->orderBy('COUNT(DISTINCT v)', $order);
// $qb->addSelect('COUNT(DISTINCT v)')
// ->leftJoin('s.visits', 'v', Join::WITH, $qb->expr()->andX(...$leftJoinConditions))
// ->groupBy('s')
// ->orderBy('COUNT(DISTINCT v)', $order);
}
}

View File

@@ -0,0 +1,19 @@
<?php
declare(strict_types=1);
namespace Shlinkio\Shlink\Core\Visit\Entity;
use Shlinkio\Shlink\Common\Entity\AbstractEntity;
use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
class ShortUrlVisitsCount extends AbstractEntity
{
public function __construct(
private readonly ShortUrl $shortUrl,
private readonly bool $potentialBot = false,
private readonly int $slotId = 1,
private readonly string $count = '1',
) {
}
}