# Acme Contact Form
Ein wiederverwendbares, spam-geschütztes Kontaktformular-Package für Laravel mit Livewire. Bietet Honeypot, zeitbasierte Prüfung, Inhaltsanalyse, Rate Limiting und mehr – ohne externe Dienste, DSGVO-konform.
## Features
- **Spam-Schutz**: Honeypot, Zeitprüfung, Inhaltsanalyse, Wegwerf-E-Mails, Rate Limiting, IP-Blacklist, Bot-User-Agent-Erkennung
- **Konfigurierbare Felder**: Presets (simple, full) oder eigene Felddefinitionen
- **Livewire**: Reaktives Formular ohne Page-Reload
- **Flexibel**: Einfache Formulare bis komplexe Multi-Feld-Formulare
- **DSGVO-konform**: Keine externen Services, alles in-house
## Voraussetzungen
- PHP 8.2+
- Laravel 10+ / 11+ / 12+
- Livewire 3+
## Installation
### 1. Package installieren
```bash
composer require acme/contact-form
```
Für lokale Entwicklung (Path-Repository):
```json
{
"repositories": [
{
"type": "path",
"url": "package/acme/contact-form"
}
],
"require": {
"acme/contact-form": "@dev"
}
}
```
```bash
composer update acme/contact-form
```
### 2. Konfiguration
```bash
php artisan vendor:publish --tag=contact-form-config
```
In `.env`:
```env
CONTACT_FORM_RECIPIENT=kontakt@ihre-domain.de
CONTACT_FORM_MAX_ATTEMPTS=3
CONTACT_FORM_DECAY_MINUTES=15
CONTACT_FORM_MIN_FILL_TIME=3
```
### 3. Übersetzungen (optional)
```bash
php artisan vendor:publish --tag=contact-form-lang
```
## Verwendung
### Einfaches Formular (Preset: simple)
Name, E-Mail, Nachricht, Datenschutz-Checkbox:
```blade
```
Oder mit explizitem Preset:
```blade
```
### Vollständiges Formular (Preset: full)
Vorname, Nachname, E-Mail, Telefon, Unternehmen, Nachricht, Datenschutz:
```blade
```
### Eigenes Formular mit benutzerdefinierten Feldern
Sie können beliebige Felder definieren. Jedes Feld benötigt:
- `type`: `text`, `email`, `tel`, `textarea`, `select`, `checkbox`, `honeypot`
- `rules`: Laravel-Validierungsregeln (Array)
- `label`: Anzeigename (optional)
- `placeholder`: Platzhalter (optional)
- `required`: true/false (optional, wird aus rules abgeleitet)
- `name`: Formularfeld-Name (optional, Standard: Array-Key)
- `options`: Für `select` – Array [value => label] (optional)
**Beispiel: Minimales Formular (nur E-Mail + Nachricht)**
```blade
```
**Beispiel: Formular mit Select-Feld**
```blade
```
**Wichtig**: Jedes Formular sollte ein Honeypot-Feld enthalten. Das Feld wird für Nutzer unsichtbar dargestellt; Bots füllen es oft aus und werden so erkannt.
### Eigene Presets in der Config
In `config/contact-form.php` können Sie eigene Presets definieren:
```php
'presets' => [
'mein-formular' => [
'name' => [
'type' => 'text',
'rules' => ['required', 'string', 'max:120'],
'label' => 'Name',
],
'email' => [
'type' => 'email',
'rules' => ['required', 'email:rfc,dns'],
'label' => 'E-Mail',
],
'message' => [
'type' => 'textarea',
'rules' => ['required', 'string', 'max:2000'],
'label' => 'Nachricht',
],
'privacy' => [
'type' => 'checkbox',
'rules' => ['accepted'],
'label' => 'Datenschutz',
],
'honeypot' => [
'type' => 'honeypot',
'name' => 'website',
'rules' => ['nullable', 'string', 'max:0'],
],
],
],
```
Verwendung:
```blade
```
## Spam-Schutz im Detail
| Maßnahme | Beschreibung |
|----------|--------------|
| **Honeypot** | Verstecktes Feld – wenn ausgefüllt → Spam |
| **Zeitprüfung** | Formular < 3 Sek. ausgefüllt → Spam |
| **Inhaltsanalyse** | Spam-Keywords, URLs, XSS-Muster → Spam |
| **Wegwerf-E-Mails** | tempmail.com, mailinator.com etc. → Spam |
| **Rate Limiting** | Max. 3 Anfragen/IP in 15 Min. (konfigurierbar) |
| **IP-Blacklist** | Blockierte IPs in Config |
| **Bot-User-Agent** | curl, wget, python-requests etc. → Spam |
Bei Spam wird **immer** eine Erfolgsmeldung angezeigt (Täuschung von Bots), aber **keine E-Mail** versendet. Alle Anfragen werden geloggt.
## Service und SpamDetector direkt nutzen
Falls Sie einen eigenen Controller oder eine eigene Livewire-Komponente verwenden möchten:
```php
use Acme\ContactForm\ContactFormService;
use Acme\ContactForm\SpamDetector;
// Spam prüfen
$spamDetector = SpamDetector::fromConfig();
$isSpam = $spamDetector->detect($validatedData, $formLoadedAt);
// Anfrage verarbeiten
$service = app(ContactFormService::class);
$service->handle([
'name' => $request->input('name'),
'email' => $request->input('email'),
'message' => $request->input('message'),
'ip' => $request->ip(),
'user_agent' => $request->userAgent(),
'is_spam' => $isSpam,
], 'Betreff der E-Mail', 'Log-Kontext');
```
## Konfiguration
| Option | Beschreibung | Standard |
|--------|--------------|----------|
| `recipient` | E-Mail-Empfänger | aus .env |
| `rate_limit.max_attempts` | Max. Anfragen pro IP | 3 |
| `rate_limit.decay_minutes` | Zeitfenster in Minuten | 15 |
| `blacklisted_ips` | IP-Adressen blockieren | [] |
| `honeypot_fields` | Namen der Honeypot-Felder | company_check, website, url |
| `spam.min_fill_time_seconds` | Min. Zeit zum Ausfüllen | 3 |
| `spam.suspicious_patterns` | Regex für Spam-Erkennung | siehe Config |
| `spam.disposable_email_domains` | Wegwerf-Domains | siehe Config |
## Styling anpassen
Die Standard-Views nutzen generische Klassen (`border-gray-300`, `focus:ring-primary`). Passen Sie sie an Ihr Design an:
```bash
php artisan vendor:publish --tag=contact-form-views
```
Die Views liegen dann unter `resources/views/vendor/contact-form/`.
## Event nach Absenden
Nach erfolgreichem Absenden wird das Event `contact-form-submitted` dispatched. Sie können darauf reagieren:
```blade
Vielen Dank für Ihre Nachricht!
```
## Lizenz
MIT License