CallbackValidatorを使わずにFormEventでフィールドのバリデーション

Symfony2.1でCallbackValidatorを使わずに、addEventListnerでエンティティに関係ないフィールドのバリデーションを実装する方法。

コードは「効率的なWebアプリケーションの作り方」p.215より

Before

public function buildForm(FormBuilder $builder, array $options)
  {
    $builder
      ->add('name')
      ->add('email', 'repeated', array(
        'type' => 'email',
        'invalid_message' => '同じ値を入力してください',
      ))
      ->add('rawPassword', 'password', array(
        'always_empty' => false,
      ))
      ->add('tel')
      ->add('birthday', 'birthday')
      ->add('agreement', 'checkbox', array(
        'property_path' => false,
        'required'      => true,
      ))
      ;

      $builder->addValidator(new CallbackValidator(function($form) {
      if (!$form['agreement']->getData()) {
        $form['agreement']->addError(new FormError('利用規約に同意してください'));
      }
    }));
}

after

//...

use Symfony\Component\Form\FormEvents;
//...

  public function buildForm(FormBuilderInterface $builder, array $options)
  {
    $builder
    ->add('name')
    ->add('email','repeated',array(
      'type' => 'email',
      'invalid_message' => '同じ値を入力してください',
    ))
    ->add('rawPassword','password',array(
      'always_empty' => false,
    ))
    ->add('tel')
    ->add('birthday','birthday')
    ->add('agreement','checkbox',array(
      'property_path' => false,
      'required'      => true,
    ))
    ;

    $builder->addEventListener(FormEvents::POST_BIND,function($event){
      $form = $event->getForm();
      if(!$form->has('agreement')){
        $form->addError(new FormError('利用規約に同意してください'));
      }
    });
  }

該当箇所以外も載せているので、ちょっとわかりにくいですが、変更されているのは下から6行くらい。

//...

use Symfony\Component\Form\FormEvents;

//...
$builder->addEventListener(FormEvents::POST_BIND,function($event){
  $form = $event->getForm();
  if(!$form->has('agreement')){
        $form->addError(new FormError('利用規約に同意してください'));
  }

まず、use Symfony\Component\Form\FormEvents; を追加、POST_BINDイベントを監視する。

リスナーの関数に渡されるのはFormオブジェクトではなく、FormEventオブジェクトになる。なので、FormEventオブジェクトからgetForm()でフォームを取り出し、フォームに値がセットされているかを確認し、適宜addError()する。

効率的なWebアプリケーションの作り方 ~PHPによるモダン開発入門

効率的なWebアプリケーションの作り方 ~PHPによるモダン開発入門