# Validierungsregeln

> **Dokumentationshinweis:** Diese Dokumentation ist vollständig aktualisiert und stellt die aktuelle Implementierung der Validierungsregeln korrekt dar.

## Übersicht

Das Validation Framework bietet eine umfangreiche Sammlung vordefinierter Validierungsregeln, die als PHP-Attribute verwendet werden können. Diese Regeln können auf Objekteigenschaften angewendet werden, um Daten zu validieren und sicherzustellen, dass sie den erwarteten Anforderungen entsprechen.

## Grundlegende Regeln

### Required

Die `Required`-Regel stellt sicher, dass ein Wert vorhanden ist und nicht leer ist:

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

class UserData
{
    #[Required]
    public string $username;
    
    #[Required(message: "Die E-Mail-Adresse ist erforderlich.")]
    public string $email;
}
```

**Parameter:**
- `message` (optional): Benutzerdefinierte Fehlermeldung
- `groups` (optional): Array von Validierungsgruppen, zu denen diese Regel gehört

**Validierungslogik:**
- Gibt `false` zurück, wenn der Wert `null` oder ein leerer String ist
- Gibt `true` zurück für alle anderen Werte, einschließlich `0` und `false`

### Email

Die `Email`-Regel validiert, dass ein Wert eine gültige E-Mail-Adresse ist:

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

class UserData
{
    #[Email]
    public string $email;
    
    #[Email(message: "Bitte geben Sie eine gültige E-Mail-Adresse ein.")]
    public string $alternativeEmail;
}
```

**Parameter:**
- `message` (optional): Benutzerdefinierte Fehlermeldung

**Validierungslogik:**
- Verwendet `filter_var()` mit `FILTER_VALIDATE_EMAIL` zur Validierung
- Leere Werte werden als gültig betrachtet (verwenden Sie `Required` in Kombination, um leere Werte zu verhindern)

### StringLength

Die `StringLength`-Regel validiert die Länge eines Strings:

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

class UserData
{
    #[StringLength(min: 3, max: 50)]
    public string $username;
    
    #[StringLength(min: 8, message: "Das Passwort muss mindestens 8 Zeichen lang sein.")]
    public string $password;
    
    #[StringLength(max: 500)]
    public ?string $bio;
}
```

**Parameter:**
- `min` (optional): Minimale Länge des Strings
- `max` (optional): Maximale Länge des Strings
- `message` (optional): Benutzerdefinierte Fehlermeldung

**Validierungslogik:**
- Mindestens einer der Parameter `min` oder `max` muss gesetzt sein
- Verwendet `mb_strlen()` für korrekte Behandlung von Multibyte-Zeichen
- Leere Werte werden als gültig betrachtet (verwenden Sie `Required` in Kombination, um leere Werte zu verhindern)

### Url

Die `Url`-Regel validiert, dass ein Wert eine gültige URL ist:

```php
use App\Framework\Validation\Rules\Url;

class UserData
{
    #[Url]
    public string $website;
    
    #[Url(message: "Bitte geben Sie eine gültige URL ein.")]
    public string $profileUrl;
}
```

**Parameter:**
- `message` (optional): Benutzerdefinierte Fehlermeldung

**Validierungslogik:**
- Verwendet `filter_var()` mit `FILTER_VALIDATE_URL` zur Validierung
- Leere Werte werden als gültig betrachtet (verwenden Sie `Required` in Kombination, um leere Werte zu verhindern)

### Numeric

Die `Numeric`-Regel validiert, dass ein Wert numerisch ist:

```php
use App\Framework\Validation\Rules\Numeric;

class ProductData
{
    #[Numeric]
    public $price;
    
