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 / single-submission.php

single-submission.php in Contact Forms by Cimatti 2.2.32, at admin/single-submission.php

337 lines 17.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' ) ) exit;
3
4 // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Submission detail page with prepared queries
5
6 function accua_forms_single_submission_movetotrash($id_sub)
7 {
8 if (accua_forms_trash_submission($id_sub)) {
9 echo "<span class='savedsettings'>" . esc_html__('Moved 1 submission to trash.', 'contact-forms') . "</span>";
10 } else {
11 echo "<span class='error_savedsettings'>" . esc_html__('Error moving submissions to trash.', 'contact-forms') . "</span>";
12 }
13 }
14
15 function accua_forms_add_submission_note($id_sub, $note_text)
16 {
17 global $wpdb;
18 $time = time();
19 $current_date = gmdate('Y-m-d H:i:s', $time);
20
21 $current_user = wp_get_current_user();
22 $current_user_email = $current_user->user_email;
23
24 // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- Query is a template string with placeholders, prepared inline below
25 $query_add_note = "INSERT INTO {$wpdb->prefix}accua_forms_submissions_notes (afsn_sub_id, afsn_date, afsn_text, afsn_user) VALUES (%d, %s, %s, %s)";
26
27 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared -- Custom table requires direct query, query is prepared inline
28 if ($wpdb->query($wpdb->prepare($query_add_note, $id_sub, $current_date, sanitize_textarea_field($note_text), $current_user_email)) === false) {
29 return false;
30 }
31 return array(
32 'date' => $current_date,
33 'user' => $current_user->display_name,
34 );
35 }
36 function accua_forms_count_submission_note($id_sub)
37 {
38 global $wpdb;
39 // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- Query is a template string with placeholders, prepared inline below
40 $query_data_submission_notes = "SELECT DISTINCT COUNT(afsn_sub_id)
41 FROM `{$wpdb->prefix}accua_forms_submissions_notes`
42 WHERE `afsn_sub_id` = %d";
43 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared -- Custom table requires direct query, query is prepared inline
44 $count_submissions_form = $wpdb->get_var($wpdb->prepare($query_data_submission_notes, $id_sub));
45 return $count_submissions_form;
46 }
47 function accua_forms_return_submission_note($id_sub)
48 {
49 global $wpdb;
50 // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- Query is a template string with placeholders, prepared inline below
51 $query_data_submission_notes = "SELECT *
52 FROM `{$wpdb->prefix}accua_forms_submissions_notes`
53 WHERE `afsn_sub_id` = %d
54 ORDER BY `afsn_date` DESC";
55
56 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared -- Custom table requires direct query, query is prepared inline
57 $query_submission_notes = $wpdb->get_results($wpdb->prepare($query_data_submission_notes, $id_sub));
58
59 $del_nonce = wp_create_nonce( "submission_{$id_sub}_note_del" );
60 foreach ($query_submission_notes as $value) {
61 $note_user = get_user_by( 'email', $value->afsn_user );
62 $note_user_name = $note_user ? $note_user->display_name : $value->afsn_user;
63 echo '<div class="accua-note">
64 <div class="accua-note-content">' . esc_html($value->afsn_text) . '</div>
65 <p class="accua-note-meta">' . esc_html($value->afsn_date) . '<br>' . esc_html($note_user_name) . '
66 <span class="row-actions">
67 <button type="button" class="button-link accua-delete-note" data-subid="' . (int) $value->afsn_sub_id . '" data-date="' . esc_attr($value->afsn_date) . '" data-nonce="' . esc_attr($del_nonce) . '">' . esc_html__('Delete', 'contact-forms') . '</button>
68 </span>
69 </p>
70 </div>';
71 }
72 }
73
74 function accua_forms_delete_submission_note($sid, $date)
75 {
76 global $wpdb;
77 // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- Query is a template string with placeholders, prepared inline below
78 $query_delete_notes = "DELETE FROM `{$wpdb->prefix}accua_forms_submissions_notes` WHERE `afsn_sub_id` = %d AND `afsn_date` = %s";
79 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared -- Custom table requires direct query, query is prepared inline
80 return $wpdb->query($wpdb->prepare($query_delete_notes, $sid, $date)) !== false;
81 }
82
83
84 function accua_forms_single_submission($head = false)
85 {
86 wp_enqueue_style('accua-forms-admin', plugins_url('assets/css/admin.css', ACCUA_FORMS_FILE), array(), ACCUA_FORMS_CSS_VERSION);
87 wp_enqueue_script('accua-forms-set-lead-status', plugins_url('assets/js/admin/set-lead-status.js', ACCUA_FORMS_FILE), array('jquery'), ACCUA_FORMS_JS_VERSION, true);
88 wp_enqueue_script('accua-forms-single-submission', plugins_url('assets/js/admin/single-submission.js', ACCUA_FORMS_FILE), array('jquery'), ACCUA_FORMS_JS_VERSION, true);
89 wp_localize_script('accua-forms-single-submission', 'accuaSingleSubmission', array(
90 'l10n' => array(
91 'confirmAnonymize' => __('Are you sure you want to anonymize this submission? Personal data will be replaced with placeholders. This cannot be undone.', 'contact-forms'),
92 'anonymizing' => __('Anonymizing…', 'contact-forms'),
93 'anonymize' => __('Anonymize', 'contact-forms'),
94 'errorAnonymize' => __('Error anonymizing submission. Please try again.', 'contact-forms'),
95 'confirmDeleteNote' => __('Are you sure you want to delete this note?', 'contact-forms'),
96 'deleteNote' => __('Delete', 'contact-forms'),
97 'errorNote' => __('Error saving note. Please try again.', 'contact-forms'),
98 ),
99 ));
100 global $wpdb;
101 if (isset($_GET['sid'])) {
102 $sid = (int) $_GET['sid'];
103 }
104
105 if ($head === true) {
106 return;
107 }
108 if ($sid) {
109 // Handle GET-based trash action (WP standard link pattern)
110 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verified below before processing
111 if ( isset( $_GET['action'] ) && $_GET['action'] === 'trash' ) {
112 check_admin_referer( 'del_sub_form_' . $sid );
113 accua_forms_trash_submission( (int) $sid ); // Use echo-free function so redirect header can be sent
114 wp_safe_redirect( admin_url( 'admin.php?page=accua_forms_submissions_list&trashed=1' ) );
115 exit;
116 }
117 // Handle GET-based restore action
118 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verified below before processing
119 if ( isset( $_GET['action'] ) && $_GET['action'] === 'restore' ) {
120 check_admin_referer( 'restore_sub_form_' . $sid );
121 accua_forms_restore_submission( (int) $sid );
122 wp_safe_redirect( admin_url( 'admin.php?page=accua_forms_submissions_list&restored=1' ) );
123 exit;
124 }
125
126 $submission_row = $wpdb->get_row($wpdb->prepare("SELECT `afs_status`, `afs_anonymized` FROM `{$wpdb->prefix}accua_forms_submissions` WHERE `afs_id` = %d", $sid));
127 $form_status = $submission_row ? (int) $submission_row->afs_status : null;
128 $is_anonymized = $submission_row ? (int) $submission_row->afs_anonymized : 0;
129 $is_trashed = ( $form_status === -1 );
130 ?>
131 <div id="accua_forms_submissions_list_page" class="accua_forms_admin_page wrap">
132 <h1 class="wp-heading-inline"><?php
133 /* translators: %d: submission ID */
134 printf( esc_html__( 'Submission #%d', 'contact-forms' ), absint( $sid ) );
135 ?></h1>
136 <?php
137 $prev = $wpdb->get_var($wpdb->prepare("SELECT `afs_id` FROM `{$wpdb->prefix}accua_forms_submissions` WHERE `afs_status` >= 0 AND `afs_id` < %d ORDER BY `afs_id` DESC LIMIT 1", $sid));
138 $next = $wpdb->get_var($wpdb->prepare("SELECT `afs_id` FROM `{$wpdb->prefix}accua_forms_submissions` WHERE `afs_status` >= 0 AND `afs_id` > %d ORDER BY `afs_id` ASC LIMIT 1", $sid));
139 if ($prev !== null) {
140 echo '<a class="page-title-action" href="' . esc_url( admin_url( 'admin.php?page=accua_forms_submissions_list&sid=' . absint($prev) ) ) . '">&#8249; ' . esc_html__('Previous', 'contact-forms') . '</a>';
141 }
142 if ($next !== null) {
143 echo '<a class="page-title-action" href="' . esc_url( admin_url( 'admin.php?page=accua_forms_submissions_list&sid=' . absint($next) ) ) . '">' . esc_html__('Next', 'contact-forms') . ' &#8250;</a>';
144 }
145 ?>
146 <a class="page-title-action" href="<?php echo esc_url( admin_url( 'admin.php?page=accua_forms_submissions_list' ) ); ?>"><?php esc_html_e('All submissions', 'contact-forms'); ?></a>
147 <hr class="wp-header-end">
148
149 <?php if ( $is_anonymized ) { ?>
150 <div class="notice notice-warning inline">
151 <p><?php esc_html_e('This submission has been anonymized. Personal data has been replaced with placeholders.', 'contact-forms'); ?></p>
152 </div>
153 <?php } ?>
154
155 <?php
156 // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- Query is a template string with placeholders, prepared inline below
157 $query_data_submission = "SELECT *
158 FROM `{$wpdb->prefix}accua_forms_submissions`
159 WHERE `afs_id` = %d";
160
161 // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- Query is a template string with placeholders, prepared inline below
162 $query_data_submission_value = "SELECT *
163 FROM `{$wpdb->prefix}accua_forms_submissions_values`
164 WHERE `afsv_sub_id` = %d";
165
166 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared -- Custom table requires direct query, query is prepared inline
167 $data_submission = $wpdb->get_row($wpdb->prepare($query_data_submission, $sid));
168 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared -- Custom table requires direct query, query is prepared inline
169 $data_submission_values = $wpdb->get_results($wpdb->prepare($query_data_submission_value, $sid));
170 ?>
171
172 <?php if ( $data_submission ) { ?>
173 <?php
174 // Resolve form name
175 $forms_data = get_option( 'accua_forms_saved_forms', array() );
176 $form_name = isset( $forms_data[ $data_submission->afs_form_id ]['title'] )
177 ? $forms_data[ $data_submission->afs_form_id ]['title']
178 : '#' . $data_submission->afs_form_id;
179
180 // Resolve page title
181 $page_title = '';
182 if ( (int) $data_submission->afs_post_id > 0 ) {
183 $page_title = get_the_title( (int) $data_submission->afs_post_id );
184 }
185 ?>
186 <div id="poststuff">
187 <div id="post-body" class="metabox-holder columns-2">
188 <div id="post-body-content">
189 <div class="postbox">
190 <div class="postbox-header"><h2><?php esc_html_e('Submitted fields', 'contact-forms'); ?></h2></div>
191 <div class="inside">
192 <?php
193 // Build a field_id => label map from global fields
194 $avail_fields = get_option( 'accua_forms_avail_fields', array() );
195 $field_labels = array();
196 foreach ( $avail_fields as $field ) {
197 if ( ! empty( $field['id'] ) && ! empty( $field['name'] ) ) {
198 $field_labels[ $field['id'] ] = $field['name'];
199 }
200 }
201 ?>
202 <table class="widefat fixed striped">
203 <?php foreach ($data_submission_values as $value) {
204 // Skip internal/structural fields
205 if ( str_starts_with( $value->afsv_field_id, '__' ) || str_starts_with( $value->afsv_field_id, '_accua_' ) ) {
206 continue;
207 }
208
209 $label = $field_labels[ $value->afsv_field_id ] ?? ucwords( str_replace( array( '-', '_' ), ' ', $value->afsv_field_id ) );
210
211 if ($value->afsv_type === 'file') {
212 $fieldid = rawurlencode($value->afsv_field_id);
213 $filename = rawurlencode($value->afsv_value);
214 $url = admin_url('admin-ajax.php') . "?action=accua_forms_download_submitted_file&subid={$value->afsv_sub_id}&field={$fieldid}&file={$filename}&nonce=" . wp_create_nonce('accua_forms_download_nonce') . "&_wpnonce=" . wp_create_nonce('download_file_' . $value->afsv_sub_id . '_' . $fieldid);
215 echo '<tr>';
216 echo '<td>' . esc_html( $label ) . '</td>';
217 echo '<td><a href="' . esc_url( $url ) . '" target="_blank">' . esc_html( $value->afsv_value ) . '</a></td>';
218 echo '</tr>';
219 } else {
220 echo '<tr>';
221 echo '<td>' . esc_html( $label ) . '</td>';
222 echo '<td class="accua-field-value">' . esc_html( $value->afsv_value ) . '</td>';
223 echo '</tr>';
224 }
225 } ?>
226 </table>
227 </div>
228 </div>
229
230 <div class="postbox">
231 <div class="postbox-header"><h2><?php esc_html_e('Details', 'contact-forms'); ?></h2></div>
232 <div class="inside">
233 <table class="widefat fixed striped">
234 <tr>
235 <td><?php esc_html_e('Form', 'contact-forms'); ?></td>
236 <td><a href="<?php echo esc_url( wp_nonce_url( admin_url( 'admin.php?page=accua_forms_list&fid=' . absint( $data_submission->afs_form_id ) ), 'edit_posts' ) ); ?>"><?php echo esc_html( $form_name ); ?></a></td>
237 </tr>
238 <?php if ( $data_submission->afs_ip ) { ?>
239 <tr>
240 <td><?php esc_html_e('IP', 'contact-forms'); ?></td>
241 <td><?php echo esc_html( $data_submission->afs_ip ); ?></td>
242 </tr>
243 <?php } ?>
244 <?php if ( $data_submission->afs_lang ) { ?>
245 <tr>
246 <td><?php esc_html_e('Language', 'contact-forms'); ?></td>
247 <td><?php echo esc_html( $data_submission->afs_lang ); ?></td>
248 </tr>
249 <?php } ?>
250 <?php if ( $data_submission->afs_uri ) { ?>
251 <tr>
252 <td><?php esc_html_e('URI', 'contact-forms'); ?></td>
253 <td class="accua-field-value"><a href="<?php echo esc_url( home_url( $data_submission->afs_uri ) ); ?>" target="_blank"><?php echo esc_html( $data_submission->afs_uri ); ?></a></td>
254 </tr>
255 <?php } ?>
256 <?php if ( $data_submission->afs_referrer ) { ?>
257 <tr>
258 <td><?php esc_html_e('Referrer', 'contact-forms'); ?></td>
259 <td class="accua-field-value"><a href="<?php echo esc_url( $data_submission->afs_referrer ); ?>" target="_blank"><?php echo esc_html( $data_submission->afs_referrer ); ?></a></td>
260 </tr>
261 <?php } ?>
262 </table>
263 </div>
264 </div>
265
266 </div><!-- #post-body-content -->
267
268 <div id="postbox-container-1" class="postbox-container">
269 <div class="postbox">
270 <div class="postbox-header"><h2><?php esc_html_e('Submission', 'contact-forms'); ?></h2></div>
271 <div class="inside">
272 <?php if ( $data_submission->afs_created && $data_submission->afs_created !== $data_submission->afs_submitted ) { ?>
273 <p>
274 <strong><?php esc_html_e('Opened', 'contact-forms'); ?></strong><br>
275 <?php echo esc_html( wp_date( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), strtotime( $data_submission->afs_created ) ) ); ?>
276 </p>
277 <?php } ?>
278 <p>
279 <strong><?php esc_html_e('Submitted', 'contact-forms'); ?></strong><br>
280 <?php echo esc_html( wp_date( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), strtotime( $data_submission->afs_submitted ) ) ); ?>
281 </p>
282 <?php if ( $page_title ) { ?>
283 <p>
284 <strong><?php esc_html_e('Page', 'contact-forms'); ?></strong><br>
285 <a href="<?php echo esc_url( get_permalink( (int) $data_submission->afs_post_id ) ); ?>" target="_blank"><?php echo esc_html( $page_title ); ?></a>
286 </p>
287 <?php } ?>
288 <?php if ( ! $is_anonymized ) { ?>
289 <p><a href="#" id="accua-forms-anonymize-btn" data-subid="<?php echo absint($sid); ?>" data-nonce="<?php echo esc_attr( wp_create_nonce( "anonymize_sub_{$sid}" ) ); ?>"><?php esc_html_e('Anonymize personal data', 'contact-forms'); ?></a></p>
290 <?php } ?>
291 <p>
292 <?php if ( $is_trashed ) { ?>
293 <a href="<?php echo esc_url( wp_nonce_url( admin_url( 'admin.php?page=accua_forms_submissions_list&sid=' . absint($sid) . '&action=restore' ), 'restore_sub_form_' . $sid ) ); ?>"><?php esc_html_e('Restore from Trash', 'contact-forms'); ?></a>
294 <?php } else { ?>
295 <a class="submitdelete deletion" href="<?php echo esc_url( wp_nonce_url( admin_url( 'admin.php?page=accua_forms_submissions_list&sid=' . absint($sid) . '&action=trash' ), 'del_sub_form_' . $sid ) ); ?>" onclick='return window.confirm("<?php echo esc_js(__('Are you sure you want to trash this submission?', 'contact-forms')); ?>");'><?php esc_html_e('Move to Trash', 'contact-forms'); ?></a>
296 <?php } ?>
297 </p>
298 </div>
299 </div>
300 <div class="postbox">
301 <div class="postbox-header"><h2><?php esc_html_e('Lead status', 'contact-forms'); ?></h2></div>
302 <div class="inside">
303 <?php
304 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Function returns escaped HTML select element
305 echo accua_forms_select_lead_status( $data_submission->afs_id, $data_submission->afs_lead_status );
306 ?>
307 </div>
308 </div>
309 <div class="postbox">
310 <div class="postbox-header"><h2><?php esc_html_e('Notes', 'contact-forms'); ?></h2></div>
311 <div class="inside">
312 <div id="accua-notes-form">
313 <textarea id="note_site_user" rows="2" placeholder="<?php esc_attr_e('Add a note…', 'contact-forms'); ?>"></textarea>
314 <button type="button" id="accua-add-note-btn" class="button" data-subid="<?php echo absint($sid); ?>" data-nonce="<?php echo esc_attr( wp_create_nonce( "submission_{$sid}_note_add" ) ); ?>"><?php esc_html_e('Add note', 'contact-forms'); ?></button>
315 </div>
316 <div id="accua-notes-list">
317 <?php
318 $conta_note = accua_forms_count_submission_note($sid);
319 if ($conta_note > 0) {
320 accua_forms_return_submission_note($sid);
321 }
322 ?>
323 </div>
324 </div>
325 </div>
326 </div><!-- #postbox-container-1 -->
327 </div><!-- #post-body -->
328 </div><!-- #poststuff -->
329
330 <?php } ?>
331 </div>
332 <?php
333 }
334 }
335
336 // phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
337