63日目:sfPagerでページング

Googleで検索した時に、ヒットした件数が多いと G o o o o g l eと表示されますが、あれがページングです。単に次のページへ案内するだけじゃなくて、先まで一気に飛べる便利なインターフェースです。あれを実装してみました。

symfonyには sfPropelPagerという便利なオブジェクトがあって、それを使えば一発なのですが、徹底攻略本を見ても、いまいち良く分かりませんでした。色々Webを見て回った結果、codezineさんの記事が一番わかりやすかったので、それを元に実装(というかコピペ)してみました(メソッド一覧があるのが嬉しかったです)。

思うに、フレームワークを使ったプログラミングで、あまり特殊な事をしない場合、プログラミングの8割がコピペで足りると思うのですが、どうでしょう? 自分の頭の中に沢山事例集を用意して、それを取ってくるだけで、大抵のケースは十分な気がします。僕は PHPの文法をちょっとしかしていませんが、コピペプログラミングだけでも、掲示板程度のアプリは作れてしまいます。最近のフレームワークの進歩にはびっくりです。

というわけで、今回参考にしたのはこの記事です。
http://codezine.jp/a/article/aid/911.aspx?p=2

まずはアクション。今回は channelモジュールの listアクションに組み込んでみました。listアクションでパラメータをとる事ができるって初めて知りました(笑)。
/var/www/podtv/apps/frontend/modules/channel/actions/actions.class.php

  public function executeList()
  {
  public function executeList()
  {
//    $this->channels = ChannelPeer::doSelect(new Criteria());
		$c = new Criteria();
		$pager = new sfPropelPager( 'Channel', 3);
		$pager->setCriteria( $c);
		$pager->setPage( $this->getRequestParameter( 'page', 1));
		$pager->init();
		$this->pager = $pager;


  }

		$c = new Criteria();
		$pager = new sfPropelPager( 'Channel', 3);
		$pager->setCriteria( $c);
		$pager->setPage( $this->getRequestParameter( 'page', 1));
		$pager->init();
		$this->pager = $pager;
  }

コメントアウトした部分が symfonyで自動で作られたコードです。で、view。

/var/www/podtv/apps/frontend/modules/channel/templates/listSuccess.php

<?php
	if ( $pager->haveToPaginate())
	{
		echo link_to( '', 'channel/list?page=' .$pager->getFirstPage());
		echo link_to( '< ', 'channel/list?page=' .$pager->getPreviousPage());
		foreach ( $pager->getLinks() as $page)
		{
			echo ( $page == $pager->getPage()) ? $page : link_to( $page, 'channel/list?page=' .$page);
			if ( $page != $pager->getCurrentMaxLink())
			{
				echo ' - ';
			}
		}

		echo link_to( ' > ', 'channel/list?page=' .$pager->getNextPage());
		echo link_to( '', 'channel/list?page=' .$pager->getLastPage());
		echo '現在のページは' .$pager->getPage();
	}
?>

pager以外の部分は、ほぼ symfonyが作ったコードのままなので、省略です。変更したのは、

<?php foreach ($pager->getResults() as $channel): ?>

↑で $channelsとあったのを $pager->getResults()に変更しただけです。あら簡単。

で、動いた結果がこれ。

http://podtvlabo.com/channel/list/page/3

これは、ヘルパーだかパーシャルだかコンポーネントだかにした方が楽そうですが、どれが一番良いのでしょう?
あと、モデルに書くようなコードをアクションにガンガン書いていますが、困る事ってあるのでしょうか?