visitService = $visitService; $this->ipLocationResolver = $ipLocationResolver; $this->locker = $locker; } protected function configure(): void { $this ->setName(self::NAME) ->setDescription('Processes visits where location is not set yet'); } protected function execute(InputInterface $input, OutputInterface $output): void { $this->output = $output; $io = new SymfonyStyle($input, $output); $lock = $this->locker->createLock(self::NAME); if (! $lock->acquire()) { $io->warning(sprintf('There is already an instance of the "%s" command in execution', self::NAME)); return; } try { $this->visitService->locateVisits( [$this, 'getGeolocationDataForVisit'], function (VisitLocation $location) use ($output) { $output->writeln(sprintf(' [Address located at "%s"]', $location->getCountryName())); } ); $io->success('Finished processing all IPs'); } finally { $lock->release(); } } public function getGeolocationDataForVisit(Visit $visit): array { if (! $visit->hasRemoteAddr()) { $this->output->writeln( 'Ignored visit with no IP address', OutputInterface::VERBOSITY_VERBOSE ); throw new IpCannotBeLocatedException('Ignored visit with no IP address'); } $ipAddr = $visit->getRemoteAddr(); $this->output->write(sprintf('Processing IP %s', $ipAddr)); if ($ipAddr === IpAddress::LOCALHOST) { $this->output->writeln(' [Ignored localhost address]'); throw new IpCannotBeLocatedException('Ignored localhost address'); } try { return $this->ipLocationResolver->resolveIpLocation($ipAddr); } catch (WrongIpException $e) { $this->output->writeln(' [An error occurred while locating IP. Skipped]'); if ($this->output->isVerbose()) { $this->getApplication()->renderException($e, $this->output); } throw new IpCannotBeLocatedException('An error occurred while locating IP', $e->getCode(), $e); } } }