在我們使用PHPCMS開發一些產品展示類網站的時候,由於分類的多樣化,我們需要客戶在簡短的時間內尋找到自己需要的產品,這樣我們就會用到分類的多重篩選,也就是類似京東,淘寶等這麼電商網站裡面的產品篩選的功能,PHPCMS本身並沒有這樣的功能,需要我們進行二次開發,當然網上也出現了很多這樣的功能,但不知道為什麼,按照上面的步驟能實現的時候並不多,在經過一系列的尋找和自己測試之後,我自己總結了以下的方法,希望後來者看到之後可以省去很多不必要的麻煩,我會儘可能的詳細寫出是怎麼實現的。 實現的效果在這裡就不貼圖片了,淘寶,京東上比我做的還好。
首先,要實現這個功能,在建立欄位的時候欄位的類型必須選擇box類型,在是否作為篩選欄位的項目裡勾選“是”,是否作為搜尋條件勾選“是”。
這建立好欄位之後,剩下的就是怎麼實現這個功能了。咱們需要在PHPCMS的自訂函數庫這個檔案裡編寫相應的分類篩選函數,代碼如下:
/**
* 通過指定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 ? '<a class="click" style="color:#fff;">'.$v['name'].'</a>' : '<a href='.$array[$k]['url'].'>'.$v['name'].'</a>' ;
}
}
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#wrap';
//根據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[] = '0';
$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 ? '<a class="click" style="color:#fff;">'.$v[0].'</a>' : '<a href='.$option[$k]['url'].'>'.$v[0].'</a>' ; //這個地方的a標籤的class可以改成符合你自己網站的樣式,
}
$all['name'] = '全部';//'全部';
$all['url'] = structure_filters_url($field,array($field=>'0'),2,$modelid);
$all['menu'] = $field_value == '' ? '<a class="click" style="color:#fff;">'.$all['name'].'</a>' : '<a href='.$all['url'].'>'.$all['name'].'</a>';
array_push($option,$all);
return $option;
}
把上面的這段代碼複製到:extention.func.php這個檔案裡,在前台調用的時候需要一點點的改動,調用代碼如下:
{php $sql = structure_filters_sql($modelid);}
{pc:content action="lists" where="$sql" catid="$catid" modelid="$modelid" num="12" page="$page"}
再調用的時候一定不要忽略了catid和modelid,二者缺其一無法調用。產品分類怎麼調用呢?相信大家也看到了,在剛剛添加的函數裡面有一個fliters函數,我們使用這個函數來調用已添加的box類型的欄位,讀取出我們需要進行篩選的分類。代碼如下:
{loop filters('fengge',$modelid) $r} //filters('需要調用的欄位','欄位所在的模型ID')
<li>{$r[menu]}</li>
{/loop}
好了,在進行了如上幾個步驟之後,你就會發現前台的分類篩選功能已經可以使用了,這時你是否是發現URL太長太不美觀?沒關係,假如你的空間支援偽靜態話,就可以把網站的URL調的簡單美觀。PHPCMS安裝包裡內建了一個.htaccess檔案,直接複製到根目錄裡就好了。如果是IIS伺服器的話,需要httpd.ini檔案,轉化一下就可以了,現在的IIS7有一個匯入規則的功能,可以直接把.htaccess檔案轉化成web.config檔案,這樣就實現了偽靜態。一定要注意,把你自己添加的box篩選欄位也加入到偽靜態規則裡,否則是出現一些不必要的錯誤。