当你的评论区变成“垃圾场”
深夜两点,你的帝国CMS站点突然涌入上百条垃圾评论——涉黄链接、广告灌水、甚至恶意攻击言论,用户随手点击了“举报”按钮,但举报信息却静静地躺在数据库里,无人处理,直到第二天早上,你打开后台才发现满屏的投诉,而搜索引擎早已收录了那些违规内容。
这就是帝国CMS默认评论系统的最大短板:举报功能形同虚设,管理员无法实时感知风险,我们在二次开发中,需要让系统在用户点击举报的瞬间,立即通过邮件、短信或企业微信机器人通知管理员,同时将举报记录入库备查。
评论举报通知的实现逻辑
我们需要定位帝国CMS评论提交的入口,在/e/pl/index.php中,评论通过AddPl()函数写入数据库,我们可以在add动作执行后,增加举报检测逻辑:
// 在评论提交成功后,检测是否有举报参数
if($_POST['report']==='1' && $id){
// 写入举报表
$report_time = time();
$report_ip = getip();
$sql = "INSERT INTO {$dbtbpre}enewsreport (plid, reporttime, reportip, reason) VALUES ('$id', '$report_time', '$report_ip', '".addslashes($_POST['reason'])."')";
$empire->query($sql);
// 立即触发通知
send_report_notify($id, $_POST['reason']);
}
这里的send_report_notify()函数,我们采用多通道通知策略,以下是一个集成企业微信机器人的示例:
帝国CMS评论举报机制深度定制,从通知到自动化处理的完整方案
function send_report_notify($plid, $reason){
$webhook = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=YOUR_KEY";
$plinfo = $empire->fetch1("SELECT * FROM {$dbtbpre}enewspl WHERE plid='$plid'");
$data = [
'msgtype' => 'markdown',
'markdown' => [
'content' => "## ⚠️ 评论举报通知\n> **评论ID:** $plid\n> **举报理由:** $reason\n> **评论内容:** ".mb_substr($plinfo['saytext'],0,100)."\n> [点击处理](http://yourdomain.com/e/admin/plmanage.php)"
]
];
// 使用cURL发送
$ch = curl_init($webhook);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_exec($ch);
}
自定义模型创建后前台不显示——排查三板斧
开发中常遇到后台建好了模型,前台列表页却是空白,按以下顺序排查:
第一步:检查数据表是否生成
SHOW TABLES LIKE '%mymodel%';
若没有表,检查/e/install/model/目录下是否有对应的模型文件。
第二步:验证灵动标签调用是否正确
后台的模型ID是mymodel,列表页使用:
<?php
$temp = $empire->query("SELECT * FROM {$dbtbpre}ecms_mymodel WHERE checked=1 ORDER BY id DESC LIMIT 10");
while($r=$empire->fetch($temp)){
echo $r['title'].'<br>';
}
?>
第三步:检查系统参数设置
登录后台 → 系统设置 → 信息设置 → 是否勾选了“启用自定义模型”?同时确认模板代码中是否使用了<?= $public_r['newsurl'] ?>等系统变量。
灵动标签SQL调用实战
在列表页需要调用副表字段时,必须使用JOIN语法,以下是从主表+副表联合查询的完整示例:
SELECT m.*, s.content, s.author
FROM `{dbtbpre}ecms_news` m
LEFT JOIN `{dbtbpre}ecms_news_data` s ON m.id=s.id
WHERE m.classid=12 AND m.newstime>UNIX_TIMESTAMP()-604800
ORDER BY m.newstime DESC LIMIT 20
模板中调用:
<?php
$sql = $empire->query("SELECT m.*, s.content, s.author FROM `{$dbtbpre}ecms_news` m LEFT JOIN `{$dbtbpre}ecms_news_data` s ON m.id=s.id WHERE m.classid=12 LIMIT 5");
while($r=$empire->fetch($sql)){
echo "<h2>{$r['title']}</h2>";
echo "<p>作者:{$r['author']}</p>";
echo "<div>".mb_substr($r['content'],0,200)."...</div>";
}
?>
列表模板与内容模板的变量调用奥义
在列表模板(list.temp.php)中,系统提供$listtemp循环变量,要输出自定义字段:
// 列表页调用自定义字段“产品型号”
<?php
$temp = $empire->query("SELECT * FROM {$dbtbpre}ecms_zhubiao WHERE classid='$GLOBALS[navclassid]' LIMIT 8");
while($r=$empire->fetch($temp)){
?>
<div class="item">
<h3><?= $r['title'] ?></h3>
<p>型号:<?= $r['xinghao'] ?></p>
</div>
<?php } ?>
模板(show.temp.php)中,通过$navinfor数组直接获取:
型号:<?= $navinfor['xinghao'] ?> 参数:<?= $navinfor['canshu'] ?>
万能标签与智能标签的适用边界
万能标签适合数据量小、需频繁自定义的场景,比如首页调用最新三条公告:
[phome]select * from phome_enewsclass where classid=3 order by id desc limit 3[/phome]
智能标签则针对大数据量、需要分页或排序复杂的场景,例如实现“热门新闻TOP10”:
[e:loop={"select newsid,title,onclick from phome_ecms_news order by onclick desc limit 10",10,24,0}]
<a href="<?= $bqsr['titleurl'] ?>"><?= $bqr['title'] ?></a> (点击<?= $bqr['onclick'] ?>)
[/e:loop]
选择原则:超过千条数据用智能标签,简单列表用万能标签。
全站搜索配置与自定义字段索引
要让新模型的内容参与全站搜索,需在/e/search/index.php中增加索引逻辑,在数据更新时,同步写入搜索索引表:
// 在保存文章时,触发搜索索引更新
function update_search_index($id, $title, $content, $addtime){
global $empire;
$fulltext = $title.' '.strip_tags($content);
$sql = "INSERT INTO {$dbtbpre}enewssearch (id, title, content, addtime, modelid)
VALUES ('$id', '$title', '$fulltext', '$addtime', '".$_POST['modelid']."')
ON DUPLICATE KEY UPDATE content='$fulltext'";
$empire->query($sql);
}
注意在后台管理 → 搜索设置 → 选择“自定义索引”,并重新生成索引文件。
模板中调用附表字段的实现技巧
主表存储常用字段,副表存大字段,要在模板中直接引用副表字段,最优雅的方式是使用loadinfo扩展:
<?php
$ziduan = $empire->fetch1("SELECT * FROM {$dbtbpre}ecms_news_data WHERE id='$navinfor[id]'");
// 现在可以直接输出副表字段
echo $ziduan['longcontent']; // 长文本内容
?>
更高效的做法是修改/e/class/connect.php中的ReadInfo()函数,使其自动合并副表数据:
function ReadInfo($id){
global $empire, $dbtbpre;
$main = $empire->fetch1("SELECT * FROM {$dbtbpre}ecms_news WHERE id='$id'");
$sub = $empire->fetch1("SELECT * FROM {$dbtbpre}ecms_news_data WHERE id='$id'");
return array_merge($main, $sub);
}
这样在模板中直接使用$navinfor['custom_field']即可,无需二次查询。
通过以上七个维度的实战解析,我们已经打通了评论举报通知、自定义模型排错、模板变量调用、搜索索引定义等多个关键节点,帝国CMS的二次开发精髓在于:理解底层数据流,善用系统钩子,灵活拼装SQL,当遇到任何异常,先检查数据表结构,再验证模板标签,最后审视全局配置——按这个顺序排查,没有解决不了的问题。



发表评论