Version Description
Download this release
Release Info
Developer | pluginkollektiv |
Plugin | Antispam Bee |
Version | 2.10.0 |
Comparing to | |
See all releases |
Code changes from version 2.9.4 to 2.10.0
- CHANGELOG.md +26 -3
- README.md +0 -65
- antispam_bee.php +375 -205
- behat.yml +47 -0
- css/dashboard.css +2 -1
- css/dashboard.min.css +1 -1
- css/styles.css +121 -132
- css/styles.min.css +1 -1
- docker_tag +1 -0
- inc/gui.class.php +39 -34
- js/dashboard.js +107 -106
- js/dashboard.min.js +4 -4
- js/raphael.helper.js +135 -137
- js/raphael.helper.min.js +4 -5
- js/scripts.js +6 -6
- js/scripts.min.js +2 -1
- output.log +66 -0
- phpunit.xml.dist +0 -25
- readme.txt +15 -4
CHANGELOG.md
CHANGED
@@ -1,5 +1,28 @@
|
|
1 |
## Changelog ##
|
2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
### 2.9.4 ###
|
4 |
* **English**
|
5 |
* Enhancement: Add filter to allow ajax calls
|
@@ -136,7 +159,7 @@
|
|
136 |
* Minor interface improvements
|
137 |
* Remove old russian and Dutch translation files
|
138 |
* For more details see https://github.com/pluginkollektiv/antispam-bee/milestone/4?closed=1
|
139 |
-
|
140 |
* **Deutsch**
|
141 |
- Entfernt stopforumspam.com zur Vorbeugung möglicher DSGVO-Verletzungen
|
142 |
- Verändert den Umgang mit IP-Adressen um der DSGVO zu entsprechen
|
@@ -146,7 +169,7 @@
|
|
146 |
- Verberesserungen an der Benutzeroberfläche
|
147 |
- Entfernt alte russische und holländische Sprachversionen
|
148 |
- Mehr Details: https://github.com/pluginkollektiv/antispam-bee/milestone/4?closed=1
|
149 |
-
|
150 |
### 2.7.1 ###
|
151 |
|
152 |
* **English**
|
@@ -524,7 +547,7 @@
|
|
524 |
* **Deutsch**
|
525 |
* Kompatibilität mit WPtouch
|
526 |
* Unterstützung für do_action hinzugefügt
|
527 |
-
* Übersetzung auf brasilianisches Portugiesisch
|
528 |
|
529 |
### 1.4 ###
|
530 |
* **English**
|
1 |
## Changelog ##
|
2 |
|
3 |
+
### 2.10.0 ###
|
4 |
+
* **English**
|
5 |
+
* Fix: Switch from ip2country.info to iplocate.io for country check
|
6 |
+
* Enhancement: Use filter to add the honeypot field instead of output buffering for new installations and added option to switch between the both ways
|
7 |
+
* Tweak: Added comment user agent to regex pattern check
|
8 |
+
* Tweak: Make the ping detection filterable to support new comment types
|
9 |
+
* Tweak: Updated internal documentation links
|
10 |
+
* Tweak: Several updates and optimizations in the testing process
|
11 |
+
* Tweak: Adjust color palette to recent WP version
|
12 |
+
* Tweak: Adjust wording in variables and option names
|
13 |
+
* Readme: Add new contributor and clean up unused code
|
14 |
+
|
15 |
+
* **Deutsch**
|
16 |
+
* Fix: Wechsel von ip2country.info zu iplocate.io für die Länderprüfung
|
17 |
+
* Verbesserung: Bei neuen Installationen wird ein Filter zum Hinzufügen des Honeypot-Felds genutzt statt Output-Buffering. Es wurde eine Option hinzugefügt, zwischen den beiden Wegen zu wechseln
|
18 |
+
* Tweak: Kommentar User-Agent zu Regex-Pattern hinzugefügt
|
19 |
+
* Tweak: Die Ping-Erkennung ist jetzt filterbar, um neue Kommentartypen zu unterstützen
|
20 |
+
* Tweak: Aktualisierte Links zur internen Dokumentation
|
21 |
+
* Tweak: Verschiedene Aktualisierungen und Optimierungen im Testprozess
|
22 |
+
* Tweak: Farbpalette an aktuelle WP-Version anpassen
|
23 |
+
* Tweak: Wortlaut in Variablen und Optionsnamen wurden angepasst
|
24 |
+
* Readme: Neuer Contributor hinzugefügt und unbenutzten Code bereinigt
|
25 |
+
|
26 |
### 2.9.4 ###
|
27 |
* **English**
|
28 |
* Enhancement: Add filter to allow ajax calls
|
159 |
* Minor interface improvements
|
160 |
* Remove old russian and Dutch translation files
|
161 |
* For more details see https://github.com/pluginkollektiv/antispam-bee/milestone/4?closed=1
|
162 |
+
|
163 |
* **Deutsch**
|
164 |
- Entfernt stopforumspam.com zur Vorbeugung möglicher DSGVO-Verletzungen
|
165 |
- Verändert den Umgang mit IP-Adressen um der DSGVO zu entsprechen
|
169 |
- Verberesserungen an der Benutzeroberfläche
|
170 |
- Entfernt alte russische und holländische Sprachversionen
|
171 |
- Mehr Details: https://github.com/pluginkollektiv/antispam-bee/milestone/4?closed=1
|
172 |
+
|
173 |
### 2.7.1 ###
|
174 |
|
175 |
* **English**
|
547 |
* **Deutsch**
|
548 |
* Kompatibilität mit WPtouch
|
549 |
* Unterstützung für do_action hinzugefügt
|
550 |
+
* Übersetzung auf brasilianisches Portugiesisch
|
551 |
|
552 |
### 1.4 ###
|
553 |
* **English**
|
README.md
DELETED
@@ -1,65 +0,0 @@
|
|
1 |
-
# Antispam Bee #
|
2 |
-
|
3 |
-
[![Build Status](https://travis-ci.org/pluginkollektiv/antispam-bee.svg?branch=master)](https://travis-ci.org/pluginkollektiv/antispam-bee) [![Current Antispam Bee version](https://img.shields.io/wordpress/plugin/v/antispam-bee.svg)](https://wordpress.org/plugins/antispam-bee/) [![Number of downloads](https://img.shields.io/wordpress/plugin/dt/antispam-bee.svg)](https://wordpress.org/plugins/antispam-bee/advanced/) [![Number of active installs](https://img.shields.io/wordpress/plugin/installs/antispam-bee.svg)](https://wordpress.org/plugins/antispam-bee/advanced/) [![WordPress plugin rating](https://img.shields.io/wordpress/plugin/r/antispam-bee.svg)](https://wordpress.org/plugins/antispam-bee/#reviews) [![Donate with PayPal](https://img.shields.io/badge/PayPal-Donate-yellow.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=TD4AMD2D8EMZW)
|
4 |
-
|
5 |
-
Antispam plugin with a sophisticated toolset for effective day to day comment and trackback spam-fighting. Built with data protection and privacy in mind.
|
6 |
-
|
7 |
-
## Description ##
|
8 |
-
Say Goodbye to comment spam on your WordPress blog or website. *Antispam Bee* blocks spam comments and trackbacks effectively and without captchas. It is free of charge, ad-free and compliant with European data privacy standards.
|
9 |
-
|
10 |
-
### Feature/Settings Overview ###
|
11 |
-
* Trust approved commenters.
|
12 |
-
* Trust commenters with a Gravatar.
|
13 |
-
* Consider the comment time.
|
14 |
-
* Treat BBCode links as spam.
|
15 |
-
* Validate the IP address of commenters.
|
16 |
-
* Use regular expressions.
|
17 |
-
* Search local spam database for commenters previously marked as spammers.
|
18 |
-
* Notify admins by e-mail about incoming spam.
|
19 |
-
* Delete existing spam after n days.
|
20 |
-
* Limit approval to comments/pings (will delete other comment types).
|
21 |
-
* Select spam indicators to send comments to deletion directly.
|
22 |
-
* Optionally exclude trackbacks and pingbacks from spam detection.
|
23 |
-
* Optionally spam-check comment forms on archive pages.
|
24 |
-
* Display spam statistics on the dashboard, including daily updates of spam detection rate and a total of blocked spam comments.
|
25 |
-
|
26 |
-
### Support ###
|
27 |
-
* Community support via the [support forums on wordpress.org](https://wordpress.org/support/plugin/antispam-bee)
|
28 |
-
* We don’t handle support via e-mail, Twitter, GitHub issues etc.
|
29 |
-
|
30 |
-
### Contribute ###
|
31 |
-
* Active development of this plugin is handled [on GitHub](https://github.com/pluginkollektiv/antispam-bee).
|
32 |
-
* Pull requests for documented bugs are highly appreciated.
|
33 |
-
* If you think you’ve found a bug (e.g. you’re experiencing unexpected behavior), please post at the [support forums](https://wordpress.org/support/plugin/antispam-bee) first.
|
34 |
-
* If you want to help us translate this plugin you can do so [on WordPress Translate](https://translate.wordpress.org/projects/wp-plugins/antispam-bee).
|
35 |
-
* To test the plugin on your local machine, simply run `docker-compose up` in the root folder and open `http://localhost:8081/` in your browser.
|
36 |
-
|
37 |
-
### Donate
|
38 |
-
[Donate for us via Paypal](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=TD4AMD2D8EMZW)
|
39 |
-
|
40 |
-
### Credits ###
|
41 |
-
* Author: [Sergej Müller](https://sergejmueller.github.io/)
|
42 |
-
* Maintainers: [pluginkollektiv](https://pluginkollektiv.org)
|
43 |
-
|
44 |
-
## Installation ##
|
45 |
-
* If you don’t know how to install a plugin for WordPress, [here’s how](http://codex.wordpress.org/Managing_Plugins#Installing_Plugins).
|
46 |
-
|
47 |
-
### Requirements ###
|
48 |
-
* PHP 5.2.4 or greater
|
49 |
-
* WordPress 4.5 or greater
|
50 |
-
|
51 |
-
### Settings ###
|
52 |
-
After you have activated *Antispam Bee* the plugin will block spam comments out of the box. However, you may want to visit *Settings → Antispam Bee* to configure your custom set of anti-spam options that works best for your site.
|
53 |
-
|
54 |
-
### Privacy Notice ###
|
55 |
-
On sites operating from within the EU the option *Use a public antispam database* should not be activated for privacy reasons. When that option has been activated, *Antispam Bee* will match full IP addresses from comments against a public spam database. Technically it is not possible to encrypt those IPs, because spam databases only store and operate with complete, unencrypted IP addresses.
|
56 |
-
|
57 |
-
## Frequently Asked Questions ##
|
58 |
-
|
59 |
-
Please have a look [in the FAQ pages](https://github.com/pluginkollektiv/antispam-bee/wiki/en-FAQ).
|
60 |
-
|
61 |
-
A complete documentation is available in the [GitHub repository Wiki](https://github.com/pluginkollektiv/antispam-bee/wiki).
|
62 |
-
|
63 |
-
## Changelog ##
|
64 |
-
|
65 |
-
[Changelog](https://github.com/pluginkollektiv/antispam-bee/blob/master/CHANGELOG.md).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
antispam_bee.php
CHANGED
@@ -9,9 +9,7 @@
|
|
9 |
* Domain Path: /lang
|
10 |
* License: GPLv2 or later
|
11 |
* License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
12 |
-
* Version: 2.
|
13 |
-
*
|
14 |
-
* [](http://coderisk.com/wp/plugin/antispam-bee/RIPS-lAHLcgvqY8)
|
15 |
*
|
16 |
* @package Antispam Bee
|
17 |
**/
|
@@ -41,8 +39,8 @@ defined( 'ABSPATH' ) || exit;
|
|
41 |
/**
|
42 |
* Antispam_Bee
|
43 |
*
|
44 |
-
* @since
|
45 |
-
* @
|
46 |
*/
|
47 |
class Antispam_Bee {
|
48 |
|
@@ -58,7 +56,7 @@ class Antispam_Bee {
|
|
58 |
*
|
59 |
* @var int
|
60 |
*/
|
61 |
-
private static $db_version = 1.
|
62 |
|
63 |
/**
|
64 |
* The base.
|
@@ -91,10 +89,31 @@ class Antispam_Bee {
|
|
91 |
/**
|
92 |
* "Constructor" of the class
|
93 |
*
|
94 |
-
* @since
|
95 |
-
* @
|
|
|
96 |
*/
|
97 |
public static function init() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
98 |
add_action(
|
99 |
'unspam_comment',
|
100 |
array(
|
@@ -302,13 +321,24 @@ class Antispam_Bee {
|
|
302 |
)
|
303 |
);
|
304 |
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
312 |
add_action(
|
313 |
'init',
|
314 |
array(
|
@@ -345,13 +375,16 @@ class Antispam_Bee {
|
|
345 |
/**
|
346 |
* Action during the activation of the Plugins
|
347 |
*
|
348 |
-
* @since
|
349 |
-
* @
|
|
|
350 |
*/
|
351 |
public static function activate() {
|
352 |
add_option(
|
353 |
'antispam_bee',
|
354 |
-
array(
|
|
|
|
|
355 |
'',
|
356 |
'no'
|
357 |
);
|
@@ -365,8 +398,8 @@ class Antispam_Bee {
|
|
365 |
/**
|
366 |
* Action to deactivate the plugin
|
367 |
*
|
368 |
-
* @since
|
369 |
-
* @
|
370 |
*/
|
371 |
public static function deactivate() {
|
372 |
self::clear_scheduled_hook();
|
@@ -376,8 +409,7 @@ class Antispam_Bee {
|
|
376 |
/**
|
377 |
* Action deleting the plugin
|
378 |
*
|
379 |
-
* @since
|
380 |
-
* @change 2.4
|
381 |
*/
|
382 |
public static function uninstall() {
|
383 |
if ( ! self::get_option( 'delete_data_on_uninstall' ) ) {
|
@@ -388,10 +420,10 @@ class Antispam_Bee {
|
|
388 |
delete_option( 'antispam_bee' );
|
389 |
$wpdb->query( 'OPTIMIZE TABLE `' . $wpdb->options . '`' );
|
390 |
|
391 |
-
//phpcs:disable WordPress.
|
392 |
$sql = 'delete from `' . $wpdb->commentmeta . '` where `meta_key` IN ("antispam_bee_iphash", "antispam_bee_reason")';
|
393 |
$wpdb->query( $sql );
|
394 |
-
//phpcs:enable WordPress.
|
395 |
}
|
396 |
|
397 |
|
@@ -405,8 +437,9 @@ class Antispam_Bee {
|
|
405 |
/**
|
406 |
* Initialization of the internal variables
|
407 |
*
|
408 |
-
* @since
|
409 |
-
* @
|
|
|
410 |
*/
|
411 |
private static function _init_internal_vars() {
|
412 |
self::$_base = plugin_basename( __FILE__ );
|
@@ -422,14 +455,13 @@ class Antispam_Bee {
|
|
422 |
'gravatar_check' => 0,
|
423 |
'time_check' => 0,
|
424 |
'ignore_pings' => 0,
|
425 |
-
'always_allowed' => 0,
|
426 |
|
427 |
'dashboard_chart' => 0,
|
428 |
'dashboard_count' => 0,
|
429 |
|
430 |
'country_code' => 0,
|
431 |
-
'
|
432 |
-
'
|
433 |
|
434 |
'translate_api' => 0,
|
435 |
'translate_lang' => array(),
|
@@ -470,26 +502,44 @@ class Antispam_Bee {
|
|
470 |
* Check and return an array key
|
471 |
*
|
472 |
* @since 2.4.2
|
473 |
-
* @
|
474 |
*
|
475 |
* @param array $array Array with values.
|
476 |
* @param string $key Name of the key.
|
477 |
* @return mixed Value of the requested key.
|
478 |
*/
|
479 |
public static function get_key( $array, $key ) {
|
480 |
-
if ( empty( $array ) || empty( $key ) ||
|
481 |
return null;
|
482 |
}
|
483 |
|
484 |
return $array[ $key ];
|
485 |
}
|
486 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
487 |
|
488 |
/**
|
489 |
* Localization of the admin pages
|
490 |
*
|
491 |
* @since 0.1
|
492 |
-
* @
|
493 |
*
|
494 |
* @param string $page Mark the page.
|
495 |
* @return boolean True on success.
|
@@ -522,8 +572,8 @@ class Antispam_Bee {
|
|
522 |
/**
|
523 |
* Integration of the localization file
|
524 |
*
|
525 |
-
* @since
|
526 |
-
* @
|
527 |
*/
|
528 |
public static function load_plugin_lang() {
|
529 |
load_plugin_textdomain(
|
@@ -535,8 +585,7 @@ class Antispam_Bee {
|
|
535 |
/**
|
536 |
* Add the link to the settings
|
537 |
*
|
538 |
-
* @since
|
539 |
-
* @change 1.1
|
540 |
*
|
541 |
* @param array $data The action link array.
|
542 |
* @return array $data The action link array.
|
@@ -566,8 +615,8 @@ class Antispam_Bee {
|
|
566 |
/**
|
567 |
* Meta links of the plugin
|
568 |
*
|
569 |
-
* @since
|
570 |
-
* @
|
571 |
*
|
572 |
* @param array $input Existing links.
|
573 |
* @param string $file Current page.
|
@@ -596,8 +645,8 @@ class Antispam_Bee {
|
|
596 |
/**
|
597 |
* Registration of resources (CSS & JS)
|
598 |
*
|
599 |
-
* @since
|
600 |
-
* @
|
601 |
*/
|
602 |
public static function init_plugin_sources() {
|
603 |
$plugin = get_plugin_data( __FILE__ );
|
@@ -621,8 +670,8 @@ class Antispam_Bee {
|
|
621 |
/**
|
622 |
* Initialization of the option page
|
623 |
*
|
624 |
-
* @since
|
625 |
-
* @
|
626 |
*/
|
627 |
public static function add_sidebar_menu() {
|
628 |
$page = add_options_page(
|
@@ -665,8 +714,8 @@ class Antispam_Bee {
|
|
665 |
/**
|
666 |
* Initialization of JavaScript
|
667 |
*
|
668 |
-
* @since
|
669 |
-
* @
|
670 |
*/
|
671 |
public static function add_options_script() {
|
672 |
wp_enqueue_script( 'ab_script' );
|
@@ -676,8 +725,8 @@ class Antispam_Bee {
|
|
676 |
/**
|
677 |
* Initialization of Stylesheets
|
678 |
*
|
679 |
-
* @since
|
680 |
-
* @
|
681 |
*/
|
682 |
public static function add_options_style() {
|
683 |
wp_enqueue_style( 'ab_style' );
|
@@ -688,7 +737,6 @@ class Antispam_Bee {
|
|
688 |
* Integration of the GUI
|
689 |
*
|
690 |
* @since 2.4
|
691 |
-
* @change 2.4
|
692 |
*/
|
693 |
public static function init_options_page() {
|
694 |
require_once dirname( __FILE__ ) . '/inc/gui.class.php';
|
@@ -705,8 +753,8 @@ class Antispam_Bee {
|
|
705 |
/**
|
706 |
* Display the spam counter on the dashboard
|
707 |
*
|
708 |
-
* @since
|
709 |
-
* @
|
710 |
*
|
711 |
* @param array $items Initial array with dashboard items.
|
712 |
* @return array $items Merged array with dashboard items.
|
@@ -732,8 +780,8 @@ class Antispam_Bee {
|
|
732 |
/**
|
733 |
* Initialize the dashboard chart
|
734 |
*
|
735 |
-
* @since
|
736 |
-
* @
|
737 |
*/
|
738 |
public static function add_dashboard_chart() {
|
739 |
if ( ! current_user_can( 'publish_posts' ) || ! self::get_option( 'dashboard_chart' ) ) {
|
@@ -761,8 +809,8 @@ class Antispam_Bee {
|
|
761 |
/**
|
762 |
* Print dashboard styles
|
763 |
*
|
764 |
-
* @since
|
765 |
-
* @
|
766 |
*/
|
767 |
public static function add_dashboard_style() {
|
768 |
$plugin = get_plugin_data( __FILE__ );
|
@@ -781,8 +829,8 @@ class Antispam_Bee {
|
|
781 |
/**
|
782 |
* Print dashboard scripts
|
783 |
*
|
784 |
-
* @since
|
785 |
-
* @
|
786 |
*/
|
787 |
public static function add_dashboard_script() {
|
788 |
if ( ! self::get_option( 'daily_stats' ) ) {
|
@@ -819,8 +867,8 @@ class Antispam_Bee {
|
|
819 |
/**
|
820 |
* Print dashboard html
|
821 |
*
|
822 |
-
* @since
|
823 |
-
* @
|
824 |
*/
|
825 |
public static function show_spam_chart() {
|
826 |
$items = (array) self::get_option( 'daily_stats' );
|
@@ -866,8 +914,8 @@ class Antispam_Bee {
|
|
866 |
/**
|
867 |
* Get all plugin options
|
868 |
*
|
869 |
-
* @since
|
870 |
-
* @
|
871 |
*
|
872 |
* @return array $options Array with option fields.
|
873 |
*/
|
@@ -893,8 +941,8 @@ class Antispam_Bee {
|
|
893 |
/**
|
894 |
* Get single option field
|
895 |
*
|
896 |
-
* @since
|
897 |
-
* @
|
898 |
*
|
899 |
* @param string $field Field name.
|
900 |
* @return mixed Field value.
|
@@ -909,8 +957,8 @@ class Antispam_Bee {
|
|
909 |
/**
|
910 |
* Update single option field
|
911 |
*
|
912 |
-
* @since
|
913 |
-
* @
|
914 |
*
|
915 |
* @param string $field Field name.
|
916 |
* @param mixed $value The Field value.
|
@@ -927,8 +975,8 @@ class Antispam_Bee {
|
|
927 |
/**
|
928 |
* Update multiple option fields
|
929 |
*
|
930 |
-
* @since
|
931 |
-
* @
|
932 |
*
|
933 |
* @param array $data Array with plugin option fields.
|
934 |
*/
|
@@ -966,8 +1014,8 @@ class Antispam_Bee {
|
|
966 |
/**
|
967 |
* Execution of the daily cronjobs
|
968 |
*
|
969 |
-
* @since
|
970 |
-
* @
|
971 |
*/
|
972 |
public static function start_daily_cronjob() {
|
973 |
if ( ! self::get_option( 'cronjob_enable' ) ) {
|
@@ -986,8 +1034,8 @@ class Antispam_Bee {
|
|
986 |
/**
|
987 |
* Delete old spam comments
|
988 |
*
|
989 |
-
* @since
|
990 |
-
* @
|
991 |
*/
|
992 |
private static function _delete_old_spam() {
|
993 |
$days = (int) self::get_option( 'cronjob_interval' );
|
@@ -1012,8 +1060,8 @@ class Antispam_Bee {
|
|
1012 |
/**
|
1013 |
* Initialization of the cronjobs
|
1014 |
*
|
1015 |
-
* @since
|
1016 |
-
* @
|
1017 |
*/
|
1018 |
public static function init_scheduled_hook() {
|
1019 |
if ( ! wp_next_scheduled( 'antispam_bee_daily_cronjob' ) ) {
|
@@ -1029,8 +1077,8 @@ class Antispam_Bee {
|
|
1029 |
/**
|
1030 |
* Deletion of the cronjobs
|
1031 |
*
|
1032 |
-
* @since
|
1033 |
-
* @
|
1034 |
*/
|
1035 |
public static function clear_scheduled_hook() {
|
1036 |
if ( wp_next_scheduled( 'antispam_bee_daily_cronjob' ) ) {
|
@@ -1049,11 +1097,11 @@ class Antispam_Bee {
|
|
1049 |
/**
|
1050 |
* Check POST values
|
1051 |
*
|
1052 |
-
* @since
|
1053 |
-
* @
|
1054 |
*/
|
1055 |
public static function precheck_incoming_request() {
|
1056 |
-
// phpcs:disable WordPress.
|
1057 |
if ( is_feed() || is_trackback() || empty( $_POST ) || self::_is_mobile() ) {
|
1058 |
return;
|
1059 |
}
|
@@ -1075,15 +1123,16 @@ class Antispam_Bee {
|
|
1075 |
} else {
|
1076 |
$_POST['ab_spam__hidden_field'] = 1;
|
1077 |
}
|
1078 |
-
// phpcs:enable WordPress.
|
1079 |
}
|
1080 |
|
1081 |
|
1082 |
/**
|
1083 |
* Check incoming requests for spam
|
1084 |
*
|
1085 |
-
* @since
|
1086 |
-
* @
|
|
|
1087 |
*
|
1088 |
* @param array $comment Untreated comment.
|
1089 |
* @return array $comment Treated comment.
|
@@ -1101,15 +1150,12 @@ class Antispam_Bee {
|
|
1101 |
);
|
1102 |
}
|
1103 |
|
1104 |
-
$
|
1105 |
-
'types' => array( 'pingback', 'trackback', 'pings' ),
|
1106 |
-
'allowed' => ! self::get_option( 'ignore_pings' ),
|
1107 |
-
);
|
1108 |
|
1109 |
-
// phpcs:disable WordPress.
|
1110 |
// Everybody can post.
|
1111 |
if ( strpos( $request_path, 'wp-comments-post.php' ) !== false && ! empty( $_POST ) ) {
|
1112 |
-
// phpcs:enable WordPress.
|
1113 |
$status = self::_verify_comment_request( $comment );
|
1114 |
|
1115 |
if ( ! empty( $status['reason'] ) ) {
|
@@ -1118,7 +1164,7 @@ class Antispam_Bee {
|
|
1118 |
$status['reason']
|
1119 |
);
|
1120 |
}
|
1121 |
-
} elseif (
|
1122 |
$status = self::_verify_trackback_request( $comment );
|
1123 |
|
1124 |
if ( ! empty( $status['reason'] ) ) {
|
@@ -1133,43 +1179,37 @@ class Antispam_Bee {
|
|
1133 |
return $comment;
|
1134 |
}
|
1135 |
|
1136 |
-
|
1137 |
/**
|
1138 |
-
* Prepares the replacement of the comment field
|
1139 |
*
|
1140 |
-
* @since
|
1141 |
-
* @change 2.4
|
1142 |
*/
|
1143 |
-
public static function
|
1144 |
if ( is_feed() || is_trackback() || is_robots() || self::_is_mobile() ) {
|
1145 |
return;
|
1146 |
}
|
1147 |
|
1148 |
-
if ( ! is_singular() && ! self::get_option( 'always_allowed' ) ) {
|
1149 |
-
return;
|
1150 |
-
}
|
1151 |
-
|
1152 |
ob_start(
|
1153 |
array(
|
1154 |
'Antispam_Bee',
|
1155 |
-
'
|
1156 |
)
|
1157 |
);
|
1158 |
}
|
1159 |
|
1160 |
|
1161 |
/**
|
1162 |
-
*
|
1163 |
*
|
1164 |
-
* @since
|
1165 |
-
* @
|
|
|
1166 |
*
|
1167 |
-
* @param
|
1168 |
-
* @return string Treated HTML code.
|
1169 |
*/
|
1170 |
-
public static function
|
1171 |
if ( empty( $data ) ) {
|
1172 |
-
return;
|
1173 |
}
|
1174 |
|
1175 |
if ( ! preg_match( '#<textarea.+?name=["\']comment["\']#s', $data ) ) {
|
@@ -1250,8 +1290,8 @@ class Antispam_Bee {
|
|
1250 |
/**
|
1251 |
* Check the trackbacks
|
1252 |
*
|
1253 |
-
* @since
|
1254 |
-
* @
|
1255 |
*
|
1256 |
* @param array $comment Trackback data.
|
1257 |
* @return array Array with suspected reason.
|
@@ -1370,18 +1410,20 @@ class Antispam_Bee {
|
|
1370 |
/**
|
1371 |
* Check the comment
|
1372 |
*
|
1373 |
-
* @since
|
1374 |
-
* @
|
|
|
1375 |
*
|
1376 |
* @param array $comment Data of the comment.
|
1377 |
* @return array|void Array with suspected reason
|
1378 |
*/
|
1379 |
private static function _verify_comment_request( $comment ) {
|
1380 |
-
$ip
|
1381 |
-
$url
|
1382 |
-
$body
|
1383 |
-
$email
|
1384 |
-
$author
|
|
|
1385 |
|
1386 |
if ( empty( $body ) ) {
|
1387 |
return array(
|
@@ -1411,13 +1453,13 @@ class Antispam_Bee {
|
|
1411 |
return;
|
1412 |
}
|
1413 |
|
1414 |
-
// phpcs:disable WordPress.
|
1415 |
if ( ! empty( $_POST['ab_spam__hidden_field'] ) ) {
|
1416 |
return array(
|
1417 |
'reason' => 'css',
|
1418 |
);
|
1419 |
}
|
1420 |
-
// phpcs:enable WordPress.
|
1421 |
|
1422 |
if ( $options['time_check'] && self::_is_shortest_time() ) {
|
1423 |
return array(
|
@@ -1433,12 +1475,13 @@ class Antispam_Bee {
|
|
1433 |
|
1434 |
if ( $options['regexp_check'] && self::_is_regexp_spam(
|
1435 |
array(
|
1436 |
-
'ip'
|
1437 |
-
'rawurl'
|
1438 |
-
'host'
|
1439 |
-
'body'
|
1440 |
-
'email'
|
1441 |
-
'author'
|
|
|
1442 |
)
|
1443 |
) ) {
|
1444 |
return array(
|
@@ -1469,8 +1512,7 @@ class Antispam_Bee {
|
|
1469 |
/**
|
1470 |
* Check for a Gravatar image
|
1471 |
*
|
1472 |
-
* @since
|
1473 |
-
* @change 2.6.5
|
1474 |
*
|
1475 |
* @param string $email Input email.
|
1476 |
* @return boolean Check status (true = Gravatar available).
|
@@ -1499,15 +1541,14 @@ class Antispam_Bee {
|
|
1499 |
* Check for comment action time
|
1500 |
*
|
1501 |
* @since 2.6.4
|
1502 |
-
* @change 2.6.4
|
1503 |
*
|
1504 |
* @return boolean TRUE if the action time is less than 5 seconds
|
1505 |
*/
|
1506 |
private static function _is_shortest_time() {
|
1507 |
-
// phpcs:disable WordPress.
|
1508 |
// Everybody can Post.
|
1509 |
$init_time = (int) self::get_key( $_POST, 'ab_init_time' );
|
1510 |
-
// phpcs:enable WordPress.
|
1511 |
if ( 0 === $init_time ) {
|
1512 |
return false;
|
1513 |
}
|
@@ -1541,8 +1582,9 @@ class Antispam_Bee {
|
|
1541 |
/**
|
1542 |
* Usage of regexp, also custom
|
1543 |
*
|
1544 |
-
* @since
|
1545 |
-
* @
|
|
|
1546 |
*
|
1547 |
* @param array $comment Array with commentary data.
|
1548 |
* @return boolean True for suspicious comment.
|
@@ -1554,6 +1596,7 @@ class Antispam_Bee {
|
|
1554 |
'body',
|
1555 |
'email',
|
1556 |
'author',
|
|
|
1557 |
);
|
1558 |
|
1559 |
$patterns = array(
|
@@ -1652,8 +1695,8 @@ class Antispam_Bee {
|
|
1652 |
/**
|
1653 |
* Review a comment on its existence in the local spam
|
1654 |
*
|
1655 |
-
* @since
|
1656 |
-
* @
|
1657 |
*
|
1658 |
* @param string $ip Comment IP.
|
1659 |
* @param string $url Comment URL (optional).
|
@@ -1682,7 +1725,7 @@ class Antispam_Bee {
|
|
1682 |
return false;
|
1683 |
}
|
1684 |
|
1685 |
-
// phpcs:disable WordPress.
|
1686 |
// phpcs:disable WordPress.DB.PreparedSQLPlaceholders.ReplacementsWrongNumber
|
1687 |
$filter_sql = implode( ' OR ', $filter );
|
1688 |
|
@@ -1696,7 +1739,7 @@ class Antispam_Bee {
|
|
1696 |
)
|
1697 |
);
|
1698 |
// phpcs:enable WordPress.DB.PreparedSQLPlaceholders.ReplacementsWrongNumber
|
1699 |
-
// phpcs:enable WordPress.
|
1700 |
|
1701 |
return ! empty( $result );
|
1702 |
}
|
@@ -1705,8 +1748,8 @@ class Antispam_Bee {
|
|
1705 |
/**
|
1706 |
* Check for country spam by (anonymized) IP
|
1707 |
*
|
1708 |
-
* @since
|
1709 |
-
* @
|
1710 |
*
|
1711 |
* @param string $ip IP address.
|
1712 |
* @return boolean True if the comment is spam based on country filter.
|
@@ -1714,28 +1757,58 @@ class Antispam_Bee {
|
|
1714 |
private static function _is_country_spam( $ip ) {
|
1715 |
$options = self::get_options();
|
1716 |
|
1717 |
-
$
|
1718 |
'/[\s,;]+/',
|
1719 |
-
$options['
|
1720 |
-1,
|
1721 |
PREG_SPLIT_NO_EMPTY
|
1722 |
);
|
1723 |
-
$
|
1724 |
'/[\s,;]+/',
|
1725 |
-
$options['
|
1726 |
-1,
|
1727 |
PREG_SPLIT_NO_EMPTY
|
1728 |
);
|
1729 |
|
1730 |
-
if ( empty( $
|
1731 |
return false;
|
1732 |
}
|
1733 |
|
1734 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1735 |
esc_url_raw(
|
1736 |
sprintf(
|
1737 |
-
'https://
|
1738 |
-
self::_anonymize_ip( $ip )
|
|
|
1739 |
),
|
1740 |
'https'
|
1741 |
)
|
@@ -1749,17 +1822,30 @@ class Antispam_Bee {
|
|
1749 |
return false;
|
1750 |
}
|
1751 |
|
1752 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1753 |
|
1754 |
if ( empty( $country ) || strlen( $country ) !== 2 ) {
|
1755 |
return false;
|
1756 |
}
|
1757 |
|
1758 |
-
if ( ! empty( $
|
1759 |
-
return ( in_array( $country, $
|
1760 |
}
|
1761 |
|
1762 |
-
return ( ! in_array( $country, $
|
1763 |
}
|
1764 |
|
1765 |
|
@@ -1767,7 +1853,6 @@ class Antispam_Bee {
|
|
1767 |
* Check for BBCode spam
|
1768 |
*
|
1769 |
* @since 2.5.1
|
1770 |
-
* @change 2.5.1
|
1771 |
*
|
1772 |
* @param string $body Content of a comment.
|
1773 |
* @return boolean True for BBCode in content
|
@@ -1780,8 +1865,8 @@ class Antispam_Bee {
|
|
1780 |
/**
|
1781 |
* Check for an already approved e-mail address
|
1782 |
*
|
1783 |
-
* @since
|
1784 |
-
* @
|
1785 |
*
|
1786 |
* @param string $email E-mail address.
|
1787 |
* @return boolean True for a found entry.
|
@@ -1806,9 +1891,9 @@ class Antispam_Bee {
|
|
1806 |
/**
|
1807 |
* Check for unwanted languages
|
1808 |
*
|
1809 |
-
* @since
|
1810 |
-
* @
|
1811 |
-
* @
|
1812 |
*
|
1813 |
* @param string $comment_content Content of the comment.
|
1814 |
*
|
@@ -1846,7 +1931,7 @@ class Antispam_Bee {
|
|
1846 |
* enter 'characters_excluding_spaces' or 'characters_including_spaces'. Otherwise, enter 'words'.
|
1847 |
* Do not translate into your own language.
|
1848 |
*/
|
1849 |
-
if ( strpos( _x( 'words', 'Word count type. Do not translate!' ), 'characters' ) === 0 && preg_match( '/^utf\-?8$/i', get_option( 'blog_charset' ) ) ) {
|
1850 |
preg_match_all( '/./u', $text, $words_array );
|
1851 |
if ( isset( $words_array[0] ) ) {
|
1852 |
$word_count = count( $words_array[0] );
|
@@ -2091,8 +2176,8 @@ class Antispam_Bee {
|
|
2091 |
/**
|
2092 |
* Trim IP addresses
|
2093 |
*
|
2094 |
-
* @since
|
2095 |
-
* @
|
2096 |
*
|
2097 |
* @param string $ip Original IP.
|
2098 |
* @param boolean $cut_end Shortening the end.
|
@@ -2113,7 +2198,6 @@ class Antispam_Bee {
|
|
2113 |
* Anonymize the IP addresses
|
2114 |
*
|
2115 |
* @since 2.5.1
|
2116 |
-
* @change 2.5.1
|
2117 |
*
|
2118 |
* @param string $ip Original IP.
|
2119 |
* @return string Anonymous IP.
|
@@ -2131,7 +2215,6 @@ class Antispam_Bee {
|
|
2131 |
* Rotates the IP address
|
2132 |
*
|
2133 |
* @since 2.4.5
|
2134 |
-
* @change 2.4.5
|
2135 |
*
|
2136 |
* @param string $ip IP address.
|
2137 |
* @return string Turned IP address.
|
@@ -2152,8 +2235,8 @@ class Antispam_Bee {
|
|
2152 |
/**
|
2153 |
* Check for an IPv4 address
|
2154 |
*
|
2155 |
-
* @since
|
2156 |
-
* @
|
2157 |
*
|
2158 |
* @param string $ip IP to validate.
|
2159 |
* @return integer TRUE if IPv4.
|
@@ -2170,8 +2253,8 @@ class Antispam_Bee {
|
|
2170 |
/**
|
2171 |
* Check for an IPv6 address
|
2172 |
*
|
2173 |
-
* @since
|
2174 |
-
* @
|
2175 |
*
|
2176 |
* @param string $ip IP to validate.
|
2177 |
* @return boolean TRUE if IPv6.
|
@@ -2188,8 +2271,8 @@ class Antispam_Bee {
|
|
2188 |
/**
|
2189 |
* Testing on mobile devices
|
2190 |
*
|
2191 |
-
* @since
|
2192 |
-
* @
|
2193 |
*
|
2194 |
* @return boolean TRUE if "wptouch" is active
|
2195 |
*/
|
@@ -2220,13 +2303,13 @@ class Antispam_Bee {
|
|
2220 |
/**
|
2221 |
* Execution of the delete/marking process
|
2222 |
*
|
2223 |
-
* @since
|
2224 |
-
* @
|
2225 |
*
|
2226 |
* @param array $comment Untreated commentary data.
|
2227 |
* @param string $reason Reason for suspicion.
|
2228 |
* @param boolean $is_ping Ping (optional).
|
2229 |
-
* @return array
|
2230 |
*/
|
2231 |
private static function _handle_spam_request( $comment, $reason, $is_ping = false ) {
|
2232 |
|
@@ -2296,8 +2379,8 @@ class Antispam_Bee {
|
|
2296 |
/**
|
2297 |
* Logfile with detected spam
|
2298 |
*
|
2299 |
-
* @since
|
2300 |
-
* @
|
2301 |
*
|
2302 |
* @param array $comment Array with commentary data.
|
2303 |
* @return mixed FALSE in case of error
|
@@ -2327,7 +2410,6 @@ class Antispam_Bee {
|
|
2327 |
* Sends the 403 header and terminates the connection
|
2328 |
*
|
2329 |
* @since 2.5.6
|
2330 |
-
* @change 2.5.6
|
2331 |
*/
|
2332 |
private static function _go_in_peace() {
|
2333 |
status_header( 403 );
|
@@ -2339,12 +2421,11 @@ class Antispam_Bee {
|
|
2339 |
* Return real client IP
|
2340 |
*
|
2341 |
* @since 2.6.1
|
2342 |
-
* @change 2.6.1
|
2343 |
*
|
2344 |
* @return mixed $ip Client IP
|
2345 |
*/
|
2346 |
public static function get_client_ip() {
|
2347 |
-
// phpcs:disable WordPress.
|
2348 |
// Sanitization of $ip takes place further down.
|
2349 |
$ip = '';
|
2350 |
|
@@ -2371,7 +2452,7 @@ class Antispam_Bee {
|
|
2371 |
}
|
2372 |
|
2373 |
return '';
|
2374 |
-
// phpcs:enable WordPress.
|
2375 |
}
|
2376 |
|
2377 |
/**
|
@@ -2406,7 +2487,6 @@ class Antispam_Bee {
|
|
2406 |
* Add spam reason as comment data
|
2407 |
*
|
2408 |
* @since 2.6.0
|
2409 |
-
* @change 2.6.0
|
2410 |
*
|
2411 |
* @param integer $comment_id Comment ID.
|
2412 |
*/
|
@@ -2423,7 +2503,6 @@ class Antispam_Bee {
|
|
2423 |
* Delete spam reason as comment data
|
2424 |
*
|
2425 |
* @since 2.6.0
|
2426 |
-
* @change 2.6.0
|
2427 |
*
|
2428 |
* @param integer $comment_id Comment ID.
|
2429 |
*/
|
@@ -2461,8 +2540,9 @@ class Antispam_Bee {
|
|
2461 |
/**
|
2462 |
* Send notification via e-mail
|
2463 |
*
|
2464 |
-
* @since
|
2465 |
-
* @
|
|
|
2466 |
*
|
2467 |
* @hook string antispam_bee_notification_subject Custom subject for notification mails
|
2468 |
*
|
@@ -2492,6 +2572,7 @@ class Antispam_Bee {
|
|
2492 |
$subject = sprintf(
|
2493 |
'[%s] %s',
|
2494 |
stripslashes_deep(
|
|
|
2495 |
html_entity_decode(
|
2496 |
get_bloginfo( 'name' ),
|
2497 |
ENT_QUOTES
|
@@ -2570,7 +2651,7 @@ class Antispam_Bee {
|
|
2570 |
) . sprintf(
|
2571 |
"%s\r\n%s\r\n",
|
2572 |
esc_html__( 'Notify message by Antispam Bee', 'antispam-bee' ),
|
2573 |
-
esc_html__( 'https://antispambee.
|
2574 |
);
|
2575 |
|
2576 |
wp_mail(
|
@@ -2609,8 +2690,8 @@ class Antispam_Bee {
|
|
2609 |
/**
|
2610 |
* Return the number of spam comments
|
2611 |
*
|
2612 |
-
* @since
|
2613 |
-
* @
|
2614 |
*/
|
2615 |
private static function _get_spam_count() {
|
2616 |
// Init.
|
@@ -2624,8 +2705,8 @@ class Antispam_Bee {
|
|
2624 |
/**
|
2625 |
* Output the number of spam comments
|
2626 |
*
|
2627 |
-
* @since
|
2628 |
-
* @
|
2629 |
*/
|
2630 |
public static function the_spam_count() {
|
2631 |
echo esc_html( self::_get_spam_count() );
|
@@ -2635,8 +2716,8 @@ class Antispam_Bee {
|
|
2635 |
/**
|
2636 |
* Update the number of spam comments
|
2637 |
*
|
2638 |
-
* @since
|
2639 |
-
* @
|
2640 |
*/
|
2641 |
private static function _update_spam_count() {
|
2642 |
// Skip if not enabled.
|
@@ -2653,8 +2734,8 @@ class Antispam_Bee {
|
|
2653 |
/**
|
2654 |
* Update statistics
|
2655 |
*
|
2656 |
-
* @since
|
2657 |
-
* @
|
2658 |
*/
|
2659 |
private static function _update_daily_stats() {
|
2660 |
// Skip if not enabled.
|
@@ -2686,17 +2767,14 @@ class Antispam_Bee {
|
|
2686 |
/**
|
2687 |
* Returns the secret of a post used in the textarea name attribute.
|
2688 |
*
|
|
|
|
|
2689 |
* @param int $post_id The Post ID.
|
2690 |
*
|
2691 |
* @return string
|
2692 |
*/
|
2693 |
public static function get_secret_name_for_post( $post_id ) {
|
2694 |
-
|
2695 |
-
if ( self::get_option( 'always_allowed' ) ) {
|
2696 |
-
$secret = substr( sha1( md5( 'comment-id' . self::$_salt ) ), 0, 10 );
|
2697 |
-
} else {
|
2698 |
-
$secret = substr( sha1( md5( 'comment-id' . self::$_salt . (int) $post_id ) ), 0, 10 );
|
2699 |
-
}
|
2700 |
|
2701 |
$secret = self::ensure_secret_starts_with_letter( $secret );
|
2702 |
|
@@ -2719,17 +2797,15 @@ class Antispam_Bee {
|
|
2719 |
/**
|
2720 |
* Returns the secret of a post used in the textarea id attribute.
|
2721 |
*
|
|
|
|
|
2722 |
* @param int $post_id The post ID.
|
2723 |
*
|
2724 |
* @return string
|
2725 |
*/
|
2726 |
public static function get_secret_id_for_post( $post_id ) {
|
2727 |
|
2728 |
-
|
2729 |
-
$secret = substr( sha1( md5( 'comment-id' . self::$_salt ) ), 0, 10 );
|
2730 |
-
} else {
|
2731 |
-
$secret = substr( sha1( md5( 'comment-id' . self::$_salt . (int) $post_id ) ), 0, 10 );
|
2732 |
-
}
|
2733 |
|
2734 |
$secret = self::ensure_secret_starts_with_letter( $secret );
|
2735 |
|
@@ -2795,22 +2871,51 @@ class Antispam_Bee {
|
|
2795 |
|
2796 |
/**
|
2797 |
* Updates the database structure if necessary
|
|
|
|
|
2798 |
*/
|
2799 |
public static function update_database() {
|
2800 |
if ( self::db_version_is_current() ) {
|
2801 |
return;
|
2802 |
}
|
2803 |
|
2804 |
-
|
|
|
|
|
2805 |
|
2806 |
-
|
2807 |
-
|
2808 |
-
|
2809 |
-
|
2810 |
-
|
2811 |
-
|
2812 |
-
|
2813 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2814 |
|
2815 |
update_option( 'antispambee_db_version', self::$db_version );
|
2816 |
}
|
@@ -2818,14 +2923,79 @@ class Antispam_Bee {
|
|
2818 |
/**
|
2819 |
* Whether the database structure is up to date.
|
2820 |
*
|
|
|
|
|
2821 |
* @return bool
|
2822 |
*/
|
2823 |
private static function db_version_is_current() {
|
2824 |
|
2825 |
-
$current_version =
|
2826 |
return $current_version === self::$db_version;
|
2827 |
|
2828 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2829 |
}
|
2830 |
|
2831 |
|
9 |
* Domain Path: /lang
|
10 |
* License: GPLv2 or later
|
11 |
* License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
12 |
+
* Version: 2.10.0
|
|
|
|
|
13 |
*
|
14 |
* @package Antispam Bee
|
15 |
**/
|
39 |
/**
|
40 |
* Antispam_Bee
|
41 |
*
|
42 |
+
* @since 0.1
|
43 |
+
* @since 2.4
|
44 |
*/
|
45 |
class Antispam_Bee {
|
46 |
|
56 |
*
|
57 |
* @var int
|
58 |
*/
|
59 |
+
private static $db_version = 1.02;
|
60 |
|
61 |
/**
|
62 |
* The base.
|
89 |
/**
|
90 |
* "Constructor" of the class
|
91 |
*
|
92 |
+
* @since 0.1
|
93 |
+
* @since 2.6.4
|
94 |
+
* @since 2.10.0 Change handling of comment field honeypot and call functions after completed upgrades
|
95 |
*/
|
96 |
public static function init() {
|
97 |
+
add_action(
|
98 |
+
'upgrader_process_complete',
|
99 |
+
array(
|
100 |
+
__CLASS__,
|
101 |
+
'upgrades_completed',
|
102 |
+
),
|
103 |
+
10,
|
104 |
+
2
|
105 |
+
);
|
106 |
+
|
107 |
+
add_action(
|
108 |
+
'upgrader_overwrote_package',
|
109 |
+
array(
|
110 |
+
__CLASS__,
|
111 |
+
'uploaded_upgrade_completed',
|
112 |
+
),
|
113 |
+
10,
|
114 |
+
3
|
115 |
+
);
|
116 |
+
|
117 |
add_action(
|
118 |
'unspam_comment',
|
119 |
array(
|
321 |
)
|
322 |
);
|
323 |
|
324 |
+
if ( 1 == self::get_option( 'use_output_buffer' ) || null === self::get_option( 'use_output_buffer' ) ) {
|
325 |
+
add_action(
|
326 |
+
'template_redirect',
|
327 |
+
array(
|
328 |
+
__CLASS__,
|
329 |
+
'prepare_comment_field_output_buffering',
|
330 |
+
)
|
331 |
+
);
|
332 |
+
} else {
|
333 |
+
add_filter(
|
334 |
+
'comment_form_field_comment',
|
335 |
+
array(
|
336 |
+
__CLASS__,
|
337 |
+
'prepare_comment_field',
|
338 |
+
)
|
339 |
+
);
|
340 |
+
}
|
341 |
+
|
342 |
add_action(
|
343 |
'init',
|
344 |
array(
|
375 |
/**
|
376 |
* Action during the activation of the Plugins
|
377 |
*
|
378 |
+
* @since 0.1
|
379 |
+
* @since 2.4
|
380 |
+
* @since 2.10.0 Set `use_output_buffer` option to `0`
|
381 |
*/
|
382 |
public static function activate() {
|
383 |
add_option(
|
384 |
'antispam_bee',
|
385 |
+
array(
|
386 |
+
'use_output_buffer' => 0,
|
387 |
+
),
|
388 |
'',
|
389 |
'no'
|
390 |
);
|
398 |
/**
|
399 |
* Action to deactivate the plugin
|
400 |
*
|
401 |
+
* @since 0.1
|
402 |
+
* @since 2.4
|
403 |
*/
|
404 |
public static function deactivate() {
|
405 |
self::clear_scheduled_hook();
|
409 |
/**
|
410 |
* Action deleting the plugin
|
411 |
*
|
412 |
+
* @since 2.4
|
|
|
413 |
*/
|
414 |
public static function uninstall() {
|
415 |
if ( ! self::get_option( 'delete_data_on_uninstall' ) ) {
|
420 |
delete_option( 'antispam_bee' );
|
421 |
$wpdb->query( 'OPTIMIZE TABLE `' . $wpdb->options . '`' );
|
422 |
|
423 |
+
//phpcs:disable WordPress.DB.PreparedSQL.NotPrepared
|
424 |
$sql = 'delete from `' . $wpdb->commentmeta . '` where `meta_key` IN ("antispam_bee_iphash", "antispam_bee_reason")';
|
425 |
$wpdb->query( $sql );
|
426 |
+
//phpcs:enable WordPress.DB.PreparedSQL.NotPrepared
|
427 |
}
|
428 |
|
429 |
|
437 |
/**
|
438 |
* Initialization of the internal variables
|
439 |
*
|
440 |
+
* @since 2.4
|
441 |
+
* @since 2.7.0
|
442 |
+
* @since 2.10.0 Change renamed country option names in options array
|
443 |
*/
|
444 |
private static function _init_internal_vars() {
|
445 |
self::$_base = plugin_basename( __FILE__ );
|
455 |
'gravatar_check' => 0,
|
456 |
'time_check' => 0,
|
457 |
'ignore_pings' => 0,
|
|
|
458 |
|
459 |
'dashboard_chart' => 0,
|
460 |
'dashboard_count' => 0,
|
461 |
|
462 |
'country_code' => 0,
|
463 |
+
'country_denied' => '',
|
464 |
+
'country_allowed' => '',
|
465 |
|
466 |
'translate_api' => 0,
|
467 |
'translate_lang' => array(),
|
502 |
* Check and return an array key
|
503 |
*
|
504 |
* @since 2.4.2
|
505 |
+
* @since 2.10.0 Only return `null` if option does not exist.
|
506 |
*
|
507 |
* @param array $array Array with values.
|
508 |
* @param string $key Name of the key.
|
509 |
* @return mixed Value of the requested key.
|
510 |
*/
|
511 |
public static function get_key( $array, $key ) {
|
512 |
+
if ( empty( $array ) || empty( $key ) || ! isset( $array[ $key ] ) ) {
|
513 |
return null;
|
514 |
}
|
515 |
|
516 |
return $array[ $key ];
|
517 |
}
|
518 |
|
519 |
+
/**
|
520 |
+
* Check if comment is a ping (pingback, trackback or something similar)
|
521 |
+
*
|
522 |
+
* @since 2.10.0
|
523 |
+
*
|
524 |
+
* @param array $comment Treated commentary data.
|
525 |
+
* @return boolean `true` if ping and `false` if classic comment
|
526 |
+
*/
|
527 |
+
public static function is_ping( $comment ) {
|
528 |
+
$types = array( 'pingback', 'trackback', 'pings' );
|
529 |
+
$is_ping = false;
|
530 |
+
|
531 |
+
if ( in_array( self::get_key( $comment, 'comment_type' ), $types, true ) ) {
|
532 |
+
$is_ping = true;
|
533 |
+
}
|
534 |
+
|
535 |
+
return apply_filters( 'antispam_bee_is_ping', $is_ping, $comment );
|
536 |
+
}
|
537 |
|
538 |
/**
|
539 |
* Localization of the admin pages
|
540 |
*
|
541 |
* @since 0.1
|
542 |
+
* @since 2.4
|
543 |
*
|
544 |
* @param string $page Mark the page.
|
545 |
* @return boolean True on success.
|
572 |
/**
|
573 |
* Integration of the localization file
|
574 |
*
|
575 |
+
* @since 0.1
|
576 |
+
* @since 2.4
|
577 |
*/
|
578 |
public static function load_plugin_lang() {
|
579 |
load_plugin_textdomain(
|
585 |
/**
|
586 |
* Add the link to the settings
|
587 |
*
|
588 |
+
* @since 1.1
|
|
|
589 |
*
|
590 |
* @param array $data The action link array.
|
591 |
* @return array $data The action link array.
|
615 |
/**
|
616 |
* Meta links of the plugin
|
617 |
*
|
618 |
+
* @since 0.1
|
619 |
+
* @since 2.6.2
|
620 |
*
|
621 |
* @param array $input Existing links.
|
622 |
* @param string $file Current page.
|
645 |
/**
|
646 |
* Registration of resources (CSS & JS)
|
647 |
*
|
648 |
+
* @since 1.6
|
649 |
+
* @since 2.4.5
|
650 |
*/
|
651 |
public static function init_plugin_sources() {
|
652 |
$plugin = get_plugin_data( __FILE__ );
|
670 |
/**
|
671 |
* Initialization of the option page
|
672 |
*
|
673 |
+
* @since 0.1
|
674 |
+
* @since 2.4.3
|
675 |
*/
|
676 |
public static function add_sidebar_menu() {
|
677 |
$page = add_options_page(
|
714 |
/**
|
715 |
* Initialization of JavaScript
|
716 |
*
|
717 |
+
* @since 1.6
|
718 |
+
* @since 2.4
|
719 |
*/
|
720 |
public static function add_options_script() {
|
721 |
wp_enqueue_script( 'ab_script' );
|
725 |
/**
|
726 |
* Initialization of Stylesheets
|
727 |
*
|
728 |
+
* @since 1.6
|
729 |
+
* @since 2.4
|
730 |
*/
|
731 |
public static function add_options_style() {
|
732 |
wp_enqueue_style( 'ab_style' );
|
737 |
* Integration of the GUI
|
738 |
*
|
739 |
* @since 2.4
|
|
|
740 |
*/
|
741 |
public static function init_options_page() {
|
742 |
require_once dirname( __FILE__ ) . '/inc/gui.class.php';
|
753 |
/**
|
754 |
* Display the spam counter on the dashboard
|
755 |
*
|
756 |
+
* @since 0.1
|
757 |
+
* @since 2.6.5
|
758 |
*
|
759 |
* @param array $items Initial array with dashboard items.
|
760 |
* @return array $items Merged array with dashboard items.
|
780 |
/**
|
781 |
* Initialize the dashboard chart
|
782 |
*
|
783 |
+
* @since 1.9
|
784 |
+
* @since 2.5.6
|
785 |
*/
|
786 |
public static function add_dashboard_chart() {
|
787 |
if ( ! current_user_can( 'publish_posts' ) || ! self::get_option( 'dashboard_chart' ) ) {
|
809 |
/**
|
810 |
* Print dashboard styles
|
811 |
*
|
812 |
+
* @since 1.9.0
|
813 |
+
* @since 2.5.8
|
814 |
*/
|
815 |
public static function add_dashboard_style() {
|
816 |
$plugin = get_plugin_data( __FILE__ );
|
829 |
/**
|
830 |
* Print dashboard scripts
|
831 |
*
|
832 |
+
* @since 1.9.0
|
833 |
+
* @since 2.5.8
|
834 |
*/
|
835 |
public static function add_dashboard_script() {
|
836 |
if ( ! self::get_option( 'daily_stats' ) ) {
|
867 |
/**
|
868 |
* Print dashboard html
|
869 |
*
|
870 |
+
* @since 1.9.0
|
871 |
+
* @since 2.5.8
|
872 |
*/
|
873 |
public static function show_spam_chart() {
|
874 |
$items = (array) self::get_option( 'daily_stats' );
|
914 |
/**
|
915 |
* Get all plugin options
|
916 |
*
|
917 |
+
* @since 2.4
|
918 |
+
* @since 2.6.1
|
919 |
*
|
920 |
* @return array $options Array with option fields.
|
921 |
*/
|
941 |
/**
|
942 |
* Get single option field
|
943 |
*
|
944 |
+
* @since 0.1
|
945 |
+
* @since 2.4.2
|
946 |
*
|
947 |
* @param string $field Field name.
|
948 |
* @return mixed Field value.
|
957 |
/**
|
958 |
* Update single option field
|
959 |
*
|
960 |
+
* @since 0.1
|
961 |
+
* @since 2.4
|
962 |
*
|
963 |
* @param string $field Field name.
|
964 |
* @param mixed $value The Field value.
|
975 |
/**
|
976 |
* Update multiple option fields
|
977 |
*
|
978 |
+
* @since 0.1
|
979 |
+
* @since 2.6.1
|
980 |
*
|
981 |
* @param array $data Array with plugin option fields.
|
982 |
*/
|
1014 |
/**
|
1015 |
* Execution of the daily cronjobs
|
1016 |
*
|
1017 |
+
* @since 0.1
|
1018 |
+
* @since 2.4
|
1019 |
*/
|
1020 |
public static function start_daily_cronjob() {
|
1021 |
if ( ! self::get_option( 'cronjob_enable' ) ) {
|
1034 |
/**
|
1035 |
* Delete old spam comments
|
1036 |
*
|
1037 |
+
* @since 0.1
|
1038 |
+
* @since 2.4
|
1039 |
*/
|
1040 |
private static function _delete_old_spam() {
|
1041 |
$days = (int) self::get_option( 'cronjob_interval' );
|
1060 |
/**
|
1061 |
* Initialization of the cronjobs
|
1062 |
*
|
1063 |
+
* @since 0.1
|
1064 |
+
* @since 2.4
|
1065 |
*/
|
1066 |
public static function init_scheduled_hook() {
|
1067 |
if ( ! wp_next_scheduled( 'antispam_bee_daily_cronjob' ) ) {
|
1077 |
/**
|
1078 |
* Deletion of the cronjobs
|
1079 |
*
|
1080 |
+
* @since 0.1
|
1081 |
+
* @since 2.4
|
1082 |
*/
|
1083 |
public static function clear_scheduled_hook() {
|
1084 |
if ( wp_next_scheduled( 'antispam_bee_daily_cronjob' ) ) {
|
1097 |
/**
|
1098 |
* Check POST values
|
1099 |
*
|
1100 |
+
* @since 0.1
|
1101 |
+
* @since 2.6.3
|
1102 |
*/
|
1103 |
public static function precheck_incoming_request() {
|
1104 |
+
// phpcs:disable WordPress.Security.NonceVerification.Missing
|
1105 |
if ( is_feed() || is_trackback() || empty( $_POST ) || self::_is_mobile() ) {
|
1106 |
return;
|
1107 |
}
|
1123 |
} else {
|
1124 |
$_POST['ab_spam__hidden_field'] = 1;
|
1125 |
}
|
1126 |
+
// phpcs:enable WordPress.Security.NonceVerification.Missing
|
1127 |
}
|
1128 |
|
1129 |
|
1130 |
/**
|
1131 |
* Check incoming requests for spam
|
1132 |
*
|
1133 |
+
* @since 0.1
|
1134 |
+
* @since 2.6.3
|
1135 |
+
* @since 2.10.0 Refactoring of code if pings are allowed and if is ping
|
1136 |
*
|
1137 |
* @param array $comment Untreated comment.
|
1138 |
* @return array $comment Treated comment.
|
1150 |
);
|
1151 |
}
|
1152 |
|
1153 |
+
$pings_allowed = ! self::get_option( 'ignore_pings' );
|
|
|
|
|
|
|
1154 |
|
1155 |
+
// phpcs:disable WordPress.Security.NonceVerification.Missing
|
1156 |
// Everybody can post.
|
1157 |
if ( strpos( $request_path, 'wp-comments-post.php' ) !== false && ! empty( $_POST ) ) {
|
1158 |
+
// phpcs:enable WordPress.Security.NonceVerification.Missing
|
1159 |
$status = self::_verify_comment_request( $comment );
|
1160 |
|
1161 |
if ( ! empty( $status['reason'] ) ) {
|
1164 |
$status['reason']
|
1165 |
);
|
1166 |
}
|
1167 |
+
} elseif ( self::is_ping( $comment ) && $pings_allowed ) {
|
1168 |
$status = self::_verify_trackback_request( $comment );
|
1169 |
|
1170 |
if ( ! empty( $status['reason'] ) ) {
|
1179 |
return $comment;
|
1180 |
}
|
1181 |
|
|
|
1182 |
/**
|
1183 |
+
* Prepares the replacement of the comment field with output buffering.
|
1184 |
*
|
1185 |
+
* @since 2.10.0
|
|
|
1186 |
*/
|
1187 |
+
public static function prepare_comment_field_output_buffering() {
|
1188 |
if ( is_feed() || is_trackback() || is_robots() || self::_is_mobile() ) {
|
1189 |
return;
|
1190 |
}
|
1191 |
|
|
|
|
|
|
|
|
|
1192 |
ob_start(
|
1193 |
array(
|
1194 |
'Antispam_Bee',
|
1195 |
+
'prepare_comment_field',
|
1196 |
)
|
1197 |
);
|
1198 |
}
|
1199 |
|
1200 |
|
1201 |
/**
|
1202 |
+
* Prepares the replacement of the comment field
|
1203 |
*
|
1204 |
+
* @since 0.1
|
1205 |
+
* @since 2.4
|
1206 |
+
* @since 2.10.0 Changes needed because of new way to add the honeypot field via filter instead of output buffering
|
1207 |
*
|
1208 |
+
* @param string $data Markup of the comment field or whole page (depending on ob option).
|
|
|
1209 |
*/
|
1210 |
+
public static function prepare_comment_field( $data ) {
|
1211 |
if ( empty( $data ) ) {
|
1212 |
+
return $data;
|
1213 |
}
|
1214 |
|
1215 |
if ( ! preg_match( '#<textarea.+?name=["\']comment["\']#s', $data ) ) {
|
1290 |
/**
|
1291 |
* Check the trackbacks
|
1292 |
*
|
1293 |
+
* @since 2.4
|
1294 |
+
* @since 2.7.0
|
1295 |
*
|
1296 |
* @param array $comment Trackback data.
|
1297 |
* @return array Array with suspected reason.
|
1410 |
/**
|
1411 |
* Check the comment
|
1412 |
*
|
1413 |
+
* @since 2.4
|
1414 |
+
* @since 2.7.0
|
1415 |
+
* @since 2.10.0 Add useragent as data to regex check
|
1416 |
*
|
1417 |
* @param array $comment Data of the comment.
|
1418 |
* @return array|void Array with suspected reason
|
1419 |
*/
|
1420 |
private static function _verify_comment_request( $comment ) {
|
1421 |
+
$ip = self::get_key( $comment, 'comment_author_IP' );
|
1422 |
+
$url = self::get_key( $comment, 'comment_author_url' );
|
1423 |
+
$body = self::get_key( $comment, 'comment_content' );
|
1424 |
+
$email = self::get_key( $comment, 'comment_author_email' );
|
1425 |
+
$author = self::get_key( $comment, 'comment_author' );
|
1426 |
+
$useragent = self::get_key( $comment, 'comment_agent' );
|
1427 |
|
1428 |
if ( empty( $body ) ) {
|
1429 |
return array(
|
1453 |
return;
|
1454 |
}
|
1455 |
|
1456 |
+
// phpcs:disable WordPress.Security.NonceVerification.Missing
|
1457 |
if ( ! empty( $_POST['ab_spam__hidden_field'] ) ) {
|
1458 |
return array(
|
1459 |
'reason' => 'css',
|
1460 |
);
|
1461 |
}
|
1462 |
+
// phpcs:enable WordPress.Security.NonceVerification.Missing
|
1463 |
|
1464 |
if ( $options['time_check'] && self::_is_shortest_time() ) {
|
1465 |
return array(
|
1475 |
|
1476 |
if ( $options['regexp_check'] && self::_is_regexp_spam(
|
1477 |
array(
|
1478 |
+
'ip' => $ip,
|
1479 |
+
'rawurl' => $url,
|
1480 |
+
'host' => self::parse_url( $url, 'host' ),
|
1481 |
+
'body' => $body,
|
1482 |
+
'email' => $email,
|
1483 |
+
'author' => $author,
|
1484 |
+
'useragent' => $useragent,
|
1485 |
)
|
1486 |
) ) {
|
1487 |
return array(
|
1512 |
/**
|
1513 |
* Check for a Gravatar image
|
1514 |
*
|
1515 |
+
* @since 2.6.5
|
|
|
1516 |
*
|
1517 |
* @param string $email Input email.
|
1518 |
* @return boolean Check status (true = Gravatar available).
|
1541 |
* Check for comment action time
|
1542 |
*
|
1543 |
* @since 2.6.4
|
|
|
1544 |
*
|
1545 |
* @return boolean TRUE if the action time is less than 5 seconds
|
1546 |
*/
|
1547 |
private static function _is_shortest_time() {
|
1548 |
+
// phpcs:disable WordPress.Security.NonceVerification.Missing
|
1549 |
// Everybody can Post.
|
1550 |
$init_time = (int) self::get_key( $_POST, 'ab_init_time' );
|
1551 |
+
// phpcs:enable WordPress.Security.NonceVerification.Missing
|
1552 |
if ( 0 === $init_time ) {
|
1553 |
return false;
|
1554 |
}
|
1582 |
/**
|
1583 |
* Usage of regexp, also custom
|
1584 |
*
|
1585 |
+
* @since 2.5.2
|
1586 |
+
* @since 2.5.6
|
1587 |
+
* @since 2.10.0 Use useragent in check
|
1588 |
*
|
1589 |
* @param array $comment Array with commentary data.
|
1590 |
* @return boolean True for suspicious comment.
|
1596 |
'body',
|
1597 |
'email',
|
1598 |
'author',
|
1599 |
+
'useragent',
|
1600 |
);
|
1601 |
|
1602 |
$patterns = array(
|
1695 |
/**
|
1696 |
* Review a comment on its existence in the local spam
|
1697 |
*
|
1698 |
+
* @since 2.0.0
|
1699 |
+
* @since 2.5.4
|
1700 |
*
|
1701 |
* @param string $ip Comment IP.
|
1702 |
* @param string $url Comment URL (optional).
|
1725 |
return false;
|
1726 |
}
|
1727 |
|
1728 |
+
// phpcs:disable WordPress.DB.PreparedSQL.NotPrepared
|
1729 |
// phpcs:disable WordPress.DB.PreparedSQLPlaceholders.ReplacementsWrongNumber
|
1730 |
$filter_sql = implode( ' OR ', $filter );
|
1731 |
|
1739 |
)
|
1740 |
);
|
1741 |
// phpcs:enable WordPress.DB.PreparedSQLPlaceholders.ReplacementsWrongNumber
|
1742 |
+
// phpcs:enable WordPress.DB.PreparedSQL.NotPrepared
|
1743 |
|
1744 |
return ! empty( $result );
|
1745 |
}
|
1748 |
/**
|
1749 |
* Check for country spam by (anonymized) IP
|
1750 |
*
|
1751 |
+
* @since 2.6.9
|
1752 |
+
* @since 2.10.0 Make country check API filterable and use iplocate.io instead of ip2country.info
|
1753 |
*
|
1754 |
* @param string $ip IP address.
|
1755 |
* @return boolean True if the comment is spam based on country filter.
|
1757 |
private static function _is_country_spam( $ip ) {
|
1758 |
$options = self::get_options();
|
1759 |
|
1760 |
+
$allowed = preg_split(
|
1761 |
'/[\s,;]+/',
|
1762 |
+
$options['country_allowed'],
|
1763 |
-1,
|
1764 |
PREG_SPLIT_NO_EMPTY
|
1765 |
);
|
1766 |
+
$denied = preg_split(
|
1767 |
'/[\s,;]+/',
|
1768 |
+
$options['country_denied'],
|
1769 |
-1,
|
1770 |
PREG_SPLIT_NO_EMPTY
|
1771 |
);
|
1772 |
|
1773 |
+
if ( empty( $allowed ) && empty( $denied ) ) {
|
1774 |
return false;
|
1775 |
}
|
1776 |
|
1777 |
+
/**
|
1778 |
+
* Filter to hook into the `_is_country_spam` functionality, to implement for example a custom IP check.
|
1779 |
+
*
|
1780 |
+
* @since 2.10.0
|
1781 |
+
*
|
1782 |
+
* @param null $is_country_spam The `is_country_spam` result.
|
1783 |
+
* @param string $ip The IP address.
|
1784 |
+
* @param array $allowed The list of allowed country codes.
|
1785 |
+
* @param array $denied The list of denied country codes.
|
1786 |
+
*
|
1787 |
+
* @return null|boolean The `is_country_spam` result or null.
|
1788 |
+
*/
|
1789 |
+
$is_country_spam = apply_filters( 'antispam_bee_is_country_spam', null, $ip, $allowed, $denied );
|
1790 |
+
|
1791 |
+
if ( is_bool( $is_country_spam ) ) {
|
1792 |
+
return $is_country_spam;
|
1793 |
+
}
|
1794 |
+
|
1795 |
+
/**
|
1796 |
+
* Filters the IPLocate API key. With this filter, you can add your own IPLocate API key.
|
1797 |
+
*
|
1798 |
+
* @since 2.10.0
|
1799 |
+
*
|
1800 |
+
* @param string The current IPLocate API key. Default is `null`.
|
1801 |
+
*
|
1802 |
+
* @return string The changed IPLocate API key or null.
|
1803 |
+
*/
|
1804 |
+
$apikey = apply_filters( 'antispam_bee_country_spam_apikey', '' );
|
1805 |
+
|
1806 |
+
$response = wp_safe_remote_get(
|
1807 |
esc_url_raw(
|
1808 |
sprintf(
|
1809 |
+
'https://www.iplocate.io/api/lookup/%s?apikey=%s',
|
1810 |
+
self::_anonymize_ip( $ip ),
|
1811 |
+
$apikey
|
1812 |
),
|
1813 |
'https'
|
1814 |
)
|
1822 |
return false;
|
1823 |
}
|
1824 |
|
1825 |
+
$body = (string) wp_remote_retrieve_body( $response );
|
1826 |
+
|
1827 |
+
$json = json_decode( $body, true );
|
1828 |
+
|
1829 |
+
// Check if response is valid json.
|
1830 |
+
if ( ! is_array( $json ) ) {
|
1831 |
+
return false;
|
1832 |
+
}
|
1833 |
+
|
1834 |
+
if ( empty( $json['country_code'] ) ) {
|
1835 |
+
return false;
|
1836 |
+
}
|
1837 |
+
|
1838 |
+
$country = strtoupper( $json['country_code'] );
|
1839 |
|
1840 |
if ( empty( $country ) || strlen( $country ) !== 2 ) {
|
1841 |
return false;
|
1842 |
}
|
1843 |
|
1844 |
+
if ( ! empty( $denied ) ) {
|
1845 |
+
return ( in_array( $country, $denied, true ) );
|
1846 |
}
|
1847 |
|
1848 |
+
return ( ! in_array( $country, $allowed, true ) );
|
1849 |
}
|
1850 |
|
1851 |
|
1853 |
* Check for BBCode spam
|
1854 |
*
|
1855 |
* @since 2.5.1
|
|
|
1856 |
*
|
1857 |
* @param string $body Content of a comment.
|
1858 |
* @return boolean True for BBCode in content
|
1865 |
/**
|
1866 |
* Check for an already approved e-mail address
|
1867 |
*
|
1868 |
+
* @since 2.0
|
1869 |
+
* @since 2.5.1
|
1870 |
*
|
1871 |
* @param string $email E-mail address.
|
1872 |
* @return boolean True for a found entry.
|
1891 |
/**
|
1892 |
* Check for unwanted languages
|
1893 |
*
|
1894 |
+
* @since 2.0
|
1895 |
+
* @since 2.6.6
|
1896 |
+
* @since 2.8.2
|
1897 |
*
|
1898 |
* @param string $comment_content Content of the comment.
|
1899 |
*
|
1931 |
* enter 'characters_excluding_spaces' or 'characters_including_spaces'. Otherwise, enter 'words'.
|
1932 |
* Do not translate into your own language.
|
1933 |
*/
|
1934 |
+
if ( strpos( _x( 'words', 'Word count type. Do not translate!' ), 'characters' ) === 0 && preg_match( '/^utf\-?8$/i', get_option( 'blog_charset' ) ) ) { // phpcs:ignore WordPress.WP.I18n.MissingArgDomain
|
1935 |
preg_match_all( '/./u', $text, $words_array );
|
1936 |
if ( isset( $words_array[0] ) ) {
|
1937 |
$word_count = count( $words_array[0] );
|
2176 |
/**
|
2177 |
* Trim IP addresses
|
2178 |
*
|
2179 |
+
* @since 0.1
|
2180 |
+
* @since 2.5.1
|
2181 |
*
|
2182 |
* @param string $ip Original IP.
|
2183 |
* @param boolean $cut_end Shortening the end.
|
2198 |
* Anonymize the IP addresses
|
2199 |
*
|
2200 |
* @since 2.5.1
|
|
|
2201 |
*
|
2202 |
* @param string $ip Original IP.
|
2203 |
* @return string Anonymous IP.
|
2215 |
* Rotates the IP address
|
2216 |
*
|
2217 |
* @since 2.4.5
|
|
|
2218 |
*
|
2219 |
* @param string $ip IP address.
|
2220 |
* @return string Turned IP address.
|
2235 |
/**
|
2236 |
* Check for an IPv4 address
|
2237 |
*
|
2238 |
+
* @since 2.4
|
2239 |
+
* @since 2.6.4
|
2240 |
*
|
2241 |
* @param string $ip IP to validate.
|
2242 |
* @return integer TRUE if IPv4.
|
2253 |
/**
|
2254 |
* Check for an IPv6 address
|
2255 |
*
|
2256 |
+
* @since 2.6.2
|
2257 |
+
* @since 2.6.4
|
2258 |
*
|
2259 |
* @param string $ip IP to validate.
|
2260 |
* @return boolean TRUE if IPv6.
|
2271 |
/**
|
2272 |
* Testing on mobile devices
|
2273 |
*
|
2274 |
+
* @since 0.1
|
2275 |
+
* @since 2.4
|
2276 |
*
|
2277 |
* @return boolean TRUE if "wptouch" is active
|
2278 |
*/
|
2303 |
/**
|
2304 |
* Execution of the delete/marking process
|
2305 |
*
|
2306 |
+
* @since 0.1
|
2307 |
+
* @since 2.6.0
|
2308 |
*
|
2309 |
* @param array $comment Untreated commentary data.
|
2310 |
* @param string $reason Reason for suspicion.
|
2311 |
* @param boolean $is_ping Ping (optional).
|
2312 |
+
* @return array $comment Treated commentary data.
|
2313 |
*/
|
2314 |
private static function _handle_spam_request( $comment, $reason, $is_ping = false ) {
|
2315 |
|
2379 |
/**
|
2380 |
* Logfile with detected spam
|
2381 |
*
|
2382 |
+
* @since 2.5.7
|
2383 |
+
* @since 2.6.1
|
2384 |
*
|
2385 |
* @param array $comment Array with commentary data.
|
2386 |
* @return mixed FALSE in case of error
|
2410 |
* Sends the 403 header and terminates the connection
|
2411 |
*
|
2412 |
* @since 2.5.6
|
|
|
2413 |
*/
|
2414 |
private static function _go_in_peace() {
|
2415 |
status_header( 403 );
|
2421 |
* Return real client IP
|
2422 |
*
|
2423 |
* @since 2.6.1
|
|
|
2424 |
*
|
2425 |
* @return mixed $ip Client IP
|
2426 |
*/
|
2427 |
public static function get_client_ip() {
|
2428 |
+
// phpcs:disable WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
2429 |
// Sanitization of $ip takes place further down.
|
2430 |
$ip = '';
|
2431 |
|
2452 |
}
|
2453 |
|
2454 |
return '';
|
2455 |
+
// phpcs:enable WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
2456 |
}
|
2457 |
|
2458 |
/**
|
2487 |
* Add spam reason as comment data
|
2488 |
*
|
2489 |
* @since 2.6.0
|
|
|
2490 |
*
|
2491 |
* @param integer $comment_id Comment ID.
|
2492 |
*/
|
2503 |
* Delete spam reason as comment data
|
2504 |
*
|
2505 |
* @since 2.6.0
|
|
|
2506 |
*
|
2507 |
* @param integer $comment_id Comment ID.
|
2508 |
*/
|
2540 |
/**
|
2541 |
* Send notification via e-mail
|
2542 |
*
|
2543 |
+
* @since 0.1
|
2544 |
+
* @since 2.5.7
|
2545 |
+
* @since 2.10.0 Change plugin website URL
|
2546 |
*
|
2547 |
* @hook string antispam_bee_notification_subject Custom subject for notification mails
|
2548 |
*
|
2572 |
$subject = sprintf(
|
2573 |
'[%s] %s',
|
2574 |
stripslashes_deep(
|
2575 |
+
// phpcs:ignore PHPCompatibility.ParameterValues.NewHTMLEntitiesEncodingDefault.NotSet
|
2576 |
html_entity_decode(
|
2577 |
get_bloginfo( 'name' ),
|
2578 |
ENT_QUOTES
|
2651 |
) . sprintf(
|
2652 |
"%s\r\n%s\r\n",
|
2653 |
esc_html__( 'Notify message by Antispam Bee', 'antispam-bee' ),
|
2654 |
+
esc_html__( 'https://antispambee.pluginkollektiv.org/', 'antispam-bee' )
|
2655 |
);
|
2656 |
|
2657 |
wp_mail(
|
2690 |
/**
|
2691 |
* Return the number of spam comments
|
2692 |
*
|
2693 |
+
* @since 0.1
|
2694 |
+
* @since 2.4
|
2695 |
*/
|
2696 |
private static function _get_spam_count() {
|
2697 |
// Init.
|
2705 |
/**
|
2706 |
* Output the number of spam comments
|
2707 |
*
|
2708 |
+
* @since 0.1
|
2709 |
+
* @since 2.4
|
2710 |
*/
|
2711 |
public static function the_spam_count() {
|
2712 |
echo esc_html( self::_get_spam_count() );
|
2716 |
/**
|
2717 |
* Update the number of spam comments
|
2718 |
*
|
2719 |
+
* @since 0.1
|
2720 |
+
* @since 2.6.1
|
2721 |
*/
|
2722 |
private static function _update_spam_count() {
|
2723 |
// Skip if not enabled.
|
2734 |
/**
|
2735 |
* Update statistics
|
2736 |
*
|
2737 |
+
* @since 1.9
|
2738 |
+
* @since 2.6.1
|
2739 |
*/
|
2740 |
private static function _update_daily_stats() {
|
2741 |
// Skip if not enabled.
|
2767 |
/**
|
2768 |
* Returns the secret of a post used in the textarea name attribute.
|
2769 |
*
|
2770 |
+
* @since 2.10.0 Modify secret generation because `always_allowed` option not longer exists
|
2771 |
+
*
|
2772 |
* @param int $post_id The Post ID.
|
2773 |
*
|
2774 |
* @return string
|
2775 |
*/
|
2776 |
public static function get_secret_name_for_post( $post_id ) {
|
2777 |
+
$secret = substr( sha1( md5( 'comment-id' . self::$_salt ) ), 0, 10 );
|
|
|
|
|
|
|
|
|
|
|
2778 |
|
2779 |
$secret = self::ensure_secret_starts_with_letter( $secret );
|
2780 |
|
2797 |
/**
|
2798 |
* Returns the secret of a post used in the textarea id attribute.
|
2799 |
*
|
2800 |
+
* @since 2.10.0 Modify secret generation because `always_allowed` option not longer exists
|
2801 |
+
*
|
2802 |
* @param int $post_id The post ID.
|
2803 |
*
|
2804 |
* @return string
|
2805 |
*/
|
2806 |
public static function get_secret_id_for_post( $post_id ) {
|
2807 |
|
2808 |
+
$secret = substr( sha1( md5( 'comment-id' . self::$_salt ) ), 0, 10 );
|
|
|
|
|
|
|
|
|
2809 |
|
2810 |
$secret = self::ensure_secret_starts_with_letter( $secret );
|
2811 |
|
2871 |
|
2872 |
/**
|
2873 |
* Updates the database structure if necessary
|
2874 |
+
*
|
2875 |
+
* @since 2.10.0 Add update routine for country option names
|
2876 |
*/
|
2877 |
public static function update_database() {
|
2878 |
if ( self::db_version_is_current() ) {
|
2879 |
return;
|
2880 |
}
|
2881 |
|
2882 |
+
$version_from_db = floatval( get_option( 'antispambee_db_version', 0 ) );
|
2883 |
+
if ( $version_from_db < 1.01 ) {
|
2884 |
+
global $wpdb;
|
2885 |
|
2886 |
+
/**
|
2887 |
+
* In Version 2.9 the IP of the commenter was saved as a hash. We reverted this solution.
|
2888 |
+
* Therefore, we need to delete this unused data.
|
2889 |
+
*/
|
2890 |
+
//phpcs:disable WordPress.DB.PreparedSQL.NotPrepared
|
2891 |
+
$sql = 'delete from `' . $wpdb->commentmeta . '` where `meta_key` IN ("antispam_bee_iphash")';
|
2892 |
+
$wpdb->query( $sql );
|
2893 |
+
//phpcs:enable WordPress.DB.PreparedSQL.NotPrepared
|
2894 |
+
}
|
2895 |
+
|
2896 |
+
// DB version was raised in ASB 2.10.0 to 1.02.
|
2897 |
+
if ( $version_from_db < 1.02 ) {
|
2898 |
+
// Update option names.
|
2899 |
+
$options = self::get_options();
|
2900 |
+
if ( isset( $options['country_black'] ) ) {
|
2901 |
+
$options['country_denied'] = $options['country_black'];
|
2902 |
+
unset( $options['country_black'] );
|
2903 |
+
}
|
2904 |
+
if ( isset( $options['country_white'] ) ) {
|
2905 |
+
$options['country_allowed'] = $options['country_white'];
|
2906 |
+
unset( $options['country_white'] );
|
2907 |
+
}
|
2908 |
+
|
2909 |
+
update_option(
|
2910 |
+
'antispam_bee',
|
2911 |
+
$options
|
2912 |
+
);
|
2913 |
+
|
2914 |
+
wp_cache_set(
|
2915 |
+
'antispam_bee',
|
2916 |
+
$options
|
2917 |
+
);
|
2918 |
+
}
|
2919 |
|
2920 |
update_option( 'antispambee_db_version', self::$db_version );
|
2921 |
}
|
2923 |
/**
|
2924 |
* Whether the database structure is up to date.
|
2925 |
*
|
2926 |
+
* @since 2.10.0 Return a float instead of int
|
2927 |
+
*
|
2928 |
* @return bool
|
2929 |
*/
|
2930 |
private static function db_version_is_current() {
|
2931 |
|
2932 |
+
$current_version = floatval( get_option( 'antispambee_db_version', 0 ) );
|
2933 |
return $current_version === self::$db_version;
|
2934 |
|
2935 |
}
|
2936 |
+
|
2937 |
+
/**
|
2938 |
+
* Runs after upgrades are completed.
|
2939 |
+
*
|
2940 |
+
* @since 2.10.0
|
2941 |
+
*
|
2942 |
+
* @param \WP_Upgrader $wp_upgrader WP_Upgrader instance.
|
2943 |
+
* @param array $hook_extra Array of bulk item update data.
|
2944 |
+
*/
|
2945 |
+
public static function upgrades_completed( $wp_upgrader, $hook_extra ) {
|
2946 |
+
if ( ! $wp_upgrader instanceof Plugin_Upgrader || ! isset( $hook_extra['plugins'] ) ) {
|
2947 |
+
return;
|
2948 |
+
}
|
2949 |
+
|
2950 |
+
$updated_plugins = $hook_extra['plugins'];
|
2951 |
+
$asb_updated = false;
|
2952 |
+
foreach ( $updated_plugins as $updated_plugin ) {
|
2953 |
+
if ( $updated_plugin !== self::$_base ) {
|
2954 |
+
continue;
|
2955 |
+
}
|
2956 |
+
$asb_updated = true;
|
2957 |
+
}
|
2958 |
+
|
2959 |
+
if ( false === $asb_updated ) {
|
2960 |
+
return;
|
2961 |
+
}
|
2962 |
+
|
2963 |
+
self::asb_updated();
|
2964 |
+
}
|
2965 |
+
|
2966 |
+
/**
|
2967 |
+
* Runs after an upgrade via an uploaded ZIP package was completed.
|
2968 |
+
*
|
2969 |
+
* @since 2.10.0
|
2970 |
+
*
|
2971 |
+
* @param string $package The package file.
|
2972 |
+
* @param array $data The new plugin or theme data.
|
2973 |
+
* @param string $package_type The package type.
|
2974 |
+
*/
|
2975 |
+
public static function uploaded_upgrade_completed( $package, $data, $package_type ) {
|
2976 |
+
if ( 'plugin' !== $package_type ) {
|
2977 |
+
return;
|
2978 |
+
}
|
2979 |
+
|
2980 |
+
$text_domain = isset( $data['TextDomain'] ) ? $data['TextDomain'] : '';
|
2981 |
+
|
2982 |
+
if ( 'antispam-bee' !== $text_domain ) {
|
2983 |
+
return;
|
2984 |
+
}
|
2985 |
+
|
2986 |
+
self::asb_updated();
|
2987 |
+
}
|
2988 |
+
|
2989 |
+
/**
|
2990 |
+
* Runs after ASB was updated.
|
2991 |
+
*
|
2992 |
+
* @since 2.10.0
|
2993 |
+
*
|
2994 |
+
* @return void
|
2995 |
+
*/
|
2996 |
+
private static function asb_updated() {
|
2997 |
+
self::update_database();
|
2998 |
+
}
|
2999 |
}
|
3000 |
|
3001 |
|
behat.yml
ADDED
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
default:
|
2 |
+
autoload:
|
3 |
+
'': tests/Acceptance/Behat/bootstrap
|
4 |
+
suites:
|
5 |
+
default:
|
6 |
+
paths:
|
7 |
+
features: tests/Acceptance/Behat
|
8 |
+
contexts:
|
9 |
+
# Keep WordpressContext first!
|
10 |
+
- PaulGibbs\WordpressBehatExtension\Context\WordpressContext
|
11 |
+
- FeatureContext
|
12 |
+
- CommentContext
|
13 |
+
- TrackbackContext
|
14 |
+
- PluginContext
|
15 |
+
- Behat\MinkExtension\Context\MinkContext
|
16 |
+
- PaulGibbs\WordpressBehatExtension\Context\ContentContext
|
17 |
+
- PaulGibbs\WordpressBehatExtension\Context\DashboardContext
|
18 |
+
- PaulGibbs\WordpressBehatExtension\Context\UserContext
|
19 |
+
- PaulGibbs\WordpressBehatExtension\Context\EditPostContext
|
20 |
+
extensions:
|
21 |
+
DMore\ChromeExtension\Behat\ServiceContainer\ChromeExtension: ~
|
22 |
+
Behat\MinkExtension:
|
23 |
+
base_url: http://localhost:8080 # [!] Change this for your local development.
|
24 |
+
browser_name: chrome
|
25 |
+
default_session: headless
|
26 |
+
javascript_session: javascript
|
27 |
+
sessions:
|
28 |
+
headless:
|
29 |
+
goutte:
|
30 |
+
guzzle_parameters:
|
31 |
+
verify: false
|
32 |
+
javascript:
|
33 |
+
chrome:
|
34 |
+
api_url: http://localhost:9222
|
35 |
+
validate_certificate: false
|
36 |
+
|
37 |
+
PaulGibbs\WordpressBehatExtension:
|
38 |
+
path: %paths.base%/tmp/antispam-bee/ # [!] Change this for your local development.
|
39 |
+
default_driver: wpcli
|
40 |
+
wpcli:
|
41 |
+
binary: %paths.base%/vendor/bin/wp
|
42 |
+
database:
|
43 |
+
restore_after_test: true
|
44 |
+
users:
|
45 |
+
admin:
|
46 |
+
username: admin
|
47 |
+
password: abc
|
css/dashboard.css
CHANGED
@@ -1,9 +1,10 @@
|
|
1 |
#ab_chart {
|
2 |
-
color: #
|
3 |
height: 140px;
|
4 |
margin: 0 -4px;
|
5 |
text-align: center;
|
6 |
}
|
|
|
7 |
#ab_chart_data {
|
8 |
display: none;
|
9 |
}
|
1 |
#ab_chart {
|
2 |
+
color: #a7aaad;
|
3 |
height: 140px;
|
4 |
margin: 0 -4px;
|
5 |
text-align: center;
|
6 |
}
|
7 |
+
|
8 |
#ab_chart_data {
|
9 |
display: none;
|
10 |
}
|
css/dashboard.min.css
CHANGED
@@ -1 +1 @@
|
|
1 |
-
#ab_chart{color:#
|
1 |
+
#ab_chart{color:#a7aaad;height:140px;margin:0 -4px;text-align:center}#ab_chart_data{display:none}#ab_widget .inside{height:1%;margin:0;padding-bottom:0;overflow:hidden;position:relative;white-space:nowrap}
|
css/styles.css
CHANGED
@@ -1,26 +1,15 @@
|
|
1 |
/* @group General */
|
2 |
|
3 |
.ab-main *,
|
4 |
-
.ab-main
|
5 |
-
.ab-main
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
}
|
14 |
-
|
15 |
-
/* @end group */
|
16 |
-
|
17 |
-
/* @group Browse Happy */
|
18 |
-
|
19 |
-
.browsehappy {
|
20 |
-
margin: 0 0 20px;
|
21 |
-
padding: 10px;
|
22 |
-
border: 1px solid #e66f00;
|
23 |
-
text-align: center;
|
24 |
}
|
25 |
|
26 |
/* @end group */
|
@@ -28,15 +17,15 @@
|
|
28 |
/* @group Columns */
|
29 |
|
30 |
.ab-wrap {
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
}
|
35 |
|
36 |
.ab-column {
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
}
|
41 |
|
42 |
/* @end group */
|
@@ -44,44 +33,44 @@
|
|
44 |
/* @group Headlines + Icons */
|
45 |
|
46 |
.ab-column h3 {
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
}
|
53 |
|
54 |
-
.ab-column h3.icon
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
}
|
66 |
|
67 |
-
.ab-column.ab-arrow h3.icon
|
68 |
-
|
69 |
}
|
70 |
|
71 |
-
.ab-column.ab-join h3.icon
|
72 |
-
|
73 |
}
|
74 |
|
75 |
-
.ab-column.ab-diff h3.icon
|
76 |
-
|
77 |
}
|
78 |
|
79 |
.ab-column h6 {
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
}
|
86 |
|
87 |
/* @end group */
|
@@ -91,18 +80,18 @@
|
|
91 |
.ab-column input[type="text"],
|
92 |
.ab-column input[type="number"],
|
93 |
.ab-column select {
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
}
|
98 |
|
99 |
.ab-column input[type="number"] {
|
100 |
-
|
101 |
}
|
102 |
|
103 |
.ab-column select[multiple] {
|
104 |
-
|
105 |
-
|
106 |
}
|
107 |
|
108 |
.ab-column select[multiple][name="ab_ignore_reasons[]"] {
|
@@ -110,20 +99,20 @@
|
|
110 |
}
|
111 |
|
112 |
.ab-column input.ab-mini-field {
|
113 |
-
|
114 |
}
|
115 |
|
116 |
.ab-column .ab-medium-field {
|
117 |
-
|
118 |
-
|
119 |
}
|
120 |
|
121 |
.ab-column input[type="text"] + label,
|
122 |
.ab-column select + label {
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
}
|
128 |
|
129 |
/* @end group */
|
@@ -131,86 +120,86 @@
|
|
131 |
/* @group Column contents */
|
132 |
|
133 |
.ab-column > ul {
|
134 |
-
|
135 |
}
|
136 |
|
137 |
.ab-column:last-of-type > ul {
|
138 |
-
|
139 |
}
|
140 |
|
141 |
.ab-column > ul > li {
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
}
|
148 |
|
149 |
.ab-column > ul > li a {
|
150 |
-
|
151 |
}
|
152 |
|
153 |
.ab-column > ul > li a:hover {
|
154 |
-
|
155 |
}
|
156 |
|
157 |
.ab-column > ul > li label {
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
}
|
164 |
|
165 |
.ab-column > ul > li label span {
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
}
|
172 |
|
173 |
/* @end group */
|
174 |
|
175 |
/* @group Separator */
|
176 |
|
177 |
-
.ab-column > ul > li
|
178 |
-
.ab-column > ul > li
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
}
|
183 |
|
184 |
-
.ab-column.ab-arrow > ul > li
|
185 |
-
.ab-column.ab-arrow > ul > li
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
}
|
190 |
|
191 |
-
.ab-column.ab-arrow > ul > li
|
192 |
-
|
193 |
-
|
194 |
}
|
195 |
|
196 |
-
.ab-column.ab-arrow > ul > li
|
197 |
-
|
198 |
-
|
199 |
}
|
200 |
|
201 |
-
.ab-column.ab-join > ul > li
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
}
|
207 |
|
208 |
-
.ab-column.ab-diff > ul > li
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
}
|
215 |
|
216 |
/* @end group */
|
@@ -218,59 +207,59 @@
|
|
218 |
/* @group Submit & Service */
|
219 |
|
220 |
.ab-column--submit-service {
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
}
|
225 |
|
226 |
.ab-column--submit-service p {
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
}
|
232 |
|
233 |
.ab-column--submit-service p:first-of-type {
|
234 |
-
|
235 |
}
|
236 |
|
237 |
.ab-column--submit-service p:last-of-type {
|
238 |
-
|
239 |
}
|
240 |
|
241 |
.ab-column--submit-service .button {
|
242 |
-
|
243 |
-
|
244 |
}
|
245 |
|
246 |
/* @end group */
|
247 |
|
248 |
/* @group 2nd level */
|
249 |
|
250 |
-
.ab-column > ul > li:last-of-type
|
251 |
-
.ab-column > ul > li:last-of-type
|
252 |
-
|
253 |
}
|
254 |
|
255 |
.ab-column > ul > li > ul {
|
256 |
-
|
257 |
-
|
258 |
}
|
259 |
|
260 |
.ab-column > ul > li > ul li {
|
261 |
-
|
262 |
}
|
263 |
|
264 |
.ab-column > ul > li > ul label {
|
265 |
-
|
266 |
}
|
267 |
|
268 |
.ab-column > ul > li > ul label[for="ab_ignore_reasons"] {
|
269 |
-
|
270 |
}
|
271 |
|
272 |
.ab-column > ul > li > input[type="checkbox"]:checked ~ ul {
|
273 |
-
|
274 |
}
|
275 |
|
276 |
/* @end group */
|
1 |
/* @group General */
|
2 |
|
3 |
.ab-main *,
|
4 |
+
.ab-main *::after,
|
5 |
+
.ab-main *::before {
|
6 |
+
border: 0;
|
7 |
+
margin: 0;
|
8 |
+
padding: 0;
|
9 |
+
outline: 0;
|
10 |
+
-webkit-box-sizing: border-box;
|
11 |
+
-moz-box-sizing: border-box;
|
12 |
+
box-sizing: border-box;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
}
|
14 |
|
15 |
/* @end group */
|
17 |
/* @group Columns */
|
18 |
|
19 |
.ab-wrap {
|
20 |
+
margin: 0 0 0 -10px;
|
21 |
+
padding: 20px 0 0 0;
|
22 |
+
text-rendering: optimizeLegibility;
|
23 |
}
|
24 |
|
25 |
.ab-column {
|
26 |
+
float: left;
|
27 |
+
margin: 0 0 0 10px;
|
28 |
+
position: relative;
|
29 |
}
|
30 |
|
31 |
/* @end group */
|
33 |
/* @group Headlines + Icons */
|
34 |
|
35 |
.ab-column h3 {
|
36 |
+
margin: 0;
|
37 |
+
font-size: 18px;
|
38 |
+
font-weight: normal;
|
39 |
+
line-height: 20px;
|
40 |
+
color: #1d2327;
|
41 |
}
|
42 |
|
43 |
+
.ab-column h3.icon::before {
|
44 |
+
font: normal 30px/30px Dashicons;
|
45 |
+
top: 4px;
|
46 |
+
right: 20px;
|
47 |
+
speak: none;
|
48 |
+
width: 1em;
|
49 |
+
color: #8c8f94;
|
50 |
+
position: absolute;
|
51 |
+
text-align: center;
|
52 |
+
-webkit-font-smoothing: antialiased;
|
53 |
+
-moz-osx-font-smoothing: grayscale;
|
54 |
}
|
55 |
|
56 |
+
.ab-column.ab-arrow h3.icon::before {
|
57 |
+
content: "\f536";
|
58 |
}
|
59 |
|
60 |
+
.ab-column.ab-join h3.icon::before {
|
61 |
+
content: "\f108";
|
62 |
}
|
63 |
|
64 |
+
.ab-column.ab-diff h3.icon::before {
|
65 |
+
content: "\f237";
|
66 |
}
|
67 |
|
68 |
.ab-column h6 {
|
69 |
+
clear: both;
|
70 |
+
color: #3c434a;
|
71 |
+
margin: 0 0 20px;
|
72 |
+
font-weight: normal;
|
73 |
+
font-size: 13px;
|
74 |
}
|
75 |
|
76 |
/* @end group */
|
80 |
.ab-column input[type="text"],
|
81 |
.ab-column input[type="number"],
|
82 |
.ab-column select {
|
83 |
+
font-size: 13px;
|
84 |
+
text-align: center;
|
85 |
+
background: #f6f7f7;
|
86 |
}
|
87 |
|
88 |
.ab-column input[type="number"] {
|
89 |
+
padding: 0;
|
90 |
}
|
91 |
|
92 |
.ab-column select[multiple] {
|
93 |
+
width: 175px;
|
94 |
+
min-height: 60px;
|
95 |
}
|
96 |
|
97 |
.ab-column select[multiple][name="ab_ignore_reasons[]"] {
|
99 |
}
|
100 |
|
101 |
.ab-column input.ab-mini-field {
|
102 |
+
width: 40px;
|
103 |
}
|
104 |
|
105 |
.ab-column .ab-medium-field {
|
106 |
+
width: 100%;
|
107 |
+
max-width: 285px;
|
108 |
}
|
109 |
|
110 |
.ab-column input[type="text"] + label,
|
111 |
.ab-column select + label {
|
112 |
+
color: #8c8f94;
|
113 |
+
margin: 0 0 0 7px;
|
114 |
+
display: inline-block;
|
115 |
+
text-transform: uppercase;
|
116 |
}
|
117 |
|
118 |
/* @end group */
|
120 |
/* @group Column contents */
|
121 |
|
122 |
.ab-column > ul {
|
123 |
+
padding: 0 20px 0 0;
|
124 |
}
|
125 |
|
126 |
.ab-column:last-of-type > ul {
|
127 |
+
border: 0;
|
128 |
}
|
129 |
|
130 |
.ab-column > ul > li {
|
131 |
+
width: 330px;
|
132 |
+
margin: 0 0 36px;
|
133 |
+
padding: 10px 0 12px 12px;
|
134 |
+
position: relative;
|
135 |
+
background: #fff;
|
136 |
}
|
137 |
|
138 |
.ab-column > ul > li a {
|
139 |
+
text-decoration: underline;
|
140 |
}
|
141 |
|
142 |
.ab-column > ul > li a:hover {
|
143 |
+
border-color: inherit;
|
144 |
}
|
145 |
|
146 |
.ab-column > ul > li label {
|
147 |
+
cursor: default;
|
148 |
+
display: inline-block;
|
149 |
+
font-size: 14px;
|
150 |
+
max-width: 286px;
|
151 |
+
color: #1d2327;
|
152 |
}
|
153 |
|
154 |
.ab-column > ul > li label span {
|
155 |
+
color: #3c434a;
|
156 |
+
display: block;
|
157 |
+
font-size: 13px;
|
158 |
+
line-height: 16px;
|
159 |
+
margin-top: 5px;
|
160 |
}
|
161 |
|
162 |
/* @end group */
|
163 |
|
164 |
/* @group Separator */
|
165 |
|
166 |
+
.ab-column > ul > li::after,
|
167 |
+
.ab-column > ul > li::before {
|
168 |
+
width: 0;
|
169 |
+
content: "";
|
170 |
+
position: absolute;
|
171 |
}
|
172 |
|
173 |
+
.ab-column.ab-arrow > ul > li::before,
|
174 |
+
.ab-column.ab-arrow > ul > li::after {
|
175 |
+
left: 157px;
|
176 |
+
border-width: 10px 10px 0;
|
177 |
+
border-style: solid;
|
178 |
}
|
179 |
|
180 |
+
.ab-column.ab-arrow > ul > li::before {
|
181 |
+
bottom: -24px;
|
182 |
+
border-color: #fff transparent;
|
183 |
}
|
184 |
|
185 |
+
.ab-column.ab-arrow > ul > li::after {
|
186 |
+
bottom: -22px;
|
187 |
+
border-color: #f0f0f1 transparent;
|
188 |
}
|
189 |
|
190 |
+
.ab-column.ab-join > ul > li::before {
|
191 |
+
left: 171px;
|
192 |
+
bottom: -27px;
|
193 |
+
height: 18px;
|
194 |
+
border-right: 2px solid #fff;
|
195 |
}
|
196 |
|
197 |
+
.ab-column.ab-diff > ul > li::before {
|
198 |
+
left: 162px;
|
199 |
+
bottom: -19px;
|
200 |
+
width: 18px;
|
201 |
+
height: 0;
|
202 |
+
border-bottom: 2px solid #fff;
|
203 |
}
|
204 |
|
205 |
/* @end group */
|
207 |
/* @group Submit & Service */
|
208 |
|
209 |
.ab-column--submit-service {
|
210 |
+
width: 342px;
|
211 |
+
margin-top: 20px;
|
212 |
+
padding-right: 20px;
|
213 |
}
|
214 |
|
215 |
.ab-column--submit-service p {
|
216 |
+
padding: 5px 0;
|
217 |
+
margin: 0;
|
218 |
+
text-align: center;
|
219 |
+
width: 100%;
|
220 |
}
|
221 |
|
222 |
.ab-column--submit-service p:first-of-type {
|
223 |
+
border-top: 1px solid #dcdcde;
|
224 |
}
|
225 |
|
226 |
.ab-column--submit-service p:last-of-type {
|
227 |
+
border-bottom: 1px solid #dcdcde;
|
228 |
}
|
229 |
|
230 |
.ab-column--submit-service .button {
|
231 |
+
width: 100%;
|
232 |
+
margin: 35px 0 10px;
|
233 |
}
|
234 |
|
235 |
/* @end group */
|
236 |
|
237 |
/* @group 2nd level */
|
238 |
|
239 |
+
.ab-column > ul > li:last-of-type::after,
|
240 |
+
.ab-column > ul > li:last-of-type::before {
|
241 |
+
display: none;
|
242 |
}
|
243 |
|
244 |
.ab-column > ul > li > ul {
|
245 |
+
margin: 10px 10px 0 26px;
|
246 |
+
display: none;
|
247 |
}
|
248 |
|
249 |
.ab-column > ul > li > ul li {
|
250 |
+
padding: 2px 0;
|
251 |
}
|
252 |
|
253 |
.ab-column > ul > li > ul label {
|
254 |
+
margin: 0 0 0 7px;
|
255 |
}
|
256 |
|
257 |
.ab-column > ul > li > ul label[for="ab_ignore_reasons"] {
|
258 |
+
margin: 0 0 5px 0;
|
259 |
}
|
260 |
|
261 |
.ab-column > ul > li > input[type="checkbox"]:checked ~ ul {
|
262 |
+
display: block;
|
263 |
}
|
264 |
|
265 |
/* @end group */
|
css/styles.min.css
CHANGED
@@ -1 +1 @@
|
|
1 |
-
.ab-main *,.ab-main
|
1 |
+
.ab-main *,.ab-main *::after,.ab-main *::before{border:0;margin:0;padding:0;outline:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.ab-wrap{margin:0 0 0 -10px;padding:20px 0 0 0;text-rendering:optimizeLegibility}.ab-column{float:left;margin:0 0 0 10px;position:relative}.ab-column h3{margin:0;font-size:18px;font-weight:400;line-height:20px;color:#1d2327}.ab-column h3.icon::before{font:normal 30px/30px Dashicons;top:4px;right:20px;speak:none;width:1em;color:#8c8f94;position:absolute;text-align:center;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.ab-column.ab-arrow h3.icon::before{content:"\f536"}.ab-column.ab-join h3.icon::before{content:"\f108"}.ab-column.ab-diff h3.icon::before{content:"\f237"}.ab-column h6{clear:both;color:#3c434a;margin:0 0 20px;font-weight:400;font-size:13px}.ab-column input[type="text"],.ab-column input[type="number"],.ab-column select{font-size:13px;text-align:center;background:#f6f7f7}.ab-column input[type="number"]{padding:0}.ab-column select[multiple]{width:175px;min-height:60px}.ab-column select[multiple][name="ab_ignore_reasons[]"]{width:auto}.ab-column input.ab-mini-field{width:40px}.ab-column .ab-medium-field{width:100%;max-width:285px}.ab-column input[type="text"]+label,.ab-column select+label{color:#8c8f94;margin:0 0 0 7px;display:inline-block;text-transform:uppercase}.ab-column>ul{padding:0 20px 0 0}.ab-column:last-of-type>ul{border:0}.ab-column>ul>li{width:330px;margin:0 0 36px;padding:10px 0 12px 12px;position:relative;background:#fff}.ab-column>ul>li a{text-decoration:underline}.ab-column>ul>li a:hover{border-color:inherit}.ab-column>ul>li label{cursor:default;display:inline-block;font-size:14px;max-width:286px;color:#1d2327}.ab-column>ul>li label span{color:#3c434a;display:block;font-size:13px;line-height:16px;margin-top:5px}.ab-column>ul>li::after,.ab-column>ul>li::before{width:0;content:"";position:absolute}.ab-column.ab-arrow>ul>li::before,.ab-column.ab-arrow>ul>li::after{left:157px;border-width:10px 10px 0;border-style:solid}.ab-column.ab-arrow>ul>li::before{bottom:-24px;border-color:#fff transparent}.ab-column.ab-arrow>ul>li::after{bottom:-22px;border-color:#f0f0f1 transparent}.ab-column.ab-join>ul>li::before{left:171px;bottom:-27px;height:18px;border-right:2px solid #fff}.ab-column.ab-diff>ul>li::before{left:162px;bottom:-19px;width:18px;height:0;border-bottom:2px solid #fff}.ab-column--submit-service{width:342px;margin-top:20px;padding-right:20px}.ab-column--submit-service p{padding:5px 0;margin:0;text-align:center;width:100%}.ab-column--submit-service p:first-of-type{border-top:1px solid #dcdcde}.ab-column--submit-service p:last-of-type{border-bottom:1px solid #dcdcde}.ab-column--submit-service .button{width:100%;margin:35px 0 10px}.ab-column>ul>li:last-of-type::after,.ab-column>ul>li:last-of-type::before{display:none}.ab-column>ul>li>ul{margin:10px 10px 0 26px;display:none}.ab-column>ul>li>ul li{padding:2px 0}.ab-column>ul>li>ul label{margin:0 0 0 7px}.ab-column>ul>li>ul label[for="ab_ignore_reasons"]{margin:0 0 5px 0}.ab-column>ul>li>input[type="checkbox"]:checked~ul{display:block}
|
docker_tag
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
docker.pkg.github.com/pluginkollektiv/antispam-bee/php-actions_composer_antispam-bee:php-latest-build2
|
inc/gui.class.php
CHANGED
@@ -17,8 +17,9 @@ class Antispam_Bee_GUI extends Antispam_Bee {
|
|
17 |
/**
|
18 |
* Save the GUI
|
19 |
*
|
20 |
-
* @since
|
21 |
-
* @
|
|
|
22 |
*/
|
23 |
public static function save_changes() {
|
24 |
if ( empty( $_POST ) ) {
|
@@ -58,7 +59,6 @@ class Antispam_Bee_GUI extends Antispam_Bee {
|
|
58 |
'spam_ip' => (int) ( ! empty( $_POST['ab_spam_ip'] ) ),
|
59 |
'already_commented' => (int) ( ! empty( $_POST['ab_already_commented'] ) ),
|
60 |
'time_check' => (int) ( ! empty( $_POST['ab_time_check'] ) ),
|
61 |
-
'always_allowed' => (int) ( ! empty( $_POST['ab_always_allowed'] ) ),
|
62 |
|
63 |
'ignore_pings' => (int) ( ! empty( $_POST['ab_ignore_pings'] ) ),
|
64 |
'ignore_filter' => (int) ( ! empty( $_POST['ab_ignore_filter'] ) ),
|
@@ -70,14 +70,16 @@ class Antispam_Bee_GUI extends Antispam_Bee {
|
|
70 |
'bbcode_check' => (int) ( ! empty( $_POST['ab_bbcode_check'] ) ),
|
71 |
'gravatar_check' => (int) ( ! empty( $_POST['ab_gravatar_check'] ) ),
|
72 |
'country_code' => (int) ( ! empty( $_POST['ab_country_code'] ) ),
|
73 |
-
'
|
74 |
-
'
|
75 |
|
76 |
'translate_api' => (int) ( ! empty( $_POST['ab_translate_api'] ) ),
|
77 |
'translate_lang' => $selected_languages,
|
78 |
|
79 |
'delete_data_on_uninstall' => (int) ( ! empty( $_POST['delete_data_on_uninstall'] ) ),
|
80 |
|
|
|
|
|
81 |
);
|
82 |
|
83 |
foreach ( $options['ignore_reasons'] as $key => $val ) {
|
@@ -98,23 +100,23 @@ class Antispam_Bee_GUI extends Antispam_Bee {
|
|
98 |
$options['ignore_reasons'] = array();
|
99 |
}
|
100 |
|
101 |
-
if ( ! empty( $options['
|
102 |
-
$options['
|
103 |
'/[^A-Z ,;]/',
|
104 |
'',
|
105 |
-
strtoupper( $options['
|
106 |
);
|
107 |
}
|
108 |
|
109 |
-
if ( ! empty( $options['
|
110 |
-
$options['
|
111 |
'/[^A-Z ,;]/',
|
112 |
'',
|
113 |
-
strtoupper( $options['
|
114 |
);
|
115 |
}
|
116 |
|
117 |
-
if ( empty( $options['
|
118 |
$options['country_code'] = 0;
|
119 |
}
|
120 |
|
@@ -142,7 +144,6 @@ class Antispam_Bee_GUI extends Antispam_Bee {
|
|
142 |
* Generation of a selectbox
|
143 |
*
|
144 |
* @since 2.4.5
|
145 |
-
* @change 2.4.5
|
146 |
*
|
147 |
* @param string $name Name of the Selectbox.
|
148 |
* @param array $data Array with values.
|
@@ -163,8 +164,9 @@ class Antispam_Bee_GUI extends Antispam_Bee {
|
|
163 |
/**
|
164 |
* Display the GUI
|
165 |
*
|
166 |
-
* @since
|
167 |
-
* @
|
|
|
168 |
*/
|
169 |
public static function options_page() { ?>
|
170 |
<div class="wrap" id="ab_main">
|
@@ -179,11 +181,6 @@ class Antispam_Bee_GUI extends Antispam_Bee {
|
|
179 |
|
180 |
<?php $options = self::get_options(); ?>
|
181 |
<div class="ab-wrap">
|
182 |
-
<!--[if lt IE 9]>
|
183 |
-
<p class="browsehappy">
|
184 |
-
<a href="http://browsehappy.com">Browse Happy</a>
|
185 |
-
</p>
|
186 |
-
<![endif]-->
|
187 |
|
188 |
<div class="ab-column ab-arrow">
|
189 |
<h3 class="icon">
|
@@ -212,7 +209,7 @@ class Antispam_Bee_GUI extends Antispam_Bee {
|
|
212 |
$link1 = sprintf(
|
213 |
'<a href="%s" target="_blank" rel="noopener noreferrer">',
|
214 |
esc_url(
|
215 |
-
__( 'https://antispambee.pluginkollektiv.org/documentation
|
216 |
'https'
|
217 |
)
|
218 |
);
|
@@ -270,14 +267,15 @@ class Antispam_Bee_GUI extends Antispam_Bee {
|
|
270 |
$link1 = sprintf(
|
271 |
'<a href="%s" target="_blank" rel="noopener noreferrer">',
|
272 |
esc_url(
|
273 |
-
__( 'https://antispambee.pluginkollektiv.org/documentation
|
274 |
'https'
|
275 |
)
|
276 |
);
|
277 |
printf(
|
278 |
/* translators: 1: opening <a> tag with link to documentation. 2: closing </a> tag. */
|
279 |
esc_html__( 'Filtering the requests depending on country. Please note the %1$sprivacy notice%2$s for this option.', 'antispam-bee' ),
|
280 |
-
wp_kses_post( $link1 ),
|
|
|
281 |
);
|
282 |
?>
|
283 |
</span>
|
@@ -294,8 +292,8 @@ class Antispam_Bee_GUI extends Antispam_Bee {
|
|
294 |
);
|
295 |
?>
|
296 |
<li>
|
297 |
-
<textarea name="
|
298 |
-
<label for="
|
299 |
<span>
|
300 |
<?php
|
301 |
printf(
|
@@ -309,8 +307,8 @@ class Antispam_Bee_GUI extends Antispam_Bee {
|
|
309 |
</label>
|
310 |
</li>
|
311 |
<li>
|
312 |
-
<textarea name="
|
313 |
-
<label for="
|
314 |
<span>
|
315 |
<?php
|
316 |
printf(
|
@@ -335,7 +333,7 @@ class Antispam_Bee_GUI extends Antispam_Bee {
|
|
335 |
$link1 = sprintf(
|
336 |
'<a href="%s" target="_blank" rel="noopener noreferrer">',
|
337 |
esc_url(
|
338 |
-
__( 'https://antispambee.pluginkollektiv.org/documentation
|
339 |
'https'
|
340 |
)
|
341 |
);
|
@@ -423,7 +421,7 @@ class Antispam_Bee_GUI extends Antispam_Bee {
|
|
423 |
<label for="ab_ignore_filter">
|
424 |
<?php
|
425 |
echo sprintf(
|
426 |
-
// phpcs:disable WordPress.
|
427 |
// Output gets escaped in _build_select()
|
428 |
// translators: %s is the select field.
|
429 |
esc_html__( 'Limit approval to %s', 'antispam-bee' ),
|
@@ -435,7 +433,7 @@ class Antispam_Bee_GUI extends Antispam_Bee {
|
|
435 |
),
|
436 |
$options['ignore_type']
|
437 |
)
|
438 |
-
// phpcs:enable
|
439 |
);
|
440 |
?>
|
441 |
<span><?php esc_html_e( 'Other types of spam will be deleted immediately', 'antispam-bee' ); ?></span>
|
@@ -509,10 +507,17 @@ class Antispam_Bee_GUI extends Antispam_Bee {
|
|
509 |
</li>
|
510 |
|
511 |
<li>
|
512 |
-
<input type="checkbox" name="
|
513 |
-
<label for="
|
514 |
-
<?php esc_html_e( '
|
515 |
-
<span
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
516 |
</label>
|
517 |
</li>
|
518 |
</ul>
|
17 |
/**
|
18 |
* Save the GUI
|
19 |
*
|
20 |
+
* @since 0.1
|
21 |
+
* @since 2.7.0
|
22 |
+
* @since 2.10.0 Change country option names
|
23 |
*/
|
24 |
public static function save_changes() {
|
25 |
if ( empty( $_POST ) ) {
|
59 |
'spam_ip' => (int) ( ! empty( $_POST['ab_spam_ip'] ) ),
|
60 |
'already_commented' => (int) ( ! empty( $_POST['ab_already_commented'] ) ),
|
61 |
'time_check' => (int) ( ! empty( $_POST['ab_time_check'] ) ),
|
|
|
62 |
|
63 |
'ignore_pings' => (int) ( ! empty( $_POST['ab_ignore_pings'] ) ),
|
64 |
'ignore_filter' => (int) ( ! empty( $_POST['ab_ignore_filter'] ) ),
|
70 |
'bbcode_check' => (int) ( ! empty( $_POST['ab_bbcode_check'] ) ),
|
71 |
'gravatar_check' => (int) ( ! empty( $_POST['ab_gravatar_check'] ) ),
|
72 |
'country_code' => (int) ( ! empty( $_POST['ab_country_code'] ) ),
|
73 |
+
'country_denied' => sanitize_text_field( wp_unslash( self::get_key( $_POST, 'ab_country_denied' ) ) ),
|
74 |
+
'country_allowed' => sanitize_text_field( wp_unslash( self::get_key( $_POST, 'ab_country_allowed' ) ) ),
|
75 |
|
76 |
'translate_api' => (int) ( ! empty( $_POST['ab_translate_api'] ) ),
|
77 |
'translate_lang' => $selected_languages,
|
78 |
|
79 |
'delete_data_on_uninstall' => (int) ( ! empty( $_POST['delete_data_on_uninstall'] ) ),
|
80 |
|
81 |
+
'use_output_buffer' => (int) ( ! empty( $_POST['ab_use_output_buffer'] ) ),
|
82 |
+
|
83 |
);
|
84 |
|
85 |
foreach ( $options['ignore_reasons'] as $key => $val ) {
|
100 |
$options['ignore_reasons'] = array();
|
101 |
}
|
102 |
|
103 |
+
if ( ! empty( $options['country_denied'] ) ) {
|
104 |
+
$options['country_denied'] = preg_replace(
|
105 |
'/[^A-Z ,;]/',
|
106 |
'',
|
107 |
+
strtoupper( $options['country_denied'] )
|
108 |
);
|
109 |
}
|
110 |
|
111 |
+
if ( ! empty( $options['country_allowed'] ) ) {
|
112 |
+
$options['country_allowed'] = preg_replace(
|
113 |
'/[^A-Z ,;]/',
|
114 |
'',
|
115 |
+
strtoupper( $options['country_allowed'] )
|
116 |
);
|
117 |
}
|
118 |
|
119 |
+
if ( empty( $options['country_denied'] ) && empty( $options['country_allowed'] ) ) {
|
120 |
$options['country_code'] = 0;
|
121 |
}
|
122 |
|
144 |
* Generation of a selectbox
|
145 |
*
|
146 |
* @since 2.4.5
|
|
|
147 |
*
|
148 |
* @param string $name Name of the Selectbox.
|
149 |
* @param array $data Array with values.
|
164 |
/**
|
165 |
* Display the GUI
|
166 |
*
|
167 |
+
* @since 0.1
|
168 |
+
* @since 2.7.0
|
169 |
+
* @since 2.10.0 Change documentation links, change country option name, and add option to parse complete markup for comment forms
|
170 |
*/
|
171 |
public static function options_page() { ?>
|
172 |
<div class="wrap" id="ab_main">
|
181 |
|
182 |
<?php $options = self::get_options(); ?>
|
183 |
<div class="ab-wrap">
|
|
|
|
|
|
|
|
|
|
|
184 |
|
185 |
<div class="ab-column ab-arrow">
|
186 |
<h3 class="icon">
|
209 |
$link1 = sprintf(
|
210 |
'<a href="%s" target="_blank" rel="noopener noreferrer">',
|
211 |
esc_url(
|
212 |
+
__( 'https://antispambee.pluginkollektiv.org/documentation/#trust-commenters-with-a-gravatar', 'antispam-bee' ),
|
213 |
'https'
|
214 |
)
|
215 |
);
|
267 |
$link1 = sprintf(
|
268 |
'<a href="%s" target="_blank" rel="noopener noreferrer">',
|
269 |
esc_url(
|
270 |
+
__( 'https://antispambee.pluginkollektiv.org/documentation/#block-comments-from-specific-countries', 'antispam-bee' ),
|
271 |
'https'
|
272 |
)
|
273 |
);
|
274 |
printf(
|
275 |
/* translators: 1: opening <a> tag with link to documentation. 2: closing </a> tag. */
|
276 |
esc_html__( 'Filtering the requests depending on country. Please note the %1$sprivacy notice%2$s for this option.', 'antispam-bee' ),
|
277 |
+
wp_kses_post( $link1 ),
|
278 |
+
'</a>'
|
279 |
);
|
280 |
?>
|
281 |
</span>
|
292 |
);
|
293 |
?>
|
294 |
<li>
|
295 |
+
<textarea name="ab_country_denied" id="ab_country_denied" class="ab-medium-field code" placeholder="<?php esc_attr_e( 'e.g. BF, SG, YE', 'antispam-bee' ); ?>"><?php echo esc_attr( $options['country_denied'] ); ?></textarea>
|
296 |
+
<label for="ab_country_denied">
|
297 |
<span>
|
298 |
<?php
|
299 |
printf(
|
307 |
</label>
|
308 |
</li>
|
309 |
<li>
|
310 |
+
<textarea name="ab_country_allowed" id="ab_country_allowed" class="ab-medium-field code" placeholder="<?php esc_attr_e( 'e.g. BF, SG, YE', 'antispam-bee' ); ?>"><?php echo esc_attr( $options['country_allowed'] ); ?></textarea>
|
311 |
+
<label for="ab_country_allowed">
|
312 |
<span>
|
313 |
<?php
|
314 |
printf(
|
333 |
$link1 = sprintf(
|
334 |
'<a href="%s" target="_blank" rel="noopener noreferrer">',
|
335 |
esc_url(
|
336 |
+
__( 'https://antispambee.pluginkollektiv.org/documentation/#allow-comments-only-in-certain-language', 'antispam-bee' ),
|
337 |
'https'
|
338 |
)
|
339 |
);
|
421 |
<label for="ab_ignore_filter">
|
422 |
<?php
|
423 |
echo sprintf(
|
424 |
+
// phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped
|
425 |
// Output gets escaped in _build_select()
|
426 |
// translators: %s is the select field.
|
427 |
esc_html__( 'Limit approval to %s', 'antispam-bee' ),
|
433 |
),
|
434 |
$options['ignore_type']
|
435 |
)
|
436 |
+
// phpcs:enable WordPress.Security.EscapeOutput.OutputNotEscaped
|
437 |
);
|
438 |
?>
|
439 |
<span><?php esc_html_e( 'Other types of spam will be deleted immediately', 'antispam-bee' ); ?></span>
|
507 |
</li>
|
508 |
|
509 |
<li>
|
510 |
+
<input type="checkbox" name="ab_use_output_buffer" id="ab_use_output_buffer" value="1" <?php checked( ! isset( $options['use_output_buffer'] ) || 1 == $options['use_output_buffer'], true ); ?> />
|
511 |
+
<label for="ab_use_output_buffer">
|
512 |
+
<?php esc_html_e( 'Check complete site markup for comment forms', 'antispam-bee' ); ?>
|
513 |
+
<span>
|
514 |
+
<?php
|
515 |
+
printf( /* translators: s=filter name */
|
516 |
+
esc_html__( 'Uses output buffering instead of the %s filter.', 'antispam-bee' ),
|
517 |
+
'<code>comment_form_field_comment</code>'
|
518 |
+
);
|
519 |
+
?>
|
520 |
+
</span>
|
521 |
</label>
|
522 |
</li>
|
523 |
</ul>
|
js/dashboard.js
CHANGED
@@ -1,111 +1,112 @@
|
|
1 |
-
(function
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
|
|
|
|
|
|
12 |
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
X = (width - leftgutter * 2) / labels.length,
|
23 |
-
max = Math.max.apply(Math, data),
|
24 |
-
Y = (height - bottomgutter - topgutter) / max;
|
25 |
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
|
|
|
|
|
|
35 |
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
47 |
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
var side = "right";
|
73 |
-
if (x + frame.getBBox().width > width) {
|
74 |
-
side = "left";
|
75 |
-
}
|
76 |
-
// set label content to determine correct dimensions
|
77 |
-
label[0].attr({text: date });
|
78 |
-
label[1].attr({text: data + "× Spam"});
|
79 |
-
var ppp = r.popup(x, y, label, side, 1),
|
80 |
-
anim = Raphael.animation({
|
81 |
-
path: ppp.path,
|
82 |
-
transform: ["t", ppp.dx, ppp.dy]
|
83 |
-
}, 200 * is_label_visible);
|
84 |
-
lx = label[0].transform()[0][1] + ppp.dx;
|
85 |
-
ly = label[0].transform()[0][2] + ppp.dy;
|
86 |
-
frame.show().stop().animate(anim);
|
87 |
-
|
88 |
-
label[0].show().stop().animateWith(frame, anim, {transform: ["t", lx, ly]}, 200 * is_label_visible);
|
89 |
-
label[1].show().stop().animateWith(frame, anim, {transform: ["t", lx, ly]}, 200 * is_label_visible);
|
90 |
-
dot.attr("r", 6);
|
91 |
-
is_label_visible = true;
|
92 |
-
}, function () {
|
93 |
-
dot.attr("r", 4);
|
94 |
-
leave_timer = setTimeout(function () {
|
95 |
-
frame.hide();
|
96 |
-
label[0].hide();
|
97 |
-
label[1].hide();
|
98 |
-
is_label_visible = false;
|
99 |
-
}, 1);
|
100 |
-
});
|
101 |
-
})(x, y, data[i], labels[i], dot);
|
102 |
-
}
|
103 |
-
p = p.concat([x, y, x, y]);
|
104 |
-
bgpp = bgpp.concat([x, y, x, y, "L", x, height - bottomgutter, "z"]);
|
105 |
-
path.attr({path: p});
|
106 |
-
bgp.attr({path: bgpp});
|
107 |
-
frame.toFront();
|
108 |
-
label[0].toFront();
|
109 |
-
label[1].toFront();
|
110 |
-
blanket.toFront();
|
111 |
-
})();
|
1 |
+
( function() {
|
2 |
+
// Grab the data
|
3 |
+
var labels = [],
|
4 |
+
data = [];
|
5 |
+
jQuery( '#ab_chart_data tfoot th' ).each( function() {
|
6 |
+
labels.push( jQuery( this ).text() );
|
7 |
+
} );
|
8 |
+
jQuery( '#ab_chart_data tbody td' ).each( function() {
|
9 |
+
data.push( jQuery( this ).text() );
|
10 |
+
} );
|
11 |
|
12 |
+
// Draw
|
13 |
+
var width = jQuery( '#ab_chart' ).parent().width() + 8,
|
14 |
+
height = 140,
|
15 |
+
leftgutter = 0,
|
16 |
+
bottomgutter = 22,
|
17 |
+
topgutter = 22,
|
18 |
+
color = '#135e96',
|
19 |
+
r = Raphael( 'ab_chart', width, height ),
|
20 |
+
txt = { font: 'bold 12px "Open Sans", sans-serif', fill: '#1d2327' },
|
21 |
+
X = ( width - leftgutter * 2 ) / labels.length,
|
22 |
+
max = Math.max.apply( Math, data ),
|
23 |
+
Y = ( height - bottomgutter - topgutter ) / max;
|
24 |
|
25 |
+
// Max value
|
26 |
+
r
|
27 |
+
.text( 16, 16, max )
|
28 |
+
.attr(
|
29 |
+
{
|
30 |
+
font: 'normal 10px "Open Sans", sans-serif',
|
31 |
+
fill: '#a7aaad',
|
32 |
+
}
|
33 |
+
);
|
|
|
|
|
|
|
34 |
|
35 |
+
var path = r.path().attr( { stroke: color, 'stroke-width': 2, 'stroke-linejoin': 'round' } ),
|
36 |
+
bgp = r.path().attr( { stroke: 'none', opacity: .3, fill: color } ),
|
37 |
+
label = r.set(),
|
38 |
+
lx = 0,
|
39 |
+
ly = 0,
|
40 |
+
is_label_visible = false,
|
41 |
+
leave_timer,
|
42 |
+
blanket = r.set();
|
43 |
+
label.push( r.text( 60, 12, '' ).attr( txt ) );
|
44 |
+
label.push( r.text( 60, 27, '' ).attr( txt ).attr( { fill: color } ) );
|
45 |
+
label.hide();
|
46 |
+
var frame = r.popup( 100, 100, label, 'right' ).attr( { fill: '#fff', stroke: '#444', 'stroke-width': 1 } ).hide();
|
47 |
|
48 |
+
var p, bgpp;
|
49 |
+
for ( var i = 0, ii = labels.length; i < ii; i++ ) {
|
50 |
+
var y = Math.round( height - bottomgutter - Y * data[i] ),
|
51 |
+
x = Math.round( leftgutter + X * ( i + .5 ) );
|
52 |
+
if ( ! i ) {
|
53 |
+
p = [ 'M', x, y, 'C', x, y ];
|
54 |
+
bgpp = [ 'M', leftgutter + X * .5, height - bottomgutter, 'L', x, y, 'C', x, y ];
|
55 |
+
}
|
56 |
+
if ( i && i < ii - 1 ) {
|
57 |
+
var Y0 = Math.round( height - bottomgutter - Y * data[i - 1] ),
|
58 |
+
X0 = Math.round( leftgutter + X * ( i - .5 ) ),
|
59 |
+
Y2 = Math.round( height - bottomgutter - Y * data[i + 1] ),
|
60 |
+
X2 = Math.round( leftgutter + X * ( i + 1.5 ) );
|
61 |
+
var a = getAnchors( X0, Y0, x, y, X2, Y2 );
|
62 |
+
p = p.concat( [ a.x1, a.y1, x, y, a.x2, a.y2 ] );
|
63 |
+
bgpp = bgpp.concat( [ a.x1, a.y1, x, y, a.x2, a.y2 ] );
|
64 |
+
}
|
65 |
+
var dot = r.circle( x, y, 4 ).attr( { fill: '#fff', stroke: color, 'stroke-width': 1 } );
|
66 |
+
blanket.push( r.rect( leftgutter + X * i, 0, X, height - bottomgutter ).attr( { stroke: 'none', fill: '#fff', opacity: .2 } ) );
|
67 |
+
var rect = blanket[blanket.length - 1];
|
68 |
+
( function( x, y, data, date, dot ) {
|
69 |
+
var timer,
|
70 |
+
i = 0;
|
71 |
+
rect.hover( function() {
|
72 |
+
clearTimeout( leave_timer );
|
73 |
+
var side = 'right';
|
74 |
+
if ( x + frame.getBBox().width > width ) {
|
75 |
+
side = 'left';
|
76 |
+
}
|
77 |
+
// set label content to determine correct dimensions
|
78 |
+
label[0].attr( { text: date } );
|
79 |
+
label[1].attr( { text: data + '× Spam' } );
|
80 |
+
var ppp = r.popup( x, y, label, side, 1 ),
|
81 |
+
anim = Raphael.animation( {
|
82 |
+
path: ppp.path,
|
83 |
+
transform: [ 't', ppp.dx, ppp.dy ],
|
84 |
+
}, 200 * is_label_visible );
|
85 |
+
lx = label[0].transform()[0][1] + ppp.dx;
|
86 |
+
ly = label[0].transform()[0][2] + ppp.dy;
|
87 |
+
frame.show().stop().animate( anim );
|
88 |
|
89 |
+
label[0].show().stop().animateWith( frame, anim, { transform: [ 't', lx, ly ] }, 200 * is_label_visible );
|
90 |
+
label[1].show().stop().animateWith( frame, anim, { transform: [ 't', lx, ly ] }, 200 * is_label_visible );
|
91 |
+
dot.attr( 'r', 6 );
|
92 |
+
is_label_visible = true;
|
93 |
+
}, function() {
|
94 |
+
dot.attr( 'r', 4 );
|
95 |
+
leave_timer = setTimeout( function() {
|
96 |
+
frame.hide();
|
97 |
+
label[0].hide();
|
98 |
+
label[1].hide();
|
99 |
+
is_label_visible = false;
|
100 |
+
}, 1 );
|
101 |
+
} );
|
102 |
+
}( x, y, data[i], labels[i], dot ) );
|
103 |
+
}
|
104 |
+
p = p.concat( [ x, y, x, y ] );
|
105 |
+
bgpp = bgpp.concat( [ x, y, x, y, 'L', x, height - bottomgutter, 'z' ] );
|
106 |
+
path.attr( { path: p } );
|
107 |
+
bgp.attr( { path: bgpp } );
|
108 |
+
frame.toFront();
|
109 |
+
label[0].toFront();
|
110 |
+
label[1].toFront();
|
111 |
+
blanket.toFront();
|
112 |
+
}() );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
js/dashboard.min.js
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
-
(function(){var labels=[],data=[];jQuery(
|
2 |
if(i&&i<ii-1){var Y0=Math.round(height-bottomgutter-Y*data[i-1]),X0=Math.round(leftgutter+X*(i-.5)),Y2=Math.round(height-bottomgutter-Y*data[i+1]),X2=Math.round(leftgutter+X*(i+1.5));var a=getAnchors(X0,Y0,x,y,X2,Y2);p=p.concat([a.x1,a.y1,x,y,a.x2,a.y2]);bgpp=bgpp.concat([a.x1,a.y1,x,y,a.x2,a.y2])}
|
3 |
-
var dot=r.circle(x,y,4).attr({fill:
|
4 |
-
label[0].attr({text:date});label[1].attr({text:data+
|
5 |
-
p=p.concat([x,y,x,y]);bgpp=bgpp.concat([x,y,x,y,
|
1 |
+
(function(){var labels=[],data=[];jQuery('#ab_chart_data tfoot th').each(function(){labels.push(jQuery(this).text())});jQuery('#ab_chart_data tbody td').each(function(){data.push(jQuery(this).text())});var width=jQuery('#ab_chart').parent().width()+8,height=140,leftgutter=0,bottomgutter=22,topgutter=22,color='#135e96',r=Raphael('ab_chart',width,height),txt={font:'bold 12px "Open Sans", sans-serif',fill:'#1d2327'},X=(width-leftgutter*2)/labels.length,max=Math.max.apply(Math,data),Y=(height-bottomgutter-topgutter)/max;r.text(16,16,max).attr({font:'normal 10px "Open Sans", sans-serif',fill:'#a7aaad',});var path=r.path().attr({stroke:color,'stroke-width':2,'stroke-linejoin':'round'}),bgp=r.path().attr({stroke:'none',opacity:.3,fill:color}),label=r.set(),lx=0,ly=0,is_label_visible=!1,leave_timer,blanket=r.set();label.push(r.text(60,12,'').attr(txt));label.push(r.text(60,27,'').attr(txt).attr({fill:color}));label.hide();var frame=r.popup(100,100,label,'right').attr({fill:'#fff',stroke:'#444','stroke-width':1}).hide();var p,bgpp;for(var i=0,ii=labels.length;i<ii;i++){var y=Math.round(height-bottomgutter-Y*data[i]),x=Math.round(leftgutter+X*(i+.5));if(!i){p=['M',x,y,'C',x,y];bgpp=['M',leftgutter+X*.5,height-bottomgutter,'L',x,y,'C',x,y]}
|
2 |
if(i&&i<ii-1){var Y0=Math.round(height-bottomgutter-Y*data[i-1]),X0=Math.round(leftgutter+X*(i-.5)),Y2=Math.round(height-bottomgutter-Y*data[i+1]),X2=Math.round(leftgutter+X*(i+1.5));var a=getAnchors(X0,Y0,x,y,X2,Y2);p=p.concat([a.x1,a.y1,x,y,a.x2,a.y2]);bgpp=bgpp.concat([a.x1,a.y1,x,y,a.x2,a.y2])}
|
3 |
+
var dot=r.circle(x,y,4).attr({fill:'#fff',stroke:color,'stroke-width':1});blanket.push(r.rect(leftgutter+X*i,0,X,height-bottomgutter).attr({stroke:'none',fill:'#fff',opacity:.2}));var rect=blanket[blanket.length-1];(function(x,y,data,date,dot){var timer,i=0;rect.hover(function(){clearTimeout(leave_timer);var side='right';if(x+frame.getBBox().width>width){side='left'}
|
4 |
+
label[0].attr({text:date});label[1].attr({text:data+'× Spam'});var ppp=r.popup(x,y,label,side,1),anim=Raphael.animation({path:ppp.path,transform:['t',ppp.dx,ppp.dy],},200*is_label_visible);lx=label[0].transform()[0][1]+ppp.dx;ly=label[0].transform()[0][2]+ppp.dy;frame.show().stop().animate(anim);label[0].show().stop().animateWith(frame,anim,{transform:['t',lx,ly]},200*is_label_visible);label[1].show().stop().animateWith(frame,anim,{transform:['t',lx,ly]},200*is_label_visible);dot.attr('r',6);is_label_visible=!0},function(){dot.attr('r',4);leave_timer=setTimeout(function(){frame.hide();label[0].hide();label[1].hide();is_label_visible=!1},1)})}(x,y,data[i],labels[i],dot))}
|
5 |
+
p=p.concat([x,y,x,y]);bgpp=bgpp.concat([x,y,x,y,'L',x,height-bottomgutter,'z']);path.attr({path:p});bgp.attr({path:bgpp});frame.toFront();label[0].toFront();label[1].toFront();blanket.toFront()}())
|
js/raphael.helper.js
CHANGED
@@ -1,142 +1,140 @@
|
|
1 |
var tokenRegex = /\{([^\}]+)\}/g,
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
23 |
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
dy = Y - (y - gap);
|
99 |
-
break;
|
100 |
-
case "left":
|
101 |
-
dx = X - (x + r + w + r + gap);
|
102 |
-
dy = Y - (y + r + mask.top + gap);
|
103 |
-
break;
|
104 |
-
case "right":
|
105 |
-
dx = X - (x - gap);
|
106 |
-
dy = Y - (y + r + mask.top + gap);
|
107 |
-
break;
|
108 |
-
}
|
109 |
-
out.translate(dx, dy);
|
110 |
-
if (ret) {
|
111 |
-
ret = out.attr("path");
|
112 |
-
out.remove();
|
113 |
-
return {
|
114 |
-
path: ret,
|
115 |
-
dx: dx,
|
116 |
-
dy: dy
|
117 |
-
};
|
118 |
-
}
|
119 |
-
set.translate(dx, dy);
|
120 |
-
return out;
|
121 |
};
|
122 |
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
}
|
1 |
var tokenRegex = /\{([^\}]+)\}/g,
|
2 |
+
objNotationRegex = /(?:(?:^|\.)(.+?)(?=\[|\.|$|\()|\[('|")(.+?)\2\])(\(\))?/g,
|
3 |
+
replacer = function( all, key, obj ) {
|
4 |
+
var res = obj;
|
5 |
+
key.replace( objNotationRegex, function( all, name, quote, quotedName, isFunc ) {
|
6 |
+
name = name || quotedName;
|
7 |
+
if ( res ) {
|
8 |
+
if ( name in res ) {
|
9 |
+
res = res[name];
|
10 |
+
}
|
11 |
+
typeof res === 'function' && isFunc && ( res = res() );
|
12 |
+
}
|
13 |
+
} );
|
14 |
+
res = ( res == null || res == obj ? all : res ) + '';
|
15 |
+
return res;
|
16 |
+
},
|
17 |
+
fill = function( str, obj ) {
|
18 |
+
return String( str ).replace( tokenRegex, function( all, key ) {
|
19 |
+
return replacer( all, key, obj );
|
20 |
+
} );
|
21 |
+
};
|
22 |
|
23 |
+
Raphael.fn.popup = function( X, Y, set, pos, ret ) {
|
24 |
+
pos = String( pos || 'top-middle' ).split( '-' );
|
25 |
+
pos[1] = pos[1] || 'middle';
|
26 |
+
var r = 5,
|
27 |
+
bb = set.getBBox(),
|
28 |
+
w = Math.round( bb.width ),
|
29 |
+
h = Math.round( bb.height ),
|
30 |
+
x = Math.round( bb.x ) - r,
|
31 |
+
y = Math.round( bb.y ) - r,
|
32 |
+
gap = Math.min( h / 2, w / 2, 10 ),
|
33 |
+
shapes = {
|
34 |
+
top: 'M{x},{y}h{w4},{w4},{w4},{w4}a{r},{r},0,0,1,{r},{r}v{h4},{h4},{h4},{h4}a{r},{r},0,0,1,-{r},{r}l-{right},0-{gap},{gap}-{gap}-{gap}-{left},0a{r},{r},0,0,1-{r}-{r}v-{h4}-{h4}-{h4}-{h4}a{r},{r},0,0,1,{r}-{r}z',
|
35 |
+
bottom: 'M{x},{y}l{left},0,{gap}-{gap},{gap},{gap},{right},0a{r},{r},0,0,1,{r},{r}v{h4},{h4},{h4},{h4}a{r},{r},0,0,1,-{r},{r}h-{w4}-{w4}-{w4}-{w4}a{r},{r},0,0,1-{r}-{r}v-{h4}-{h4}-{h4}-{h4}a{r},{r},0,0,1,{r}-{r}z',
|
36 |
+
right: 'M{x},{y}h{w4},{w4},{w4},{w4}a{r},{r},0,0,1,{r},{r}v{h4},{h4},{h4},{h4}a{r},{r},0,0,1,-{r},{r}h-{w4}-{w4}-{w4}-{w4}a{r},{r},0,0,1-{r}-{r}l0-{bottom}-{gap}-{gap},{gap}-{gap},0-{top}a{r},{r},0,0,1,{r}-{r}z',
|
37 |
+
left: 'M{x},{y}h{w4},{w4},{w4},{w4}a{r},{r},0,0,1,{r},{r}l0,{top},{gap},{gap}-{gap},{gap},0,{bottom}a{r},{r},0,0,1,-{r},{r}h-{w4}-{w4}-{w4}-{w4}a{r},{r},0,0,1-{r}-{r}v-{h4}-{h4}-{h4}-{h4}a{r},{r},0,0,1,{r}-{r}z',
|
38 |
+
},
|
39 |
+
offset = {
|
40 |
+
hx0: X - ( x + r + w - gap * 2 ),
|
41 |
+
hx1: X - ( x + r + w / 2 - gap ),
|
42 |
+
hx2: X - ( x + r + gap ),
|
43 |
+
vhy: Y - ( y + r + h + r + gap ),
|
44 |
+
'^hy': Y - ( y - gap ),
|
45 |
|
46 |
+
},
|
47 |
+
mask = [ {
|
48 |
+
x: x + r,
|
49 |
+
y: y,
|
50 |
+
w: w,
|
51 |
+
w4: w / 4,
|
52 |
+
h4: h / 4,
|
53 |
+
right: 0,
|
54 |
+
left: w - gap * 2,
|
55 |
+
bottom: 0,
|
56 |
+
top: h - gap * 2,
|
57 |
+
r: r,
|
58 |
+
h: h,
|
59 |
+
gap: gap,
|
60 |
+
}, {
|
61 |
+
x: x + r,
|
62 |
+
y: y,
|
63 |
+
w: w,
|
64 |
+
w4: w / 4,
|
65 |
+
h4: h / 4,
|
66 |
+
left: w / 2 - gap,
|
67 |
+
right: w / 2 - gap,
|
68 |
+
top: h / 2 - gap,
|
69 |
+
bottom: h / 2 - gap,
|
70 |
+
r: r,
|
71 |
+
h: h,
|
72 |
+
gap: gap,
|
73 |
+
}, {
|
74 |
+
x: x + r,
|
75 |
+
y: y,
|
76 |
+
w: w,
|
77 |
+
w4: w / 4,
|
78 |
+
h4: h / 4,
|
79 |
+
left: 0,
|
80 |
+
right: w - gap * 2,
|
81 |
+
top: 0,
|
82 |
+
bottom: h - gap * 2,
|
83 |
+
r: r,
|
84 |
+
h: h,
|
85 |
+
gap: gap,
|
86 |
+
} ][pos[1] == 'middle' ? 1 : ( pos[1] == 'top' || pos[1] == 'left' ) * 2];
|
87 |
+
var dx = 0,
|
88 |
+
dy = 0,
|
89 |
+
out = this.path( fill( shapes[pos[0]], mask ) ).insertBefore( set );
|
90 |
+
switch ( pos[0] ) {
|
91 |
+
case 'top':
|
92 |
+
dx = X - ( x + r + mask.left + gap );
|
93 |
+
dy = Y - ( y + r + h + r + gap );
|
94 |
+
break;
|
95 |
+
case 'bottom':
|
96 |
+
dx = X - ( x + r + mask.left + gap );
|
97 |
+
dy = Y - ( y - gap );
|
98 |
+
break;
|
99 |
+
case 'left':
|
100 |
+
dx = X - ( x + r + w + r + gap );
|
101 |
+
dy = Y - ( y + r + mask.top + gap );
|
102 |
+
break;
|
103 |
+
case 'right':
|
104 |
+
dx = X - ( x - gap );
|
105 |
+
dy = Y - ( y + r + mask.top + gap );
|
106 |
+
break;
|
107 |
+
}
|
108 |
+
out.translate( dx, dy );
|
109 |
+
if ( ret ) {
|
110 |
+
ret = out.attr( 'path' );
|
111 |
+
out.remove();
|
112 |
+
return {
|
113 |
+
path: ret,
|
114 |
+
dx: dx,
|
115 |
+
dy: dy,
|
116 |
+
};
|
117 |
+
}
|
118 |
+
set.translate( dx, dy );
|
119 |
+
return out;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
120 |
};
|
121 |
|
122 |
+
function getAnchors( p1x, p1y, p2x, p2y, p3x, p3y ) {
|
123 |
+
var l1 = ( p2x - p1x ) / 2,
|
124 |
+
l2 = ( p3x - p2x ) / 2,
|
125 |
+
a = Math.atan( ( p2x - p1x ) / Math.abs( p2y - p1y ) ),
|
126 |
+
b = Math.atan( ( p3x - p2x ) / Math.abs( p2y - p3y ) );
|
127 |
+
a = p1y < p2y ? Math.PI - a : a;
|
128 |
+
b = p3y < p2y ? Math.PI - b : b;
|
129 |
+
var alpha = Math.PI / 2 - ( ( a + b ) % ( Math.PI * 2 ) ) / 2,
|
130 |
+
dx1 = l1 * Math.sin( alpha + a ),
|
131 |
+
dy1 = l1 * Math.cos( alpha + a ),
|
132 |
+
dx2 = l2 * Math.sin( alpha + b ),
|
133 |
+
dy2 = l2 * Math.cos( alpha + b );
|
134 |
+
return {
|
135 |
+
x1: p2x - dx1,
|
136 |
+
y1: p2y + dy1,
|
137 |
+
x2: p2x + dx2,
|
138 |
+
y2: p2y + dy2,
|
139 |
+
};
|
140 |
+
}
|
|
js/raphael.helper.min.js
CHANGED
@@ -1,5 +1,4 @@
|
|
1 |
-
var tokenRegex=/\{([^\}]+)\}/g,objNotationRegex=/(?:(?:^|\.)(.+?)(?=\[|\.|$|\()|\[('|")(.+?)\2\])(\(\))?/g,replacer=function(
|
2 |
-
Raphael.fn.popup=function(
|
3 |
-
|
4 |
-
|
5 |
-
{path:k,dx:m,dy:n};g.translate(m,n);return q};function getAnchors(c,h,g,a,k,b){var f=(g-c)/2,d=(k-g)/2;c=Math.atan((g-c)/Math.abs(a-h));k=Math.atan((k-g)/Math.abs(a-b));c=h<a?Math.PI-c:c;k=b<a?Math.PI-k:k;b=Math.PI/2-(c+k)%(2*Math.PI)/2;h=f*Math.sin(b+c);f*=Math.cos(b+c);c=d*Math.sin(b+k);d*=Math.cos(b+k);return{x1:g-h,y1:a+f,x2:g+c,y2:a+d}};
|
1 |
+
var tokenRegex=/\{([^\}]+)\}/g,objNotationRegex=/(?:(?:^|\.)(.+?)(?=\[|\.|$|\()|\[('|")(.+?)\2\])(\(\))?/g,replacer=function(all,key,obj){var res=obj;key.replace(objNotationRegex,function(all,name,quote,quotedName,isFunc){name=name||quotedName;if(res){if(name in res){res=res[name]}
|
2 |
+
typeof res==='function'&&isFunc&&(res=res())}});res=(res==null||res==obj?all:res)+'';return res},fill=function(str,obj){return String(str).replace(tokenRegex,function(all,key){return replacer(all,key,obj)})};Raphael.fn.popup=function(X,Y,set,pos,ret){pos=String(pos||'top-middle').split('-');pos[1]=pos[1]||'middle';var r=5,bb=set.getBBox(),w=Math.round(bb.width),h=Math.round(bb.height),x=Math.round(bb.x)-r,y=Math.round(bb.y)-r,gap=Math.min(h/2,w/2,10),shapes={top:'M{x},{y}h{w4},{w4},{w4},{w4}a{r},{r},0,0,1,{r},{r}v{h4},{h4},{h4},{h4}a{r},{r},0,0,1,-{r},{r}l-{right},0-{gap},{gap}-{gap}-{gap}-{left},0a{r},{r},0,0,1-{r}-{r}v-{h4}-{h4}-{h4}-{h4}a{r},{r},0,0,1,{r}-{r}z',bottom:'M{x},{y}l{left},0,{gap}-{gap},{gap},{gap},{right},0a{r},{r},0,0,1,{r},{r}v{h4},{h4},{h4},{h4}a{r},{r},0,0,1,-{r},{r}h-{w4}-{w4}-{w4}-{w4}a{r},{r},0,0,1-{r}-{r}v-{h4}-{h4}-{h4}-{h4}a{r},{r},0,0,1,{r}-{r}z',right:'M{x},{y}h{w4},{w4},{w4},{w4}a{r},{r},0,0,1,{r},{r}v{h4},{h4},{h4},{h4}a{r},{r},0,0,1,-{r},{r}h-{w4}-{w4}-{w4}-{w4}a{r},{r},0,0,1-{r}-{r}l0-{bottom}-{gap}-{gap},{gap}-{gap},0-{top}a{r},{r},0,0,1,{r}-{r}z',left:'M{x},{y}h{w4},{w4},{w4},{w4}a{r},{r},0,0,1,{r},{r}l0,{top},{gap},{gap}-{gap},{gap},0,{bottom}a{r},{r},0,0,1,-{r},{r}h-{w4}-{w4}-{w4}-{w4}a{r},{r},0,0,1-{r}-{r}v-{h4}-{h4}-{h4}-{h4}a{r},{r},0,0,1,{r}-{r}z',},offset={hx0:X-(x+r+w-gap*2),hx1:X-(x+r+w/2-gap),hx2:X-(x+r+gap),vhy:Y-(y+r+h+r+gap),'^hy':Y-(y-gap),},mask=[{x:x+r,y:y,w:w,w4:w/4,h4:h/4,right:0,left:w-gap*2,bottom:0,top:h-gap*2,r:r,h:h,gap:gap,},{x:x+r,y:y,w:w,w4:w/4,h4:h/4,left:w/2-gap,right:w/2-gap,top:h/2-gap,bottom:h/2-gap,r:r,h:h,gap:gap,},{x:x+r,y:y,w:w,w4:w/4,h4:h/4,left:0,right:w-gap*2,top:0,bottom:h-gap*2,r:r,h:h,gap:gap,}][pos[1]=='middle'?1:(pos[1]=='top'||pos[1]=='left')*2];var dx=0,dy=0,out=this.path(fill(shapes[pos[0]],mask)).insertBefore(set);switch(pos[0]){case 'top':dx=X-(x+r+mask.left+gap);dy=Y-(y+r+h+r+gap);break;case 'bottom':dx=X-(x+r+mask.left+gap);dy=Y-(y-gap);break;case 'left':dx=X-(x+r+w+r+gap);dy=Y-(y+r+mask.top+gap);break;case 'right':dx=X-(x-gap);dy=Y-(y+r+mask.top+gap);break}
|
3 |
+
out.translate(dx,dy);if(ret){ret=out.attr('path');out.remove();return{path:ret,dx:dx,dy:dy,}}
|
4 |
+
set.translate(dx,dy);return out};function getAnchors(p1x,p1y,p2x,p2y,p3x,p3y){var l1=(p2x-p1x)/2,l2=(p3x-p2x)/2,a=Math.atan((p2x-p1x)/Math.abs(p2y-p1y)),b=Math.atan((p3x-p2x)/Math.abs(p2y-p3y));a=p1y<p2y?Math.PI-a:a;b=p3y<p2y?Math.PI-b:b;var alpha=Math.PI/2-((a+b)%(Math.PI*2))/2,dx1=l1*Math.sin(alpha+a),dy1=l1*Math.cos(alpha+a),dx2=l2*Math.sin(alpha+b),dy2=l2*Math.cos(alpha+b);return{x1:p2x-dx1,y1:p2y+dy1,x2:p2x+dx2,y2:p2y+dy2,}}
|
|
js/scripts.js
CHANGED
@@ -1,16 +1,16 @@
|
|
1 |
-
jQuery(document).ready(
|
2 |
-
function($) {
|
3 |
function ab_flag_spam() {
|
4 |
-
var $$ = $('#ab_flag_spam'),
|
5 |
-
nextAll = $$.parent('li').nextAll( '.ab_flag_spam_child' );
|
6 |
|
7 |
nextAll.css(
|
8 |
'display',
|
9 |
-
( $$.is(':checked') ? 'list-item' : 'none' )
|
10 |
);
|
11 |
}
|
12 |
|
13 |
-
$('#ab_flag_spam').on(
|
14 |
'change',
|
15 |
ab_flag_spam
|
16 |
);
|
1 |
+
jQuery( document ).ready(
|
2 |
+
function( $ ) {
|
3 |
function ab_flag_spam() {
|
4 |
+
var $$ = $( '#ab_flag_spam' ),
|
5 |
+
nextAll = $$.parent( 'li' ).nextAll( '.ab_flag_spam_child' );
|
6 |
|
7 |
nextAll.css(
|
8 |
'display',
|
9 |
+
( $$.is( ':checked' ) ? 'list-item' : 'none' )
|
10 |
);
|
11 |
}
|
12 |
|
13 |
+
$( '#ab_flag_spam' ).on(
|
14 |
'change',
|
15 |
ab_flag_spam
|
16 |
);
|
js/scripts.min.js
CHANGED
@@ -1 +1,2 @@
|
|
1 |
-
jQuery(document).ready(function(
|
|
1 |
+
jQuery(document).ready(function($){function ab_flag_spam(){var $$=$('#ab_flag_spam'),nextAll=$$.parent('li').nextAll('.ab_flag_spam_child');nextAll.css('display',($$.is(':checked')?'list-item':'none'))}
|
2 |
+
$('#ab_flag_spam').on('change',ab_flag_spam);ab_flag_spam()})
|
output.log
ADDED
@@ -0,0 +1,66 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Running php-build composer
|
2 |
+
WARNING! Your password will be stored unencrypted in /home/runner/.docker/config.json.
|
3 |
+
Configure a credential helper to remove this warning. See
|
4 |
+
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
|
5 |
+
|
6 |
+
Login Succeeded
|
7 |
+
Pulling docker.pkg.github.com/pluginkollektiv/antispam-bee/php-actions_composer_antispam-bee:php-latest-build2
|
8 |
+
WARNING: ⚠️ Failed to pull manifest by the resolved digest. This registry does not
|
9 |
+
appear to conform to the distribution registry specification; falling back to
|
10 |
+
pull by tag. This fallback is DEPRECATED, and will be removed in a future
|
11 |
+
release. Please contact admins of https://docker.pkg.github.com. ⚠️
|
12 |
+
|
13 |
+
php-latest-build2: Pulling from pluginkollektiv/antispam-bee/php-actions_composer_antispam-bee
|
14 |
+
9aae54b2144e: Pulling fs layer
|
15 |
+
0552190813ec: Pulling fs layer
|
16 |
+
d6abf49ad7ff: Pulling fs layer
|
17 |
+
4a7b791901cf: Pulling fs layer
|
18 |
+
483f3f97a5bc: Pulling fs layer
|
19 |
+
e078e9d6b760: Pulling fs layer
|
20 |
+
2c134042be40: Pulling fs layer
|
21 |
+
db5fecf1aa2d: Pulling fs layer
|
22 |
+
f28c38a75bec: Pulling fs layer
|
23 |
+
159f106d1fc1: Pulling fs layer
|
24 |
+
4a7b791901cf: Waiting
|
25 |
+
483f3f97a5bc: Waiting
|
26 |
+
e078e9d6b760: Waiting
|
27 |
+
2c134042be40: Waiting
|
28 |
+
db5fecf1aa2d: Waiting
|
29 |
+
f28c38a75bec: Waiting
|
30 |
+
159f106d1fc1: Waiting
|
31 |
+
d6abf49ad7ff: Verifying Checksum
|
32 |
+
d6abf49ad7ff: Download complete
|
33 |
+
0552190813ec: Verifying Checksum
|
34 |
+
0552190813ec: Download complete
|
35 |
+
4a7b791901cf: Verifying Checksum
|
36 |
+
4a7b791901cf: Download complete
|
37 |
+
9aae54b2144e: Verifying Checksum
|
38 |
+
9aae54b2144e: Download complete
|
39 |
+
e078e9d6b760: Verifying Checksum
|
40 |
+
e078e9d6b760: Download complete
|
41 |
+
9aae54b2144e: Pull complete
|
42 |
+
0552190813ec: Pull complete
|
43 |
+
d6abf49ad7ff: Pull complete
|
44 |
+
4a7b791901cf: Pull complete
|
45 |
+
483f3f97a5bc: Verifying Checksum
|
46 |
+
483f3f97a5bc: Download complete
|
47 |
+
483f3f97a5bc: Pull complete
|
48 |
+
e078e9d6b760: Pull complete
|
49 |
+
f28c38a75bec: Verifying Checksum
|
50 |
+
f28c38a75bec: Download complete
|
51 |
+
2c134042be40: Verifying Checksum
|
52 |
+
2c134042be40: Download complete
|
53 |
+
db5fecf1aa2d: Verifying Checksum
|
54 |
+
db5fecf1aa2d: Download complete
|
55 |
+
159f106d1fc1: Verifying Checksum
|
56 |
+
159f106d1fc1: Download complete
|
57 |
+
2c134042be40: Pull complete
|
58 |
+
db5fecf1aa2d: Pull complete
|
59 |
+
f28c38a75bec: Pull complete
|
60 |
+
159f106d1fc1: Pull complete
|
61 |
+
Digest: sha256:a6b0df3c018b4a3bb89e86996e4f4f3b15381d959d9985a1074cb62e916119df
|
62 |
+
Status: Downloaded newer image for docker.pkg.github.com/pluginkollektiv/antispam-bee/php-actions_composer_antispam-bee:php-latest-build2
|
63 |
+
docker.pkg.github.com/pluginkollektiv/antispam-bee/php-actions_composer_antispam-bee:php-latest-build2
|
64 |
+
Docker tag: docker.pkg.github.com/pluginkollektiv/antispam-bee/php-actions_composer_antispam-bee:php-latest-build2
|
65 |
+
No private keys supplied
|
66 |
+
Command: composer install --no-progress --no-interaction --ignore-platform-reqs
|
phpunit.xml.dist
DELETED
@@ -1,25 +0,0 @@
|
|
1 |
-
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
-
<phpunit
|
3 |
-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
4 |
-
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.8/phpunit.xsd"
|
5 |
-
backupGlobals="false"
|
6 |
-
backupStaticAttributes="false"
|
7 |
-
bootstrap="vendor/autoload.php"
|
8 |
-
colors="true"
|
9 |
-
convertErrorsToExceptions="true"
|
10 |
-
convertNoticesToExceptions="true"
|
11 |
-
convertWarningsToExceptions="true"
|
12 |
-
processIsolation="false"
|
13 |
-
stopOnFailure="false">
|
14 |
-
<testsuites>
|
15 |
-
<testsuite name="unit">
|
16 |
-
<directory suffix=".php">tests/Unit</directory>
|
17 |
-
</testsuite>
|
18 |
-
<testsuite name="integration">
|
19 |
-
<directory suffix=".php">tests/Integration</directory>
|
20 |
-
</testsuite>
|
21 |
-
</testsuites>
|
22 |
-
<listeners>
|
23 |
-
<listener class="TestListener" file="tests/TestListener.php"/>
|
24 |
-
</listeners>
|
25 |
-
</phpunit>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
readme.txt
CHANGED
@@ -1,11 +1,11 @@
|
|
1 |
# Antispam Bee #
|
2 |
-
* Contributors: pluginkollektiv, websupporter, schlessera, zodiac1978, swissspidy, krafit, kau-boy, florianbrinkmann
|
3 |
* Tags: anti-spam, antispam, block spam, comment, comments, comment spam, pingback, spam, spam filter, trackback, GDPR
|
4 |
* Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=TD4AMD2D8EMZW
|
5 |
* Requires at least: 4.5
|
6 |
-
* Tested up to: 5.
|
7 |
* Requires PHP: 5.2
|
8 |
-
* Stable tag: 2.
|
9 |
* License: GPLv2 or later
|
10 |
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
|
11 |
|
@@ -92,8 +92,19 @@ A complete documentation is available on [pluginkollektiv.org](https://antispamb
|
|
92 |
|
93 |
## Changelog ##
|
94 |
|
95 |
-
### 2.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
96 |
|
|
|
97 |
* Enhancement: Add filter to allow ajax calls
|
98 |
* Tweak: Better wording for BBCode feature in plugin description
|
99 |
* Tweak: Better screenshots in the plugin directory
|
1 |
# Antispam Bee #
|
2 |
+
* Contributors: pluginkollektiv, websupporter, schlessera, zodiac1978, swissspidy, krafit, kau-boy, florianbrinkmann, pfefferle
|
3 |
* Tags: anti-spam, antispam, block spam, comment, comments, comment spam, pingback, spam, spam filter, trackback, GDPR
|
4 |
* Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=TD4AMD2D8EMZW
|
5 |
* Requires at least: 4.5
|
6 |
+
* Tested up to: 5.8
|
7 |
* Requires PHP: 5.2
|
8 |
+
* Stable tag: 2.10.0
|
9 |
* License: GPLv2 or later
|
10 |
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
|
11 |
|
92 |
|
93 |
## Changelog ##
|
94 |
|
95 |
+
### 2.10.0 ###
|
96 |
+
* Fix: Switch from ip2country.info to iplocate.io for country check
|
97 |
+
* Enhancement: Use filter to add the honeypot field instead of output buffering for new installations and added option to switch between the both ways
|
98 |
+
* Tweak: Added comment user agent to regex pattern check
|
99 |
+
* Tweak: Make the ping detection filterable to support new comment types
|
100 |
+
* Tweak: Updated internal documentation links
|
101 |
+
* Tweak: Several updates and optimizations in the testing process
|
102 |
+
* Tweak: Adjust color palette to recent WP version
|
103 |
+
* Tweak: Adjust wording in variables and option names
|
104 |
+
* Readme: Add new contributor and clean up unused code
|
105 |
+
|
106 |
|
107 |
+
### 2.9.4 ###
|
108 |
* Enhancement: Add filter to allow ajax calls
|
109 |
* Tweak: Better wording for BBCode feature in plugin description
|
110 |
* Tweak: Better screenshots in the plugin directory
|