phpcms v9 實現篩選功能圖文教程

phpcms v9實現數據內容篩選功能,很多人都想要這個功能,今天我就講一下我是怎麼實現phpcms v9數據內容篩選功能的。

先來看圖:

wKiom1kBqPSzgShpAAB2OSfZxZ8492.jpg



注意:此教程目前只適用於動態頁面,並且可能有些不完善的地方,因爲數據是直接讀取SQL的,所以會把同模型的其他欄目數據調用出來。所以建議單獨新建一個模型。

添加字段:

後臺 --> 內容 --> 內容相關設置 --> 模型管理 --> 文章模型 --> 字段管理 --> 添加字段


如下圖示例

wKioL1kBqYfB-j_QAACxU5WSiSI446.jpg


添加自定義函數:

將以下代碼添加到 phpcms/libs/functions/extention.func.php 文件

/** 
 *  extention.func.php 用戶自定義函數庫 
 * 
 * @copyright                        (C) 2005-2010 PHPCMS 
 * @license                           http://www.phpcms.cn/license/ 
 * @lastmodify                        2010-10-27 
 */ 
 
/********************實現篩選功能************************/ 
 /** 
 * 通過指定keyid形式顯示所有聯動菜單 
 * @param  $keyid 菜單主id 
 * @param  $linkageid  聯動菜單id,0調用頂級 
 * @param  $modelid 模型id 
 * @param  $fieldname  字段名稱 
 */ 
function show_linkage($keyid, $linkageid = 0, $modelid = '', $fieldname='zone') { 
    $datas = $infos = $array = array(); 
    $keyid = intval($keyid); 
    $linkageid = intval($linkageid); 
    //當前菜單id 
    $field_value = intval($_GET[$fieldname]); 
    $urlrule = structure_filters_url($fieldname,$array,1,$modelid); 
    if($keyid == 0) return false; 
    $datas = getcache($keyid,'linkage'); 
    $infos = $datas['data']; 
 
    foreach($infos as $k=>$v){ 
        if($v['parentid']==$field_value){ 
            $array[$k]['name'] = $v['name']; 
            $array[$k]['value'] = $k; 
            $array[$k]['url'] = str_replace('{$'.$fieldname.'}',$k,$urlrule); 
            $array[$k]['menu'] = $field_value == $k ? ''.$v['name'].'' : '.$array[$k]['url'].'>'.$v['name'].'' ; 
            } 
            } 
            return $array; 
            } 
function structure_filters_url($fieldname,$array=array(),$type = 1,$modelid) { 
    if(empty($array)) { 
        $array = $_GET; 
        } else { 
            $array = array_merge($_GET,$array); 
            } 
        //TODO 
        $fields = getcache('model_field_'.$modelid,'model'); 
        if(is_array($fields) && !empty($fields)) { 
            ksort($fields); 
            foreach ($fields as $_v=>$_k) { 
                if($_k['filtertype'] || $_k['rangetype']) { 
                    if(strpos(URLRULE,'.html') === FALSE) $urlpars .= '&'.$_v.'={$'.$_v.'}'; 
                    else $urlpars .= '-{$'.$_v.'}'; 
                    } 
                    } 
                    } 
        //後期增加僞靜態等其他url規則管理,apache僞靜態支持9個參數 
        if(strpos(URLRULE,'.html') === FALSE) $urlrule =APP_PATH.'index.php?m=content&c=index&a=lists&catid={$catid}'.$urlpars.'&page={$page}' ; 
        else $urlrule =APP_PATH.'list-{$catid}'.$urlpars.'-{$page}.html'; 
        //根據get傳值構造URL 
        if (is_array($array)) foreach ($array as $_k=>$_v) { 
            if($_k=='page') $_v=1; 
            if($type == 1) if($_k==$fieldname) continue; 
            $_findme[] = '/{\$'.$_k.'}/'; 
            $_replaceme[] = $_v; 
            } 
     //type 模式的時候,構造排除該字段名稱的正則 
        if($type==1) $filter = '(?!'.$fieldname.'.)'; 
        $_findme[] = '/{\$'.$filter.'([a-z0-9_]+)}/'; 
        $_replaceme[] = ''; 
        $urlrule = preg_replace($_findme, $_replaceme, $urlrule); 
        return         $urlrule; 
        } 
