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

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

864 lines 27.0 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 boolean $reset
107 * @param array $args
108 *
109 * @return string|array $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 boolean $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
217 // This is an embeded form.
218 if ( strpos( $atts['embedded_field_id'], 'form' ) === 0 ) {
219 // This is a repeating section.
220 $child_entries = FrmEntry::getAll( array( 'it.parent_item_id' => $entry->id ), '', '', true );
221 } else {
222 // Get all values for this field.
223 $child_values = isset( $entry->metas[ $atts['embedded_field_id'] ] ) ? $entry->metas[ $atts['embedded_field_id'] ] : false;
224
225 if ( $child_values ) {
226 $child_entries = FrmEntry::getAll( array( 'it.id' => (array) $child_values ) );
227 }
228 }
229
230 $field_value = array();
231
232 if ( empty( $child_entries ) ) {
233 return '';
234 }
235
236 foreach ( $child_entries as $child_entry ) {
237 $atts['item_id'] = $child_entry->id;
238 $atts['post_id'] = $child_entry->post_id;
239
240 // Fet the value for this field -- check for post values as well.
241 $entry_val = FrmProEntryMetaHelper::get_post_or_meta_value( $child_entry, $field );
242
243 if ( $entry_val || '0' === $entry_val ) {
244 // foreach entry get display_value.
245 $field_value[] = self::display_value( $entry_val, $field, $atts );
246 }
247
248 unset( $child_entry );
249 }
250
251 $sep = ', ';
252 if ( strpos( implode( ' ', (array) $field_value ), '<img' ) !== false ) {
253 $sep = '<br/>';
254 }
255 $val = implode( $sep, (array) $field_value );
256
257 return FrmAppHelper::kses( $val, 'all' );
258 }
259
260 /**
261 * Prepare the saved value for display
262 *
263 * @param array|string $value
264 * @param object $field
265 * @param array $atts
266 *
267 * @return string
268 */
269 public static function display_value( $value, $field, $atts = array() ) {
270
271 $defaults = array(
272 'type' => '',
273 'html' => false,
274 'show_filename' => true,
275 'truncate' => false,
276 'sep' => ', ',
277 'post_id' => 0,
278 'form_id' => $field->form_id,
279 'field' => $field,
280 'keepjs' => 0,
281 'return_array' => false,
282 );
283
284 $atts = wp_parse_args( $atts, $defaults );
285
286 if ( FrmField::is_image( $field ) || $field->type == 'star' ) {
287 $atts['truncate'] = false;
288 $atts['html'] = true;
289 }
290
291 $atts = apply_filters( 'frm_display_value_atts', $atts, $field, $value );
292
293 if ( ! isset( $field->field_options['post_field'] ) ) {
294 $field->field_options['post_field'] = '';
295 }
296
297 if ( ! isset( $field->field_options['custom_field'] ) ) {
298 $field->field_options['custom_field'] = '';
299 }
300
301 if ( FrmAppHelper::pro_is_installed() && $atts['post_id'] && ( $field->field_options['post_field'] || $atts['type'] == 'tag' ) ) {
302 $atts['pre_truncate'] = $atts['truncate'];
303 $atts['truncate'] = true;
304 $atts['exclude_cat'] = isset( $field->field_options['exclude_cat'] ) ? $field->field_options['exclude_cat'] : 0;
305
306 $value = FrmProEntryMetaHelper::get_post_value( $atts['post_id'], $field->field_options['post_field'], $field->field_options['custom_field'], $atts );
307 $atts['truncate'] = $atts['pre_truncate'];
308 }
309
310 if ( $value == '' ) {
311 return $value;
312 }
313
314 $unfiltered_value = $value;
315 FrmFieldsHelper::prepare_field_value( $unfiltered_value, $field->type );
316
317 $value = apply_filters( 'frm_display_value_custom', $unfiltered_value, $field, $atts );
318 $value = apply_filters( 'frm_display_' . $field->type . '_value_custom', $value, compact( 'field', 'atts' ) );
319
320 if ( $value == $unfiltered_value ) {
321 $value = FrmFieldsHelper::get_unfiltered_display_value( compact( 'value', 'field', 'atts' ) );
322 }
323
324 if ( $atts['truncate'] && $atts['type'] != 'url' ) {
325 $value = FrmAppHelper::truncate( $value, 50 );
326 }
327
328 if ( ! $atts['keepjs'] && ! is_array( $value ) ) {
329 $value = FrmAppHelper::kses( $value, 'all' );
330 }
331
332 return apply_filters( 'frm_display_value', $value, $field, $atts );
333 }
334
335 public static function set_posted_value( $field, $value, $args ) {
336 // If validating a field with "other" opt, set back to prev value now.
337 if ( isset( $args['other'] ) && $args['other'] ) {
338 $value = $args['temp_value'];
339 }
340 if ( empty( $args['parent_field_id'] ) ) {
341 $_POST['item_meta'][ $field->id ] = $value;
342 } else {
343 self::set_parent_field_posted_value( $field, $value, $args );
344 }
345 }
346
347 /**
348 * Init arrays if necessary, else we get fatal error.
349 *
350 * @since 4.01
351 */
352 private static function set_parent_field_posted_value( $field, $value, $args ) {
353 if ( isset( $_POST['item_meta'][ $args['parent_field_id'] ] ) && is_array( $_POST['item_meta'][ $args['parent_field_id'] ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
354 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
355 $_POST['item_meta'][ $args['parent_field_id'] ][ $args['key_pointer'] ] = array(); // phpcs:ignore WordPress.Security.NonceVerification.Missing
356 }
357 } else {
358 // All of the section was probably removed.
359 $_POST['item_meta'][ $args['parent_field_id'] ] = array(); // phpcs:ignore WordPress.Security.NonceVerification.Missing
360 $_POST['item_meta'][ $args['parent_field_id'] ][ $args['key_pointer'] ] = array(); // phpcs:ignore WordPress.Security.NonceVerification.Missing
361 }
362
363 $_POST['item_meta'][ $args['parent_field_id'] ][ $args['key_pointer'] ][ $field->id ] = $value; // phpcs:ignore WordPress.Security.NonceVerification.Missing
364 }
365
366 public static function get_posted_value( $field, &$value, $args ) {
367 if ( is_array( $field ) ) {
368 $field_id = $field['id'];
369 $field_obj = FrmFieldFactory::get_field_object( $field['id'] );
370 } elseif ( is_object( $field ) ) {
371 $field_id = $field->id;
372 $field_obj = FrmFieldFactory::get_field_object( $field );
373 } elseif ( is_numeric( $field ) ) {
374 $field_id = $field;
375 $field_obj = FrmFieldFactory::get_field_object( $field );
376 } else {
377 $value = self::get_posted_meta( $field, $args );
378 FrmAppHelper::sanitize_value( 'sanitize_text_field', $value );
379 return;
380 }
381
382 $value = self::get_posted_meta( $field_id, $args );
383
384 $field_obj->sanitize_value( $value );
385 }
386
387 /**
388 * @since 4.02.04
389 */
390 private static function get_posted_meta( $field_id, $args ) {
391 if ( empty( $args['parent_field_id'] ) ) {
392 // Sanitizing is done next.
393 $value = isset( $_POST['item_meta'][ $field_id ] ) ? wp_unslash( $_POST['item_meta'][ $field_id ] ) : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing
394 } else {
395 $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
396 }
397 return $value;
398 }
399
400 /**
401 * Check if field has an "Other" option and if any other values are posted
402 *
403 * @since 2.0
404 *
405 * @param object $field
406 * @param string|array $value
407 * @param array $args
408 */
409 public static function maybe_set_other_validation( $field, &$value, &$args ) {
410 $args['other'] = false;
411 if ( ! $value || ! FrmAppHelper::pro_is_installed() ) {
412 return;
413 }
414
415 // Trim excess values if selection limit is exceeded for checkbox. Necessary to do here
416 // as the value set here will be used later in this class's set_posted_value() method.
417 if ( FrmField::is_checkbox( $field ) ) {
418 $field_obj = FrmFieldFactory::get_field_object( $field );
419 $field_obj->maybe_trim_excess_values( $value );
420 }
421
422 // Get other value for fields in repeating section.
423 self::set_other_repeating_vals( $field, $value, $args );
424
425 // Check if there are any posted "Other" values.
426 if ( FrmField::is_option_true( $field, 'other' ) && isset( $_POST['item_meta']['other'][ $field->id ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
427
428 // Save original value.
429 $args['temp_value'] = $value;
430 $args['other'] = true;
431
432 // Sanitizing is done next.
433 $other_vals = wp_unslash( $_POST['item_meta']['other'][ $field->id ] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing
434 FrmAppHelper::sanitize_value( 'sanitize_text_field', $other_vals );
435
436 // Set the validation value now
437 self::set_other_validation_val( $value, $other_vals, $field, $args );
438 }
439 }
440
441 /**
442 * Sets radio or checkbox value equal to "other" value if it is set - FOR REPEATING SECTIONS
443 *
444 * @since 2.0
445 *
446 * @param object $field
447 * @param string|array $value
448 * @param array $args
449 */
450 public static function set_other_repeating_vals( $field, &$value, &$args ) {
451 if ( ! $args['parent_field_id'] ) {
452 return;
453 }
454
455 // Check if there are any other posted "other" values for this field.
456 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
457 // Save original value
458 $args['temp_value'] = $value;
459 $args['other'] = true;
460
461 $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
462 FrmAppHelper::sanitize_value( 'sanitize_text_field', $other_vals );
463
464 // Set the validation value now.
465 self::set_other_validation_val( $value, $other_vals, $field, $args );
466 }
467 }
468
469 /**
470 * Modify value used for validation
471 * This function essentially removes the "Other" radio or checkbox value from the $value being validated.
472 * It also adds any text from the free text fields to the value
473 *
474 * Needs to accommodate for times when other opt is selected, but no other free text is entered
475 *
476 * @since 2.0
477 *
478 * @param string|array $value
479 * @param string|array $other_vals (usually of posted values).
480 * @param object $field
481 * @param array $args
482 */
483 public static function set_other_validation_val( &$value, $other_vals, $field, &$args ) {
484 // Checkboxes and multi-select dropdowns.
485 if ( is_array( $value ) && $field->type === 'checkbox' ) {
486 // Combine "Other" values with checked values. "Other" values will override checked box values.
487 foreach ( $other_vals as $k => $v ) {
488 if ( isset( $value[ $k ] ) && trim( $v ) === '' ) {
489 // If the other box is checked, but doesn't have a value.
490 $value = '';
491 break;
492 }
493 }
494
495 if ( is_array( $value ) && ! empty( $value ) ) {
496 $value = array_merge( $value, $other_vals );
497 }
498 } else {
499 // Radio and dropdowns.
500 $other_key = array_filter( array_keys( $field->options ), 'is_string' );
501 $other_key = reset( $other_key );
502
503 // Multi-select dropdown.
504 if ( is_array( $value ) ) {
505 $o_key = array_search( $field->options[ $other_key ], $value );
506
507 if ( $o_key !== false ) {
508 // Modify the original value so other key will be preserved.
509 $value[ $other_key ] = $value[ $o_key ];
510
511 // By default, the array keys will be numeric for multi-select dropdowns.
512 // If going backwards and forwards between pages, the array key will match the other key.
513 if ( $o_key !== $other_key ) {
514 unset( $value[ $o_key ] );
515 }
516
517 $args['temp_value'] = $value;
518 $value[ $other_key ] = reset( $other_vals );
519 if ( FrmAppHelper::is_empty_value( $value[ $other_key ] ) ) {
520 unset( $value[ $other_key ] );
521 }
522 }
523 } elseif ( $field->options[ $other_key ] == $value ) {
524 $value = $other_vals;
525 }//end if
526 }//end if
527 }
528
529 /**
530 * Add submitted values to a string for spam checking.
531 *
532 * @param array $values
533 * @return string
534 */
535 public static function entry_array_to_string( $values ) {
536 $content = '';
537 foreach ( $values['item_meta'] as $val ) {
538 if ( $content != '' ) {
539 $content .= "\n\n";
540 }
541
542 if ( is_array( $val ) ) {
543 $val = FrmAppHelper::array_flatten( $val );
544 $val = implode( ', ', $val );
545 }
546
547 $content .= $val;
548 }
549
550 return $content;
551 }
552
553 /**
554 * Get the browser from the user agent
555 *
556 * @since 2.04
557 *
558 * @param string $u_agent
559 *
560 * @return string
561 */
562 public static function get_browser( $u_agent ) {
563 $bname = __( 'Unknown', 'formidable' );
564 $platform = __( 'Unknown', 'formidable' );
565 $ub = '';
566
567 // Get the operating system
568 if ( preg_match( '/windows|win32/i', $u_agent ) ) {
569 $platform = 'Windows';
570 } elseif ( preg_match( '/android/i', $u_agent ) ) {
571 $platform = 'Android';
572 } elseif ( preg_match( '/linux/i', $u_agent ) ) {
573 $platform = 'Linux';
574 } elseif ( preg_match( '/macintosh|mac os x/i', $u_agent ) ) {
575 $platform = 'OS X';
576 }
577
578 $agent_options = array(
579 'Chrome' => 'Google Chrome',
580 'Safari' => 'Apple Safari',
581 'Opera' => 'Opera',
582 'Netscape' => 'Netscape',
583 'Firefox' => 'Mozilla Firefox',
584 );
585
586 // Next get the name of the useragent yes seperately and for good reason
587 if ( strpos( $u_agent, 'MSIE' ) !== false && strpos( $u_agent, 'Opera' ) === false ) {
588 $bname = 'Internet Explorer';
589 $ub = 'MSIE';
590 } else {
591 foreach ( $agent_options as $agent_key => $agent_name ) {
592 if ( strpos( $u_agent, $agent_key ) !== false ) {
593 $bname = $agent_name;
594 $ub = $agent_key;
595 break;
596 }
597 }
598 }
599
600 // finally get the correct version number
601 $known = array( 'Version', $ub, 'other' );
602 $pattern = '#(?<browser>' . join( '|', $known ) . ')[/ ]+(?<version>[0-9.|a-zA-Z.]*)#';
603 // Get the matching numbers.
604 preg_match_all( $pattern, $u_agent, $matches );
605
606 // see how many we have
607 $i = count( $matches['browser'] );
608
609 if ( $i > 1 ) {
610 // We will have two since we are not using 'other' argument yet
611 // see if version is before or after the name.
612 if ( strripos( $u_agent, 'Version' ) < strripos( $u_agent, $ub ) ) {
613 $version = $matches['version'][0];
614 } else {
615 $version = $matches['version'][1];
616 }
617 } elseif ( $i === 1 ) {
618 $version = $matches['version'][0];
619 } else {
620 $version = '';
621 }
622
623 // check if we have a number
624 if ( $version == '' ) {
625 $version = '?';
626 }
627
628 return $bname . ' ' . $version . ' / ' . $platform;
629 }
630
631 /**
632 * @since 3.0
633 */
634 public static function actions_dropdown( $atts ) {
635 $id = isset( $atts['id'] ) ? $atts['id'] : FrmAppHelper::get_param( 'id', 0, 'get', 'absint' );
636 $links = self::get_action_links( $id, $atts['entry'] );
637
638 foreach ( $links as $link ) {
639 ?>
640 <div class="misc-pub-section">
641 <a href="<?php echo esc_url( $link['url'] ); ?>"
642 <?php
643 if ( isset( $link['data'] ) ) {
644 foreach ( $link['data'] as $data => $value ) {
645 echo 'data-' . esc_attr( $data ) . '="' . esc_attr( $value ) . '" ';
646 }
647 }
648 if ( isset( $link['class'] ) ) {
649 echo 'class="' . esc_attr( $link['class'] ) . '" ';
650 }
651 if ( isset( $link['id'] ) ) {
652 echo 'id="' . esc_attr( $link['id'] ) . '" ';
653 }
654 ?>
655 >
656 <?php FrmAppHelper::icon_by_class( $link['icon'], array( 'aria-hidden' => 'true' ) ); ?>
657 <span class="frm_link_label"><?php echo esc_html( $link['label'] ); ?></span>
658 </a>
659 </div>
660 <?php
661 }//end foreach
662 }
663
664 /**
665 * @since 3.0
666 */
667 private static function get_action_links( $id, $entry ) {
668 $page = FrmAppHelper::get_param( 'frm_action' );
669 $actions = array();
670
671 if ( $page != 'show' ) {
672 $actions['frm_view'] = array(
673 'url' => admin_url( 'admin.php?page=formidable-entries&frm_action=show&id=' . $id . '&form=' . $entry->form_id ),
674 'label' => __( 'View Entry', 'formidable' ),
675 'icon' => 'frm_icon_font frm_save_icon',
676 );
677 }
678
679 if ( current_user_can( 'frm_delete_entries' ) ) {
680 $actions['frm_delete'] = array(
681 'url' => wp_nonce_url( admin_url( 'admin.php?page=formidable-entries&frm_action=destroy&id=' . $id . '&form=' . $entry->form_id ) ),
682 'label' => __( 'Delete Entry', 'formidable' ),
683 'icon' => 'frm_icon_font frm_delete_icon',
684 'data' => array(
685 'frmverify' => __( 'Delete this form entry?', 'formidable' ),
686 ),
687 );
688 }
689
690 if ( $page == 'show' ) {
691 $actions['frm_print'] = array(
692 'url' => '#',
693 'label' => __( 'Print Entry', 'formidable' ),
694 'data' => array(
695 'frmprint' => '1',
696 ),
697 'icon' => 'frm_icon_font frm_printer_icon',
698 );
699 }
700
701 $actions['frm_resend'] = array(
702 'url' => '#',
703 'label' => __( 'Resend Emails', 'formidable' ),
704 'class' => 'frm_noallow',
705 'data' => array(
706 'upgrade' => __( 'Resend Emails', 'formidable' ),
707 'medium' => 'resend-email',
708 'content' => 'entry',
709 ),
710 'icon' => 'frm_icon_font frm_email_icon',
711 );
712
713 if ( ! function_exists( 'frm_pdfs_autoloader' ) && FrmAppHelper::show_new_feature( 'pdfs' ) ) {
714 $actions['frm_download_pdf'] = array(
715 'url' => '#',
716 'label' => __( 'Download as PDF', 'formidable' ),
717 'class' => 'frm_noallow',
718 'data' => self::get_pdfs_upgrade_link_data( 'download-pdf-entry' ),
719 'icon' => 'frm_icon_font frm_download_icon',
720 );
721 }
722
723 $actions['frm_edit'] = array(
724 'url' => '#',
725 'label' => __( 'Edit Entry', 'formidable' ),
726 'class' => 'frm_noallow',
727 'data' => array(
728 'upgrade' => __( 'Entry edits', 'formidable' ),
729 'medium' => 'edit-entries',
730 'content' => 'entry',
731 ),
732 'icon' => 'frm_icon_font frm_pencil_icon',
733 );
734
735 return apply_filters( 'frm_entry_actions_dropdown', $actions, compact( 'id', 'entry' ) );
736 }
737
738 /**
739 * Gets data attributes for PDFs addon upgrade link.
740 *
741 * @param string $medium The source of the upgrade link used for analytics data.
742 * @return array
743 */
744 private static function get_pdfs_upgrade_link_data( $medium = 'pdfs' ) {
745 $data = array(
746 'oneclick' => '',
747 'requires' => '',
748 'upgrade' => __( 'Forms to PDF', 'formidable' ),
749 'medium' => $medium,
750 );
751
752 $upgrading = FrmAddonsController::install_link( 'pdfs' );
753 if ( isset( $upgrading['url'] ) ) {
754 $data['oneclick'] = json_encode( $upgrading );
755 } else {
756 $data['requires'] = FrmAddonsController::get_addon_required_plan( 28136428 );
757 }
758
759 return $data;
760 }
761
762 /**
763 * @since 5.0.15
764 *
765 * @param string|int $entry_id
766 * @return void
767 */
768 public static function maybe_render_captcha_score( $entry_id ) {
769 $query = array(
770 'item_id' => (int) $entry_id,
771 'field_id' => 0,
772 );
773 $metas_without_a_field = (array) FrmEntryMeta::getAll( $query, ' ORDER BY it.created_at DESC', '', true );
774 foreach ( $metas_without_a_field as $meta ) {
775 if ( ! empty( $meta->meta_value['captcha_score'] ) ) {
776 echo '<div class="misc-pub-section">';
777 FrmAppHelper::icon_by_class( 'frm_icon_font frm_shield_check_icon', array( 'aria-hidden' => 'true' ) );
778 echo ' ' . esc_html__( 'reCAPTCHA Score', 'formidable' ) . ': ';
779 echo '<b>' . esc_html( $meta->meta_value['captcha_score'] ) . '</b>';
780 echo '</div>';
781 return;
782 }
783 }
784 }
785
786 /**
787 * Return entry status based on is_draft column value.
788 *
789 * @since 6.5
790 *
791 * @param int $status is_draft column.
792 *
793 * @return int
794 */
795 public static function get_entry_status( $status ) {
796 $statuses = self::get_entry_statuses();
797
798 if ( array_key_exists( $status, $statuses ) ) {
799 return $status;
800 }
801
802 if ( empty( $status ) ) {
803 // If the status is empty, let's default to 0.
804 return self::SUBMITTED_ENTRY_STATUS;
805 }
806
807 // 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.
808 return self::DRAFT_ENTRY_STATUS;
809 }
810
811 /**
812 * Return entry status label based on passed value.
813 *
814 * @since 6.5
815 *
816 * @param int $status is_draft column.
817 *
818 * @return string
819 */
820 public static function get_entry_status_label( $status ) {
821 $statuses = self::get_entry_statuses();
822
823 return $statuses[ self::get_entry_status( $status ) ];
824 }
825
826 /**
827 * Get all entry statuses.
828 *
829 * @since 6.5
830 * @since 6.6 function went from private to public.
831 *
832 * @return array<string>
833 */
834 public static function get_entry_statuses() {
835
836 $default_entry_statuses = array(
837 self::SUBMITTED_ENTRY_STATUS => __( 'Submitted', 'formidable' ),
838 self::DRAFT_ENTRY_STATUS => __( 'Draft', 'formidable' ),
839 );
840
841 /**
842 * Register entry status.
843 *
844 * "2" is used in abandonment-addon and reserved for "In progress".
845 * "3" is used in abandonment-addon and reserved for "Abandoned".
846 *
847 * @since 6.5
848 *
849 * @param array<string> $extended_entry_status Entry statuses.
850 */
851 $extended_entry_status = apply_filters( 'frm_entry_statuses', array() );
852
853 if ( ! is_array( $extended_entry_status ) ) {
854 _doing_it_wrong( __METHOD__, esc_html__( 'Entry status must be return in array format.', 'formidable' ), '6.5' );
855 $extended_entry_status = array();
856 }
857
858 $existing_entry_statuses = array_replace( $default_entry_statuses, $extended_entry_status );
859
860 return $existing_entry_statuses;
861 }
862
863 }
864