[ Index ]

PHP Cross Reference of BBPress

title

Body

[close]

/src/includes/extend/ -> akismet.php (source)

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


Generated: Mon Jun 14 01:01:28 2021 Cross-referenced by PHPXref 0.7.1