CluPilotCloud/app/Http/Controllers/ContactController.php

79 lines
3.1 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\Mail\ContactRequestMail;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
use Illuminate\View\View;
/**
* „Sprechen Sie uns an" als Seite, nicht als `mailto:`.
*
* Der Knopf unter den Paketen zeigte auf `mailto:`, und der tut auf den meisten
* Geräten nichts Sichtbares: ohne eingerichtetes Mailprogramm passiert gar
* nichts, im Browser öffnet sich bestenfalls ein Dialog, den niemand erwartet
* hat. Das ist ausgerechnet an der Stelle fatal, an der das Selbstbedienen
* aufhört und ein Gespräch beginnen soll — wer hier klickt, hat sich schon
* entschieden zu fragen.
*
* Eine Seite statt eines Modals: die öffentliche Website lädt kein Livewire,
* ein gewöhnlicher Formular-POST kommt also auch dann an, wenn JavaScript
* scheitert. Und eine Seite hat eine Adresse — sie lässt sich aus einer Mail
* heraus verlinken, ein Modal nicht.
*/
class ContactController extends Controller
{
/** Themen, die das Formular kennt. Alles andere wird zu `general`. */
private const TOPICS = ['enterprise', 'general'];
public function show(Request $request): View
{
$topic = (string) $request->query('thema', 'general');
return view('contact', [
'topic' => in_array($topic, self::TOPICS, true) ? $topic : 'general',
'sent' => $request->session()->get('contact.sent', false),
]);
}
public function send(Request $request): RedirectResponse
{
$data = $request->validate([
'company' => ['nullable', 'string', 'max:120'],
'name' => ['required', 'string', 'max:120'],
'email' => ['required', 'email:rfc', 'max:190'],
'phone' => ['nullable', 'string', 'max:60'],
'message' => ['required', 'string', 'min:10', 'max:4000'],
'topic' => ['nullable', 'string', 'in:'.implode(',', self::TOPICS)],
// Honigtopf: ein Feld, das im Browser niemand sieht und ein
// Formularroboter trotzdem ausfüllt. `filled` statt einer eigenen
// Regel, damit die Meldung, die ein Mensch nie zu sehen bekommt,
// auch keine eigene Übersetzung braucht.
'website' => ['nullable', 'prohibited'],
], [], [
'name' => 'Name',
'email' => 'E-Mail-Adresse',
'message' => 'Nachricht',
]);
Mail::send(new ContactRequestMail([
'company' => $data['company'] ?? null,
'name' => $data['name'],
'email' => $data['email'],
'phone' => $data['phone'] ?? null,
'message' => $data['message'],
'topic' => $data['topic'] ?? 'general',
]));
// Zurück auf dieselbe Seite, mit einer Fahne in der Sitzung statt einer
// Kennung in der Adresse: ein Neuladen zeigt danach wieder das leere
// Formular und nicht dauerhaft eine Bestätigung für etwas, das längst
// erledigt ist.
return redirect()
->route('contact')
->with('contact.sent', true);
}
}