Files
server-manager/src/Core/Validator.php
2026-06-06 17:58:34 -04:00

161 lines
5.4 KiB
PHP
Executable File

<?php
declare(strict_types=1);
namespace ServerManager\Core;
class Validator
{
private array $errors = [];
private array $data;
private array $rules = [];
public function __construct(array $data = [])
{
$this->data = $data;
}
public function validate(array $data, array $rules): bool
{
$this->data = $data;
$this->errors = [];
$this->rules = $rules;
foreach ($rules as $field => $fieldRules) {
$fieldRules = is_string($fieldRules) ? explode('|', $fieldRules) : $fieldRules;
$value = $data[$field] ?? null;
foreach ($fieldRules as $rule) {
$params = [];
if (str_contains($rule, ':')) {
[$rule, $paramStr] = explode(':', $rule, 2);
$params = explode(',', $paramStr);
}
$method = 'validate' . ucfirst($rule);
if (method_exists($this, $method)) {
$this->{$method}($field, $value, $params);
}
}
}
return empty($this->errors);
}
public function getErrors(): array
{
return $this->errors;
}
public function getFirstError(): ?string
{
if (empty($this->errors)) {
return null;
}
$first = reset($this->errors);
return is_array($first) ? reset($first) : $first;
}
public function addError(string $field, string $message): void
{
$this->errors[$field][] = $message;
}
private function validateRequired(string $field, mixed $value, array $params): void
{
if ($value === null || $value === '' || (is_array($value) && empty($value))) {
$this->errors[$field][] = "The {$field} field is required.";
}
}
private function validateEmail(string $field, mixed $value, array $params): void
{
if ($value !== null && $value !== '' && !filter_var($value, FILTER_VALIDATE_EMAIL)) {
$this->errors[$field][] = "The {$field} field must be a valid email address.";
}
}
private function validateMin(string $field, mixed $value, array $params): void
{
$min = (int) ($params[0] ?? 0);
if (is_string($value) && mb_strlen($value) < $min) {
$this->errors[$field][] = "The {$field} field must be at least {$min} characters.";
} elseif (is_numeric($value) && $value < $min) {
$this->errors[$field][] = "The {$field} field must be at least {$min}.";
}
}
private function validateMax(string $field, mixed $value, array $params): void
{
$max = (int) ($params[0] ?? 0);
if (is_string($value) && mb_strlen($value) > $max) {
$this->errors[$field][] = "The {$field} field must not exceed {$max} characters.";
} elseif (is_numeric($value) && $value > $max) {
$this->errors[$field][] = "The {$field} field must not exceed {$max}.";
}
}
private function validatesNumeric(string $field, mixed $value, array $params): void
{
if ($value !== null && $value !== '' && !is_numeric($value)) {
$this->errors[$field][] = "The {$field} field must be a number.";
}
}
private function validatesInteger(string $field, mixed $value, array $params): void
{
if ($value !== null && $value !== '' && filter_var($value, FILTER_VALIDATE_INT) === false) {
$this->errors[$field][] = "The {$field} field must be an integer.";
}
}
private function validatesIp(string $field, mixed $value, array $params): void
{
if ($value !== null && $value !== '' && !filter_var($value, FILTER_VALIDATE_IP)) {
$this->errors[$field][] = "The {$field} field must be a valid IP address or hostname.";
}
}
private function validatesPort(string $field, mixed $value, array $params): void
{
if ($value !== null && $value !== '') {
$port = (int) $value;
if ($port < 1 || $port > 65535) {
$this->errors[$field][] = "The {$field} field must be a valid port (1-65535).";
}
}
}
private function validatesAlphaNum(string $field, mixed $value, array $params): void
{
if ($value !== null && $value !== '' && !preg_match('/^[a-zA-Z0-9_\-]+$/', $value)) {
$this->errors[$field][] = "The {$field} field may only contain letters, numbers, dashes and underscores.";
}
}
private function validatesMatch(string $field, mixed $value, array $params): void
{
$otherField = $params[0] ?? null;
if ($otherField && ($this->data[$otherField] ?? null) !== $value) {
$this->errors[$field][] = "The {$field} field does not match {$otherField}.";
}
}
private function validatesIn(string $field, mixed $value, array $params): void
{
if ($value !== null && $value !== '' && !in_array($value, $params, true)) {
$this->errors[$field][] = "The selected {$field} is invalid.";
}
}
private function validatesJson(string $field, mixed $value, array $params): void
{
if ($value !== null && $value !== '' && is_string($value)) {
json_decode($value);
if (json_last_error() !== JSON_ERROR_NONE) {
$this->errors[$field][] = "The {$field} field must be valid JSON.";
}
}
}
}