// Make sure this file is only run from within the WordPress context. defined( 'ABSPATH' ) || exit; /** * Antispam_Bee * * @since 0.1 * @since 2.4 */ class Antispam_Bee { /** * The option defaults. * * @var array */ public static $defaults; /** * Which internal datastructure version we are running on. * * @var int * @var string */ private static $_salt; /** * The spam reason. * * @var string */ private static $_reason; /** * The current Post ID. * * @var int */ private static $_current_post_id; /** * "Constructor" of the class * * @since 0.1 * @since 2.6.4 * @since 2.10.0 Change handling of comment field honeypot and call functions after completed upgrades * @since 2.11.0 Change priority from default 10 to 99 for comment_form_field_comment */ public static function init() { add_action( 'upgrader_process_complete', array( __CLASS__, 'upgrades_completed', ), 10, 2 ); add_action( 'upgrader_overwrote_package', array( __CLASS__, 'uploaded_upgrade_completed', ), 10, 3 ); add_action( 'unspam_comment', array( __CLASS__, 'delete_spam_reason_by_comment', ) ); add_action( 'comment_unapproved_to_spam', array( __CLASS__, 'update_antispam_bee_reason', ) ); add_action( 'comment_approved_to_spam', array( __CLASS__, 'update_antispam_bee_reason', ) ); $disallow_ajax = apply_filters( 'antispam_bee_disallow_ajax_calls', true ); if ( defined( 'DOING_AJAX' ) && DOING_AJAX && $disallow_ajax ) { return; } if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) { return; } self::_init_internal_vars(); if ( self::_current_page( 'dashboard' ) || self::_current_page( 'plugins' ) || self::_current_page( 'options' ) || self::_current_page( 'edit-comments' ) || self::_current_page( 'admin-post' ) ) { self::load_plugin_lang(); self::add_reasons_to_defaults(); } if ( defined( 'DOING_CRON' ) ) { add_action( 'antispam_bee_daily_cronjob', array( __CLASS__, 'start_daily_cronjob', ) ); } elseif ( is_admin() ) { add_action( 'admin_menu', array( __CLASS__, 'add_sidebar_menu', ) ); if ( self::_current_page( 'dashboard' ) ) { add_filter( 'dashboard_glance_items', array( __CLASS__, 'add_dashboard_count', add_action( 'admin_init', array( __CLASS__, 'init_plugin_sources', ) ); add_action( 'admin_init', array( __CLASS__, 'update_database', ) // phpcs:enable WordPress.CSRF.NonceVerification.NoNonceVerification require_once dirname( __FILE__ ) . '/inc/columns.class.php'; add_filter( 'manage_edit-comments_columns', array( 'Antispam_Bee_Columns', 'register_plugin_columns', ) ); add_filter( 'manage_comments_custom_column', array( 'Antispam_Bee_Columns', 'print_plugin_column', ), 10, 2 ); add_filter( 'admin_print_styles-edit-comments.php', array( 'Antispam_Bee_Columns', 'print_column_styles', ) ); add_filter( 'manage_edit-comments_sortable_columns', array( 'Antispam_Bee_Columns', 'register_sortable_columns', ) ); add_action( 'pre_get_comments', array( 'Antispam_Bee_Columns', 'set_orderby_query', ) ); add_action( 'restrict_manage_comments', array( 'Antispam_Bee_Columns', 'filter_columns', ) ); add_action( 'pre_get_comments', array( 'Antispam_Bee_Columns', 'filter_by_spam_reason', ) ); } } } else { add_action( 'wp', array( __CLASS__, 'populate_post_id', ) ); if ( 1 == self::get_option( 'use_output_buffer' ) || null === self::get_option( 'use_output_buffer' ) ) { add_action( 'template_redirect', array( __CLASS__, 'prepare_comment_field_output_buffering', ) ); } else { add_filter( 'comment_form_field_comment', array( __CLASS__, 'prepare_comment_field', ), 99 ); } add_action( 'init', array( __CLASS__, 'precheck_incoming_request', ) ); add_action( 'preprocess_comment', array( __CLASS__, 'handle_incoming_request', ), 1 ); add_action( 'antispam_bee_count', array( __CLASS__, 'the_spam_count', ) ); } } /* * ############################ * ######## INSTALL ######### * ############################ */ /** * Action during the activation of the Plugins * * @since 0.1 * @since 2.4 * @since 2.10.0 Set `use_output_buffer` option to `0` */ public static function activate() { add_option( 'antispam_bee', array( 'use_output_buffer' => 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, ), ); } /** * Adds spam reason labels to the `$defaults` array. * * That is done in an extra method instead of `_init_internal_vars` * so that the translations are loaded before. * * @since 2.11.2 */ private static function add_reasons_to_defaults() { self::$defaults['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; } wp_add_dashboard_widget( 'ab_widget', 'Antispam Bee', array( __CLASS__, 'show_spam_chart', ) ); add_action( 'admin_head', array( __CLASS__, 'add_dashboard_style', ) ); } /** * Print dashboard styles * * @since 1.9.0 * @since 2.5.8 */ public static function add_dashboard_style() { $plugin = get_plugin_data( __FILE__ ); 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 .= "