пятница, 29 октября 2010 г.

Формы в Symfony2. Часть вторая - валидация форм.

Это вторая часть рассказа о формах в Symfony2
В этой части мы рассмотрим как реализовать валидацию формы (на сервере).
В первой части мы создали модель 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' => 'Введите хоть, что-то!',
        )));
   }
}

Опять очень просто!

Т.к. статья получилась довольно большой, я принял решение перенести вывод формы в отдельную часть.
Если вы дочитали эту часть, милости просим в последнюю.
Более прдробную информацию о валидации форм, вы можете найти здесь.

1 комментарий:

  1. А как можно сделать названия полей в форме мультиязычным? Спасибо!

    ОтветитьУдалить