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

898 lines 27.7 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' => __( 'Delete this form entry?', 'formidable' ),
693 ),
694 );
695 }
696
697 if ( $page === 'show' ) {
698 $actions['frm_print'] = array(
699 'url' => '#',
700 'label' => __( 'Print Entry', 'formidable' ),
701 'data' => array(
702 'frmprint' => '1',
703 ),
704 'icon' => 'frm_icon_font frm_printer_icon',
705 );
706 }
707
708 $actions['frm_resend'] = array(
709 'url' => '#',
710 'label' => __( 'Resend Emails', 'formidable' ),
711 'class' => 'frm_noallow',
712 'data' => array(
713 'upgrade' => __( 'Resend Emails', 'formidable' ),
714 'medium' => 'resend-email',
715 'content' => 'entry',
716 ),
717 'icon' => 'frm_icon_font frm_email_icon',
718 );
719
720 if ( ! function_exists( 'frm_pdfs_autoloader' ) && FrmAppHelper::show_new_feature( 'pdfs' ) ) {
721 $actions['frm_download_pdf'] = array(
722 'url' => '#',
723 'label' => __( 'Download as PDF', 'formidable' ),
724 'class' => 'frm_noallow',
725 'data' => self::get_pdfs_upgrade_link_data( 'download-pdf-entry' ),
726 'icon' => 'frm_icon_font frm_download_icon',
727 );
728 }
729
730 $actions['frm_edit'] = array(
731 'url' => '#',
732 'label' => __( 'Edit Entry', 'formidable' ),
733 'class' => 'frm_noallow',
734 'data' => array(
735 'upgrade' => __( 'Entry edits', 'formidable' ),
736 'medium' => 'edit-entries',
737 'content' => 'entry',
738 ),
739 'icon' => 'frm_icon_font frm_pencil_icon',
740 );
741
742 return apply_filters( 'frm_entry_actions_dropdown', $actions, compact( 'id', 'entry' ) );
743 }
744
745 /**
746 * Gets data attributes for PDFs addon upgrade link.
747 *
748 * @param string $medium The source of the upgrade link used for analytics data.
749 * @return array
750 */
751 private static function get_pdfs_upgrade_link_data( $medium = 'pdfs' ) {
752 $data = array(
753 'oneclick' => '',
754 'requires' => '',
755 'upgrade' => __( 'Forms to PDF', 'formidable' ),
756 'medium' => $medium,
757 );
758
759 $upgrading = FrmAddonsController::install_link( 'pdfs' );
760 if ( isset( $upgrading['url'] ) ) {
761 $data['oneclick'] = json_encode( $upgrading );
762 } else {
763 $data['requires'] = FrmAddonsController::get_addon_required_plan( 28136428 );
764 }
765
766 return $data;
767 }
768
769 /**
770 * @since 5.0.15
771 *
772 * @param int|string $entry_id
773 * @return void
774 */
775 public static function maybe_render_captcha_score( $entry_id ) {
776 $query = array(
777 'item_id' => (int) $entry_id,
778 'field_id' => 0,
779 );
780 $metas_without_a_field = (array) FrmEntryMeta::getAll( $query, ' ORDER BY it.created_at DESC', '', true );
781 foreach ( $metas_without_a_field as $meta ) {
782 if ( ! empty( $meta->meta_value['captcha_score'] ) ) {
783 echo '<div class="misc-pub-section">';
784 FrmAppHelper::icon_by_class( 'frm_icon_font frm_shield_check_icon', array( 'aria-hidden' => 'true' ) );
785 echo ' ' . esc_html__( 'reCAPTCHA Score', 'formidable' ) . ': ';
786 echo '<b>' . esc_html( $meta->meta_value['captcha_score'] ) . '</b>';
787 echo '</div>';
788 return;
789 }
790 }
791 }
792
793 /**
794 * Return entry status based on is_draft column value.
795 *
796 * @since 6.5
797 *
798 * @param int $status is_draft column.
799 *
800 * @return int
801 */
802 public static function get_entry_status( $status ) {
803 $statuses = self::get_entry_statuses();
804
805 if ( array_key_exists( $status, $statuses ) ) {
806 return $status;
807 }
808
809 if ( empty( $status ) ) {
810 // If the status is empty, let's default to 0.
811 return self::SUBMITTED_ENTRY_STATUS;
812 }
813
814 // 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.
815 return self::DRAFT_ENTRY_STATUS;
816 }
817
818 /**
819 * Return entry status label based on passed value.
820 *
821 * @since 6.5
822 *
823 * @param int $status is_draft column.
824 *
825 * @return string
826 */
827 public static function get_entry_status_label( $status ) {
828 $statuses = self::get_entry_statuses();
829
830 return $statuses[ self::get_entry_status( $status ) ];
831 }
832
833 /**
834 * Get all entry statuses.
835 *
836 * @since 6.5
837 * @since 6.6 function went from private to public.
838 *
839 * @return array<string>
840 */
841 public static function get_entry_statuses() {
842
843 $default_entry_statuses = array(
844 self::SUBMITTED_ENTRY_STATUS => __( 'Submitted', 'formidable' ),
845 self::DRAFT_ENTRY_STATUS => __( 'Draft', 'formidable' ),
846 );
847
848 /**
849 * Register entry status.
850 *
851 * "2" is used in abandonment-addon and reserved for "In progress".
852 * "3" is used in abandonment-addon and reserved for "Abandoned".
853 *
854 * @since 6.5
855 *
856 * @param array<string> $extended_entry_status Entry statuses.
857 */
858 $extended_entry_status = apply_filters( 'frm_entry_statuses', array() );
859
860 if ( ! is_array( $extended_entry_status ) ) {
861 _doing_it_wrong( __METHOD__, esc_html__( 'Entry status must be return in array format.', 'formidable' ), '6.5' );
862 $extended_entry_status = array();
863 }
864
865 $existing_entry_statuses = array_replace( $default_entry_statuses, $extended_entry_status );
866
867 return $existing_entry_statuses;
868 }
869
870 /**
871 * @since 6.17
872 *
873 * @return int
874 */
875 public static function get_visible_unread_inbox_count() {
876 $menu_name = FrmAppHelper::get_menu_name();
877 if ( ! in_array( $menu_name, array( 'Formidable', 'Forms' ), true ) ) {
878 return 0;
879 }
880
881 $inbox = new FrmInbox();
882 $inbox_count = count( $inbox->unread() );
883
884 if ( ! $inbox_count ) {
885 return 0;
886 }
887
888 if ( is_callable( 'FrmProSettingsController::inbox_badge' ) ) {
889 $inbox_count = FrmProSettingsController::inbox_badge( $inbox_count );
890 if ( ! $inbox_count ) {
891 return 0;
892 }
893 }
894
895 return $inbox_count;
896 }
897 }
898