ipLocationResolver = $ipLocationResolver; $this->em = $em; $this->logger = $logger; $this->dbUpdater = $dbUpdater; $this->eventDispatcher = $eventDispatcher; } public function __invoke(UrlVisited $shortUrlVisited): void { $visitId = $shortUrlVisited->visitId(); /** @var Visit|null $visit */ $visit = $this->em->find(Visit::class, $visitId); if ($visit === null) { $this->logger->warning('Tried to locate visit with id "{visitId}", but it does not exist.', [ 'visitId' => $visitId, ]); return; } $this->locateVisit($visitId, $shortUrlVisited->originalIpAddress(), $visit); $this->eventDispatcher->dispatch(new VisitLocated($visitId)); } private function locateVisit(string $visitId, ?string $originalIpAddress, Visit $visit): void { if (! $this->dbUpdater->databaseFileExists()) { $this->logger->warning('Tried to locate visit with id "{visitId}", but a GeoLite2 db was not found.', [ 'visitId' => $visitId, ]); return; } $isLocatable = $originalIpAddress !== null || $visit->isLocatable(); $addr = $originalIpAddress ?? $visit->getRemoteAddr(); try { $location = $isLocatable ? $this->ipLocationResolver->resolveIpLocation($addr) : Location::emptyInstance(); $visit->locate(new VisitLocation($location)); $this->em->flush(); } catch (WrongIpException $e) { $this->logger->warning( 'Tried to locate visit with id "{visitId}", but its address seems to be wrong. {e}', ['e' => $e, 'visitId' => $visitId], ); } catch (Throwable $e) { $this->logger->error( 'An unexpected error occurred while trying to locate visit with id "{visitId}". {e}', ['e' => $e, 'visitId' => $visitId], ); } } }