-
Notifications
You must be signed in to change notification settings - Fork 1
/
Plugin.php
executable file
·362 lines (317 loc) · 13.7 KB
/
Plugin.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
<?php
/**
* IQapTcha 评论滑动解锁
*
* @package IQapTcha
* @author Byends
* @version 1.1.2
* @link http://www.byends.com
*/
class IQapTcha_Plugin implements Typecho_Plugin_Interface
{
/**
* 激活插件方法,如果激活失败,直接抛出异常
*
* @access public
* @return void
* @throws Typecho_Plugin_Exception
*/
public static function activate()
{
Typecho_Plugin::factory('Widget_Feedback')->comment = array('IQapTcha_Plugin', 'filter');
Typecho_Plugin::factory('Widget_Archive')->header = array('IQapTcha_Plugin', 'headerScript');
Typecho_Plugin::factory('Widget_Archive')->footer = array('IQapTcha_Plugin', 'footerScript');
Helper::addRoute('iQapTcha4tyepcho', '/'.self::getCheckStr('slug'), 'IQapTcha_Plugin');
return _t('评论滑动解锁插件启用成功,请配置 评论滑动解锁 相关项');
}
/**
* 禁用插件方法,如果禁用失败,直接抛出异常
*
* @static
* @access public
* @return void
* @throws Typecho_Plugin_Exception
*/
public static function deactivate()
{
Helper::removeRoute('iQapTcha4tyepcho');
}
public static function execute()
{
$aResponse['code'] = false;
$options = Helper::options();
$iQapTchaOpt = $options->plugin('IQapTcha');
$action = self::getCheckStr('action');
$req = Typecho_Request::getInstance();
if ( !$req->isAjax() || !$req->isPost() || !$req->is('action='.$action) ) {
$msg = $iQapTchaOpt->opt_lock_txt;
$aResponse['msg'] = $msg;
}
else{
$aResponse['code'] = true;
$msg = $iQapTchaOpt->opt_unlock_txt;
$aResponse['msg'] = $msg;
@session_start();
$_SESSION[$action] = $req->get('iQaptcha');
}
echo json_encode($aResponse);
exit;
}
/**
* 获取插件配置面板
*
* @access public
* @param Typecho_Widget_Helper_Form $form 配置面板
* @return void
*/
public static function config(Typecho_Widget_Helper_Form $form)
{
//jquery 设置
$opt_jq_set = new Typecho_Widget_Helper_Form_Element_Radio('opt_jq_set', array('0'=> '自己处理', '1'=> '自动载入'), 1, 'jQuery 来源', '如果选择 【自动载入】,会从开放静态文件CDN自动载入 jQurey 1.8.3 到 header<br />http://cdn.staticfile.org/jquery/1.8.3/jquery.min.js');
$form->addInput($opt_jq_set);
//IQapTcha 配置
$opt_admin_unlock = new Typecho_Widget_Helper_Form_Element_Radio('opt_admin_unlock', array("true" => "是", "false" => "否"), "false", _t('博主是否无须上锁'), '若选择 【是】,博主登录后 IQapTcha 将不再显示,且不进行相应的 session 检验');
$form->addInput($opt_admin_unlock);
$opt_autoSubmit = new Typecho_Widget_Helper_Form_Element_Radio('opt_autoSubmit', array("true" => "是", "false" => "否"), "false", _t('解锁后立即提交评论'), '若选择 【是】,IQapTcha 解锁后将立即自动提交评论');
$form->addInput($opt_autoSubmit);
$opt_lock_txt = new Typecho_Widget_Helper_Form_Element_Text('opt_lock_txt', NULL, '发表评论前,请滑动滚动条解锁', _t('IQapTcha 解锁前的提示'));
$form->addInput( $opt_lock_txt->addRule('required', _t('IQapTcha 解锁前的提示不能为空')) );
$opt_unlock_txt = new Typecho_Widget_Helper_Form_Element_Text('opt_unlock_txt', NULL, '已解锁,可以发表评论了', _t('IQapTcha 解锁后的提示'));
$form->addInput( $opt_unlock_txt->addRule('required', _t('IQapTcha 解锁后的提示不能为空')) );
$opt_autoRevert = new Typecho_Widget_Helper_Form_Element_Radio('opt_autoRevert', array("true" => "是", "false" => "否"), "true", _t('滚动条是否自动回滚'), '在拖动 IQapTcha 滚动条中途释放时,滚动条是否自动回滚');
$form->addInput($opt_autoRevert);
$opt_disabledSubmit = new Typecho_Widget_Helper_Form_Element_Radio('opt_disabledSubmit', array("false" => "是", "true" => "否"), "false", _t('提交按钮是否可用'), 'IQapTcha 未解锁时,评论提交按钮是否可用');
$form->addInput($opt_disabledSubmit);
//屏蔽IP操作
$opt_ip = new Typecho_Widget_Helper_Form_Element_Radio('opt_ip', array("none" => "无动作", "waiting" => "标记为待审核", "spam" => "标记为垃圾", "abandon" => "评论失败"), "abandon",
_t('屏蔽IP操作'), "如果评论发布者的IP在屏蔽IP段,将执行该操作");
$form->addInput($opt_ip);
$opt_ip_txt = new Typecho_Widget_Helper_Form_Element_Text('opt_ip_txt', NULL, '你的IP已被管理员屏蔽!', _t('屏蔽IP后的提示'), _t('仅当屏蔽IP操作为 【评论失败】 时有效'));
$form->addInput( $opt_ip_txt->addRule('required', _t('屏蔽IP后的提示不能为空')) );
$wordsIp = new Typecho_Widget_Helper_Form_Element_Textarea('words_ip', NULL, "0.0.0.0",
_t('屏蔽IP'), _t('多条IP请用换行符隔开<br />支持用*号匹配IP段,如:192.168.*.*'));
$form->addInput($wordsIp);
//非中文评论操作
$opt_nocn = new Typecho_Widget_Helper_Form_Element_Radio('opt_nocn', array("none" => "无动作", "waiting" => "标记为待审核", "spam" => "标记为垃圾", "abandon" => "评论失败"), "abandon",
_t('非中文评论操作'), "如果评论中不包含中文,则强行按该操作执行");
$form->addInput($opt_nocn);
$opt_nocn_txt = new Typecho_Widget_Helper_Form_Element_Text('opt_nocn_txt', NULL, '评论内容不能少于2个汉字!', _t('非中文评论的提示'), _t('仅当非中文评论操作为 【评论失败】 时有效'));
$form->addInput( $opt_nocn_txt->addRule('required', _t('非中文评论的提示不能为空')) );
//禁止词汇操作
$opt_ban = new Typecho_Widget_Helper_Form_Element_Radio('opt_ban', array("none" => "无动作", "waiting" => "标记为待审核", "spam" => "标记为垃圾", "abandon" => "评论失败"), "abandon",
_t('禁止词汇操作'), "如果评论中包含禁止词汇列表中的词汇,将执行该操作");
$form->addInput($opt_ban);
$opt_ban_txt = new Typecho_Widget_Helper_Form_Element_Text('opt_ban_txt', NULL, '评论内容包含禁止词汇!', _t('禁止词汇后的提示'), _t('仅当禁止词汇操作为 【评论失败】 时有效'));
$form->addInput( $opt_ban_txt->addRule('required', _t('禁止词汇后的提示不能为空')) );
$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" => "评论失败"), "abandon",
_t('敏感词汇操作'), "如果评论中包含敏感词汇列表中的词汇,将执行该操作");
$form->addInput($opt_chk);
$opt_chk_txt = new Typecho_Widget_Helper_Form_Element_Text('opt_chk_txt', NULL, '评论内容包含敏感词汇!', _t('包含敏感词汇的提示'), _t('仅当敏感词汇操作为 【评论失败】 时有效'));
$form->addInput( $opt_chk_txt->addRule('required', _t('包含敏感词汇的提示不能为空')) );
$words_chk = new Typecho_Widget_Helper_Form_Element_Textarea('words_chk', NULL, "http://",
_t('敏感词汇'), _t('多条词汇请用换行符隔开<br />注意:如果词汇同时出现于禁止词汇,则执行禁止词汇操作'));
$form->addInput($words_chk);
}
/**
* 个人用户的配置面板
*
* @access public
* @param Typecho_Widget_Helper_Form $form
* @return void
*/
public static function personalConfig(Typecho_Widget_Helper_Form $form){}
/**
* 自定义 header
*
* @access public
* @return void
*/
public static function headerScript()
{
if (Typecho_Widget::widget('Widget_Archive')->is('single')) {
$user = Typecho_Widget::widget('Widget_User');
$options = Helper::options();
$iQapTchaOpt = $options->plugin('IQapTcha');
if( $iQapTchaOpt->opt_admin_unlock == 'false' || !($user->hasLogin() && $user->pass('administrator'))) {
$pluginUrl = Typecho_Common::url('IQapTcha/static', $options->pluginUrl);
if ($iQapTchaOpt->opt_jq_set == 1) {
echo "<script type=\"text/javascript\" src=\"http://cdn.staticfile.org/jquery/1.8.3/jquery.min.js\"></script>\n";
}
echo '<link rel="stylesheet" type="text/css" media="all" href="'.$pluginUrl.'/QapTcha.jquery.css" />'."\n";
}
}
}
/**
* 自定义 footer
*
* @access public
* @return void
*/
public static function footerScript()
{
if (Typecho_Widget::widget('Widget_Archive')->is('single')) {
$user = Typecho_Widget::widget('Widget_User');
$options = Helper::options();
$iQapTchaOpt = $options->plugin('IQapTcha');
if( $iQapTchaOpt->opt_admin_unlock == 'false' || !($user->hasLogin() && $user->pass('administrator'))) {
$pluginUrl = Typecho_Common::url('IQapTcha/static', $options->pluginUrl);
$url = Typecho_Router::url('iQapTcha4tyepcho', array(), $options->index);
$action = self::getCheckStr('action');
$script = <<<EOT
\n<script type="text/javascript" src="{$pluginUrl}/jquery-ui.js"></script>
<script type="text/javascript" src="{$pluginUrl}/jquery.ui.touch.js"></script>
<script type="text/javascript" src="{$pluginUrl}/QapTcha.jquery.js"></script>
<script>
(function($){
$(document).ready(function() {
if ( ! $('#QapTcha').is('div')) {
$('#comment_form textarea').parent().before('<div id="QapTcha"></div>\\n');
}
$('#QapTcha').QapTcha({
txtLock : '{$iQapTchaOpt->opt_lock_txt}',
txtUnlock : '{$iQapTchaOpt->opt_unlock_txt}',
disabledSubmit : {$iQapTchaOpt->opt_disabledSubmit},
autoRevert: {$iQapTchaOpt->opt_autoRevert},
autoSubmit : {$iQapTchaOpt->opt_autoSubmit},
url : '{$url}',
action : '{$action}'
});
});
})(jQuery)
</script>
EOT;
echo $script;
}
}
}
/**
* 评论过滤器
*
*/
public static function filter($comment, $post)
{
$user = Typecho_Widget::widget('Widget_User');
$options = Helper::options();
$iQapTchaOpt = $options->plugin('IQapTcha');
$opt = 'none';
$error = '';
$action = self::getCheckStr('action');
$req = Typecho_Request::getInstance();
//登录检测,session 检测
if( $iQapTchaOpt->opt_admin_unlock == 'false' || !($user->hasLogin() && $user->pass('administrator'))) {
@session_start();
if (!isset($_SESSION[$action]) || !$_SESSION[$action] || !$req->is('iQapTcha='.$_SESSION[$action]) ) {
throw new Typecho_Widget_Exception($iQapTchaOpt->opt_lock_txt);
}
}
//屏蔽IP段处理
if ($iQapTchaOpt->opt_ip != "none") {
if (IQapTcha_Plugin::checkIp($iQapTchaOpt->words_ip, $comment['ip'])) {
$error = $iQapTchaOpt->opt_ip_txt;
$opt = $iQapTchaOpt->opt_ip;
}
}
//纯英文评论处理
if ($iQapTchaOpt->opt_nocn != "none") {
$result = preg_match_all("/[\x{4e00}-\x{9fa5}]/u", $comment['text'], $txt);
if ($result == false || $result < 2) {
$error = $iQapTchaOpt->opt_nocn_txt;
$opt = $iQapTchaOpt->opt_nocn;
}
}
//检查禁止词汇
if ($iQapTchaOpt->opt_ban != "none") {
if (IQapTcha_Plugin::checkIn($iQapTchaOpt->words_ban, $comment['text'])) {
$error = $iQapTchaOpt->opt_ban_txt;
$opt = $iQapTchaOpt->opt_ban;
}
}
//检查敏感词汇
if ($iQapTchaOpt->opt_chk != "none") {
if (IQapTcha_Plugin::checkIn($iQapTchaOpt->words_chk, $comment['text'])) {
$error = $iQapTchaOpt->opt_chk_txt;
$opt = $iQapTchaOpt->opt_chk;
}
}
//执行操作
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';
}
Typecho_Cookie::delete('__typecho_remember_text');
return $comment;
}
/**
* 获取 安全检测 字符串
* @param string $type
* @return string
*/
private static function getCheckStr($type)
{
$options = Helper::options();
switch ($type) {
case 'slug':
$chkStr = md5($options->siteUrl.'_slug_iQapTcha4tyepcho_admin_');
break;
case 'action':
$chkStr = md5($options->siteUrl.'_action_iQapTcha4tyepcho_');
break;
default:
$chkStr = '';
break;
}
return $chkStr;
}
/**
* 检查$str中是否含有$wordsStr中的词汇
*
*/
private static function checkIn($wordsStr, $str)
{
$words = explode("\n", $wordsStr);
if (empty($words)) {
return false;
}
foreach ($words as $word) {
if (false !== strpos($str, trim($word))) {
return true;
}
}
return false;
}
/**
* 检查$ip中是否在$wordsIp的IP段中
*
*/
private static function checkIp($wordsIp, $ip)
{
$words = explode("\n", $wordsIp);
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;
}
}