PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 4.01.02
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v4.01.02
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/controllers/FrmFieldsController.php +80 -141 6.3.24.01.02 View file →
@@ -1,8 +1,5 @@
1 1 <?php
2 -if ( ! defined( 'ABSPATH' ) ) {
3 - die( 'You are not allowed to call this page directly.' );
4 -}
5 2
6 3 class FrmFieldsController {
7 4
8 5 public static function load_field() {
@@ -8,10 +5,8 @@
8 5 public static function load_field() {
9 6 FrmAppHelper::permission_check( 'frm_edit_forms' );
10 7 check_ajax_referer( 'frm_ajax', 'nonce' );
11 8
12 - // Javascript may be included in some field settings.
13 - // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
14 9 $fields = isset( $_POST['field'] ) ? wp_unslash( $_POST['field'] ) : array();
15 10 if ( empty( $fields ) ) {
16 11 wp_die();
17 12 }
@@ -59,10 +54,8 @@
59 54
60 55 $field_type = FrmAppHelper::get_post_param( 'field_type', '', 'sanitize_text_field' );
61 56 $form_id = FrmAppHelper::get_post_param( 'form_id', 0, 'absint' );
62 57
63 - do_action( 'frm_before_create_field', $field_type, $form_id );
64 -
65 58 $field = self::include_new_field( $field_type, $form_id );
66 59
67 60 // this hook will allow for multiple fields to be added at once
68 61 do_action( 'frm_after_field_created', $field, $form_id );
@@ -111,12 +104,25 @@
111 104
112 105 $field_id = FrmAppHelper::get_post_param( 'field_id', 0, 'absint' );
113 106 $form_id = FrmAppHelper::get_post_param( 'form_id', 0, 'absint' );
114 107
115 - $new_field = FrmField::duplicate_single_field( $field_id, $form_id );
108 + $copy_field = FrmField::getOne( $field_id );
109 + if ( ! $copy_field ) {
110 + wp_die();
111 + }
116 112
117 - if ( is_array( $new_field ) && ! empty( $new_field['field_id'] ) ) {
118 - self::load_single_field( $new_field['field_id'], $new_field['values'] );
113 + do_action( 'frm_duplicate_field', $copy_field, $form_id );
114 + do_action( 'frm_duplicate_field_' . $copy_field->type, $copy_field, $form_id );
115 +
116 + $values = array(
117 + 'id' => $copy_field->id,
118 + );
119 + FrmFieldsHelper::fill_field( $values, $copy_field, $copy_field->form_id );
120 + $values = apply_filters( 'frm_prepare_single_field_for_duplication', $values );
121 +
122 + $field_id = FrmField::create( $values );
123 + if ( $field_id ) {
124 + self::load_single_field( $field_id, $values );
119 125 }
120 126
121 127 wp_die();
122 128 }
@@ -178,18 +184,19 @@
178 184 /**
179 185 * @since 3.0
180 186 */
181 187 private static function get_classes_for_builder_field( $field, $display, $field_info ) {
182 - $li_classes = $field_info->form_builder_classes( $display['type'] );
183 - $li_classes .= ' frm_form_field frmstart ';
188 + $li_classes = $field_info->form_builder_classes( $display['type'] );
189 + $classes = isset( $field['classes'] ) ? $field['classes'] : '';
184 190
185 - if ( isset( $field['classes'] ) ) {
186 - $li_classes .= trim( $field['classes'] ) . ' ';
191 + // Exclude alignright for now since we aren't using widths.
192 + $classes = str_replace( ' frm_alignright ', ' ', $classes );
193 + if ( trim( $classes ) === 'frm_alignright' ) {
194 + $classes = '';
187 195 }
188 196
189 - $li_classes .= 'frmend';
190 -
191 - if ( $field ) {
197 + $li_classes .= ' frm_form_field frmstart ' . $classes . ' frmend';
198 + if ( ! empty( $field ) ) {
192 199 $li_classes = apply_filters( 'frm_build_field_class', $li_classes, $field );
193 200 }
194 201
195 202 return $li_classes;
@@ -305,19 +312,38 @@
305 312 if ( $field['type'] === 'divider' && FrmField::is_option_true( $field, 'repeat' ) ) {
306 313 $type_name = $all_field_types['divider|repeat']['name'];
307 314 }
308 315
316 + $display_type = self::displayed_field_type( $field );
317 +
309 318 if ( $display['default'] ) {
310 319 $default_value_types = self::default_value_types( $field, compact( 'display' ) );
311 320 }
312 321
313 322 if ( $display['clear_on_focus'] && is_array( $field['placeholder'] ) ) {
314 - $field['placeholder'] = implode( ', ', $field['placeholder'] );
323 + $field['placeholder'] = implode( $field['placeholder'], ', ' );
315 324 }
316 325 include( FrmAppHelper::plugin_path() . '/classes/views/frm-fields/back-end/settings.php' );
317 326 }
318 327
319 328 /**
329 + * Get the type of field being displayed for lookups and dynamic fields.
330 + *
331 + * @since 4.0
332 + * @return array
333 + */
334 + private static function displayed_field_type( $field ) {
335 + $display_type = array(
336 + 'radio' => FrmField::is_field_type( $field, 'radio' ),
337 + 'checkbox' => FrmField::is_field_type( $field, 'checkbox' ),
338 + 'select' => FrmField::is_field_type( $field, 'select' ),
339 + 'lookup' => FrmField::is_field_type( $field, 'lookup' ),
340 + 'data' => FrmField::is_field_type( $field, 'data' ),
341 + );
342 + return array_filter( $display_type );
343 + }
344 +
345 + /**
320 346 * Get the list of default value types that can be toggled in the builder.
321 347 *
322 348 * @since 4.0
323 349 * @return array
@@ -443,9 +469,9 @@
443 469 $add_html = apply_filters( 'frm_field_extra_html', $add_html, $field );
444 470 $add_html = ' ' . implode( ' ', $add_html ) . ' ';
445 471
446 472 if ( $echo ) {
447 - echo $add_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
473 + echo $add_html; // WPCS: XSS ok.
448 474 }
449 475
450 476 return $add_html;
451 477 }
@@ -568,19 +594,17 @@
568 594 }
569 595 }
570 596 }
571 597
572 - /**
573 - * Prepares field placeholder.
574 - *
575 - * @since 5.4 This doesn't call `FrmFieldsController::get_default_value_from_name()` anymore.
576 - *
577 - * @param array $field Field array.
578 - * @return string
579 - */
580 598 private static function prepare_placeholder( $field ) {
581 - $placeholder = isset( $field['placeholder'] ) ? $field['placeholder'] : '';
599 + $is_placeholder_field = FrmFieldsHelper::is_placeholder_field_type( $field['type'] );
600 + $is_combo_field = in_array( $field['type'], array( 'address', 'credit_card' ) );
582 601
602 + $placeholder = $field['placeholder'];
603 + if ( empty( $placeholder ) && $is_placeholder_field && ! $is_combo_field ) {
604 + $placeholder = self::get_default_value_from_name( $field );
605 + }
606 +
583 607 return $placeholder;
584 608 }
585 609
586 610 /**
@@ -587,9 +611,8 @@
587 611 * If the label position is "inside",
588 612 * get the label to use as the placeholder
589 613 *
590 614 * @since 2.05
591 - * @since 5.4 Remove the logic code for "inside" label position.
592 615 *
593 616 * @param array $field
594 617 *
595 618 * @return string
@@ -594,34 +617,16 @@
594 617 *
595 618 * @return string
596 619 */
597 620 public static function get_default_value_from_name( $field ) {
598 - return '';
599 - }
600 -
601 - /**
602 - * Maybe add a blank placeholder option before any options
603 - * in a dropdown.
604 - *
605 - * @since 4.04
606 - * @return bool True if placeholder was added.
607 - */
608 - public static function add_placeholder_to_select( $field ) {
609 - $placeholder = FrmField::get_option( $field, 'placeholder' );
610 - if ( empty( $placeholder ) ) {
611 - $placeholder = self::get_default_value_from_name( $field );
621 + $position = FrmField::get_option( $field, 'label' );
622 + if ( $position == 'inside' ) {
623 + $default_value = $field['name'];
624 + } else {
625 + $default_value = '';
612 626 }
613 627
614 - if ( $placeholder !== '' ) {
615 - ?>
616 - <option value="">
617 - <?php echo esc_html( FrmField::get_option( $field, 'autocom' ) ? '' : $placeholder ); ?>
618 - </option>
619 - <?php
620 - return true;
621 - }
622 -
623 - return false;
628 + return $default_value;
624 629 }
625 630
626 631 /**
627 632 * Use HMTL5 placeholder with js fallback
@@ -659,93 +664,12 @@
659 664 if ( ! FrmField::is_option_empty( $field, 'invalid' ) ) {
660 665 $invalid_message = FrmFieldsHelper::get_error_msg( $field, 'invalid' );
661 666 $add_html['data-invmsg'] = 'data-invmsg="' . esc_attr( $invalid_message ) . '"';
662 667 }
663 -
664 - if ( ! empty( $add_html['data-reqmsg'] ) || ! empty( $add_html['data-invmsg'] ) ) {
665 - self::maybe_add_error_html_for_js_validation( $field, $add_html );
666 - }
667 668 }
668 669
669 670 /**
670 - * @since 5.0.03
671 - *
672 - * @param array $field
673 - * @param array $add_html
674 - */
675 - private static function maybe_add_error_html_for_js_validation( $field, array &$add_html ) {
676 - $form = self::get_form_for_js_validation( $field );
677 - if ( false === $form ) {
678 - return;
679 - }
680 -
681 - $error_body = self::pull_custom_error_body_from_custom_html( $form, $field );
682 - if ( false !== $error_body ) {
683 - $error_body = urlencode( $error_body );
684 - $add_html['data-error-html'] = 'data-error-html="' . esc_attr( $error_body ) . '"';
685 - }
686 - }
687 -
688 - /**
689 - * @since 5.0.03
690 - *
691 - * @param array $field
692 - * @return stdClass|false false if there is no form object found with JS validation active.
693 - */
694 - private static function get_form_for_js_validation( $field ) {
695 - global $frm_vars;
696 - if ( ! empty( $frm_vars['js_validate_forms'] ) ) {
697 - if ( isset( $frm_vars['js_validate_forms'][ $field['form_id'] ] ) ) {
698 - return $frm_vars['js_validate_forms'][ $field['form_id'] ];
699 - }
700 - if ( ! empty( $field['parent_form_id'] ) && isset( $frm_vars['js_validate_forms'][ $field['parent_form_id'] ] ) ) {
701 - return $frm_vars['js_validate_forms'][ $field['parent_form_id'] ];
702 - }
703 - }
704 - return false;
705 - }
706 -
707 - /**
708 - * @param stdClass $form
709 - * @param array $field
710 - * @param array $errors
711 - * @return string|false
712 - */
713 - public static function pull_custom_error_body_from_custom_html( $form, $field, $errors = array() ) {
714 - if ( empty( $field['custom_html'] ) ) {
715 - return false;
716 - }
717 -
718 - $custom_html = $field['custom_html'];
719 - $custom_html = apply_filters( 'frm_before_replace_shortcodes', $custom_html, $field, $errors, $form );
720 -
721 - $start = strpos( $custom_html, '[if error]' );
722 - if ( false === $start ) {
723 - return false;
724 - }
725 -
726 - $end = strpos( $custom_html, '[/if error]' );
727 - if ( false === $end || $end < $start ) {
728 - return false;
729 - }
730 -
731 - $error_body = substr( $custom_html, $start + 10, $end - $start - 10 );
732 - $default_html = array(
733 - '<div class="frm_error" id="frm_error_field_[key]">[error]</div>',
734 - '<div class="frm_error" role="alert" id="frm_error_field_[key]">[error]</div>',
735 - '<div class="frm_error">[error]</div>',
736 - '<div class="frm_error" role="alert">[error]</div>',
737 - );
738 -
739 - if ( in_array( $error_body, $default_html, true ) ) {
740 - return false;
741 - }
742 -
743 - return $error_body;
744 - }
745 -
746 - /**
747 - * If 'required' is added to a conditionally hidden field, the form won't
671 + * If 'required' is added to a conditionall hidden field, the form won't
748 672 * submit in many browsers. Check to make sure the javascript to conditionally
749 673 * remove it is present if needed.
750 674 *
751 675 * @since 3.06.01
@@ -752,9 +676,9 @@
752 676 * @param array $field
753 677 * @param array $add_html
754 678 */
755 679 private static function maybe_add_html_required( $field, array &$add_html ) {
756 - if ( in_array( $field['type'], array( 'file', 'data', 'lookup' ), true ) ) {
680 + if ( in_array( $field['type'], array( 'radio', 'checkbox', 'file', 'data', 'lookup' ) ) ) {
757 681 return;
758 682 }
759 683
760 684 $include_html = FrmAppHelper::meets_min_pro_version( '3.06.01' );
@@ -767,12 +691,8 @@
767 691 if ( FrmField::is_option_empty( $field, 'shortcodes' ) ) {
768 692 return;
769 693 }
770 694
771 - if ( ! empty( $field['autocomplete'] ) ) {
772 - unset( $field['shortcodes']['autocomplete'] );
773 - }
774 -
775 695 foreach ( $field['shortcodes'] as $k => $v ) {
776 696 if ( 'opt' === $k ) {
777 697 continue;
778 698 }
@@ -878,9 +798,12 @@
878 798 *
879 799 * @deprecated 4.0 Moved to Pro for Other option only.
880 800 */
881 801 public static function add_option() {
882 - _deprecated_function( __METHOD__, '4.0', 'FrmProFieldsController::add_other_option' );
802 + _deprecated_function( __METHOD__, '4.0', 'FrmProFormsController::add_other_option' );
803 + if ( is_callable( 'FrmProFormsController::add_other_option' ) ) {
804 + FrmProFormsController::add_other_option();
805 + }
883 806 }
884 807
885 808 /**
886 809 * @deprecated 4.0
@@ -908,6 +831,22 @@
908 831 * @return array
909 832 */
910 833 public static function include_single_field( $field_id, $values, $form_id = 0 ) {
911 834 return FrmDeprecated::include_single_field( $field_id, $values, $form_id );
835 + }
836 +
837 + /**
838 + * @deprecated 2.3
839 + * @codeCoverageIgnore
840 + */
841 + public static function edit_option() {
842 + FrmDeprecated::deprecated( __METHOD__, '2.3' );
843 + }
844 +
845 + /**
846 + * @deprecated 2.3
847 + * @codeCoverageIgnore
848 + */
849 + public static function delete_option() {
850 + FrmDeprecated::deprecated( __METHOD__, '2.3' );
912 851 }
913 852 }