资源教程
当前位置:资源教程 >
phpcms v9 实现列表筛选功能图文教程
发布日期:2019-12-14 17:23:51 阅读次数:0 字体大小:

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这个参数!
大功告成,这样既然正常分页传参,也能正常获取当前栏目信息,获取的信息总数也正确了


豆豆网络公司服务电话

微信同号(请先加微信)

18700509585

Copyright 2018-2020 豆豆网一个被工作耽误的程序员 地址:陕西安康    陕ICP备16007519号-3  

服务电话
服务电话 服务电话  18700509585
电话(微信同号)
电话(微信同号) 电话(微信同号)  18700509585
工具条

扫一扫,加微信咨询

返回顶部
返回顶部 返回顶部