161 lines
5.4 KiB
PHP
Executable File
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.";
|
|
}
|
|
}
|
|
}
|
|
}
|