Let a form send from its own address in 1.15.1
CMS quality / php (8.2) (push) Canceled after 0s
CMS quality / php (8.4) (push) Canceled after 0s
CMS quality / browser (push) Canceled after 0s
CMS quality / mysql (push) Canceled after 0s

Umut asked where a contact form's mail is sent from: it was the recipient
address, `From` equal to `To`. That breaks as soon as the recipient is a
mailbox at another provider, because most hosts only deliver mail that
claims an address of their own domain, and the provider's SPF/DMARC then
treats it as forged.

Each form now has an optional `sender` setting, validated like the
recipient; empty keeps the old behaviour, so stored forms need no
migration. Delivery uses `sender ?: recipient`; the reply-to field is
untouched. The administration shows the field under the recipient with a
note on why it matters. The pilot launch config moves to port 8091 because
8087 was held by another session.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
kantarciandClaude Fable 5.1 committed 2026-09-15 10:16:15 +02:00
1 parent 4d1f51801c
commit d05dba3042
10 files changed
+70 -7

No files matched your search

+6
View File
@@ -164,6 +164,11 @@ final class FormRepository
if (false === filter_var($recipient, FILTER_VALIDATE_EMAIL)) {
throw new InvalidForm('Bitte gib eine gültige Empfängeradresse an.');
}
// Der Absender ist freiwillig: leer heisst, die Post kommt von der Empfaengeradresse.
$sender = trim((string) ($settings['sender'] ?? ''));
if ('' !== $sender && false === filter_var($sender, FILTER_VALIDATE_EMAIL)) {
throw new InvalidForm('Bitte gib eine gültige Absenderadresse an oder lass das Feld leer.');
}
$replyTo = trim((string) ($settings['replyToField'] ?? ''));
if ('' !== $replyTo) {
$match = array_filter($fields, static fn (array $f): bool => $f['name'] === $replyTo && 'email' === $f['type']);
@@ -174,6 +179,7 @@ final class FormRepository
$clean = [
'recipient' => $recipient,
'sender' => $sender,
'subject' => mb_substr(trim((string) ($settings['subject'] ?? '')), 0, 160) ?: 'Neue Formularnachricht',
'success' => mb_substr(trim((string) ($settings['success'] ?? '')), 0, 300) ?: 'Vielen Dank. Deine Nachricht ist angekommen.',
'replyToField' => $replyTo,
+1
View File
@@ -62,6 +62,7 @@ final class FormAdminController extends AbstractController
$fields,
[
'recipient' => $request->request->getString('recipient'),
'sender' => $request->request->getString('sender'),
'subject' => $request->request->getString('subject'),
'success' => $request->request->getString('success'),
'replyToField' => $request->request->getString('replyToField'),
+3 -1
View File
@@ -90,8 +90,10 @@ final class FormController extends AbstractController
foreach ($form['fields'] as $field) {
$lines[] = $field['label'].': '.($values[$field['name']] ?? '');
}
// Der Absender ist die eigene Adresse des Formulars, sonst der Empfaenger. Viele Hoster
// liefern nur aus, was von einer Adresse ihrer eigenen Domain kommt.
$email = (new Email())
->from($form['settings']['recipient'])
->from(($form['settings']['sender'] ?? '') ?: $form['settings']['recipient'])
->to($form['settings']['recipient'])
->subject($form['settings']['subject'])
->text(implode("\n", $lines)."\n\n-- \nGesendet über ".rtrim($this->siteOrigin, '/'));