# Validation Framework

> **Dokumentationshinweis:** Diese Dokumentation ist vollständig aktualisiert und stellt die aktuelle Implementierung des Validation Frameworks korrekt dar.

## Übersicht

Das Validation Framework ist ein leistungsstarkes System zur Validierung von Objekten und Daten in der Anwendung. Es nutzt moderne PHP-Attribute, um Validierungsregeln direkt an Objekteigenschaften zu definieren, und bietet eine flexible, erweiterbare Architektur für verschiedene Validierungsanforderungen.

## Hauptkomponenten

### Validator-Klasse

Die zentrale Klasse für die Validierungsfunktionalität:

```php
// Klasse initialisieren
$validator = new Validator($reflectionProvider);

// Objekt validieren
$result = $validator->validate($object);

// Validierungsergebnis prüfen
if ($result->hasErrors()) {
    // Fehlerbehandlung
    $errors = $result->getAllErrorMessages();
}
```

### ValidationRule-Interface

Das Basis-Interface für alle Validierungsregeln:

```php
interface ValidationRule
{
    public function validate(mixed $value): bool;
    public function getErrorMessages(): array;
}
```

Alle Validierungsregeln implementieren dieses Interface und werden als PHP-Attribute verwendet.

### ValidationResult-Klasse

Speichert und verwaltet Validierungsergebnisse:

- Sammelt Fehlermeldungen für verschiedene Felder
- Bietet Methoden zum Abfragen von Fehlern
- Ermöglicht das Zusammenführen mehrerer Validierungsergebnisse

```php
// Fehler prüfen
if ($result->hasErrors()) {
    // Alle Fehlermeldungen abrufen
    $allErrors = $result->getAllErrorMessages();
    
    // Fehler für ein bestimmtes Feld abrufen
    $fieldErrors = $result->getFieldErrors('email');
}
```

## Validierungsregeln

Das Framework bietet eine Vielzahl vordefinierter Validierungsregeln:

### Grundlegende Regeln

- **Required**: Stellt sicher, dass ein Wert vorhanden ist
- **Email**: Validiert E-Mail-Adressen
- **Url**: Validiert URLs
- **Numeric**: Stellt sicher, dass ein Wert numerisch ist
- **StringLength**: Validiert die Länge eines Strings

### Erweiterte Regeln

- **Pattern**: Validiert Werte gegen reguläre Ausdrücke
- **Range**: Validiert numerische Werte innerhalb eines Bereichs
- **In**: Prüft, ob ein Wert in einer Liste gültiger Werte enthalten ist
- **DateFormat**: Validiert Datumsformate
- **Phone**: Validiert Telefonnummern
- **Ulid**: Validiert ULID-Werte
- **IsTrue**: Prüft, ob ein Wert true ist

### Benutzerdefinierte Regeln

Eigene Validierungsregeln können durch Implementierung des ValidationRule-Interfaces erstellt werden:

```php
#[Attribute(Attribute::TARGET_PROPERTY)]
final readonly class CustomRule implements ValidationRule
{
    public function __construct(
        private string $param,
        private ?string $message = null
    ) {
    }

    public function validate(mixed $value): bool
    {
        // Validierungslogik implementieren
        return true; // oder false
    }

    public function getErrorMessages(): array
    {
        return [$this->message ?? 'Standardfehlermeldung'];
    }
}
```

## Verwendung

### Objekte mit Attributen validieren

```php
class UserData
{
    #[Required]
    #[StringLength(min: 3, max: 50)]
    public string $name;

    #[Required]
    #[Email]
    public string $email;

    #[StringLength(max: 500)]
    public ?string $bio = null;

    #[Range(min: 18)]
    public ?int $age = null;
}

// Validierung durchführen
$userData = new UserData();
$userData->name = 'Max';
$userData->email = 'invalid-email';

$result = $validator->validate($userData);
```

### Validierungsgruppen

Das Framework unterstützt Validierungsgruppen, um verschiedene Validierungsszenarien zu ermöglichen:

```php
class UserData
{
    #[Required(groups: ['registration', 'profile'])]
    #[StringLength(min: 3, max: 50)]
    public string $name;

    #[Required(groups: ['registration'])]
    #[Email]
    public string $email;

    #[Required(groups: ['profile'])]
    #[StringLength(max: 500)]
    public ?string $bio = null;
}

// Validierung mit Gruppe durchführen
$result = $validator->validate($userData, 'registration');
```

