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