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 +296 -97 6.27 → trunk View file →
@@ -165,16 +165,18 @@
165 165 * @param int|string $entry_id
166 166 * @param array $args
167 167 */
168 168 $field_array = apply_filters( 'frm_setup_edit_fields_vars', $field_array, $field, $args['entry_id'], $args );
169 - } else {
170 - /**
171 - * @param array $field_array
172 - * @param stdClass $field
173 - * @param array $args
174 - */
175 - $field_array = apply_filters( 'frm_setup_new_fields_vars', $field_array, $field, $args );
169 +
170 + return;
176 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 );
177 179 }
178 180
179 181 /**
180 182 * @since 3.0
@@ -471,10 +473,18 @@
471 473 'part' => $conf_msg,
472 474 ),
473 475 );
474 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 +
475 485 $msg = FrmField::get_option( $field, $error );
476 - $msg = empty( $msg ) ? $defaults[ $error ]['part'] : $msg;
486 + $msg = $msg ? $msg : $defaults[ $error ]['part'];
477 487 $msg = do_shortcode( $msg );
478 488
479 489 return self::maybe_replace_substrings_with_field_name( $msg, $error, $field );
480 490 }
@@ -561,9 +571,9 @@
561 571 public static function get_default_html( $type = 'text' ) {
562 572 $field = FrmFieldFactory::get_field_type( $type );
563 573 $default_html = $field->default_html();
564 574
565 - // these hooks are here for reverse compatibility since 3.0
575 + // These hooks are here for reverse compatibility since 3.0
566 576 if ( ! apply_filters( 'frm_normal_field_type_html', true, $type ) ) {
567 577 $default_html = apply_filters( 'frm_other_custom_html', '', $type );
568 578 }
569 579
@@ -579,8 +589,12 @@
579 589 * @return void
580 590 */
581 591 public static function show_fields( $fields, $errors, $form, $form_action ) {
582 592 foreach ( $fields as $field ) {
593 + if ( ! is_array( $field ) ) {
594 + continue;
595 + }
596 +
583 597 $field_obj = FrmFieldFactory::get_field_type( $field['type'], $field );
584 598 $field_obj->show_field( compact( 'errors', 'form', 'form_action' ) );
585 599 }
586 600 }
@@ -595,15 +609,17 @@
595 609 */
596 610 public static function run_wpautop( $atts, &$value ) {
597 611 $autop = $atts['wpautop'] ?? true;
598 612
599 - if ( apply_filters( 'frm_use_wpautop', $autop ) ) {
600 - if ( is_array( $value ) ) {
601 - $value = implode( "\n", $value );
602 - }
613 + if ( ! apply_filters( 'frm_use_wpautop', $autop ) ) {
614 + return;
615 + }
603 616
604 - $value = wpautop( $value );
617 + if ( is_array( $value ) ) {
618 + $value = implode( "\n", $value );
605 619 }
620 +
621 + $value = wpautop( $value );
606 622 }
607 623
608 624 /**
609 625 * Get the class to use for the label position
@@ -615,12 +631,12 @@
615 631 * @param bool|object|string $form
616 632 *
617 633 * @return string
618 634 */
619 - public static function &label_position( $position, $field, $form ) {
635 + public static function label_position( $position, $field, $form ) {
620 636 if ( $position ) {
621 637 if ( $position === 'inside' && ! self::is_placeholder_field_type( $field['type'] ) ) {
622 - $position = 'top';
638 + return 'top';
623 639 }
624 640
625 641 return $position;
626 642 }
@@ -635,11 +651,9 @@
635 651 $position = 'top';
636 652 }
637 653
638 654 $position = apply_filters( 'frm_html_label_position', $position, $field, $form );
639 - $position = ! empty( $position ) ? $position : 'top';
640 -
641 - return $position;
655 + return $position ? $position : 'top';
642 656 }
643 657
644 658 /**
645 659 * Check if this field type allows placeholders
@@ -693,9 +707,9 @@
693 707 $opt = self::get_label_from_array( $opt, $opt_key, $field );
694 708 $field_name = $base_name . ( $default_type === 'checkbox' ? '[' . $opt_key . ']' : '' );
695 709
696 710 // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict, Universal.Operators.StrictComparisons, SlevomatCodingStandard.Files.LineLength.LineTooLong
697 - $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'] ) ) );
711 + $checked = isset( $field['default_value'] ) && ( is_array( $field['default_value'] ) ? in_array( $field_val, $field['default_value'] ) : $field['default_value'] == $field_val );
698 712
699 713 // If this is an "Other" option, get the HTML for it.
700 714 if ( self::is_other_opt( $opt_key ) ) {
701 715 if ( FrmAppHelper::pro_is_installed() ) {
@@ -809,15 +823,17 @@
809 823 */
810 824 public static function smart_values() {
811 825 $continue = apply_filters( 'frm_smart_values_box', true );
812 826
813 - if ( $continue === true ) {
814 - $upgrade_link = array(
815 - 'medium' => 'builder',
816 - 'content' => 'smart-tags',
817 - );
818 - include FrmAppHelper::plugin_path() . '/classes/views/frm-fields/back-end/smart-values.php';
827 + if ( $continue !== true ) {
828 + return;
819 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';
820 836 }
821 837
822 838 /**
823 839 * @since 4.0
@@ -848,19 +864,16 @@
848 864 if ( ! $tax ) {
849 865 return '';
850 866 }
851 867
852 - $link = sprintf(
868 + return sprintf(
853 869 /* translators: %1$s: Start HTML link, %2$s: Content type label, %3$s: Content type, %4$s: End HTML link */
854 870 esc_html__( 'Options are dynamically created from your %1$s%2$s: %3$s%4$s', 'formidable' ),
855 871 '<a href="' . esc_url( admin_url( 'edit-tags.php?taxonomy=' . $tax->name ) ) . '" target="_blank">',
856 872 esc_html__( 'taxonomy', 'formidable' ),
857 - empty( $tax->labels->name ) ? esc_html__( 'Categories', 'formidable' ) : $tax->labels->name,
873 + ! empty( $tax->labels->name ) ? $tax->labels->name : esc_html__( 'Categories', 'formidable' ),
858 874 '</a>'
859 875 );
860 - unset( $tax );
861 -
862 - return $link;
863 876 }
864 877
865 878 /**
866 879 * @param array|string $observed_value
@@ -894,14 +907,14 @@
894 907 } elseif ( $cond === 'LIKE' || $cond === 'not LIKE' ) {
895 908 $m = stripos( $observed_value, $hide_opt );
896 909 $m = $cond === 'not LIKE' ? $m === false : $m !== false;
897 910 } elseif ( $cond === '%LIKE' ) {
898 - // ends with
911 + // Ends with
899 912 $length = strlen( $hide_opt );
900 913 $substr = substr( $observed_value, strlen( $observed_value ) - $length );
901 914 $m = 0 === strcasecmp( $substr, $hide_opt );
902 915 } elseif ( 'LIKE%' === $cond ) {
903 - // starts with
916 + // Starts with
904 917 $length = strlen( $hide_opt );
905 918 $substr = substr( $observed_value, 0, $length );
906 919 $m = 0 === strcasecmp( $substr, $hide_opt );
907 920 }//end if
@@ -950,13 +963,11 @@
950 963 } elseif ( $cond === '!=' ) {
951 964 // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
952 965 $m = ! in_array( $hide_opt, $observed_value );
953 966 } elseif ( $cond === '>' ) {
954 - $min = min( $observed_value );
955 - $m = $min > $hide_opt;
967 + $m = min( $observed_value ) > $hide_opt;
956 968 } elseif ( $cond === '<' ) {
957 - $max = max( $observed_value );
958 - $m = $max < $hide_opt;
969 + $m = max( $observed_value ) < $hide_opt;
959 970 } elseif ( $cond === 'LIKE' || $cond === 'not LIKE' ) {
960 971 foreach ( $observed_value as $ob ) {
961 972 $m = strpos( $ob, $hide_opt );
962 973
@@ -969,9 +980,9 @@
969 980 if ( $cond === 'not LIKE' ) {
970 981 $m = $m === false;
971 982 }
972 983 } elseif ( $cond === '%LIKE' ) {
973 - // ends with
984 + // Ends with
974 985 foreach ( $observed_value as $ob ) {
975 986 if ( $hide_opt === substr( $ob, strlen( $ob ) - strlen( $hide_opt ) ) ) {
976 987 $m = true;
977 988 break;
@@ -977,9 +988,9 @@
977 988 break;
978 989 }
979 990 }
980 991 } elseif ( $cond === 'LIKE%' ) {
981 - // starts with
992 + // Starts with
982 993 foreach ( $observed_value as $ob ) {
983 994 if ( str_starts_with( $ob, $hide_opt ) ) {
984 995 $m = true;
985 996 break;
@@ -1346,9 +1357,9 @@
1346 1357 $new_value = $atts['default'] ?? $atts['prev_val'];
1347 1358 }
1348 1359
1349 1360 if ( is_array( $new_value ) && ! $return_array ) {
1350 - $new_value = implode( ', ', $new_value );
1361 + return implode( ', ', $new_value );
1351 1362 }
1352 1363
1353 1364 return $new_value;
1354 1365 }
@@ -1417,15 +1428,15 @@
1417 1428 } else {
1418 1429 $info = $user->$user_info ?? '';
1419 1430 }
1420 1431
1421 - if ( 'display_name' === $user_info && empty( $info ) && ! $args['blank'] ) {
1432 + if ( 'display_name' === $user_info && ! $info && ! $args['blank'] ) {
1422 1433 $info = $user->user_login;
1423 1434 }
1424 1435 }
1425 1436
1426 1437 if ( $args['link'] ) {
1427 - $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>';
1428 1439 }
1429 1440
1430 1441 return $info;
1431 1442 }
@@ -1531,9 +1542,9 @@
1531 1542 $pointer = $args['pointer'];
1532 1543 $other_val = '';
1533 1544
1534 1545 // If option is an "other" option and there is a value set for this field,
1535 - // 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
1536 1547 if ( ! self::is_other_opt( $opt_key ) || ! FrmField::is_option_true( $field, 'value' ) ) {
1537 1548 return $other_val;
1538 1549 }
1539 1550
@@ -1596,9 +1607,9 @@
1596 1607 unset( $opt_val, $temp_val );
1597 1608 }
1598 1609
1599 1610 // For multi-select dropdowns only
1600 - if ( is_array( $field['value'] ) && ! empty( $field['value'] ) ) {
1611 + if ( is_array( $field['value'] ) && $field['value'] ) {
1601 1612 $other_val = reset( $field['value'] );
1602 1613 }
1603 1614 }//end if
1604 1615
@@ -1614,9 +1625,9 @@
1614 1625 * @param array $args Should include field, opt_key and field name.
1615 1626 * @param bool $other_opt
1616 1627 * @param string $checked
1617 1628 *
1618 - * @return array $other_args
1629 + * @return array Other args.
1619 1630 */
1620 1631 public static function prepare_other_input( $args, &$other_opt, &$checked ) {
1621 1632 $other_args = array(
1622 1633 'name' => '',
@@ -1721,9 +1732,9 @@
1721 1732
1722 1733 $classes = array( 'frm_other_input' );
1723 1734
1724 1735 if ( ! $args['checked'] || trim( $args['checked'] ) === '' ) {
1725 - // hide the field if the other option is not selected
1736 + // Hide the field if the other option is not selected
1726 1737 $classes[] = 'frm_pos_none';
1727 1738 }
1728 1739
1729 1740 if ( $args['field']['type'] === 'select' && ! empty( $args['field']['multiple'] ) ) {
@@ -1734,8 +1745,9 @@
1734 1745 $other_id = self::get_other_field_html_id( $args['field']['type'], $args['html_id'], $args['opt_key'] );
1735 1746
1736 1747 $label = $args['opt_label'] ?? $args['field']['name'];
1737 1748
1749 + // phpcs:disable Generic.WhiteSpace.ScopeIndent
1738 1750 echo '<label for="' . esc_attr( $other_id ) . '" class="frm_screen_reader frm_hidden">' .
1739 1751 esc_html( $label ) .
1740 1752 '</label>' .
1741 1753 '<input type="text" id="' . esc_attr( $other_id ) . '" class="' . esc_attr( implode( ' ', $classes ) ) . '" ' .
@@ -1740,8 +1752,9 @@
1740 1752 '</label>' .
1741 1753 '<input type="text" id="' . esc_attr( $other_id ) . '" class="' . esc_attr( implode( ' ', $classes ) ) . '" ' .
1742 1754 ( $args['read_only'] ? ' readonly="readonly" disabled="disabled"' : '' ) .
1743 1755 ' name="' . esc_attr( $args['name'] ) . '" value="' . esc_attr( $args['value'] ) . '" />';
1756 + // phpcs:enable Generic.WhiteSpace.ScopeIndent
1744 1757 }
1745 1758
1746 1759 /**
1747 1760 * Get the HTML id for an "Other" text field
@@ -1752,9 +1765,9 @@
1752 1765 * @param string $type Field type.
1753 1766 * @param string $html_id
1754 1767 * @param bool|string $opt_key
1755 1768 *
1756 - * @return string $other_id
1769 + * @return string Other ID.
1757 1770 */
1758 1771 public static function get_other_field_html_id( $type, $html_id, $opt_key = false ) {
1759 1772 $other_id = $html_id;
1760 1773
@@ -1770,11 +1783,11 @@
1770 1783 return $other_id . '-otext';
1771 1784 }
1772 1785
1773 1786 /**
1774 - * @param string $val
1787 + * @param array|string $val
1775 1788 *
1776 - * @return string
1789 + * @return array|string
1777 1790 */
1778 1791 public static function switch_field_ids( $val ) {
1779 1792 global $frm_duplicate_ids;
1780 1793 $replace = array();
@@ -1808,23 +1821,25 @@
1808 1821 $replace_with[] = '_field":"' . $new . '","';
1809 1822 unset( $old, $new );
1810 1823 }//end foreach
1811 1824
1812 - if ( is_array( $val ) ) {
1813 - foreach ( $val as $k => $v ) {
1814 - if ( is_string( $v ) ) {
1815 - if ( 'custom_html' === $k ) {
1816 - $val[ $k ] = self::switch_ids_except_strings( $replace, $replace_with, array( '[if description]', '[description]', '[/if description]' ), $v );
1817 - unset( $k, $v );
1818 - continue;
1819 - }
1825 + if ( ! is_array( $val ) ) {
1826 + return str_replace( $replace, $replace_with, $val );
1827 + }
1820 1828
1821 - $val[ $k ] = str_replace( $replace, $replace_with, $v );
1822 - unset( $k, $v );
1823 - }
1829 + foreach ( $val as $k => $v ) {
1830 + if ( ! is_string( $v ) ) {
1831 + continue;
1824 1832 }
1825 - } else {
1826 - $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 );
1827 1842 }
1828 1843
1829 1844 return $val;
1830 1845 }
@@ -2349,8 +2364,39 @@
2349 2364 return $field_array + $field_options;
2350 2365 }
2351 2366
2352 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 + /**
2353 2399 * @since 4.04
2354 2400 *
2355 2401 * @param array $args
2356 2402 *
@@ -2369,34 +2415,22 @@
2369 2415 $field_label .= ob_get_clean();
2370 2416 }
2371 2417
2372 2418 // If the individual field isn't allowed, disable it.
2373 - $run_filter = true;
2374 - $single_no_allow = ' ';
2375 - $install_data = '';
2376 - $requires = '';
2377 - $link = isset( $field_type['link'] ) ? esc_url_raw( $field_type['link'] ) : '';
2378 - $has_show_upgrade_class = isset( $field_type['icon'] ) && str_contains( $field_type['icon'], ' frm_show_upgrade' );
2379 - $show_upgrade = $has_show_upgrade_class || str_contains( $args['no_allow_class'], 'frm_show_upgrade' );
2419 + $link = isset( $field_type['link'] ) ? esc_url_raw( $field_type['link'] ) : '';
2380 2420
2381 - if ( $has_show_upgrade_class ) {
2382 - $single_no_allow .= 'frm_show_upgrade';
2383 - $field_type['icon'] = str_replace( ' frm_show_upgrade', '', $field_type['icon'] );
2384 - $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 );
2385 2431
2386 - if ( isset( $field_type['addon'] ) ) {
2387 - $upgrading = FrmAddonsController::install_link( $field_type['addon'] );
2388 -
2389 - if ( isset( $upgrading['url'] ) ) {
2390 - $install_data = json_encode( $upgrading );
2391 - }
2392 -
2393 - $requires = FrmFormsHelper::get_plan_required( $upgrading );
2394 - } elseif ( isset( $field_type['require'] ) ) {
2395 - $requires = $field_type['require'];
2396 - }
2397 - }
2398 -
2432 + $show_upgrade = $has_show_upgrade_class || $has_show_update_class || str_contains( $args['no_allow_class'], 'frm_show_upgrade' );
2399 2433 $upgrade_label = '';
2400 2434 $upgrade_message = '';
2401 2435
2402 2436 if ( $show_upgrade ) {
@@ -2438,10 +2472,17 @@
2438 2472 str_contains( $field_type['learn-more'], '/' )
2439 2473 );
2440 2474 }
2441 2475
2442 - if ( isset( $upgrading['url'] ) ) {
2476 + if ( $has_show_update_class ) {
2443 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(
2444 2485 // translators: %s: Field name
2445 2486 esc_html__( 'You already have access to %s fields, you\'ll just need to activate to start using them.', 'formidable' ),
2446 2487 $field_name
2447 2488 );
@@ -2447,8 +2488,9 @@
2447 2488 );
2448 2489 } elseif ( $upgrade_message ) {
2449 2490 $li_params['data-message'] = $upgrade_message;
2450 2491 }
2492 + // phpcs:disable Generic.WhiteSpace.ScopeIndent
2451 2493 ?>
2452 2494 <li <?php FrmAppHelper::array_to_html_params( $li_params, true ); ?>>
2453 2495 <?php
2454 2496 if ( $run_filter ) {
@@ -2453,15 +2495,87 @@
2453 2495 <?php
2454 2496 if ( $run_filter ) {
2455 2497 $field_label = apply_filters( 'frmpro_field_links', $field_label, $args['id'], $field_key );
2456 2498 }
2499 +
2457 2500 FrmAppHelper::kses_echo( $field_label, array( 'a', 'i', 'span', 'use', 'svg' ) );
2458 2501 ?>
2459 2502 </li>
2460 2503 <?php
2504 + // phpcs:enable Generic.WhiteSpace.ScopeIndent
2461 2505 }
2462 2506
2463 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 + /**
2464 2578 * Updates the params with limit data (the data-limit attribute, and possibly the frm_at_limit class).
2465 2579 * Some field types are limited to a certain number per form, including coupon fields.
2466 2580 *
2467 2581 * @since 6.27
@@ -2539,8 +2653,12 @@
2539 2653 'content' => 'button-options',
2540 2654 ),
2541 2655 );
2542 2656
2657 + if ( 'product' === FrmField::get_field_type( $field ) ) {
2658 + unset( $options['buttons'] );
2659 + }
2660 +
2543 2661 /**
2544 2662 * Allows modifying the options of Display format setting of Radio field.
2545 2663 *
2546 2664 * @since 5.0.04
@@ -2636,12 +2754,11 @@
2636 2754 if ( 'pro' === $option['addon'] ) {
2637 2755 return $custom_attrs;
2638 2756 }
2639 2757
2640 - $upgrading = FrmAddonsController::install_link( $option['addon'] );
2641 - $install_data = isset( $upgrading['url'] ) ? wp_json_encode( $upgrading ) : '';
2758 + $upgrading = FrmAddonsController::install_link( $option['addon'] );
2642 2759
2643 - $custom_attrs['data-oneclick'] = $install_data;
2760 + $custom_attrs['data-oneclick'] = isset( $upgrading['url'] ) ? wp_json_encode( $upgrading ) : '';
2644 2761 $custom_attrs['data-requires'] = FrmFormsHelper::get_plan_required( $upgrading );
2645 2762
2646 2763 return $custom_attrs;
2647 2764 }
@@ -2726,12 +2843,13 @@
2726 2843 * @return void
2727 2844 */
2728 2845 public static function render_ai_generate_options_button( $args, $should_hide_bulk_edit = false ) {
2729 2846 $attributes = array(
2730 - 'type' => 'button',
2731 - 'class' => self::get_ai_generate_options_button_class(),
2847 + 'type' => 'button',
2732 2848 );
2733 2849
2850 + $attributes['class'] = ! empty( $args['class'] ) ? $args['class'] : self::get_ai_generate_options_button_class();
2851 +
2734 2852 if ( $should_hide_bulk_edit ) {
2735 2853 $attributes['class'] .= ' frm-force-hidden';
2736 2854 }
2737 2855
@@ -2738,9 +2856,9 @@
2738 2856 $data = FrmAppHelper::get_upgrade_data_params(
2739 2857 'ai',
2740 2858 array(
2741 2859 'requires' => 'Business',
2742 - 'upgrade' => __( 'Generate options with AI', 'formidable' ),
2860 + 'upgrade' => $args['upgrade_text'] ?? __( 'Generate options with AI', 'formidable' ),
2743 2861 'medium' => 'builder',
2744 2862 'content' => 'generate-options-with-ai',
2745 2863 ),
2746 2864 true
@@ -2747,16 +2865,16 @@
2747 2865 );
2748 2866
2749 2867 if ( in_array( FrmAddonsController::license_type(), array( 'elite', 'business' ), true ) && 'active' === $data['plugin-status'] ) {
2750 2868 // Backwards compatibility "@since 6.24".
2751 - 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 {
2752 2873 $data = array(
2753 2874 'modal-title' => __( 'Generate options with AI', 'formidable' ),
2754 2875 'modal-content' => __( 'Update the Formidable AI add-on to the last version to use this feature.', 'formidable' ),
2755 2876 );
2756 - } else {
2757 - $attributes['class'] .= ' frm-ai-generate-options-modal-trigger';
2758 - $attributes['data-fid'] = $args['likert_id'] ?? $args['field']['id'];
2759 2877 }
2760 2878 }
2761 2879
2762 2880 if ( empty( $attributes['data-fid'] ) ) {
@@ -2796,6 +2914,87 @@
2796 2914 'frm-mt-xs',
2797 2915 'frm-mb-12',
2798 2916 )
2799 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 );
2800 2999 }
2801 3000 }