# Validation Framework Beispiele

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

## Übersicht

Diese Dokumentation enthält praktische Beispiele für die Verwendung des Validation Frameworks in verschiedenen Szenarien. Die Beispiele zeigen, wie Sie Validierungsregeln auf Objekteigenschaften anwenden, Validierungsergebnisse verarbeiten und das Framework in verschiedenen Kontexten integrieren können.

## Grundlegende Verwendung

### Einfache Objektvalidierung

```php
use App\Framework\Validation\Rules\Required;
use App\Framework\Validation\Rules\Email;
use App\Framework\Validation\Rules\StringLength;

// 1. Definieren Sie eine Klasse mit Validierungsregeln
class UserData
{
    #[Required]
    #[StringLength(min: 3, max: 50)]
    public string $name;

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

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

// 2. Erstellen Sie eine Instanz der Klasse
$userData = new UserData();
$userData->name = 'Max Mustermann';
$userData->email = 'max@example.com';

// 3. Validieren Sie das Objekt
$validator = $container->get(Validator::class);
$result = $validator->validate($userData);

// 4. Überprüfen Sie das Ergebnis
if ($result->hasErrors()) {
    // Fehlerbehandlung
    $errors = $result->getAllErrorMessages();
    foreach ($errors as $error) {
        echo $error . "\n";
    }
} else {
    // Erfolgreiche Validierung
    echo "Validierung erfolgreich!";
}
```

### Validierung mit benutzerdefinierten Fehlermeldungen

```php
class ProductData
{
    #[Required(message: "Der Produktname ist erforderlich.")]
    #[StringLength(min: 3, max: 100, message: "Der Produktname muss zwischen 3 und 100 Zeichen lang sein.")]
    public string $name;

    #[Required(message: "Der Preis ist erforderlich.")]
    #[Range(min: 0, message: "Der Preis muss größer oder gleich 0 sein.")]
    public float $price;

    #[Required(message: "Die Kategorie ist erforderlich.")]
    #[In(values: ['electronics', 'books', 'clothing'], message: "Ungültige Kategorie.")]
    public string $category;
}
```

### Zugriff auf feldspezifische Fehler

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

if ($result->hasErrors()) {
    // Alle Fehler für ein bestimmtes Feld abrufen
    $emailErrors = $result->getFieldErrors('email');
    foreach ($emailErrors as $error) {
        echo "Fehler im Feld 'email': $error\n";
    }
    
    // Alle Fehler nach Feld gruppiert abrufen
    $allErrors = $result->getAll();
    foreach ($allErrors as $field => $errors) {
        echo "Fehler im Feld '$field':\n";
        foreach ($errors as $error) {
            echo "- $error\n";
        }
    }
}
```

## Fortgeschrittene Verwendung

### Validierungsgruppen

Validierungsgruppen ermöglichen es, verschiedene Validierungsszenarien für dasselbe Objekt zu definieren:

```php
use App\Framework\Validation\Rules\Required;
use App\Framework\Validation\Rules\Email;
use App\Framework\Validation\Rules\StringLength;

class UserProfile
{
    #[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;

    #[Required(groups: ['profile'])]
    #[Url]
    public ?string $website = null;
}

// Validierung mit einer bestimmten Gruppe
$result = $validator->validate($userProfile, 'registration');

// In diesem Fall werden nur die Regeln angewendet, die zur Gruppe 'registration' gehören
// oder keine Gruppe spezifiziert haben
```

### Verschachtelte Validierung

Validierung von Objekten, die andere validierbare Objekte enthalten:

```php
use App\Framework\Validation\Rules\Required;
use App\Framework\Validation\Rules\Email;

class Address
{
    #[Required]
    #[StringLength(min: 3, max: 100)]
    public string $street;

    #[Required]
    #[StringLength(min: 3, max: 50)]
    public string $city;

    #[Required]
    #[StringLength(min: 5, max: 10)]
    public string $zipCode;
}

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

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

    #[Required]
    public Address $address;
}

// Validierung eines Objekts mit verschachtelten Objekten
$address = new Address();
$address->street = 'Musterstraße 123';
$address->city = 'Berlin';
$address->zipCode = '10115';

$customer = new Customer();
$customer->name = 'Max Mustermann';
$customer->email = 'max@example.com';
$customer->address = $address;

// Validierung des Hauptobjekts
$result = $validator->validate($customer);

// Manuelle Validierung des verschachtelten Objekts
$addressResult = $validator->validate($customer->address);
$result->merge($addressResult); // Kombinieren der Ergebnisse
```

### Benutzerdefinierte Validierungslogik

Verwendung der `Custom`-Regel für komplexe Validierungsanforderungen:

```php
use App\Framework\Validation\Rules\Custom;
use App\Framework\Validation\Rules\Required;

class PasswordReset
{
    #[Required]
    public string $email;

    #[Required]
    public string $password;

    #[Required]
    #[Custom(callback: 'validatePasswordConfirmation', message: "Die Passwörter stimmen nicht überein.")]
    public string $passwordConfirmation;

