-
Notifications
You must be signed in to change notification settings - Fork 52
Ru:formarticle
Мы часто работаем с различными данными - данные пользователей, данные других систем, данные парсеров, данные ботов. Хорошая практика - не доверять входящим данным и валидировать их. В onPHP для этого используются Form'ы и Primitive'ы.
Form - класс контейнер, хранящий совокупность примитивов и позволяющий делать с ними групповой импорт и экспорт.
Операция импорта в примитиве - получение из строковых значений производных, валидных значений в Primitiv'ах.
Операция экспорта в примитиве обратна операции импорта - имея заполненый примитив - получение из него соответствующего строкового значения.
Если для импорта в примитив передается одно конкретное значение, то в форму для импорта необходимо передавать ассоциативный массив вида array(primitiveName => stringvalue, ...)
Производные значения от строковых - это те значения, которые примитивы возвращают через метод getValue, например, для PrimitiveString - строка, для PrimitiveEnumeration - Enumeration объект, для PrimitiveBoolean - true|false и т.д.
Пусть у нас есть форма в html в которой пользователь должен передать нам свой email (обязателен) и возраст (необязателен). Тогда создадим форму с двумя примитивами:
<?php
$form = Form::create()->
add(Primitive::string('email')->setAllowedPattern(PrimitiveString::MAIL_PATTERN)->required())->
add(Primitive::integer('yearOld')->setMin(1));
Теперь им:
<?php
$form->import(array('email' => '123', 'yearOld' => 'twenty');
Дальше нужно проверить форму на наличие ошибок:
<?php
$errorsList = $form->getErrors();
В данном случае в импорт были переданы не валидные данные и $errorsList оказался не пустым: array('email' => 1, 'yearOld' => 1)
. Если импортировать правильные значения, напримери array('email' => '[email protected]', 'yearOld' => '20')
, то массив $errorsList будет пустым. В таком случае можно получить 'чистые' данные:
<?php
$email = $form->getValue('email');
$yearOld = $form->getValue('yearOld');
Бывает необходимость импортировать в форму данные из нескольких источников. В таких случаях можно использовать метод importMore:
<?php
$form
->import(array('email' => '[email protected]')
->importMore(array('yearOld' => '20');
Отличие import от importMore - в случае первого (import) перед импортированием значения всех примитивов формы очищаются.
Так же иногда возникает необходимость из массива входящих данных импортировать значение лишь для какого-то одного примитива, для этого используются методы Form'ы importOne и importOneMore:
<?php
$form->importOne('email', array('email' => '[email protected]', 'yearOld' => '20'));
В данном случае будет импортирован только email.
Особняком стоит метод importValue. В отличие от других импортов в него нужно передавать объект такого же вида, который можно получить при вызове метода getValue (т.е. производный объект от строки для данного примитива).
Это последовательный вызов у всех примитивов метод export и составление ассоциативного массива вида array(primitiveName => exportedValue)
. Т.е. результат экспорта это такой массив, который можно импортировать куда-то еще.
В некоторых случаях часть примитивов удобно связать между собой простыми правилами. Для правил у формы есть метод addRule, где первый аргумент имя правила, а второй логическое выражение. Правила можно использовать, например, в форме где пользователь должен ввести пароль и повторить его:
<?php
$form = Form::create()->
add(Primitive::string('username')->required())->
add(Primitive::string('password')->required())->
add(Primitive::string('passwordRepear')->required())->
addRule(
'ruleName',
Expression::eq(
FormField::create('password'),
FormField::create('passwordRepear')
)
);
Надо отметить, что проверка правил не происходит при каждом импорте и вызывать проверку нужно методом $form->checkRules();
Узнать, что правило не было выполнено можно через метод $form->getErrors()
.
Так же ошибки правил не сбрасываются при каждом импорте или при каждом вызове checkRules. Так что, если вы используете одну и ту же форму с правилами для нескольких импортов не забудьте перед очередным импортом вызвать у формы метод $form->dropAllErrors()
(эта статья еще не закончена)