PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 4.04.05
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v4.04.05
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 4.04.05, at classes/controllers/FrmEntriesController.php

665 lines 18.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 class FrmEntriesController {
4
5 public static function menu() {
6 FrmAppHelper::force_capability( 'frm_view_entries' );
7
8 add_submenu_page( 'formidable', 'Formidable | ' . __( 'Entries', 'formidable' ), __( 'Entries', 'formidable' ), 'frm_view_entries', 'formidable-entries', 'FrmEntriesController::route' );
9
10 self::load_manage_entries_hooks();
11 }
12
13 /**
14 * @since 2.05.07
15 */
16 private static function load_manage_entries_hooks() {
17 if ( ! in_array( FrmAppHelper::simple_get( 'frm_action', 'sanitize_title' ), array( 'edit', 'show', 'new' ) ) ) {
18 $menu_name = FrmAppHelper::get_menu_name();
19 $base = self::base_column_key( $menu_name );
20
21 add_filter( 'manage_' . $base . '_columns', 'FrmEntriesController::manage_columns' );
22 add_filter( 'get_user_option_' . self::hidden_column_key( $menu_name ), 'FrmEntriesController::hidden_columns' );
23 add_filter( 'manage_' . $base . '_sortable_columns', 'FrmEntriesController::sortable_columns' );
24 } else {
25 add_filter( 'screen_options_show_screen', __CLASS__ . '::remove_screen_options', 10, 2 );
26 }
27 }
28
29 /* Display in Back End */
30 public static function route() {
31 $action = FrmAppHelper::get_param( 'frm_action', '', 'get', 'sanitize_title' );
32 FrmAppHelper::include_svg();
33
34 switch ( $action ) {
35 case 'show':
36 case 'destroy':
37 return self::$action();
38
39 default:
40 do_action( 'frm_entry_action_route', $action );
41 if ( apply_filters( 'frm_entry_stop_action_route', false, $action ) ) {
42 return;
43 }
44
45 return self::display_list();
46 }
47 }
48
49 /**
50 * Prevent the "screen options" tab from showing when
51 * editing or creating an entry
52 *
53 * @since 3.0
54 */
55 public static function remove_screen_options( $show_screen, $screen ) {
56 $menu_name = sanitize_title( FrmAppHelper::get_menu_name() );
57 if ( $screen->id == $menu_name . '_page_formidable-entries' ) {
58 $show_screen = false;
59 }
60
61 return $show_screen;
62 }
63
64 public static function manage_columns( $columns ) {
65 global $frm_vars;
66 $form_id = FrmForm::get_current_form_id();
67
68 $columns[ $form_id . '_id' ] = 'ID';
69 $columns[ $form_id . '_item_key' ] = esc_html__( 'Entry Key', 'formidable' );
70
71 if ( $form_id ) {
72 self::get_columns_for_form( $form_id, $columns );
73 } else {
74 $columns[ $form_id . '_form_id' ] = __( 'Form', 'formidable' );
75 $columns[ $form_id . '_name' ] = __( 'Entry Name', 'formidable' );
76 $columns[ $form_id . '_user_id' ] = __( 'Created By', 'formidable' );
77 }
78
79 $columns[ $form_id . '_created_at' ] = __( 'Entry creation date', 'formidable' );
80 $columns[ $form_id . '_updated_at' ] = __( 'Entry update date', 'formidable' );
81 self::maybe_add_ip_col( $form_id, $columns );
82
83 $frm_vars['cols'] = $columns;
84
85 $action = FrmAppHelper::simple_get( 'frm_action', 'sanitize_title' );
86 if ( FrmAppHelper::is_admin_page( 'formidable-entries' ) && in_array( $action, array( '', 'list', 'destroy' ) ) ) {
87 add_screen_option(
88 'per_page',
89 array(
90 'label' => __( 'Entries', 'formidable' ),
91 'default' => 20,
92 'option' => 'formidable_page_formidable_entries_per_page',
93 )
94 );
95 }
96
97 return $columns;
98 }
99
100 private static function get_columns_for_form( $form_id, &$columns ) {
101 $form_cols = FrmField::get_all_for_form( $form_id, '', 'include' );
102
103 foreach ( $form_cols as $form_col ) {
104 if ( FrmField::is_no_save_field( $form_col->type ) ) {
105 continue;
106 }
107
108 $has_child_fields = $form_col->type == 'form' && isset( $form_col->field_options['form_select'] ) && ! empty( $form_col->field_options['form_select'] );
109 if ( $has_child_fields ) {
110 self::add_subform_cols( $form_col, $form_id, $columns );
111 } else {
112 self::add_field_cols( $form_col, $form_id, $columns );
113 }
114 }
115 }
116
117 /**
118 * @since 3.01
119 */
120 private static function add_subform_cols( $field, $form_id, &$columns ) {
121 $sub_form_cols = FrmField::get_all_for_form( $field->field_options['form_select'] );
122 if ( empty( $sub_form_cols ) ) {
123 return;
124 }
125
126 foreach ( $sub_form_cols as $k => $sub_form_col ) {
127 if ( FrmField::is_no_save_field( $sub_form_col->type ) ) {
128 unset( $sub_form_cols[ $k ] );
129 continue;
130 }
131 $columns[ $form_id . '_' . $sub_form_col->field_key . '-_-' . $field->id ] = FrmAppHelper::truncate( $sub_form_col->name, 35 );
132 unset( $sub_form_col );
133 }
134 }
135
136 /**
137 * @since 3.01
138 */
139 private static function add_field_cols( $field, $form_id, &$columns ) {
140 $col_id = $field->field_key;
141 if ( $field->form_id != $form_id ) {
142 $col_id .= '-_-form' . $field->form_id;
143 }
144
145 $has_separate_value = ! FrmField::is_option_empty( $field, 'separate_value' );
146 $is_post_status = FrmField::is_option_true( $field, 'post_field' ) && $field->field_options['post_field'] == 'post_status';
147 if ( $has_separate_value && ! $is_post_status ) {
148 $columns[ $form_id . '_frmsep_' . $col_id ] = FrmAppHelper::truncate( $field->name, 35 );
149 }
150
151 $columns[ $form_id . '_' . $col_id ] = FrmAppHelper::truncate( $field->name, 35 );
152 }
153
154 private static function maybe_add_ip_col( $form_id, &$columns ) {
155 if ( FrmAppHelper::ips_saved() ) {
156 $columns[ $form_id . '_ip' ] = 'IP';
157 }
158 }
159
160 public static function check_hidden_cols( $check, $object_id, $meta_key, $meta_value, $prev_value ) {
161 $this_page_name = self::hidden_column_key();
162 if ( $meta_key != $this_page_name || $meta_value == $prev_value ) {
163 return $check;
164 }
165
166 if ( empty( $prev_value ) ) {
167 $prev_value = get_metadata( 'user', $object_id, $meta_key, true );
168 }
169
170 global $frm_vars;
171 //add a check so we don't create a loop
172 $frm_vars['prev_hidden_cols'] = ( isset( $frm_vars['prev_hidden_cols'] ) && $frm_vars['prev_hidden_cols'] ) ? false : $prev_value;
173
174 return $check;
175 }
176
177 /**
178 * Add hidden columns back from other forms
179 */
180 public static function update_hidden_cols( $meta_id, $object_id, $meta_key, $meta_value ) {
181 $this_page_name = self::hidden_column_key();
182 if ( $meta_key != $this_page_name ) {
183 return;
184 }
185
186 global $frm_vars;
187 if ( ! isset( $frm_vars['prev_hidden_cols'] ) || ! $frm_vars['prev_hidden_cols'] ) {
188 return; // Don't continue if there's no previous value.
189 }
190
191 foreach ( $meta_value as $mk => $mv ) {
192 // Remove blank values.
193 if ( empty( $mv ) ) {
194 unset( $meta_value[ $mk ] );
195 }
196 }
197
198 $cur_form_prefix = reset( $meta_value );
199 $cur_form_prefix = explode( '_', $cur_form_prefix );
200 $cur_form_prefix = $cur_form_prefix[0];
201 $save = false;
202
203 foreach ( (array) $frm_vars['prev_hidden_cols'] as $prev_hidden ) {
204 if ( empty( $prev_hidden ) || in_array( $prev_hidden, $meta_value ) ) {
205 // Don't add blank cols or process included cols.
206 continue;
207 }
208
209 $form_prefix = explode( '_', $prev_hidden );
210 $form_prefix = $form_prefix[0];
211 if ( $form_prefix == $cur_form_prefix ) {
212 // Don't add back columns that are meant to be hidden.
213 continue;
214 }
215
216 $meta_value[] = $prev_hidden;
217 $save = true;
218 unset( $form_prefix );
219 }
220
221 if ( $save ) {
222 $user_id = get_current_user_id();
223 update_user_option( $user_id, $this_page_name, $meta_value, true );
224 }
225 }
226
227 /**
228 * @since 2.05.07
229 */
230 private static function hidden_column_key( $menu_name = '' ) {
231 $base = self::base_column_key( $menu_name );
232
233 return 'manage' . $base . 'columnshidden';
234 }
235
236 /**
237 * @since 2.05.07
238 */
239 private static function base_column_key( $menu_name = '' ) {
240 if ( empty( $menu_name ) ) {
241 $menu_name = FrmAppHelper::get_menu_name();
242 }
243
244 return sanitize_title( $menu_name ) . '_page_formidable-entries';
245 }
246
247 public static function save_per_page( $save, $option, $value ) {
248 if ( $option == 'formidable_page_formidable_entries_per_page' ) {
249 $save = (int) $value;
250 }
251
252 return $save;
253 }
254
255 public static function sortable_columns() {
256 $form_id = FrmForm::get_current_form_id();
257 $fields = FrmField::get_all_for_form( $form_id );
258
259 $columns = array(
260 $form_id . '_id' => 'id',
261 $form_id . '_created_at' => 'created_at',
262 $form_id . '_updated_at' => 'updated_at',
263 $form_id . '_ip' => 'ip',
264 $form_id . '_item_key' => 'item_key',
265 $form_id . '_is_draft' => 'is_draft',
266 );
267
268 foreach ( $fields as $field ) {
269 if ( $field->type != 'checkbox' && ( ! isset( $field->field_options['post_field'] ) || $field->field_options['post_field'] == '' ) ) {
270 // Can't sort on checkboxes because they are stored serialized, or post fields
271 $columns[ $form_id . '_' . $field->field_key ] = 'meta_' . $field->id;
272 }
273 }
274
275 return $columns;
276 }
277
278 public static function hidden_columns( $result ) {
279 $form_id = FrmForm::get_current_form_id();
280
281 $hidden = self::user_hidden_columns_for_form( $form_id, $result );
282
283 global $frm_vars;
284 $i = isset( $frm_vars['cols'] ) ? count( $frm_vars['cols'] ) : 0;
285
286 if ( ! empty( $hidden ) ) {
287 $result = $hidden;
288 $i = $i - count( $result );
289 $max_columns = 11;
290 } else {
291 $max_columns = 8;
292 }
293
294 if ( $i <= $max_columns ) {
295 return $result;
296 }
297
298 self::remove_excess_cols( compact( 'i', 'max_columns', 'form_id' ), $result );
299
300 return $result;
301 }
302
303 /**
304 * @since 2.05.07
305 */
306 private static function user_hidden_columns_for_form( $form_id, $result ) {
307 $hidden = array();
308 foreach ( (array) $result as $r ) {
309 if ( ! empty( $r ) ) {
310 list( $form_prefix, $field_key ) = explode( '_', $r );
311
312 if ( (int) $form_prefix == (int) $form_id ) {
313 $hidden[] = $r;
314 }
315
316 unset( $form_prefix );
317 }
318 }
319
320 return $hidden;
321 }
322
323 /**
324 * Remove some columns by default when there are too many
325 *
326 * @since 2.05.07
327 */
328 private static function remove_excess_cols( $atts, &$result ) {
329 global $frm_vars;
330
331 $remove_first = array(
332 $atts['form_id'] . '_item_key' => '',
333 $atts['form_id'] . '_id' => '',
334 );
335 $cols = $remove_first + array_reverse( $frm_vars['cols'], true );
336
337 $i = $atts['i'];
338
339 foreach ( $cols as $col_key => $col ) {
340 if ( $i <= $atts['max_columns'] ) {
341 break;
342 }
343
344 if ( empty( $result ) || ! in_array( $col_key, $result, true ) ) {
345 $result[] = $col_key;
346 $i--;
347 }
348
349 unset( $col_key, $col );
350 }
351 }
352
353 public static function display_list( $message = '', $errors = array() ) {
354 global $wpdb, $frm_vars;
355
356 $form = FrmForm::maybe_get_current_form();
357 $params = FrmForm::get_admin_params( $form );
358
359 if ( $form ) {
360 $params['form'] = $form->id;
361 $frm_vars['current_form'] = $form;
362
363 self::get_delete_form_time( $form, $errors );
364 }
365
366 $table_class = apply_filters( 'frm_entries_list_class', 'FrmEntriesListHelper' );
367
368 $wp_list_table = new $table_class( array( 'params' => $params ) );
369
370 $pagenum = $wp_list_table->get_pagenum();
371
372 $wp_list_table->prepare_items();
373
374 $total_pages = $wp_list_table->get_pagination_arg( 'total_pages' );
375 if ( $pagenum > $total_pages && $total_pages > 0 ) {
376 $url = add_query_arg( 'paged', $total_pages );
377 if ( headers_sent() ) {
378 echo FrmAppHelper::js_redirect( $url ); // WPCS: XSS ok.
379 } else {
380 wp_redirect( esc_url_raw( $url ) );
381 }
382 die();
383 }
384
385 if ( empty( $message ) && isset( $_GET['import-message'] ) ) {
386 $message = __( 'Your import is complete', 'formidable' );
387 }
388
389 require( FrmAppHelper::plugin_path() . '/classes/views/frm-entries/list.php' );
390 }
391
392 private static function get_delete_form_time( $form, &$errors ) {
393 if ( 'trash' == $form->status ) {
394 $delete_timestamp = time() - ( DAY_IN_SECONDS * EMPTY_TRASH_DAYS );
395 $time_to_delete = FrmAppHelper::human_time_diff( $delete_timestamp, ( isset( $form->options['trash_time'] ) ? ( $form->options['trash_time'] ) : time() ) );
396
397 /* translators: %1$s: Time string */
398 $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 );
399 }
400 }
401
402 /* Back End CRUD */
403 public static function show( $id = 0 ) {
404 FrmAppHelper::permission_check( 'frm_view_entries' );
405
406 if ( ! $id ) {
407 $id = FrmAppHelper::get_param( 'id', 0, 'get', 'absint' );
408
409 if ( ! $id ) {
410 $id = FrmAppHelper::get_param( 'item_id', 0, 'get', 'absint' );
411 }
412 }
413
414 $entry = FrmEntry::getOne( $id, true );
415 if ( ! $entry ) {
416 echo '<div id="form_show_entry_page" class="wrap">' .
417 esc_html__( 'You are trying to view an entry that does not exist.', 'formidable' ) .
418 '</div>';
419
420 return;
421 }
422
423 $data = $entry->description;
424 if ( ! is_array( $data ) || ! isset( $data['referrer'] ) ) {
425 $data = array( 'referrer' => $data );
426 }
427
428 $fields = FrmField::get_all_for_form( $entry->form_id, '', 'include' );
429 $form = FrmForm::getOne( $entry->form_id );
430
431 include( FrmAppHelper::plugin_path() . '/classes/views/frm-entries/show.php' );
432 }
433
434 public static function destroy() {
435 FrmAppHelper::permission_check( 'frm_delete_entries' );
436
437 $params = FrmForm::get_admin_params();
438
439 if ( isset( $params['keep_post'] ) && $params['keep_post'] ) {
440 self::unlink_post( $params['id'] );
441 }
442
443 $message = '';
444 if ( FrmEntry::destroy( $params['id'] ) ) {
445 $message = __( 'Entry was Successfully Deleted', 'formidable' );
446 }
447
448 self::display_list( $message );
449 }
450
451 /**
452 * @deprecated 4.02.04 - Moved to Pro since it was unused in Lite.
453 */
454 public static function destroy_all() {
455 _deprecated_function( __METHOD__, '4.02.04', 'FrmProEntriesController::destroy_all' );
456 if ( is_callable( 'FrmProEntriesController::destroy_all' ) ) {
457 FrmProEntriesController::destroy_all();
458 }
459 }
460
461 public static function process_entry( $errors = '', $ajax = false ) {
462 $form_id = FrmAppHelper::get_post_param( 'form_id', '', 'absint' );
463 if ( FrmAppHelper::is_admin() || empty( $_POST ) || empty( $form_id ) || ! isset( $_POST['item_key'] ) ) {
464 return;
465 }
466
467 global $frm_vars;
468
469 $form = FrmForm::getOne( $form_id );
470 if ( ! $form ) {
471 return;
472 }
473
474 $params = FrmForm::get_params( $form );
475
476 if ( ! isset( $frm_vars['form_params'] ) ) {
477 $frm_vars['form_params'] = array();
478 }
479 $frm_vars['form_params'][ $form->id ] = $params;
480
481 if ( isset( $frm_vars['created_entries'][ $form_id ] ) ) {
482 return;
483 }
484
485 if ( $errors == '' && ! $ajax ) {
486 $errors = FrmEntryValidate::validate( wp_unslash( $_POST ) );
487 }
488
489 /**
490 * Use this filter to add trigger actions and add errors after
491 * all other errors have been processed
492 *
493 * @since 2.0.6
494 */
495 $errors = apply_filters( 'frm_entries_before_create', $errors, $form );
496
497 $frm_vars['created_entries'][ $form_id ] = array( 'errors' => $errors );
498
499 if ( empty( $errors ) ) {
500 $_POST['frm_skip_cookie'] = 1;
501 $do_success = false;
502 if ( $params['action'] == 'create' ) {
503 if ( apply_filters( 'frm_continue_to_create', true, $form_id ) && ! isset( $frm_vars['created_entries'][ $form_id ]['entry_id'] ) ) {
504 $frm_vars['created_entries'][ $form_id ]['entry_id'] = FrmEntry::create( $_POST );
505
506 $params['id'] = $frm_vars['created_entries'][ $form_id ]['entry_id'];
507 $do_success = true;
508 }
509 }
510
511 do_action( 'frm_process_entry', $params, $errors, $form, array( 'ajax' => $ajax ) );
512 if ( $do_success ) {
513 FrmFormsController::maybe_trigger_redirect( $form, $params, array( 'ajax' => $ajax ) );
514 }
515 unset( $_POST['frm_skip_cookie'] );
516 }
517 }
518
519 /**
520 * Escape url entities before redirect
521 *
522 * @since 3.0
523 *
524 * @param string $url
525 *
526 * @return string
527 */
528 public static function prepare_redirect_url( $url ) {
529 return str_replace( array( ' ', '[', ']', '|', '@' ), array( '%20', '%5B', '%5D', '%7C', '%40' ), $url );
530 }
531
532 public static function delete_entry_before_redirect( $url, $form, $atts ) {
533 self::_delete_entry( $atts['id'], $form );
534
535 return $url;
536 }
537
538 /**
539 * Delete entry if not redirected.
540 *
541 * @param array $atts
542 */
543 public static function delete_entry_after_save( $atts ) {
544 self::_delete_entry( $atts['entry_id'], $atts['form'] );
545 }
546
547 private static function _delete_entry( $entry_id, $form ) {
548 if ( ! $form ) {
549 return;
550 }
551
552 FrmAppHelper::unserialize_or_decode( $form->options );
553 if ( isset( $form->options['no_save'] ) && $form->options['no_save'] ) {
554 self::unlink_post( $entry_id );
555 FrmEntry::destroy( $entry_id );
556 }
557 }
558
559 /**
560 * Unlink entry from post
561 */
562 private static function unlink_post( $entry_id ) {
563 global $wpdb;
564 $wpdb->update( $wpdb->prefix . 'frm_items', array( 'post_id' => '' ), array( 'id' => $entry_id ) );
565 FrmEntry::clear_cache();
566 }
567
568 /**
569 * @param $atts
570 *
571 * @return array|string
572 */
573 public static function show_entry_shortcode( $atts ) {
574 $defaults = array(
575 'id' => false,
576 'entry' => false,
577 'fields' => false,
578 'plain_text' => false,
579 'user_info' => false,
580 'include_blank' => false,
581 'default_email' => false,
582 'form_id' => false,
583 'format' => 'text',
584 'array_key' => 'key',
585 'direction' => 'ltr',
586 'font_size' => '',
587 'text_color' => '',
588 'border_width' => '',
589 'border_color' => '',
590 'bg_color' => '',
591 'alt_bg_color' => '',
592 'class' => '',
593 'clickable' => false,
594 'exclude_fields' => '',
595 'include_fields' => '',
596 'include_extras' => '',
597 'inline_style' => 1,
598 'child_array' => false, // return embedded fields as nested array
599 );
600 $defaults = apply_filters( 'frm_show_entry_defaults', $defaults );
601
602 $atts = shortcode_atts( $defaults, $atts );
603
604 if ( $atts['default_email'] ) {
605 $shortcode_atts = array(
606 'format' => $atts['format'],
607 'plain_text' => $atts['plain_text'],
608 );
609
610 $entry_formatter = FrmEntryFactory::entry_shortcode_formatter_instance( $atts['form_id'], $shortcode_atts );
611 $formatted_entry = $entry_formatter->content();
612
613 } else {
614
615 $entry_formatter = FrmEntryFactory::entry_formatter_instance( $atts );
616 $formatted_entry = $entry_formatter->get_formatted_entry_values();
617
618 }
619
620 return $formatted_entry;
621 }
622
623 public static function entry_sidebar( $entry = false ) {
624 $data = array();
625 $id = 0;
626
627 $date_format = get_option( 'date_format' );
628 $time_format = get_option( 'time_format' );
629
630 if ( $entry ) {
631 $id = $entry->id;
632 $data = $entry->description;
633 if ( isset( $data['browser'] ) ) {
634 $browser = FrmEntriesHelper::get_browser( $data['browser'] );
635 }
636 }
637
638 include( FrmAppHelper::plugin_path() . '/classes/views/frm-entries/sidebar-shared.php' );
639 }
640
641 /**
642 * @deprecated 4.0
643 */
644 public static function contextual_help( $help, $screen_id, $screen ) {
645 _deprecated_function( __METHOD__, '4.0' );
646 return $help;
647 }
648
649 /**
650 * @deprecated 1.07.05
651 * @codeCoverageIgnore
652 */
653 public static function show_form( $id = '', $key = '', $title = false, $description = false ) {
654 return FrmDeprecated::show_form( $id, $key, $title, $description );
655 }
656
657 /**
658 * @deprecated 1.07.05
659 * @codeCoverageIgnore
660 */
661 public static function get_form( $filename, $form, $title, $description ) {
662 return FrmDeprecated::get_form( $filename, $form, $title, $description );
663 }
664 }
665