| Server IP : 65.108.144.40 / Your IP : 216.73.217.165 Web Server : Apache/2.4.52 (Ubuntu) System : Linux ubuntu-8gb-hel1-1 5.15.0-173-generic #183-Ubuntu SMP Fri Mar 6 13:29:34 UTC 2026 x86_64 User : dev ( 1000) PHP Version : 8.2.30 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : ON Directory : /var/www/html/project-slim/app/Validators/ |
Upload File : |
<?php
namespace App\Validators;
use App\Exceptions\ValidationException;
/**
* Base validator with comprehensive validation methods
*/
abstract class BaseValidator
{
protected array $data = [];
protected array $errors = [];
/**
* Clear all validation errors
*/
protected function clearErrors(): void
{
$this->errors = [];
}
/**
* Add an error for a specific field
*/
protected function addError(string $field, string $message): void
{
if (!isset($this->errors[$field])) {
$this->errors[$field] = [];
}
$this->errors[$field][] = $message;
}
/**
* Check if there are any validation errors
*/
protected function hasErrors(): bool
{
return !empty($this->errors);
}
/**
* Get all validation errors
*/
protected function getErrors(): array
{
return $this->errors;
}
/**
* Throw ValidationException if there are errors
*/
protected function throwIfErrors(string $message = 'Validation failed'): void
{
if ($this->hasErrors()) {
throw new ValidationException($message, $this->errors);
}
}
/**
* Validate that a field is required (not empty)
*/
public function required(string $field, ?string $message = null): self
{
if (!isset($this->data[$field]) || empty($this->data[$field])) {
$this->addError($field, $message ?? "{$field} is required");
}
return $this;
}
/**
* Validate email format
*/
public function email(string $field, ?string $message = null): self
{
if (isset($this->data[$field]) && !empty($this->data[$field])) {
if (!filter_var($this->data[$field], FILTER_VALIDATE_EMAIL)) {
$this->addError($field, $message ?? 'Please enter a valid email address');
}
}
return $this;
}
/**
* Validate minimum length
*/
public function minLength(string $field, int $length, ?string $message = null): self
{
if (isset($this->data[$field]) && !empty($this->data[$field])) {
if (strlen($this->data[$field]) < $length) {
$this->addError($field, $message ?? "{$field} must be at least {$length} characters long");
}
}
return $this;
}
/**
* Validate maximum length
*/
public function maxLength(string $field, int $length, ?string $message = null): self
{
if (isset($this->data[$field]) && !empty($this->data[$field])) {
if (strlen($this->data[$field]) > $length) {
$this->addError($field, $message ?? "{$field} must not exceed {$length} characters");
}
}
return $this;
}
/**
* Validate phone number format
*/
public function phone(string $field, ?string $message = null): self
{
if (isset($this->data[$field]) && !empty($this->data[$field])) {
// Remove all non-digit characters except +
$cleaned = preg_replace('/[^\d+]/', '', $this->data[$field]);
// Check if it's a valid international phone number format
if (!preg_match('/^[\+]?[1-9]\d{9,14}$/', $cleaned)) {
$this->addError($field, $message ?? 'Please enter a valid phone number (10-15 digits)');
}
}
return $this;
}
/**
* Validate numeric value
*/
public function numeric(string $field, ?string $message = null): self
{
if (isset($this->data[$field]) && !empty($this->data[$field])) {
if (!is_numeric($this->data[$field])) {
$this->addError($field, $message ?? "{$field} must be a numeric value");
}
}
return $this;
}
/**
* Validate integer value
*/
public function integer(string $field, ?string $message = null): self
{
if (isset($this->data[$field]) && !empty($this->data[$field])) {
if (!filter_var($this->data[$field], FILTER_VALIDATE_INT)) {
$this->addError($field, $message ?? "{$field} must be a valid integer");
}
}
return $this;
}
/**
* Validate minimum value
*/
public function min(string $field, float $min, ?string $message = null): self
{
if (isset($this->data[$field]) && !empty($this->data[$field])) {
if (is_numeric($this->data[$field]) && (float)$this->data[$field] < $min) {
$this->addError($field, $message ?? "{$field} must be at least {$min}");
}
}
return $this;
}
/**
* Validate maximum value
*/
public function max(string $field, float $max, ?string $message = null): self
{
if (isset($this->data[$field]) && !empty($this->data[$field])) {
if (is_numeric($this->data[$field]) && (float)$this->data[$field] > $max) {
$this->addError($field, $message ?? "{$field} must not exceed {$max}");
}
}
return $this;
}
/**
* Validate that two fields match
*/
public function matches(string $field, string $otherField, ?string $message = null): self
{
if (isset($this->data[$field]) && isset($this->data[$otherField])) {
if ($this->data[$field] !== $this->data[$otherField]) {
$this->addError($field, $message ?? "{$field} does not match {$otherField}");
}
}
return $this;
}
/**
* Validate strong password
*/
public function strongPassword(string $field, ?string $message = null): self
{
if (isset($this->data[$field]) && !empty($this->data[$field])) {
$password = $this->data[$field];
$errors = [];
if (strlen($password) < 8) {
$errors[] = 'at least 8 characters long';
}
if (!preg_match('/[a-z]/', $password)) {
$errors[] = 'contain at least one lowercase letter';
}
if (!preg_match('/[A-Z]/', $password)) {
$errors[] = 'contain at least one uppercase letter';
}
if (!preg_match('/\d/', $password)) {
$errors[] = 'contain at least one number';
}
if (!preg_match('/[^\w\s]/', $password)) {
$errors[] = 'contain at least one special character';
}
if (!empty($errors)) {
$defaultMessage = 'Password must ' . implode(', ', $errors);
$this->addError($field, $message ?? $defaultMessage);
}
}
return $this;
}
/**
* Validate URL format
*/
public function url(string $field, ?string $message = null): self
{
if (isset($this->data[$field]) && !empty($this->data[$field])) {
if (!filter_var($this->data[$field], FILTER_VALIDATE_URL)) {
$this->addError($field, $message ?? 'Please enter a valid URL');
}
}
return $this;
}
/**
* Validate that value is in allowed list
*/
public function in(string $field, array $allowed, ?string $message = null): self
{
if (isset($this->data[$field]) && !empty($this->data[$field])) {
if (!in_array($this->data[$field], $allowed)) {
$allowedStr = implode(', ', $allowed);
$this->addError($field, $message ?? "{$field} must be one of: {$allowedStr}");
}
}
return $this;
}
/**
* Validate date format
*/
public function date(string $field, string $format = 'Y-m-d', ?string $message = null): self
{
if (isset($this->data[$field]) && !empty($this->data[$field])) {
$date = \DateTime::createFromFormat($format, $this->data[$field]);
if (!$date || $date->format($format) !== $this->data[$field]) {
$this->addError($field, $message ?? "{$field} must be a valid date in {$format} format");
}
}
return $this;
}
/**
* Validate boolean value
*/
public function boolean(string $field, ?string $message = null): self
{
if (isset($this->data[$field])) {
if (!is_bool($this->data[$field]) && !in_array($this->data[$field], [0, 1, '0', '1', 'true', 'false'], true)) {
$this->addError($field, $message ?? "{$field} must be a boolean value");
}
}
return $this;
}
/**
* Validate using regular expression
*/
public function regex(string $field, string $pattern, ?string $message = null): self
{
if (isset($this->data[$field]) && !empty($this->data[$field])) {
if (!preg_match($pattern, $this->data[$field])) {
$this->addError($field, $message ?? "{$field} format is invalid");
}
}
return $this;
}
}