『CakePHP』で読んだ本メモを作る 〜3〜 Amazon Web Serviceを利用して登録する本の候補リストを取得する

登録する本のデータを取得するまでの処理。

登録までの流れ

検索フォームから本のタイトルや著者名を検索し、出てきたリストから選択してそれを登録するという方式。
早い話がはてなの「はまぞう」みたいなカンジ。
はてな認証を通った後の、ログイン後メニューに登録ページへのリンクを追加した。
セッションがない場合は、そこにアクセスしても見ることができないようにする。


  • APP/controllers/search_controller.php
<?php
class SearchController extends AppController
{
	var $name = 'Search';
	var $uses = null;

	function beforeFilter()
	{
		$this->checkSession();
	}

	function checkSession()
	{
		if(!$this->Session->check('user'))
		{
			$this->redirect(FULL_BASE_URL . '/login/');
			exit;
		}
	}
}
?>

beforeFilter でセッションの確認。
セッションがない場合にリダイレクトする先でも同じようにセッションチェックの beforeFilter が動いていると無限ループとなるので注意しましょう、というブログエントリをたくさんみた。なるほど。
AppController に入れちゃう場合とかは特に注意が必要。


リファレンスを参考に「var $beforeFilter」でやってみたけど、
いつものパターンで 1.2 からは beforeFilter() を使うように、と警告が出たことをメモ。

本の検索には PEAR の Services_Amazon を使う

いつもお世話になっている PEAR の Services_Amazon を使うことに。
バージョンが 0.7 まで上がっていて驚いた。
最後に使ったときのバージョンはいくつだろう。ECS3の時くらいかな。
ECS3使えなくなるよ−、ってアマゾンからメールきたけど移行させていないことを思い出した。

検索フォームのビューを作る
  • APP/views/search/index.html
<h3>登録する本を検索</h3>

<p>登録する本を検索します。タイトル名を入力してください。</p>

<?php echo $form->create('', array('action' => 'keyword'));?>
<?php echo $form->input('Search.keyword', array('type' => 'text', 'size' => 40, 'label' => 'タイトル', 'error'=> array('required' => true, 'message'=> '本のタイトルを入力してください。')));?>
<?php echo $form->submit('タイトル検索');?>
<?php echo $form->end()?>


検索フォームのコントローラを作る

「フォームにキーワードを入力して検索する場合」と「リンクから検索する場合」の2パターンで動くようにしてみた。
後者は例えば、「http://books.theworld.jp/search/keyword/CakePHP/2/」みたいな。
これだと「CakePHP」をキーワードにした検索結果の2ページ目ということにしたい。
要は、ページング用のアクセス方法。

  • APP/controllers/search_controller.php
<?php
include_once('Services/AmazonECS4.php');
class SearchController extends AppController
{
	var $name = 'Search';
	var $uses = null;

	function beforeFilter()
	{
		$this->checkSession();
	}

	function checkSession()
	{
		if(!$this->Session->check('user'))
		{
			$this->redirect(FULL_BASE_URL . '/login/');
			exit;
		}
	}

	function keyword($keyword=null, $page=1)
	{
		if($this->data['Search']['keyword'])
		{
			// POST の場合
			$keyword = $this->data['Search']['keyword'];
		}
		else
		{
			// GET の場合。フォームに文字列を表示させるためデータを入れる
			$this->data['Search']['keyword'] = $keyword;
		}
		
		$result = array();
		
		if($keyword)
		{
			$page = ereg("[0-9]", $page) ? $page : 1;

			$amazon = new Services_AmazonECS4(ACCESS_KEY_ID, ASSOC_ID);
			$amazon->setLocale('JP');
			
			$options = array();
			$options['Keywords'] = urlencode($keyword);
			$options['Sort'] = 'daterank';
			$options['ItemPage'] = $page;
			$options['ResponseGroup'] = 'ItemIds,ItemAttributes,Images';
			$result = $amazon->ItemSearch('Books', $options);
		}
	}
}
?>

Search用のデータベースというものはないので、var $uses = nullにしている。
ただ、これだとモデルが使えなくなるので、validateをどうしたらいいのかよくわからない。
未入力でフォームが押された場合は「キーワードを入力してください」とかしたいんだけど。
とりあえず、スルーして先に進むことにして、これで検索結果のリストを表示できるようになった。
自分で使うのをいいことにエラーチェックとか適当。

ページング

ページング処理は CakePHP に用意されていないのか調べてみたら、PaginatorHelperというのをみつけた。


でも、これはデータベースに入っているデータを取るときにページングの処理もしてくれるものらしい。
詳しい使い方解説をしている方がいたのでメモ。


とりあえず、分割してリンクを追加するだけの適当な処理を追加しておいた。

http://books.theworld.jp/search/keyword/%E8%8D%92%E6%9C%A8%E9%A3%9B%E5%91%82%E5%BD%A6/1


次は、選んだ本を登録する処理か。


CakePHP のコードの書き方の参考にと思って OpenFLP のソースを読んでみたらレベルが違いすぎて悶絶した。すごいなあ。
こんな風にコードを書ける日は来るのだろうか。

3月末でやることがアレコレあるけどちょっとずつ CakePHP に慣れていきたい。