PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 6.23
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v6.23
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 +255 -168 6.56.23 View file →
@@ -4,8 +4,15 @@
4 4 }
5 5
6 6 class FrmFieldsController {
7 7
8 + /**
9 + * This is stored statically so we can re-use this data for every field.
10 + *
11 + * @var FrmFieldSelectionData|null
12 + */
13 + private static $field_selection_data;
14 +
8 15 public static function load_field() {
9 16 FrmAppHelper::permission_check( 'frm_edit_forms' );
10 17 check_ajax_referer( 'frm_ajax', 'nonce' );
11 18
@@ -56,14 +63,15 @@
56 63 public static function create() {
57 64 FrmAppHelper::permission_check( 'frm_edit_forms' );
58 65 check_ajax_referer( 'frm_ajax', 'nonce' );
59 66
60 - $field_type = FrmAppHelper::get_post_param( 'field_type', '', 'sanitize_text_field' );
61 - $form_id = FrmAppHelper::get_post_param( 'form_id', 0, 'absint' );
67 + $field_type = FrmAppHelper::get_post_param( 'field_type', '', 'sanitize_text_field' );
68 + $form_id = FrmAppHelper::get_post_param( 'form_id', 0, 'absint' );
69 + $field_options = FrmAppHelper::get_post_param( 'field_options', array(), 'wp_kses_post' );
62 70
63 71 do_action( 'frm_before_create_field', $field_type, $form_id );
64 72
65 - $field = self::include_new_field( $field_type, $form_id );
73 + $field = self::include_new_field( $field_type, $form_id, $field_options );
66 74
67 75 // this hook will allow for multiple fields to be added at once
68 76 do_action( 'frm_after_field_created', $field, $form_id );
69 77
@@ -73,15 +81,23 @@
73 81 /**
74 82 * Set up and create a new field
75 83 *
76 84 * @param string $field_type
77 - * @param integer $form_id
85 + * @param int $form_id
86 + * @param array $field_options
78 87 *
79 - * @return array|bool
88 + * @return array|false
80 89 */
81 - public static function include_new_field( $field_type, $form_id ) {
90 + public static function include_new_field( $field_type, $form_id, $field_options = array() ) {
82 91 $field_values = FrmFieldsHelper::setup_new_vars( $field_type, $form_id );
83 92
93 + if ( ! empty( $field_options ) ) {
94 + $field_values['field_options'] = array_merge( $field_values['field_options'], $field_options );
95 + }
96 +
97 + // When a new field is added to the form, flag it as draft and hide it from the front-end.
98 + $field_values['field_options']['draft'] = 1;
99 +
84 100 /**
85 101 * @param array $field_values
86 102 */
87 103 $field_values = apply_filters( 'frm_before_field_created', $field_values );
@@ -139,11 +155,11 @@
139 155
140 156 /**
141 157 * @since 3.0
142 158 *
143 - * @param int|array|object $field_object
144 - * @param array $values
145 - * @param int $form_id
159 + * @param array|int|object $field_object
160 + * @param array $values
161 + * @param int $form_id
146 162 */
147 163 public static function load_single_field( $field_object, $values, $form_id = 0 ) {
148 164 global $frm_vars;
149 165 $frm_vars['is_admin'] = true;
@@ -157,30 +173,46 @@
157 173
158 174 $field_obj = FrmFieldFactory::get_field_factory( $field_object );
159 175 $display = self::display_field_options( array(), $field_obj );
160 176
161 - $ajax_loading = isset( $values['ajax_load'] ) && $values['ajax_load'];
162 - $ajax_this_field = isset( $values['count'] ) && $values['count'] > 10 && ! in_array( $field_object->type, array( 'divider', 'end_divider' ) );
177 + $ajax_loading = ! empty( $values['ajax_load'] );
178 + $ajax_this_field = isset( $values['count'] ) && $values['count'] > 10 && ! in_array( $field_object->type, array( 'divider', 'end_divider' ), true );
163 179
164 180 if ( $ajax_loading && $ajax_this_field ) {
165 181 $li_classes = self::get_classes_for_builder_field( array(), $display, $field_obj );
166 - include( FrmAppHelper::plugin_path() . '/classes/views/frm-fields/back-end/ajax-field-placeholder.php' );
167 - } else {
168 - if ( ! isset( $field ) && is_object( $field_object ) ) {
169 - $field_object->parent_form_id = isset( $values['id'] ) ? $values['id'] : $field_object->form_id;
182 + include FrmAppHelper::plugin_path() . '/classes/views/frm-fields/back-end/ajax-field-placeholder.php';
183 + return;
184 + }
170 185
171 - $field = FrmFieldsHelper::setup_edit_vars( $field_object );
172 - }
186 + if ( ! isset( $field ) && is_object( $field_object ) ) {
187 + $field_object->parent_form_id = isset( $values['id'] ) ? $values['id'] : $field_object->form_id;
188 + $field = FrmFieldsHelper::setup_edit_vars( $field_object );
189 + }
173 190
174 - $li_classes = self::get_classes_for_builder_field( $field, $display, $field_obj );
175 - $li_classes .= ' ui-state-default widgets-holder-wrap';
191 + /**
192 + * Filter for adding extra attributes to the field container.
193 + *
194 + * @since 6.23
195 + *
196 + * @param array $extra_field_attributes
197 + * @param array $field
198 + * @param array $display
199 + */
200 + $extra_field_attributes = apply_filters( 'frm_field_container_extra_attributes', array(), $field, $display );
176 201
177 - require( FrmAppHelper::plugin_path() . '/classes/views/frm-forms/add_field.php' );
178 - }
202 + $li_classes = self::get_classes_for_builder_field( $field, $display, $field_obj );
203 + $li_classes .= ' ui-state-default widgets-holder-wrap';
204 +
205 + require FrmAppHelper::plugin_path() . '/classes/views/frm-forms/add_field.php';
179 206 }
180 207
181 208 /**
182 209 * @since 3.0
210 + *
211 + * @param array $field
212 + * @param array $display
213 + * @param FrmFieldType $field_info
214 + * @return string
183 215 */
184 216 private static function get_classes_for_builder_field( $field, $display, $field_info ) {
185 217 $li_classes = $field_info->form_builder_classes( $display['type'] );
186 218 $li_classes .= ' frm_form_field frmstart ';
@@ -206,10 +238,11 @@
206 238 FrmField::destroy( $field_id );
207 239 wp_die();
208 240 }
209 241
210 - /* Field Options */
211 -
242 + /**
243 + * Field Options.
244 + */
212 245 public static function import_options() {
213 246 FrmAppHelper::permission_check( 'frm_edit_forms' );
214 247 check_ajax_referer( 'frm_ajax', 'nonce' );
215 248
@@ -216,12 +249,23 @@
216 249 if ( ! is_admin() || ! current_user_can( 'frm_edit_forms' ) ) {
217 250 return;
218 251 }
219 252
220 - $field_id = FrmAppHelper::get_param( 'field_id', '', 'post', 'absint' );
221 - $field = FrmField::getOne( $field_id );
253 + $field_id = FrmAppHelper::get_param( 'field_id', '', 'post', 'absint' );
254 + $field = FrmField::getOne( $field_id );
255 + $bulk_edit_types = array( 'radio', 'checkbox', 'select' );
222 256
223 - if ( ! in_array( $field->type, array( 'radio', 'checkbox', 'select' ) ) ) {
257 + /**
258 + * Filter to add new fields that will support import_options/Bulk Edit Options.
259 + *
260 + * @since 6.8.4
261 + *
262 + * @param array $bulk_edit_types
263 + * @return array
264 + */
265 + $bulk_edit_types = apply_filters( 'frm_bulk_edit_field_types', $bulk_edit_types );
266 +
267 + if ( ! in_array( $field->type, $bulk_edit_types, true ) ) {
224 268 return;
225 269 }
226 270
227 271 $field = FrmFieldsHelper::setup_edit_vars( $field );
@@ -228,15 +272,15 @@
228 272 $opts = FrmAppHelper::get_param( 'opts', '', 'post', 'wp_kses_post' );
229 273 $opts = explode( "\n", rtrim( $opts, "\n" ) );
230 274 $opts = array_map( 'trim', $opts );
231 275
232 - $separate = FrmAppHelper::get_param( 'separate', '', 'post', 'sanitize_text_field' );
233 - $field['separate_value'] = ( $separate === 'true' );
276 + $separate = FrmAppHelper::get_param( 'separate', '', 'post', 'sanitize_text_field' );
277 + $field['separate_value'] = $separate === 'true';
234 278
235 279 if ( $field['separate_value'] ) {
236 280 foreach ( $opts as $opt_key => $opt ) {
237 281 if ( strpos( $opt, '|' ) !== false ) {
238 - $vals = explode( '|', $opt );
282 + $vals = explode( '|', $opt );
239 283 $opts[ $opt_key ] = array(
240 284 'label' => trim( $vals[0] ),
241 285 'value' => trim( $vals[1] ),
242 286 );
@@ -270,8 +314,9 @@
270 314 /**
271 315 * @since 4.0
272 316 *
273 317 * @param array $atts - Includes field array, field_obj, display array, values array.
318 + * @return void
274 319 */
275 320 public static function load_single_field_settings( $atts ) {
276 321 $field = $atts['field'];
277 322 $field_obj = $atts['field_obj'];
@@ -286,13 +331,13 @@
286 331 if ( ! isset( $field['read_only'] ) ) {
287 332 $field['read_only'] = false;
288 333 }
289 334
290 - $field_types = FrmFieldsHelper::get_field_types( $field['type'] );
291 - $pro_field_selection = FrmField::pro_field_selection();
292 - $all_field_types = array_merge( $pro_field_selection, FrmField::field_selection() );
293 - $disabled_fields = FrmAppHelper::pro_is_installed() ? array() : $pro_field_selection;
294 - $frm_settings = FrmAppHelper::get_settings();
335 + $field_selection_data = self::maybe_define_field_selection_data();
336 + $all_field_types = $field_selection_data->all_field_types;
337 + $disabled_fields = $field_selection_data->disabled_fields;
338 + $frm_settings = FrmAppHelper::get_settings();
339 + $field_types = FrmFieldTypeOptionData::get_field_types( $field['type'] );
295 340
296 341 if ( ! isset( $all_field_types[ $field['type'] ] ) ) {
297 342 // Add fallback for an add-on field type that has been deactivated.
298 343 $all_field_types[ $field['type'] ] = array(
@@ -320,16 +365,31 @@
320 365 include FrmAppHelper::plugin_path() . '/classes/views/frm-fields/back-end/settings.php';
321 366 }
322 367
323 368 /**
369 + * @since 6.9.1
370 + *
371 + * @return FrmFieldSelectionData
372 + */
373 + private static function maybe_define_field_selection_data() {
374 + if ( ! isset( self::$field_selection_data ) ) {
375 + self::$field_selection_data = new FrmFieldSelectionData();
376 + }
377 + return self::$field_selection_data;
378 + }
379 +
380 + /**
324 381 * Get the list of default value types that can be toggled in the builder.
325 382 *
326 383 * @since 4.0
384 + *
385 + * @param array $field
386 + * @param array $atts
327 387 * @return array
328 388 */
329 389 private static function default_value_types( $field, $atts ) {
330 390 $types = array(
331 - 'default_value' => array(
391 + 'default_value' => array(
332 392 'class' => '',
333 393 'icon' => 'frm_icon_font frm_text2_icon',
334 394 'title' => __( 'Default Value (Text)', 'formidable' ),
335 395 'data' => array(
@@ -335,9 +395,9 @@
335 395 'data' => array(
336 396 'frmshow' => '#default-value-for-',
337 397 ),
338 398 ),
339 - 'calc' => array(
399 + 'calc' => array(
340 400 'class' => 'frm_show_upgrade frm_noallow',
341 401 'title' => __( 'Default Value (Calculation)', 'formidable' ),
342 402 'icon' => 'frm_icon_font frm_calculator_icon',
343 403 'data' => array(
@@ -357,13 +417,8 @@
357 417 );
358 418
359 419 $types = apply_filters( 'frm_default_value_types', $types, $atts );
360 420
361 - if ( FrmAppHelper::pro_is_installed() && ! FrmAppHelper::meets_min_pro_version( '4.0' ) ) {
362 - // Prevent settings from showing in 2 spots.
363 - unset( $types['calc'], $types['get_values_field'] );
364 - }
365 -
366 421 // Set active class.
367 422 $settings = array_keys( $types );
368 423 $active = 'default_value';
369 424
@@ -378,8 +433,12 @@
378 433
379 434 return $types;
380 435 }
381 436
437 + /**
438 + * @param string $type
439 + * @return string
440 + */
382 441 public static function change_type( $type ) {
383 442 $type_switch = array(
384 443 'scale' => 'radio',
385 444 'star' => 'radio',
@@ -404,16 +463,18 @@
404 463 return $type;
405 464 }
406 465
407 466 /**
408 - * @param array $settings
409 - * @param object $field_info
467 + * @param array $settings
468 + * @param FrmFieldType|null $field_info
410 469 *
411 470 * @return array
412 471 */
413 472 public static function display_field_options( $settings, $field_info = null ) {
414 473 if ( $field_info ) {
415 - $settings = $field_info->display_field_settings();
474 + $settings = $field_info->display_field_settings();
475 +
476 + // Field appears to be protected but there is a __get function in FrmFieldType that makes this public.
416 477 $settings['field_data'] = $field_info->field;
417 478 }
418 479
419 480 return apply_filters( 'frm_display_field_options', $settings );
@@ -423,12 +484,23 @@
423 484 * Display the format option
424 485 *
425 486 * @since 3.0
426 487 *
427 - * @param array $field
488 + * @param array $field Field data.
489 + * @param bool $is_hidden Whether the format option should be hidden.
490 + * @return void
428 491 */
429 - public static function show_format_option( $field ) {
430 - include( FrmAppHelper::plugin_path() . '/classes/views/frm-fields/back-end/value-format.php' );
492 + public static function show_format_option( $field, $is_hidden = false ) {
493 + $attributes = array(
494 + 'class' => 'frm-has-modal',
495 + 'id' => 'frm-field-format-custom-' . $field['id'],
496 + );
497 +
498 + if ( $is_hidden ) {
499 + $attributes['class'] .= ' frm_hidden';
500 + }
501 +
502 + include FrmAppHelper::plugin_path() . '/classes/views/frm-fields/back-end/value-format.php';
431 503 }
432 504
433 505 public static function input_html( $field, $echo = true ) {
434 506 $class = array();
@@ -456,14 +528,19 @@
456 528
457 529 return $add_html;
458 530 }
459 531
532 + /**
533 + * @param array $field
534 + * @param array $class
535 + * @return void
536 + */
460 537 private static function add_input_classes( $field, array &$class ) {
461 - if ( isset( $field['input_class'] ) && ! empty( $field['input_class'] ) ) {
538 + if ( ! empty( $field['input_class'] ) ) {
462 539 $class[] = $field['input_class'];
463 540 }
464 541
465 - if ( $field['type'] == 'hidden' || $field['type'] == 'user_id' ) {
542 + if ( $field['type'] === 'hidden' || $field['type'] === 'user_id' ) {
466 543 return;
467 544 }
468 545
469 546 if ( isset( $field['size'] ) && $field['size'] > 0 ) {
@@ -470,8 +547,13 @@
470 547 $class[] = 'auto_width';
471 548 }
472 549 }
473 550
551 + /**
552 + * @param array $field
553 + * @param array $add_html
554 + * @return void
555 + */
474 556 private static function add_html_size( $field, array &$add_html ) {
475 557 $size_fields = array(
476 558 'select',
477 559 'data',
@@ -480,9 +562,9 @@
480 562 'file',
481 563 'lookup',
482 564 );
483 565
484 - if ( ! isset( $field['size'] ) || $field['size'] <= 0 || in_array( $field['type'], $size_fields ) ) {
566 + if ( ! isset( $field['size'] ) || $field['size'] <= 0 || in_array( $field['type'], $size_fields, true ) ) {
485 567 return;
486 568 }
487 569
488 570 if ( FrmAppHelper::is_admin_page( 'formidable' ) ) {
@@ -499,8 +581,13 @@
499 581
500 582 self::add_html_cols( $field, $add_html );
501 583 }
502 584
585 + /**
586 + * @param array $field
587 + * @param array $add_html
588 + * @return void
589 + */
503 590 private static function add_html_cols( $field, array &$add_html ) {
504 591 if ( ! in_array( $field['type'], array( 'textarea', 'rte' ), true ) ) {
505 592 return;
506 593 }
@@ -524,8 +611,13 @@
524 611
525 612 $add_html['cols'] = 'cols="' . absint( $size ) . '"';
526 613 }
527 614
615 + /**
616 + * @param array $field
617 + * @param array $add_html
618 + * @return void
619 + */
528 620 private static function add_html_length( $field, array &$add_html ) {
529 621 // Check for max setting and if this field accepts maxlength.
530 622 $fields = array(
531 623 'textarea',
@@ -533,9 +625,9 @@
533 625 'hidden',
534 626 'file',
535 627 );
536 628
537 - if ( FrmField::is_option_empty( $field, 'max' ) || in_array( $field['type'], $fields ) ) {
629 + if ( FrmField::is_option_empty( $field, 'max' ) || in_array( $field['type'], $fields, true ) ) {
538 630 return;
539 631 }
540 632
541 633 if ( FrmAppHelper::is_admin_page( 'formidable' ) ) {
@@ -545,8 +637,14 @@
545 637
546 638 $add_html['maxlength'] = 'maxlength="' . esc_attr( $field['max'] ) . '"';
547 639 }
548 640
641 + /**
642 + * @param array $field
643 + * @param array $add_html
644 + * @param array $class
645 + * @return void
646 + */
549 647 private static function add_html_placeholder( $field, array &$add_html, array &$class ) {
550 648 if ( $field['default_value'] != '' ) {
551 649 if ( is_array( $field['default_value'] ) ) {
552 650 $add_html['data-frmval'] = 'data-frmval="' . esc_attr( json_encode( $field['default_value'] ) ) . '"';
@@ -560,21 +658,9 @@
560 658 // don't include a json placeholder
561 659 return;
562 660 }
563 661
564 - $frm_settings = FrmAppHelper::get_settings();
565 -
566 - if ( $frm_settings->use_html ) {
567 - self::add_placeholder_to_input( $field, $add_html );
568 - } else {
569 - self::add_frmval_to_input( $field, $add_html );
570 -
571 - $class[] = 'frm_toggle_default';
572 -
573 - if ( $field['value'] == $field['placeholder'] ) {
574 - $class[] = 'frm_default';
575 - }
576 - }
662 + self::add_placeholder_to_input( $field, $add_html );
577 663 }
578 664
579 665 /**
580 666 * Prepares field placeholder.
@@ -617,14 +703,26 @@
617 703 if ( empty( $placeholder ) ) {
618 704 $placeholder = self::get_default_value_from_name( $field );
619 705 }
620 706
707 + $use_placeholder = $placeholder;
708 + $autocomplete = FrmField::get_option( $field, 'autocom' );
709 +
710 + if ( $autocomplete ) {
711 + $use_chosen = ! is_callable( 'FrmProAppHelper::use_chosen_js' ) || FrmProAppHelper::use_chosen_js();
712 + if ( $use_chosen ) {
713 + $use_placeholder = '';
714 + }
715 + }
716 +
621 717 if ( $placeholder !== '' ) {
622 - ?>
623 - <option value="">
624 - <?php echo esc_html( FrmField::get_option( $field, 'autocom' ) ? '' : $placeholder ); ?>
625 - </option>
626 - <?php
718 + $placeholder_attributes = array(
719 + 'class' => 'frm-select-placeholder',
720 + 'value' => '',
721 + 'data-placeholder' => 'true',
722 + );
723 +
724 + FrmHtmlHelper::echo_dropdown_option( $use_placeholder, false, $placeholder_attributes );
627 725 return true;
628 726 }
629 727
630 728 return false;
@@ -630,12 +728,13 @@
630 728 return false;
631 729 }
632 730
633 731 /**
634 - * Use HMTL5 placeholder with js fallback
732 + * Use HTML5 placeholder with js fallback.
635 733 *
636 734 * @param array $field
637 735 * @param array $add_html
736 + * @return void
638 737 */
639 738 private static function add_placeholder_to_input( $field, &$add_html ) {
640 739 if ( FrmFieldsHelper::is_placeholder_field_type( $field['type'] ) ) {
641 740 $add_html['placeholder'] = 'placeholder="' . esc_attr( $field['placeholder'] ) . '"';
@@ -641,8 +740,13 @@
641 740 $add_html['placeholder'] = 'placeholder="' . esc_attr( $field['placeholder'] ) . '"';
642 741 }
643 742 }
644 743
744 + /**
745 + * @param array $field
746 + * @param array $add_html
747 + * @return void
748 + */
645 749 private static function add_frmval_to_input( $field, &$add_html ) {
646 750 if ( $field['placeholder'] != '' ) {
647 751 $add_html['data-frmval'] = 'data-frmval="' . esc_attr( $field['placeholder'] ) . '"';
648 752
@@ -656,15 +760,17 @@
656 760 }
657 761 }
658 762
659 763 private static function add_validation_messages( $field, array &$add_html ) {
660 - if ( FrmField::is_required( $field ) ) {
764 + $field_validation_messages_status = self::get_validation_data_attribute_visibility_info( $field );
765 +
766 + if ( FrmField::is_required( $field ) && ! empty( $field_validation_messages_status['data-reqmsg'] ) ) {
661 767 $required_message = FrmFieldsHelper::get_error_msg( $field, 'blank' );
662 768 $add_html['data-reqmsg'] = 'data-reqmsg="' . esc_attr( $required_message ) . '"';
663 769 self::maybe_add_html_required( $field, $add_html );
664 770 }
665 771
666 - if ( ! FrmField::is_option_empty( $field, 'invalid' ) ) {
772 + if ( ! FrmField::is_option_empty( $field, 'invalid' ) && ! empty( $field_validation_messages_status['data-invmsg'] ) ) {
667 773 $invalid_message = FrmFieldsHelper::get_error_msg( $field, 'invalid' );
668 774 $add_html['data-invmsg'] = 'data-invmsg="' . esc_attr( $invalid_message ) . '"';
669 775 }
670 776
@@ -673,12 +779,45 @@
673 779 }
674 780 }
675 781
676 782 /**
783 + * Returns an array that contains field validation messages status.
784 + *
785 + * @since 6.9
786 + *
787 + * @param array|object $field
788 + * @return array
789 + */
790 + private static function get_validation_data_attribute_visibility_info( $field ) {
791 + if ( FrmField::get_field_type( $field ) === 'hidden' ) {
792 + $field_validation_data_attributes = array(
793 + 'data-invmsg' => false,
794 + 'data-reqmsg' => false,
795 + );
796 + } else {
797 + $field_validation_data_attributes = array(
798 + 'data-invmsg' => true,
799 + 'data-reqmsg' => true,
800 + );
801 + }
802 +
803 + /**
804 + * Allows controlling which field validation messages would be included in the field html.
805 + *
806 + * @since 6.9
807 + *
808 + * @param array $field_validation_messages_status
809 + * @param array|object $field
810 + */
811 + return apply_filters( 'frm_field_validation_include_data_attributes', $field_validation_data_attributes, $field );
812 + }
813 +
814 + /**
677 815 * @since 5.0.03
678 816 *
679 817 * @param array $field
680 818 * @param array $add_html
819 + * @return void
681 820 */
682 821 private static function maybe_add_error_html_for_js_validation( $field, array &$add_html ) {
683 822 $form = self::get_form_for_js_validation( $field );
684 823 if ( false === $form ) {
@@ -695,9 +834,9 @@
695 834 /**
696 835 * @since 5.0.03
697 836 *
698 837 * @param array $field
699 - * @return stdClass|false false if there is no form object found with JS validation active.
838 + * @return false|stdClass false if there is no form object found with JS validation active.
700 839 */
701 840 private static function get_form_for_js_validation( $field ) {
702 841 global $frm_vars;
703 842 if ( ! empty( $frm_vars['js_validate_forms'] ) ) {
@@ -714,9 +853,9 @@
714 853 /**
715 854 * @param stdClass $form
716 855 * @param array $field
717 856 * @param array $errors
718 - * @return string|false
857 + * @return false|string
719 858 */
720 859 public static function pull_custom_error_body_from_custom_html( $form, $field, $errors = array() ) {
721 860 if ( empty( $field['custom_html'] ) ) {
722 861 return false;
@@ -757,8 +896,9 @@
757 896 *
758 897 * @since 3.06.01
759 898 * @param array $field
760 899 * @param array $add_html
900 + * @return void
761 901 */
762 902 private static function maybe_add_html_required( $field, array &$add_html ) {
763 903 $excluded_field_types =
764 904 FrmField::is_radio( $field ) ||
@@ -770,14 +910,16 @@
770 910 if ( $excluded_field_types ) {
771 911 return;
772 912 }
773 913
774 - $include_html = FrmAppHelper::meets_min_pro_version( '3.06.01' );
775 - if ( $include_html ) {
776 - $add_html['aria-required'] = 'aria-required="true"';
777 - }
914 + $add_html['aria-required'] = 'aria-required="true"';
778 915 }
779 916
917 + /**
918 + * @param array $field
919 + * @param array $add_html
920 + * @return void
921 + */
780 922 private static function add_shortcodes_to_html( $field, array &$add_html ) {
781 923 if ( FrmField::is_option_empty( $field, 'shortcodes' ) ) {
782 924 return;
783 925 }
@@ -786,9 +928,19 @@
786 928 unset( $field['shortcodes']['autocomplete'] );
787 929 }
788 930
789 931 foreach ( $field['shortcodes'] as $k => $v ) {
790 - if ( 'opt' === $k ) {
932 + if ( isset( $field['subfield_name'] ) && 0 === strpos( $k, 'aria-invalid' ) ) {
933 + $subfield_name = $field['subfield_name'];
934 + if ( ! isset( $field['shortcodes'][ 'aria-invalid-' . $subfield_name ] ) ) {
935 + continue;
936 + }
937 + // Change the key to the correct aria-invalid value so that $add_html is set correctly for the current subfield of a combo field.
938 + $k = 'aria-invalid';
939 + $v = $field['shortcodes'][ 'aria-invalid-' . $subfield_name ];
940 + unset( $field['shortcodes'][ 'aria-invalid-' . $subfield_name ] );
941 + }
942 + if ( 'opt' === $k || ! self::should_allow_input_attribute( $k ) ) {
791 943 continue;
792 944 }
793 945
794 946 if ( is_numeric( $k ) && strpos( $v, '=' ) ) {
@@ -799,32 +951,45 @@
799 951 $add_html[ $k ] = $k . '="' . esc_attr( $v ) . '"';
800 952 }
801 953
802 954 unset( $k, $v );
955 + }//end foreach
956 + }
957 +
958 + /**
959 + * Disallow possibly unsafe attributees (that trigger JavaScript) when unasfe HTML is not allowed.
960 + *
961 + * @since 6.11.2
962 + *
963 + * @param string $key The option key.
964 + * @return bool
965 + */
966 + private static function should_allow_input_attribute( $key ) {
967 + if ( ! FrmAppHelper::should_never_allow_unfiltered_html() ) {
968 + return true;
803 969 }
970 + return FrmAppHelper::input_key_is_safe( $key );
804 971 }
805 972
806 973 /**
807 - * Add pattern attribute
974 + * Add pattern attribute.
808 975 *
809 976 * @since 3.0
810 977 *
811 978 * @param array $field
812 979 * @param array $add_html
980 + * @return void
813 981 */
814 982 private static function add_pattern_attribute( $field, array &$add_html ) {
815 - $has_format = FrmField::is_option_true_in_array( $field, 'format' );
983 + $format_value = FrmField::get_option( $field, 'format' );
984 + $has_format = $format_value && ! FrmCurrencyHelper::is_currency_format( $format_value );
816 985 $format_field = FrmField::is_field_type( $field, 'text' );
817 986
818 - if ( $field['type'] == 'phone' || ( $has_format && $format_field ) ) {
819 - $frm_settings = FrmAppHelper::get_settings();
987 + if ( $field['type'] === 'phone' || ( $has_format && $format_field ) ) {
988 + $format = FrmEntryValidate::phone_format( $field );
989 + $format = substr( $format, 2, - 1 );
820 990
821 - if ( $frm_settings->use_html ) {
822 - $format = FrmEntryValidate::phone_format( $field );
823 - $format = substr( $format, 2, - 1 );
824 -
825 - $add_html['pattern'] = 'pattern="' . esc_attr( $format ) . '"';
826 - }
991 + $add_html['pattern'] = 'pattern="' . esc_attr( $format ) . '"';
827 992 }
828 993 }
829 994
830 995 public static function check_value( $opt, $opt_key, $field ) {
@@ -840,88 +1005,10 @@
840 1005 }
841 1006
842 1007 public static function check_label( $opt ) {
843 1008 if ( is_array( $opt ) ) {
844 - $opt = ( isset( $opt['label'] ) ? $opt['label'] : reset( $opt ) );
1009 + $opt = isset( $opt['label'] ) ? $opt['label'] : reset( $opt );
845 1010 }
846 1011
847 1012 return $opt;
848 - }
849 -
850 - /**
851 - * @deprecated 4.0
852 - */
853 - public static function update_ajax_option() {
854 - _deprecated_function( __METHOD__, '4.0' );
855 - FrmAppHelper::permission_check( 'frm_edit_forms' );
856 - check_ajax_referer( 'frm_ajax', 'nonce' );
857 -
858 - $field_id = FrmAppHelper::get_post_param( 'field', 0, 'absint' );
859 - if ( ! $field_id ) {
860 - wp_die();
861 - }
862 -
863 - $field = FrmField::getOne( $field_id );
864 -
865 - if ( isset( $_POST['separate_value'] ) ) {
866 - $new_val = FrmField::is_option_true( $field, 'separate_value' ) ? 0 : 1;
867 -
868 - $field->field_options['separate_value'] = $new_val;
869 - unset( $new_val );
870 - }
871 -
872 - FrmField::update(
873 - $field_id,
874 - array(
875 - 'field_options' => $field->field_options,
876 - 'form_id' => $field->form_id,
877 - )
878 - );
879 - wp_die();
880 - }
881 -
882 - /**
883 - * @deprecated 4.0
884 - */
885 - public static function import_choices() {
886 - _deprecated_function( __METHOD__, '4.0' );
887 - wp_die();
888 - }
889 -
890 - /**
891 - * Add Single Option or Other Option.
892 - *
893 - * @deprecated 4.0 Moved to Pro for Other option only.
894 - */
895 - public static function add_option() {
896 - _deprecated_function( __METHOD__, '4.0', 'FrmProFieldsController::add_other_option' );
897 - }
898 -
899 - /**
900 - * @deprecated 4.0
901 - */
902 - public static function update_order() {
903 - FrmDeprecated::update_order();
904 - }
905 -
906 - /**
907 - * @deprecated 3.0
908 - * @codeCoverageIgnore
909 - */
910 - public static function edit_name( $field = 'name', $id = '' ) {
911 - FrmDeprecated::edit_name( $field, $id );
912 - }
913 -
914 - /**
915 - * @deprecated 3.0
916 - * @codeCoverageIgnore
917 - *
918 - * @param int $field_id
919 - * @param array $values
920 - * @param int $form_id
921 - *
922 - * @return array
923 - */
924 - public static function include_single_field( $field_id, $values, $form_id = 0 ) {
925 - return FrmDeprecated::include_single_field( $field_id, $values, $form_id );
926 1013 }
927 1014 }