### Fehlerbehandlung

```php
if ($result->hasErrors()) {
    foreach ($result->getAll() as $field => $errors) {
        echo "Fehler im Feld '$field':\n";
        foreach ($errors as $error) {
            echo "- $error\n";
        }
    }
}
```

## Integration

### Formular-Validierung

Das Framework bietet eine `ValidationFormHandler`-Klasse für die Validierung von Formulardaten:

```php
// In einem Controller
public function handleForm(Request $request, ValidationFormHandler $formHandler): Response
{
    $formData = $request->getFormData();
    
    $result = $formHandler->validate(UserData::class, $formData);
    
    if ($result->hasErrors()) {
        return $this->renderForm('user_form', [
            'errors' => $result->getAll(),
            'data' => $formData
        ]);
    }
    
    // Erfolgreiche Validierung, Daten verarbeiten
    $this->userService->createUser($formData);
    
    return $this->redirect('/success');
}
```

### Middleware-Integration

Das Framework bietet eine `InputValidationMiddleware` für die automatische Validierung von API-Anfragen:

```php
// In der Bootstrap-Datei oder Router-Konfiguration
$app->addMiddleware(InputValidationMiddleware::class);
```

Konfiguration in `config/validation.php`:

```php
return [
    'routes' => [
        '/api/users' => [
            'POST' => UserData::class,
            'PUT' => UserUpdateData::class
        ]
    ]
];
```

## Erweiterbarkeit

### Eigene Validierungsregeln erstellen

1. Interface implementieren:

```php
#[Attribute(Attribute::TARGET_PROPERTY)]
final readonly class Password implements ValidationRule
{
    public function __construct(
        private int $minLength = 8,
        private bool $requireSpecialChars = true,
        private ?string $message = null
    ) {
    }

    public function validate(mixed $value): bool
    {
        if ($value === null || $value === '') {
            return true; // Leere Werte werden von Required-Regel behandelt
        }

        if (!is_string($value) || strlen($value) < $this->minLength) {
            return false;
        }

        if ($this->requireSpecialChars && !preg_match('/[^a-zA-Z0-9]/', $value)) {
            return false;
        }

        return true;
    }

    public function getErrorMessages(): array
    {
        return [$this->message ?? "Das Passwort muss mindestens {$this->minLength} Zeichen lang sein und Sonderzeichen enthalten."];
    }
}
```

2. Verwendung:

```php
class UserRegistration
{
    #[Required]
    #[Email]
    public string $email;

    #[Required]
    #[Password(minLength: 10)]
    public string $password;
}
```

### Validierungsgruppen implementieren

Für Regeln, die Validierungsgruppen unterstützen sollen, implementieren Sie das `GroupAware`-Interface:

```php
#[Attribute(Attribute::TARGET_PROPERTY)]
final readonly class Required implements ValidationRule, GroupAware
{
    /**
     * @param array<string> $groups Validierungsgruppen
     */
    public function __construct(
        private ?string $message = null,
        private array $groups = []
    ) {
    }

    public function validate(mixed $value): bool
    {
        return $value !== null && $value !== '';
    }

    public function getErrorMessages(): array
    {
        return [$this->message ?? 'Dieser Wert ist erforderlich.'];
    }

    public function belongsToGroup(string $group): bool
    {
        return empty($this->groups) || in_array($group, $this->groups);
    }
}
```

## Fehlerbehebung

### Häufige Probleme

1. **Validierungsregeln werden nicht angewendet**:
   - Stellen Sie sicher, dass die Attribute korrekt definiert sind
   - Überprüfen Sie, ob die Eigenschaften für den Validator zugänglich sind (public oder mit Reflection)

2. **Falsche Fehlermeldungen**:
   - Überprüfen Sie die Reihenfolge der Validierungsregeln
   - Stellen Sie sicher, dass die Regeln für den richtigen Datentyp verwendet werden

3. **Leistungsprobleme**:
   - Verwenden Sie ValidationCacheDecorator für häufig validierte Objekte
   - Vermeiden Sie zu komplexe Validierungsregeln

## Weiterführende Informationen

- [Verfügbare Validierungsregeln](rules.md)
- [Formular-Integration](examples.md)
- [API-Validierung](/guides/api-validation.md)
