VisitsTracker.php 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. <?php
  2. declare(strict_types=1);
  3. namespace Shlinkio\Shlink\Core\Service;
  4. use Doctrine\ORM;
  5. use Laminas\Paginator\Paginator;
  6. use Psr\EventDispatcher\EventDispatcherInterface;
  7. use Shlinkio\Shlink\Core\Entity\ShortUrl;
  8. use Shlinkio\Shlink\Core\Entity\Visit;
  9. use Shlinkio\Shlink\Core\EventDispatcher\ShortUrlVisited;
  10. use Shlinkio\Shlink\Core\Exception\ShortUrlNotFoundException;
  11. use Shlinkio\Shlink\Core\Model\Visitor;
  12. use Shlinkio\Shlink\Core\Model\VisitsParams;
  13. use Shlinkio\Shlink\Core\Paginator\Adapter\VisitsPaginatorAdapter;
  14. use Shlinkio\Shlink\Core\Repository\VisitRepository;
  15. class VisitsTracker implements VisitsTrackerInterface
  16. {
  17. private ORM\EntityManagerInterface $em;
  18. private EventDispatcherInterface $eventDispatcher;
  19. public function __construct(ORM\EntityManagerInterface $em, EventDispatcherInterface $eventDispatcher)
  20. {
  21. $this->em = $em;
  22. $this->eventDispatcher = $eventDispatcher;
  23. }
  24. /**
  25. * Tracks a new visit to provided short code from provided visitor
  26. */
  27. public function track(string $shortCode, Visitor $visitor): void
  28. {
  29. /** @var ShortUrl $shortUrl */
  30. $shortUrl = $this->em->getRepository(ShortUrl::class)->findOneBy([
  31. 'shortCode' => $shortCode,
  32. ]);
  33. $visit = new Visit($shortUrl, $visitor);
  34. $this->em->persist($visit);
  35. $this->em->flush();
  36. $this->eventDispatcher->dispatch(new ShortUrlVisited($visit->getId()));
  37. }
  38. /**
  39. * Returns the visits on certain short code
  40. *
  41. * @return Visit[]|Paginator
  42. * @throws ShortUrlNotFoundException
  43. */
  44. public function info(string $shortCode, VisitsParams $params): Paginator
  45. {
  46. /** @var ORM\EntityRepository $repo */
  47. $repo = $this->em->getRepository(ShortUrl::class);
  48. if ($repo->count(['shortCode' => $shortCode]) < 1) {
  49. throw ShortUrlNotFoundException::fromNotFoundShortCode($shortCode);
  50. }
  51. /** @var VisitRepository $repo */
  52. $repo = $this->em->getRepository(Visit::class);
  53. $paginator = new Paginator(new VisitsPaginatorAdapter($repo, $shortCode, $params));
  54. $paginator->setItemCountPerPage($params->getItemsPerPage())
  55. ->setCurrentPageNumber($params->getPage());
  56. return $paginator;
  57. }
  58. }