В этой части мы рассмотрим как реализовать валидацию формы (на сервере).
В первой части мы создали модель User, которая является формой и добавили два свойства (поля) - name, surname.
Давайте переместимся в контроллер, где мы получим готовую форму и передадим её во view.
Итак для начала создадим новое действие в контроллере (action), назовём его user.
<?php
namespace Application\HelloBundle\Controller;
...
use Application\HelloBundle\Model\User;
class HelloController extends Controller{
...
public function userAction(){
//получим сервис отвечающий за валидацию
$validators = $this->container->getValidatorService();
//создаём новый экзампляр нашей модели
$user = new User();
//получаем форму из нашей модели
//подготавливаем её для отображения
$form = $this['templating.form']->get($user->prepareForm($validators));
return $this->render('HelloBundle:Hello:user.php', array(
'form' => $form
));
}
}
Думаю, что из-за наличия комментариев всё понятно. Теперь переместимся в класс нашей модели и модифицируем его.<?php
namespace Application\HelloBundle\Model;
...
class User{
public $name;
public $surname;
//тут должны быть get и set методы для выше перечисленных свойств
...
public function prepareFrom($validators){
$form = new Form('user', $this, $validators);
$form->add(new TextField('name'));
$form->add(new TextField('surname'));
return $form;
}
}
Как мы видим, в качестве параметра, в метод prepareFrom добавилась новая переменная validators. Теперь, чтобы определить как же валидировать поля, нам необходимо подключить два класса Constraints и ClassMetadata. Давайте сделаем это и добавим для обоих полей следующие правила
1) оба поля при отправке не должны быть пустыми
2) минимальное кол-во символов при отправке должно быть 3
<?php
namespace Application\HelloBundle\Model\User;
...
//подключаем следующие классы для валидации
use Application\HelloBundle\Model\User;
class User{
...
//для добавления валидации свойсвт
//необходимо добавить следующий метод
public static function loadValidatorMetadata(ClassMetadata $metadata){
//валидация свойства name
$metadata->addPropertyConstraint(
'name', new Constraints\NotBlank()
);
$metadata->addPropertyConstraint(
'name', new Constraints\MinLength(3)
);
//валидация свойства surname
$metadata->addPropertyConstraint(
'surname', new Constraints\NotBlank()
);
$metadata->addPropertyConstraint(
'surnname', new Constraints\MinLength(3)
);
}
}
Вот и всё! Мы только, что добавили к нашим полям валидацию и теперь при отправке формы, если вы не заполнили какое-либо из них или же ввели коичество символов меньше трёх, то вы увидите сообщение об ошибке возле поля формы которое не прошло валидацию.
Хотелось бы добавить ещё несколько слов о валидации. В Symfony2 есть так называемая валидацию в аннотации к свойству. Т.е. возмём к примеру наше поле name. Есть ещё один способ добавить к нему валидацию, выглядит он следующим образом.
<?php
namespace Application\HelloBundle\Model\User;
...
//подключаем следующие классы для валидации
use Application\HelloBundle\Model\User;
class User{
/**
* @validation:NotBlank
* @validation:MinLength(3)
*/
public $user;
}
Неправда ли, довольно элегантно! Мне очень, нравится, но пока я не пользовался данным способом.
Спешу заметить, чтобы валидация через аннотацию заработала, её необходимо включить в конфигурационном файле
<?php
$container->loadFromExtension('app', 'config', array(
...
'validation' => array('enabled' => true, 'annotations' => true),
));
Ещё одна замечательная вещь, это возможность добавления своего сообщение об ошибке, делается это следующим образом.
<?php
namespace Application\HelloBundle\Model;
...
class User{
public $name;
public static function loadValidatorMetadata(CввlassMetadata $metadata){
$metadata->addGetterConstraint(
'name', new Constraints\NotBlank(array(
'message' => 'Введите хоть, что-то!',
)));
}
}
Опять очень просто!
Т.к. статья получилась довольно большой, я принял решение перенести вывод формы в отдельную часть.
Если вы дочитали эту часть, милости просим в последнюю.
Более прдробную информацию о валидации форм, вы можете найти здесь.
А как можно сделать названия полей в форме мультиязычным? Спасибо!
ОтветитьУдалить