From d70aabe9576a2aa12d55e8649f04c3a853de902a Mon Sep 17 00:00:00 2001 From: Yury German Date: Wed, 15 Jun 2022 12:23:54 -0400 Subject: update akismet 4.2.4 Signed-off-by: Yury German --- plugins/akismet/akismet.php | 6 +- plugins/akismet/class.akismet-admin.php | 184 +++++++++++++++++--------------- plugins/akismet/class.akismet.php | 80 +++++++++++--- plugins/akismet/readme.txt | 28 ++++- plugins/akismet/views/config.php | 6 +- plugins/akismet/views/connect-jp.php | 4 +- plugins/akismet/views/get.php | 6 +- plugins/akismet/views/stats.php | 2 +- 8 files changed, 203 insertions(+), 113 deletions(-) diff --git a/plugins/akismet/akismet.php b/plugins/akismet/akismet.php index 2175a913..e6b45ba7 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.2.1 +Version: 4.2.4 Author: Automattic Author URI: https://automattic.com/wordpress-plugins/ License: GPLv2 or later @@ -37,10 +37,10 @@ if ( !function_exists( 'add_action' ) ) { exit; } -define( 'AKISMET_VERSION', '4.2.1' ); +define( 'AKISMET_VERSION', '4.2.4' ); define( 'AKISMET__MINIMUM_WP_VERSION', '5.0' ); define( 'AKISMET__PLUGIN_DIR', plugin_dir_path( __FILE__ ) ); -define( 'AKISMET_DELETE_LIMIT', 100000 ); +define( 'AKISMET_DELETE_LIMIT', 10000 ); register_activation_hook( __FILE__, array( 'Akismet', 'plugin_activation' ) ); register_deactivation_hook( __FILE__, array( 'Akismet', 'plugin_deactivation' ) ); diff --git a/plugins/akismet/class.akismet-admin.php b/plugins/akismet/class.akismet-admin.php index c6cb1355..3b6badfc 100644 --- a/plugins/akismet/class.akismet-admin.php +++ b/plugins/akismet/class.akismet-admin.php @@ -434,7 +434,7 @@ class Akismet_Admin { if ( ! wp_verify_nonce( $_POST['nonce'], 'akismet_check_for_spam' ) ) { wp_send_json( array( - 'error' => __( "You don't have permission to do that."), + 'error' => __( 'You don’t have permission to do that.', 'akismet' ), )); return; } @@ -584,10 +584,8 @@ class Akismet_Admin { if ( $history ) { foreach ( $history as $row ) { - $time = date( 'D d M Y @ h:i:s a', $row['time'] ) . ' GMT'; - $message = ''; - + if ( ! empty( $row['message'] ) ) { // Old versions of Akismet stored the message as a literal string in the commentmeta. // New versions don't do that for two reasons: @@ -595,96 +593,112 @@ class Akismet_Admin { // 2) The message can be translated into the current language of the blog, not stuck // in the language of the blog when the comment was made. $message = esc_html( $row['message'] ); - } - - // If possible, use a current translation. - switch ( $row['event'] ) { - case 'recheck-spam'; - $message = esc_html( __( 'Akismet re-checked and caught this comment as spam.', 'akismet' ) ); - break; - case 'check-spam': - $message = esc_html( __( 'Akismet caught this comment as spam.', 'akismet' ) ); - break; - case 'recheck-ham': - $message = esc_html( __( 'Akismet re-checked and cleared this comment.', 'akismet' ) ); - break; - case 'check-ham': - $message = esc_html( __( 'Akismet cleared this comment.', 'akismet' ) ); - break; - case 'wp-blacklisted': - case 'wp-disallowed': - $message = sprintf( - /* translators: The placeholder is a WordPress PHP function name. */ - esc_html( __( 'Comment was caught by %s.', 'akismet' ) ), - function_exists( 'wp_check_comment_disallowed_list' ) ? 'wp_check_comment_disallowed_list' : 'wp_blacklist_check' - ); - break; - case 'report-spam': - if ( isset( $row['user'] ) ) { - $message = esc_html( sprintf( __( '%s reported this comment as spam.', 'akismet' ), $row['user'] ) ); - } - else if ( ! $message ) { - $message = esc_html( __( 'This comment was reported as spam.', 'akismet' ) ); - } - break; - case 'report-ham': - if ( isset( $row['user'] ) ) { - $message = esc_html( sprintf( __( '%s reported this comment as not spam.', 'akismet' ), $row['user'] ) ); - } - else if ( ! $message ) { - $message = esc_html( __( 'This comment was reported as not spam.', 'akismet' ) ); - } - break; - case 'cron-retry-spam': - $message = esc_html( __( 'Akismet caught this comment as spam during an automatic retry.' , 'akismet') ); - break; - case 'cron-retry-ham': - $message = esc_html( __( 'Akismet cleared this comment during an automatic retry.', 'akismet') ); - break; - case 'check-error': - if ( isset( $row['meta'], $row['meta']['response'] ) ) { - $message = sprintf( esc_html( __( 'Akismet was unable to check this comment (response: %s) but will automatically retry later.', 'akismet') ), '' . esc_html( $row['meta']['response'] ) . '' ); - } - else { - $message = esc_html( __( 'Akismet was unable to check this comment but will automatically retry later.', 'akismet' ) ); - } - break; - case 'recheck-error': - if ( isset( $row['meta'], $row['meta']['response'] ) ) { - $message = sprintf( esc_html( __( 'Akismet was unable to recheck this comment (response: %s).', 'akismet') ), '' . esc_html( $row['meta']['response'] ) . '' ); - } - else { - $message = esc_html( __( 'Akismet was unable to recheck this comment.', 'akismet' ) ); - } - break; - default: - if ( preg_match( '/^status-changed/', $row['event'] ) ) { - // Half of these used to be saved without the dash after 'status-changed'. - // See https://plugins.trac.wordpress.org/changeset/1150658/akismet/trunk - $new_status = preg_replace( '/^status-changed-?/', '', $row['event'] ); - $message = sprintf( esc_html( __( 'Comment status was changed to %s', 'akismet' ) ), '' . esc_html( $new_status ) . '' ); - } - else if ( preg_match( '/^status-/', $row['event'] ) ) { - $new_status = preg_replace( '/^status-/', '', $row['event'] ); - + } else if ( ! empty( $row['event'] ) ) { + // If possible, use a current translation. + switch ( $row['event'] ) { + case 'recheck-spam': + $message = esc_html( __( 'Akismet re-checked and caught this comment as spam.', 'akismet' ) ); + break; + case 'check-spam': + $message = esc_html( __( 'Akismet caught this comment as spam.', 'akismet' ) ); + break; + case 'recheck-ham': + $message = esc_html( __( 'Akismet re-checked and cleared this comment.', 'akismet' ) ); + break; + case 'check-ham': + $message = esc_html( __( 'Akismet cleared this comment.', 'akismet' ) ); + break; + case 'wp-blacklisted': + case 'wp-disallowed': + $message = sprintf( + /* translators: The placeholder is a WordPress PHP function name. */ + esc_html( __( 'Comment was caught by %s.', 'akismet' ) ), + function_exists( 'wp_check_comment_disallowed_list' ) ? 'wp_check_comment_disallowed_list' : 'wp_blacklist_check' + ); + break; + case 'report-spam': if ( isset( $row['user'] ) ) { - $message = sprintf( esc_html( __( '%1$s changed the comment status to %2$s.', 'akismet' ) ), $row['user'], '' . esc_html( $new_status ) . '' ); + /* translators: The placeholder is a username. */ + $message = esc_html( sprintf( __( '%s reported this comment as spam.', 'akismet' ), $row['user'] ) ); + } else if ( ! $message ) { + $message = esc_html( __( 'This comment was reported as spam.', 'akismet' ) ); } - } - break; - + break; + case 'report-ham': + if ( isset( $row['user'] ) ) { + /* translators: The placeholder is a username. */ + $message = esc_html( sprintf( __( '%s reported this comment as not spam.', 'akismet' ), $row['user'] ) ); + } else if ( ! $message ) { + $message = esc_html( __( 'This comment was reported as not spam.', 'akismet' ) ); + } + break; + case 'cron-retry-spam': + $message = esc_html( __( 'Akismet caught this comment as spam during an automatic retry.', 'akismet' ) ); + break; + case 'cron-retry-ham': + $message = esc_html( __( 'Akismet cleared this comment during an automatic retry.', 'akismet' ) ); + break; + case 'check-error': + if ( isset( $row['meta'], $row['meta']['response'] ) ) { + /* translators: The placeholder is an error response returned by the API server. */ + $message = sprintf( esc_html( __( 'Akismet was unable to check this comment (response: %s) but will automatically retry later.', 'akismet' ) ), '' . esc_html( $row['meta']['response'] ) . '' ); + } else { + $message = esc_html( __( 'Akismet was unable to check this comment but will automatically retry later.', 'akismet' ) ); + } + break; + case 'recheck-error': + if ( isset( $row['meta'], $row['meta']['response'] ) ) { + /* translators: The placeholder is an error response returned by the API server. */ + $message = sprintf( esc_html( __( 'Akismet was unable to recheck this comment (response: %s).', 'akismet' ) ), '' . esc_html( $row['meta']['response'] ) . '' ); + } else { + $message = esc_html( __( 'Akismet was unable to recheck this comment.', 'akismet' ) ); + } + break; + default: + if ( preg_match( '/^status-changed/', $row['event'] ) ) { + // Half of these used to be saved without the dash after 'status-changed'. + // See https://plugins.trac.wordpress.org/changeset/1150658/akismet/trunk + $new_status = preg_replace( '/^status-changed-?/', '', $row['event'] ); + /* translators: The placeholder is a short string (like 'spam' or 'approved') denoting the new comment status. */ + $message = sprintf( esc_html( __( 'Comment status was changed to %s', 'akismet' ) ), '' . esc_html( $new_status ) . '' ); + } else if ( preg_match( '/^status-/', $row['event'] ) ) { + $new_status = preg_replace( '/^status-/', '', $row['event'] ); + + if ( isset( $row['user'] ) ) { + /* translators: %1$s is a username; %2$s is a short string (like 'spam' or 'approved') denoting the new comment status. */ + $message = sprintf( esc_html( __( '%1$s changed the comment status to %2$s.', 'akismet' ) ), $row['user'], '' . esc_html( $new_status ) . '' ); + } + } + break; + } } if ( ! empty( $message ) ) { echo '

