diff --git a/packages/vitec/Classes/Command/SsrHealthSampleCommand.php b/packages/vitec/Classes/Command/SsrHealthSampleCommand.php
index 2b8a59b..ebe37d8 100644
--- a/packages/vitec/Classes/Command/SsrHealthSampleCommand.php
+++ b/packages/vitec/Classes/Command/SsrHealthSampleCommand.php
@@ -9,6 +9,7 @@ use Evomedien\Vitec\Service\SsrPurgeService;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Http\RequestFactory;
@@ -33,8 +34,24 @@ final class SsrHealthSampleCommand extends Command
parent::__construct();
}
+ protected function configure(): void
+ {
+ $this->addOption(
+ 'test-mail',
+ null,
+ InputOption::VALUE_OPTIONAL,
+ 'Send a sample alert mail through the real alert path and exit (no health sample). Optional address; default: the configured alert recipients',
+ false
+ );
+ }
+
protected function execute(InputInterface $input, OutputInterface $output): int
{
+ $testMail = $input->getOption('test-mail');
+ if ($testMail !== false) {
+ return $this->sendTestMail((string)$testMail, $output);
+ }
+
$endpoint = $this->purgeService->getHealthEndpoint();
if ($endpoint === '') {
$output->writeln('SSR_HEALTH_ENDPOINT missing in var/vitec-ssr-purge.env');
@@ -204,6 +221,38 @@ final class SsrHealthSampleCommand extends Command
return Command::SUCCESS;
}
+ /**
+ * Deliverability check (e.g. mail-tester.com): same sender, mailer and
+ * plain-text format as a real alert, clearly marked as a test.
+ */
+ private function sendTestMail(string $address, OutputInterface $output): int
+ {
+ $override = [];
+ if ($address !== '') {
+ if (!GeneralUtility::validEmail($address)) {
+ $output->writeln('invalid address: ' . $address . '');
+ return Command::INVALID;
+ }
+ $override = [$address];
+ }
+ $this->sendAlert(
+ '[VITEC SSR] TEST: alert mail check',
+ "This is a test of the VITEC SSR alert mail - nothing is wrong.\n\n"
+ . "Real alerts look like this one and are sent when the 5-minute health\n"
+ . "check sees the SSR server go down or come back, and when the\n"
+ . "auto-failover switches the site to SPA delivery.\n\n"
+ . 'Time: ' . date('d.m.Y H:i:s') . "\n"
+ . 'Current state: switch vitec.ssr.enabled = '
+ . ($this->flagService->isEnabledInSettings() ? 'ON' : 'OFF')
+ . ', flag file ' . ($this->flagService->isFlagSet() ? 'present (SSR active)' : 'missing (SPA delivery)') . ".\n\n"
+ . "Recipients are maintained in the TYPO3 backend:\n"
+ . "Site Management > Settings > VITEC > SSR alert mail recipients.\n",
+ $output,
+ $override
+ );
+ return Command::SUCCESS;
+ }
+
/**
* Mails are best effort: a mail problem must never break the sampler
* (the cron would stop logging history). Recipients come from the site
@@ -211,13 +260,13 @@ final class SsrHealthSampleCommand extends Command
* fallback SSR_ALERT_EMAIL in var/vitec-ssr-purge.env - none at all
* means "alerts off", which the output states so the cron log shows why.
*/
- private function sendAlert(string $subject, string $body, OutputInterface $output): void
+ private function sendAlert(string $subject, string $body, OutputInterface $output, array $override = []): void
{
$alert = $this->purgeService->getAlertRecipients();
- if ($alert['invalid'] !== []) {
+ if ($alert['invalid'] !== [] && $override === []) {
$output->writeln('skipped invalid alert addresses: ' . implode(', ', $alert['invalid']) . '');
}
- $recipients = $alert['recipients'];
+ $recipients = $override !== [] ? $override : $alert['recipients'];
if ($recipients === []) {
$output->writeln('transition detected but no alert recipients are configured (Site settings › VITEC or SSR_ALERT_EMAIL) - no mail sent');
return;