スポンサードリンク

CakePHP
CakePHP

前回CakePHPで検索ページを作って

データを表示させました。

しかし、データ量が多くなると

検索結果が多くなり

さらに、SQLの処理も遅くなってしまうため

Limitを付けて検索させたいと思いました。

なら、簡単にページネーションまで作ってくれる

CakePHPのPagenateを使って表示するようにしました。

スポンサードリンク

CakePHPのページネーションを設定

前回の検索機能にページネーションを付けます。

まずはページネーションの設定です。

(例)Controller/PostsController.php
//Paginationの設定

public $paginate = array(
	//モデルの指定
	'Post' => array(
  	    //1ページ表示できるデータ数の設定
	    'limit' => 20,
	)
);

次にアクション部分の設定です。

前回の検索機能のコントローラー
(例)Controller/PostController.php

public function search(){
 //リクエストがPOSTで送られたデータが空白で無ければ
   if($this->request->is('post') && $this->request->data['Post']['title'] != ""){
      //Formの値を取得
      $title = $this->request->data['Post']['title'];
    //検索文字を空白(全角又は半角)で区切って配列$keywordsに代入
    $keywords = preg_split("/ |\\s/",$title);
    //配列$keywordsの数だけ繰り返して検索条件を$conditionsに代入
    foreach($keywords as $keyword){
      $conditions[] = "title like '%$keyword%'";
    }
    //POSTされたデータを曖昧検索
    $data=$this->->find('all',array(
     'conditions' => $conditions
    ));
     $this->set('datas',$data);
   }
 }

これを、下記のように変更します。

public function search(){
 //リクエストがPOSTで送られたデータが空白で無ければ
   if($this->request->is('post') && $this->request->data['Search']['title'] != ""){
      //Formの値を取得
      $title = $this->request->data['Post']['title'];
    //検索文字を空白(全角又は半角)で区切って配列$keywordsに代入
    $keywords = preg_split("/ |\\s/",$title);
    //配列$keywordsの数だけ繰り返して検索条件を$conditionsに代入
    foreach($keywords as $keyword){
      $conditions[] = "title like '%$keyword%'";
    }
     $data = $this->paginate($conditions);
     $this->set('datas',$data);
   }
 }

pagenateに検索条件を指定してあげればいいだけです。

pagenateメソッドの引数に条件を配列で指定すると

ページネーションの機能を使って検索結果を表示できます。

また、アクションの前のpagenate変数にオーダーなどの指定もできますが、

アクションによって並び替えをしたい場合は

public function search(){
 //リクエストがPOSTで送られたデータが空白で無ければ
   if($this->request->is('post') && $this->request->data['Search']['title'] != ""){
      //Formの値を取得
      $title = $this->request->data['Post']['title'];
    //検索文字を空白(全角又は半角)で区切って配列$keywordsに代入
    $keywords = preg_split("/ |\\s/",$title);
    //配列$keywordsの数だけ繰り返して検索条件を$conditionsに代入
    foreach($keywords as $keyword){
      $conditions[] = "title like '%$keyword%'";
    }
      //作成日の新しい順に並べ替える
      $this->paginate = array(
         'order' => array('created' => 'DSEC')
     );
     $data = $this->paginate($conditions);
     $this->set('datas',$data);
   }
 }

このようにするとページネーションを

各アクションごとに条件を指定できます。

ページを変えても同じ結果が出るようにする

最初の方法だとページが変わったときに

1ページ目のみしか検索結果が表示されなくなります。

2ページ目以降も同じ結果が出るようにするために

検索条件をセッションに入れるようにします。

