アドミンでカスタムフィルター

アドミンでカスタムフィルターを作る方法。

別テーブルのレコードを参照しているとき、参照先レコードでフィルタリングする例。

Application テーブルの要素が Product テーブルの要素を参照している。
Application のリストで Product の text フィールドでフィルタリングする。

まず、Application の generator.yml に、これを追加。

    list:
      peer_method: doSelectJoinAll
      peer_count_method: doCountJoinAll
      filters: [_product_text]

_product_text がパーシャルフィルタになる。
外部のテーブルを参照しているので、peer_method、peer_count_method ではジョインする。
例では全てをジョインしているが、フィルタに関わるテーブルだけジョインしても機能する。

パーシャルフィルタのビューのために、 application/templates/_product_text.php を作成。
内容は、こんな感じに。

<?php echo input_tag('filters[product_text]', isset($filters['product_text']) ? $filters['product_text'] : null, array (
  'size' => 15,
)) ?>

そして、フィルタを解釈してクライテリアを作る部分。
これは、application/actions/action.class.php を編集する。
アドミンジェネレータで作成されたコードは、addFiltersCriteria メソッドを呼ぶので、
これをオーバーライドする。

  protected function addFiltersCriteria($c)
  {
    if (isset($this->filters['product_text']) && $this->filters['product_text'] != '')
    {
      $c->add(ProductPeer::TEXT, strtr($this->filters['product_text'], '*', '%'), Criteria::LIKE);
    }

    $keys = array('product_text');
    $tmp = array();
    foreach ($keys as $k)
    {
      if (isset($this->filters[$k]))
      {
        $tmp[$k] = $this->filters[$k];
        unset($this->filters[$k]);
      }
    }
    parent::addFiltersCriteria($c);
    foreach ($keys as $k)
    {
      $this->filters[$k] = $tmp[$k];
    }
  }

後半は、
filters から product_text を消して、
親クラスの同メソッドをコールして、
消した product_text を再度 filters に挿入して、
という処理をしている。

親クラスのメソッドはアドミンジェネレータが作成したもの。
filters をそのままにしておくと、ApplicationPeer::PRODUCT_TEXT にアクセスしようとしてエラーになる。

2012年11月

        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30  

アーカイブ