PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 6.2.3
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v6.2.3
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
formidable / classes / helpers / FrmFieldsHelper.php

FrmFieldsHelper.php in Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More 6.2.3, at classes/helpers/FrmFieldsHelper.php

2,164 lines 63.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) {
3 die( 'You are not allowed to call this page directly.' );
4 }
5
6 class FrmFieldsHelper {
7
8 public static function setup_new_vars( $type = '', $form_id = '' ) {
9
10 if ( strpos( $type, '|' ) ) {
11 list( $type, $setting ) = explode( '|', $type );
12 }
13
14 $values = self::get_default_field( $type );
15
16 global $wpdb;
17 $field_count = FrmDb::get_var( 'frm_fields', array( 'form_id' => $form_id ), 'field_order', array( 'order_by' => 'field_order DESC' ) );
18
19 $values['field_key'] = FrmAppHelper::get_unique_key( '', $wpdb->prefix . 'frm_fields', 'field_key' );
20 $values['form_id'] = $form_id;
21 $values['field_order'] = $field_count + 1;
22
23 $values['field_options']['custom_html'] = self::get_default_html( $type );
24
25 if ( isset( $setting ) && ! empty( $setting ) ) {
26 if ( in_array( $type, array( 'data', 'lookup' ) ) ) {
27 $values['field_options']['data_type'] = $setting;
28 } else {
29 $values['field_options'][ $setting ] = 1;
30 }
31 }
32
33 return $values;
34 }
35
36 public static function get_html_id( $field, $plus = '' ) {
37 return apply_filters( 'frm_field_html_id', 'field_' . $field['field_key'] . $plus, $field );
38 }
39
40 public static function setup_edit_vars( $field, $doing_ajax = false ) {
41 $values = self::field_object_to_array( $field );
42
43 return apply_filters( 'frm_setup_edit_field_vars', $values, array( 'doing_ajax' => $doing_ajax ) );
44 }
45
46 public static function field_object_to_array( $field ) {
47 $values = (array) $field;
48
49 self::fill_field_array( $field, $values );
50
51 $values['custom_html'] = ( isset( $field->field_options['custom_html'] ) ) ? $field->field_options['custom_html'] : self::get_default_html( $field->type );
52
53 return $values;
54 }
55
56 private static function fill_field_array( $field, array &$field_array ) {
57 $field_array['options'] = $field->options;
58 $field_array['value'] = $field->default_value;
59
60 self::prepare_edit_front_field( $field_array, $field );
61
62 $field_array = array_merge( (array) $field->field_options, $field_array );
63 }
64
65 /**
66 * Prepare field while creating a new entry
67 *
68 * @since 3.0
69 */
70 public static function prepare_new_front_field( &$field_array, $field, $args = array() ) {
71 $args['action'] = 'new';
72 self::prepare_front_field( $field_array, $field, $args );
73 }
74
75 /**
76 * Prepare field while editing an entry
77 *
78 * @since 3.0
79 */
80 public static function prepare_edit_front_field( &$field_array, $field, $entry_id = 0, $args = array() ) {
81 $args['entry_id'] = $entry_id;
82 $args['action'] = 'edit';
83 self::prepare_front_field( $field_array, $field, $args );
84 }
85
86 /**
87 * Prepare field while creating a new entry
88 *
89 * @since 3.0
90 */
91 private static function prepare_front_field( &$field_array, $field, $args ) {
92 self::fill_default_field_opts( $field, $field_array );
93 self::fill_cleared_strings( $field, $field_array );
94
95 // Track the original field's type
96 $field_array['original_type'] = isset( $field->field_options['original_type'] ) ? $field->field_options['original_type'] : $field->type;
97
98 self::prepare_field_options_for_display( $field_array, $field, $args );
99
100 if ( $args['action'] == 'edit' ) {
101 $field_array = apply_filters( 'frm_setup_edit_fields_vars', $field_array, $field, $args['entry_id'], $args );
102 } else {
103 $field_array = apply_filters( 'frm_setup_new_fields_vars', $field_array, $field, $args );
104 }
105 }
106
107 /**
108 * @since 3.0
109 *
110 * @param string $type
111 *
112 * @return array
113 */
114 public static function get_default_field_options( $type ) {
115 $field_type = FrmFieldFactory::get_field_type( $type );
116
117 return $field_type->get_default_field_options();
118 }
119
120 /**
121 * @since 3.0
122 *
123 * @param object $field
124 * @param array $values
125 */
126 private static function fill_default_field_opts( $field, array &$values ) {
127 $check_post = FrmAppHelper::is_admin_page() && $_POST && isset( $_POST['field_options'] ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
128
129 $defaults = self::get_default_field_options_from_field( $field, $values );
130 if ( ! $check_post ) {
131 $defaults['required_indicator'] = '';
132 $defaults['original_type'] = $field->type;
133 }
134
135 foreach ( $defaults as $opt => $default ) {
136 $values[ $opt ] = isset( $field->field_options[ $opt ] ) ? $field->field_options[ $opt ] : $default;
137
138 if ( $check_post ) {
139 self::get_posted_field_setting( $opt . '_' . $field->id, $values[ $opt ] );
140 }
141
142 unset( $opt, $default );
143 }
144 }
145
146 /**
147 * Fill the required message, invalid message,
148 * and refill the HTML when cleared
149 *
150 * @since 3.0
151 *
152 * @param object $field
153 * @param array $field_array
154 */
155 private static function fill_cleared_strings( $field, array &$field_array ) {
156 $frm_settings = FrmAppHelper::get_settings();
157
158 if ( '' == $field_array['blank'] && '1' === $field_array['required'] ) {
159 $field_array['blank'] = $frm_settings->blank_msg;
160 }
161
162 if ( '' === $field_array['invalid'] ) {
163 if ( 'captcha' === $field->type ) {
164 $field_array['invalid'] = $frm_settings->re_msg;
165 } else {
166 /* translators: %s: Field name */
167 $field_array['invalid'] = sprintf( __( '%s is invalid', 'formidable' ), $field_array['name'] );
168 }
169 }
170
171 if ( '' == $field_array['custom_html'] ) {
172 $field_array['custom_html'] = self::get_default_html( $field->type );
173 }
174 }
175
176 /**
177 * @since 3.0
178 *
179 * @param string $setting
180 * @param mixed $value
181 */
182 private static function get_posted_field_setting( $setting, &$value ) {
183 if ( ! isset( $_POST['field_options'][ $setting ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
184 return;
185 }
186
187 if ( strpos( $setting, 'html' ) !== false ) {
188 // Strip slashes from HTML but not regex or script tags.
189 $value = wp_unslash( $_POST['field_options'][ $setting ] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing
190 } elseif ( strpos( $setting, 'format_' ) === 0 ) {
191 // TODO: Remove stripslashes on output, and use on input only.
192 $value = sanitize_text_field( $_POST['field_options'][ $setting ] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.NonceVerification.Missing
193 } else {
194 $value = wp_unslash( $_POST['field_options'][ $setting ] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing
195 FrmAppHelper::sanitize_value( 'wp_kses_post', $value );
196 }
197 }
198
199 /**
200 * @since 3.0
201 *
202 * @param object $field
203 * @param array $values The field array is needed for hooks
204 *
205 * @return array
206 */
207 public static function get_default_field_options_from_field( $field, $values = array() ) {
208 $field_type = self::get_original_field( $field );
209 $opts = $field_type->get_default_field_options();
210
211 $opts = apply_filters( 'frm_default_field_opts', $opts, $values, $field );
212 $opts = apply_filters( 'frm_default_' . $field->type . '_field_opts', $opts, $values, $field );
213
214 return $opts;
215 }
216
217 /**
218 * @since 3.0
219 *
220 * @param object $field
221 *
222 * @return array
223 */
224 private static function get_original_field( $field ) {
225 $original_type = FrmField::get_option( $field, 'original_type' );
226 if ( ! empty( $original_type ) && $field->type != $original_type ) {
227 $field->type = $original_type;
228 }
229
230 return FrmFieldFactory::get_field_object( $field );
231 }
232
233 /**
234 * @since 3.0
235 *
236 * @param array $field_array
237 * @param object $field
238 * @param array $atts
239 */
240 private static function prepare_field_options_for_display( &$field_array, $field, $atts ) {
241 $field_obj = FrmFieldFactory::get_field_object( $field );
242 $field_array = $field_obj->prepare_front_field( $field_array, $atts );
243 }
244
245 /**
246 * @since 3.0
247 *
248 * @param string $type
249 *
250 * @return array
251 */
252 public static function get_default_field( $type ) {
253 $field_type = FrmFieldFactory::get_field_type( $type );
254
255 return $field_type->get_new_field_defaults();
256 }
257
258 public static function fill_field( &$values, $field, $form_id, $new_key = '' ) {
259 global $wpdb;
260
261 $values['field_key'] = FrmAppHelper::get_unique_key( $new_key, $wpdb->prefix . 'frm_fields', 'field_key' );
262 $values['form_id'] = $form_id;
263 $values['options'] = maybe_serialize( $field->options );
264 $values['default_value'] = FrmAppHelper::maybe_json_encode( $field->default_value );
265
266 foreach ( array( 'name', 'description', 'type', 'field_order', 'field_options', 'required' ) as $col ) {
267 $values[ $col ] = $field->{$col};
268 }
269 }
270
271 /**
272 * @since 2.0
273 *
274 * @param $field
275 * @param $error
276 *
277 * @return string
278 */
279 public static function get_error_msg( $field, $error ) {
280 $frm_settings = FrmAppHelper::get_settings();
281 $default_settings = $frm_settings->default_options();
282 $field_name = is_array( $field ) ? $field['name'] : $field->name;
283
284 $conf_msg = __( 'The entered values do not match', 'formidable' );
285 $defaults = array(
286 'unique_msg' => array(
287 'full' => $default_settings['unique_msg'],
288 /* translators: %s: Field name */
289 'part' => sprintf( __( '%s must be unique', 'formidable' ), $field_name ),
290 ),
291 'invalid' => array(
292 'full' => __( 'This field is invalid', 'formidable' ),
293 /* translators: %s: Field name */
294 'part' => sprintf( __( '%s is invalid', 'formidable' ), $field_name ),
295 ),
296 'blank' => array(
297 'full' => $frm_settings->blank_msg,
298 'part' => $frm_settings->blank_msg,
299 ),
300 'conf_msg' => array(
301 'full' => $conf_msg,
302 'part' => $conf_msg,
303 ),
304 );
305
306 $msg = FrmField::get_option( $field, $error );
307 $msg = empty( $msg ) ? $defaults[ $error ]['part'] : $msg;
308 $msg = do_shortcode( $msg );
309
310 return $msg;
311 }
312
313 public static function get_form_fields( $form_id, $error = array() ) {
314 $fields = FrmField::get_all_for_form( $form_id );
315
316 return apply_filters( 'frm_get_paged_fields', $fields, $form_id, $error );
317 }
318
319 public static function get_default_html( $type = 'text' ) {
320 $field = FrmFieldFactory::get_field_type( $type );
321 $default_html = $field->default_html();
322
323 // these hooks are here for reverse compatibility since 3.0
324 if ( ! apply_filters( 'frm_normal_field_type_html', true, $type ) ) {
325 $default_html = apply_filters( 'frm_other_custom_html', '', $type );
326 }
327
328 return apply_filters( 'frm_custom_html', $default_html, $type );
329 }
330
331 /**
332 * @param array $fields
333 * @param array $errors
334 * @param object $form
335 * @param $form_action
336 */
337 public static function show_fields( $fields, $errors, $form, $form_action ) {
338 foreach ( $fields as $field ) {
339 $field_obj = FrmFieldFactory::get_field_type( $field['type'], $field );
340 $field_obj->show_field( compact( 'errors', 'form', 'form_action' ) );
341 }
342 }
343
344 /**
345 * @since 3.0
346 *
347 * @param array $atts
348 * @param string|array $value
349 */
350 public static function run_wpautop( $atts, &$value ) {
351 $autop = isset( $atts['wpautop'] ) ? $atts['wpautop'] : true;
352 if ( apply_filters( 'frm_use_wpautop', $autop ) ) {
353 if ( is_array( $value ) ) {
354 $value = implode( "\n", $value );
355 }
356 $value = wpautop( $value );
357 }
358 }
359
360 /**
361 * Get the class to use for the label position
362 *
363 * @since 2.05
364 */
365 public static function &label_position( $position, $field, $form ) {
366 if ( $position && $position != '' ) {
367 if ( $position == 'inside' && ! self::is_placeholder_field_type( $field['type'] ) ) {
368 $position = 'top';
369 }
370
371 return $position;
372 }
373
374 $position = FrmStylesController::get_style_val( 'position', $form );
375 if ( $position == 'none' ) {
376 $position = 'top';
377 } elseif ( $position == 'no_label' ) {
378 $position = 'none';
379 } elseif ( $position == 'inside' && ! self::is_placeholder_field_type( $field['type'] ) ) {
380 $position = 'top';
381 }
382
383 $position = apply_filters( 'frm_html_label_position', $position, $field, $form );
384 $position = ( ! empty( $position ) ) ? $position : 'top';
385
386 return $position;
387 }
388
389 /**
390 * Check if this field type allows placeholders
391 *
392 * @since 2.05
393 * @param string $type
394 * @return bool
395 */
396 public static function is_placeholder_field_type( $type ) {
397 return ! in_array( $type, array( 'radio', 'checkbox', 'hidden', 'file' ), true );
398 }
399
400 public static function get_checkbox_id( $field, $opt_key, $type = 'checkbox' ) {
401 $id = $field['id'];
402 if ( isset( $field['in_section'] ) && $field['in_section'] && ! FrmAppHelper::is_admin_page( 'formidable' ) ) {
403 $id .= '-' . $field['in_section'];
404 }
405
406 return 'frm_' . $type . '_' . $id . '-' . $opt_key;
407 }
408
409 public static function show_single_option( $field ) {
410 self::hidden_field_option( $field );
411
412 if ( ! is_array( $field['options'] ) ) {
413 return;
414 }
415
416 $base_name = 'default_value_' . $field['id'];
417 $html_id = isset( $field['html_id'] ) ? $field['html_id'] : self::get_html_id( $field );
418
419 $default_type = self::get_default_value_type( $field );
420
421 foreach ( $field['options'] as $opt_key => $opt ) {
422 $field_val = self::get_value_from_array( $opt, $opt_key, $field );
423 $opt = self::get_label_from_array( $opt, $opt_key, $field );
424
425 $field_name = $base_name . ( $default_type === 'checkbox' ? '[' . $opt_key . ']' : '' );
426
427 $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'] ) ) ) );
428
429 // If this is an "Other" option, get the HTML for it.
430 if ( self::is_other_opt( $opt_key ) ) {
431 if ( FrmAppHelper::pro_is_installed() ) {
432 require( FrmProAppHelper::plugin_path() . '/classes/views/frmpro-fields/other-option.php' );
433 }
434 } else {
435 require( FrmAppHelper::plugin_path() . '/classes/views/frm-fields/single-option.php' );
436 }
437
438 unset( $checked );
439 }
440 }
441
442 /**
443 * Include hidden row for javascript to duplicate.
444 *
445 * @since 4.0
446 * @param array $field
447 */
448 private static function hidden_field_option( $field ) {
449 // Don't duplicate during an ajax add option.
450 $ajax_action = FrmAppHelper::get_param( 'action', '', 'post', 'sanitize_text_field' );
451 if ( $ajax_action === 'frm_add_field_option' ) {
452 return;
453 }
454
455 $opt_key = '000';
456 $field_val = __( 'New Option', 'formidable' );
457 $opt = __( 'New Option', 'formidable' );
458 $checked = false;
459 $field_name = 'default_value_' . $field['id'];
460 $html_id = isset( $field['html_id'] ) ? $field['html_id'] : self::get_html_id( $field );
461
462 $default_type = self::get_default_value_type( $field );
463 $field_name .= ( $default_type === 'checkbox' ? '[' . $opt_key . ']' : '' );
464
465 require( FrmAppHelper::plugin_path() . '/classes/views/frm-fields/single-option.php' );
466 }
467
468 /**
469 * @since 4.0
470 *
471 * @param array $field
472 * @return string radio or checkbox
473 */
474 private static function get_default_value_type( $field ) {
475 $default_type = $field['type'];
476 if ( $field['type'] === 'select' ) {
477 $default_type = FrmField::is_multiple_select( $field ) ? 'checkbox' : 'radio';
478 }
479 return $default_type;
480 }
481
482 public static function get_value_from_array( $opt, $opt_key, $field ) {
483 $opt = apply_filters( 'frm_field_value_saved', $opt, $opt_key, $field );
484
485 return FrmFieldsController::check_value( $opt, $opt_key, $field );
486 }
487
488 public static function get_label_from_array( $opt, $opt_key, $field ) {
489 $opt = apply_filters( 'frm_field_label_seen', $opt, $opt_key, $field );
490
491 return FrmFieldsController::check_label( $opt );
492 }
493
494 /**
495 * @since 4.0
496 */
497 public static function inline_modal( $args ) {
498 $defaults = array(
499 'id' => '',
500 'class' => '',
501 'show' => 0,
502 'callback' => array(),
503 'args' => array(),
504 'title' => '',
505 );
506 $args = array_merge( $defaults, $args );
507
508 include( FrmAppHelper::plugin_path() . '/classes/views/frm-fields/back-end/inline-modal.php' );
509 }
510
511 /**
512 * @since 4.0
513 */
514 public static function smart_values() {
515 $continue = apply_filters( 'frm_smart_values_box', true );
516 if ( $continue === true ) {
517 $upgrade_link = array(
518 'medium' => 'builder',
519 'content' => 'smart-tags',
520 );
521 include( FrmAppHelper::plugin_path() . '/classes/views/frm-fields/back-end/smart-values.php' );
522 }
523 }
524
525 /**
526 * @since 4.0
527 */
528 public static function input_mask() {
529 include( FrmAppHelper::plugin_path() . '/classes/views/frm-fields/back-end/input-mask-info.php' );
530 }
531
532 /**
533 * @since 4.0
534 */
535 public static function layout_classes() {
536 include( FrmAppHelper::plugin_path() . '/classes/views/frm-fields/back-end/layout-classes.php' );
537 }
538
539 /**
540 * @param int $tax_id
541 *
542 * @return string
543 */
544 public static function get_term_link( $tax_id ) {
545 $tax = get_taxonomy( $tax_id );
546 if ( ! $tax ) {
547 return '';
548 }
549
550 $link = sprintf(
551 /* translators: %1$s: Start HTML link, %2$s: Content type label, %3$s: Content type, %4$s: End HTML link */
552 esc_html__( 'Options are dynamically created from your %1$s%2$s: %3$s%4$s', 'formidable' ),
553 '<a href="' . esc_url( admin_url( 'edit-tags.php?taxonomy=' . $tax->name ) ) . '" target="_blank">',
554 esc_html__( 'taxonomy', 'formidable' ),
555 empty( $tax->labels->name ) ? esc_html__( 'Categories', 'formidable' ) : $tax->labels->name,
556 '</a>'
557 );
558 unset( $tax );
559
560 return $link;
561 }
562
563 public static function value_meets_condition( $observed_value, $cond, $hide_opt ) {
564 $hide_opt = self::get_value_for_comparision( $hide_opt );
565 $observed_value = self::get_value_for_comparision( $observed_value );
566
567 if ( is_array( $observed_value ) ) {
568 return self::array_value_condition( $observed_value, $cond, $hide_opt );
569 }
570
571 $m = false;
572 if ( $cond === '==' ) {
573 $m = $observed_value == $hide_opt;
574 } elseif ( $cond === '!=' ) {
575 $m = $observed_value != $hide_opt;
576 } elseif ( $cond === '>' ) {
577 $m = $observed_value > $hide_opt;
578 } elseif ( $cond === '>=' ) {
579 $m = $observed_value >= $hide_opt;
580 } elseif ( $cond === '<' ) {
581 $m = $observed_value < $hide_opt;
582 } elseif ( $cond === '<=' ) {
583 $m = $observed_value <= $hide_opt;
584 } elseif ( $cond === 'LIKE' || $cond === 'not LIKE' ) {
585 $m = stripos( $observed_value, $hide_opt );
586 if ( $cond === 'not LIKE' ) {
587 $m = ( $m === false ) ? true : false;
588 } else {
589 $m = ( $m === false ) ? false : true;
590 }
591 } elseif ( $cond === '%LIKE' ) {
592 // ends with
593 $length = strlen( $hide_opt );
594 $substr = substr( $observed_value, strlen( $observed_value ) - $length );
595 $m = 0 === strcasecmp( $substr, $hide_opt );
596 } elseif ( 'LIKE%' === $cond ) {
597 // starts with
598 $length = strlen( $hide_opt );
599 $substr = substr( $observed_value, 0, $length );
600 $m = 0 === strcasecmp( $substr, $hide_opt );
601 }
602
603 return $m;
604 }
605
606 /**
607 * Trim and sanitize the values
608 *
609 * @since 2.05
610 */
611 private static function get_value_for_comparision( $value ) {
612 // Remove white space from hide_opt
613 if ( ! is_array( $value ) ) {
614 $value = trim( $value );
615 }
616
617 FrmAppHelper::sanitize_value( 'wp_kses_post', $value );
618
619 return $value;
620 }
621
622 public static function array_value_condition( $observed_value, $cond, $hide_opt ) {
623 $m = false;
624 if ( $cond === '==' ) {
625 if ( is_array( $hide_opt ) ) {
626 $m = array_intersect( $hide_opt, $observed_value );
627 $m = empty( $m ) ? false : true;
628 } else {
629 $m = in_array( $hide_opt, $observed_value );
630 }
631 } elseif ( $cond === '!=' ) {
632 $m = ! in_array( $hide_opt, $observed_value );
633 } elseif ( $cond === '>' ) {
634 $min = min( $observed_value );
635 $m = $min > $hide_opt;
636 } elseif ( $cond === '<' ) {
637 $max = max( $observed_value );
638 $m = $max < $hide_opt;
639 } elseif ( $cond === 'LIKE' || $cond === 'not LIKE' ) {
640 foreach ( $observed_value as $ob ) {
641 $m = strpos( $ob, $hide_opt );
642 if ( $m !== false ) {
643 $m = true;
644 break;
645 }
646 }
647
648 if ( $cond === 'not LIKE' ) {
649 $m = ( $m === false ) ? true : false;
650 }
651 } elseif ( $cond === '%LIKE' ) {
652 // ends with
653 foreach ( $observed_value as $ob ) {
654 if ( $hide_opt === substr( $ob, strlen( $ob ) - strlen( $hide_opt ) ) ) {
655 $m = true;
656 break;
657 }
658 }
659 } elseif ( $cond === 'LIKE%' ) {
660 // starts with
661 foreach ( $observed_value as $ob ) {
662 if ( $hide_opt === substr( $ob, 0, strlen( $hide_opt ) ) ) {
663 $m = true;
664 break;
665 }
666 }
667 }
668
669 return $m;
670 }
671
672 /**
673 * Replace a few basic shortcodes and field ids
674 *
675 * @since 2.0
676 * @return string
677 */
678 public static function basic_replace_shortcodes( $value, $form, $entry ) {
679 if ( strpos( $value, '[sitename]' ) !== false ) {
680 $new_value = wp_specialchars_decode( FrmAppHelper::site_name(), ENT_QUOTES );
681 $value = str_replace( '[sitename]', $new_value, $value );
682 }
683
684 $value = apply_filters( 'frm_content', $value, $form, $entry );
685 $value = do_shortcode( $value );
686
687 return $value;
688 }
689
690 public static function get_shortcodes( $content, $form_id ) {
691 if ( FrmAppHelper::pro_is_installed() ) {
692 return FrmProDisplaysHelper::get_shortcodes( $content, $form_id );
693 }
694
695 $fields = FrmField::getAll(
696 array(
697 'fi.form_id' => (int) $form_id,
698 'fi.type not' => FrmField::no_save_fields(),
699 )
700 );
701
702 $tagregexp = self::allowed_shortcodes( $fields );
703
704 preg_match_all( "/\[(if )?($tagregexp)\b(.*?)(?:(\/))?\](?:(.+?)\[\/\2\])?/s", $content, $matches, PREG_PATTERN_ORDER );
705
706 return $matches;
707 }
708
709 public static function allowed_shortcodes( $fields = array() ) {
710 $tagregexp = array(
711 'editlink',
712 'id',
713 'key',
714 'ip',
715 'siteurl',
716 'sitename',
717 'admin_email',
718 'post[-|_]id',
719 'created[-|_]at',
720 'updated[-|_]at',
721 'updated[-|_]by',
722 'parent[-|_]id',
723 );
724
725 foreach ( $fields as $field ) {
726 $tagregexp[] = $field->id;
727 $tagregexp[] = $field->field_key;
728 }
729
730 $tagregexp = implode( '|', $tagregexp );
731
732 return $tagregexp;
733 }
734
735 public static function replace_content_shortcodes( $content, $entry, $shortcodes ) {
736 foreach ( $shortcodes[0] as $short_key => $tag ) {
737 if ( empty( $tag ) ) {
738 continue;
739 }
740
741 $atts = FrmShortcodeHelper::get_shortcode_attribute_array( $shortcodes[3][ $short_key ] );
742 $tag = FrmShortcodeHelper::get_shortcode_tag( $shortcodes, $short_key );
743
744 $atts['entry'] = $entry;
745 $atts['tag'] = $tag;
746 $replace_with = self::get_value_for_shortcode( $atts );
747
748 if ( $replace_with !== null ) {
749 $replace_with = self::trigger_shortcode_atts( $replace_with, $atts );
750 self::sanitize_embedded_shortcodes( compact( 'entry' ), $replace_with );
751 $content = str_replace( $shortcodes[0][ $short_key ], $replace_with, $content );
752 }
753
754 unset( $atts, $replace_with );
755 }
756
757 return $content;
758 }
759
760 /**
761 * @param string $replace_with
762 * @param array $atts
763 * @return string
764 */
765 private static function trigger_shortcode_atts( $replace_with, $atts ) {
766 $supported_atts = array( 'sanitize', 'sanitize_url' );
767 $included_atts = array_intersect( $supported_atts, array_keys( $atts ) );
768 foreach ( $included_atts as $included_att ) {
769 if ( '0' === $atts[ $included_att ] ) {
770 // Skip any option that uses 0 so sanitize_url=0 does not encode.
771 continue;
772 }
773 $function = 'atts_' . $included_att;
774 $replace_with = self::$function( $replace_with, $atts );
775 }
776 return $replace_with;
777 }
778
779 /**
780 * @param string $replace_with
781 * @return string
782 */
783 private static function atts_sanitize( $replace_with ) {
784 return sanitize_title_with_dashes( $replace_with );
785 }
786
787 /**
788 * @param string $replace_with
789 * @return string
790 */
791 private static function atts_sanitize_url( $replace_with ) {
792 return urlencode( $replace_with );
793 }
794
795 /**
796 * Prevent shortcodes in fields from being processed
797 *
798 * @since 3.01.02
799 *
800 * @param array $atts - includes entry object
801 * @param string $value
802 */
803 public static function sanitize_embedded_shortcodes( $atts, &$value ) {
804 $atts['value'] = $value;
805 $should_sanitize = apply_filters( 'frm_sanitize_shortcodes', true, $atts );
806 if ( $should_sanitize ) {
807 $value = str_replace( '[', '&#91;', $value );
808 }
809 }
810
811 /**
812 * @since 3.0
813 *
814 * @param $atts
815 *
816 * @return string
817 */
818 private static function get_value_for_shortcode( $atts ) {
819 $clean_tag = str_replace( '-', '_', $atts['tag'] );
820
821 $shortcode_values = array(
822 'id' => $atts['entry']->id,
823 'key' => $atts['entry']->item_key,
824 'ip' => $atts['entry']->ip,
825 );
826
827 $dynamic_default = array( 'admin_email', 'siteurl', 'frmurl', 'sitename', 'get' );
828
829 if ( isset( $shortcode_values[ $atts['tag'] ] ) ) {
830 $replace_with = $shortcode_values[ $atts['tag'] ];
831 } elseif ( in_array( $atts['tag'], $dynamic_default ) ) {
832 $replace_with = self::dynamic_default_values( $atts['tag'], $atts );
833 } elseif ( $clean_tag == 'user_agent' ) {
834 $description = $atts['entry']->description;
835 $replace_with = FrmEntriesHelper::get_browser( $description['browser'] );
836 } elseif ( $clean_tag == 'created_at' || $clean_tag == 'updated_at' ) {
837 $atts['tag'] = $clean_tag;
838 $replace_with = self::get_entry_timestamp( $atts );
839 } elseif ( $clean_tag == 'created_by' || $clean_tag == 'updated_by' ) {
840 $replace_with = self::get_display_value( $atts['entry']->{$clean_tag}, (object) array( 'type' => 'user_id' ), $atts );
841 } else {
842 $replace_with = self::get_field_shortcode_value( $atts );
843 }
844
845 return $replace_with;
846 }
847
848 /**
849 * @since 3.0
850 *
851 * @param $atts
852 *
853 * @return string
854 */
855 private static function get_entry_timestamp( $atts ) {
856 if ( isset( $atts['format'] ) ) {
857 $time_format = ' ';
858 } else {
859 $atts['format'] = get_option( 'date_format' );
860 $time_format = '';
861 }
862
863 return FrmAppHelper::get_formatted_time( $atts['entry']->{$atts['tag']}, $atts['format'], $time_format );
864 }
865
866 /**
867 * @since 3.0
868 *
869 * @param $atts
870 *
871 * @return null|string
872 */
873 private static function get_field_shortcode_value( $atts ) {
874 $field = FrmField::getOne( $atts['tag'] );
875 if ( empty( $field ) ) {
876 return null;
877 }
878
879 if ( isset( $atts['show'] ) && $atts['show'] === 'field_label' ) {
880 $replace_with = $field->name;
881 } elseif ( isset( $atts['show'] ) && $atts['show'] === 'description' ) {
882 $replace_with = $field->description;
883 } else {
884 $replace_with = FrmEntryMeta::get_meta_value( $atts['entry'], $field->id );
885 $string_value = $replace_with;
886 if ( is_array( $replace_with ) ) {
887 $sep = isset( $atts['sep'] ) ? $atts['sep'] : ', ';
888 $string_value = implode( $sep, $replace_with );
889 }
890
891 if ( empty( $string_value ) && $string_value != '0' ) {
892 $replace_with = '';
893 } else {
894 $atts['entry_id'] = $atts['entry']->id;
895 $atts['entry_key'] = $atts['entry']->item_key;
896 $replace_with = self::get_display_value( $replace_with, $field, $atts );
897 }
898 }
899
900 return $replace_with;
901 }
902
903 /**
904 * Get the value to replace a few standard shortcodes
905 *
906 * @since 2.0
907 * @return string
908 */
909 public static function dynamic_default_values( $tag, $atts = array(), $return_array = false ) {
910 $new_value = '';
911 switch ( $tag ) {
912 case 'admin_email':
913 $new_value = get_option( 'admin_email' );
914 break;
915 case 'siteurl':
916 $new_value = FrmAppHelper::site_url();
917 break;
918 case 'frmurl':
919 $new_value = FrmAppHelper::plugin_url();
920 break;
921 case 'sitename':
922 $new_value = FrmAppHelper::site_name();
923 break;
924 case 'get':
925 $new_value = self::process_get_shortcode( $atts, $return_array );
926 }
927
928 return $new_value;
929 }
930
931 /**
932 * Process the [get] shortcode
933 *
934 * @since 2.0
935 * @return string|array
936 */
937 public static function process_get_shortcode( $atts, $return_array = false ) {
938 if ( ! isset( $atts['param'] ) ) {
939 return '';
940 }
941
942 if ( strpos( $atts['param'], '&#91;' ) ) {
943 $atts['param'] = str_replace( '&#91;', '[', $atts['param'] );
944 $atts['param'] = str_replace( '&#93;', ']', $atts['param'] );
945 }
946
947 $new_value = FrmAppHelper::get_param( $atts['param'], '', 'get', 'sanitize_text_field' );
948 $new_value = FrmAppHelper::get_query_var( $new_value, $atts['param'] );
949
950 if ( $new_value == '' ) {
951 if ( ! isset( $atts['prev_val'] ) ) {
952 $atts['prev_val'] = '';
953 }
954
955 $new_value = isset( $atts['default'] ) ? $atts['default'] : $atts['prev_val'];
956 }
957
958 if ( is_array( $new_value ) && ! $return_array ) {
959 $new_value = implode( ', ', $new_value );
960 }
961
962 return $new_value;
963 }
964
965 public static function get_display_value( $value, $field, $atts = array() ) {
966
967 $value = apply_filters( 'frm_get_' . $field->type . '_display_value', $value, $field, $atts );
968 $value = apply_filters( 'frm_get_display_value', $value, $field, $atts );
969
970 $value = self::get_unfiltered_display_value( compact( 'value', 'field', 'atts' ) );
971
972 return apply_filters( 'frm_display_value', $value, $field, $atts );
973 }
974
975 /**
976 * @param $atts array Includes value, field, and atts
977 */
978 public static function get_unfiltered_display_value( $atts ) {
979 $value = $atts['value'];
980 $field = $atts['field'];
981 $atts = isset( $atts['atts'] ) ? $atts['atts'] : $atts;
982
983 if ( is_array( $field ) ) {
984 $field = $field['id'];
985 }
986
987 $field_obj = FrmFieldFactory::get_field_object( $field );
988
989 return $field_obj->get_display_value( $value, $atts );
990 }
991
992 /**
993 * Get a value from the user profile from the user ID
994 *
995 * @since 3.0
996 */
997 public static function get_user_display_name( $user_id, $user_info = 'display_name', $args = array() ) {
998 $defaults = array(
999 'blank' => false,
1000 'link' => false,
1001 'size' => 96,
1002 );
1003
1004 $args = wp_parse_args( $args, $defaults );
1005
1006 $user = get_userdata( $user_id );
1007 $info = '';
1008
1009 if ( $user ) {
1010 if ( $user_info == 'avatar' ) {
1011 $info = get_avatar( $user_id, $args['size'] );
1012 } elseif ( $user_info == 'author_link' ) {
1013 $info = get_author_posts_url( $user_id );
1014 } else {
1015 $info = isset( $user->$user_info ) ? $user->$user_info : '';
1016 }
1017
1018 if ( 'display_name' === $user_info && empty( $info ) && ! $args['blank'] ) {
1019 $info = $user->user_login;
1020 }
1021 }
1022
1023 if ( $args['link'] ) {
1024 $info = '<a href="' . esc_url( admin_url( 'user-edit.php?user_id=' . $user_id ) ) . '">' . $info . '</a>';
1025 }
1026
1027 return $info;
1028 }
1029
1030 public static function get_field_types( $type ) {
1031 $single_input = self::single_input_fields();
1032 $multiple_input = array( 'radio', 'checkbox', 'select', 'scale', 'star', 'lookup' );
1033
1034 $field_selection = FrmField::all_field_selection();
1035
1036 $field_types = array();
1037 if ( in_array( $type, $single_input ) ) {
1038 self::field_types_for_input( $single_input, $field_selection, $field_types );
1039 } elseif ( in_array( $type, $multiple_input ) ) {
1040 self::field_types_for_input( $multiple_input, $field_selection, $field_types );
1041 } elseif ( isset( $field_selection[ $type ] ) ) {
1042 $field_types[ $type ] = $field_selection[ $type ];
1043 }
1044
1045 $field_types = apply_filters( 'frm_switch_field_types', $field_types, compact( 'type', 'field_selection' ) );
1046
1047 return $field_types;
1048 }
1049
1050 /**
1051 * Get a list of all fields that use a single value input.
1052 *
1053 * @since 4.0
1054 */
1055 public static function single_input_fields() {
1056 $fields = array(
1057 'text',
1058 'textarea',
1059 'rte',
1060 'number',
1061 'email',
1062 'url',
1063 'date',
1064 'phone',
1065 'hidden',
1066 'time',
1067 'tag',
1068 'password',
1069 );
1070 return apply_filters( 'frm_single_input_fields', $fields );
1071 }
1072
1073 private static function field_types_for_input( $inputs, $fields, &$field_types ) {
1074 foreach ( $inputs as $input ) {
1075 $field_types[ $input ] = $fields[ $input ];
1076 unset( $input );
1077 }
1078 }
1079
1080 /**
1081 * Check if current field option is an "other" option
1082 *
1083 * @since 2.0.6
1084 *
1085 * @param string $opt_key
1086 *
1087 * @return boolean Returns true if current field option is an "Other" option
1088 */
1089 public static function is_other_opt( $opt_key ) {
1090 return $opt_key && strpos( $opt_key, 'other_' ) === 0;
1091 }
1092
1093 /**
1094 * Get value that belongs in "Other" text box
1095 *
1096 * @since 2.0.6
1097 *
1098 * @param array $args
1099 */
1100 public static function get_other_val( $args ) {
1101 $defaults = array(
1102 'opt_key' => 0,
1103 'field' => array(),
1104 'parent' => false,
1105 'pointer' => false,
1106 );
1107 $args = wp_parse_args( $args, $defaults );
1108
1109 $opt_key = $args['opt_key'];
1110 $field = $args['field'];
1111 $parent = $args['parent'];
1112 $pointer = $args['pointer'];
1113 $other_val = '';
1114
1115 // If option is an "other" option and there is a value set for this field,
1116 // check if the value belongs in the current "Other" option text field
1117 if ( ! self::is_other_opt( $opt_key ) || ! FrmField::is_option_true( $field, 'value' ) ) {
1118 return $other_val;
1119 }
1120
1121 // Check posted vals before checking saved values
1122 // For fields inside repeating sections - note, don't check if $pointer is true because it will often be zero
1123 if ( $parent && isset( $_POST['item_meta'][ $parent ][ $pointer ]['other'][ $field['id'] ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
1124 if ( FrmField::is_field_with_multiple_values( $field ) ) {
1125 // phpcs:ignore WordPress.Security.NonceVerification.Missing
1126 $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 ] ) ) : '';
1127 } else {
1128 $other_val = sanitize_text_field( wp_unslash( $_POST['item_meta'][ $parent ][ $pointer ]['other'][ $field['id'] ] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
1129 }
1130
1131 return $other_val;
1132
1133 } elseif ( isset( $field['id'] ) && isset( $_POST['item_meta']['other'][ $field['id'] ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
1134 // For normal fields
1135
1136 if ( FrmField::is_field_with_multiple_values( $field ) ) {
1137 // phpcs:ignore WordPress.Security.NonceVerification.Missing
1138 $other_val = isset( $_POST['item_meta']['other'][ $field['id'] ][ $opt_key ] ) ? sanitize_text_field( wp_unslash( $_POST['item_meta']['other'][ $field['id'] ][ $opt_key ] ) ) : '';
1139 } else {
1140 $other_val = sanitize_text_field( wp_unslash( $_POST['item_meta']['other'][ $field['id'] ] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
1141 }
1142
1143 return $other_val;
1144 }
1145
1146 // For checkboxes
1147 if ( $field['type'] === 'checkbox' && is_array( $field['value'] ) ) {
1148 // Check if there is an "other" val in saved value and make sure the
1149 // "other" val is not equal to the Other checkbox option
1150 if ( isset( $field['value'][ $opt_key ] ) && $field['options'][ $opt_key ] != $field['value'][ $opt_key ] ) {
1151 $other_val = $field['value'][ $opt_key ];
1152 }
1153 } else {
1154 /**
1155 * For radio buttons and dropdowns
1156 * Check if saved value equals any of the options. If not, set it as the other value.
1157 */
1158 foreach ( $field['options'] as $opt_key => $opt_val ) {
1159 $temp_val = is_array( $opt_val ) ? $opt_val['value'] : $opt_val;
1160 // Multi-select dropdowns - key is not preserved
1161 if ( is_array( $field['value'] ) ) {
1162 $o_key = array_search( $temp_val, $field['value'] );
1163 if ( isset( $field['value'][ $o_key ] ) ) {
1164 unset( $field['value'][ $o_key ], $o_key );
1165 }
1166 } elseif ( $temp_val == $field['value'] ) {
1167 // For radio and regular dropdowns
1168 return '';
1169 } else {
1170 $other_val = $field['value'];
1171 }
1172 unset( $opt_key, $opt_val, $temp_val );
1173 }
1174 // For multi-select dropdowns only
1175 if ( is_array( $field['value'] ) && ! empty( $field['value'] ) ) {
1176 $other_val = reset( $field['value'] );
1177 }
1178 }
1179
1180 return $other_val;
1181 }
1182
1183 /**
1184 * Check if there is a saved value for the "Other" text field. If so, set it as the $other_val.
1185 * Intended for front-end use
1186 *
1187 * @since 2.0.6
1188 *
1189 * @param array $args should include field, opt_key and field name
1190 * @param boolean $other_opt
1191 * @param string $checked
1192 *
1193 * @return array $other_args
1194 */
1195 public static function prepare_other_input( $args, &$other_opt, &$checked ) {
1196 $other_args = array(
1197 'name' => '',
1198 'value' => '',
1199 );
1200
1201 //Check if this is an "Other" option
1202 if ( ! self::is_other_opt( $args['opt_key'] ) ) {
1203 return $other_args;
1204 }
1205
1206 $other_opt = true;
1207
1208 self::set_other_name( $args, $other_args );
1209 self::set_other_value( $args, $other_args );
1210
1211 if ( '' !== $other_args['value'] ) {
1212 $checked = 'checked="checked" ';
1213 }
1214
1215 return $other_args;
1216 }
1217
1218 /**
1219 * @param array $args
1220 * @param array $other_args
1221 *
1222 * @since 2.0.6
1223 */
1224 private static function set_other_name( $args, &$other_args ) {
1225 //Set up name for other field
1226 $other_args['name'] = str_replace( '[]', '', $args['field_name'] );
1227 $other_args['name'] = preg_replace( '/\[' . $args['field']['id'] . '\]$/', '', $other_args['name'] );
1228 $other_args['name'] = $other_args['name'] . '[other][' . $args['field']['id'] . ']';
1229
1230 //Converts item_meta[field_id] => item_meta[other][field_id] and
1231 //item_meta[parent][0][field_id] => item_meta[parent][0][other][field_id]
1232 if ( FrmField::is_field_with_multiple_values( $args['field'] ) ) {
1233 $other_args['name'] .= '[' . $args['opt_key'] . ']';
1234 }
1235 }
1236
1237 /**
1238 * Find the parent and pointer, and get text for "other" text field
1239 *
1240 * @param array $args
1241 * @param array $other_args
1242 *
1243 * @since 2.0.6
1244 */
1245 private static function set_other_value( $args, &$other_args ) {
1246 $parent = '';
1247 $pointer = '';
1248
1249 // Check for parent ID and pointer
1250 $temp_array = explode( '[', $args['field_name'] );
1251
1252 // Count should only be greater than 3 if inside of a repeating section
1253 if ( count( $temp_array ) > 3 ) {
1254 $parent = str_replace( ']', '', $temp_array[1] );
1255 $pointer = str_replace( ']', '', $temp_array[2] );
1256 }
1257
1258 // Get text for "other" text field
1259 $other_args['value'] = self::get_other_val(
1260 array(
1261 'opt_key' => $args['opt_key'],
1262 'field' => $args['field'],
1263 'parent' => $parent,
1264 'pointer' => $pointer,
1265 )
1266 );
1267 }
1268
1269 /**
1270 * If this field includes an other option, show it
1271 *
1272 * @param $args array
1273 *
1274 * @since 2.0.6
1275 */
1276 public static function include_other_input( $args ) {
1277 if ( ! $args['other_opt'] ) {
1278 return;
1279 }
1280
1281 $classes = array( 'frm_other_input' );
1282 if ( ! $args['checked'] || trim( $args['checked'] ) == '' ) {
1283 // hide the field if the other option is not selected
1284 $classes[] = 'frm_pos_none';
1285 }
1286 if ( $args['field']['type'] == 'select' && $args['field']['multiple'] ) {
1287 $classes[] = 'frm_other_full';
1288 }
1289
1290 // Set up HTML ID for Other field
1291 $other_id = self::get_other_field_html_id( $args['field']['type'], $args['html_id'], $args['opt_key'] );
1292
1293 $label = isset( $args['opt_label'] ) ? $args['opt_label'] : $args['field']['name'];
1294
1295 echo '<label for="' . esc_attr( $other_id ) . '" class="frm_screen_reader frm_hidden">' .
1296 esc_html( $label ) .
1297 '</label>' .
1298 '<input type="text" id="' . esc_attr( $other_id ) . '" class="' . esc_attr( implode( ' ', $classes ) ) . '" ' .
1299 ( $args['read_only'] ? ' readonly="readonly" disabled="disabled"' : '' ) .
1300 ' name="' . esc_attr( $args['name'] ) . '" value="' . esc_attr( $args['value'] ) . '" />';
1301 }
1302
1303 /**
1304 * Get the HTML id for an "Other" text field
1305 * Note: This does not affect fields in repeating sections
1306 *
1307 * @since 2.0.08
1308 *
1309 * @param string $type - field type
1310 * @param string $html_id
1311 * @param string|boolean $opt_key
1312 *
1313 * @return string $other_id
1314 */
1315 public static function get_other_field_html_id( $type, $html_id, $opt_key = false ) {
1316 $other_id = $html_id;
1317
1318 // If hidden radio field, add an opt key of 0
1319 if ( $type == 'radio' && $opt_key === false ) {
1320 $opt_key = 0;
1321 }
1322
1323 if ( $opt_key !== false ) {
1324 $other_id .= '-' . $opt_key;
1325 }
1326
1327 $other_id .= '-otext';
1328
1329 return $other_id;
1330 }
1331
1332 public static function switch_field_ids( $val ) {
1333 global $frm_duplicate_ids;
1334 $replace = array();
1335 $replace_with = array();
1336 foreach ( (array) $frm_duplicate_ids as $old => $new ) {
1337 $replace[] = '[if ' . $old . ']';
1338 $replace_with[] = '[if ' . $new . ']';
1339 $replace[] = '[if ' . $old . ' ';
1340 $replace_with[] = '[if ' . $new . ' ';
1341 $replace[] = '[/if ' . $old . ']';
1342 $replace_with[] = '[/if ' . $new . ']';
1343 $replace[] = '[\/if ' . $old . ']';
1344 $replace_with[] = '[\/if ' . $new . ']';
1345 $replace[] = '[foreach ' . $old . ']';
1346 $replace_with[] = '[foreach ' . $new . ']';
1347 $replace[] = '[/foreach ' . $old . ']';
1348 $replace_with[] = '[/foreach ' . $new . ']';
1349 $replace[] = '[\/foreach ' . $old . ']';
1350 $replace_with[] = '[\/foreach ' . $new . ']';
1351 $replace[] = '[' . $old . ']';
1352 $replace_with[] = '[' . $new . ']';
1353 $replace[] = '[' . $old . ' ';
1354 $replace_with[] = '[' . $new . ' ';
1355 $replace[] = 'field_id="' . $old . '"';
1356 $replace_with[] = 'field_id="' . $new . '"';
1357 $replace[] = 'field_id=\"' . $old . '\"';
1358 $replace_with[] = 'field_id=\"' . $new . '\"';
1359 unset( $old, $new );
1360 }
1361 if ( is_array( $val ) ) {
1362 foreach ( $val as $k => $v ) {
1363 if ( is_string( $v ) ) {
1364 $val[ $k ] = str_replace( $replace, $replace_with, $v );
1365 unset( $k, $v );
1366 }
1367 }
1368 } else {
1369 $val = str_replace( $replace, $replace_with, $val );
1370 }
1371
1372 return $val;
1373 }
1374
1375 /**
1376 * @since 4.0
1377 */
1378 public static function bulk_options_overlay() {
1379 $prepop = array();
1380 self::get_bulk_prefilled_opts( $prepop, true );
1381
1382 include( FrmAppHelper::plugin_path() . '/classes/views/frm-fields/back-end/bulk-options-overlay.php' );
1383 }
1384
1385 public static function get_us_states() {
1386 $states = array(
1387 'AL' => 'Alabama',
1388 'AK' => 'Alaska',
1389 'AR' => 'Arkansas',
1390 'AZ' => 'Arizona',
1391 'CA' => 'California',
1392 'CO' => 'Colorado',
1393 'CT' => 'Connecticut',
1394 'DE' => 'Delaware',
1395 'DC' => 'District of Columbia',
1396 'FL' => 'Florida',
1397 'GA' => 'Georgia',
1398 'HI' => 'Hawaii',
1399 'ID' => 'Idaho',
1400 'IL' => 'Illinois',
1401 'IN' => 'Indiana',
1402 'IA' => 'Iowa',
1403 'KS' => 'Kansas',
1404 'KY' => 'Kentucky',
1405 'LA' => 'Louisiana',
1406 'ME' => 'Maine',
1407 'MD' => 'Maryland',
1408 'MA' => 'Massachusetts',
1409 'MI' => 'Michigan',
1410 'MN' => 'Minnesota',
1411 'MS' => 'Mississippi',
1412 'MO' => 'Missouri',
1413 'MT' => 'Montana',
1414 'NE' => 'Nebraska',
1415 'NV' => 'Nevada',
1416 'NH' => 'New Hampshire',
1417 'NJ' => 'New Jersey',
1418 'NM' => 'New Mexico',
1419 'NY' => 'New York',
1420 'NC' => 'North Carolina',
1421 'ND' => 'North Dakota',
1422 'OH' => 'Ohio',
1423 'OK' => 'Oklahoma',
1424 'OR' => 'Oregon',
1425 'PA' => 'Pennsylvania',
1426 'RI' => 'Rhode Island',
1427 'SC' => 'South Carolina',
1428 'SD' => 'South Dakota',
1429 'TN' => 'Tennessee',
1430 'TX' => 'Texas',
1431 'UT' => 'Utah',
1432 'VT' => 'Vermont',
1433 'VA' => 'Virginia',
1434 'WA' => 'Washington',
1435 'WV' => 'West Virginia',
1436 'WI' => 'Wisconsin',
1437 'WY' => 'Wyoming',
1438 );
1439
1440 return apply_filters( 'frm_us_states', $states );
1441 }
1442
1443 public static function get_countries() {
1444 $countries = array(
1445 __( 'Afghanistan', 'formidable' ),
1446 __( 'Aland Islands', 'formidable' ),
1447 __( 'Albania', 'formidable' ),
1448 __( 'Algeria', 'formidable' ),
1449 __( 'American Samoa', 'formidable' ),
1450 __( 'Andorra', 'formidable' ),
1451 __( 'Angola', 'formidable' ),
1452 __( 'Anguilla', 'formidable' ),
1453 __( 'Antarctica', 'formidable' ),
1454 __( 'Antigua and Barbuda', 'formidable' ),
1455 __( 'Argentina', 'formidable' ),
1456 __( 'Armenia', 'formidable' ),
1457 __( 'Aruba', 'formidable' ),
1458 __( 'Australia', 'formidable' ),
1459 __( 'Austria', 'formidable' ),
1460 __( 'Azerbaijan', 'formidable' ),
1461 __( 'Bahamas', 'formidable' ),
1462 __( 'Bahrain', 'formidable' ),
1463 __( 'Bangladesh', 'formidable' ),
1464 __( 'Barbados', 'formidable' ),
1465 __( 'Belarus', 'formidable' ),
1466 __( 'Belgium', 'formidable' ),
1467 __( 'Belize', 'formidable' ),
1468 __( 'Benin', 'formidable' ),
1469 __( 'Bermuda', 'formidable' ),
1470 __( 'Bhutan', 'formidable' ),
1471 __( 'Bolivia', 'formidable' ),
1472 __( 'Bonaire, Sint Eustatius and Saba', 'formidable' ),
1473 __( 'Bosnia and Herzegovina', 'formidable' ),
1474 __( 'Botswana', 'formidable' ),
1475 __( 'Bouvet Island', 'formidable' ),
1476 __( 'Brazil', 'formidable' ),
1477 __( 'British Indian Ocean Territory', 'formidable' ),
1478 __( 'Brunei', 'formidable' ),
1479 __( 'Bulgaria', 'formidable' ),
1480 __( 'Burkina Faso', 'formidable' ),
1481 __( 'Burundi', 'formidable' ),
1482 __( 'Cambodia', 'formidable' ),
1483 __( 'Cameroon', 'formidable' ),
1484 __( 'Canada', 'formidable' ),
1485 __( 'Cape Verde', 'formidable' ),
1486 __( 'Cayman Islands', 'formidable' ),
1487 __( 'Central African Republic', 'formidable' ),
1488 __( 'Chad', 'formidable' ),
1489 __( 'Chile', 'formidable' ),
1490 __( 'China', 'formidable' ),
1491 __( 'Christmas Island', 'formidable' ),
1492 __( 'Cocos (Keeling) Islands', 'formidable' ),
1493 __( 'Colombia', 'formidable' ),
1494 __( 'Comoros', 'formidable' ),
1495 __( 'Congo', 'formidable' ),
1496 __( 'Cook Islands', 'formidable' ),
1497 __( 'Costa Rica', 'formidable' ),
1498 __( 'C&ocirc;te d\'Ivoire', 'formidable' ),
1499 __( 'Croatia', 'formidable' ),
1500 __( 'Cuba', 'formidable' ),
1501 __( 'Curacao', 'formidable' ),
1502 __( 'Cyprus', 'formidable' ),
1503 __( 'Czech Republic', 'formidable' ),
1504 __( 'Denmark', 'formidable' ),
1505 __( 'Djibouti', 'formidable' ),
1506 __( 'Dominica', 'formidable' ),
1507 __( 'Dominican Republic', 'formidable' ),
1508 __( 'East Timor', 'formidable' ),
1509 __( 'Ecuador', 'formidable' ),
1510 __( 'Egypt', 'formidable' ),
1511 __( 'El Salvador', 'formidable' ),
1512 __( 'Equatorial Guinea', 'formidable' ),
1513 __( 'Eritrea', 'formidable' ),
1514 __( 'Estonia', 'formidable' ),
1515 __( 'Ethiopia', 'formidable' ),
1516 __( 'Falkland Islands (Malvinas)', 'formidable' ),
1517 __( 'Faroe Islands', 'formidable' ),
1518 __( 'Fiji', 'formidable' ),
1519 __( 'Finland', 'formidable' ),
1520 __( 'France', 'formidable' ),
1521 __( 'French Guiana', 'formidable' ),
1522 __( 'French Polynesia', 'formidable' ),
1523 __( 'French Southern Territories', 'formidable' ),
1524 __( 'Gabon', 'formidable' ),
1525 __( 'Gambia', 'formidable' ),
1526 __( 'Georgia', 'formidable' ),
1527 __( 'Germany', 'formidable' ),
1528 __( 'Ghana', 'formidable' ),
1529 __( 'Gibraltar', 'formidable' ),
1530 __( 'Greece', 'formidable' ),
1531 __( 'Greenland', 'formidable' ),
1532 __( 'Grenada', 'formidable' ),
1533 __( 'Guadeloupe', 'formidable' ),
1534 __( 'Guam', 'formidable' ),
1535 __( 'Guatemala', 'formidable' ),
1536 __( 'Guernsey', 'formidable' ),
1537 __( 'Guinea', 'formidable' ),
1538 __( 'Guinea-Bissau', 'formidable' ),
1539 __( 'Guyana', 'formidable' ),
1540 __( 'Haiti', 'formidable' ),
1541 __( 'Heard Island and McDonald Islands', 'formidable' ),
1542 __( 'Holy See', 'formidable' ),
1543 __( 'Honduras', 'formidable' ),
1544 __( 'Hong Kong', 'formidable' ),
1545 __( 'Hungary', 'formidable' ),
1546 __( 'Iceland', 'formidable' ),
1547 __( 'India', 'formidable' ),
1548 __( 'Indonesia', 'formidable' ),
1549 __( 'Iran', 'formidable' ),
1550 __( 'Iraq', 'formidable' ),
1551 __( 'Ireland', 'formidable' ),
1552 __( 'Israel', 'formidable' ),
1553 __( 'Isle of Man', 'formidable' ),
1554 __( 'Italy', 'formidable' ),
1555 __( 'Jamaica', 'formidable' ),
1556 __( 'Japan', 'formidable' ),
1557 __( 'Jersey', 'formidable' ),
1558 __( 'Jordan', 'formidable' ),
1559 __( 'Kazakhstan', 'formidable' ),
1560 __( 'Kenya', 'formidable' ),
1561 __( 'Kiribati', 'formidable' ),
1562 __( 'North Korea', 'formidable' ),
1563 __( 'South Korea', 'formidable' ),
1564 __( 'Kosovo', 'formidable' ),
1565 __( 'Kuwait', 'formidable' ),
1566 __( 'Kyrgyzstan', 'formidable' ),
1567 __( 'Laos', 'formidable' ),
1568 __( 'Latvia', 'formidable' ),
1569 __( 'Lebanon', 'formidable' ),
1570 __( 'Lesotho', 'formidable' ),
1571 __( 'Liberia', 'formidable' ),
1572 __( 'Libya', 'formidable' ),
1573 __( 'Liechtenstein', 'formidable' ),
1574 __( 'Lithuania', 'formidable' ),
1575 __( 'Luxembourg', 'formidable' ),
1576 __( 'Macao', 'formidable' ),
1577 __( 'Macedonia', 'formidable' ),
1578 __( 'Madagascar', 'formidable' ),
1579 __( 'Malawi', 'formidable' ),
1580 __( 'Malaysia', 'formidable' ),
1581 __( 'Maldives', 'formidable' ),
1582 __( 'Mali', 'formidable' ),
1583 __( 'Malta', 'formidable' ),
1584 __( 'Marshall Islands', 'formidable' ),
1585 __( 'Martinique', 'formidable' ),
1586 __( 'Mauritania', 'formidable' ),
1587 __( 'Mauritius', 'formidable' ),
1588 __( 'Mayotte', 'formidable' ),
1589 __( 'Mexico', 'formidable' ),
1590 __( 'Micronesia', 'formidable' ),
1591 __( 'Moldova', 'formidable' ),
1592 __( 'Monaco', 'formidable' ),
1593 __( 'Mongolia', 'formidable' ),
1594 __( 'Montenegro', 'formidable' ),
1595 __( 'Montserrat', 'formidable' ),
1596 __( 'Morocco', 'formidable' ),
1597 __( 'Mozambique', 'formidable' ),
1598 __( 'Myanmar', 'formidable' ),
1599 __( 'Namibia', 'formidable' ),
1600 __( 'Nauru', 'formidable' ),
1601 __( 'Nepal', 'formidable' ),
1602 __( 'Netherlands', 'formidable' ),
1603 __( 'New Caledonia', 'formidable' ),
1604 __( 'New Zealand', 'formidable' ),
1605 __( 'Nicaragua', 'formidable' ),
1606 __( 'Niger', 'formidable' ),
1607 __( 'Nigeria', 'formidable' ),
1608 __( 'Niue', 'formidable' ),
1609 __( 'Norfolk Island', 'formidable' ),
1610 __( 'Northern Mariana Islands', 'formidable' ),
1611 __( 'Norway', 'formidable' ),
1612 __( 'Oman', 'formidable' ),
1613 __( 'Pakistan', 'formidable' ),
1614 __( 'Palau', 'formidable' ),
1615 __( 'Palestine', 'formidable' ),
1616 __( 'Panama', 'formidable' ),
1617 __( 'Papua New Guinea', 'formidable' ),
1618 __( 'Paraguay', 'formidable' ),
1619 __( 'Peru', 'formidable' ),
1620 __( 'Philippines', 'formidable' ),
1621 __( 'Pitcairn', 'formidable' ),
1622 __( 'Poland', 'formidable' ),
1623 __( 'Portugal', 'formidable' ),
1624 __( 'Puerto Rico', 'formidable' ),
1625 __( 'Qatar', 'formidable' ),
1626 __( 'Reunion', 'formidable' ),
1627 __( 'Romania', 'formidable' ),
1628 __( 'Russia', 'formidable' ),
1629 __( 'Rwanda', 'formidable' ),
1630 __( 'Saint Barthelemy', 'formidable' ),
1631 __( 'Saint Helena, Ascension and Tristan da Cunha', 'formidable' ),
1632 __( 'Saint Kitts and Nevis', 'formidable' ),
1633 __( 'Saint Lucia', 'formidable' ),
1634 __( 'Saint Martin (French part)', 'formidable' ),
1635 __( 'Saint Pierre and Miquelon', 'formidable' ),
1636 __( 'Saint Vincent and the Grenadines', 'formidable' ),
1637 __( 'Samoa', 'formidable' ),
1638 __( 'San Marino', 'formidable' ),
1639 __( 'Sao Tome and Principe', 'formidable' ),
1640 __( 'Saudi Arabia', 'formidable' ),
1641 __( 'Senegal', 'formidable' ),
1642 __( 'Serbia', 'formidable' ),
1643 __( 'Seychelles', 'formidable' ),
1644 __( 'Sierra Leone', 'formidable' ),
1645 __( 'Singapore', 'formidable' ),
1646 __( 'Sint Maarten (Dutch part)', 'formidable' ),
1647 __( 'Slovakia', 'formidable' ),
1648 __( 'Slovenia', 'formidable' ),
1649 __( 'Solomon Islands', 'formidable' ),
1650 __( 'Somalia', 'formidable' ),
1651 __( 'South Africa', 'formidable' ),
1652 __( 'South Georgia and the South Sandwich Islands', 'formidable' ),
1653 __( 'South Sudan', 'formidable' ),
1654 __( 'Spain', 'formidable' ),
1655 __( 'Sri Lanka', 'formidable' ),
1656 __( 'Sudan', 'formidable' ),
1657 __( 'Suriname', 'formidable' ),
1658 __( 'Svalbard and Jan Mayen', 'formidable' ),
1659 __( 'Swaziland', 'formidable' ),
1660 __( 'Sweden', 'formidable' ),
1661 __( 'Switzerland', 'formidable' ),
1662 __( 'Syria', 'formidable' ),
1663 __( 'Taiwan', 'formidable' ),
1664 __( 'Tajikistan', 'formidable' ),
1665 __( 'Tanzania', 'formidable' ),
1666 __( 'Thailand', 'formidable' ),
1667 __( 'Timor-Leste', 'formidable' ),
1668 __( 'Togo', 'formidable' ),
1669 __( 'Tokelau', 'formidable' ),
1670 __( 'Tonga', 'formidable' ),
1671 __( 'Trinidad and Tobago', 'formidable' ),
1672 __( 'Tunisia', 'formidable' ),
1673 __( 'Turkey', 'formidable' ),
1674 __( 'Turkmenistan', 'formidable' ),
1675 __( 'Turks and Caicos Islands', 'formidable' ),
1676 __( 'Tuvalu', 'formidable' ),
1677 __( 'Uganda', 'formidable' ),
1678 __( 'Ukraine', 'formidable' ),
1679 __( 'United Arab Emirates', 'formidable' ),
1680 __( 'United Kingdom', 'formidable' ),
1681 __( 'United States', 'formidable' ),
1682 __( 'United States Minor Outlying Islands', 'formidable' ),
1683 __( 'Uruguay', 'formidable' ),
1684 __( 'Uzbekistan', 'formidable' ),
1685 __( 'Vanuatu', 'formidable' ),
1686 __( 'Vatican City', 'formidable' ),
1687 __( 'Venezuela', 'formidable' ),
1688 __( 'Vietnam', 'formidable' ),
1689 __( 'Virgin Islands, British', 'formidable' ),
1690 __( 'Virgin Islands, U.S.', 'formidable' ),
1691 __( 'Wallis and Futuna', 'formidable' ),
1692 __( 'Western Sahara', 'formidable' ),
1693 __( 'Yemen', 'formidable' ),
1694 __( 'Zambia', 'formidable' ),
1695 __( 'Zimbabwe', 'formidable' ),
1696 );
1697
1698 sort( $countries, SORT_LOCALE_STRING );
1699 return apply_filters( 'frm_countries', $countries );
1700 }
1701
1702 /**
1703 * Gets bulk prefilled options.
1704 *
1705 * @since 5.0.04 Add `$include_class` param.
1706 *
1707 * @param array $prepop Bulk options.
1708 * @param array|false $include_class Include the class in the bulk options.
1709 */
1710 public static function get_bulk_prefilled_opts( array &$prepop, $include_class = false ) {
1711 // Countries.
1712 $countries = self::get_countries();
1713 if ( $include_class ) {
1714 $countries['class'] = 'frm-countries-opts';
1715 }
1716
1717 $prepop[ __( 'Countries', 'formidable' ) ] = $countries;
1718
1719 // State abv.
1720 $states = self::get_us_states();
1721 $state_abv = array_keys( $states );
1722 sort( $state_abv );
1723 if ( $include_class ) {
1724 $state_abv['class'] = 'frm-state-abv-opts';
1725 }
1726
1727 $prepop[ __( 'U.S. State Abbreviations', 'formidable' ) ] = $state_abv;
1728
1729 // States.
1730 $states = array_values( $states );
1731 sort( $states );
1732 if ( $include_class ) {
1733 $states['class'] = 'frm-states-opts';
1734 }
1735
1736 $prepop[ __( 'U.S. States', 'formidable' ) ] = $states;
1737 unset( $state_abv, $states );
1738
1739 // Age.
1740 $ages = array(
1741 __( 'Under 18', 'formidable' ),
1742 __( '18-24', 'formidable' ),
1743 __( '25-34', 'formidable' ),
1744 __( '35-44', 'formidable' ),
1745 __( '45-54', 'formidable' ),
1746 __( '55-64', 'formidable' ),
1747 __( '65 or Above', 'formidable' ),
1748 __( 'Prefer Not to Answer', 'formidable' ),
1749 );
1750 if ( $include_class ) {
1751 $ages['class'] = 'frm-age-opts';
1752 }
1753
1754 $prepop[ __( 'Age', 'formidable' ) ] = $ages;
1755
1756 // Satisfaction.
1757 $satisfaction = array(
1758 __( 'Very Unsatisfied', 'formidable' ),
1759 __( 'Unsatisfied', 'formidable' ),
1760 __( 'Neutral', 'formidable' ),
1761 __( 'Satisfied', 'formidable' ),
1762 __( 'Very Satisfied', 'formidable' ),
1763 __( 'N/A', 'formidable' ),
1764 );
1765 if ( $include_class ) {
1766 $satisfaction['class'] = 'frm-satisfaction-opts';
1767 }
1768
1769 $prepop[ __( 'Satisfaction', 'formidable' ) ] = $satisfaction;
1770
1771 // Importance.
1772 $importance = array(
1773 __( 'Not at all Important', 'formidable' ),
1774 __( 'Somewhat Important', 'formidable' ),
1775 __( 'Neutral', 'formidable' ),
1776 __( 'Important', 'formidable' ),
1777 __( 'Very Important', 'formidable' ),
1778 __( 'N/A', 'formidable' ),
1779 );
1780 if ( $include_class ) {
1781 $importance['class'] = 'frm-importance-opts';
1782 }
1783
1784 $prepop[ __( 'Importance', 'formidable' ) ] = $importance;
1785
1786 // Agreement.
1787 $agreement = array(
1788 __( 'Strongly Disagree', 'formidable' ),
1789 __( 'Disagree', 'formidable' ),
1790 __( 'Neutral', 'formidable' ),
1791 __( 'Agree', 'formidable' ),
1792 __( 'Strongly Agree', 'formidable' ),
1793 __( 'N/A', 'formidable' ),
1794 );
1795 if ( $include_class ) {
1796 $agreement['class'] = 'frm-agreement-opts';
1797 }
1798
1799 $prepop[ __( 'Agreement', 'formidable' ) ] = $agreement;
1800
1801 // Likely.
1802 $likely = array(
1803 __( 'Extremely Unlikely', 'formidable' ),
1804 __( 'Unlikely', 'formidable' ),
1805 __( 'Neutral', 'formidable' ),
1806 __( 'Likely', 'formidable' ),
1807 __( 'Extremely Likely', 'formidable' ),
1808 __( 'N/A', 'formidable' ),
1809 );
1810 if ( $include_class ) {
1811 $likely['class'] = 'frm-likely-opts';
1812 }
1813
1814 $prepop[ __( 'Likely', 'formidable' ) ] = $likely;
1815
1816 $prepop = apply_filters( 'frm_bulk_field_choices', $prepop );
1817 }
1818
1819 /**
1820 * Display a field value selector
1821 *
1822 * @since 2.03.05
1823 *
1824 * @param int $selector_field_id
1825 * @param array $selector_args
1826 */
1827 public static function display_field_value_selector( $selector_field_id, $selector_args ) {
1828 $field_value_selector = FrmFieldFactory::create_field_value_selector( $selector_field_id, $selector_args );
1829 $field_value_selector->display();
1830 }
1831
1832 /**
1833 * Convert a field object to a flat array
1834 *
1835 * @since 2.03.05
1836 *
1837 * @param object $field
1838 *
1839 * @return array
1840 */
1841 public static function convert_field_object_to_flat_array( $field ) {
1842 $field_options = $field->field_options;
1843 $field_array = get_object_vars( $field );
1844 unset( $field_array['field_options'] );
1845
1846 return $field_array + $field_options;
1847 }
1848
1849 /**
1850 * @since 4.04
1851 *
1852 * @param array $args
1853 * @return void
1854 */
1855 public static function show_add_field_buttons( $args ) {
1856 $field_key = $args['field_key'];
1857 $field_type = $args['field_type'];
1858 $field_label = FrmAppHelper::icon_by_class( FrmFormsHelper::get_field_link_icon( $field_type ), array( 'echo' => false ) );
1859 $field_name = FrmFormsHelper::get_field_link_name( $field_type );
1860 $field_label .= ' <span>' . $field_name . '</span>';
1861
1862 // If the individual field isn't allowed, disable it.
1863 $run_filter = true;
1864 $single_no_allow = ' ';
1865 $install_data = '';
1866 $requires = '';
1867 $link = isset( $field_type['link'] ) ? esc_url_raw( $field_type['link'] ) : '';
1868 $has_show_upgrade_class = strpos( $field_type['icon'], ' frm_show_upgrade' );
1869 $show_upgrade = $has_show_upgrade_class || false !== strpos( $args['no_allow_class'], 'frm_show_upgrade' );
1870
1871 if ( $has_show_upgrade_class ) {
1872 $single_no_allow .= 'frm_show_upgrade';
1873 $field_type['icon'] = str_replace( ' frm_show_upgrade', '', $field_type['icon'] );
1874 $run_filter = false;
1875 if ( isset( $field_type['addon'] ) ) {
1876 $upgrading = FrmAddonsController::install_link( $field_type['addon'] );
1877 if ( isset( $upgrading['url'] ) ) {
1878 $install_data = json_encode( $upgrading );
1879 }
1880 $requires = FrmFormsHelper::get_plan_required( $upgrading );
1881 } elseif ( isset( $field_type['require'] ) ) {
1882 $requires = $field_type['require'];
1883 }
1884 }
1885
1886 $upgrade_label = '';
1887 $upgrade_message = '';
1888 if ( $show_upgrade ) {
1889 /* translators: %s: Field name */
1890 $upgrade_label = sprintf( esc_html__( '%s fields', 'formidable' ), $field_name );
1891
1892 if ( isset( $field_type['message'] ) ) {
1893 $upgrade_message = FrmAppHelper::kses( $field_type['message'], array( 'a', 'img' ) );
1894 }
1895 }
1896
1897 $li_params = array(
1898 'class' => 'frmbutton frm6 ' . $args['no_allow_class'] . $single_no_allow . ' frm_t' . str_replace( '|', '-', $field_key ),
1899 'id' => $field_key,
1900 'data-upgrade' => $upgrade_label,
1901 'data-link' => $link,
1902 'data-medium' => 'builder',
1903 'data-oneclick' => $install_data,
1904 'data-content' => $field_key,
1905 'data-requires' => $requires,
1906 );
1907
1908 if ( $upgrade_message ) {
1909 $li_params['data-message'] = $upgrade_message;
1910 }
1911 ?>
1912 <li <?php FrmAppHelper::array_to_html_params( $li_params, true ); ?>>
1913 <?php
1914 if ( $run_filter ) {
1915 $field_label = apply_filters( 'frmpro_field_links', $field_label, $args['id'], $field_key );
1916 }
1917 echo FrmAppHelper::kses( $field_label, array( 'a', 'i', 'span', 'use', 'svg' ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1918 ?>
1919 </li>
1920 <?php
1921 }
1922
1923 /**
1924 * Shows Display format option.
1925 *
1926 * @since 5.0.04
1927 *
1928 * @param array $field Field data.
1929 */
1930 public static function show_radio_display_format( $field ) {
1931 $options = array(
1932 '0' => array(
1933 'text' => __( 'Simple', 'formidable' ),
1934 'svg' => 'frm_simple_radio',
1935 ),
1936 '1' => array(
1937 'text' => __( 'Images', 'formidable' ),
1938 'svg' => 'frm_image_as_option',
1939 'addon' => 'pro',
1940 'upgrade' => __( 'Image Options', 'formidable' ),
1941 '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" />',
1942 'content' => 'image-options',
1943 ),
1944 'buttons' => array(
1945 'text' => __( 'Buttons', 'formidable' ),
1946 'svg' => 'frm_button_as_option',
1947 'addon' => 'surveys',
1948 'upgrade' => __( 'Button Options', 'formidable' ),
1949 'message' => __( 'Show buttons for radio buttons or check boxes. This is ideal for polls, surveys, segmenting questionnaires and more.', 'formidable' ),
1950 'content' => 'button-options',
1951 ),
1952 );
1953
1954 /**
1955 * Allows modifying the options of Display format setting of Radio field.
1956 *
1957 * @since 5.0.04
1958 *
1959 * @param array $options Options.
1960 */
1961 $options = apply_filters( 'frm_radio_display_format_options', $options );
1962
1963 $args = self::get_display_format_args( $field, $options );
1964
1965 include FrmAppHelper::plugin_path() . '/classes/views/frm-fields/back-end/radio-display-format.php';
1966 }
1967
1968 /**
1969 * Gets display format arguments to pass to the images_dropdown() method.
1970 *
1971 * @since 5.0.04
1972 *
1973 * @param array $field Field data.
1974 * @param array $options Options array.
1975 * @return array
1976 */
1977 private static function get_display_format_args( $field, $options ) {
1978 $args = array(
1979 'selected' => '0',
1980 'options' => array(),
1981 'name' => 'field_options[image_options_' . $field['id'] . ']',
1982 'input_attrs' => array(
1983 'class' => 'frm_toggle_image_options',
1984 ),
1985 );
1986
1987 self::fill_image_setting_options( $options, $args );
1988
1989 /**
1990 * Allows modifying the arguments of Display format setting of Radio field.
1991 *
1992 * @since 5.0.04
1993 *
1994 * @param array $args Arguments.
1995 * @param array $method_args The arguments from the method. Contains `field`, `options`.
1996 */
1997 return apply_filters( 'frm_radio_display_format_args', $args, compact( 'field', 'options' ) );
1998 }
1999
2000 /**
2001 * @since 5.0.04
2002 */
2003 private static function fill_image_setting_options( $options, &$args ) {
2004 foreach ( $options as $key => $option ) {
2005 $args['options'][ $key ] = $option;
2006
2007 if ( ! empty( $option['addon'] ) ) {
2008 $args['options'][ $key ]['custom_attrs'] = self::fill_image_setting_addon_link( $option );
2009 }
2010
2011 unset( $args['options'][ $key ]['addon'] );
2012 $fill = array( 'upgrade', 'message', 'content' );
2013 foreach ( $fill as $f ) {
2014 unset( $args['options'][ $key ][ $f ], $f );
2015 }
2016 }
2017 }
2018
2019 /**
2020 * @since 5.0.04
2021 *
2022 * @return array
2023 */
2024 private static function fill_image_setting_addon_link( $option ) {
2025 $custom_attrs = array(
2026 'class' => 'frm_noallow frm_show_upgrade',
2027 'data-medium' => 'builder',
2028 );
2029
2030 // translators: Add-on name.
2031 $custom_attrs['data-upgrade'] = sprintf( __( 'Formidable %s', 'formidable' ), ucwords( $option['addon'] ) );
2032
2033 $fill = array( 'upgrade', 'message', 'content' );
2034 foreach ( $fill as $f ) {
2035 if ( isset( $option[ $f ] ) ) {
2036 $custom_attrs[ 'data-' . $f ] = $option[ $f ];
2037 }
2038 }
2039
2040 if ( 'pro' === $option['addon'] ) {
2041 return $custom_attrs;
2042 }
2043
2044 $upgrading = FrmAddonsController::install_link( $option['addon'] );
2045 if ( isset( $upgrading['url'] ) ) {
2046 $install_data = wp_json_encode( $upgrading );
2047 } else {
2048 $install_data = '';
2049 }
2050
2051 $custom_attrs['data-oneclick'] = $install_data;
2052 $custom_attrs['data-requires'] = FrmFormsHelper::get_plan_required( $upgrading );
2053
2054 return $custom_attrs;
2055 }
2056
2057 /**
2058 * Maybe adjust a field value based on type.
2059 * Some types require unserializing an array (@see self::field_type_requires_unserialize).
2060 *
2061 * @since 6.2
2062 *
2063 * @param mixed $value
2064 * @param string $field_type
2065 * @return void
2066 */
2067 public static function prepare_field_value( &$value, $field_type ) {
2068 $field_object = FrmFieldFactory::get_field_type( $field_type );
2069 $value = $field_object->maybe_decode_value( $value );
2070 }
2071
2072 /**
2073 * @deprecated 4.0
2074 */
2075 public static function show_icon_link_js( $atts ) {
2076 _deprecated_function( __METHOD__, '4.0' );
2077 $atts['icon'] .= $atts['is_selected'] ? ' ' : ' frm_inactive_icon ';
2078 if ( isset( $atts['has_default'] ) && ! $atts['has_default'] ) {
2079 $atts['icon'] .= 'frm_hidden ';
2080 }
2081 echo '<a href="javascript:void(0)" class="frm_bstooltip ' . esc_attr( $atts['icon'] ) . 'frm_default_val_icons frm_action_icon frm_icon_font" title="' . esc_attr( $atts['message'] ) . '"></a>';
2082 }
2083
2084 /**
2085 * @deprecated 4.0
2086 */
2087 public static function show_default_blank_js( $is_selected, $has_default_value = true ) {
2088 _deprecated_function( __METHOD__, '4.0' );
2089 }
2090
2091 /**
2092 * @deprecated 4.0
2093 */
2094 public static function clear_on_focus_html( $field, $display, $id = '' ) {
2095 _deprecated_function( __METHOD__, '4.0' );
2096 }
2097
2098 /**
2099 * @deprecated 4.0
2100 */
2101 public static function show_onfocus_js( $is_selected, $has_default_value = true ) {
2102 _deprecated_function( __METHOD__, '4.0' );
2103 }
2104
2105 /**
2106 * @deprecated 3.0
2107 * @codeCoverageIgnore
2108 */
2109 public static function display_recaptcha() {
2110 _deprecated_function( __FUNCTION__, '3.0', 'FrmFieldCaptcha::field_input' );
2111 }
2112
2113 /**
2114 * @deprecated 3.0
2115 * @codeCoverageIgnore
2116 */
2117 public static function remove_inline_conditions( $no_vars, $code, $replace_with, &$html ) {
2118 FrmDeprecated::remove_inline_conditions( $no_vars, $code, $replace_with, $html );
2119 }
2120
2121 /**
2122 * @deprecated 3.0
2123 * @codeCoverageIgnore
2124 */
2125 public static function get_shortcode_tag( $shortcodes, $short_key, $args ) {
2126 return FrmDeprecated::get_shortcode_tag( $shortcodes, $short_key, $args );
2127 }
2128
2129 /**
2130 * @deprecated 3.0
2131 * @codeCoverageIgnore
2132 *
2133 * @param string $html
2134 * @param array $field
2135 * @param array $errors
2136 * @param object|false $form
2137 * @param array $args
2138 *
2139 * @return string
2140 */
2141 public static function replace_shortcodes( $html, $field, $errors = array(), $form = false, $args = array() ) {
2142 return FrmDeprecated::replace_shortcodes( $html, $field, $errors, $form, $args );
2143 }
2144
2145 /**
2146 * @deprecated 3.0
2147 * @codeCoverageIgnore
2148 */
2149 public static function get_default_field_opts( $type, $field = null, $limit = false ) {
2150 return FrmDeprecated::get_default_field_opts( $type, $field, $limit );
2151 }
2152
2153 /**
2154 * @deprecated 2.02.07 This is still referenced in the Highrise add on as of v1.06.
2155 * @codeCoverageIgnore
2156 *
2157 * @param array $args
2158 * @return string
2159 */
2160 public static function dropdown_categories( $args ) {
2161 return FrmDeprecated::dropdown_categories( $args );
2162 }
2163 }
2164