postValidatorから個別のフィールドにエラーを設定

http://d.hatena.ne.jp/Fivestar/20100118/1263788888

先ほど書いた記事ではpostValidatorにsfValidatorCallbackを指定して、複数フィールドに対するバリデーションを行うというものでした。

バリデーションに失敗するとフォームの内部に保持しているsfValidatorErrorSchemaオブジェクトに失敗した分だけエラーオブジェクトが格納されます。このエラーオブジェクトはValidatorErrorSchemaオブジェクトの内部で2種類に分けて保持されます。

1つは NamedError です。これは要するに単一のフィールドに対するエラーです。

もう1つは GlobalError です。これは単一のフィールドではなく、複数フィールドにまたがるエラーであったり、フォーム全体としてみなすエラーです。

postValidatorにセットしたsfValidatorCallbackからsfValidatorErrorをthrowすると、通常GlobalErrorに格納されます。ここでGlobalErrorではなくNamedErrorに格納したい場合もあると思いますが、その場合どのようにすればNamedErrorに入るようになるかをご紹介します。

例えば、カテゴリー用のセレクトボックス[category_id]があったとして、新規作成(value='')が選択されている場合、新規カテゴリー名を入力するインプットフィールド[category_new]を必須にする、というフォームがあったとします。とりあえずバリデーションをするため、以下のようなコールバックを記述しました。

<?php

public function validateCategory(sfValidatorBase $validator, $values)
{
  if (!$values['category_id'])
  {
    if (!strlen($values['category_new']))
    {
      throw new sfValidatorError($validator, 'カテゴリー名を入力してください');
    }
  }
}

これでエラーは出るようになりましたが、ここで出たエラーを category_new のエラーとして設定したいとします。ここで登場するのがsfValidatorErrorSchemaです。次のように記述することで、category_newのエラーとして設定することができます。

<?php

public function validateCategory(sfValidatorBase $validator, $values)
{
  if (!$values['category_id'])
  {
    if (!strlen($values['category_new']))
    {
      // sfValidatorErrorSchema でラッピング
      throw new sfValidatorErrorSchema($validator, array(
        'category_new' => new sfValidatorError($validator, 'カテゴリー名を入力してください'),
      ));
    }
  }
}

先ほどは単純にsfValidatorErrorをthrowするだけでした。これをNameErrorにしたい場合は、sfValidatorErrorSchemaというオブジェクトでラッピングしてあげることで可能になります。