    private function validatePasswordConfirmation($value): bool
    {
        return $value === $this->password;
    }
}
```

## Integration mit Formularen

### Formularvalidierung

Verwendung des Validation Frameworks zur Validierung von Formulardaten:

```php
use App\Framework\Validation\ValidationFormHandler;
use App\Framework\Http\Response;

class UserController
{
    public function handleRegistration(
        Request $request,
        ValidationFormHandler $formHandler,
        UserService $userService
    ): Response {
        // Formulardaten abrufen
        $formData = $request->getFormData();
        
        // Validierung durchführen
        $result = $formHandler->validate(UserRegistration::class, $formData);
        
        if ($result->hasErrors()) {
            // Formular mit Fehlern neu rendern
            return $this->renderForm('registration', [
                'errors' => $result->getAll(),
                'data' => $formData
            ]);
        }
        
        // Erfolgreiche Validierung, Benutzer registrieren
        $userService->registerUser($formData);
        
        // Weiterleitung zur Erfolgsseite
        return $this->redirect('/registration/success');
    }
}
```

### Formularvorlage mit Fehleranzeige

```html
<form method="post" action="/register">
    <div class="form-group">
        <label for="name">Name:</label>
        <input type="text" id="name" name="name" value="<?= htmlspecialchars($data['name'] ?? '') ?>">
        <?php if (isset($errors['name'])): ?>
            <div class="error">
                <?= htmlspecialchars($errors['name'][0]) ?>
            </div>
        <?php endif; ?>
    </div>
    
    <div class="form-group">
        <label for="email">E-Mail:</label>
        <input type="email" id="email" name="email" value="<?= htmlspecialchars($data['email'] ?? '') ?>">
        <?php if (isset($errors['email'])): ?>
            <div class="error">
                <?= htmlspecialchars($errors['email'][0]) ?>
            </div>
        <?php endif; ?>
    </div>
    
    <div class="form-group">
        <label for="password">Passwort:</label>
        <input type="password" id="password" name="password">
        <?php if (isset($errors['password'])): ?>
            <div class="error">
                <?= htmlspecialchars($errors['password'][0]) ?>
            </div>
        <?php endif; ?>
    </div>
    
    <button type="submit">Registrieren</button>
</form>
```

## API-Validierung

### Middleware für API-Validierung

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' => UserCreateData::class,
            'PUT' => UserUpdateData::class
        ],
        '/api/products' => [
            'POST' => ProductCreateData::class,
            'PUT' => ProductUpdateData::class
        ]
    ]
];
```

### API-Controller mit Validierung

```php
class ApiController
{
    public function createUser(Request $request): Response
    {
        // Die Validierung wurde bereits durch die Middleware durchgeführt
        // Wenn wir hier sind, waren die Daten gültig
        
        $userData = $request->getJsonData();
        $user = $this->userService->createUser($userData);
        
        return new Response(201, [], [
            'success' => true,
            'user' => $user->toArray()
        ]);
    }
}
```

### Fehlerbehandlung für API-Validierung

Die `InputValidationMiddleware` gibt automatisch eine Fehlerantwort zurück, wenn die Validierung fehlschlägt:

```json
{
    "error": "Validation failed",
    "validation_errors": {
        "name": ["Der Name ist erforderlich."],
        "email": ["Bitte geben Sie eine gültige E-Mail-Adresse ein."]
    }
}
```

## Leistungsoptimierung

### Validierungs-Cache

Für häufig validierte Objekte kann ein Cache verwendet werden, um die Leistung zu verbessern:

```php
use App\Framework\Validation\ValidationCacheDecorator;

// Cache-Decorator erstellen
$cachedValidator = new ValidationCacheDecorator($validator, $cache);

// Validierung mit Cache durchführen
$result = $cachedValidator->validate($userData);
```

### Validierungsgruppen für partielle Validierung

Verwenden Sie Validierungsgruppen, um nur die relevanten Teile eines Objekts zu validieren:

```php
// Nur die für die Aktualisierung relevanten Felder validieren
$result = $validator->validate($userData, 'update');
```

## Fehlerbehebung

### Häufige Probleme und Lösungen

#### Validierungsregeln werden nicht angewendet

Stellen Sie sicher, dass:
- Die Attribute korrekt definiert sind
- Die Eigenschaften für den Validator zugänglich sind (public oder mit Reflection)
- Der Validator korrekt initialisiert wurde

```php
// Korrekte Initialisierung des Validators
$validator = new Validator($reflectionProvider);
```

#### Falsche Fehlermeldungen

Überprüfen Sie die Reihenfolge der Validierungsregeln:

```php
// Korrekte Reihenfolge: Required vor anderen Regeln
#[Required]
#[Email]
public string $email;
```

#### Leistungsprobleme

Verwenden Sie den ValidationCacheDecorator und vermeiden Sie zu komplexe Validierungsregeln:

```php
// Einfache Regeln verwenden
#[StringLength(max: 255)] // Besser als komplexe reguläre Ausdrücke
public string $name;
```

## Weiterführende Informationen

- [Validation Framework Übersicht](index.md)
- [Verfügbare Validierungsregeln](rules.md)
- [API-Validierung](/guides/api-validation.md)
