em = $em; $this->eventDispatcher = $eventDispatcher; } /** * Tracks a new visit to provided short code from provided visitor */ public function track(ShortUrl $shortUrl, Visitor $visitor): void { $visit = new Visit($shortUrl, $visitor); $this->em->persist($visit); $this->em->flush(); $this->eventDispatcher->dispatch(new ShortUrlVisited($visit->getId(), $visitor->getRemoteAddress())); } /** * Returns the visits on certain short code * * @return Visit[]|Paginator * @throws ShortUrlNotFoundException */ public function info(ShortUrlIdentifier $identifier, VisitsParams $params): Paginator { /** @var ShortUrlRepositoryInterface $repo */ $repo = $this->em->getRepository(ShortUrl::class); if (! $repo->shortCodeIsInUse($identifier->shortCode(), $identifier->domain())) { throw ShortUrlNotFoundException::fromNotFound($identifier); } /** @var VisitRepository $repo */ $repo = $this->em->getRepository(Visit::class); $paginator = new Paginator(new VisitsPaginatorAdapter($repo, $identifier, $params)); $paginator->setItemCountPerPage($params->getItemsPerPage()) ->setCurrentPageNumber($params->getPage()); return $paginator; } }