PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 6.25.1
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v6.25.1
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 / controllers / FrmEntriesController.php

FrmEntriesController.php in Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More 6.25.1, at classes/controllers/FrmEntriesController.php

816 lines 23.6 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 FrmEntriesController {
7
8 public static function menu() {
9 FrmAppHelper::force_capability( 'frm_view_entries' );
10
11 add_submenu_page( 'formidable', 'Formidable | ' . __( 'Entries', 'formidable' ), __( 'Entries', 'formidable' ), 'frm_view_entries', 'formidable-entries', 'FrmEntriesController::route' );
12
13 $views_installed = is_callable( 'FrmProAppHelper::views_is_installed' ) && FrmProAppHelper::views_is_installed();
14 if ( ! $views_installed ) {
15 add_submenu_page( 'formidable', 'Formidable | ' . __( 'Views', 'formidable' ), __( 'Views', 'formidable' ), 'frm_view_entries', 'formidable-views', 'FrmFormsController::no_views' );
16 self::maybe_redirect_to_views_upsell();
17 } else {
18 self::maybe_redirect_to_views_index();
19 }
20
21 if ( FrmAppHelper::is_admin_page( 'formidable-entries' ) ) {
22 self::load_manage_entries_hooks();
23 }
24 }
25
26 /**
27 * This function is called when views is installed.
28 * The Views add-on uses a different URL for the Views tab than the upsell page.
29 * If the user is on the upsell page, instead of showing a permission error on reload,
30 * redirect to the views index page.
31 *
32 * @since 6.14.1
33 *
34 * @return void
35 */
36 private static function maybe_redirect_to_views_index() {
37 if ( ! FrmAppHelper::is_admin_page( 'formidable-views' ) ) {
38 return;
39 }
40
41 $query_args = array(
42 'post_type' => 'frm_display',
43 );
44 $query_args = self::add_url_params_to_views_redirect_query_args( $query_args );
45
46 wp_safe_redirect( add_query_arg( $query_args, admin_url( 'edit.php' ) ) );
47 die();
48 }
49
50 /**
51 * This function is called when views is inactive.
52 * A user may deactivate views but then try to reload the views index.
53 * Instead of showing a permission error, redirect to the views upsell page.
54 *
55 * @since 6.14.1
56 *
57 * @return void
58 */
59 private static function maybe_redirect_to_views_upsell() {
60 global $pagenow;
61 if ( 'edit.php' !== $pagenow || 'frm_display' !== FrmAppHelper::simple_get( 'post_type' ) ) {
62 return;
63 }
64
65 $query_args = array(
66 'page' => 'formidable-views',
67 );
68 $query_args = self::add_url_params_to_views_redirect_query_args( $query_args );
69
70 wp_safe_redirect( add_query_arg( $query_args, admin_url( 'admin.php' ) ) );
71 die();
72 }
73
74 /**
75 * @since 6.14.1
76 *
77 * @param array $query_args
78 * @return array
79 */
80 private static function add_url_params_to_views_redirect_query_args( $query_args ) {
81 $query_args['show_nav'] = FrmAppHelper::simple_get( 'show_nav', 'absint', 0 );
82
83 $form_id = FrmAppHelper::simple_get( 'form', 'absint', 0 );
84 if ( $form_id ) {
85 $query_args['form'] = $form_id;
86 }
87
88 return $query_args;
89 }
90
91 /**
92 * @since 2.05.07
93 */
94 private static function load_manage_entries_hooks() {
95 if ( ! in_array( FrmAppHelper::simple_get( 'frm_action', 'sanitize_title' ), array( 'edit', 'show', 'new', 'duplicate' ), true ) ) {
96 $menu_name = FrmAppHelper::get_menu_name();
97 $base = self::base_column_key( $menu_name );
98
99 add_filter( 'manage_' . $base . '_columns', 'FrmEntriesController::manage_columns' );
100 add_filter( 'get_user_option_' . self::hidden_column_key( $menu_name ), 'FrmEntriesController::hidden_columns' );
101 add_filter( 'manage_' . $base . '_sortable_columns', 'FrmEntriesController::sortable_columns' );
102 } else {
103 add_filter( 'screen_options_show_screen', self::class . '::remove_screen_options', 10, 2 );
104 }
105 }
106
107 /**
108 * Display in Back End.
109 */
110 public static function route() {
111 $action = FrmAppHelper::get_param( 'frm_action', '', 'get', 'sanitize_title' );
112 FrmAppHelper::include_svg();
113
114 switch ( $action ) {
115 case 'show':
116 case 'destroy':
117 return self::$action();
118
119 default:
120 do_action( 'frm_entry_action_route', $action );
121 if ( apply_filters( 'frm_entry_stop_action_route', false, $action ) ) {
122 return;
123 }
124
125 return self::display_list();
126 }
127 }
128
129 /**
130 * Prevent the "screen options" tab from showing when
131 * editing or creating an entry
132 *
133 * @since 3.0
134 */
135 public static function remove_screen_options( $show_screen, $screen ) {
136 $menu_name = sanitize_title( FrmAppHelper::get_menu_name() );
137 $unread_count = FrmEntriesHelper::get_visible_unread_inbox_count();
138
139 if ( $screen->id === $menu_name . ( $unread_count ? '-' . $unread_count : '' ) . '_page_formidable-entries' ) {
140 $show_screen = false;
141 }
142
143 return $show_screen;
144 }
145
146 public static function manage_columns( $columns ) {
147 global $frm_vars;
148 $form_id = FrmForm::get_current_form_id();
149
150 $columns[ $form_id . '_id' ] = 'ID';
151 $columns[ $form_id . '_item_key' ] = esc_html__( 'Entry Key', 'formidable' );
152
153 if ( $form_id ) {
154 self::get_columns_for_form( $form_id, $columns );
155 } else {
156 $columns[ $form_id . '_form_id' ] = esc_html__( 'Form', 'formidable' );
157 $columns[ $form_id . '_name' ] = esc_html__( 'Entry Name', 'formidable' );
158 $columns[ $form_id . '_user_id' ] = esc_html__( 'Created By', 'formidable' );
159 }
160
161 $columns[ $form_id . '_is_draft' ] = esc_html__( 'Entry Status', 'formidable' );
162 $columns[ $form_id . '_created_at' ] = __( 'Entry creation date', 'formidable' );
163 $columns[ $form_id . '_updated_at' ] = __( 'Entry update date', 'formidable' );
164 self::maybe_add_ip_col( $form_id, $columns );
165
166 $frm_vars['cols'] = $columns;
167
168 $action = FrmAppHelper::simple_get( 'frm_action', 'sanitize_title' );
169 if ( FrmAppHelper::is_admin_page( 'formidable-entries' ) && in_array( $action, array( '', 'list', 'destroy' ) ) ) {
170 add_screen_option(
171 'per_page',
172 array(
173 'label' => esc_html__( 'Entries', 'formidable' ),
174 'default' => 20,
175 'option' => 'formidable_page_formidable_entries_per_page',
176 )
177 );
178 }
179
180 return $columns;
181 }
182
183 private static function get_columns_for_form( $form_id, &$columns ) {
184 $form_cols = FrmField::get_all_for_form( $form_id, '', 'include' );
185
186 /**
187 * Allows changing fields in the Entries list table heading.
188 *
189 * @since 5.0.04
190 *
191 * @param array $fields Array of fields.
192 * @param array $args The arguments. Contains `form_id`.
193 */
194 $form_cols = apply_filters( 'frm_fields_in_entries_list_table', $form_cols, compact( 'form_id' ) );
195
196 foreach ( $form_cols as $form_col ) {
197 if ( FrmField::is_no_save_field( $form_col->type ) ) {
198 continue;
199 }
200
201 $has_child_fields = $form_col->type === 'form' && ! empty( $form_col->field_options['form_select'] );
202 if ( $has_child_fields ) {
203 self::add_subform_cols( $form_col, $form_id, $columns );
204 } else {
205 self::add_field_cols( $form_col, $form_id, $columns );
206 }
207 }
208 }
209
210 /**
211 * @since 3.01
212 */
213 private static function add_subform_cols( $field, $form_id, &$columns ) {
214 $sub_form_cols = FrmField::get_all_for_form( $field->field_options['form_select'] );
215 if ( empty( $sub_form_cols ) ) {
216 return;
217 }
218
219 foreach ( $sub_form_cols as $k => $sub_form_col ) {
220 if ( FrmField::is_no_save_field( $sub_form_col->type ) ) {
221 unset( $sub_form_cols[ $k ] );
222 continue;
223 }
224 $columns[ $form_id . '_' . $sub_form_col->field_key . '-_-' . $field->id ] = FrmAppHelper::truncate( $sub_form_col->name, 35 );
225 unset( $sub_form_col );
226 }
227 }
228
229 /**
230 * @since 3.01
231 */
232 private static function add_field_cols( $field, $form_id, &$columns ) {
233 $col_id = $field->field_key;
234 if ( $field->form_id != $form_id ) {
235 $col_id .= '-_-form' . $field->form_id;
236 }
237
238 $has_separate_value = ! FrmField::is_option_empty( $field, 'separate_value' );
239 $is_post_status = FrmField::is_option_true( $field, 'post_field' ) && $field->field_options['post_field'] === 'post_status';
240 $include_column_for_sep_val = $has_separate_value && ! $is_post_status;
241 if ( $include_column_for_sep_val ) {
242 $columns[ $form_id . '_frmsep_' . $col_id ] = self::maybe_format_field_name_for_column_title( $field, $include_column_for_sep_val );
243 }
244
245 $columns[ $form_id . '_' . $col_id ] = self::maybe_format_field_name_for_column_title( $field, $include_column_for_sep_val, false );
246 }
247
248 /**
249 * Appends "(Value)" or "(Label)" to the field name if it's an option field that has a separate value/label.
250 *
251 * @since 6.25.1
252 *
253 * @param object $field
254 * @param bool $include_column_for_sep_val
255 * @param bool $is_value
256 *
257 * @return string
258 */
259 private static function maybe_format_field_name_for_column_title( $field, $include_column_for_sep_val, $is_value = true ) {
260 $field_name = FrmAppHelper::truncate( $field->name, 35 );
261 if ( ! $include_column_for_sep_val || ! in_array( $field->type, array( 'select', 'radio', 'checkbox' ), true ) ) {
262 return $field_name;
263 }
264 $append_text = $is_value ? esc_html__( 'value', 'formidable' ) : esc_html__( 'label', 'formidable' );
265
266 return sprintf( '%s (%s)', $field_name, $append_text );
267 }
268
269 private static function maybe_add_ip_col( $form_id, &$columns ) {
270 if ( FrmAppHelper::ips_saved() ) {
271 $columns[ $form_id . '_ip' ] = 'IP';
272 }
273 }
274
275 public static function check_hidden_cols( $check, $object_id, $meta_key, $meta_value, $prev_value ) {
276 $this_page_name = self::hidden_column_key();
277 if ( $meta_key != $this_page_name || $meta_value == $prev_value ) {
278 return $check;
279 }
280
281 if ( empty( $prev_value ) ) {
282 $prev_value = get_metadata( 'user', $object_id, $meta_key, true );
283 }
284
285 global $frm_vars;
286 // Add a check so we don't create a loop.
287 $frm_vars['prev_hidden_cols'] = ! empty( $frm_vars['prev_hidden_cols'] ) ? false : $prev_value;
288
289 return $check;
290 }
291
292 /**
293 * Add hidden columns back from other forms
294 */
295 public static function update_hidden_cols( $meta_id, $object_id, $meta_key, $meta_value ) {
296 $this_page_name = self::hidden_column_key();
297 if ( $meta_key != $this_page_name ) {
298 return;
299 }
300
301 global $frm_vars;
302 if ( ! isset( $frm_vars['prev_hidden_cols'] ) || ! $frm_vars['prev_hidden_cols'] ) {
303 // Don't continue if there's no previous value.
304 return;
305 }
306
307 foreach ( $meta_value as $mk => $mv ) {
308 // Remove blank values.
309 if ( empty( $mv ) ) {
310 unset( $meta_value[ $mk ] );
311 }
312 }
313
314 $cur_form_prefix = reset( $meta_value );
315 $cur_form_prefix = explode( '_', $cur_form_prefix );
316 $cur_form_prefix = $cur_form_prefix[0];
317 $save = false;
318
319 foreach ( (array) $frm_vars['prev_hidden_cols'] as $prev_hidden ) {
320 if ( empty( $prev_hidden ) || in_array( $prev_hidden, $meta_value ) ) {
321 // Don't add blank cols or process included cols.
322 continue;
323 }
324
325 $form_prefix = explode( '_', $prev_hidden );
326 $form_prefix = $form_prefix[0];
327 if ( $form_prefix == $cur_form_prefix ) {
328 // Don't add back columns that are meant to be hidden.
329 continue;
330 }
331
332 $meta_value[] = $prev_hidden;
333 $save = true;
334 unset( $form_prefix );
335 }
336
337 if ( $save ) {
338 $user_id = get_current_user_id();
339 update_user_option( $user_id, $this_page_name, $meta_value, true );
340 }
341 }
342
343 /**
344 * @since 2.05.07
345 */
346 private static function hidden_column_key( $menu_name = '' ) {
347 $base = self::base_column_key( $menu_name );
348
349 return 'manage' . $base . 'columnshidden';
350 }
351
352 /**
353 * @since 2.05.07
354 */
355 private static function base_column_key( $menu_name = '' ) {
356 if ( empty( $menu_name ) ) {
357 $menu_name = FrmAppHelper::get_menu_name();
358 }
359
360 $unread_count = FrmEntriesHelper::get_visible_unread_inbox_count();
361
362 return sanitize_title( $menu_name ) . ( $unread_count ? '-' . $unread_count : '' ) . '_page_formidable-entries';
363 }
364
365 public static function save_per_page( $save, $option, $value ) {
366 if ( $option === 'formidable_page_formidable_entries_per_page' ) {
367 $save = (int) $value;
368 }
369
370 return $save;
371 }
372
373 public static function sortable_columns() {
374 $form_id = FrmForm::get_current_form_id();
375 $fields = FrmField::get_all_for_form( $form_id );
376
377 $columns = array(
378 $form_id . '_id' => 'id',
379 $form_id . '_created_at' => 'created_at',
380 $form_id . '_updated_at' => 'updated_at',
381 $form_id . '_ip' => 'ip',
382 $form_id . '_item_key' => 'item_key',
383 $form_id . '_is_draft' => 'is_draft',
384 );
385
386 if ( ! $form_id ) {
387 $columns[ $form_id . '_user_id' ] = 'user_id';
388 $columns[ $form_id . '_name' ] = 'name';
389 $columns[ $form_id . '_form_id' ] = 'form_id';
390 }
391
392 foreach ( $fields as $field ) {
393 if ( self::field_supports_sorting( $field ) ) {
394 $columns[ $form_id . '_' . $field->field_key ] = 'meta_' . $field->id;
395 }
396 }
397
398 return $columns;
399 }
400
401 /**
402 * Can't sort on checkboxes because they are sorted serialized.
403 * Some post content can be sorted but not everything.
404 *
405 * @param stdClass $field
406 * @return bool
407 */
408 private static function field_supports_sorting( $field ) {
409 $is_sortable = 'checkbox' !== $field->type && empty( $field->field_options['post_field'] );
410 return apply_filters( 'frm_field_column_is_sortable', $is_sortable, $field );
411 }
412
413 /**
414 * @param mixed $result Option value from database for hidden columns in entries table.
415 * @return array
416 */
417 public static function hidden_columns( $result ) {
418 global $frm_vars;
419
420 if ( ! is_array( $result ) ) {
421 // Force an unexpected value to be an array.
422 // Since $result is a filtered option and gets saved to the database, it's possible it could be a string.
423 // Since this code expects an array it would break with a "Uncaught Error: [] operator not supported for strings" error.
424 $result = array();
425 }
426
427 $form_id = FrmForm::get_current_form_id();
428 $hidden = self::user_hidden_columns_for_form( $form_id, $result );
429 $i = isset( $frm_vars['cols'] ) ? count( $frm_vars['cols'] ) : 0;
430 $max_columns = 11;
431
432 if ( ! empty( $hidden ) ) {
433 $result = $hidden;
434 $i = $i - count( $result );
435 }
436
437 if ( $i <= $max_columns ) {
438 return $result;
439 }
440
441 self::remove_excess_cols( compact( 'i', 'max_columns', 'form_id' ), $result );
442
443 return $result;
444 }
445
446 /**
447 * @since 2.05.07
448 */
449 private static function user_hidden_columns_for_form( $form_id, $result ) {
450 $hidden = array();
451 foreach ( (array) $result as $r ) {
452 if ( ! empty( $r ) ) {
453 list( $form_prefix, $field_key ) = explode( '_', $r );
454
455 if ( (int) $form_prefix === (int) $form_id ) {
456 $hidden[] = $r;
457 }
458
459 unset( $form_prefix );
460 }
461 }
462
463 return $hidden;
464 }
465
466 /**
467 * Remove some columns by default when there are too many
468 *
469 * @since 2.05.07
470 *
471 * @param array $atts
472 * @param array $result
473 * @return void
474 */
475 private static function remove_excess_cols( $atts, &$result ) {
476 global $frm_vars;
477
478 $remove_first = array(
479 $atts['form_id'] . '_item_key' => '',
480 $atts['form_id'] . '_id' => '',
481 );
482 $cols = $remove_first + array_reverse( $frm_vars['cols'], true );
483
484 $i = $atts['i'];
485
486 foreach ( $cols as $col_key => $col ) {
487 if ( $i <= $atts['max_columns'] ) {
488 break;
489 }
490
491 if ( empty( $result ) || ! in_array( $col_key, $result, true ) ) {
492 $result[] = $col_key;
493 --$i;
494 }
495
496 unset( $col_key, $col );
497 }
498 }
499
500 public static function display_list( $message = '', $errors = array() ) {
501 global $wpdb, $frm_vars;
502
503 $form = FrmForm::maybe_get_current_form();
504 $params = FrmForm::get_admin_params( $form );
505
506 if ( $form ) {
507 $params['form'] = $form->id;
508 $frm_vars['current_form'] = $form;
509
510 self::get_delete_form_time( $form, $errors );
511 }
512
513 $table_class = apply_filters( 'frm_entries_list_class', 'FrmEntriesListHelper' );
514
515 $wp_list_table = new $table_class( array( 'params' => $params ) );
516
517 $pagenum = $wp_list_table->get_pagenum();
518
519 $wp_list_table->prepare_items();
520
521 $total_pages = $wp_list_table->get_pagination_arg( 'total_pages' );
522 if ( $pagenum > $total_pages && $total_pages > 0 ) {
523 $url = add_query_arg( 'paged', $total_pages );
524 if ( headers_sent() ) {
525 FrmAppHelper::js_redirect( $url, true );
526 } else {
527 wp_redirect( esc_url_raw( $url ) );
528 }
529 die();
530 }
531
532 if ( empty( $message ) && isset( $_GET['import-message'] ) ) {
533 $message = __( 'Your import is complete', 'formidable' );
534 }
535
536 require FrmAppHelper::plugin_path() . '/classes/views/frm-entries/list.php';
537 }
538
539 private static function get_delete_form_time( $form, &$errors ) {
540 if ( 'trash' === $form->status ) {
541 $delete_timestamp = time() - ( DAY_IN_SECONDS * EMPTY_TRASH_DAYS );
542 $time_to_delete = FrmAppHelper::human_time_diff( $delete_timestamp, ( $form->options['trash_time'] ?? time() ) );
543
544 /* translators: %1$s: Time string */
545 $errors['trash'] = sprintf( __( 'This form is in the trash and is scheduled to be deleted permanently in %s along with any entries.', 'formidable' ), $time_to_delete );
546 }
547 }
548
549 /**
550 * Back End CRUD.
551 */
552 public static function show( $id = 0 ) {
553 FrmAppHelper::permission_check( 'frm_view_entries' );
554
555 if ( ! $id ) {
556 $id = FrmAppHelper::get_param( 'id', 0, 'get', 'absint' );
557
558 if ( ! $id ) {
559 $id = FrmAppHelper::get_param( 'item_id', 0, 'get', 'absint' );
560 }
561 }
562
563 $entry = FrmEntry::getOne( $id, true );
564 if ( ! $entry ) {
565 FrmAppController::show_error_modal(
566 array(
567 'title' => __( 'You can\'t view the entry', 'formidable' ),
568 'body' => __( 'You are trying to view an entry that does not exist', 'formidable' ),
569 'cancel_url' => admin_url( 'admin.php?page=formidable' ),
570 )
571 );
572 return;
573 }
574
575 $data = $entry->description;
576 if ( ! is_array( $data ) || ! isset( $data['referrer'] ) ) {
577 $data = array( 'referrer' => $data );
578 }
579
580 $fields = FrmField::get_all_for_form( $entry->form_id, '', 'include' );
581 $form = FrmForm::getOne( $entry->form_id );
582
583 include FrmAppHelper::plugin_path() . '/classes/views/frm-entries/show.php';
584 }
585
586 /**
587 * Destroy an entry from the admin page.
588 * This is triggered from the entries list from the "Delete" row action, and also from the "Delete Entry" trigger in the view/edit entry sidebar.
589 *
590 * @return void
591 */
592 public static function destroy() {
593 $permission_error = FrmAppHelper::permission_nonce_error( 'frm_delete_entries', '_wpnonce', -1 );
594 if ( false !== $permission_error ) {
595 $error_args = array(
596 'title' => __( 'Verification failed', 'formidable' ),
597 'body' => $permission_error,
598 'cancel_url' => admin_url( 'admin.php?page=formidable-entries' ),
599 );
600 FrmAppController::show_error_modal( $error_args );
601 return;
602 }
603
604 $params = FrmForm::get_admin_params();
605
606 if ( isset( $params['keep_post'] ) && $params['keep_post'] ) {
607 self::unlink_post( $params['id'] );
608 }
609
610 $message = '';
611 if ( FrmEntry::destroy( $params['id'] ) ) {
612 $message = __( 'Entry was successfully deleted', 'formidable' );
613 }
614
615 self::display_list( $message );
616 }
617
618 public static function process_entry( $errors = '', $ajax = false ) {
619 $form_id = FrmAppHelper::get_post_param( 'form_id', '', 'absint' );
620 if ( FrmAppHelper::is_admin() || empty( $_POST ) || empty( $form_id ) || ! isset( $_POST['item_key'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
621 return;
622 }
623
624 global $frm_vars;
625
626 $form = FrmForm::getOne( $form_id );
627 if ( ! $form ) {
628 return;
629 }
630
631 $is_preview = 'frm_forms_preview' === FrmAppHelper::simple_get( 'action' );
632 if ( $is_preview && FrmFormsHelper::should_block_preview( $form->form_key ) ) {
633 return;
634 }
635
636 $params = FrmForm::get_params( $form );
637
638 if ( ! isset( $frm_vars['form_params'] ) ) {
639 $frm_vars['form_params'] = array();
640 }
641 $frm_vars['form_params'][ $form->id ] = $params;
642
643 if ( isset( $frm_vars['created_entries'][ $form_id ] ) ) {
644 return;
645 }
646
647 if ( $errors == '' && ! $ajax ) {
648 $errors = FrmEntryValidate::validate( wp_unslash( $_POST ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
649 }
650
651 /**
652 * Use this filter to add trigger actions and add errors after
653 * all other errors have been processed
654 *
655 * @since 2.0.6
656 */
657 $errors = apply_filters( 'frm_entries_before_create', $errors, $form );
658
659 $frm_vars['created_entries'][ $form_id ] = array( 'errors' => $errors );
660
661 if ( empty( $errors ) ) {
662 $_POST['frm_skip_cookie'] = 1;
663 $do_success = false;
664 if ( $params['action'] === 'create' ) {
665 if ( apply_filters( 'frm_continue_to_create', true, $form_id ) && ! isset( $frm_vars['created_entries'][ $form_id ]['entry_id'] ) ) {
666 $frm_vars['created_entries'][ $form_id ]['entry_id'] = FrmEntry::create( $_POST ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
667
668 $params['id'] = $frm_vars['created_entries'][ $form_id ]['entry_id'];
669 $do_success = true;
670 }
671 }
672
673 do_action( 'frm_process_entry', $params, $errors, $form, array( 'ajax' => $ajax ) );
674 if ( $do_success ) {
675 FrmFormsController::maybe_trigger_redirect( $form, $params, array( 'ajax' => $ajax ) );
676 }
677 unset( $_POST['frm_skip_cookie'] ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
678 }
679 }
680
681 /**
682 * Escape url entities before redirect
683 *
684 * @since 3.0
685 *
686 * @param string $url
687 *
688 * @return string
689 */
690 public static function prepare_redirect_url( $url ) {
691 return str_replace( array( ' ', '[', ']', '|', '@' ), array( '%20', '%5B', '%5D', '%7C', '%40' ), $url );
692 }
693
694 public static function delete_entry_before_redirect( $url, $form, $atts ) {
695 self::_delete_entry( $atts['id'], $form );
696
697 return $url;
698 }
699
700 /**
701 * Delete entry if not redirected.
702 *
703 * @param array $atts
704 */
705 public static function delete_entry_after_save( $atts ) {
706 self::_delete_entry( $atts['entry_id'], $atts['form'] );
707 }
708
709 private static function _delete_entry( $entry_id, $form ) {
710 if ( ! $form ) {
711 return;
712 }
713
714 FrmAppHelper::unserialize_or_decode( $form->options );
715 if ( isset( $form->options['no_save'] ) && $form->options['no_save'] ) {
716 self::unlink_post( $entry_id );
717 FrmEntry::destroy( $entry_id );
718 }
719 }
720
721 /**
722 * Unlink entry from post
723 */
724 private static function unlink_post( $entry_id ) {
725 global $wpdb;
726 $wpdb->update( $wpdb->prefix . 'frm_items', array( 'post_id' => '' ), array( 'id' => $entry_id ) );
727 FrmEntry::clear_cache();
728 }
729
730 /**
731 * @param array $atts
732 *
733 * @return array|string
734 */
735 public static function show_entry_shortcode( $atts ) {
736 $defaults = array(
737 'id' => false,
738 'entry' => false,
739 'fields' => false,
740 'plain_text' => false,
741 'user_info' => false,
742 'include_blank' => false,
743 'default_email' => false,
744 'form_id' => false,
745 'format' => 'text',
746 'array_key' => 'key',
747 'direction' => 'ltr',
748 'font_size' => '',
749 'text_color' => '',
750 'border_width' => '',
751 'border_color' => '',
752 'bg_color' => '',
753 'alt_bg_color' => '',
754 'class' => '',
755 'clickable' => false,
756 'exclude_fields' => '',
757 'include_fields' => '',
758 'include_extras' => '',
759 'inline_style' => 1,
760 'table_style' => '',
761 // Return embedded fields as nested array.
762 'child_array' => false,
763 'line_breaks' => true,
764 'array_separator' => ', ',
765 );
766 $defaults = apply_filters( 'frm_show_entry_defaults', $defaults );
767
768 $atts = shortcode_atts( $defaults, $atts );
769
770 if ( $atts['default_email'] ) {
771 $shortcode_atts = array(
772 'format' => $atts['format'],
773 'plain_text' => $atts['plain_text'],
774 );
775
776 $entry_formatter = FrmEntryFactory::entry_shortcode_formatter_instance( $atts['form_id'], $shortcode_atts );
777 $formatted_entry = $entry_formatter->content();
778
779 } else {
780
781 $entry_formatter = FrmEntryFactory::entry_formatter_instance( $atts );
782 $formatted_entry = $entry_formatter->get_formatted_entry_values();
783
784 }
785
786 return $formatted_entry;
787 }
788
789 public static function entry_sidebar( $entry = false ) {
790 $data = array();
791 $id = 0;
792
793 $date_format = get_option( 'date_format' );
794 $time_format = get_option( 'time_format' );
795
796 if ( $entry ) {
797 $id = $entry->id;
798 $data = $entry->description;
799 if ( isset( $data['browser'] ) ) {
800 $browser = FrmEntriesHelper::get_browser( $data['browser'] );
801 }
802 /**
803 * Add or remove information in the entry sidebar.
804 *
805 * @since 5.5.2
806 *
807 * @param array $data
808 * @param array{entry:\stdClass} $entry
809 */
810 $data = apply_filters( 'frm_sidebar_data', $data, compact( 'entry' ) );
811 }
812
813 include FrmAppHelper::plugin_path() . '/classes/views/frm-entries/sidebar-shared.php';
814 }
815 }
816