古典的なログインフォームは2つのフィールド: ユーザー名とパスワードで構成されます。
バリデーションのルールはとても直感的です:
- それぞれのフィールドを必須にしたい
- パスワードの正しさをチェックしたい
ログインフォームの最初の実装です:
class loginForm extends sfForm { public function configure() { $this->setWidgets(array( 'username' => new sfWidgetFormInput(), 'password' => new sfWidgetFormInputPassword(), )); $this->setValidators(array( 'username' => new sfValidatorString(array('required' => true)), 'password' => new sfValidatorString(array('required' => true)), )); $this->widgetSchema->setNameFormat('login[%s]'); } }
このフォームによってユーザー名とパスワードフィールドの要件が強制されますがパスワードの正しさはチェックされません。
ユーザー名の値へのアクセス権限もある場合のみパスワードはバリデート可能です。 しかしおわかりの通り、フィールドに添付されたバリデーターはフォームの他の値にアクセスする権限がありません。
バリデーターが別の投稿された値に依存するとき、ポストバリデーターを作ることが必要です. ポストバリデーターは他のすべてのバリデーターの後で実行されクリーンナップされた値の全体の配列が渡されます。
パスワードをチェックするために、投稿されたパスワードがユーザーと等しいことを確認するために シンプルなコールバックバリデーターを実装します。 もちろん、彼の実際のプロジェクトに関して、実際の作業を行うためにモデルレイヤーを呼び出さなければなりません。
追加されたpostバリデーターつきの修正されたログインフォームは次の通りです:
class loginForm extends sfForm { public function configure() { $this->setWidgets(array( 'username' => new sfWidgetFormInput(), 'password' => new sfWidgetFormInputPassword(), )); $this->setValidators(array( 'username' => new sfValidatorString(array('required' => true)), 'password' => new sfValidatorString(array('required' => true)), )); $this->widgetSchema->setNameFormat('login[%s]'); // postバリデーターを追加する $this->validatorSchema->setPostValidator( new sfValidatorCallback(array('callback' => array($this, 'checkPassword'))) ); } public function checkPassword($validator, $values) { if ($values['password'] != $values['username']) { // パスワードが正しくなければ、エラーを投げる throw new sfValidatorError($validator, 'Invalid password'); } // パスワードが正しければ、クリーンな値を返す return $values; } }
これで、フォームは期待通りに動作しますが、小さな問題が1つあります: ユーザー名を入力せずにランダムなパスワードを投稿すると、 2つのエラーメッセージ: 必須項目のユーザー名に対するエラーと間違ったパスワードに対するグローバルエラーが表示されます。
しかし、少しお待ちください。ユーザー名が空の場合、パスワードをバリデートする必要はありません。 ユーザー名が投稿される場合のみパスワードをバリデートするようにフォームを変更してみましょう。 $values['username']`が空ではないことを確認することだけなので、これはとても簡単です:
public function checkPassword($validator, $values) { // パスワードをバリデートする前に、ユーザー名が空ではないことをチェックする if (!empty($values['username']) && $values['password'] != $values['username']) { throw new sfValidatorError($validator, 'Invalid password'); } return $values; }
グローバルエラーを用意する代わりに、上記のパスワードフィールドで'Invalid password'エラーメッセージを表示したいとします。
グローバルエラーを投げる代わりに、password
フィールドにバインドされたエラーを投げることで実現するのはとても簡単です:
public function checkPassword($validator, $values) { if (!empty($values['username']) && $values['password'] != $values['username']) { $error = new sfValidatorError($validator, 'Invalid password'); // パスワードフィールドにバインドされたエラーを投げる throw new sfValidatorErrorSchema($validator, array('password' => $error)); } return $values; }
This work is licensed under the Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 Unported License license.