Initial commit
Some checks failed
定时更新GitHub源插件 / 自动更新GitHub插件 (push) Has been cancelled

This commit is contained in:
chorblack
2026-03-07 11:19:25 +08:00
commit e75f275ef4
4484 changed files with 645480 additions and 0 deletions

314
CommentFilter/Plugin.php Normal file
View 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
View 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))
* 实现评论内容按屏蔽词过滤功能;
* 实现过滤非中文评论功能。
## 贡献作者
[![jzwalk](https://avatars1.githubusercontent.com/u/252331?v=3&s=100)](https://github.com/jzwalk) | [![jrotty](https://avatars1.githubusercontent.com/u/16165576?v=3&s=100)](https://github.com/jrotty) | [![ghostry](https://secure.gravatar.com/avatar/1623d5f14ef33ea40a084416f59ee93e?s=100)](https://blog.ghostry.cn) | [![Hanny](https://secure.gravatar.com/avatar/?d=mp&s=100)](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)