PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 5.0
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v5.0
6.35 6.34 6.33.1 6.33 6.32.1 6.32 6.31 6.25 6.25.1 6.26 6.26.1 6.27 6.28 6.29 6.3 6.3.1 6.3.2 6.30 6.4 6.4.1 6.4.2 6.5 6.5.1 6.5.2 6.5.3 All 141 releases
← All changes | classes/models/FrmHoneypot.php +24 -282 6.265.0 View file →
@@ -5,26 +5,8 @@
5 5
6 6 class FrmHoneypot extends FrmValidate {
7 7
8 8 /**
9 - * Track the printed selectors so we do not print the same CSS twice.
10 - *
11 - * @since 6.22
12 - *
13 - * @var array
14 - */
15 - private static $printed_honeypot_selectors = array();
16 -
17 - /**
18 - * Option type.
19 - *
20 - * @since 6.21
21 - *
22 - * @var string
23 - */
24 - protected $option_type = 'global';
25 -
26 - /**
27 9 * @return string
28 10 */
29 11 protected function get_option_key() {
30 12 return 'honeypot';
@@ -32,16 +14,8 @@
32 14
33 15 /**
34 16 * @return bool
35 17 */
36 - private static function is_enabled() {
37 - $frm_settings = FrmAppHelper::get_settings();
38 - return $frm_settings->honeypot;
39 - }
40 -
41 - /**
42 - * @return bool
43 - */
44 18 public function validate() {
45 19 if ( ! $this->is_option_on() || ! $this->check_honeypot_filter() ) {
46 20 // never flag as honeypot spam if disabled.
47 21 return true;
@@ -49,49 +23,19 @@
49 23 return ! $this->is_honeypot_spam();
50 24 }
51 25
52 26 /**
53 - * @return bool
27 + * @return boolean
54 28 */
55 29 private function is_honeypot_spam() {
56 - $is_honeypot_spam = $this->is_legacy_honeypot_spam();
57 -
58 - if ( ! $is_honeypot_spam ) {
59 -
60 - $field_id = $this->get_honeypot_field_id();
61 -
62 - if ( ! $field_id ) {
63 - return false;
64 - }
65 -
66 - $value = $this->get_honeypot_field_value( $field_id );
67 - $is_honeypot_spam = '' !== $value;
68 - }
69 -
70 - $atts = array(
71 - 'form' => $this->get_form(),
72 - );
73 -
74 - /**
75 - * Filters the honeypot spam check.
76 - *
77 - * @param bool $is_honeypot_spam Set to `true` if is spam.
78 - * @param array $atts Contains `form` and `fields`.
79 - */
30 + $honeypot_value = FrmAppHelper::get_param( 'frm_verify', '', 'get', 'sanitize_text_field' );
31 + $is_honeypot_spam = $honeypot_value !== '';
32 + $form = $this->get_form();
33 + $atts = compact( 'form' );
80 34 return apply_filters( 'frm_process_honeypot', $is_honeypot_spam, $atts );
81 35 }
82 36
83 37 /**
84 - * Check the old frm_verify key. We'll continue to consider any entry with an frm_verify value as spam.
85 - *
86 - * @return bool
87 - */
88 - private function is_legacy_honeypot_spam() {
89 - $legacy_honeypot_value = FrmAppHelper::get_param( 'frm_verify', '', 'get', 'sanitize_text_field' );
90 - return '' !== $legacy_honeypot_value;
91 - }
92 -
93 - /**
94 38 * @return mixed either true, or false.
95 39 */
96 40 private function check_honeypot_filter() {
97 41 $form = $this->get_form();
@@ -98,123 +42,27 @@
98 42 return apply_filters( 'frm_run_honeypot', true, compact( 'form' ) );
99 43 }
100 44
101 45 /**
102 - * @param int $form_id Form ID.
103 - *
104 - * @return void
46 + * @return string
105 47 */
106 - public static function maybe_render_field( $form_id ) {
107 - $honeypot = new self( $form_id );
108 -
109 - if ( ! $honeypot->should_render_field() ) {
110 - return;
111 - }
112 -
113 - $max_field_id = FrmDb::get_var(
114 - 'frm_fields',
115 - array(),
116 - 'id',
117 - array(
118 - 'order_by' => 'id DESC',
119 - )
120 - );
121 -
122 - global $frm_vars;
123 - $offset = isset( $frm_vars['honeypot_selectors'] ) ? count( $frm_vars['honeypot_selectors'] ) + 1 : 1;
124 - $honeypot_field_id = $max_field_id ? $max_field_id + $offset : $offset;
125 -
126 - $class = class_exists( 'FrmProFormState' ) ? 'FrmProFormState' : 'FrmFormState';
127 - $class::set_initial_value( 'honeypot_field_id', $honeypot_field_id );
128 -
129 - $honeypot->render_field( $honeypot_field_id );
130 - self::maybe_print_honeypot_css();
48 + private function check_honeypot_setting() {
49 + $form = $this->get_form();
50 + $key = $this->get_option_key();
51 + return $form->options[ $key ];
131 52 }
132 53
133 54 /**
134 - * Maybe print honeypot JS.
135 - *
136 - * @since 6.21
137 - *
138 - * @return void
55 + * @param int $form_id
139 56 */
140 - public static function maybe_print_honeypot_js() {
141 - if ( FrmAppHelper::is_admin() || ! self::is_enabled() ) {
142 - return;
57 + public static function maybe_render_field( $form_id ) {
58 + $honeypot = new self( $form_id );
59 + if ( $honeypot->should_render_field() ) {
60 + $honeypot->render_field();
143 61 }
144 -
145 - $css = self::get_honeypot_field_css();
146 -
147 - if ( ! $css ) {
148 - return;
149 - }
150 -
151 - // There must be no empty lines inside the script. Otherwise, wpautop adds <p> tags which break script execution.
152 - printf(
153 - "<script>
154 - ( function() {
155 - const style = document.createElement( 'style' );
156 - style.appendChild( document.createTextNode( '%s' ) );
157 - document.head.appendChild( style );
158 - document.currentScript?.remove();
159 - } )();
160 - </script>",
161 - esc_js( $css )
162 - );
163 -
164 - global $frm_vars;
165 - self::$printed_honeypot_selectors = $frm_vars['honeypot_selectors'];
166 62 }
167 63
168 64 /**
169 - * Maybe print honeypot CSS in case JS doesn't run.
170 - *
171 - * @since 6.21
172 - *
173 - * @return void
174 - */
175 - public static function maybe_print_honeypot_css() {
176 - // Print the CSS if form is loaded by API.
177 - if ( ! FrmFormsHelper::form_is_loaded_by_api() ) {
178 - return;
179 - }
180 -
181 - $css = self::get_honeypot_field_css();
182 -
183 - if ( $css ) {
184 - echo '<style>' . esc_html( $css ) . '</style>';
185 - }
186 - }
187 -
188 - /**
189 - * Gets honeypot field CSS.
190 - *
191 - * @return string
192 - */
193 - private static function get_honeypot_field_css() {
194 - global $frm_vars;
195 -
196 - if ( empty( $frm_vars['honeypot_selectors'] ) ) {
197 - return '';
198 - }
199 -
200 - $selectors = $frm_vars['honeypot_selectors'];
201 -
202 - if ( self::$printed_honeypot_selectors ) {
203 - $selectors = array_diff( $selectors, self::$printed_honeypot_selectors );
204 -
205 - if ( ! $selectors ) {
206 - return '';
207 - }
208 - }
209 -
210 - return sprintf(
211 - '%s {visibility:hidden;overflow:hidden;width:0;height:0;position:absolute;}',
212 - implode( ',', $selectors )
213 - );
214 - }
215 -
216 - /**
217 65 * @return bool
218 66 */
219 67 public function should_render_field() {
220 68 return $this->is_option_on() && $this->check_honeypot_filter();
@@ -219,123 +67,17 @@
219 67 public function should_render_field() {
220 68 return $this->is_option_on() && $this->check_honeypot_filter();
221 69 }
222 70
223 - /**
224 - * @param int $honeypot_field_id
225 - *
226 - * @return void
227 - */
228 - public function render_field( $honeypot_field_id = 0 ) {
229 - if ( ! $honeypot_field_id ) {
230 - return;
231 - }
232 -
233 - $field_id = $honeypot_field_id;
234 - $field_key = $this->get_honeypot_field_key();
235 - $input_attrs = array(
236 - 'id' => 'field_' . $field_key,
237 - 'type' => 'text',
238 - 'class' => 'frm_form_field form-field frm_verify',
239 - 'name' => 'item_meta[' . $field_id . ']',
240 - 'value' => $this->get_honeypot_field_value( $field_id ),
241 - );
242 -
243 - $container_id = 'frm_field_' . $field_id . '_container';
244 - $this->track_html_id( $container_id );
71 + public function render_field() {
72 + $honeypot = $this->check_honeypot_setting();
73 + $form = $this->get_form();
245 74 ?>
246 - <div id="<?php echo esc_attr( $container_id ); ?>">
247 - <label for="<?php echo esc_attr( $input_attrs['id'] ); ?>" <?php FrmFormsHelper::maybe_hide_inline(); ?>>
248 - <?php esc_html_e( 'If you are human, leave this field blank.', 'formidable' ); ?>
249 - </label>
250 - <input <?php FrmAppHelper::array_to_html_params( $input_attrs, true ); ?> <?php FrmFormsHelper::maybe_hide_inline(); ?> />
251 - </div>
75 + <div class="frm_verify" <?php echo in_array( $honeypot, array( true, 'strict' ), true ) ? '' : 'aria-hidden="true"'; ?>>
76 + <label for="frm_email_<?php echo esc_attr( $form->id ); ?>">
77 + <?php esc_html_e( 'If you are human, leave this field blank.', 'formidable' ); ?>
78 + </label>
79 + <input type="<?php echo esc_attr( 'strict' === $honeypot ? 'email' : 'text' ); ?>" class="frm_verify" id="frm_email_<?php echo esc_attr( $form->id ); ?>" name="frm_verify" value="<?php echo esc_attr( FrmAppHelper::get_param( 'frm_verify', '', 'get', 'wp_kses_post' ) ); ?>" <?php FrmFormsHelper::maybe_hide_inline(); ?> />
80 + </div>
252 81 <?php
253 - }
254 -
255 - /**
256 - * @param string $html_id
257 - *
258 - * @return void
259 - */
260 - private function track_html_id( $html_id ) {
261 - global $frm_vars;
262 -
263 - if ( ! isset( $frm_vars['honeypot_selectors'] ) ) {
264 - $frm_vars['honeypot_selectors'] = array();
265 - }
266 -
267 - $frm_vars['honeypot_selectors'][] = '#' . $html_id;
268 - }
269 -
270 - /**
271 - * @return int
272 - */
273 - private function get_honeypot_field_id() {
274 - $class = class_exists( 'FrmProFormState' ) ? 'FrmProFormState' : 'FrmFormState';
275 - $honeypot_field_id = $class::get_from_request( 'honeypot_field_id', 0 );
276 - return $honeypot_field_id;
277 - }
278 -
279 - /**
280 - * @return string
281 - */
282 - private function get_honeypot_field_key() {
283 - return FrmAppHelper::generate_new_key( 5 );
284 - }
285 -
286 - /**
287 - * Gets honeypot field value.
288 - *
289 - * @param string $field_id Field ID.
290 - *
291 - * @return string
292 - */
293 - private function get_honeypot_field_value( $field_id ) {
294 - $item_meta = FrmAppHelper::get_simple_request(
295 - array(
296 - 'param' => 'item_meta',
297 - 'default' => array(),
298 - 'type' => 'post',
299 - )
300 - );
301 -
302 - if ( ! $item_meta || ! is_array( $item_meta ) ) {
303 - return '';
304 - }
305 -
306 - return $item_meta[ $field_id ] ?? '';
307 - }
308 -
309 - /**
310 - * Generate a random class name for our honeypot so it is less easy to detect.
311 - *
312 - * @return string The generated class name.
313 - */
314 - public static function generate_class_name() {
315 - $class_name = self::get_honeypot_class_name();
316 -
317 - if ( 'frm_verify' !== $class_name ) {
318 - // Re-use the option.
319 - // We can't generate a new class too often or the field may not be hidden.
320 - return $class_name;
321 - }
322 -
323 - $prefix = 'frm__';
324 - $class_name = $prefix . uniqid();
325 - update_option( 'frm_honeypot_class', $class_name );
326 - return $class_name;
327 - }
328 -
329 - /**
330 - * @return string The current class name to use the for Honeypot field.
331 - */
332 - private static function get_honeypot_class_name() {
333 - $option = get_option( 'frm_honeypot_class' );
334 -
335 - if ( ! is_string( $option ) ) {
336 - // For backward compatibility use the old class name.
337 - return 'frm_verify';
338 - }
339 - return $option;
340 82 }
341 83 }