天天看點

phpcms-v9】前台模闆檔案中{pc}标簽的執行流程

前台pc标簽的使用:{pc:content 參數名="參數值" 參數名="參數值" 參數名="參數值"} 
如: {pc:content action="lists" catid="9" cache="3600" num="20" page="$page"}{/pc} 
執行流程如下:
     ①子產品名:content
     ②子產品類檔案:modules/content/classes/content_tag.class.php,便于二次開發或标簽的擴充
     ③檔案中的方法:lists
     ④action後面的參數以數組的形式傳遞給lists方法,如:function lists($data=array()) 
此标簽實際擷取的是:content_tag.class.php檔案中lists方法傳回的資料
注意:此标簽會根據catid的值去尋找對應的模型id,然後再根據對應的模型id尋找到對應的模型表,如:news
注意:幾乎所有的子產品都有一個标簽類,格式如下:子產品名_tag.class.php
注意:前台模闆檔案中出現{pc}标簽的位置,都可在"碎片管理"中進行編輯修改,非常友善

content_tag.class.php檔案分析-pc标簽調用的方法

<?php
class content_tag {
    private $db;                                                            //主要針對v9_news表
    public function __construct() {
        $this->db = pc_base::load_model('content_model');                    //資料模型,對應資料表news 和 news_data 
        $this->position = pc_base::load_model('position_data_model');        //position_data表
    }
    /**
     * 初始化模型,其實就是為了根據欄目id設定對應對應的模型表及資料表:news-模型表、v9_news-資料表
     * @param $catid
     */
    public function set_modelid($catid) {
        $siteids = getcache('category_content','commons');    //擷取所有欄目所屬的站點id 
        if(!$siteids[$catid]) return false;                    //不存在此欄目,傳回false 
        $siteid = $siteids[$catid];                            //目前欄目所屬站點id  
        $this->category = getcache('category_content_'.$siteid,'commons');//擷取目前站點id下所有欄目的配置資訊
        if($this->category[$catid]['type']!=0) return false;//如果不為内部欄目,傳回false  0-内部欄目 1-單網頁 2-外部連結
        $this->modelid = $this->category[$catid]['modelid'];//擷取目前欄目所屬模型id  
        $this->db->set_model($this->modelid);                //根據模型id擷取目前模型所對應的模型表和資料表 1:文檔模型-news  3:圖檔模型-picture   2:下載下傳模型-download
        $this->tablename = $this->db->table_name;            //資料表:v9_news
        if(empty($this->category)) {                        //如果目前站點下不存在欄目配置資訊,則傳回false
            return false;
        } else {                                            //如果目前站點下存在欄目配置資訊,則傳回true
            return true;
        }
    }
    /**
     * 分頁統計
     * @param $data
     */
    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);
        }
    }
    
    /**
     * 清單頁标簽:主要傳回的是主表中資料與附表中資料, {pc:content action="lists"} {/pc}标簽調用的都是lists方法
     * @param $data
     */
    public function lists($data) {
        $catid = intval($data['catid']);                                    //pc标簽中catid屬性
        if(!$this->set_modelid($catid)) return false;                        //會根據欄目id->對應的模型id->對應的模型表
        if(isset($data['where'])) {                                            //如果pc标簽中設定了where屬性,一般情況下不存在
            $sql = $data['where'];                                            
        } else {                                                            //如果pc标簽中沒有設定where屬性 
            $thumb = intval($data['thumb']) ? " AND thumb != ''" : '';        //如果有thumb屬性
            if($this->category[$catid]['child']) {                            //目前欄目下是否存在子欄目
                $catids_str = $this->category[$catid]['arrchildid'];        //所有子欄目id,包括目前欄目自身id
                $pos = strpos($catids_str,',')+1;                            
                $catids_str = substr($catids_str, $pos);                    //所有子欄目id,不包括目前欄目自身id
                $sql = "status=99 AND catid IN ($catids_str)".$thumb;        //拼接成一個sql語句
            } else {
                $sql = "status=99 AND catid='$catid'".$thumb;                //如果目前欄目下不存在子欄目
            }
        }
        $order = $data['order'];                                            //pc标簽中order屬性
        //$sql作為一個條件出現,調用的是model.calss.php檔案中的select方法,傳回結果集數組,并按照鍵名'id'排序
        $return = $this->db->select($sql, '*', $data['limit'], $order, '', 'id');//從資料庫中擷取主表資料,使用的也是sql語句查詢
                        
        //調用副表的資料
        if (isset($data['moreinfo']) && intval($data['moreinfo']) == 1) {    //如果pc标簽中設定了moreinfo屬性:是否調用附表資料
            $ids = array();
            //$return為傳回的主表資料
            foreach ($return as $v) {                                        //循環主表中的記錄資訊:$v-主表中的每條記錄
                if (isset($v['id']) && !empty($v['id'])) {
                    $ids[] = $v['id'];                                        //ids[]是主表中排序完成的文章id數組
                } else {
                    continue;
                }
            }
            if (!empty($ids)) {
                $this->db->table_name = $this->db->table_name.'_data';        //副表名 
                $ids = implode('\',\'', $ids);                                //以逗号拼接成一個字元串
                $r = $this->db->select("`id` IN ('$ids')", '*', '', '', '', 'id');//查詢與主表中資料有關的副表中的資料
                if (!empty($r)) {
                    foreach ($r as $k=>$v) {                                //副表中的資料
                        //$return:傳回的主表中的資料,主表中的id字段值與附表中的id字段值是對應的,也就是說一篇文章在主表中存儲的id跟在附表中存儲的id的值是相等的
                        if (isset($return[$k])) $return[$k] = array_merge($v, $return[$k]);//主表中資料與副表中資料合并 
                    }
                }
            }
        }
        return $return;
    }
    
    /**
     * 相關文章标簽,{pc:content action="relation"} {/pc}标簽調用的都是relation方法
     * @param $data
     */
    public function relation($data) {
        $catid = intval($data['catid']);                                    //pc标簽的catid屬性:欄目id
        if(!$this->set_modelid($catid)) return false;
        $order = $data['order'];                                            //pc标簽的order屬性
        $sql = "`status`=99";                                                //拼接sql
        $limit = $data['id'] ? $data['limit']+1 : $data['limit'];
        if($data['relation']) {                                                //pc标簽的relation屬性:相關文章id   格式如下:2|7|5
            $relations = explode('|',trim($data['relation'],'|'));            //以 | 分割成一個數組
            $relations = array_diff($relations, array(null));
            $relations = implode(',',$relations);
            $sql = " `id` IN ($relations)";                                    //拼接sql
            $key_array = $this->db->select($sql, '*', $limit, $order,'','id');//關聯的文章
        } elseif($data['keywords']) {                                        //相關關鍵詞
            $keywords = str_replace('%', '',$data['keywords']);
            $keywords_arr = explode(' ',$keywords);                            //以空格将關鍵詞分割為一個數組
            $key_array = array();
            $number = 0;                                                    //相關熱詞文章數量
            $i =1;                                                            //控制傳回文章數量的辨別
            foreach ($keywords_arr as $_k) {                                
                $sql2 = $sql." AND `keywords` LIKE '%$_k%'".(isset($data['id']) && intval($data['id']) ? " AND `id` != '".abs(intval($data['id']))."'" : '');
                $r = $this->db->select($sql2, '*', $limit, '','','id');
                $number += count($r);                                        //所有熱詞文章的總量
                foreach ($r as $id=>$v) {
                    if($i<= $data['limit'] && !in_array($id, $key_array)) $key_array[$id] = $v;//$key_array[文章id]=文章記錄
                    $i++;
                }
                if($data['limit']<$number) break;
            }
        }
        if($data['id']) unset($key_array[$data['id']]);//針對性的屏蔽某篇文章
        return $key_array;
    }
    
    /**
     * 排行榜标簽{pc:content action="hits"} {/pc}标簽調用的都是hits方法
     * @param $data
     */
    public function hits($data) {
        $catid = intval($data['catid']);                                    //欄目id,pc标簽的catid屬性
        if(!$this->set_modelid($catid)) return false;                        //根據欄目id->對應的模型id->模型表,如:news

        $this->hits_db = pc_base::load_model('hits_model');                    //hits:點選量表            
        $sql = $desc = $ids = '';
        $array = $ids_array = array();
        $order = $data['order'];                                            //pc标簽中order屬性
        $hitsid = 'c-'.$this->modelid.'-%';                                    //hits點選量表中hitsid字段的組成:c-模型id-文章id
        $sql = "hitsid LIKE '$hitsid'";                                        //拼接sql
        if(isset($data['day'])) {                                            //pc标簽中day屬性:表示調用多少天内的排行
            $updatetime = SYS_TIME-intval($data['day'])*86400;                //表示調用多少天内的排行
            $sql .= " AND updatetime>'$updatetime'";                        //拼接sql
        }
        if($this->category[$catid]['child']) {                                //目前欄目是否有子欄目
            $catids_str = $this->category[$catid]['arrchildid'];            //目前欄目下所有子欄目id,包括目前欄目自身的id
            $pos = strpos($catids_str,',')+1;
            $catids_str = substr($catids_str, $pos);                        //目前欄目下所有子欄目id,不包括目前欄目自身id
            $sql .= " AND catid IN ($catids_str)";                            //拼接sql
        } else {
            $sql .= " AND catid='$catid'";                                    //如果目前欄目不存在子欄目
        }
        $hits = array();
        $result = $this->hits_db->select($sql, '*', $data['limit'], $order);//查詢v9_hits點選量表
        foreach ($result as $r) {                                            //$result:v9_hits表中傳回的資料
            $pos = strpos($r['hitsid'],'-',2) + 1;                            //格式:c-模型id-文章id,如,c-1-1 ,查找第二個 "-"的位置
            $ids_array[] = $id = substr($r['hitsid'],$pos);                    //文章的id
            $hits[$id] = $r;                                                //每篇文章的點選量資訊 ,格式:$hits[文章id]= 文章點選記錄資訊
        }
        $ids = implode(',', $ids_array);                                    //以逗号拼接成一個字元串
        if($ids) {                                    
            $sql = "status=99 AND id IN ($ids)";                            //拼接sql
        } else {
            $sql = '';
        }
        $this->db->table_name = $this->tablename;                            //内容主表:v9_news
        $result = $this->db->select($sql, '*', $data['limit'],'','','id');  //查詢内容主表:v9_news
        foreach ($ids_array as $id) {
            if($result[$id]['title']!='') {
                $array[$id] = $result[$id];
                $array[$id] = array_merge($array[$id], $hits[$id]);            //将内容主表v9_news中資料與點選量表v9_hits中資料合并,合并橋梁為id
            }
        }
        return $array;
    }
    /**
     * 欄目标簽:主要用來傳回目前欄目下的所有子欄目及子欄目的url連結位址等資訊:{pc:content action="category"} {/pc}标簽調用的都是category方法
     * @param $data
     */
    public function category($data) {
        $data['catid'] = intval($data['catid']);                            //pc标簽的catid屬性:欄目id
        $array = array();
        $siteid = $data['siteid'] && intval($data['siteid']) ? intval($data['siteid']) : get_siteid();//pc标簽的siteid屬性:預設調用系統站點
        $categorys = getcache('category_content_'.$siteid,'commons');        //擷取目前站點下所有欄目的詳細配置資訊
        $site = siteinfo($siteid);                                            //擷取目前站點的資訊
        $i = 1;
        foreach ($categorys as $catid=>$cat) {
            if($i>$data['limit']) break;
            if((!$cat['ismenu']) || $siteid && $cat['siteid']!=$siteid) continue;//ismenu:是否顯示欄目,1-顯示欄目   0-不顯示欄目
            if (strpos($cat['url'], '://') === false) {                        //目前欄目的url連結位址中是否存在 "://"
                $cat['url'] = substr($site['domain'],0,-1).$cat['url'];        //目前欄目的url連結位址
            }
            if($cat['parentid']==$data['catid']) {                            //預設為0,調用一級欄目,$cat['parentid']隻有一個值
                $array[$catid] = $cat;                                        //所有子欄目資訊
                $i++;
            }
        }
        return $array;
    }
    
    /**
     * 推薦位,主要用來傳回目前推薦位置所有文章的标題和url連結位址等資訊:{pc:content action="position"} {/pc}标簽調用的都是position方法
     * @param $data
     */
    public function position($data) {
        $sql = '';
        $array = array();
        $posid = intval($data['posid']);                                    //pc标簽中posid屬性:推薦位id
        $order = $data['order'];                                            //pc标簽中order屬性
        $thumb = (empty($data['thumb']) || intval($data['thumb']) == 0) ? 0 : 1;//pc标簽中thumb屬性
        $siteid = $GLOBALS['siteid'] ? $GLOBALS['siteid'] : 1;                //目前站點id
        $catid = (empty($data['catid']) || $data['catid'] == 0) ? '' : intval($data['catid']);//pc标簽中的catid屬性
        if($catid) {                                                        //如果欄目id存在
            $siteids = getcache('category_content','commons');                //擷取所有欄目所對應的站點id
            if(!$siteids[$catid]) return false;                                //目前站點下不存在目前欄目,則傳回false
            $siteid = $siteids[$catid];                                        //目前站點id
            $this->category = getcache('category_content_'.$siteid,'commons');//目前站點id下所有欄目的詳細配置資訊
        }
        if($catid && $this->category[$catid]['child']) {                    //目前欄目是否存在子欄目
            $catids_str = $this->category[$catid]['arrchildid'];            //目前欄目下所有子欄目id,包括目前欄目自身id
            $pos = strpos($catids_str,',')+1;
            $catids_str = substr($catids_str, $pos);                        //目前欄目下所有子欄目id,不包括目前欄目自身id
            $sql = "`catid` IN ($catids_str) AND ";                            //拼接sql
        }  elseif($catid && !$this->category[$catid]['child']) {            //如果目前欄目不存在子欄目
                $sql = "`catid` = '$catid' AND ";
        }
        if($thumb) $sql .= "`thumb` = '1' AND ";                            //有縮略圖的情況
        if(isset($data['where'])) $sql .= $data['where'].' AND ';            //pc标簽的where屬性:一般情況下沒有此屬性
        if(isset($data['expiration']) && $data['expiration']==1) $sql .= '(`expiration` >= \''.SYS_TIME.'\' OR `expiration` = \'0\' ) AND ';
        $sql .= "`posid` = '$posid' AND `siteid` = '".$siteid."'";            //拼接sql
        $pos_arr = $this->position->select($sql, '*', $data['limit'],$order);//查詢v9_position_data表
        if(!empty($pos_arr)) {
            foreach ($pos_arr as $info) {                                    //循環查詢到的v9_position_data表中的記錄
                $key = $info['catid'].'-'.$info['id'];                        //格式:欄目id-文章id 
                $array[$key] = string2array($info['data']);                    //将v9_position_data表中data字段的值轉換為數組
                $array[$key]['url'] = go($info['catid'],$info['id']);        //url連結位址
                $array[$key]['id'] = $info['id'];                            //文章id
                $array[$key]['catid'] = $info['catid'];                        //欄目id
                $array[$key]['listorder'] = $info['listorder'];                //排序
            }
        }
        return $array;
    }
    /**
     * 可視化标簽,主要用于在背景可視化的對pc标簽進行編輯
     */
    public function pc_tag() {
        $positionlist = getcache('position','commons');
        $sites = pc_base::load_app_class('sites','admin');
        $sitelist = $sites->pc_tag_list();
        
        foreach ($positionlist as $_v) if($_v['siteid'] == get_siteid() || $_v['siteid'] == 0) $poslist[$_v['posid']] = $_v['name'];
        return array(
            'action'=>array('lists'=>L('list','', 'content'),'position'=>L('position','', 'content'), 'category'=>L('subcat', '', 'content'), 'relation'=>L('related_articles', '', 'content'), 'hits'=>L('top', '', 'content')),
            'lists'=>array(
                'catid'=>array('name'=>L('catid', '', 'content'),'htmltype'=>'input_select_category','data'=>array('type'=>0),'validator'=>array('min'=>1)),
                'order'=>array('name'=>L('sort', '', 'content'), 'htmltype'=>'select','data'=>array('id DESC'=>L('id_desc', '', 'content'), 'updatetime DESC'=>L('updatetime_desc', '', 'content'), 'listorder ASC'=>L('listorder_asc', '', 'content'))),
                'thumb'=>array('name'=>L('thumb', '', 'content'), 'htmltype'=>'radio','data'=>array('0'=>L('all_list', '', 'content'), '1'=>L('thumb_list', '', 'content'))),
                'moreinfo'=>array('name'=>L('moreinfo', '', 'content'), 'htmltype'=>'radio', 'data'=>array('1'=>L('yes'), '0'=>L('no')))
            ),
            'position'=>array(
                'posid'=>array('name'=>L('posid', '', 'content'),'htmltype'=>'input_select','data'=>$poslist,'validator'=>array('min'=>1)),
                'catid'=>array('name'=>L('catid', '', 'content'),'htmltype'=>'input_select_category','data'=>array('type'=>0),'validator'=>array('min'=>0)),
                'thumb'=>array('name'=>L('thumb', '', 'content'), 'htmltype'=>'radio','data'=>array('0'=>L('all_list', '', 'content'), '1'=>L('thumb_list', '', 'content'))),            
                'order'=>array('name'=>L('sort', '', 'content'), 'htmltype'=>'select','data'=>array('listorder DESC'=>L('listorder_desc', '', 'content'),'listorder ASC'=>L('listorder_asc', '', 'content'),'id DESC'=>L('id_desc', '', 'content'))),
            ),
            'category'=>array(
                'siteid'=>array('name'=>L('siteid'), 'htmltype'=>'input_select', 'data'=>$sitelist),
                'catid'=>array('name'=>L('catid', '', 'content'), 'htmltype'=>'input_select_category', 'data'=>array('type'=>0))
            ),
            'relation'=>array(
                'catid'=>array('name'=>L('catid', '', 'content'), 'htmltype'=>'input_select_category', 'data'=>array('type'=>0), 'validator'=>array('min'=>1)),
                'order'=>array('name'=>L('sort', '', 'content'), 'htmltype'=>'select','data'=>array('id DESC'=>L('id_desc', '', 'content'), 'updatetime DESC'=>L('updatetime_desc', '', 'content'), 'listorder ASC'=>L('listorder_asc', '', 'content'))),
                'relation'=>array('name'=>L('relevant_articles_id', '', 'content'), 'htmltype'=>'input'),
                'keywords'=>array('name'=>L('key_word', '', 'content'), 'htmltype'=>'input')
            ),
            'hits'=>array(
                'catid'=>array('name'=>L('catid', '', 'content'), 'htmltype'=>'input_select_category', 'data'=>array('type'=>0), 'validator'=>array('min'=>1)),
                'day'=>array('name'=>L('day_select', '', 'content'), 'htmltype'=>'input', 'data'=>array('type'=>0)),
            ),
                
        );
    }
}