|
| 1 | +<?php |
| 2 | + |
| 3 | +namespace Monster\App\Models; |
| 4 | + |
| 5 | +class Validation |
| 6 | +{ |
| 7 | + private $data; |
| 8 | + private $rules; |
| 9 | + private $errors; |
| 10 | + private $lang; |
| 11 | + |
| 12 | + public function __construct(array $data, array $rules, string $lang = 'en') |
| 13 | + { |
| 14 | + $this->data = $data; |
| 15 | + $this->rules = $rules; |
| 16 | + $this->errors = []; |
| 17 | + $this->lang = $this->loadLanguageFile($lang); |
| 18 | + } |
| 19 | + |
| 20 | + public function validate(): bool |
| 21 | + { |
| 22 | + foreach ($this->rules as $field => $rule) { |
| 23 | + $rules = explode('|', $rule); |
| 24 | + |
| 25 | + foreach ($rules as $singleRule) { |
| 26 | + [$ruleName, $params] = $this->parseRule($singleRule); |
| 27 | + |
| 28 | + if (!$this->executeRule($field, $ruleName, $params)) { |
| 29 | + $this->addError($field, $ruleName, $params); |
| 30 | + } |
| 31 | + } |
| 32 | + } |
| 33 | + |
| 34 | + return empty($this->errors); |
| 35 | + } |
| 36 | + |
| 37 | + public function getErrors(): array |
| 38 | + { |
| 39 | + return $this->errors; |
| 40 | + } |
| 41 | + |
| 42 | + private function parseRule(string $rule): array |
| 43 | + { |
| 44 | + $params = []; |
| 45 | + |
| 46 | + if (strpos($rule, ':') !== false) { |
| 47 | + [$ruleName, $paramsString] = explode(':', $rule, 2); |
| 48 | + $params = explode(',', $paramsString); |
| 49 | + } else { |
| 50 | + $ruleName = $rule; |
| 51 | + } |
| 52 | + |
| 53 | + return [$ruleName, $params]; |
| 54 | + } |
| 55 | + |
| 56 | + private function executeRule(string $field, string $ruleName, array $params): bool |
| 57 | + { |
| 58 | + $value = $this->data[$field] ?? null; |
| 59 | + |
| 60 | + switch ($ruleName) { |
| 61 | + case 'required': |
| 62 | + return isset($value) && $value !== ''; |
| 63 | + case 'min': |
| 64 | + return strlen($value) >= $params[0]; |
| 65 | + case 'max': |
| 66 | + return strlen($value) <= $params[0]; |
| 67 | + case 'email': |
| 68 | + return filter_var($value, FILTER_VALIDATE_EMAIL) !== false; |
| 69 | + case 'number': |
| 70 | + return is_numeric($value); |
| 71 | + case 'regex': |
| 72 | + return preg_match($params[0], $value) === 1; |
| 73 | + case 'url': |
| 74 | + return filter_var($value, FILTER_VALIDATE_URL) !== false; |
| 75 | + // Add more validation rules as needed |
| 76 | + default: |
| 77 | + return false; |
| 78 | + } |
| 79 | + } |
| 80 | + |
| 81 | + private function addError(string $field, string $ruleName, array $params) |
| 82 | + { |
| 83 | + $message = $this->lang[$ruleName] ?? $this->lang['error'] ?? 'Invalid value'; |
| 84 | + $replacements = [':key' => $field, ':value' => $params[0] ?? '']; |
| 85 | + |
| 86 | + foreach ($replacements as $key => $value) { |
| 87 | + $message = str_replace($key, $value, $message); |
| 88 | + } |
| 89 | + |
| 90 | + $this->errors[$field][] = $message; |
| 91 | + } |
| 92 | + |
| 93 | + private function loadLanguageFile(string $lang): array |
| 94 | + { |
| 95 | + $path = __DIR__ . "/../../routes/lang/errors/{$lang}.php"; |
| 96 | + |
| 97 | + if (file_exists($path)) { |
| 98 | + return include $path; |
| 99 | + } |
| 100 | + |
| 101 | + // Fallback language file |
| 102 | + return include __DIR__ . '/../../routes/lang/errors/en.php'; |
| 103 | + } |
| 104 | +} |
0 commit comments