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

2,199 lines 64.8 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 * Shows the inline modal.
496 *
497 * @since 4.0
498 * @since 6.4.1 Added `inside_class` in the arguments.
499 *
500 * @param array $args The arguments.
501 */
502 public static function inline_modal( $args ) {
503 $defaults = array(
504 'id' => '',
505 'class' => '',
506 'show' => 0,
507 'callback' => array(),
508 'args' => array(),
509 'title' => '',
510 'inside_class' => 'inside',
511 );
512 $args = array_merge( $defaults, $args );
513
514 include( FrmAppHelper::plugin_path() . '/classes/views/frm-fields/back-end/inline-modal.php' );
515 }
516
517 /**
518 * @since 4.0
519 */
520 public static function smart_values() {
521 $continue = apply_filters( 'frm_smart_values_box', true );
522 if ( $continue === true ) {
523 $upgrade_link = array(
524 'medium' => 'builder',
525 'content' => 'smart-tags',
526 );
527 include( FrmAppHelper::plugin_path() . '/classes/views/frm-fields/back-end/smart-values.php' );
528 }
529 }
530
531 /**
532 * @since 4.0
533 */
534 public static function input_mask() {
535 include( FrmAppHelper::plugin_path() . '/classes/views/frm-fields/back-end/input-mask-info.php' );
536 }
537
538 /**
539 * @since 4.0
540 */
541 public static function layout_classes() {
542 include( FrmAppHelper::plugin_path() . '/classes/views/frm-fields/back-end/layout-classes.php' );
543 }
544
545 /**
546 * @param int $tax_id
547 *
548 * @return string
549 */
550 public static function get_term_link( $tax_id ) {
551 $tax = get_taxonomy( $tax_id );
552 if ( ! $tax ) {
553 return '';
554 }
555
556 $link = sprintf(
557 /* translators: %1$s: Start HTML link, %2$s: Content type label, %3$s: Content type, %4$s: End HTML link */
558 esc_html__( 'Options are dynamically created from your %1$s%2$s: %3$s%4$s', 'formidable' ),
559 '<a href="' . esc_url( admin_url( 'edit-tags.php?taxonomy=' . $tax->name ) ) . '" target="_blank">',
560 esc_html__( 'taxonomy', 'formidable' ),
561 empty( $tax->labels->name ) ? esc_html__( 'Categories', 'formidable' ) : $tax->labels->name,
562 '</a>'
563 );
564 unset( $tax );
565
566 return $link;
567 }
568
569 public static function value_meets_condition( $observed_value, $cond, $hide_opt ) {
570 $hide_opt = self::get_value_for_comparision( $hide_opt );
571 $observed_value = self::get_value_for_comparision( $observed_value );
572
573 if ( is_array( $observed_value ) ) {
574 return self::array_value_condition( $observed_value, $cond, $hide_opt );
575 }
576
577 $m = false;
578 if ( $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 === '>=' ) {
585 $m = $observed_value >= $hide_opt;
586 } elseif ( $cond === '<' ) {
587 $m = $observed_value < $hide_opt;
588 } elseif ( $cond === '<=' ) {
589 $m = $observed_value <= $hide_opt;
590 } elseif ( $cond === 'LIKE' || $cond === 'not LIKE' ) {
591 $m = stripos( $observed_value, $hide_opt );
592 if ( $cond === 'not LIKE' ) {
593 $m = ( $m === false ) ? true : false;
594 } else {
595 $m = ( $m === false ) ? false : true;
596 }
597 } elseif ( $cond === '%LIKE' ) {
598 // ends with
599 $length = strlen( $hide_opt );
600 $substr = substr( $observed_value, strlen( $observed_value ) - $length );
601 $m = 0 === strcasecmp( $substr, $hide_opt );
602 } elseif ( 'LIKE%' === $cond ) {
603 // starts with
604 $length = strlen( $hide_opt );
605 $substr = substr( $observed_value, 0, $length );
606 $m = 0 === strcasecmp( $substr, $hide_opt );
607 }
608
609 return $m;
610 }
611
612 /**
613 * Trim and sanitize the values
614 *
615 * @since 2.05
616 */
617 private static function get_value_for_comparision( $value ) {
618 // Remove white space from hide_opt
619 if ( ! is_array( $value ) ) {
620 $value = trim( $value );
621 }
622
623 FrmAppHelper::sanitize_value( 'wp_kses_post', $value );
624
625 return $value;
626 }
627
628 public static function array_value_condition( $observed_value, $cond, $hide_opt ) {
629 $m = false;
630 if ( $cond === '==' ) {
631 if ( is_array( $hide_opt ) ) {
632 $m = array_intersect( $hide_opt, $observed_value );
633 $m = empty( $m ) ? false : true;
634 } else {
635 $m = in_array( $hide_opt, $observed_value );
636 }
637 } elseif ( $cond === '!=' ) {
638 $m = ! in_array( $hide_opt, $observed_value );
639 } elseif ( $cond === '>' ) {
640 $min = min( $observed_value );
641 $m = $min > $hide_opt;
642 } elseif ( $cond === '<' ) {
643 $max = max( $observed_value );
644 $m = $max < $hide_opt;
645 } elseif ( $cond === 'LIKE' || $cond === 'not LIKE' ) {
646 foreach ( $observed_value as $ob ) {
647 $m = strpos( $ob, $hide_opt );
648 if ( $m !== false ) {
649 $m = true;
650 break;
651 }
652 }
653
654 if ( $cond === 'not LIKE' ) {
655 $m = ( $m === false ) ? true : false;
656 }
657 } elseif ( $cond === '%LIKE' ) {
658 // ends with
659 foreach ( $observed_value as $ob ) {
660 if ( $hide_opt === substr( $ob, strlen( $ob ) - strlen( $hide_opt ) ) ) {
661 $m = true;
662 break;
663 }
664 }
665 } elseif ( $cond === 'LIKE%' ) {
666 // starts with
667 foreach ( $observed_value as $ob ) {
668 if ( $hide_opt === substr( $ob, 0, strlen( $hide_opt ) ) ) {
669 $m = true;
670 break;
671 }
672 }
673 }
674
675 return $m;
676 }
677
678 /**
679 * Replace a few basic shortcodes and field ids
680 *
681 * @since 2.0
682 * @return string
683 */
684 public static function basic_replace_shortcodes( $value, $form, $entry ) {
685 if ( strpos( $value, '[sitename]' ) !== false ) {
686 $new_value = wp_specialchars_decode( FrmAppHelper::site_name(), ENT_QUOTES );
687 $value = str_replace( '[sitename]', $new_value, $value );
688 }
689
690 $value = apply_filters( 'frm_content', $value, $form, $entry );
691 $value = do_shortcode( $value );
692
693 return $value;
694 }
695
696 public static function get_shortcodes( $content, $form_id ) {
697 if ( FrmAppHelper::pro_is_installed() ) {
698 return FrmProDisplaysHelper::get_shortcodes( $content, $form_id );
699 }
700
701 $fields = FrmField::getAll(
702 array(
703 'fi.form_id' => (int) $form_id,
704 'fi.type not' => FrmField::no_save_fields(),
705 )
706 );
707
708 $tagregexp = self::allowed_shortcodes( $fields );
709
710 preg_match_all( "/\[(if )?($tagregexp)\b(.*?)(?:(\/))?\](?:(.+?)\[\/\2\])?/s", $content, $matches, PREG_PATTERN_ORDER );
711
712 return $matches;
713 }
714
715 public static function allowed_shortcodes( $fields = array() ) {
716 $tagregexp = array(
717 'editlink',
718 'id',
719 'key',
720 'ip',
721 'siteurl',
722 'sitename',
723 'admin_email',
724 'post[-|_]id',
725 'created[-|_]at',
726 'updated[-|_]at',
727 'updated[-|_]by',
728 'parent[-|_]id',
729 );
730
731 foreach ( $fields as $field ) {
732 $tagregexp[] = $field->id;
733 $tagregexp[] = $field->field_key;
734 }
735
736 $tagregexp = implode( '|', $tagregexp );
737
738 return $tagregexp;
739 }
740
741 public static function replace_content_shortcodes( $content, $entry, $shortcodes ) {
742 foreach ( $shortcodes[0] as $short_key => $tag ) {
743 if ( empty( $tag ) ) {
744 continue;
745 }
746
747 $atts = FrmShortcodeHelper::get_shortcode_attribute_array( $shortcodes[3][ $short_key ] );
748 $tag = FrmShortcodeHelper::get_shortcode_tag( $shortcodes, $short_key );
749
750 $atts['entry'] = $entry;
751 $atts['tag'] = $tag;
752 $replace_with = self::get_value_for_shortcode( $atts );
753
754 if ( $replace_with !== null ) {
755 $replace_with = self::trigger_shortcode_atts( $replace_with, $atts );
756 self::sanitize_embedded_shortcodes( compact( 'entry' ), $replace_with );
757 $content = str_replace( $shortcodes[0][ $short_key ], $replace_with, $content );
758 }
759
760 unset( $atts, $replace_with );
761 }
762
763 return $content;
764 }
765
766 /**
767 * @param string $replace_with
768 * @param array $atts
769 * @return string
770 */
771 private static function trigger_shortcode_atts( $replace_with, $atts ) {
772 $supported_atts = array( 'remove_accents', 'sanitize', 'sanitize_url' );
773 $included_atts = array_intersect( $supported_atts, array_keys( $atts ) );
774 foreach ( $included_atts as $included_att ) {
775 if ( '0' === $atts[ $included_att ] ) {
776 // Skip any option that uses 0 so sanitize_url=0 does not encode.
777 continue;
778 }
779 $function = 'atts_' . $included_att;
780 $replace_with = self::$function( $replace_with, $atts );
781 }
782 return $replace_with;
783 }
784
785 /**
786 * Converts all accent characters to ASCII characters.
787 *
788 * @since 6.3.1
789 *
790 * @param string $replace_with The text to remove accents from.
791 *
792 * @return string
793 */
794 public static function atts_remove_accents( $replace_with ) {
795 return remove_accents( $replace_with );
796 }
797
798 /**
799 * @param string $replace_with
800 * @return string
801 */
802 private static function atts_sanitize( $replace_with ) {
803 return sanitize_title_with_dashes( $replace_with );
804 }
805
806 /**
807 * @param string $replace_with
808 * @return string
809 */
810 private static function atts_sanitize_url( $replace_with ) {
811 return urlencode( $replace_with );
812 }
813
814 /**
815 * Prevent shortcodes in fields from being processed
816 *
817 * @since 3.01.02
818 *
819 * @param array $atts - includes entry object
820 * @param string $value
821 */
822 public static function sanitize_embedded_shortcodes( $atts, &$value ) {
823 $atts['value'] = $value;
824 $should_sanitize = apply_filters( 'frm_sanitize_shortcodes', true, $atts );
825 if ( $should_sanitize ) {
826 $value = str_replace( '[', '&#91;', $value );
827 }
828 }
829
830 /**
831 * @since 3.0
832 *
833 * @param $atts
834 *
835 * @return string
836 */
837 private static function get_value_for_shortcode( $atts ) {
838 $clean_tag = str_replace( '-', '_', $atts['tag'] );
839
840 $shortcode_values = array(
841 'id' => $atts['entry']->id,
842 'key' => $atts['entry']->item_key,
843 'ip' => $atts['entry']->ip,
844 );
845
846 $dynamic_default = array( 'admin_email', 'siteurl', 'frmurl', 'sitename', 'get' );
847
848 if ( isset( $shortcode_values[ $atts['tag'] ] ) ) {
849 $replace_with = $shortcode_values[ $atts['tag'] ];
850 } elseif ( in_array( $atts['tag'], $dynamic_default ) ) {
851 $replace_with = self::dynamic_default_values( $atts['tag'], $atts );
852 } elseif ( $clean_tag == 'user_agent' ) {
853 $description = $atts['entry']->description;
854 $replace_with = FrmEntriesHelper::get_browser( $description['browser'] );
855 } elseif ( $clean_tag == 'created_at' || $clean_tag == 'updated_at' ) {
856 $atts['tag'] = $clean_tag;
857 $replace_with = self::get_entry_timestamp( $atts );
858 } elseif ( $clean_tag == 'created_by' || $clean_tag == 'updated_by' ) {
859 $replace_with = self::get_display_value( $atts['entry']->{$clean_tag}, (object) array( 'type' => 'user_id' ), $atts );
860 } else {
861 $replace_with = self::get_field_shortcode_value( $atts );
862 }
863
864 return $replace_with;
865 }
866
867 /**
868 * @since 3.0
869 *
870 * @param $atts
871 *
872 * @return string
873 */
874 private static function get_entry_timestamp( $atts ) {
875 if ( isset( $atts['format'] ) ) {
876 $time_format = ' ';
877 } else {
878 $atts['format'] = get_option( 'date_format' );
879 $time_format = '';
880 }
881
882 return FrmAppHelper::get_formatted_time( $atts['entry']->{$atts['tag']}, $atts['format'], $time_format );
883 }
884
885 /**
886 * @since 3.0
887 *
888 * @param $atts
889 *
890 * @return null|string
891 */
892 private static function get_field_shortcode_value( $atts ) {
893 $field = FrmField::getOne( $atts['tag'] );
894 if ( empty( $field ) ) {
895 return null;
896 }
897
898 if ( isset( $atts['show'] ) && $atts['show'] === 'field_label' ) {
899 $replace_with = $field->name;
900 } elseif ( isset( $atts['show'] ) && $atts['show'] === 'description' ) {
901 $replace_with = $field->description;
902 } else {
903 $replace_with = FrmEntryMeta::get_meta_value( $atts['entry'], $field->id );
904 $string_value = $replace_with;
905 if ( is_array( $replace_with ) ) {
906 $sep = isset( $atts['sep'] ) ? $atts['sep'] : ', ';
907 $string_value = implode( $sep, $replace_with );
908 }
909
910 if ( empty( $string_value ) && $string_value != '0' ) {
911 $replace_with = '';
912 } else {
913 $atts['entry_id'] = $atts['entry']->id;
914 $atts['entry_key'] = $atts['entry']->item_key;
915 $replace_with = self::get_display_value( $replace_with, $field, $atts );
916 }
917 }
918
919 return $replace_with;
920 }
921
922 /**
923 * Get the value to replace a few standard shortcodes
924 *
925 * @since 2.0
926 * @return string
927 */
928 public static function dynamic_default_values( $tag, $atts = array(), $return_array = false ) {
929 $new_value = '';
930 switch ( $tag ) {
931 case 'admin_email':
932 $new_value = get_option( 'admin_email' );
933 break;
934 case 'siteurl':
935 $new_value = FrmAppHelper::site_url();
936 break;
937 case 'frmurl':
938 $new_value = FrmAppHelper::plugin_url();
939 break;
940 case 'sitename':
941 $new_value = FrmAppHelper::site_name();
942 break;
943 case 'get':
944 $new_value = self::process_get_shortcode( $atts, $return_array );
945 }
946
947 return $new_value;
948 }
949
950 /**
951 * Process the [get] shortcode
952 *
953 * @since 2.0
954 * @return string|array
955 */
956 public static function process_get_shortcode( $atts, $return_array = false ) {
957 if ( ! isset( $atts['param'] ) ) {
958 return '';
959 }
960
961 if ( strpos( $atts['param'], '&#91;' ) ) {
962 $atts['param'] = str_replace( '&#91;', '[', $atts['param'] );
963 $atts['param'] = str_replace( '&#93;', ']', $atts['param'] );
964 }
965
966 $new_value = FrmAppHelper::get_param( $atts['param'], '', 'get', 'sanitize_text_field' );
967 $new_value = FrmAppHelper::get_query_var( $new_value, $atts['param'] );
968
969 if ( $new_value == '' ) {
970 if ( ! isset( $atts['prev_val'] ) ) {
971 $atts['prev_val'] = '';
972 }
973
974 $new_value = isset( $atts['default'] ) ? $atts['default'] : $atts['prev_val'];
975 }
976
977 if ( is_array( $new_value ) && ! $return_array ) {
978 $new_value = implode( ', ', $new_value );
979 }
980
981 return $new_value;
982 }
983
984 public static function get_display_value( $value, $field, $atts = array() ) {
985
986 $value = apply_filters( 'frm_get_' . $field->type . '_display_value', $value, $field, $atts );
987 $value = apply_filters( 'frm_get_display_value', $value, $field, $atts );
988
989 $value = self::get_unfiltered_display_value( compact( 'value', 'field', 'atts' ) );
990
991 return apply_filters( 'frm_display_value', $value, $field, $atts );
992 }
993
994 /**
995 * @param $atts array Includes value, field, and atts
996 */
997 public static function get_unfiltered_display_value( $atts ) {
998 $value = $atts['value'];
999 $field = $atts['field'];
1000 $atts = isset( $atts['atts'] ) ? $atts['atts'] : $atts;
1001
1002 if ( is_array( $field ) ) {
1003 $field = $field['id'];
1004 }
1005
1006 $field_obj = FrmFieldFactory::get_field_object( $field );
1007
1008 return $field_obj->get_display_value( $value, $atts );
1009 }
1010
1011 /**
1012 * Get a value from the user profile from the user ID
1013 *
1014 * @since 3.0
1015 */
1016 public static function get_user_display_name( $user_id, $user_info = 'display_name', $args = array() ) {
1017 $defaults = array(
1018 'blank' => false,
1019 'link' => false,
1020 'size' => 96,
1021 );
1022
1023 $args = wp_parse_args( $args, $defaults );
1024
1025 $user = get_userdata( $user_id );
1026 $info = '';
1027
1028 if ( $user ) {
1029 if ( $user_info == 'avatar' ) {
1030 $info = get_avatar( $user_id, $args['size'] );
1031 } elseif ( $user_info == 'author_link' ) {
1032 $info = get_author_posts_url( $user_id );
1033 } else {
1034 $info = isset( $user->$user_info ) ? $user->$user_info : '';
1035 }
1036
1037 if ( 'display_name' === $user_info && empty( $info ) && ! $args['blank'] ) {
1038 $info = $user->user_login;
1039 }
1040 }
1041
1042 if ( $args['link'] ) {
1043 $info = '<a href="' . esc_url( admin_url( 'user-edit.php?user_id=' . $user_id ) ) . '">' . $info . '</a>';
1044 }
1045
1046 return $info;
1047 }
1048
1049 public static function get_field_types( $type ) {
1050 $single_input = self::single_input_fields();
1051 $multiple_input = array( 'radio', 'checkbox', 'select', 'scale', 'star', 'lookup' );
1052
1053 $field_selection = FrmField::all_field_selection();
1054
1055 $field_types = array();
1056 if ( in_array( $type, $single_input ) ) {
1057 self::field_types_for_input( $single_input, $field_selection, $field_types );
1058 } elseif ( in_array( $type, $multiple_input ) ) {
1059 self::field_types_for_input( $multiple_input, $field_selection, $field_types );
1060 } elseif ( isset( $field_selection[ $type ] ) ) {
1061 $field_types[ $type ] = $field_selection[ $type ];
1062 }
1063
1064 $field_types = apply_filters( 'frm_switch_field_types', $field_types, compact( 'type', 'field_selection' ) );
1065
1066 return $field_types;
1067 }
1068
1069 /**
1070 * Get a list of all fields that use a single value input.
1071 *
1072 * @since 4.0
1073 */
1074 public static function single_input_fields() {
1075 $fields = array(
1076 'text',
1077 'textarea',
1078 'rte',
1079 'number',
1080 'email',
1081 'url',
1082 'date',
1083 'phone',
1084 'hidden',
1085 'time',
1086 'tag',
1087 'password',
1088 );
1089 return apply_filters( 'frm_single_input_fields', $fields );
1090 }
1091
1092 private static function field_types_for_input( $inputs, $fields, &$field_types ) {
1093 foreach ( $inputs as $input ) {
1094 $field_types[ $input ] = $fields[ $input ];
1095 unset( $input );
1096 }
1097 }
1098
1099 /**
1100 * Check if current field option is an "other" option
1101 *
1102 * @since 2.0.6
1103 *
1104 * @param string $opt_key
1105 *
1106 * @return boolean Returns true if current field option is an "Other" option
1107 */
1108 public static function is_other_opt( $opt_key ) {
1109 return $opt_key && strpos( $opt_key, 'other_' ) === 0;
1110 }
1111
1112 /**
1113 * Get value that belongs in "Other" text box
1114 *
1115 * @since 2.0.6
1116 *
1117 * @param array $args
1118 */
1119 public static function get_other_val( $args ) {
1120 $defaults = array(
1121 'opt_key' => 0,
1122 'field' => array(),
1123 'parent' => false,
1124 'pointer' => false,
1125 );
1126 $args = wp_parse_args( $args, $defaults );
1127
1128 $opt_key = $args['opt_key'];
1129 $field = $args['field'];
1130 $parent = $args['parent'];
1131 $pointer = $args['pointer'];
1132 $other_val = '';
1133
1134 // If option is an "other" option and there is a value set for this field,
1135 // check if the value belongs in the current "Other" option text field
1136 if ( ! self::is_other_opt( $opt_key ) || ! FrmField::is_option_true( $field, 'value' ) ) {
1137 return $other_val;
1138 }
1139
1140 // Check posted vals before checking saved values
1141 // For fields inside repeating sections - note, don't check if $pointer is true because it will often be zero
1142 if ( $parent && isset( $_POST['item_meta'][ $parent ][ $pointer ]['other'][ $field['id'] ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
1143 if ( FrmField::is_field_with_multiple_values( $field ) ) {
1144 // phpcs:ignore WordPress.Security.NonceVerification.Missing
1145 $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 ] ) ) : '';
1146 } else {
1147 $other_val = sanitize_text_field( wp_unslash( $_POST['item_meta'][ $parent ][ $pointer ]['other'][ $field['id'] ] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
1148 }
1149
1150 return $other_val;
1151
1152 } elseif ( isset( $field['id'] ) && isset( $_POST['item_meta']['other'][ $field['id'] ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
1153 // For normal fields
1154
1155 if ( FrmField::is_field_with_multiple_values( $field ) ) {
1156 // phpcs:ignore WordPress.Security.NonceVerification.Missing
1157 $other_val = isset( $_POST['item_meta']['other'][ $field['id'] ][ $opt_key ] ) ? sanitize_text_field( wp_unslash( $_POST['item_meta']['other'][ $field['id'] ][ $opt_key ] ) ) : '';
1158 } else {
1159 $other_val = sanitize_text_field( wp_unslash( $_POST['item_meta']['other'][ $field['id'] ] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
1160 }
1161
1162 return $other_val;
1163 }
1164
1165 // For checkboxes
1166 if ( $field['type'] === 'checkbox' && is_array( $field['value'] ) ) {
1167 // Check if there is an "other" val in saved value and make sure the
1168 // "other" val is not equal to the Other checkbox option
1169 if ( isset( $field['value'][ $opt_key ] ) && $field['options'][ $opt_key ] != $field['value'][ $opt_key ] ) {
1170 $other_val = $field['value'][ $opt_key ];
1171 }
1172 } else {
1173 /**
1174 * For radio buttons and dropdowns
1175 * Check if saved value equals any of the options. If not, set it as the other value.
1176 */
1177 foreach ( $field['options'] as $opt_key => $opt_val ) {
1178 $temp_val = is_array( $opt_val ) ? $opt_val['value'] : $opt_val;
1179 // Multi-select dropdowns - key is not preserved
1180 if ( is_array( $field['value'] ) ) {
1181 $o_key = array_search( $temp_val, $field['value'] );
1182 if ( isset( $field['value'][ $o_key ] ) ) {
1183 unset( $field['value'][ $o_key ], $o_key );
1184 }
1185 } elseif ( $temp_val == $field['value'] ) {
1186 // For radio and regular dropdowns
1187 return '';
1188 } else {
1189 $other_val = $field['value'];
1190 }
1191 unset( $opt_key, $opt_val, $temp_val );
1192 }
1193 // For multi-select dropdowns only
1194 if ( is_array( $field['value'] ) && ! empty( $field['value'] ) ) {
1195 $other_val = reset( $field['value'] );
1196 }
1197 }
1198
1199 return $other_val;
1200 }
1201
1202 /**
1203 * Check if there is a saved value for the "Other" text field. If so, set it as the $other_val.
1204 * Intended for front-end use
1205 *
1206 * @since 2.0.6
1207 *
1208 * @param array $args should include field, opt_key and field name
1209 * @param boolean $other_opt
1210 * @param string $checked
1211 *
1212 * @return array $other_args
1213 */
1214 public static function prepare_other_input( $args, &$other_opt, &$checked ) {
1215 $other_args = array(
1216 'name' => '',
1217 'value' => '',
1218 );
1219
1220 //Check if this is an "Other" option
1221 if ( ! self::is_other_opt( $args['opt_key'] ) ) {
1222 return $other_args;
1223 }
1224
1225 $other_opt = true;
1226
1227 self::set_other_name( $args, $other_args );
1228 self::set_other_value( $args, $other_args );
1229
1230 if ( '' !== $other_args['value'] ) {
1231 $checked = 'checked="checked" ';
1232 }
1233
1234 return $other_args;
1235 }
1236
1237 /**
1238 * @param array $args
1239 * @param array $other_args
1240 *
1241 * @since 2.0.6
1242 */
1243 private static function set_other_name( $args, &$other_args ) {
1244 //Set up name for other field
1245 $other_args['name'] = str_replace( '[]', '', $args['field_name'] );
1246 $other_args['name'] = preg_replace( '/\[' . $args['field']['id'] . '\]$/', '', $other_args['name'] );
1247 $other_args['name'] = $other_args['name'] . '[other][' . $args['field']['id'] . ']';
1248
1249 //Converts item_meta[field_id] => item_meta[other][field_id] and
1250 //item_meta[parent][0][field_id] => item_meta[parent][0][other][field_id]
1251 if ( FrmField::is_field_with_multiple_values( $args['field'] ) ) {
1252 $other_args['name'] .= '[' . $args['opt_key'] . ']';
1253 }
1254 }
1255
1256 /**
1257 * Find the parent and pointer, and get text for "other" text field
1258 *
1259 * @param array $args
1260 * @param array $other_args
1261 *
1262 * @since 2.0.6
1263 */
1264 private static function set_other_value( $args, &$other_args ) {
1265 $parent = '';
1266 $pointer = '';
1267
1268 // Check for parent ID and pointer
1269 $temp_array = explode( '[', $args['field_name'] );
1270
1271 // Count should only be greater than 3 if inside of a repeating section
1272 if ( count( $temp_array ) > 3 ) {
1273 $parent = str_replace( ']', '', $temp_array[1] );
1274 $pointer = str_replace( ']', '', $temp_array[2] );
1275 }
1276
1277 // Get text for "other" text field
1278 $other_args['value'] = self::get_other_val(
1279 array(
1280 'opt_key' => $args['opt_key'],
1281 'field' => $args['field'],
1282 'parent' => $parent,
1283 'pointer' => $pointer,
1284 )
1285 );
1286 }
1287
1288 /**
1289 * If this field includes an other option, show it
1290 *
1291 * @param $args array
1292 *
1293 * @since 2.0.6
1294 */
1295 public static function include_other_input( $args ) {
1296 if ( ! $args['other_opt'] ) {
1297 return;
1298 }
1299
1300 $classes = array( 'frm_other_input' );
1301 if ( ! $args['checked'] || trim( $args['checked'] ) == '' ) {
1302 // hide the field if the other option is not selected
1303 $classes[] = 'frm_pos_none';
1304 }
1305 if ( $args['field']['type'] == 'select' && $args['field']['multiple'] ) {
1306 $classes[] = 'frm_other_full';
1307 }
1308
1309 // Set up HTML ID for Other field
1310 $other_id = self::get_other_field_html_id( $args['field']['type'], $args['html_id'], $args['opt_key'] );
1311
1312 $label = isset( $args['opt_label'] ) ? $args['opt_label'] : $args['field']['name'];
1313
1314 echo '<label for="' . esc_attr( $other_id ) . '" class="frm_screen_reader frm_hidden">' .
1315 esc_html( $label ) .
1316 '</label>' .
1317 '<input type="text" id="' . esc_attr( $other_id ) . '" class="' . esc_attr( implode( ' ', $classes ) ) . '" ' .
1318 ( $args['read_only'] ? ' readonly="readonly" disabled="disabled"' : '' ) .
1319 ' name="' . esc_attr( $args['name'] ) . '" value="' . esc_attr( $args['value'] ) . '" />';
1320 }
1321
1322 /**
1323 * Get the HTML id for an "Other" text field
1324 * Note: This does not affect fields in repeating sections
1325 *
1326 * @since 2.0.08
1327 *
1328 * @param string $type - field type
1329 * @param string $html_id
1330 * @param string|boolean $opt_key
1331 *
1332 * @return string $other_id
1333 */
1334 public static function get_other_field_html_id( $type, $html_id, $opt_key = false ) {
1335 $other_id = $html_id;
1336
1337 // If hidden radio field, add an opt key of 0
1338 if ( $type == 'radio' && $opt_key === false ) {
1339 $opt_key = 0;
1340 }
1341
1342 if ( $opt_key !== false ) {
1343 $other_id .= '-' . $opt_key;
1344 }
1345
1346 $other_id .= '-otext';
1347
1348 return $other_id;
1349 }
1350
1351 public static function switch_field_ids( $val ) {
1352 global $frm_duplicate_ids;
1353 $replace = array();
1354 $replace_with = array();
1355 foreach ( (array) $frm_duplicate_ids as $old => $new ) {
1356 $replace[] = '[if ' . $old . ']';
1357 $replace_with[] = '[if ' . $new . ']';
1358 $replace[] = '[if ' . $old . ' ';
1359 $replace_with[] = '[if ' . $new . ' ';
1360 $replace[] = '[/if ' . $old . ']';
1361 $replace_with[] = '[/if ' . $new . ']';
1362 $replace[] = '[\/if ' . $old . ']';
1363 $replace_with[] = '[\/if ' . $new . ']';
1364 $replace[] = '[foreach ' . $old . ']';
1365 $replace_with[] = '[foreach ' . $new . ']';
1366 $replace[] = '[/foreach ' . $old . ']';
1367 $replace_with[] = '[/foreach ' . $new . ']';
1368 $replace[] = '[\/foreach ' . $old . ']';
1369 $replace_with[] = '[\/foreach ' . $new . ']';
1370 $replace[] = '[' . $old . ']';
1371 $replace_with[] = '[' . $new . ']';
1372 $replace[] = '[' . $old . ' ';
1373 $replace_with[] = '[' . $new . ' ';
1374 $replace[] = 'field_id="' . $old . '"';
1375 $replace_with[] = 'field_id="' . $new . '"';
1376 $replace[] = 'field_id=\"' . $old . '\"';
1377 $replace_with[] = 'field_id=\"' . $new . '\"';
1378 unset( $old, $new );
1379 }
1380 if ( is_array( $val ) ) {
1381 foreach ( $val as $k => $v ) {
1382 if ( is_string( $v ) ) {
1383 $val[ $k ] = str_replace( $replace, $replace_with, $v );
1384 unset( $k, $v );
1385 }
1386 }
1387 } else {
1388 $val = str_replace( $replace, $replace_with, $val );
1389 }
1390
1391 return $val;
1392 }
1393
1394 /**
1395 * @since 4.0
1396 */
1397 public static function bulk_options_overlay() {
1398 $prepop = array();
1399 self::get_bulk_prefilled_opts( $prepop, true );
1400
1401 include( FrmAppHelper::plugin_path() . '/classes/views/frm-fields/back-end/bulk-options-overlay.php' );
1402 }
1403
1404 public static function get_us_states() {
1405 $states = array(
1406 'AL' => 'Alabama',
1407 'AK' => 'Alaska',
1408 'AR' => 'Arkansas',
1409 'AZ' => 'Arizona',
1410 'CA' => 'California',
1411 'CO' => 'Colorado',
1412 'CT' => 'Connecticut',
1413 'DE' => 'Delaware',
1414 'DC' => 'District of Columbia',
1415 'FL' => 'Florida',
1416 'GA' => 'Georgia',
1417 'HI' => 'Hawaii',
1418 'ID' => 'Idaho',
1419 'IL' => 'Illinois',
1420 'IN' => 'Indiana',
1421 'IA' => 'Iowa',
1422 'KS' => 'Kansas',
1423 'KY' => 'Kentucky',
1424 'LA' => 'Louisiana',
1425 'ME' => 'Maine',
1426 'MD' => 'Maryland',
1427 'MA' => 'Massachusetts',
1428 'MI' => 'Michigan',
1429 'MN' => 'Minnesota',
1430 'MS' => 'Mississippi',
1431 'MO' => 'Missouri',
1432 'MT' => 'Montana',
1433 'NE' => 'Nebraska',
1434 'NV' => 'Nevada',
1435 'NH' => 'New Hampshire',
1436 'NJ' => 'New Jersey',
1437 'NM' => 'New Mexico',
1438 'NY' => 'New York',
1439 'NC' => 'North Carolina',
1440 'ND' => 'North Dakota',
1441 'OH' => 'Ohio',
1442 'OK' => 'Oklahoma',
1443 'OR' => 'Oregon',
1444 'PA' => 'Pennsylvania',
1445 'RI' => 'Rhode Island',
1446 'SC' => 'South Carolina',
1447 'SD' => 'South Dakota',
1448 'TN' => 'Tennessee',
1449 'TX' => 'Texas',
1450 'UT' => 'Utah',
1451 'VT' => 'Vermont',
1452 'VA' => 'Virginia',
1453 'WA' => 'Washington',
1454 'WV' => 'West Virginia',
1455 'WI' => 'Wisconsin',
1456 'WY' => 'Wyoming',
1457 );
1458
1459 return apply_filters( 'frm_us_states', $states );
1460 }
1461
1462 public static function get_countries() {
1463 $countries = array(
1464 __( 'Afghanistan', 'formidable' ),
1465 __( 'Aland Islands', 'formidable' ),
1466 __( 'Albania', 'formidable' ),
1467 __( 'Algeria', 'formidable' ),
1468 __( 'American Samoa', 'formidable' ),
1469 __( 'Andorra', 'formidable' ),
1470 __( 'Angola', 'formidable' ),
1471 __( 'Anguilla', 'formidable' ),
1472 __( 'Antarctica', 'formidable' ),
1473 __( 'Antigua and Barbuda', 'formidable' ),
1474 __( 'Argentina', 'formidable' ),
1475 __( 'Armenia', 'formidable' ),
1476 __( 'Aruba', 'formidable' ),
1477 __( 'Australia', 'formidable' ),
1478 __( 'Austria', 'formidable' ),
1479 __( 'Azerbaijan', 'formidable' ),
1480 __( 'Bahamas', 'formidable' ),
1481 __( 'Bahrain', 'formidable' ),
1482 __( 'Bangladesh', 'formidable' ),
1483 __( 'Barbados', 'formidable' ),
1484 __( 'Belarus', 'formidable' ),
1485 __( 'Belgium', 'formidable' ),
1486 __( 'Belize', 'formidable' ),
1487 __( 'Benin', 'formidable' ),
1488 __( 'Bermuda', 'formidable' ),
1489 __( 'Bhutan', 'formidable' ),
1490 __( 'Bolivia', 'formidable' ),
1491 __( 'Bonaire, Sint Eustatius and Saba', 'formidable' ),
1492 __( 'Bosnia and Herzegovina', 'formidable' ),
1493 __( 'Botswana', 'formidable' ),
1494 __( 'Bouvet Island', 'formidable' ),
1495 __( 'Brazil', 'formidable' ),
1496 __( 'British Indian Ocean Territory', 'formidable' ),
1497 __( 'Brunei', 'formidable' ),
1498 __( 'Bulgaria', 'formidable' ),
1499 __( 'Burkina Faso', 'formidable' ),
1500 __( 'Burundi', 'formidable' ),
1501 __( 'Cambodia', 'formidable' ),
1502 __( 'Cameroon', 'formidable' ),
1503 __( 'Canada', 'formidable' ),
1504 __( 'Cape Verde', 'formidable' ),
1505 __( 'Cayman Islands', 'formidable' ),
1506 __( 'Central African Republic', 'formidable' ),
1507 __( 'Chad', 'formidable' ),
1508 __( 'Chile', 'formidable' ),
1509 __( 'China', 'formidable' ),
1510 __( 'Christmas Island', 'formidable' ),
1511 __( 'Cocos (Keeling) Islands', 'formidable' ),
1512 __( 'Colombia', 'formidable' ),
1513 __( 'Comoros', 'formidable' ),
1514 __( 'Congo', 'formidable' ),
1515 __( 'Cook Islands', 'formidable' ),
1516 __( 'Costa Rica', 'formidable' ),
1517 __( 'C&ocirc;te d\'Ivoire', 'formidable' ),
1518 __( 'Croatia', 'formidable' ),
1519 __( 'Cuba', 'formidable' ),
1520 __( 'Curacao', 'formidable' ),
1521 __( 'Cyprus', 'formidable' ),
1522 __( 'Czech Republic', 'formidable' ),
1523 __( 'Denmark', 'formidable' ),
1524 __( 'Djibouti', 'formidable' ),
1525 __( 'Dominica', 'formidable' ),
1526 __( 'Dominican Republic', 'formidable' ),
1527 __( 'East Timor', 'formidable' ),
1528 __( 'Ecuador', 'formidable' ),
1529 __( 'Egypt', 'formidable' ),
1530 __( 'El Salvador', 'formidable' ),
1531 __( 'Equatorial Guinea', 'formidable' ),
1532 __( 'Eritrea', 'formidable' ),
1533 __( 'Estonia', 'formidable' ),
1534 __( 'Ethiopia', 'formidable' ),
1535 __( 'Falkland Islands (Malvinas)', 'formidable' ),
1536 __( 'Faroe Islands', 'formidable' ),
1537 __( 'Fiji', 'formidable' ),
1538 __( 'Finland', 'formidable' ),
1539 __( 'France', 'formidable' ),
1540 __( 'French Guiana', 'formidable' ),
1541 __( 'French Polynesia', 'formidable' ),
1542 __( 'French Southern Territories', 'formidable' ),
1543 __( 'Gabon', 'formidable' ),
1544 __( 'Gambia', 'formidable' ),
1545 __( 'Georgia', 'formidable' ),
1546 __( 'Germany', 'formidable' ),
1547 __( 'Ghana', 'formidable' ),
1548 __( 'Gibraltar', 'formidable' ),
1549 __( 'Greece', 'formidable' ),
1550 __( 'Greenland', 'formidable' ),
1551 __( 'Grenada', 'formidable' ),
1552 __( 'Guadeloupe', 'formidable' ),
1553 __( 'Guam', 'formidable' ),
1554 __( 'Guatemala', 'formidable' ),
1555 __( 'Guernsey', 'formidable' ),
1556 __( 'Guinea', 'formidable' ),
1557 __( 'Guinea-Bissau', 'formidable' ),
1558 __( 'Guyana', 'formidable' ),
1559 __( 'Haiti', 'formidable' ),
1560 __( 'Heard Island and McDonald Islands', 'formidable' ),
1561 __( 'Holy See', 'formidable' ),
1562 __( 'Honduras', 'formidable' ),
1563 __( 'Hong Kong', 'formidable' ),
1564 __( 'Hungary', 'formidable' ),
1565 __( 'Iceland', 'formidable' ),
1566 __( 'India', 'formidable' ),
1567 __( 'Indonesia', 'formidable' ),
1568 __( 'Iran', 'formidable' ),
1569 __( 'Iraq', 'formidable' ),
1570 __( 'Ireland', 'formidable' ),
1571 __( 'Israel', 'formidable' ),
1572 __( 'Isle of Man', 'formidable' ),
1573 __( 'Italy', 'formidable' ),
1574 __( 'Jamaica', 'formidable' ),
1575 __( 'Japan', 'formidable' ),
1576 __( 'Jersey', 'formidable' ),
1577 __( 'Jordan', 'formidable' ),
1578 __( 'Kazakhstan', 'formidable' ),
1579 __( 'Kenya', 'formidable' ),
1580 __( 'Kiribati', 'formidable' ),
1581 __( 'North Korea', 'formidable' ),
1582 __( 'South Korea', 'formidable' ),
1583 __( 'Kosovo', 'formidable' ),
1584 __( 'Kuwait', 'formidable' ),
1585 __( 'Kyrgyzstan', 'formidable' ),
1586 __( 'Laos', 'formidable' ),
1587 __( 'Latvia', 'formidable' ),
1588 __( 'Lebanon', 'formidable' ),
1589 __( 'Lesotho', 'formidable' ),
1590 __( 'Liberia', 'formidable' ),
1591 __( 'Libya', 'formidable' ),
1592 __( 'Liechtenstein', 'formidable' ),
1593 __( 'Lithuania', 'formidable' ),
1594 __( 'Luxembourg', 'formidable' ),
1595 __( 'Macao', 'formidable' ),
1596 __( 'Macedonia', 'formidable' ),
1597 __( 'Madagascar', 'formidable' ),
1598 __( 'Malawi', 'formidable' ),
1599 __( 'Malaysia', 'formidable' ),
1600 __( 'Maldives', 'formidable' ),
1601 __( 'Mali', 'formidable' ),
1602 __( 'Malta', 'formidable' ),
1603 __( 'Marshall Islands', 'formidable' ),
1604 __( 'Martinique', 'formidable' ),
1605 __( 'Mauritania', 'formidable' ),
1606 __( 'Mauritius', 'formidable' ),
1607 __( 'Mayotte', 'formidable' ),
1608 __( 'Mexico', 'formidable' ),
1609 __( 'Micronesia', 'formidable' ),
1610 __( 'Moldova', 'formidable' ),
1611 __( 'Monaco', 'formidable' ),
1612 __( 'Mongolia', 'formidable' ),
1613 __( 'Montenegro', 'formidable' ),
1614 __( 'Montserrat', 'formidable' ),
1615 __( 'Morocco', 'formidable' ),
1616 __( 'Mozambique', 'formidable' ),
1617 __( 'Myanmar', 'formidable' ),
1618 __( 'Namibia', 'formidable' ),
1619 __( 'Nauru', 'formidable' ),
1620 __( 'Nepal', 'formidable' ),
1621 __( 'Netherlands', 'formidable' ),
1622 __( 'New Caledonia', 'formidable' ),
1623 __( 'New Zealand', 'formidable' ),
1624 __( 'Nicaragua', 'formidable' ),
1625 __( 'Niger', 'formidable' ),
1626 __( 'Nigeria', 'formidable' ),
1627 __( 'Niue', 'formidable' ),
1628 __( 'Norfolk Island', 'formidable' ),
1629 __( 'Northern Mariana Islands', 'formidable' ),
1630 __( 'Norway', 'formidable' ),
1631 __( 'Oman', 'formidable' ),
1632 __( 'Pakistan', 'formidable' ),
1633 __( 'Palau', 'formidable' ),
1634 __( 'Palestine', 'formidable' ),
1635 __( 'Panama', 'formidable' ),
1636 __( 'Papua New Guinea', 'formidable' ),
1637 __( 'Paraguay', 'formidable' ),
1638 __( 'Peru', 'formidable' ),
1639 __( 'Philippines', 'formidable' ),
1640 __( 'Pitcairn', 'formidable' ),
1641 __( 'Poland', 'formidable' ),
1642 __( 'Portugal', 'formidable' ),
1643 __( 'Puerto Rico', 'formidable' ),
1644 __( 'Qatar', 'formidable' ),
1645 __( 'Reunion', 'formidable' ),
1646 __( 'Romania', 'formidable' ),
1647 __( 'Russia', 'formidable' ),
1648 __( 'Rwanda', 'formidable' ),
1649 __( 'Saint Barthelemy', 'formidable' ),
1650 __( 'Saint Helena, Ascension and Tristan da Cunha', 'formidable' ),
1651 __( 'Saint Kitts and Nevis', 'formidable' ),
1652 __( 'Saint Lucia', 'formidable' ),
1653 __( 'Saint Martin (French part)', 'formidable' ),
1654 __( 'Saint Pierre and Miquelon', 'formidable' ),
1655 __( 'Saint Vincent and the Grenadines', 'formidable' ),
1656 __( 'Samoa', 'formidable' ),
1657 __( 'San Marino', 'formidable' ),
1658 __( 'Sao Tome and Principe', 'formidable' ),
1659 __( 'Saudi Arabia', 'formidable' ),
1660 __( 'Senegal', 'formidable' ),
1661 __( 'Serbia', 'formidable' ),
1662 __( 'Seychelles', 'formidable' ),
1663 __( 'Sierra Leone', 'formidable' ),
1664 __( 'Singapore', 'formidable' ),
1665 __( 'Sint Maarten (Dutch part)', 'formidable' ),
1666 __( 'Slovakia', 'formidable' ),
1667 __( 'Slovenia', 'formidable' ),
1668 __( 'Solomon Islands', 'formidable' ),
1669 __( 'Somalia', 'formidable' ),
1670 __( 'South Africa', 'formidable' ),
1671 __( 'South Georgia and the South Sandwich Islands', 'formidable' ),
1672 __( 'South Sudan', 'formidable' ),
1673 __( 'Spain', 'formidable' ),
1674 __( 'Sri Lanka', 'formidable' ),
1675 __( 'Sudan', 'formidable' ),
1676 __( 'Suriname', 'formidable' ),
1677 __( 'Svalbard and Jan Mayen', 'formidable' ),
1678 __( 'Swaziland', 'formidable' ),
1679 __( 'Sweden', 'formidable' ),
1680 __( 'Switzerland', 'formidable' ),
1681 __( 'Syria', 'formidable' ),
1682 __( 'Taiwan', 'formidable' ),
1683 __( 'Tajikistan', 'formidable' ),
1684 __( 'Tanzania', 'formidable' ),
1685 __( 'Thailand', 'formidable' ),
1686 __( 'Timor-Leste', 'formidable' ),
1687 __( 'Togo', 'formidable' ),
1688 __( 'Tokelau', 'formidable' ),
1689 __( 'Tonga', 'formidable' ),
1690 __( 'Trinidad and Tobago', 'formidable' ),
1691 __( 'Tunisia', 'formidable' ),
1692 __( 'Turkey', 'formidable' ),
1693 __( 'Turkmenistan', 'formidable' ),
1694 __( 'Turks and Caicos Islands', 'formidable' ),
1695 __( 'Tuvalu', 'formidable' ),
1696 __( 'Uganda', 'formidable' ),
1697 __( 'Ukraine', 'formidable' ),
1698 __( 'United Arab Emirates', 'formidable' ),
1699 __( 'United Kingdom', 'formidable' ),
1700 __( 'United States', 'formidable' ),
1701 __( 'United States Minor Outlying Islands', 'formidable' ),
1702 __( 'Uruguay', 'formidable' ),
1703 __( 'Uzbekistan', 'formidable' ),
1704 __( 'Vanuatu', 'formidable' ),
1705 __( 'Vatican City', 'formidable' ),
1706 __( 'Venezuela', 'formidable' ),
1707 __( 'Vietnam', 'formidable' ),
1708 __( 'Virgin Islands, British', 'formidable' ),
1709 __( 'Virgin Islands, U.S.', 'formidable' ),
1710 __( 'Wallis and Futuna', 'formidable' ),
1711 __( 'Western Sahara', 'formidable' ),
1712 __( 'Yemen', 'formidable' ),
1713 __( 'Zambia', 'formidable' ),
1714 __( 'Zimbabwe', 'formidable' ),
1715 );
1716
1717 sort( $countries, SORT_LOCALE_STRING );
1718 return apply_filters( 'frm_countries', $countries );
1719 }
1720
1721 /**
1722 * Gets bulk prefilled options.
1723 *
1724 * @since 5.0.04 Add `$include_class` param.
1725 *
1726 * @param array $prepop Bulk options.
1727 * @param array|false $include_class Include the class in the bulk options.
1728 */
1729 public static function get_bulk_prefilled_opts( array &$prepop, $include_class = false ) {
1730 // Countries.
1731 $countries = self::get_countries();
1732 if ( $include_class ) {
1733 $countries['class'] = 'frm-countries-opts';
1734 }
1735
1736 $prepop[ __( 'Countries', 'formidable' ) ] = $countries;
1737
1738 // State abv.
1739 $states = self::get_us_states();
1740 $state_abv = array_keys( $states );
1741 sort( $state_abv );
1742 if ( $include_class ) {
1743 $state_abv['class'] = 'frm-state-abv-opts';
1744 }
1745
1746 $prepop[ __( 'U.S. State Abbreviations', 'formidable' ) ] = $state_abv;
1747
1748 // States.
1749 $states = array_values( $states );
1750 sort( $states );
1751 if ( $include_class ) {
1752 $states['class'] = 'frm-states-opts';
1753 }
1754
1755 $prepop[ __( 'U.S. States', 'formidable' ) ] = $states;
1756 unset( $state_abv, $states );
1757
1758 // Age.
1759 $ages = array(
1760 __( 'Under 18', 'formidable' ),
1761 __( '18-24', 'formidable' ),
1762 __( '25-34', 'formidable' ),
1763 __( '35-44', 'formidable' ),
1764 __( '45-54', 'formidable' ),
1765 __( '55-64', 'formidable' ),
1766 __( '65 or Above', 'formidable' ),
1767 __( 'Prefer Not to Answer', 'formidable' ),
1768 );
1769 if ( $include_class ) {
1770 $ages['class'] = 'frm-age-opts';
1771 }
1772
1773 $prepop[ __( 'Age', 'formidable' ) ] = $ages;
1774
1775 // Satisfaction.
1776 $satisfaction = array(
1777 __( 'Very Unsatisfied', 'formidable' ),
1778 __( 'Unsatisfied', 'formidable' ),
1779 __( 'Neutral', 'formidable' ),
1780 __( 'Satisfied', 'formidable' ),
1781 __( 'Very Satisfied', 'formidable' ),
1782 __( 'N/A', 'formidable' ),
1783 );
1784 if ( $include_class ) {
1785 $satisfaction['class'] = 'frm-satisfaction-opts';
1786 }
1787
1788 $prepop[ __( 'Satisfaction', 'formidable' ) ] = $satisfaction;
1789
1790 // Importance.
1791 $importance = array(
1792 __( 'Not at all Important', 'formidable' ),
1793 __( 'Somewhat Important', 'formidable' ),
1794 __( 'Neutral', 'formidable' ),
1795 __( 'Important', 'formidable' ),
1796 __( 'Very Important', 'formidable' ),
1797 __( 'N/A', 'formidable' ),
1798 );
1799 if ( $include_class ) {
1800 $importance['class'] = 'frm-importance-opts';
1801 }
1802
1803 $prepop[ __( 'Importance', 'formidable' ) ] = $importance;
1804
1805 // Agreement.
1806 $agreement = array(
1807 __( 'Strongly Disagree', 'formidable' ),
1808 __( 'Disagree', 'formidable' ),
1809 __( 'Neutral', 'formidable' ),
1810 __( 'Agree', 'formidable' ),
1811 __( 'Strongly Agree', 'formidable' ),
1812 __( 'N/A', 'formidable' ),
1813 );
1814 if ( $include_class ) {
1815 $agreement['class'] = 'frm-agreement-opts';
1816 }
1817
1818 $prepop[ __( 'Agreement', 'formidable' ) ] = $agreement;
1819
1820 // Likely.
1821 $likely = array(
1822 __( 'Extremely Unlikely', 'formidable' ),
1823 __( 'Unlikely', 'formidable' ),
1824 __( 'Neutral', 'formidable' ),
1825 __( 'Likely', 'formidable' ),
1826 __( 'Extremely Likely', 'formidable' ),
1827 __( 'N/A', 'formidable' ),
1828 );
1829 if ( $include_class ) {
1830 $likely['class'] = 'frm-likely-opts';
1831 }
1832
1833 $prepop[ __( 'Likely', 'formidable' ) ] = $likely;
1834
1835 $prepop = apply_filters( 'frm_bulk_field_choices', $prepop );
1836 }
1837
1838 /**
1839 * Display a field value selector
1840 *
1841 * @since 2.03.05
1842 *
1843 * @param int $selector_field_id
1844 * @param array $selector_args
1845 */
1846 public static function display_field_value_selector( $selector_field_id, $selector_args ) {
1847 $field_value_selector = FrmFieldFactory::create_field_value_selector( $selector_field_id, $selector_args );
1848 $field_value_selector->display();
1849 }
1850
1851 /**
1852 * Convert a field object to a flat array
1853 *
1854 * @since 2.03.05
1855 *
1856 * @param object $field
1857 *
1858 * @return array
1859 */
1860 public static function convert_field_object_to_flat_array( $field ) {
1861 $field_options = $field->field_options;
1862 $field_array = get_object_vars( $field );
1863 unset( $field_array['field_options'] );
1864
1865 return $field_array + $field_options;
1866 }
1867
1868 /**
1869 * @since 4.04
1870 *
1871 * @param array $args
1872 * @return void
1873 */
1874 public static function show_add_field_buttons( $args ) {
1875 $field_key = $args['field_key'];
1876 $field_type = $args['field_type'];
1877 $field_label = FrmAppHelper::icon_by_class( FrmFormsHelper::get_field_link_icon( $field_type ), array( 'echo' => false ) );
1878 $field_name = FrmFormsHelper::get_field_link_name( $field_type );
1879 $field_label .= ' <span>' . $field_name . '</span>';
1880
1881 // If the individual field isn't allowed, disable it.
1882 $run_filter = true;
1883 $single_no_allow = ' ';
1884 $install_data = '';
1885 $requires = '';
1886 $link = isset( $field_type['link'] ) ? esc_url_raw( $field_type['link'] ) : '';
1887 $has_show_upgrade_class = strpos( $field_type['icon'], ' frm_show_upgrade' );
1888 $show_upgrade = $has_show_upgrade_class || false !== strpos( $args['no_allow_class'], 'frm_show_upgrade' );
1889
1890 if ( $has_show_upgrade_class ) {
1891 $single_no_allow .= 'frm_show_upgrade';
1892 $field_type['icon'] = str_replace( ' frm_show_upgrade', '', $field_type['icon'] );
1893 $run_filter = false;
1894 if ( isset( $field_type['addon'] ) ) {
1895 $upgrading = FrmAddonsController::install_link( $field_type['addon'] );
1896 if ( isset( $upgrading['url'] ) ) {
1897 $install_data = json_encode( $upgrading );
1898 }
1899 $requires = FrmFormsHelper::get_plan_required( $upgrading );
1900 } elseif ( isset( $field_type['require'] ) ) {
1901 $requires = $field_type['require'];
1902 }
1903 }
1904
1905 $upgrade_label = '';
1906 $upgrade_message = '';
1907 if ( $show_upgrade ) {
1908 /* translators: %s: Field name */
1909 $upgrade_label = sprintf( esc_html__( '%s fields', 'formidable' ), $field_name );
1910
1911 if ( isset( $field_type['message'] ) ) {
1912 $upgrade_message = FrmAppHelper::kses( $field_type['message'], array( 'a', 'img' ) );
1913 }
1914 }
1915
1916 $li_params = array(
1917 'class' => 'frmbutton frm6 ' . $args['no_allow_class'] . $single_no_allow . ' frm_t' . str_replace( '|', '-', $field_key ),
1918 'id' => $field_key,
1919 'data-upgrade' => $upgrade_label,
1920 'data-link' => $link,
1921 'data-medium' => 'builder',
1922 'data-oneclick' => $install_data,
1923 'data-content' => $field_key,
1924 'data-requires' => $requires,
1925 );
1926
1927 if ( $upgrade_message ) {
1928 $li_params['data-message'] = $upgrade_message;
1929 }
1930 ?>
1931 <li <?php FrmAppHelper::array_to_html_params( $li_params, true ); ?>>
1932 <?php
1933 if ( $run_filter ) {
1934 $field_label = apply_filters( 'frmpro_field_links', $field_label, $args['id'], $field_key );
1935 }
1936 echo FrmAppHelper::kses( $field_label, array( 'a', 'i', 'span', 'use', 'svg' ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1937 ?>
1938 </li>
1939 <?php
1940 }
1941
1942 /**
1943 * Shows Display format option.
1944 *
1945 * @since 5.0.04
1946 *
1947 * @param array $field Field data.
1948 */
1949 public static function show_radio_display_format( $field ) {
1950 $options = self::get_display_format_options( $field );
1951
1952 $args = self::get_display_format_args( $field, $options );
1953
1954 include FrmAppHelper::plugin_path() . '/classes/views/frm-fields/back-end/radio-display-format.php';
1955 }
1956
1957 /**
1958 * Creates an array that contains variables used for display format options setting.
1959 *
1960 * @since 6.3.2
1961 *
1962 * @param array $field The field.
1963 *
1964 * @return array
1965 */
1966 public static function get_display_format_options( $field ) {
1967 $options = array(
1968 '0' => array(
1969 'text' => __( 'Simple', 'formidable' ),
1970 'svg' => 'frm_simple_radio',
1971 ),
1972 '1' => array(
1973 'text' => __( 'Images', 'formidable' ),
1974 'svg' => 'frm_image_as_option',
1975 'addon' => 'pro',
1976 'upgrade' => __( 'Image Options', 'formidable' ),
1977 '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" />',
1978 'content' => 'image-options',
1979 ),
1980 'buttons' => array(
1981 'text' => __( 'Buttons', 'formidable' ),
1982 'svg' => 'frm_button_as_option',
1983 'addon' => 'surveys',
1984 'upgrade' => __( 'Button Options', 'formidable' ),
1985 'message' => __( 'Show buttons for radio buttons or check boxes. This is ideal for polls, surveys, segmenting questionnaires and more.', 'formidable' ),
1986 'content' => 'button-options',
1987 ),
1988 );
1989
1990 /**
1991 * Allows modifying the options of Display format setting of Radio field.
1992 *
1993 * @since 5.0.04
1994 *
1995 * @param array $options Options.
1996 * @param array $field
1997 */
1998 $options = apply_filters( 'frm_' . $field['type'] . '_display_format_options', $options, $field );
1999
2000 return $options;
2001 }
2002
2003 /**
2004 * Gets display format arguments to pass to the images_dropdown() method.
2005 *
2006 * @since 5.0.04
2007 *
2008 * @param array $field Field data.
2009 * @param array $options Options array.
2010 * @return array
2011 */
2012 public static function get_display_format_args( $field, $options ) {
2013 $args = array(
2014 'selected' => '0',
2015 'options' => array(),
2016 'name' => 'field_options[image_options_' . $field['id'] . ']',
2017 'input_attrs' => array(
2018 'class' => 'frm_toggle_image_options',
2019 ),
2020 );
2021
2022 self::fill_image_setting_options( $options, $args );
2023
2024 /**
2025 * Allows modifying the arguments of Display format setting of Radio field.
2026 *
2027 * @since 5.0.04
2028 *
2029 * @param array $args Arguments.
2030 * @param array $method_args The arguments from the method. Contains `field`, `options`.
2031 */
2032 return apply_filters( 'frm_' . $field['type'] . '_display_format_args', $args, compact( 'field', 'options' ) );
2033 }
2034
2035 /**
2036 * @since 5.0.04
2037 */
2038 private static function fill_image_setting_options( $options, &$args ) {
2039 foreach ( $options as $key => $option ) {
2040 $args['options'][ $key ] = $option;
2041
2042 if ( ! empty( $option['addon'] ) ) {
2043 $args['options'][ $key ]['custom_attrs'] = self::fill_image_setting_addon_link( $option );
2044 }
2045
2046 unset( $args['options'][ $key ]['addon'] );
2047 $fill = array( 'upgrade', 'message', 'content' );
2048 foreach ( $fill as $f ) {
2049 unset( $args['options'][ $key ][ $f ], $f );
2050 }
2051 }
2052 }
2053
2054 /**
2055 * @since 5.0.04
2056 *
2057 * @return array
2058 */
2059 private static function fill_image_setting_addon_link( $option ) {
2060 $custom_attrs = array(
2061 'class' => 'frm_noallow frm_show_upgrade',
2062 'data-medium' => 'builder',
2063 );
2064
2065 // translators: Add-on name.
2066 $custom_attrs['data-upgrade'] = sprintf( __( 'Formidable %s', 'formidable' ), ucwords( $option['addon'] ) );
2067
2068 $fill = array( 'upgrade', 'message', 'content' );
2069 foreach ( $fill as $f ) {
2070 if ( isset( $option[ $f ] ) ) {
2071 $custom_attrs[ 'data-' . $f ] = $option[ $f ];
2072 }
2073 }
2074
2075 if ( 'pro' === $option['addon'] ) {
2076 return $custom_attrs;
2077 }
2078
2079 $upgrading = FrmAddonsController::install_link( $option['addon'] );
2080 if ( isset( $upgrading['url'] ) ) {
2081 $install_data = wp_json_encode( $upgrading );
2082 } else {
2083 $install_data = '';
2084 }
2085
2086 $custom_attrs['data-oneclick'] = $install_data;
2087 $custom_attrs['data-requires'] = FrmFormsHelper::get_plan_required( $upgrading );
2088
2089 return $custom_attrs;
2090 }
2091
2092 /**
2093 * Maybe adjust a field value based on type.
2094 * Some types require unserializing an array (@see self::field_type_requires_unserialize).
2095 *
2096 * @since 6.2
2097 *
2098 * @param mixed $value
2099 * @param string $field_type
2100 * @return void
2101 */
2102 public static function prepare_field_value( &$value, $field_type ) {
2103 $field_object = FrmFieldFactory::get_field_type( $field_type );
2104 $value = $field_object->maybe_decode_value( $value );
2105 }
2106
2107 /**
2108 * @deprecated 4.0
2109 */
2110 public static function show_icon_link_js( $atts ) {
2111 _deprecated_function( __METHOD__, '4.0' );
2112 $atts['icon'] .= $atts['is_selected'] ? ' ' : ' frm_inactive_icon ';
2113 if ( isset( $atts['has_default'] ) && ! $atts['has_default'] ) {
2114 $atts['icon'] .= 'frm_hidden ';
2115 }
2116 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>';
2117 }
2118
2119 /**
2120 * @deprecated 4.0
2121 */
2122 public static function show_default_blank_js( $is_selected, $has_default_value = true ) {
2123 _deprecated_function( __METHOD__, '4.0' );
2124 }
2125
2126 /**
2127 * @deprecated 4.0
2128 */
2129 public static function clear_on_focus_html( $field, $display, $id = '' ) {
2130 _deprecated_function( __METHOD__, '4.0' );
2131 }
2132
2133 /**
2134 * @deprecated 4.0
2135 */
2136 public static function show_onfocus_js( $is_selected, $has_default_value = true ) {
2137 _deprecated_function( __METHOD__, '4.0' );
2138 }
2139
2140 /**
2141 * @deprecated 3.0
2142 * @codeCoverageIgnore
2143 */
2144 public static function display_recaptcha() {
2145 _deprecated_function( __FUNCTION__, '3.0', 'FrmFieldCaptcha::field_input' );
2146 }
2147
2148 /**
2149 * @deprecated 3.0
2150 * @codeCoverageIgnore
2151 */
2152 public static function remove_inline_conditions( $no_vars, $code, $replace_with, &$html ) {
2153 FrmDeprecated::remove_inline_conditions( $no_vars, $code, $replace_with, $html );
2154 }
2155
2156 /**
2157 * @deprecated 3.0
2158 * @codeCoverageIgnore
2159 */
2160 public static function get_shortcode_tag( $shortcodes, $short_key, $args ) {
2161 return FrmDeprecated::get_shortcode_tag( $shortcodes, $short_key, $args );
2162 }
2163
2164 /**
2165 * @deprecated 3.0
2166 * @codeCoverageIgnore
2167 *
2168 * @param string $html
2169 * @param array $field
2170 * @param array $errors
2171 * @param object|false $form
2172 * @param array $args
2173 *
2174 * @return string
2175 */
2176 public static function replace_shortcodes( $html, $field, $errors = array(), $form = false, $args = array() ) {
2177 return FrmDeprecated::replace_shortcodes( $html, $field, $errors, $form, $args );
2178 }
2179
2180 /**
2181 * @deprecated 3.0
2182 * @codeCoverageIgnore
2183 */
2184 public static function get_default_field_opts( $type, $field = null, $limit = false ) {
2185 return FrmDeprecated::get_default_field_opts( $type, $field, $limit );
2186 }
2187
2188 /**
2189 * @deprecated 2.02.07 This is still referenced in the Highrise add on as of v1.06.
2190 * @codeCoverageIgnore
2191 *
2192 * @param array $args
2193 * @return string
2194 */
2195 public static function dropdown_categories( $args ) {
2196 return FrmDeprecated::dropdown_categories( $args );
2197 }
2198 }
2199