PluginProbe
bbPress / 2.6.6
bbPress v2.6.6
trunk 2.0 2.0-beta-1 2.0-beta-2b 2.0-beta-3 2.0-beta-3b 2.0-rc-2 2.0-rc-3 2.0-rc-4 2.0-rc-5 2.0.1 2.0.2 2.0.3 2.1 2.1-beta-1 2.1-rc1 2.1-rc2 2.1-rc3 2.1-rc4 2.1.1 2.1.2 2.1.3 2.2 2.2.1 2.2.2 All 71 releases
bbpress / includes / extend / akismet.php

akismet.php in bbPress 2.6.6, at includes/extend/akismet.php

893 lines 25.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Main bbPress Akismet Class
5 *
6 * @package bbPress
7 * @subpackage Akismet
8 */
9
10 // Exit if accessed directly
11 defined( 'ABSPATH' ) || exit;
12
13 if ( ! class_exists( 'BBP_Akismet' ) ) :
14 /**
15 * Loads Akismet extension
16 *
17 * @since 2.0.0 bbPress (r3277)
18 *
19 * @package bbPress
20 * @subpackage Akismet
21 */
22 class BBP_Akismet {
23
24 /**
25 * The main bbPress Akismet loader
26 *
27 * @since 2.0.0 bbPress (r3277)
28 */
29 public function __construct() {
30 $this->setup_actions();
31 }
32
33 /**
34 * Setup the admin hooks
35 *
36 * @since 2.0.0 bbPress (r3277)
37 *
38 * @access private
39 */
40 private function setup_actions() {
41
42 // Prevent debug notices
43 $checks = array();
44
45 // bbPress functions to check for spam
46 $checks['check'] = array(
47 'bbp_new_topic_pre_insert' => 1, // New topic check
48 'bbp_new_reply_pre_insert' => 1, // New reply check
49 'bbp_edit_topic_pre_insert' => 1, // Edit topic check
50 'bbp_edit_reply_pre_insert' => 1 // Edit reply check
51 );
52
53 // bbPress functions for spam and ham submissions
54 $checks['submit'] = array(
55 'bbp_spammed_topic' => 10, // Spammed topic
56 'bbp_unspammed_topic' => 10, // Unspammed reply
57 'bbp_spammed_reply' => 10, // Spammed reply
58 'bbp_unspammed_reply' => 10, // Unspammed reply
59 );
60
61 // Add the checks
62 foreach ( $checks as $type => $functions ) {
63 foreach ( $functions as $function => $priority ) {
64 add_filter( $function, array( $this, $type . '_post' ), $priority );
65 }
66 }
67
68 // Update post meta
69 add_action( 'wp_insert_post', array( $this, 'update_post_meta' ), 10, 2 );
70
71 // Admin
72 if ( is_admin() ) {
73 add_action( 'add_meta_boxes', array( $this, 'add_metaboxes' ) );
74 }
75 }
76
77 /**
78 * Converts topic/reply data into Akismet comment checking format
79 *
80 * @since 2.0.0 bbPress (r3277)
81 *
82 * @param array $post_data
83 *
84 * @return array Array of post data
85 */
86 public function check_post( $post_data = array() ) {
87
88 // Define local variables
89 $user_data = array();
90 $post_permalink = '';
91
92 // Post is not published
93 if ( bbp_get_public_status_id() !== $post_data['post_status'] ) {
94 return $post_data;
95 }
96
97 // Cast the post_author to 0 if it's empty
98 if ( empty( $post_data['post_author'] ) ) {
99 $post_data['post_author'] = 0;
100 }
101
102 /** Author ************************************************************/
103
104 $user_data['last_active'] = '';
105 $user_data['registered'] = date( 'Y-m-d H:i:s');
106 $user_data['total_posts'] = (int) bbp_get_user_post_count( $post_data['post_author'] );
107
108 // Get user data
109 $userdata = get_userdata( $post_data['post_author'] );
110 $anonymous_data = bbp_filter_anonymous_post_data();
111
112 // Author is anonymous
113 if ( ! bbp_has_errors() ) {
114 $user_data['name'] = $anonymous_data['bbp_anonymous_name'];
115 $user_data['email'] = $anonymous_data['bbp_anonymous_email'];
116 $user_data['website'] = $anonymous_data['bbp_anonymous_website'];
117
118 // Author is logged in
119 } elseif ( ! empty( $userdata ) ) {
120 $user_data['name'] = $userdata->display_name;
121 $user_data['email'] = $userdata->user_email;
122 $user_data['website'] = $userdata->user_url;
123 $user_data['registered'] = $userdata->user_registered;
124
125 // Missing author data, so set some empty strings
126 } else {
127 $user_data['name'] = '';
128 $user_data['email'] = '';
129 $user_data['website'] = '';
130 }
131
132 /** Post **************************************************************/
133
134 if ( ! empty( $post_data['post_parent'] ) ) {
135
136 // Use post parent for permalink
137 $post_permalink = get_permalink( $post_data['post_parent'] );
138
139 // Use post parent to get datetime of last reply on this topic
140 $reply_id = bbp_get_topic_last_reply_id( $post_data['post_parent'] );
141 if ( ! empty( $reply_id ) ) {
142 $user_data['last_active'] = get_post_field( 'post_date', $reply_id );
143 }
144 }
145
146 // Pass title & content together into comment content
147 $_post_content = trim( $post_data['post_title'] . "\n\n" . $post_data['post_content'] );
148
149 // Check if the post data is spammy...
150 $_post = $this->maybe_spam( array(
151 'comment_author' => $user_data['name'],
152 'comment_author_email' => $user_data['email'],
153 'comment_author_url' => $user_data['website'],
154 'comment_content' => $_post_content,
155 'comment_post_ID' => $post_data['post_parent'],
156 'comment_type' => $post_data['post_type'],
157 'comment_total' => $user_data['total_posts'],
158 'comment_last_active_gmt' => $user_data['last_active'],
159 'comment_account_registered_gmt' => $user_data['registered'],
160 'permalink' => $post_permalink,
161 'referrer' => wp_get_raw_referer(),
162 'user_agent' => bbp_current_author_ua(),
163 'user_ID' => $post_data['post_author'],
164 'user_ip' => bbp_current_author_ip(),
165 'user_role' => $this->get_user_roles( $post_data['post_author'] ),
166 ) );
167
168 // Set the result headers (from maybe_spam() above)
169 $post_data['bbp_akismet_result_headers'] = ! empty( $_post['bbp_akismet_result_headers'] )
170 ? $_post['bbp_akismet_result_headers'] // raw
171 : esc_html__( 'No response', 'bbpress' );
172
173 // Set the result (from maybe_spam() above)
174 $post_data['bbp_akismet_result'] = ! empty( $_post['bbp_akismet_result'] )
175 ? $_post['bbp_akismet_result'] // raw
176 : esc_html__( 'No response', 'bbpress' );
177
178 // Avoid recurrsion by unsetting results
179 unset(
180 $_post['bbp_akismet_result_headers'],
181 $_post['bbp_akismet_result']
182 );
183 $post_data['bbp_post_as_submitted'] = $_post;
184
185 // Cleanup to avoid touching this variable again below
186 unset( $_post );
187
188 // Allow post_data to be manipulated
189 $post_data = apply_filters( 'bbp_akismet_check_post', $post_data );
190
191 // Parse and log the last response
192 $this->last_post = $this->parse_response( $post_data );
193
194 // Return the last response back to the filter
195 return $this->last_post;
196 }
197
198 /**
199 * Parse the response from the Akismet service, and alter the post data as
200 * necessary. For example, switch the status to `spam` if spammy.
201 *
202 * Note: this method also skiis responsible for allowing users who can moderate, to
203 * never have their posts marked as spam. This is because they are "trusted"
204 * users. However, their posts are still sent to Akismet to be checked.
205 *
206 * @since 2.6.0 bbPress (r6873)
207 *
208 * @param array $post_data
209 *
210 * @return array
211 */
212 private function parse_response( $post_data = array() ) {
213
214 // Get the parent ID of the post as submitted
215 $parent_id = ! empty( $post_data['bbp_post_as_submitted']['comment_post_ID'] )
216 ? absint( $post_data['bbp_post_as_submitted']['comment_post_ID'] )
217 : 0;
218
219 // Allow moderators to skip spam (includes per-forum moderators via $parent_id)
220 $skip_spam = current_user_can( 'moderate', $parent_id );
221
222 // Bail early if current user can skip spam enforcement
223 if ( apply_filters( 'bbp_bypass_spam_enforcement', $skip_spam, $post_data ) ) {
224 return $post_data;
225 }
226
227 // Result is spam, so set the status as such
228 if ( 'true' === $post_data['bbp_akismet_result'] ) {
229
230 // Let plugins do their thing
231 do_action( 'bbp_akismet_spam_caught' );
232
233 // Set post_status to spam
234 $post_data['post_status'] = bbp_get_spam_status_id();
235
236 // Filter spammy tags into meta data
237 add_filter( 'bbp_new_reply_pre_set_terms', array( $this, 'filter_post_terms' ), 1, 3 );
238 }
239
240 // Return the (potentially modified) post data
241 return $post_data;
242 }
243
244 /**
245 * Submit a post for spamming or hamming
246 *
247 * @since 2.0.0 bbPress (r3277)
248 *
249 * @param int $post_id
250 *
251 * @global string $akismet_api_host
252 * @global string $akismet_api_port
253 * @global object $current_user
254 * @global object $current_site
255 *
256 * @return array Array of existing topic terms
257 */
258 public function submit_post( $post_id = 0 ) {
259 global $current_user, $current_site;
260
261 // Innocent until proven guilty
262 $request_type = 'ham';
263 $current_filter = current_filter();
264
265 // Check this filter and adjust the $request_type accordingly
266 switch ( $current_filter ) {
267
268 // Mysterious, and straight from the can
269 case 'bbp_spammed_topic' :
270 case 'bbp_spammed_reply' :
271 $request_type = 'spam';
272 break;
273
274 // Honey-glazed, a straight off the bone
275 case 'bbp_unspammed_topic' :
276 case 'bbp_unspammed_reply' :
277 $request_type = 'ham';
278 break;
279
280 // Possibly poison...
281 default :
282 return;
283 }
284
285 // Setup some variables
286 $post_id = (int) $post_id;
287
288 // Make sure we have a post
289 $_post = get_post( $post_id );
290
291 // Bail if get_post() fails
292 if ( empty( $_post ) ) {
293 return;
294 }
295
296 // Bail if we're spamming, but the post_status isn't spam
297 if ( ( 'spam' === $request_type ) && ( bbp_get_spam_status_id() !== $_post->post_status ) ) {
298 return;
299 }
300
301 // Pass title & content together into comment content
302 $_post_content = trim( $_post->post_title . "\n\n" . $_post->post_content );
303
304 // Set some default post_data
305 $post_data = array(
306 'comment_approved' => $_post->post_status,
307 'comment_author' => $_post->post_author ? get_the_author_meta( 'display_name', $_post->post_author ) : get_post_meta( $post_id, '_bbp_anonymous_name', true ),
308 'comment_author_email' => $_post->post_author ? get_the_author_meta( 'email', $_post->post_author ) : get_post_meta( $post_id, '_bbp_anonymous_email', true ),
309 'comment_author_url' => $_post->post_author ? bbp_get_user_profile_url( $_post->post_author ) : get_post_meta( $post_id, '_bbp_anonymous_website', true ),
310 'comment_content' => $_post_content,
311 'comment_date_gmt' => $_post->post_date_gmt,
312 'comment_ID' => $post_id,
313 'comment_post_ID' => $_post->post_parent,
314 'comment_type' => $_post->post_type,
315 'permalink' => get_permalink( $post_id ),
316 'user_ID' => $_post->post_author,
317 'user_ip' => get_post_meta( $post_id, '_bbp_author_ip', true ),
318 'user_role' => $this->get_user_roles( $_post->post_author ),
319 );
320
321 // Use the original version stored in post_meta if available
322 $as_submitted = get_post_meta( $post_id, '_bbp_akismet_as_submitted', true );
323 if ( $as_submitted && is_array( $as_submitted ) && isset( $as_submitted['comment_content'] ) ) {
324 $post_data = array_merge( $post_data, $as_submitted );
325 }
326
327 // Add the reporter IP address
328 $post_data['reporter_ip'] = bbp_current_author_ip();
329
330 // Add some reporter info
331 if ( is_object( $current_user ) ) {
332 $post_data['reporter'] = $current_user->user_login;
333 }
334
335 // Add the current site domain
336 if ( is_object( $current_site ) ) {
337 $post_data['site_domain'] = $current_site->domain;
338 }
339
340 // Place your slide beneath the microscope
341 $post_data = $this->maybe_spam( $post_data, 'submit', $request_type );
342
343 // Manual user action
344 if ( isset( $post_data['reporter'] ) ) {
345
346 // What kind of action
347 switch ( $request_type ) {
348
349 // Spammy
350 case 'spam' :
351 if ( 'topic' === $post_data['comment_type'] ) {
352 /* translators: %s: reporter name */
353 $message = sprintf( esc_html__( '%s reported this topic as spam', 'bbpress' ),
354 $post_data['reporter']
355 );
356 } elseif ( 'reply' === $post_data['comment_type'] ) {
357 /* translators: %s: reporter name */
358 $message = sprintf( esc_html__( '%s reported this reply as spam', 'bbpress' ),
359 $post_data['reporter']
360 );
361 } else {
362 /* translators: 1: reporter name, 2: comment type */
363 $message = sprintf( esc_html__( '%1$s reported this %2$s as spam', 'bbpress' ),
364 $post_data['reporter'],
365 $post_data['comment_type']
366 );
367 }
368
369 $this->update_post_history( $post_id, $message, 'report-spam' );
370 update_post_meta( $post_id, '_bbp_akismet_user_result', 'true' );
371 update_post_meta( $post_id, '_bbp_akismet_user', $post_data['reporter'] );
372 break;
373
374 // Hammy
375 case 'ham' :
376 if ( 'topic' === $post_data['comment_type'] ) {
377 /* translators: %s: reporter name */
378 $message = sprintf( esc_html__( '%s reported this topic as not spam', 'bbpress' ),
379 $post_data['reporter']
380 );
381 } elseif ( 'reply' === $post_data['comment_type'] ) {
382 /* translators: %s: reporter name */
383 $message = sprintf( esc_html__( '%s reported this reply as not spam', 'bbpress' ),
384 $post_data['reporter']
385 );
386 } else {
387 /* translators: 1: reporter name, 2: comment type */
388 $message = sprintf( esc_html__( '%1$s reported this %2$s as not spam', 'bbpress' ),
389 $post_data['reporter'],
390 $post_data['comment_type']
391 );
392 }
393
394 $this->update_post_history( $post_id, $message, 'report-ham' );
395 update_post_meta( $post_id, '_bbp_akismet_user_result', 'false' );
396 update_post_meta( $post_id, '_bbp_akismet_user', $post_data['reporter'] );
397
398 // @todo Topic term revision history
399 break;
400
401 // Possible other actions
402 default :
403 break;
404 }
405 }
406
407 do_action( 'bbp_akismet_submit_' . $request_type . '_post', $post_id, $post_data['bbp_akismet_result'] );
408 }
409
410 /**
411 * Ping Akismet service and check for spam/ham response
412 *
413 * @since 2.0.0 bbPress (r3277)
414 *
415 * @param array $post_data
416 * @param string $check Accepts check|submit
417 * @param string $spam Accepts spam|ham
418 *
419 * @global string $akismet_api_host
420 * @global string $akismet_api_port
421 *
422 * @return array Array of post data
423 */
424 private function maybe_spam( $post_data = array(), $check = 'check', $spam = 'spam' ) {
425 global $akismet_api_host, $akismet_api_port;
426
427 // Define variables
428 $query_string = $path = $response = '';
429
430 // Make sure post data is an array
431 if ( ! is_array( $post_data ) ) {
432 $post_data = array();
433 }
434
435 // Populate post data
436 $post_data['blog'] = get_option( 'home' );
437 $post_data['blog_charset'] = get_option( 'blog_charset' );
438 $post_data['blog_lang'] = get_locale();
439 $post_data['referrer'] = wp_get_raw_referer();
440 $post_data['user_agent'] = bbp_current_author_ua();
441
442 // Loop through _POST args and rekey strings
443 if ( ! empty( $_POST ) && is_countable( $_POST ) ) {
444 foreach ( $_POST as $key => $value ) {
445 if ( is_string( $value ) ) {
446 $post_data['POST_' . $key] = $value;
447 }
448 }
449 }
450
451 // Loop through _SERVER args and remove allowed keys
452 if ( ! empty( $_SERVER ) && is_countable( $_SERVER ) ) {
453
454 // Keys to ignore
455 $ignore = array( 'HTTP_COOKIE', 'HTTP_COOKIE2', 'PHP_AUTH_PW' );
456
457 foreach ( $_SERVER as $key => $value ) {
458
459 // Key should not be ignored
460 if ( ! in_array( $key, $ignore, true ) && is_string( $value ) ) {
461 $post_data[ $key ] = $value;
462
463 // Key should be ignored
464 } else {
465 $post_data[ $key ] = '';
466 }
467 }
468 }
469
470 // Encode post data
471 if ( ! empty( $post_data ) && is_countable( $post_data ) ) {
472 foreach ( $post_data as $key => $data ) {
473 $query_string .= $key . '=' . urlencode( wp_unslash( $data ) ) . '&';
474 }
475 }
476
477 // Setup the API route
478 if ( 'check' === $check ) {
479 $path = '/1.1/comment-check';
480 } elseif ( 'submit' === $check ) {
481 $path = '/1.1/submit-' . $spam;
482 }
483
484 // Send data to Akismet
485 $response = ! apply_filters( 'bbp_bypass_check_for_spam', false, $post_data )
486 ? $this->http_post( $query_string, $akismet_api_host, $path, $akismet_api_port )
487 : false;
488
489 // Set the result headers
490 $post_data['bbp_akismet_result_headers'] = ! empty( $response[0] )
491 ? $response[0]
492 : esc_html__( 'No response', 'bbpress' );
493
494 // Set the result
495 $post_data['bbp_akismet_result'] = ! empty( $response[1] )
496 ? $response[1]
497 : esc_html__( 'No response', 'bbpress' );
498
499 // Return the post data, with the results of the external Akismet request
500 return $post_data;
501 }
502
503 /**
504 * Update post meta after a spam check
505 *
506 * @since 2.0.0 bbPress (r3308)
507 *
508 * @param int $post_id
509 * @param object $_post
510 *
511 * @global object $this->last_post
512 */
513 public function update_post_meta( $post_id = 0, $_post = false ) {
514
515 // Define local variable(s)
516 $as_submitted = false;
517
518 // Setup some variables
519 $post_id = (int) $post_id;
520
521 // Ensure we have a post object
522 if ( empty( $_post ) ) {
523 $_post = get_post( $post_id );
524 }
525
526 // Set up Akismet last post data
527 if ( ! empty( $this->last_post['bbp_post_as_submitted'] ) ) {
528 $as_submitted = $this->last_post['bbp_post_as_submitted'];
529 }
530
531 // wp_insert_post() might be called in other contexts. Ensure this is
532 // the same topic/reply as was checked by BBP_Akismet::check_post()
533 if ( is_object( $_post ) && ! empty( $this->last_post ) && is_array( $as_submitted ) ) {
534
535 // Get user data
536 $userdata = get_userdata( $_post->post_author );
537 $anonymous_data = bbp_filter_anonymous_post_data();
538
539 // Which name?
540 $name = ! empty( $anonymous_data['bbp_anonymous_name'] )
541 ? $anonymous_data['bbp_anonymous_name']
542 : $userdata->display_name;
543
544 // Which email?
545 $email = ! empty( $anonymous_data['bbp_anonymous_email'] )
546 ? $anonymous_data['bbp_anonymous_email']
547 : $userdata->user_email;
548
549 // More checks
550 if (
551
552 // Post matches
553 ( intval( $as_submitted['comment_post_ID'] ) === intval( $_post->post_parent ) )
554
555 &&
556
557 // Name matches
558 ( $as_submitted['comment_author'] === $name )
559
560 &&
561
562 // Email matches
563 ( $as_submitted['comment_author_email'] === $email )
564 ) {
565
566 // Normal result: true
567 if ( ! empty( $this->last_post['bbp_akismet_result'] ) && ( $this->last_post['bbp_akismet_result'] === 'true' ) ) {
568
569 // Leave a trail so other's know what we did
570 update_post_meta( $post_id, '_bbp_akismet_result', 'true' );
571 $this->update_post_history(
572 $post_id,
573 esc_html__( 'Akismet caught this post as spam', 'bbpress' ),
574 'check-spam'
575 );
576
577 // If post_status isn't the spam status, as expected, leave a note
578 if ( bbp_get_spam_status_id() !== $_post->post_status ) {
579 $this->update_post_history(
580 $post_id,
581 sprintf(
582 esc_html__( 'Post status was changed to %s', 'bbpress' ),
583 $_post->post_status
584 ),
585 'status-changed-' . $_post->post_status
586 );
587 }
588
589 // Normal result: false
590 } elseif ( ! empty( $this->last_post['bbp_akismet_result'] ) && ( $this->last_post['bbp_akismet_result'] === 'false' ) ) {
591
592 // Leave a trail so other's know what we did
593 update_post_meta( $post_id, '_bbp_akismet_result', 'false' );
594 $this->update_post_history(
595 $post_id,
596 esc_html__( 'Akismet cleared this post as not spam', 'bbpress' ),
597 'check-ham'
598 );
599
600 // If post_status is the spam status, which isn't expected, leave a note
601 if ( bbp_get_spam_status_id() === $_post->post_status ) {
602 $this->update_post_history(
603 $post_id,
604 sprintf(
605 esc_html__( 'Post status was changed to %s', 'bbpress' ),
606 $_post->post_status
607 ),
608 'status-changed-' . $_post->post_status
609 );
610 }
611
612 // Abnormal result: error
613 } else {
614 // Leave a trail so other's know what we did
615 update_post_meta( $post_id, '_bbp_akismet_error', time() );
616 $this->update_post_history(
617 $post_id,
618 sprintf(
619 esc_html__( 'Akismet was unable to check this post (response: %s), will automatically retry again later.', 'bbpress' ),
620 $this->last_post['bbp_akismet_result']
621 ),
622 'check-error'
623 );
624 }
625
626 // Record the complete original data as submitted for checking
627 if ( isset( $this->last_post['bbp_post_as_submitted'] ) ) {
628 update_post_meta(
629 $post_id,
630 '_bbp_akismet_as_submitted',
631 $this->last_post['bbp_post_as_submitted']
632 );
633 }
634 }
635 }
636 }
637
638 /**
639 * Update Akismet history of a Post
640 *
641 * @since 2.0.0 bbPress (r3308)
642 *
643 * @param int $post_id
644 * @param string $message
645 * @param string $event
646 */
647 private function update_post_history( $post_id = 0, $message = null, $event = null ) {
648
649 // Define local variable(s)
650 $user = '';
651
652 // Get the current user
653 $current_user = wp_get_current_user();
654
655 // Get the user's login name if possible
656 if ( is_object( $current_user ) && isset( $current_user->user_login ) ) {
657 $user = $current_user->user_login;
658 }
659
660 // This used to be akismet_microtime() but it was removed in 3.0
661 $mtime = explode( ' ', microtime() );
662 $message_time = $mtime[1] + $mtime[0];
663
664 // Setup the event to be saved
665 $event = array(
666 'time' => $message_time,
667 'message' => $message,
668 'event' => $event,
669 'user' => $user,
670 );
671
672 // Save the event data
673 add_post_meta( $post_id, '_bbp_akismet_history', $event );
674 }
675
676 /**
677 * Get the Akismet history of a Post
678 *
679 * @since 2.0.0 bbPress (r3308)
680 *
681 * @param int $post_id
682 *
683 * @return array Array of Akismet history
684 */
685 public function get_post_history( $post_id = 0 ) {
686
687 // Retrieve any previous history
688 $history = get_post_meta( $post_id, '_bbp_akismet_history' );
689
690 // Sort it by the time recorded
691 usort( $history, 'akismet_cmp_time' );
692
693 return $history;
694 }
695
696 /**
697 * Handle any terms submitted with a post flagged as spam
698 *
699 * @since 2.0.0 bbPress (r3308)
700 *
701 * @param string $terms Comma-separated list of terms
702 * @param int $topic_id
703 * @param int $reply_id
704 *
705 * @return array Array of existing topic terms
706 */
707 public function filter_post_terms( $terms = '', $topic_id = 0, $reply_id = 0 ) {
708
709 // Validate the reply_id and topic_id
710 $reply_id = bbp_get_reply_id( $reply_id );
711 $topic_id = bbp_get_topic_id( $topic_id );
712
713 // Get any pre-existing terms
714 $existing_terms = bbp_get_topic_tag_names( $topic_id );
715
716 // Save the terms for later in case the reply gets hammed
717 if ( ! empty( $terms ) ) {
718 update_post_meta( $reply_id, '_bbp_akismet_spam_terms', $terms );
719 }
720
721 // Keep the topic tags the same for now
722 return $existing_terms;
723 }
724
725 /**
726 * Submit data to Akismet service with unique bbPress User Agent
727 *
728 * This code is directly taken from the akismet_http_post() function and
729 * documented to bbPress 2.0 standard.
730 *
731 * @since 2.0.0 bbPress (r3466)
732 *
733 * @param string $request The request we are sending
734 * @param string $host The host to send our request to
735 * @param string $path The path from the host
736 * @param string $port The port to use
737 * @param string $ip Optional Override $host with an IP address
738 * @return mixed WP_Error on error, array on success, empty on failure
739 */
740 private function http_post( $request, $host, $path, $port = 80, $ip = '' ) {
741
742 // Preload required variables
743 $bbp_version = bbp_get_version();
744 $http_host = $host;
745 $blog_charset = get_option( 'blog_charset' );
746 $response = '';
747
748 // Untque User Agent
749 $akismet_ua = "bbPress/{$bbp_version} | ";
750 $akismet_ua .= 'Akismet/' . constant( 'AKISMET_VERSION' );
751
752 // Use specific IP (if provided)
753 if ( ! empty( $ip ) && long2ip( ip2long( $ip ) ) ) {
754 $http_host = $ip;
755 }
756
757 // Setup the arguments
758 $http_args = array(
759 'body' => $request,
760 'headers' => array(
761 'Content-Type' => 'application/x-www-form-urlencoded; charset=' . $blog_charset,
762 'Host' => $host,
763 'User-Agent' => $akismet_ua
764 ),
765 'httpversion' => '1.0',
766 'timeout' => 15
767 );
768
769 // Where we are sending our request
770 $akismet_url = 'http://' . $http_host . $path;
771
772 // Send the request
773 $response = wp_remote_post( $akismet_url, $http_args );
774
775 // Bail if the response is an error
776 if ( is_wp_error( $response ) ) {
777 return '';
778 }
779
780 // No errors so return response
781 return array( $response['headers'], $response['body'] );
782 }
783
784 /**
785 * Return a user's roles on this site (including super_admin)
786 *
787 * @since 2.3.0 bbPress (r4812)
788 *
789 * @param int $user_id
790 *
791 * @return boolean
792 */
793 private function get_user_roles( $user_id = 0 ) {
794
795 // Default return value
796 $roles = array();
797
798 // Bail if cannot query the user
799 if ( ! class_exists( 'WP_User' ) || empty( $user_id ) ) {
800 return false;
801 }
802
803 // User ID
804 $user = new WP_User( $user_id );
805 if ( isset( $user->roles ) ) {
806 $roles = (array) $user->roles;
807 }
808
809 // Super admin
810 if ( is_multisite() && is_super_admin( $user_id ) ) {
811 $roles[] = 'super_admin';
812 }
813
814 return implode( ',', $roles );
815 }
816
817 /** Admin *****************************************************************/
818
819 /**
820 * Add Aksimet History meta-boxes to topics and replies
821 *
822 * @since 2.4.0 bbPress (r5049)
823 */
824 public function add_metaboxes() {
825
826 // Topics
827 add_meta_box(
828 'bbp_akismet_topic_history',
829 __( 'Akismet History', 'bbpress' ),
830 array( $this, 'history_metabox' ),
831 bbp_get_topic_post_type(),
832 'normal',
833 'core'
834 );
835
836 // Replies
837 add_meta_box(
838 'bbp_akismet_reply_history',
839 __( 'Akismet History', 'bbpress' ),
840 array( $this, 'history_metabox' ),
841 bbp_get_reply_post_type(),
842 'normal',
843 'core'
844 );
845 }
846
847 /**
848 * Output for Akismet History meta-box
849 *
850 * @since 2.4.0 bbPress (r5049)
851 */
852 public function history_metabox() {
853
854 // Post ID
855 $history = $this->get_post_history( get_the_ID() ); ?>
856
857 <div class="akismet-history" style="margin: 13px 0;">
858
859 <?php if ( ! empty( $history ) ) : ?>
860
861 <table>
862 <tbody>
863
864 <?php foreach ( $history as $row ) : ?>
865
866 <tr>
867 <td style="color: #999; text-align: right; white-space: nowrap;">
868 <span title="<?php echo esc_attr( date( 'D d M Y @ h:i:m a', $row['time'] ) . ' GMT' ); ?>">
869 <?php bbp_time_since( $row['time'], false, true ); ?>
870 </span>
871 </td>
872 <td style="padding-left: 5px;">
873 <?php echo esc_html( $row['message'] ); ?>
874 </td>
875 </tr>
876
877 <?php endforeach; ?>
878 </tbody>
879 </table>
880
881 <?php else : ?>
882
883 <p><?php esc_html_e( 'No recorded history. Akismet has not checked this post.', 'bbpress' ); ?></p>
884
885 <?php endif; ?>
886
887 </div>
888
889 <?php
890 }
891 }
892 endif;
893