Валидация данных

    Валидация данных

    При валидации данных валидатор последовательно применяет к значению поля заданные правила, при возникновении ошибки в массив данных об ошибках добавляется запись и дальнейшая обработка формы прекращается.

    Валидация считается пройденной, если в массиве данных об ошибках отсутствуют записи.

    Правила валидации

    Список правил задается в виде массива. Ключом является имя поля, а значением - массив правил валидации. Правило валидации является методом класса-валидатора.

    В массиве правил ключом является имя правила (название метода валидации), значением может быть либо строка с сообщением об ошибке валидации правила, или же массив с описанием.

    В этом массиве в ключе params задаются необходимые для валидации значения, а в ключе message задается строка с сообщением об ошибке. Вместо ключа params можно использовать ключ @params. В этом случае значения будут браться из полей формы, имя поля задается как "@имя":

    "field":{
        "equals": {
            "@params" : "@foobar",
            "message": "Поле 'field' должно быть  равно полю 'foobar'"
        }
    }

    Если требуется задать два значения для правила, то их следует задавать как массив:

    &rules=`{
        "field" : {
            "lengthBetween" : {
                "params" : [10, 20],
                "message" : "Длина должна быть от 10 до 20"
            }
        }
    }`

    Для правила in (и других правил, использующих массив) массив значений следует задавать следующим образом:

    &rules=`{
        "field" : {
            "in" : {
                "params" : [ [10, 20, 30] ],
                "message" : "Значение поля field должно быть равно 10, 20 или 30"
            }
        }
    }`

    Это нужно, чтобы массив был передан в функцию одним аргументом.

    Можно также использовать отрицание правил, если добавить перед именем правила восклицательный знак: "!numeric" - поле пройдет валидацию, если его значение не является числом.

    Если нужно реализовать проверку только заполненных полей, то перед именем поля в списке правил нужно добавить восклицательный знак. В этом случае если значение поля пустое, правила будут проигнорированы.

    {
        "имя поля 1": {
            "правило 1" : "сообщение об ошибке",
            "правило 2" : "сообщение об ошибке"
        },
        "имя поля 2": {
            "правило 1" : "сообщение об ошибке",
            "правило 2" : {
                "params" : значение,
                "message" : "сообщение об ошибке"
            }
        },
        "!имя поля 3":{
            "правило 1" : "сообщение об ошибке"
        }
    }

    Стандартным классом валидации (\FormLister\Validator) предусмотрены правила:

    • required: поле заполнено;
      "field":{
      "required":"Поле 'field' должно быть заполнено"
      }
    • date: значение поля является датой в заданном формате (формат задается как для php-функции date);
      "field":{
      "date": {
          "params" : "d.m.Y",
          "message": "Поле 'field' должно быть в формате ДД.ММ.ГГГГ"
      }
      }
    • min: значение поля больше заданного или равно ему;
      "field":{
      "min": {
          "params" : 10,
          "message": "Поле 'field' должно быть больше или равно 10"
      }
      }
    • max: значение поля меньше заданного или равно ему;
      "field":{
      "max": {
          "params" : 20,
          "message": "Поле 'field' должно быть меньше или равно 20"
      }
      }
    • greater: значение поля строго больше заданного;
      "field":{
      "greater": {
          "params" : 20,
          "message": "Поле 'field' должно быть строго больше 20"
      }
      }
    • less: значение поля строго меньше заданного;
      "field":{
      "less": {
          "params" : 10,
          "message": "Поле 'field' должно быть  строго меньше 10"
      }
      }
    • between: значение поля входит в диапазон (строго или не строго, по умолчанию - не строго);
      "field":{
      "less": {
          "params" : [10, 20],
          "message": "Поле 'field' должно быть больше или равно 10 и меньше или равно 20"
      }
      },
      "another_field":{
      "less": {
          "params" : [10, 20, true],
          "message": "Поле 'another_field' должно быть строго больше 10 и строго меньше 20"
      }
      }
    • equals: значение поля равно заданному;
      "field":{
      "less": {
          "params" : 10,
          "message": "Поле 'field' должно равно 10"
      }
      }
    • in: значение поля входит в заданный массив значений;
      "field":{
      "in": {
          "params" : [ ["a", "b", "c"] ]
          "message": "Поле 'field' должно быть равно a, b или c"
      }
      }
    • alpha: значение поля содержит только буквы;
      "field":{
      "alpha":"Поле 'field' должно быть заполнено"
      }
    • numeric: значение поля содержит только цифры;
      "field":{
      "numeric":"Поле 'field' должно быть заполнено"
      }
    • alphaNumeric: значение поля содержит только буквы и цифры;
      "field":{
      "alphaNumeric":"Поле 'field' должно быть заполнено"
      }
    • slug: значение поля является частью url;
    • decimal: значение поля является десятичным числом;
      "field":{
      "decimal":"Поле 'field' должно быть заполнено"
      }
    • phone: значение поля является номером телефона;
      "field":{
      "phone":"Поле 'field' должно быть заполнено"
      }
    • matches: значение поля удовлетворяет регулярному выражению;
      "field":{
      "matches":{
          "params":"/[0-9]{6}/",
          "message":"Поле 'field' должно содержать 6 цифр"
      }
      }
    • url: значение поля является ссылкой;
      "field":{
      "url":"Поле 'field' должно быть ссылкой"
      }
    • email: значение поля является email-адресом;
      "field":{
      "email":"Поле 'field' должно быть адресом email"
      }
    • length: длина значения поля равна заданному;
      "field":{
      "length": {
          "params" : 10,
          "message": "Поле 'field' должно содержать 10 символов"
      }
      }
    • minLength: длина значения поля больше заданного (строго или не строго, по умолчанию - не строго);
      "field":{
      "minLength": {
          "params" : 10,
          "message": "Длина поля 'field' должна быть от 10 символов"
      }
      },
      "another_field":{
      "minLength": {
          "params" : [10, true],
          "message": "Длина поля 'another_field' должна быть 10 или больше символов"
      }
      }
    • maxLength: длина значения поля меньше заданного (строго или не строго, по умолчанию - не строго);
      "field":{
      "maxLength": {
          "params" : 20,
          "message": "Длина поля 'field' должна быть до 20 символов"
      }
      },
      "another_field":{
      "maxLength": {
          "params" : [20, true],
          "message": "Длина поля 'another_field' должна быть 20 или меньше символов"
      }
      }
    • lengthBetween: длина значения поля входит в диапазон (строго или не строго, по умолчанию - не строго);
      "field":{
      "lengthBetween": {
          "params" : [10, 20],
          "message": "Длина поля 'field' должна быть от 10 до 20 символов"
      }
      },
      "another_field":{
      "lengthBetween": {
          "params" : [10, 20, true],
          "message": "Длина поля 'another_field' должна быть от 10 до 20 символов включительно"
      }
      }
    • minCount: размер массива больше заданного (строго или не строго, по умолчанию - не строго);
      "field":{
      "minCount": {
          "params" : 10,
          "message": "В поле 'field' должно быть больше 10 элементов"
      }
      },
      "another_field":{
      "minLength": {
          "params" : [10, true],
          "message": "В поле 'another_field' должно быть 10 или больше элементов"
      }
      }
    • maxCount: размер массива меньше заданного (строго или не строго, по умолчанию - не строго);
      "field":{
      "maxCount": {
          "params" : 10,
          "message": "В поле 'field' должно быть меньше 10 элементов"
      }
      },
      "another_field":{
      "maxCount": {
          "params" : [10, true],
          "message": "В поле 'another_field' должнр быть 10 или меньше элементов"
      }
      }
    • countBetween: размер массива входит в диапазон (строго или не строго, по умолчанию - не строго).
      "field":{
      "countBetween": {
          "params" : [10, 20],
          "message": "В поле 'field' должно быть от 10 до 20 элементов"
      }
      },
      "another_field":{
      "countBetween": {
          "params" : [10, 20, true],
          "message": "В поле 'another_field' должно быть от 10 до 20 элементов включительно"
      }
      }

    Предусмотрена также возможность использовать для валидации функции или статические методы загруженного класса:

    &rules=`{
        "myfield":{
            "required":"Required field",
            "custom":{
                "function":"\\Namespace\\Classname::myCustomRule",
                "params":[10,20,30],
                "message":"Custom check failed"
            }
        }
    }`

    Метод должен принимать первым аргументом экземпляр контроллера из которого вызывается правило, вторым аргументом - значение проверяемого поля, далее - параметры передаваемые в ключе описания params:

    public static function myCustomRule($fl, $value, $a, $b, $c) {
        $result = $fl->getField('field1') == $a && $fl->getField('field2') == $b && $value == $c;
        return $result;
    }

    В примере правило будет пройдено, если значение поля field1 = 10, значение поля field2 = 20, а значение поля, к которму применяется правило, = 30.

    Метод должен вернуть true, false или текст сообщения об ошибке (в этом случае можно не указывать message в списке правил).

    В примере используется название правила "сustom", но можно использовать любое название правила, которого нет в классе валидации. Таким образом можно использовать несколько правил данного типа.

    Валидация файлов

    Cтандартный валидатор файлов (\FormLister\FileValidator) поддерживает правила:

    • required: файлы успешно отправлены;
    • allowed: расширение файла входит в заданный массив;
    • images: расширение файла jpg, jpeg, gif, png, bmp;
    • minSize: размер файла в килобайтах больше заданного (строго или не строго, по умолчанию - не строго);
    • maxSize: размер файла в килобайтах меньше заданного (строго или не строго, по умолчанию - не строго);
    • sizeBetween: размер файла в килобайтах входит в диапазон (строго или не строго, по умолчанию - не строго);
    • minCount: количество файлов больше заданного (строго или не строго, по умолчанию - не строго);
    • maxCount: количество файлов меньше заданного (строго или не строго, по умолчанию - не строго);
    • countBetween: количество файлов входит в диапазон (строго или не строго, по умолчанию - не строго).

    Результаты валидации

    Данные об ошибках хранятся в виде массива и могут быть получены вызовом метода getFormData('errors'):

    {
        "имя поля 1": {
            "имя нарушенного правила" : "сообщение об ошибке"
        },
        "имя поля 2": {
            "имя нарушенного правила" : "сообщение об ошибке"
        }
    }

    Для добавления данных в этот массив используется метод addError(имя поля, имя правила, сообщение об ошибке). Таким образом, можно влиять на итоговый результат валидации, вручную добавляя записи в этот массив. Можно также объявить валидацию непройденной по умолчанию, вызвав метод setValid(false).

    В шаблонах результаты валидации для каждого поля выводятся с помощью плейсхолдера [+имя поля.error+]. Общий результат может быть выведен в плейсхолдер [+form.messages+], который задается шаблоном messagesTpl. В свою очередь, в этом шаблоне можно использовать плейсхолдеры:

    • [+required+] - сообщения о незаполенных полях;
    • [+errors+] - сообщения о неверно заполненных полях.

    Получить сообщения об ошибках для определенного поля можно с помощью метода getErrorMessage(имя поля).