ValidationService.php

6.74 KB
27/04/2025 13:38
PHP
ValidationService.php
<?php
class ValidationService
{
    /**
     * @var array
     */
    private $errors = [];

    /**
     * @param $data
     * @param $rules
     */
    public function validate($data, $rules)
    {
        $this->errors = [];

        foreach ($rules as $field => $fieldRules) {
            foreach ($fieldRules as $rule) {
                // Check if the rule has parameters
                if (strpos($rule, ':') !== false) {
                    list($ruleName, $ruleParam) = explode(':', $rule, 2);
                } else {
                    $ruleName = $rule;
                    $ruleParam = null;
                }

                // Skip validation if the field is not required and empty
                if ($ruleName !== 'required' && (!isset($data[$field]) || $data[$field] === '')) {
                    continue;
                }

                // Validate according to rule
                $method = 'validate'.ucfirst($ruleName);
                if (method_exists($this, $method)) {
                    $this->$method($field, $data[$field] ?? null, $ruleParam);
                }
            }
        }

        return empty($this->errors);
    }

    /**
     * @return mixed
     */
    public function getErrors()
    {
        return $this->errors;
    }

    /**
     * @return mixed
     */
    public function getFirstError()
    {
        foreach ($this->errors as $field => $errors) {
            if (!empty($errors)) {
                return $errors[0];
            }
        }
        return null;
    }

    /**
     * @param $field
     * @param $value
     * @param $param
     */
    private function validateRequired($field, $value, $param = null)
    {
        if (!isset($value) || $value === '') {
            $this->errors[$field][] = "The $field field is required.";
        }
    }

    /**
     * @param $field
     * @param $value
     * @param $param
     */
    private function validateEmail($field, $value, $param = null)
    {
        if (!filter_var($value, FILTER_VALIDATE_EMAIL)) {
            $this->errors[$field][] = "The $field must be a valid email address.";
        }
    }

    /**
     * @param $field
     * @param $value
     * @param $param
     */
    private function validateMin($field, $value, $param)
    {
        if (is_string($value) && mb_strlen($value) < $param) {
            $this->errors[$field][] = "The $field must be at least $param characters.";
        } elseif (is_numeric($value) && $value < $param) {
            $this->errors[$field][] = "The $field must be at least $param.";
        }
    }

    /**
     * @param $field
     * @param $value
     * @param $param
     */
    private function validateMax($field, $value, $param)
    {
        if (is_string($value) && mb_strlen($value) > $param) {
            $this->errors[$field][] = "The $field may not be greater than $param characters.";
        } elseif (is_numeric($value) && $value > $param) {
            $this->errors[$field][] = "The $field may not be greater than $param.";
        }
    }

    /**
     * @param $field
     * @param $value
     * @param $param
     */
    private function validateNumeric($field, $value, $param = null)
    {
        if (!is_numeric($value)) {
            $this->errors[$field][] = "The $field must be a number.";
        }
    }

    /**
     * @param $field
     * @param $value
     * @param $param
     */
    private function validateInteger($field, $value, $param = null)
    {
        if (!filter_var($value, FILTER_VALIDATE_INT)) {
            $this->errors[$field][] = "The $field must be an integer.";
        }
    }

    /**
     * @param $field
     * @param $value
     * @param $param
     */
    private function validateFloat($field, $value, $param = null)
    {
        if (!filter_var($value, FILTER_VALIDATE_FLOAT)) {
            $this->errors[$field][] = "The $field must be a decimal number.";
        }
    }

    /**
     * @param $field
     * @param $value
     * @param $param
     */
    private function validateAlpha($field, $value, $param = null)
    {
        if (!ctype_alpha($value)) {
            $this->errors[$field][] = "The $field may only contain letters.";
        }
    }

    /**
     * @param $field
     * @param $value
     * @param $param
     */
    private function validateAlphaNum($field, $value, $param = null)
    {
        if (!ctype_alnum($value)) {
            $this->errors[$field][] = "The $field may only contain letters and numbers.";
        }
    }

    /**
     * @param $field
     * @param $value
     * @param $param
     */
    private function validateUrl($field, $value, $param = null)
    {
        if (!filter_var($value, FILTER_VALIDATE_URL)) {
            $this->errors[$field][] = "The $field must be a valid URL.";
        }
    }

    /**
     * @param $field
     * @param $value
     * @param $param
     */
    private function validateDate($field, $value, $param = null)
    {
        if (!strtotime($value)) {
            $this->errors[$field][] = "The $field must be a valid date.";
        }
    }

    /**
     * @param $field
     * @param $value
     * @param $param
     */
    private function validateIn($field, $value, $param)
    {
        $allowedValues = explode(',', $param);
        if (!in_array($value, $allowedValues)) {
            $this->errors[$field][] = "The selected $field is invalid.";
        }
    }

    /**
     * @param $field
     * @param $value
     * @param $param
     */
    private function validateUnique($field, $value, $param)
    {
        list($table, $column, $exceptId) = array_pad(explode(',', $param), 3, null);

        $db = Database::getInstance();

        $query = "SELECT COUNT(*) FROM $table WHERE $column = ?";
        $params = [$value];

        if ($exceptId) {
            $query .= " AND id != ?";
            $params[] = $exceptId;
        }

        $count = $db->fetchColumn($query, $params);

        if ($count > 0) {
            $this->errors[$field][] = "The $field has already been taken.";
        }
    }

    /**
     * @param $field
     * @param $value
     * @param $param
     */
    private function validateExists($field, $value, $param)
    {
        list($table, $column) = explode(',', $param);

        $db = Database::getInstance();

        $query = "SELECT COUNT(*) FROM $table WHERE $column = ?";
        $count = $db->fetchColumn($query, [$value]);

        if ($count == 0) {
            $this->errors[$field][] = "The selected $field is invalid.";
        }
    }

    /**
     * @param $field
     * @param $value
     * @param $param
     */
    private function validateConfirmed($field, $value, $param = null)
    {
        $confirmation = $field.'_confirmation';

        if (!isset($_POST[$confirmation]) || $value !== $_POST[$confirmation]) {
            $this->errors[$field][] = "The $field confirmation does not match.";
        }
    }
}