mirror of
https://github.com/shlinkio/shlink.git
synced 2026-03-11 01:33:11 +08:00
Added event dispatcher to track when a short URL is visited
This commit is contained in:
@@ -65,6 +65,11 @@ class Visit extends AbstractEntity implements JsonSerializable
|
||||
return $this->visitLocation ?? new UnknownVisitLocation();
|
||||
}
|
||||
|
||||
public function isLocatable(): bool
|
||||
{
|
||||
return $this->hasRemoteAddr() && $this->remoteAddr !== IpAddress::LOCALHOST;
|
||||
}
|
||||
|
||||
public function locate(VisitLocation $visitLocation): self
|
||||
{
|
||||
$this->visitLocation = $visitLocation;
|
||||
|
||||
52
module/Core/src/EventDispatcher/LocateShortUrlVisit.php
Normal file
52
module/Core/src/EventDispatcher/LocateShortUrlVisit.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Shlinkio\Shlink\Core\EventDispatcher;
|
||||
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Shlinkio\Shlink\Common\IpGeolocation\IpLocationResolverInterface;
|
||||
use Shlinkio\Shlink\Common\IpGeolocation\Model\Location;
|
||||
use Shlinkio\Shlink\Core\Entity\Visit;
|
||||
use Shlinkio\Shlink\Core\Entity\VisitLocation;
|
||||
|
||||
use function sprintf;
|
||||
|
||||
class LocateShortUrlVisit
|
||||
{
|
||||
/** @var IpLocationResolverInterface */
|
||||
private $ipLocationResolver;
|
||||
/** @var EntityManagerInterface */
|
||||
private $em;
|
||||
/** @var LoggerInterface */
|
||||
private $logger;
|
||||
|
||||
public function __construct(
|
||||
IpLocationResolverInterface $ipLocationResolver,
|
||||
EntityManagerInterface $em,
|
||||
LoggerInterface $logger
|
||||
) {
|
||||
$this->ipLocationResolver = $ipLocationResolver;
|
||||
$this->em = $em;
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
public function __invoke(ShortUrlVisited $shortUrlVisited): void
|
||||
{
|
||||
$visitId = $shortUrlVisited->visitId();
|
||||
|
||||
/** @var Visit|null $visit */
|
||||
$visit = $this->em->find(Visit::class, $visitId);
|
||||
if ($visit === null) {
|
||||
$this->logger->warning(sprintf('Tried to locate visit with id "%s", but it does not exist.', $visitId));
|
||||
return;
|
||||
}
|
||||
|
||||
$location = $visit->isLocatable()
|
||||
? $this->ipLocationResolver->resolveIpLocation($visit->getRemoteAddr())
|
||||
: Location::emptyInstance();
|
||||
|
||||
$visit->locate(new VisitLocation($location));
|
||||
$this->em->flush($visit);
|
||||
}
|
||||
}
|
||||
20
module/Core/src/EventDispatcher/ShortUrlVisited.php
Normal file
20
module/Core/src/EventDispatcher/ShortUrlVisited.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Shlinkio\Shlink\Core\EventDispatcher;
|
||||
|
||||
final class ShortUrlVisited
|
||||
{
|
||||
/** @var string */
|
||||
private $visitId;
|
||||
|
||||
public function __construct(string $visitId)
|
||||
{
|
||||
$this->visitId = $visitId;
|
||||
}
|
||||
|
||||
public function visitId(): string
|
||||
{
|
||||
return $this->visitId;
|
||||
}
|
||||
}
|
||||
@@ -4,8 +4,10 @@ declare(strict_types=1);
|
||||
namespace Shlinkio\Shlink\Core\Service;
|
||||
|
||||
use Doctrine\ORM;
|
||||
use Psr\EventDispatcher\EventDispatcherInterface;
|
||||
use Shlinkio\Shlink\Core\Entity\ShortUrl;
|
||||
use Shlinkio\Shlink\Core\Entity\Visit;
|
||||
use Shlinkio\Shlink\Core\EventDispatcher\ShortUrlVisited;
|
||||
use Shlinkio\Shlink\Core\Exception\InvalidArgumentException;
|
||||
use Shlinkio\Shlink\Core\Model\Visitor;
|
||||
use Shlinkio\Shlink\Core\Model\VisitsParams;
|
||||
@@ -19,10 +21,13 @@ class VisitsTracker implements VisitsTrackerInterface
|
||||
{
|
||||
/** @var ORM\EntityManagerInterface */
|
||||
private $em;
|
||||
/** @var EventDispatcherInterface */
|
||||
private $eventDispatcher;
|
||||
|
||||
public function __construct(ORM\EntityManagerInterface $em)
|
||||
public function __construct(ORM\EntityManagerInterface $em, EventDispatcherInterface $eventDispatcher)
|
||||
{
|
||||
$this->em = $em;
|
||||
$this->eventDispatcher = $eventDispatcher;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -41,6 +46,8 @@ class VisitsTracker implements VisitsTrackerInterface
|
||||
$em = $this->em;
|
||||
$em->persist($visit);
|
||||
$em->flush($visit);
|
||||
|
||||
$this->eventDispatcher->dispatch(new ShortUrlVisited($visit->getId()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user