-
Notifications
You must be signed in to change notification settings - Fork 3
/
gravityforms-zero-spam.php
244 lines (203 loc) · 7.47 KB
/
gravityforms-zero-spam.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
<?php
/**
* Plugin Name: Gravity Forms Zero Spam
* Plugin URI: https://www.gravitykit.com?utm_source=plugin&utm_campaign=zero-spam&utm_content=pluginuri
* Description: Enhance Gravity Forms to include effective anti-spam measures—without using a CAPTCHA.
* Version: 1.4.5
* Author: GravityKit
* Author URI: https://www.gravitykit.com?utm_source=plugin&utm_campaign=zero-spam&utm_content=authoruri
* License: GPL-2.0+
* License URI: http://www.gnu.org/licenses/gpl-2.0.txt
* Text Domain: gravity-forms-zero-spam
*/
// my mother always said to use things as they're intended or not at all.
if ( ! defined( 'WPINC' ) ) {
die;
}
define( 'GF_ZERO_SPAM_BASENAME', plugin_basename( __FILE__ ) );
// clean up after ourselves.
register_deactivation_hook( __FILE__, array( 'GF_Zero_Spam', 'deactivate' ) );
// Fire it up.
add_action( 'gform_loaded', array( 'GF_Zero_Spam', 'gform_loaded' ) );
class GF_Zero_Spam {
/**
* Instantiate the plugin on Gravity Forms loading.
*/
public static function gform_loaded() {
include_once plugin_dir_path( __FILE__ ) . 'gravityforms-zero-spam-form-settings.php';
new self;
}
/**
* Cleans up plugin options when deactivating.
*
* @return void
*/
public static function deactivate() {
delete_option( 'gf_zero_spam_key' );
if ( class_exists( 'GF_Zero_Spam_AddOn' ) ) {
wp_clear_scheduled_hook( GF_Zero_Spam_AddOn::REPORT_CRON_HOOK_NAME );
}
}
public function __construct() {
add_action( 'gform_register_init_scripts', array( $this, 'add_key_field' ), 1 );
add_filter( 'gform_entry_is_spam', array( $this, 'check_key_field' ), 10, 3 );
add_filter( 'gform_incomplete_submission_pre_save', array( $this, 'add_zero_spam_key_to_entry' ), 10, 3 );
}
/**
* Adds the Zero Spam key to the Gravity Forms entry during form submission.
*
* @see GFFormsModel::filter_draft_submission_pre_save() The source of the hook.
* @since 1.4.1
*
* @param string $submission_json The JSON representation of the form submission.
* @param string $resume_token The resume token for the submission.
* @param array $form The Gravity Forms form object.
*
* @return string The modified JSON representation of the form submission.
*/
public function add_zero_spam_key_to_entry( $submission_json, $resume_token, $form ) {
$submission = json_decode( $submission_json, true );
// Not valid JSON.
if ( ! is_array( $submission ) ) {
return $submission_json;
}
/**
* Something isn't right...bail. This should be set.
* @see GFFormsModel::save_draft_submission()
*/
if ( ! isset( $submission['partial_entry'] ) ) {
return $submission_json;
}
// The Zero Spam key is already set; we don't need to do anything.
if ( isset( $submission['partial_entry']['gf_zero_spam_key'] ) ) {
return $submission_json;
}
// Add the Zero Spam key to the partial entry if it's available in the POST data.
$submission['partial_entry']['gf_zero_spam_key'] = rgpost( 'gf_zero_spam_key' );
return wp_json_encode( $submission );
}
/**
* Retrieves the zero spam key (generating if needed).
*
* @return false|mixed|void
*/
public function get_key() {
$key = get_option( 'gf_zero_spam_key' );
if ( ! $key ) {
$key = wp_generate_password( 64, false, false );
update_option( 'gf_zero_spam_key', $key, false );
}
return $key;
}
/**
* Injects the hidden field and key into the form at submission.
*
* @uses GFFormDisplay::add_init_script() to inject the code into the `gform_post_render` jQuery hook.
*
* @param array $form The Form Object.
*
* @return void
*/
public function add_key_field( $form ) {
/**
* Allows the zero spam key field to be disabled by returning false.
*
* @since 1.4
*
* @param bool $add_key_field Whether to add the key field to the form. Default true.
*/
$add_key_field = apply_filters( 'gf_zero_spam_add_key_field', true );
if ( ! $add_key_field ) {
return;
}
$spam_key = esc_js( $this->get_key() );
$form_id = (int) $form['id'];
if ( version_compare( GFForms::$version, '2.9.0', '>=' ) ) {
$script = <<<EOD
gform.utils.addAsyncFilter('gform/submission/pre_submission', async (data) => {
const input = document.createElement('input');
input.type = 'hidden';
input.name = 'gf_zero_spam_key';
input.value = '{$spam_key}';
input.setAttribute('autocomplete', 'new-password');
data.form.appendChild(input);
return data;
});
EOD;
} else {
$autocomplete = RGFormsModel::is_html5_enabled() ? ".attr( 'autocomplete', 'new-password' )\n\t\t" : '';
$script = <<<EOD
jQuery( "#gform_{$form_id}" ).on( 'submit', function( event ) {
jQuery( '<input>' )
.attr( 'type', 'hidden' )
.attr( 'name', 'gf_zero_spam_key' )
.attr( 'value', '{$spam_key}' )
$autocomplete.appendTo( jQuery( this ) );
} );
EOD;
}
GFFormDisplay::add_init_script( $form_id, 'gf-zero-spam', GFFormDisplay::ON_PAGE_RENDER, $script );
}
/**
* Checks for our zero spam key during validation.
*
* @param bool $is_spam Indicates if the submission has been flagged as spam.
* @param array $form The form currently being processed.
* @param array $entry The entry currently being processed.
*
* @return bool True: it's spam; False: it's not spam!
*/
public function check_key_field( $is_spam = false, $form = array(), $entry = array() ) {
// If the user can edit entries, they're not a spammer. It may be spam, but it's their prerogative.
if ( GFCommon::current_user_can_any( 'gravityforms_edit_entries' ) ) {
return false;
}
$should_check_key_field = ! GFCommon::is_preview();
/**
* Modify whether to process this entry submission for spam.
*
* @since 1.2
*
* @param bool $should_check_key_field Whether the Zero Spam plugin should check for the existence and validity of the key field. Default: true.
* @param array $form The form currently being processed.
* @param array $entry The entry currently being processed.
*/
$should_check_key_field = gf_apply_filters( 'gf_zero_spam_check_key_field', rgar( $form, 'id' ), $should_check_key_field, $form, $entry );
if( false === $should_check_key_field ) {
return $is_spam;
}
$supports_context = method_exists( 'GFFormDisplay', 'get_submission_context' );
if ( $supports_context && GFFormDisplay::get_submission_context() !== 'form-submit' ) {
return $is_spam;
}
// This was not submitted using a web form; created using API.
if ( ! $supports_context && ! did_action( 'gform_pre_submission' ) ) {
return $is_spam;
}
// Created using REST API or GFAPI.
if ( isset( $entry['user_agent'] ) && 'API' === $entry['user_agent'] ) {
return $is_spam;
}
if ( ! isset( $_POST['gf_zero_spam_key'] ) || html_entity_decode( sanitize_text_field( wp_unslash( $_POST['gf_zero_spam_key'] ) ) ) !== $this->get_key() ) {
add_action( 'gform_entry_created', array( $this, 'add_entry_note' ) );
return true;
}
return $is_spam;
}
/**
* Adds a note to the entry once the spam status is set (GF 2.4.18+).
*
* @since 1.1.3
*
* @param array $entry The entry data.
*/
public function add_entry_note( $entry ) {
if ( 'spam' !== rgar( $entry, 'status' ) ) {
return;
}
if ( ! method_exists( 'GFAPI', 'add_note' ) ) {
return;
}
GFAPI::add_note( $entry['id'], 0, 'Zero Spam', __( 'This entry has been marked as spam.', 'gravity-forms-zero-spam' ), 'gf-zero-spam', 'success' );
}
}