/** 
 * 生成分類信息中的篩選菜單 
 * @param $field   字段名稱 
 * @param $modelid  模型ID 
 */ 
function filters($field,$modelid,$diyarr = array()) { 
    $fields = getcache('model_field_'.$modelid,'model'); 
    $options = empty($diyarr) ?  explode("\n",$fields[$field]['options']) : $diyarr; 
    $field_value = intval($_GET[$field]); 
    foreach($options as $_k) { 
        $v = explode("|",$_k); 
        $k = trim($v[1]); 
        $option[$k]['name'] = $v[0]; 
        $option[$k]['value'] = $k; 
        $option[$k]['url'] = structure_filters_url($field,array($field=>$k),2,$modelid); 
        $option[$k]['menu'] = $field_value == $k ? ''.$v[0].'' : '.$option[$k]['url'].'>'.$v[0].'' ; 
    } 
    $all['name'] = '全部'; 
    $all['url'] = structure_filters_url($field,array($field=>''),2,$modelid); 
    $all['menu'] = $field_value == '' ? ''.$all['name'].'' : '.$all['url'].'>'.$all['name'].''; 
 
    array_unshift($option,$all); 
    return $option; 
} 
 
/** 
 * 獲取聯動菜單層級 
 * @param  $keyid     聯動菜單分類id 
 * @param  $linkageid 菜單id 
 * @param  $leveltype 獲取類型 parentid 獲取父級id child 獲取時候有子欄目 arrchildid 獲取子欄目數組 
 */ 
function get_linkage_level($keyid,$linkageid,$leveltype = 'parentid') { 
    $child_arr = $childs = array(); 
    $leveltypes = array('parentid','child','arrchildid','arrchildinfo'); 
    $datas = getcache($keyid,'linkage'); 
    $infos = $datas['data']; 
    if (in_array($leveltype, $leveltypes)) { 
        if($leveltype == 'arrchildinfo') { 
            $child_arr = explode(',',$infos[$linkageid]['arrchildid']); 
            foreach ($child_arr as $r) { 
                $childs[] = $infos[$r]; 
            } 
            return $childs; 
        } else { 
            return $infos[$linkageid][$leveltype]; 
        } 
    }     
} 
 
// 根據linkageid遞歸到父級 
function get_parent_url($modelid,$field,$linkageid=0,$array = array()){ 
    $modelid = intval($modelid); 
    if(!$modelid || empty($field)) return false; 
    $fields = getcache('model_field_'.$modelid,'model'); 
    $keyid = $fields[$field]['linkageid']; 
    $datas = getcache($keyid,'linkage'); 
    $infos = $datas['data']; 
                 
    if(empty($linkageid)){ 
        $linkageid = intval($_GET[$field]); 
        if(!$linkageid) return false; 
        } 
         
        $urlrule = structure_filters_url($field,array(),1,$modelid); 
        $urlrule = str_replace('{$'.$field.'}',$infos[$linkageid]['parentid'],$urlrule); 
        array_unshift($array,array('name'=> $infos[$linkageid]['name'],'url'=>$urlrule)); 
        if($infos[$linkageid]['parentid']){ 
            return get_parent_url($modelid,$field,$infos[$linkageid]['parentid'],$array); 
            } 
            return $array; 
            } 
/** 
 * 構造篩選時候的sql語句 
 */ 
