PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 6.23
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v6.23
6.35 6.34 6.33.1 6.33 6.32.1 6.32 6.31 6.25 6.25.1 6.26 6.26.1 6.27 6.28 6.29 6.3 6.3.1 6.3.2 6.30 6.4 6.4.1 6.4.2 6.5 6.5.1 6.5.2 6.5.3 All 141 releases
formidable / classes / helpers / FrmEntriesHelper.php

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

899 lines 27.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 FrmEntriesHelper {
7
8 /**
9 * "Submitted" entry status.
10 *
11 * @since 6.4.2
12 * @var int
13 */
14 const SUBMITTED_ENTRY_STATUS = 0;
15
16 /**
17 * "Draft" entry status.
18 *
19 * @since 6.4.2
20 * @var int
21 */
22 const DRAFT_ENTRY_STATUS = 1;
23
24 public static function setup_new_vars( $fields, $form = '', $reset = false, $args = array() ) {
25 remove_action( 'media_buttons', 'FrmFormsController::insert_form_button' );
26
27 $values = array(
28 'name' => '',
29 'description' => '',
30 'item_key' => '',
31 );
32
33 $values['fields'] = array();
34 if ( empty( $fields ) ) {
35 return apply_filters( 'frm_setup_new_entry', $values );
36 }
37
38 foreach ( (array) $fields as $field ) {
39 $original_default = $field->default_value;
40 self::prepare_field_default_value( $field );
41 $new_value = self::get_field_value_for_new_entry( $field, $reset, $args );
42
43 $field_array = FrmAppHelper::start_field_array( $field );
44 $field_array['value'] = $new_value;
45 $field_array['type'] = apply_filters( 'frm_field_type', $field->type, $field, $new_value );
46 $field_array['parent_form_id'] = isset( $args['parent_form_id'] ) ? $args['parent_form_id'] : $field->form_id;
47 $field_array['reset_value'] = $reset;
48 $field_array['in_embed_form'] = isset( $args['in_embed_form'] ) ? $args['in_embed_form'] : '0';
49 $field_array['original_default'] = $original_default;
50
51 FrmFieldsHelper::prepare_new_front_field( $field_array, $field, $args );
52
53 if ( ! is_array( $field->field_options ) ) {
54 $field->field_options = array();
55 }
56
57 $field_array = array_merge( $field->field_options, $field_array );
58
59 $values['fields'][] = $field_array;
60
61 if ( ! $form || ! isset( $form->id ) ) {
62 $form = FrmForm::getOne( $field->form_id );
63 }
64 }//end foreach
65
66 FrmAppHelper::unserialize_or_decode( $form->options );
67 if ( is_array( $form->options ) ) {
68 $values = array_merge( $values, $form->options );
69 }
70
71 $form_defaults = FrmFormsHelper::get_default_opts();
72 $form_defaults['custom_style'] = FrmAppHelper::custom_style_value( array() );
73
74 $values = array_merge( $form_defaults, $values );
75
76 return apply_filters( 'frm_setup_new_entry', $values );
77 }
78
79 /**
80 * @since 2.05
81 *
82 * @param object $field
83 */
84 private static function prepare_field_default_value( &$field ) {
85 // If checkbox, multi-select dropdown, or checkbox data from entries field, the value should be an array.
86 $return_array = FrmField::is_field_with_multiple_values( $field );
87
88 /**
89 * Do any shortcodes in default value and allow customization of default value.
90 * Calls FrmProFieldsHelper::get_default_value
91 */
92 $field->default_value = apply_filters( 'frm_get_default_value', $field->default_value, $field, true, $return_array );
93
94 if ( isset( $field->field_options['placeholder'] ) ) {
95 $field->field_options['placeholder'] = apply_filters( 'frm_get_default_value', $field->field_options['placeholder'], $field, false, false );
96 }
97 }
98
99 /**
100 * Set the value for each field
101 * This function is used when the form is first loaded and on all page turns *for a new entry*
102 *
103 * @since 2.0.13
104 *
105 * @param object $field - this is passed by reference since it is an object.
106 * @param bool $reset
107 * @param array $args
108 *
109 * @return array|string $new_value
110 */
111 private static function get_field_value_for_new_entry( $field, $reset, $args ) {
112 $new_value = $field->default_value;
113
114 if ( ! $reset && self::value_is_posted( $field, $args ) ) {
115 self::get_posted_value( $field, $new_value, $args );
116 }
117
118 if ( ! is_array( $new_value ) ) {
119 $new_value = str_replace( '"', '&quot;', $new_value );
120 }
121
122 return $new_value;
123 }
124
125 /**
126 * Check if a field has a posted value
127 *
128 * @since 2.01.0
129 *
130 * @param object $field
131 * @param array $args
132 *
133 * @return bool $value_is_posted
134 */
135 public static function value_is_posted( $field, $args ) {
136 $value_is_posted = false;
137 if ( $_POST ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
138 $repeating = isset( $args['repeating'] ) && $args['repeating'];
139 if ( $repeating ) {
140 if ( isset( $_POST['item_meta'][ $args['parent_field_id'] ][ $args['key_pointer'] ][ $field->id ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
141 $value_is_posted = true;
142 }
143 } elseif ( isset( $_POST['item_meta'][ $field->id ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
144 $value_is_posted = true;
145 }
146 }
147
148 return $value_is_posted;
149 }
150
151 public static function setup_edit_vars( $values, $record ) {
152 remove_action( 'media_buttons', 'FrmFormsController::insert_form_button' );
153
154 $values['item_key'] = FrmAppHelper::get_post_param( 'item_key', $record->item_key, 'sanitize_title' );
155 $values['form_id'] = $record->form_id;
156 $values['is_draft'] = $record->is_draft;
157
158 return apply_filters( 'frm_setup_edit_entry_vars', $values, $record );
159 }
160
161 public static function replace_default_message( $message, $atts ) {
162 if ( strpos( $message, '[default-message' ) === false &&
163 strpos( $message, '[default_message' ) === false &&
164 ! empty( $message ) ) {
165 return $message;
166 }
167
168 if ( empty( $message ) ) {
169 $message = '[default-message]';
170 }
171
172 preg_match_all( "/\[(default-message|default_message)\b(.*?)(?:(\/))?\]/s", $message, $shortcodes, PREG_PATTERN_ORDER );
173
174 foreach ( $shortcodes[0] as $short_key => $tag ) {
175 $add_atts = FrmShortcodeHelper::get_shortcode_attribute_array( $shortcodes[2][ $short_key ] );
176 if ( ! empty( $add_atts ) ) {
177 $this_atts = array_merge( $atts, $add_atts );
178 } else {
179 $this_atts = $atts;
180 }
181
182 $default = FrmEntriesController::show_entry_shortcode( $this_atts );
183
184 // Add the default message.
185 $message = str_replace( $shortcodes[0][ $short_key ], $default, $message );
186 }
187
188 return $message;
189 }
190
191 /**
192 * @param stdClass $entry
193 * @param stdClass $field
194 * @param array $atts
195 * @return string
196 */
197 public static function prepare_display_value( $entry, $field, $atts ) {
198 $field_value = isset( $entry->metas[ $field->id ] ) ? $entry->metas[ $field->id ] : false;
199
200 if ( FrmAppHelper::pro_is_installed() ) {
201 $empty = empty( $field_value );
202 FrmProEntriesHelper::get_dynamic_list_values( $field, $entry, $field_value );
203 if ( $empty && ! empty( $field_value ) ) {
204 // We've got an entry id, so switch it to a value.
205 $atts['force_id'] = true;
206 }
207 }
208
209 if ( $field->form_id == $entry->form_id || empty( $atts['embedded_field_id'] ) ) {
210 return self::display_value( $field_value, $field, $atts );
211 }
212
213 if ( ! FrmAppHelper::pro_is_installed() ) {
214 return '';
215 }
216 if ( is_callable( 'FrmProEntriesHelper::prepare_child_display_value' ) ) {
217 return FrmProEntriesHelper::prepare_child_display_value( $entry, $field, $atts );
218 }
219
220 // This is an embedded form.
221 if ( strpos( $atts['embedded_field_id'], 'form' ) === 0 ) {
222 // This is a repeating section.
223 $child_entries = FrmEntry::getAll( array( 'it.parent_item_id' => $entry->id ), '', '', true );
224 } else {
225 // Get all values for this field.
226 $child_values = isset( $entry->metas[ $atts['embedded_field_id'] ] ) ? $entry->metas[ $atts['embedded_field_id'] ] : false;
227
228 if ( $child_values ) {
229 $child_entries = FrmEntry::getAll( array( 'it.id' => (array) $child_values ) );
230 }
231 }
232
233 $field_value = array();
234
235 if ( empty( $child_entries ) ) {
236 return '';
237 }
238
239 foreach ( $child_entries as $child_entry ) {
240 $atts['item_id'] = $child_entry->id;
241 $atts['post_id'] = $child_entry->post_id;
242
243 // Fet the value for this field -- check for post values as well.
244 $entry_val = FrmProEntryMetaHelper::get_post_or_meta_value( $child_entry, $field );
245
246 if ( $entry_val || '0' === $entry_val ) {
247 // foreach entry get display_value.
248 $field_value[] = self::display_value( $entry_val, $field, $atts );
249 }
250
251 unset( $child_entry );
252 }
253
254 $sep = ', ';
255 if ( strpos( implode( ' ', $field_value ), '<img' ) !== false ) {
256 $sep = '<br/>';
257 }
258 $val = implode( $sep, $field_value );
259
260 return FrmAppHelper::kses( $val, 'all' );
261 }
262
263 /**
264 * Prepare the saved value for display
265 *
266 * @param array|string $value
267 * @param object $field
268 * @param array $atts
269 *
270 * @return string
271 */
272 public static function display_value( $value, $field, $atts = array() ) {
273
274 $defaults = array(
275 'type' => '',
276 'html' => false,
277 'show_filename' => true,
278 'truncate' => false,
279 'sep' => ', ',
280 'post_id' => 0,
281 'form_id' => $field->form_id,
282 'field' => $field,
283 'keepjs' => 0,
284 'return_array' => false,
285 );
286
287 $atts = wp_parse_args( $atts, $defaults );
288
289 if ( FrmField::is_image( $field ) || $field->type === 'star' ) {
290 $atts['truncate'] = false;
291 $atts['html'] = true;
292 }
293
294 $atts = apply_filters( 'frm_display_value_atts', $atts, $field, $value );
295
296 if ( is_string( $field->field_options ) ) {
297 $field->field_options = array();
298 }
299
300 if ( ! isset( $field->field_options['post_field'] ) ) {
301 $field->field_options['post_field'] = '';
302 }
303
304 if ( ! isset( $field->field_options['custom_field'] ) ) {
305 $field->field_options['custom_field'] = '';
306 }
307
308 if ( FrmAppHelper::pro_is_installed() && $atts['post_id'] && ( $field->field_options['post_field'] || $atts['type'] === 'tag' ) ) {
309 $atts['pre_truncate'] = $atts['truncate'];
310 $atts['truncate'] = true;
311 $atts['exclude_cat'] = isset( $field->field_options['exclude_cat'] ) ? $field->field_options['exclude_cat'] : 0;
312
313 $value = FrmProEntryMetaHelper::get_post_value( $atts['post_id'], $field->field_options['post_field'], $field->field_options['custom_field'], $atts );
314 $atts['truncate'] = $atts['pre_truncate'];
315 }
316
317 if ( $value == '' ) {
318 return $value;
319 }
320
321 $unfiltered_value = $value;
322 FrmFieldsHelper::prepare_field_value( $unfiltered_value, $field->type );
323
324 $value = apply_filters( 'frm_display_value_custom', $unfiltered_value, $field, $atts );
325 $value = apply_filters( 'frm_display_' . $field->type . '_value_custom', $value, compact( 'field', 'atts' ) );
326
327 if ( $value == $unfiltered_value ) {
328 $value = FrmFieldsHelper::get_unfiltered_display_value( compact( 'value', 'field', 'atts' ) );
329 }
330
331 if ( $atts['truncate'] && $atts['type'] !== 'url' ) {
332 $value = FrmAppHelper::truncate( $value, 50 );
333 }
334
335 if ( ! $atts['keepjs'] && ! is_array( $value ) ) {
336 $value = FrmAppHelper::kses( $value, 'all' );
337 }
338
339 return apply_filters( 'frm_display_value', $value, $field, $atts );
340 }
341
342 public static function set_posted_value( $field, $value, $args ) {
343 // If validating a field with "other" opt, set back to prev value now.
344 if ( ! empty( $args['other'] ) ) {
345 $value = $args['temp_value'];
346 }
347 if ( empty( $args['parent_field_id'] ) ) {
348 $_POST['item_meta'][ $field->id ] = $value;
349 } else {
350 self::set_parent_field_posted_value( $field, $value, $args );
351 }
352 }
353
354 /**
355 * Init arrays if necessary, else we get fatal error.
356 *
357 * @since 4.01
358 */
359 private static function set_parent_field_posted_value( $field, $value, $args ) {
360 if ( isset( $_POST['item_meta'][ $args['parent_field_id'] ] ) && is_array( $_POST['item_meta'][ $args['parent_field_id'] ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
361 if ( ! isset( $_POST['item_meta'][ $args['parent_field_id'] ][ $args['key_pointer'] ] ) || ! is_array( $_POST['item_meta'][ $args['parent_field_id'] ][ $args['key_pointer'] ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
362 $_POST['item_meta'][ $args['parent_field_id'] ][ $args['key_pointer'] ] = array(); // phpcs:ignore WordPress.Security.NonceVerification.Missing
363 }
364 } else {
365 // All of the section was probably removed.
366 $_POST['item_meta'][ $args['parent_field_id'] ] = array(); // phpcs:ignore WordPress.Security.NonceVerification.Missing
367 $_POST['item_meta'][ $args['parent_field_id'] ][ $args['key_pointer'] ] = array(); // phpcs:ignore WordPress.Security.NonceVerification.Missing
368 }
369
370 $_POST['item_meta'][ $args['parent_field_id'] ][ $args['key_pointer'] ][ $field->id ] = $value; // phpcs:ignore WordPress.Security.NonceVerification.Missing
371 }
372
373 public static function get_posted_value( $field, &$value, $args ) {
374 if ( is_array( $field ) ) {
375 $field_id = $field['id'];
376 $field_obj = FrmFieldFactory::get_field_object( $field['id'] );
377 } elseif ( is_object( $field ) ) {
378 $field_id = $field->id;
379 $field_obj = FrmFieldFactory::get_field_object( $field );
380 } elseif ( is_numeric( $field ) ) {
381 $field_id = $field;
382 $field_obj = FrmFieldFactory::get_field_object( $field );
383 } else {
384 $value = self::get_posted_meta( $field, $args );
385 FrmAppHelper::sanitize_value( 'sanitize_text_field', $value );
386 return;
387 }
388
389 $value = self::get_posted_meta( $field_id, $args );
390
391 $field_obj->sanitize_value( $value );
392 }
393
394 /**
395 * @since 4.02.04
396 */
397 private static function get_posted_meta( $field_id, $args ) {
398 if ( empty( $args['parent_field_id'] ) ) {
399 // Sanitizing is done next.
400 $value = isset( $_POST['item_meta'][ $field_id ] ) ? wp_unslash( $_POST['item_meta'][ $field_id ] ) : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing
401 } else {
402 $value = isset( $_POST['item_meta'][ $args['parent_field_id'] ][ $args['key_pointer'] ][ $field_id ] ) ? wp_unslash( $_POST['item_meta'][ $args['parent_field_id'] ][ $args['key_pointer'] ][ $field_id ] ) : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing
403 }
404 return $value;
405 }
406
407 /**
408 * Check if field has an "Other" option and if any other values are posted
409 *
410 * @since 2.0
411 *
412 * @param object $field
413 * @param array|string $value
414 * @param array $args
415 */
416 public static function maybe_set_other_validation( $field, &$value, &$args ) {
417 $args['other'] = false;
418 if ( ! $value || ! FrmAppHelper::pro_is_installed() ) {
419 return;
420 }
421
422 // Trim excess values if selection limit is exceeded for checkbox. Necessary to do here
423 // as the value set here will be used later in this class's set_posted_value() method.
424 if ( FrmField::is_checkbox( $field ) ) {
425 $field_obj = FrmFieldFactory::get_field_object( $field );
426 $field_obj->maybe_trim_excess_values( $value );
427 }
428
429 // Get other value for fields in repeating section.
430 self::set_other_repeating_vals( $field, $value, $args );
431
432 // Check if there are any posted "Other" values.
433 if ( FrmField::is_option_true( $field, 'other' ) && isset( $_POST['item_meta']['other'][ $field->id ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
434
435 // Save original value.
436 $args['temp_value'] = $value;
437 $args['other'] = true;
438
439 // Sanitizing is done next.
440 $other_vals = wp_unslash( $_POST['item_meta']['other'][ $field->id ] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing
441 FrmAppHelper::sanitize_value( 'sanitize_text_field', $other_vals );
442
443 // Set the validation value now
444 self::set_other_validation_val( $value, $other_vals, $field, $args );
445 }
446 }
447
448 /**
449 * Sets radio or checkbox value equal to "other" value if it is set - FOR REPEATING SECTIONS
450 *
451 * @since 2.0
452 *
453 * @param object $field
454 * @param array|string $value
455 * @param array $args
456 */
457 public static function set_other_repeating_vals( $field, &$value, &$args ) {
458 if ( ! $args['parent_field_id'] ) {
459 return;
460 }
461
462 // Check if there are any other posted "other" values for this field.
463 if ( FrmField::is_option_true( $field, 'other' ) && isset( $_POST['item_meta'][ $args['parent_field_id'] ][ $args['key_pointer'] ]['other'][ $field->id ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
464 // Save original value
465 $args['temp_value'] = $value;
466 $args['other'] = true;
467
468 $other_vals = wp_unslash( $_POST['item_meta'][ $args['parent_field_id'] ][ $args['key_pointer'] ]['other'][ $field->id ] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing
469 FrmAppHelper::sanitize_value( 'sanitize_text_field', $other_vals );
470
471 // Set the validation value now.
472 self::set_other_validation_val( $value, $other_vals, $field, $args );
473 }
474 }
475
476 /**
477 * Modify value used for validation
478 * This function essentially removes the "Other" radio or checkbox value from the $value being validated.
479 * It also adds any text from the free text fields to the value
480 *
481 * Needs to accommodate for times when other opt is selected, but no other free text is entered
482 *
483 * @since 2.0
484 *
485 * @param array|string $value
486 * @param array|string $other_vals (usually of posted values).
487 * @param object $field
488 * @param array $args
489 */
490 public static function set_other_validation_val( &$value, $other_vals, $field, &$args ) {
491 // Checkboxes and multi-select dropdowns.
492 if ( is_array( $value ) && $field->type === 'checkbox' ) {
493 // Combine "Other" values with checked values. "Other" values will override checked box values.
494 foreach ( $other_vals as $k => $v ) {
495 if ( isset( $value[ $k ] ) && trim( $v ) === '' ) {
496 // If the other box is checked, but doesn't have a value.
497 $value = '';
498 break;
499 }
500 }
501
502 if ( is_array( $value ) && ! empty( $value ) ) {
503 $value = array_merge( $value, $other_vals );
504 }
505 } else {
506 // Radio and dropdowns.
507 $other_key = array_filter( array_keys( $field->options ), 'is_string' );
508 $other_key = reset( $other_key );
509
510 // Multi-select dropdown.
511 if ( is_array( $value ) ) {
512 $o_key = array_search( $field->options[ $other_key ], $value );
513
514 if ( $o_key !== false ) {
515 // Modify the original value so other key will be preserved.
516 $value[ $other_key ] = $value[ $o_key ];
517
518 // By default, the array keys will be numeric for multi-select dropdowns.
519 // If going backwards and forwards between pages, the array key will match the other key.
520 if ( $o_key !== $other_key ) {
521 unset( $value[ $o_key ] );
522 }
523
524 $args['temp_value'] = $value;
525 $value[ $other_key ] = reset( $other_vals );
526 if ( FrmAppHelper::is_empty_value( $value[ $other_key ] ) ) {
527 unset( $value[ $other_key ] );
528 }
529 }
530 } elseif ( $field->options[ $other_key ] == $value ) {
531 $value = $other_vals;
532 }//end if
533 }//end if
534 }
535
536 /**
537 * Add submitted values to a string for spam checking.
538 *
539 * @param array $values
540 * @return string
541 */
542 public static function entry_array_to_string( $values ) {
543 $content = '';
544 foreach ( $values['item_meta'] as $val ) {
545 if ( $content != '' ) {
546 $content .= "\n\n";
547 }
548
549 if ( is_array( $val ) ) {
550 $val = FrmAppHelper::array_flatten( $val );
551 $val = implode( ', ', $val );
552 }
553
554 $content .= $val;
555 }
556
557 return $content;
558 }
559
560 /**
561 * Get the browser from the user agent
562 *
563 * @since 2.04
564 *
565 * @param string $u_agent
566 *
567 * @return string
568 */
569 public static function get_browser( $u_agent ) {
570 $bname = __( 'Unknown', 'formidable' );
571 $platform = $bname;
572 $ub = '';
573
574 // Get the operating system
575 if ( preg_match( '/windows|win32/i', $u_agent ) ) {
576 $platform = 'Windows';
577 } elseif ( preg_match( '/android/i', $u_agent ) ) {
578 $platform = 'Android';
579 } elseif ( preg_match( '/linux/i', $u_agent ) ) {
580 $platform = 'Linux';
581 } elseif ( preg_match( '/macintosh|mac os x/i', $u_agent ) ) {
582 $platform = 'OS X';
583 }
584
585 $agent_options = array(
586 'Chrome' => 'Google Chrome',
587 'Safari' => 'Apple Safari',
588 'Opera' => 'Opera',
589 'Netscape' => 'Netscape',
590 'Firefox' => 'Mozilla Firefox',
591 );
592
593 // Next get the name of the useragent yes separately and for good reason.
594 if ( strpos( $u_agent, 'MSIE' ) !== false && strpos( $u_agent, 'Opera' ) === false ) {
595 $bname = 'Internet Explorer';
596 $ub = 'MSIE';
597 } else {
598 foreach ( $agent_options as $agent_key => $agent_name ) {
599 if ( strpos( $u_agent, $agent_key ) !== false ) {
600 $bname = $agent_name;
601 $ub = $agent_key;
602 break;
603 }
604 }
605 }
606
607 // finally get the correct version number
608 $known = array( 'Version', $ub, 'other' );
609 $pattern = '#(?<browser>' . join( '|', $known ) . ')[/ ]+(?<version>[0-9.|a-zA-Z.]*)#';
610 // Get the matching numbers.
611 preg_match_all( $pattern, $u_agent, $matches );
612
613 // see how many we have
614 $i = count( $matches['browser'] );
615
616 if ( $i > 1 ) {
617 // We will have two since we are not using 'other' argument yet
618 // see if version is before or after the name.
619 if ( strripos( $u_agent, 'Version' ) < strripos( $u_agent, $ub ) ) {
620 $version = $matches['version'][0];
621 } else {
622 $version = $matches['version'][1];
623 }
624 } elseif ( $i === 1 ) {
625 $version = $matches['version'][0];
626 } else {
627 $version = '';
628 }
629
630 // check if we have a number
631 if ( $version == '' ) {
632 $version = '?';
633 }
634
635 return $bname . ' ' . $version . ' / ' . $platform;
636 }
637
638 /**
639 * @since 3.0
640 */
641 public static function actions_dropdown( $atts ) {
642 $id = isset( $atts['id'] ) ? $atts['id'] : FrmAppHelper::get_param( 'id', 0, 'get', 'absint' );
643 $links = self::get_action_links( $id, $atts['entry'] );
644
645 foreach ( $links as $link ) {
646 ?>
647 <div class="misc-pub-section">
648 <a href="<?php echo esc_url( $link['url'] ); ?>"
649 <?php
650 if ( isset( $link['data'] ) ) {
651 foreach ( $link['data'] as $data => $value ) {
652 echo 'data-' . esc_attr( $data ) . '="' . esc_attr( $value ) . '" ';
653 }
654 }
655 if ( isset( $link['class'] ) ) {
656 echo 'class="' . esc_attr( $link['class'] ) . '" ';
657 }
658 if ( isset( $link['id'] ) ) {
659 echo 'id="' . esc_attr( $link['id'] ) . '" ';
660 }
661 ?>
662 >
663 <?php FrmAppHelper::icon_by_class( $link['icon'], array( 'aria-hidden' => 'true' ) ); ?>
664 <span class="frm_link_label"><?php echo esc_html( $link['label'] ); ?></span>
665 </a>
666 </div>
667 <?php
668 }//end foreach
669 }
670
671 /**
672 * @since 3.0
673 */
674 private static function get_action_links( $id, $entry ) {
675 $page = FrmAppHelper::get_param( 'frm_action' );
676 $actions = array();
677
678 if ( $page !== 'show' ) {
679 $actions['frm_view'] = array(
680 'url' => admin_url( 'admin.php?page=formidable-entries&frm_action=show&id=' . $id . '&form=' . $entry->form_id ),
681 'label' => __( 'View Entry', 'formidable' ),
682 'icon' => 'frm_icon_font frm_save_icon',
683 );
684 }
685
686 if ( current_user_can( 'frm_delete_entries' ) ) {
687 $actions['frm_delete'] = array(
688 'url' => wp_nonce_url( admin_url( 'admin.php?page=formidable-entries&frm_action=destroy&id=' . $id . '&form=' . $entry->form_id ) ),
689 'label' => __( 'Delete Entry', 'formidable' ),
690 'icon' => 'frm_icon_font frm_delete_icon',
691 'data' => array(
692 'frmverify' => __( 'Permanently delete this entry?', 'formidable' ),
693 'frmverify-btn' => 'frm-button-red',
694 ),
695 );
696 }
697
698 if ( $page === 'show' ) {
699 $actions['frm_print'] = array(
700 'url' => '#',
701 'label' => __( 'Print Entry', 'formidable' ),
702 'data' => array(
703 'frmprint' => '1',
704 ),
705 'icon' => 'frm_icon_font frm_printer_icon',
706 );
707 }
708
709 $actions['frm_resend'] = array(
710 'url' => '#',
711 'label' => __( 'Resend Emails', 'formidable' ),
712 'class' => 'frm_noallow',
713 'data' => array(
714 'upgrade' => __( 'Resend Emails', 'formidable' ),
715 'medium' => 'resend-email',
716 'content' => 'entry',
717 ),
718 'icon' => 'frm_icon_font frm_email_icon',
719 );
720
721 if ( ! function_exists( 'frm_pdfs_autoloader' ) && FrmAppHelper::show_new_feature( 'pdfs' ) ) {
722 $actions['frm_download_pdf'] = array(
723 'url' => '#',
724 'label' => __( 'Download as PDF', 'formidable' ),
725 'class' => 'frm_noallow',
726 'data' => self::get_pdfs_upgrade_link_data( 'download-pdf-entry' ),
727 'icon' => 'frm_icon_font frm_download_icon',
728 );
729 }
730
731 $actions['frm_edit'] = array(
732 'url' => '#',
733 'label' => __( 'Edit Entry', 'formidable' ),
734 'class' => 'frm_noallow',
735 'data' => array(
736 'upgrade' => __( 'Entry edits', 'formidable' ),
737 'medium' => 'edit-entries',
738 'content' => 'entry',
739 ),
740 'icon' => 'frm_icon_font frm_pencil_icon',
741 );
742
743 return apply_filters( 'frm_entry_actions_dropdown', $actions, compact( 'id', 'entry' ) );
744 }
745
746 /**
747 * Gets data attributes for PDFs addon upgrade link.
748 *
749 * @param string $medium The source of the upgrade link used for analytics data.
750 * @return array
751 */
752 private static function get_pdfs_upgrade_link_data( $medium = 'pdfs' ) {
753 $data = array(
754 'oneclick' => '',
755 'requires' => '',
756 'upgrade' => __( 'Forms to PDF', 'formidable' ),
757 'medium' => $medium,
758 );
759
760 $upgrading = FrmAddonsController::install_link( 'pdfs' );
761 if ( isset( $upgrading['url'] ) ) {
762 $data['oneclick'] = json_encode( $upgrading );
763 } else {
764 $data['requires'] = FrmAddonsController::get_addon_required_plan( 28136428 );
765 }
766
767 return $data;
768 }
769
770 /**
771 * @since 5.0.15
772 *
773 * @param int|string $entry_id
774 * @return void
775 */
776 public static function maybe_render_captcha_score( $entry_id ) {
777 $query = array(
778 'item_id' => (int) $entry_id,
779 'field_id' => 0,
780 );
781 $metas_without_a_field = (array) FrmEntryMeta::getAll( $query, ' ORDER BY it.created_at DESC', '', true );
782 foreach ( $metas_without_a_field as $meta ) {
783 if ( ! empty( $meta->meta_value['captcha_score'] ) ) {
784 echo '<div class="misc-pub-section">';
785 FrmAppHelper::icon_by_class( 'frm_icon_font frm_shield_check_icon', array( 'aria-hidden' => 'true' ) );
786 echo ' ' . esc_html__( 'reCAPTCHA Score', 'formidable' ) . ': ';
787 echo '<b>' . esc_html( $meta->meta_value['captcha_score'] ) . '</b>';
788 echo '</div>';
789 return;
790 }
791 }
792 }
793
794 /**
795 * Return entry status based on is_draft column value.
796 *
797 * @since 6.5
798 *
799 * @param int $status is_draft column.
800 *
801 * @return int
802 */
803 public static function get_entry_status( $status ) {
804 $statuses = self::get_entry_statuses();
805
806 if ( array_key_exists( $status, $statuses ) ) {
807 return $status;
808 }
809
810 if ( empty( $status ) ) {
811 // If the status is empty, let's default to 0.
812 return self::SUBMITTED_ENTRY_STATUS;
813 }
814
815 // If it has a value that isn't in the array, let's default to 1. There may be old entries that don't have a value for is_draft.
816 return self::DRAFT_ENTRY_STATUS;
817 }
818
819 /**
820 * Return entry status label based on passed value.
821 *
822 * @since 6.5
823 *
824 * @param int $status is_draft column.
825 *
826 * @return string
827 */
828 public static function get_entry_status_label( $status ) {
829 $statuses = self::get_entry_statuses();
830
831 return $statuses[ self::get_entry_status( $status ) ];
832 }
833
834 /**
835 * Get all entry statuses.
836 *
837 * @since 6.5
838 * @since 6.6 function went from private to public.
839 *
840 * @return array<string>
841 */
842 public static function get_entry_statuses() {
843
844 $default_entry_statuses = array(
845 self::SUBMITTED_ENTRY_STATUS => __( 'Submitted', 'formidable' ),
846 self::DRAFT_ENTRY_STATUS => __( 'Draft', 'formidable' ),
847 );
848
849 /**
850 * Register entry status.
851 *
852 * "2" is used in abandonment-addon and reserved for "In progress".
853 * "3" is used in abandonment-addon and reserved for "Abandoned".
854 *
855 * @since 6.5
856 *
857 * @param array<string> $extended_entry_status Entry statuses.
858 */
859 $extended_entry_status = apply_filters( 'frm_entry_statuses', array() );
860
861 if ( ! is_array( $extended_entry_status ) ) {
862 _doing_it_wrong( __METHOD__, esc_html__( 'Entry status must be return in array format.', 'formidable' ), '6.5' );
863 $extended_entry_status = array();
864 }
865
866 $existing_entry_statuses = array_replace( $default_entry_statuses, $extended_entry_status );
867
868 return $existing_entry_statuses;
869 }
870
871 /**
872 * @since 6.17
873 *
874 * @return int
875 */
876 public static function get_visible_unread_inbox_count() {
877 $menu_name = FrmAppHelper::get_menu_name();
878 if ( ! in_array( $menu_name, array( 'Formidable', 'Forms' ), true ) ) {
879 return 0;
880 }
881
882 $inbox = new FrmInbox();
883 $inbox_count = count( $inbox->unread() );
884
885 if ( ! $inbox_count ) {
886 return 0;
887 }
888
889 if ( is_callable( 'FrmProSettingsController::inbox_badge' ) ) {
890 $inbox_count = FrmProSettingsController::inbox_badge( $inbox_count );
891 if ( ! $inbox_count ) {
892 return 0;
893 }
894 }
895
896 return $inbox_count;
897 }
898 }
899