開発メモ,主に補足by子連れ親父プログラマー

2011-10-28

CakePHP1.3で作る会員管理システム(23) 検索とPagination

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

このブログを検索

Powered by Blogger.

ラベル

php (17) jQuery (13) OSX (10) MySQL (8) Javascript (7) Postgres (7) port (7) apache (6) Java (3) Smarty (2) html (2) pear (2) FCKEditor (1) XAMPP (1) css (1) git (1) perl (1) ruby (1)

Facebookバナー