function structure_filters_sql($modelid) { 
    $sql = $fieldname = $min = $max = ''; 
    $fieldvalue = array(); 
    $modelid = intval($modelid); 
    $model =  getcache('model','commons'); 
    $fields = getcache('model_field_'.$modelid,'model'); 
    $fields_key = array_keys($fields); 
    //TODO 
    $sql = '`status` = \'99\''; 
 
         
    foreach ($_GET as $k=>$r) { 
        if(in_array($k,$fields_key) && intval($r)!=0 && ($fields[$k]['filtertype'] || $fields[$k]['rangetype']|| $fields[$k]['boxtype'])) { 
            if($fields[$k]['formtype'] == 'linkage') { 
                $datas = getcache($fields[$k]['linkageid'],'linkage'); 
                $infos = $datas['data']; 
                if($infos[$r]['arrchildid']) { 
                    $sql .=  ' AND `'.$k.'` in('.$infos[$r]['arrchildid'].')'; 
                } 
            } elseif($fields[$k]['rangetype']) { 
                        if(is_numeric($r)) { 
                            $sql .=" AND `$k` = '$r'"; 
                        } else { 
                                $fieldvalue = explode('_',$r); 
                                $min = intval($fieldvalue[0]); 
                                $max = $fieldvalue[1] ? intval($fieldvalue[1]) : 999999; 
                                $sql .=" AND `$k` >= '$min' AND  `$k` < '$max'"; 
                        } 
            }elseif($fields[$k]['boxtype']=='checkbox') { 
                   $sql .=" AND `$k` like '%,$r,%'"; 
 
            } else { 
                   $sql .=" AND `$k` = '$r'"; 
            } 
        } 
    } 
   // echo $sql; 
   return $sql; 
} 
 
/** 
 * 分頁,如去掉則分頁會有問題 
 */ 
function makeurlrule() { 
    if(strpos(URLRULE,'.html') === FALSE) { 
        return url_par('page={$'.'page}'); 
    } 
    else { 
        $url = preg_replace('/-[0-9]+.html$/','-{$page}.html',get_url()); 
        return $url; 
    } 
} 
 
 
/********************實現前臺輸出“選項名稱”功能************************/ 
/** 
* 根據box類型字段獲取顯示名稱 
* @param $field 字段名稱 
* @param $value 字段值 
* @param $modelid 字段所在模型id 
*/ 
function box($field, $value, $modelid='') { 
        $fields = getcache('model_field_'.$modelid,'model'); 
        extract(string2array($fields[$field]['setting'])); 
        $options = explode("\n",$fields[$field]['options']); 
        foreach($options as $_k) { 
                $v = explode("|",$_k); 
                $k = trim($v[1]); 
                $option[$k] = $v[0]; 
        } 
        $string = ''; 
        switch($fields[$field]['boxtype']) { 
                        case 'radio': 
                                $string = $option[$value]; 
                        break; 
                        case 'checkbox': 
                                $value_arr = explode(',',$value); 
                                foreach($value_arr as $_v) { 
                                        if($_v) $string .= $option[$_v].' 、'; 
                                } 
                        break; 
 
                        case 'select': 
                                $string = $option[$value]; 
                        break; 
 
                        case 'multiple': 
                                $value_arr = explode(',',$value); 
                                foreach($value_arr as $_v) { 
                                        if($_v) $string .= $option[$_v].' 、'; 
                                } 
                        break; 
                } 
                        return $string; 
} 
?>

