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/helpers/FrmFieldsHelper.php +402 -205 6.26 → trunk View file →
@@ -18,10 +18,9 @@
18 18 *
19 19 * @return array
20 20 */
21 21 public static function setup_new_vars( $type = '', $form_id = '' ) {
22 -
23 - if ( strpos( $type, '|' ) ) {
22 + if ( str_contains( $type, '|' ) ) {
24 23 list( $type, $setting ) = explode( '|', $type );
25 24 }
26 25
27 26 $values = self::get_default_field( $type );
@@ -71,9 +70,8 @@
71 70 * @return array
72 71 */
73 72 public static function setup_edit_vars( $field, $doing_ajax = false ) {
74 73 $values = self::field_object_to_array( $field );
75 -
76 74 return apply_filters( 'frm_setup_edit_field_vars', $values, array( 'doing_ajax' => $doing_ajax ) );
77 75 }
78 76
79 77 /**
@@ -167,16 +165,18 @@
167 165 * @param int|string $entry_id
168 166 * @param array $args
169 167 */
170 168 $field_array = apply_filters( 'frm_setup_edit_fields_vars', $field_array, $field, $args['entry_id'], $args );
171 - } else {
172 - /**
173 - * @param array $field_array
174 - * @param stdClass $field
175 - * @param array $args
176 - */
177 - $field_array = apply_filters( 'frm_setup_new_fields_vars', $field_array, $field, $args );
169 +
170 + return;
178 171 }
172 +
173 + /**
174 + * @param array $field_array
175 + * @param stdClass $field
176 + * @param array $args
177 + */
178 + $field_array = apply_filters( 'frm_setup_new_fields_vars', $field_array, $field, $args );
179 179 }
180 180
181 181 /**
182 182 * @since 3.0
@@ -186,9 +186,8 @@
186 186 * @return array
187 187 */
188 188 public static function get_default_field_options( $type ) {
189 189 $field_type = FrmFieldFactory::get_field_type( $type );
190 -
191 190 return $field_type->get_default_field_options();
192 191 }
193 192
194 193 /**
@@ -279,8 +278,9 @@
279 278 *
280 279 * @return void
281 280 */
282 281 private static function fill_cleared_strings( $field, array &$field_array ) {
282 + // phpcs:ignore Universal.Operators.StrictComparisons
283 283 if ( '' == $field_array['blank'] && '1' === $field_array['required'] ) {
284 284 $field_array['blank'] = self::default_blank_msg();
285 285 }
286 286
@@ -292,8 +292,9 @@
292 292 $field_array['invalid'] = self::default_invalid_msg();
293 293 }
294 294 }
295 295
296 + // phpcs:ignore Universal.Operators.StrictComparisons
296 297 if ( '' == $field_array['custom_html'] ) {
297 298 $field_array['custom_html'] = self::get_default_html( $field->type );
298 299 }
299 300 }
@@ -315,10 +316,9 @@
315 316 */
316 317 public static function default_unique_msg() {
317 318 $frm_settings = FrmAppHelper::get_settings();
318 319 $unique_message = $frm_settings->unique_msg;
319 - $unique_message = str_replace( 'This value', '[field_name]', $unique_message );
320 - return $unique_message;
320 + return str_replace( 'This value', '[field_name]', $unique_message );
321 321 }
322 322
323 323 /**
324 324 * @since 6.8.3
@@ -327,10 +327,9 @@
327 327 */
328 328 public static function default_blank_msg() {
329 329 $frm_settings = FrmAppHelper::get_settings();
330 330 $blank_message = $frm_settings->blank_msg;
331 - $blank_message = str_replace( 'This field', '[field_name]', $blank_message );
332 - return $blank_message;
331 + return str_replace( 'This field', '[field_name]', $blank_message );
333 332 }
334 333
335 334 /**
336 335 * When loading settings for a field, check the $_POST data and possibly use that instead of the DB value.
@@ -346,20 +345,20 @@
346 345 if ( ! isset( $_POST['field_options'][ $setting ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
347 346 return;
348 347 }
349 348
350 - if ( strpos( $setting, 'html' ) !== false ) {
351 - $value = wp_unslash( $_POST['field_options'][ $setting ] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing
349 + if ( str_contains( $setting, 'html' ) ) {
350 + $value = wp_unslash( $_POST['field_options'][ $setting ] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing, SlevomatCodingStandard.Files.LineLength.LineTooLong
352 351
353 352 // Conditionally strip script tags if the user sending $_POST data is not allowed to use unfiltered HTML.
354 353 if ( ! FrmAppHelper::allow_unfiltered_html() ) {
355 354 $value = FrmAppHelper::kses( $value, 'all' );
356 355 }
357 - } elseif ( strpos( $setting, 'format_' ) === 0 ) {
356 + } elseif ( str_starts_with( $setting, 'format_' ) ) {
358 357 // TODO: Remove stripslashes on output, and use on input only.
359 - $value = sanitize_text_field( $_POST['field_options'][ $setting ] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.NonceVerification.Missing
358 + $value = sanitize_text_field( $_POST['field_options'][ $setting ] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.NonceVerification.Missing, SlevomatCodingStandard.Files.LineLength.LineTooLong
360 359 } else {
361 - $value = wp_unslash( $_POST['field_options'][ $setting ] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing
360 + $value = wp_unslash( $_POST['field_options'][ $setting ] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing, SlevomatCodingStandard.Files.LineLength.LineTooLong
362 361 FrmAppHelper::sanitize_value( 'wp_kses_post', $value );
363 362 }
364 363 }
365 364
@@ -373,13 +372,11 @@
373 372 */
374 373 public static function get_default_field_options_from_field( $field, $values = array() ) {
375 374 $field_type = self::get_original_field( $field );
376 375 $opts = $field_type->get_default_field_options();
376 + $opts = apply_filters( 'frm_default_field_opts', $opts, $values, $field );
377 377
378 - $opts = apply_filters( 'frm_default_field_opts', $opts, $values, $field );
379 - $opts = apply_filters( 'frm_default_' . $field->type . '_field_opts', $opts, $values, $field );
380 -
381 - return $opts;
378 + return apply_filters( 'frm_default_' . $field->type . '_field_opts', $opts, $values, $field );
382 379 }
383 380
384 381 /**
385 382 * @since 3.0
@@ -390,9 +387,9 @@
390 387 */
391 388 private static function get_original_field( $field ) {
392 389 $original_type = FrmField::get_option( $field, 'original_type' );
393 390
394 - if ( ! empty( $original_type ) && $field->type != $original_type ) {
391 + if ( $original_type && $field->type !== $original_type ) {
395 392 $field->type = $original_type;
396 393 }
397 394
398 395 return FrmFieldFactory::get_field_object( $field );
@@ -420,9 +417,8 @@
420 417 * @return array
421 418 */
422 419 public static function get_default_field( $type ) {
423 420 $field_type = FrmFieldFactory::get_field_type( $type );
424 -
425 421 return $field_type->get_new_field_defaults();
426 422 }
427 423
428 424 /**
@@ -455,11 +451,10 @@
455 451 * @return string
456 452 */
457 453 public static function get_error_msg( $field, $error ) {
458 454 $frm_settings = FrmAppHelper::get_settings();
459 -
460 - $conf_msg = __( 'The entered values do not match', 'formidable' );
461 - $defaults = array(
455 + $conf_msg = __( 'The entered values do not match', 'formidable' );
456 + $defaults = array(
462 457 'unique_msg' => array(
463 458 'full' => self::default_unique_msg(),
464 459 /* translators: %s: Field name */
465 460 'part' => sprintf( __( '%s must be unique', 'formidable' ), '[field_name]' ),
@@ -478,15 +473,21 @@
478 473 'part' => $conf_msg,
479 474 ),
480 475 );
481 476
477 + /**
478 + * @since 6.28
479 + *
480 + * @param array $defaults
481 + * @param array|object $field
482 + */
483 + $defaults = apply_filters( 'frm_default_field_validation_messages', $defaults, $field );
484 +
482 485 $msg = FrmField::get_option( $field, $error );
483 - $msg = empty( $msg ) ? $defaults[ $error ]['part'] : $msg;
486 + $msg = $msg ? $msg : $defaults[ $error ]['part'];
484 487 $msg = do_shortcode( $msg );
485 488
486 - $msg = self::maybe_replace_substrings_with_field_name( $msg, $error, $field );
487 -
488 - return $msg;
489 + return self::maybe_replace_substrings_with_field_name( $msg, $error, $field );
489 490 }
490 491
491 492 /**
492 493 * @since 6.8.3
@@ -503,17 +504,12 @@
503 504 $substrings = self::get_substrings_to_replace_with_field_name( $field_name, compact( 'msg', 'error', 'field' ) );
504 505
505 506 // Use the "This value"/"This field" placeholder strings if field name is empty.
506 507 if ( ! $field_name ) {
507 - if ( 'unique_msg' === $error ) {
508 - $field_name = __( 'This value', 'formidable' );
509 - } else {
510 - $field_name = __( 'This field', 'formidable' );
511 - }
508 + $field_name = 'unique_msg' === $error ? __( 'This value', 'formidable' ) : __( 'This field', 'formidable' );
512 509 }
513 510
514 - $msg = str_replace( $substrings, $field_name, $msg );
515 - return $msg;
511 + return str_replace( $substrings, $field_name, $msg );
516 512 }
517 513
518 514 /**
519 515 * @since 6.8.3
@@ -575,9 +571,9 @@
575 571 public static function get_default_html( $type = 'text' ) {
576 572 $field = FrmFieldFactory::get_field_type( $type );
577 573 $default_html = $field->default_html();
578 574
579 - // these hooks are here for reverse compatibility since 3.0
575 + // These hooks are here for reverse compatibility since 3.0
580 576 if ( ! apply_filters( 'frm_normal_field_type_html', true, $type ) ) {
581 577 $default_html = apply_filters( 'frm_other_custom_html', '', $type );
582 578 }
583 579
@@ -593,8 +589,12 @@
593 589 * @return void
594 590 */
595 591 public static function show_fields( $fields, $errors, $form, $form_action ) {
596 592 foreach ( $fields as $field ) {
593 + if ( ! is_array( $field ) ) {
594 + continue;
595 + }
596 +
597 597 $field_obj = FrmFieldFactory::get_field_type( $field['type'], $field );
598 598 $field_obj->show_field( compact( 'errors', 'form', 'form_action' ) );
599 599 }
600 600 }
@@ -609,15 +609,17 @@
609 609 */
610 610 public static function run_wpautop( $atts, &$value ) {
611 611 $autop = $atts['wpautop'] ?? true;
612 612
613 - if ( apply_filters( 'frm_use_wpautop', $autop ) ) {
614 - if ( is_array( $value ) ) {
615 - $value = implode( "\n", $value );
616 - }
613 + if ( ! apply_filters( 'frm_use_wpautop', $autop ) ) {
614 + return;
615 + }
617 616
618 - $value = wpautop( $value );
617 + if ( is_array( $value ) ) {
618 + $value = implode( "\n", $value );
619 619 }
620 +
621 + $value = wpautop( $value );
620 622 }
621 623
622 624 /**
623 625 * Get the class to use for the label position
@@ -629,12 +631,12 @@
629 631 * @param bool|object|string $form
630 632 *
631 633 * @return string
632 634 */
633 - public static function &label_position( $position, $field, $form ) {
634 - if ( $position && $position != '' ) {
635 + public static function label_position( $position, $field, $form ) {
636 + if ( $position ) {
635 637 if ( $position === 'inside' && ! self::is_placeholder_field_type( $field['type'] ) ) {
636 - $position = 'top';
638 + return 'top';
637 639 }
638 640
639 641 return $position;
640 642 }
@@ -649,11 +651,9 @@
649 651 $position = 'top';
650 652 }
651 653
652 654 $position = apply_filters( 'frm_html_label_position', $position, $field, $form );
653 - $position = ! empty( $position ) ? $position : 'top';
654 -
655 - return $position;
655 + return $position ? $position : 'top';
656 656 }
657 657
658 658 /**
659 659 * Check if this field type allows placeholders
@@ -677,9 +677,9 @@
677 677 */
678 678 public static function get_checkbox_id( $field, $opt_key, $type = 'checkbox' ) {
679 679 $id = $field['id'];
680 680
681 - if ( isset( $field['in_section'] ) && $field['in_section'] && ! FrmAppHelper::is_admin_page( 'formidable' ) ) {
681 + if ( ! empty( $field['in_section'] ) && ! FrmAppHelper::is_admin_page( 'formidable' ) ) {
682 682 $id .= '-' . $field['in_section'];
683 683 }
684 684
685 685 return 'frm_' . $type . '_' . $id . '-' . $opt_key;
@@ -696,21 +696,20 @@
696 696 if ( ! is_array( $field['options'] ) ) {
697 697 return;
698 698 }
699 699
700 - $base_name = 'default_value_' . $field['id'];
701 - $html_id = $field['html_id'] ?? self::get_html_id( $field );
702 -
700 + $base_name = 'default_value_' . $field['id'];
701 + $html_id = $field['html_id'] ?? self::get_html_id( $field );
703 702 $default_type = self::get_default_value_type( $field );
704 703 $options_count = count( $field['options'] );
705 704
706 705 foreach ( $field['options'] as $opt_key => $opt ) {
707 - $field_val = self::get_value_from_array( $opt, $opt_key, $field );
708 - $opt = self::get_label_from_array( $opt, $opt_key, $field );
709 -
706 + $field_val = self::get_value_from_array( $opt, $opt_key, $field );
707 + $opt = self::get_label_from_array( $opt, $opt_key, $field );
710 708 $field_name = $base_name . ( $default_type === 'checkbox' ? '[' . $opt_key . ']' : '' );
711 709
712 - $checked = ( isset( $field['default_value'] ) && ( ( ! is_array( $field['default_value'] ) && $field['default_value'] == $field_val ) || ( is_array( $field['default_value'] ) && in_array( $field_val, $field['default_value'] ) ) ) );
710 + // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict, Universal.Operators.StrictComparisons, SlevomatCodingStandard.Files.LineLength.LineTooLong
711 + $checked = isset( $field['default_value'] ) && ( is_array( $field['default_value'] ) ? in_array( $field_val, $field['default_value'] ) : $field['default_value'] == $field_val );
713 712
714 713 // If this is an "Other" option, get the HTML for it.
715 714 if ( self::is_other_opt( $opt_key ) ) {
716 715 if ( FrmAppHelper::pro_is_installed() ) {
@@ -740,17 +739,16 @@
740 739 if ( $ajax_action === 'frm_add_field_option' ) {
741 740 return;
742 741 }
743 742
744 - $opt_key = '000';
745 - $field_val = __( 'New Option', 'formidable' );
746 - $opt = __( 'New Option', 'formidable' );
747 - $checked = false;
748 - $field_name = 'default_value_' . $field['id'];
749 - $html_id = $field['html_id'] ?? self::get_html_id( $field );
750 -
743 + $opt_key = '000';
744 + $field_val = __( 'New Option', 'formidable' );
745 + $opt = __( 'New Option', 'formidable' );
746 + $checked = false;
747 + $field_name = 'default_value_' . $field['id'];
748 + $html_id = $field['html_id'] ?? self::get_html_id( $field );
751 749 $default_type = self::get_default_value_type( $field );
752 - $field_name .= ( $default_type === 'checkbox' ? '[' . $opt_key . ']' : '' );
750 + $field_name .= $default_type === 'checkbox' ? '[' . $opt_key . ']' : '';
753 751
754 752 require FrmAppHelper::plugin_path() . '/classes/views/frm-fields/single-option.php';
755 753 }
756 754
@@ -761,14 +759,12 @@
761 759 *
762 760 * @return string radio or checkbox
763 761 */
764 762 private static function get_default_value_type( $field ) {
765 - $default_type = $field['type'];
766 -
767 763 if ( $field['type'] === 'select' ) {
768 - $default_type = FrmField::is_multiple_select( $field ) ? 'checkbox' : 'radio';
764 + return FrmField::is_multiple_select( $field ) ? 'checkbox' : 'radio';
769 765 }
770 - return $default_type;
766 + return $field['type'];
771 767 }
772 768
773 769 /**
774 770 * @param array|string $opt
@@ -778,9 +774,8 @@
778 774 * @return mixed
779 775 */
780 776 public static function get_value_from_array( $opt, $opt_key, $field ) {
781 777 $opt = apply_filters( 'frm_field_value_saved', $opt, $opt_key, $field );
782 -
783 778 return FrmFieldsController::check_value( $opt, $opt_key, $field );
784 779 }
785 780
786 781 /**
@@ -791,9 +786,8 @@
791 786 * @return string
792 787 */
793 788 public static function get_label_from_array( $opt, $opt_key, $field ) {
794 789 $opt = apply_filters( 'frm_field_label_seen', $opt, $opt_key, $field );
795 -
796 790 return FrmFieldsController::check_label( $opt );
797 791 }
798 792
799 793 /**
@@ -829,15 +823,17 @@
829 823 */
830 824 public static function smart_values() {
831 825 $continue = apply_filters( 'frm_smart_values_box', true );
832 826
833 - if ( $continue === true ) {
834 - $upgrade_link = array(
835 - 'medium' => 'builder',
836 - 'content' => 'smart-tags',
837 - );
838 - include FrmAppHelper::plugin_path() . '/classes/views/frm-fields/back-end/smart-values.php';
827 + if ( $continue !== true ) {
828 + return;
839 829 }
830 +
831 + $upgrade_link = array(
832 + 'medium' => 'builder',
833 + 'content' => 'smart-tags',
834 + );
835 + include FrmAppHelper::plugin_path() . '/classes/views/frm-fields/back-end/smart-values.php';
840 836 }
841 837
842 838 /**
843 839 * @since 4.0
@@ -868,19 +864,16 @@
868 864 if ( ! $tax ) {
869 865 return '';
870 866 }
871 867
872 - $link = sprintf(
868 + return sprintf(
873 869 /* translators: %1$s: Start HTML link, %2$s: Content type label, %3$s: Content type, %4$s: End HTML link */
874 870 esc_html__( 'Options are dynamically created from your %1$s%2$s: %3$s%4$s', 'formidable' ),
875 871 '<a href="' . esc_url( admin_url( 'edit-tags.php?taxonomy=' . $tax->name ) ) . '" target="_blank">',
876 872 esc_html__( 'taxonomy', 'formidable' ),
877 - empty( $tax->labels->name ) ? esc_html__( 'Categories', 'formidable' ) : $tax->labels->name,
873 + ! empty( $tax->labels->name ) ? $tax->labels->name : esc_html__( 'Categories', 'formidable' ),
878 874 '</a>'
879 875 );
880 - unset( $tax );
881 -
882 - return $link;
883 876 }
884 877
885 878 /**
886 879 * @param array|string $observed_value
@@ -899,11 +892,11 @@
899 892
900 893 $m = false;
901 894
902 895 if ( $cond === '==' ) {
903 - $m = $observed_value == $hide_opt;
896 + $m = $observed_value == $hide_opt; // phpcs:ignore Universal.Operators.StrictComparisons
904 897 } elseif ( $cond === '!=' ) {
905 - $m = $observed_value != $hide_opt;
898 + $m = $observed_value != $hide_opt; // phpcs:ignore Universal.Operators.StrictComparisons
906 899 } elseif ( $cond === '>' ) {
907 900 $m = $observed_value > $hide_opt;
908 901 } elseif ( $cond === '>=' ) {
909 902 $m = $observed_value >= $hide_opt;
@@ -912,21 +905,16 @@
912 905 } elseif ( $cond === '<=' ) {
913 906 $m = $observed_value <= $hide_opt;
914 907 } elseif ( $cond === 'LIKE' || $cond === 'not LIKE' ) {
915 908 $m = stripos( $observed_value, $hide_opt );
916 -
917 - if ( $cond === 'not LIKE' ) {
918 - $m = $m === false;
919 - } else {
920 - $m = $m !== false;
921 - }
909 + $m = $cond === 'not LIKE' ? $m === false : $m !== false;
922 910 } elseif ( $cond === '%LIKE' ) {
923 - // ends with
911 + // Ends with
924 912 $length = strlen( $hide_opt );
925 913 $substr = substr( $observed_value, strlen( $observed_value ) - $length );
926 914 $m = 0 === strcasecmp( $substr, $hide_opt );
927 915 } elseif ( 'LIKE%' === $cond ) {
928 - // starts with
916 + // Starts with
929 917 $length = strlen( $hide_opt );
930 918 $substr = substr( $observed_value, 0, $length );
931 919 $m = 0 === strcasecmp( $substr, $hide_opt );
932 920 }//end if
@@ -966,20 +954,20 @@
966 954
967 955 if ( $cond === '==' ) {
968 956 if ( is_array( $hide_opt ) ) {
969 957 $m = array_intersect( $hide_opt, $observed_value );
970 - $m = ! empty( $m );
958 + $m = $m !== array();
971 959 } else {
960 + // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
972 961 $m = in_array( $hide_opt, $observed_value );
973 962 }
974 963 } elseif ( $cond === '!=' ) {
964 + // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
975 965 $m = ! in_array( $hide_opt, $observed_value );
976 966 } elseif ( $cond === '>' ) {
977 - $min = min( $observed_value );
978 - $m = $min > $hide_opt;
967 + $m = min( $observed_value ) > $hide_opt;
979 968 } elseif ( $cond === '<' ) {
980 - $max = max( $observed_value );
981 - $m = $max < $hide_opt;
969 + $m = max( $observed_value ) < $hide_opt;
982 970 } elseif ( $cond === 'LIKE' || $cond === 'not LIKE' ) {
983 971 foreach ( $observed_value as $ob ) {
984 972 $m = strpos( $ob, $hide_opt );
985 973
@@ -992,9 +980,9 @@
992 980 if ( $cond === 'not LIKE' ) {
993 981 $m = $m === false;
994 982 }
995 983 } elseif ( $cond === '%LIKE' ) {
996 - // ends with
984 + // Ends with
997 985 foreach ( $observed_value as $ob ) {
998 986 if ( $hide_opt === substr( $ob, strlen( $ob ) - strlen( $hide_opt ) ) ) {
999 987 $m = true;
1000 988 break;
@@ -1000,11 +988,11 @@
1000 988 break;
1001 989 }
1002 990 }
1003 991 } elseif ( $cond === 'LIKE%' ) {
1004 - // starts with
992 + // Starts with
1005 993 foreach ( $observed_value as $ob ) {
1006 - if ( $hide_opt === substr( $ob, 0, strlen( $hide_opt ) ) ) {
994 + if ( str_starts_with( $ob, $hide_opt ) ) {
1007 995 $m = true;
1008 996 break;
1009 997 }
1010 998 }
@@ -1024,17 +1012,16 @@
1024 1012 *
1025 1013 * @return string
1026 1014 */
1027 1015 public static function basic_replace_shortcodes( $value, $form, $entry ) {
1028 - if ( strpos( $value, '[sitename]' ) !== false ) {
1016 + if ( str_contains( $value, '[sitename]' ) ) {
1029 1017 $new_value = wp_specialchars_decode( FrmAppHelper::site_name(), ENT_QUOTES );
1030 1018 $value = str_replace( '[sitename]', $new_value, $value );
1031 1019 }
1032 1020
1033 1021 $value = apply_filters( 'frm_content', $value, $form, $entry );
1034 - $value = do_shortcode( $value );
1035 1022
1036 - return $value;
1023 + return do_shortcode( $value );
1037 1024 }
1038 1025
1039 1026 /**
1040 1027 * @param string $content
@@ -1089,11 +1076,9 @@
1089 1076 $tagregexp[] = $field->id;
1090 1077 $tagregexp[] = $field->field_key;
1091 1078 }
1092 1079
1093 - $tagregexp = implode( '|', $tagregexp );
1094 -
1095 - return $tagregexp;
1080 + return implode( '|', $tagregexp );
1096 1081 }
1097 1082
1098 1083 /**
1099 1084 * @param string $content
@@ -1103,9 +1088,9 @@
1103 1088 * @return string
1104 1089 */
1105 1090 public static function replace_content_shortcodes( $content, $entry, $shortcodes ) {
1106 1091 foreach ( $shortcodes[0] as $short_key => $tag ) {
1107 - if ( empty( $tag ) ) {
1092 + if ( ! $tag ) {
1108 1093 continue;
1109 1094 }
1110 1095
1111 1096 $atts = FrmShortcodeHelper::get_shortcode_attribute_array( $shortcodes[3][ $short_key ] );
@@ -1143,10 +1128,11 @@
1143 1128 continue;
1144 1129 }
1145 1130
1146 1131 $function = 'atts_' . $included_att;
1147 - $replace_with = self::$function( $replace_with, $atts );
1132 + $replace_with = self::$function( $replace_with );
1148 1133 }
1134 +
1149 1135 return $replace_with;
1150 1136 }
1151 1137
1152 1138 /**
@@ -1267,9 +1253,9 @@
1267 1253 */
1268 1254 private static function get_field_shortcode_value( $atts ) {
1269 1255 $field = FrmField::getOne( $atts['tag'] );
1270 1256
1271 - if ( empty( $field ) ) {
1257 + if ( ! $field ) {
1272 1258 return null;
1273 1259 }
1274 1260
1275 1261 if ( isset( $atts['show'] ) && $atts['show'] === 'field_label' ) {
@@ -1284,9 +1270,10 @@
1284 1270 $sep = $atts['sep'] ?? ', ';
1285 1271 $string_value = FrmAppHelper::safe_implode( $sep, $replace_with );
1286 1272 }
1287 1273
1288 - if ( empty( $string_value ) && $string_value != '0' ) {
1274 + // phpcs:ignore Universal.Operators.StrictComparisons
1275 + if ( ! $string_value && $string_value != '0' ) {
1289 1276 $replace_with = '';
1290 1277 } else {
1291 1278 $atts['entry_id'] = $atts['entry']->id;
1292 1279 $atts['entry_key'] = $atts['entry']->item_key;
@@ -1352,9 +1339,9 @@
1352 1339 if ( ! isset( $atts['param'] ) ) {
1353 1340 return '';
1354 1341 }
1355 1342
1356 - if ( strpos( $atts['param'], '&#91;' ) ) {
1343 + if ( str_contains( $atts['param'], '&#91;' ) ) {
1357 1344 $atts['param'] = str_replace( '&#91;', '[', $atts['param'] );
1358 1345 $atts['param'] = str_replace( '&#93;', ']', $atts['param'] );
1359 1346 }
1360 1347
@@ -1360,8 +1347,9 @@
1360 1347
1361 1348 $new_value = FrmAppHelper::get_param( $atts['param'], '', 'get', 'sanitize_text_field' );
1362 1349 $new_value = FrmAppHelper::get_query_var( $new_value, $atts['param'] );
1363 1350
1351 + // phpcs:ignore Universal.Operators.StrictComparisons
1364 1352 if ( $new_value == '' ) {
1365 1353 if ( ! isset( $atts['prev_val'] ) ) {
1366 1354 $atts['prev_val'] = '';
1367 1355 }
@@ -1369,9 +1357,9 @@
1369 1357 $new_value = $atts['default'] ?? $atts['prev_val'];
1370 1358 }
1371 1359
1372 1360 if ( is_array( $new_value ) && ! $return_array ) {
1373 - $new_value = implode( ', ', $new_value );
1361 + return implode( ', ', $new_value );
1374 1362 }
1375 1363
1376 1364 return $new_value;
1377 1365 }
@@ -1383,12 +1371,10 @@
1383 1371 *
1384 1372 * @return mixed
1385 1373 */
1386 1374 public static function get_display_value( $value, $field, $atts = array() ) {
1387 -
1388 1375 $value = apply_filters( 'frm_get_' . $field->type . '_display_value', $value, $field, $atts );
1389 1376 $value = apply_filters( 'frm_get_display_value', $value, $field, $atts );
1390 -
1391 1377 $value = self::get_unfiltered_display_value( compact( 'value', 'field', 'atts' ) );
1392 1378
1393 1379 return apply_filters( 'frm_display_value', $value, $field, $atts );
1394 1380 }
@@ -1430,9 +1416,8 @@
1430 1416 'size' => 96,
1431 1417 );
1432 1418
1433 1419 $args = wp_parse_args( $args, $defaults );
1434 -
1435 1420 $user = get_userdata( $user_id );
1436 1421 $info = '';
1437 1422
1438 1423 if ( $user ) {
@@ -1443,15 +1428,15 @@
1443 1428 } else {
1444 1429 $info = $user->$user_info ?? '';
1445 1430 }
1446 1431
1447 - if ( 'display_name' === $user_info && empty( $info ) && ! $args['blank'] ) {
1432 + if ( 'display_name' === $user_info && ! $info && ! $args['blank'] ) {
1448 1433 $info = $user->user_login;
1449 1434 }
1450 1435 }
1451 1436
1452 1437 if ( $args['link'] ) {
1453 - $info = '<a href="' . esc_url( admin_url( 'user-edit.php?user_id=' . $user_id ) ) . '">' . $info . '</a>';
1438 + return '<a href="' . esc_url( admin_url( 'user-edit.php?user_id=' . $user_id ) ) . '">' . $info . '</a>';
1454 1439 }
1455 1440
1456 1441 return $info;
1457 1442 }
@@ -1474,11 +1459,9 @@
1474 1459 } elseif ( isset( $field_selection[ $type ] ) ) {
1475 1460 $field_types[ $type ] = $field_selection[ $type ];
1476 1461 }
1477 1462
1478 - $field_types = apply_filters( 'frm_switch_field_types', $field_types, compact( 'type', 'field_selection' ) );
1479 -
1480 - return $field_types;
1463 + return apply_filters( 'frm_switch_field_types', $field_types, compact( 'type', 'field_selection' ) );
1481 1464 }
1482 1465
1483 1466 /**
1484 1467 * Get a list of all fields that use a single value input.
@@ -1532,9 +1515,9 @@
1532 1515 *
1533 1516 * @return bool Returns true if current field option is an "Other" option
1534 1517 */
1535 1518 public static function is_other_opt( $opt_key ) {
1536 - return $opt_key && strpos( $opt_key, 'other_' ) === 0;
1519 + return $opt_key && str_starts_with( $opt_key, 'other_' );
1537 1520 }
1538 1521
1539 1522 /**
1540 1523 * Get value that belongs in "Other" text box
@@ -1544,17 +1527,16 @@
1544 1527 * @param array $args
1545 1528 *
1546 1529 * @return string
1547 1530 */
1548 - public static function get_other_val( $args ) {
1549 - $defaults = array(
1531 + public static function get_other_val( $args ) { // phpcs:ignore SlevomatCodingStandard.Complexity.Cognitive.ComplexityTooHigh
1532 + $defaults = array(
1550 1533 'opt_key' => 0,
1551 1534 'field' => array(),
1552 1535 'parent' => false,
1553 1536 'pointer' => false,
1554 1537 );
1555 - $args = wp_parse_args( $args, $defaults );
1556 -
1538 + $args = wp_parse_args( $args, $defaults );
1557 1539 $opt_key = $args['opt_key'];
1558 1540 $field = $args['field'];
1559 1541 $parent = $args['parent'];
1560 1542 $pointer = $args['pointer'];
@@ -1560,9 +1542,9 @@
1560 1542 $pointer = $args['pointer'];
1561 1543 $other_val = '';
1562 1544
1563 1545 // If option is an "other" option and there is a value set for this field,
1564 - // check if the value belongs in the current "Other" option text field
1546 + // Check if the value belongs in the current "Other" option text field
1565 1547 if ( ! self::is_other_opt( $opt_key ) || ! FrmField::is_option_true( $field, 'value' ) ) {
1566 1548 return $other_val;
1567 1549 }
1568 1550
@@ -1569,12 +1551,12 @@
1569 1551 // Check posted vals before checking saved values
1570 1552 // For fields inside repeating sections - note, don't check if $pointer is true because it will often be zero
1571 1553 if ( $parent && isset( $_POST['item_meta'][ $parent ][ $pointer ]['other'][ $field['id'] ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
1572 1554 if ( FrmField::is_field_with_multiple_values( $field ) ) {
1555 + $other_val = isset( $_POST['item_meta'][ $parent ][ $pointer ]['other'][ $field['id'] ][ $opt_key ] ) ? sanitize_text_field( wp_unslash( $_POST['item_meta'][ $parent ][ $pointer ]['other'][ $field['id'] ][ $opt_key ] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing, SlevomatCodingStandard.Files.LineLength.LineTooLong
1556 + } else {
1573 1557 // phpcs:ignore WordPress.Security.NonceVerification.Missing
1574 - $other_val = isset( $_POST['item_meta'][ $parent ][ $pointer ]['other'][ $field['id'] ][ $opt_key ] ) ? sanitize_text_field( wp_unslash( $_POST['item_meta'][ $parent ][ $pointer ]['other'][ $field['id'] ][ $opt_key ] ) ) : '';
1575 - } else {
1576 - $other_val = sanitize_text_field( wp_unslash( $_POST['item_meta'][ $parent ][ $pointer ]['other'][ $field['id'] ] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
1558 + $other_val = sanitize_text_field( wp_unslash( $_POST['item_meta'][ $parent ][ $pointer ]['other'][ $field['id'] ] ) );
1577 1559 }
1578 1560
1579 1561 return $other_val;
1580 1562 }
@@ -1582,9 +1564,9 @@
1582 1564 if ( isset( $field['id'] ) && isset( $_POST['item_meta']['other'][ $field['id'] ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
1583 1565 // For normal fields
1584 1566
1585 1567 if ( FrmField::is_field_with_multiple_values( $field ) ) {
1586 - // phpcs:ignore WordPress.Security.NonceVerification.Missing
1568 + // phpcs:ignore WordPress.Security.NonceVerification.Missing, SlevomatCodingStandard.Files.LineLength.LineTooLong
1587 1569 $other_val = isset( $_POST['item_meta']['other'][ $field['id'] ][ $opt_key ] ) ? sanitize_text_field( wp_unslash( $_POST['item_meta']['other'][ $field['id'] ][ $opt_key ] ) ) : '';
1588 1570 } else {
1589 1571 $other_val = sanitize_text_field( wp_unslash( $_POST['item_meta']['other'][ $field['id'] ] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
1590 1572 }
@@ -1595,8 +1577,9 @@
1595 1577 // For checkboxes
1596 1578 if ( $field['type'] === 'checkbox' && is_array( $field['value'] ) ) {
1597 1579 // Check if there is an "other" val in saved value and make sure the
1598 1580 // "other" val is not equal to the Other checkbox option
1581 + // phpcs:ignore Universal.Operators.StrictComparisons
1599 1582 if ( isset( $field['value'][ $opt_key ] ) && $field['options'][ $opt_key ] != $field['value'][ $opt_key ] ) {
1600 1583 $other_val = $field['value'][ $opt_key ];
1601 1584 }
1602 1585 } else {
@@ -1608,14 +1591,15 @@
1608 1591 $temp_val = is_array( $opt_val ) ? $opt_val['value'] : $opt_val;
1609 1592
1610 1593 // Multi-select dropdowns - key is not preserved
1611 1594 if ( is_array( $field['value'] ) ) {
1595 + // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
1612 1596 $o_key = array_search( $temp_val, $field['value'] );
1613 1597
1614 1598 if ( isset( $field['value'][ $o_key ] ) ) {
1615 1599 unset( $field['value'][ $o_key ], $o_key );
1616 1600 }
1617 - } elseif ( $temp_val == $field['value'] ) {
1601 + } elseif ( $temp_val == $field['value'] ) { // phpcs:ignore Universal.Operators.StrictComparisons
1618 1602 // For radio and regular dropdowns
1619 1603 return '';
1620 1604 } else {
1621 1605 $other_val = $field['value'];
@@ -1623,9 +1607,9 @@
1623 1607 unset( $opt_val, $temp_val );
1624 1608 }
1625 1609
1626 1610 // For multi-select dropdowns only
1627 - if ( is_array( $field['value'] ) && ! empty( $field['value'] ) ) {
1611 + if ( is_array( $field['value'] ) && $field['value'] ) {
1628 1612 $other_val = reset( $field['value'] );
1629 1613 }
1630 1614 }//end if
1631 1615
@@ -1641,9 +1625,9 @@
1641 1625 * @param array $args Should include field, opt_key and field name.
1642 1626 * @param bool $other_opt
1643 1627 * @param string $checked
1644 1628 *
1645 - * @return array $other_args
1629 + * @return array Other args.
1646 1630 */
1647 1631 public static function prepare_other_input( $args, &$other_opt, &$checked ) {
1648 1632 $other_args = array(
1649 1633 'name' => '',
@@ -1748,9 +1732,9 @@
1748 1732
1749 1733 $classes = array( 'frm_other_input' );
1750 1734
1751 1735 if ( ! $args['checked'] || trim( $args['checked'] ) === '' ) {
1752 - // hide the field if the other option is not selected
1736 + // Hide the field if the other option is not selected
1753 1737 $classes[] = 'frm_pos_none';
1754 1738 }
1755 1739
1756 1740 if ( $args['field']['type'] === 'select' && ! empty( $args['field']['multiple'] ) ) {
@@ -1761,8 +1745,9 @@
1761 1745 $other_id = self::get_other_field_html_id( $args['field']['type'], $args['html_id'], $args['opt_key'] );
1762 1746
1763 1747 $label = $args['opt_label'] ?? $args['field']['name'];
1764 1748
1749 + // phpcs:disable Generic.WhiteSpace.ScopeIndent
1765 1750 echo '<label for="' . esc_attr( $other_id ) . '" class="frm_screen_reader frm_hidden">' .
1766 1751 esc_html( $label ) .
1767 1752 '</label>' .
1768 1753 '<input type="text" id="' . esc_attr( $other_id ) . '" class="' . esc_attr( implode( ' ', $classes ) ) . '" ' .
@@ -1767,8 +1752,9 @@
1767 1752 '</label>' .
1768 1753 '<input type="text" id="' . esc_attr( $other_id ) . '" class="' . esc_attr( implode( ' ', $classes ) ) . '" ' .
1769 1754 ( $args['read_only'] ? ' readonly="readonly" disabled="disabled"' : '' ) .
1770 1755 ' name="' . esc_attr( $args['name'] ) . '" value="' . esc_attr( $args['value'] ) . '" />';
1756 + // phpcs:enable Generic.WhiteSpace.ScopeIndent
1771 1757 }
1772 1758
1773 1759 /**
1774 1760 * Get the HTML id for an "Other" text field
@@ -1779,9 +1765,9 @@
1779 1765 * @param string $type Field type.
1780 1766 * @param string $html_id
1781 1767 * @param bool|string $opt_key
1782 1768 *
1783 - * @return string $other_id
1769 + * @return string Other ID.
1784 1770 */
1785 1771 public static function get_other_field_html_id( $type, $html_id, $opt_key = false ) {
1786 1772 $other_id = $html_id;
1787 1773
@@ -1793,17 +1779,15 @@
1793 1779 if ( $opt_key !== false ) {
1794 1780 $other_id .= '-' . $opt_key;
1795 1781 }
1796 1782
1797 - $other_id .= '-otext';
1798 -
1799 - return $other_id;
1783 + return $other_id . '-otext';
1800 1784 }
1801 1785
1802 1786 /**
1803 - * @param string $val
1787 + * @param array|string $val
1804 1788 *
1805 - * @return string
1789 + * @return array|string
1806 1790 */
1807 1791 public static function switch_field_ids( $val ) {
1808 1792 global $frm_duplicate_ids;
1809 1793 $replace = array();
@@ -1837,22 +1821,25 @@
1837 1821 $replace_with[] = '_field":"' . $new . '","';
1838 1822 unset( $old, $new );
1839 1823 }//end foreach
1840 1824
1841 - if ( is_array( $val ) ) {
1842 - foreach ( $val as $k => $v ) {
1843 - if ( is_string( $v ) ) {
1844 - if ( 'custom_html' === $k ) {
1845 - $val[ $k ] = self::switch_ids_except_strings( $replace, $replace_with, array( '[if description]', '[description]', '[/if description]' ), $v );
1846 - unset( $k, $v );
1847 - continue;
1848 - }
1849 - $val[ $k ] = str_replace( $replace, $replace_with, $v );
1850 - unset( $k, $v );
1851 - }
1825 + if ( ! is_array( $val ) ) {
1826 + return str_replace( $replace, $replace_with, $val );
1827 + }
1828 +
1829 + foreach ( $val as $k => $v ) {
1830 + if ( ! is_string( $v ) ) {
1831 + continue;
1852 1832 }
1853 - } else {
1854 - $val = str_replace( $replace, $replace_with, $val );
1833 +
1834 + if ( 'custom_html' === $k ) {
1835 + $val[ $k ] = self::switch_ids_except_strings( $replace, $replace_with, array( '[if description]', '[description]', '[/if description]' ), $v );
1836 + unset( $k, $v );
1837 + continue;
1838 + }
1839 +
1840 + $val[ $k ] = str_replace( $replace, $replace_with, $v );
1841 + unset( $k, $v );
1855 1842 }
1856 1843
1857 1844 return $val;
1858 1845 }
@@ -1879,10 +1866,9 @@
1879 1866 unset( $replace[ $index ] );
1880 1867 unset( $replace_with[ $index ] );
1881 1868 }
1882 1869
1883 - $value = str_replace( $replace, $replace_with, $value );
1884 - return $value;
1870 + return str_replace( $replace, $replace_with, $value );
1885 1871 }
1886 1872
1887 1873 /**
1888 1874 * @since 4.0
@@ -2378,8 +2364,39 @@
2378 2364 return $field_array + $field_options;
2379 2365 }
2380 2366
2381 2367 /**
2368 + * Shows add field link.
2369 + *
2370 + * @since 6.30
2371 + *
2372 + * @param array $field_type See file `classes/views/frm-forms/add_field_links.php`.
2373 + *
2374 + * @return void
2375 + */
2376 + public static function show_add_field_link( $field_type ) {
2377 + $field_label = FrmFormsHelper::get_field_link_name( $field_type );
2378 + $classes = 'frmbutton frm6 frm_t' . $field_type['key'];
2379 +
2380 + if ( ! empty( $field_type['hide'] ) ) {
2381 + $classes .= ' frm_hidden';
2382 + }
2383 + ?>
2384 +<li class="<?php echo esc_attr( $classes ); ?>" id="<?php echo esc_attr( $field_type['key'] ); ?>">
2385 + <a href="#" class="frm_add_field" title="<?php echo esc_attr( $field_label ); ?>" role="button" aria-label="<?php echo esc_attr( $field_label ); ?>">
2386 + <?php FrmAppHelper::icon_by_class( FrmFormsHelper::get_field_link_icon( $field_type ) ); ?>
2387 + <span><?php echo esc_html( $field_label ); ?></span>
2388 + <?php
2389 + if ( 'credit_card' === $field_type['key'] && ! FrmTransLiteAppHelper::payments_table_exists() ) {
2390 + FrmAppHelper::show_pill_text();
2391 + }
2392 + ?>
2393 + </a>
2394 +</li>
2395 + <?php
2396 + }
2397 +
2398 + /**
2382 2399 * @since 4.04
2383 2400 *
2384 2401 * @param array $args
2385 2402 *
@@ -2398,34 +2415,22 @@
2398 2415 $field_label .= ob_get_clean();
2399 2416 }
2400 2417
2401 2418 // If the individual field isn't allowed, disable it.
2402 - $run_filter = true;
2403 - $single_no_allow = ' ';
2404 - $install_data = '';
2405 - $requires = '';
2406 - $link = isset( $field_type['link'] ) ? esc_url_raw( $field_type['link'] ) : '';
2407 - $has_show_upgrade_class = isset( $field_type['icon'] ) && strpos( $field_type['icon'], ' frm_show_upgrade' );
2408 - $show_upgrade = $has_show_upgrade_class || false !== strpos( $args['no_allow_class'], 'frm_show_upgrade' );
2419 + $link = isset( $field_type['link'] ) ? esc_url_raw( $field_type['link'] ) : '';
2409 2420
2410 - if ( $has_show_upgrade_class ) {
2411 - $single_no_allow .= 'frm_show_upgrade';
2412 - $field_type['icon'] = str_replace( ' frm_show_upgrade', '', $field_type['icon'] );
2413 - $run_filter = false;
2421 + list(
2422 + $run_filter,
2423 + $single_no_allow,
2424 + $install_data,
2425 + $requires,
2426 + $has_show_upgrade_class,
2427 + $has_show_update_class,
2428 + $upgrading,
2429 + $update_addon_name
2430 + ) = self::get_field_upgrade_state( $field_type );
2414 2431
2415 - if ( isset( $field_type['addon'] ) ) {
2416 - $upgrading = FrmAddonsController::install_link( $field_type['addon'] );
2417 -
2418 - if ( isset( $upgrading['url'] ) ) {
2419 - $install_data = json_encode( $upgrading );
2420 - }
2421 -
2422 - $requires = FrmFormsHelper::get_plan_required( $upgrading );
2423 - } elseif ( isset( $field_type['require'] ) ) {
2424 - $requires = $field_type['require'];
2425 - }
2426 - }
2427 -
2432 + $show_upgrade = $has_show_upgrade_class || $has_show_update_class || str_contains( $args['no_allow_class'], 'frm_show_upgrade' );
2428 2433 $upgrade_label = '';
2429 2434 $upgrade_message = '';
2430 2435
2431 2436 if ( $show_upgrade ) {
@@ -2451,8 +2456,12 @@
2451 2456 if ( ! empty( $field_type['hide'] ) ) {
2452 2457 $li_params['class'] .= ' frm_hidden';
2453 2458 }
2454 2459
2460 + if ( ! $show_upgrade && ! empty( $field_type['limit'] ) ) {
2461 + $li_params = self::update_params_with_limit_data( $li_params, $args['id'], $field_key, $field_type['limit'] );
2462 + }
2463 +
2455 2464 if ( ! empty( $field_type['upsell_image'] ) ) {
2456 2465 $li_params['data-upsell-image'] = $field_type['upsell_image'];
2457 2466 }
2458 2467
@@ -2459,14 +2468,21 @@
2459 2468 if ( ! empty( $field_type['learn-more'] ) ) {
2460 2469 $li_params['data-learn-more'] = FrmAppHelper::get_doc_url(
2461 2470 $field_type['learn-more'],
2462 2471 'form-builder-add-fields',
2463 - false !== strpos( $field_type['learn-more'], '/' )
2472 + str_contains( $field_type['learn-more'], '/' )
2464 2473 );
2465 2474 }
2466 2475
2467 - if ( isset( $upgrading['url'] ) ) {
2476 + if ( $has_show_update_class ) {
2468 2477 $li_params['data-message'] = sprintf(
2478 + // translators: %1$s: Add-on name, %2$s: Field type name.
2479 + esc_html__( 'You need a newer version of %1$s for %2$s fields.', 'formidable' ),
2480 + $update_addon_name,
2481 + $field_name
2482 + );
2483 + } elseif ( isset( $upgrading['url'] ) ) {
2484 + $li_params['data-message'] = sprintf(
2469 2485 // translators: %s: Field name
2470 2486 esc_html__( 'You already have access to %s fields, you\'ll just need to activate to start using them.', 'formidable' ),
2471 2487 $field_name
2472 2488 );
@@ -2472,8 +2488,9 @@
2472 2488 );
2473 2489 } elseif ( $upgrade_message ) {
2474 2490 $li_params['data-message'] = $upgrade_message;
2475 2491 }
2492 + // phpcs:disable Generic.WhiteSpace.ScopeIndent
2476 2493 ?>
2477 2494 <li <?php FrmAppHelper::array_to_html_params( $li_params, true ); ?>>
2478 2495 <?php
2479 2496 if ( $run_filter ) {
@@ -2478,15 +2495,118 @@
2478 2495 <?php
2479 2496 if ( $run_filter ) {
2480 2497 $field_label = apply_filters( 'frmpro_field_links', $field_label, $args['id'], $field_key );
2481 2498 }
2499 +
2482 2500 FrmAppHelper::kses_echo( $field_label, array( 'a', 'i', 'span', 'use', 'svg' ) );
2483 2501 ?>
2484 2502 </li>
2485 2503 <?php
2504 + // phpcs:enable Generic.WhiteSpace.ScopeIndent
2486 2505 }
2487 2506
2488 2507 /**
2508 + * Parse the upgrade and update flags from a field type's icon class.
2509 + *
2510 + * @since 6.29
2511 + *
2512 + * @param array $field_type Field type configuration, modified in place to strip icon flag classes.
2513 + *
2514 + * @return array Upgrade and update state values for the field button, in positional order.
2515 + */
2516 + private static function get_field_upgrade_state( &$field_type ) {
2517 + $single_no_allow = ' ';
2518 + $run_filter = true;
2519 + $has_show_upgrade_class = false;
2520 + $has_show_update_class = false;
2521 + $install_data = '';
2522 + $requires = '';
2523 + $upgrading = array();
2524 + $update_addon_name = '';
2525 +
2526 + if ( isset( $field_type['icon'] ) ) {
2527 + $has_show_upgrade_class = str_contains( $field_type['icon'], ' frm_show_upgrade' );
2528 + $has_show_update_class = str_contains( $field_type['icon'], ' frm_show_update' );
2529 + }
2530 +
2531 + if ( $has_show_upgrade_class ) {
2532 + $single_no_allow .= 'frm_show_upgrade';
2533 + $field_type['icon'] = str_replace( ' frm_show_upgrade', '', $field_type['icon'] );
2534 + $run_filter = false;
2535 +
2536 + if ( isset( $field_type['addon'] ) ) {
2537 + $upgrading = FrmAddonsController::install_link( $field_type['addon'] );
2538 +
2539 + if ( isset( $upgrading['url'] ) ) {
2540 + $install_data = json_encode( $upgrading );
2541 + }
2542 +
2543 + $requires = FrmFormsHelper::get_plan_required( $upgrading );
2544 + } elseif ( isset( $field_type['require'] ) ) {
2545 + $requires = $field_type['require'];
2546 + }
2547 + }
2548 +
2549 + if ( $has_show_update_class ) {
2550 + $single_no_allow .= ' frm_show_update';
2551 + $field_type['icon'] = str_replace( ' frm_show_update', '', $field_type['icon'] );
2552 + $run_filter = false;
2553 + $addon_slug = $field_type['addon'] ?? 'pro';
2554 +
2555 + if ( 'pro' === $addon_slug ) {
2556 + $update_addon_name = __( 'Formidable Pro', 'formidable' );
2557 + } else {
2558 + $addon_data = FrmAddonsController::get_addon( $addon_slug );
2559 + $update_addon_name = $addon_data && ! empty( $addon_data['title'] ) ? $addon_data['title'] : ucfirst( $addon_slug );
2560 + }
2561 +
2562 + $install_data = FrmAddonsController::get_update_install_data( $addon_slug );
2563 + }
2564 +
2565 + return array(
2566 + $run_filter,
2567 + $single_no_allow,
2568 + $install_data,
2569 + $requires,
2570 + $has_show_upgrade_class,
2571 + $has_show_update_class,
2572 + $upgrading,
2573 + $update_addon_name,
2574 + );
2575 + }
2576 +
2577 + /**
2578 + * Updates the params with limit data (the data-limit attribute, and possibly the frm_at_limit class).
2579 + * Some field types are limited to a certain number per form, including coupon fields.
2580 + *
2581 + * @since 6.27
2582 + *
2583 + * @param array $li_params The params.
2584 + * @param int $form_id The form ID.
2585 + * @param string $field_type The field type.
2586 + * @param int $limit The limit.
2587 + *
2588 + * @return array The updated params.
2589 + */
2590 + private static function update_params_with_limit_data( $li_params, $form_id, $field_type, $limit ) {
2591 + $fields_in_form = FrmDb::get_count(
2592 + 'frm_fields',
2593 + array(
2594 + 'form_id' => $form_id,
2595 + 'type' => $field_type,
2596 + )
2597 + );
2598 +
2599 + if ( $fields_in_form >= $limit ) {
2600 + $li_params['class'] .= ' frm_at_limit';
2601 + }
2602 +
2603 + $li_params['data-limit'] = $limit;
2604 +
2605 + return $li_params;
2606 + }
2607 +
2608 + /**
2489 2609 * Shows Display format option.
2490 2610 *
2491 2611 * @since 5.0.04
2492 2612 *
@@ -2495,11 +2615,10 @@
2495 2615 * @return void
2496 2616 */
2497 2617 public static function show_radio_display_format( $field ) {
2498 2618 $options = self::get_display_format_options( $field );
2619 + $args = self::get_display_format_args( $field, $options );
2499 2620
2500 - $args = self::get_display_format_args( $field, $options );
2501 -
2502 2621 include FrmAppHelper::plugin_path() . '/classes/views/frm-fields/back-end/radio-display-format.php';
2503 2622 }
2504 2623
2505 2624 /**
@@ -2521,9 +2640,9 @@
2521 2640 'text' => __( 'Images', 'formidable' ),
2522 2641 'svg' => 'frm_image_as_option',
2523 2642 'addon' => 'pro',
2524 2643 'upgrade' => __( 'Image Options', 'formidable' ),
2525 - 'message' => __( 'Show images instead of radio buttons or check boxes. This is ideal for polls, surveys, segmenting questionnaires and more.', 'formidable' ) . '<img src="' . esc_url( FrmAppHelper::plugin_url() ) . '/images/image-options.png" />',
2644 + 'message' => __( 'Show images instead of radio buttons or check boxes. This is ideal for polls, surveys, segmenting questionnaires and more.', 'formidable' ) . '<img src="' . esc_url( FrmAppHelper::plugin_url() ) . '/images/image-options.png" />', // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
2526 2645 'content' => 'image-options',
2527 2646 ),
2528 2647 'buttons' => array(
2529 2648 'text' => __( 'Buttons', 'formidable' ),
@@ -2534,8 +2653,12 @@
2534 2653 'content' => 'button-options',
2535 2654 ),
2536 2655 );
2537 2656
2657 + if ( 'product' === FrmField::get_field_type( $field ) ) {
2658 + unset( $options['buttons'] );
2659 + }
2660 +
2538 2661 /**
2539 2662 * Allows modifying the options of Display format setting of Radio field.
2540 2663 *
2541 2664 * @since 5.0.04
@@ -2542,11 +2665,9 @@
2542 2665 *
2543 2666 * @param array $options Options.
2544 2667 * @param array $field
2545 2668 */
2546 - $options = apply_filters( 'frm_' . $field['type'] . '_display_format_options', $options, $field );
2547 -
2548 - return $options;
2669 + return apply_filters( 'frm_' . $field['type'] . '_display_format_options', $options, $field );
2549 2670 }
2550 2671
2551 2672 /**
2552 2673 * Gets display format arguments to pass to the images_dropdown() method.
@@ -2635,15 +2756,9 @@
2635 2756 }
2636 2757
2637 2758 $upgrading = FrmAddonsController::install_link( $option['addon'] );
2638 2759
2639 - if ( isset( $upgrading['url'] ) ) {
2640 - $install_data = wp_json_encode( $upgrading );
2641 - } else {
2642 - $install_data = '';
2643 - }
2644 -
2645 - $custom_attrs['data-oneclick'] = $install_data;
2760 + $custom_attrs['data-oneclick'] = isset( $upgrading['url'] ) ? wp_json_encode( $upgrading ) : '';
2646 2761 $custom_attrs['data-requires'] = FrmFormsHelper::get_plan_required( $upgrading );
2647 2762
2648 2763 return $custom_attrs;
2649 2764 }
@@ -2728,13 +2843,14 @@
2728 2843 * @return void
2729 2844 */
2730 2845 public static function render_ai_generate_options_button( $args, $should_hide_bulk_edit = false ) {
2731 2846 $attributes = array(
2732 - 'type' => 'button',
2733 - 'class' => self::get_ai_generate_options_button_class(),
2847 + 'type' => 'button',
2734 2848 );
2735 2849
2736 - if ( ! empty( $should_hide_bulk_edit ) ) {
2850 + $attributes['class'] = ! empty( $args['class'] ) ? $args['class'] : self::get_ai_generate_options_button_class();
2851 +
2852 + if ( $should_hide_bulk_edit ) {
2737 2853 $attributes['class'] .= ' frm-force-hidden';
2738 2854 }
2739 2855
2740 2856 $data = FrmAppHelper::get_upgrade_data_params(
@@ -2740,9 +2856,9 @@
2740 2856 $data = FrmAppHelper::get_upgrade_data_params(
2741 2857 'ai',
2742 2858 array(
2743 2859 'requires' => 'Business',
2744 - 'upgrade' => __( 'Generate options with AI', 'formidable' ),
2860 + 'upgrade' => $args['upgrade_text'] ?? __( 'Generate options with AI', 'formidable' ),
2745 2861 'medium' => 'builder',
2746 2862 'content' => 'generate-options-with-ai',
2747 2863 ),
2748 2864 true
@@ -2749,16 +2865,16 @@
2749 2865 );
2750 2866
2751 2867 if ( in_array( FrmAddonsController::license_type(), array( 'elite', 'business' ), true ) && 'active' === $data['plugin-status'] ) {
2752 2868 // Backwards compatibility "@since 6.24".
2753 - if ( ! method_exists( 'FrmAIAppController', 'get_ai_generated_options_summary' ) ) {
2869 + if ( method_exists( 'FrmAIAppController', 'get_ai_generated_options_summary' ) ) {
2870 + $attributes['class'] .= ' frm-ai-generate-options-modal-trigger';
2871 + $attributes['data-fid'] = $args['likert_id'] ?? $args['field']['id'];
2872 + } else {
2754 2873 $data = array(
2755 2874 'modal-title' => __( 'Generate options with AI', 'formidable' ),
2756 2875 'modal-content' => __( 'Update the Formidable AI add-on to the last version to use this feature.', 'formidable' ),
2757 2876 );
2758 - } else {
2759 - $attributes['class'] .= ' frm-ai-generate-options-modal-trigger';
2760 - $attributes['data-fid'] = $args['likert_id'] ?? $args['field']['id'];
2761 2877 }
2762 2878 }
2763 2879
2764 2880 if ( empty( $attributes['data-fid'] ) ) {
@@ -2798,6 +2914,87 @@
2798 2914 'frm-mt-xs',
2799 2915 'frm-mb-12',
2800 2916 )
2801 2917 );
2918 + }
2919 +
2920 + /**
2921 + * Checks if the field choice should be hidden due to choice limit being reached.
2922 + *
2923 + * @since 6.28
2924 + *
2925 + * @param string $choice_key
2926 + * @param array $field
2927 + *
2928 + * @return bool
2929 + */
2930 + public static function should_hide_field_choice( $choice_key, $field ) {
2931 + /**
2932 + * @since 6.28
2933 + *
2934 + * @param bool $hide_field_choice
2935 + * @param string $choice_key
2936 + * @param array $field
2937 + */
2938 + return (bool) apply_filters( 'frm_hide_field_choice', false, $choice_key, $field );
2939 + }
2940 +
2941 + /**
2942 + * @since 6.28
2943 + *
2944 + * @param array $field
2945 + *
2946 + * @return bool
2947 + */
2948 + public static function should_skip_rendering_choices_for_field( $field ) {
2949 + /**
2950 + * @since 6.28
2951 + *
2952 + * @param bool $skip_rendering_options_for_field
2953 + * @param array $field
2954 + */
2955 + return (bool) apply_filters( 'frm_should_skip_rendering_choices_for_field', false, $field );
2956 + }
2957 +
2958 + /**
2959 + * Determine if 'disabled' attribute should be echoed in a field choice's HTML.
2960 + *
2961 + * @since 6.28
2962 + *
2963 + * @param string $choice_key
2964 + * @param bool $is_selected_choice
2965 + * @param array $field
2966 + *
2967 + * @return bool
2968 + */
2969 + public static function should_disable_choice( $choice_key, $is_selected_choice, $field ) {
2970 + /**
2971 + * @since 6.28
2972 + *
2973 + * @param bool $echo_disabled_attribute
2974 + * @param string $choice_key
2975 + * @param bool $is_selected_choice
2976 + * @param array $field
2977 + */
2978 + return (bool) apply_filters( 'frm_disable_choice', false, $choice_key, $is_selected_choice, $field );
2979 + }
2980 +
2981 + /**
2982 + * @since 6.28
2983 + *
2984 + * @param array $field
2985 + * @param string $choice_key
2986 + *
2987 + * @return void
2988 + */
2989 + public static function after_choice_input( $field, $choice_key ) {
2990 + /**
2991 + * Allows adding content after checkbox, radio button, or dropdown fields.
2992 + *
2993 + * @since 6.28
2994 + *
2995 + * @param array $field The field data.
2996 + * @param string $choice_key The option key.
2997 + */
2998 + do_action( 'frm_after_choice_input', $field, $choice_key );
2802 2999 }
2803 3000 }