├── index.php ├── .gitattributes ├── .gitignore ├── fortify-info.php ├── fortify-settings.php ├── fortify.php ├── readme.txt └── fortify-functions.php /index.php: -------------------------------------------------------------------------------- 1 | 19 |
20 |

21 | spam comments have been blocked by Fortify plugin so far. 22 |

23 |
24 | 44 | 49 |
50 | 51 | 56 | 57 |
58 | '; 55 | echo ' Save spam comments into spam section'; 56 | echo '

Useful for testing how the plugin works. View spam section.

'; 57 | } 58 | 59 | 60 | function fortify_settings() { 61 | $fortify_stats = get_option('fortify_stats', array()); 62 | 63 | if (array_key_exists('blocked_total', $fortify_stats)) { 64 | $blocked_total = $fortify_stats['blocked_total']; 65 | } else { 66 | $blocked_total = 0; 67 | } 68 | 69 | ?> 70 |
71 | 72 |

Fortify

73 | 74 |
75 |

76 | 77 | spam comments were blocked 78 | by Fortify plugin so far. 79 |

80 |
81 | 82 |
83 | 84 |
85 | 86 |
87 | 88 |
89 | 90 |
91 | 28 | 33 | 37 | '; 41 | } 42 | } 43 | add_action('comment_form', 'fortify_form_part'); // add fortify inputs to the comment form 44 | 45 | 46 | function fortify_check_comment($commentdata) { 47 | $fortify_settings = fortify_get_settings(); 48 | 49 | extract($commentdata); 50 | 51 | if ( ! is_user_logged_in() && $comment_type != 'pingback' && $comment_type != 'trackback') { // logged in user is not a spammer 52 | if( fortify_check_for_spam() ) { 53 | if( $fortify_settings['save_spam_comments'] ) { 54 | fortify_store_comment($commentdata); 55 | } 56 | fortify_counter_stats(); 57 | wp_die('Comment is spam.'); // die - do not send comment and show error message 58 | } 59 | } 60 | 61 | if ($comment_type == 'trackback') { 62 | if( $fortify_settings['save_spam_comments'] ) { 63 | fortify_store_comment($commentdata); 64 | } 65 | fortify_counter_stats(); 66 | wp_die('Trackbacks are disabled.'); // die - do not send trackback and show error message 67 | } 68 | 69 | return $commentdata; // if comment does not looks like spam 70 | } 71 | 72 | if ( ! is_admin()) { // without this check it is not possible to add comment in admin section 73 | add_filter('preprocess_comment', 'fortify_check_comment', 1); 74 | } 75 | 76 | 77 | function fortify_plugin_meta($links, $file) { // add some links to plugin meta row 78 | if ( $file == plugin_basename( __FILE__ ) ) { 79 | $row_meta = array( 80 | 'support' => '' . __( 'Fortify', 'fortify' ) . '', 81 | 'donate' => '' . __( 'Donate', 'fortify' ) . '' 82 | ); 83 | $links = array_merge( $links, $row_meta ); 84 | } 85 | return (array) $links; 86 | } 87 | add_filter('plugin_row_meta', 'fortify_plugin_meta', 10, 2); 88 | -------------------------------------------------------------------------------- /readme.txt: -------------------------------------------------------------------------------- 1 | === Fortify === 2 | Contributors: webvitaly 3 | Donate link: http://web-profile.net/donate/ 4 | Tags: spam, spammer, comment, comments, comment-spam, antispam, anti-spam, block-spam, spam-free, spambot, spam-bot, bot 5 | Requires at least: 5.0 6 | Tested up to: 5.8.2 7 | Stable tag: 1.0 8 | License: GPLv3 9 | License URI: http://www.gnu.org/licenses/gpl.html 10 | 11 | No spam in comments. No captcha. 12 | 13 | == Description == 14 | 15 | * **[Fortify](http://web-profile.net/wordpress/plugins/fortify/ "Plugin page")** 16 | * **[Donate](http://web-profile.net/donate/ "Support the development")** 17 | * **[GitHub](https://github.com/webvitalii/fortify "Fork")** 18 | 19 | 20 | Fortify plugin blocks automatic spam in comments section. No captcha. 21 | 22 | Plugin is easy to use: just install it and it just works. 23 | 24 | Blocked comments can be stored in the Spam area if needed. This can be enabled/disabled via Settings page. This is useful for testing and debug purpose. Blocked spam comments can be easily converted to regular comments if needed. 25 | 26 | Fortify plugin is GDPR compliant and does not store any other user data except of the behavior mentioned above. 27 | 28 | **Plugin blocks spam only in comments section**. 29 | 30 | 31 | 32 | After installing the Fortify plugin **try to submit a comment on your site being logged out**. 33 | If you get an error - you may check the solution in the [Support section](http://wordpress.org/support/plugin/fortify ) or submit a new topic with detailed description of your problem. 34 | 35 | 36 | == Installation == 37 | 38 | 1. Install and activate the plugin on the Plugins page 39 | 2. Enjoy life without spam in comments 40 | 41 | == Frequently Asked Questions == 42 | 43 | = How to test what spam comments were blocked? = 44 | 45 | You can visit Fortify settings page and enable saving blocked comments as spam in the spam section. 46 | To enabled that you need to go to: WordPress admin dashboard => Settings section => Fortify 47 | Saving blocked comments into spam section is disabled by default. 48 | Saving spam comments can help you to keep all the comments saved and review them in future if needed. You can easily mark comment as "not spam" if some of the comments have been blocked by mistake. 49 | 50 | = What is the percentage of spam blocked? = 51 | 52 | Fortify plugin blocks 100% of automatic spam messages (sent by spam-bots via post requests). 53 | Plugin does not block manual spam (submitted by spammers manually via browser). 54 | 55 | = Incompatible with: = 56 | 57 | * Disqus 58 | * Jetpack Comments 59 | * AJAX Comment Form 60 | * bbPress 61 | 62 | = How does Fortify plugin work? = 63 | 64 | The blocking algorithm is based on "honeypot technique" and the fact that spam bots does not have JavaScript enabled. 65 | Fortify plugin adds invisible to regular users input fields. 66 | And spam bots fill in those fields which helps to identify that as spam. 67 | 68 | = How to know the counter of blocked spam comments? = 69 | 70 | You can find the info block with total spam blocked counter in the admin comments section. 71 | You can hide or show this info block in the "Screen Options" section. 72 | The visibility option for this info block is saved per user. 73 | 74 | = Does plugin block spam from Contact or other forms? = 75 | 76 | Plugin blocks spam only in comments form section and does not block spam from any other forms on site. 77 | If you installed and activated the plugin and you still receiving spam - probably this could be because of some other forms on your site (for example feedback form). 78 | 79 | = What about trackback spam? = 80 | 81 | Users rarely use trackbacks because it is manual and requires extra input. Spammers uses trackbacks because it is easy to cheat here. 82 | Users use pingbacks very often because they work automatically. Spammers does not use pingbacks because backlinks are checked. 83 | So trackbacks are blocked but pingbacks are enabled. 84 | You may read more about the [difference between trackbacks and pingbacks](http://web-profile.net/web/trackback-vs-pingback/) 85 | 86 | = What browsers are supported? = 87 | 88 | All modern browsers and IE8+ are supported. 89 | 90 | = Not enough information about the plugin? = 91 | 92 | You may check out the [source code of the plugin](http://plugins.trac.wordpress.org/browser/fortify/trunk/fortify.php). 93 | 94 | 95 | == Changelog == 96 | 97 | = 1.0 = 98 | * initial release 99 | -------------------------------------------------------------------------------- /fortify-functions.php: -------------------------------------------------------------------------------- 1 | 0 10 | ); 11 | return $settings; 12 | } 13 | 14 | 15 | function fortify_get_settings() { 16 | $fortify_settings = (array) get_option('fortify_settings'); 17 | $default_settings = fortify_default_settings(); 18 | $fortify_settings = array_merge($default_settings, $fortify_settings); // set empty options with default values 19 | return $fortify_settings; 20 | } 21 | 22 | 23 | function fortify_counter_stats() { 24 | $fortify_stats = get_option('fortify_stats', array()); 25 | if (array_key_exists('blocked_total', $fortify_stats)){ 26 | $fortify_stats['blocked_total']++; 27 | } else { 28 | $fortify_stats['blocked_total'] = 1; 29 | } 30 | update_option('fortify_stats', $fortify_stats); 31 | } 32 | 33 | 34 | function fortify_check_for_spam() { 35 | $spam_flag = false; 36 | 37 | $fortify_q = ''; 38 | if (isset($_POST['fortify-q'])) { 39 | $fortify_q = sanitize_text_field($_POST['fortify-q']); 40 | } 41 | 42 | $fortify_e = ''; 43 | if (isset($_POST['fortify-e-email-url-website'])) { 44 | $fortify_e = sanitize_text_field($_POST['fortify-e-email-url-website']); 45 | } 46 | 47 | if ( $fortify_q != date('Y') ) { // year-answer is wrong - it is spam 48 | $spam_flag = true; 49 | } 50 | 51 | if ( ! empty($fortify_e)) { // trap field is not empty - it is spam 52 | $spam_flag = true; 53 | } 54 | 55 | return $spam_flag; 56 | } 57 | 58 | 59 | function fortify_store_comment($commentdata) { 60 | global $wpdb; 61 | $wp_error = true; 62 | 63 | if ( isset( $commentdata['user_ID'] ) ) { 64 | $commentdata['user_id'] = $commentdata['user_ID'] = (int) $commentdata['user_ID']; 65 | } 66 | 67 | $prefiltered_user_id = ( isset( $commentdata['user_id'] ) ) ? (int) $commentdata['user_id'] : 0; 68 | 69 | $commentdata['comment_post_ID'] = (int) $commentdata['comment_post_ID']; 70 | if ( isset( $commentdata['user_ID'] ) && $prefiltered_user_id !== (int) $commentdata['user_ID'] ) { 71 | $commentdata['user_id'] = $commentdata['user_ID'] = (int) $commentdata['user_ID']; 72 | } elseif ( isset( $commentdata['user_id'] ) ) { 73 | $commentdata['user_id'] = (int) $commentdata['user_id']; 74 | } 75 | 76 | $commentdata['comment_parent'] = isset($commentdata['comment_parent']) ? absint($commentdata['comment_parent']) : 0; 77 | $parent_status = ( 0 < $commentdata['comment_parent'] ) ? wp_get_comment_status($commentdata['comment_parent']) : ''; 78 | $commentdata['comment_parent'] = ( 'approved' == $parent_status || 'unapproved' == $parent_status ) ? $commentdata['comment_parent'] : 0; 79 | 80 | if ( ! isset( $commentdata['comment_author_IP'] ) ) { 81 | $commentdata['comment_author_IP'] = $_SERVER['REMOTE_ADDR']; 82 | } 83 | $commentdata['comment_author_IP'] = preg_replace( '/[^0-9a-fA-F:., ]/', '', $commentdata['comment_author_IP'] ); 84 | 85 | if ( ! isset( $commentdata['comment_agent'] ) ) { 86 | $commentdata['comment_agent'] = isset( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT']: ''; 87 | } 88 | $commentdata['comment_agent'] = substr( $commentdata['comment_agent'], 0, 254 ); 89 | 90 | if ( empty( $commentdata['comment_date'] ) ) { 91 | $commentdata['comment_date'] = current_time('mysql'); 92 | } 93 | 94 | if ( empty( $commentdata['comment_date_gmt'] ) ) { 95 | $commentdata['comment_date_gmt'] = current_time( 'mysql', 1 ); 96 | } 97 | 98 | $commentdata = wp_filter_comment($commentdata); 99 | 100 | $commentdata['comment_approved'] = wp_allow_comment( $commentdata, $wp_error ); 101 | if ( is_wp_error( $commentdata['comment_approved'] ) ) { 102 | return $commentdata['comment_approved']; 103 | } 104 | 105 | $comment_ID = wp_insert_comment($commentdata); 106 | if ( ! $comment_ID ) { 107 | $fields = array( 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_content' ); 108 | 109 | foreach ( $fields as $field ) { 110 | if ( isset( $commentdata[ $field ] ) ) { 111 | $commentdata[ $field ] = $wpdb->strip_invalid_text_for_column( $wpdb->comments, $field, $commentdata[ $field ] ); 112 | } 113 | } 114 | 115 | $commentdata = wp_filter_comment( $commentdata ); 116 | 117 | $commentdata['comment_approved'] = wp_allow_comment( $commentdata, $wp_error ); 118 | if ( is_wp_error( $commentdata['comment_approved'] ) ) { 119 | return $commentdata['comment_approved']; 120 | } 121 | 122 | $comment_ID = wp_insert_comment( $commentdata ); 123 | if ( ! $comment_ID ) { 124 | return false; 125 | } 126 | } 127 | 128 | wp_set_comment_status( $comment_ID, 'spam' ); 129 | } 130 | --------------------------------------------------------------------------------