(注:makeurlrule函數對分頁是否能傳遞相關參數很重要!

第三步:前臺模板調用

{php $sql = structure_filters_sql($modelid);}  
{php $urlrule = makeurlrule()} 
{pc:content action="lists" catid="$catid" where="$sql"  modelid="$modelid" num="10" page="$page" moreinfo="1"  urlrule="$urlrule" return="data" } 
{loop $data $r} 
........
{/loop} 
{/pc}



第一個問題:list條件下加入where後其他條件失效的問題


之前的一篇文章:解決lists標籤中,加上where後其他條件失效的問題,其他條件失效了,如catid,thumb等等,也就是無法獲取當前欄目的信息,而是把整個欄目下的所有文章都調用出來了!
打開/phpcms/modules/content/classes/目錄下的content_tag.class.php這個文件,把下面的代碼(大概第63行)

if(isset($data['where'])) {   
$sql = $data['where'];   
} else {   
$thumb = intval($data['thumb']) ? " AND thumb != ''" : '';   
if($this->category[$catid]['child']) {   
$catids_str = $this->category[$catid]['arrchildid'];   
$pos = strpos($catids_str,',')+1;   
$catids_str = substr($catids_str, $pos);   
$sql = "status=99 AND catid IN ($catids_str)".$thumb;   
} else {   
$sql = "status=99 AND catid='$catid'".$thumb;   
}   
}

替換爲下面的代碼即可

if(isset($data['where'])) {   
$where = (isset($data['where'])&&(!empty($data['where'])))?' AND '.$data['where']:'';   
$thumb = intval($data['thumb']) ? " AND thumb != ''" : '';   
if($this->category[$catid]['child']) {   
$catids_str = $this->category[$catid]['arrchildid'];   
$pos = strpos($catids_str,',')+1;   
$catids_str = substr($catids_str, $pos);   
$sql = "status=99".$where." AND catid IN ($catids_str)".$thumb;   
} else {   
$sql = "status=99".$where." AND catid='$catid'".$thumb;   
}   
} else {   
$thumb = intval($data['thumb']) ? " AND thumb != ''" : '';   
if($this->category[$catid]['child']) {   
$catids_str = $this->category[$catid]['arrchildid'];   
$pos = strpos($catids_str,',')+1;   
$catids_str = substr($catids_str, $pos);   
$sql = "status=99 AND catid IN ($catids_str)".$thumb;   
} else {   
$sql = "status=99 AND catid='$catid'".$thumb;   
}   
}

其實主要的修改思路是$where參數中並不包含當前欄目的id值,所以在$sql增加獲取相關id的參數


第二個問題:分頁數量不對

通過研究緩存得知,調用分頁總數的函數是:

$content_total = $content_tag->count(array('catid'=>$catid,'where'=>$sql,'modelid'=>$modelid,'moreinfo'=>'1','limit'=>$offset.",".$pagesize,'action'=>'lists',));

通過這個,找到phpcms\modules\content\classes\content_tag.class.php大致36-56行,count函數如下:

public function count($data) { 
        if($data['action'] == 'lists') { 
            $catid = intval($data['catid']); 
            if(!$this->set_modelid($catid)) return false; 
            if(isset($data['where'])) { 
                $sql = $data['where']; 
            } else { 
                if($this->category[$catid]['child']) { 
                    $catids_str = $this->category[$catid]['arrchildid']; 
                    $pos = strpos($catids_str,',')+1; 
                    $catids_str = substr($catids_str, $pos); 
                    $sql = "status=99 AND catid IN ($catids_str)"; 
                } else { 
                    $sql = "status=99 AND catid='$catid'"; 
                } 
            } 
            return $this->db->count($sql); 
        } 
    }

改爲:

public function count($data) { 
        if($data['action'] == 'lists') { 
            $catid = intval($data['catid']); 
            $catids_str = $this->category[$catid]['arrchildid']; 
            if(!$this->set_modelid($catid)) return false; 
            if(isset($data['where'])) { 
                 $sql = $data['where']; 
                if($this->category[$catid]['child']) {   
                $catids_str = $this->category[$catid]['arrchildid'];   
                $pos = strpos($catids_str,',')+1;   
                $catids_str = substr($catids_str, $pos);   
                $sql = $sql." AND catid IN ($catids_str)"; 
                } else {   
                $sql = $sql." AND catid='$catid'"; 
                }   
            } else { 
                if($this->category[$catid]['child']) { 
                    $catids_str = $this->category[$catid]['arrchildid']; 
                    $pos = strpos($catids_str,',')+1; 
                    $catids_str = substr($catids_str, $pos); 
                    $sql = "status=99 AND catid IN ($catids_str)"; 
                } else { 
                    $sql = "status=99 AND catid='$catid'"; 
                } 
            } 
            return $this->db->count($sql); 
        } 
    }

你會發現,分頁統計的修改原理仍然是$where條件下,沒有傳入當前欄目id這個參數!
大功告成,這樣既然正常分頁傳參,也能正常獲取當前欄目信息,獲取的信息總數也正確了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章