<?php

class FormInputFilter {
    
    /**
     * Hauptfunktion zur Filterung verschiedener Input-Typen
     * 
     * @param mixed $input Der zu filternde Input
     * @param string $type Der Typ des Inputs ('string', 'number', 'email', 'url')
     * @param array $options Zusätzliche Optionen für die Filterung
     * @return mixed Gefilterter Input oder false bei ungültigen Daten
     */
    public static function filterInput($input, $type, $options = []) {
        // Basis-Sanitizing für alle Inputs
        $input = trim($input);
        
        switch (strtolower($type)) {
            case 'string':
                return self::filterString($input, $options);
            case 'number':
            case 'integer':
            case 'int':
                return self::filterNumber($input, $options);
            case 'email':
                return self::filterEmail($input);
            case 'url':
                return self::filterUrl($input);
            default:
                return self::filterString($input, $options);
        }
    }
    
    /**
     * Filtert String-Eingaben
     */
    private static function filterString($input, $options = []) {
        // Standard-Optionen
        $defaults = [
            'allow_html' => false,
            'max_length' => 1000,
            'min_length' => 0,
            'allowed_chars' => null, // Regex für erlaubte Zeichen
            'strip_tags' => true
        ];
        
        $options = array_merge($defaults, $options);
        
        // Längenprüfung
        if (strlen($input) > $options['max_length'] || strlen($input) < $options['min_length']) {
            return false;
        }
        
        // HTML-Tags entfernen wenn nicht erlaubt
        if (!$options['allow_html'] && $options['strip_tags']) {
            $input = strip_tags($input);
        }
        
        // HTML-Entities kodieren für Sicherheit
        $input = htmlspecialchars($input, ENT_QUOTES, 'UTF-8');
        
        // Spezielle Zeichen-Validierung
        if ($options['allowed_chars'] && !preg_match($options['allowed_chars'], $input)) {
            return false;
        }
        
        // Gefährliche Zeichen entfernen
        $input = preg_replace('/[<>"\']/', '', $input);
        
        return $input;
    }
    
    /**
     * Filtert numerische Eingaben
     */
    private static function filterNumber($input, $options = []) {
        $defaults = [
            'allow_float' => true,
            'allow_negative' => true,
            'min_value' => null,
            'max_value' => null
        ];
        
        $options = array_merge($defaults, $options);
        
        // Nur Zahlen, Punkte, Kommas und Minus erlauben
        $input = preg_replace('/[^0-9.,-]/', '', $input);
        
        // Komma zu Punkt für float-Konvertierung
        $input = str_replace(',', '.', $input);
        
        if ($options['allow_float']) {
            $number = filter_var($input, FILTER_VALIDATE_FLOAT);
        } else {
            $number = filter_var($input, FILTER_VALIDATE_INT);
        }
        
        if ($number === false) {
            return false;
        }
        
        // Negative Zahlen prüfen
        if (!$options['allow_negative'] && $number < 0) {
            return false;
        }
        
        // Min/Max Werte prüfen
        if ($options['min_value'] !== null && $number < $options['min_value']) {
            return false;
        }
        
        if ($options['max_value'] !== null && $number > $options['max_value']) {
            return false;
        }
        
        return $number;
    }
    
    /**
     * Filtert E-Mail-Adressen
     */
    private static function filterEmail($input) {
        // Basis-Sanitizing
        $email = filter_var($input, FILTER_SANITIZE_EMAIL);
        
        // E-Mail-Validierung
        if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
            return false;
        }
        
        // Zusätzliche Sicherheitsprüfungen
        if (strlen($email) > 254) { // RFC 5321 Limit
            return false;
        }
        
        // Gefährliche Zeichen prüfen
        if (preg_match('/[<>"\']/', $email)) {
            return false;
        }
        
        return $email;
    }
    
    /**
     * Filtert URLs
     */
    private static function filterUrl($input) {
        // URL säubern
        $url = filter_var($input, FILTER_SANITIZE_URL);
        
        // URL-Validierung
        if (!filter_var($url, FILTER_VALIDATE_URL)) {
            return false;
        }
        
        // Nur HTTP/HTTPS erlauben
        $parsed_url = parse_url($url);
        if (!isset($parsed_url['scheme']) || !in_array($parsed_url['scheme'], ['http', 'https'])) {
            return false;
        }
        
        // Länge prüfen
        if (strlen($url) > 2048) {
            return false;
        }
        
        return $url;
    }
    
    /**
     * Filtert mehrere Formular-Felder auf einmal
     * 
     * @param array $data Assoziatives Array mit Feldname => Wert
     * @param array $rules Assoziatives Array mit Feldname => ['type' => 'string', 'options' => []]
     * @return array Gefiltertes Array oder false bei Fehlern
     */
    public static function filterFormData($data, $rules) {
        $filtered_data = [];
        $errors = [];
        
        foreach ($rules as $field => $rule) {
            if (!isset($data[$field])) {
                $errors[$field] = "Feld fehlt";
                continue;
            }
            
            $type = $rule['type'] ?? 'string';
            $options = $rule['options'] ?? [];
            
            $filtered_value = self::filterInput($data[$field], $type, $options);
            
            if ($filtered_value === false) {
                $errors[$field] = "Ungültiger Wert";
                continue;
            }
            
            $filtered_data[$field] = $filtered_value;
        }
        
        return empty($errors) ? $filtered_data : ['errors' => $errors];
    }
}

// Beispiel-Verwendung:

// Einzelne Werte filtern
/*$name = FormInputFilter::filterInput($_POST['name'] ?? '', 'string', [
    'max_length' => 100,
    'min_length' => 2
]);

$age = FormInputFilter::filterInput($_POST['age'] ?? '', 'number', [
    'allow_float' => false,
    'min_value' => 0,
    'max_value' => 150
]);

$email = FormInputFilter::filterInput($_POST['email'] ?? '', 'email');

$website = FormInputFilter::filterInput($_POST['website'] ?? '', 'url');

// Komplettes Formular filtern
$form_data = [
    'name' => 'John Doe',
    'email' => 'john@example.com',
    'age' => '25',
    'website' => 'https://example.com'
];

$rules = [
    'name' => [
        'type' => 'string',
        'options' => ['max_length' => 100, 'min_length' => 2]
    ],
    'email' => [
        'type' => 'email'
    ],
    'age' => [
        'type' => 'number',
        'options' => ['allow_float' => false, 'min_value' => 0, 'max_value' => 80]
    ],
    'website' => [
        'type' => 'url'
    ]
];

$result = FormInputFilter::filterFormData($form_data, $rules);

if (isset($result['errors'])) {
    // Fehler behandeln
    print_r($result['errors']);
} else {
    // Gefilterte Daten verwenden
    print_r($result);
}
 */ 
?>
