<?php
/**
* Класс валидации данных
* Выполняет простейшую валидацию данных, длина строк, размеры чисел, сравнение, наличие в списке итд
* @license Code and contributions have MIT License
* @link http://visavi.net
* @author Alexander Grigorev <[email protected]>
*/
class Validation
{
/**
* @var array validation errors
*/
private $errors = [];
/**
* @var array validation rules
*/
private $validation_rules = [];
/**
* the constructor, duh!
*/
public function __construct()
{
}
/**
* run the validation rules
* @return bool;
*/
public function run()
{
foreach (new ArrayIterator($this->validation_rules) as $opt) {
switch ($opt['type']) {
case 'string':
$this->validateString($opt['var'], $opt['label'], $opt['min'], $opt['max'], $opt['required']);
break;
case 'numeric':
$this->validateNumeric($opt['var'], $opt['label'], $opt['min'], $opt['max'], $opt['required']);
break;
case 'max':
$this->validateMax($opt['var'], $opt['label']);
break;
case 'min':
$this->validateMin($opt['var'], $opt['label']);
break;
case 'equal':
$this->validateEqual($opt['var'], $opt['label']);
break;
case 'not_equal':
$this->validateNotEqual($opt['var'], $opt['label']);
break;
case 'empty':
$this->validateEmpty($opt['var'], $opt['label']);
break;
case 'not_empty':
$this->validateNotEmpty($opt['var'], $opt['label']);
break;
case 'in':
$this->validateIn($opt['var'], $opt['label']);
break;
case 'regex':
$this->validateRegex($opt['var'], $opt['label'], $opt['required']);
break;
case 'float':
$this->validateFloat($opt['var'], $opt['label'], $opt['required']);
break;
case 'url':
$this->validateUrl($opt['var'], $opt['label'], $opt['required']);
break;
case 'email':
$this->validateEmail($opt['var'], $opt['label'], $opt['required']);
break;
case 'bool':
$this->validateBool($opt['var'], $opt['label']);
break;
case 'custom':
$this->validateCustom($opt['var'], $opt['label']);
break;
default:
$this->addError('Ошибка! Не найден тип правила "' . $opt['type'] . '"');
}
}
if ($this->getErrors()) {
return false;
}
return true;
}
/**
* add a rule to the validation rules array
* @param string $type The type of variable
* @param string $var The variable
* @param mixed $label The label of variable
* @param bool $required If the field is required
* @param int $min The minimum length or range
* @param int $max The maximum length or range
* @return $this
*/
public function addRule($type, $var, $label, $required = false, $min = 0, $max = 0)
{
$this->validation_rules[] = compact('type', 'var', 'label', 'required', 'min', 'max');
return $this;
}
/**
* displays an error
* @param string $error The error text
* @param null $description
*/
public function addError($error, $description = null)
{
$key = 0;
if (is_array($error)) {
$key = key($error);
$error = current($error);
}
if (isset($this->errors[$key])) {
$this->errors[] = $error.$description;
} else {
$this->errors[$key] = $error.$description;
}
}
/**
* Возвращает список ошибок
* @return array
*/
public function getErrors()
{
return $this->errors;
}
/**
* validate a string
* @param string $var The variable
* @param mixed $label The label of variable
* @param int $min The minimum string length
* @param int $max The maximum string length
* @param bool $required
* @return bool
*/
private function validateString($var, $label, $min = 0, $max = 0, $required = false)
{
if ($required == false && mb_strlen($var, 'utf-8') == 0) {
return true;
}
if (mb_strlen($var, 'utf-8') < $min) {
$this->addError($label, ' (Не менее ' . $min . ' симв.)');
} elseif (mb_strlen($var, 'utf-8') > $max) {
$this->addError($label, ' (Не более ' . $max . ' симв.)');
}
}
/**
* Checks whether numeric input has a minimum value
* @param array $var The variable
* @param mixed $label The label of variable
* @return bool
*/
private function validateMin($var, $label)
{
if (is_array($var) && count($var) == 2 && $var[0] <= $var[1]) {
return true;
} else {
$this->addError($label);
}
}
/**
* Checks whether numeric input has a maximum value
* @param array $var The variable
* @param mixed $label The label of variable
* @return bool
*/
private function validateMax($var, $label)
{
if (is_array($var) && count($var) == 2 && $var[0] >= $var[1]) {
return true;
} else {
$this->addError($label);
}
}
/**
* validate an number
* @param int $var The variable
* @param mixed $label The label of variable
* @param int $min The minimum number range
* @param int $max The maximum number range
* @param bool $required
*
* @return bool
*/
private function validateNumeric($var, $label, $min = 0, $max = 0, $required = false)
{
if ($required == false && mb_strlen($var, 'utf-8') == 0) {
return true;
}
if (filter_var($var, FILTER_VALIDATE_INT, ['options' => ['min_range' => $min, 'max_range' => $max]]) === false) {
$this->addError($label);
}
}
/**
* validate a equality
* @param array $var List of variables
* @param mixed $label The label of variable
* @return bool
*/
private function validateEqual($var, $label)
{
if (is_array($var) && count($var) == 2 && $var[0] === $var[1]) {
return true;
} else {
$this->addError($label);
}
}
/**
* validate the inequality
* @param array $var List of variables
* @param mixed $label The label of variable
* @return bool
*/
private function validateNotEqual($var, $label)
{
if (is_array($var) && count($var) == 2 && $var[0] !== $var[1]) {
return true;
} else {
$this->addError($label);
}
}
/**
* validate is empty
* @param string $var The variable
* @param mixed $label The label of variable
*/
private function validateEmpty($var, $label)
{
if (!empty($var)) {
$this->addError($label);
}
}
/**
* validate is not empty
* @param string $var The variable
* @param mixed $label The label of variable
*/
private function validateNotEmpty($var, $label)
{
if (empty($var)) {
$this->addError($label);
}
}
/**
* validate is InArray
* @param array $var List of variables
* @param mixed $label The label of variable
* @return bool
*/
private function validateIn($var, $label)
{
if (is_array($var) && count($var) == 2 && in_array($var[0], $var[1], true)) {
return true;
} else {
$this->addError($label);
}
}
/**
* validate on a regular expression
* @param string $var The variable
* @param mixed $label The label of variable
* @param bool $required
* @return bool
*/
private function validateRegex($var, $label, $required = false)
{
if (is_array($var) && count($var) == 2 && $required == false && mb_strlen($var[0], 'utf-8') == 0) {
return true;
}
if (!preg_match($var[1], $var[0])) {
$this->addError($label);
}
}
/**
* validate a floating point number
* @param string $var The variable
* @param mixed $label The label of variable
* @param bool $required
* @return bool
*/
private function validateFloat($var, $label, $required = false)
{
if ($required == false && mb_strlen($var, 'utf-8') == 0) {
return true;
}
if (filter_var($var, FILTER_VALIDATE_FLOAT) === false) {
$this->addError($label);
}
}
/**
* validate a url
* @param string $var The variable
* @param mixed $label The label of variable
* @param bool $required
* @return bool
*/
private function validateUrl($var, $label, $required = false)
{
if ($required == false && mb_strlen($var, 'utf-8') == 0) {
return true;
}
if (!preg_match('#^https?://([а-яa-z0-9_\-\.])+(\.([а-яa-z0-9\/])+)+$#u', $var)) {
$this->addError($label);
}
}
/**
* validate a email address
* @param string $var The variable
* @param mixed $label The label of variable
* @param bool $required
* @return bool
*/
private function validateEmail($var, $label, $required = false)
{
if ($required == false && mb_strlen($var, 'utf-8') == 0) {
return true;
}
if (!preg_match('#^([a-z0-9_\-\.])+\@([a-z0-9_\-\.])+(\.([a-z0-9])+)+$#', $var)) {
$this->addError($label);
}
}
/**
* validate a boolean
* @param string $var The variable
* @param mixed $label The label of variable
* @internal param bool $required
*/
private function validateBool($var, $label)
{
if (filter_var($var, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) === false) {
$this->addError($label);
}
}
/**
* validate custom
* @param string $condition The condition
* @param mixed $label The label of variable
*/
private function validateCustom($condition, $label)
{
if (!$condition) {
$this->addError($label);
}
}
}