PluginProbe
Contact Forms by Cimatti / 2.2.32
Contact Forms by Cimatti v2.2.32
2.3.6 2.3.5 2.3.0 2.2.32 2.2.4 2.2.0 2.1.2 2.1.1 trunk 1.0 1.1 1.2 1.2.1 1.3 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 All 62 releases
contact-forms / admin / list-page.php

list-page.php in Contact Forms by Cimatti 2.2.32, at admin/list-page.php

406 lines 15.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) exit;
3
4 if (!class_exists('WP_List_Table')) {
5 require_once(ABSPATH . 'wp-admin/includes/class-wp-list-table.php');
6 }
7
8 class Accua_Forms_List_Table extends WP_List_Table {
9 var $message = NULL;
10 var $active_items = 0;
11 var $del_items = 0;
12 var $accua_orderby = null;
13 var $accua_order_asc = null;
14
15 function __construct(){
16 global $status, $page;
17 $this->message = '';
18 parent::__construct(array(
19 'singular' => 'form',
20 'plural' => 'forms',
21 'ajax' => false
22 ));
23 }
24
25 function get_num_of_active_items(){
26 return $this->active_items;
27 }
28
29 function get_num_of_del_items(){
30 return $this->del_items;
31 }
32
33 function column_default($item, $column_name){
34 if (isset($item[$column_name])) {
35 return esc_attr($item[$column_name]);
36 } else {
37 return '';
38 }
39 }
40
41 function column_cb($item){
42 return sprintf(
43 '<input type="checkbox" name="%1$s[]" value="%2$s" />',
44 /*$1%s*/ $this->_args['singular'],
45 /*$2%s*/ $item['ID']
46 );
47 }
48
49 function column_title($item){
50 if ($item['deleted']) {
51 if (isset($item['title'])) {
52 $item_name = esc_html($item['title']);
53 } else {
54 $item_name = $item['ID'];
55 }
56 $nonced_edit = wp_nonce_url('admin.php?page=accua_forms_list&amp;fid=' . $item['ID'] . '&amp;restore=1', 'edit_posts');
57 $actions = array(
58 'edit' => "<a href='" . $nonced_edit . "'>" . __("Restore", 'contact-forms') . "</a>",
59 );
60 return "<strong>" . $item_name . "</strong>" . $this->row_actions($actions);
61 } else {
62 $nonced_edit = wp_nonce_url('admin.php?page=accua_forms_list&amp;fid=' . $item['ID'], 'edit_posts');
63 $nonced_clone = wp_nonce_url('admin.php?page=accua_forms_add&amp;clonefrom=' . $item['ID'], 'clone_posts');
64 $nonced_del = wp_nonce_url('admin.php?page=accua_forms_list&amp;fid_del=' . $item['ID'], 'trash_posts');
65 $actions = array(
66 'edit' => "<a href='{$nonced_edit}'>" . __("Edit", 'contact-forms') . "</a>"
67 . " &middot; <a href='{$nonced_clone}'>" . __("Clone", 'contact-forms') . "</a>"
68 . " &middot; <a href='admin.php?page=accua_forms_submissions_list&amp;fid={$item['ID']}'>" . __("Report", 'contact-forms') . "</a>"
69 . " &middot; <a href='{$nonced_del}'>" . __("Trash", 'contact-forms') . "</a>",
70 );
71 return "<strong><a class='row-title' href='{$nonced_edit}'>" . esc_html($item['title']) . "</a></strong>" . $this->row_actions($actions);
72 }
73 }
74
75 function column_submissions($item){
76 if ($item['submissions'] != 0)
77 return sprintf(
78 '<a href="admin.php?page=accua_forms_submissions_list&amp;fid=%1$s">%2$s</a>',
79 /*$1%s*/ $item['ID'],
80 /*$2%s*/ $item['submissions']
81 );
82 else
83 return "0";
84 }
85
86 function get_columns(){
87 $columns = array(
88 'cb' => '<input type="checkbox" />', //Render a checkbox instead of text
89 'title' => __('Title', 'contact-forms'),
90 'ID' => 'ID',
91 'shortcode' => __('Shortcode', 'contact-forms'),
92 'phpcode' => __('PHP code', 'contact-forms'),
93 'fromemail' => __('From Email', 'contact-forms'),
94 'fromname' => __('From Name', 'contact-forms'),
95 'adminemail' => __('Admin Email', 'contact-forms'),
96 'bccemail' => __('BCC Email', 'contact-forms'),
97 'retention' => __('Data Retention', 'contact-forms'),
98 'submissions' => __('Submissions', 'contact-forms'),
99 );
100 return $columns;
101 }
102
103 function column_retention( $item ) {
104 return isset( $item['retention'] ) ? esc_html( $item['retention'] ) : '';
105 }
106
107 function get_sortable_columns(){
108 return array(
109 'title' => array('title', false),
110 'ID' => array('ID', false),
111 'shortcode' => array('ID', false),
112 'phpcode' => array('ID', false),
113 'fromemail' => array('fromemail', false),
114 'fromname' => array('fromname', false),
115 'adminemail' => array('adminemail', false),
116 'bccemail' => array('bccemail', false),
117 'retention' => array('retention_seconds', false),
118 'submissions' => array('submissions', false),
119 );
120 }
121
122 function get_bulk_actions(){
123 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Display logic only, no data processing
124 if (isset($_GET['del']) && absint($_GET['del']) === 1) {
125 $actions = array();
126 } else {
127 $actions = array(
128 'delete' => __('Move to trash', 'contact-forms')
129 );
130 }
131 return $actions;
132 }
133
134 function set_message($single_message){
135 $this->message = $single_message;
136 }
137
138 function get_message(){
139 if ($this->message != NULL)
140 return $this->message;
141 else
142 return NULL;
143 }
144
145 function accua_usort_numeric($a, $b){
146 $result = ((int)$a[$this->accua_orderby]) - ((int)$b[$this->accua_orderby]);
147 if (!$result) {
148 $result = ((int)$a['ID']) - ((int)$b['ID']);
149 }
150 return ($this->accua_order_asc) ? $result : -$result;
151 }
152
153 function accua_usort_string($a, $b){
154 $result = strcasecmp($a[$this->accua_orderby], $b[$this->accua_orderby]);
155 if (!$result) {
156 $result = ((int)$a['ID']) - ((int)$b['ID']);
157 }
158 return ($this->accua_order_asc) ? $result : -$result;
159 }
160
161 function process_bulk_action(){
162 $current_action = $this->current_action();
163 if ($current_action) {
164 check_admin_referer('bulk-forms'); //check nonce generated for 'bulk-'.$this->_args['plural']
165 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash -- Values sanitized in array_map below
166 $forms_raw = (isset($_GET['form']) && is_array($_GET['form'])) ? wp_unslash($_GET['form']) : array();
167 $forms = array_map('sanitize_text_field', $forms_raw);
168 if ('delete' === $current_action) {
169 $forms_deleted = false;
170 $forms_data = get_option('accua_forms_saved_forms', array());
171 $trash_data = get_option('accua_forms_trash_forms', array());
172
173 foreach ($forms as $single_form) {
174 if (isset($forms_data[$single_form])) {
175 $trash_data[$single_form] = $forms_data[$single_form];
176 unset($forms_data[$single_form]);
177 $forms_deleted = true;
178 ?>
179 <script type="text/javascript">
180 jQuery(function($){
181 jQuery("#the-list tr:has(th.check-column input[type='checkbox'][value='<?php echo esc_js( $single_form ); ?>'])").fadeOut();
182 });
183 </script>
184 <?php
185 }
186 }
187 if ($forms_deleted) {
188 update_option('accua_forms_trash_forms', $trash_data);
189 update_option('accua_forms_saved_forms', $forms_data);
190 $this->set_message(__("Forms deleted", 'contact-forms'));
191 }
192
193 }
194 }
195 }
196
197 function prepare_items(){
198 global $wpdb, $hook_suffix;
199 $per_page = 50;
200 $del = isset($_GET['del']) && $_GET['del'] == 1;
201
202 $columns = $this->get_columns();
203 $hidden = get_hidden_columns($hook_suffix);
204 $sortable = $this->get_sortable_columns();
205
206 $this->_column_headers = array($columns, $hidden, $sortable);
207
208 $current_page = $this->get_pagenum();
209
210 $limit = ($current_page - 1) * $per_page;
211
212 $forms_data = get_option('accua_forms_saved_forms', array());
213 $forms_trash = get_option('accua_forms_trash_forms', array());
214 $forms_default = get_option('accua_forms_default_form_data', array());
215
216 $this->active_items = count($forms_data);
217 $this->del_items = count($forms_trash);
218
219 $data = array();
220 $global_retention = get_option( 'accua_forms_retention_data', array() );
221
222 if ($del) {
223 check_admin_referer('deleted_forms');
224 $start = $forms_trash;
225 } else {
226 $start = $forms_data;
227 }
228
229 foreach ($start as $id => $form) {
230 if (isset($form['title']) && (trim($form['title']) !== '')) {
231 $title = $form['title'];
232 } else {
233 $title = __('(no title)', 'contact-forms');
234 }
235
236 $data[$id] = array(
237 'ID' => $id,
238 'title' => $title,
239 'submissions' => 0,
240 'shortcode' => $del ? '' : '[accua-form fid="' . $id . '"]',
241 'phpcode' => $del ? '' : "<?php accua_forms_include('$id'); ?>",
242 'deleted' => $del,
243 );
244
245 $forminfos = array(
246 'fromemail' => 'emails_from',
247 'fromname' => 'emails_from_name',
248 'adminemail' => 'admin_emails_to',
249 'bccemail' => 'emails_bcc',
250 );
251
252 foreach ($forminfos as $infodest => $infoid) {
253 if (isset($form[$infoid])) {
254 $data[$id][$infodest] = $form[$infoid];
255 } else {
256 $data[$id][$infodest] = $forms_default[$infoid] . " (default)";
257 }
258 }
259
260 // Compute effective data retention column
261 $config = accua_forms_get_retention_config( $id );
262 $has_override = ! empty( $form['submission_retention_override'] );
263 $unit_labels = array( 'days' => __( 'days', 'contact-forms' ), 'months' => __( 'months', 'contact-forms' ), 'years' => __( 'years', 'contact-forms' ) );
264 $mode_labels = array( 'anonymize' => __( 'Anonymize', 'contact-forms' ), 'delete' => __( 'Delete', 'contact-forms' ) );
265 $data[$id]['retention_seconds'] = $config['seconds'];
266 if ( $config['seconds'] > 0 ) {
267 // Reverse-engineer the display value from the form or global settings
268 if ( $has_override ) {
269 $r_val = isset( $form['submission_retention_value'] ) ? (int) $form['submission_retention_value'] : 0;
270 $r_unit = isset( $form['submission_retention_unit'] ) ? $form['submission_retention_unit'] : 'months';
271 } else {
272 $r_val = isset( $global_retention['retention_value'] ) ? (int) $global_retention['retention_value'] : 0;
273 $r_unit = isset( $global_retention['retention_unit'] ) ? $global_retention['retention_unit'] : 'months';
274 }
275 $r_unit_label = $unit_labels[ $r_unit ] ?? $r_unit;
276 $r_mode_label = $mode_labels[ $config['mode'] ] ?? $config['mode'];
277 $data[$id]['retention'] = sprintf( '%d %s / %s', $r_val, $r_unit_label, $r_mode_label );
278 } else {
279 $data[$id]['retention'] = __( 'Keep indefinitely', 'contact-forms' );
280 }
281
282 }
283
284 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Custom table query for form submissions count
285 $submissions = $wpdb->get_results(
286 $wpdb->prepare(
287 "SELECT afs_form_id AS fid, count(*) AS submissions
288 FROM `{$wpdb->prefix}accua_forms_submissions`
289 WHERE afs_status >= %d
290 GROUP BY afs_form_id",
291 0
292 ),
293 OBJECT
294 );
295 foreach ($submissions as $fsub) {
296 if (isset($data[$fsub->fid])) {
297 $data[$fsub->fid]['submissions'] = $fsub->submissions;
298 } else if ($del) {
299 if (!isset($forms_data[$fsub->fid])) {
300 $data[$fsub->fid] = array(
301 'ID' => $fsub->fid,
302 'submissions' => $fsub->submissions,
303 'deleted' => true,
304 'shortcode' => '',
305 'phpcode' => '',
306 'fromemail' => '',
307 'fromname' => '',
308 'adminemail' => '',
309 'bccemail' => '',
310 );
311 $this->del_items++;
312 }
313 } else if (!isset($forms_trash[$fsub->fid])) {
314 $this->del_items++;
315 }
316 }
317
318 $numeric_keys = array( 'ID', 'submissions', 'retention_seconds' );
319 $string_keys = array( 'title', 'fromemail', 'fromname', 'adminemail', 'bccemail' );
320 $allowed_keys = array_merge( $numeric_keys, $string_keys );
321
322 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only sort parameter
323 $this->accua_orderby = isset($_GET['orderby']) ? sanitize_key(wp_unslash($_GET['orderby'])) : 'ID';
324 if ( ! in_array( $this->accua_orderby, $allowed_keys, true ) ) {
325 $this->accua_orderby = 'ID';
326 }
327 // Default order: ascending for string columns, descending for numeric columns
328 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only sort direction
329 if (empty($_GET['order'])) {
330 $this->accua_order_asc = in_array( $this->accua_orderby, $string_keys, true );
331 } else {
332 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only sort direction
333 $this->accua_order_asc = (sanitize_key(wp_unslash($_GET['order'])) !== 'desc');
334 }
335 if ( in_array( $this->accua_orderby, $numeric_keys, true ) ) {
336 usort($data, array(&$this, 'accua_usort_numeric'));
337 } else {
338 usort($data, array(&$this, 'accua_usort_string'));
339 }
340
341 $total_items = count($data);
342
343 $this->items = array_slice($data, $limit, $per_page);
344
345 $this->set_pagination_args(array(
346 'total_items' => $total_items,
347 'per_page' => $per_page,
348 'total_pages' => ceil($total_items / $per_page)
349 ));
350 }
351 }
352
353 function accua_forms_list_page_table($head = false){
354 static $listTable = null;
355 //var_dump($_REQUEST);
356
357 if (isset($_GET['fid_del'])) {
358 check_admin_referer('trash_posts');
359 $fid = sanitize_text_field( wp_unslash( $_GET['fid_del'] ) );
360 $forms_data = get_option('accua_forms_saved_forms', array());
361 if (isset($forms_data[$fid])) {
362 $trash_data = get_option('accua_forms_trash_forms', array());
363 $trash_data[$fid] = $forms_data[$fid];
364 update_option('accua_forms_trash_forms', $trash_data);
365 unset($forms_data[$fid]);
366 update_option('accua_forms_saved_forms', $forms_data);
367 }
368 }
369
370 if ($listTable === null) {
371 $listTable = new Accua_Forms_List_Table();
372 $listTable->process_bulk_action();
373 $listTable->prepare_items();
374 }
375
376 if ($head === true) {
377 return;
378 }
379
380 if ($listTable->get_message() != NULL) { ?>
381 <div class="updated"><p><?php echo esc_html( $listTable->get_message() ); ?></p></div>
382 <?php } ?>
383 <ul class="subsubsub">
384 <li>
385 <?php $nonced_url = wp_nonce_url('admin.php?page=accua_forms_list', 'home_forms') ?>
386 <a <?php if (!isset($_GET['del']) || ($_GET['del'] != 1)) { echo " class='current' "; } ?> href="<?php echo esc_url($nonced_url) ?>">
387 <?php esc_html_e("Active", 'contact-forms'); ?></a> (<?php echo esc_html($listTable->get_num_of_active_items()); ?>) |
388 </li>
389 <li>
390 <?php $nonced_url = wp_nonce_url('admin.php?page=accua_forms_list&del=1', 'deleted_forms'); ?>
391 <a <?php if (isset($_GET['del']) && ($_GET['del'] == 1)) { echo " class='current' "; } ?> href="<?php echo esc_url($nonced_url) ?>">
392 <?php esc_html_e("Trash", 'contact-forms'); ?></a> (<?php echo esc_html($listTable->get_num_of_del_items()); ?>)
393 </li>
394 </ul>
395
396 <form id="accua-forms-list-filter" method="get">
397 <input type="hidden" name="page" value="<?php echo esc_attr( isset( $_REQUEST['page'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['page'] ) ) : '' ); ?>" />
398 <?php
399 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- WP_List_Table display() outputs safe HTML
400 $listTable->display();
401 ?>
402 </form>
403 <?php /* echo '<pre>$listTable = ' htmlspecialchars(print_r($listTable, true)); ?></pre> */ ?>
404 <?php
405 }
406