├── css
├── dashboard.css
└── styles.css
├── js
├── scripts.js
├── dashboard.js
└── raphael.helper.js
├── inc
├── columns.class.php
└── gui.class.php
├── readme.txt
├── LICENSE.txt
├── CHANGELOG.md
└── antispam_bee.php
/css/dashboard.css:
--------------------------------------------------------------------------------
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 | }
11 |
12 | #ab_widget .inside {
13 | height: 1%;
14 | margin: 0;
15 | padding-bottom: 0;
16 | overflow: hidden;
17 | position: relative;
18 | white-space: nowrap;
19 | }
20 |
--------------------------------------------------------------------------------
/js/scripts.js:
--------------------------------------------------------------------------------
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 | );
17 |
18 | ab_flag_spam();
19 | }
20 | );
21 |
--------------------------------------------------------------------------------
/js/dashboard.js:
--------------------------------------------------------------------------------
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 | }() );
113 |
--------------------------------------------------------------------------------
/js/raphael.helper.js:
--------------------------------------------------------------------------------
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 | }
141 |
--------------------------------------------------------------------------------
/css/styles.css:
--------------------------------------------------------------------------------
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 */
16 |
17 | /* @group Columns */
18 |
19 | .ab-wrap {
20 | margin: 0 0 0 -10px;
21 | padding: 20px 0 0 0;
22 | text-rendering: optimizeLegibility; /* stylelint-disable-line value-keyword-case */
23 | }
24 |
25 | .ab-column {
26 | float: left;
27 | margin: 0 0 0 10px;
28 | position: relative;
29 | }
30 |
31 | /* @end group */
32 |
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 */
77 |
78 | /* @group Form */
79 |
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[]"] {
98 | width: auto;
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 */
119 |
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 */
206 |
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 */
266 |
--------------------------------------------------------------------------------
/inc/columns.class.php:
--------------------------------------------------------------------------------
1 | esc_html__( 'Spam Reason', 'antispam-bee' ),
29 | )
30 | );
31 | }
32 |
33 | /**
34 | * Display plugin column values on comments screen
35 | *
36 | * @since 2.6.0
37 | * @change 2.6.0
38 | *
39 | * @param string $column Currently selected column.
40 | * @param integer $comment_id Comment ID.
41 | */
42 | public static function print_plugin_column( $column, $comment_id ) {
43 | if ( 'antispam_bee_reason' !== $column ) {
44 | return;
45 | }
46 |
47 | $spam_reason = get_comment_meta( $comment_id, $column, true );
48 | $spam_reasons = Antispam_Bee::$defaults['reasons'];
49 |
50 | if ( empty( $spam_reason ) || empty( $spam_reasons[ $spam_reason ] ) ) {
51 | return;
52 | }
53 |
54 | echo esc_html( $spam_reasons[ $spam_reason ] );
55 | }
56 |
57 | /**
58 | * Register plugin sortable columns on comments screen
59 | *
60 | * @since 2.6.3
61 | * @change 2.6.3
62 | *
63 | * @param array $columns Registered columns.
64 | * @return array $columns Columns with AB field.
65 | */
66 | public static function register_sortable_columns( $columns ) {
67 | $columns['antispam_bee_reason'] = 'antispam_bee_reason';
68 |
69 | return $columns;
70 | }
71 |
72 | // phpcs:disable WordPress.VIP.SlowDBQuery.slow_db_query_meta_key
73 | // phpcs:disable WordPress.CSRF.NonceVerification.NoNonceVerification
74 | /**
75 | * Adjust orderby query
76 | *
77 | * @since 2.6.3
78 | * @change 2.6.3
79 | *
80 | * @param \WP_Comment_Query $query Current WordPress query.
81 | */
82 | public static function set_orderby_query( $query ) {
83 | $orderby = isset( $_GET['orderby'] ) ? sanitize_text_field( wp_unslash( $_GET['orderby'] ) ) : '';
84 |
85 | if ( empty( $orderby ) || 'antispam_bee_reason' !== $orderby ) {
86 | return;
87 | }
88 |
89 | $query->query_vars['meta_key'] = 'antispam_bee_reason';
90 | $query->query_vars['orderby'] = 'meta_value';
91 | }
92 | // phpcs:enable WordPress.VIP.SlowDBQuery.slow_db_query_meta_key
93 | // phpcs:enable WordPress.CSRF.NonceVerification.NoNonceVerification
94 |
95 | //phpcs:disable WordPress.CSRF.NonceVerification.NoNonceVerification
96 | /**
97 | * Filter comments by the spam reason
98 | *
99 | * @global \wpdb $wpdb
100 | */
101 | public static function filter_columns() {
102 | global $wpdb;
103 | ?>
104 |
105 |
120 | query_vars['meta_key'] = 'antispam_bee_reason';
139 | $query->query_vars['meta_value'] = $spam_reason;
140 | }
141 | //phpcs:enable WordPress.VIP.SlowDBQuery.slow_db_query_meta_key
142 | //phpcs:enable WordPress.VIP.SlowDBQuery.slow_db_query_meta_value
143 | //phpcs:enable WordPress.CSRF.NonceVerification.NoNonceVerification
144 |
145 | /**
146 | * Print CSS for the plugin column
147 | *
148 | * @since 2.6.1
149 | * @change 2.6.1
150 | */
151 | public static function print_column_styles() {
152 | ?>
153 |
158 | if (req.restarts == 0) {
88 | > set req.http.X-Forwarded-For = client.ip;
89 | > }
90 |
91 | ### Are there some paid services or limitations? ###
92 | No, Antispam Bee is free forever, for both private and commercial projects. You can use it on as many sites as you want. There is no limitation to the number of sites you use the plugin on.
93 |
94 | A complete documentation is available on [pluginkollektiv.org](https://antispambee.pluginkollektiv.org/documentation/).
95 |
96 | ### How can I report security bugs? ###
97 | You can report security bugs through the Patchstack Vulnerability Disclosure Program. The Patchstack team helps validate, triage and handle any security vulnerabilities. [Report a security vulnerability.](https://patchstack.com/database/vdp/445425e4-f5dd-4404-80a7-690999f5bcb3)
98 |
99 | ## Changelog ##
100 |
101 | ### 2.11.8 ###
102 | * Tweak: Minor code changes and housekeeping
103 | * Tweak: Add link to Patchstack in readme
104 | * Maintenance: Tested up to WordPress 6.8
105 |
106 | ### 2.11.7 ###
107 | * Tweak: Use SCRIPT_NAME instead of REQUEST_URI to check path
108 | * Fix: Remove `add_reasons_to_defaults()` from general initialization for better WordPress 6.7 compatibility
109 | * Maintenance: Tested up to WordPress 6.7
110 |
111 | ### 2.11.6 ###
112 | * Fix: Delete missed out option on uninstall (Thanks @okvee!)
113 | * Tweak: Minor i18n improvements (Thanks Pedro!)
114 | * Tweak: Minor code changes and housekeeping
115 | * Tweak: Updated dependencies
116 |
117 | ### 2.11.5 ###
118 | IMPORTANT: If you use the country check and are behind a proxy or similar, you need to use the `antispam_bee_trusted_ip` filter to get the correct IP from a header like `HTTP_X_FORWARDED` (don’t return an empty value here, otherwise all comments are marked as spam).
119 |
120 | * Fix: Usage of core filter `pre_comment_user_ip` breaks ASB if the IP address is removed for GDPR compliance
121 |
122 | ### 2.11.4 ###
123 | IMPORTANT: If you use the country check and are behind a proxy or similar, you need to use the `pre_comment_user_ip` filter to get the correct IP from a header like `HTTP_X_FORWARDED`.
124 |
125 | * Fix: Read client IP for country check from `REMOTE_ADDR` only (filterable via `pre_comment_user_ip`)
126 | * Fix: No spam reason in spam notification email, and related PHP warning
127 | * Fix: Remove outdated info from readme
128 | * Enhancement: Show upgrade notice on plugin overview page
129 | * Maintenance: Tested up to WordPress 6.3
130 |
131 | ### 2.11.3 ###
132 | * Fix: Multiselect for "Delete comments by spam reasons" was not saving values
133 | * Fix: Fix broken link for ISO country codes
134 | * Maintenance: Added test for PHP 8.2
135 | * Maintenance: Tested up to WordPress 6.2
136 |
137 | ### 2.11.2 ###
138 | * Tweak: remove superfluous translations
139 | * Tweak: make FAQ link an anchor link
140 | * Fix: spam counter no longer raises a warning with PHP 8.1 if no spam is present yet
141 | * Fix: spam reasons are now localized correctly
142 | * Fix: Translations were loaded twice on some admin pages
143 | * Maintenance: Tested up to WordPress 6.1
144 |
145 | ### 2.11.1 ###
146 | * Tweak: remove superfluous type attribute from inline script tag
147 | * Maintenance: Tested up to WordPress 6.0
148 |
149 | ### 2.11.0 ###
150 | * Fix: Allow empty comments if `allow_empty_comment` is set to true
151 | * Fix: Add `aria-label` to work around bug in a11y testing tools
152 | * Fix: Change priority for `comment_form_field_comment` from 10 to 99
153 | * Tweak: Updated some FAQ entries
154 | * Tweak: Updated build tooling
155 |
156 | ### 2.10.0 ###
157 | * Fix: Switch from ip2country.info to iplocate.io for country check
158 | * Enhancement: Use filter to add the honeypot field instead of output buffering for new installations and added option to switch between the both ways
159 | * Tweak: Added comment user agent to regex pattern check
160 | * Tweak: Make the ping detection filterable to support new comment types
161 | * Tweak: Updated internal documentation links
162 | * Tweak: Several updates and optimizations in the testing process
163 | * Tweak: Adjust color palette to recent WP version
164 | * Tweak: Adjust wording in variables and option names
165 | * Readme: Add new contributor and clean up unused code
166 |
167 |
168 | ### 2.9.4 ###
169 | * Enhancement: Add filter to allow ajax calls
170 | * Tweak: Better wording for BBCode feature in plugin description
171 | * Tweak: Better screenshots in the plugin directory
172 | * Maintenance: Tested up to WordPress 5.7
173 |
174 | ### 2.9.3 ###
175 | * Fixed: Compatibility with WordPress 5.5
176 | * Fixed: Undefined index on spam list page
177 | * Tweak: Better wording on settings page
178 | * Tweak: AMP compatibility
179 | * Tweak: Protect CSS from overwrite through bad themes
180 |
181 | ### 2.9.2 ###
182 | * Fix: Delete comment meta for deleted old spam. For the cleanup of older orphaned comment meta we suggest the usage of [WP Sweep](https://wordpress.org/plugins/wp-sweep/)
183 | * Fix: Statistic in dashboard showed wrong value
184 | * Tweak: Change autocomplete attribute to "new-password"
185 | * Tweak: Autoptimize compatibility improved
186 | * Tweak: Renamed blacklist/whitelist to a better phrase
187 | * Tweak: Added new pattern
188 | * Tweak: UI and text optimizations
189 | * Tweak: Better compatibility with some server configurations
190 | * Tweak: Make spam reason sortable and filterable
191 | * Tweak: Add spam reason for manually marked spam
192 | * Maintenance: Deleted unused code
193 | * Maintenance: Removed Fake IP check (unreliable and producing false positives)
194 | * Maintenance: Fix some coding standard issues
195 | * Maintenance: Tested up to WordPress 5.4
196 | * Maintenance: Tested up to PHP 7.4
197 |
198 | ### 2.9.1 ###
199 | * Improved backend accessibility
200 | * Prefilled comment textareas do now work with the honeypot
201 | * Compatible with the AMP plugin (https://wordpress.org/plugins/amp/)
202 | * Improved dashboard tooltips
203 | * Improvements for the language detection API
204 | * Scalable IP look up for local spam database
205 |
206 | ### 2.9.0 ###
207 | * Introduction of coding standards.
208 | * Switch to franc language detection API for the language check.
209 | * Do not longer overwrite the IP address WordPress saves with the comment by using `pre_comment_user_ip`.
210 | * Do not show "Trust commenters with a Gravatar" if the "Show Gravatar" option is not set.
211 | * Skip the checks, when I ping myself.
212 | * Fixes some wrong usages of the translation functions.
213 | * Use the regular expressions check also for trackbacks.
214 | * Add option to delete Antispam Bee related data when plugin gets deleted via the admin interface.
215 | * Save a hashed + salted IP for every comment
216 | * New check for incoming trackbacks.
217 | * Introduction of behat tests.
218 | * Updates the used JavaScript library for the statistics widget.
219 | * Bugfix in the "Comment form used outside of posts" option.
220 |
221 | ### 2.8.1 ###
222 | * PHP 5.3 compatibility
223 | * Bugfix where a spam trackback produced a fatal error
224 | * For more details see https://github.com/pluginkollektiv/antispam-bee/milestone/8?closed=1
225 |
226 | ### 2.8.0 ###
227 | * Removed stopforumspam.com to avoid potential GDPR violation
228 | * Improves IP handling to comply with GDPR
229 | * Improves PHP7.2 compatibility
230 | * Fixes small bug on mobile views
231 | * Allow more than one language in language check
232 | * Minor interface improvements
233 | * Remove old russian and Dutch translation files
234 | * For more details see https://github.com/pluginkollektiv/antispam-bee/milestone/4?closed=1
235 |
236 | ### 2.7.1 ###
237 | * Fixes an incompatibility with Chrome autofill
238 | * Fixes some incompatibilities with other plugins/themes where the comment field was left empty
239 | * Support for RTL
240 | * Solve some translation/language issues
241 | * A new filter to add languages to the language check
242 | * For more details see https://github.com/pluginkollektiv/antispam-bee/milestone/6?closed=1
243 |
244 | ### 2.7.0 ###
245 | * Country check is back again (thanks to Sergej Müller for his amazing work and the service page)
246 | * Improved Honeypot
247 | * Language check through Google Translate API is back again (thanks to Simon Kraft of https://moenus.net/ for offering to cover the costs)
248 | * More default Regexes
249 | * Unit Test Framework
250 | * Accessibility and GUI improvements
251 | * An [english documentation](https://github.com/pluginkollektiv/antispam-bee/wiki) is now available, too. Some corrections in the german documentation.
252 | * Some bugfixes - Among other things for WPML compatibility
253 | * For more details see https://github.com/pluginkollektiv/antispam-bee/milestone/3?closed=1
254 |
255 | ### 2.6.9 ###
256 | * Updates donation links throughout the plugin
257 | * Fixes an error were JavaScript on the dashboard was erroneously being enqueued
258 | * Ensures compatibility with the latest WordPress version
259 |
260 | ### 2.6.8 ###
261 | * added a POT file
262 | * updated German translation, added formal version
263 | * updated plugin text domain to include a dash instead of an underscore
264 | * updated, translated + formatted README.md
265 | * updated expired link URLs in plugin and languages files
266 | * updated [plugin authors](https://pluginkollektiv.org/hello-world/)
267 |
268 | ### 2.6.7 ###
269 | * Removal of functions *Block comments from specific countries* and *Allow comments only in certain language* for financial reasons - [more information](https://antispambee.pluginkollektiv.org/news/2015/removal-of-allow-comments-only-in-certain-language/)
270 |
271 | ### 2.6.6 ###
272 | * Switch to the official Google Translation API
273 | * *Release time investment (Development & QA): 2.5 h*
274 |
275 | ### 2.6.5 ###
276 | * Fix: Return parameters on `dashboard_glance_items` callback / thx [@toscho](https://twitter.com/toscho)
277 | * New function: Trust commenters with a Gravatar / thx [@glueckpress](https://twitter.com/glueckpress)
278 | * Additional plausibility checks and filters
279 | * *Release time investment (Development & QA): 12 h*
280 |
281 | ### 2.6.4 ###
282 | * Consideration of the comment time (Spam if a comment was written in less than 5 seconds) - [more information](https://antispambee.pluginkollektiv.org/news/2014/antispam-bee-2-6-4/)
283 | * *Release time investment (Development & QA): 6.25 h*
284 |
285 | ### 2.6.3 ###
286 | * Sorting for the Antispam Bee column in the spam comments overview
287 | * Code refactoring around the use of REQUEST_URI
288 | * *Release time investment (Development & QA): 2.75 h*
289 |
290 | ### 2.6.2 ###
291 | * Improving detection of fake IPs
292 | * *Release time investment (Development & QA): 11 h*
293 |
294 | ### 2.6.1 ###
295 | * Code refactoring of options management
296 | * Support for `HTTP_FORWARDED_FOR` header
297 | * *Release time investment (Development & QA): 8.5 h*
298 |
299 | ### 2.6.0 ###
300 | * Optimizations for WordPress 3.8
301 | * Clear invalid UTF-8 characters in comment fields
302 | * Spam reason as a column in the table with spam comments
303 |
304 | For the complete changelog, check out our [GitHub repository](https://github.com/pluginkollektiv/antispam-bee).
305 |
306 | == Upgrade Notice ==
307 |
308 | = 2.11.5 =
309 | Instead of pre_comment_user_ip you need to use our new filter antispam_bee_trusted_ip to send the correct IP address
310 |
311 | = 2.11.3 =
312 | The multiselect field for "Delete comments by spam reasons" did not store any values in the last version - please check the setting after the update!
313 |
314 | = 2.8.0 =
315 | This update makes sure your spam check is GDPR compliant, no matter the options you choose. Please make sure to update before May 25th!
316 |
317 | ## Screenshots ##
318 | 1. Block or allow comments from specific countries.
319 | 2. Allow comments only in certain languages.
320 | 3. Add useful spam stats to your dashboard.
321 | 4. Tailor WordPress' spam management to your workflow.
322 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 2, June 1991
3 |
4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6 | Everyone is permitted to copy and distribute verbatim copies
7 | of this license document, but changing it is not allowed.
8 |
9 | Preamble
10 |
11 | The licenses for most software are designed to take away your
12 | freedom to share and change it. By contrast, the GNU General Public
13 | License is intended to guarantee your freedom to share and change free
14 | software--to make sure the software is free for all its users. This
15 | General Public License applies to most of the Free Software
16 | Foundation's software and to any other program whose authors commit to
17 | using it. (Some other Free Software Foundation software is covered by
18 | the GNU Lesser General Public License instead.) You can apply it to
19 | your programs, too.
20 |
21 | When we speak of free software, we are referring to freedom, not
22 | price. Our General Public Licenses are designed to make sure that you
23 | have the freedom to distribute copies of free software (and charge for
24 | this service if you wish), that you receive source code or can get it
25 | if you want it, that you can change the software or use pieces of it
26 | in new free programs; and that you know you can do these things.
27 |
28 | To protect your rights, we need to make restrictions that forbid
29 | anyone to deny you these rights or to ask you to surrender the rights.
30 | These restrictions translate to certain responsibilities for you if you
31 | distribute copies of the software, or if you modify it.
32 |
33 | For example, if you distribute copies of such a program, whether
34 | gratis or for a fee, you must give the recipients all the rights that
35 | you have. You must make sure that they, too, receive or can get the
36 | source code. And you must show them these terms so they know their
37 | rights.
38 |
39 | We protect your rights with two steps: (1) copyright the software, and
40 | (2) offer you this license which gives you legal permission to copy,
41 | distribute and/or modify the software.
42 |
43 | Also, for each author's protection and ours, we want to make certain
44 | that everyone understands that there is no warranty for this free
45 | software. If the software is modified by someone else and passed on, we
46 | want its recipients to know that what they have is not the original, so
47 | that any problems introduced by others will not reflect on the original
48 | authors' reputations.
49 |
50 | Finally, any free program is threatened constantly by software
51 | patents. We wish to avoid the danger that redistributors of a free
52 | program will individually obtain patent licenses, in effect making the
53 | program proprietary. To prevent this, we have made it clear that any
54 | patent must be licensed for everyone's free use or not licensed at all.
55 |
56 | The precise terms and conditions for copying, distribution and
57 | modification follow.
58 |
59 | GNU GENERAL PUBLIC LICENSE
60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61 |
62 | 0. This License applies to any program or other work which contains
63 | a notice placed by the copyright holder saying it may be distributed
64 | under the terms of this General Public License. The "Program", below,
65 | refers to any such program or work, and a "work based on the Program"
66 | means either the Program or any derivative work under copyright law:
67 | that is to say, a work containing the Program or a portion of it,
68 | either verbatim or with modifications and/or translated into another
69 | language. (Hereinafter, translation is included without limitation in
70 | the term "modification".) Each licensee is addressed as "you".
71 |
72 | Activities other than copying, distribution and modification are not
73 | covered by this License; they are outside its scope. The act of
74 | running the Program is not restricted, and the output from the Program
75 | is covered only if its contents constitute a work based on the
76 | Program (independent of having been made by running the Program).
77 | Whether that is true depends on what the Program does.
78 |
79 | 1. You may copy and distribute verbatim copies of the Program's
80 | source code as you receive it, in any medium, provided that you
81 | conspicuously and appropriately publish on each copy an appropriate
82 | copyright notice and disclaimer of warranty; keep intact all the
83 | notices that refer to this License and to the absence of any warranty;
84 | and give any other recipients of the Program a copy of this License
85 | along with the Program.
86 |
87 | You may charge a fee for the physical act of transferring a copy, and
88 | you may at your option offer warranty protection in exchange for a fee.
89 |
90 | 2. You may modify your copy or copies of the Program or any portion
91 | of it, thus forming a work based on the Program, and copy and
92 | distribute such modifications or work under the terms of Section 1
93 | above, provided that you also meet all of these conditions:
94 |
95 | a) You must cause the modified files to carry prominent notices
96 | stating that you changed the files and the date of any change.
97 |
98 | b) You must cause any work that you distribute or publish, that in
99 | whole or in part contains or is derived from the Program or any
100 | part thereof, to be licensed as a whole at no charge to all third
101 | parties under the terms of this License.
102 |
103 | c) If the modified program normally reads commands interactively
104 | when run, you must cause it, when started running for such
105 | interactive use in the most ordinary way, to print or display an
106 | announcement including an appropriate copyright notice and a
107 | notice that there is no warranty (or else, saying that you provide
108 | a warranty) and that users may redistribute the program under
109 | these conditions, and telling the user how to view a copy of this
110 | License. (Exception: if the Program itself is interactive but
111 | does not normally print such an announcement, your work based on
112 | the Program is not required to print an announcement.)
113 |
114 | These requirements apply to the modified work as a whole. If
115 | identifiable sections of that work are not derived from the Program,
116 | and can be reasonably considered independent and separate works in
117 | themselves, then this License, and its terms, do not apply to those
118 | sections when you distribute them as separate works. But when you
119 | distribute the same sections as part of a whole which is a work based
120 | on the Program, the distribution of the whole must be on the terms of
121 | this License, whose permissions for other licensees extend to the
122 | entire whole, and thus to each and every part regardless of who wrote it.
123 |
124 | Thus, it is not the intent of this section to claim rights or contest
125 | your rights to work written entirely by you; rather, the intent is to
126 | exercise the right to control the distribution of derivative or
127 | collective works based on the Program.
128 |
129 | In addition, mere aggregation of another work not based on the Program
130 | with the Program (or with a work based on the Program) on a volume of
131 | a storage or distribution medium does not bring the other work under
132 | the scope of this License.
133 |
134 | 3. You may copy and distribute the Program (or a work based on it,
135 | under Section 2) in object code or executable form under the terms of
136 | Sections 1 and 2 above provided that you also do one of the following:
137 |
138 | a) Accompany it with the complete corresponding machine-readable
139 | source code, which must be distributed under the terms of Sections
140 | 1 and 2 above on a medium customarily used for software interchange; or,
141 |
142 | b) Accompany it with a written offer, valid for at least three
143 | years, to give any third party, for a charge no more than your
144 | cost of physically performing source distribution, a complete
145 | machine-readable copy of the corresponding source code, to be
146 | distributed under the terms of Sections 1 and 2 above on a medium
147 | customarily used for software interchange; or,
148 |
149 | c) Accompany it with the information you received as to the offer
150 | to distribute corresponding source code. (This alternative is
151 | allowed only for noncommercial distribution and only if you
152 | received the program in object code or executable form with such
153 | an offer, in accord with Subsection b above.)
154 |
155 | The source code for a work means the preferred form of the work for
156 | making modifications to it. For an executable work, complete source
157 | code means all the source code for all modules it contains, plus any
158 | associated interface definition files, plus the scripts used to
159 | control compilation and installation of the executable. However, as a
160 | special exception, the source code distributed need not include
161 | anything that is normally distributed (in either source or binary
162 | form) with the major components (compiler, kernel, and so on) of the
163 | operating system on which the executable runs, unless that component
164 | itself accompanies the executable.
165 |
166 | If distribution of executable or object code is made by offering
167 | access to copy from a designated place, then offering equivalent
168 | access to copy the source code from the same place counts as
169 | distribution of the source code, even though third parties are not
170 | compelled to copy the source along with the object code.
171 |
172 | 4. You may not copy, modify, sublicense, or distribute the Program
173 | except as expressly provided under this License. Any attempt
174 | otherwise to copy, modify, sublicense or distribute the Program is
175 | void, and will automatically terminate your rights under this License.
176 | However, parties who have received copies, or rights, from you under
177 | this License will not have their licenses terminated so long as such
178 | parties remain in full compliance.
179 |
180 | 5. You are not required to accept this License, since you have not
181 | signed it. However, nothing else grants you permission to modify or
182 | distribute the Program or its derivative works. These actions are
183 | prohibited by law if you do not accept this License. Therefore, by
184 | modifying or distributing the Program (or any work based on the
185 | Program), you indicate your acceptance of this License to do so, and
186 | all its terms and conditions for copying, distributing or modifying
187 | the Program or works based on it.
188 |
189 | 6. Each time you redistribute the Program (or any work based on the
190 | Program), the recipient automatically receives a license from the
191 | original licensor to copy, distribute or modify the Program subject to
192 | these terms and conditions. You may not impose any further
193 | restrictions on the recipients' exercise of the rights granted herein.
194 | You are not responsible for enforcing compliance by third parties to
195 | this License.
196 |
197 | 7. If, as a consequence of a court judgment or allegation of patent
198 | infringement or for any other reason (not limited to patent issues),
199 | conditions are imposed on you (whether by court order, agreement or
200 | otherwise) that contradict the conditions of this License, they do not
201 | excuse you from the conditions of this License. If you cannot
202 | distribute so as to satisfy simultaneously your obligations under this
203 | License and any other pertinent obligations, then as a consequence you
204 | may not distribute the Program at all. For example, if a patent
205 | license would not permit royalty-free redistribution of the Program by
206 | all those who receive copies directly or indirectly through you, then
207 | the only way you could satisfy both it and this License would be to
208 | refrain entirely from distribution of the Program.
209 |
210 | If any portion of this section is held invalid or unenforceable under
211 | any particular circumstance, the balance of the section is intended to
212 | apply and the section as a whole is intended to apply in other
213 | circumstances.
214 |
215 | It is not the purpose of this section to induce you to infringe any
216 | patents or other property right claims or to contest validity of any
217 | such claims; this section has the sole purpose of protecting the
218 | integrity of the free software distribution system, which is
219 | implemented by public license practices. Many people have made
220 | generous contributions to the wide range of software distributed
221 | through that system in reliance on consistent application of that
222 | system; it is up to the author/donor to decide if he or she is willing
223 | to distribute software through any other system and a licensee cannot
224 | impose that choice.
225 |
226 | This section is intended to make thoroughly clear what is believed to
227 | be a consequence of the rest of this License.
228 |
229 | 8. If the distribution and/or use of the Program is restricted in
230 | certain countries either by patents or by copyrighted interfaces, the
231 | original copyright holder who places the Program under this License
232 | may add an explicit geographical distribution limitation excluding
233 | those countries, so that distribution is permitted only in or among
234 | countries not thus excluded. In such case, this License incorporates
235 | the limitation as if written in the body of this License.
236 |
237 | 9. The Free Software Foundation may publish revised and/or new versions
238 | of the General Public License from time to time. Such new versions will
239 | be similar in spirit to the present version, but may differ in detail to
240 | address new problems or concerns.
241 |
242 | Each version is given a distinguishing version number. If the Program
243 | specifies a version number of this License which applies to it and "any
244 | later version", you have the option of following the terms and conditions
245 | either of that version or of any later version published by the Free
246 | Software Foundation. If the Program does not specify a version number of
247 | this License, you may choose any version ever published by the Free Software
248 | Foundation.
249 |
250 | 10. If you wish to incorporate parts of the Program into other free
251 | programs whose distribution conditions are different, write to the author
252 | to ask for permission. For software which is copyrighted by the Free
253 | Software Foundation, write to the Free Software Foundation; we sometimes
254 | make exceptions for this. Our decision will be guided by the two goals
255 | of preserving the free status of all derivatives of our free software and
256 | of promoting the sharing and reuse of software generally.
257 |
258 | NO WARRANTY
259 |
260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268 | REPAIR OR CORRECTION.
269 |
270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278 | POSSIBILITY OF SUCH DAMAGES.
279 |
280 | END OF TERMS AND CONDITIONS
281 |
282 | How to Apply These Terms to Your New Programs
283 |
284 | If you develop a new program, and you want it to be of the greatest
285 | possible use to the public, the best way to achieve this is to make it
286 | free software which everyone can redistribute and change under these terms.
287 |
288 | To do so, attach the following notices to the program. It is safest
289 | to attach them to the start of each source file to most effectively
290 | convey the exclusion of warranty; and each file should have at least
291 | the "copyright" line and a pointer to where the full notice is found.
292 |
293 | {description}
294 | Copyright (C) {year} {fullname}
295 |
296 | This program is free software; you can redistribute it and/or modify
297 | it under the terms of the GNU General Public License as published by
298 | the Free Software Foundation; either version 2 of the License, or
299 | (at your option) any later version.
300 |
301 | This program is distributed in the hope that it will be useful,
302 | but WITHOUT ANY WARRANTY; without even the implied warranty of
303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304 | GNU General Public License for more details.
305 |
306 | You should have received a copy of the GNU General Public License along
307 | with this program; if not, write to the Free Software Foundation, Inc.,
308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
309 |
310 | Also add information on how to contact you by electronic and paper mail.
311 |
312 | If the program is interactive, make it output a short notice like this
313 | when it starts in an interactive mode:
314 |
315 | Gnomovision version 69, Copyright (C) year name of author
316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
317 | This is free software, and you are welcome to redistribute it
318 | under certain conditions; type `show c' for details.
319 |
320 | The hypothetical commands `show w' and `show c' should show the appropriate
321 | parts of the General Public License. Of course, the commands you use may
322 | be called something other than `show w' and `show c'; they could even be
323 | mouse-clicks or menu items--whatever suits your program.
324 |
325 | You should also get your employer (if you work as a programmer) or your
326 | school, if any, to sign a "copyright disclaimer" for the program, if
327 | necessary. Here is a sample; alter the names:
328 |
329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program
330 | `Gnomovision' (which makes passes at compilers) written by James Hacker.
331 |
332 | {signature of Ty Coon}, 1 April 1989
333 | Ty Coon, President of Vice
334 |
335 | This General Public License does not permit incorporating your program into
336 | proprietary programs. If your program is a subroutine library, you may
337 | consider it more useful to permit linking proprietary applications with the
338 | library. If this is what you want to do, use the GNU Lesser General
339 | Public License instead of this License.
340 |
--------------------------------------------------------------------------------
/inc/gui.class.php:
--------------------------------------------------------------------------------
1 | (int) ( ! empty( $_POST['ab_flag_spam'] ) ),
50 | 'email_notify' => (int) ( ! empty( $_POST['ab_email_notify'] ) ),
51 | 'cronjob_enable' => (int) ( ! empty( $_POST['ab_cronjob_enable'] ) ),
52 | 'cronjob_interval' => (int) self::get_key( $_POST, 'ab_cronjob_interval' ),
53 |
54 | 'no_notice' => (int) ( ! empty( $_POST['ab_no_notice'] ) ),
55 |
56 | 'dashboard_count' => (int) ( ! empty( $_POST['ab_dashboard_count'] ) ),
57 | 'dashboard_chart' => (int) ( ! empty( $_POST['ab_dashboard_chart'] ) ),
58 | 'regexp_check' => (int) ( ! empty( $_POST['ab_regexp_check'] ) ),
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'] ) ),
65 | 'ignore_type' => (int) self::get_key( $_POST, 'ab_ignore_type' ),
66 |
67 | 'reasons_enable' => (int) ( ! empty( $_POST['ab_reasons_enable'] ) ),
68 | 'ignore_reasons' => (array) self::get_key( $_POST, 'ab_ignore_reasons' ),
69 |
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 ) {
86 | if ( ! isset( self::$defaults['reasons'][ $val ] ) ) {
87 | unset( $options['ignore_reasons'][ $key ] );
88 | }
89 | }
90 |
91 | if ( empty( $options['cronjob_interval'] ) ) {
92 | $options['cronjob_enable'] = 0;
93 | }
94 |
95 | if ( empty( $options['translate_lang'] ) ) {
96 | $options['translate_api'] = 0;
97 | }
98 |
99 | if ( empty( $options['reasons_enable'] ) ) {
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 |
123 | if ( $options['cronjob_enable'] && ! self::get_option( 'cronjob_enable' ) ) {
124 | self::init_scheduled_hook();
125 | } elseif ( ! $options['cronjob_enable'] && self::get_option( 'cronjob_enable' ) ) {
126 | self::clear_scheduled_hook();
127 | }
128 |
129 | self::update_options( $options );
130 |
131 | wp_safe_redirect(
132 | add_query_arg(
133 | array(
134 | 'updated' => 'true',
135 | ),
136 | wp_get_referer()
137 | )
138 | );
139 |
140 | die();
141 | }
142 |
143 | /**
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.
150 | * @param string $selected Selected value.
151 | * @return string $html Generated HTML.
152 | */
153 | private static function _build_select( $name, $data, $selected ) {
154 | $html = '';
159 |
160 | return $html;
161 | }
162 |
163 |
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 | ?>
173 |
174 |
175 | Antispam Bee
176 |
177 |
178 |
542 |
543 | __( 'German', 'antispam-bee' ),
556 | 'en' => __( 'English', 'antispam-bee' ),
557 | 'fr' => __( 'French', 'antispam-bee' ),
558 | 'it' => __( 'Italian', 'antispam-bee' ),
559 | 'es' => __( 'Spanish', 'antispam-bee' ),
560 | );
561 |
562 | /**
563 | * Filter the possible languages for the language spam test
564 | *
565 | * @since 2.7.1
566 | * @param (array) $lang The languages
567 | * @return (array)
568 | */
569 | return apply_filters( 'ab_get_allowed_translate_languages', $lang );
570 | }
571 | }
572 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## Changelog ##
2 |
3 | ### 2.11.8 ###
4 | * **English**
5 | * Tweak: Minor code changes and housekeeping
6 | * Tweak: Add link to Patchstack in readme
7 | * Maintenance: Tested up to WordPress 6.8
8 |
9 | * **Deutsch**
10 | * Tweak: Kleinere Code-Änderungen und Aufräumarbeiten
11 | * Tweak: Link zu Patchstack in readme hinzugefügt
12 | * Wartung: Getestet mit WordPress 6.8
13 |
14 | ### 2.11.7 ###
15 | * **English**
16 | * Tweak: Use SCRIPT_NAME instead of REQUEST_URI to check path
17 | * Fix: Remove `add_reasons_to_defaults()` from general initialization for better WordPress 6.7 compatibility
18 | * Maintenance: Tested up to WordPress 6.7
19 |
20 | * **Deutsch**
21 | * Tweak: Verwende SCRIPT_NAME anstelle von REQUEST_URI, um den Pfad zu prüfen
22 | * Fix: Entfernen von `add_reasons_to_defaults()` von der allgemeinen Initialisierung für bessere WordPress 6.7 Kompatibilität
23 | * Wartung: Getestet mit WordPress 6.7
24 |
25 | ### 2.11.6 ###
26 | * **English**
27 | * Fix: Delete missed out option on uninstall (Thanks @okvee!)
28 | * Tweak: Minor i18n improvements (Thanks Pedro!)
29 | * Tweak: Minor code changes and housekeeping
30 | * Tweak: Updated dependencies
31 |
32 | * **Deutsch**
33 | * Fix: Bei Deinstallation wurde eine Option nicht korrekt gelöscht (Danke @okvee!)
34 | * Tweak: Kleinere i18n-Verbesserungen (Danke Pedro!)
35 | * Tweak: Kleinere Code-Änderungen und Aufräumarbeiten
36 | * Tweak: Aktualisierte Abhängigkeiten
37 |
38 | ### 2.11.5 ###
39 | IMPORTANT: If you use the country check and are behind a proxy or similar, you need to use the `antispam_bee_trusted_ip` filter to get the correct IP from a header like `HTTP_X_FORWARDED` (don’t return an empty value here, otherwise all comments are marked as spam).
40 | WICHTIG: Wenn du den Spam-Check für bestimmte Länder verwendest und hinter einem Proxy oder ähnlich bist, musst du den `antispam_bee_trusted_ip`-Filter verwenden, um die richtige Adresse des Users von einem Header wie `HTTP_X_FORWARDED` zu bekommen (hier darfst du keinen leeren String zurückgeben, sonst werden alle Kommentare als Spam markiert).
41 | * **English**
42 | * Fix: Usage of core filter `pre_comment_user_ip` breaks ASB if the IP address is removed for GDPR compliance
43 |
44 | * **Deutsch**
45 | * Fix: Die Verwendung des Core-Filters `pre_comment_user_ip` sorgt für Fehler, wenn die IP-Adresse für die Einhaltung der DSGVO entfernt wird
46 |
47 | ### 2.11.4 ###
48 | IMPORTANT: If you use the country check and are behind a proxy or similar, you need to use the `pre_comment_user_ip` filter to get the correct IP from a header like `HTTP_X_FORWARDED`.
49 | WICHTIG: Wenn du den Spam-Check für bestimmte Länder verwendest und hinter einem Proxy oder ähnlich bist, musst du den `pre_comment_user_ip`-Filter verwenden, um die richtige Adresse des Users von einem Header wie `HTTP_X_FORWARDED` zu bekommen.
50 | * **English**
51 | * Fix: Read client IP for country check from `REMOTE_ADDR` only (filterable via `pre_comment_user_ip`)
52 | * Fix: No spam reason in spam notification email, and related PHP warning
53 | * Fix: Remove outdated info from readme
54 | * Enhancement: Show upgrade notice on plugin overview page
55 | * Maintenance: Tested up to WordPress 6.3
56 |
57 | * **Deutsch**
58 | * Fix: Client-IP wird nur noch aus `REMOTE_ADDR` ermittelt (filterbar über `pre_comment_user_ip`)
59 | * Fix: Der Spam-Grund wird wieder korrekt in der Benachrichtigungs-E-Mail zu Spam angezeigt und die damit zusammenhängende PHP-Warning behoben
60 | * Fix: Veraltete Infos aus der Readme wurden entfernt
61 | * Verbesserung: Upgrade-Hinweis wird auch in der Plugin-Übersicht angezeigt
62 | * Wartung: Getestet mit WordPress 6.3
63 |
64 | ### 2.11.3 ###
65 | * **English**
66 | * Fix: Multiselect for "Delete comments by spam reasons" was not saving values
67 | * Fix: Fix broken link for ISO country codes
68 | * Maintenance: Added test for PHP 8.2
69 | * Maintenance: Tested up to WordPress 6.2
70 |
71 | * **Deutsch**
72 | * Behoben: Multiselect für "Kommentare aus Spamgründen löschen" speicherte keine Werte
73 | * Fix: Fehlerhafter Link für ISO-Ländercodes behoben
74 | * Wartung: Test für PHP 8.2 hinzugefügt
75 | * Wartung: Getestet mit WordPress 6.2
76 |
77 | ### 2.11.2 ###
78 | * **English**
79 | * Tweak: remove superfluous translations
80 | * Tweak: make FAQ link an anchor link
81 | * Fix: spam counter no longer raises a warning with PHP 8.1 if no spam is present yet
82 | * Fix: spam reasons are now localized correctly
83 | * Fix: Translations were loaded twice on some admin pages
84 | * Maintenance: Tested up to WordPress 6.1
85 |
86 | * **Deutsch**
87 | * Tweak: Überflüssige Übersetzungen entfernt
88 | * Tweak: Link zu den FAQ ist jetzt ein Anker-Link
89 | * Fix: Der Spam-Zähler erzeugt mit PHP 8.1 keine Warnung mehr, wenn noch kein Spam vorhanden ist
90 | * Fix: Spam-Gründe werden nun korrekt übersetzt
91 | * Fix: Übersetzungen wurden auf einzelnen Adminseiten doppelt geladen
92 | * Wartung: Getestet mit WordPress 6.1
93 |
94 | ### 2.11.1 ###
95 | * **English**
96 | * Tweak: remove superfluous type attribute from inline script tag
97 | * Maintenance: Tested up to WordPress 6.0
98 |
99 | * **Deutsch**
100 | * Tweak: Überflüssiges type-Attribut von script-Tag entfernt
101 | * Wartung: Getestet mit WordPress 6.0
102 |
103 | ### 2.11.0 ###
104 | * **English**
105 | * Fix: Allow empty comments if `allow_empty_comment` is set to true
106 | * Fix: Add `aria-label` to work around bug in a11y testing tools
107 | * Fix: Change priority for `comment_form_field_comment` from 10 to 99
108 | * Tweak: Updated some FAQ entries
109 | * Tweak: Updated build tooling
110 |
111 | * **Deutsch**
112 | * Fix: Leere Kommentare erlauben, wenn der Filter `allow_empty_comment` gesetzt ist
113 | * Fix: Ein `aria-label` hinzugefügt, um einen bekannten Fehler bei Tests zu umgehen
114 | * Fix: Änderung der Priorität vom Filter `comment_form_field_comment` von 10 auf 99
115 | * Tweak: Aktualisierungen in der FAQ
116 | * Tweak: Optimierungen am Build-Prozess
117 |
118 | ### 2.10.0 ###
119 | * **English**
120 | * Fix: Switch from ip2country.info to iplocate.io for country check
121 | * Enhancement: Use filter to add the honeypot field instead of output buffering for new installations and added option to switch between the both ways
122 | * Tweak: Added comment user agent to regex pattern check
123 | * Tweak: Make the ping detection filterable to support new comment types
124 | * Tweak: Updated internal documentation links
125 | * Tweak: Several updates and optimizations in the testing process
126 | * Tweak: Adjust color palette to recent WP version
127 | * Tweak: Adjust wording in variables and option names
128 | * Readme: Add new contributor and clean up unused code
129 |
130 | * **Deutsch**
131 | * Fix: Wechsel von ip2country.info zu iplocate.io für die Länderprüfung
132 | * 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
133 | * Tweak: Kommentar User-Agent zu Regex-Pattern hinzugefügt
134 | * Tweak: Die Ping-Erkennung ist jetzt filterbar, um neue Kommentartypen zu unterstützen
135 | * Tweak: Aktualisierte Links zur internen Dokumentation
136 | * Tweak: Verschiedene Aktualisierungen und Optimierungen im Testprozess
137 | * Tweak: Farbpalette an aktuelle WP-Version anpassen
138 | * Tweak: Wortlaut in Variablen und Optionsnamen wurden angepasst
139 | * Readme: Neuer Contributor hinzugefügt und unbenutzten Code bereinigt
140 |
141 | ### 2.9.4 ###
142 | * **English**
143 | * Enhancement: Add filter to allow ajax calls
144 | * Tweak: Better wording for BBCode feature in plugin description
145 | * Tweak: Better screenshots in the plugin directory
146 | * Maintenance: Tested up to WordPress 5.7
147 |
148 | * **Deutsch**
149 | * Verbesserung: Filter hinzugefügt, um Ajax-Aufrufe zuzulassen
150 | * Tweak: Bessere Formulierung für BBCode-Funktion in Plugin-Beschreibung
151 | * Tweak: Bessere Screenshots im Plugin-Verzeichnis
152 | * Wartung: Getestet mit WordPress 5.7
153 |
154 | ### 2.9.3 ###
155 | * **English**
156 | * Fixed: Compatibility with WordPress 5.5
157 | * Fixed: Undefined index on spam list page
158 | * Tweak: Better wording on settings page
159 | * Tweak: AMP compatibility
160 | * Tweak: Protect CSS from overwrite through bad themes
161 |
162 | * **Deutsch**
163 | * Fix: Kompatibilität mit WordPress 5.5
164 | * Fix: Undefined index in Spamliste
165 | * Tweak: Inklusivere Sprache unter Einstellungen
166 | * Tweak: AMP-Kompatibilität
167 | * Tweak: Schütze CSS besser vor Überschreiben durch schlechte Themes
168 |
169 | ### 2.9.2 ###
170 | * **English**
171 | * Fix: Delete comment meta for deleted old spam. For the cleanup of older orphaned comment meta we suggest the usage of [WP Sweep](https://wordpress.org/plugins/wp-sweep/)
172 | * Fix: Statistic in dashboard showed wrong value
173 | * Tweak: Change autocomplete attribute to "new-password"
174 | * Tweak: Autoptimize compatibility improved
175 | * Tweak: Renamed blacklist/whitelist to a better phrase
176 | * Tweak: Added new pattern
177 | * Tweak: UI and text optimizations
178 | * Tweak: Better compatibility with some server configurations
179 | * Tweak: Make spam reason sortable and filterable
180 | * Tweak: Add spam reason for manually marked spam
181 | * Maintenance: Deleted unused code
182 | * Maintenance: Removed Fake IP check (unreliable and producing false positives)
183 | * Maintenance: Fix some coding standard issues
184 | * Maintenance: Tested up to WordPress 5.4
185 | * Maintenance: Tested up to PHP 7.4
186 |
187 |
188 | * **Deutsch**
189 | * Fix: Lösche Kommentarmeta beim Löschen von Spamkommentaren. Für das Aufräumen alter verwaister Kommentarmetas empfehlen wir die Verwendung von [WP Sweep](https://de.wordpress.org/plugins/wp-sweep/)
190 | * Fix: Dashboard Statistiken zeigten falschen Wert
191 | * Tweak: Änderung des autocomplete Attributs zu "new-password"
192 | * Tweak: Kompatibilität mit Autoptimize verbessert
193 | * Tweak: "Blacklist/Whitelist" umbenannt
194 | * Tweak: Neue Spamerkennungsmuster hinzugefügt
195 | * Tweak: UI und Textverbesserungen
196 | * Tweak: Erhöhte Kompatibilität mit einigen Serverkonfigurationen
197 | * Tweak: Kommentare nach Spamgrund sortier- und filterbar gemacht
198 | * Tweak: Neuer Spamgrund für manuell markierten Spam eingeführt
199 | * Maintenance: Ungenutzter Code wurde gelöscht
200 | * Maintenance: Der Fake IP check wurde entfernt. Dieser war unzuverlässig und produzierte falsche Ergebnisse
201 | * Maintenance: Einige Probleme mit unseren Coding standards wurden gefixt
202 | * Maintenance: Getestet bis WordPress 5.4
203 | * Maintenance: Getestet bis PHP 7.4
204 |
205 | ### 2.9.1 ###
206 | * **English**
207 | * Improved backend accessibility
208 | * Prefilled comment textareas do now work with the honeypot
209 | * Compatible with the AMP plugin (https://wordpress.org/plugins/amp/)
210 | * Improved dashboard tooltips
211 | * Improvements for the language detection API
212 | * Scalable IP look up for local spam database
213 |
214 |
215 | * **Deutsch**
216 | * Verbesserte Barrierefreiheit im Backend
217 | * Vorausgefüllte Kommentarfelder arbeiten jetzt mit dem Honeypot zusammen
218 | * Kompatibel mit dem AMP Plugin (https://wordpress.org/plugins/amp/)
219 | * Verbesserte Tooltips im Dashboard
220 | * Verbesserte Kommunikation mit der Spracherkennungs-API
221 | * Skalierbarer IP-Abgleich für den lokalen Datenbank-Check.
222 |
223 | ### 2.9.0 ###
224 | * **English**
225 | * Introduction of coding standards.
226 | * Switch to franc language detection API for the language check.
227 | * Do not longer overwrite the IP address WordPress saves with the comment by using `pre_comment_user_ip`.
228 | * Do not show "Trust commenters with a Gravatar" if the "Show Gravatar" option is not set.
229 | * Skip the checks, when I ping myself.
230 | * Fixes some wrong usages of the translation functions.
231 | * Use the regular expressions check also for trackbacks.
232 | * Add option to delete Antispam Bee related data when plugin gets deleted via the admin interface.
233 | * Save a hashed + salted IP for every comment
234 | * New check for incoming Trackbacks.
235 | * Introduction of behat tests.
236 | * Updates the used JavaScript library for the statistics widget.
237 | * Bugfix in the "Comment form used outside of posts" option.
238 |
239 | * **Deutsch**
240 | * Einführung von Coding Standards.
241 | * Wechsel auf die Franc Spracherkennungs API für den Sprach-Check.
242 | * Beendet das Überschreiben der IP Adresse via `pre_comment_user_ip`, welche WordPress mit dem Kommentar speichert.
243 | * Zeige die Option "Vertraue Kommentaren mit Gravatar" nur an wenn die Option "Zeige Gravatar" aktiviert ist.
244 | * Überspringe die Filter, wenn ich mich selbst anpinge.
245 | * Repariert einige falsche Verwendungsweisen der Übersetzungsfunktionalitäten.
246 | * Wende den reguläre Ausdrücke Check auch auf Trackbacks an.
247 | * Option hinzugefügt, dass Daten von Antispam Bee gelöscht werden, wenn das Plugin über das Admin Interface gelöscht wird.
248 | * Speichere für jeden Kommentar eine salted Hash der IP Adresse.
249 | * Ein neuer Check für eingehende Trackbacks.
250 | * Einführung von Behat tests.
251 | * Aktualisiert die genutzte JavaScript Bibliothek für das Statistik Widget.
252 | * Bugfix in der "Kommentarformular wird außerhalb von Beiträgen verwendet" Einstellung
253 |
254 | ### 2.8.1 ###
255 |
256 | * **English**
257 | * PHP 5.3 compatibility
258 | * Bugfix where a spam trackback produced a fatal error
259 | * For more details see https://github.com/pluginkollektiv/antispam-bee/milestone/8?closed=1
260 |
261 | * **Deutsch**
262 | * PHP 5.3 Kompatibilität wieder hergestellt
263 | * Bugfix: Ein Spam Trackback produzierte einen Fatal Error
264 | * Mehr Details: https://github.com/pluginkollektiv/antispam-bee/milestone/8?closed=1
265 |
266 | ### 2.8.0 ###
267 |
268 | * **English**
269 | * Removed stopforumspam.com to avoid potential GDPR violation
270 | * Improves IP handling to comply with GDPR
271 | * Improves PHP7.2 compatibility
272 | * Fixes small bug on mobile views
273 | * Allow more than one language in language check
274 | * Minor interface improvements
275 | * Remove old russian and Dutch translation files
276 | * For more details see https://github.com/pluginkollektiv/antispam-bee/milestone/4?closed=1
277 |
278 | * **Deutsch**
279 | - Entfernt stopforumspam.com zur Vorbeugung möglicher DSGVO-Verletzungen
280 | - Verändert den Umgang mit IP-Adressen um der DSGVO zu entsprechen
281 | - Verbessert PHP7.2-Kompatibilität
282 | - Behebt einen CSS-Bugfix der mobilen Darstellung
283 | - Erlaube mehr als eine Sprache im Sprachencheck
284 | - Verberesserungen an der Benutzeroberfläche
285 | - Entfernt alte russische und holländische Sprachversionen
286 | - Mehr Details: https://github.com/pluginkollektiv/antispam-bee/milestone/4?closed=1
287 |
288 | ### 2.7.1 ###
289 |
290 | * **English**
291 | * Fixes an incompatibility with Chrome autofill
292 | * Fixes some incompatibilities with other plugins/themes where the comment field was left empty
293 | * Support for RTL
294 | * Solve some translation/language issues
295 | * A new filter to add languages to the language check
296 | * For more details see https://github.com/pluginkollektiv/antispam-bee/milestone/6?closed=1
297 | * **Deutsch**
298 | - Behebt eine Inkompatibilität mit Chromes Autofill-Funktion
299 | - Behebt einige Inkompatibilitäten mit anderen Plugins/Themes, wo das Kommentarfeld leer bliebt
300 | - Unterstützt RTL-Sprachen
301 | - Behebt einige Probleme im Bereich Sprache/Übersetzung
302 | - Bietet einen neuen Filter zum HInzufügen von Sprachen zum Sprach-Check
303 | - Mehr Details: https://github.com/pluginkollektiv/antispam-bee/milestone/6?closed=1
304 |
305 | ### 2.7.0 ###
306 | * **English**
307 | * Country check is back again (thanks to Sergej Müller for his amazing work and the service page)
308 | * Improved Honeypot
309 | * Language check through Google Translate API is back again (thanks to [Simon Kraft](https://simonkraft.de/) for offering to cover the costs)
310 | * More default Regexes
311 | * Unit Test Framework
312 | * Accessibility and GUI improvements
313 | * An [english documentation](https://github.com/pluginkollektiv/antispam-bee/wiki) is now available, too. Some corrections in the german documentation.
314 | * Some bugfixes - Among other things for WPML compatibility
315 | * For more details see https://github.com/pluginkollektiv/antispam-bee/milestone/3?closed=1
316 |
317 | * **Deutsch**
318 | * Die Länderprüfung ist wieder zurück (dank an Sergej Müller für seine fantastische Arbeit und die Service-Seite)
319 | * Der Honeypot wurde verbessert
320 | * Die Sprachenprüfung über die Google Translate API ist wieder zurück (Dank an [Simon Kraft](https://simonkraft.de/), der sich angeboten hat, die Kosten zu übernehmen)
321 | * Mehr Standard-Regexe
322 | * Verbesserungen an Barrierefreiheit und Benutzer-Oberfläche
323 | * Eine [englische Dokumentation](https://github.com/pluginkollektiv/antispam-bee/wiki) ist jetzt verfügbar. Einige Korrekturen in der deutschen Dokumentation.
324 | * Einige Fehlerkorrekturen - Unter anderem für WPML-Kompatibilität
325 | * Mehr Details: https://github.com/pluginkollektiv/antispam-bee/milestone/3?closed=1
326 |
327 | ### 2.6.9 ###
328 | * **English**
329 | * Updates donation links throughout the plugin
330 | * Fixes an error were JavaScript on the dashboard was erroneously being enqueued
331 | * Ensures compatibility with the latest WordPress version
332 | * **Deutsch**
333 | * Aktualisierung der Spenden Links im gesamten Plugin
334 | * Behebt einen Fehler, durch den auf dem Dashboard fälschlicherweise JavaScript geladen wird
335 | * Gewährleistet die Kompatibilität mit der neuesten WordPress-Version
336 |
337 | ### 2.6.8 ###
338 | * **English**
339 | * added a POT file
340 | * updated German translation, added formal version
341 | * updated plugin text domain to include a dash instead of an underscore
342 | * updated, translated + formatted README.md
343 | * updated expired link URLs in plugin and languages files
344 | * updated [plugin authors](https://gist.github.com/glueckpress/f058c0ab973d45a72720)
345 | * **Deutsch**
346 | * eine POT-Datei hinzugefügt
347 | * deutsche Übersetzung aktualisiert, formale Version hinzugefügt
348 | * Die Text Domain des Plugins in der ReadMe aktualisiert. Statt einem Unterstrich enthält der Name nun ein Bindestrich.
349 | * README.md aktualisiert, übersetzt und formatiert
350 | * verwaiste Link-Adressen in dem Plugin und den Sprachdateien aktualisiert
351 | * [Plugin Autor](https://gist.github.com/glueckpress/f058c0ab973d45a72720) aktualisiert
352 |
353 | ### 2.6.7 ###
354 | * **English**
355 | * Removal of functions *Block comments from specific countries* and *Allow comments only in certain language* for financial reasons
356 | * **Deutsch**
357 | * Entfernung der Funktionen *Kommentare nur in einer Sprache zulassen* und *Bestimmte Länder blockieren bzw. erlauben* aus finanziellen Gründen - [Hintergrund-Informationen](https://antispambee.pluginkollektiv.org/news/2015/removal-of-allow-comments-only-in-certain-language/)
358 |
359 | ### 2.6.6 ###
360 | * **English**
361 | * Switch to the official Google Translation API
362 | * *Release time investment (Development & QA): 2.5 h*
363 | * **Deutsch**
364 | * (Testweise) Umstellung auf die offizielle Google Translation API
365 | * *Release-Zeitaufwand (Development & QA): 2,5 Stunden*
366 |
367 | ### 2.6.5 ###
368 | * **English**
369 | * Fix: Return parameters on `dashboard_glance_items` callback / thx [@toscho](https://twitter.com/toscho)
370 | * New function: [Trust commenters with a Gravatar](https://antispambee.pluginkollektiv.org/documentation#gravatar) / thx [@glueckpress](https://twitter.com/glueckpress)
371 | * Additional plausibility checks and filters
372 | * *Release time investment (Development & QA): 12 h*
373 | * **Deutsch**
374 | * Fix: Parameter-Rückgabe bei `dashboard_glance_items` / thx [@toscho](https://twitter.com/toscho)
375 | * Neue Funktion: [Kommentatoren mit Gravatar vertrauen](https://antispambee.pluginkollektiv.org/de/dokumentation#gravatar) / thx [@glueckpress](https://twitter.com/glueckpress)
376 | * Zusätzliche Plausibilitätsprüfungen und Filter
377 | * *Release-Zeitaufwand (Development & QA): 12 Stunden*
378 |
379 | ### 2.6.4 ###
380 | * **English**
381 | * Consideration of the comment time (Spam if a comment was written in less than 5 seconds)
382 | * *Release time investment (Development & QA): 6.25 h*
383 | * **Deutsch**
384 | * Berücksichtigung der Kommentarzeit (Spam, wenn ein Kommentar in unter 5 Sekunden verfasst) - [Hintergrund-Informationen](https://antispambee.pluginkollektiv.org/news/2014/antispam-bee-2-6-4/)
385 | * *Release-Zeitaufwand (Development & QA): 6,25 Stunden*
386 |
387 | ### 2.6.3 ###
388 | * **English**
389 | * Sorting for the Antispam Bee column in the spam comments overview
390 | * Code refactoring around the use of REQUEST_URI
391 | * *Release time investment (Development & QA): 2.75 h*
392 | * **Deutsch**
393 | * Sortierung für die Antispam Bee Spalte in der Spam-Übersicht
394 | * Code-Refactoring rund um die Nutzung von REQUEST_URI
395 | * *Release-Zeitaufwand (Development & QA): 2,75 Stunden*
396 |
397 | ### 2.6.2 ###
398 | * **English**
399 | * Improving detection of fake IPs
400 | * *Release time investment (Development & QA): 11 h*
401 | * **Deutsch**
402 | * Überarbeitung der Erkennung von gefälschten IPs
403 | * *Release-Zeitaufwand (Development & QA): 11 Stunden*
404 |
405 | ### 2.6.1 ###
406 | * **English**
407 | * Code refactoring of options management
408 | * Support for `HTTP_FORWARDED_FOR` header
409 | * *Release time investment (Development & QA): 8.5 h*
410 | * **Deutsch**
411 | * Überarbeitung der Optionen-Verwaltung
412 | * Berücksichtigung der Header `HTTP_FORWARDED_FOR`
413 | * *Release-Zeitaufwand (Development & QA): 8,5 Stunden*
414 |
415 | ### 2.6.0 ###
416 | * **English**
417 | * Optimizations for WordPress 3.8
418 | * Clear invalid UTF-8 characters in comment fields
419 | * Spam reason as a column in the table with spam comments
420 | * **Deutsch**
421 | * Optimierungen für WordPress 3.8
422 | * Zusatzprüfung auf Nicht-UTF-8-Zeichen in Kommentardaten
423 | * Spamgrund als Spalte in der Übersicht mit Spamkommentaren
424 |
425 | ### 2.5.9 ###
426 | * **English**
427 | * Dashboard widget changes to work with [Statify](http://statify.de)
428 | * **Deutsch**
429 | * Anpassung des Dashboard-Skriptes für die Zusammenarbeit mit [Statify](http://statify.de)
430 |
431 | ### 2.5.8 ###
432 | * **English**
433 | * Switch from TornevallDNSBL to [Stop Forum Spam](http://www.stopforumspam.com)
434 | * New JS library for the Antispam Bee dashboard chart
435 | * **Deutsch**
436 | * Umstellung von TornevallDNSBL zu [Stop Forum Spam](http://www.stopforumspam.com)
437 | * Neue JS-Bibliothek für das Dashboard-Widget
438 |
439 | ### 2.5.7 ###
440 | * **English**
441 | * Optional logfile with spam entries e.g. for [Fail2Ban](https://help.ubuntu.com/community/Fail2ban)
442 | * Filter `antispam_bee_notification_subject` for a custom subject in notifications
443 | * **Deutsch**
444 | * Optionale Spam-Logdatei z.B. für [Fail2Ban](https://wiki.ubuntuusers.de/fail2ban/)
445 | * Filter `antispam_bee_notification_subject` für eigenen Betreff in Benachrichtigungen
446 |
447 | ### 2.5.6 ###
448 | * **English**
449 | * [Added new detection/patterns for spam comments](https://antispambee.pluginkollektiv.org/news/2013/new-patterns-in-antispam-bee-2-5-6/)
450 | * **Deutsch**
451 | * [Neue Erkennungsmuster für Spam hinzugefügt](https://antispambee.pluginkollektiv.org/de/news/2013/neue-erkennungsmuster-in-antispam-bee-2-5-6/)
452 |
453 | ### 2.5.5 ###
454 | * **English**
455 | * Detection and filtering of spam comments that try to exploit the latest [W3 Total Cache and WP Super Cache Vulnerability](http://blog.sucuri.net/2013/05/w3-total-cache-and-wp-super-cache-vulnerability-being-targeted-in-the-wild.html).
456 | * **Deutsch**
457 | * Erkennung und Ausfilterung von Spam-Kommentaren, die versuchen, [Sicherheitslücken von W3 Total Cache und WP Super Cache](http://blog.sucuri.net/2013/05/w3-total-cache-and-wp-super-cache-vulnerability-being-targeted-in-the-wild.html) auszunutzen. [Ausführliche Informationen](https://antispambee.pluginkollektiv.org/de/news/2013/antispam-bee-nun-auch-als-antimalware-plugin/).
458 |
459 | ### 2.5.4 ###
460 | * **English**
461 | * Jubilee edition
462 | * New mascot for Antispam Bee
463 | * Advanced Scanning on IP, URL and e-mail address of incoming comments in local blog spam database
464 | * **Deutsch**
465 | * Jubiläumsausgabe: [Details zum Update](https://plus.googlehttps://antispambee.pluginkollektiv.org/de/news/2013/jubilaeumsausgabe-antispam-bee-2-5-4/)
466 | * Neues Maskottchen für Antispam Bee
467 | * Erweiterte Prüfung eingehender Kommentare in lokaler Blog-Spamdatenbank auf IP, URL und E-Mail-Adresse
468 |
469 | ### 2.5.3 ###
470 | * **English**
471 | * Optimization of regular expression
472 | * **Deutsch**
473 | * Optimierung des Regulären Ausdrucks
474 |
475 | ### 2.5.2 ###
476 | * **English**
477 | * New: Use of regular expressions with predefined and own identification patterns
478 | * Change the filter order
479 | * Improvements to the language file
480 | * **Deutsch**
481 | * Neu: [Reguläre Ausdrücke anwenden](hhttps://antispambee.pluginkollektiv.org/de/dokumentation#regex) mit vordefinierten und eigenen Erkennungsmustern
482 | * Änderung der Filter-Reihenfolge
483 | * Verbesserungen an der Sprachdatei
484 |
485 | ### 2.5.1 ###
486 | * **English**
487 | * Treat BBCode as spam
488 | * IP anonymization in the country evaluation
489 | * More transparency by added Privacy Policy
490 | * PHP 5.2.4 as a requirement (is also the prerequisite for WP 3.4)
491 | * **Deutsch**
492 | * [BBCode im Kommentar als Spamgrund](hhttps://antispambee.pluginkollektiv.org/de/dokumentation#bbcode)
493 | * IP-Anonymisierung bei der Länderprüfung
494 | * [Mehr Transparenz](https://antispambee.pluginkollektiv.org/de/news/2012/datenschutz-update/) durch hinzugefügte Datenschutzhinweise
495 | * PHP 5.2.4 als Voraussetzung (ist zugleich die Voraussetzung für WP 3.4)
496 |
497 | ### 2.5.0 ###
498 | * **English**
499 | * [Edition 2012](https://antispambee.pluginkollektiv.org/news/2012/edition-2012/)
500 | * **Deutsch**
501 | * [Edition 2012](https://antispambee.pluginkollektiv.org/de/news/2012/edition-2012/)
502 |
503 | ### 2.4.6 ###
504 | * **English**
505 | * Russian translation
506 | * Change the secret string
507 | * **Deutsch**
508 | * Russische Übersetzung
509 | * Veränderung der Secret-Zeichenfolge
510 |
511 | ### 2.4.5 ###
512 | * **English**
513 | * Revised layout settings
514 | * Deletion of Project Honey Pot
515 | * TornevallNET as new DNSBL service
516 | * WordPress 3.4 as a minimum requirement
517 | * WordPress 3.5 support
518 | * Recast of the online manual
519 | * **Deutsch**
520 | * Überarbeitetes Layout der Einstellungen
521 | * Streichung von Project Honey Pot
522 | * TornevallNET als neuer DNSBL-Dienst
523 | * WordPress 3.4 als Mindestvoraussetzung
524 | * WordPress 3.5 Unterstützung
525 | * Neufassung des Online-Handbuchs
526 |
527 | ### 2.4.4 ###
528 | * **English**
529 | * Technical and visual support for WordPress 3.5
530 | * Modification of the file structure: from `xyz.dev.css` to `xyz.min.css`
531 | * Retina screenshot
532 | * **Deutsch**
533 | * Technische und optische Unterstützung für WordPress 3.5
534 | * Änderung der Dateistruktur: von `xyz.dev.css` zu `xyz.min.css`
535 | * Retina Bildschirmfoto
536 |
537 | ### 2.4.3 ###
538 | * **English**
539 | * Check for basic requirements
540 | * Remove the sidebar plugin icon
541 | * Set the Google API calls to SSL
542 | * Compatibility with WordPress 3.4
543 | * Add retina plugin icon on options
544 | * Depending on WordPress settings: anonymous comments allowed
545 | * **Deutsch**
546 | * Mindestvoraussetzungen werden nun überprüft
547 | * Entfernung des Plugin Icons in der Sidebar
548 | * Google API Aufrufe auf SSL umgestellt
549 | * Kompatibilität mit WordPress 3.4
550 | * Retina Plugin Icon in den Einstellungen hinzugefügt
551 | * In Abhängigkeit zu den Wordpress-Einstellungen: anonyme Kommentare erlauben
552 |
553 | ### 2.4.2 ###
554 | * **English**
555 | * New geo ip location service (without the api key)
556 | * Code cleanup: Replacement of `@` characters by a function
557 | * JS-Fallback for missing jQuery UI
558 | * **Deutsch**
559 | * Neuer IP-Geolocation-Dienst (ohne api key)
560 | * Quelltext aufgeräumt: Austausch von `@` Zeichen durch eine Funktion
561 | * S-Fallback für fehlende jQuery UI
562 |
563 | ### 2.4.1 ###
564 | * **English**
565 | * Add russian translation
566 | * Fix for the textarea replace
567 | * Detect and hide admin notices
568 | * **Deutsch**
569 | * Russian Übersetzung hinzugefügt
570 | * Fehlerbehebung bei dem ersetzten Textfeld
571 | * Erkennen und verstecken von Admin-Mitteilungen
572 |
573 | ### 2.4 ###
574 | * **English**
575 | * Support for IPv6
576 | * Source code revision
577 | * Delete spam by reason
578 | * Changing the user interface
579 | * Requirements: PHP 5.1.2 and WordPress 3.3
580 | * **Deutsch**
581 | * Unterstützung für IPv6
582 | * Quellcode Überarbeitung
583 | * Spam mit Begründung löschen
584 | * Änderung der Benutzeroberfläche
585 | * Voraussetzungen: PHP 5.1.2 und WordPress 3.3
586 |
587 | ### 2.3 ###
588 | * **English**
589 | * Xmas Edition
590 | * **Deutsch**
591 | * Weihnachtsausgabe
592 |
593 | ### 2.2 ###
594 | * **English**
595 | * Interactive Dashboard Stats
596 | * **Deutsch**
597 | * Interaktive Dashboard Statistik
598 |
599 | ### 2.1 ###
600 | * **English**
601 | * Remove Google Translate API support
602 | * **Deutsch**
603 | * Google Translate API Unterstützung entfernt
604 |
605 | ### 2.0 ###
606 | * **English**
607 | * Allow comments only in certain language (English/German)
608 | * Consider comments which are already marked as spam
609 | * Dashboard Stats: Change from canvas to image format
610 | * System requirements: WordPress 2.8
611 | * Removal of the migration script
612 | * Increase plugin security
613 | * **Deutsch**
614 | * Kommentare nur in bestimmten Sprachen erlauben (Englisch/Deutsch)
615 | * Das Plugin kann nun Kommentare berücksichtigen, die bereits als Spam markiert wurden
616 | * Dashboard-Statistik: Wechsel von canvas zu einem Bildformat
617 | * Systemvoraussetzungen: WordPress 2.8
618 | * Entfernung des Migrationsscriptes
619 | * Plugin Sicherheit verbessert
620 |
621 | ### 1.9 ###
622 | * **English**
623 | * Dashboard History Stats (HTML5 Canvas)
624 | * **Deutsch**
625 | * Dashboard Statistiken (HTML5 Canvas)
626 |
627 | ### 1.8 ###
628 | * **English**
629 | * Support for the new IPInfoDB API (including API Key)
630 | * **Deutsch**
631 | * Unterstützung der neuen IPInfoDB API (einschließlich API-Key)
632 |
633 | ### 1.7 ###
634 | * **English**
635 | * Black and whitelisting for specific countries
636 | * "Project Honey Pot" as a optional spammer source
637 | * Spam reason in the notification email
638 | * Visual refresh of the notification email
639 | * Advanced GUI changes + Fold-out options
640 | * **Deutsch**
641 | * Schwarze und weiße Liste für bestimmte Länder
642 | * "Project Honey Pot" als optionale Spammer-Quelle
643 | * Spam-Begründung in der E-Mail-Benachrichtigung
644 | * Visuelle Überarbeitung der E-Mail-Benachrichtigung
645 | * Erweiterte Benutzeroberflächenanpassungen + ausklappbare Einstellungen
646 |
647 | ### 1.6 ###
648 | * **English**
649 | * Support for WordPress 3.0
650 | * System requirements: WordPress 2.7
651 | * Code optimization
652 | * **Deutsch**
653 | * Unterstützung für WordPress 3.0
654 | * Systemvoraussetzungen: WordPress 2.7
655 | * Quelltext optimiert
656 |
657 | ### 1.5 ###
658 | * **English**
659 | * Compatibility with WPtouch
660 | * Add support for do_action
661 | * Translation to Portuguese of Brazil
662 | * **Deutsch**
663 | * Kompatibilität mit WPtouch
664 | * Unterstützung für do_action hinzugefügt
665 | * Übersetzung auf brasilianisches Portugiesisch
666 |
667 | ### 1.4 ###
668 | * **English**
669 | * Enable stricter inspection for incomming comments
670 | * Do not check if the author has already commented and approved
671 | * **Deutsch**
672 | * strengere Kontrolle für eingehende Kommentare aktiviert
673 | * Nicht auf Spam überprüfen, wenn der Autor bereits kommentiert hat und freigegeben wurde
674 |
675 | ### 1.3 ###
676 | * **English**
677 | * New code structure
678 | * Email notifications about new spam comments
679 | * Novel Algorithm: Advanced spam checking
680 | * **Deutsch**
681 | * Neue Quelltextstruktur
682 | * E-Mail-Benachrichtigungen über neue Spam-Kommentare
683 | * Neuartiger Algorithmus: Erweiterte Spamprüfung
684 |
685 | ### 1.2 ###
686 | * **English**
687 | * Antispam Bee spam counter on dashboard
688 | * **Deutsch**
689 | * Antispam Bee Spam-Zähler auf dem Dashboard
690 |
691 | ### 1.1 ###
692 | * **English**
693 | * Adds support for WordPress new changelog readme.txt standard
694 | * Various changes for more speed, usability and security
695 | * **Deutsch**
696 | * Unterstützung des neuen readme.txt Standards für das Änderungsprotokoll hinzugefügt
697 | * Verschiedene Änderungen für mehr Geschwindigkeit, Benutzerfreundlichkeit und Sicherheit
698 |
699 | ### 1.0 ###
700 | * **English**
701 | * Adds WordPress 2.8 support
702 | * **Deutsch**
703 | * WordPress 2.8 Unterstützung hinzugefügt
704 |
705 | ### 0.9 ###
706 | * **English**
707 | * Mark as spam only comments or only pings
708 | * **Deutsch**
709 | * nur Kommentare oder nur Pings als Spam markieren
710 |
711 | ### 0.8 ###
712 | * **English**
713 | * Optical adjustments of the settings page
714 | * Translation for Simplified Chinese, Spanish and Catalan
715 | * **Deutsch**
716 | * Optische Anpassungen der Einstellungsseite
717 | * Übersetzung für vereinfachtes Chinesisch, Spanisch und Katalanisch
718 |
719 | ### 0.7 ###
720 | * **English**
721 | * Spam folder cleanup after X days
722 | * Optional hide the "MARKED AS SPAM" note
723 | * Language support for Italian and Turkish
724 | * **Deutsch**
725 | * Spam-Ordner Bereinigung nach n Tagen
726 | * Optionales verstecken des "als Spam markiert" Hinweises
727 | * Übersetzungen für Italienisch und Türkisch
728 |
729 | ### 0.6 ###
730 | * **English**
731 | * Language support for English, German, Russian
732 | * **Deutsch**
733 | * Übersetzungen für Englisch, Deutsch und Russisch
734 |
735 | ### 0.5 ###
736 | * **English**
737 | * Workaround for empty comments
738 | * **Deutsch**
739 | * Problembehebung für leere Kommentare
740 |
741 | ### 0.4 ###
742 | * **English**
743 | * Option for trackback and pingback protection
744 | * **Deutsch**
745 | * Einstellung für den Trackback- und Pingback-Schutz
746 |
747 | ### 0.3 ###
748 | * **English**
749 | * Trackback and Pingback spam protection
750 | * **Deutsch**
751 | * Trackback und Pingback Spam-Schutz
752 |
--------------------------------------------------------------------------------
/antispam_bee.php:
--------------------------------------------------------------------------------
1 | 0,
374 | ),
375 | '',
376 | 'no'
377 | );
378 |
379 | if ( self::get_option( 'cronjob_enable' ) ) {
380 | self::init_scheduled_hook();
381 | }
382 | }
383 |
384 |
385 | /**
386 | * Action to deactivate the plugin
387 | *
388 | * @since 0.1
389 | * @since 2.4
390 | */
391 | public static function deactivate() {
392 | self::clear_scheduled_hook();
393 | }
394 |
395 |
396 | /**
397 | * Action deleting the plugin
398 | *
399 | * @since 2.4
400 | */
401 | public static function uninstall() {
402 | if ( ! self::get_option( 'delete_data_on_uninstall' ) ) {
403 | return;
404 | }
405 | global $wpdb;
406 |
407 | delete_option( 'antispam_bee' );
408 | delete_option( 'antispambee_db_version' );
409 | $wpdb->query( 'OPTIMIZE TABLE `' . $wpdb->options . '`' );
410 |
411 | //phpcs:disable WordPress.DB.PreparedSQL.NotPrepared
412 | $sql = 'delete from `' . $wpdb->commentmeta . '` where `meta_key` IN ("antispam_bee_iphash", "antispam_bee_reason")';
413 | $wpdb->query( $sql );
414 | //phpcs:enable WordPress.DB.PreparedSQL.NotPrepared
415 | }
416 |
417 |
418 |
419 | /*
420 | * ############################
421 | * ######## INTERNAL ########
422 | * ############################
423 | */
424 |
425 | /**
426 | * Initialization of the internal variables
427 | *
428 | * @since 2.4
429 | * @since 2.7.0
430 | * @since 2.10.0 Change renamed country option names in options array
431 | */
432 | private static function _init_internal_vars() {
433 | self::$_base = plugin_basename( __FILE__ );
434 |
435 | $salt = defined( 'NONCE_SALT' ) ? NONCE_SALT : ABSPATH;
436 | self::$_salt = substr( sha1( $salt ), 0, 10 );
437 |
438 | self::$defaults = array(
439 | 'options' => array(
440 | 'regexp_check' => 1,
441 | 'spam_ip' => 1,
442 | 'already_commented' => 1,
443 | 'gravatar_check' => 0,
444 | 'time_check' => 0,
445 | 'ignore_pings' => 0,
446 |
447 | 'dashboard_chart' => 0,
448 | 'dashboard_count' => 0,
449 |
450 | 'country_code' => 0,
451 | 'country_denied' => '',
452 | 'country_allowed' => '',
453 |
454 | 'translate_api' => 0,
455 | 'translate_lang' => array(),
456 |
457 | 'bbcode_check' => 1,
458 |
459 | 'flag_spam' => 1,
460 | 'email_notify' => 0,
461 | 'no_notice' => 0,
462 | 'cronjob_enable' => 0,
463 | 'cronjob_interval' => 0,
464 |
465 | 'ignore_filter' => 0,
466 | 'ignore_type' => 0,
467 |
468 | 'reasons_enable' => 0,
469 | 'ignore_reasons' => array(),
470 |
471 | 'delete_data_on_uninstall' => 1,
472 | ),
473 | );
474 | }
475 |
476 | /**
477 | * Adds spam reason labels to the `$defaults` array.
478 | *
479 | * That is done in an extra method instead of `_init_internal_vars`
480 | * so that the translations are loaded before.
481 | *
482 | * @since 2.11.2
483 | */
484 | public static function add_reasons_to_defaults() {
485 | self::$defaults['reasons'] = array(
486 | 'css' => esc_attr__( 'Honeypot', 'antispam-bee' ),
487 | 'time' => esc_attr__( 'Comment time', 'antispam-bee' ),
488 | 'empty' => esc_attr__( 'Empty Data', 'antispam-bee' ),
489 | 'localdb' => esc_attr__( 'Local DB Spam', 'antispam-bee' ),
490 | 'server' => esc_attr__( 'Fake IP', 'antispam-bee' ),
491 | 'country' => esc_attr__( 'Country Check', 'antispam-bee' ),
492 | 'bbcode' => esc_attr__( 'BBCode', 'antispam-bee' ),
493 | 'lang' => esc_attr__( 'Comment Language', 'antispam-bee' ),
494 | 'regexp' => esc_attr__( 'Regular Expression', 'antispam-bee' ),
495 | 'title_is_name' => esc_attr__( 'Identical Post title and blog title', 'antispam-bee' ),
496 | 'manually' => esc_attr__( 'Manually', 'antispam-bee' ),
497 | );
498 | }
499 |
500 | /**
501 | * Check and return an array key
502 | *
503 | * @since 2.4.2
504 | * @since 2.10.0 Only return `null` if option does not exist.
505 | *
506 | * @param array $array Array with values.
507 | * @param string $key Name of the key.
508 | * @return mixed Value of the requested key.
509 | */
510 | public static function get_key( $array, $key ) {
511 | if ( empty( $array ) || empty( $key ) || ! isset( $array[ $key ] ) ) {
512 | return null;
513 | }
514 |
515 | return $array[ $key ];
516 | }
517 |
518 | /**
519 | * Check if comment is a ping (pingback, trackback or something similar)
520 | *
521 | * @since 2.10.0
522 | *
523 | * @param array $comment Treated commentary data.
524 | * @return boolean `true` if ping and `false` if classic comment
525 | */
526 | public static function is_ping( $comment ) {
527 | $types = array( 'pingback', 'trackback', 'pings' );
528 | $is_ping = false;
529 |
530 | if ( in_array( self::get_key( $comment, 'comment_type' ), $types, true ) ) {
531 | $is_ping = true;
532 | }
533 |
534 | return apply_filters( 'antispam_bee_is_ping', $is_ping, $comment );
535 | }
536 |
537 | /**
538 | * Localization of the admin pages
539 | *
540 | * @since 0.1
541 | * @since 2.4
542 | *
543 | * @param string $page Mark the page.
544 | * @return boolean True on success.
545 | */
546 | private static function _current_page( $page ) {
547 | // phpcs:disable WordPress.CSRF.NonceVerification.NoNonceVerification
548 | switch ( $page ) {
549 | case 'dashboard':
550 | return ( empty( $GLOBALS['pagenow'] ) || ( ! empty( $GLOBALS['pagenow'] ) && 'index.php' === $GLOBALS['pagenow'] ) );
551 |
552 | case 'options':
553 | return ( ! empty( $_GET['page'] ) && 'antispam_bee' === $_GET['page'] );
554 |
555 | case 'plugins':
556 | return ( ! empty( $GLOBALS['pagenow'] ) && 'plugins.php' === $GLOBALS['pagenow'] );
557 |
558 | case 'admin-post':
559 | return ( ! empty( $GLOBALS['pagenow'] ) && 'admin-post.php' === $GLOBALS['pagenow'] );
560 |
561 | case 'edit-comments':
562 | return ( ! empty( $GLOBALS['pagenow'] ) && 'edit-comments.php' === $GLOBALS['pagenow'] );
563 |
564 | default:
565 | return false;
566 | }
567 | // phpcs:enable WordPress.CSRF.NonceVerification.NoNonceVerification
568 | }
569 |
570 |
571 | /**
572 | * Add the link to the settings
573 | *
574 | * @since 1.1
575 | *
576 | * @param array $data The action link array.
577 | * @return array $data The action link array.
578 | */
579 | public static function init_action_links( $data ) {
580 | if ( ! current_user_can( 'manage_options' ) ) {
581 | return $data;
582 | }
583 |
584 | return array_merge(
585 | $data,
586 | array(
587 | sprintf(
588 | '%s',
589 | add_query_arg(
590 | array(
591 | 'page' => 'antispam_bee',
592 | ),
593 | admin_url( 'options-general.php' )
594 | ),
595 | esc_attr__( 'Settings', 'antispam-bee' )
596 | ),
597 | )
598 | );
599 | }
600 |
601 | /**
602 | * Meta links of the plugin
603 | *
604 | * @since 0.1
605 | * @since 2.6.2
606 | *
607 | * @param array $input Existing links.
608 | * @param string $file Current page.
609 | * @return array $data Modified links.
610 | */
611 | public static function init_row_meta( $input, $file ) {
612 | if ( $file !== self::$_base ) {
613 | return $input;
614 | }
615 |
616 | return array_merge(
617 | $input,
618 | array(
619 | '' . esc_html__( 'Donate', 'antispam-bee' ) . '',
620 | '' . esc_html__( 'Support', 'antispam-bee' ) . '',
621 | )
622 | );
623 | }
624 |
625 | /*
626 | * ############################
627 | * ####### RESOURCES ########
628 | * ############################
629 | */
630 |
631 | /**
632 | * Registration of resources (CSS & JS)
633 | *
634 | * @since 1.6
635 | * @since 2.4.5
636 | */
637 | public static function init_plugin_sources() {
638 | $plugin = get_plugin_data( __FILE__ );
639 |
640 | wp_register_script(
641 | 'ab_script',
642 | plugins_url( 'js/scripts.min.js', __FILE__ ),
643 | array( 'jquery' ),
644 | $plugin['Version']
645 | );
646 |
647 | wp_register_style(
648 | 'ab_style',
649 | plugins_url( 'css/styles.min.css', __FILE__ ),
650 | array( 'dashicons' ),
651 | $plugin['Version']
652 | );
653 | }
654 |
655 |
656 | /**
657 | * Initialization of the option page
658 | *
659 | * @since 0.1
660 | * @since 2.4.3
661 | */
662 | public static function add_sidebar_menu() {
663 | $page = add_options_page(
664 | 'Antispam Bee',
665 | 'Antispam Bee',
666 | 'manage_options',
667 | 'antispam_bee',
668 | array(
669 | 'Antispam_Bee_GUI',
670 | 'options_page',
671 | )
672 | );
673 |
674 | add_action(
675 | 'admin_print_scripts-' . $page,
676 | array(
677 | __CLASS__,
678 | 'add_options_script',
679 | )
680 | );
681 |
682 | add_action(
683 | 'admin_print_styles-' . $page,
684 | array(
685 | __CLASS__,
686 | 'add_options_style',
687 | )
688 | );
689 |
690 | add_action(
691 | 'load-' . $page,
692 | array(
693 | __CLASS__,
694 | 'init_options_page',
695 | )
696 | );
697 | }
698 |
699 |
700 | /**
701 | * Initialization of JavaScript
702 | *
703 | * @since 1.6
704 | * @since 2.4
705 | */
706 | public static function add_options_script() {
707 | wp_enqueue_script( 'ab_script' );
708 | }
709 |
710 |
711 | /**
712 | * Initialization of Stylesheets
713 | *
714 | * @since 1.6
715 | * @since 2.4
716 | */
717 | public static function add_options_style() {
718 | wp_enqueue_style( 'ab_style' );
719 | }
720 |
721 |
722 | /**
723 | * Integration of the GUI
724 | *
725 | * @since 2.4
726 | */
727 | public static function init_options_page() {
728 | require_once dirname( __FILE__ ) . '/inc/gui.class.php';
729 | }
730 |
731 |
732 |
733 | /*
734 | * ############################
735 | * ####### DASHBOARD ########
736 | * ############################
737 | */
738 |
739 | /**
740 | * Display the spam counter on the dashboard
741 | *
742 | * @since 0.1
743 | * @since 2.6.5
744 | *
745 | * @param array $items Initial array with dashboard items.
746 | * @return array $items Merged array with dashboard items.
747 | */
748 | public static function add_dashboard_count( $items = array() ) {
749 | if ( ! current_user_can( 'manage_options' ) || ! self::get_option( 'dashboard_count' ) ) {
750 | return $items;
751 | }
752 |
753 | echo '';
754 |
755 | $items[] = '' . esc_html(
756 | sprintf(
757 | // translators: The number of spam comments Antispam Bee blocked so far.
758 | _n(
759 | '%s Blocked',
760 | '%s Blocked',
761 | self::_get_spam_count(),
762 | 'antispam-bee'
763 | ),
764 | self::_get_spam_count()
765 | )
766 | ) . '';
767 |
768 | return $items;
769 | }
770 |
771 | /**
772 | * Initialize the dashboard chart
773 | *
774 | * @since 1.9
775 | * @since 2.5.6
776 | */
777 | public static function add_dashboard_chart() {
778 | if ( ! current_user_can( 'publish_posts' ) || ! self::get_option( 'dashboard_chart' ) ) {
779 | return;
780 | }
781 |
782 | wp_add_dashboard_widget(
783 | 'ab_widget',
784 | 'Antispam Bee',
785 | array(
786 | __CLASS__,
787 | 'show_spam_chart',
788 | )
789 | );
790 |
791 | add_action(
792 | 'admin_head',
793 | array(
794 | __CLASS__,
795 | 'add_dashboard_style',
796 | )
797 | );
798 | }
799 |
800 | /**
801 | * Print dashboard styles
802 | *
803 | * @since 1.9.0
804 | * @since 2.5.8
805 | */
806 | public static function add_dashboard_style() {
807 | $plugin = get_plugin_data( __FILE__ );
808 |
809 | wp_register_style(
810 | 'ab_chart',
811 | plugins_url( 'css/dashboard.min.css', __FILE__ ),
812 | array(),
813 | $plugin['Version']
814 | );
815 |
816 | wp_print_styles( 'ab_chart' );
817 | }
818 |
819 |
820 | /**
821 | * Print dashboard scripts
822 | *
823 | * @since 1.9.0
824 | * @since 2.5.8
825 | */
826 | public static function add_dashboard_script() {
827 | if ( ! self::get_option( 'daily_stats' ) ) {
828 | return;
829 | }
830 |
831 | $plugin = get_plugin_data( __FILE__ );
832 |
833 | wp_enqueue_script(
834 | 'raphael',
835 | plugins_url( 'js/raphael.min.js', __FILE__ ),
836 | array(),
837 | '2.1.0',
838 | true
839 | );
840 |
841 | wp_enqueue_script(
842 | 'ab-raphael',
843 | plugins_url( 'js/raphael.helper.min.js', __FILE__ ),
844 | array( 'raphael' ),
845 | $plugin['Version'],
846 | true
847 | );
848 |
849 | wp_enqueue_script(
850 | 'ab_chart_js',
851 | plugins_url( 'js/dashboard.min.js', __FILE__ ),
852 | array( 'jquery', 'ab-raphael' ),
853 | $plugin['Version'],
854 | true
855 | );
856 | }
857 |
858 | /**
859 | * Print dashboard html
860 | *
861 | * @since 1.9.0
862 | * @since 2.5.8
863 | */
864 | public static function show_spam_chart() {
865 | $items = (array) self::get_option( 'daily_stats' );
866 |
867 | if ( empty( $items ) ) {
868 | printf(
869 | '