PluginProbe ʕ •ᴥ•ʔ
Everest Forms – Contact Form, Payment Form, Quiz, Survey & Custom Form Builder with AI / 1.6.3
Everest Forms – Contact Form, Payment Form, Quiz, Survey & Custom Form Builder with AI v1.6.3
3.5.2 3.5.1 3.5.0 3.4.8 3.4.7 3.4.6 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.5.1 1.1.6 1.1.7 1.1.8 1.1.9 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.5.0 1.5.1 1.5.10 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.6.1 1.6.7 1.7.0 1.7.0.1 1.7.0.2 1.7.0.3 1.7.1 1.7.2 1.7.2.1 1.7.2.2 1.7.3 1.7.4 1.7.5 1.7.5.1 1.7.5.2 1.7.6 1.7.7 1.7.7.1 1.7.7.2 1.7.8 1.7.9 1.8.0 1.8.0.1 1.8.1 1.8.2 1.8.2.1 1.8.2.2 1.8.2.3 1.8.3 1.8.4 1.8.5 1.8.6 1.8.7 1.8.8 1.8.9 1.9.0 1.9.0.1 1.9.1 1.9.2 1.9.3 1.9.4 1.9.4.1 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0.0 2.0.0.1 2.0.1 2.0.2 2.0.3 2.0.3.1 2.0.4 2.0.4.1 2.0.5 2.0.6 2.0.7 2.0.8 2.0.8.1 2.0.9 3.0.0 3.0.0.1 3.0.1 3.0.2 3.0.3 3.0.3.1 3.0.4 3.0.4.1 3.0.4.2 3.0.5 3.0.5.1 3.0.5.2 3.0.6 3.0.6.1 3.0.7.1 3.0.8 3.0.8.1 3.0.9 3.0.9.1 3.0.9.2 3.0.9.3 3.0.9.4 3.0.9.5 3.1.0 3.1.1 3.1.2 3.2.0 3.2.1 3.2.2 3.2.3 3.2.4 3.2.5 3.2.6 3.3.0 3.4.0 3.4.1 3.4.2 3.4.2.1 3.4.3 3.4.4 3.4.5 trunk 1.0 1.0.1 1.0.2 1.0.3
everest-forms / includes / abstracts / class-evf-form-fields.php
everest-forms / includes / abstracts Last commit date
legacy 6 years ago class-evf-background-process.php 7 years ago class-evf-deprecated-hooks.php 6 years ago class-evf-form-fields.php 6 years ago class-evf-integration.php 7 years ago class-evf-log-handler.php 6 years ago class-evf-session.php 8 years ago class-evf-settings-api.php 6 years ago
class-evf-form-fields.php
1464 lines
1 <?php
2 /**
3 * Abstract EVF_Form_Fields Class
4 *
5 * @version 1.0.0
6 * @package EverestFroms/Abstracts
7 */
8
9 defined( 'ABSPATH' ) || exit;
10
11 /**
12 * Form fields class.
13 */
14 abstract class EVF_Form_Fields {
15
16 /**
17 * Field name.
18 *
19 * @var string
20 */
21 public $name;
22
23 /**
24 * Field type.
25 *
26 * @var string
27 */
28 public $type;
29
30 /**
31 * Field icon.
32 *
33 * @var mixed
34 */
35 public $icon = '';
36
37 /**
38 * Field class.
39 *
40 * @var string
41 */
42 public $class = '';
43
44 /**
45 * Form ID.
46 *
47 * @var int|mixed
48 */
49 public $form_id;
50
51 /**
52 * Field group.
53 *
54 * @var string
55 */
56 public $group = 'general';
57
58 /**
59 * Is available in Pro?
60 *
61 * @var boolean
62 */
63 public $is_pro = false;
64
65 /**
66 * Placeholder to hold default value(s) for some field types.
67 *
68 * @var mixed
69 */
70 public $defaults;
71
72 /**
73 * Array of form data.
74 *
75 * @var array
76 */
77 public $form_data;
78
79 /**
80 * Array of field settings.
81 *
82 * @var array
83 */
84 protected $settings = array();
85
86 /**
87 * Constructor.
88 */
89 public function __construct() {
90 $this->class = $this->is_pro ? 'upgrade-modal' : '';
91 $this->form_id = isset( $_GET['form_id'] ) ? absint( $_GET['form_id'] ) : false; // phpcs:ignore WordPress.Security.NonceVerification
92
93 // Init hooks.
94 $this->init_hooks();
95
96 // Hooks.
97 add_action( 'everest_forms_builder_fields_options_' . $this->type, array( $this, 'field_options' ) );
98 add_action( 'everest_forms_builder_fields_preview_' . $this->type, array( $this, 'field_preview' ) );
99 add_action( 'wp_ajax_everest_forms_new_field_' . $this->type, array( $this, 'field_new' ) );
100 add_action( 'everest_forms_display_field_' . $this->type, array( $this, 'field_display' ), 10, 3 );
101 add_action( 'everest_forms_process_validate_' . $this->type, array( $this, 'validate' ), 10, 3 );
102 add_action( 'everest_forms_process_format_' . $this->type, array( $this, 'format' ), 10, 4 );
103 }
104
105 /**
106 * Hook in tabs.
107 */
108 public function init_hooks() {}
109
110 /**
111 * Get the form fields after they are initialized.
112 *
113 * @return array of options
114 */
115 public function get_field_settings() {
116 return apply_filters( 'everest_forms_get_field_settings_' . $this->type, $this->settings );
117 }
118
119 /**
120 * Output form fields options.
121 *
122 * Loops though the field options array and outputs each field.
123 *
124 * @param array $field Field data.
125 */
126 public function field_options( $field ) {
127 $settings = $this->get_field_settings();
128
129 foreach ( $settings as $option_key => $option ) {
130 $this->field_option(
131 $option_key,
132 $field,
133 array(
134 'markup' => 'open',
135 )
136 );
137
138 if ( ! empty( $option['field_options'] ) ) {
139 foreach ( $option['field_options'] as $option_name ) {
140 $this->field_option( $option_name, $field );
141 }
142 }
143
144 $this->field_option(
145 $option_key,
146 $field,
147 array(
148 'markup' => 'close',
149 )
150 );
151 }
152 }
153
154 /**
155 * Field preview inside the builder.
156 *
157 * @since 1.0.0
158 * @param array $field Field settings.
159 */
160 public function field_preview( $field ) {}
161
162 /**
163 * Helper function to create field option elements.
164 *
165 * Field option elements are pieces that help create a field option.
166 * They are used to quickly build field options.
167 *
168 * @since 1.0.0
169 *
170 * @param string $option Field option to render.
171 * @param array $field Field data and settings.
172 * @param array $args Field preview arguments.
173 * @param boolean $echo Print or return the value. Print by default.
174 *
175 * @return mixed echo or return string
176 */
177 public function field_element( $option, $field, $args = array(), $echo = true ) {
178 $id = (string) $field['id'];
179 $class = ! empty( $args['class'] ) && is_string( $args['class'] ) ? esc_attr( $args['class'] ) : '';
180 $slug = ! empty( $args['slug'] ) ? sanitize_title( $args['slug'] ) : '';
181 $data = '';
182 $output = '';
183
184 if ( ! empty( $args['data'] ) ) {
185 foreach ( $args['data'] as $key => $val ) {
186 if ( is_array( $val ) ) {
187 $val = wp_json_encode( $val );
188 }
189 $data .= ' data-' . $key . '=\'' . $val . '\'';
190 }
191 }
192
193 // BW compat for number attrs.
194 if ( ! empty( $args['min'] ) ) {
195 $args['attrs']['min'] = esc_attr( $args['min'] );
196 unset( $args['min'] );
197 }
198 if ( ! empty( $args['max'] ) ) {
199 $args['attrs']['max'] = esc_attr( $args['max'] );
200 unset( $args['min'] );
201 }
202 if ( ! empty( $args['required'] ) && $args['required'] ) {
203 $args['attrs']['required'] = 'required';
204 unset( $args['required'] );
205 }
206
207 if ( ! empty( $args['attrs'] ) ) {
208 foreach ( $args['attrs'] as $arg_key => $val ) {
209 if ( is_array( $val ) ) {
210 $val = wp_json_encode( $val );
211 }
212 $data .= $arg_key . '=\'' . $val . '\'';
213 }
214 }
215
216 switch ( $option ) {
217
218 // Row.
219 case 'row':
220 $output = sprintf( '<div class="everest-forms-field-option-row everest-forms-field-option-row-%s %s" id="everest-forms-field-option-row-%s-%s" data-field-id="%s">%s</div>', $slug, $class, $id, $slug, $id, $args['content'] );
221 break;
222
223 // Icon.
224 case 'icon':
225 $element_tooltip = isset( $args['tooltip'] ) ? $args['tooltip'] : 'Edit Label';
226 $icon = isset( $args['icon'] ) ? $args['icon'] : 'dashicons-edit';
227 $output .= sprintf( ' <i class="dashicons %s everest-forms-icon %s" title="%s" %s></i>', esc_attr( $icon ), $class, esc_attr( $element_tooltip ), $data );
228 break;
229
230 // Label.
231 case 'label':
232 $output = sprintf( '<label for="everest-forms-field-option-%s-%s" class="%s" %s>%s', $id, $slug, $class, $data, esc_html( $args['value'] ) );
233 if ( isset( $args['tooltip'] ) && ! empty( $args['tooltip'] ) ) {
234 $output .= ' ' . sprintf( '<i class="dashicons dashicons-editor-help everest-forms-help-tooltip" title="%s"></i>', esc_attr( $args['tooltip'] ) );
235 }
236 if ( isset( $args['after_tooltip'] ) && ! empty( $args['after_tooltip'] ) ) {
237 $output .= $args['after_tooltip'];
238 }
239 $output .= '</label>';
240 break;
241
242 // Text input.
243 case 'text':
244 $type = ! empty( $args['type'] ) ? esc_attr( $args['type'] ) : 'text';
245 $placeholder = ! empty( $args['placeholder'] ) ? esc_attr( $args['placeholder'] ) : '';
246 $before = ! empty( $args['before'] ) ? '<span class="before-input">' . esc_html( $args['before'] ) . '</span>' : '';
247 if ( ! empty( $before ) ) {
248 $class .= ' has-before';
249 }
250
251 $output = sprintf( '%s<input type="%s" class="widefat %s" id="everest-forms-field-option-%s-%s" name="form_fields[%s][%s]" value="%s" placeholder="%s" %s>', $before, $type, $class, $id, $slug, $id, $slug, esc_attr( $args['value'] ), $placeholder, $data );
252 break;
253
254 // Textarea.
255 case 'textarea':
256 $rows = ! empty( $args['rows'] ) ? (int) $args['rows'] : '3';
257 $output = sprintf( '<textarea class="widefat %s" id="everest-forms-field-option-%s-%s" name="form_fields[%s][%s]" rows="%s" %s>%s</textarea>', $class, $id, $slug, $id, $slug, $rows, $data, $args['value'] );
258 break;
259
260 // Checkbox.
261 case 'checkbox':
262 $checked = checked( '1', $args['value'], false );
263 $output = sprintf( '<input type="checkbox" class="widefat %s" id="everest-forms-field-option-%s-%s" name="form_fields[%s][%s]" value="1" %s %s>', $class, $id, $slug, $id, $slug, $checked, $data );
264 $output .= sprintf( '<label for="everest-forms-field-option-%s-%s" class="inline">%s', $id, $slug, $args['desc'] );
265 if ( isset( $args['tooltip'] ) && ! empty( $args['tooltip'] ) ) {
266 $output .= ' ' . sprintf( '<i class="dashicons dashicons-editor-help everest-forms-help-tooltip" title="%s"></i>', esc_attr( $args['tooltip'] ) );
267 }
268 $output .= '</label>';
269 break;
270
271 // Toggle.
272 case 'toggle':
273 $checked = checked( '1', $args['value'], false );
274 $icon = $args['value'] ? 'fa-toggle-on' : 'fa-toggle-off';
275 $cls = $args['value'] ? 'everest-forms-on' : 'everest-forms-off';
276 $status = $args['value'] ? __( 'On', 'everest-forms' ) : __( 'Off', 'everest-forms' );
277 $output = sprintf( '<span class="everest-forms-toggle-icon %s"><i class="fa %s" aria-hidden="true"></i> <span class="everest-forms-toggle-icon-label">%s</span>', $cls, $icon, $status );
278 $output .= sprintf( '<input type="checkbox" class="widefat %s" id="everest-forms-field-option-%s-%s" name="form_fields[%s][%s]" value="1" %s %s></span>', $class, $id, $slug, $id, $slug, $checked, $data );
279 break;
280
281 // Select.
282 case 'select':
283 $options = $args['options'];
284 $value = isset( $args['value'] ) ? $args['value'] : '';
285 $output = sprintf( '<select class="widefat %s" id="everest-forms-field-option-%s-%s" name="form_fields[%s][%s]" %s>', $class, $id, $slug, $id, $slug, $data );
286 foreach ( $options as $key => $option ) {
287 $output .= sprintf( '<option value="%s" %s>%s</option>', esc_attr( $key ), selected( $key, $value, false ), $option );
288 }
289 $output .= '</select>';
290 break;
291
292 // Radio.
293 case 'radio':
294 $options = $args['options'];
295 $default = isset( $args['default'] ) ? $args['default'] : '';
296 $output = '<label>' . $args['desc'];
297
298 if ( isset( $args['tooltip'] ) && ! empty( $args['tooltip'] ) ) {
299 $output .= ' ' . sprintf( '<i class="dashicons dashicons-editor-help everest-forms-help-tooltip" title="%s"></i></label>', esc_attr( $args['tooltip'] ) );
300 } else {
301 $output .= '</label>';
302 }
303 $output .= '<ul>';
304
305 foreach ( $options as $key => $option ) {
306 $output .= '<li>';
307 $output .= sprintf( '<label><input type="radio" class="widefat %s" id="everest-forms-field-option-%s-%s-%s" value="%s" name="form_fields[%s][%s]" %s %s>%s</label>', $class, $id, $slug, $key, $key, $id, $slug, $data, checked( $key, $default, false ), $option );
308 $output .= '</li>';
309 }
310 $output .= '</ul>';
311 break;
312 }
313
314 if ( $echo ) {
315 echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
316 } else {
317 return $output;
318 }
319 }
320
321 /**
322 * Helper function to create common field options that are used frequently.
323 *
324 * @since 1.0.0
325 *
326 * @param string $option Option.
327 * @param array $field Field data.
328 * @param array $args Arguments.
329 * @param boolean $echo True to echo.
330 *
331 * @return mixed echo or return string
332 */
333 public function field_option( $option, $field, $args = array(), $echo = true ) {
334 $output = '';
335
336 switch ( $option ) {
337 /**
338 * Basic Fields.
339 */
340
341 /*
342 * Basic Options markup.
343 */
344 case 'basic-options':
345 $markup = ! empty( $args['markup'] ) ? $args['markup'] : 'open';
346 $class = ! empty( $args['class'] ) ? esc_html( $args['class'] ) : '';
347 if ( 'open' === $markup ) {
348 $output = sprintf( '<div class="everest-forms-field-option-group everest-forms-field-option-group-basic open" id="everest-forms-field-option-basic-%s">', $field['id'] );
349 $output .= sprintf( '<a href="#" class="everest-forms-field-option-group-toggle">%s<span> (ID #%s)</span> <i class="handlediv"></i></a>', $this->name, $field['id'] );
350 $output .= sprintf( '<div class="everest-forms-field-option-group-inner %s">', $class );
351 } else {
352 $output = '</div></div>';
353 }
354 break;
355
356 /*
357 * Field Label.
358 */
359 case 'label':
360 $value = ! empty( $field['label'] ) ? esc_attr( $field['label'] ) : '';
361 $tooltip = esc_html__( 'Enter text for the form field label. This is recommended and can be hidden in the Advanced Settings.', 'everest-forms' );
362 $output = $this->field_element(
363 'label',
364 $field,
365 array(
366 'slug' => 'label',
367 'value' => esc_html__( 'Label', 'everest-forms' ),
368 'tooltip' => $tooltip,
369 ),
370 false
371 );
372 $output .= $this->field_element(
373 'text',
374 $field,
375 array(
376 'slug' => 'label',
377 'value' => $value,
378 ),
379 false
380 );
381 $output = $this->field_element(
382 'row',
383 $field,
384 array(
385 'slug' => 'label',
386 'content' => $output,
387 ),
388 false
389 );
390 break;
391
392 /*
393 * Field Meta.
394 */
395 case 'meta':
396 $value = ! empty( $field['meta-key'] ) ? esc_attr( $field['meta-key'] ) : evf_get_meta_key_field_option( $field );
397 $tooltip = esc_html__( 'Enter meta key to be stored in database.', 'everest-forms' );
398 $output = $this->field_element(
399 'label',
400 $field,
401 array(
402 'slug' => 'meta-key',
403 'value' => esc_html__( 'Meta Key', 'everest-forms' ),
404 'tooltip' => $tooltip,
405 ),
406 false
407 );
408 $output .= $this->field_element(
409 'text',
410 $field,
411 array(
412 'slug' => 'meta-key',
413 'class' => 'evf-input-meta-key',
414 'value' => $value,
415 ),
416 false
417 );
418 $output = $this->field_element(
419 'row',
420 $field,
421 array(
422 'slug' => 'meta-key',
423 'content' => $output,
424 ),
425 false
426 );
427 break;
428
429 /*
430 * Field Description.
431 */
432 case 'description':
433 $value = ! empty( $field['description'] ) ? esc_attr( $field['description'] ) : '';
434 $tooltip = esc_html__( 'Enter text for the form field description.', 'everest-forms' );
435 $output = $this->field_element(
436 'label',
437 $field,
438 array(
439 'slug' => 'description',
440 'value' => esc_html__( 'Description', 'everest-forms' ),
441 'tooltip' => $tooltip,
442 ),
443 false
444 );
445 $output .= $this->field_element(
446 'textarea',
447 $field,
448 array(
449 'slug' => 'description',
450 'value' => $value,
451 ),
452 false
453 );
454 $output = $this->field_element(
455 'row',
456 $field,
457 array(
458 'slug' => 'description',
459 'content' => $output,
460 ),
461 false
462 );
463 break;
464
465 /*
466 * Field Required toggle.
467 */
468 case 'required':
469 $default = ! empty( $args['default'] ) ? $args['default'] : '0';
470 $value = isset( $field['required'] ) ? $field['required'] : $default;
471 $tooltip = esc_html__( 'Check this option to mark the field required. A form will not submit unless all required fields are provided.', 'everest-forms' );
472 $output = $this->field_element(
473 'checkbox',
474 $field,
475 array(
476 'slug' => 'required',
477 'value' => $value,
478 'desc' => esc_html__( 'Required', 'everest-forms' ),
479 'tooltip' => $tooltip,
480 ),
481 false
482 );
483 $output = $this->field_element(
484 'row',
485 $field,
486 array(
487 'slug' => 'required',
488 'content' => $output,
489 ),
490 false
491 );
492 break;
493
494 /*
495 * Required Field Message.
496 */
497 case 'required_field_message':
498 $has_sub_fields = false;
499 $sub_fields = array();
500
501 $required_validation = get_option( 'everest_forms_required_validation' );
502 if ( in_array( $field['type'], array( 'number', 'email', 'url', 'phone' ), true ) ) {
503 $required_validation = get_option( 'everest_forms_' . $field['type'] . '_validation' );
504 }
505
506 if ( 'likert' === $field['type'] ) {
507 $has_sub_fields = true;
508 $likert_rows = isset( $field['likert_rows'] ) ? $field['likert_rows'] : array();
509 foreach ( $likert_rows as $row_number => $row_label ) {
510 $row_slug = 'required-field-message-' . $row_number;
511 $sub_fields[ $row_slug ] = array(
512 'label' => array(
513 'value' => $row_label,
514 'tooltip' => esc_html__( 'Enter a message to show for this row if it\'s required.', 'everest-forms' ),
515 ),
516 'text' => array(
517 'value' => isset( $field[ $row_slug ] ) ? esc_attr( $field[ $row_slug ] ) : esc_attr( $required_validation ),
518 ),
519 );
520 }
521 } elseif ( 'address' === $field['type'] ) {
522 $has_sub_fields = true;
523 $sub_fields = array(
524 'required-field-message-address1' => array(
525 'label' => array(
526 'value' => esc_html__( 'Address Line 1', 'everest-forms' ),
527 'tooltip' => esc_html__( 'Enter a message to show for Address Line 1 if it\'s required.', 'everest-forms' ),
528 ),
529 'text' => array(
530 'value' => isset( $field['required-field-message-address1'] ) ? esc_attr( $field['required-field-message-address1'] ) : esc_attr( $required_validation ),
531 ),
532 ),
533 'required-field-message-city' => array(
534 'label' => array(
535 'value' => esc_html__( 'City', 'everest-forms' ),
536 'tooltip' => esc_html__( 'Enter a message to show for City if it\'s required.', 'everest-forms' ),
537 ),
538 'text' => array(
539 'value' => isset( $field['required-field-message-city'] ) ? esc_attr( $field['required-field-message-city'] ) : esc_attr( $required_validation ),
540 ),
541 ),
542 'required-field-message-state' => array(
543 'label' => array(
544 'value' => esc_html__( 'State / Province / Region', 'everest-forms' ),
545 'tooltip' => esc_html__( 'Enter a message to show for State/Province/Region if it\'s required.', 'everest-forms' ),
546 ),
547 'text' => array(
548 'value' => isset( $field['required-field-message-state'] ) ? esc_attr( $field['required-field-message-state'] ) : esc_attr( $required_validation ),
549 ),
550 ),
551 'required-field-message-postal' => array(
552 'label' => array(
553 'value' => esc_html__( 'Zip / Postal Code', 'everest-forms' ),
554 'tooltip' => esc_html__( 'Enter a message to show for Zip/Postal Code if it\'s required.', 'everest-forms' ),
555 ),
556 'text' => array(
557 'value' => isset( $field['required-field-message-postal'] ) ? esc_attr( $field['required-field-message-postal'] ) : esc_attr( $required_validation ),
558 ),
559 ),
560 'required-field-message-country' => array(
561 'label' => array(
562 'value' => esc_html__( 'Country', 'everest-forms' ),
563 'tooltip' => esc_html__( 'Enter a message to show for Country if it\'s required.', 'everest-forms' ),
564 ),
565 'text' => array(
566 'value' => isset( $field['required-field-message-country'] ) ? esc_attr( $field['required-field-message-country'] ) : esc_attr( $required_validation ),
567 ),
568 ),
569 );
570 }
571
572 if ( true === $has_sub_fields ) {
573 $sub_field_output_array = array();
574 foreach ( $sub_fields as $sub_field_slug => $sub_field_data ) {
575 $value = isset( $field['required-field-message'] ) ? esc_attr( $field['required-field-message'] ) : esc_attr( $required_validation );
576 $tooltip = esc_html__( 'Enter a message to show for this field if it\'s required.', 'everest-forms' );
577 $output = $this->field_element(
578 'label',
579 $field,
580 array(
581 'slug' => $sub_field_slug,
582 'value' => $sub_field_data['label']['value'],
583 'tooltip' => $sub_field_data['label']['tooltip'],
584 ),
585 false
586 );
587 $output .= $this->field_element(
588 'text',
589 $field,
590 array(
591 'slug' => $sub_field_slug,
592 'value' => $sub_field_data['text']['value'],
593 ),
594 false
595 );
596 $output = $this->field_element(
597 'row',
598 $field,
599 array(
600 'slug' => $sub_field_slug,
601 'content' => $output,
602 ),
603 false
604 );
605
606 $sub_field_output_array[] = $output;
607 }
608 $output = implode( '', $sub_field_output_array );
609 $output = $this->field_element(
610 'row',
611 $field,
612 array(
613 'slug' => 'required-field-message',
614 'class' => isset( $field['required'] ) ? '' : 'hidden',
615 'content' => $output,
616 ),
617 false
618 );
619 } else {
620 $value = isset( $field['required-field-message'] ) ? esc_attr( $field['required-field-message'] ) : esc_attr( $required_validation );
621 $tooltip = esc_html__( 'Enter a message to show for this field if it\'s required.', 'everest-forms' );
622 $output = $this->field_element(
623 'label',
624 $field,
625 array(
626 'slug' => 'required-field-message',
627 'value' => esc_html__( 'Required Field Message', 'everest-forms' ),
628 'tooltip' => $tooltip,
629 ),
630 false
631 );
632 $output .= $this->field_element(
633 'text',
634 $field,
635 array(
636 'slug' => 'required-field-message',
637 'value' => $value,
638 ),
639 false
640 );
641 $output = $this->field_element(
642 'row',
643 $field,
644 array(
645 'slug' => 'required-field-message',
646 'class' => isset( $field['required'] ) ? '' : 'hidden',
647 'content' => $output,
648 ),
649 false
650 );
651 }
652 break;
653
654 /*
655 * Code Block.
656 */
657 case 'code':
658 $value = ! empty( $field['code'] ) ? esc_attr( $field['code'] ) : '';
659 $tooltip = esc_html__( 'Enter code for the form field.', 'everest-forms' );
660 $output = $this->field_element(
661 'label',
662 $field,
663 array(
664 'slug' => 'code',
665 'value' => esc_html__( 'Code', 'everest-forms' ),
666 'tooltip' => $tooltip,
667 ),
668 false
669 );
670 $output .= $this->field_element(
671 'textarea',
672 $field,
673 array(
674 'slug' => 'code',
675 'value' => $value,
676 ),
677 false
678 );
679 $output = $this->field_element(
680 'row',
681 $field,
682 array(
683 'slug' => 'code',
684 'content' => $output,
685 ),
686 false
687 );
688 break;
689
690 /*
691 * Choices.
692 */
693 case 'choices':
694 $class = array();
695 $label = ! empty( $args['label'] ) ? esc_html( $args['label'] ) : esc_html__( 'Choices', 'everest-forms' );
696 $choices = ! empty( $field['choices'] ) ? $field['choices'] : $this->defaults;
697 $input_type = in_array( $field['type'], array( 'radio', 'payment-multiple' ), true ) ? 'radio' : 'checkbox';
698
699 if ( ! empty( $field['show_values'] ) ) {
700 $class[] = 'show-values';
701 }
702 if ( ! empty( $field['choices_images'] ) ) {
703 $class[] = 'show-images';
704 }
705
706 // Field label.
707 $field_label = $this->field_element(
708 'label',
709 $field,
710 array(
711 'slug' => 'choices',
712 'value' => $label,
713 'tooltip' => esc_html__( 'Add choices for the form field.', 'everest-forms' ),
714 'after_tooltip' => '', // @todo Bulk import and export for choices.
715 )
716 );
717
718 // Field contents.
719 $field_content = sprintf(
720 '<ul data-next-id="%s" class="evf-choices-list %s" data-field-id="%s" data-field-type="%s">',
721 max( array_keys( $choices ) ) + 1,
722 evf_sanitize_classes( $class, true ),
723 $field['id'],
724 $this->type
725 );
726 foreach ( $choices as $key => $choice ) {
727 $default = ! empty( $choice['default'] ) ? $choice['default'] : '';
728 $name = sprintf( 'form_fields[%s][choices][%s]', $field['id'], $key );
729 $image = ! empty( $choice['image'] ) ? $choice['image'] : '';
730
731 // BW compatibility for value in payment fields.
732 if ( ! empty( $field['amount'][ $key ]['value'] ) ) {
733 $choice['value'] = evf_format_amount( evf_sanitize_amount( $field['amount'][ $key ]['value'] ) );
734 }
735
736 $field_content .= sprintf( '<li data-key="%1$d">', absint( $key ) );
737 $field_content .= '<span class="sort"><svg width="18" height="18" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18" role="img" aria-hidden="true" focusable="false"><path d="M13,8c0.6,0,1-0.4,1-1s-0.4-1-1-1s-1,0.4-1,1S12.4,8,13,8z M5,6C4.4,6,4,6.4,4,7s0.4,1,1,1s1-0.4,1-1S5.6,6,5,6z M5,10 c-0.6,0-1,0.4-1,1s0.4,1,1,1s1-0.4,1-1S5.6,10,5,10z M13,10c-0.6,0-1,0.4-1,1s0.4,1,1,1s1-0.4,1-1S13.6,10,13,10z M9,6 C8.4,6,8,6.4,8,7s0.4,1,1,1s1-0.4,1-1S9.6,6,9,6z M9,10c-0.6,0-1,0.4-1,1s0.4,1,1,1s1-0.4,1-1S9.6,10,9,10z"></path></svg></span>';
738 $field_content .= sprintf( '<input type="%1$s" name="%2$s[default]" class="default" value="1" %3$s>', $input_type, $name, checked( '1', $default, false ) );
739 $field_content .= '<div class="evf-choice-list-input">';
740 $field_content .= sprintf( '<input type="text" name="%1$s[label]" value="%2$s" class="label" data-key="%3$s">', $name, esc_attr( $choice['label'] ), absint( $key ) );
741 if ( in_array( $field['type'], array( 'payment-multiple', 'payment-checkbox' ), true ) ) {
742 $field_content .= sprintf( '<input type="text" name="%1$s[value]" value="%2$s" class="value evf-money-input" placeholder="%3$s">', $name, esc_attr( $choice['value'] ), evf_format_amount( 0 ) );
743 } else {
744 $field_content .= sprintf( '<input type="text" name="%1$s[value]" value="%2$s" class="value">', $name, esc_attr( $choice['value'] ) );
745 }
746 $field_content .= '</div>';
747 $field_content .= '<a class="add" href="#"><i class="dashicons dashicons-plus-alt"></i></a>';
748 $field_content .= '<a class="remove" href="#"><i class="dashicons dashicons-dismiss"></i></a>';
749 $field_content .= '<div class="everest-forms-attachment-media-view">';
750 $field_content .= sprintf( '<input type="hidden" class="source" name="%s[image]" value="%s">', $name, esc_url_raw( $image ) );
751 $field_content .= sprintf( '<button type="button" class="upload-button button-add-media"%s>%s</button>', ! empty( $image ) ? ' style="display:none;"' : '', esc_html__( 'Upload Image', 'everest-forms' ) );
752 $field_content .= '<div class="thumbnail thumbnail-image">';
753 if ( ! empty( $image ) ) {
754 $field_content .= sprintf( '<img class="attachment-thumb" src="%1$s">', esc_url_raw( $image ) );
755 }
756 $field_content .= '</div>';
757 $field_content .= sprintf( '<div class="actions"%s>', empty( $image ) ? ' style="display:none;"' : '' );
758 $field_content .= sprintf( '<button type="button" class="button remove-button">%1$s</button>', esc_html__( 'Remove', 'everest-forms' ) );
759 $field_content .= sprintf( '<button type="button" class="button upload-button">%1$s</button>', esc_html__( 'Change image', 'everest-forms' ) );
760 $field_content .= '</div>';
761 $field_content .= '</div>';
762 $field_content .= '</li>';
763 }
764 $field_content .= '</ul>';
765
766 // Final field output.
767 $output = $this->field_element(
768 'row',
769 $field,
770 array(
771 'slug' => 'choices',
772 'content' => $field_label . $field_content,
773 ),
774 false
775 );
776 break;
777
778 /*
779 * Choices Images.
780 */
781 case 'choices_images':
782 $field_content = sprintf(
783 '<div class="notice notice-warning%s"><p>%s</p></div>',
784 empty( $field['choices_images'] ) ? ' hidden' : '',
785 esc_html__( 'For best results, images should be square and at least 200 × 160 pixels or smaller.', 'everest-forms' )
786 );
787
788 $field_content .= $this->field_element(
789 'checkbox',
790 $field,
791 array(
792 'slug' => 'choices_images',
793 'value' => isset( $field['choices_images'] ) ? '1' : '0',
794 'desc' => esc_html__( 'Use image choices', 'everest-forms' ),
795 'tooltip' => esc_html__( 'Check this option to enable using images with the choices.', 'everest-forms' ),
796 ),
797 false
798 );
799
800 // Final field output.
801 $output = $this->field_element(
802 'row',
803 $field,
804 array(
805 'slug' => 'choices_images',
806 'content' => $field_content,
807 ),
808 false
809 );
810 break;
811
812 /**
813 * Advanced Fields.
814 */
815
816 /*
817 * Default value.
818 */
819 case 'default_value':
820 $value = ! empty( $field['default_value'] ) ? esc_attr( $field['default_value'] ) : '';
821 $tooltip = esc_html__( 'Enter text for the default form field value.', 'everest-forms' );
822 $toggle = '';
823 $output = $this->field_element(
824 'label',
825 $field,
826 array(
827 'slug' => 'default_value',
828 'value' => esc_html__( 'Default Value', 'everest-forms' ),
829 'tooltip' => $tooltip,
830 'after_tooltip' => $toggle,
831 ),
832 false
833 );
834 $output .= $this->field_element(
835 'text',
836 $field,
837 array(
838 'slug' => 'default_value',
839 'value' => $value,
840 ),
841 false
842 );
843
844 // Smart tag for default value.
845 if ( 'rating' !== $field['type'] ) {
846 $output .= '<a href="#" class="evf-toggle-smart-tag-display" data-type="other"><span class="dashicons dashicons-editor-code"></span></a>';
847 $output .= '<div class="evf-smart-tag-lists" style="display: none">';
848 $output .= '<div class="smart-tag-title other-tag-title">Others</div><ul class="evf-others"></ul></div>';
849 }
850
851 $output = $this->field_element(
852 'row',
853 $field,
854 array(
855 'slug' => 'default_value',
856 'content' => $output,
857 ),
858 false
859 );
860 break;
861
862 /*
863 * Advanced Options markup.
864 */
865 case 'advanced-options':
866 $markup = ! empty( $args['markup'] ) ? $args['markup'] : 'open';
867 if ( 'open' === $markup ) {
868 $override = apply_filters( 'everest_forms_advanced_options_override', false );
869 $override = ! empty( $override ) ? 'style="display:' . $override . ';"' : '';
870 $output = sprintf( '<div class="everest-forms-field-option-group everest-forms-field-option-group-advanced everest-forms-hide closed" id="everest-forms-field-option-advanced-%s" %s>', $field['id'], $override );
871 $output .= sprintf( '<a href="#" class="everest-forms-field-option-group-toggle">%s<i class="handlediv"></i></a>', __( 'Advanced Options', 'everest-forms' ) );
872 $output .= '<div class="everest-forms-field-option-group-inner">';
873 } else {
874 $output = '</div></div>';
875 }
876 break;
877
878 /*
879 * Placeholder.
880 */
881 case 'placeholder':
882 $value = ! empty( $field['placeholder'] ) ? esc_attr( $field['placeholder'] ) : '';
883 $tooltip = esc_html__( 'Enter text for the form field placeholder.', 'everest-forms' );
884 $output = $this->field_element(
885 'label',
886 $field,
887 array(
888 'slug' => 'placeholder',
889 'value' => esc_html__( 'Placeholder Text', 'everest-forms' ),
890 'tooltip' => $tooltip,
891 ),
892 false
893 );
894 $output .= $this->field_element(
895 'text',
896 $field,
897 array(
898 'slug' => 'placeholder',
899 'value' => $value,
900 ),
901 false
902 );
903 $output = $this->field_element(
904 'row',
905 $field,
906 array(
907 'slug' => 'placeholder',
908 'content' => $output,
909 ),
910 false
911 );
912 break;
913
914 /*
915 * CSS classes.
916 */
917 case 'css':
918 $toggle = '';
919 $tooltip = esc_html__( 'Enter CSS class names for this field container. Multiple class names should be separated with spaces.', 'everest-forms' );
920 $value = ! empty( $field['css'] ) ? esc_attr( $field['css'] ) : '';
921
922 // Build output.
923 $output = $this->field_element(
924 'label',
925 $field,
926 array(
927 'slug' => 'css',
928 'value' => esc_html__( 'CSS Classes', 'everest-forms' ),
929 'tooltip' => $tooltip,
930 'after_tooltip' => $toggle,
931 ),
932 false
933 );
934 $output .= $this->field_element(
935 'text',
936 $field,
937 array(
938 'slug' => 'css',
939 'value' => $value,
940 ),
941 false
942 );
943 $output = $this->field_element(
944 'row',
945 $field,
946 array(
947 'slug' => 'css',
948 'content' => $output,
949 ),
950 false
951 );
952 break;
953
954 /*
955 * Hide Label.
956 */
957 case 'label_hide':
958 $value = isset( $field['label_hide'] ) ? $field['label_hide'] : '0';
959 $tooltip = esc_html__( 'Check this option to hide the form field label.', 'everest-forms' );
960
961 // Build output.
962 $output = $this->field_element(
963 'checkbox',
964 $field,
965 array(
966 'slug' => 'label_hide',
967 'value' => $value,
968 'desc' => esc_html__( 'Hide Label', 'everest-forms' ),
969 'tooltip' => $tooltip,
970 ),
971 false
972 );
973 $output = $this->field_element(
974 'row',
975 $field,
976 array(
977 'slug' => 'label_hide',
978 'content' => $output,
979 ),
980 false
981 );
982 break;
983
984 /*
985 * Hide Sub-Labels.
986 */
987 case 'sublabel_hide':
988 $value = isset( $field['sublabel_hide'] ) ? $field['sublabel_hide'] : '0';
989 $tooltip = esc_html__( 'Check this option to hide the form field sub-label.', 'everest-forms' );
990
991 // Build output.
992 $output = $this->field_element(
993 'checkbox',
994 $field,
995 array(
996 'slug' => 'sublabel_hide',
997 'value' => $value,
998 'desc' => esc_html__( 'Hide Sub-Labels', 'everest-forms' ),
999 'tooltip' => $tooltip,
1000 ),
1001 false
1002 );
1003 $output = $this->field_element(
1004 'row',
1005 $field,
1006 array(
1007 'slug' => 'sublabel_hide',
1008 'content' => $output,
1009 ),
1010 false
1011 );
1012 break;
1013
1014 /*
1015 * Input columns.
1016 */
1017 case 'input_columns':
1018 $value = ! empty( $field['input_columns'] ) ? esc_attr( $field['input_columns'] ) : '';
1019 $tooltip = esc_html__( 'Select the column layout for displaying field choices.', 'everest-forms' );
1020 $options = array(
1021 '' => esc_html__( 'One Column', 'everest-forms' ),
1022 '2' => esc_html__( 'Two Columns', 'everest-forms' ),
1023 '3' => esc_html__( 'Three Columns', 'everest-forms' ),
1024 'inline' => esc_html__( 'Inline', 'everest-forms' ),
1025 );
1026
1027 // Build output.
1028 $output = $this->field_element(
1029 'label',
1030 $field,
1031 array(
1032 'slug' => 'input_columns',
1033 'value' => esc_html__( 'Layout', 'everest-forms' ),
1034 'tooltip' => $tooltip,
1035 ),
1036 false
1037 );
1038 $output .= $this->field_element(
1039 'select',
1040 $field,
1041 array(
1042 'slug' => 'input_columns',
1043 'value' => $value,
1044 'options' => $options,
1045 ),
1046 false
1047 );
1048 $output = $this->field_element(
1049 'row',
1050 $field,
1051 array(
1052 'slug' => 'input_columns',
1053 'content' => $output,
1054 ),
1055 false
1056 );
1057 break;
1058
1059 /*
1060 * Default.
1061 */
1062 default:
1063 if ( is_callable( array( $this, $option ) ) ) {
1064 $this->{$option}( $field );
1065 }
1066 do_action( 'everest_forms_field_options_' . $option, $this, $field, $args );
1067 break;
1068
1069 }
1070
1071 if ( $echo ) {
1072 if ( in_array( $option, array( 'basic-options', 'advanced-options' ), true ) ) {
1073 if ( 'open' === $markup ) {
1074 do_action( "everest_forms_field_options_before_{$option}", $field, $this );
1075 }
1076
1077 if ( 'close' === $markup ) {
1078 do_action( "everest_forms_field_options_bottom_{$option}", $field, $this );
1079 }
1080
1081 echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1082
1083 if ( 'open' === $markup ) {
1084 do_action( "everest_forms_field_options_top_{$option}", $field, $this );
1085 }
1086
1087 if ( 'close' === $markup ) {
1088 do_action( "everest_forms_field_options_after_{$option}", $field, $this );
1089 }
1090 } else {
1091 echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1092 }
1093 } else {
1094 return $output;
1095 }
1096 }
1097
1098 /**
1099 * Helper function to create common field options that are used frequently
1100 * in the field preview.
1101 *
1102 * @since 1.0.0
1103 *
1104 * @param string $option Field option to render.
1105 * @param array $field Field data and settings.
1106 * @param array $args Field preview arguments.
1107 * @param boolean $echo Print or return the value. Print by default.
1108 *
1109 * @return mixed Print or return a string.
1110 */
1111 public function field_preview_option( $option, $field, $args = array(), $echo = true ) {
1112 $output = '';
1113 $class = ! empty( $args['class'] ) ? evf_sanitize_classes( $args['class'] ) : '';
1114
1115 switch ( $option ) {
1116 case 'label':
1117 $label = isset( $field['label'] ) && ! empty( $field['label'] ) ? esc_html( $field['label'] ) : '';
1118 $output = sprintf( '<label class="label-title %s"><span class="text">%s</span><span class="required">*</span></label>', $class, $label );
1119 break;
1120
1121 case 'description':
1122 $description = isset( $field['description'] ) && ! empty( $field['description'] ) ? $field['description'] : '';
1123 $description = false !== strpos( $class, 'nl2br' ) ? nl2br( $description ) : $description;
1124 $output = sprintf( '<div class="description %s">%s</div>', $class, $description );
1125 break;
1126
1127 case 'choices':
1128 $values = ! empty( $field['choices'] ) ? $field['choices'] : $this->defaults;
1129 $choices_fields = array( 'select', 'radio', 'checkbox', 'payment-multiple', 'payment-checkbox' );
1130
1131 // Notify if choices source is currently empty.
1132 if ( empty( $values ) ) {
1133 $values = array(
1134 'label' => esc_html__( '(empty)', 'everest-forms' ),
1135 );
1136 }
1137
1138 // Build output.
1139 if ( ! in_array( $field['type'], $choices_fields, true ) ) {
1140 break;
1141 }
1142
1143 switch ( $field['type'] ) {
1144 case 'checkbox':
1145 case 'payment-checkbox':
1146 $type = 'checkbox';
1147 break;
1148
1149 case 'select':
1150 $type = 'select';
1151 break;
1152
1153 default:
1154 $type = 'radio';
1155 break;
1156 }
1157
1158 $list_class = array( 'widefat', 'primary-input' );
1159 $choices_images = ! empty( $field['choices_images'] );
1160
1161 if ( $choices_images ) {
1162 $list_class[] = 'everest-forms-image-choices';
1163 }
1164
1165 if ( 'select' === $type ) {
1166 $placeholder = ! empty( $field['placeholder'] ) ? esc_attr( $field['placeholder'] ) : '';
1167 $output = sprintf( '<select class="%s" disabled>', evf_sanitize_classes( $list_class, true ) );
1168
1169 // Optional placeholder.
1170 if ( ! empty( $placeholder ) ) {
1171 $output .= sprintf( '<option value="" class="placeholder">%s</option>', esc_html( $placeholder ) );
1172 }
1173
1174 // Build the select options (even though user can only see 1st option).
1175 foreach ( $values as $value ) {
1176 $default = isset( $value['default'] ) ? (bool) $value['default'] : false;
1177 $selected = ! empty( $placeholder ) ? '' : selected( true, $default, false );
1178 $output .= sprintf( '<option %s>%s</option>', $selected, esc_html( $value['label'] ) );
1179 }
1180
1181 $output .= '</select>';
1182 } else {
1183 $output = sprintf( '<ul class="%s">', evf_sanitize_classes( $list_class, true ) );
1184
1185 // Individual checkbox/radio options.
1186 foreach ( $values as $value ) {
1187 $default = isset( $value['default'] ) ? $value['default'] : '';
1188 $selected = checked( '1', $default, false );
1189 $placeholder = evf()->plugin_url() . '/assets/images/everest-forms-placeholder.png';
1190 $image_src = ! empty( $value['image'] ) ? esc_url( $value['image'] ) : $placeholder;
1191 $item_class = array();
1192
1193 if ( ! empty( $value['default'] ) ) {
1194 $item_class[] = 'everest-forms-selected';
1195 }
1196
1197 if ( $choices_images ) {
1198 $item_class[] = 'everest-forms-image-choices-item';
1199 }
1200
1201 $output .= sprintf( '<li class="%s">', evf_sanitize_classes( $item_class, true ) );
1202
1203 if ( $choices_images ) {
1204 $output .= '<label>';
1205 $output .= sprintf( '<span class="everest-forms-image-choices-image"><img src="%s" alt="%s"%s></span>', $image_src, esc_attr( $value['label'] ), ! empty( $value['label'] ) ? ' title="' . esc_attr( $value['label'] ) . '"' : '' );
1206 $output .= sprintf( '<input type="%s" %s disabled>', $type, $selected );
1207 $output .= '<span class="everest-forms-image-choices-label">' . wp_kses_post( $value['label'] ) . '</span>';
1208 $output .= '</label>';
1209 } else {
1210 $output .= sprintf( '<input type="%s" %s disabled>%s', $type, $selected, $value['label'] );
1211 }
1212
1213 $output .= '</li>';
1214 }
1215
1216 $output .= '</ul>';
1217 }
1218 break;
1219 }
1220
1221 if ( $echo ) {
1222 echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1223 } else {
1224 return $output;
1225 }
1226 }
1227
1228 /**
1229 * Create a new field in the admin AJAX editor.
1230 *
1231 * @since 1.0.0
1232 */
1233 public function field_new() {
1234 // Run a security check.
1235 check_ajax_referer( 'everest_forms_field_drop', 'security' );
1236
1237 // Check for permissions.
1238 if ( ! current_user_can( apply_filters( 'everest_forms_manage_cap', 'manage_options' ) ) ) {
1239 die( esc_html__( 'You do no have permission.', 'everest-forms' ) );
1240 }
1241
1242 // Check for form ID.
1243 if ( ! isset( $_POST['form_id'] ) || empty( $_POST['form_id'] ) ) {
1244 die( esc_html__( 'No form ID found', 'everest-forms' ) );
1245 }
1246
1247 // Check for field type to add.
1248 if ( ! isset( $_POST['field_type'] ) || empty( $_POST['field_type'] ) ) {
1249 die( esc_html__( 'No field type found', 'everest-forms' ) );
1250 }
1251
1252 // Grab field data.
1253 $field_args = ! empty( $_POST['defaults'] ) ? (array) wp_unslash( $_POST['defaults'] ) : array(); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1254 $field_type = esc_attr( wp_unslash( $_POST['field_type'] ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1255 $field_id = evf()->form->field_unique_key( wp_unslash( $_POST['form_id'] ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
1256 $field = array(
1257 'id' => $field_id,
1258 'type' => $field_type,
1259 'label' => $this->name,
1260 'description' => '',
1261 );
1262 $field = wp_parse_args( $field_args, $field );
1263 $field = apply_filters( 'everest_forms_field_new_default', $field );
1264 $field_required = apply_filters( 'everest_forms_field_new_required', '', $field );
1265 $field_class = apply_filters( 'everest_forms_field_new_class', '', $field );
1266
1267 // Field types that default to required.
1268 if ( ! empty( $field_required ) ) {
1269 $field_required = 'required';
1270 $field['required'] = '1';
1271 }
1272
1273 // Build Preview.
1274 ob_start();
1275 $this->field_preview( $field );
1276 $preview = sprintf( '<div class="everest-forms-field everest-forms-field-%s %s %s" id="everest-forms-field-%s" data-field-id="%s" data-field-type="%s">', $field_type, $field_required, $field_class, $field['id'], $field['id'], $field_type );
1277 $preview .= sprintf( '<div class="evf-field-action">' );
1278 $preview .= sprintf( '<a href="#" class="everest-forms-field-duplicate" title="%s"><span class="dashicons dashicons-media-default"></span></a>', __( 'Duplicate Field', 'everest-forms' ) );
1279 $preview .= sprintf( '<a href="#" class="everest-forms-field-delete" title="%s"><span class="dashicons dashicons-trash"></span></a>', __( 'Delete Field', 'everest-forms' ) );
1280 $preview .= sprintf( '<a href="#" class="everest-forms-field-setting" title="%s"><span class="dashicons dashicons-admin-generic"></span></a>', __( 'Settings', 'everest-forms' ) );
1281 $preview .= sprintf( '</div>' );
1282 $preview .= ob_get_clean();
1283 $preview .= '</div>';
1284
1285 // Build Options.
1286 $options = sprintf( '<div class="everest-forms-field-option everest-forms-field-option-%s" id="everest-forms-field-option-%s" data-field-id="%s">', esc_attr( $field['type'] ), $field['id'], $field['id'] );
1287 $options .= sprintf( '<input type="hidden" name="form_fields[%s][id]" value="%s" class="everest-forms-field-option-hidden-id">', $field['id'], $field['id'] );
1288 $options .= sprintf( '<input type="hidden" name="form_fields[%s][type]" value="%s" class="everest-forms-field-option-hidden-type">', $field['id'], esc_attr( $field['type'] ) );
1289 ob_start();
1290 $this->field_options( $field );
1291 $options .= ob_get_clean();
1292 $options .= '</div>';
1293
1294 $form_field_array = explode( '-', $field_id );
1295 $field_id_int = absint( $form_field_array[ count( $form_field_array ) - 1 ] );
1296
1297 // Prepare to return compiled results.
1298 wp_send_json_success(
1299 array(
1300 'form_id' => (int) $_POST['form_id'],
1301 'field' => $field,
1302 'preview' => $preview,
1303 'options' => $options,
1304 'form_field_id' => ( $field_id_int + 1 ),
1305 )
1306 );
1307 }
1308
1309 /**
1310 * Field display on the form front-end.
1311 *
1312 * @since 1.0.0
1313 *
1314 * @param array $field Field Data.
1315 * @param array $field_atts Field attributes.
1316 * @param array $form_data All Form Data.
1317 */
1318 public function field_display( $field, $field_atts, $form_data ) {}
1319
1320 /**
1321 * Display field input errors if present.
1322 *
1323 * @since 1.0.0
1324 *
1325 * @param string $key Input key.
1326 * @param array $field Field data and settings.
1327 */
1328 public function field_display_error( $key, $field ) {
1329 // Need an error.
1330 if ( empty( $field['properties']['error']['value'][ $key ] ) ) {
1331 return;
1332 }
1333
1334 printf(
1335 '<label class="everest-forms-error evf-error" for="%s">%s</label>',
1336 esc_attr( $field['properties']['inputs'][ $key ]['id'] ),
1337 esc_html( $field['properties']['error']['value'][ $key ] )
1338 );
1339 }
1340
1341 /**
1342 * Display field input sublabel if present.
1343 *
1344 * @since 1.0.0
1345 *
1346 * @param string $key Input key.
1347 * @param string $position Sublabel position.
1348 * @param array $field Field data and settings.
1349 */
1350 public function field_display_sublabel( $key, $position, $field ) {
1351 // Need a sublabel value.
1352 if ( empty( $field['properties']['inputs'][ $key ]['sublabel']['value'] ) ) {
1353 return;
1354 }
1355
1356 $pos = ! empty( $field['properties']['inputs'][ $key ]['sublabel']['position'] ) ? $field['properties']['inputs'][ $key ]['sublabel']['position'] : 'after';
1357 $hidden = ! empty( $field['properties']['inputs'][ $key ]['sublabel']['hidden'] ) ? 'everest-forms-sublabel-hide' : '';
1358
1359 if ( $pos !== $position ) {
1360 return;
1361 }
1362
1363 printf(
1364 '<label for="%s" class="everest-forms-field-sublabel %s %s">%s</label>',
1365 esc_attr( $field['properties']['inputs'][ $key ]['id'] ),
1366 sanitize_html_class( $pos ),
1367 $hidden, // phpcs:ignore WordPress.Security.EscapeOutput
1368 $field['properties']['inputs'][ $key ]['sublabel']['value'] // phpcs:ignore WordPress.Security.EscapeOutput
1369 );
1370 }
1371
1372 /**
1373 * Validates field on form submit.
1374 *
1375 * @since 1.0.0
1376 *
1377 * @param string $field_id Field Id.
1378 * @param array $field_submit Submitted Data.
1379 * @param array $form_data All Form Data.
1380 */
1381 public function validate( $field_id, $field_submit, $form_data ) {
1382 $field_type = isset( $form_data['form_fields'][ $field_id ]['type'] ) ? $form_data['form_fields'][ $field_id ]['type'] : '';
1383 $required_field = isset( $form_data['form_fields'][ $field_id ]['required'] ) ? $form_data['form_fields'][ $field_id ]['required'] : false;
1384 $conditional_status = isset( $form_data['form_fields'][ $field_id ]['conditional_logic_status'] ) ? $form_data['form_fields'][ $field_id ]['conditional_logic_status'] : 0;
1385
1386 // Basic required check - If field is marked as required, check for entry data.
1387 if ( false !== $required_field && '1' !== $conditional_status && ( empty( $field_submit ) && '0' !== $field_submit ) ) {
1388 evf()->task->errors[ $form_data['id'] ][ $field_id ] = evf_get_required_label();
1389 update_option( 'evf_validation_error', 'yes' );
1390 }
1391
1392 // Type validations.
1393 switch ( $field_type ) {
1394 case 'url':
1395 if ( ! empty( $_POST['everest_forms']['form_fields'][ $field_id ] ) && filter_var( $field_submit, FILTER_VALIDATE_URL ) === false ) { // phpcs:ignore WordPress.Security.NonceVerification
1396 $validation_text = get_option( 'evf_' . $field_type . '_validation', esc_html__( 'Please enter a valid url', 'everest-forms' ) );
1397 }
1398 break;
1399 case 'email':
1400 if ( is_array( $field_submit ) ) {
1401 $value = ! empty( $field_submit['primary'] ) ? $field_submit['primary'] : '';
1402 } else {
1403 $value = ! empty( $field_submit ) ? $field_submit : '';
1404 }
1405 if ( ! empty( $_POST['everest_forms']['form_fields'][ $field_id ] ) && ! is_email( $value ) ) { // phpcs:ignore WordPress.Security.NonceVerification
1406 $validation_text = get_option( 'evf_' . $field_type . '_validation', esc_html__( 'Please enter a valid email address', 'everest-forms' ) );
1407 }
1408 break;
1409 case 'number':
1410 if ( ! empty( $_POST['everest_forms']['form_fields'][ $field_id ] ) && ! is_numeric( $field_submit ) ) { // phpcs:ignore WordPress.Security.NonceVerification
1411 $validation_text = get_option( 'evf_' . $field_type . '_validation', esc_html__( 'Please enter a valid number', 'everest-forms' ) );
1412 }
1413 break;
1414 }
1415
1416 if ( isset( $validation_text ) ) {
1417 evf()->task->errors[ $form_data['id'] ][ $field_id ] = apply_filters( 'everest_forms_type_validation', $validation_text );
1418 update_option( 'evf_validation_error', 'yes' );
1419 }
1420 }
1421
1422 /**
1423 * Formats and sanitizes field.
1424 *
1425 * @since 1.0.0
1426 *
1427 * @param int $field_id Field ID.
1428 * @param mixed $field_submit Submitted field value.
1429 * @param array $form_data Form data and settings.
1430 * @param string $meta_key Field meta key.
1431 */
1432 public function format( $field_id, $field_submit, $form_data, $meta_key ) {
1433 if ( is_array( $field_submit ) ) {
1434 $field_submit = array_filter( $field_submit );
1435 $field_submit = implode( "\r\n", $field_submit );
1436 }
1437
1438 $name = ! empty( $form_data['form_fields'][ $field_id ]['label'] ) ? sanitize_text_field( $form_data['form_fields'][ $field_id ]['label'] ) : '';
1439
1440 // Sanitize but keep line breaks.
1441 $value = evf_sanitize_textarea_field( $field_submit );
1442
1443 evf()->task->form_fields[ $field_id ] = array(
1444 'name' => $name,
1445 'value' => $value,
1446 'id' => $field_id,
1447 'type' => $this->type,
1448 'meta_key' => $meta_key,
1449 );
1450 }
1451
1452 /**
1453 * Field with limit.
1454 *
1455 * @param array $field Field to check.
1456 * @return boolean
1457 */
1458 protected function field_is_limit( $field ) {
1459 if ( in_array( $field['type'], array( 'text', 'textarea' ), true ) ) {
1460 return isset( $field['limit_enabled'] ) && ! empty( $field['limit_count'] );
1461 }
1462 }
1463 }
1464