找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 1265|回复: 0

[分享] dedecms AJAX 评论实现评论楼层化 引用内嵌美化

[复制链接]
发表于 2018-2-25 10:10:06 | 显示全部楼层 |阅读模式 来自 中国–河南–新乡
AJAX 无刷新评论功能是DeDeCMS 5.5 Final 正式版的一大亮点,也是众多站长们选择升级中一个重要原因。
  相比5.3 版本的评论,AJAX评论能达到无刷新即时显示最新留言及其回复功能,同时,支持游客对游客发表的评论进行引用回复,增加了“支持者”“反对者”“中立者”三个不同的人物较色,让文章的互动性更人性化、合理化。
  但是,惊喜之余难免有丝丝遗憾。
AJAX 评论无法实现楼层化,游客引用的评论无法嵌套在新评论,样式不够醒目直观。
最近九亿博客在升级程序时,着重对DeDeCMS 5.5 中新增加的AJAX评论插件进行了二次开发美化。
开发的主要内容包括两方面:评论实现楼层效果;评论回复为内嵌样式。
  评论实现楼层效果的解决办法:
  分析观察plus/feedback_ajax.php 插件文件,源代码如下所示
  1. <?php
  2. require_once(dirname(__FILE__)."/../include/common.inc.php");
  3. if($cfg_feedback_forbid==’Y’) exit(‘系统已经禁止评论功能!‘);
  4. require_once(DEDEINC."/filter.inc.php");
  5. if(!isset($action))
  6. {
  7. $action = ”;
  8. }
  9. //兼容旧的JS代码
  10. if($action == ‘good’ || $action == ‘bad’)
  11. {
  12. if(!empty($aid)) $id = $aid;
  13. require_once(dirname(__FILE__).’/digg_ajax.php’);
  14. exit();
  15. }

  16. $cfg_formmember = isset($cfg_formmember) ? true : false;
  17. $ischeck = $cfg_feedbackcheck==’Y’ ? 0 : 1;
  18. $aid = (isset($aid) && is_numeric($aid)) ? $aid : 0;
  19. $fid = (isset($fid) && is_numeric($fid)) ? $fid : 0;
  20. if(empty($aid) && empty($fid))
  21. {
  22. ShowMsg(‘文档id不能为空!’,’-1′);
  23. exit();
  24. }
  25. include_once(DEDEINC."/memberlogin.class.php");
  26. $cfg_ml = new MemberLogin();

  27. if($action==’goodfb’)
  28. {
  29. AjaxHead();
  30. $fid = intval($fid);
  31. $dsql->ExecuteNoneQuery("Update `dede_feedback` set good = good+1 where id=’$fid’ ");
  32. $row = $dsql->GetOne("Select good From `dede_feedback` where id=’$fid’ ");
  33. echo "<a onclick="postBadGood(‘goodfb’,{$aid})">支持</a>[{$row['good']}]";
  34. exit();
  35. }
  36. else if($action==’badfb’)
  37. {
  38. AjaxHead();
  39. $fid = intval($fid);
  40. $dsql->ExecuteNoneQuery("Update `dede_feedback` set bad = bad+1 where id=’$fid’ ");
  41. $row = $dsql->GetOne("Select bad From `dede_feedback` where id=’$fid’ ");
  42. echo "<a onclick="postBadGood(‘badfb’,{$aid})">反对</a>[{$row['bad']}]";
  43. exit();
  44. }
  45. //查看评论
  46. /*
  47. function __ViewFeedback(){ }
  48. */
  49. //———————————–
  50. else if($action==” || $action==’show’)
  51. {
  52. //读取文档信息
  53. $arcRow = GetOneArchive($aid);
  54. if(empty($arcRow['aid']))
  55. {
  56. ShowMsg(‘无法查看未知文档的评论!’,’-1′);
  57. exit();
  58. }
  59. extract($arcRow, EXTR_SKIP);
  60. include_once(DEDEINC.’/datalistcp.class.php’);
  61. $dlist = new DataListCP();
  62. $dlist->pageSize = 20;
  63. if(empty($ftype) || ($ftype!=’good’ && $ftype!=’bad’ && $ftype!=’feedback’))
  64. {
  65. $ftype = ”;
  66. }
  67. $wquery = $ftype!=” ? " And ftype like ‘$ftype’ " : ”;
  68. //评论内容列表
  69. $querystring = "select fb.*,mb.userid,mb.face as mface,mb.spacesta,mb.scores from `dede_feedback` fb
  70. left join `dede_member` mb on mb.mid = fb.mid
  71. where fb.aid=’$aid’ and fb.ischeck=’1′ $wquery order by fb.id desc";
  72. $dlist->SetParameter(‘aid’,$aid);
  73. $dlist->SetParameter(‘action’,’show’);
  74. $dlist->SetTemplate(DEDETEMPLATE.’/plus/feedback_templet.htm’);
  75. $dlist->SetSource($querystring);
  76. $dlist->Display();
  77. exit();
  78. }
  79. //引用评论
  80. //————————————
  81. /*
  82. function __Quote(){ }
  83. */
  84. else if($action==’quote’)
  85. {
  86. $row = $dsql->GetOne("Select * from `dede_feedback` where id =’$fid’");
  87. require_once(DEDEINC.’/dedetemplate.class.php’);
  88. $dtp = new DedeTemplate();
  89. $dtp->LoadTemplate(DEDETEMPLATE.’/plus/feedback_quote.htm’);
  90. $dtp->Display();
  91. exit();
  92. }
  93. //发表评论
  94. //————————————
  95. /*
  96. function __SendFeedback(){ }
  97. */
  98. else if($action==’send’)
  99. {
  100. //读取文档信息
  101. $arcRow = GetOneArchive($aid);
  102. if((empty($arcRow['aid']) || $arcRow['notpost']==’1′)&&empty($fid))
  103. {
  104. ShowMsg(‘无法对该文档发表评论!’,’-1′);
  105. exit();
  106. }
  107. //是否加验证码重确认
  108. if(empty($isconfirm))
  109. {
  110. $isconfirm = ”;
  111. }
  112. if($isconfirm!=’yes’ && $cfg_feedback_ck==’Y’)
  113. {
  114. extract($arcRow, EXTR_SKIP);
  115. require_once(DEDEINC.’/dedetemplate.class.php’);
  116. $dtp = new DedeTemplate();
  117. $dtp->LoadTemplate(DEDETEMPLATE.’/plus/feedback_confirm.htm’);
  118. $dtp->Display();
  119. exit();
  120. }
  121. //检查验证码
  122. if($cfg_feedback_ck==’Y’)
  123. {
  124. $validate = isset($validate) ? strtolower(trim($validate)) : ”;
  125. $svali = strtolower(trim(GetCkVdValue()));
  126. if($validate != $svali || $svali==”)
  127. {
  128. ResetVdValue();
  129. ShowMsg(‘验证码错误!‘,’-1′);
  130. exit();
  131. }
  132. }
  133. //检查用户登录
  134. if(empty($notuser))
  135. {
  136. $notuser=0;
  137. }
  138. //匿名发表评论
  139. if($notuser==1)
  140. {
  141. $username = $cfg_ml->M_ID > 0 ? ‘匿名‘ : ‘游客‘;
  142. }
  143. //已登录的用户
  144. else if($cfg_ml->M_ID > 0)
  145. {
  146. $username = $cfg_ml->M_UserName;
  147. }
  148. //用户身份验证
  149. else
  150. {
  151. if($username!=” && $pwd!=”)
  152. {
  153. $rs = $cfg_ml->CheckUser($username,$pwd);
  154. if($rs==1)
  155. {
  156. $dsql->ExecuteNoneQuery("Update `dede_member` set logintime=’".time()."’,loginip=’".GetIP()."’ where mid=’{$cfg_ml->M_ID}’; ");
  157. }
  158. else
  159. {
  160. $username = ‘游客‘;
  161. }
  162. }
  163. else
  164. {
  165. $username = ‘游客‘;
  166. }
  167. }
  168. $ip = GetIP();
  169. $dtime = time();
  170. //检查评论间隔时间;
  171. if(!empty($cfg_feedback_time))
  172. {
  173. //检查最后发表评论时间,如果未登陆判断当前IP最后评论时间
  174. if($cfg_ml->M_ID > 0)
  175. {
  176. $where = "WHERE `mid` = ‘$cfg_ml->M_ID’";
  177. }
  178. else
  179. {
  180. $where = "WHERE `ip` = ‘$ip’";
  181. }
  182. $row = $dsql->GetOne("SELECT dtime FROM `dede_feedback` $where ORDER BY `id` DESC ");
  183. if(is_array($row) && $dtime – $row['dtime'] < $cfg_feedback_time)
  184. {
  185. ResetVdValue();
  186. ShowMsg(‘管理员设置了评论间隔时间,请稍等休息一下!‘,’-1′);
  187. exit();
  188. }
  189. }
  190. if(empty($face))
  191. {
  192. $face = 0;
  193. }
  194. $face = intval($face);
  195. extract($arcRow, EXTR_SKIP);
  196. $msg = cn_substrR(TrimMsg($msg),1000);
  197. $username = cn_substrR(HtmlReplace($username,2),20);
  198. if(empty($feedbacktype) || ($feedbacktype!=’good’ && $feedbacktype!=’bad’))
  199. {
  200. $feedbacktype = ‘feedback’;
  201. }
  202. //保存评论内容
  203. if($comtype == ‘comments’)
  204. {
  205. $arctitle = addslashes($title);
  206. if($msg!=”)
  207. {
  208. $inquery = "INSERT INTO `dede_feedback`(`aid`,`typeid`,`username`,`arctitle`,`ip`,`ischeck`,`dtime`, `mid`,`bad`,`good`,`ftype`,`face`,`msg`)
  209. VALUES (‘$aid’,’$typeid’,’$username’,’$arctitle’,’$ip’,’$ischeck’,’$dtime’, ‘{$cfg_ml->M_ID}’,’0′,’0′,’$feedbacktype’,’$face’,’$msg’); ";
  210. $rs = $dsql->ExecuteNoneQuery($inquery);
  211. if(!$rs)
  212. {
  213. ShowMsg(‘ 发表评论错误! ‘, ‘-1′);
  214. //echo $dsql->GetError();
  215. exit();
  216. }
  217. }
  218. }
  219. //引用回复
  220. elseif ($comtype == ‘reply’)
  221. {
  222. $row = $dsql->GetOne("Select * from `dede_feedback` where id =’$fid’");
  223. $arctitle = $row['arctitle'];
  224. $aid =$row['aid'];
  225. $msg = $quotemsg.$msg;
  226. $msg = HtmlReplace($msg,2);
  227. $inquery = "INSERT INTO `dede_feedback`(`aid`,`typeid`,`username`,`arctitle`,`ip`,`ischeck`,`dtime`,`mid`,`bad`,`good`,`ftype`,`face`,`msg`)
  228. VALUES (‘$aid’,’$typeid’,’$username’,’$arctitle’,’$ip’,’$ischeck’,’$dtime’,’{$cfg_ml->M_ID}’,’0′,’0′,’$feedbacktype’,’$face’,’$msg’)";
  229. $dsql->ExecuteNoneQuery($inquery);
  230. }
  231. if($feedbacktype==’bad’)
  232. {
  233. $dsql->ExecuteNoneQuery("Update `dede_archives` set scores=scores-{cfg_feedback_sub},badpost=badpost+1,lastpost=’$dtime’ where id=’$aid’ ");
  234. }
  235. else if($feedbacktype==’good’)
  236. {
  237. $dsql->ExecuteNoneQuery("Update `dede_archives` set scores=scores+{$cfg_feedback_add},goodpost=goodpost+1,lastpost=’$dtime’ where id=’$aid’ ");
  238. }
  239. else
  240. {
  241. $dsql->ExecuteNoneQuery("Update `dede_archives` set scores=scores+1,lastpost=’$dtime’ where id=’$aid’ ");
  242. }
  243. if($cfg_ml->M_ID > 0)
  244. {
  245. $dsql->ExecuteNoneQuery("Update `dede_member` set scores=scores+{$cfg_sendfb_scores} where mid=’{$cfg_ml->M_ID}’ ");
  246. }
  247. //统计用户发出的评论
  248. if($cfg_ml->M_ID > 0)
  249. {
  250. #api{{
  251. if(defined(‘UC_API’) && @include_once DEDEROOT.’/api/uc.func.php’)
  252. {
  253. //同步积分
  254. uc_credit_note($cfg_ml->M_LoginID, $cfg_sendfb_scores);
  255. //推送事件
  256. $arcRow = GetOneArchive($aid);
  257. $feed['icon'] = ‘thread’;
  258. $feed['title_template'] = ‘<b>{username} 在网站发表了评论</b>’;
  259. $feed['title_data'] = array(‘username’ => $cfg_ml->M_UserName);
  260. $feed['body_template'] = ‘<b>{subject}</b><br>{message}’;
  261. $url = !strstr($arcRow['arcurl'],’http://’) ? ($cfg_basehost.$arcRow['arcurl']) : $arcRow['arcurl'];
  262. $feed['body_data'] = array(‘subject’ => "<a href="".$url."">$arcRow[arctitle]</a>", ‘message’ => cn_substr(strip_tags(preg_replace("/[.+?]/is", ”, $msg)), 150));
  263. $feed['images'][] = array(‘url’ => $cfg_basehost.’/images/scores.gif’, ‘link’=> $cfg_basehost);
  264. uc_feed_note($cfg_ml->M_LoginID,$feed); unset($arcRow);
  265. }
  266. #/aip}}
  267. $row = $dsql->GetOne("SELECT COUNT(*) AS nums FROM `dede_feedback` WHERE `mid`=’".$cfg_ml->M_ID."’");
  268. $dsql->ExecuteNoneQuery("UPDATE `dede_member_tj` SET `feedback`=’$row[nums]‘ WHERE `mid`=’".$cfg_ml->M_ID."’");
  269. }
  270. $_SESSION['sedtime'] = time();
  271. if(empty($uid) && isset($cmtuser)) $uid = $cmtuser;
  272. $backurl = $cfg_formmember ? "index.php?uid={$uid}&action=viewarchives&aid={$aid}" : "feedback.php?aid=$aid";
  273. if($ischeck==0)
  274. {
  275. ShowMsg(‘成功发表评论,但需审核后才会显示你的评论!’, $backurl);
  276. }
  277. else
  278. {
  279. ShowMsg(‘成功发表评论,现在转到评论页面!’, $backurl);
  280. }
  281. exit();
  282. }
  283. ?>
复制代码

  分析这个文件,有不少循环语句。
哪个是与评论列表有关的呢?首先,你必须明白一个技术常识。
实现楼层化,要靠那种CSS+DIV 技术效果来表现?最简单的方法,就是用<ul><li></li></ul>这个方式了。
然后对<li style="list-style-type: decimal;list-style-position: inside;"></li>设置列表的类型为数字,位置为内。
这样一来,<ul>下循环语句用<li>来控制,就很轻松实现评论楼层的效果了。
  再来讲一讲,如何将引用过评论嵌套在新评论的上方。
首先,你要明白文章内容页调用的是ajaxfeedback.htm这个模板文件,而这个文件又由feedback_ajax.php 程序来控制。
也就是,修改引用样式就修改feedback_ajax.php 文件,而不是feedback_quote.htm 这个文件。
  找到了程序文件,接着查找与引用有关的函数值。
下面这段代码中就包含我所要找的{quote}参数:
  1. //保存评论内容
  2. if(!empty($fid))
  3. {
  4.   $row = $dsql->GetOne("Select username,msg from `dede_feedback` where id =’$fid’ ");
  5.   $qmsg = ‘{quote}{title}’.$row['username'].’ 的原帖:{/title}{content}’.$row['msg'].’{/content}{/quote}’;
  6.   $msg = addslashes($qmsg).$msg;
  7. }
  8. $ischeck = ($cfg_feedbackcheck==’Y’ ? 0 : 1);
  9. $arctitle = addslashes($title);
  10. $inquery = "INSERT INTO `dede_feedback`(`aid`,`typeid`,`username`,`arctitle`,`ip`,`ischeck`,`dtime`, `mid`,`bad`,`good`,`ftype`,`face`,`msg`)
  11.                 VALUES (‘$aid’,’$typeid’,’$username’,’$arctitle’,’$ip’,’$ischeck’,’$dtime’, ‘{$cfg_ml->M_ID}’,’0′,’0′,’$feedbacktype’,’$face’,’$msg’); ";
  12. $rs = $dsql->ExecuteNoneQuery($inquery);
  13. if( !$rs )
  14. {
  15.    echo "<font color=’red’>发表评论出错了!</font>";
  16.    //echo $dslq->GetError();
  17.    exit();
  18. }
  19. $newid = $dsql->GetLastID();
复制代码

  也许,不能找出是哪个CSS控制了这个引用样式。
官方提供的帮助文档,也没有提供该参数的具体信息。
看来,只要靠自己分析了。
既然知道引用的函数值是{quote} 字样。
那就是用DW的查找替换功能,在全站范围内展开搜索,终于找到了,在include/channelunit.func.php 这个程序文件中发现了{quote} 影子。
  快速打开这个文件,查找到第506行的位置,代码如下:
  1. //引用回复标记处理
  2. function Quote_replace($quote)
  3. {
  4. $quote = str_replace(‘{quote}’,’<div>’,$quote);
  5. $quote = str_replace(‘{title}’,’<div class="reply1">’,$quote);
  6. $quote = str_replace(‘{/title}’,’</div>’,$quote);
  7. $quote = str_replace(‘&lt;br/&gt;’,’<br>’,$quote);
  8. $quote = str_replace(‘{content}’,’<div class="reply2">’,$quote);
  9. $quote = str_replace(‘{/content}’,’</div>’,$quote);
  10. $quote = str_replace(‘{/quote}’,’</div>’,$quote);
  11. return $quote;
  12. }
复制代码

  将其修改为以下内容:
  1. //引用回复标记处理
  2. function Quote_replace($quote)
  3. {
  4. $quote = str_replace(‘{quote}’,’<div class="decmt-box">’,$quote);
  5. $quote = str_replace(‘{title}’,’<div class="decmt-title"><span class="username">’,$quote);
  6. $quote = str_replace(‘{/title}’,’</span></div>’,$quote);
  7. $quote = str_replace(‘&lt;br/&gt;’,’<br>’,$quote);
  8. $quote = str_replace(‘{content}’,’<div class="decmt-content">’,$quote);
  9. $quote = str_replace(‘{/content}’,’</div>’,$quote);
  10. $quote = str_replace(‘{/quote}’,’</div>’,$quote);
  11. return $quote;
  12. }
复制代码

  层<div class="reply1"></div> 主要用于显示引用的标题字样,如“引用XXX的原帖”,层<div class="reply2"></div> 主要用于控制引用评论的内容,如“楼上评论的内容”,明白了这些,再加以合理的CSS样式美化,就可以实现完美的评论内嵌效果了。

发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;

如何回报帮助你解决问题的坛友,好办法就是点击帖子下方的评分按钮给对方加【金币】不会扣除自己的积分,做一个热心并受欢迎的人!

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则 需要先绑定手机号

关闭

站长推荐上一条 /1 下一条

QQ|侵权投诉|广告报价|手机版|小黑屋|西部数码代理|飘仙建站论坛 ( 豫ICP备2022021143号-1 )

GMT+8, 2025-1-10 16:18 , Processed in 0.049118 second(s), 8 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表