PluginProbe
wpForo Forum / 1.4.11
wpForo Forum v1.4.11
3.1.5 3.1.4 3.1.2 3.1.1 3.1.0 3.0.9 3.0.8 3.0.7 trunk 1.0.0 1.0.1 1.0.2 1.1.0 1.1.1 1.1.2 1.2.0 1.3.0 1.3.1 1.4.0 1.4.1 1.4.10 1.4.11 1.4.12 1.4.13 1.4.2 All 137 releases
wpforo / wpf-includes / class-moderation.php

class-moderation.php in wpForo Forum 1.4.11, at wpf-includes/class-moderation.php

385 lines 14.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 // Exit if accessed directly
3 if (!defined('ABSPATH')) exit;
4
5 class wpForoModeration
6 {
7 public $post_statuses;
8
9 public function __construct(){
10 $this->post_statuses = apply_filters('wpforo_post_statuses', array('approved', 'unapproved'));
11 }
12
13 public function init(){
14 if( !WPF()->perm->usergroup_can( 'aup' ) ){
15 add_filter('wpforo_add_topic_data_filter', array(&$this, 'auto_moderate'));
16 add_filter('wpforo_add_post_data_filter', array(&$this, 'auto_moderate'));
17 }
18 else{
19 if( !WPF()->perm->can_link() ){
20 add_filter('wpforo_add_topic_data_filter', array(&$this, 'remove_links'), 7);
21 add_filter('wpforo_edit_topic_data_filter', array(&$this, 'remove_links'), 7);
22 add_filter('wpforo_add_post_data_filter', array(&$this, 'remove_links'), 7);
23 add_filter('wpforo_edit_post_data_filter', array(&$this, 'remove_links'), 7);
24 }
25 if( WPF()->member->current_user_is_new() ){
26 if (class_exists('Akismet')) {
27 add_filter('wpforo_add_topic_data_filter', array(&$this, 'akismet_topic'), 8);
28 add_filter('wpforo_edit_topic_data_filter', array(&$this, 'akismet_topic'), 8);
29 add_filter('wpforo_add_post_data_filter', array(&$this, 'akismet_post'), 8);
30 add_filter('wpforo_edit_post_data_filter', array(&$this, 'akismet_post'), 8);
31 }
32 if ( WPF()->tools_antispam['spam_filter'] ) {
33 add_filter('wpforo_add_topic_data_filter', array(&$this, 'spam_topic'), 9);
34 add_filter('wpforo_edit_topic_data_filter', array(&$this, 'spam_topic'), 9);
35 add_filter('wpforo_add_topic_data_filter', array(&$this, 'spam_post'), 9);
36 add_filter('wpforo_edit_topic_data_filter', array(&$this, 'spam_post'), 9);
37 add_filter('wpforo_add_post_data_filter', array(&$this, 'spam_post'), 9);
38 add_filter('wpforo_edit_post_data_filter', array(&$this, 'spam_post'), 9);
39 }
40 }
41 if ( WPF()->tools_antispam['spam_filter'] ) {
42 add_filter('wpforo_add_topic_data_filter', array(&$this, 'auto_moderate'), 10);
43 add_filter('wpforo_add_post_data_filter', array(&$this, 'auto_moderate'), 10);
44 }
45 }
46 }
47
48 public function get_post_status_dname($status)
49 {
50 $status = intval($status);
51 return (isset($this->post_statuses[$status]) ? $this->post_statuses[$status] : $status);
52 }
53
54 public function get_moderations($args, &$items_count = 0)
55 {
56 if (isset($_GET['filter_by_userid']) && wpforo_bigintval($_GET['filter_by_userid'])) $args['userid'] = wpforo_bigintval($_GET['filter_by_userid']);
57 $filter_by_status = intval((isset($_GET['filter_by_status']) ? $_GET['filter_by_status'] : 1));
58 $args['status'] = $filter_by_status;
59 if( !isset($_GET['order']) ) $args['orderby'] = '`created` DESC, `postid` DESC';
60 $posts = WPF()->post->get_posts($args, $items_count);
61 return $posts;
62 }
63
64 public function search($needle, $fields = array())
65 {
66 $posts = WPF()->post->search($needle);
67 $pids = array();
68 foreach ($posts as $post) $pids[] = $post['postid'];
69 return $pids;
70 }
71
72 public function post_approve($postid)
73 {
74 return WPF()->post->status($postid, 0);
75 }
76
77 public function post_unapprove($postid)
78 {
79 return WPF()->post->status($postid, 1);
80 }
81
82 public function get_view_url($arg)
83 {
84 return WPF()->post->get_post_url($arg);
85 }
86
87 public function akismet_topic($item)
88 {
89 $post = array();
90 $post['user_ip'] = (isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : null);
91 $post['user_agent'] = (isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : null);
92 $post['referrer'] = (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : null);
93 $post['blog'] = get_option('home');
94 $post['blog_lang'] = get_locale();
95 $post['blog_charset'] = get_option('blog_charset');
96 $post['comment_type'] = 'forum-post';
97
98 if (empty($item['forumid'])) {
99 $topic = WPF()->topic->get_topic($item['topicid']);
100 $item['forumid'] = $topic['forumid'];
101 }
102
103 $post['comment_author'] = WPF()->current_user['user_nicename'];
104 $post['comment_author_email'] = WPF()->current_user['user_email'];
105 $post['comment_author_url'] = WPF()->member->get_profile_url(WPF()->current_userid);
106 $post['comment_post_modified_gmt'] = current_time('mysql', 1);
107 $post['comment_content'] = $item['title'] . " \r\n " . $item['body'];
108 $post['permalink'] = WPF()->forum->get_forum_url($item['forumid']);
109
110 $response = Akismet::http_post(Akismet::build_query($post), 'comment-check');
111 if ($response[1] == 'true') {
112 $this->ban_for_spam( WPF()->current_userid );
113 $item['status'] = 1;
114 }
115
116 return $item;
117 }
118
119 public function akismet_post($item)
120 {
121 $post = array();
122 $post['user_ip'] = (isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : null);
123 $post['user_agent'] = (isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : null);
124 $post['referrer'] = (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : null);
125 $post['blog'] = get_option('home');
126 $post['blog_lang'] = get_locale();
127 $post['blog_charset'] = get_option('blog_charset');
128 $post['comment_type'] = 'forum-post';
129
130 $topic = WPF()->topic->get_topic($item['topicid']);
131
132 $post['comment_author'] = WPF()->current_user['user_nicename'];
133 $post['comment_author_email'] = WPF()->current_user['user_email'];
134 $post['comment_author_url'] = WPF()->member->get_profile_url(WPF()->current_userid);
135 $post['comment_post_modified_gmt'] = $topic['modified'];
136 $post['comment_content'] = $item['body'];
137 $post['permalink'] = WPF()->topic->get_topic_url($item['topicid']);
138
139 $response = Akismet::http_post(Akismet::build_query($post), 'comment-check');
140 if ($response[1] == 'true') {
141 $this->ban_for_spam( WPF()->current_userid );
142 $item['status'] = 1;
143 }
144
145 return $item;
146 }
147
148 public function spam_attachment(){
149 $upload_dir = wp_upload_dir();
150 $default_attachments_dir = $upload_dir['basedir'] . '/wpforo/default_attachments/';
151 if(is_dir($default_attachments_dir)){
152 if ($handle = opendir($default_attachments_dir)){
153 while (false !== ($filename = readdir($handle))){
154 $file = $default_attachments_dir . '/' . $filename;
155 if( $filename == '.' || $filename == '..') continue;
156 $level = $this->spam_file($filename);
157 if( $level > 2 ){
158 $link = '<a href="' . admin_url('admin.php?page=wpforo-tools&tab=antispam#spam-files') . '"><strong>&gt;&gt;</strong></a>';
159 $phrase = '<strong>SPAM! - </strong>' . sprintf( __('Probably spam file attachments have been detected by wpForo Spam Control. Please moderate suspected files in Forums &gt; Tools &gt; Antispam Tab.', 'wpforo'), $link);
160 WPF()->notice->add( $phrase, 'error' );
161 return true;
162 }
163 }
164 }
165 }
166 return false;
167 }
168
169 public function spam_file( $item, $type = 'file' ){
170 if( !isset($item) || !$item ) return false;
171 $level = 0;
172 $item = strtolower($item);
173 $spam_file_phrases = array(
174 0 => array( 'watch', 'movie'),
175 1 => array( 'download', 'free')
176 );
177 if($type == 'file'){
178 $ext_whitelist = explode('|', WPF()->tools_antispam['exclude_file_ext'] );
179 $ext_whitelist = array_map('trim', $ext_whitelist);
180 $ext = strtolower(pathinfo($item, PATHINFO_EXTENSION));
181 $ext_risk = array('pdf', 'doc', 'docx', 'txt', 'htm', 'html', 'rtf', 'xml', 'xls', 'xlsx', 'php', 'cgi');
182 $ext_risk = wpforo_clear_array($ext_risk, $ext_whitelist);
183 $ext_high_risk = array('php', 'cgi', 'exe');
184 $ext_high_risk = wpforo_clear_array($ext_high_risk, $ext_whitelist);
185 if( in_array($ext, $ext_risk) ){
186 $has_post = WPF()->db->get_var( "SELECT `postid` FROM `".WPF()->tables->posts."` WHERE `body` LIKE '%" . esc_sql( $item ) . "%' LIMIT 1" );
187 foreach($spam_file_phrases as $phrases){
188 foreach($phrases as $phrase){
189 if( strpos($item, $phrase) !== FALSE ){
190 if( !$has_post ){
191 $level = 4; break 2;
192 }
193 else{
194 $level = 2; break 2;
195 }
196 }
197 }
198 }
199 if( !$level ){
200 if( !$has_post ){
201 $level = 3;
202 }
203 else{
204 if( in_array($ext, $ext_high_risk) ){
205 $level = 5;
206 }
207 else{
208 $level = 1;
209 }
210 }
211 }
212 }
213 return $level;
214 }
215 elseif($type == 'file-open'){
216 $ext = strtolower(pathinfo($item, PATHINFO_EXTENSION));
217 $allow_to_open = array('pdf', 'doc', 'docx', 'txt', 'rtf', 'xls', 'xlsx');
218 if( in_array($ext, $allow_to_open) ){
219 return true;
220 }
221 else{
222 return false;
223 }
224 }
225 return 0;
226 }
227
228 public function spam_topic($topic)
229 {
230 if( empty($topic) ) return $topic;
231 if( isset($topic['title']) ){
232 $item = $topic['title'];
233 }
234 else{
235 return $topic;
236 }
237 $len = wpforo_strlen($item);
238 if( $len < 10 ) return $topic;
239 $item = strip_tags($item);
240 $is_similar = false;
241 $topic_args = array( 'userid' => $topic['userid'] );
242 $topics = WPF()->topic->get_topics($topic_args);
243 $sc_level = ( isset(WPF()->tools_antispam['spam_filter_level_topic'])) ? intval(WPF()->tools_antispam['spam_filter_level_topic']) : 100;
244 if( $sc_level > 100 ) $sc_level = 60; $sc_level = (101 - $sc_level);
245 if( !empty($topics) ){
246 $count = count($topics);
247 $keys[0] = array_rand($topics); if( $count > 1) $keys[1] = array_rand($topics);
248 $check_1 = (isset($keys[0])) ? strip_tags($topics[$keys[0]]['title']) : '';
249 $check_2 = (isset($keys[1])) ? strip_tags($topics[$keys[1]]['title']) : '';
250 if($check_1){ similar_text($item, $check_1, $percent); if( $percent > $sc_level ) $is_similar = true; }
251 if($check_2 && !$is_similar){ similar_text($item, $check_2, $percent); if( $percent > $sc_level ) $is_similar = true; }
252 if( $is_similar ){
253 $this->ban_for_spam( WPF()->current_userid );
254 $topic['status'] = 1;
255 }
256 }
257 return $topic;
258 }
259
260 public function spam_post($post)
261 {
262 if( empty($post) ) return $post;
263 if( isset($post['body']) ){
264 $item = $post['body'];
265 }
266 else{
267 return $post;
268 }
269
270 // $len = wpforo_strlen($item);
271 $item = strip_tags($item);
272 $is_similar = false;
273 $post_args = array( 'userid' => $post['userid'] );
274 $posts = WPF()->post->get_posts($post_args);
275 $sc_level = ( isset(WPF()->tools_antispam['spam_filter_level_post'])) ? intval(WPF()->tools_antispam['spam_filter_level_post']) : 100;
276 if( $sc_level > 100 ) $sc_level = 70; $sc_level = (101 - $sc_level);
277 if( !empty($posts) ){
278 $count = count($posts);
279 $keys[0] = array_rand($posts); if( $count > 1) $keys[1] = array_rand($posts);
280 $check_1 = (isset($keys[0])) ? strip_tags($posts[$keys[0]]['body']) : '';
281 $check_2 = (isset($keys[1])) ? strip_tags($posts[$keys[1]]['body']) : '';
282 if($check_1){ similar_text($item, $check_1, $percent); if( isset($percent) && $percent > $sc_level ) $is_similar = true; }
283 if($check_2 && !$is_similar){ similar_text($item, $check_2, $percent); if( isset($percent) && $percent > $sc_level ) $is_similar = true; }
284 if( $is_similar ){
285 $this->ban_for_spam( WPF()->current_userid );
286 $post['status'] = 1;
287 }
288 }
289 return $post;
290 }
291
292 public function auto_moderate($item){
293
294 if( empty($item) ) return $item;
295 if( WPF()->perm->usergroup_can( 'em' ) ){
296 $item['status'] = 0;
297 return $item;
298 }
299 if( !WPF()->perm->usergroup_can( 'aup' ) ){
300 $item['status'] = 1;
301 return $item;
302 }
303
304 if( WPF()->member->current_user_is_new() ){
305 if( ( isset($item['status']) && $item['status'] == 1 ) || $this->has_unapproved( WPF()->current_userid ) ){
306 $this->set_all_unapproved( WPF()->current_userid );
307 $item['status'] = 1;
308 }
309 if( isset($item['body']) && isset($item['title']) && ( $this->has_link($item['body']) || $this->has_link($item['title']) ) ){
310 $item['status'] = 1;
311 }
312 }
313
314 return $item;
315 }
316
317 public function has_approved($user){
318 if( !$user ) return false;
319 if( isset($user['ID']) ){
320 $userid = intval($user['ID']);
321 }
322 else{
323 $userid = intval($user);
324 }
325 $has_approved_post = WPF()->db->get_var( "SELECT `postid` FROM `".WPF()->tables->posts."` WHERE `userid` = '" . intval($userid) . "' AND `status` = 0 LIMIT 1" );
326 if( $has_approved_post ){
327 return true;
328 }
329 else{
330 return false;
331 }
332 }
333
334 public function has_unapproved($user){
335 if( empty($user) ) return false;
336 if( isset($user['ID']) ){
337 $userid = intval($user['ID']);
338 }
339 else{
340 $userid = intval($user);
341 }
342 $has_unapproved_post = WPF()->db->get_var( "SELECT `postid` FROM `".WPF()->tables->posts."` WHERE `userid` = '" . intval($userid) . "' AND `status` = 1 LIMIT 1" );
343 if( $has_unapproved_post ){
344 return true;
345 }
346 else{
347 return false;
348 }
349 }
350
351 public function ban_for_spam( $userid ){
352 if ( isset($userid) && WPF()->tools_antispam['spam_user_ban'] ) {
353 if( !$this->has_approved( WPF()->current_userid ) ){
354 WPF()->member->autoban( $userid );
355 }
356 }
357 }
358
359 public function set_all_unapproved( $userid ){
360 if ( isset($userid) ) {
361 WPF()->db->update( WPF()->tables->topics, array('status' => 1), array('userid' => intval($userid)), array('%d'), array('%d'));
362 WPF()->db->update( WPF()->tables->posts, array('status' => 1), array('userid' => intval($userid)), array('%d'), array('%d'));
363 }
364 }
365
366 public function remove_links( $item ){
367 if( isset($item['body']) && $item['body'] ){
368 $item['body'] = preg_replace('/((http|https)\:\/\/)?[a-zA-Z0-9\.\/\?\:@\-_=#]+\.([a-zA-Z0-9\&\.\/\?\:@\-_=#])*/is', ' <span style="color:#aaa;">' . wpforo_phrase('removed link', false, false) . '</span> ', $item['body']);
369 }
370 if( isset($item['title']) && $item['title'] ){
371 if(preg_match('/((http|https)\:\/\/)?[a-zA-Z0-9\.\/\?\:@\-_=#]+\.([a-zA-Z0-9\&\.\/\?\:@\-_=#])*/is', $item['title'] )){
372 $item['title'] = preg_replace('/((http|https)\:\/\/)?[a-zA-Z0-9\.\/\?\:@\-_=#]+\.([a-zA-Z0-9\&\.\/\?\:@\-_=#])*/is', ' -' . wpforo_phrase('removed link', false, false) . '- ', $item['title']);
373 }
374 }
375 return $item;
376 }
377
378 public function has_link( $content ){
379 if( preg_match('/((http|https)\:\/\/)?[a-zA-Z0-9\.\/\?\:@\-_=#]+\.([a-zA-Z0-9\&\.\/\?\:@\-_=#])*/is', $content ) ){
380 return true;
381 }
382 return false;
383 }
384
385 }