PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 3.06.06
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v3.06.06
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/FrmEntryValidate.php +114 -543 6.5.33.06.06 View file →
@@ -1,30 +1,19 @@
1 1 <?php
2 -if ( ! defined( 'ABSPATH' ) ) {
3 - die( 'You are not allowed to call this page directly.' );
4 -}
5 2
6 3 class FrmEntryValidate {
4 + public static function validate( $values, $exclude = false ) {
5 + FrmEntry::sanitize_entry_post( $values );
6 + $errors = array();
7 7
8 - /**
9 - * @param array $values
10 - * @param string[]|bool $exclude
11 - * @return array
12 - */
13 - public static function validate( $values, $exclude = false ) {
14 - FrmEntry::sanitize_entry_post( $values );
15 - $errors = array();
16 -
17 8 if ( ! isset( $values['form_id'] ) || ! isset( $values['item_meta'] ) ) {
18 - $errors['form'] = __( 'There was a problem with your submission. Please try again.', 'formidable' );
9 + $errors['form'] = __( 'There was a problem with your submission. Please try again.', 'formidable' );
10 + return $errors;
11 + }
19 12
20 - return $errors;
21 - }
22 -
23 13 if ( FrmAppHelper::is_admin() && is_user_logged_in() && ( ! isset( $values[ 'frm_submit_entry_' . $values['form_id'] ] ) || ! wp_verify_nonce( $values[ 'frm_submit_entry_' . $values['form_id'] ], 'frm_submit_entry_nonce' ) ) ) {
24 - $frm_settings = FrmAppHelper::get_settings();
25 - $errors['form'] = $frm_settings->admin_permission;
26 - }
14 + $errors['form'] = __( 'You do not have permission to do that', 'formidable' );
15 + }
27 16
28 17 self::set_item_key( $values );
29 18
30 19 $posted_fields = self::get_fields_to_validate( $values, $exclude );
@@ -40,25 +29,10 @@
40 29 if ( empty( $errors ) ) {
41 30 self::spam_check( $exclude, $values, $errors );
42 31 }
43 32
44 - /**
45 - * Allows modifying the validation errors after validating all fields.
46 - *
47 - * @since 5.0.04 Added `posted_fields` to the third param.
48 - *
49 - * @param array $errors Errors data.
50 - * @param array $values Value data of the form.
51 - * @param array $args Custom arguments. Contains `exclude` and `posted_fields`.
52 - */
53 - $filtered_errors = apply_filters( 'frm_validate_entry', $errors, $values, compact( 'exclude', 'posted_fields' ) );
33 + $errors = apply_filters( 'frm_validate_entry', $errors, $values, compact( 'exclude' ) );
54 34
55 - if ( is_array( $filtered_errors ) ) {
56 - $errors = $filtered_errors;
57 - } else {
58 - _doing_it_wrong( __FUNCTION__, 'Only arrays should be returned when using the frm_validate_entry filter.', '6.3' );
59 - }
60 -
61 35 return $errors;
62 36 }
63 37
64 38 private static function set_item_key( &$values ) {
@@ -64,9 +38,9 @@
64 38 private static function set_item_key( &$values ) {
65 39 if ( ! isset( $values['item_key'] ) || $values['item_key'] == '' ) {
66 40 global $wpdb;
67 41 $values['item_key'] = FrmAppHelper::get_unique_key( '', $wpdb->prefix . 'frm_items', 'item_key' );
68 - $_POST['item_key'] = $values['item_key'];
42 + $_POST['item_key'] = $values['item_key'];
69 43 }
70 44 }
71 45
72 46 private static function get_fields_to_validate( $values, $exclude ) {
@@ -79,44 +53,34 @@
79 53 if ( ! empty( $exclude ) ) {
80 54 $where['fi.type not'] = $exclude;
81 55 }
82 56
83 - $fields = FrmField::getAll( $where, 'field_order' );
84 -
85 - /**
86 - * Allows modifying fields to validate.
87 - *
88 - * @since 5.0.06
89 - *
90 - * @param array $fields List of fields.
91 - * @param array $args Includes `values`, `exclude`, `where`.
92 - */
93 - return apply_filters( 'frm_fields_to_validate', $fields, compact( 'values', 'exclude', 'where' ) );
57 + return FrmField::getAll( $where, 'field_order' );
94 58 }
95 59
96 - public static function validate_field( $posted_field, &$errors, $values, $args = array() ) {
97 - $defaults = array(
98 - 'id' => $posted_field->id,
99 - 'parent_field_id' => '', // the id of the repeat or embed form
100 - 'key_pointer' => '', // the pointer in the posted array
101 - 'exclude' => array(), // exclude these field types from validation
102 - );
103 - $args = wp_parse_args( $args, $defaults );
60 + public static function validate_field( $posted_field, &$errors, $values, $args = array() ) {
61 + $defaults = array(
62 + 'id' => $posted_field->id,
63 + 'parent_field_id' => '', // the id of the repeat or embed form
64 + 'key_pointer' => '', // the pointer in the posted array
65 + 'exclude' => array(), // exclude these field types from validation
66 + );
67 + $args = wp_parse_args( $args, $defaults );
104 68
105 69 if ( empty( $args['parent_field_id'] ) ) {
106 70 $value = isset( $values['item_meta'][ $args['id'] ] ) ? $values['item_meta'][ $args['id'] ] : '';
107 - } else {
108 - // value is from a nested form
109 - $value = $values;
110 - }
71 + } else {
72 + // value is from a nested form
73 + $value = $values;
74 + }
111 75
112 - // Check for values in "Other" fields
113 - FrmEntriesHelper::maybe_set_other_validation( $posted_field, $value, $args );
76 + // Check for values in "Other" fields
77 + FrmEntriesHelper::maybe_set_other_validation( $posted_field, $value, $args );
114 78
115 79 self::maybe_clear_value_for_default_blank_setting( $posted_field, $value );
116 80
117 - $should_trim = is_array( $value ) && count( $value ) == 1 && isset( $value[0] ) && $posted_field->type !== 'checkbox';
118 - if ( $should_trim ) {
81 + // Reset arrays with only one value if it's not a field where array keys need to be preserved
82 + if ( is_array( $value ) && count( $value ) == 1 && isset( $value[0] ) ) {
119 83 $value = reset( $value );
120 84 }
121 85
122 86 if ( ! is_array( $value ) ) {
@@ -122,22 +86,18 @@
122 86 if ( ! is_array( $value ) ) {
123 87 $value = trim( $value );
124 88 }
125 89
126 - if ( $posted_field->required == '1' && FrmAppHelper::is_empty_value( $value ) ) {
90 + if ( $posted_field->required == '1' && FrmAppHelper::is_empty_value( $value ) ) {
127 91 $errors[ 'field' . $args['id'] ] = FrmFieldsHelper::get_error_msg( $posted_field, 'blank' );
128 - } elseif ( ! isset( $_POST['item_name'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
129 - self::maybe_add_item_name( $value, $posted_field );
130 - }
92 + } else if ( $posted_field->type == 'text' && ! isset( $_POST['item_name'] ) ) { // WPCS: CSRF ok.
93 + $_POST['item_name'] = $value;
94 + }
131 95
132 96 FrmEntriesHelper::set_posted_value( $posted_field, $value, $args );
133 97
134 98 self::validate_field_types( $errors, $posted_field, $value, $args );
135 99
136 - // Field might want to modify value before other parts of the system
137 - // e.g. trim off excess values like in the case of fields with limit.
138 - $value = apply_filters( 'frm_modify_posted_field_value', $value, $errors, $posted_field, $args );
139 -
140 100 if ( $value != '' ) {
141 101 self::validate_phone_field( $errors, $posted_field, $value, $args );
142 102 }
143 103
@@ -142,52 +102,31 @@
142 102 }
143 103
144 104 $errors = apply_filters( 'frm_validate_' . $posted_field->type . '_field_entry', $errors, $posted_field, $value, $args );
145 105 $errors = apply_filters( 'frm_validate_field_entry', $errors, $posted_field, $value, $args );
146 - }
106 + }
147 107
148 - /**
149 - * Maybe add item_name to $_POST to save it in items table.
150 - *
151 - * @since 5.2.02
152 - *
153 - * @param object $field Field object.
154 - */
155 - private static function maybe_add_item_name( $value, $field ) {
156 - $item_name = false;
157 - if ( 'name' === $field->type ) {
158 - $field_obj = FrmFieldFactory::get_field_object( $field );
159 - $item_name = $field_obj->get_display_value( $value );
160 - } elseif ( 'text' === $field->type ) {
161 - $item_name = $value;
162 - }
108 + private static function maybe_clear_value_for_default_blank_setting( $field, &$value ) {
109 + $is_default = ( FrmField::is_option_true_in_object( $field, 'default_blank' ) && $value == $field->default_value );
110 + $is_label = false;
163 111
164 - if ( false !== $item_name ) {
165 - // Item name has a max length of 255 characters so truncate it so it doesn't fail to save in the database.
166 - $_POST['item_name'] = substr( $item_name, 0, 255 );
167 - }
168 - }
112 + if ( ! $is_default ) {
113 + $position = FrmField::get_option( $field, 'label' );
114 + if ( empty( $position ) ) {
115 + $position = FrmStylesController::get_style_val( 'position', $field->form_id );
116 + }
169 117
170 - /**
171 - * Set $value to an empty string if it matches its label
172 - *
173 - * @param object $field
174 - * @param string $value
175 - */
176 - private static function maybe_clear_value_for_default_blank_setting( $field, &$value ) {
177 - $position = FrmField::get_option( $field, 'label' );
178 - if ( ! $position ) {
179 - $position = FrmStylesController::get_style_val( 'position', $field->form_id );
118 + $is_label = ( $position == 'inside' && FrmFieldsHelper::is_placeholder_field_type( $field->type ) && $value == $field->name );
180 119 }
181 120
182 - if ( $position === 'inside' && FrmFieldsHelper::is_placeholder_field_type( $field->type ) && $value === $field->name ) {
121 + if ( $is_label || $is_default ) {
183 122 $value = '';
184 123 }
185 124 }
186 125
187 126 public static function validate_field_types( &$errors, $posted_field, $value, $args ) {
188 - $field_obj = FrmFieldFactory::get_field_object( $posted_field );
189 - $args['value'] = $value;
127 + $field_obj = FrmFieldFactory::get_field_object( $posted_field );
128 + $args['value'] = $value;
190 129 $args['errors'] = $errors;
191 130
192 131 $new_errors = $field_obj->validate( $args );
193 132 if ( ! empty( $new_errors ) ) {
@@ -220,9 +159,8 @@
220 159 $pattern = self::create_regular_expression_from_format( $pattern );
221 160 }
222 161
223 162 $pattern = '/' . $pattern . '/';
224 -
225 163 return $pattern;
226 164 }
227 165
228 166 /**
@@ -235,11 +173,9 @@
235 173 /**
236 174 * Create a regular expression from a phone number format
237 175 *
238 176 * @since 2.02.02
239 - *
240 177 * @param string $pattern
241 - *
242 178 * @return string
243 179 */
244 180 private static function create_regular_expression_from_format( $pattern ) {
245 181 $pattern = preg_quote( $pattern );
@@ -248,15 +184,15 @@
248 184 $pattern = str_replace( array( '\-', '\:' ), array( '-', ':' ), $pattern );
249 185
250 186 // Switch generic values out for their regular expression
251 187 $pattern = preg_replace( '/\d/', '\d', $pattern );
188 + $pattern = str_replace( 'a', '[a-z]', $pattern );
252 189 $pattern = str_replace( 'A', '[A-Z]', $pattern );
253 - $pattern = str_replace( 'a', '[a-zA-Z]', $pattern );
254 190 $pattern = str_replace( '*', 'w', $pattern );
255 191 $pattern = str_replace( '/', '\/', $pattern );
256 192
257 193 if ( strpos( $pattern, '\?' ) !== false ) {
258 - $parts = explode( '\?', $pattern );
194 + $parts = explode( '\?', $pattern );
259 195 $pattern = '';
260 196 foreach ( $parts as $part ) {
261 197 if ( empty( $pattern ) ) {
262 198 $pattern .= $part;
@@ -276,167 +212,90 @@
276 212 * @param boolean $exclude
277 213 * @param array $values
278 214 * @param array $errors by reference
279 215 */
280 - public static function spam_check( $exclude, $values, &$errors ) {
281 - if ( ! empty( $exclude ) || ! isset( $values['item_meta'] ) || empty( $values['item_meta'] ) || ! empty( $errors ) ) {
282 - // only check spam if there are no other errors
283 - return;
284 - }
216 + public static function spam_check( $exclude, $values, &$errors ) {
217 + if ( ! empty( $exclude ) || ! isset( $values['item_meta'] ) || empty( $values['item_meta'] ) || ! empty( $errors ) ) {
218 + // only check spam if there are no other errors
219 + return;
220 + }
285 221
286 - $antispam_check = self::is_antispam_check( $values['form_id'] );
287 - if ( is_string( $antispam_check ) ) {
288 - $errors['spam'] = $antispam_check;
289 - } elseif ( self::is_honeypot_spam( $values ) || self::is_spam_bot() ) {
222 + if ( self::is_honeypot_spam() || self::is_spam_bot() ) {
290 223 $errors['spam'] = __( 'Your entry appears to be spam!', 'formidable' );
291 - } elseif ( self::blacklist_check( $values ) ) {
292 - $errors['spam'] = __( 'Your entry appears to be blocked spam!', 'formidable' );
293 224 }
294 225
295 - if ( isset( $errors['spam'] ) || self::form_is_in_progress( $values ) ) {
296 - return;
297 - }
226 + if ( self::blacklist_check( $values ) ) {
227 + $errors['spam'] = __( 'Your entry appears to be blacklist spam!', 'formidable' );
228 + }
298 229
299 - if ( self::is_akismet_enabled_for_user( $values['form_id'] ) && self::is_akismet_spam( $values ) ) {
300 - $errors['spam'] = __( 'Your entry appears to be spam!', 'formidable' );
301 - }
302 - }
230 + if ( self::is_akismet_spam( $values ) ) {
231 + if ( self::is_akismet_enabled_for_user( $values['form_id'] ) ) {
232 + $errors['spam'] = __( 'Your entry appears to be spam!', 'formidable' );
233 + }
234 + }
235 + }
303 236
304 - /**
305 - * Checks if form is in progress.
306 - *
307 - * @since 5.0.13
308 - *
309 - * @param array $values The values.
310 - * @return bool
311 - */
312 - private static function form_is_in_progress( $values ) {
313 - return FrmAppHelper::pro_is_installed() &&
314 - ( isset( $values[ 'frm_page_order_' . $values['form_id'] ] ) || FrmAppHelper::get_post_param( 'frm_next_page' ) ) &&
315 - FrmField::get_all_types_in_form( $values['form_id'], 'break' );
237 + private static function is_honeypot_spam() {
238 + $honeypot_value = FrmAppHelper::get_param( 'frm_verify', '', 'get', 'sanitize_text_field' );
239 + return ( $honeypot_value !== '' );
316 240 }
317 241
318 - /**
319 - * @param int $form_id
320 - *
321 - * @return bool|string
322 - */
323 - private static function is_antispam_check( $form_id ) {
324 - $aspm = new FrmAntiSpam( $form_id );
325 - return $aspm->validate();
326 - }
327 -
328 - /**
329 - * @param array $values
330 - * @return boolean
331 - */
332 - private static function is_honeypot_spam( $values ) {
333 - $honeypot = new FrmHoneypot( $values['form_id'] );
334 - return ! $honeypot->validate();
335 - }
336 -
337 - /**
338 - * @return boolean
339 - */
340 242 private static function is_spam_bot() {
341 243 $ip = FrmAppHelper::get_ip_address();
342 -
343 244 return empty( $ip );
344 245 }
345 246
346 - /**
347 - * @param array $values
348 - * @return boolean
349 - */
350 247 private static function is_akismet_spam( $values ) {
351 248 global $wpcom_api_key;
352 -
353 249 return ( is_callable( 'Akismet::http_post' ) && ( get_option( 'wordpress_api_key' ) || $wpcom_api_key ) && self::akismet( $values ) );
354 250 }
355 251
356 - /**
357 - * @param int $form_id
358 - * @return bool
359 - */
360 252 private static function is_akismet_enabled_for_user( $form_id ) {
361 253 $form = FrmForm::getOne( $form_id );
362 -
363 - return ( ! empty( $form->options['akismet'] ) && ( $form->options['akismet'] !== 'logged' || ! is_user_logged_in() ) );
254 + return ( isset( $form->options['akismet'] ) && ! empty( $form->options['akismet'] ) && ( $form->options['akismet'] != 'logged' || ! is_user_logged_in() ) );
364 255 }
365 256
366 - public static function blacklist_check( $values ) {
257 + public static function blacklist_check( $values ) {
367 258 if ( ! apply_filters( 'frm_check_blacklist', true, $values ) ) {
368 - return false;
369 - }
259 + return false;
260 + }
370 261
371 - $mod_keys = trim( self::get_disallowed_words() );
372 - if ( empty( $mod_keys ) ) {
262 + $mod_keys = trim( get_option( 'blacklist_keys' ) );
263 + if ( empty( $mod_keys ) ) {
264 + return false;
265 + }
266 +
267 + $content = FrmEntriesHelper::entry_array_to_string( $values );
268 + if ( empty( $content ) ) {
373 269 return false;
374 270 }
375 271
376 - $content = FrmEntriesHelper::entry_array_to_string( $values );
377 -
378 - self::prepare_values_for_spam_check( $values );
379 - $ip = FrmAppHelper::get_ip_address();
272 + $ip = FrmAppHelper::get_ip_address();
380 273 $user_agent = FrmAppHelper::get_server_value( 'HTTP_USER_AGENT' );
381 - $user_info = self::get_spam_check_user_info( $values );
274 + $user_info = self::get_spam_check_user_info( $values );
382 275
383 - return self::check_disallowed_words( $user_info['comment_author'], $user_info['comment_author_email'], $user_info['comment_author_url'], $content, $ip, $user_agent );
384 - }
276 + return wp_blacklist_check( $user_info['comment_author'], $user_info['comment_author_email'], $user_info['comment_author_url'], $content, $ip, $user_agent );
277 + }
385 278
386 279 /**
387 - * For WP 5.5 compatibility.
388 - *
389 - * @since 4.06.02
390 - */
391 - private static function check_disallowed_words( $author, $email, $url, $content, $ip, $user_agent ) {
392 - if ( function_exists( 'wp_check_comment_disallowed_list' ) ) {
393 - return wp_check_comment_disallowed_list( $author, $email, $url, $content, $ip, $user_agent );
394 - } else {
395 - return wp_blacklist_check( $author, $email, $url, $content, $ip, $user_agent );
396 - }
397 - }
398 -
399 - /**
400 - * For WP 5.5 compatibility.
401 - *
402 - * @since 4.06.02
403 - */
404 - private static function get_disallowed_words() {
405 - $keys = get_option( 'disallowed_keys' );
406 - if ( false === $keys ) {
407 - // Fallback for WP < 5.5.
408 - $keys = get_option( 'blacklist_keys' );
409 - }
410 - return $keys;
411 - }
412 -
413 - /**
414 280 * Check entries for Akismet spam
415 281 *
416 282 * @return boolean true if is spam
417 283 */
418 284 public static function akismet( $values ) {
419 - if ( empty( $values['item_meta'] ) ) {
285 + $content = FrmEntriesHelper::entry_array_to_string( $values );
286 + if ( empty( $content ) ) {
420 287 return false;
421 288 }
422 289
423 290 $datas = array(
424 - 'comment_type' => 'formidable',
291 + 'comment_type' => 'formidable',
292 + 'comment_content' => $content,
425 293 );
426 294 self::parse_akismet_array( $datas, $values );
427 295
428 - /**
429 - * Allows modifying the values sent to Akismet.
430 - *
431 - * @since 5.0.07
432 - *
433 - * @param array $datas The array of values being sent to Akismet.
434 - */
435 - $datas = apply_filters( 'frm_akismet_values', $datas );
436 -
437 296 $query_string = _http_build_query( $datas, '', '&' );
438 - $response = Akismet::http_post( $query_string, 'comment-check' );
297 + $response = Akismet::http_post( $query_string, 'comment-check' );
439 298
440 299 return ( is_array( $response ) && $response[1] == 'true' );
441 300 }
442 301
@@ -444,22 +303,18 @@
444 303 * @since 2.0
445 304 */
446 305 private static function parse_akismet_array( &$datas, $values ) {
447 306 self::add_site_info_to_akismet( $datas );
307 + self::add_user_info_to_akismet( $datas, $values );
448 308 self::add_server_values_to_akismet( $datas );
449 -
450 - self::prepare_values_for_spam_check( $values );
451 -
452 - self::add_user_info_to_akismet( $datas, $values );
453 - self::add_comment_content_to_akismet( $datas, $values );
454 309 }
455 310
456 311 private static function add_site_info_to_akismet( &$datas ) {
457 - $datas['blog'] = FrmAppHelper::site_url();
458 - $datas['user_ip'] = preg_replace( '/[^0-9., ]/', '', FrmAppHelper::get_ip_address() );
459 - $datas['user_agent'] = FrmAppHelper::get_server_value( 'HTTP_USER_AGENT' );
460 - $datas['referrer'] = isset( $_SERVER['HTTP_REFERER'] ) ? FrmAppHelper::get_server_value( 'HTTP_REFERER' ) : false;
461 - $datas['blog_lang'] = get_locale();
312 + $datas['blog'] = FrmAppHelper::site_url();
313 + $datas['user_ip'] = preg_replace( '/[^0-9., ]/', '', FrmAppHelper::get_ip_address() );
314 + $datas['user_agent'] = FrmAppHelper::get_server_value( 'HTTP_USER_AGENT' );
315 + $datas['referrer'] = isset( $_SERVER['HTTP_REFERER'] ) ? FrmAppHelper::get_server_value( 'HTTP_REFERER' ) : false;
316 + $datas['blog_lang'] = get_locale();
462 317 $datas['blog_charset'] = get_option( 'blog_charset' );
463 318
464 319 if ( akismet_test_mode() ) {
465 320 $datas['is_test'] = 'true';
@@ -467,9 +322,9 @@
467 322 }
468 323
469 324 private static function add_user_info_to_akismet( &$datas, $values ) {
470 325 $user_info = self::get_spam_check_user_info( $values );
471 - $datas = $datas + $user_info;
326 + $datas = $datas + $user_info;
472 327
473 328 if ( isset( $user_info['user_ID'] ) ) {
474 329 $datas['user_role'] = Akismet::get_user_roles( $user_info['user_ID'] );
475 330 }
@@ -474,127 +329,38 @@
474 329 $datas['user_role'] = Akismet::get_user_roles( $user_info['user_ID'] );
475 330 }
476 331 }
477 332
478 - /**
479 - * Gets user info for Akismet spam check.
480 - *
481 - * @since 5.0.13 Separate code for guest. Handle value of embedded|repeater.
482 - *
483 - * @param array $values Entry values after running through {@see FrmEntryValidate::prepare_values_for_spam_check()}.
484 - * @return array
485 - */
486 333 private static function get_spam_check_user_info( $values ) {
487 - if ( ! is_user_logged_in() ) {
488 - return self::get_spam_check_user_info_for_guest( $values );
489 - }
334 + $datas = array();
490 335
491 - $user = wp_get_current_user();
336 + if ( is_user_logged_in() ) {
337 + $user = wp_get_current_user();
338 + $datas['user_ID'] = $user->ID;
339 + $datas['user_id'] = $user->ID;
340 + $datas['comment_author'] = $user->display_name;
341 + $datas['comment_author_email'] = $user->user_email;
342 + $datas['comment_author_url'] = $user->user_url;
343 + } else {
344 + $datas['comment_author'] = '';
345 + $datas['comment_author_email'] = '';
346 + $datas['comment_author_url'] = '';
492 347
493 - return array(
494 - 'user_ID' => $user->ID,
495 - 'user_id' => $user->ID,
496 - 'comment_author' => $user->display_name,
497 - 'comment_author_email' => $user->user_email,
498 - 'comment_author_url' => $user->user_url,
499 - );
500 - }
501 -
502 - /**
503 - * Gets user info for Akismet spam check for guest.
504 - *
505 - * @since 5.0.13
506 - *
507 - * @param array $values Entry values after flattened.
508 - * @return array
509 - */
510 - private static function get_spam_check_user_info_for_guest( $values ) {
511 - $datas = array(
512 - 'comment_author' => '',
513 - 'comment_author_email' => '',
514 - 'comment_author_url' => '',
515 - 'name_field_ids' => $values['name_field_ids'],
516 - 'missing_keys' => array( 'comment_author_email', 'comment_author_url', 'comment_author' ),
517 - 'frm_duplicated' => array(),
518 - );
519 -
520 - if ( isset( $values['item_meta'] ) ) {
521 - $values = $values['item_meta'];
522 - }
523 -
524 - $values = array_filter( $values );
525 -
526 - self::recursive_add_akismet_guest_info( $datas, $values );
527 - unset( $datas['name_field_ids'] );
528 - unset( $datas['missing_keys'] );
529 -
530 - return $datas;
531 - }
532 -
533 - /**
534 - * Recursive adds akismet guest info.
535 - *
536 - * @since 5.0.13
537 - *
538 - * @param array $datas Guest data.
539 - * @param array $values The values.
540 - * @param int|null $custom_index Custom index (or field ID).
541 - */
542 - private static function recursive_add_akismet_guest_info( &$datas, $values, $custom_index = null ) {
543 - foreach ( $values as $index => $value ) {
544 - if ( ! $datas['missing_keys'] ) {
545 - return; // Found all info.
546 - }
547 -
548 - if ( is_array( $value ) ) {
549 - self::recursive_add_akismet_guest_info( $datas, $value, $index );
550 - continue;
551 - }
552 -
553 - $field_id = ! is_null( $custom_index ) ? $custom_index : $index;
554 - foreach ( $datas['missing_keys'] as $key_index => $key ) {
555 - $found = self::is_akismet_guest_info_value( $key, $value, $field_id, $datas['name_field_ids'] );
556 - if ( $found ) {
557 - $datas[ $key ] = $value;
558 - $datas['frm_duplicated'][] = $field_id;
559 - unset( $datas['missing_keys'][ $key_index ] );
348 + $values = array_filter( $values );
349 + foreach ( $values as $value ) {
350 + if ( ! is_array( $value ) ) {
351 + if ( $datas['comment_author_email'] == '' && strpos( $value, '@' ) && is_email( $value ) ) {
352 + $datas['comment_author_email'] = $value;
353 + } elseif ( $datas['comment_author_url'] == '' && strpos( $value, 'http' ) === 0 ) {
354 + $datas['comment_author_url'] = $value;
355 + } elseif ( $datas['comment_author'] == '' && ! is_numeric( $value ) && strlen( $value ) < 200 ) {
356 + $datas['comment_author'] = $value;
357 + }
560 358 }
561 359 }
562 360 }
563 - }
564 361
565 - /**
566 - * Checks if given value is an akismet guest info.
567 - *
568 - * @since 5.0.13
569 - *
570 - * @param string $key Guest info key.
571 - * @param string $value Value to check.
572 - * @param int $field_id Field ID.
573 - * @param array $name_field_ids Name field IDs.
574 - * @return bool
575 - */
576 - private static function is_akismet_guest_info_value( $key, $value, $field_id, $name_field_ids ) {
577 - if ( ! $value || is_numeric( $value ) ) {
578 - return false;
579 - }
580 -
581 - switch ( $key ) {
582 - case 'comment_author_email':
583 - return strpos( $value, '@' ) && is_email( $value );
584 -
585 - case 'comment_author_url':
586 - return 0 === strpos( $value, 'http' );
587 -
588 - case 'comment_author':
589 - if ( $name_field_ids ) {
590 - // If there is name field in the form, we should always use it as author name.
591 - return in_array( $field_id, $name_field_ids, true );
592 - }
593 - return strlen( $value ) < 200;
594 - }
595 -
596 - return false;
362 + return $datas;
597 363 }
598 364
599 365 private static function add_server_values_to_akismet( &$datas ) {
600 366 foreach ( $_SERVER as $key => $value ) {
@@ -605,203 +371,8 @@
605 371 $datas[ $key ] = $value;
606 372 }
607 373 unset( $key, $value );
608 374 }
609 - }
610 -
611 - /**
612 - * Adds comment content to Akismet data.
613 - *
614 - * @since 5.0.09
615 - *
616 - * @param array $datas The array of values being sent to Akismet.
617 - * @param array $values Entry values.
618 - */
619 - private static function add_comment_content_to_akismet( &$datas, $values ) {
620 - if ( isset( $datas['frm_duplicated'] ) ) {
621 - foreach ( $datas['frm_duplicated'] as $index ) {
622 - if ( isset( $values['item_meta'][ $index ] ) ) {
623 - unset( $values['item_meta'][ $index ] );
624 - } else {
625 - unset( $values[ $index ] );
626 - }
627 - }
628 - unset( $datas['frm_duplicated'] );
629 - }
630 -
631 - self::skip_adding_values_to_akismet( $values );
632 -
633 - $datas['comment_content'] = FrmEntriesHelper::entry_array_to_string( $values );
634 - }
635 -
636 - /**
637 - * Skips adding field values to Akismet.
638 - *
639 - * @since 5.0.09
640 - *
641 - * @param array $values Entry values.
642 - */
643 - private static function skip_adding_values_to_akismet( &$values ) {
644 - $skipped_fields = self::get_akismet_skipped_field_ids( $values );
645 - foreach ( $skipped_fields as $skipped_field ) {
646 - if ( ! isset( $values['item_meta'][ $skipped_field->id ] ) ) {
647 - continue;
648 - }
649 -
650 - if ( self::should_really_skip_field( $skipped_field, $values ) ) {
651 - unset( $values['item_meta'][ $skipped_field->id ] );
652 - if ( isset( $values['item_meta']['other'][ $skipped_field->id ] ) ) {
653 - unset( $values['item_meta']['other'][ $skipped_field->id ] );
654 - }
655 - }
656 - }
657 - }
658 -
659 - /**
660 - * Checks if a skip field should be really skipped.
661 - *
662 - * @since 5.02.04
663 - *
664 - * @param object $field_data Object contains `id` and `options`.
665 - * @param array $values Entry values.
666 - * @return bool
667 - */
668 - private static function should_really_skip_field( $field_data, $values ) {
669 - if ( empty( $field_data->options ) ) { // This is skipped field types.
670 - return true;
671 - }
672 -
673 - FrmAppHelper::unserialize_or_decode( $field_data->options );
674 - if ( ! $field_data->options ) { // Check if an error happens when unserializing, or empty options.
675 - return true;
676 - }
677 -
678 - end( $field_data->options );
679 - $last_key = key( $field_data->options );
680 -
681 - // If a choice field has no Other option.
682 - if ( is_numeric( $last_key ) || 0 !== strpos( $last_key, 'other_' ) ) {
683 - return true;
684 - }
685 -
686 - // If a choice field has Other option, but Other is not selected.
687 - if ( empty( $values['item_meta']['other'][ $field_data->id ] ) ) {
688 - return true;
689 - }
690 -
691 - // Check if submitted value is same as one of field option.
692 - foreach ( $field_data->options as $option ) {
693 - $option_value = ! is_array( $option ) ? $option : ( isset( $option['value'] ) ? $option['value'] : '' );
694 - if ( $values['item_meta']['other'][ $field_data->id ] === $option_value ) {
695 - return true;
696 - }
697 - }
698 -
699 - return false;
700 - }
701 -
702 - /**
703 - * Gets field IDs that are skipped from sending to Akismet spam check.
704 - *
705 - * @since 5.0.09
706 - * @since 5.0.13 Move out get_all_form_ids_and_flatten_meta() call and get `form_ids` from `$values`.
707 - * @since 5.2.04 This method returns array of object contains `id` and `options` instead of array of `id` only.
708 - *
709 - * @param array $values Entry values after running through {@see FrmEntryValidate::prepare_values_for_spam_check()}.
710 - * @return array
711 - */
712 - private static function get_akismet_skipped_field_ids( $values ) {
713 - if ( empty( $values['form_ids'] ) ) {
714 - return array();
715 - }
716 -
717 - $skipped_types = array( 'divider', 'form', 'hidden', 'user_id', 'file', 'date', 'time', 'scale', 'star', 'range', 'toggle', 'data', 'lookup', 'likert', 'nps' );
718 - $has_other_types = array( 'radio', 'checkbox', 'select' );
719 -
720 - $where = array(
721 - array(
722 - 'form_id' => $values['form_ids'],
723 - 'type' => array_merge( $skipped_types, $has_other_types ),
724 - ),
725 - );
726 -
727 - return FrmDb::get_results( 'frm_fields', $where, 'id,options' );
728 - }
729 -
730 - /**
731 - * Prepares values array for spam check.
732 - *
733 - * @since 5.0.13
734 - *
735 - * @param array $values Entry values.
736 - */
737 - private static function prepare_values_for_spam_check( &$values ) {
738 - $form_ids = self::get_all_form_ids_and_flatten_meta( $values );
739 - $values['form_ids'] = $form_ids;
740 - }
741 -
742 - /**
743 - * Gets all form IDs (include child form IDs) and flatten item_meta array. Used for skipping values sent to Akismet.
744 - * This also removes some unused data from the item_meta.
745 - *
746 - * @since 5.0.09
747 - * @since 5.0.13 Convert name field value to string.
748 - *
749 - * @param array $values Entry values.
750 - * @return array Form IDs.
751 - */
752 - private static function get_all_form_ids_and_flatten_meta( &$values ) {
753 - $values['name_field_ids'] = array();
754 -
755 - // Blacklist check for File field in the old version doesn't contain `form_id`.
756 - $form_ids = isset( $values['form_id'] ) ? array( absint( $values['form_id'] ) ) : array();
757 - foreach ( $values['item_meta'] as $field_id => $value ) {
758 - if ( ! is_numeric( $field_id ) ) { // Maybe `other`.
759 - continue;
760 - }
761 -
762 - // Convert name array to string.
763 - if ( isset( $value['first'] ) && isset( $value['last'] ) ) {
764 - $values['item_meta'][ $field_id ] = trim( implode( ' ', $value ) );
765 - $values['name_field_ids'][] = $field_id;
766 - continue;
767 - }
768 -
769 - if ( ! is_array( $value ) || empty( $value['form'] ) ) {
770 - continue;
771 - }
772 -
773 - $form_ids[] = absint( $value['form'] );
774 -
775 - foreach ( $value as $subindex => $subvalue ) {
776 - if ( ! is_numeric( $subindex ) || ! is_array( $subvalue ) ) {
777 - continue;
778 - }
779 -
780 - foreach ( $subvalue as $subsubindex => $subsubvalue ) {
781 - if ( ! $subsubvalue ) {
782 - continue;
783 - }
784 -
785 - if ( ! isset( $values['item_meta'][ $subsubindex ] ) ) {
786 - $values['item_meta'][ $subsubindex ] = array();
787 - }
788 -
789 - // Convert name array to string.
790 - if ( isset( $subsubvalue['first'] ) && isset( $subsubvalue['last'] ) ) {
791 - $subsubvalue = trim( implode( ' ', $subsubvalue ) );
792 -
793 - $values['name_field_ids'][] = $subsubindex;
794 - }
795 -
796 - $values['item_meta'][ $subsubindex ][] = $subsubvalue;
797 - }
798 - }
799 -
800 - unset( $values['item_meta'][ $field_id ] );
801 - }
802 -
803 - return $form_ids;
804 375 }
805 376
806 377 /**
807 378 * @deprecated 3.0