%command.name%
Send all visits created before 2024:
%command.name% --until 2023-12-31
Send all visits created after a specific day:
%command.name% --since 2022-03-27
Send all visits created during 2022:
%command.name% --since 2022-01-01 --until 2022-12-31
HELP,
)]
class MatomoSendVisitsCommand extends Command implements VisitSendingProgressTrackerInterface
{
public const string NAME = 'integration:matomo:send-visits';
private readonly bool $matomoEnabled;
private SymfonyStyle $io;
public function __construct(MatomoOptions $matomoOptions, private readonly MatomoVisitSenderInterface $visitSender)
{
$this->matomoEnabled = $matomoOptions->enabled;
parent::__construct();
}
public function __invoke(
SymfonyStyle $io,
InputInterface $input,
#[Option('Only visits created since this date, inclusively, will be sent to Matomo', shortcut: 's')]
string|null $since = null,
#[Option('Only visits created until this date, inclusively, will be sent to Matomo', shortcut: 'u')]
string|null $until = null,
): int {
$this->io = $io;
if (! $this->matomoEnabled) {
$this->io->warning('Matomo integration is not enabled in this Shlink instance');
return self::INVALID;
}
// TODO Validate provided date formats
$dateRange = buildDateRange(
startDate: normalizeOptionalDate($since),
endDate: normalizeOptionalDate($until),
);
if ($input->isInteractive()) {
$this->io->warning([
'You are about to send visits from this Shlink instance to Matomo',
'Resolved date range -> ' . dateRangeToHumanFriendly($dateRange),
'Shlink will not check for already sent visits, which could result in some duplications. Make sure '
. 'you have verified only visits in the right date range are going to be sent.',
]);
if (! $this->io->confirm('Continue?', default: false)) {
return self::INVALID;
}
}
$result = $this->visitSender->sendVisitsInDateRange($dateRange, $this);
match (true) {
$result->hasFailures() && $result->hasSuccesses() => $this->io->warning(
sprintf('%s visits sent to Matomo. %s failed.', $result->successfulVisits, $result->failedVisits),
),
$result->hasFailures() => $this->io->error(
sprintf('Failed to send %s visits to Matomo.', $result->failedVisits),
),
$result->hasSuccesses() => $this->io->success(
sprintf('%s visits sent to Matomo.', $result->successfulVisits),
),
default => $this->io->info('There was no visits matching provided date range.'),
};
return self::SUCCESS;
}
public function success(int $index): void
{
$this->io->write('.');
}
public function error(int $index, Throwable $e): void
{
$this->io->write('E');
if ($this->io->isVerbose()) {
$this->getApplication()?->renderThrowable($e, $this->io);
}
}
}