'; - echo '' . sprintf( esc_html__('%s ago', 'akismet'), human_time_diff( $row['time'] ) ) . ''; - echo ' - '; - echo $message; // esc_html() is done above so that we can use HTML in some messages. + + if ( isset( $row['time'] ) ) { + $time = gmdate( 'D d M Y @ h:i:s a', $row['time'] ) . ' GMT'; + + /* translators: The placeholder is an amount of time, like "7 seconds" or "3 days" returned by the function human_time_diff(). */ + $time_html = '' . sprintf( esc_html__( '%s ago', 'akismet' ), human_time_diff( $row['time'] ) ) . ''; + + echo sprintf( + /* translators: %1$s is a human-readable time difference, like "3 hours ago", and %2$s is an already-translated phrase describing how a comment's status changed, like "This comment was reported as spam." */ + esc_html( __( '%1$s - %2$s', 'akismet' ) ), + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + $time_html, + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + $message + ); // esc_html() is done above so that we can use HTML in $message. + } else { + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo $message; // esc_html() is done above so that we can use HTML in $message. + } + echo '

'; } } - } - else { + } else { echo '

'; echo esc_html( __( 'No comment history.', 'akismet' ) ); echo '

'; diff --git a/plugins/akismet/class.akismet.php b/plugins/akismet/class.akismet.php index 1681d0e1..3ca53391 100644 --- a/plugins/akismet/class.akismet.php +++ b/plugins/akismet/class.akismet.php @@ -64,6 +64,14 @@ class Akismet { add_filter( 'wpcf7_form_elements', array( 'Akismet', 'append_custom_form_fields' ) ); add_filter( 'wpcf7_akismet_parameters', array( 'Akismet', 'prepare_custom_form_values' ) ); + // Formidable Forms + add_filter( 'frm_filter_final_form', array( 'Akismet', 'inject_custom_form_fields' ) ); + add_filter( 'frm_akismet_values', array( 'Akismet', 'prepare_custom_form_values' ) ); + + // Fluent Forms + add_filter( 'fluentform_form_element_start', array( 'Akismet', 'output_custom_form_fields' ) ); + add_filter( 'fluentform_akismet_fields', array( 'Akismet', 'prepare_custom_form_values' ), 10, 2 ); + add_action( 'update_option_wordpress_api_key', array( 'Akismet', 'updated_option' ), 10, 2 ); add_action( 'add_option_wordpress_api_key', array( 'Akismet', 'added_option' ), 10, 2 ); @@ -410,8 +418,12 @@ class Akismet { $wpdb->queries = array(); + $comments = array(); + foreach ( $comment_ids as $comment_id ) { - do_action( 'delete_comment', $comment_id ); + $comments[ $comment_id ] = get_comment( $comment_id ); + + do_action( 'delete_comment', $comment_id, $comments[ $comment_id ] ); do_action( 'akismet_batch_delete_count', __FUNCTION__ ); } @@ -421,12 +433,13 @@ class Akismet { $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->comments} WHERE comment_id IN ( " . $format_string . " )", $comment_ids ) ); $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->commentmeta} WHERE comment_id IN ( " . $format_string . " )", $comment_ids ) ); - clean_comment_cache( $comment_ids ); - do_action( 'akismet_delete_comment_batch', count( $comment_ids ) ); - foreach ( $comment_ids as $comment_id ) { - do_action( 'deleted_comment', $comment_id ); + do_action( 'deleted_comment', $comment_id, $comments[ $comment_id ] ); + unset( $comments[ $comment_id ] ); } + + clean_comment_cache( $comment_ids ); + do_action( 'akismet_delete_comment_batch', count( $comment_ids ) ); } if ( apply_filters( 'akismet_optimize_table', ( mt_rand(1, 5000) == 11), $wpdb->comments ) ) // lucky number @@ -504,11 +517,38 @@ class Akismet { public static function get_user_comments_approved( $user_id, $comment_author_email, $comment_author, $comment_author_url ) { global $wpdb; - if ( !empty( $user_id ) ) - return (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->comments} WHERE user_id = %d AND comment_approved = 1", $user_id ) ); + /** + * Which comment types should be ignored when counting a user's approved comments? + * + * Some plugins add entries to the comments table that are not actual + * comments that could have been checked by Akismet. Allow these comments + * to be excluded from the "approved comment count" query in order to + * avoid artificially inflating the approved comment count. + * + * @param array $comment_types An array of comment types that won't be considered + * when counting a user's approved comments. + * + * @since 4.2.2 + */ + $excluded_comment_types = apply_filters( 'akismet_excluded_comment_types', array() ); + + $comment_type_where = ''; - if ( !empty( $comment_author_email ) ) - return (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->comments} WHERE comment_author_email = %s AND comment_author = %s AND comment_author_url = %s AND comment_approved = 1", $comment_author_email, $comment_author, $comment_author_url ) ); + if ( is_array( $excluded_comment_types ) && ! empty( $excluded_comment_types ) ) { + $excluded_comment_types = array_unique( $excluded_comment_types ); + + foreach ( $excluded_comment_types as $excluded_comment_type ) { + $comment_type_where .= $wpdb->prepare( ' AND comment_type <> %s ', $excluded_comment_type ); + } + } + + if ( ! empty( $user_id ) ) { + return (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->comments} WHERE user_id = %d AND comment_approved = 1" . $comment_type_where, $user_id ) ); + } + + if ( ! empty( $comment_author_email ) ) { + return (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->comments} WHERE comment_author_email = %s AND comment_author = %s AND comment_author_url = %s AND comment_approved = 1" . $comment_type_where, $comment_author_email, $comment_author, $comment_author_url ) ); + } return 0; } @@ -1327,8 +1367,14 @@ class Akismet { $fields .= ''; if ( ! function_exists( 'amp_is_request' ) || ! amp_is_request() ) { - $fields .= ''; - $fields .= ''; + // Keep track of how many ak_js fields are in this page so that we don't re-use + // the same ID. + static $field_count = 0; + + $field_count++; + + $fields .= ''; + $fields .= ''; } $fields .= '

'; @@ -1357,9 +1403,16 @@ class Akismet { * Ensure that any Akismet-added form fields are included in the comment-check call. * * @param array $form + * @param array $data Some plugins will supply the POST data via the filter, since they don't + * read it directly from $_POST. * @return array $form */ - public static function prepare_custom_form_values( $form ) { + public static function prepare_custom_form_values( $form, $data = null ) { + if ( is_null( $data ) ) { + // phpcs:ignore WordPress.Security.NonceVerification.Missing + $data = $_POST; + } + $prefix = 'ak_'; // Contact Form 7 uses _wpcf7 as a prefix to know which fields to exclude from comment_content. @@ -1367,8 +1420,7 @@ class Akismet { $prefix = '_wpcf7_ak_'; } - // phpcs:ignore WordPress.Security.NonceVerification.Missing - foreach ( $_POST as $key => $val ) { + foreach ( $data as $key => $val ) { if ( 0 === strpos( $key, $prefix ) ) { $form[ 'POST_ak_' . substr( $key, strlen( $prefix ) ) ] = $val; } diff --git a/plugins/akismet/readme.txt b/plugins/akismet/readme.txt index 0058c338..198e7933 100644 --- a/plugins/akismet/readme.txt +++ b/plugins/akismet/readme.txt @@ -2,8 +2,8 @@ Contributors: matt, ryan, andy, mdawaffe, tellyworth, josephscott, lessbloat, eoigal, cfinke, automattic, jgs, procifer, stephdau Tags: comments, spam, antispam, anti-spam, contact form, anti spam, comment moderation, comment spam, contact form spam, spam comments Requires at least: 5.0 -Tested up to: 5.8 -Stable tag: 4.2.1 +Tested up to: 6.0 +Stable tag: 4.2.4 License: GPLv2 or later The best anti-spam protection to block spam comments and spam in a contact form. The most trusted antispam solution for WordPress and WooCommerce. @@ -30,6 +30,28 @@ Upload the Akismet plugin to your blog, activate it, and then enter your Akismet == Changelog == += 4.2.4 = +*Release Date - 20 May 2022* + +* Improved translator instructions for comment history. +* Bumped the "Tested up to" tag to WP 6.0. + += 4.2.3 = +*Release Date - 25 April 2022* + +* Improved compatibility with Fluent Forms +* Fixed missing translation domains +* Updated stats URL. +* Improved accessibility of elements on the config page. + += 4.2.2 = +*Release Date - 24 January 2022* + +* Improved compatibility with Formidable Forms +* Fixed a bug that could cause issues when multiple contact forms appear on one page. +* Updated delete_comment and deleted_comment actions to pass two arguments to match WordPress core since 4.9.0. +* Added a filter that allows comment types to be excluded when counting users' approved comments. + = 4.2.1 = *Release Date - 1 October 2021* @@ -85,6 +107,6 @@ Upload the Akismet plugin to your blog, activate it, and then enter your Akismet *Release Date - 4 June 2020* * Disable "Check for Spam" button until the page is loaded to avoid errors with clicking through to queue recheck endpoint directly. -* Add filter "akismet_enable_mshots" to allow disabling screenshot popups on the edit comments admin page. +* Added filter "akismet_enable_mshots" to allow disabling screenshot popups on the edit comments admin page. For older changelog entries, please see the [additional changelog.txt file](https://plugins.svn.wordpress.org/akismet/trunk/changelog.txt) delivered with the plugin. diff --git a/plugins/akismet/views/config.php b/plugins/akismet/views/config.php index df24b91d..0aa1ac93 100644 --- a/plugins/akismet/views/config.php +++ b/plugins/akismet/views/config.php @@ -35,7 +35,7 @@
- +
  • @@ -73,7 +73,9 @@ - + + + diff --git a/plugins/akismet/views/connect-jp.php b/plugins/akismet/views/connect-jp.php index 5b33999a..401cc754 100644 --- a/plugins/akismet/views/connect-jp.php +++ b/plugins/akismet/views/connect-jp.php @@ -62,8 +62,8 @@
- - + +

diff --git a/plugins/akismet/views/get.php b/plugins/akismet/views/get.php index b1abe0eb..e9fa3f9a 100644 --- a/plugins/akismet/views/get.php +++ b/plugins/akismet/views/get.php @@ -2,11 +2,11 @@ //phpcs:disable VariableAnalysis // There are "undefined" variables here because they're defined in the code that includes this file as a template. - ?> +
- -
\ No newline at end of file + + diff --git a/plugins/akismet/views/stats.php b/plugins/akismet/views/stats.php index 81d82ce4..4e982a26 100644 --- a/plugins/akismet/views/stats.php +++ b/plugins/akismet/views/stats.php @@ -7,5 +7,5 @@ - + \ No newline at end of file -- cgit v1.2.3-18-g5258