[ ][ ]Paginator(4/18 修正)Add Starcohtan cohtan

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円