PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / trunk
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More vtrunk
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 +74 -75 6.26 → trunk View file →
@@ -23,13 +23,12 @@
23 23 $errors = array();
24 24
25 25 if ( ! isset( $values['form_id'] ) || ! isset( $values['item_meta'] ) ) {
26 26 $errors['form'] = __( 'There was a problem with your submission. Please try again.', 'formidable' );
27 -
28 27 return $errors;
29 28 }
30 29
31 - 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' ) ) ) {
30 + 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' ) ) ) { // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
32 31 $frm_settings = FrmAppHelper::get_settings();
33 32 $errors['form'] = $frm_settings->admin_permission;
34 33 }
35 34
@@ -45,9 +44,9 @@
45 44 self::validate_field( $posted_field, $errors, $values, $args );
46 45 unset( $posted_field );
47 46 }
48 47
49 - if ( empty( $errors ) ) {
48 + if ( ! $errors ) {
50 49 self::spam_check( $exclude, $values, $errors );
51 50 }
52 51
53 52 /**
@@ -90,13 +89,16 @@
90 89 *
91 90 * @return void
92 91 */
93 92 private static function set_item_key( &$values ) {
94 - if ( ! isset( $values['item_key'] ) || $values['item_key'] == '' ) {
95 - global $wpdb;
96 - $values['item_key'] = FrmAppHelper::get_unique_key( '', $wpdb->prefix . 'frm_items', 'item_key' );
97 - $_POST['item_key'] = $values['item_key'];
93 + // phpcs:ignore Universal.Operators.StrictComparisons
94 + if ( isset( $values['item_key'] ) && $values['item_key'] != '' ) {
95 + return;
98 96 }
97 +
98 + global $wpdb;
99 + $values['item_key'] = FrmAppHelper::get_unique_key( '', $wpdb->prefix . 'frm_items', 'item_key' );
100 + $_POST['item_key'] = $values['item_key'];
99 101 }
100 102
101 103 /**
102 104 * @param array $values
@@ -110,9 +112,9 @@
110 112 // Don't get subfields
111 113 $where['fr.parent_form_id'] = array( null, 0 );
112 114
113 115 // Don't get excluded fields (like file upload fields in the ajax validation)
114 - if ( ! empty( $exclude ) ) {
116 + if ( $exclude ) {
115 117 $where['fi.type not'] = $exclude;
116 118 }
117 119
118 120 $fields = FrmField::getAll( $where, 'field_order' );
@@ -146,23 +148,17 @@
146 148 // Exclude these field types from validation.
147 149 'exclude' => array(),
148 150
149 151 );
150 - $args = wp_parse_args( $args, $defaults );
152 + $args = wp_parse_args( $args, $defaults );
153 + $value = ! empty( $args['parent_field_id'] ) ? $values : ( $values['item_meta'][ $args['id'] ] ?? '' );
151 154
152 - if ( empty( $args['parent_field_id'] ) ) {
153 - $value = $values['item_meta'][ $args['id'] ] ?? '';
154 - } else {
155 - // value is from a nested form
156 - $value = $values;
157 - }
158 -
159 155 // Check for values in "Other" fields
160 156 FrmEntriesHelper::maybe_set_other_validation( $posted_field, $value, $args );
161 157
162 158 self::maybe_clear_value_for_default_blank_setting( $posted_field, $value );
163 159
164 - $should_trim = is_array( $value ) && count( $value ) == 1 && isset( $value[0] ) && $posted_field->type !== 'checkbox';
160 + $should_trim = is_array( $value ) && count( $value ) === 1 && isset( $value[0] ) && $posted_field->type !== 'checkbox';
165 161
166 162 if ( $should_trim ) {
167 163 $value = reset( $value );
168 164 }
@@ -170,8 +166,9 @@
170 166 if ( ! is_array( $value ) ) {
171 167 $value = trim( $value );
172 168 }
173 169
170 + // phpcs:ignore Universal.Operators.StrictComparisons
174 171 if ( $posted_field->required == '1' && FrmAppHelper::is_empty_value( $value ) ) {
175 172 $errors[ 'field' . $args['id'] ] = FrmFieldsHelper::get_error_msg( $posted_field, 'blank' );
176 173 } elseif ( ! isset( $_POST['item_name'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
177 174 self::maybe_add_item_name( $value, $posted_field );
@@ -185,8 +182,9 @@
185 182 // Field might want to modify value before other parts of the system
186 183 // e.g. trim off excess values like in the case of fields with limit.
187 184 $value = apply_filters( 'frm_modify_posted_field_value', $value, $errors, $posted_field, $args );
188 185
186 + // phpcs:ignore Universal.Operators.StrictComparisons
189 187 if ( $value != '' ) {
190 188 self::validate_phone_field( $errors, $posted_field, $value, $args );
191 189 }
192 190
@@ -239,9 +237,9 @@
239 237 * @param array $options
240 238 *
241 239 * @return bool
242 240 */
243 - private static function option_is_valid( $field, $value, $options ) {
241 + private static function option_is_valid( $field, $value, $options ) { // phpcs:ignore SlevomatCodingStandard.Complexity.Cognitive.ComplexityTooHigh
244 242 if ( '' === $value ) {
245 243 return true;
246 244 }
247 245
@@ -269,9 +267,9 @@
269 267 foreach ( $value as $current_value ) {
270 268 $match = false;
271 269
272 270 foreach ( $options as $key => $option ) {
273 - if ( strpos( $key, 'other_' ) === 0 ) {
271 + if ( str_starts_with( $key, 'other_' ) ) {
274 272 // Always return true if an other option is found.
275 273 return true;
276 274 }
277 275
@@ -281,8 +279,11 @@
281 279 } else {
282 280 $option_value = $option;
283 281 }
284 282
283 + /**
284 + * @var string $current_value
285 + */
285 286 $match = trim( $current_value ) === trim( $option_value );
286 287
287 288 if ( $match ) {
288 289 break;
@@ -299,14 +300,16 @@
299 300 if ( $match ) {
300 301 break;
301 302 }
302 303
303 - if ( is_numeric( $current_value ) ) {
304 - $match = (int) $current_value === (int) $option_value;
304 + if ( ! is_numeric( $current_value ) ) {
305 + continue;
306 + }
305 307
306 - if ( $match ) {
307 - break;
308 - }
308 + $match = (int) $current_value === (int) $option_value;
309 +
310 + if ( $match ) {
311 + break;
309 312 }
310 313 }//end foreach
311 314
312 315 if ( ! $match ) {
@@ -341,8 +344,9 @@
341 344
342 345 if ( is_numeric( $filter_priority ) ) {
343 346 add_filter( 'the_content', 'wpautop', $filter_priority );
344 347 }
348 +
345 349 return trim( $value ) === trim( $filtered_option );
346 350 }
347 351
348 352 /**
@@ -367,11 +371,9 @@
367 371 $option_value = $separate_value ? $option['value'] : $option['label'];
368 372 } else {
369 373 $option_value = $option;
370 374 }
371 -
372 - $option_value = do_shortcode( $option_value );
373 - return $option_value;
375 + return do_shortcode( $option_value );
374 376 };
375 377
376 378 $values_options = array_map( $map_callback, $values['options'] );
377 379 $field_object_options = array_map( $map_callback, $field_object->options );
@@ -400,9 +402,9 @@
400 402 }
401 403
402 404 if ( false !== $item_name ) {
403 405 // Item name has a max length of 255 characters so truncate it so it doesn't fail to save in the database.
404 - $_POST['item_name'] = substr( $item_name, 0, 255 );
406 + $_POST['item_name'] = FrmAppHelper::truncate( $item_name, 255, 1, '', true );
405 407 }
406 408 }
407 409
408 410 /**
@@ -439,9 +441,9 @@
439 441 $args['errors'] = $errors;
440 442
441 443 $new_errors = $field_obj->validate( $args );
442 444
443 - if ( ! empty( $new_errors ) ) {
445 + if ( $new_errors ) {
444 446 $errors = array_merge( $errors, $new_errors );
445 447 }
446 448 }
447 449
@@ -455,14 +457,16 @@
455 457 */
456 458 public static function validate_phone_field( &$errors, $field, $value, $args ) {
457 459 $format_value = FrmField::get_option( $field, 'format' );
458 460
459 - if ( $field->type === 'phone' || ( $field->type === 'text' && $format_value && ! FrmCurrencyHelper::is_currency_format( $format_value ) ) ) {
460 - $pattern = self::phone_format( $field );
461 + if ( $field->type !== 'phone' && ( $field->type !== 'text' || ! $format_value || FrmCurrencyHelper::is_currency_format( $format_value ) ) ) {
462 + return;
463 + }
461 464
462 - if ( ! preg_match( $pattern, $value ) ) {
463 - $errors[ 'field' . $args['id'] ] = FrmFieldsHelper::get_error_msg( $field, 'invalid' );
464 - }
465 + $pattern = self::phone_format( $field );
466 +
467 + if ( ! preg_match( $pattern, $value ) ) {
468 + $errors[ 'field' . $args['id'] ] = FrmFieldsHelper::get_error_msg( $field, 'invalid' );
465 469 }
466 470 }
467 471
468 472 /**
@@ -482,15 +486,13 @@
482 486 $pattern = html_entity_decode( $pattern );
483 487 $pattern = apply_filters( 'frm_phone_pattern', $pattern, $field );
484 488
485 489 // Create a regexp if format is not already a regexp
486 - if ( strpos( $pattern, '^' ) !== 0 ) {
490 + if ( ! str_starts_with( $pattern, '^' ) ) {
487 491 $pattern = self::create_regular_expression_from_format( $pattern );
488 492 }
489 493
490 - $pattern = '/' . $pattern . '/';
491 -
492 - return $pattern;
494 + return '/' . $pattern . '/';
493 495 }
494 496
495 497 /**
496 498 * @since 3.01
@@ -522,24 +524,22 @@
522 524 $pattern = str_replace( 'a', '[a-zA-Z]', $pattern );
523 525 $pattern = str_replace( '*', 'w', $pattern );
524 526 $pattern = str_replace( '/', '\/', $pattern );
525 527
526 - if ( strpos( $pattern, '\?' ) !== false ) {
528 + if ( str_contains( $pattern, '\?' ) ) {
527 529 $parts = explode( '\?', $pattern );
528 530 $pattern = '';
529 531
530 532 foreach ( $parts as $part ) {
531 - if ( empty( $pattern ) ) {
533 + if ( $pattern ) {
534 + $pattern .= '(' . $part . ')?';
535 + } else {
532 536 $pattern .= $part;
533 - } else {
534 - $pattern .= '(' . $part . ')?';
535 537 }
536 538 }
537 539 }
538 540
539 - $pattern = '^' . $pattern . '$';
540 -
541 - return $pattern;
541 + return '^' . $pattern . '$';
542 542 }
543 543
544 544 /**
545 545 * Check for spam.
@@ -555,10 +555,10 @@
555 555 // Do not check spam on importing.
556 556 return;
557 557 }
558 558
559 - if ( ! empty( $exclude ) || empty( $values['item_meta'] ) || ! empty( $errors ) ) {
560 - // only check spam if there are no other errors
559 + if ( $exclude || empty( $values['item_meta'] ) || $errors ) {
560 + // Only check spam if there are no other errors
561 561 return;
562 562 }
563 563
564 564 $antispam_check = self::is_antispam_check( $values['form_id'] );
@@ -594,11 +594,13 @@
594 594 *
595 595 * @return bool
596 596 */
597 597 private static function form_is_in_progress( $values ) {
598 + // phpcs:disable Generic.WhiteSpace.ScopeIndent
598 599 return FrmAppHelper::pro_is_installed() &&
599 600 ( isset( $values[ 'frm_page_order_' . $values['form_id'] ] ) || FrmAppHelper::get_post_param( 'frm_next_page' ) ) &&
600 601 FrmField::get_all_types_in_form( $values['form_id'], 'break' );
602 + // phpcs:enable Generic.WhiteSpace.ScopeIndent
601 603 }
602 604
603 605 /**
604 606 * @param int $form_id
@@ -623,11 +625,9 @@
623 625 /**
624 626 * @return bool
625 627 */
626 628 private static function is_spam_bot() {
627 - $ip = FrmAppHelper::get_ip_address();
628 -
629 - return empty( $ip );
629 + return ! FrmAppHelper::get_ip_address();
630 630 }
631 631
632 632 /**
633 633 * @param array $values
@@ -635,10 +635,9 @@
635 635 * @return bool
636 636 */
637 637 private static function is_akismet_spam( $values ) {
638 638 global $wpcom_api_key;
639 -
640 - return ( is_callable( 'Akismet::http_post' ) && ( get_option( 'wordpress_api_key' ) || $wpcom_api_key ) && self::akismet( $values ) );
639 + return is_callable( 'Akismet::http_post' ) && ( get_option( 'wordpress_api_key' ) || $wpcom_api_key ) && self::akismet( $values );
641 640 }
642 641
643 642 /**
644 643 * @param int $form_id
@@ -646,10 +645,9 @@
646 645 * @return bool
647 646 */
648 647 private static function is_akismet_enabled_for_user( $form_id ) {
649 648 $form = FrmForm::getOne( $form_id );
650 -
651 - return ( ! empty( $form->options['akismet'] ) && ( $form->options['akismet'] !== 'logged' || ! is_user_logged_in() ) );
649 + return ! empty( $form->options['akismet'] ) && ( $form->options['akismet'] !== 'logged' || ! is_user_logged_in() );
652 650 }
653 651
654 652 /**
655 653 * Checks spam using WordPress disallowed words and Frm denylist.
@@ -690,9 +688,9 @@
690 688
691 689 $query_string = _http_build_query( $datas, '', '&' );
692 690 $response = Akismet::http_post( $query_string, 'comment-check' );
693 691
694 - return ( is_array( $response ) && $response[1] === 'true' );
692 + return is_array( $response ) && $response[1] === 'true';
695 693 }
696 694
697 695 /**
698 696 * @since 2.0
@@ -831,13 +829,15 @@
831 829
832 830 foreach ( $datas['missing_keys'] as $key_index => $key ) {
833 831 $found = self::is_akismet_guest_info_value( $key, $value, $field_id, $datas['name_field_ids'], $values );
834 832
835 - if ( $found ) {
836 - $datas[ $key ] = $value;
837 - $datas['frm_duplicated'][] = $field_id;
838 - unset( $datas['missing_keys'][ $key_index ] );
833 + if ( ! $found ) {
834 + continue;
839 835 }
836 +
837 + $datas[ $key ] = $value;
838 + $datas['frm_duplicated'][] = $field_id;
839 + unset( $datas['missing_keys'][ $key_index ] );
840 840 }
841 841 }//end foreach
842 842 }
843 843
@@ -860,12 +860,12 @@
860 860 }
861 861
862 862 switch ( $key ) {
863 863 case 'comment_author_email':
864 - return strpos( $value, '@' ) && is_email( $value );
864 + return str_contains( $value, '@' ) && is_email( $value );
865 865
866 866 case 'comment_author_url':
867 - return 0 === strpos( $value, 'http' );
867 + return str_starts_with( $value, 'http' );
868 868
869 869 case 'comment_author':
870 870 if ( $name_field_ids && in_array( $field_id, $name_field_ids, true ) ) {
871 871 // If there is name field in the form, we should always use it as author name.
@@ -985,14 +985,16 @@
985 985 if ( ! isset( $values['item_meta'][ $skipped_field->id ] ) ) {
986 986 continue;
987 987 }
988 988
989 - if ( self::should_really_skip_field( $skipped_field, $values ) ) {
990 - unset( $values['item_meta'][ $skipped_field->id ] );
989 + if ( ! self::should_really_skip_field( $skipped_field, $values ) ) {
990 + continue;
991 + }
991 992
992 - if ( isset( $values['item_meta']['other'][ $skipped_field->id ] ) ) {
993 - unset( $values['item_meta']['other'][ $skipped_field->id ] );
994 - }
993 + unset( $values['item_meta'][ $skipped_field->id ] );
994 +
995 + if ( isset( $values['item_meta']['other'][ $skipped_field->id ] ) ) {
996 + unset( $values['item_meta']['other'][ $skipped_field->id ] );
995 997 }
996 998 }
997 999 }
998 1000
@@ -1018,13 +1020,12 @@
1018 1020 // Check if an error happens when unserializing, or empty options.
1019 1021 return true;
1020 1022 }
1021 1023
1022 - end( $field_data->options );
1023 - $last_key = key( $field_data->options );
1024 + $last_key = array_key_last( $field_data->options );
1024 1025
1025 1026 // If a choice field has no Other option.
1026 - if ( is_numeric( $last_key ) || 0 !== strpos( $last_key, 'other_' ) ) {
1027 + if ( is_numeric( $last_key ) || ! str_starts_with( $last_key, 'other_' ) ) {
1027 1028 return true;
1028 1029 }
1029 1030
1030 1031 // If a choice field has Other option, but Other is not selected.
@@ -1033,9 +1034,9 @@
1033 1034 }
1034 1035
1035 1036 // Check if submitted value is same as one of field option.
1036 1037 foreach ( $field_data->options as $option ) {
1037 - $option_value = ! is_array( $option ) ? $option : ( $option['value'] ?? '' );
1038 + $option_value = is_array( $option ) ? ( $option['value'] ?? '' ) : $option;
1038 1039
1039 1040 if ( $values['item_meta']['other'][ $field_data->id ] === $option_value ) {
1040 1041 return true;
1041 1042 }
@@ -1083,10 +1084,9 @@
1083 1084 *
1084 1085 * @return void
1085 1086 */
1086 1087 public static function prepare_values_for_spam_check( &$values ) {
1087 - $form_ids = self::get_all_form_ids_and_flatten_meta( $values );
1088 - $values['form_ids'] = $form_ids;
1088 + $values['form_ids'] = self::get_all_form_ids_and_flatten_meta( $values );
1089 1089 }
1090 1090
1091 1091 /**
1092 1092 * Gets all form IDs (include child form IDs) and flatten item_meta array. Used for skipping values sent to Akismet.
@@ -1098,9 +1098,9 @@
1098 1098 * @param array $values Entry values.
1099 1099 *
1100 1100 * @return array Form IDs.
1101 1101 */
1102 - private static function get_all_form_ids_and_flatten_meta( &$values ) {
1102 + private static function get_all_form_ids_and_flatten_meta( &$values ) { // phpcs:ignore SlevomatCodingStandard.Complexity.Cognitive.ComplexityTooHigh
1103 1103 $values['name_field_ids'] = array();
1104 1104
1105 1105 // Blacklist check for File field in the old version doesn't contain `form_id`.
1106 1106 $form_ids = isset( $values['form_id'] ) ? array( absint( $values['form_id'] ) ) : array();
@@ -1139,10 +1139,9 @@
1139 1139 }
1140 1140
1141 1141 // Convert name array to string.
1142 1142 if ( isset( $subsubvalue['first'] ) && isset( $subsubvalue['last'] ) ) {
1143 - $subsubvalue = trim( implode( ' ', $subsubvalue ) );
1144 -
1143 + $subsubvalue = trim( implode( ' ', $subsubvalue ) );
1145 1144 $values['name_field_ids'][] = $subsubindex;
1146 1145 }
1147 1146
1148 1147 if ( is_array( $values['item_meta'][ $subsubindex ] ) ) {