public function search($page = null, $sort = null, $direction = null){//ページのパラメータを取る
 //リクエストがPOSTで送られたデータが空白で無ければ
   if($this->request->is('post') && $this->request->data['Search']['title'] != ""){
      //Formの値を取得
      $title = $this->request->data['Post']['title'];
      //session用
      $search['title'] = $title;
    //検索文字を空白(全角又は半角)で区切って配列$keywordsに代入
    $keywords = preg_split("/ |\\s/",$title);
    //配列$keywordsの数だけ繰り返して検索条件を$conditionsに代入
    foreach($keywords as $keyword){
      $conditions[] = "title like '%$keyword%'";
    }
      
      //検索条件をセッションに保存
      if($this->Session->check('conditions')){
         $this->Session->delete('conditions');	//古いのは削除
      }

      if($this->Session->check('search')){
         $this->Session->delete('search');	//古いのは削除
      }

      $this->Session->write('conditions', $conditions);
      $this->Session->write('seach', $search);
 
      //作成日の新しい順に並べ替える
      $this->paginate = array(
         'order' => array('created' => 'DSEC')
     );
     $data = $this->paginate($conditions);
     $this->set('datas',$data);
   }else{
     if($this->Session->check('conditions')){
         //パラメータがなければ新しい検索のため削除
         if(empty($this->params['named']['page']) && empty($this->params['named']['sort']) && empty($this->params['named']['direction'])){
             $this->Session->delete('conditions');
             $this->Session->delete('search');
         }else{
             $conditions = $this->Session->read('conditions');
             $search = $this->Session->read('search');
               //作成日の新しい順に並べ替える
             $this->paginate = array(
               'order' => array('created' => 'DSEC')
             );
             $data = $this->paginate($conditions);
             $this->set('datas', $data);
             $this->set('search', $search);
        }
     }
 }

検索ボタンを押したとき

//検索条件をセッションに保存
      if($this->Session->check('conditions')){
         $this->Session->delete('conditions');	//古いのは削除
      }

      if($this->Session->check('search')){
         $this->Session->delete('search');	//古いのは削除
      }

まず検索ボタンを押した場合に

検索条件をセッションに保存します。

その際に、検索キーワードもセッションに入れておきます。

2ページ目とかに移動した場合に

フォームにキーワードが入っていた方が親切だと思うので・・・

セッションにデータを保存する前に

セッションに前の検索データがあるかを調べて

あれば削除してから、セッションに保存します。

検索条件をセッションに入れると

他のページへ行ってから検索ページに戻ると

検索条件が残ってるといけないので

ページの最初に来たときに

セッションに検索結果があれば削除するようにします。

ページを移動したときと最初に来たとき

if($this->Session->check('conditions')){
  ・・・
   略
  }else{
  ・・・
  略

ページを移動したときと最初に検索ページに来たときは

まず、検索用のセッションがあるかないかを調べます。

無い場合は一番最初の状態なのでセッションがないです。

なので何もしません。

セッションがある場合はページ移動か以前検索した場合なので

ページ移動かどうかを調べます。

ページ移動の場合はパラメーターがあるので

パラメーターがあるかどうかを調べます。

まずは、パラメータを取得できるようにsearchメソッドの引数に

設定を追加しておきます。

public function search($page = null, $sort = null, $direction = null){//ページのパラメータを取る
・・・
略

上記のようにしておくとページ番号や並び順などをパラメータとして取得できます。

if($this->Session->check('conditions')){
  //パラメータがなければ新しい検索のため削除
  if(empty($this->params['named']['page']) && empty($this->params['named']['sort']) && empty($this->params['named']['direction'])){
       $this->Session->delete('conditions');
       $this->Session->delete('search');
  }else{
  ・・・
  略

ページ番号などのパラメータがなければ

ページ移動ではないので検索ページに新しく来たことになります。

なので、前回の検索条件を削除します。

         if(empty($this->params['named']['page']) && empty($this->params['named']['sort']) && empty($this->params['named']['direction'])){
             $this->Session->delete('conditions');
             $this->Session->delete('search');
         }else{
             $conditions = $this->Session->read('conditions');
             $search = $this->Session->read('search');
               //作成日の新しい順に並べ替える
             $this->paginate = array(
               'order' => array('created' => 'DSEC')
             );
             $data = $this->paginate($conditions);
             $this->set('datas', $data);
             $this->set('search', $search);

パラメーターのデータがあればページ移動なので

セッションの検索条件と検索キーワードをセッションから読んで

変数にセットします。

スポンサードリンク

ビューファイルの調整

コントローラーは調整できたので

次にフォームに検索キーワードを入れるようにします。

検索フォームの部分に以下のように変えます。

(例)View/Posts/search.php

<?php
if(!empty($search)){
   $title = $search['title'];
}else{
   $title = "";
}
 echo $this->Form->create('Post', array('action'=>'search'));
 echo $this->Form->input('title', array('label' => 'タイトル名を入れてください', 'default' => $title));
 echo $this->Form->end('検索');
?>

これでページ移動しても

検索フォームに検索キーワードが入力された状態になります。

スポンサードリンク