    #[Numeric(message: "Die Menge muss eine Zahl sein.")]
    public $quantity;
}
```

**Parameter:**
- `message` (optional): Benutzerdefinierte Fehlermeldung

**Validierungslogik:**
- Verwendet `is_numeric()` zur Validierung
- Leere Werte werden als gültig betrachtet (verwenden Sie `Required` in Kombination, um leere Werte zu verhindern)

## Erweiterte Regeln

### Pattern

Die `Pattern`-Regel validiert einen Wert gegen einen regulären Ausdruck:

```php
use App\Framework\Validation\Rules\Pattern;

class UserData
{
    #[Pattern(pattern: '/^[a-zA-Z0-9_]+$/', message: "Der Benutzername darf nur Buchstaben, Zahlen und Unterstriche enthalten.")]
    public string $username;
}
```

**Parameter:**
- `pattern`: Regulärer Ausdruck für die Validierung
- `message` (optional): Benutzerdefinierte Fehlermeldung

**Validierungslogik:**
- Verwendet `preg_match()` zur Validierung gegen den angegebenen regulären Ausdruck
- Leere Werte werden als gültig betrachtet (verwenden Sie `Required` in Kombination, um leere Werte zu verhindern)

### Range

Die `Range`-Regel validiert, dass ein numerischer Wert innerhalb eines bestimmten Bereichs liegt:

```php
use App\Framework\Validation\Rules\Range;

class ProductData
{
    #[Range(min: 0)]
    public float $price;
    
    #[Range(min: 1, max: 100, message: "Die Menge muss zwischen 1 und 100 liegen.")]
    public int $quantity;
}
```

**Parameter:**
- `min` (optional): Minimaler Wert
- `max` (optional): Maximaler Wert
- `message` (optional): Benutzerdefinierte Fehlermeldung

**Validierungslogik:**
- Mindestens einer der Parameter `min` oder `max` muss gesetzt sein
- Leere Werte werden als gültig betrachtet (verwenden Sie `Required` in Kombination, um leere Werte zu verhindern)

### In

Die `In`-Regel validiert, dass ein Wert in einer Liste gültiger Werte enthalten ist:

```php
use App\Framework\Validation\Rules\In;

class ProductData
{
    #[In(values: ['small', 'medium', 'large'])]
    public string $size;
    
    #[In(values: [1, 2, 3, 4, 5], message: "Bitte wählen Sie eine gültige Kategorie.")]
    public int $category;
}
```

**Parameter:**
- `values`: Array gültiger Werte
- `message` (optional): Benutzerdefinierte Fehlermeldung

**Validierungslogik:**
- Verwendet `in_array()` zur Validierung
- Leere Werte werden als gültig betrachtet (verwenden Sie `Required` in Kombination, um leere Werte zu verhindern)

### DateFormat

Die `DateFormat`-Regel validiert, dass ein Wert ein gültiges Datum in einem bestimmten Format ist:

```php
use App\Framework\Validation\Rules\DateFormat;

class EventData
{
    #[DateFormat(format: 'Y-m-d')]
    public string $date;
    
    #[DateFormat(format: 'Y-m-d H:i:s', message: "Bitte geben Sie ein gültiges Datum und eine gültige Uhrzeit ein.")]
    public string $datetime;
}
```

**Parameter:**
- `format`: Das erwartete Datumsformat (PHP date()-Format)
- `message` (optional): Benutzerdefinierte Fehlermeldung

**Validierungslogik:**
- Verwendet `DateTime::createFromFormat()` zur Validierung
- Leere Werte werden als gültig betrachtet (verwenden Sie `Required` in Kombination, um leere Werte zu verhindern)

### Phone

Die `Phone`-Regel validiert, dass ein Wert eine gültige Telefonnummer ist:

```php
use App\Framework\Validation\Rules\Phone;

class ContactData
{
    #[Phone]
    public string $phoneNumber;
    
