WordPress Zero Spam - Version 4.9.5

Version Description

  • Enhancement - Added the BotScout Count Minimum field in settings to allow sites to control when a BotScout result should be marked spam/malicious. See BotScout's documentation for more information.
  • Enhancement - Improved performance by only querying the blacklist API once every X number of days (set in the admin settings).
  • Fix - Removed double slashes in some required PHP & JS paths.
Download this release

Release Info

Developer bmarshall511
Plugin Icon 128x128 WordPress Zero Spam
Version 4.9.5
Comparing to
See all releases

Code changes from version 4.9.4 to 4.9.5

Files changed (6) hide show
  1. inc/admin.php +34 -13
  2. inc/helpers.php +44 -1
  3. inc/scripts.php +12 -12
  4. inc/utilities.php +3 -1
  5. readme.txt +14 -3
  6. wordpress-zero-spam.php +16 -16
inc/admin.php CHANGED
@@ -69,13 +69,13 @@ function wpzerospam_spam_detections_page() {
69
  <div class="wrap">
70
  <h1><?php echo esc_html( get_admin_page_title() ); ?></h1>
71
 
72
- <?php require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . '/templates/callout.php'; ?>
73
 
74
  <?php
75
  /**
76
  * Log table
77
  */
78
- require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . '/classes/class-wpzerospam-log-table.php';
79
 
80
  $table_data = new WPZeroSpam_Log_Table();
81
 
@@ -98,13 +98,13 @@ function wpzerospam_blacklist_page() {
98
  <div class="wrap">
99
  <h1><?php echo esc_html( get_admin_page_title() ); ?></h1>
100
 
101
- <?php require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . '/templates/callout.php'; ?>
102
 
103
  <?php
104
  /**
105
  * Blocked IP table
106
  */
107
- require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . '/classes/class-wpzerospam-blacklisted-table.php';
108
 
109
  $table_data = new WPZeroSpam_Blacklisted_Table();
110
 
@@ -180,7 +180,7 @@ function wpzerospam_blocked_ips_page() {
180
  <div class="wrap">
181
  <h1><?php echo esc_html( get_admin_page_title() ); ?></h1>
182
 
183
- <?php require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . '/templates/callout.php'; ?>
184
 
185
  <?php if ( ! empty( $_GET['error'] ) ): ?>
186
  <div class="notice notice-error is-dismissible">
@@ -250,7 +250,7 @@ function wpzerospam_blocked_ips_page() {
250
  /**
251
  * Blocked IP table
252
  */
253
- require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . '/classes/class-wpzerospam-blocked-ip-table.php';
254
 
255
  $table_data = new WPZeroSpam_Blocked_IP_Table();
256
 
@@ -279,15 +279,15 @@ function wpzerospam_dashboard() {
279
  <div class="wrap">
280
  <h1><?php echo esc_html( get_admin_page_title() ); ?></h1>
281
 
282
- <?php require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . '/templates/callout.php'; ?>
283
 
284
  <h2><?php _e( 'Statistics', 'wpzerospam' ); ?></h2>
285
  <div class="wpzerospam-boxes">
286
- <?php require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . '/templates/map.php'; ?>
287
- <?php require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . '/templates/ip-list.php'; ?>
288
- <?php require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . '/templates/countries-pie-chart.php'; ?>
289
- <?php require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . '/templates/regions-pie-chart.php'; ?>
290
- <?php require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . '/templates/spam-line-chart.php'; ?>
291
  </div>
292
  </div>
293
  <?php
@@ -299,7 +299,7 @@ function wpzerospam_options_page() {
299
  <div class="wrap">
300
  <h1><?php echo esc_html( get_admin_page_title() ); ?></h1>
301
 
302
- <?php require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . '/templates/callout.php'; ?>
303
 
304
  <form action="options.php" method="post">
305
  <?php
@@ -328,6 +328,8 @@ function wpzerospam_validate_options( $input ) {
328
  if ( empty( $input['auto_block_permanently'] ) ) { $input['auto_block_permanently'] = 3; }
329
  if ( empty( $input['api_timeout'] ) ) { $input['api_timeout'] = 5; }
330
  if ( empty( $input['stopforumspam_confidence_min'] ) ) { $input['stopforumspam_confidence_min'] = 20; }
 
 
331
 
332
  if ( empty( $input['ip_whitelist'] ) ) {
333
  $input['ip_whitelist'] = '';
@@ -422,6 +424,16 @@ function wpzerospam_admin_init() {
422
  add_settings_section( 'wpzerospam_onsite', __( 'On-site Spam Prevention', 'wpzerospam' ), 'wpzerospam_onsite_cb', 'wpzerospam' );
423
  add_settings_section( 'wpzerospam_spam_checks', __( 'Integrations & Third-party APIs', 'wpzerospam' ), 'wpzerospam_spam_checks_cb', 'wpzerospam' );
424
 
 
 
 
 
 
 
 
 
 
 
425
  // Determines is spam detections should be shared with WordPress Zero Spam
426
  add_settings_field( 'share_detections', __( 'Share Spam Detections', 'wpzerospam' ), 'wpzerospam_field_cb', 'wpzerospam', 'wpzerospam_general_settings', [
427
  'label_for' => 'share_detections',
@@ -517,6 +529,15 @@ function wpzerospam_admin_init() {
517
  'desc' => 'Enter your BotScout API key to check user IPs against <a href="https://botscout.com/" target="_blank" rel="noopener noreferrer">BotScout</a>\'s blacklist. Don\'t have an API key? <a href="https://botscout.com/getkey.htm" target="_blank" rel="noopener noreferrer"><strong>Get one for free!</strong></a>'
518
  ]);
519
 
 
 
 
 
 
 
 
 
 
520
  // Enables the ability to check IPs against Stop Forum Spam blacklists.
521
  add_settings_field( 'stop_forum_spam', __( 'Stop Forum Spam', 'wpzerospam' ), 'wpzerospam_field_cb', 'wpzerospam', 'wpzerospam_spam_checks', [
522
  'label_for' => 'stop_forum_spam',
69
  <div class="wrap">
70
  <h1><?php echo esc_html( get_admin_page_title() ); ?></h1>
71
 
72
+ <?php require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . 'templates/callout.php'; ?>
73
 
74
  <?php
75
  /**
76
  * Log table
77
  */
78
+ require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . 'classes/class-wpzerospam-log-table.php';
79
 
80
  $table_data = new WPZeroSpam_Log_Table();
81
 
98
  <div class="wrap">
99
  <h1><?php echo esc_html( get_admin_page_title() ); ?></h1>
100
 
101
+ <?php require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . 'templates/callout.php'; ?>
102
 
103
  <?php
104
  /**
105
  * Blocked IP table
106
  */
107
+ require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . 'classes/class-wpzerospam-blacklisted-table.php';
108
 
109
  $table_data = new WPZeroSpam_Blacklisted_Table();
110
 
180
  <div class="wrap">
181
  <h1><?php echo esc_html( get_admin_page_title() ); ?></h1>
182
 
183
+ <?php require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . 'templates/callout.php'; ?>
184
 
185
  <?php if ( ! empty( $_GET['error'] ) ): ?>
186
  <div class="notice notice-error is-dismissible">
250
  /**
251
  * Blocked IP table
252
  */
253
+ require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . 'classes/class-wpzerospam-blocked-ip-table.php';
254
 
255
  $table_data = new WPZeroSpam_Blocked_IP_Table();
256
 
279
  <div class="wrap">
280
  <h1><?php echo esc_html( get_admin_page_title() ); ?></h1>
281
 
282
+ <?php require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . 'templates/callout.php'; ?>
283
 
284
  <h2><?php _e( 'Statistics', 'wpzerospam' ); ?></h2>
285
  <div class="wpzerospam-boxes">
286
+ <?php require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . 'templates/map.php'; ?>
287
+ <?php require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . 'templates/ip-list.php'; ?>
288
+ <?php require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . 'templates/countries-pie-chart.php'; ?>
289
+ <?php require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . 'templates/regions-pie-chart.php'; ?>
290
+ <?php require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . 'templates/spam-line-chart.php'; ?>
291
  </div>
292
  </div>
293
  <?php
299
  <div class="wrap">
300
  <h1><?php echo esc_html( get_admin_page_title() ); ?></h1>
301
 
302
+ <?php require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . 'templates/callout.php'; ?>
303
 
304
  <form action="options.php" method="post">
305
  <?php
328
  if ( empty( $input['auto_block_permanently'] ) ) { $input['auto_block_permanently'] = 3; }
329
  if ( empty( $input['api_timeout'] ) ) { $input['api_timeout'] = 5; }
330
  if ( empty( $input['stopforumspam_confidence_min'] ) ) { $input['stopforumspam_confidence_min'] = 20; }
331
+ if ( empty( $input['botscout_count_min'] ) ) { $input['botscout_count_min'] = 5; }
332
+ if ( empty( $input['cookie_expiration'] ) ) { $input['cookie_expiration'] = 7; }
333
 
334
  if ( empty( $input['ip_whitelist'] ) ) {
335
  $input['ip_whitelist'] = '';
424
  add_settings_section( 'wpzerospam_onsite', __( 'On-site Spam Prevention', 'wpzerospam' ), 'wpzerospam_onsite_cb', 'wpzerospam' );
425
  add_settings_section( 'wpzerospam_spam_checks', __( 'Integrations & Third-party APIs', 'wpzerospam' ), 'wpzerospam_spam_checks_cb', 'wpzerospam' );
426
 
427
+ // Cookie expiration
428
+ add_settings_field( 'cookie_expiration', __( 'Cookie Expiration', 'wpzerospam' ), 'wpzerospam_field_cb', 'wpzerospam', 'wpzerospam_general_settings', [
429
+ 'label_for' => 'cookie_expiration',
430
+ 'type' => 'number',
431
+ 'desc' => 'Number of days until a user\'s cookie is expired. Helps boost site performance so blacklist API requests aren\'t sent each page visit. <strong>Minimum recommend is 7 days</strong>.',
432
+ 'class' => 'small-text',
433
+ 'placeholder' => '7',
434
+ 'suffix' => __( 'days', 'wpzerospam' )
435
+ ]);
436
+
437
  // Determines is spam detections should be shared with WordPress Zero Spam
438
  add_settings_field( 'share_detections', __( 'Share Spam Detections', 'wpzerospam' ), 'wpzerospam_field_cb', 'wpzerospam', 'wpzerospam_general_settings', [
439
  'label_for' => 'share_detections',
529
  'desc' => 'Enter your BotScout API key to check user IPs against <a href="https://botscout.com/" target="_blank" rel="noopener noreferrer">BotScout</a>\'s blacklist. Don\'t have an API key? <a href="https://botscout.com/getkey.htm" target="_blank" rel="noopener noreferrer"><strong>Get one for free!</strong></a>'
530
  ]);
531
 
532
+ // BotScout count minimum
533
+ add_settings_field( 'botscout_count_min', __( 'BotScout Count Minimum', 'wpzerospam' ), 'wpzerospam_field_cb', 'wpzerospam', 'wpzerospam_spam_checks', [
534
+ 'label_for' => 'botscout_count_min',
535
+ 'type' => 'number',
536
+ 'desc' => 'Minimum <a href="https://botscout.com/api.htm" target="_blank" rel="noopener noreferrer">count</a> an IP must meet before being marked as spam/malicious.<br /><strong>WARNING:</strong> Setting this too low could cause users to be blocked that shouldn\'t be, <strong>recommended is 5</strong>.',
537
+ 'class' => 'small-text',
538
+ 'placeholder' => '20',
539
+ ]);
540
+
541
  // Enables the ability to check IPs against Stop Forum Spam blacklists.
542
  add_settings_field( 'stop_forum_spam', __( 'Stop Forum Spam', 'wpzerospam' ), 'wpzerospam_field_cb', 'wpzerospam', 'wpzerospam_spam_checks', [
543
  'label_for' => 'stop_forum_spam',
inc/helpers.php CHANGED
@@ -7,6 +7,31 @@
7
  * @link https://benmarshall.me/wordpress-zero-spam/
8
  */
9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  /**
11
  * Check access
12
  *
@@ -101,6 +126,10 @@ if ( ! function_exists( 'wpzerospam_is_api_blacklisted' ) ) {
101
  function wpzerospam_is_api_blacklisted( $ip, $blacklisted_record = false ) {
102
  global $wpdb;
103
 
 
 
 
 
104
  $options = wpzerospam_options();
105
 
106
  if ( $blacklisted_record ) {
@@ -118,7 +147,12 @@ if ( ! function_exists( 'wpzerospam_is_api_blacklisted' ) ) {
118
  );
119
 
120
  if ( $query ) {
121
- if ( ! empty( $query['confidence'] ) && $query['confidence'] < $options['stopforumspam_confidence_min'] ) {
 
 
 
 
 
122
  // Does not meet the stopforumspam confidence minimum, delete record
123
  $wpdb->delete( wpzerospam_tables( 'blacklist' ), [
124
  'blacklist_id' => $blacklisted_record['blacklist_id']
@@ -175,6 +209,15 @@ if ( ! function_exists( 'wpzerospam_is_api_blacklisted' ) ) {
175
 
176
  $botscout = wpzerospam_query_blacklist_api( $ip, 'botscout' );
177
  if ( $botscout ) {
 
 
 
 
 
 
 
 
 
178
  $blacklisted_record = [
179
  'blacklist_service' => 'botscout',
180
  'user_ip' => $ip,
7
  * @link https://benmarshall.me/wordpress-zero-spam/
8
  */
9
 
10
+ /**
11
+ * Sets a cookie
12
+ */
13
+ if ( ! function_exists( 'wpzerospam_set_cookie' ) ) {
14
+ function wpzerospam_set_cookie( $key, $value ) {
15
+ $options = wpzerospam_options();
16
+ $expiration = current_time( 'timestamp' ) + ( $options['cookie_expiration'] * DAY_IN_SECONDS );
17
+
18
+ setcookie( 'wpzerospam_' . $key, $value, $expiration, COOKIEPATH, COOKIE_DOMAIN );
19
+ }
20
+ }
21
+
22
+ /**
23
+ * Get a cookie
24
+ */
25
+ if ( ! function_exists( 'wpzerospam_get_cookie' ) ) {
26
+ function wpzerospam_get_cookie( $key ) {
27
+ if ( ! empty( $_COOKIE[ 'wpzerospam_' . $key ] ) ) {
28
+ return $_COOKIE[ 'wpzerospam_' . $key ];
29
+ }
30
+
31
+ return false;
32
+ }
33
+ }
34
+
35
  /**
36
  * Check access
37
  *
126
  function wpzerospam_is_api_blacklisted( $ip, $blacklisted_record = false ) {
127
  global $wpdb;
128
 
129
+ // No need to check everytime a user visits a page
130
+ if ( wpzerospam_get_cookie( 'api_blacklist' ) ) { return false; }
131
+ wpzerospam_set_cookie( 'api_blacklist', current_time( 'timestamp' ) );
132
+
133
  $options = wpzerospam_options();
134
 
135
  if ( $blacklisted_record ) {
147
  );
148
 
149
  if ( $query ) {
150
+ if (
151
+ // Check for Stop Forum Spam confidence level
152
+ ( ! empty( $query['confidence'] ) && $query['confidence'] < $options['stopforumspam_confidence_min'] ) ||
153
+ // Check for BotScout counts
154
+ ( ! empty( $query['count'] ) && $query['count'] < $options['botscout_count_min'] )
155
+ ) {
156
  // Does not meet the stopforumspam confidence minimum, delete record
157
  $wpdb->delete( wpzerospam_tables( 'blacklist' ), [
158
  'blacklist_id' => $blacklisted_record['blacklist_id']
209
 
210
  $botscout = wpzerospam_query_blacklist_api( $ip, 'botscout' );
211
  if ( $botscout ) {
212
+ if ( ! empty( $botscout['count'] ) && $botscout['count'] < $options['botscout_count_min'] ) {
213
+ // Does not meet the botscout count minimum, delete record
214
+ $wpdb->delete( wpzerospam_tables( 'blacklist' ), [
215
+ 'user_ip' => $ip
216
+ ]);
217
+
218
+ return false;
219
+ }
220
+
221
  $blacklisted_record = [
222
  'blacklist_service' => 'botscout',
223
  'user_ip' => $ip,
inc/scripts.php CHANGED
@@ -14,7 +14,7 @@ if ( ! function_exists( 'wpzerospam_admin_scripts' ) ) {
14
  wp_enqueue_style(
15
  'wpzerospam-admin',
16
  plugin_dir_url( WORDPRESS_ZERO_SPAM ) .
17
- '/assets/css/admin.css',
18
  false,
19
  WORDPRESS_ZERO_SPAM_VERSION
20
  );
@@ -23,7 +23,7 @@ if ( ! function_exists( 'wpzerospam_admin_scripts' ) ) {
23
  wp_register_script(
24
  'wpzerospam-charts',
25
  plugin_dir_url( WORDPRESS_ZERO_SPAM ) .
26
- '/assets/js/Chart.bundle.min.js',
27
  [],
28
  '2.9.3'
29
  );
@@ -32,7 +32,7 @@ if ( ! function_exists( 'wpzerospam_admin_scripts' ) ) {
32
  wp_register_style(
33
  'wpzerospam-charts',
34
  plugin_dir_url( WORDPRESS_ZERO_SPAM ) .
35
- '/assets/css/Chart.min.css',
36
  false,
37
  '2.9.3'
38
  );
@@ -41,7 +41,7 @@ if ( ! function_exists( 'wpzerospam_admin_scripts' ) ) {
41
  wp_register_script(
42
  'wpzerospam-map',
43
  plugin_dir_url( WORDPRESS_ZERO_SPAM ) .
44
- '/assets/js/jquery-jvectormap-2.0.5.min.js',
45
  [ 'jquery' ],
46
  '2.0.5'
47
  );
@@ -49,7 +49,7 @@ if ( ! function_exists( 'wpzerospam_admin_scripts' ) ) {
49
  wp_register_script(
50
  'wpzerospam-world-map',
51
  plugin_dir_url( WORDPRESS_ZERO_SPAM ) .
52
- '/assets/js/jquery-jvectormap-world-mill.js',
53
  [ 'wpzerospam-map' ],
54
  '2.0.5'
55
  );
@@ -58,7 +58,7 @@ if ( ! function_exists( 'wpzerospam_admin_scripts' ) ) {
58
  wp_register_style(
59
  'wpzerospam-map',
60
  plugin_dir_url( WORDPRESS_ZERO_SPAM ) .
61
- '/assets/css/jquery-jvectormap-2.0.5.css',
62
  false,
63
  '2.9.3'
64
  );
@@ -66,7 +66,7 @@ if ( ! function_exists( 'wpzerospam_admin_scripts' ) ) {
66
  wp_register_script(
67
  'wpzerospam-admin-tables',
68
  plugin_dir_url( WORDPRESS_ZERO_SPAM ) .
69
- '/assets/js/admin-tables.js',
70
  [ 'jquery' ],
71
  WORDPRESS_ZERO_SPAM_VERSION,
72
  true
@@ -75,7 +75,7 @@ if ( ! function_exists( 'wpzerospam_admin_scripts' ) ) {
75
  wp_register_style(
76
  'wpzerospam-admin-tables',
77
  plugin_dir_url( WORDPRESS_ZERO_SPAM ) .
78
- '/assets/css/admin-tables.css',
79
  false,
80
  WORDPRESS_ZERO_SPAM_VERSION
81
  );
@@ -99,7 +99,7 @@ if ( ! function_exists( 'wpzerospam_admin_scripts' ) ) {
99
  wp_enqueue_style(
100
  'wpzerospam-admin-dashboard',
101
  plugin_dir_url( WORDPRESS_ZERO_SPAM ) .
102
- '/assets/css/admin-dashboard.css',
103
  false,
104
  WORDPRESS_ZERO_SPAM_VERSION
105
  );
@@ -112,7 +112,7 @@ if ( ! function_exists( 'wpzerospam_admin_scripts' ) ) {
112
  wp_enqueue_script(
113
  'wpzerospam-admin-blocked-ips',
114
  plugin_dir_url( WORDPRESS_ZERO_SPAM ) .
115
- '/assets/js/admin-blocked-ips.js',
116
  [ 'jquery' ],
117
  WORDPRESS_ZERO_SPAM_VERSION,
118
  true
@@ -122,7 +122,7 @@ if ( ! function_exists( 'wpzerospam_admin_scripts' ) ) {
122
  wp_enqueue_style(
123
  'wpzerospam-admin-block_ips',
124
  plugin_dir_url( WORDPRESS_ZERO_SPAM ) .
125
- '/assets/css/admin-blocked-ips.css',
126
  false,
127
  WORDPRESS_ZERO_SPAM_VERSION
128
  );
@@ -142,7 +142,7 @@ if ( ! function_exists( 'wpzerospam_enqueue_scripts' ) ) {
142
  wp_enqueue_script(
143
  'wpzerospam',
144
  plugin_dir_url( WORDPRESS_ZERO_SPAM ) .
145
- '/assets/js/wpzerospam.js',
146
  [ 'jquery' ],
147
  WORDPRESS_ZERO_SPAM_VERSION,
148
  true
14
  wp_enqueue_style(
15
  'wpzerospam-admin',
16
  plugin_dir_url( WORDPRESS_ZERO_SPAM ) .
17
+ 'assets/css/admin.css',
18
  false,
19
  WORDPRESS_ZERO_SPAM_VERSION
20
  );
23
  wp_register_script(
24
  'wpzerospam-charts',
25
  plugin_dir_url( WORDPRESS_ZERO_SPAM ) .
26
+ 'assets/js/Chart.bundle.min.js',
27
  [],
28
  '2.9.3'
29
  );
32
  wp_register_style(
33
  'wpzerospam-charts',
34
  plugin_dir_url( WORDPRESS_ZERO_SPAM ) .
35
+ 'assets/css/Chart.min.css',
36
  false,
37
  '2.9.3'
38
  );
41
  wp_register_script(
42
  'wpzerospam-map',
43
  plugin_dir_url( WORDPRESS_ZERO_SPAM ) .
44
+ 'assets/js/jquery-jvectormap-2.0.5.min.js',
45
  [ 'jquery' ],
46
  '2.0.5'
47
  );
49
  wp_register_script(
50
  'wpzerospam-world-map',
51
  plugin_dir_url( WORDPRESS_ZERO_SPAM ) .
52
+ 'assets/js/jquery-jvectormap-world-mill.js',
53
  [ 'wpzerospam-map' ],
54
  '2.0.5'
55
  );
58
  wp_register_style(
59
  'wpzerospam-map',
60
  plugin_dir_url( WORDPRESS_ZERO_SPAM ) .
61
+ 'assets/css/jquery-jvectormap-2.0.5.css',
62
  false,
63
  '2.9.3'
64
  );
66
  wp_register_script(
67
  'wpzerospam-admin-tables',
68
  plugin_dir_url( WORDPRESS_ZERO_SPAM ) .
69
+ 'assets/js/admin-tables.js',
70
  [ 'jquery' ],
71
  WORDPRESS_ZERO_SPAM_VERSION,
72
  true
75
  wp_register_style(
76
  'wpzerospam-admin-tables',
77
  plugin_dir_url( WORDPRESS_ZERO_SPAM ) .
78
+ 'assets/css/admin-tables.css',
79
  false,
80
  WORDPRESS_ZERO_SPAM_VERSION
81
  );
99
  wp_enqueue_style(
100
  'wpzerospam-admin-dashboard',
101
  plugin_dir_url( WORDPRESS_ZERO_SPAM ) .
102
+ 'assets/css/admin-dashboard.css',
103
  false,
104
  WORDPRESS_ZERO_SPAM_VERSION
105
  );
112
  wp_enqueue_script(
113
  'wpzerospam-admin-blocked-ips',
114
  plugin_dir_url( WORDPRESS_ZERO_SPAM ) .
115
+ 'assets/js/admin-blocked-ips.js',
116
  [ 'jquery' ],
117
  WORDPRESS_ZERO_SPAM_VERSION,
118
  true
122
  wp_enqueue_style(
123
  'wpzerospam-admin-block_ips',
124
  plugin_dir_url( WORDPRESS_ZERO_SPAM ) .
125
+ 'assets/css/admin-blocked-ips.css',
126
  false,
127
  WORDPRESS_ZERO_SPAM_VERSION
128
  );
142
  wp_enqueue_script(
143
  'wpzerospam',
144
  plugin_dir_url( WORDPRESS_ZERO_SPAM ) .
145
+ 'assets/js/wpzerospam.js',
146
  [ 'jquery' ],
147
  WORDPRESS_ZERO_SPAM_VERSION,
148
  true
inc/utilities.php CHANGED
@@ -12,7 +12,7 @@
12
  /**
13
  * Locations helper
14
  */
15
- require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . '/inc/locations.php';
16
 
17
  /**
18
  * Get the user's current URL
@@ -109,6 +109,8 @@ if ( ! function_exists( 'wpzerospam_options' ) ) {
109
  if ( empty( $options['ip_whitelist'] ) ) { $options['ip_whitelist'] = false; }
110
  if ( empty( $options['api_timeout'] ) ) { $options['api_timeout'] = 5; }
111
  if ( empty( $options['stopforumspam_confidence_min'] ) ) { $options['stopforumspam_confidence_min'] = 20; }
 
 
112
 
113
  if ( empty( $options['verify_cf7'] ) ) {
114
  $options['verify_cf7'] = 'enabled';
12
  /**
13
  * Locations helper
14
  */
15
+ require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . 'inc/locations.php';
16
 
17
  /**
18
  * Get the user's current URL
109
  if ( empty( $options['ip_whitelist'] ) ) { $options['ip_whitelist'] = false; }
110
  if ( empty( $options['api_timeout'] ) ) { $options['api_timeout'] = 5; }
111
  if ( empty( $options['stopforumspam_confidence_min'] ) ) { $options['stopforumspam_confidence_min'] = 20; }
112
+ if ( empty( $options['botscout_count_min'] ) ) { $options['botscout_count_min'] = 5; }
113
+ if ( empty( $options['cookie_expiration'] ) ) { $options['cookie_expiration'] = 7; }
114
 
115
  if ( empty( $options['verify_cf7'] ) ) {
116
  $options['verify_cf7'] = 'enabled';
readme.txt CHANGED
@@ -5,7 +5,7 @@ Donate link: https://benmarshall.me/donate/?utm_source=wordpress_zero_spam&utm_m
5
  Requires at least: 5.2
6
  Tested up to: 5.4.2
7
  Requires PHP: 7.1
8
- Stable tag: 4.9.4
9
  License: GNU GPLv3
10
  License URI: https://choosealicense.com/licenses/gpl-3.0/
11
 
@@ -17,7 +17,7 @@ Quit forcing users to answer silly questions, read confusing captchas, or take a
17
 
18
  [WordPress Zero Spam](https://benmarshall.me/wordpress-zero-spam/?utm_source=wordpress.org&utm_medium=plugin&utm_campaign=wordpress_zero_spam) uses AI in combination with proven spam detection techniques and a database of known malicious IPs from around the world to detect and block unwanted visitors.
19
 
20
- In addition, it integrates with other popular plugins to provide all around protection. Just install, activate, and enjoy a spam-free site.
21
 
22
  = WordPress Zero Spam features =
23
 
@@ -104,6 +104,10 @@ It's easy as adding the class `wpzerospam` to the `form` element, then adding a
104
 
105
  Yes. One of the many techniques WordPress Zero Spam employs requires JavaScript be enabled to work properly.
106
 
 
 
 
 
107
  == Screenshots ==
108
 
109
  1. WordPress Zero Spam dashboard
@@ -114,6 +118,12 @@ Yes. One of the many techniques WordPress Zero Spam employs requires JavaScript
114
 
115
  == Changelog ==
116
 
 
 
 
 
 
 
117
  = 4.9.4 =
118
 
119
  * Fixed issued with BuddyPress checks not running.
@@ -134,7 +144,8 @@ Yes. One of the many techniques WordPress Zero Spam employs requires JavaScript
134
  * Fix for BotScout not checking IPs
135
  * Fix for table not found notice on activation
136
 
137
- 4.9.1
 
138
  Fix for PHP notice on the modals for spam detections
139
 
140
  = 4.9.0 =
5
  Requires at least: 5.2
6
  Tested up to: 5.4.2
7
  Requires PHP: 7.1
8
+ Stable tag: 4.9.5
9
  License: GNU GPLv3
10
  License URI: https://choosealicense.com/licenses/gpl-3.0/
11
 
17
 
18
  [WordPress Zero Spam](https://benmarshall.me/wordpress-zero-spam/?utm_source=wordpress.org&utm_medium=plugin&utm_campaign=wordpress_zero_spam) uses AI in combination with proven spam detection techniques and a database of known malicious IPs from around the world to detect and block unwanted visitors.
19
 
20
+ In addition, it integrates with other popular plugins to provide all around protection. **Just install, activate, and enjoy a spam-free site!**
21
 
22
  = WordPress Zero Spam features =
23
 
104
 
105
  Yes. One of the many techniques WordPress Zero Spam employs requires JavaScript be enabled to work properly.
106
 
107
+ = Does WordPress Zero Spam use cookies? =
108
+
109
+ Yes. It does not store any kind of personally identifiable information. Only one cookie is stored (`wpzerospam_api_blacklist`) to log the last time the site queried the blacklist APIs. This is used to boost performance so each page visit doesn't trigger an API call. The expiration can be set in *Admin > WP Zero Spam > Settings*
110
+
111
  == Screenshots ==
112
 
113
  1. WordPress Zero Spam dashboard
118
 
119
  == Changelog ==
120
 
121
+ = 4.9.5 =
122
+
123
+ * Enhancement - Added the *BotScout Count Minimum* field in settings to allow sites to control when a BotScout result should be marked spam/malicious. See [BotScout's documentation](https://botscout.com/api.htm) for more information.
124
+ * Enhancement - Improved performance by only querying the blacklist API once every X number of days (set in the admin settings).
125
+ * Fix - Removed double slashes in some required PHP & JS paths.
126
+
127
  = 4.9.4 =
128
 
129
  * Fixed issued with BuddyPress checks not running.
144
  * Fix for BotScout not checking IPs
145
  * Fix for table not found notice on activation
146
 
147
+ = 4.9.1 =
148
+
149
  Fix for PHP notice on the modals for spam detections
150
 
151
  = 4.9.0 =
wordpress-zero-spam.php CHANGED
@@ -13,7 +13,7 @@
13
  * Plugin Name: WordPress Zero Spam
14
  * Plugin URI: https://benmarshall.me/wordpress-zero-spam
15
  * Description: Tired of all the useless and bloated WordPress spam plugins? The WordPress Zero Spam plugin makes blocking spam a cinch. <strong>Just install, activate and say goodbye to spam.</strong> Based on work by <a href="http://davidwalsh.name/wordpress-comment-spam" target="_blank">David Walsh</a>.
16
- * Version: 4.9.4
17
  * Requires at least: 5.2
18
  * Requires PHP: 7.2
19
  * Author: Ben Marshall
@@ -31,22 +31,22 @@ defined( 'ABSPATH' ) or die( 'No script kiddies please!' );
31
  // Define plugin constants
32
  define( 'WORDPRESS_ZERO_SPAM', __FILE__ );
33
  define( 'WORDPRESS_ZERO_SPAM_DB_VERSION', '0.5' );
34
- define( 'WORDPRESS_ZERO_SPAM_VERSION', '4.9.4' );
35
 
36
  /**
37
  * Utility helper functions
38
  */
39
- require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . '/inc/utilities.php';
40
 
41
  /**
42
  * Helpers
43
  */
44
- require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . '/inc/helpers.php';
45
 
46
  /**
47
  * Plugin updates
48
  */
49
- require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . '/inc/updates.php';
50
 
51
  /**
52
  * Install plugin tables
@@ -125,46 +125,46 @@ add_action( 'plugins_loaded', 'wpzerospam_db_check' );
125
  /**
126
  * Plugin scripts
127
  */
128
- require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . '/inc/scripts.php';
129
 
130
  /**
131
  * Admin interface & functionality
132
  */
133
- require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . '/inc/admin.php';
134
 
135
  /**
136
  * WP filters
137
  */
138
- require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . '/inc/filters.php';
139
 
140
  /**
141
  * Below are the includes for individual spam check integrations
142
  */
143
- require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . '/integrations/comments/comments.php';
144
- require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . '/integrations/registrations/registrations.php';
145
 
146
  if ( wpzerospam_plugin_integration_enabled( 'cf7' ) ) {
147
- require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . '/integrations/contact-form-7/contact-form-7.php';
148
  }
149
 
150
  if ( wpzerospam_plugin_integration_enabled( 'gforms' ) ) {
151
- require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . '/integrations/gravity-forms/gravity-forms.php';
152
  }
153
 
154
  if ( wpzerospam_plugin_integration_enabled( 'bp_registrations' ) ) {
155
- require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . '/integrations/buddypress/buddypress.php';
156
  }
157
 
158
  if ( wpzerospam_plugin_integration_enabled( 'wpforms' ) ) {
159
- require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . '/integrations/wpforms/wpforms.php';
160
  }
161
 
162
  if ( wpzerospam_plugin_integration_enabled( 'fluentform' ) ) {
163
- require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . '/integrations/fluentform/fluentform.php';
164
  }
165
 
166
  if ( wpzerospam_plugin_integration_enabled( 'formidable' ) ) {
167
- require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . '/integrations/formidable/formidable.php';
168
  }
169
 
170
  /**
13
  * Plugin Name: WordPress Zero Spam
14
  * Plugin URI: https://benmarshall.me/wordpress-zero-spam
15
  * Description: Tired of all the useless and bloated WordPress spam plugins? The WordPress Zero Spam plugin makes blocking spam a cinch. <strong>Just install, activate and say goodbye to spam.</strong> Based on work by <a href="http://davidwalsh.name/wordpress-comment-spam" target="_blank">David Walsh</a>.
16
+ * Version: 4.9.5
17
  * Requires at least: 5.2
18
  * Requires PHP: 7.2
19
  * Author: Ben Marshall
31
  // Define plugin constants
32
  define( 'WORDPRESS_ZERO_SPAM', __FILE__ );
33
  define( 'WORDPRESS_ZERO_SPAM_DB_VERSION', '0.5' );
34
+ define( 'WORDPRESS_ZERO_SPAM_VERSION', '4.9.5' );
35
 
36
  /**
37
  * Utility helper functions
38
  */
39
+ require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . 'inc/utilities.php';
40
 
41
  /**
42
  * Helpers
43
  */
44
+ require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . 'inc/helpers.php';
45
 
46
  /**
47
  * Plugin updates
48
  */
49
+ require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . 'inc/updates.php';
50
 
51
  /**
52
  * Install plugin tables
125
  /**
126
  * Plugin scripts
127
  */
128
+ require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . 'inc/scripts.php';
129
 
130
  /**
131
  * Admin interface & functionality
132
  */
133
+ require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . 'inc/admin.php';
134
 
135
  /**
136
  * WP filters
137
  */
138
+ require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . 'inc/filters.php';
139
 
140
  /**
141
  * Below are the includes for individual spam check integrations
142
  */
143
+ require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . 'integrations/comments/comments.php';
144
+ require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . 'integrations/registrations/registrations.php';
145
 
146
  if ( wpzerospam_plugin_integration_enabled( 'cf7' ) ) {
147
+ require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . 'integrations/contact-form-7/contact-form-7.php';
148
  }
149
 
150
  if ( wpzerospam_plugin_integration_enabled( 'gforms' ) ) {
151
+ require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . 'integrations/gravity-forms/gravity-forms.php';
152
  }
153
 
154
  if ( wpzerospam_plugin_integration_enabled( 'bp_registrations' ) ) {
155
+ require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . 'integrations/buddypress/buddypress.php';
156
  }
157
 
158
  if ( wpzerospam_plugin_integration_enabled( 'wpforms' ) ) {
159
+ require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . 'integrations/wpforms/wpforms.php';
160
  }
161
 
162
  if ( wpzerospam_plugin_integration_enabled( 'fluentform' ) ) {
163
+ require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . 'integrations/fluentform/fluentform.php';
164
  }
165
 
166
  if ( wpzerospam_plugin_integration_enabled( 'formidable' ) ) {
167
+ require plugin_dir_path( WORDPRESS_ZERO_SPAM ) . 'integrations/formidable/formidable.php';
168
  }
169
 
170
  /**