This commit is contained in:
314
CommentFilter/Plugin.php
Normal file
314
CommentFilter/Plugin.php
Normal file
@@ -0,0 +1,314 @@
|
||||
<?php
|
||||
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
|
||||
|
||||
/**
|
||||
* 评论过滤器 【<a href="https://github.com/typecho-fans/plugins" target="_blank">TF</a>社区维护版】
|
||||
*
|
||||
* @package CommentFilter
|
||||
* @author jrotty,ghostry,Hanny
|
||||
* @version 1.2.1
|
||||
* @link https://github.com/typecho-fans/plugins/tree/master/CommentFilter
|
||||
*
|
||||
* version 1.2.1 at 2020-06-27[typecho-fans合并2012-12-31 ghostry修改版]
|
||||
* 增加首次评论过滤,评论者可以在评论底部看到自己的未审核评论
|
||||
*
|
||||
* version 1.2.0 at 2017-10-10[非原作者更新修改,jrotty魔改更新]
|
||||
* 增加评论者昵称/超链接过滤功能
|
||||
*
|
||||
* 历史版本
|
||||
* version 1.1.0 at 2014-01-04
|
||||
* 增加机器评论过滤
|
||||
* version 1.0.2 at 2010-05-16
|
||||
* 修正发表评论成功后,评论内容Cookie不清空的Bug
|
||||
* version 1.0.1 at 2009-11-29
|
||||
* 增加IP段过滤功能
|
||||
* version 1.0.0 at 2009-11-14
|
||||
* 实现评论内容按屏蔽词过滤功能
|
||||
* 实现过滤非中文评论功能
|
||||
*/
|
||||
class CommentFilter_Plugin implements Typecho_Plugin_Interface
|
||||
{
|
||||
/**
|
||||
* 激活插件方法,如果激活失败,直接抛出异常
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
* @throws Typecho_Plugin_Exception
|
||||
*/
|
||||
public static function activate()
|
||||
{
|
||||
Typecho_Plugin::factory('Widget_Feedback')->comment = array('CommentFilter_Plugin', 'filter');
|
||||
Typecho_Plugin::factory('Widget_Archive')->header = array('CommentFilter_Plugin', 'add_filter_spam_input');
|
||||
return _t('评论过滤器启用成功,请配置需要过滤的内容');
|
||||
}
|
||||
|
||||
/**
|
||||
* 禁用插件方法,如果禁用失败,直接抛出异常
|
||||
*
|
||||
* @static
|
||||
* @access public
|
||||
* @return void
|
||||
* @throws Typecho_Plugin_Exception
|
||||
*/
|
||||
public static function deactivate(){}
|
||||
|
||||
/**
|
||||
* 获取插件配置面板
|
||||
*
|
||||
* @access public
|
||||
* @param Typecho_Widget_Helper_Form $form 配置面板
|
||||
* @return void
|
||||
*/
|
||||
public static function config(Typecho_Widget_Helper_Form $form)
|
||||
{
|
||||
$opt_spam = new Typecho_Widget_Helper_Form_Element_Radio('opt_spam', array("none" => "无动作", "waiting" => "标记为待审核", "spam" => "标记为垃圾", "abandon" => "评论失败"), "none",
|
||||
_t('屏蔽机器人评论'), "如果为机器人评论,将执行该操作。如果需要开启该过滤功能,请尝试进行评论测试,以免不同模板造成误判。");
|
||||
$form->addInput($opt_spam);
|
||||
|
||||
$opt_ip = new Typecho_Widget_Helper_Form_Element_Radio('opt_ip', array("none" => "无动作", "waiting" => "标记为待审核", "spam" => "标记为垃圾", "abandon" => "评论失败"), "none",
|
||||
_t('屏蔽IP操作'), "如果评论发布者的IP在屏蔽IP段,将执行该操作");
|
||||
$form->addInput($opt_ip);
|
||||
|
||||
$words_ip = new Typecho_Widget_Helper_Form_Element_Textarea('words_ip', NULL, "0.0.0.0",
|
||||
_t('屏蔽IP'), _t('多条IP请用换行符隔开<br />支持用*号匹配IP段,如:192.168.*.*'));
|
||||
$form->addInput($words_ip);
|
||||
|
||||
$opt_nocn = new Typecho_Widget_Helper_Form_Element_Radio('opt_nocn', array("none" => "无动作", "waiting" => "标记为待审核", "spam" => "标记为垃圾", "abandon" => "评论失败"), "none",
|
||||
_t('非中文评论操作'), "如果评论中不包含中文,则强行按该操作执行");
|
||||
$form->addInput($opt_nocn);
|
||||
|
||||
$opt_nopl = new Typecho_Widget_Helper_Form_Element_Radio('opt_nopl', array("none" => "无动作", "waiting" => "标记为待审核", "spam" => "标记为垃圾", "abandon" => "评论失败"), "none",
|
||||
_t('首次评论操作'), "如果评论人没有评论过,则强行按该操作执行");
|
||||
$form->addInput($opt_nopl);
|
||||
|
||||
$opt_ban = new Typecho_Widget_Helper_Form_Element_Radio('opt_ban', array("none" => "无动作", "waiting" => "标记为待审核", "spam" => "标记为垃圾", "abandon" => "评论失败"), "abandon",
|
||||
_t('禁止词汇操作'), "如果评论中包含禁止词汇列表中的词汇,将执行该操作");
|
||||
$form->addInput($opt_ban);
|
||||
|
||||
$words_ban = new Typecho_Widget_Helper_Form_Element_Textarea('words_ban', NULL, "fuck\n操你妈\n[url\n[/url]",
|
||||
_t('禁止词汇'), _t('多条词汇请用换行符隔开'));
|
||||
$form->addInput($words_ban);
|
||||
|
||||
$opt_chk = new Typecho_Widget_Helper_Form_Element_Radio('opt_chk', array("none" => "无动作", "waiting" => "标记为待审核", "spam" => "标记为垃圾", "abandon" => "评论失败"), "waiting",
|
||||
_t('敏感词汇操作'), "如果评论中包含敏感词汇列表中的词汇,将执行该操作");
|
||||
$form->addInput($opt_chk);
|
||||
|
||||
$words_chk = new Typecho_Widget_Helper_Form_Element_Textarea('words_chk', NULL, "http://",
|
||||
_t('敏感词汇'), _t('多条词汇请用换行符隔开<br />注意:如果词汇同时出现于禁止词汇,则执行禁止词汇操作'));
|
||||
$form->addInput($words_chk);
|
||||
|
||||
$opt_author = new Typecho_Widget_Helper_Form_Element_Radio('opt_author', array("none" => "无动作", "waiting" => "标记为待审核", "spam" => "标记为垃圾", "abandon" => "评论失败"), "spam",
|
||||
_t('关键昵称操作'), "如果评论中包含关键昵称词汇列表中的词汇,将执行该操作");
|
||||
$form->addInput($opt_author);
|
||||
|
||||
$words_author = new Typecho_Widget_Helper_Form_Element_Textarea('words_author', NULL, "澳门银座\n自动化软件\n量化交易",
|
||||
_t('关键昵称词汇'), _t('多条词汇请用换行符隔开'));
|
||||
$form->addInput($words_author);
|
||||
|
||||
$opt_url = new Typecho_Widget_Helper_Form_Element_Radio('opt_url', array("none" => "无动作", "waiting" => "标记为待审核", "spam" => "标记为垃圾", "abandon" => "评论失败"), "spam",
|
||||
_t('垃圾链接过滤操作'), "如果评论中包含垃圾链接列表中字符串,将执行该操作");
|
||||
$form->addInput($opt_url);
|
||||
|
||||
$words_url = new Typecho_Widget_Helper_Form_Element_Textarea('words_url', NULL, "www.vps521.cn",
|
||||
_t('垃圾链接'), _t('多条词汇请用换行符隔开,链接格式请参考上边输入框默认的链接'));
|
||||
$form->addInput($words_url);
|
||||
}
|
||||
|
||||
/**
|
||||
* 个人用户的配置面板
|
||||
*
|
||||
* @access public
|
||||
* @param Typecho_Widget_Helper_Form $form
|
||||
* @return void
|
||||
*/
|
||||
public static function personalConfig(Typecho_Widget_Helper_Form $form){}
|
||||
|
||||
/**
|
||||
* 评论过滤器
|
||||
*
|
||||
*/
|
||||
public static function filter($comment, $post)
|
||||
{
|
||||
$options = Typecho_Widget::widget('Widget_Options');
|
||||
$filter_set = $options->plugin('CommentFilter');
|
||||
$opt = "none";
|
||||
$error = "";
|
||||
|
||||
//机器评论处理
|
||||
if ($opt == "none" && $filter_set->opt_spam != "none") {
|
||||
if ($_POST['filter_spam'] != '48616E6E79') {
|
||||
$error = "请勿使用第三方工具进行评论";
|
||||
$opt = $filter_set->opt_spam;
|
||||
}
|
||||
}
|
||||
|
||||
//屏蔽IP段处理
|
||||
if ($opt == "none" && $filter_set->opt_ip != "none") {
|
||||
if (CommentFilter_Plugin::check_ip($filter_set->words_ip, $comment['ip'])) {
|
||||
$error = "评论发布者的IP已被管理员屏蔽";
|
||||
$opt = $filter_set->opt_ip;
|
||||
}
|
||||
}
|
||||
|
||||
//纯中文评论处理
|
||||
if ($opt == "none" && $filter_set->opt_nocn != "none") {
|
||||
if (preg_match("/[\x{4e00}-\x{9fa5}]/u", $comment['text']) == 0) {
|
||||
$error = "评论内容请不少于一个中文汉字";
|
||||
$opt = $filter_set->opt_nocn;
|
||||
}
|
||||
}
|
||||
|
||||
//首次评论操作
|
||||
if($opt == "none" && $filter_set->opt_nopl != "none"){
|
||||
if($comment['mail']){
|
||||
$db = Typecho_Db::get();
|
||||
$select=$db->select('mail')
|
||||
->from('table.comments')
|
||||
->where('mail = ?', $comment['mail']);
|
||||
$result = $db->query($select);
|
||||
$row = $db->fetchRow($result);
|
||||
if(!$row['mail']){
|
||||
$opt = $filter_set->opt_nopl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//检查禁止词汇
|
||||
if ($opt == "none" && $filter_set->opt_ban != "none") {
|
||||
if (CommentFilter_Plugin::check_in($filter_set->words_ban, $comment['text'])) {
|
||||
$error = "评论内容中包含禁止词汇";
|
||||
$opt = $filter_set->opt_ban;
|
||||
}
|
||||
}
|
||||
|
||||
//检查敏感词汇
|
||||
if ($opt == "none" && $filter_set->opt_chk != "none") {
|
||||
if (CommentFilter_Plugin::check_in($filter_set->words_chk, $comment['text'])) {
|
||||
$error = "评论内容中包含敏感词汇";
|
||||
$opt = $filter_set->opt_chk;
|
||||
}
|
||||
}
|
||||
|
||||
//检查关键昵称词汇
|
||||
if ($opt == "none" && $filter_set->opt_author != "none") {
|
||||
if (CommentFilter_Plugin::check_in($filter_set->words_author, $comment['author'])) {
|
||||
$error = "该类型昵称已被禁止评论";
|
||||
$opt = $filter_set->opt_author;
|
||||
}
|
||||
}
|
||||
|
||||
//检查评论者链接
|
||||
if ($opt == "none" && $filter_set->opt_url != "none") {
|
||||
if (CommentFilter_Plugin::check_in($filter_set->words_url, $comment['url'])) {
|
||||
$error = "该类型评论者超链接被禁止评论";
|
||||
$opt = $filter_set->opt_url;
|
||||
}
|
||||
}
|
||||
|
||||
//执行操作
|
||||
if ($opt == "abandon") {
|
||||
Typecho_Cookie::set('__typecho_remember_text', $comment['text']);
|
||||
throw new Typecho_Widget_Exception($error);
|
||||
}
|
||||
else if ($opt == "spam") {
|
||||
$comment['status'] = 'spam';
|
||||
}
|
||||
else if ($opt == "waiting") {
|
||||
$comment['status'] = 'waiting';
|
||||
}
|
||||
$_SESSION['comment']=$comment;
|
||||
Typecho_Cookie::delete('__typecho_remember_text');
|
||||
return $comment;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查$str中是否含有$words_str中的词汇
|
||||
*
|
||||
*/
|
||||
private static function check_in($words_str, $str)
|
||||
{
|
||||
$words = explode("\n", $words_str);
|
||||
if (empty($words)) {
|
||||
return false;
|
||||
}
|
||||
foreach ($words as $word) {
|
||||
if (false !== strpos($str, trim($word))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查$ip中是否在$words_ip的IP段中
|
||||
*
|
||||
*/
|
||||
private static function check_ip($words_ip, $ip)
|
||||
{
|
||||
$words = explode("\n", $words_ip);
|
||||
if (empty($words)) {
|
||||
return false;
|
||||
}
|
||||
foreach ($words as $word) {
|
||||
$word = trim($word);
|
||||
if (false !== strpos($word, '*')) {
|
||||
$word = "/^".str_replace('*', '\d{1,3}', $word)."$/";
|
||||
if (preg_match($word, $ip)) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (false !== strpos($ip, $word)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 在表单中增加 filter_spam 隐藏域
|
||||
*
|
||||
*/
|
||||
public static function add_filter_spam_input($header, $archive)
|
||||
{
|
||||
$options = Typecho_Widget::widget('Widget_Options');
|
||||
$filter_set = $options->plugin('CommentFilter');
|
||||
if ($filter_set->opt_spam != "none" && $archive->is('single') && $archive->allow('comment')) {
|
||||
echo '<script type="text/javascript">
|
||||
function get_form(input) {
|
||||
var node = input;
|
||||
while (node) {
|
||||
node = node.parentNode;
|
||||
if (node.nodeName.toLowerCase() == "form") {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
window.onload = function() {
|
||||
var inputs = document.getElementsByTagName("textarea");
|
||||
var i, input_author;
|
||||
input_author = null;
|
||||
for (i=0; i<inputs.length; i++) {
|
||||
if (inputs[i].name.toLowerCase() == "text") {
|
||||
input_author = inputs[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
var form_comment = get_form(input_author);
|
||||
if (form_comment) {
|
||||
var input_hd = document.createElement("input");
|
||||
input_hd.type = "hidden";
|
||||
input_hd.name = "filter_spam";
|
||||
input_hd.value = "48616E6E79";
|
||||
form_comment.appendChild(input_hd);
|
||||
} else {
|
||||
alert("find input author error!");
|
||||
}
|
||||
}
|
||||
</script>
|
||||
';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
80
CommentFilter/README.md
Normal file
80
CommentFilter/README.md
Normal file
@@ -0,0 +1,80 @@
|
||||
<a href="https://typecho-fans.github.io">
|
||||
<img src="https://typecho-fans.github.io/text-logo.svg" alt="TF Logo" title="Typecho Fans开源作品社区" align="right" height="100" />
|
||||
</a>
|
||||
|
||||
CommentFilter v1.2.1 - 社区维护版
|
||||
======================
|
||||
<h4 align="center">—— 全能评论过滤器插件,支持按内容/IP/昵称/链接等拦截垃圾评论。</h4>
|
||||
|
||||
<p align="center">
|
||||
<a href="#使用说明">使用说明</a> •
|
||||
<a href="#版本历史">版本历史</a> •
|
||||
<a href="#贡献作者">贡献作者</a> •
|
||||
<a href="#附注链接">附注/链接</a> •
|
||||
<a href="#授权协议">授权协议</a>
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
## 使用说明
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
###### Comment Filter 是一款给力的 Typecho 评论过滤插件,从IP/关键词黑名单到无中文屏蔽,再到隐藏域陷阱拦截机器人等,现在加入魔改的昵称/链接和首次评论过滤后功能更为全面。
|
||||
|
||||
**使用方法**:
|
||||
##### 1. 下载本插件,放在 `usr/plugins/` 目录中,确保文件夹名为 CommentFilter;
|
||||
##### 2. 激活插件,选择并填写各项过滤规则配置;
|
||||
##### 3. 保存设置,即可自动监管全站新发评论。
|
||||
|
||||
**注意事项**:
|
||||
* ##### 已通过session增加评论内容临时变量,可在模板输出让评论者看到自己的未审核评论。
|
||||
* ##### 此插件历史悠久,如果被spammer针对发现效果不佳可尝试另一款插件[SmartSpam](http://www.yovisun.com/archive/typecho-plugin-smartspam.html)。
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
## 版本历史
|
||||
|
||||
* v1.2.1 (20-6-27 [@jzwalk](https://github.com/jzwalk))
|
||||
* 上传至GitHub的Typecho-Fans目录,产生社区维护版;
|
||||
* 合并1个衍生版本功能:
|
||||
* 增加新用户判断,**过滤首次评论**[@ghostry](https://blog.ghostry.cn);
|
||||
* 增加session输出,让评论者**可看到未审核评论**[@ghostry](https://blog.ghostry.cn)。
|
||||
* v1.2.0 (17-10-10 [@jrotty](https://github.com/jrotty))
|
||||
* 增加评论者**昵称/超链接过滤**功能。
|
||||
* v1.1.0 (14-01-04 [@Hanny](http://www.imhan.com))
|
||||
* 增加机器评论过滤。
|
||||
* v1.0.2 (10-05-16 [@Hanny](http://www.imhan.com))
|
||||
* 修正发表评论成功后,评论内容Cookie不清空的Bug。
|
||||
* v1.0.1 (09-11-29 [@Hanny](http://www.imhan.com))
|
||||
* 增加IP段过滤功能。
|
||||
* v1.0.0 (09-11-14 [@Hanny](http://www.imhan.com))
|
||||
* 实现评论内容按屏蔽词过滤功能;
|
||||
* 实现过滤非中文评论功能。
|
||||
|
||||
## 贡献作者
|
||||
|
||||
[](https://github.com/jzwalk) | [](https://github.com/jrotty) | [](https://blog.ghostry.cn) | [](http://www.imhan.com)
|
||||
:---:|:---:|:---:|:---:
|
||||
[jzwalk](https://github.com/jzwalk) (2020) | [jrotty](https://github.com/jrotty) (2017) | [ghostry](https://blog.ghostry.cn) (2012) | [Hanny](http://www.imhan.com) (2009)
|
||||
|
||||
## 附注/链接
|
||||
|
||||
本社区维护版已包含以下各版本功能:
|
||||
|
||||
* [魔改版备份(ClayMoreBoy)](https://github.com/ClayMoreBoy/CommentFilter-typecho) - GitHub上的源码备份。
|
||||
* [魔改版(jrotty)](https://qqdie.com/archives/typecho-CommentFilter.html) - 加入昵称链接过滤。
|
||||
* [衍生版(ghostry)](https://blog.ghostry.cn/program/huan-zhe-teng-cha-jian---zhe-ci-shi-commentfilter.html) - 加入首次评论过滤和待审核输出。
|
||||
* [原版](http://www.imhan.com/archives/typecho_commentfilter_110) - 实现各项过滤拦截功能。
|
||||
|
||||
欢迎社区成员继续贡献代码参与更新。
|
||||
|
||||
## 授权协议
|
||||
|
||||
TF目录下的社区维护版作品如果没有明确声明,默认采用与Typecho相同的[GPLv2](https://github.com/typecho/typecho/blob/master/LICENSE.txt)开源协议。(要求提及出处,保持开源并注明修改。)
|
||||
|
||||
> CommentFilter原作未附协议声明,原作者保留所有权利。 © [Hanny](http://www.imhan.com)
|
||||
Reference in New Issue
Block a user