'asko@bien.ee']; * $validators = ['email' => 'required|email']; * $validator = new Validator($fields, $validators); * * if ($validator->fails()) { * return $validator->errors(); * } * ``` * * @author Asko Nomm */ class Validator { private array $errors = []; public function __construct( private array $fields, private array $validators, array $rules = [], ) { if (empty($rules)) { $this->rules = $this->defaultRules(); } $this->validate(); } /** * Returns the default, built-in validation rules. * * @return array */ public function defaultRules(): array { return [ 'len' => ValidatorRules::len(), 'email' => ValidatorRules::email(), 'required' => ValidatorRules::required(), ]; } /** * Runs `$this->validators` over `$this->fields` to construct * potential errors that will be stored as an array of strings * in `$this->errors`. * * @return void */ private function validate(): void { foreach ($this->validators as $field => $validator) { $value = $this->fields[$field]; foreach (explode('|', $validator) as $item) { if (str_contains($item, ':')) { [$name, $modifier] = explode(':', $item); if (!$this->rules[$name]['validates']($value, $modifier)) { $this->errors[] = $this->rules[$name]['error']($field, $modifier); } } else { if (!$this->rules[$item]['validates']($value)) { $this->errors[] = $this->rules[$item]['error']($field); } } } } } /** * Returns a boolean `true` if there have been any errors. * Returns `false` otherwise. * * @return boolean */ public function fails(): bool { return count($this->errors) !== 0; } /** * Returns an array of strings where each string * is a single error that happened during validation. * * @return array */ public function errors(): array { return $this->errors; } /** * If errors are present, returns the first one. * Otherwise returns an empty string. * * @return string */ public function firstError(): string { if (count($this->errors) > 0) { return $this->errors[0]; } return ''; } }