From 056e9aabd5b356b57e66575340e47acf5901b65b Mon Sep 17 00:00:00 2001 From: "Anthony G. Basile" Date: Mon, 20 Nov 2017 16:49:07 -0500 Subject: Update akismet 4.0.1 Signed-off-by: Anthony G. Basile --- plugins/akismet/akismet.php | 4 +- plugins/akismet/class.akismet-admin.php | 24 +++++++++--- plugins/akismet/class.akismet.php | 66 ++++++++++++++++++++++++++------- plugins/akismet/readme.txt | 15 ++++++-- 4 files changed, 85 insertions(+), 24 deletions(-) diff --git a/plugins/akismet/akismet.php b/plugins/akismet/akismet.php index 56babcba..c29057e2 100644 --- a/plugins/akismet/akismet.php +++ b/plugins/akismet/akismet.php @@ -6,7 +6,7 @@ Plugin Name: Akismet Anti-Spam Plugin URI: https://akismet.com/ Description: Used by millions, Akismet is quite possibly the best way in the world to protect your blog from spam. It keeps your site protected even while you sleep. To get started: activate the Akismet plugin and then go to your Akismet Settings page to set up your API key. -Version: 4.0 +Version: 4.0.1 Author: Automattic Author URI: https://automattic.com/wordpress-plugins/ License: GPLv2 or later @@ -37,7 +37,7 @@ if ( !function_exists( 'add_action' ) ) { exit; } -define( 'AKISMET_VERSION', '4.0' ); +define( 'AKISMET_VERSION', '4.0.1' ); define( 'AKISMET__MINIMUM_WP_VERSION', '4.0' ); define( 'AKISMET__PLUGIN_DIR', plugin_dir_path( __FILE__ ) ); define( 'AKISMET_DELETE_LIMIT', 100000 ); diff --git a/plugins/akismet/class.akismet-admin.php b/plugins/akismet/class.akismet-admin.php index bc00260f..926b3c7a 100644 --- a/plugins/akismet/class.akismet-admin.php +++ b/plugins/akismet/class.akismet-admin.php @@ -92,10 +92,10 @@ class Akismet_Admin { public static function load_menu() { if ( class_exists( 'Jetpack' ) ) { - $hook = add_submenu_page( 'jetpack', __( 'Akismet' , 'akismet'), __( 'Akismet' , 'akismet'), 'manage_options', 'akismet-key-config', array( 'Akismet_Admin', 'display_page' ) ); + $hook = add_submenu_page( 'jetpack', __( 'Akismet Anti-Spam' , 'akismet'), __( 'Akismet Anti-Spam' , 'akismet'), 'manage_options', 'akismet-key-config', array( 'Akismet_Admin', 'display_page' ) ); } else { - $hook = add_options_page( __('Akismet', 'akismet'), __('Akismet', 'akismet'), 'manage_options', 'akismet-key-config', array( 'Akismet_Admin', 'display_page' ) ); + $hook = add_options_page( __('Akismet Anti-Spam', 'akismet'), __('Akismet Anti-Spam', 'akismet'), 'manage_options', 'akismet-key-config', array( 'Akismet_Admin', 'display_page' ) ); } if ( $hook ) { @@ -1061,8 +1061,22 @@ class Akismet_Admin { if ( !$xml->isError() ) { $responses = $xml->getResponse(); if ( count( $responses ) > 1 ) { - $api_key = array_shift( $responses[0] ); - $user_id = (int) array_shift( $responses[1] ); + // Due to a quirk in how Jetpack does multi-calls, the response order + // can't be trusted to match the call order. It's a good thing our + // return values can be mostly differentiated from each other. + $first_response_value = array_shift( $responses[0] ); + $second_response_value = array_shift( $responses[1] ); + + // If WPCOM ever reaches 100 billion users, this will fail. :-) + if ( preg_match( '/^[a-f0-9]{12}$/i', $first_response_value ) ) { + $api_key = $first_response_value; + $user_id = (int) $second_response_value; + } + else { + $api_key = $second_response_value; + $user_id = (int) $first_response_value; + } + return compact( 'api_key', 'user_id' ); } } @@ -1100,4 +1114,4 @@ class Akismet_Admin { return $all_plugins; } -} \ No newline at end of file +} diff --git a/plugins/akismet/class.akismet.php b/plugins/akismet/class.akismet.php index 02d994d1..32b23ea8 100644 --- a/plugins/akismet/class.akismet.php +++ b/plugins/akismet/class.akismet.php @@ -37,6 +37,7 @@ class Akismet { add_action( 'admin_head-edit-comments.php', array( 'Akismet', 'load_form_js' ) ); add_action( 'comment_form', array( 'Akismet', 'load_form_js' ) ); add_action( 'comment_form', array( 'Akismet', 'inject_ak_js' ) ); + add_filter( 'script_loader_tag', array( 'Akismet', 'set_form_js_async' ), 10, 3 ); add_filter( 'comment_moderation_recipients', array( 'Akismet', 'disable_moderation_emails_if_unreachable' ), 1000, 2 ); add_filter( 'pre_comment_approved', array( 'Akismet', 'last_comment_status' ), 10, 2 ); @@ -533,24 +534,36 @@ class Akismet { if ( get_comment_meta( $comment->comment_ID, 'akismet_rechecking' ) ) return; - global $current_user; - $reporter = ''; - if ( is_object( $current_user ) ) - $reporter = $current_user->user_login; - // Assumption alert: // We want to submit comments to Akismet only when a moderator explicitly spams or approves it - not if the status // is changed automatically by another plugin. Unfortunately WordPress doesn't provide an unambiguous way to // determine why the transition_comment_status action was triggered. And there are several different ways by which // to spam and unspam comments: bulk actions, ajax, links in moderation emails, the dashboard, and perhaps others. // We'll assume that this is an explicit user action if certain POST/GET variables exist. - if ( ( isset( $_POST['status'] ) && in_array( $_POST['status'], array( 'spam', 'unspam' ) ) ) || - ( isset( $_POST['spam'] ) && (int) $_POST['spam'] == 1 ) || - ( isset( $_POST['unspam'] ) && (int) $_POST['unspam'] == 1 ) || - ( isset( $_POST['comment_status'] ) && in_array( $_POST['comment_status'], array( 'spam', 'unspam' ) ) ) || - ( isset( $_GET['action'] ) && in_array( $_GET['action'], array( 'spam', 'unspam', 'spamcomment', 'unspamcomment', ) ) ) || - ( isset( $_POST['action'] ) && in_array( $_POST['action'], array( 'editedcomment' ) ) ) || - ( isset( $_GET['for'] ) && ( 'jetpack' == $_GET['for'] ) ) // Moderation via WP.com notifications/WP app/etc. + if ( + // status=spam: Marking as spam via the REST API or... + // status=unspam: I'm not sure. Maybe this used to be used instead of status=approved? Or the UI for removing from spam but not approving has been since removed?... + // status=approved: Unspamming via the REST API (Calypso) or... + ( isset( $_POST['status'] ) && in_array( $_POST['status'], array( 'spam', 'unspam', 'approved', ) ) ) + // spam=1: Clicking "Spam" underneath a comment in wp-admin and allowing the AJAX request to happen. + || ( isset( $_POST['spam'] ) && (int) $_POST['spam'] == 1 ) + // unspam=1: Clicking "Not Spam" underneath a comment in wp-admin and allowing the AJAX request to happen. Or, clicking "Undo" after marking something as spam. + || ( isset( $_POST['unspam'] ) && (int) $_POST['unspam'] == 1 ) + // comment_status=spam/unspam: It's unclear where this is happening. + || ( isset( $_POST['comment_status'] ) && in_array( $_POST['comment_status'], array( 'spam', 'unspam' ) ) ) + // action=spam: Choosing "Mark as Spam" from the Bulk Actions dropdown in wp-admin (or the "Spam it" link in notification emails). + // action=unspam: Choosing "Not Spam" from the Bulk Actions dropdown in wp-admin. + // action=spamcomment: Following the "Spam" link below a comment in wp-admin (not allowing AJAX request to happen). + // action=unspamcomment: Following the "Not Spam" link below a comment in wp-admin (not allowing AJAX request to happen). + || ( isset( $_GET['action'] ) && in_array( $_GET['action'], array( 'spam', 'unspam', 'spamcomment', 'unspamcomment', ) ) ) + // action=editedcomment: Editing a comment via wp-admin (and possibly changing its status). + || ( isset( $_POST['action'] ) && in_array( $_POST['action'], array( 'editedcomment' ) ) ) + // for=jetpack: Moderation via the WordPress app, Calypso, anything powered by the Jetpack connection. + || ( isset( $_GET['for'] ) && ( 'jetpack' == $_GET['for'] ) && ( ! defined( 'IS_WPCOM' ) || ! IS_WPCOM ) ) + // Certain WordPress.com API requests + || ( defined( 'REST_API_REQUEST' ) && REST_API_REQUEST ) + // WordPress.org REST API requests + || ( defined( 'REST_REQUEST' ) && REST_REQUEST ) ) { if ( $new_status == 'spam' && ( $old_status == 'approved' || $old_status == 'unapproved' || !$old_status ) ) { return self::submit_spam_comment( $comment->comment_ID ); @@ -1104,6 +1117,19 @@ class Akismet { wp_enqueue_script( 'akismet-form' ); } + /** + * Mark form.js as async. Because nothing depends on it, it can run at any time + * after it's loaded, and the browser won't have to wait for it to load to continue + * parsing the rest of the page. + */ + public static function set_form_js_async( $tag, $handle, $src ) { + if ( 'akismet-form' !== $handle ) { + return $tag; + } + + return preg_replace( '/^