検索とPagination

で、検索しつつ Pagination する部分ですが、ちょっとややこしくて、一気に全部書くと訳が分からないので、仮にメールアドレスだけで検索する場合を最初に考えます。
普通に「検索」ボタンで検索した場合は

$this->data['Member']['email']

に値が渡ってきます。
一方 paginate で次へ、とかページ数をクリックした場合は、

$this->passedArgs['email']

に値が渡ってきます。
これをふまえて考えると、
まず、ボタンかリンクかで判別して渡ってきた値を変数に入れます。

if (!empty($this->data)) {
    $email = $this->data['Member']['email'];
} else {
    $email = urldecode($this->passedArgs['email']);
}

ボタンできた場合はいいですが、リンクで来た場合は$this->data['Member']に値が入っていないので、入れ直します。

if (isset($email)) {
    $this->data['Member']['email'] = $email;
}

前回ビューで作った、peginator に検索キーワードを渡すためのオプションに値を設定します。

$searchword = array(
    "email" => urlencode("$email"),
);

検索のクエリーの条件をセットします。

$conditions = array("Member.email LIKE" => "%$email%");

条件を使って検索してビューに渡します。

$data = $this->paginate('Member', $conditions);
$this->set('searchword', $searchword);
$this->set("members", $data);

基本的にはこの流れでいきます。
やっかいなのは日付データです。年月日を分割したり、結合したり、しないといけません。
ボタンから来た時は年月日の配列になってるので、そのまま入れて、リンクから来た時は文字列になってるのでsplitしたものを配列に入れます。

if (!empty($this->data)) {
    $f = $this->data['Member']['from'];
    $t = $this->data['Member']['to'];
} else {
    list($f['year'], $f['month'], $f['day']) = preg_split("/-/", $this->passedArgs['from']);
    list($t['year'], $t['month'], $t['day']) = preg_split("/-/", $this->passedArgs['to']);
}

同じように $this->data に戻しておきます。

$this->data['Member']['from'] = $f;
$this->data['Member']['to'] = $t;

conditions や searchword 用には結合したものを使います。

$from = $f['year']."-".$f['month']."-".$f['day'];
$to = $t['year']."-".$t['month']."-".$t['day'];

こんな感じになります。

$searchword = array(
    "from" => urlencode("$from"),
    "to" => urlencode("$to"),
);
$conditions = array("Member.created BETWEEN ? AND ?" => array($from,$to));

で、存在しない日付とかを入れると思いっきりエラーになるので、日付データのチェックを別途 function を作って入れておきます。
こんな感じで。

    function _from_to_check($f, $t) {
        if (!preg_match("/^[0-9]{4}$/", $f['year'])) {return false;}
        if (!preg_match("/^[0-9]{2}$/", $f['month'])) {return false;}
        if (!preg_match("/^[0-9]{2}$/", $f['day'])) {return false;}
        if (!preg_match("/^[0-9]{4}$/", $t['year'])) {return false;}
        if (!preg_match("/^[0-9]{2}$/", $t['month'])) {return false;}
        if (!preg_match("/^[0-9]{2}$/", $t['day'])) {return false;}
        if (!checkdate($f['month'], $f['day'], $f['year'])) {return false;}
        if (!checkdate($t['month'], $t['day'], $t['year'])) {return false;}
         
        return true;
    }

ここまでを整理するとこうなります。

    function admin_search() {
        $this->Member->recursive = 0;

        if (!empty($this->data)) {
            $f = $this->data['Member']['from'];
            $t = $this->data['Member']['to'];
            $email = $this->data['Member']['email'];
            $type_id = $this->data['Member']['type_id'];
        }else{
            foreach ($this->passedArgs as $k => $v){
                if ($k == 'from'){
                    list($f['year'], $f['month'], $f['day']) = preg_split("/-/", $v);
                }elseif($k == 'to'){
                    list($t['year'], $t['month'], $t['day']) = preg_split("/-/", $v);
                }elseif($k == 'email'){
                    $email = urldecode($v);
                }elseif($k == 'type_id'){
                    $type_id = urldecode($v);
                }
            }
        }
     
        if (isset($f) && isset($t)){
            if ($this->_from_to_check($f, $t)) {
                $from = $f['year']."-".$f['month']."-".$f['day'];
                $to = $t['year']."-".$t['month']."-".$t['day'];
                $this->data['Member']['from'] = $f;
                $this->data['Member']['to'] = $t;
            }
        }
        if(isset($email)){
            $this->data['Member']['email'] = $email;
        }
        if(isset($type_id)){
            $this->data['Member']['type_id'] = $type_id;
        }
     
        $searchword = array();
        $conditions = array();
        if (isset($from) && isset($to)){
            $searchword = array(
                "from" => urlencode($from),
                "to" => urlencode($to),
            );
            $conditions = array("Member.created BETWEEN ? AND ?" => array($from,$to));
        }
        if (isset($email) && $email){
            $searchword = $searchword + array(
                "email" => urlencode("$email"),
            );
            $conditions = $conditions + array("Member.email LIKE" => "%$email%");
        }
        if (isset($type_id) && $type_id){
            $searchword = $searchword + array(
                "type_id" => urlencode("$type_id"),
            );
            $conditions = $conditions + array("Member.type_id" => "$type_id");
        }
     
        $data = $this->paginate('Member', $conditions);
        $this->set('searchword', $searchword);
        $this->set("members", $data);
         
        $favorites = $this->Member->Favorite->find('list');
        $types = $this->Member->Type->find('list');
        $this->set(compact('favorites','types'));
    }