- 前ページ
- 次ページ
■
[PHP
][CakePHP
]Paginator(4/18 修正)

CakePHP の1.2ではBakeで作成したindexページに標準でページャー がついています。
ページャー の仕組みは、URL を「/controller_name/action_name/page:1/sort:field_name/direction:asc」(例:/mails/index/page:1/sort:date/direction:desc)などのようにして、URL をクリックするたびにdirectionがasc(昇順)かdesc(降順)かが切り替わります。
CakePHP などどのフレームワーク を使ってもそうなんですが、フレームワーク は自動化が進むにつれてちょっとの変更が大変になりますorz ....
当然CakePHP のページャー もしかりで、上の例のURL を/mails/index/2(「2」は例えばアカウント IDやカテゴリー IDなど、where句の絞込み条件とするための値と思ってください)のようなページに対してページャー を利用しようとするととても大変です。
- 絞り込み条件の追加
<?php function index($category_id){ $options = array(); if(isset($category_id) && is_numeric($category_id)){ $options['conditions'] = 'Mail.category_id = '.$category_id; } $this->Mail->recursive = 1; $this->paginate = am($this->paginate,$options); $this->set('mails', $this->paginate()); } ?>
これで表示されるページャー の絞り込み条件(category_id = n)を指定できました。上のソースはまぁ直感的にも言いたい事はわかるのではないでしょうか。
しかし問題は絞込み条件を指定した後で、絞り込み条件を指定した際に/views/index.ctpよりページを表示した際、ソート 条件を切り替えるためのURL が未だに「/mails/index/page:1/sort:date/direction:desc」のままであることに気がつくかと思います。
mails_controller.php に「$this->set('category_id',$category_id);」と指定して色々すればなんとかなるのかと試行錯誤したのですが、結局のところ
<?php //mails_controller.php function index($category_id){ $this->Mail->recursive = 1; if(isset($this->passedArgs['category_id'])){$id = $this->passedArgs['category_id'];} $options = array(); $pager_options = array(); if(isset($id) && is_numeric($id)){ $options['conditions'] = 'Mail.category_id = '.$category_id; $pager_options['url'] = array('category_id'=>$id); } $this->paginate = am($this->paginate,$options); $this->set('options',$pager_options); $this->set('mails', $this->paginate()); } //mails/index.ctpの該当行を変更 <?php echo $paginator->sort('field_name',null,$options);?>
で対応できるかと思います(この手法が一般的で最適かどうかはわかりませんが、現状ではこうするしかなさそうです)。
何をしているかと言うと、mails_controller.php にて$idに$this->passedArgs['category_id']を代入していますがここがミソです。passedArgsは、上のURL でいえばdirection:descの部分からarray('direction'=>'desc')を作成し、代入されたクラス変数 なので、そこにcategory_idを「category_id:$id」となるようにURL を書き換えさせています。
それでindex.ctp側にて$paginator->sortの第三引数 に$optionsとしてarray('url '=>array('category_id'=>$id));を用いることによってページャー の切り替え用URL に「category_id:$id」が追加されます。
・・・とまぁ手法としてはこれでいいとは思いますが、スマートではないですね。
現在CakePHP の1.2系列はまだα版ですが、stable版になる頃にはそのまま$paginator->sort('field_name')でURL がそのまま指定できたらと思います。
-----------------------------
- 修正
最後のサンプルコードで
<?php echo $paginator->sort('field_name',null,$options);?>
をindex.ctpに書くとありましたが、全てのページャー クラスに$optionsの引数 を渡すよりスマートな方法がありました。
<?php echo $paginator->options($options); <table><tr> <th><?php echo $paginator->sort('field_name1');?></th> <th><?php echo $paginator->sort('field_name2');?></th> ・・・・・ </tr><table> ?>
$paginator->optionsで、全てのリンクにオプション を追加することができます。
「Sets default options for all pagination links」とコメントにもあります
-42,500
ファンコミ 0
ファンコミ買 -2000
ファンコミ売 -25000
ファンコミ買 -15000
ファンコミ売 1000
ファンコミ買 2000
ファンコミ売 -2000
2勝4敗
-40341
手数料 -1800
-42,500
ファンコミ 0
ファンコミ買 2000
ファンコミ 0
ファンコミ売 2000
ファンコミ 0
ファンコミ売 2000
ファンコミ買 -2000
ファンコミ買 2000
ファンコミ売 2000
ファンコミ買 2000
ファンコミ売 -2000
6勝2敗3分
9623円
手数料 -1800円
+7,500円
ファンコミ 0
ファンコミ 0
ファンコミ買 2000
ファンコミ 0
ファンコミ買 2000
ファンコミ売 -2000
ファンコミ売 4000
ファンコミ売 -6000
ファンコミ売 2000
ファンコミ買 2000
ファンコミ売 1000
ファンコミ売 4000
7勝2敗3分
8662円
手数料 -1800円
+6500円
ファンコミ買 2000
ファンコミ0
ファンコミ買 12000
ファンコミ買 2000
ファンコミ売 -2000
ファンコミ売 -1000
ファンコミ売 1000
ファンコミ売 2000
ファンコミ買 4000
6勝2敗1分
19,457円
手数料 -2660円
16,500円
ファンコミ売 2000
ファンコミ売 2000
ファンコミ 0
ファンコミ売 5000
ファンコミ 0
ファンコミ売 2000
ファンコミ売 -2000
ファンコミ 0
ファンコミ買 4000
ファンコミ買 -7000
ファンコミ売 4000
ファンコミ 0
ファンコミ買 2000
ファンコミ買 -2000
7勝3敗4分
合計 9100
手数料 -2600
収支 +6500円