symfonyでカスタムバリデータを使ってフィルタを実装する

symfony the world

昨日、ついにsymfonyの1.4がリリースされましたね。1.0同様、3年間の Long Term Support ということで、今後しばらくは1.4で落ち着くのかなぁ。。。と感じてるところです。

さて、symfonyでフォーム(sfForm)を作っていて常々感じるのは、POSTされたデータをそのままバリデートするのではなく、せめてmb_convert_kanaでフィルタ(正規化)した後にバリデートしたい、ということです。PEARのHTML_QuickFormでいうところのapplyFilter()の機能ですね。

ただしsfFormには上記のようなフィルタ機能がありません。そのため、私は既存のsfValidatorStringを継承して以下のカスタムバリデータを使ってます。symfony 1.2 で動作確認していますが、コードを見る限りでは1.3, 1.4でも問題なく使えるはずです。

サンプルコード

sfValidatorStringKana.class.php

<?php
 
/*
 * This file is part of the symfony package.
 * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
 
/**
 * sfValidatorStringKana validates a multibyte string.
 *
 * @package    symfony
 * @subpackage validator
 * @author     Yoshinori Ishii <ishii.yoshinori@itra.jp>
 * @version    SVN: $Id$
 */
class sfValidatorStringKana extends sfValidatorString
{
  /**
   * Configures the current validator.
   *
   * Available options:
   *
   *  * convert_option: Convert option for mb_convert_kana()
   *
   * @param array $options   An array of options
   * @param array $messages  An array of error messages
   *
   * @see sfValidatorString
   */
  protected function configure($options = array(), $messages = array())
  {
    parent::configure($options, $messages);
 
    $this->setOption('trim', true);
    $this->addOption('convert_option', 'asKV');
  }
 
  /**
   * @see sfValidatorBase
   */
  public function clean($value)
  {
    if ($this->hasOption('convert_option')) {
        $value = mb_convert_kana($value, $this->getOption('convert_option'), $this->getCharset());
    }
 
    return parent::clean($value);
  }
}

上記のコードをsfValidatorStringKana.class.phpとしてlib/以下にファイルを配置すればインストールは完了です。

フォームクラスからの呼び出し方は以下のサンプルの通り、sfValidatorStringとほぼ同じです。convert_optionはmb_convert_kanaの第2引数に渡す変換オプションです(デフォルトで'asKV'が設定されています)。

呼び出し方サンプル

$form->setValidators(array(
    'name' => new sfValidatorStringKana(array(
        'min_length' => 4,
        'max_length' => 50,
        'convert_option' => 'asKV', // mb_convert_kanaの変換オプション
    )),
));

clean()をオーバーライドした理由

既存のバリデータを見る限り、カスタムバリデータでオーバーライドされるべきメソッドはdoClean()なんですが、このクラスではdoClean()ではなくclean()をオーバーライドしています。

あえてclean()をオーバーライドした理由は、sfValidatorBase::clean()で行われるデフォルトのバリデーション(trimや必須チェック)の前にフィルタリングを行いたかったからです。

例えば全角スペースのみを含む文字列がPOSTされた場合、doClean()をオーバーライドしただけだと、trimと必須チェックをすり抜けてしまうため、フィルタの意味を成さなくなってしまうのです。ここのところ、文字だとちょっとわかりづらいので、図でまとめてみました↓

doClean()をオーバーライドしたとき

doclean.png

clean()をオーバーライドしたとき

clean.png

他にも使いまわしがききそうなカスタムバリデータを作ってる方がいらっしゃったら、コメントなどで教えてもらえるととてもうれしいです。

トラックバック(0)

このブログ記事を参照しているブログ一覧: symfonyでカスタムバリデータを使ってフィルタを実装する

このブログ記事に対するトラックバックURL: http://monolog.spanstyle.com/mt/mt-tb.cgi/429

このサイトについて

自分用リンク

Powered by Movable Type 4.22-ja

PR

このブログ記事について

このページは、ishiiが2009年12月 2日 16:19に書いたブログ記事です。

ひとつ前のブログ記事は「Twitterの「これはいい画像ですね!」のUIを3分で実装してみる」です。

次のブログ記事は「【注意】Mooter フリー検索が改ざんされています」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

アイテム

  • swfobject.png
  • symfony.png
  • doclean.png
  • clean.png
  • twitterui.png
  • php5.2.8-warning.png
  • pagesaver.png
  • analytics.png
  • Munsell Hue Test.png
  • Munsell Hue Test0.png