Akismet Anti-Spam - Version 3.2

Version Description

Release Date - 6 September 2016

  • Added a WP-CLI module. You can now check comments and recheck the moderation queue from the command line.
  • Stopped using the deprecated jQuery function .live().
  • Fixed a bug in remove_comment_author_url() and add_comment_author_url() that could generate PHP notices.
  • Fixed a bug that could cause an infinite loop for sites with very very very large comment IDs.
  • Fixed a bug that could cause the Akismet widget title to be blank.
Download this release

Release Info

Developer cfinke
Plugin Icon 128x128 Akismet Anti-Spam
Version 3.2
Comparing to
See all releases

Code changes from version 3.1.11 to 3.2

_inc/akismet.js CHANGED
@@ -45,7 +45,8 @@ jQuery( function ( $ ) {
45
  );
46
  }
47
  });
48
- $('.remove_url').live('click', function () {
 
49
  var thisId = $(this).attr('commentid');
50
  var data = {
51
  action: 'comment_author_deurl',
@@ -82,8 +83,7 @@ jQuery( function ( $ ) {
82
  });
83
 
84
  return false;
85
- });
86
- $('.akismet_undo_link_removal').live('click', function () {
87
  var thisId = $(this).attr('cid');
88
  var thisUrl = $(this).attr('href');
89
  var data = {
@@ -177,7 +177,7 @@ jQuery( function ( $ ) {
177
  'limit': limit
178
  },
179
  function(result) {
180
- if (result.processed < limit) {
181
  window.location.reload();
182
  }
183
  else {
45
  );
46
  }
47
  });
48
+
49
+ $( '#the-comment-list' ).on( 'click', '.remove_url', function () {
50
  var thisId = $(this).attr('commentid');
51
  var data = {
52
  action: 'comment_author_deurl',
83
  });
84
 
85
  return false;
86
+ }).on( 'click', '.akismet_undo_link_removal', function () {
 
87
  var thisId = $(this).attr('cid');
88
  var thisUrl = $(this).attr('href');
89
  var data = {
177
  'limit': limit
178
  },
179
  function(result) {
180
+ if (result.counts.processed < limit) {
181
  window.location.reload();
182
  }
183
  else {
akismet.php CHANGED
@@ -6,7 +6,7 @@
6
  Plugin Name: Akismet
7
  Plugin URI: https://akismet.com/
8
  Description: Used by millions, Akismet is quite possibly the best way in the world to <strong>protect your blog from spam</strong>. It keeps your site protected even while you sleep. To get started: 1) Click the "Activate" link to the left of this description, 2) <a href="https://akismet.com/get/">Sign up for an Akismet plan</a> to get an API key, and 3) Go to your Akismet configuration page, and save your API key.
9
- Version: 3.1.11
10
  Author: Automattic
11
  Author URI: https://automattic.com/wordpress-plugins/
12
  License: GPLv2 or later
@@ -37,8 +37,8 @@ if ( !function_exists( 'add_action' ) ) {
37
  exit;
38
  }
39
 
40
- define( 'AKISMET_VERSION', '3.1.11' );
41
- define( 'AKISMET__MINIMUM_WP_VERSION', '3.2' );
42
  define( 'AKISMET__PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
43
  define( 'AKISMET_DELETE_LIMIT', 100000 );
44
 
@@ -50,7 +50,7 @@ require_once( AKISMET__PLUGIN_DIR . 'class.akismet-widget.php' );
50
 
51
  add_action( 'init', array( 'Akismet', 'init' ) );
52
 
53
- if ( is_admin() ) {
54
  require_once( AKISMET__PLUGIN_DIR . 'class.akismet-admin.php' );
55
  add_action( 'init', array( 'Akismet_Admin', 'init' ) );
56
  }
@@ -58,3 +58,6 @@ if ( is_admin() ) {
58
  //add wrapper class around deprecated akismet functions that are referenced elsewhere
59
  require_once( AKISMET__PLUGIN_DIR . 'wrapper.php' );
60
 
 
 
 
6
  Plugin Name: Akismet
7
  Plugin URI: https://akismet.com/
8
  Description: Used by millions, Akismet is quite possibly the best way in the world to <strong>protect your blog from spam</strong>. It keeps your site protected even while you sleep. To get started: 1) Click the "Activate" link to the left of this description, 2) <a href="https://akismet.com/get/">Sign up for an Akismet plan</a> to get an API key, and 3) Go to your Akismet configuration page, and save your API key.
9
+ Version: 3.2
10
  Author: Automattic
11
  Author URI: https://automattic.com/wordpress-plugins/
12
  License: GPLv2 or later
37
  exit;
38
  }
39
 
40
+ define( 'AKISMET_VERSION', '3.2' );
41
+ define( 'AKISMET__MINIMUM_WP_VERSION', '3.7' );
42
  define( 'AKISMET__PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
43
  define( 'AKISMET_DELETE_LIMIT', 100000 );
44
 
50
 
51
  add_action( 'init', array( 'Akismet', 'init' ) );
52
 
53
+ if ( is_admin() || ( defined( 'WP_CLI' ) && WP_CLI ) ) {
54
  require_once( AKISMET__PLUGIN_DIR . 'class.akismet-admin.php' );
55
  add_action( 'init', array( 'Akismet_Admin', 'init' ) );
56
  }
58
  //add wrapper class around deprecated akismet functions that are referenced elsewhere
59
  require_once( AKISMET__PLUGIN_DIR . 'wrapper.php' );
60
 
61
+ if ( defined( 'WP_CLI' ) && WP_CLI ) {
62
+ require_once( AKISMET__PLUGIN_DIR . 'class.akismet-cli.php' );
63
+ }
class.akismet-admin.php CHANGED
@@ -357,85 +357,68 @@ class Akismet_Admin {
357
 
358
  Akismet::fix_scheduled_recheck();
359
 
360
- if ( ! ( isset( $_GET['recheckqueue'] ) || ( isset( $_REQUEST['action'] ) && 'akismet_recheck_queue' == $_REQUEST['action'] ) ) )
361
  return;
 
 
 
362
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
363
  $paginate = '';
364
- if ( isset( $_POST['limit'] ) && isset( $_POST['offset'] ) ) {
365
- $paginate = $wpdb->prepare( " LIMIT %d OFFSET %d", array( $_POST['limit'], $_POST['offset'] ) );
 
 
 
 
 
366
  }
367
- $moderation = $wpdb->get_results( "SELECT * FROM {$wpdb->comments} WHERE comment_approved = '0'{$paginate}", ARRAY_A );
 
368
 
369
  $result_counts = array(
 
370
  'spam' => 0,
371
  'ham' => 0,
372
  'error' => 0,
373
  );
374
 
375
- foreach ( (array) $moderation as $c ) {
376
- $c['user_ip'] = $c['comment_author_IP'];
377
- $c['user_agent'] = $c['comment_agent'];
378
- $c['referrer'] = '';
379
- $c['blog'] = get_bloginfo('url');
380
- $c['blog_lang'] = get_locale();
381
- $c['blog_charset'] = get_option('blog_charset');
382
- $c['permalink'] = get_permalink($c['comment_post_ID']);
383
-
384
- $c['user_role'] = '';
385
- if ( isset( $c['user_ID'] ) )
386
- $c['user_role'] = Akismet::get_user_roles($c['user_ID']);
387
 
388
- if ( Akismet::is_test_mode() )
389
- $c['is_test'] = 'true';
390
-
391
- add_comment_meta( $c['comment_ID'], 'akismet_rechecking', true );
392
-
393
- $response = Akismet::http_post( Akismet::build_query( $c ), 'comment-check' );
394
-
395
- if ( 'true' == $response[1] ) {
396
- wp_set_comment_status( $c['comment_ID'], 'spam' );
397
- update_comment_meta( $c['comment_ID'], 'akismet_result', 'true' );
398
- delete_comment_meta( $c['comment_ID'], 'akismet_error' );
399
- delete_comment_meta( $c['comment_ID'], 'akismet_delayed_moderation_email' );
400
- Akismet::update_comment_history( $c['comment_ID'], '', 'recheck-spam' );
401
  ++$result_counts['spam'];
402
- } elseif ( 'false' == $response[1] ) {
403
- update_comment_meta( $c['comment_ID'], 'akismet_result', 'false' );
404
- delete_comment_meta( $c['comment_ID'], 'akismet_error' );
405
- delete_comment_meta( $c['comment_ID'], 'akismet_delayed_moderation_email' );
406
- Akismet::update_comment_history( $c['comment_ID'], '', 'recheck-ham' );
407
  ++$result_counts['ham'];
408
- } else {
409
- // abnormal result: error
410
- update_comment_meta( $c['comment_ID'], 'akismet_result', 'error' );
411
- Akismet::update_comment_history(
412
- $c['comment_ID'],
413
- '',
414
- 'recheck-error',
415
- array( 'response' => substr( $response[1], 0, 50 ) )
416
- );
417
  ++$result_counts['error'];
418
  }
419
-
420
- delete_comment_meta( $c['comment_ID'], 'akismet_rechecking' );
421
- }
422
- if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
423
- wp_send_json( array(
424
- 'processed' => count((array) $moderation),
425
- 'counts' => $result_counts,
426
- ));
427
- }
428
- else {
429
- $redirect_to = isset( $_SERVER['HTTP_REFERER'] ) ? $_SERVER['HTTP_REFERER'] : admin_url( 'edit-comments.php' );
430
- wp_safe_redirect( $redirect_to );
431
- exit;
432
  }
 
 
433
  }
434
 
435
  // Adds an 'x' link next to author URLs, clicking will remove the author URL and show an undo link
436
  public static function remove_comment_author_url() {
437
  if ( !empty( $_POST['id'] ) && check_admin_referer( 'comment_author_url_nonce' ) ) {
438
- $comment = get_comment( intval( $_POST['id'] ), ARRAY_A );
 
439
  if ( $comment && current_user_can( 'edit_comment', $comment['comment_ID'] ) ) {
440
  $comment['comment_author_url'] = '';
441
  do_action( 'comment_remove_author_url' );
@@ -447,7 +430,8 @@ class Akismet_Admin {
447
 
448
  public static function add_comment_author_url() {
449
  if ( !empty( $_POST['id'] ) && !empty( $_POST['url'] ) && check_admin_referer( 'comment_author_url_nonce' ) ) {
450
- $comment = get_comment( intval( $_POST['id'] ), ARRAY_A );
 
451
  if ( $comment && current_user_can( 'edit_comment', $comment['comment_ID'] ) ) {
452
  $comment['comment_author_url'] = esc_url( $_POST['url'] );
453
  do_action( 'comment_add_author_url' );
@@ -689,9 +673,14 @@ class Akismet_Admin {
689
  update_option('akismet_available_servers', $servers);
690
  update_option('akismet_connectivity_time', time());
691
  }
692
-
693
- $response = wp_remote_get( 'http://rest.akismet.com/1.1/test' );
694
-
 
 
 
 
 
695
  $debug[ 'gethostbynamel' ] = function_exists('gethostbynamel') ? 'exists' : 'not here';
696
  $debug[ 'Servers' ] = $servers;
697
  $debug[ 'Test Connection' ] = $response;
@@ -731,7 +720,7 @@ class Akismet_Admin {
731
  public static function get_akismet_user( $api_key ) {
732
  $akismet_user = false;
733
 
734
- $subscription_verification = Akismet::http_post( Akismet::build_query( array( 'key' => $api_key, 'blog' => get_bloginfo( 'url' ) ) ), 'get-subscription' );
735
 
736
  if ( ! empty( $subscription_verification[1] ) ) {
737
  if ( 'invalid' !== $subscription_verification[1] ) {
@@ -746,7 +735,7 @@ class Akismet_Admin {
746
  $stat_totals = array();
747
 
748
  foreach( array( '6-months', 'all' ) as $interval ) {
749
- $response = Akismet::http_post( Akismet::build_query( array( 'blog' => get_bloginfo( 'url' ), 'key' => $api_key, 'from' => $interval ) ), 'get-stats' );
750
 
751
  if ( ! empty( $response[1] ) ) {
752
  $stat_totals[$interval] = json_decode( $response[1] );
357
 
358
  Akismet::fix_scheduled_recheck();
359
 
360
+ if ( ! ( isset( $_GET['recheckqueue'] ) || ( isset( $_REQUEST['action'] ) && 'akismet_recheck_queue' == $_REQUEST['action'] ) ) ) {
361
  return;
362
+ }
363
+
364
+ $result_counts = self::recheck_queue_portion( empty( $_POST['offset'] ) ? 0 : $_POST['offset'], empty( $_POST['limit'] ) ? 100 : $_POST['limit'] );
365
 
366
+ if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
367
+ wp_send_json( array(
368
+ 'counts' => $result_counts,
369
+ ));
370
+ }
371
+ else {
372
+ $redirect_to = isset( $_SERVER['HTTP_REFERER'] ) ? $_SERVER['HTTP_REFERER'] : admin_url( 'edit-comments.php' );
373
+ wp_safe_redirect( $redirect_to );
374
+ exit;
375
+ }
376
+ }
377
+
378
+ public static function recheck_queue_portion( $start = 0, $limit = 100 ) {
379
+ global $wpdb;
380
+
381
  $paginate = '';
382
+
383
+ if ( $limit <= 0 ) {
384
+ $limit = 100;
385
+ }
386
+
387
+ if ( $start < 0 ) {
388
+ $start = 0;
389
  }
390
+
391
+ $moderation = $wpdb->get_col( $wpdb->prepare( "SELECT * FROM {$wpdb->comments} WHERE comment_approved = '0' LIMIT %d OFFSET %d", $limit, $start ) );
392
 
393
  $result_counts = array(
394
+ 'processed' => count( $moderation ),
395
  'spam' => 0,
396
  'ham' => 0,
397
  'error' => 0,
398
  );
399
 
400
+ foreach ( $moderation as $comment_id ) {
401
+ $api_response = Akismet::recheck_comment( $comment_id, 'recheck_queue' );
 
 
 
 
 
 
 
 
 
 
402
 
403
+ if ( 'true' === $api_response ) {
 
 
 
 
 
 
 
 
 
 
 
 
404
  ++$result_counts['spam'];
405
+ }
406
+ elseif ( 'false' === $api_response ) {
 
 
 
407
  ++$result_counts['ham'];
408
+ }
409
+ else {
 
 
 
 
 
 
 
410
  ++$result_counts['error'];
411
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
412
  }
413
+
414
+ return $result_counts;
415
  }
416
 
417
  // Adds an 'x' link next to author URLs, clicking will remove the author URL and show an undo link
418
  public static function remove_comment_author_url() {
419
  if ( !empty( $_POST['id'] ) && check_admin_referer( 'comment_author_url_nonce' ) ) {
420
+ $comment_id = intval( $_POST['id'] );
421
+ $comment = get_comment( $comment_id, ARRAY_A );
422
  if ( $comment && current_user_can( 'edit_comment', $comment['comment_ID'] ) ) {
423
  $comment['comment_author_url'] = '';
424
  do_action( 'comment_remove_author_url' );
430
 
431
  public static function add_comment_author_url() {
432
  if ( !empty( $_POST['id'] ) && !empty( $_POST['url'] ) && check_admin_referer( 'comment_author_url_nonce' ) ) {
433
+ $comment_id = intval( $_POST['id'] );
434
+ $comment = get_comment( $comment_id, ARRAY_A );
435
  if ( $comment && current_user_can( 'edit_comment', $comment['comment_ID'] ) ) {
436
  $comment['comment_author_url'] = esc_url( $_POST['url'] );
437
  do_action( 'comment_add_author_url' );
673
  update_option('akismet_available_servers', $servers);
674
  update_option('akismet_connectivity_time', time());
675
  }
676
+
677
+ if ( function_exists( 'wp_http_supports' ) && ( wp_http_supports( array( 'ssl' ) ) ) ) {
678
+ $response = wp_remote_get( 'https://rest.akismet.com/1.1/test' );
679
+ }
680
+ else {
681
+ $response = wp_remote_get( 'http://rest.akismet.com/1.1/test' );
682
+ }
683
+
684
  $debug[ 'gethostbynamel' ] = function_exists('gethostbynamel') ? 'exists' : 'not here';
685
  $debug[ 'Servers' ] = $servers;
686
  $debug[ 'Test Connection' ] = $response;
720
  public static function get_akismet_user( $api_key ) {
721
  $akismet_user = false;
722
 
723
+ $subscription_verification = Akismet::http_post( Akismet::build_query( array( 'key' => $api_key, 'blog' => get_option( 'home' ) ) ), 'get-subscription' );
724
 
725
  if ( ! empty( $subscription_verification[1] ) ) {
726
  if ( 'invalid' !== $subscription_verification[1] ) {
735
  $stat_totals = array();
736
 
737
  foreach( array( '6-months', 'all' ) as $interval ) {
738
+ $response = Akismet::http_post( Akismet::build_query( array( 'blog' => get_option( 'home' ), 'key' => $api_key, 'from' => $interval ) ), 'get-stats' );
739
 
740
  if ( ! empty( $response[1] ) ) {
741
  $stat_totals[$interval] = json_decode( $response[1] );
class.akismet-cli.php ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ WP_CLI::add_command( 'akismet', 'Akismet_CLI' );
4
+
5
+ /**
6
+ * Filter spam comments.
7
+ */
8
+ class Akismet_CLI extends WP_CLI_Command {
9
+ /**
10
+ * Checks one or more comments against the Akismet API.
11
+ *
12
+ * ## OPTIONS
13
+ * <comment_id>...
14
+ * : The ID(s) of the comment(s) to check.
15
+ *
16
+ * [--noaction]
17
+ * : Don't change the status of the comment. Just report what Akismet thinks it is.
18
+ *
19
+ * ## EXAMPLES
20
+ *
21
+ * wp akismet check 12345
22
+ *
23
+ * @alias comment-check
24
+ */
25
+ public function check( $args, $assoc_args ) {
26
+ foreach ( $args as $comment_id ) {
27
+ if ( isset( $assoc_args['noaction'] ) ) {
28
+ // Check the comment, but don't reclassify it.
29
+ $api_response = Akismet::check_db_comment( $comment_id, 'wp-cli' );
30
+ }
31
+ else {
32
+ $api_response = Akismet::recheck_comment( $comment_id, 'wp-cli' );
33
+ }
34
+
35
+ if ( 'true' === $api_response ) {
36
+ WP_CLI::line( sprintf( __( "Comment #%d is spam.", 'akismet' ), $comment_id ) );
37
+ }
38
+ else if ( 'false' === $api_response ) {
39
+ WP_CLI::line( sprintf( __( "Comment #%d is not spam.", 'akismet' ), $comment_id ) );
40
+ }
41
+ else {
42
+ if ( false === $api_response ) {
43
+ WP_CLI::error( __( "Failed to connect to Akismet.", 'akismet' ) );
44
+ }
45
+ else if ( is_wp_error( $api_response ) ) {
46
+ WP_CLI::warning( sprintf( __( "Comment #%d could not be checked.", 'akismet' ), $comment_id ) );
47
+ }
48
+ }
49
+ }
50
+ }
51
+
52
+ /**
53
+ * Recheck all comments in the Pending queue.
54
+ *
55
+ * ## EXAMPLES
56
+ *
57
+ * wp akismet recheck_queue
58
+ *
59
+ * @alias recheck-queue
60
+ */
61
+ public function recheck_queue() {
62
+ $batch_size = 100;
63
+ $start = 0;
64
+
65
+ $total_counts = array();
66
+
67
+ do {
68
+ $result_counts = Akismet_Admin::recheck_queue_portion( $start, $batch_size );
69
+
70
+ if ( $result_counts['processed'] > 0 ) {
71
+ foreach ( $result_counts as $key => $count ) {
72
+ if ( ! isset( $total_counts[ $key ] ) ) {
73
+ $total_counts[ $key ] = $count;
74
+ }
75
+ else {
76
+ $total_counts[ $key ] += $count;
77
+ }
78
+ }
79
+ $start += $batch_size;
80
+ $start -= $result_counts['spam']; // These comments will have been removed from the queue.
81
+ }
82
+ } while ( $result_counts['processed'] > 0 );
83
+
84
+ WP_CLI::line( sprintf( _n( "Processed %d comment.", "Processed %d comments.", $total_counts['processed'], 'akismet' ), number_format( $total_counts['processed'] ) ) );
85
+ WP_CLI::line( sprintf( _n( "%d comment moved to Spam.", "%d comments moved to Spam.", $total_counts['spam'], 'akismet' ), number_format( $total_counts['spam'] ) ) );
86
+
87
+ if ( $total_counts['error'] ) {
88
+ WP_CLI::line( sprintf( _n( "%d comment could not be checked.", "%d comments could not be checked.", $total_counts['error'], 'akismet' ), number_format( $total_counts['error'] ) ) );
89
+ }
90
+ }
91
+ }
class.akismet-widget.php CHANGED
@@ -66,7 +66,7 @@ class Akismet_Widget extends WP_Widget {
66
  $title = $instance['title'];
67
  }
68
  else {
69
- $title = __( 'Spam Blocked' , 'akismet');
70
  }
71
  ?>
72
 
@@ -86,6 +86,10 @@ class Akismet_Widget extends WP_Widget {
86
  function widget( $args, $instance ) {
87
  $count = get_option( 'akismet_spam_count' );
88
 
 
 
 
 
89
  echo $args['before_widget'];
90
  if ( ! empty( $instance['title'] ) ) {
91
  echo $args['before_title'];
66
  $title = $instance['title'];
67
  }
68
  else {
69
+ $title = __( 'Spam Blocked' , 'akismet' );
70
  }
71
  ?>
72
 
86
  function widget( $args, $instance ) {
87
  $count = get_option( 'akismet_spam_count' );
88
 
89
+ if ( ! isset( $instance['title'] ) ) {
90
+ $instance['title'] = __( 'Spam Blocked' , 'akismet' );
91
+ }
92
+
93
  echo $args['before_widget'];
94
  if ( ! empty( $instance['title'] ) ) {
95
  echo $args['before_title'];
class.akismet.php CHANGED
@@ -64,7 +64,7 @@ class Akismet {
64
  }
65
 
66
  public static function check_key_status( $key, $ip = null ) {
67
- return self::http_post( Akismet::build_query( array( 'key' => $key, 'blog' => get_option('home') ) ), 'verify-key', $ip );
68
  }
69
 
70
  public static function verify_key( $key, $ip = null ) {
@@ -77,7 +77,7 @@ class Akismet {
77
  }
78
 
79
  public static function deactivate_key( $key ) {
80
- $response = self::http_post( Akismet::build_query( array( 'key' => $key, 'blog' => get_option('home') ) ), 'deactivate' );
81
 
82
  if ( $response[1] != 'deactivated' )
83
  return 'failed';
@@ -124,7 +124,7 @@ class Akismet {
124
  $comment['user_ip'] = self::get_ip_address();
125
  $comment['user_agent'] = self::get_user_agent();
126
  $comment['referrer'] = self::get_referer();
127
- $comment['blog'] = get_option('home');
128
  $comment['blog_lang'] = get_locale();
129
  $comment['blog_charset'] = get_option('blog_charset');
130
  $comment['permalink'] = get_permalink( $comment['comment_post_ID'] );
@@ -347,10 +347,11 @@ class Akismet {
347
  do_action( 'delete_comment', $comment_id );
348
  }
349
 
350
- $comma_comment_ids = implode( ', ', array_map('intval', $comment_ids) );
 
351
 
352
- $wpdb->query("DELETE FROM {$wpdb->comments} WHERE comment_id IN ( $comma_comment_ids )");
353
- $wpdb->query("DELETE FROM {$wpdb->commentmeta} WHERE comment_id IN ( $comma_comment_ids )");
354
 
355
  clean_comment_cache( $comment_ids );
356
  }
@@ -449,27 +450,72 @@ class Akismet {
449
  global $wpdb;
450
 
451
  $c = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->comments} WHERE comment_ID = %d", $id ), ARRAY_A );
452
- if ( !$c )
453
- return;
 
 
454
 
455
  $c['user_ip'] = $c['comment_author_IP'];
456
  $c['user_agent'] = $c['comment_agent'];
457
  $c['referrer'] = '';
458
- $c['blog'] = get_option('home');
459
  $c['blog_lang'] = get_locale();
460
  $c['blog_charset'] = get_option('blog_charset');
461
  $c['permalink'] = get_permalink($c['comment_post_ID']);
462
  $c['recheck_reason'] = $recheck_reason;
463
 
 
 
 
 
464
  if ( self::is_test_mode() )
465
  $c['is_test'] = 'true';
466
 
467
  $response = self::http_post( Akismet::build_query( $c ), 'comment-check' );
468
 
469
- return ( is_array( $response ) && ! empty( $response[1] ) ) ? $response[1] : false;
 
 
 
 
470
  }
471
 
472
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
473
 
474
  public static function transition_comment_status( $new_status, $old_status, $comment ) {
475
 
@@ -538,7 +584,7 @@ class Akismet {
538
  if ( $as_submitted && is_array( $as_submitted ) && isset( $as_submitted['comment_content'] ) )
539
  $comment = (object) array_merge( (array)$comment, $as_submitted );
540
 
541
- $comment->blog = get_bloginfo('url');
542
  $comment->blog_lang = get_locale();
543
  $comment->blog_charset = get_option('blog_charset');
544
  $comment->permalink = get_permalink($comment->comment_post_ID);
@@ -584,7 +630,7 @@ class Akismet {
584
  if ( $as_submitted && is_array($as_submitted) && isset($as_submitted['comment_content']) )
585
  $comment = (object) array_merge( (array)$comment, $as_submitted );
586
 
587
- $comment->blog = get_bloginfo('url');
588
  $comment->blog_lang = get_locale();
589
  $comment->blog_charset = get_option('blog_charset');
590
  $comment->permalink = get_permalink( $comment->comment_post_ID );
64
  }
65
 
66
  public static function check_key_status( $key, $ip = null ) {
67
+ return self::http_post( Akismet::build_query( array( 'key' => $key, 'blog' => get_option( 'home' ) ) ), 'verify-key', $ip );
68
  }
69
 
70
  public static function verify_key( $key, $ip = null ) {
77
  }
78
 
79
  public static function deactivate_key( $key ) {
80
+ $response = self::http_post( Akismet::build_query( array( 'key' => $key, 'blog' => get_option( 'home' ) ) ), 'deactivate' );
81
 
82
  if ( $response[1] != 'deactivated' )
83
  return 'failed';
124
  $comment['user_ip'] = self::get_ip_address();
125
  $comment['user_agent'] = self::get_user_agent();
126
  $comment['referrer'] = self::get_referer();
127
+ $comment['blog'] = get_option( 'home' );
128
  $comment['blog_lang'] = get_locale();
129
  $comment['blog_charset'] = get_option('blog_charset');
130
  $comment['permalink'] = get_permalink( $comment['comment_post_ID'] );
347
  do_action( 'delete_comment', $comment_id );
348
  }
349
 
350
+ // Prepared as strings since comment_id is an unsigned BIGINT, and using %d will constrain the value to the maximum signed BIGINT.
351
+ $format_string = implode( ", ", array_fill( 0, count( $comment_ids ), '%s' ) );
352
 
353
+ $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->comments} WHERE comment_id IN ( " . $format_string . " )", $comment_ids ) );
354
+ $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->commentmeta} WHERE comment_id IN ( " . $format_string . " )", $comment_ids ) );
355
 
356
  clean_comment_cache( $comment_ids );
357
  }
450
  global $wpdb;
451
 
452
  $c = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->comments} WHERE comment_ID = %d", $id ), ARRAY_A );
453
+
454
+ if ( ! $c ) {
455
+ return new WP_Error( 'invalid-comment-id', __( 'Comment not found.', 'akismet' ) );
456
+ }
457
 
458
  $c['user_ip'] = $c['comment_author_IP'];
459
  $c['user_agent'] = $c['comment_agent'];
460
  $c['referrer'] = '';
461
+ $c['blog'] = get_option( 'home' );
462
  $c['blog_lang'] = get_locale();
463
  $c['blog_charset'] = get_option('blog_charset');
464
  $c['permalink'] = get_permalink($c['comment_post_ID']);
465
  $c['recheck_reason'] = $recheck_reason;
466
 
467
+ $c['user_role'] = '';
468
+ if ( isset( $c['user_ID'] ) )
469
+ $c['user_role'] = Akismet::get_user_roles($c['user_ID']);
470
+
471
  if ( self::is_test_mode() )
472
  $c['is_test'] = 'true';
473
 
474
  $response = self::http_post( Akismet::build_query( $c ), 'comment-check' );
475
 
476
+ if ( ! empty( $response[1] ) ) {
477
+ return $response[1];
478
+ }
479
+
480
+ return false;
481
  }
482
 
483
+ public static function recheck_comment( $id, $recheck_reason = 'recheck_queue' ) {
484
+ add_comment_meta( $id, 'akismet_rechecking', true );
485
+
486
+ $api_response = self::check_db_comment( $id, $recheck_reason );
487
+
488
+ delete_comment_meta( $id, 'akismet_rechecking' );
489
+
490
+ if ( is_wp_error( $api_response ) ) {
491
+ // Invalid comment ID.
492
+ }
493
+ else if ( 'true' === $api_response ) {
494
+ wp_set_comment_status( $id, 'spam' );
495
+ update_comment_meta( $id, 'akismet_result', 'true' );
496
+ delete_comment_meta( $id, 'akismet_error' );
497
+ delete_comment_meta( $id, 'akismet_delayed_moderation_email' );
498
+ Akismet::update_comment_history( $id, '', 'recheck-spam' );
499
+ }
500
+ elseif ( 'false' === $api_response ) {
501
+ update_comment_meta( $id, 'akismet_result', 'false' );
502
+ delete_comment_meta( $id, 'akismet_error' );
503
+ delete_comment_meta( $id, 'akismet_delayed_moderation_email' );
504
+ Akismet::update_comment_history( $id, '', 'recheck-ham' );
505
+ }
506
+ else {
507
+ // abnormal result: error
508
+ update_comment_meta( $id, 'akismet_result', 'error' );
509
+ Akismet::update_comment_history(
510
+ $id,
511
+ '',
512
+ 'recheck-error',
513
+ array( 'response' => substr( $api_response, 0, 50 ) )
514
+ );
515
+ }
516
+
517
+ return $api_response;
518
+ }
519
 
520
  public static function transition_comment_status( $new_status, $old_status, $comment ) {
521
 
584
  if ( $as_submitted && is_array( $as_submitted ) && isset( $as_submitted['comment_content'] ) )
585
  $comment = (object) array_merge( (array)$comment, $as_submitted );
586
 
587
+ $comment->blog = get_option( 'home' );
588
  $comment->blog_lang = get_locale();
589
  $comment->blog_charset = get_option('blog_charset');
590
  $comment->permalink = get_permalink($comment->comment_post_ID);
630
  if ( $as_submitted && is_array($as_submitted) && isset($as_submitted['comment_content']) )
631
  $comment = (object) array_merge( (array)$comment, $as_submitted );
632
 
633
+ $comment->blog = get_option( 'home' );
634
  $comment->blog_lang = get_locale();
635
  $comment->blog_charset = get_option('blog_charset');
636
  $comment->permalink = get_permalink( $comment->comment_post_ID );
readme.txt CHANGED
@@ -1,9 +1,9 @@
1
  === Akismet ===
2
  Contributors: matt, ryan, andy, mdawaffe, tellyworth, josephscott, lessbloat, eoigal, cfinke, automattic, jgs
3
  Tags: akismet, comments, spam, antispam, anti-spam, anti spam, comment moderation, comment spam, contact form spam, spam comments
4
- Requires at least: 3.2
5
- Tested up to: 4.5.2
6
- Stable tag: 3.1.11
7
  License: GPLv2 or later
8
 
9
  Akismet checks your comments against the Akismet Web service to see if they look like spam or not.
@@ -30,6 +30,15 @@ Upload the Akismet plugin to your blog, Activate it, then enter your [Akismet.co
30
 
31
  == Changelog ==
32
 
 
 
 
 
 
 
 
 
 
33
  = 3.1.11 =
34
  *Release Date - 12 May 2016*
35
 
1
  === Akismet ===
2
  Contributors: matt, ryan, andy, mdawaffe, tellyworth, josephscott, lessbloat, eoigal, cfinke, automattic, jgs
3
  Tags: akismet, comments, spam, antispam, anti-spam, anti spam, comment moderation, comment spam, contact form spam, spam comments
4
+ Requires at least: 3.7
5
+ Tested up to: 4.7
6
+ Stable tag: 3.2
7
  License: GPLv2 or later
8
 
9
  Akismet checks your comments against the Akismet Web service to see if they look like spam or not.
30
 
31
  == Changelog ==
32
 
33
+ = 3.2 =
34
+ *Release Date - 6 September 2016*
35
+
36
+ * Added a WP-CLI module. You can now check comments and recheck the moderation queue from the command line.
37
+ * Stopped using the deprecated jQuery function `.live()`.
38
+ * Fixed a bug in `remove_comment_author_url()` and `add_comment_author_url()` that could generate PHP notices.
39
+ * Fixed a bug that could cause an infinite loop for sites with very very very large comment IDs.
40
+ * Fixed a bug that could cause the Akismet widget title to be blank.
41
+
42
  = 3.1.11 =
43
  *Release Date - 12 May 2016*
44
 
views/config.php CHANGED
@@ -12,7 +12,7 @@
12
  <a href="<?php echo esc_url( Akismet_Admin::get_page_url( 'stats' ) ); ?>" class=""><?php esc_html_e( 'Summaries' , 'akismet');?></a>
13
  </span>
14
 
15
- <iframe allowtransparency="true" scrolling="no" frameborder="0" style="width: 100%; height: 215px; overflow: hidden;" src="<?php printf( '//akismet.com/web/1.0/snapshot.php?blog=%s&api_key=%s&height=180&locale=%s', urlencode( get_bloginfo('url') ), Akismet::get_api_key(), get_locale() );?>"></iframe>
16
  <ul>
17
  <li>
18
  <h3><?php esc_html_e( 'Past six months' , 'akismet');?></h3>
@@ -26,7 +26,7 @@
26
  </li>
27
  <li>
28
  <h3><?php esc_html_e( 'Accuracy' , 'akismet');?></h3>
29
- <span><?php echo $stat_totals['all']->accuracy; ?>%</span>
30
  <?php printf( _n( '%s missed spam', '%s missed spam', $stat_totals['all']->missed_spam, 'akismet' ), number_format( $stat_totals['all']->missed_spam ) ); ?>
31
  |
32
  <?php printf( _n( '%s false positive', '%s false positives', $stat_totals['all']->false_positives, 'akismet' ), number_format( $stat_totals['all']->false_positives ) ); ?>
@@ -63,7 +63,7 @@
63
  <th class="akismet-api-key" width="10%" align="left" scope="row"><?php esc_html_e('API Key', 'akismet');?></th>
64
  <td width="5%"/>
65
  <td align="left">
66
- <span class="api-key"><input id="key" name="key" type="text" size="15" value="<?php echo esc_attr( get_option('wordpress_api_key') ); ?>" class="regular-text code <?php echo $akismet_user->status;?>"></span>
67
  </td>
68
  </tr>
69
  <?php endif; ?>
@@ -166,7 +166,7 @@
166
  <th scope="row" align="left"><?php esc_html_e( 'Subscription Type' , 'akismet');?></th>
167
  <td width="5%"/>
168
  <td align="left">
169
- <span><?php echo $akismet_user->account_name; ?></span>
170
  </td>
171
  </tr>
172
  <tr>
12
  <a href="<?php echo esc_url( Akismet_Admin::get_page_url( 'stats' ) ); ?>" class=""><?php esc_html_e( 'Summaries' , 'akismet');?></a>
13
  </span>
14
 
15
+ <iframe allowtransparency="true" scrolling="no" frameborder="0" style="width: 100%; height: 215px; overflow: hidden;" src="<?php printf( '//akismet.com/web/1.0/snapshot.php?blog=%s&api_key=%s&height=180&locale=%s', urlencode( get_option( 'home' ) ), Akismet::get_api_key(), get_locale() );?>"></iframe>
16
  <ul>
17
  <li>
18
  <h3><?php esc_html_e( 'Past six months' , 'akismet');?></h3>
26
  </li>
27
  <li>
28
  <h3><?php esc_html_e( 'Accuracy' , 'akismet');?></h3>
29
+ <span><?php echo floatval( $stat_totals['all']->accuracy ); ?>%</span>
30
  <?php printf( _n( '%s missed spam', '%s missed spam', $stat_totals['all']->missed_spam, 'akismet' ), number_format( $stat_totals['all']->missed_spam ) ); ?>
31
  |
32
  <?php printf( _n( '%s false positive', '%s false positives', $stat_totals['all']->false_positives, 'akismet' ), number_format( $stat_totals['all']->false_positives ) ); ?>
63
  <th class="akismet-api-key" width="10%" align="left" scope="row"><?php esc_html_e('API Key', 'akismet');?></th>
64
  <td width="5%"/>
65
  <td align="left">
66
+ <span class="api-key"><input id="key" name="key" type="text" size="15" value="<?php echo esc_attr( get_option('wordpress_api_key') ); ?>" class="<?php echo esc_attr( 'regular-text code ' . $akismet_user->status ); ?>"></span>
67
  </td>
68
  </tr>
69
  <?php endif; ?>
166
  <th scope="row" align="left"><?php esc_html_e( 'Subscription Type' , 'akismet');?></th>
167
  <td width="5%"/>
168
  <td align="left">
169
+ <span><?php echo esc_html( $akismet_user->account_name ); ?></span>
170
  </td>
171
  </tr>
172
  <tr>
views/get.php CHANGED
@@ -1,6 +1,6 @@
1
  <form name="akismet_activate" action="https://akismet.com/get/" method="POST" target="_blank">
2
  <input type="hidden" name="passback_url" value="<?php echo esc_url( Akismet_Admin::get_page_url() ); ?>"/>
3
- <input type="hidden" name="blog" value="<?php echo esc_url( get_bloginfo('url') ); ?>"/>
4
  <input type="hidden" name="redirect" value="<?php echo isset( $redirect ) ? $redirect : 'plugin-signup'; ?>"/>
5
  <input type="submit" class="<?php echo isset( $classes ) && count( $classes ) > 0 ? implode( ' ', $classes ) : 'button button-primary';?>" value="<?php echo esc_attr( $text ); ?>"/>
6
  </form>
1
  <form name="akismet_activate" action="https://akismet.com/get/" method="POST" target="_blank">
2
  <input type="hidden" name="passback_url" value="<?php echo esc_url( Akismet_Admin::get_page_url() ); ?>"/>
3
+ <input type="hidden" name="blog" value="<?php echo esc_url( get_option( 'home' ) ); ?>"/>
4
  <input type="hidden" name="redirect" value="<?php echo isset( $redirect ) ? $redirect : 'plugin-signup'; ?>"/>
5
  <input type="submit" class="<?php echo isset( $classes ) && count( $classes ) > 0 ? implode( ' ', $classes ) : 'button button-primary';?>" value="<?php echo esc_attr( $text ); ?>"/>
6
  </form>
views/start.php CHANGED
@@ -9,8 +9,8 @@
9
  </div>
10
  <form name="akismet_activate" id="akismet_activate" action="https://akismet.com/get/" method="post" class="right" target="_blank">
11
  <input type="hidden" name="passback_url" value="<?php echo esc_url( Akismet_Admin::get_page_url() ); ?>"/>
12
- <input type="hidden" name="blog" value="<?php echo esc_url( get_bloginfo('url') ); ?>"/>
13
- <input type="hidden" name="auto-connect" value="<?php echo $akismet_user->ID;?>"/>
14
  <input type="hidden" name="redirect" value="plugin-signup"/>
15
  <input type="submit" class="button button-primary" value="<?php esc_attr_e( 'Register for Akismet' , 'akismet'); ?>"/>
16
  </form>
@@ -20,12 +20,12 @@
20
  <div class="activate-highlight activate-option">
21
  <div class="option-description" style="width:75%;">
22
  <strong class="small-heading"><?php esc_html_e('Connected via Jetpack', 'akismet'); ?></strong>
23
- <?php printf( esc_html__( 'Your subscription for %s is cancelled' , 'akismet'), $akismet_user->user_email ); ?>
24
  </div>
25
  <form name="akismet_activate" id="akismet_activate" action="https://akismet.com/get/" method="post" class="right" target="_blank">
26
  <input type="hidden" name="passback_url" value="<?php echo esc_url( Akismet_Admin::get_page_url() ); ?>"/>
27
- <input type="hidden" name="blog" value="<?php echo esc_url( get_bloginfo('url') ); ?>"/>
28
- <input type="hidden" name="user_id" value="<?php echo $akismet_user->ID;?>"/>
29
  <input type="hidden" name="redirect" value="upgrade"/>
30
  <input type="submit" class="button button-primary" value="<?php esc_attr_e( 'Reactivate Akismet' , 'akismet'); ?>"/>
31
  </form>
@@ -34,7 +34,7 @@
34
  <p><?php esc_html_e('Akismet eliminates spam from your site.', 'akismet'); ?></p>
35
  <div class="activate-highlight centered activate-option">
36
  <strong class="small-heading"><?php esc_html_e( 'Connected via Jetpack' , 'akismet'); ?></strong>
37
- <h3 class="alert-text"><?php printf( esc_html__( 'Your subscription for %s is suspended' , 'akismet'), $akismet_user->user_email ); ?></h3>
38
  <p><?php esc_html_e('No worries! Get in touch and we&#8217;ll sort this out.', 'akismet'); ?></p>
39
  <a href="https://akismet.com/contact" class="button button-primary"><?php esc_html_e( 'Contact Akismet support' , 'akismet'); ?></a>
40
  </div>
9
  </div>
10
  <form name="akismet_activate" id="akismet_activate" action="https://akismet.com/get/" method="post" class="right" target="_blank">
11
  <input type="hidden" name="passback_url" value="<?php echo esc_url( Akismet_Admin::get_page_url() ); ?>"/>
12
+ <input type="hidden" name="blog" value="<?php echo esc_url( get_option( 'home' ) ); ?>"/>
13
+ <input type="hidden" name="auto-connect" value="<?php echo esc_attr( $akismet_user->ID ); ?>"/>
14
  <input type="hidden" name="redirect" value="plugin-signup"/>
15
  <input type="submit" class="button button-primary" value="<?php esc_attr_e( 'Register for Akismet' , 'akismet'); ?>"/>
16
  </form>
20
  <div class="activate-highlight activate-option">
21
  <div class="option-description" style="width:75%;">
22
  <strong class="small-heading"><?php esc_html_e('Connected via Jetpack', 'akismet'); ?></strong>
23
+ <?php echo esc_html( sprintf( __( 'Your subscription for %s is cancelled' , 'akismet'), $akismet_user->user_email ) ); ?>
24
  </div>
25
  <form name="akismet_activate" id="akismet_activate" action="https://akismet.com/get/" method="post" class="right" target="_blank">
26
  <input type="hidden" name="passback_url" value="<?php echo esc_url( Akismet_Admin::get_page_url() ); ?>"/>
27
+ <input type="hidden" name="blog" value="<?php echo esc_url( get_option( 'home' ) ); ?>"/>
28
+ <input type="hidden" name="user_id" value="<?php echo esc_attr( $akismet_user->ID ); ?>"/>
29
  <input type="hidden" name="redirect" value="upgrade"/>
30
  <input type="submit" class="button button-primary" value="<?php esc_attr_e( 'Reactivate Akismet' , 'akismet'); ?>"/>
31
  </form>
34
  <p><?php esc_html_e('Akismet eliminates spam from your site.', 'akismet'); ?></p>
35
  <div class="activate-highlight centered activate-option">
36
  <strong class="small-heading"><?php esc_html_e( 'Connected via Jetpack' , 'akismet'); ?></strong>
37
+ <h3 class="alert-text"><?php echo esc_html( sprintf( __( 'Your subscription for %s is suspended' , 'akismet'), $akismet_user->user_email ) ); ?></h3>
38
  <p><?php esc_html_e('No worries! Get in touch and we&#8217;ll sort this out.', 'akismet'); ?></p>
39
  <a href="https://akismet.com/contact" class="button button-primary"><?php esc_html_e( 'Contact Akismet support' , 'akismet'); ?></a>
40
  </div>
views/stats.php CHANGED
@@ -1,4 +1,4 @@
1
  <div class="wrap">
2
  <h2><?php esc_html_e( 'Akismet Stats' , 'akismet');?><?php if ( !isset( $hide_settings_link ) ): ?> <a href="<?php echo esc_url( Akismet_Admin::get_page_url() );?>" class="add-new-h2"><?php esc_html_e( 'Settings' , 'akismet');?></a><?php endif;?></h2>
3
- <iframe src="<?php echo esc_url( sprintf( '//akismet.com/web/1.0/user-stats.php?blog=%s&api_key=%s&locale=%s', urlencode( get_bloginfo('url') ), Akismet::get_api_key(), get_locale() ) ); ?>" width="100%" height="2500px" frameborder="0" id="akismet-stats-frame"></iframe>
4
  </div>
1
  <div class="wrap">
2
  <h2><?php esc_html_e( 'Akismet Stats' , 'akismet');?><?php if ( !isset( $hide_settings_link ) ): ?> <a href="<?php echo esc_url( Akismet_Admin::get_page_url() );?>" class="add-new-h2"><?php esc_html_e( 'Settings' , 'akismet');?></a><?php endif;?></h2>
3
+ <iframe src="<?php echo esc_url( sprintf( '//akismet.com/web/1.0/user-stats.php?blog=%s&api_key=%s&locale=%s', urlencode( get_option( 'home' ) ), Akismet::get_api_key(), get_locale() ) ); ?>" width="100%" height="2500px" frameborder="0" id="akismet-stats-frame"></iframe>
4
  </div>