    #[Phone(message: "Bitte geben Sie eine gültige Telefonnummer ein.")]
    public string $mobileNumber;
}
```

**Parameter:**
- `message` (optional): Benutzerdefinierte Fehlermeldung

**Validierungslogik:**
- Validiert Telefonnummern mit einem flexiblen Muster, das verschiedene Formate unterstützt
- Leere Werte werden als gültig betrachtet (verwenden Sie `Required` in Kombination, um leere Werte zu verhindern)

### Ulid

Die `Ulid`-Regel validiert, dass ein Wert ein gültiger ULID (Universally Unique Lexicographically Sortable Identifier) ist:

```php
use App\Framework\Validation\Rules\Ulid;

class EntityData
{
    #[Ulid]
    public string $id;
    
    #[Ulid(message: "Die ID muss ein gültiger ULID sein.")]
    public string $parentId;
}
```

**Parameter:**
- `message` (optional): Benutzerdefinierte Fehlermeldung

**Validierungslogik:**
- Validiert, dass der Wert ein gültiger ULID ist (26 Zeichen, Base32-Kodierung)
- Leere Werte werden als gültig betrachtet (verwenden Sie `Required` in Kombination, um leere Werte zu verhindern)

### IsTrue

Die `IsTrue`-Regel validiert, dass ein Wert `true` ist:

```php
use App\Framework\Validation\Rules\IsTrue;

class RegistrationData
{
    #[IsTrue(message: "Sie müssen die Nutzungsbedingungen akzeptieren.")]
    public bool $termsAccepted;
}
```

**Parameter:**
- `message` (optional): Benutzerdefinierte Fehlermeldung

**Validierungslogik:**
- Gibt `true` zurück, wenn der Wert `true` ist
- Gibt `false` zurück für alle anderen Werte
- Leere Werte werden als ungültig betrachtet

## Benutzerdefinierte Regeln

### Custom

Die `Custom`-Regel ermöglicht die Definition einer benutzerdefinierten Validierungslogik mit einer Callback-Funktion:

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

class UserData
{
    #[Custom(callback: 'validateUsername', message: "Der Benutzername ist ungültig.")]
    public string $username;
    
    private function validateUsername($value): bool
    {
        // Benutzerdefinierte Validierungslogik
        return preg_match('/^[a-zA-Z0-9_]{3,20}$/', $value) === 1;
    }
}
```

**Parameter:**
- `callback`: Name der Callback-Methode oder Closure
- `message` (optional): Benutzerdefinierte Fehlermeldung

**Validierungslogik:**
- Ruft die angegebene Callback-Funktion auf und gibt deren Rückgabewert zurück
- Leere Werte werden an die Callback-Funktion übergeben

## Eigene Validierungsregeln erstellen

Sie können eigene Validierungsregeln erstellen, indem Sie das `ValidationRule`-Interface implementieren:

```php
use App\Framework\Validation\ValidationRule;
use Attribute;

#[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."];
    }
}
```

## Validierungsgruppen

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

```php
use App\Framework\Validation\ValidationRule;
use App\Framework\Validation\GroupAware;
use Attribute;

#[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);
    }
}
```

## Kombinieren von Regeln

Validierungsregeln können kombiniert werden, um komplexe Validierungsanforderungen zu erfüllen:

```php
class UserData
{
    #[Required]
    #[StringLength(min: 3, max: 50)]
    #[Pattern(pattern: '/^[a-zA-Z0-9_]+$/')]
    public string $username;
    
    #[Required]
    #[Email]
    public string $email;
    
    #[Required]
    #[StringLength(min: 8)]
    #[Custom(callback: 'validatePassword')]
    public string $password;
    
    private function validatePassword($value): bool
    {
        // Mindestens ein Großbuchstabe, ein Kleinbuchstabe, eine Zahl und ein Sonderzeichen
        return preg_match('/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^a-zA-Z\d]).+$/', $value) === 1;
    }
}
```

## Weiterführende Informationen

- [Validation Framework Übersicht](index.md)
- [Beispiele für die Verwendung von Validierungsregeln](examples.md)
- [API-Validierung](/guides/api-validation.md)
