検索と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'));
}
