Added logic to exclude bots from visits when requested

This commit is contained in:
Alejandro Celaya
2021-05-22 20:49:24 +02:00
parent db3c5a3031
commit 69d72e754f
4 changed files with 52 additions and 12 deletions

View File

@@ -53,6 +53,11 @@ final class Visitor
return new self('', '', null, '');
}
public static function botInstance(): self
{
return new self('cf-facebook', '', null, '');
}
public function getUserAgent(): string
{
return $this->userAgent;

View File

@@ -114,6 +114,10 @@ class VisitRepository extends EntitySpecificationRepository implements VisitRepo
$qb->from(Visit::class, 'v')
->where($qb->expr()->eq('v.shortUrl', $shortUrlId));
if ($filtering->excludeBots()) {
$qb->andWhere($qb->expr()->eq('v.potentialBot', 'false'));
}
// Apply date range filtering
$this->applyDatesInline($qb, $filtering->dateRange());
@@ -144,6 +148,10 @@ class VisitRepository extends EntitySpecificationRepository implements VisitRepo
->join('s.tags', 't')
->where($qb->expr()->eq('t.name', '\'' . $tag . '\'')); // This needs to be concatenated, not bound
if ($filtering->excludeBots()) {
$qb->andWhere($qb->expr()->eq('v.potentialBot', 'false'));
}
$this->applyDatesInline($qb, $filtering->dateRange());
$this->applySpecification($qb, $filtering->spec(), 'v');
@@ -158,6 +166,10 @@ class VisitRepository extends EntitySpecificationRepository implements VisitRepo
$qb->from(Visit::class, 'v')
->where($qb->expr()->isNull('v.shortUrl'));
if ($filtering->excludeBots()) {
$qb->andWhere($qb->expr()->eq('v.potentialBot', 'false'));
}
$this->applyDatesInline($qb, $filtering->dateRange());
return $this->resolveVisitsWithNativeQuery($qb, $filtering->limit(), $filtering->offset());
@@ -165,7 +177,7 @@ class VisitRepository extends EntitySpecificationRepository implements VisitRepo
public function countOrphanVisits(VisitsCountFiltering $filtering): int
{
return (int) $this->matchSingleScalarResult(new CountOfOrphanVisits($filtering->dateRange()));
return (int) $this->matchSingleScalarResult(new CountOfOrphanVisits($filtering));
}
public function countVisits(?ApiKey $apiKey = null): int

View File

@@ -7,24 +7,30 @@ namespace Shlinkio\Shlink\Core\Visit\Spec;
use Happyr\DoctrineSpecification\Spec;
use Happyr\DoctrineSpecification\Specification\BaseSpecification;
use Happyr\DoctrineSpecification\Specification\Specification;
use Shlinkio\Shlink\Common\Util\DateRange;
use Shlinkio\Shlink\Core\Spec\InDateRange;
use Shlinkio\Shlink\Core\Visit\Persistence\VisitsCountFiltering;
class CountOfOrphanVisits extends BaseSpecification
{
private ?DateRange $dateRange;
private VisitsCountFiltering $filtering;
public function __construct(?DateRange $dateRange)
public function __construct(VisitsCountFiltering $filtering)
{
parent::__construct();
$this->dateRange = $dateRange;
$this->filtering = $filtering;
}
protected function getSpec(): Specification
{
return Spec::countOf(Spec::andX(
$conditions = [
Spec::isNull('shortUrl'),
new InDateRange($this->dateRange),
));
new InDateRange($this->filtering->dateRange()),
];
if ($this->filtering->excludeBots()) {
$conditions[] = Spec::eq('potentialBot', false);
}
return Spec::countOf(Spec::andX(...$conditions));
}
}