PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / trunk
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More vtrunk
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 / FrmEntriesListHelper.php

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

591 lines 14.9 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 FrmEntriesListHelper extends FrmListHelper {
7
8 /**
9 * @var string|null
10 */
11 protected $column_name;
12
13 /**
14 * @since 4.07
15 *
16 * @var bool|int
17 */
18 public $total_items = 0;
19
20 /**
21 * @param array $args
22 */
23 public function __construct( $args ) {
24 parent::__construct( $args );
25 $this->screen->set_screen_reader_content(
26 array(
27 'heading_list' => esc_html__( 'Entries list', 'formidable' ),
28 )
29 );
30 }
31
32 /**
33 * @return void
34 */
35 public function prepare_items() {
36 $this->set_per_page();
37 $s_query = array();
38 $join_form_in_query = false;
39
40 $this->items = $this->get_entry_items( $s_query, $join_form_in_query );
41 $this->set_total_items( $s_query );
42 $this->prepare_pagination();
43 }
44
45 /**
46 * @param array $s_query
47 *
48 * @return void
49 */
50 protected function set_total_items( $s_query ) {
51 $this->total_items = FrmEntry::getRecordCount( $s_query );
52 }
53
54 /**
55 * Prepares pagination.
56 *
57 * @since 6.5.4
58 *
59 * @return void
60 */
61 protected function prepare_pagination() {
62 global $per_page;
63
64 $this->set_pagination_args(
65 array(
66 'total_items' => $this->total_items,
67 'per_page' => $per_page,
68 )
69 );
70 }
71
72 /**
73 * Sets the global $per_page variable
74 *
75 * @since 6.5.4
76 *
77 * @return void
78 */
79 protected function set_per_page() {
80 global $per_page;
81 $per_page = $this->get_items_per_page( 'formidable_page_formidable_entries_per_page' );
82 }
83
84 /**
85 * @since 6.5.4
86 *
87 * @param array $s_query
88 * @param bool $join_form_in_query
89 *
90 * @return array
91 */
92 protected function get_entry_items( &$s_query, &$join_form_in_query ) {
93 global $per_page;
94 $s_query = $this->get_search_query( $join_form_in_query );
95 $limit = $this->get_limit( $per_page );
96
97 return FrmEntry::getAll( $s_query, $this->get_order_by(), $limit, true, $join_form_in_query );
98 }
99
100 /**
101 * @since 6.5.4
102 *
103 * @return string
104 */
105 protected function get_order_by() {
106 $orderby = self::get_param(
107 array(
108 'param' => 'orderby',
109 'default' => 'id',
110 )
111 );
112 $order = self::get_param(
113 array(
114 'param' => 'order',
115 'default' => 'DESC',
116 )
117 );
118
119 FrmAppController::apply_saved_sort_preference( $orderby, $order );
120
121 if ( str_contains( $orderby, 'meta' ) ) {
122 $order_field_type = FrmField::get_type( str_replace( 'meta_', '', $orderby ) );
123
124 if ( in_array( $order_field_type, array( 'number', 'scale', 'star' ), true ) ) {
125 $orderby .= '+0';
126 }
127 }
128
129 return FrmDb::esc_order( $orderby . ' ' . $order );
130 }
131
132 /**
133 * @since 6.5.4
134 *
135 * @param int $per_page
136 *
137 * @return string
138 */
139 protected function get_limit( $per_page ) {
140 $page = $this->get_pagenum();
141 $start = (int) self::get_param(
142 array(
143 'param' => 'start',
144 'default' => ( $page - 1 ) * $per_page,
145 )
146 );
147
148 return FrmDb::esc_limit( $start . ',' . $per_page );
149 }
150
151 /**
152 * @since 6.5.4
153 *
154 * @param bool $join_form_in_query
155 *
156 * @return array
157 */
158 protected function get_search_query( &$join_form_in_query ) {
159 $form_id = $this->params['form'];
160 $s_query = array();
161
162 if ( $form_id ) {
163 $form_ids = $this->get_form_ids( $form_id );
164 $s_query['it.form_id'] = count( $form_ids ) > 1 ? $form_ids : $form_ids[0];
165 } else {
166 $s_query[] = array(
167 'or' => 1,
168 'parent_form_id' => null,
169 'parent_form_id <' => 1,
170 );
171 $join_form_in_query = true;
172 }
173
174 $s = self::get_param(
175 array(
176 'param' => 's',
177 'sanitize' => 'sanitize_text_field',
178 )
179 );
180
181 if ( $s !== '' && FrmAppHelper::pro_is_installed() ) {
182 $fid = self::get_param( array( 'param' => 'fid' ) );
183 $s_query = FrmProEntriesHelper::get_search_str( $s_query, $s, $form_id, $fid );
184 }
185
186 return apply_filters( 'frm_entries_list_query', $s_query, compact( 'form_id' ) );
187 }
188
189 /**
190 * @since 6.5.4
191 *
192 * @param int|string $form_id
193 *
194 * @return array<int>
195 */
196 protected function get_form_ids( $form_id ) {
197 return array( (int) $form_id );
198 }
199
200 /**
201 * @return void
202 */
203 public function no_items() {
204 $s = self::get_param(
205 array(
206 'param' => 's',
207 'sanitize' => 'sanitize_text_field',
208 )
209 );
210
211 if ( $s !== '' ) {
212 $current_url = set_url_scheme(
213 'http://' . FrmAppHelper::get_server_value( 'HTTP_HOST' ) . FrmAppHelper::get_server_value( 'REQUEST_URI' )
214 );
215 $clear_url = remove_query_arg( 's', $current_url );
216
217 echo '<p>';
218 printf(
219 /* translators: %1$s: Start link HTML, %2$s: End link HTML */
220 esc_html__( 'No entries match your search. %1$sClear search%2$s', 'formidable' ),
221 '<a href="' . esc_url( $clear_url ) . '">',
222 '</a>'
223 );
224 echo '</p>';
225 return;
226 }
227
228 $form_id = $this->params['form'];
229 $form = $this->params['form'];
230
231 if ( $form_id ) {
232 $form = FrmForm::getOne( $form_id );
233 }
234
235 $has_form = ! empty( $form );
236
237 if ( ! $has_form ) {
238 $has_form = FrmForm::getAll( array(), '', 1 );
239 $has_form = ! empty( $has_form );
240 }
241
242 $colspan = $this->get_column_count();
243
244 include FrmAppHelper::plugin_path() . '/classes/views/frm-entries/no_entries.php';
245 }
246
247 /**
248 * @param string $text Text.
249 * @param string $input_id Input ID.
250 *
251 * @return void
252 */
253 public function search_box( $text, $input_id ) {
254 // Searching is a pro feature
255 }
256
257 /**
258 * @param string $which
259 *
260 * @return void
261 */
262 protected function display_tablenav( $which ) {
263 $is_footer = $which !== 'top';
264
265 if ( $is_footer && ! empty( $this->items ) ) {
266 $utm = array(
267 'campaign' => 'spam-protection',
268 'content' => 'entries-list-spam-protection',
269 );
270 // phpcs:disable Generic.WhiteSpace.ScopeIndent
271 ?>
272 <p>
273 <?php esc_html_e( 'Getting spam form submissions?', 'formidable' ); ?>
274 <a href="<?php echo esc_url( FrmAppHelper::admin_upgrade_link( $utm, 'knowledgebase/add-spam-protection/' ) ); ?>" target="_blank">
275 <?php esc_html_e( 'Learn how to prevent them.', 'formidable' ); ?>
276 </a>
277 </p>
278 <?php
279 // phpcs:enable Generic.WhiteSpace.ScopeIndent
280 }
281 parent::display_tablenav( $which );
282 }
283
284 /**
285 * @param string $which
286 *
287 * @return void
288 */
289 protected function extra_tablenav( $which ) {
290 $form_id = FrmAppHelper::simple_get( 'form', 'absint' );
291
292 if ( $which !== 'top' || $form_id ) {
293 return;
294 }
295
296 echo '<div class="alignleft actions">';
297
298 // Override the referrer to prevent it from being used for the screen options.
299 echo '<input type="hidden" name="_wp_http_referer" value="" />';
300
301 echo '<label for="form" class="screen-reader-text">' . esc_html__( 'Filter by form', 'formidable' ) . '</label>';
302
303 FrmFormsHelper::forms_dropdown( 'form', $form_id, array( 'blank' => __( 'View all forms', 'formidable' ) ) );
304 submit_button( __( 'Filter', 'formidable' ), 'filter_action action', '', false, array( 'id' => 'post-query-submit' ) );
305 echo '</div>';
306 }
307
308 /**
309 * Gets the name of the primary column in the Entries screen
310 *
311 * @since 2.0.14
312 *
313 * @return string Primary column.
314 */
315 protected function get_primary_column_name() {
316 $columns = get_column_headers( $this->screen );
317 $hidden = get_hidden_columns( $this->screen );
318 $primary_column = '';
319
320 foreach ( $columns as $column_key => $column_display_name ) {
321 if ( 'cb' !== $column_key && ! in_array( $column_key, $hidden, true ) ) {
322 $primary_column = $column_key;
323 break;
324 }
325 }
326
327 return $primary_column;
328 }
329
330 /**
331 * @since 6.12
332 *
333 * @param object $item
334 *
335 * @return string
336 */
337 private static function get_entry_label( $item ) {
338 if ( $item->name ) {
339 return $item->name;
340 }
341 /* translators: %d: Entry id */
342 return sprintf( __( 'Entry %d', 'formidable' ), $item->id );
343 }
344
345 /**
346 * @param stdClass $item
347 * @param string $style
348 *
349 * @return string
350 */
351 public function single_row( $item, $style = '' ) {
352 // Set up the hover actions for this user
353 $actions = array();
354 $view_link = '?page=formidable-entries&frm_action=show&id=' . $item->id;
355
356 $this->get_actions( $actions, $item, $view_link );
357
358 $action_links = $this->row_actions( $actions );
359
360 // Set up the checkbox ( because the user is editable, otherwise its empty )
361 $checkbox = "<input type='checkbox' name='item-action[]' id='cb-item-action-{$item->id}' value='{$item->id}' />";
362 /* translators: %s: Form name */
363 $checkbox .= "<label for='cb-item-action-{$item->id}'><span class='screen-reader-text'>" . esc_html( sprintf( __( 'Select %s', 'formidable' ), self::get_entry_label( $item ) ) ) . '</span></label>'; // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
364
365 $r = "<tr id='item-action-{$item->id}'$style>";
366
367 list( $columns, $hidden, , $primary ) = $this->get_column_info();
368 $action_col = false;
369 $action_columns = $this->get_action_columns();
370
371 foreach ( $columns as $column_name => $column_display_name ) {
372 $class = $column_name . ' column-' . $column_name;
373
374 if ( $column_name === $primary ) {
375 $class .= ' column-primary';
376 }
377
378 if ( in_array( $column_name, $hidden, true ) ) {
379 $class .= ' hidden';
380 } elseif ( ! $action_col && ! in_array( $column_name, $action_columns, true ) ) {
381 $action_col = $column_name;
382 }
383
384 $attributes = 'class="' . esc_attr( $class ) . '"';
385 unset( $class );
386 $attributes .= ' data-colname="' . $column_display_name . '"';
387 $form_id = $this->params['form'] ? $this->params['form'] : 0;
388 $this->column_name = preg_replace( '/^(' . $form_id . '_)/', '', $column_name );
389
390 if ( $this->column_name === 'cb' ) {
391 $r .= "<th scope='row' class='check-column'>$checkbox</th>";
392 } else {
393 $val = in_array( $column_name, $hidden, true ) ? '' : $this->column_value( $item );
394 $r .= "<td $attributes>";
395
396 // phpcs:ignore Universal.Operators.StrictComparisons
397 if ( $column_name == $action_col ) {
398 $edit_link = admin_url( 'admin.php?page=formidable-entries&frm_action=edit&id=' . $item->id );
399 $r .= '<a href="' . esc_url( isset( $actions['edit'] ) ? $edit_link : $view_link ) . '" class="row-title" >' . $val . '</a> ';
400 $r .= $action_links;
401 } else {
402 $r .= $val;
403 }
404
405 $r .= '</td>';
406 }//end if
407 unset( $val );
408 }//end foreach
409 return $r . '</tr>';
410 }
411
412 /**
413 * Get the column names that the logged in user can action on
414 *
415 * @return string[]
416 */
417 private function get_action_columns() {
418 return array( 'cb', 'form_id', 'id', 'post_id' );
419 }
420
421 /**
422 * @param object $item
423 *
424 * @return mixed
425 */
426 private function column_value( $item ) {
427 $col_name = $this->maybe_fix_column_name( $this->column_name );
428
429 switch ( $col_name ) {
430 case 'ip':
431 case 'id':
432 case 'item_key':
433 $val = $item->{$col_name};
434 break;
435 case 'name':
436 $val = FrmAppHelper::truncate( strip_tags( $item->{$col_name} ), 100 );
437 break;
438 case 'created_at':
439 case 'updated_at':
440 $date = FrmAppHelper::get_formatted_time( $item->{$col_name} );
441 $val = '<abbr title="' . esc_attr( FrmAppHelper::get_formatted_time( $item->{$col_name}, '', 'g:i:s A' ) ) . '">' . $date . '</abbr>';
442 break;
443 case 'is_draft':
444 $entry_status = FrmEntriesHelper::get_entry_status_label( $item->is_draft );
445 $val = sprintf(
446 '<span class="frm-meta-tag frm-entry-status frm-entry-status-%s">%s</span>',
447 sanitize_html_class( $item->is_draft ),
448 esc_html( $entry_status )
449 );
450 break;
451 case 'form_id':
452 $form_id = $item->form_id;
453 $user_can_edit_forms = false === FrmAppHelper::permission_nonce_error( 'frm_edit_forms' );
454
455 if ( $user_can_edit_forms ) {
456 $val = FrmFormsHelper::edit_form_link( $form_id );
457 } else {
458 $val = FrmFormsHelper::edit_form_link_label( $form_id );
459 }
460 break;
461 case 'post_id':
462 $val = FrmAppHelper::post_edit_link( $item->post_id );
463 break;
464 case 'user_id':
465 $user = get_userdata( $item->user_id );
466 $val = $user ? $user->user_login : '';
467 break;
468 case 'parent_item_id':
469 $val = $item->parent_item_id;
470 break;
471 default:
472 $val = apply_filters( 'frm_entries_' . $col_name . '_column', false, compact( 'item' ) );
473
474 if ( $val === false ) {
475 $this->get_column_value( $item, $val );
476 }
477
478 /**
479 * Allows changing entries list column value.
480 *
481 * @since 5.1
482 *
483 * @param mixed $val Column value.
484 * @param array $args Contains `item` and `col_name`.
485 */
486 $val = apply_filters( 'frm_entries_column_value', $val, compact( 'item', 'col_name' ) );
487 }//end switch
488
489 return $val;
490 }
491
492 /**
493 * When a form has entries with the 0 item meta value, the values do not appear properly in the entries list.
494 *
495 * @since 6.11.2
496 *
497 * @param string $column_name
498 *
499 * @return string
500 */
501 private function maybe_fix_column_name( $column_name ) {
502 if ( str_starts_with( $column_name, '0_' ) ) {
503 return substr( $column_name, 2 );
504 }
505 return $column_name;
506 }
507
508 /**
509 * @param array $actions
510 * @param object $item
511 * @param string $view_link
512 *
513 * @return void
514 */
515 private function get_actions( &$actions, $item, $view_link ) {
516 $actions['view'] = '<a href="' . esc_url( $view_link ) . '">' . esc_html__( 'View', 'formidable' ) . '</a>';
517
518 if ( current_user_can( 'frm_delete_entries' ) ) {
519 $delete_link = '?page=formidable-entries&frm_action=destroy&id=' . $item->id . '&form=' . $this->params['form'];
520 $actions['delete'] = '<a href="' . esc_url( wp_nonce_url( $delete_link ) ) . '" class="submitdelete" data-frmverify="' . esc_attr__( 'Permanently delete this entry?', 'formidable' ) . '" data-frmverify-btn="frm-button-red">' . esc_html__( 'Delete', 'formidable' ) . '</a>'; // phpcs:ignore SlevomatCodingStandard.Files.LineLength.LineTooLong
521 }
522
523 $actions = apply_filters( 'frm_row_actions', $actions, $item );
524 }
525
526 /**
527 * @param object $item
528 * @param mixed $val
529 *
530 * @return void
531 */
532 private function get_column_value( $item, &$val ) {
533 $col_name = $this->column_name;
534
535 if ( str_starts_with( $col_name, 'frmsep_' ) ) {
536 $sep_val = true;
537 $col_name = str_replace( 'frmsep_', '', $col_name );
538 } else {
539 $sep_val = false;
540 }
541
542 if ( str_contains( $col_name, '-_-' ) ) {
543 list( $col_name, $embedded_field_id ) = explode( '-_-', $col_name );
544 }
545
546 $field = FrmField::getOne( $col_name );
547
548 if ( ! $field ) {
549 return;
550 }
551
552 $atts = array(
553 'type' => $field->type,
554 'truncate' => true,
555 'post_id' => $item->post_id,
556 'entry_id' => $item->id,
557 'embedded_field_id' => 0,
558 );
559
560 if ( $sep_val ) {
561 $atts['saved_value'] = true;
562 }
563
564 if ( isset( $embedded_field_id ) ) {
565 $atts['embedded_field_id'] = $embedded_field_id;
566 unset( $embedded_field_id );
567 }
568
569 $val = FrmEntriesHelper::prepare_display_value( $item, $field, $atts );
570 }
571
572 /**
573 * @return string
574 */
575 protected function confirm_bulk_delete() {
576 return sprintf(
577 /* translators: %1$s: HTML break line, %2$s: HTML bold text */
578 esc_html__( 'ALL entries in this form will be permanently deleted.%1$sWant to proceed? Type %2$s below.', 'formidable' ),
579 '<br/>',
580 '<b>DELETE ALL</b>'
581 );
582 }
583
584 /**
585 * @return string
586 */
587 protected function loaded_from() {
588 return 'entries-list';
589 }
590 }
591