Version Description
Release Date - 6 July 2021
- Simplified the code around checking comments in REST API and XML-RPC requests.
- Updated Plus plan terminology in notices to match current subscription names.
- Added
rel="noopener"to the widget link to avoid warnings in Google Lighthouse. - Set the Akismet JavaScript as deferred instead of async to improve responsiveness.
- Improved the preloading of screenshot popups on the edit comments admin page.
Download this release
Release Info
| Developer | cfinke |
| Plugin | |
| Version | 4.1.10 |
| Comparing to | |
| See all releases | |
Code changes from version 4.1.9 to 4.1.10
- _inc/akismet.js +109 -37
- akismet.php +2 -2
- class.akismet-widget.php +1 -1
- class.akismet.php +20 -24
- readme.txt +11 -2
- views/notice.php +6 -5
_inc/akismet.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
| 1 |
jQuery( function ( $ ) {
|
| 2 |
var mshotRemovalTimer = null;
|
| 3 |
-
var
|
| 4 |
-
var
|
| 5 |
-
|
| 6 |
var mshotEnabledLinkSelector = 'a[id^="author_comment_url"], tr.pingback td.column-author a:first-of-type, td.comment p a';
|
| 7 |
-
|
|
|
|
|
|
|
| 8 |
$('.akismet-status').each(function () {
|
| 9 |
var thisId = $(this).attr('commentid');
|
| 10 |
$(this).prependTo('#comment-' + thisId + ' .column-comment');
|
|
@@ -99,13 +101,25 @@ jQuery( function ( $ ) {
|
|
| 99 |
}
|
| 100 |
}
|
| 101 |
|
| 102 |
-
clearTimeout(
|
| 103 |
-
clearTimeout( mshotThirdTryTimer );
|
| 104 |
|
| 105 |
-
var
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 106 |
|
| 107 |
-
var mShot = $( '<div class="akismet-mshot mshot-container"><div class="mshot-arrow"></div><img src="' + akismet_mshot_url(
|
| 108 |
mShot.data( 'link', this );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 109 |
|
| 110 |
var offset = $( this ).offset();
|
| 111 |
|
|
@@ -114,37 +128,91 @@ jQuery( function ( $ ) {
|
|
| 114 |
top: offset.top + ( $( this ).height() / 2 ) - 101 // 101 = top offset of the arrow plus the top border thickness
|
| 115 |
} );
|
| 116 |
|
| 117 |
-
// These retries appear to be superfluous if .mshot-image has already loaded, but it's because mShots
|
| 118 |
-
// can return a "Generating thumbnail..." image if it doesn't have a thumbnail ready, so we need
|
| 119 |
-
// to retry to see if we can get the newly generated thumbnail.
|
| 120 |
-
mshotSecondTryTimer = setTimeout( function () {
|
| 121 |
-
mShot.find( '.mshot-image' ).attr( 'src', akismet_mshot_url( thisHref, 2 ) );
|
| 122 |
-
}, 6000 );
|
| 123 |
-
|
| 124 |
-
mshotThirdTryTimer = setTimeout( function () {
|
| 125 |
-
mShot.find( '.mshot-image' ).attr( 'src', akismet_mshot_url( thisHref, 3 ) );
|
| 126 |
-
}, 12000 );
|
| 127 |
-
|
| 128 |
$( 'body' ).append( mShot );
|
|
|
|
|
|
|
| 129 |
} ).on( 'mouseout', 'a[id^="author_comment_url"], tr.pingback td.column-author a:first-of-type, td.comment p a', function () {
|
| 130 |
mshotRemovalTimer = setTimeout( function () {
|
| 131 |
-
clearTimeout(
|
| 132 |
-
clearTimeout( mshotThirdTryTimer );
|
| 133 |
|
| 134 |
$( '.akismet-mshot' ).remove();
|
| 135 |
}, 200 );
|
| 136 |
-
} )
|
| 137 |
-
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
|
| 146 |
-
|
| 147 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 148 |
} );
|
| 149 |
}
|
| 150 |
|
|
@@ -273,12 +341,14 @@ jQuery( function ( $ ) {
|
|
| 273 |
* @return string The mShot URL;
|
| 274 |
*/
|
| 275 |
function akismet_mshot_url( linkUrl, retry ) {
|
| 276 |
-
var mshotUrl = '//s0.
|
| 277 |
-
|
| 278 |
-
if ( retry ) {
|
| 279 |
mshotUrl += '&r=' + encodeURIComponent( retry );
|
| 280 |
}
|
| 281 |
-
|
|
|
|
|
|
|
| 282 |
return mshotUrl;
|
| 283 |
}
|
| 284 |
|
|
@@ -290,6 +360,8 @@ jQuery( function ( $ ) {
|
|
| 290 |
function akismet_preload_mshot( linkUrl ) {
|
| 291 |
var img = new Image();
|
| 292 |
img.src = akismet_mshot_url( linkUrl );
|
|
|
|
|
|
|
| 293 |
}
|
| 294 |
|
| 295 |
$( '.akismet-could-be-primary' ).each( function () {
|
| 1 |
jQuery( function ( $ ) {
|
| 2 |
var mshotRemovalTimer = null;
|
| 3 |
+
var mshotRetryTimer = null;
|
| 4 |
+
var mshotTries = 0;
|
| 5 |
+
var mshotRetryInterval = 1000;
|
| 6 |
var mshotEnabledLinkSelector = 'a[id^="author_comment_url"], tr.pingback td.column-author a:first-of-type, td.comment p a';
|
| 7 |
+
|
| 8 |
+
var preloadedMshotURLs = [];
|
| 9 |
+
|
| 10 |
$('.akismet-status').each(function () {
|
| 11 |
var thisId = $(this).attr('commentid');
|
| 12 |
$(this).prependTo('#comment-' + thisId + ' .column-comment');
|
| 101 |
}
|
| 102 |
}
|
| 103 |
|
| 104 |
+
clearTimeout( mshotRetryTimer );
|
|
|
|
| 105 |
|
| 106 |
+
var linkUrl = $( this ).attr( 'href' );
|
| 107 |
+
|
| 108 |
+
if ( preloadedMshotURLs.indexOf( linkUrl ) !== -1 ) {
|
| 109 |
+
// This preview image was already preloaded, so begin with a retry URL so the user doesn't see the placeholder image for the first second.
|
| 110 |
+
mshotTries = 2;
|
| 111 |
+
}
|
| 112 |
+
else {
|
| 113 |
+
mshotTries = 1;
|
| 114 |
+
}
|
| 115 |
|
| 116 |
+
var mShot = $( '<div class="akismet-mshot mshot-container"><div class="mshot-arrow"></div><img src="' + akismet_mshot_url( linkUrl, mshotTries ) + '" width="450" height="338" class="mshot-image" /></div>' );
|
| 117 |
mShot.data( 'link', this );
|
| 118 |
+
mShot.data( 'url', linkUrl );
|
| 119 |
+
|
| 120 |
+
mShot.find( 'img' ).on( 'load', function () {
|
| 121 |
+
$( '.akismet-mshot' ).data( 'pending-request', false );
|
| 122 |
+
} );
|
| 123 |
|
| 124 |
var offset = $( this ).offset();
|
| 125 |
|
| 128 |
top: offset.top + ( $( this ).height() / 2 ) - 101 // 101 = top offset of the arrow plus the top border thickness
|
| 129 |
} );
|
| 130 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 131 |
$( 'body' ).append( mShot );
|
| 132 |
+
|
| 133 |
+
mshotRetryTimer = setTimeout( retryMshotUntilLoaded, mshotRetryInterval );
|
| 134 |
} ).on( 'mouseout', 'a[id^="author_comment_url"], tr.pingback td.column-author a:first-of-type, td.comment p a', function () {
|
| 135 |
mshotRemovalTimer = setTimeout( function () {
|
| 136 |
+
clearTimeout( mshotRetryTimer );
|
|
|
|
| 137 |
|
| 138 |
$( '.akismet-mshot' ).remove();
|
| 139 |
}, 200 );
|
| 140 |
+
} );
|
| 141 |
+
|
| 142 |
+
var preloadDelayTimer = null;
|
| 143 |
+
|
| 144 |
+
$( window ).on( 'scroll resize', function () {
|
| 145 |
+
clearTimeout( preloadDelayTimer );
|
| 146 |
+
|
| 147 |
+
preloadDelayTimer = setTimeout( preloadMshotsInViewport, 500 );
|
| 148 |
+
} );
|
| 149 |
+
|
| 150 |
+
preloadMshotsInViewport();
|
| 151 |
+
}
|
| 152 |
+
|
| 153 |
+
/**
|
| 154 |
+
* The way mShots works is if there was no screenshot already recently generated for the URL,
|
| 155 |
+
* it returns a "loading..." image for the first request. Then, some subsequent request will
|
| 156 |
+
* receive the actual screenshot, but it's unknown how long it will take. So, what we do here
|
| 157 |
+
* is continually re-request the mShot, waiting a second after every response until we get the
|
| 158 |
+
* actual screenshot.
|
| 159 |
+
*/
|
| 160 |
+
function retryMshotUntilLoaded() {
|
| 161 |
+
clearTimeout( mshotRetryTimer );
|
| 162 |
+
|
| 163 |
+
var imageWidth = $( '.akismet-mshot img' ).get(0).naturalWidth;
|
| 164 |
+
|
| 165 |
+
if ( imageWidth == 0 ) {
|
| 166 |
+
// It hasn't finished loading yet the first time. Check again shortly.
|
| 167 |
+
setTimeout( retryMshotUntilLoaded, mshotRetryInterval );
|
| 168 |
+
}
|
| 169 |
+
else if ( imageWidth == 400 ) {
|
| 170 |
+
// It loaded the preview image.
|
| 171 |
+
|
| 172 |
+
if ( mshotTries == 20 ) {
|
| 173 |
+
// Give up if we've requested the mShot 20 times already.
|
| 174 |
+
return;
|
| 175 |
+
}
|
| 176 |
+
|
| 177 |
+
if ( ! $( '.akismet-mshot' ).data( 'pending-request' ) ) {
|
| 178 |
+
$( '.akismet-mshot' ).data( 'pending-request', true );
|
| 179 |
+
|
| 180 |
+
mshotTries++;
|
| 181 |
+
|
| 182 |
+
$( '.akismet-mshot .mshot-image' ).attr( 'src', akismet_mshot_url( $( '.akismet-mshot' ).data( 'url' ), mshotTries ) );
|
| 183 |
+
}
|
| 184 |
+
|
| 185 |
+
mshotRetryTimer = setTimeout( retryMshotUntilLoaded, mshotRetryInterval );
|
| 186 |
+
}
|
| 187 |
+
else {
|
| 188 |
+
// All done.
|
| 189 |
+
}
|
| 190 |
+
}
|
| 191 |
+
|
| 192 |
+
function preloadMshotsInViewport() {
|
| 193 |
+
var windowWidth = $( window ).width();
|
| 194 |
+
var windowHeight = $( window ).height();
|
| 195 |
+
|
| 196 |
+
$( '#the-comment-list' ).find( mshotEnabledLinkSelector ).each( function ( index, element ) {
|
| 197 |
+
var linkUrl = $( this ).attr( 'href' );
|
| 198 |
+
|
| 199 |
+
// Don't attempt to preload an mshot for a single link twice.
|
| 200 |
+
if ( preloadedMshotURLs.indexOf( linkUrl ) !== -1 ) {
|
| 201 |
+
// The URL is already preloaded.
|
| 202 |
+
return true;
|
| 203 |
+
}
|
| 204 |
+
|
| 205 |
+
if ( typeof element.getBoundingClientRect !== 'function' ) {
|
| 206 |
+
// The browser is too old. Return false to stop this preloading entirely.
|
| 207 |
+
return false;
|
| 208 |
+
}
|
| 209 |
+
|
| 210 |
+
var rect = element.getBoundingClientRect();
|
| 211 |
+
|
| 212 |
+
if ( rect.top >= 0 && rect.left >= 0 && rect.bottom <= windowHeight && rect.right <= windowWidth ) {
|
| 213 |
+
akismet_preload_mshot( linkUrl );
|
| 214 |
+
$( this ).data( 'akismet-mshot-preloaded', true );
|
| 215 |
+
}
|
| 216 |
} );
|
| 217 |
}
|
| 218 |
|
| 341 |
* @return string The mShot URL;
|
| 342 |
*/
|
| 343 |
function akismet_mshot_url( linkUrl, retry ) {
|
| 344 |
+
var mshotUrl = '//s0.wp.com/mshots/v1/' + encodeURIComponent( linkUrl ) + '?w=900';
|
| 345 |
+
|
| 346 |
+
if ( retry > 1 ) {
|
| 347 |
mshotUrl += '&r=' + encodeURIComponent( retry );
|
| 348 |
}
|
| 349 |
+
|
| 350 |
+
mshotUrl += '&source=akismet';
|
| 351 |
+
|
| 352 |
return mshotUrl;
|
| 353 |
}
|
| 354 |
|
| 360 |
function akismet_preload_mshot( linkUrl ) {
|
| 361 |
var img = new Image();
|
| 362 |
img.src = akismet_mshot_url( linkUrl );
|
| 363 |
+
|
| 364 |
+
preloadedMshotURLs.push( linkUrl );
|
| 365 |
}
|
| 366 |
|
| 367 |
$( '.akismet-could-be-primary' ).each( function () {
|
akismet.php
CHANGED
|
@@ -6,7 +6,7 @@
|
|
| 6 |
Plugin Name: Akismet Anti-Spam
|
| 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: activate the Akismet plugin and then go to your Akismet Settings page to set up your API key.
|
| 9 |
-
Version: 4.1.
|
| 10 |
Author: Automattic
|
| 11 |
Author URI: https://automattic.com/wordpress-plugins/
|
| 12 |
License: GPLv2 or later
|
|
@@ -37,7 +37,7 @@ if ( !function_exists( 'add_action' ) ) {
|
|
| 37 |
exit;
|
| 38 |
}
|
| 39 |
|
| 40 |
-
define( 'AKISMET_VERSION', '4.1.
|
| 41 |
define( 'AKISMET__MINIMUM_WP_VERSION', '4.0' );
|
| 42 |
define( 'AKISMET__PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
|
| 43 |
define( 'AKISMET_DELETE_LIMIT', 100000 );
|
| 6 |
Plugin Name: Akismet Anti-Spam
|
| 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: activate the Akismet plugin and then go to your Akismet Settings page to set up your API key.
|
| 9 |
+
Version: 4.1.10
|
| 10 |
Author: Automattic
|
| 11 |
Author URI: https://automattic.com/wordpress-plugins/
|
| 12 |
License: GPLv2 or later
|
| 37 |
exit;
|
| 38 |
}
|
| 39 |
|
| 40 |
+
define( 'AKISMET_VERSION', '4.1.10' );
|
| 41 |
define( 'AKISMET__MINIMUM_WP_VERSION', '4.0' );
|
| 42 |
define( 'AKISMET__PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
|
| 43 |
define( 'AKISMET_DELETE_LIMIT', 100000 );
|
class.akismet-widget.php
CHANGED
|
@@ -99,7 +99,7 @@ class Akismet_Widget extends WP_Widget {
|
|
| 99 |
?>
|
| 100 |
|
| 101 |
<div class="a-stats">
|
| 102 |
-
<a href="https://akismet.com" target="_blank" title=""><?php printf( _n( '<strong class="count">%1$s spam</strong> blocked by <strong>Akismet</strong>', '<strong class="count">%1$s spam</strong> blocked by <strong>Akismet</strong>', $count , 'akismet'), number_format_i18n( $count ) ); ?></a>
|
| 103 |
</div>
|
| 104 |
|
| 105 |
<?php
|
| 99 |
?>
|
| 100 |
|
| 101 |
<div class="a-stats">
|
| 102 |
+
<a href="https://akismet.com" target="_blank" rel="noopener" title=""><?php printf( _n( '<strong class="count">%1$s spam</strong> blocked by <strong>Akismet</strong>', '<strong class="count">%1$s spam</strong> blocked by <strong>Akismet</strong>', $count , 'akismet'), number_format_i18n( $count ) ); ?></a>
|
| 103 |
</div>
|
| 104 |
|
| 105 |
<?php
|
class.akismet.php
CHANGED
|
@@ -11,13 +11,6 @@ class Akismet {
|
|
| 11 |
private static $last_comment_result = null;
|
| 12 |
private static $comment_as_submitted_allowed_keys = array( 'blog' => '', 'blog_charset' => '', 'blog_lang' => '', 'blog_ua' => '', 'comment_agent' => '', 'comment_author' => '', 'comment_author_IP' => '', 'comment_author_email' => '', 'comment_author_url' => '', 'comment_content' => '', 'comment_date_gmt' => '', 'comment_tags' => '', 'comment_type' => '', 'guid' => '', 'is_test' => '', 'permalink' => '', 'reporter' => '', 'site_domain' => '', 'submit_referer' => '', 'submit_uri' => '', 'user_ID' => '', 'user_agent' => '', 'user_id' => '', 'user_ip' => '' );
|
| 13 |
|
| 14 |
-
/**
|
| 15 |
-
* Is the comment check happening in the context of an API call? Of if false, then it's during the POST that happens after filling out a comment form.
|
| 16 |
-
*
|
| 17 |
-
* @var type bool
|
| 18 |
-
*/
|
| 19 |
-
private static $is_api_call = false;
|
| 20 |
-
|
| 21 |
public static function init() {
|
| 22 |
if ( ! self::$initiated ) {
|
| 23 |
self::init_hooks();
|
|
@@ -137,12 +130,18 @@ class Akismet {
|
|
| 137 |
}
|
| 138 |
|
| 139 |
public static function rest_auto_check_comment( $commentdata ) {
|
| 140 |
-
self
|
| 141 |
-
|
| 142 |
-
return self::auto_check_comment( $commentdata );
|
| 143 |
}
|
| 144 |
|
| 145 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 146 |
// If no key is configured, then there's no point in doing any of this.
|
| 147 |
if ( ! self::get_api_key() ) {
|
| 148 |
return $commentdata;
|
|
@@ -246,17 +245,19 @@ class Akismet {
|
|
| 246 |
update_option( 'akismet_spam_count', get_option( 'akismet_spam_count' ) + $incr );
|
| 247 |
}
|
| 248 |
|
| 249 |
-
if (
|
| 250 |
return new WP_Error( 'akismet_rest_comment_discarded', __( 'Comment discarded.', 'akismet' ) );
|
| 251 |
-
}
|
| 252 |
-
|
|
|
|
|
|
|
| 253 |
// Redirect back to the previous page, or failing that, the post permalink, or failing that, the homepage of the blog.
|
| 254 |
$redirect_to = isset( $_SERVER['HTTP_REFERER'] ) ? $_SERVER['HTTP_REFERER'] : ( $post ? get_permalink( $post ) : home_url() );
|
| 255 |
wp_safe_redirect( esc_url_raw( $redirect_to ) );
|
| 256 |
die();
|
| 257 |
}
|
| 258 |
}
|
| 259 |
-
else if (
|
| 260 |
// The way the REST API structures its calls, we can set the comment_approved value right away.
|
| 261 |
$commentdata['comment_approved'] = 'spam';
|
| 262 |
}
|
|
@@ -1286,7 +1287,7 @@ class Akismet {
|
|
| 1286 |
}
|
| 1287 |
|
| 1288 |
/**
|
| 1289 |
-
* Mark form.js as
|
| 1290 |
* after it's loaded, and the browser won't have to wait for it to load to continue
|
| 1291 |
* parsing the rest of the page.
|
| 1292 |
*/
|
|
@@ -1295,7 +1296,7 @@ class Akismet {
|
|
| 1295 |
return $tag;
|
| 1296 |
}
|
| 1297 |
|
| 1298 |
-
return preg_replace( '/^<script /i', '<script
|
| 1299 |
}
|
| 1300 |
|
| 1301 |
public static function inject_ak_js( $post_id ) {
|
|
@@ -1439,8 +1440,6 @@ p {
|
|
| 1439 |
if ( !is_object( $wp_xmlrpc_server ) )
|
| 1440 |
return false;
|
| 1441 |
|
| 1442 |
-
self::$is_api_call = true;
|
| 1443 |
-
|
| 1444 |
$is_multicall = false;
|
| 1445 |
$multicall_count = 0;
|
| 1446 |
|
|
@@ -1548,12 +1547,9 @@ p {
|
|
| 1548 |
'multicall_count' => $multicall_count,
|
| 1549 |
);
|
| 1550 |
|
| 1551 |
-
$comment =
|
| 1552 |
|
| 1553 |
-
if (
|
| 1554 |
-
is_wp_error( $comment ) // This triggered a 'discard' directive.
|
| 1555 |
-
|| ( isset( $comment['akismet_result'] ) && 'true' == $comment['akismet_result'] ) // It was just a normal spam response.
|
| 1556 |
-
) {
|
| 1557 |
// Sad: tightly coupled with the IXR classes. Unfortunately the action provides no context and no way to return anything.
|
| 1558 |
$wp_xmlrpc_server->error( new IXR_Error( 0, 'Invalid discovery target' ) );
|
| 1559 |
|
| 11 |
private static $last_comment_result = null;
|
| 12 |
private static $comment_as_submitted_allowed_keys = array( 'blog' => '', 'blog_charset' => '', 'blog_lang' => '', 'blog_ua' => '', 'comment_agent' => '', 'comment_author' => '', 'comment_author_IP' => '', 'comment_author_email' => '', 'comment_author_url' => '', 'comment_content' => '', 'comment_date_gmt' => '', 'comment_tags' => '', 'comment_type' => '', 'guid' => '', 'is_test' => '', 'permalink' => '', 'reporter' => '', 'site_domain' => '', 'submit_referer' => '', 'submit_uri' => '', 'user_ID' => '', 'user_agent' => '', 'user_id' => '', 'user_ip' => '' );
|
| 13 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
public static function init() {
|
| 15 |
if ( ! self::$initiated ) {
|
| 16 |
self::init_hooks();
|
| 130 |
}
|
| 131 |
|
| 132 |
public static function rest_auto_check_comment( $commentdata ) {
|
| 133 |
+
return self::auto_check_comment( $commentdata, 'rest_api' );
|
|
|
|
|
|
|
| 134 |
}
|
| 135 |
|
| 136 |
+
/**
|
| 137 |
+
* Check a comment for spam.
|
| 138 |
+
*
|
| 139 |
+
* @param array $commentdata
|
| 140 |
+
* @param string $context What kind of request triggered this comment check? Possible values are 'default', 'rest_api', and 'xml-rpc'.
|
| 141 |
+
* @return array|WP_Error Either the $commentdata array with additional entries related to its spam status
|
| 142 |
+
* or a WP_Error, if it's a REST API request and the comment should be discarded.
|
| 143 |
+
*/
|
| 144 |
+
public static function auto_check_comment( $commentdata, $context = 'default' ) {
|
| 145 |
// If no key is configured, then there's no point in doing any of this.
|
| 146 |
if ( ! self::get_api_key() ) {
|
| 147 |
return $commentdata;
|
| 245 |
update_option( 'akismet_spam_count', get_option( 'akismet_spam_count' ) + $incr );
|
| 246 |
}
|
| 247 |
|
| 248 |
+
if ( 'rest_api' === $context ) {
|
| 249 |
return new WP_Error( 'akismet_rest_comment_discarded', __( 'Comment discarded.', 'akismet' ) );
|
| 250 |
+
} else if ( 'xml-rpc' === $context ) {
|
| 251 |
+
// If this is a pingback that we're pre-checking, the discard behavior is the same as the normal spam response behavior.
|
| 252 |
+
return $commentdata;
|
| 253 |
+
} else {
|
| 254 |
// Redirect back to the previous page, or failing that, the post permalink, or failing that, the homepage of the blog.
|
| 255 |
$redirect_to = isset( $_SERVER['HTTP_REFERER'] ) ? $_SERVER['HTTP_REFERER'] : ( $post ? get_permalink( $post ) : home_url() );
|
| 256 |
wp_safe_redirect( esc_url_raw( $redirect_to ) );
|
| 257 |
die();
|
| 258 |
}
|
| 259 |
}
|
| 260 |
+
else if ( 'rest_api' === $context ) {
|
| 261 |
// The way the REST API structures its calls, we can set the comment_approved value right away.
|
| 262 |
$commentdata['comment_approved'] = 'spam';
|
| 263 |
}
|
| 1287 |
}
|
| 1288 |
|
| 1289 |
/**
|
| 1290 |
+
* Mark form.js as deferred. Because nothing depends on it, it can run at any time
|
| 1291 |
* after it's loaded, and the browser won't have to wait for it to load to continue
|
| 1292 |
* parsing the rest of the page.
|
| 1293 |
*/
|
| 1296 |
return $tag;
|
| 1297 |
}
|
| 1298 |
|
| 1299 |
+
return preg_replace( '/^<script /i', '<script defer ', $tag );
|
| 1300 |
}
|
| 1301 |
|
| 1302 |
public static function inject_ak_js( $post_id ) {
|
| 1440 |
if ( !is_object( $wp_xmlrpc_server ) )
|
| 1441 |
return false;
|
| 1442 |
|
|
|
|
|
|
|
| 1443 |
$is_multicall = false;
|
| 1444 |
$multicall_count = 0;
|
| 1445 |
|
| 1547 |
'multicall_count' => $multicall_count,
|
| 1548 |
);
|
| 1549 |
|
| 1550 |
+
$comment = self::auto_check_comment( $comment, 'xml-rpc' );
|
| 1551 |
|
| 1552 |
+
if ( isset( $comment['akismet_result'] ) && 'true' == $comment['akismet_result'] ) {
|
|
|
|
|
|
|
|
|
|
| 1553 |
// Sad: tightly coupled with the IXR classes. Unfortunately the action provides no context and no way to return anything.
|
| 1554 |
$wp_xmlrpc_server->error( new IXR_Error( 0, 'Invalid discovery target' ) );
|
| 1555 |
|
readme.txt
CHANGED
|
@@ -2,8 +2,8 @@
|
|
| 2 |
Contributors: matt, ryan, andy, mdawaffe, tellyworth, josephscott, lessbloat, eoigal, cfinke, automattic, jgs, procifer, stephdau
|
| 3 |
Tags: comments, spam, antispam, anti-spam, contact form, anti spam, comment moderation, comment spam, contact form spam, spam comments
|
| 4 |
Requires at least: 4.6
|
| 5 |
-
Tested up to: 5.
|
| 6 |
-
Stable tag: 4.1.
|
| 7 |
License: GPLv2 or later
|
| 8 |
|
| 9 |
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,15 @@ Upload the Akismet plugin to your blog, activate it, and then enter your Akismet
|
|
| 30 |
|
| 31 |
== Changelog ==
|
| 32 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
= 4.1.9 =
|
| 34 |
*Release Date - 2 March 2021*
|
| 35 |
|
| 2 |
Contributors: matt, ryan, andy, mdawaffe, tellyworth, josephscott, lessbloat, eoigal, cfinke, automattic, jgs, procifer, stephdau
|
| 3 |
Tags: comments, spam, antispam, anti-spam, contact form, anti spam, comment moderation, comment spam, contact form spam, spam comments
|
| 4 |
Requires at least: 4.6
|
| 5 |
+
Tested up to: 5.8
|
| 6 |
+
Stable tag: 4.1.10
|
| 7 |
License: GPLv2 or later
|
| 8 |
|
| 9 |
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 |
|
| 31 |
== Changelog ==
|
| 32 |
|
| 33 |
+
= 4.1.10 =
|
| 34 |
+
*Release Date - 6 July 2021*
|
| 35 |
+
|
| 36 |
+
* Simplified the code around checking comments in REST API and XML-RPC requests.
|
| 37 |
+
* Updated Plus plan terminology in notices to match current subscription names.
|
| 38 |
+
* Added `rel="noopener"` to the widget link to avoid warnings in Google Lighthouse.
|
| 39 |
+
* Set the Akismet JavaScript as deferred instead of async to improve responsiveness.
|
| 40 |
+
* Improved the preloading of screenshot popups on the edit comments admin page.
|
| 41 |
+
|
| 42 |
= 4.1.9 =
|
| 43 |
*Release Date - 2 March 2021*
|
| 44 |
|
views/notice.php
CHANGED
|
@@ -113,7 +113,8 @@
|
|
| 113 |
</div>
|
| 114 |
<?php elseif ( $type == 'existing-key-invalid' ) :?>
|
| 115 |
<div class="akismet-alert akismet-critical">
|
| 116 |
-
<h3 class="akismet-key-status"><?php
|
|
|
|
| 117 |
</div>
|
| 118 |
<?php elseif ( $type == 'new-key-failed' ) :?>
|
| 119 |
<div class="akismet-alert akismet-critical">
|
|
@@ -123,14 +124,14 @@
|
|
| 123 |
<?php elseif ( $type == 'limit-reached' && in_array( $level, array( 'yellow', 'red' ) ) ) :?>
|
| 124 |
<div class="akismet-alert akismet-critical">
|
| 125 |
<?php if ( $level == 'yellow' ): ?>
|
| 126 |
-
<h3 class="akismet-key-status failed"><?php esc_html_e( 'You’re using your Akismet key on more sites than your
|
| 127 |
<p class="akismet-description">
|
| 128 |
-
<?php printf( __( 'Your
|
| 129 |
<br /><br />
|
| 130 |
<?php printf( __( 'Please <a href="%s" target="_blank">contact our support team</a> with any questions.', 'akismet' ), 'https://akismet.com/contact/'); ?>
|
| 131 |
</p>
|
| 132 |
<?php elseif ( $level == 'red' ): ?>
|
| 133 |
-
<h3 class="akismet-key-status failed"><?php esc_html_e( 'You’re using Akismet on far too many sites for your
|
| 134 |
<p class="akismet-description">
|
| 135 |
<?php printf( __( 'To continue your service, <a href="%s" target="_blank">upgrade to an Enterprise subscription</a>, which covers an unlimited number of sites.', 'akismet'), 'https://akismet.com/account/upgrade/' ); ?>
|
| 136 |
<br /><br />
|
|
@@ -138,4 +139,4 @@
|
|
| 138 |
</p>
|
| 139 |
<?php endif; ?>
|
| 140 |
</div>
|
| 141 |
-
<?php endif;?>
|
| 113 |
</div>
|
| 114 |
<?php elseif ( $type == 'existing-key-invalid' ) :?>
|
| 115 |
<div class="akismet-alert akismet-critical">
|
| 116 |
+
<h3 class="akismet-key-status"><?php echo esc_html( __( 'Your API key is no longer valid.' , 'akismet' ) ); ?></h3>
|
| 117 |
+
<p class="akismet-description"><?php printf( __( 'Please enter a new key or <a href="%s" target="_blank">contact Akismet support</a>.' , 'akismet' ), 'https://akismet.com/contact/' ); ?></p>
|
| 118 |
</div>
|
| 119 |
<?php elseif ( $type == 'new-key-failed' ) :?>
|
| 120 |
<div class="akismet-alert akismet-critical">
|
| 124 |
<?php elseif ( $type == 'limit-reached' && in_array( $level, array( 'yellow', 'red' ) ) ) :?>
|
| 125 |
<div class="akismet-alert akismet-critical">
|
| 126 |
<?php if ( $level == 'yellow' ): ?>
|
| 127 |
+
<h3 class="akismet-key-status failed"><?php esc_html_e( 'You’re using your Akismet key on more sites than your Plus subscription allows.', 'akismet' ); ?></h3>
|
| 128 |
<p class="akismet-description">
|
| 129 |
+
<?php printf( __( 'Your Plus subscription allows the use of Akismet on only one site. Please <a href="%s" target="_blank">purchase additional Plus subscriptions</a> or upgrade to an Enterprise subscription that allows the use of Akismet on unlimited sites.', 'akismet' ), 'https://docs.akismet.com/billing/add-more-sites/' ); ?>
|
| 130 |
<br /><br />
|
| 131 |
<?php printf( __( 'Please <a href="%s" target="_blank">contact our support team</a> with any questions.', 'akismet' ), 'https://akismet.com/contact/'); ?>
|
| 132 |
</p>
|
| 133 |
<?php elseif ( $level == 'red' ): ?>
|
| 134 |
+
<h3 class="akismet-key-status failed"><?php esc_html_e( 'You’re using Akismet on far too many sites for your Plus subscription.', 'akismet' ); ?></h3>
|
| 135 |
<p class="akismet-description">
|
| 136 |
<?php printf( __( 'To continue your service, <a href="%s" target="_blank">upgrade to an Enterprise subscription</a>, which covers an unlimited number of sites.', 'akismet'), 'https://akismet.com/account/upgrade/' ); ?>
|
| 137 |
<br /><br />
|
| 139 |
</p>
|
| 140 |
<?php endif; ?>
|
| 141 |
</div>
|
| 142 |
+
<?php endif;?>
|
