POST TIME:2018-10-30 21:55
AJAX 無(wú)刷新評(píng)論功能是DeDeCMS 5.5 Final 正式版的一大亮點(diǎn),也是眾多站長(zhǎng)們選擇升級(jí)中一個(gè)重要原因。
相比5.3 版本的評(píng)論,AJAX評(píng)論能達(dá)到無(wú)刷新即時(shí)顯示最新留言及其回復(fù)功能,同時(shí),支持游客對(duì)游客發(fā)表的評(píng)論進(jìn)行引用回復(fù),增加了“支持者”“反對(duì)者”“中立者”三個(gè)不同的人物較色,讓文章的互動(dòng)性更人性化、合理化。
但是,驚喜之余難免有絲絲遺憾。
AJAX 評(píng)論無(wú)法實(shí)現(xiàn)樓層化,游客引用的評(píng)論無(wú)法嵌套在新評(píng)論,樣式不夠醒目直觀。
最近九億博客在升級(jí)程序時(shí),著重對(duì)DeDeCMS 5.5 中新增加的AJAX評(píng)論插件進(jìn)行了二次開發(fā)美化。
開發(fā)的主要內(nèi)容包括兩方面:評(píng)論實(shí)現(xiàn)樓層效果;評(píng)論回復(fù)為內(nèi)嵌樣式。
評(píng)論實(shí)現(xiàn)樓層效果的解決辦法:
分析觀察plus/feedback_ajax.php 插件文件,源代碼如下所示
<?php
require_once(dirname(__FILE__)."/../include/common.inc.php");
if($cfg_feedback_forbid==’Y’) exit(‘系統(tǒng)已經(jīng)禁止評(píng)論功能!‘);
require_once(DEDEINC."/filter.inc.php");
if(!isset($action))
{
$action = ”;
}
//兼容舊的JS代碼
if($action == ‘good’ || $action == ‘bad’)
{
if(!empty($aid)) $id = $aid;
require_once(dirname(__FILE__).’/digg_ajax.php’);
exit();
}
$cfg_formmember = isset($cfg_formmember) ? true : false;
$ischeck = $cfg_feedbackcheck==’Y’ ? 0 : 1;
$aid = (isset($aid) && is_numeric($aid)) ? $aid : 0;
$fid = (isset($fid) && is_numeric($fid)) ? $fid : 0;
if(empty($aid) && empty($fid))
{
ShowMsg(‘文檔id不能為空!’,’-1′);
exit();
}
include_once(DEDEINC."/memberlogin.class.php");
$cfg_ml = new MemberLogin();
if($action==’goodfb’)
{
AjaxHead();
$fid = intval($fid);
$dsql->ExecuteNoneQuery("Update `dede_feedback` set good = good+1 where id=’$fid’ ");
$row = $dsql->GetOne("Select good From `dede_feedback` where id=’$fid’ ");
echo "<a onclick="postBadGood(‘goodfb’,{$aid})">支持</a>[{$row['good']}]";
exit();
}
else if($action==’badfb’)
{
AjaxHead();
$fid = intval($fid);
$dsql->ExecuteNoneQuery("Update `dede_feedback` set bad = bad+1 where id=’$fid’ ");
$row = $dsql->GetOne("Select bad From `dede_feedback` where id=’$fid’ ");
echo "<a onclick="postBadGood(‘badfb’,{$aid})">反對(duì)</a>[{$row['bad']}]";
exit();
}
//查看評(píng)論
/*
function __ViewFeedback(){ }
*/
//———————————–
else if($action==” || $action==’show’)
{
//讀取文檔信息
$arcRow = GetOneArchive($aid);
if(empty($arcRow['aid']))
{
ShowMsg(‘無(wú)法查看未知文檔的評(píng)論!’,’-1′);
exit();
}
extract($arcRow, EXTR_SKIP);
include_once(DEDEINC.’/datalistcp.class.php’);
$dlist = new DataListCP();
$dlist->pageSize = 20;
if(empty($ftype) || ($ftype!=’good’ && $ftype!=’bad’ && $ftype!=’feedback’))
{
$ftype = ”;
}
$wquery = $ftype!=” ? " And ftype like ‘$ftype’ " : ”;
//評(píng)論內(nèi)容列表
$querystring = "select fb.*,mb.userid,mb.face as mface,mb.spacesta,mb.scores from `dede_feedback` fb
left join `dede_member` mb on mb.mid = fb.mid
where fb.aid=’$aid’ and fb.ischeck=’1′ $wquery order by fb.id desc";
$dlist->SetParameter(‘aid’,$aid);
$dlist->SetParameter(‘action’,’show’);
$dlist->SetTemplate(DEDETEMPLATE.’/plus/feedback_templet.htm’);
$dlist->SetSource($querystring);
$dlist->Display();
exit();
}
//引用評(píng)論
//————————————
/*
function __Quote(){ }
*/
else if($action==’quote’)
{
$row = $dsql->GetOne("Select * from `dede_feedback` where id =’$fid’");
require_once(DEDEINC.’/dedetemplate.class.php’);
$dtp = new DedeTemplate();
$dtp->LoadTemplate(DEDETEMPLATE.’/plus/feedback_quote.htm’);
$dtp->Display();
exit();
}
//發(fā)表評(píng)論
//————————————
/*
function __SendFeedback(){ }
*/
else if($action==’send’)
{
//讀取文檔信息
$arcRow = GetOneArchive($aid);
if((empty($arcRow['aid']) || $arcRow['notpost']==’1′)&&empty($fid))
{
ShowMsg(‘無(wú)法對(duì)該文檔發(fā)表評(píng)論!’,’-1′);
exit();
}
//是否加驗(yàn)證碼重確認(rèn)
if(empty($isconfirm))
{
$isconfirm = ”;
}
if($isconfirm!=’yes’ && $cfg_feedback_ck==’Y’)
{
extract($arcRow, EXTR_SKIP);
require_once(DEDEINC.’/dedetemplate.class.php’);
$dtp = new DedeTemplate();
$dtp->LoadTemplate(DEDETEMPLATE.’/plus/feedback_confirm.htm’);
$dtp->Display();
exit();
}
//檢查驗(yàn)證碼
if($cfg_feedback_ck==’Y’)
{
$validate = isset($validate) ? strtolower(trim($validate)) : ”;
$svali = strtolower(trim(GetCkVdValue()));
if($validate != $svali || $svali==”)
{
ResetVdValue();
ShowMsg(‘驗(yàn)證碼錯(cuò)誤!‘,’-1′);
exit();
}
}
//檢查用戶登錄
if(empty($notuser))
{
$notuser=0;
}
//匿名發(fā)表評(píng)論
if($notuser==1)
{
$username = $cfg_ml->M_ID > 0 ? ‘匿名‘ : ‘游客‘;
}
//已登錄的用戶
else if($cfg_ml->M_ID > 0)
{
$username = $cfg_ml->M_UserName;
}
//用戶身份驗(yàn)證
else
{
if($username!=” && $pwd!=”)
{
$rs = $cfg_ml->CheckUser($username,$pwd);
if($rs==1)
{
$dsql->ExecuteNoneQuery("Update `dede_member` set logintime=’".time()."’,loginip=’".GetIP()."’ where mid=’{$cfg_ml->M_ID}’; ");
}
else
{
$username = ‘游客‘;
}
}
else
{
$username = ‘游客‘;
}
}
$ip = GetIP();
$dtime = time();
//檢查評(píng)論間隔時(shí)間;
if(!empty($cfg_feedback_time))
{
//檢查最后發(fā)表評(píng)論時(shí)間,如果未登陸判斷當(dāng)前IP最后評(píng)論時(shí)間
if($cfg_ml->M_ID > 0)
{
$where = "WHERE `mid` = ‘$cfg_ml->M_ID’";
}
else
{
$where = "WHERE `ip` = ‘$ip’";
}
$row = $dsql->GetOne("SELECT dtime FROM `dede_feedback` $where ORDER BY `id` DESC ");
if(is_array($row) && $dtime – $row['dtime'] < $cfg_feedback_time)
{
ResetVdValue();
ShowMsg(‘管理員設(shè)置了評(píng)論間隔時(shí)間,請(qǐng)稍等休息一下!‘,’-1′);
exit();
}
}
if(empty($face))
{
$face = 0;
}
$face = intval($face);
extract($arcRow, EXTR_SKIP);
$msg = cn_substrR(TrimMsg($msg),1000);
$username = cn_substrR(HtmlReplace($username,2),20);
if(empty($feedbacktype) || ($feedbacktype!=’good’ && $feedbacktype!=’bad’))
{
$feedbacktype = ‘feedback’;
}
//保存評(píng)論內(nèi)容
if($comtype == ‘comments’)
{
$arctitle = addslashes($title);
if($msg!=”)
{
$inquery = "INSERT INTO `dede_feedback`(`aid`,`typeid`,`username`,`arctitle`,`ip`,`ischeck`,`dtime`, `mid`,`bad`,`good`,`ftype`,`face`,`msg`)
VALUES (‘$aid’,’$typeid’,’$username’,’$arctitle’,’$ip’,’$ischeck’,’$dtime’, ‘{$cfg_ml->M_ID}’,’0′,’0′,’$feedbacktype’,’$face’,’$msg’); ";
$rs = $dsql->ExecuteNoneQuery($inquery);
if(!$rs)
{
ShowMsg(‘ 發(fā)表評(píng)論錯(cuò)誤! ‘, ‘-1′);
//echo $dsql->GetError();
exit();
}
}
}
//引用回復(fù)
elseif ($comtype == ‘reply’)
{
$row = $dsql->GetOne("Select * from `dede_feedback` where id =’$fid’");
$arctitle = $row['arctitle'];
$aid =$row['aid'];
$msg = $quotemsg.$msg;
$msg = HtmlReplace($msg,2);
$inquery = "INSERT INTO `dede_feedback`(`aid`,`typeid`,`username`,`arctitle`,`ip`,`ischeck`,`dtime`,`mid`,`bad`,`good`,`ftype`,`face`,`msg`)
VALUES (‘$aid’,’$typeid’,’$username’,’$arctitle’,’$ip’,’$ischeck’,’$dtime’,’{$cfg_ml->M_ID}’,’0′,’0′,’$feedbacktype’,’$face’,’$msg’)";
$dsql->ExecuteNoneQuery($inquery);
}
if($feedbacktype==’bad’)
{
$dsql->ExecuteNoneQuery("Update `dede_archives` set scores=scores-{cfg_feedback_sub},badpost=badpost+1,lastpost=’$dtime’ where id=’$aid’ ");
}
else if($feedbacktype==’good’)
{
$dsql->ExecuteNoneQuery("Update `dede_archives` set scores=scores+{$cfg_feedback_add},goodpost=goodpost+1,lastpost=’$dtime’ where id=’$aid’ ");
}
else
{
$dsql->ExecuteNoneQuery("Update `dede_archives` set scores=scores+1,lastpost=’$dtime’ where id=’$aid’ ");
}
if($cfg_ml->M_ID > 0)
{
$dsql->ExecuteNoneQuery("Update `dede_member` set scores=scores+{$cfg_sendfb_scores} where mid=’{$cfg_ml->M_ID}’ ");
}
//統(tǒng)計(jì)用戶發(fā)出的評(píng)論
if($cfg_ml->M_ID > 0)
{
#api{{
if(defined(‘UC_API’) && @include_once DEDEROOT.’/api/uc.func.php’)
{
//同步積分
uc_credit_note($cfg_ml->M_LoginID, $cfg_sendfb_scores);
//推送事件
$arcRow = GetOneArchive($aid);
$feed['icon'] = ‘thread’;
$feed['title_template'] = ‘<b>{username} 在網(wǎng)站發(fā)表了評(píng)論</b>’;
$feed['title_data'] = array(‘username’ => $cfg_ml->M_UserName);
$feed['body_template'] = ‘<b>{subject}</b><br>{message}’;
$url = !strstr($arcRow['arcurl'],’http://’) ? ($cfg_basehost.$arcRow['arcurl']) : $arcRow['arcurl'];
$feed['body_data'] = array(‘subject’ => "<a href="".$url."">$arcRow[arctitle]</a>", ‘message’ => cn_substr(strip_tags(preg_replace("/[.+?]/is", ”, $msg)), 150));
$feed['images'][] = array(‘url’ => $cfg_basehost.’/images/scores.gif’, ‘link’=> $cfg_basehost);
uc_feed_note($cfg_ml->M_LoginID,$feed); unset($arcRow);
}
#/aip}}
$row = $dsql->GetOne("SELECT COUNT(*) AS nums FROM `dede_feedback` WHERE `mid`=’".$cfg_ml->M_ID."’");
$dsql->ExecuteNoneQuery("UPDATE `dede_member_tj` SET `feedback`=’$row[nums]‘ WHERE `mid`=’".$cfg_ml->M_ID."’");
}
$_SESSION['sedtime'] = time();
if(empty($uid) && isset($cmtuser)) $uid = $cmtuser;
$backurl = $cfg_formmember ? "index.php?uid={$uid}&action=viewarchives&aid={$aid}" : "feedback.php?aid=$aid";
if($ischeck==0)
{
ShowMsg(‘成功發(fā)表評(píng)論,但需審核后才會(huì)顯示你的評(píng)論!’, $backurl);
}
else
{
ShowMsg(‘成功發(fā)表評(píng)論,現(xiàn)在轉(zhuǎn)到評(píng)論頁(yè)面!’, $backurl);
}
exit();
}
?>
分析這個(gè)文件,有不少循環(huán)語(yǔ)句。
哪個(gè)是與評(píng)論列表有關(guān)的呢?首先,你必須明白一個(gè)技術(shù)常識(shí)。
實(shí)現(xiàn)樓層化,要靠那種CSS+DIV 技術(shù)效果來(lái)表現(xiàn)?最簡(jiǎn)單的方法,就是用<ul><li></li></ul>這個(gè)方式了。
然后對(duì)<li style="list-style-type: decimal;list-style-position: inside;"></li>設(shè)置列表的類型為數(shù)字,位置為內(nèi)。
這樣一來(lái),<ul>下循環(huán)語(yǔ)句用<li>來(lái)控制,就很輕松實(shí)現(xiàn)評(píng)論樓層的效果了。
再來(lái)講一講,如何將引用過(guò)評(píng)論嵌套在新評(píng)論的上方。
首先,你要明白文章內(nèi)容頁(yè)調(diào)用的是ajaxfeedback.htm這個(gè)模板文件,而這個(gè)文件又由feedback_ajax.php 程序來(lái)控制。
也就是,修改引用樣式就修改feedback_ajax.php 文件,而不是feedback_quote.htm 這個(gè)文件。
找到了程序文件,接著查找與引用有關(guān)的函數(shù)值。
下面這段代碼中就包含我所要找的{quote}參數(shù):
//保存評(píng)論內(nèi)容
if(!empty($fid))
{
$row = $dsql->GetOne("Select username,msg from `dede_feedback` where id =’$fid’ ");
$qmsg = ‘{quote}{title}’.$row['username'].’ 的原帖:{/title}{content}’.$row['msg'].’{/content}{/quote}’;
$msg = addslashes($qmsg).$msg;
}
$ischeck = ($cfg_feedbackcheck==’Y’ ? 0 : 1);
$arctitle = addslashes($title);
$inquery = "INSERT INTO `dede_feedback`(`aid`,`typeid`,`username`,`arctitle`,`ip`,`ischeck`,`dtime`, `mid`,`bad`,`good`,`ftype`,`face`,`msg`)
VALUES (‘$aid’,’$typeid’,’$username’,’$arctitle’,’$ip’,’$ischeck’,’$dtime’, ‘{$cfg_ml->M_ID}’,’0′,’0′,’$feedbacktype’,’$face’,’$msg’); ";
$rs = $dsql->ExecuteNoneQuery($inquery);
if( !$rs )
{
echo "<font color=’red’>發(fā)表評(píng)論出錯(cuò)了!</font>";
//echo $dslq->GetError();
exit();
}
$newid = $dsql->GetLastID();
也許,不能找出是哪個(gè)CSS控制了這個(gè)引用樣式。
官方提供的幫助文檔,也沒(méi)有提供該參數(shù)的具體信息。
看來(lái),只要靠自己分析了。
既然知道引用的函數(shù)值是{quote} 字樣。
那就是用DW的查找替換功能,在全站范圍內(nèi)展開搜索,終于找到了,在include/channelunit.func.php 這個(gè)程序文件中發(fā)現(xiàn)了{(lán)quote} 影子。
快速打開這個(gè)文件,查找到第506行的位置,代碼如下:
//引用回復(fù)標(biāo)記處理
function Quote_replace($quote)
{
$quote = str_replace(‘{quote}’,’<div>’,$quote);
$quote = str_replace(‘{title}’,’<div class="reply1">’,$quote);
$quote = str_replace(‘{/title}’,’</div>’,$quote);
$quote = str_replace(‘<br/>’,’<br>’,$quote);
$quote = str_replace(‘{content}’,’<div class="reply2">’,$quote);
$quote = str_replace(‘{/content}’,’</div>’,$quote);
$quote = str_replace(‘{/quote}’,’</div>’,$quote);
return $quote;
}
將其修改為以下內(nèi)容:
//引用回復(fù)標(biāo)記處理
function Quote_replace($quote)
{
$quote = str_replace(‘{quote}’,’<div class="decmt-box">’,$quote);
$quote = str_replace(‘{title}’,’<div class="decmt-title"><span class="username">’,$quote);
$quote = str_replace(‘{/title}’,’</span></div>’,$quote);
$quote = str_replace(‘<br/>’,’<br>’,$quote);
$quote = str_replace(‘{content}’,’<div class="decmt-content">’,$quote);
$quote = str_replace(‘{/content}’,’</div>’,$quote);
$quote = str_replace(‘{/quote}’,’</div>’,$quote);
return $quote;
}
層<div class="reply1"></div> 主要用于顯示引用的標(biāo)題字樣,如“引用XXX的原帖”,層<div class="reply2"></div> 主要用于控制引用評(píng)論的內(nèi)容,如“樓上評(píng)論的內(nèi)容”,明白了這些,再加以合理的CSS樣式美化,就可以實(shí)現(xiàn)完美的評(píng)論內(nèi)嵌效果了。