diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..79207a40 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,22 @@ +# This file is for unifying the coding style for different editors and IDEs +# editorconfig.org + +# WordPress Coding Standards +# https://make.wordpress.org/core/handbook/coding-standards/ + +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true +indent_style = tab +indent_size = 4 + +[{.jshintrc,*.json,*.yml}] +indent_style = space +indent_size = 2 + +[{*.txt,wp-config-sample.php}] +end_of_line = crlf diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index 782125e7..00000000 --- a/.eslintrc.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "extends": "plugin:@wordpress/eslint-plugin/es5", - "env": { - "browser": true, - "jquery": true - }, - "globals": { - "Raphael": "readonly", - "getAnchors": "readonly" - }, - "rules": { - "camelcase": 0, - "eqeqeq": 0, - "no-mixed-operators": 0, - "no-redeclare": 0, - "no-shadow": 0, - "no-unused-expressions": 0, - "no-unused-vars": 0, - "vars-on-top": 0 - } -} diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index e7b91e45..8bf180e7 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -1,11 +1,11 @@ name: Tests, Behat, Coding Standards on: push jobs: - test: + test-unit: runs-on: ubuntu-latest strategy: matrix: - php-versions: ['7.3', '7.2', '5.4'] + php-versions: ['8.3', '7.4'] steps: - uses: actions/checkout@master - name: Setup PHP @@ -14,70 +14,69 @@ jobs: php-version: ${{ matrix.php-versions }} extensions: mbstring, intl ini-values: post_max_size=256M, short_open_tag=On - tools: phpunit, composer - - name: Set COMPOSER environment variable for 5.4 - if: matrix.php-versions == '5.4' - run: echo "COMPOSER=composer-php-5-4.json" >> $GITHUB_ENV - - name: Run tests + tools: composer + - name: Install run: | composer install - ./vendor/bin/phpunit -c ./phpunit.xml.dist - behat: - runs-on: ubuntu-latest - services: - mysql: - image: mysql:5.7 - env: - MYSQL_ALLOW_EMPTY_PASSWORD: yes - MYSQL_DATABASE: pluginkollektiv_antispambee_behat - ports: - - '8888:3306' - options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 - strategy: - matrix: - php: ['8'] - wordpress: ['nightly', 'latest'] - include: - - php: '7.4' - wordpress: '5.5' - - php: '7.4' - wordpress: '5.4' - - php: '7.3' - wordpress: '5.3' - - php: '7.3' - wordpress: '5.2' - - php: '7.3' - wordpress: '5.1' - - php: '7.2' - wordpress: '4.9' - - php: '7.2' - wordpress: '4.8' - - php: '7.2' - wordpress: '4.7' - - php: '7.2' - wordpress: '4.6' - steps: - - uses: actions/checkout@master - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php }} - extensions: mbstring, intl, pdo_mysql, zip - ini-values: post_max_size=256M, short_open_tag=On - tools: phpunit, composer - - name: Start mysql service - run: sudo /etc/init.d/mysql start - - name: Install XVFB - run: sudo apt-get update && sudo apt-get install xvfb - name: Run tests run: | - composer install --ignore-platform-req=php - ./bin/behat.sh - env: - WORDPRESS_VERSION: ${{ matrix.wordpress }} - NAP_LENGTH: 10 - - name: Cleanup xvfb - uses: bcomnes/cleanup-xvfb@v1 + composer test:unit +# behat: +# runs-on: ubuntu-latest +# services: +# mysql: +# image: mysql:5.7 +# env: +# MYSQL_ALLOW_EMPTY_PASSWORD: yes +# MYSQL_DATABASE: pluginkollektiv_antispambee_behat +# ports: +# - '8888:3306' +# options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 +# strategy: +# matrix: +# php: ['8'] +# wordpress: ['nightly', 'latest'] +# include: +# - php: '7.4' +# wordpress: '5.5' +# - php: '7.4' +# wordpress: '5.4' +# - php: '7.3' +# wordpress: '5.3' +# - php: '7.3' +# wordpress: '5.2' +# - php: '7.3' +# wordpress: '5.1' +# - php: '7.2' +# wordpress: '4.9' +# - php: '7.2' +# wordpress: '4.8' +# - php: '7.2' +# wordpress: '4.7' +# - php: '7.2' +# wordpress: '4.6' +# steps: +# - uses: actions/checkout@master +# - name: Setup PHP +# uses: shivammathur/setup-php@v2 +# with: +# php-version: ${{ matrix.php }} +# extensions: mbstring, intl, pdo_mysql, zip +# ini-values: post_max_size=256M, short_open_tag=On +# tools: phpunit, composer +# - name: Start mysql service +# run: sudo /etc/init.d/mysql start +# - name: Install XVFB +# run: sudo apt-get update && sudo apt-get install xvfb +# - name: Run tests +# run: | +# composer install --ignore-platform-req=php +# ./bin/behat.sh +# env: +# WORDPRESS_VERSION: ${{ matrix.wordpress }} +# NAP_LENGTH: 10 +# - name: Cleanup xvfb +# uses: bcomnes/cleanup-xvfb@v1 quality: runs-on: ubuntu-latest steps: @@ -85,16 +84,10 @@ jobs: - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: '7.2' - extensions: mbstring, intl - ini-values: post_max_size=256M, short_open_tag=On - tools: phpunit, composer - - uses: actions/setup-node@v2 - with: - node-version: '14' + php-version: '8.2' + tools: composer - name: Run code style checks for CSS, JavaScript and PHP run: | - composer install - npm install - composer lint-all + composer install --ignore-platform-req=php + ./vendor/bin/phpcs --config-set ignore_warnings_on_exit 1 composer cs diff --git a/.gitignore b/.gitignore index 0436199f..d0402aa1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,14 @@ -css/*.min.css -js/*.min.js +assets/dist .idea/ +build/ node_modules/ tmp/ vendor/ chromedriver +composer.lock driver.tar.gz driver.zip geckodrier nohup.out package-lock.json +yarn.lock diff --git a/.stylelintrc.json b/.stylelintrc.json deleted file mode 100644 index 68e038b0..00000000 --- a/.stylelintrc.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "extends": "@wordpress/stylelint-config", - "rules": { - "declaration-property-unit-allowed-list": null, - "font-weight-notation": null, - "font-family-no-missing-generic-family-keyword": null, - "no-descending-specificity": null, - "selector-class-pattern": null, - "selector-id-pattern": null - } -} diff --git a/CHANGELOG.md b/CHANGELOG.md index 89ee8352..a14100e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,55 @@ ## Changelog ## +### 3.0.0 – WIP ### +* **English** + * Complete code rewrite and backend UI overhaul + * Allows to extend Antispam Bee with own rules + * Allows to use Antispam Bee rules for other reactions than comments, for example, forms + +* **Deutsch** + * Kompletter Code-Rewrite und Überarbeitung des Backend-User-Interfaces + * Möglichkeit der Erweiterung von Antispam Bee um eigene Spam-Regeln + * Erlaubt die Nutzung von Antispam Bee für andere Reaktionen als Kommentare, beispielsweise Formulare + +### 2.11.3 ### +* **English** + * Fix: Multiselect for "Delete comments by spam reasons" was not saving values + * Fix: Fix broken link for ISO country codes + * Maintenance: Added test for PHP 8.2 + * Maintenance: Tested up to WordPress 6.2 + +* **Deutsch** + * Behoben: Multiselect für "Kommentare aus Spamgründen löschen" speicherte keine Werte + * Fix: Fehlerhafter Link für ISO-Ländercodes behoben + * Wartung: Test für PHP 8.2 hinzugefügt + * Wartung: Getestet mit WordPress 6.2 + +### 2.11.2 ### +* **English** + * Tweak: remove superfluous translations + * Tweak: make FAQ link an anchor link + * Fix: spam counter no longer raises a warning with PHP 8.1 if no spam is present yet + * Fix: spam reasons are now localized correctly + * Fix: Translations were loaded twice on some admin pages + * Maintenance: Tested up to WordPress 6.1 + +* **Deutsch** + * Tweak: Überflüssige Übersetzungen entfernt + * Tweak: Link zu den FAQ ist jetzt ein Anker-Link + * Fix: Der Spam-Zähler erzeugt mit PHP 8.1 keine Warnung mehr, wenn noch kein Spam vorhanden ist + * Fix: Spam-Gründe werden nun korrekt übersetzt + * Fix: Übersetzungen wurden auf einzelnen Adminseiten doppelt geladen + * Wartung: Getestet mit WordPress 6.1 + +### 2.11.1 ### +* **English** + * Tweak: remove superfluous type attribute from inline script tag + * Maintenance: Tested up to WordPress 6.0 + +* **Deutsch** + * Tweak: Überflüssiges type-Attribut von script-Tag entfernt + * Wartung: Getestet mit WordPress 6.0 + ### 2.11.0 ### * **English** * Fix: Allow empty comments if `allow_empty_comment` is set to true diff --git a/README.md b/README.md index 4f5f5ad1..ea628f01 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,10 @@ [![Build status](https://github.com/pluginkollektiv/antispam-bee/actions/workflows/tests.yml/badge.svg)](https://github.com/pluginkollektiv/antispam-bee/actions/workflows/tests.yml) [![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) -Antispam plugin with a sophisticated toolset for effective day to day comment and trackback spam-fighting. Built with data protection and privacy in mind. +Antispam plugin with a sophisticated toolset for effective day to day comment and linkback spam-fighting. Built with data protection and privacy in mind, and extendable with own anti-spam rules and possibility to use Antispam Bee rules for other reactions than comments and linkbacks. ## Description ## -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. +Say Goodbye to comment spam on your WordPress blog or website. *Antispam Bee* blocks spam comments and linkbacks effectively and without captchas. It is free of charge, ad-free and compliant with European data privacy standards. ### Feature/Settings Overview ### * Trust approved commenters. @@ -45,7 +45,7 @@ Say Goodbye to comment spam on your WordPress blog or website. *Antispam Bee* bl * If you don’t know how to install a plugin for WordPress, [here’s how](http://codex.wordpress.org/Managing_Plugins#Installing_Plugins). ### Requirements ### -* PHP 5.2.4 or greater +* PHP 7.0 or greater * WordPress 4.5 or greater ### Settings ### diff --git a/antispam_bee.php b/antispam_bee.php old mode 100755 new mode 100644 index afdf2a17..f56c9e11 --- a/antispam_bee.php +++ b/antispam_bee.php @@ -1,3044 +1,104 @@ 0, - ), - '', - 'no' - ); - - if ( self::get_option( 'cronjob_enable' ) ) { - self::init_scheduled_hook(); - } - } - - - /** - * Action to deactivate the plugin - * - * @since 0.1 - * @since 2.4 - */ - public static function deactivate() { - self::clear_scheduled_hook(); - } - - - /** - * Action deleting the plugin - * - * @since 2.4 - */ - public static function uninstall() { - if ( ! self::get_option( 'delete_data_on_uninstall' ) ) { - return; - } - global $wpdb; - - delete_option( 'antispam_bee' ); - $wpdb->query( 'OPTIMIZE TABLE `' . $wpdb->options . '`' ); - - //phpcs:disable WordPress.DB.PreparedSQL.NotPrepared - $sql = 'delete from `' . $wpdb->commentmeta . '` where `meta_key` IN ("antispam_bee_iphash", "antispam_bee_reason")'; - $wpdb->query( $sql ); - //phpcs:enable WordPress.DB.PreparedSQL.NotPrepared - } - - - - /* - * ############################ - * ######## INTERNAL ######## - * ############################ - */ - - /** - * Initialization of the internal variables - * - * @since 2.4 - * @since 2.7.0 - * @since 2.10.0 Change renamed country option names in options array - */ - private static function _init_internal_vars() { - self::$_base = plugin_basename( __FILE__ ); - - $salt = defined( 'NONCE_SALT' ) ? NONCE_SALT : ABSPATH; - self::$_salt = substr( sha1( $salt ), 0, 10 ); - - self::$defaults = array( - 'options' => array( - 'regexp_check' => 1, - 'spam_ip' => 1, - 'already_commented' => 1, - 'gravatar_check' => 0, - 'time_check' => 0, - 'ignore_pings' => 0, - - 'dashboard_chart' => 0, - 'dashboard_count' => 0, - - 'country_code' => 0, - 'country_denied' => '', - 'country_allowed' => '', - - 'translate_api' => 0, - 'translate_lang' => array(), - - 'bbcode_check' => 1, - - 'flag_spam' => 1, - 'email_notify' => 0, - 'no_notice' => 0, - 'cronjob_enable' => 0, - 'cronjob_interval' => 0, - - 'ignore_filter' => 0, - 'ignore_type' => 0, - - 'reasons_enable' => 0, - 'ignore_reasons' => array(), - - 'delete_data_on_uninstall' => 1, - ), - 'reasons' => array( - 'css' => esc_attr__( 'Honeypot', 'antispam-bee' ), - 'time' => esc_attr__( 'Comment time', 'antispam-bee' ), - 'empty' => esc_attr__( 'Empty Data', 'antispam-bee' ), - 'localdb' => esc_attr__( 'Local DB Spam', 'antispam-bee' ), - 'server' => esc_attr__( 'Fake IP', 'antispam-bee' ), - 'country' => esc_attr__( 'Country Check', 'antispam-bee' ), - 'bbcode' => esc_attr__( 'BBCode', 'antispam-bee' ), - 'lang' => esc_attr__( 'Comment Language', 'antispam-bee' ), - 'regexp' => esc_attr__( 'Regular Expression', 'antispam-bee' ), - 'title_is_name' => esc_attr__( 'Identical Post title and blog title', 'antispam-bee' ), - 'manually' => esc_attr__( 'Manually', 'antispam-bee' ), - ), - ); - } - - /** - * Check and return an array key - * - * @since 2.4.2 - * @since 2.10.0 Only return `null` if option does not exist. - * - * @param array $array Array with values. - * @param string $key Name of the key. - * @return mixed Value of the requested key. - */ - public static function get_key( $array, $key ) { - if ( empty( $array ) || empty( $key ) || ! isset( $array[ $key ] ) ) { - return null; - } - - return $array[ $key ]; - } - - /** - * Check if comment is a ping (pingback, trackback or something similar) - * - * @since 2.10.0 - * - * @param array $comment Treated commentary data. - * @return boolean `true` if ping and `false` if classic comment - */ - public static function is_ping( $comment ) { - $types = array( 'pingback', 'trackback', 'pings' ); - $is_ping = false; - - if ( in_array( self::get_key( $comment, 'comment_type' ), $types, true ) ) { - $is_ping = true; - } - - return apply_filters( 'antispam_bee_is_ping', $is_ping, $comment ); - } - - /** - * Localization of the admin pages - * - * @since 0.1 - * @since 2.4 - * - * @param string $page Mark the page. - * @return boolean True on success. - */ - private static function _current_page( $page ) { - // phpcs:disable WordPress.CSRF.NonceVerification.NoNonceVerification - switch ( $page ) { - case 'dashboard': - return ( empty( $GLOBALS['pagenow'] ) || ( ! empty( $GLOBALS['pagenow'] ) && 'index.php' === $GLOBALS['pagenow'] ) ); - - case 'options': - return ( ! empty( $_GET['page'] ) && 'antispam_bee' === $_GET['page'] ); - - case 'plugins': - return ( ! empty( $GLOBALS['pagenow'] ) && 'plugins.php' === $GLOBALS['pagenow'] ); - - case 'admin-post': - return ( ! empty( $GLOBALS['pagenow'] ) && 'admin-post.php' === $GLOBALS['pagenow'] ); - - case 'edit-comments': - return ( ! empty( $GLOBALS['pagenow'] ) && 'edit-comments.php' === $GLOBALS['pagenow'] ); - - default: - return false; - } - // phpcs:enable WordPress.CSRF.NonceVerification.NoNonceVerification - } - - - /** - * Integration of the localization file - * - * @since 0.1 - * @since 2.4 - */ - public static function load_plugin_lang() { - load_plugin_textdomain( - 'antispam-bee' - ); - } - - - /** - * Add the link to the settings - * - * @since 1.1 - * - * @param array $data The action link array. - * @return array $data The action link array. - */ - public static function init_action_links( $data ) { - if ( ! current_user_can( 'manage_options' ) ) { - return $data; - } - - return array_merge( - $data, - array( - sprintf( - '%s', - add_query_arg( - array( - 'page' => 'antispam_bee', - ), - admin_url( 'options-general.php' ) - ), - esc_attr__( 'Settings', 'antispam-bee' ) - ), - ) - ); - } - - /** - * Meta links of the plugin - * - * @since 0.1 - * @since 2.6.2 - * - * @param array $input Existing links. - * @param string $file Current page. - * @return array $data Modified links. - */ - public static function init_row_meta( $input, $file ) { - if ( $file !== self::$_base ) { - return $input; - } - - return array_merge( - $input, - array( - '' . esc_html__( 'Donate', 'antispam-bee' ) . '', - '' . esc_html__( 'Support', 'antispam-bee' ) . '', - ) - ); - } - - /* - * ############################ - * ####### RESOURCES ######## - * ############################ - */ - - /** - * Registration of resources (CSS & JS) - * - * @since 1.6 - * @since 2.4.5 - */ - public static function init_plugin_sources() { - $plugin = get_plugin_data( __FILE__ ); - - wp_register_script( - 'ab_script', - plugins_url( 'js/scripts.min.js', __FILE__ ), - array( 'jquery' ), - $plugin['Version'] - ); - - wp_register_style( - 'ab_style', - plugins_url( 'css/styles.min.css', __FILE__ ), - array( 'dashicons' ), - $plugin['Version'] - ); - } - - - /** - * Initialization of the option page - * - * @since 0.1 - * @since 2.4.3 - */ - public static function add_sidebar_menu() { - $page = add_options_page( - 'Antispam Bee', - 'Antispam Bee', - 'manage_options', - 'antispam_bee', - array( - 'Antispam_Bee_GUI', - 'options_page', - ) - ); - - add_action( - 'admin_print_scripts-' . $page, - array( - __CLASS__, - 'add_options_script', - ) - ); - - add_action( - 'admin_print_styles-' . $page, - array( - __CLASS__, - 'add_options_style', - ) - ); - - add_action( - 'load-' . $page, - array( - __CLASS__, - 'init_options_page', - ) - ); - } - - - /** - * Initialization of JavaScript - * - * @since 1.6 - * @since 2.4 - */ - public static function add_options_script() { - wp_enqueue_script( 'ab_script' ); - } - - - /** - * Initialization of Stylesheets - * - * @since 1.6 - * @since 2.4 - */ - public static function add_options_style() { - wp_enqueue_style( 'ab_style' ); - } - - - /** - * Integration of the GUI - * - * @since 2.4 - */ - public static function init_options_page() { - require_once dirname( __FILE__ ) . '/inc/gui.class.php'; - } - - - - /* - * ############################ - * ####### DASHBOARD ######## - * ############################ - */ - - /** - * Display the spam counter on the dashboard - * - * @since 0.1 - * @since 2.6.5 - * - * @param array $items Initial array with dashboard items. - * @return array $items Merged array with dashboard items. - */ - public static function add_dashboard_count( $items = array() ) { - if ( ! current_user_can( 'manage_options' ) || ! self::get_option( 'dashboard_count' ) ) { - return $items; - } - - echo ''; - - $items[] = '' . esc_html( - sprintf( - // translators: The number of spam comments Antispam Bee blocked so far. - __( '%s Blocked', 'antispam-bee' ), - self::_get_spam_count() - ) - ) . ''; - - return $items; - } - - /** - * Initialize the dashboard chart - * - * @since 1.9 - * @since 2.5.6 - */ - public static function add_dashboard_chart() { - if ( ! current_user_can( 'publish_posts' ) || ! self::get_option( 'dashboard_chart' ) ) { - return; - } +function pre_init(): void { + // Load the translation, as they might be needed in pre_init. + add_action( 'plugins_loaded', __NAMESPACE__ . '\load_textdomain', 5 ); - wp_add_dashboard_widget( - 'ab_widget', - 'Antispam Bee', - array( - __CLASS__, - 'show_spam_chart', - ) - ); + // Check, if the min. required PHP version is available and if not, show an admin notice. + if ( version_compare( PHP_VERSION, '5.6', '<' ) ) { + add_action( 'admin_notices', __NAMESPACE__ . '\min_php_version_error' ); - add_action( - 'admin_head', - array( - __CLASS__, - 'add_dashboard_style', - ) - ); + // Stop the further processing of the plugin. + return; } - /** - * Print dashboard styles - * - * @since 1.9.0 - * @since 2.5.8 - */ - public static function add_dashboard_style() { - $plugin = get_plugin_data( __FILE__ ); + // Check, if the DOMDocument class exists. + if ( ! class_exists( 'DOMDocument' ) ) { + add_action( 'admin_notices', __NAMESPACE__ . '\domdocument_class_error' ); - wp_register_style( - 'ab_chart', - plugins_url( 'css/dashboard.min.css', __FILE__ ), - array(), - $plugin['Version'] - ); - - wp_print_styles( 'ab_chart' ); - } - - - /** - * Print dashboard scripts - * - * @since 1.9.0 - * @since 2.5.8 - */ - public static function add_dashboard_script() { - if ( ! self::get_option( 'daily_stats' ) ) { - return; - } - - $plugin = get_plugin_data( __FILE__ ); - - wp_enqueue_script( - 'raphael', - plugins_url( 'js/raphael.min.js', __FILE__ ), - array(), - '2.1.0', - true - ); - - wp_enqueue_script( - 'ab-raphael', - plugins_url( 'js/raphael.helper.min.js', __FILE__ ), - array( 'raphael' ), - $plugin['Version'], - true - ); - - wp_enqueue_script( - 'ab_chart_js', - plugins_url( 'js/dashboard.min.js', __FILE__ ), - array( 'jquery', 'ab-raphael' ), - $plugin['Version'], - true - ); - } - - /** - * Print dashboard html - * - * @since 1.9.0 - * @since 2.5.8 - */ - public static function show_spam_chart() { - $items = (array) self::get_option( 'daily_stats' ); - - if ( empty( $items ) ) { - echo sprintf( - '
%s
' . date_i18n( 'j. F Y', $date ) . " | \n"; - } - $html .= "
---|
' . (int) $count . " | \n"; - } - $html .= "