PluginProbe
Contact Forms by Cimatti / 1.9.2
Contact Forms by Cimatti v1.9.2
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
← All changes | accua-forms.php +2516 -2534 2.3.01.9.2 View file →
@@ -1,84 +1,11 @@
1 1 <?php
2 -if ( ! defined( 'ABSPATH' ) ) exit;
3 -
4 -require_once __DIR__ . '/admin/fields-page.php';
5 -require_once __DIR__ . '/admin/settings-page.php';
6 -require_once __DIR__ . '/admin/form-editor.php';
7 -require_once __DIR__ . '/includes/data-deletion.php';
8 -require_once __DIR__ . '/includes/privacy.php';
9 -
10 -/**
11 - * Base fill colour for the admin sidebar menu icon.
12 - *
13 - * WordPress core (svg-painter.js) recolours base64 SVG menu icons to the active
14 - * admin colour scheme on load. We resolve that same base colour here and bake it
15 - * into the icon so the first server-rendered paint already matches the painted
16 - * result, avoiding a brief flash of a differently coloured icon before the JS
17 - * repaint. Colour schemes are registered on admin_init (priority 1) which runs
18 - * after admin_menu, so the exact colour is applied later by
19 - * accua_forms_paint_menu_icon() rather than at menu-registration time.
20 - */
21 -function accua_forms_admin_menu_icon_color(){
22 - global $_wp_admin_css_colors;
23 - $scheme = get_user_option('admin_color');
24 -
25 - if ( empty($scheme) || ! isset($_wp_admin_css_colors[$scheme]) ) {
26 - $scheme = 'modern';
27 - }
28 -
29 - if ( ! empty($_wp_admin_css_colors[$scheme]->icon_colors['base']) ) {
30 - return $_wp_admin_css_colors[$scheme]->icon_colors['base'];
31 - }
32 -
33 - if ( ! empty($_wp_admin_css_colors['modern']->icon_colors['base']) ) {
34 - return $_wp_admin_css_colors['modern']->icon_colors['base'];
35 - }
36 -
37 - return '#a7aaad'; // WordPress default menu icon base colour.
38 -}
39 -
40 -/**
41 - * Monochrome sidebar menu icon as a base64 data URI.
42 - *
43 - * The standalone brand icon (assets/img/accua-contacts-forms.svg) stays coloured
44 - * and is used unchanged in page headers and other contexts; only the sidebar menu
45 - * icon is neutral, per the WordPress.org plugin guidelines.
46 - */
47 -function accua_forms_admin_menu_icon(){
48 - $color = accua_forms_admin_menu_icon_color();
49 - $svg = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 44.46 44.46"><path fill="' . esc_attr($color) . '" d="m23.97,28.72c1.85,0,2.93-.11,2.93-.11,1.49-.15,2.75.95,2.8,2.44l.01.14c.05,1.5-1.11,2.96-2.58,3.25,0,0-2.53.5-5.25.5-7.24,0-10.11-3.84-10.11-12.98,0-8.6,3.01-12.44,10.26-12.44,2.82,0,5.11.47,5.11.47,1.47.3,2.63,1.78,2.57,3.27l-.01.15c-.05,1.5-1.31,2.6-2.8,2.45,0,0-1.13-.12-2.98-.12-4.67,0-5.54,1.6-5.54,6.22,0,5.2.92,6.76,5.59,6.76M33.36,1.93c-1.06-1.06-3.15-1.93-4.65-1.93H15.75c-1.5,0-3.59.87-4.65,1.93L1.93,11.1C.87,12.16,0,14.25,0,15.75v12.97c0,1.5.87,3.59,1.93,4.65l9.17,9.17c1.06,1.06,3.15,1.93,4.65,1.93h12.97c1.5,0,3.59-.87,4.65-1.93l9.17-9.17c1.06-1.06,1.93-3.15,1.93-4.65V15.75c0-1.5-.87-3.59-1.93-4.65z"/></svg>';
50 - return 'data:image/svg+xml;base64,' . base64_encode($svg);
51 -}
52 -
53 -/**
54 - * Repaint the sidebar menu icon with the active colour scheme's base colour.
55 - *
56 - * Runs on admin_init (priority 20, after register_admin_color_schemes at 1) when
57 - * the colour schemes are available. The icon set at menu-registration time uses
58 - * the fallback colour; here we overwrite it in the $menu global with the exact
59 - * scheme colour so the first paint matches svg-painter.js and there is no flash.
60 - */
61 -add_action('admin_init', 'accua_forms_paint_menu_icon', 20);
62 -function accua_forms_paint_menu_icon(){
63 - global $menu;
64 - if ( ! is_array($menu) ) {
65 - return;
66 - }
67 - foreach ( $menu as $i => $item ) {
68 - if ( isset($item[2]) && 'accua_forms' === $item[2] ) {
69 - $menu[$i][6] = accua_forms_admin_menu_icon();
70 - break;
71 - }
72 - }
73 -}
74 -
75 2 add_action('admin_menu', 'accua_forms_menu', -95);
76 3 function accua_forms_menu(){
77 - $dashboard_admin_page=add_menu_page('Contact Forms by Cimatti', 'Contact Forms', 'manage_options', 'accua_forms', 'accua_forms_dashboard_page', accua_forms_admin_menu_icon(), '90.90300');
4 + $dashboard_admin_page=add_menu_page('Wordpress Contact Forms by Cimatti', 'Contact Forms', 'manage_options', 'accua_forms', 'accua_forms_dashboard_page', ACCUA_FORMS_DIR_URL.'img/cimatti-icon-10.png', '90.90300');
78 5 add_action('load-'.$dashboard_admin_page, 'accua_forms_dashboard_page_head');
79 6
80 - add_submenu_page('accua_forms', 'Contact Forms by Cimatti', 'Dashboard', 'manage_options', "accua_forms", 'accua_forms_dashboard_page');
7 + add_submenu_page('accua_forms', 'Wordpress Contact Forms by Cimatti', 'Dashboard', 'manage_options', "accua_forms", 'accua_forms_dashboard_page');
81 8
82 9 $form_edit_page = add_submenu_page('accua_forms', 'Forms', 'Forms', 'manage_options', "accua_forms_list", 'accua_forms_list_page');
83 10 add_action('admin_head-'.$form_edit_page, 'accua_forms_edit_page_head');
84 11 add_action( 'admin_print_styles-'.$form_edit_page, 'accua_forms_edit_page_head_styles');
@@ -89,15 +16,14 @@
89 16 add_action( 'admin_print_styles-'.$form_add_page, 'accua_forms_edit_page_head_styles');
90 17 add_action( 'admin_print_scripts-'.$form_add_page, 'accua_forms_edit_page_head_scripts');
91 18
92 19 $form_submissions_page = add_submenu_page('accua_forms', __('Forms submissions', 'contact-forms') , __('Submissions', 'contact-forms'), 'manage_options', "accua_forms_submissions_list", '__accua_forms_submissions_list_page');
93 - add_action('load-'.$form_submissions_page, 'accua_forms_submissions_list_page_load');
94 20 add_action('admin_head-'.$form_submissions_page, 'accua_forms_submissions_list_page_head');
95 21 add_action( 'admin_print_styles-'.$form_submissions_page, 'accua_forms_edit_page_head_styles');
96 22
97 23 $form_fields_page = add_submenu_page('accua_forms', __( 'Form fields', 'contact-forms'), __('Fields', 'contact-forms'), 'manage_options', "accua_forms_fields", 'accua_forms_fields_page');
24 + //add_action('admin_head-'.$form_fields_page, 'accua_forms_fields_page_head');
98 25 add_action( 'admin_print_styles-'.$form_fields_page, 'accua_forms_edit_page_head_styles');
99 - add_action( 'admin_print_scripts-'.$form_fields_page, 'accua_forms_fields_page_enqueue_scripts');
100 26
101 27 $settings_page = add_submenu_page('accua_forms', __( 'Default Forms settings', 'contact-forms'), __('Settings', 'contact-forms'), 'manage_options', "accua_forms_settings", 'accua_forms_settings_page');
102 28 add_action( 'admin_print_styles-'.$settings_page, 'accua_forms_edit_page_head_styles');
103 29 add_action( 'admin_print_scripts-'.$settings_page, 'accua_forms_settings_page_head_scripts');
@@ -104,53 +30,173 @@
104 30
105 31 wp_enqueue_script('jquery-form');
106 32 wp_enqueue_script('jquery-color');
107 33 wp_enqueue_script('jquery-ui-core');
34 + wp_enqueue_script('jquery-ui-tabs');
108 35 wp_enqueue_script('jquery-ui-sortable');
109 36 wp_enqueue_script('jquery-ui-draggable');
110 37 wp_enqueue_script('jquery-ui-droppable');
38 + wp_enqueue_script('jquery-ui-selectable');
111 39 wp_enqueue_script('jquery-ui-resizable');
40 + wp_enqueue_script('jquery-ui-dialog');
41 + wp_enqueue_style('wp-jquery-ui-dialog');
112 42 }
113 43
44 +function accua_forms_report_page_head(){
45 + $column_list = array(
46 + 'month' => __( 'Month', 'contact-forms'),
47 + 'unique_submissions' => __( 'Unique submissions', 'contact-forms') ,
48 + 'submissions' => __('Total submissions', 'contact-forms'),
49 + );
50 + global $hook_suffix;
51 + register_column_headers($hook_suffix, $column_list);
52 +
53 + //$baseurl = WP_PLUGIN_URL.'/'.substr(plugin_basename(__FILE__),0,-strlen(basename(__FILE__)));
54 + //echo '<link href="'.$baseurl.'/flot/layout.css" rel="stylesheet" type="text/css">';
55 + //echo '<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="'.$baseurl.'/flot/excanvas.min.js"></script><![endif]-->';
56 + //echo '<script language="javascript" type="text/javascript" src="'.$baseurl.'/flot/jquery.flot.js"></script>';
57 +
58 +}
59 +
60 +
61 +function accua_forms_report_page() {
62 +?>
63 + <div id="accua_forms_report_page" class="accua_forms_admin_page wrap">
64 + <h2>Forms submissions report</h2>
65 +
66 +<?php
67 + global $wpdb, $hook_suffix;
68 + $months = array(1 => 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December');
69 +
70 + $query = "SELECT YEAR(sub_date) AS `year`, MONTH(sub_date) AS `month`, COUNT(DISTINCT `email`) AS `unique_submissions`, COUNT(*) AS `submissions`
71 + FROM `{$wpdb->prefix}cformssubmissions`
72 + GROUP BY `year`, `month`
73 + ORDER BY `year` DESC, `month` DESC";
74 +
75 + $results = $wpdb->get_results($query);
76 +
77 + if ($results) {
78 +?>
79 + <style type="text/css">
80 + .column-submissions, .column-unique_submissions {
81 + text-align: right !important;
82 + }
83 + </style>
84 + <div id="accua-form-report-graph" style="height:300px;"></div>
85 + <table class="widefat" id="stnl_review_reviewed">
86 + <thead>
87 + <tr><?php print_column_headers($hook_suffix); ?></tr>
88 + </thead>
89 +
90 + <tfoot>
91 + <tr><?php print_column_headers($hook_suffix, false); ?></tr>
92 + </tfoot>
93 +
94 + <tbody>
95 +<?php
96 + $alternate = false;
97 + $hidden = get_hidden_columns($hook_suffix);
98 + $data = array(
99 + array( 'label' => __( 'Unique submissions', 'contact-forms'), 'data' => array()),
100 + array( 'label' => __( 'Total submissions', 'contact-forms'), 'data' => array()),
101 + );
102 + foreach ($results as $result){
103 + $month = $months[$result->month];
104 + echo "<tr class='iedit ".(($alternate = !$alternate)?'alternate':'')."'>\n";
105 + echo "<td class='column-month'".(in_array('month', $hidden)?" style='display:none;'":'').">$month {$result->year}</td>\n";
106 + echo "<td class='column-unique_submissions'".(in_array('unique_submissions', $hidden)?" style='display:none;'":'').">{$result->unique_submissions}</td>\n";
107 + echo "<td class='column-submissions'".(in_array('submissions', $hidden)?" style='display:none;'":'').">{$result->submissions}</td>\n";
108 + echo "</tr>\n";
109 + $time = mktime(0, 0, 0, $result->month, 1, $result->year) * 1000;
110 + $data[0]['data'][] = array($time, (int)$result->unique_submissions);
111 + $data[1]['data'][] = array($time, (int)$result->submissions);
112 + }
113 + /*
114 + $year = $results[0]->year;
115 + $month = $results[0]->month;
116 + while ($year <= $result->year || $month <= $result->month) {
117 +
118 + $month++;
119 + if ($month > 12) {
120 + $year++;
121 + $month = 1;
122 + }
123 + }
124 + */
125 +?>
126 + </tbody>
127 + </table>
128 +<script type="text/javascript">
129 +jQuery(function($){
130 + var data = <?php print _accua_forms_json_encode($data); ?> ;
131 + var options = {
132 + xaxis: {
133 + //autoscaleMargin: 0.005,
134 + mode: "time",
135 + timeformat: "%b %y",
136 + minTickSize: [1, "month"]
137 + },
138 + legend: {
139 + position: "nw"
140 + }
141 + };
142 + $.plot($("#accua-form-report-graph"), data, options);
143 +});
144 +</script>
145 +<?php
146 + }
147 +?>
148 +
149 + </div>
150 +<?php
151 +}
152 +
114 153 function accua_forms_edit_page_head_styles() {
115 - wp_enqueue_style( 'accua-forms-admin', plugins_url('assets/css/admin.css', ACCUA_FORMS_FILE), array(), ACCUA_FORMS_CSS_VERSION); //
154 + //wp_admin_css( 'widgets' );
155 + wp_enqueue_style( 'wp-pointer' ); //for tooltips
156 + wp_enqueue_style( 'accua-forms-admin', plugins_url('accua-forms-admin.css', ACCUA_FORMS_FILE), array(), ACCUA_FORMS_CSS_VERSION); //
116 157 }
117 158
118 -add_action( 'admin_enqueue_scripts', 'accua_forms_enqueue_deactivation_modal' );
119 -function accua_forms_enqueue_deactivation_modal( $hook ) {
120 - if ( $hook !== 'plugins.php' ) {
121 - return;
122 - }
159 +function accua_forms_edit_page_head_scripts() {
160 + //wp_enqueue_script('admin-widgets');
161 + /*wp_enqueue_script('jquery-ui-sortable');
162 + wp_enqueue_script('jquery-ui-draggable');
163 + wp_enqueue_script('jquery-ui-droppable');*/
164 + wp_enqueue_script( 'wp-pointer' ); //for tooltips
165 + wp_enqueue_script('accua-jqColorPicker', plugins_url('/js/jqColorPicker.min.js', ACCUA_FORMS_FILE ), array( 'jquery' ), ACCUA_FORMS_JS_VERSION);
123 166
124 - wp_enqueue_script(
125 - 'accua-forms-deactivation-modal',
126 - plugins_url( 'assets/js/admin/deactivation-modal.js', ACCUA_FORMS_FILE ),
127 - array( 'jquery' ),
128 - ACCUA_FORMS_JS_VERSION,
129 - true
130 - );
167 + wp_enqueue_script( 'accua-form-fields', plugins_url( 'form-fields.js' , ACCUA_FORMS_FILE ), array( 'jquery-ui-sortable', 'jquery-ui-draggable', 'jquery-ui-droppable' ), ACCUA_FORMS_JS_VERSION);
168 + wp_enqueue_script( 'accua-form-settings', plugins_url('form-settings.js', ACCUA_FORMS_FILE), array('jquery'), ACCUA_FORMS_JS_VERSION);
169 +}
131 170
132 - wp_localize_script( 'accua-forms-deactivation-modal', 'accuaFormsDeactivation', array(
133 - 'ajaxUrl' => admin_url( 'admin-ajax.php' ),
134 - 'nonce' => wp_create_nonce( 'accua_forms_deactivation_cleanup' ),
135 - 'pluginBasename' => plugin_basename( ACCUA_FORMS_FILE ),
136 - 'i18n' => array(
137 - 'title' => __( 'What would you like to do with your Contact Forms data?', 'contact-forms' ),
138 - 'description' => __( 'You are about to deactivate Contact Forms. Choose what to do with your existing data:', 'contact-forms' ),
139 - 'deleteAll' => __( 'Delete all data', 'contact-forms' ),
140 - 'deleteAllDesc' => __( 'Permanently remove all forms, submissions, settings, and uploaded files. This cannot be undone.', 'contact-forms' ),
141 - 'anonymizeAll' => __( 'Anonymize all submissions', 'contact-forms' ),
142 - 'anonymizeAllDesc'=> __( 'Replace personal data with placeholders and set IPs to 0.0.0.0. Forms and settings will be kept. This cannot be undone.', 'contact-forms' ),
143 - 'skip' => __( 'Just deactivate', 'contact-forms' ),
144 - 'skipDesc' => __( 'Keep all data. You can reactivate the plugin later.', 'contact-forms' ),
145 - 'confirmDelete' => __( 'Are you sure? This will permanently delete ALL forms, submissions, settings, and uploaded files. This cannot be undone.', 'contact-forms' ),
146 - 'confirmAnonymize'=> __( 'Are you sure? This will anonymize ALL submissions, replacing personal data with placeholders. This cannot be undone.', 'contact-forms' ),
147 - 'processing' => __( 'Processing…', 'contact-forms' ),
148 - 'cancel' => __( 'Cancel', 'contact-forms' ),
149 - ),
150 - ) );
171 +function accua_forms_settings_page_head_scripts() {
172 + wp_enqueue_script('accua-jqColorPicker', plugins_url('/js/jqColorPicker.min.js', ACCUA_FORMS_FILE ), array( 'jquery' ), ACCUA_FORMS_JS_VERSION);
151 173 }
152 174
175 +function accua_forms_edit_page_head() {
176 +if (isset($_POST['accua-form-edit-action']) || (!isset($_GET['fid']))) {
177 + _accua_forms_form_edit_action();
178 + require_once('accua-forms-list-page.php');
179 + accua_forms_list_page_table(true);
180 +}
181 +
182 +?>
183 + <style type="text/css">
184 + .container > div {
185 + padding: 0px;
186 + margin-bottom: 6px;
187 + }
188 + .widget-liquid-right .widget, #wp_inactive_widgets .widget, .widget-liquid-right .sidebar-description, .widget-placeholder {
189 + width: 95%;
190 + }
191 + .column-submissions {
192 + text-align: right !important;
193 + }
194 + </style>
195 +<?php
196 +}
197 +
198 +add_action( 'wp_ajax_accua-form-fields-order' , 'accua_forms_form_fields_order');
153 199 function accua_forms_form_fields_order() {
154 200 if (!current_user_can('manage_options')){
155 201 wp_die( -1, 403 );
156 202 }
@@ -156,29 +202,28 @@
156 202 }
157 203 check_ajax_referer('edit_form', '_nonce_edit_form');
158 204
159 205 $post = stripslashes_deep($_POST);
206 + //update_option('accua_forms_form_fields_order_post', $post);
160 207
161 208 if (empty($post['sidebars'])) {
162 209 die('-1');
163 210 }
164 211
165 - // Save to draft instead of directly to database
166 - foreach ($post['sidebars'] as $sidebar_id => $order) {
167 - if (strpos($sidebar_id, 'cimatti-accua-fields-form-area-') !== 0){
212 + $forms_data = get_option('accua_forms_saved_forms', array());
213 +
214 + foreach ($post['sidebars'] as $fid => $order) {
215 + if (strpos($fid, 'cimatti-accua-fields-form-area-') !== 0){
168 216 die('-1');
169 217 }
170 - $fid = substr($sidebar_id, 31);
218 + $fid = substr($fid, 31);
171 219
172 - // Get draft data for this form
173 - $draft_data = _accua_forms_get_draft_data($fid);
174 -
175 - if (empty($draft_data['fields'])) {
220 + if (empty($forms_data[$fid]['fields'])) {
176 221 die('-1');
177 222 }
178 223
179 - $old_fields = $draft_data['fields'];
180 - unset($draft_data['fields']);
224 + $old_fields = $forms_data[$fid]['fields'];
225 + unset($forms_data[$fid]['fields']);
181 226 $new_fields = array();
182 227
183 228 $order = explode(',', $order);
184 229
@@ -192,19 +237,18 @@
192 237
193 238 if($old_fields){
194 239 $new_fields += $old_fields;
195 240 }
196 - $draft_data['fields'] = $new_fields;
241 + $forms_data[$fid]['fields'] = $new_fields;
242 + }
197 243
198 - // Save to draft (not to live database)
199 - _accua_forms_save_draft($fid, $draft_data);
200 - }
244 + update_option('accua_forms_saved_forms', $forms_data);
201 245
202 246 die('1');
203 247 }
204 248
205 249 add_action( 'wp_ajax_accua-save-form-field', 'accua_forms_save_form_field');
206 -/* azione dove vengono salvati i campi dei un form - saves to draft */
250 +/* azione dove vengono salvati i campi dei un form */
207 251 function accua_forms_save_form_field() {
208 252 if (!current_user_can('manage_options')){
209 253 wp_die( -1, 403 );
210 254 }
@@ -211,17 +255,17 @@
211 255 check_ajax_referer('edit_form', '_nonce_edit_form');
212 256
213 257 $post = stripslashes_deep($_POST);
214 258
259 + //update_option('accua_forms_save_form_field_post', $post);
260 +
261 + $forms_data = get_option('accua_forms_saved_forms', array());
215 262 $fid = $post['form-id'];
216 263 if (accua_forms_validate_form_id($fid) !== '') {
217 264 die('-1');
218 265 }
219 -
220 - // Get draft data instead of live data
221 - $draft_data = _accua_forms_get_draft_data($fid);
222 - if (empty($draft_data['fields'])) {
223 - $draft_data['fields'] = array();
266 + if (empty($forms_data[$fid]['fields'])) {
267 + $forms_data[$fid]['fields'] = array();
224 268 }
225 269
226 270 $avail_fields = get_option('accua_forms_avail_fields', array());
227 271 @ $wid = (string) $post['widget-id'];
@@ -234,8 +278,9 @@
234 278 die('-1');
235 279 }
236 280 }
237 281 if (empty($post['delete_widget'])) {
282 + //$istance_id = $post['multi_number'];
238 283 @ $ref = $post['id_base'];
239 284 if ($ref !== $check_ref) {
240 285 die('-1');
241 286 }
@@ -241,15 +286,15 @@
241 286 }
242 287 $required = !empty($post["form-field-{$wid}-required"]);
243 288 $widget_number = empty($post['multi_number']) ? (empty($post['widget_number']) ? '' : (int)$post['widget_number']) : (int)$post['multi_number'];
244 289
245 - if (isset($draft_data['fields'][$wid])) {
246 - $old_istance_data = $draft_data['fields'][$wid];
290 + if (isset($forms_data[$fid]['fields'][$wid])) {
291 + $old_istance_data = $forms_data[$fid]['fields'][$wid];
247 292 } else {
248 293 $old_istance_data = array();
249 294 }
250 295
251 - $draft_data['fields'][$wid] = array (
296 + $forms_data[$fid]['fields'][$wid] = array (
252 297 'version' => 2,
253 298 'istance_id' => $wid,
254 299 'widget_number' => $widget_number,
255 300 'ref' => $ref,
@@ -260,9 +305,9 @@
260 305 @ $label = (string) $post["form-field-{$wid}-label"];
261 306 if (!current_user_can('unfiltered_html')) {
262 307 $label = wp_kses($label, 'post');
263 308 }
264 - $draft_data['fields'][$wid]['label'] = $label;
309 + $forms_data[$fid]['fields'][$wid]['label'] = $label;
265 310 }
266 311
267 312 $is_file = false;
268 313 $is_date = false;
@@ -268,9 +313,9 @@
268 313 $is_date = false;
269 314 if (isset($avail_fields[$wid]['type'])) {
270 315 if ($avail_fields[$wid]['type'] == 'file') {
271 316 $is_file = true;
272 - } elseif ($avail_fields[$wid]['type'] == 'date') {
317 + } else if ($avail_fields[$wid]['type'] == 'date') {
273 318 $is_date = true;
274 319 }
275 320 }
276 321
@@ -277,140 +322,36 @@
277 322 if (!empty($post["form-field-{$wid}-override-default-value"])) {
278 323 @ $default_value = (string) $post["form-field-{$wid}-default-value"];
279 324 if ($is_date) {
280 325 $default_value = accua_forms_filter_date($default_value);
281 - } elseif (!current_user_can('unfiltered_html')) {
326 + } else if (!current_user_can('unfiltered_html')) {
282 327 //This is filtered in any case because field type can change
283 328 $default_value = wp_kses($default_value, 'post');
284 329 }
285 - $draft_data['fields'][$wid]['default_value'] = $default_value;
330 + $forms_data[$fid]['fields'][$wid]['default_value'] = $default_value;
286 331 }
287 332
288 333 if (!empty($post["form-field-{$wid}-override-allowed-values"])) {
289 334 @ $allowed_values = (string) $post["form-field-{$wid}-allowed-values"];
290 335 if ($is_file){
291 - $draft_data['fields'][$wid]['allowed_extensions'] = accua_forms_filter_extensions($allowed_values);
336 + $forms_data[$fid]['fields'][$wid]['allowed_extensions'] = accua_forms_filter_extensions($allowed_values);
292 337 } else {
293 - $draft_data['fields'][$wid]['allowed_values'] = $allowed_values;
338 + $forms_data[$fid]['fields'][$wid]['allowed_values'] = $allowed_values;
294 339 }
295 340 }
296 341 if (!empty($post["form-field-{$wid}-override-datemin-values"])) {
297 342 @ $mindate_values = (string) $post["form-field-{$wid}-min-of-date"];
298 - $draft_data['fields'][$wid]['min_date'] = accua_forms_filter_date($mindate_values);
343 + $forms_data[$fid]['fields'][$wid]['min_date'] = accua_forms_filter_date($mindate_values);
299 344 }
300 345 if (!empty($post["form-field-{$wid}-override-datemax-values"])) {
301 346 @ $maxdate_values = (string) $post["form-field-{$wid}-max-of-date"];
302 - $draft_data['fields'][$wid]['max_date'] = accua_forms_filter_date($maxdate_values);
347 + $forms_data[$fid]['fields'][$wid]['max_date'] = accua_forms_filter_date($maxdate_values);
303 348 }
304 -
305 - // Save post_type for post-select and post-multicheckbox fields
306 - if (isset($post["form-field-{$wid}-post-type"])) {
307 - @ $post_type_value = (string) $post["form-field-{$wid}-post-type"];
308 - // Validate post type
309 - $valid_post_types = get_post_types(array('public' => true));
310 - if (isset($valid_post_types[$post_type_value])) {
311 - $draft_data['fields'][$wid]['post_type'] = $post_type_value;
312 - }
313 - }
314 -
315 - // Save spam action for reCAPTCHA v2/v3 fields (silent classification).
316 - // Only written when the "override" box is ticked — otherwise the instance
317 - // follows the site-wide default from the settings page.
318 - if (!empty($post["form-field-{$wid}-override-spam-action"]) && isset($post["form-field-{$wid}-spam-action"])) {
319 - $spam_action_value = sanitize_text_field($post["form-field-{$wid}-spam-action"]);
320 - if (isset(accua_forms_captcha_spam_action_options()[$spam_action_value])) {
321 - $draft_data['fields'][$wid]['spam_action'] = $spam_action_value;
322 - }
323 - }
324 -
325 - // Save the minimum reCAPTCHA v3 score for captcha_v3 fields
326 - if (!empty($post["form-field-{$wid}-override-score-threshold"]) && isset($post["form-field-{$wid}-score-threshold"])
327 - && is_numeric($post["form-field-{$wid}-score-threshold"])) {
328 - $draft_data['fields'][$wid]['score_threshold'] = accua_forms_recaptcha3_clamp_score($post["form-field-{$wid}-score-threshold"]);
329 - }
330 -
331 - // Save the hide-title flag for captcha fields. The override box decides
332 - // whether the value is stored at all: a missing key means the instance
333 - // follows the site-wide default resolved by
334 - // accua_forms_captcha_hide_title().
335 - if (!empty($post["form-field-{$wid}-override-hide-title"])
336 - && isset($avail_fields[$wid]['type'])
337 - && in_array($avail_fields[$wid]['type'], array('captcha', 'captcha_v3', 'cap'), true)) {
338 - $draft_data['fields'][$wid]['hide_title'] = empty($post["form-field-{$wid}-hide-title"]) ? 0 : 1;
339 - }
340 -
341 - // Save country_code for telephone fields (for libphonenumber validation)
342 - if (isset($post["form-field-{$wid}-country-code"])) {
343 - $country_code = strtoupper(sanitize_text_field($post["form-field-{$wid}-country-code"]));
344 - // Validate against the list of countries
345 - $valid_countries = accua_forms_get_countries();
346 - if (isset($valid_countries[$country_code])) {
347 - $draft_data['fields'][$wid]['country_code'] = $country_code;
348 - }
349 - }
350 -
351 - /**
352 - * Filter field instance data before saving to draft.
353 - *
354 - * @param array $field_instance The field instance data being saved.
355 - * @param string $widget_id The field widget ID.
356 - * @param array $post_data The raw POST data (already stripslashed).
357 - * @param array $field_def The field definition from avail_fields.
358 - */
359 - $draft_data['fields'][$wid] = apply_filters(
360 - 'accua_forms_save_field_data',
361 - $draft_data['fields'][$wid],
362 - $wid,
363 - $post,
364 - isset($avail_fields[$wid]) ? $avail_fields[$wid] : array()
365 - );
366 -
367 - // Save custom CSS class for the field wrapper
368 - if (isset($post["form-field-{$wid}-css-class"])) {
369 - $css_class_raw = sanitize_text_field($post["form-field-{$wid}-css-class"]);
370 - if ($css_class_raw !== '') {
371 - // Sanitize each class individually
372 - $classes = array_filter(array_map('sanitize_html_class', explode(' ', $css_class_raw)));
373 - $draft_data['fields'][$wid]['css_class'] = implode(' ', $classes);
374 - } else {
375 - $draft_data['fields'][$wid]['css_class'] = '';
376 - }
377 - }
378 -
379 - // Save custom CSS ID for the field wrapper
380 - if (isset($post["form-field-{$wid}-css-id"])) {
381 - $css_id_raw = sanitize_text_field($post["form-field-{$wid}-css-id"]);
382 - $draft_data['fields'][$wid]['css_id'] = sanitize_html_class($css_id_raw);
383 - }
384 -
385 - // Save fieldset style (fieldset-begin only)
386 - if (isset($post["form-field-{$wid}-fieldset-style"])) {
387 - $allowed_fieldset_styles = array(
388 - 'border-off-title-off', 'border-on-title-off',
389 - 'border-on-title-inline', 'border-on-title-outside',
390 - 'border-on-title-inside', 'border-off-title-on',
391 - );
392 - $fs = sanitize_text_field($post["form-field-{$wid}-fieldset-style"]);
393 - if (in_array($fs, $allowed_fieldset_styles, true)) {
394 - $draft_data['fields'][$wid]['fieldset_style'] = $fs;
395 - }
396 - }
397 -
398 - // Save custom required message override
399 - if (!empty($post["form-field-{$wid}-override-required-msg"])) {
400 - $draft_data['fields'][$wid]['custom_required_message'] = sanitize_text_field($post["form-field-{$wid}-custom-required-msg"]);
401 - }
402 -
403 - // Save custom format message override (email/phone)
404 - if (!empty($post["form-field-{$wid}-override-format-msg"])) {
405 - $draft_data['fields'][$wid]['custom_format_message'] = sanitize_text_field($post["form-field-{$wid}-custom-format-msg"]);
406 - }
407 349 } else {
408 - unset($draft_data['fields'][$wid]);
350 + unset($forms_data[$fid]['fields'][$wid]);
409 351 }
410 352
411 - // Save to draft (not to live database)
412 - _accua_forms_save_draft($fid, $draft_data);
353 + update_option('accua_forms_saved_forms', $forms_data);
413 354
414 355 die('1');
415 356 }
416 357
@@ -437,14 +378,23 @@
437 378 return accua_forms_filter_text($email);
438 379 }
439 380 }
440 381
382 +function accua_forms_filter_emails($emails) {
383 + $split_emails = preg_split("/\s*[,;]\s*/", $emails);
384 + $emails = array();
385 + foreach ($split_emails as $email) {
386 + $emails[] = accua_forms_filter_email($email);
387 + }
388 + return implode(', ', $emails);
389 +}
390 +
441 391 function accua_forms_filter_extensions($extensions) {
442 392 $cleaned_extensions = array();
443 393 $mimes = get_allowed_mime_types();
444 394 $extensions = explode("\n", $extensions);
445 395 foreach ($extensions as $extension) {
446 - $extension = strtolower( trim( ltrim( trim( $extension ), '.' ) ) );
396 + $extension = trim($extension);
447 397 if ($extension !== '') {
448 398 foreach ( $mimes as $ext_preg => $mime_match ) {
449 399 $ext_preg = '!^' . $ext_preg . '$!i';
450 400 if ( preg_match( $ext_preg, $extension ) ) {
@@ -468,14 +418,9 @@
468 418 //boolean
469 419 $form_settings[$k] = (bool) $v;
470 420 break;
471 421 case 'layout':
472 - // Only set if valid layout value, otherwise remove to use default
473 - if ($v === 'toplabel' || $v === 'inlinelabel' || $v === 'sidebyside') {
474 - $form_settings[$k] = $v;
475 - } else {
476 - unset($form_settings[$k]); // Reset to default
477 - }
422 + $form_settings[$k] = ($v === 'toplabel') ? 'toplabel' : 'sidebyside';
478 423 break;
479 424 case 'emails_from':
480 425 // single email
481 426 $form_settings[$k] = accua_forms_filter_email($v);
@@ -506,66 +451,8 @@
506 451 }
507 452 return $form_settings;
508 453 }
509 454
510 -/**
511 - * AJAX handler to restore default message values.
512 - *
513 - * Restores the default content for a specific message section:
514 - * - success_message: On-screen success message
515 - * - error_message: On-screen error message
516 - * - admin_emails: Admin notification email (subject + message only)
517 - * - confirmation_emails: Confirmation email (subject + message only)
518 - *
519 - * @since 2.0.0-beta.6
520 - */
521 -add_action('wp_ajax_accua_forms_restore_default_message', 'accua_forms_restore_default_message');
522 -function accua_forms_restore_default_message() {
523 - if (!current_user_can('manage_options')) {
524 - wp_send_json_error(array('message' => __('Permission denied.', 'contact-forms')), 403);
525 - }
526 -
527 - check_ajax_referer('accua_forms_restore_default', 'nonce');
528 -
529 - $message_type = isset($_POST['message_type']) ? sanitize_key($_POST['message_type']) : '';
530 -
531 - // Get default values
532 - $defaults = accua_forms_get_default_form_data();
533 -
534 - // Define which fields to restore for each message type
535 - $restore_map = array(
536 - 'success_message' => array('success_message'),
537 - 'error_message' => array('error_message'),
538 - 'admin_emails' => array('admin_emails_subject', 'admin_emails_message'),
539 - 'confirmation_emails' => array('confirmation_emails_subject', 'confirmation_emails_message'),
540 - );
541 -
542 - if (!isset($restore_map[$message_type])) {
543 - wp_send_json_error(array('message' => __('Invalid message type.', 'contact-forms')), 400);
544 - }
545 -
546 - // Get current form data
547 - $form_data = get_option('accua_forms_default_form_data', array());
548 - if (!is_array($form_data)) {
549 - $form_data = array();
550 - }
551 -
552 - // Restore the specified fields
553 - $restored_values = array();
554 - foreach ($restore_map[$message_type] as $field) {
555 - $form_data[$field] = $defaults[$field];
556 - $restored_values[$field] = $defaults[$field];
557 - }
558 -
559 - // Save updated form data
560 - update_option('accua_forms_default_form_data', $form_data);
561 -
562 - wp_send_json_success(array(
563 - 'message' => __('Default values restored successfully.', 'contact-forms'),
564 - 'values' => $restored_values,
565 - ));
566 -}
567 -
568 455 add_action( 'wp_ajax_accua-save-form-settings', 'accua_forms_save_form_settings');
569 456 function accua_forms_save_form_settings() {
570 457 if (!current_user_can('manage_options')){
571 458 wp_die( -1, 403 );
@@ -573,16 +460,14 @@
573 460 check_ajax_referer('edit_form', '_nonce_edit_form');
574 461
575 462 $post = stripslashes_deep($_POST);
576 463
464 + $forms_data = get_option('accua_forms_saved_forms', array());
577 465 $fid = $post['form-id'];
578 466 if (accua_forms_validate_form_id($fid) !== '') {
579 467 die('-1');
580 468 }
581 469
582 - // Get draft data instead of live data
583 - $draft_data = _accua_forms_get_draft_data($fid);
584 -
585 470 $settings = array(
586 471 'title',
587 472 'success_message',
588 473 'success_message_no_message',
@@ -597,9 +482,8 @@
597 482 'admin_emails_message_no_message',
598 483 'confirmation_emails_subject',
599 484 'confirmation_emails_message',
600 485 'confirmation_emails_message_no_message',
601 - 'gads_conversion_tracking_code',
602 486 //'use_ajax',
603 487
604 488 'layout',
605 489 'style_margin',
@@ -623,11 +507,8 @@
623 507 'style_submit_background_color',
624 508 'style_submit_padding',
625 509 'style_submit_color',
626 510 'style_submit_font_size',
627 - 'submission_retention_value',
628 - 'submission_retention_unit',
629 - 'submission_retention_mode',
630 511 );
631 512
632 513 // print_r($post);
633 514
@@ -635,328 +516,22 @@
635 516 foreach($settings as $i) {
636 517 if (isset($post[$i])) {
637 518 $new_form_settings[$i] = $post[$i];
638 519 }
639 - if (isset($draft_data[$i])) {
640 - unset($draft_data[$i]);
641 - }
520 + unset($forms_data[$fid][$i]);
642 521 }
643 522
644 - $draft_data += accua_forms_filter_settings($new_form_settings);
523 + $forms_data[$fid] += accua_forms_filter_settings($new_form_settings);
645 524
646 - $draft_data['use_ajax'] = !empty($post['use_ajax']);
647 - $draft_data['submission_retention_override'] = !empty($post['submission_retention_override']);
525 + $forms_data[$fid]['use_ajax'] = !empty($post['use_ajax']);
648 526
649 - // Save to draft (not to live database)
650 - _accua_forms_save_draft($fid, $draft_data);
527 + update_option('accua_forms_saved_forms', $forms_data);
651 528
652 - // Return JSON response for AJAX handler
653 - wp_send_json_success($draft_data);
654 -}
529 + //print_r($forms_data[$fid]);
655 530
656 -/**
657 - * AJAX handler to publish draft to live database.
658 - * Called when user clicks the Save button.
659 - */
660 -add_action( 'wp_ajax_accua-publish-form-draft', 'accua_forms_publish_form_draft');
661 -function accua_forms_publish_form_draft() {
662 - if (!current_user_can('manage_options')){
663 - wp_die( -1, 403 );
664 - }
665 - check_ajax_referer('edit_form', '_nonce_edit_form');
666 -
667 - $post = stripslashes_deep($_POST);
668 - $fid = isset($post['form-id']) ? $post['form-id'] : '';
669 -
670 - if (accua_forms_validate_form_id($fid) !== '') {
671 - wp_send_json_error(array('message' => __('Invalid form ID.', 'contact-forms')), 400);
672 - }
673 -
674 - // Publish the draft
675 - $result = _accua_forms_publish_draft($fid);
676 -
677 - if ($result) {
678 - wp_send_json_success(array('message' => __('Form saved successfully.', 'contact-forms')));
679 - } else {
680 - // Draft might not exist (nothing to publish) - this is OK for a new form
681 - // Check if form exists in database
682 - $forms_data = get_option('accua_forms_saved_forms', array());
683 - if (isset($forms_data[$fid])) {
684 - wp_send_json_success(array('message' => __('No changes to save.', 'contact-forms')));
685 - } else {
686 - wp_send_json_error(array('message' => __('Failed to save form.', 'contact-forms')), 500);
687 - }
688 - }
531 + die('');
689 532 }
690 533
691 -/**
692 - * AJAX handler to discard draft and reload from published data.
693 - * Called when user clicks "Discard changes".
694 - */
695 -add_action( 'wp_ajax_accua-discard-form-draft', 'accua_forms_discard_form_draft');
696 -function accua_forms_discard_form_draft() {
697 - if (!current_user_can('manage_options')){
698 - wp_die( -1, 403 );
699 - }
700 - check_ajax_referer('edit_form', '_nonce_edit_form');
701 -
702 - $post = stripslashes_deep($_POST);
703 - $fid = isset($post['form-id']) ? $post['form-id'] : '';
704 -
705 - if (accua_forms_validate_form_id($fid) !== '') {
706 - wp_send_json_error(array('message' => __('Invalid form ID.', 'contact-forms')), 400);
707 - }
708 -
709 - // Delete the draft
710 - _accua_forms_delete_draft($fid);
711 -
712 - wp_send_json_success(array('message' => __('Changes discarded.', 'contact-forms')));
713 -}
714 -
715 -/**
716 - * Filter an admin-configured post_status value for post fields down to the
717 - * statuses those fields may expose in a public dropdown: publish and private.
718 - *
719 - * Draft/pending/future content is never exposed, regardless of configuration.
720 - *
721 - * @since 2.2.27
722 - * @param string|array $post_status Comma-separated string or array of statuses.
723 - * @return array Allowed statuses (may be empty).
724 - */
725 -function accua_forms_filter_field_post_status($post_status) {
726 - if (!is_array($post_status)) {
727 - $post_status = explode(',', (string) $post_status);
728 - }
729 - $post_status = array_map('trim', $post_status);
730 - return array_values(array_intersect($post_status, array('publish', 'private')));
731 -}
732 -
733 -/**
734 - * Check whether an extra_args string received from the AJAX endpoint matches a
735 - * post-select / post-multicheckbox configuration actually stored by an admin,
736 - * for the post type the request resolved to.
737 - *
738 - * The extra_args string is echoed into the form markup and sent back by the
739 - * browser, so it is client-controlled. Privileged parameters (post_status=private)
740 - * are only honored when the exact string exists in a saved field configuration —
741 - * otherwise any visitor could craft a request that enumerates private post titles.
742 - * The post type is part of the match: a query string saved for one post type must
743 - * not unlock private posts of a different type (the field's post type lives in a
744 - * separate setting, so the string alone does not identify what it exposes).
745 - *
746 - * @since 2.2.27
747 - * @param string $extra_args Sanitized extra_args string from the request.
748 - * @param string $post_type Post type the request resolved to (after the
749 - * post_type override inside extra_args, if any).
750 - * @return bool True when a stored field configuration matches both.
751 - */
752 -function accua_forms_extra_args_is_saved_config($extra_args, $post_type) {
753 - $extra_args = trim($extra_args);
754 - if ($extra_args === '') {
755 - return false;
756 - }
757 -
758 - // Candidate configurations: array of (allowed_values, configured post type).
759 - $candidates = array();
760 - $avail_fields = get_option('accua_forms_avail_fields', array());
761 - foreach ($avail_fields as $field) {
762 - if (!empty($field['type']) && ($field['type'] === 'post-select' || $field['type'] === 'post-multicheckbox') && isset($field['allowed_values'])) {
763 - $candidates[] = array($field['allowed_values'], isset($field['post_type']) ? $field['post_type'] : 'page');
764 - }
765 - }
766 - $forms = get_option('accua_forms_saved_forms', array());
767 - foreach ($forms as $form) {
768 - if (empty($form['fields']) || !is_array($form['fields'])) {
769 - continue;
770 - }
771 - foreach ($form['fields'] as $inst) {
772 - if (!is_array($inst) || empty($inst['ref']) || !isset($avail_fields[$inst['ref']]['type'])) {
773 - continue;
774 - }
775 - $type = $avail_fields[$inst['ref']]['type'];
776 - if (($type === 'post-select' || $type === 'post-multicheckbox') && isset($inst['allowed_values'])) {
777 - $inst_post_type = isset($inst['post_type']) ? $inst['post_type']
778 - : (isset($avail_fields[$inst['ref']]['post_type']) ? $avail_fields[$inst['ref']]['post_type'] : 'page');
779 - $candidates[] = array($inst['allowed_values'], $inst_post_type);
780 - }
781 - }
782 - }
783 -
784 - foreach ($candidates as $candidate) {
785 - list($candidate_args, $candidate_post_type) = $candidate;
786 - if (trim(sanitize_text_field($candidate_args)) !== $extra_args) {
787 - continue;
788 - }
789 - // Resolve the candidate's effective post type the same way the request
790 - // does: a post_type override inside the string wins over the field setting.
791 - $candidate_extra = array();
792 - wp_parse_str($extra_args, $candidate_extra);
793 - if (!empty($candidate_extra['post_type'])) {
794 - $candidate_post_type = sanitize_text_field($candidate_extra['post_type']);
795 - }
796 - if ($candidate_post_type === $post_type) {
797 - return true;
798 - }
799 - }
800 - return false;
801 -}
802 -
803 -/**
804 - * AJAX handler to get posts for post-select fields with pagination.
805 - * Available to both logged-in and anonymous users (for frontend forms).
806 - *
807 - * @since 2.0.0-beta.29
808 - */
809 -add_action('wp_ajax_accua_forms_get_posts', 'accua_forms_ajax_get_posts');
810 -add_action('wp_ajax_nopriv_accua_forms_get_posts', 'accua_forms_ajax_get_posts');
811 -function accua_forms_ajax_get_posts() {
812 - // Verify nonce
813 - // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Nonce verification
814 - if (!isset($_REQUEST['_nonce']) || !wp_verify_nonce($_REQUEST['_nonce'], 'accua_forms_get_posts')) {
815 - wp_send_json_error(array('message' => __('Security check failed.', 'contact-forms')), 403);
816 - }
817 -
818 - // Sanitize inputs
819 - $post_type = isset($_REQUEST['post_type']) ? sanitize_text_field(wp_unslash($_REQUEST['post_type'])) : 'page';
820 - $search = isset($_REQUEST['search']) ? sanitize_text_field(wp_unslash($_REQUEST['search'])) : '';
821 - $page = isset($_REQUEST['page']) ? absint($_REQUEST['page']) : 1;
822 - $per_page = isset($_REQUEST['per_page']) ? min(absint($_REQUEST['per_page']), 100) : 50;
823 - $extra_args = isset($_REQUEST['extra_args']) ? sanitize_text_field(wp_unslash($_REQUEST['extra_args'])) : '';
824 - $selected = isset($_REQUEST['selected']) ? sanitize_text_field(wp_unslash($_REQUEST['selected'])) : '';
825 -
826 - // Validate post type
827 - $valid_post_types = get_post_types(array('public' => true));
828 - if (!isset($valid_post_types[$post_type])) {
829 - $post_type = 'page';
830 - }
831 -
832 - // Calculate offset
833 - $offset = ($page - 1) * $per_page;
834 -
835 - // Statuses the response may contain (extended below when the field
836 - // configuration explicitly requests private posts).
837 - $allowed_statuses = array('publish');
838 -
839 - // Build query arguments
840 - $args = array(
841 - 'post_type' => $post_type,
842 - 'number' => $per_page + 1, // Get one extra to check if there are more
843 - 'offset' => $offset,
844 - 's' => $search,
845 - );
846 -
847 - // Parse extra arguments (backward compatibility with allowed_values textarea)
848 - if (!empty($extra_args)) {
849 - // Parse the query string format
850 - $extra = array();
851 - wp_parse_str($extra_args, $extra);
852 -
853 - // Allow post_type override from extra_args (backward compatibility)
854 - if (isset($extra['post_type'])) {
855 - $override_post_type = sanitize_text_field($extra['post_type']);
856 - // Validate the overridden post type
857 - if (isset($valid_post_types[$override_post_type])) {
858 - $post_type = $override_post_type;
859 - $args['post_type'] = $post_type;
860 - }
861 - }
862 -
863 - // Merge only safe parameters
864 - $safe_params = array('meta_key', 'meta_value', 'authors', 'parent', 'child_of', 'exclude', 'include', 'sort_column', 'sort_order');
865 - foreach ($safe_params as $param) {
866 - if (isset($extra[$param])) {
867 - $args[$param] = $extra[$param];
868 - }
869 - }
870 -
871 - // post_status is a privileged parameter: only publish/private are ever
872 - // honored, and 'private' only when the extra_args string matches a field
873 - // configuration stored by an admin (or the user can read private posts,
874 - // e.g. the form editor preview). Otherwise a visitor could craft a request
875 - // that enumerates private post titles.
876 - if (!empty($extra['post_status'])) {
877 - $requested_statuses = accua_forms_filter_field_post_status($extra['post_status']);
878 - if (in_array('private', $requested_statuses, true)
879 - && !current_user_can('read_private_posts')
880 - && !accua_forms_extra_args_is_saved_config($extra_args, $post_type)) {
881 - $requested_statuses = array('publish');
882 - }
883 - if (!empty($requested_statuses)) {
884 - $args['post_status'] = $requested_statuses;
885 - $allowed_statuses = $requested_statuses;
886 - }
887 - }
888 - }
889 -
890 - // Get posts using WPML-compatible function
891 - $posts = accua_get_pages($args);
892 -
893 - // Check if there are more results
894 - $has_more = count($posts) > $per_page;
895 - if ($has_more) {
896 - array_pop($posts); // Remove the extra item
897 - }
898 -
899 - // Format results for the dropdown
900 - $results = array();
901 - foreach ($posts as $post) {
902 - $results[] = array(
903 - 'id' => $post->ID,
904 - 'text' => $post->post_title,
905 - );
906 - }
907 -
908 - // If this is the first page and we have a selected value, ensure it's in the list
909 - if ($page === 1 && !empty($selected) && is_numeric($selected)) {
910 - $selected_id = absint($selected);
911 - $found = false;
912 - foreach ($results as $result) {
913 - if ($result['id'] === $selected_id) {
914 - $found = true;
915 - break;
916 - }
917 - }
918 - // If selected post not in results, fetch it separately and prepend.
919 - // Only statuses the field is allowed to expose (publish, plus private when
920 - // explicitly configured): this endpoint is available to anonymous visitors,
921 - // so it must not disclose titles of other drafts/private/pending posts.
922 - if (!$found) {
923 - $selected_post = get_post($selected_id);
924 - if ($selected_post && $selected_post->post_type === $post_type && in_array($selected_post->post_status, $allowed_statuses, true)) {
925 - array_unshift($results, array(
926 - 'id' => $selected_post->ID,
927 - 'text' => $selected_post->post_title,
928 - ));
929 - }
930 - }
931 - }
932 -
933 - wp_send_json_success(array(
934 - 'results' => $results,
935 - 'more' => $has_more,
936 - 'page' => $page,
937 - ));
938 -}
939 -
940 -/**
941 - * Get available public post types for the post-select field editor.
942 - *
943 - * @since 2.0.0-beta.29
944 - * @return array Array of post type slug => label pairs.
945 - */
946 -function accua_forms_get_public_post_types() {
947 - $post_types = get_post_types(array('public' => true), 'objects');
948 - $options = array();
949 - foreach ($post_types as $post_type) {
950 - // Skip attachments
951 - if ($post_type->name === 'attachment') {
952 - continue;
953 - }
954 - $options[$post_type->name] = $post_type->labels->singular_name;
955 - }
956 - return $options;
957 -}
958 -
959 534 function accua_forms_field_settings_form_counter() {
960 535 static $i = 0;
961 536 $i++;
962 537 return $i;
@@ -996,10 +571,8 @@
996 571 $override_label = isset($istance_data['label']) ? 'checked="checked"' : '';
997 572 $override_default_value = isset($istance_data['default_value']) ? 'checked="checked"' : '';
998 573 $override_allowed_values = isset($istance_data['allowed_values']) ? 'checked="checked"' : '';
999 574 $override_allowed_extensions = '';
1000 - $override_custom_required_msg = isset($istance_data['custom_required_message']) ? 'checked="checked"' : '';
1001 - $override_custom_format_msg = isset($istance_data['custom_format_message']) ? 'checked="checked"' : '';
1002 575
1003 576 if ($field_data['type'] == 'file') {
1004 577 if (isset($istance_data['version']) && $istance_data['version'] >= 2) {
1005 578 if (isset($istance_data['allowed_extensions'])) {
@@ -1026,8 +599,10 @@
1026 599
1027 600 if ($field_data['type'] == 'date') {
1028 601 $override_mindate_values = isset($istance_data['min_date']) ? 'checked="checked"' : '';
1029 602 $override_maxdate_values = isset($istance_data['max_date']) ? 'checked="checked"' : '';
603 + //$override_default_value = isset($istance_data['default_date_value']) ? 'checked="checked"' : '';
604 +
1030 605 $istance_data += array(
1031 606 'min_date' => $field_data['min_date'],
1032 607 'max_date' => $field_data['max_date'],
1033 608 'default_value' => $field_data['default_date_value'],
@@ -1043,22 +618,16 @@
1043 618 'default_value' => $field_data['default_value'],
1044 619 'allowed_values' => $field_data['allowed_values'],
1045 620 'allowed_extensions' => $field_data['allowed_extensions'],
1046 621 'required' => false,
1047 - 'post_type' => 'page', // Default post type for post-select fields
1048 - 'css_class' => '',
1049 - 'css_id' => '',
1050 - 'custom_required_message' => '',
1051 - 'custom_format_message' => '',
1052 - 'fieldset_style' => 'border-off-title-off',
1053 622 );
1054 623
1055 624 foreach ($istance_data as $key => $value) {
1056 - $istance_data[$key] = esc_attr($istance_data[$key]);
625 + $istance_data[$key] = htmlspecialchars($istance_data[$key], ENT_QUOTES);
1057 626 }
1058 627
1059 628 foreach ($field_data as $key => $value) {
1060 - $field_data[$key] = esc_attr($field_data[$key]);
629 + $field_data[$key] = htmlspecialchars($field_data[$key], ENT_QUOTES);
1061 630 }
1062 631
1063 632 $multi_number = '';
1064 633 $add_new = '';
@@ -1079,9 +648,9 @@
1079 648 $forceoverride_field = false;
1080 649 $add_new = $empty_istance ? 'single' : '';
1081 650 }
1082 651
1083 - $fid = esc_attr($fid);
652 + $fid = htmlspecialchars($fid, ENT_QUOTES);
1084 653 $testi_eot = array (
1085 654 'label' => __( 'Label', 'contact-forms'),
1086 655 'override' => __( 'override', 'contact-forms'),
1087 656 'default_value' => __( 'Default value', 'contact-forms'),
@@ -1092,10 +661,8 @@
1092 661 'allowed_extensions' => __( 'Allowed extensions', 'contact-forms'),
1093 662 'desc_all_ext' => __( 'Accepted file extensions. One per line, without dots.', 'contact-forms'),
1094 663 'required' => __( 'Required', 'contact-forms'),
1095 664 'custom_HTML_content' => __( 'Custom HTML content', 'contact-forms'),
1096 - 'refresh_preview' => __( 'Refresh Preview', 'contact-forms'),
1097 - 'add' => __( 'Add field', 'contact-forms'),
1098 665 'remove' => __( 'Remove', 'contact-forms'),
1099 666 'close' => __( 'Close', 'contact-forms'),
1100 667 'save' => __( 'Save', 'contact-forms'),
1101 668 'min-of-date' => __( 'Min date', 'contact-forms'),
@@ -1111,9 +678,8 @@
1111 678 $override_type = 'checkbox';
1112 679 $override_end = ')';
1113 680 }
1114 681
1115 - // phpcs:disable PluginCheck.CodeAnalysis.Heredoc.NotAllowed, WordPress.Security.EscapeOutput.HeredocOutputNotEscaped -- Heredoc used for HTML templates with pre-escaped variables
1116 682 $content = <<<EOT
1117 683 <p><label for="widget-{$istance_data['istance_id']}-label">{$testi_eot['label']}:</label>
1118 684 {$override_begin}<input type="{$override_type}" name="form-field-{$istance_data['istance_id']}-override-label" value="1" {$override_label} />{$override_end}<br>
1119 685 <input type="text" value="{$istance_data['label']}" name="form-field-{$istance_data['istance_id']}-label" id="widget-{$istance_data['istance_id']}-label" class="widefat"></p>
@@ -1151,43 +717,8 @@
1151 717 <p><label for="widget-{$istance_data['istance_id']}-required">{$testi_eot['required']}:</label>
1152 718 <input type="checkbox" value="1" {$required_checked} name="form-field-{$istance_data['istance_id']}-required" id="widget-{$istance_data['istance_id']}-required"></p>
1153 719 EOT;
1154 720
1155 - // Custom required message override (checkbox + text input, same pattern as custom label)
1156 - $custom_required_msg_label = __( 'Custom required message', 'contact-forms');
1157 - // translators: %s is the field name/label
1158 - $custom_required_msg_desc = __( 'Overrides the default "required" error message. Use %s for the field name.', 'contact-forms');
1159 - $custom_required_msg = <<<EOT
1160 - <p><label for="widget-{$istance_data['istance_id']}-custom-required-msg">{$custom_required_msg_label}:</label>
1161 - {$override_begin}<input type="{$override_type}" name="form-field-{$istance_data['istance_id']}-override-required-msg" value="1" {$override_custom_required_msg} />{$override_end}<br>
1162 - <input type="text" value="{$istance_data['custom_required_message']}" name="form-field-{$istance_data['istance_id']}-custom-required-msg" id="widget-{$istance_data['istance_id']}-custom-required-msg" class="widefat"><br>
1163 - <small>{$custom_required_msg_desc}</small></p>
1164 -EOT;
1165 -
1166 - // Custom format message override for email and telephone fields
1167 - $custom_format_msg = '';
1168 - if ($field_data['type'] === 'email' || $field_data['type'] === 'autoreply_email') {
1169 - $custom_format_msg_label = __( 'Custom invalid email message', 'contact-forms');
1170 - // translators: %s is the field name/label
1171 - $custom_format_msg_desc = __( 'Overrides the default email format error message. Use %s for the field name.', 'contact-forms');
1172 - $custom_format_msg = <<<EOT
1173 - <p><label for="widget-{$istance_data['istance_id']}-custom-format-msg">{$custom_format_msg_label}:</label>
1174 - {$override_begin}<input type="{$override_type}" name="form-field-{$istance_data['istance_id']}-override-format-msg" value="1" {$override_custom_format_msg} />{$override_end}<br>
1175 - <input type="text" value="{$istance_data['custom_format_message']}" name="form-field-{$istance_data['istance_id']}-custom-format-msg" id="widget-{$istance_data['istance_id']}-custom-format-msg" class="widefat"><br>
1176 - <small>{$custom_format_msg_desc}</small></p>
1177 -EOT;
1178 - } elseif ($field_data['type'] === 'telephone') {
1179 - $custom_format_msg_label = __( 'Custom invalid phone message', 'contact-forms');
1180 - // translators: %s is the field name/label
1181 - $custom_format_msg_desc = __( 'Overrides the default phone format error message. Use %s for the field name.', 'contact-forms');
1182 - $custom_format_msg = <<<EOT
1183 - <p><label for="widget-{$istance_data['istance_id']}-custom-format-msg">{$custom_format_msg_label}:</label>
1184 - {$override_begin}<input type="{$override_type}" name="form-field-{$istance_data['istance_id']}-override-format-msg" value="1" {$override_custom_format_msg} />{$override_end}<br>
1185 - <input type="text" value="{$istance_data['custom_format_message']}" name="form-field-{$istance_data['istance_id']}-custom-format-msg" id="widget-{$istance_data['istance_id']}-custom-format-msg" class="widefat"><br>
1186 - <small>{$custom_format_msg_desc}</small></p>
1187 -EOT;
1188 - }
1189 -
1190 721 if ($field_data['type'] == 'date'){
1191 722 $default_date_value = <<<EOT
1192 723 <p><label for="widget-{$istance_data['istance_id']}-default-value">{$testi_eot['default_value']}:</label>
1193 724 {$override_begin}<input type="{$override_type}" name="form-field-{$istance_data['istance_id']}-override-default-value" value="1" {$override_default_value} />{$override_end}<br>
@@ -1204,137 +735,8 @@
1204 735 <input type="date" value="{$istance_data['max_date']}" name="form-field-{$istance_data['istance_id']}-max-of-date" id="widget-{$istance_data['istance_id']}-max-of-date"></p>
1205 736 EOT;
1206 737 }
1207 738
1208 - // Post type selector for post-select and post-multicheckbox fields
1209 - $post_type_selector = '';
1210 - if ($field_data['type'] === 'post-select' || $field_data['type'] === 'post-multicheckbox') {
1211 - $override_post_type = isset($istance_data['post_type']) && $istance_data['post_type'] !== 'page' ? 'checked="checked"' : '';
1212 - $post_types = accua_forms_get_public_post_types();
1213 - $post_type_options = '';
1214 - $current_post_type = esc_attr($istance_data['post_type']);
1215 - foreach ($post_types as $pt_slug => $pt_label) {
1216 - $selected = ($pt_slug === $current_post_type) ? ' selected="selected"' : '';
1217 - $post_type_options .= '<option value="' . esc_attr($pt_slug) . '"' . $selected . '>' . esc_html($pt_label) . '</option>';
1218 - }
1219 - $post_type_label = __('Post type', 'contact-forms');
1220 - $post_type_desc = __('Select which post type to show in the dropdown.', 'contact-forms');
1221 - $query_params_label = __('Additional query parameters', 'contact-forms');
1222 - // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value -- This is example help text, not actual code.
1223 - $query_params_desc = __('Optional: Filter posts using query parameters (e.g., authors=admin or meta_key=featured&meta_value=1). Add post_status=publish,private to also include private posts (their titles become visible to all visitors of this form). Leave empty for all published posts of the selected type.', 'contact-forms');
1224 - $post_type_selector = <<<EOT
1225 - <p><label for="widget-{$istance_data['istance_id']}-post-type">{$post_type_label}:</label>
1226 - {$override_begin}<input type="{$override_type}" name="form-field-{$istance_data['istance_id']}-override-post-type" value="1" {$override_post_type} />{$override_end}<br>
1227 - <select name="form-field-{$istance_data['istance_id']}-post-type" id="widget-{$istance_data['istance_id']}-post-type" class="widefat">{$post_type_options}</select><br />
1228 - {$post_type_desc}</p>
1229 - <p><label for="widget-{$istance_data['istance_id']}-allowed-values">{$query_params_label}:</label>
1230 - {$override_begin}<input type="{$override_type}" name="form-field-{$istance_data['istance_id']}-override-allowed-values" value="1" {$override_allowed_values} />{$override_end}<br>
1231 - <textarea rows="3" cols="50" name="form-field-{$istance_data['istance_id']}-allowed-values" id="widget-{$istance_data['istance_id']}-allowed-values" class="widefat">{$istance_data['allowed_values']}</textarea><br />
1232 - {$query_params_desc}</p>
1233 -EOT;
1234 - }
1235 -
1236 - // Country selector for telephone fields (for libphonenumber validation)
1237 - $country_selector = '';
1238 - if ($field_data['type'] === 'telephone') {
1239 - $countries = accua_forms_get_countries();
1240 - $current_country = isset($istance_data['country_code']) ? esc_attr($istance_data['country_code']) : 'IT';
1241 - $override_country = isset($istance_data['country_code']) && $istance_data['country_code'] !== 'IT' ? 'checked="checked"' : '';
1242 - $country_options = '';
1243 - foreach ($countries as $code => $country_name) {
1244 - $selected = ($code === $current_country) ? ' selected="selected"' : '';
1245 - $country_options .= '<option value="' . esc_attr($code) . '"' . $selected . '>' . esc_html($country_name) . '</option>';
1246 - }
1247 - $country_label = __('Default country', 'contact-forms');
1248 - // translators: Help text for phone field country selector in form editor
1249 - $country_desc = __('For numbers without international prefix, validation assumes this country.', 'contact-forms');
1250 - $country_selector = <<<EOT
1251 - <p><label for="widget-{$istance_data['istance_id']}-country-code">{$country_label}:</label>
1252 - {$override_begin}<input type="{$override_type}" name="form-field-{$istance_data['istance_id']}-override-country-code" value="1" {$override_country} />{$override_end}<br>
1253 - <select name="form-field-{$istance_data['istance_id']}-country-code" id="widget-{$istance_data['istance_id']}-country-code" class="widefat">{$country_options}</select><br />
1254 - {$country_desc}</p>
1255 -EOT;
1256 - }
1257 -
1258 - // Spam action selector for reCAPTCHA v2 and v3 fields (silent classification).
1259 - // Like every other field setting it is an override of the site-wide default
1260 - // configured in the plugin settings page.
1261 - $spam_action_selector = '';
1262 - if ($field_data['type'] === 'captcha' || $field_data['type'] === 'captcha_v3') {
1263 - $spam_actions = accua_forms_captcha_spam_action_options();
1264 - $current_spam_action = accua_forms_captcha_spam_action($istance_data, $field_data['type']);
1265 - $override_spam_action = isset($istance_data['spam_action']) ? 'checked="checked"' : '';
1266 - $spam_action_options = '';
1267 - foreach ($spam_actions as $sa_key => $sa_label) {
1268 - $sa_selected = ($sa_key === $current_spam_action) ? ' selected="selected"' : '';
1269 - $spam_action_options .= '<option value="' . esc_attr($sa_key) . '"' . $sa_selected . '>' . esc_html($sa_label) . '</option>';
1270 - }
1271 - $spam_action_label = __('When the spam check fails', 'contact-forms');
1272 - if ($field_data['type'] === 'captcha_v3') {
1273 - // translators: Help text for the reCAPTCHA v3 spam action selector in the form editor
1274 - $spam_action_desc = __('reCAPTCHA v3 classifies visitors silently with a score. Choose what happens to a submission that fails the check: accept it silently (normal success message, no notification emails) and mark it with the Spam lead status, move it to Trash, or delete it immediately without storing anything — or reject it with a visible error.', 'contact-forms');
1275 - } else {
1276 - // translators: Help text for the reCAPTCHA v2 spam action selector in the form editor
1277 - $spam_action_desc = __('Choose what happens to a submission whose reCAPTCHA verification fails: accept it silently (normal success message, no notification emails) and mark it with the Spam lead status, move it to Trash, or delete it immediately without storing anything — or reject it with a visible error so the visitor can retry the challenge.', 'contact-forms');
1278 - }
1279 - $spam_action_selector = <<<EOT
1280 - <p><label for="widget-{$istance_data['istance_id']}-spam-action">{$spam_action_label}:</label>
1281 - {$override_begin}<input type="{$override_type}" name="form-field-{$istance_data['istance_id']}-override-spam-action" value="1" {$override_spam_action} />{$override_end}<br>
1282 - <select name="form-field-{$istance_data['istance_id']}-spam-action" id="widget-{$istance_data['istance_id']}-spam-action" class="widefat">{$spam_action_options}</select><br>
1283 - <small>{$spam_action_desc}</small></p>
1284 -EOT;
1285 - }
1286 -
1287 - // Minimum score override for reCAPTCHA v3 fields
1288 - $score_threshold_field = '';
1289 - if ($field_data['type'] === 'captcha_v3') {
1290 - $current_score_threshold = esc_attr(number_format(accua_forms_recaptcha3_score_threshold($istance_data), 2, '.', ''));
1291 - $override_score_threshold = isset($istance_data['score_threshold']) ? 'checked="checked"' : '';
1292 - $score_threshold_label = __('Minimum score', 'contact-forms');
1293 - // translators: Help text for the reCAPTCHA v3 minimum score field in the form editor
1294 - $score_threshold_desc = __('reCAPTCHA v3 scores every visitor from 0.0 (almost certainly a bot) to 1.0 (almost certainly a person). Submissions scoring below this value fail the spam check. Google suggests 0.5; raise it to be stricter, lower it if legitimate visitors are being caught.', 'contact-forms');
1295 - $score_threshold_field = <<<EOT
1296 - <p><label for="widget-{$istance_data['istance_id']}-score-threshold">{$score_threshold_label}:</label>
1297 - {$override_begin}<input type="{$override_type}" name="form-field-{$istance_data['istance_id']}-override-score-threshold" value="1" {$override_score_threshold} />{$override_end}<br>
1298 - <input type="number" min="0" max="1" step="0.01" value="{$current_score_threshold}" name="form-field-{$istance_data['istance_id']}-score-threshold" id="widget-{$istance_data['istance_id']}-score-threshold" class="widefat"><br>
1299 - <small>{$score_threshold_desc}</small></p>
1300 -EOT;
1301 - }
1302 -
1303 - // Hide-title override for captcha fields
1304 - $hide_title_field = '';
1305 - if (in_array($field_data['type'], array('captcha', 'captcha_v3', 'cap'), true)) {
1306 - $hide_title_checked = accua_forms_captcha_hide_title($istance_data) ? 'checked="checked"' : '';
1307 - $override_hide_title = isset($istance_data['hide_title']) ? 'checked="checked"' : '';
1308 - $hide_title_label = __('Hide field title', 'contact-forms');
1309 - // translators: Help text for the hide-title checkbox on captcha fields in the form editor
1310 - $hide_title_desc = __('Do not display the field title in the form. The title stays in the markup for screen readers and error messages.', 'contact-forms');
1311 - $hide_title_field = <<<EOT
1312 - <p><label for="widget-{$istance_data['istance_id']}-hide-title">{$hide_title_label}:</label>
1313 - {$override_begin}<input type="{$override_type}" name="form-field-{$istance_data['istance_id']}-override-hide-title" value="1" {$override_hide_title} />{$override_end}<br>
1314 - <input type="checkbox" value="1" {$hide_title_checked} name="form-field-{$istance_data['istance_id']}-hide-title" id="widget-{$istance_data['istance_id']}-hide-title"><br>
1315 - <small>{$hide_title_desc}</small></p>
1316 -EOT;
1317 - }
1318 -
1319 - // CSS Class and CSS ID fields (universal, apply to all field types)
1320 - $css_class_label = __( 'CSS Class', 'contact-forms');
1321 - $css_id_label = __( 'CSS ID', 'contact-forms');
1322 - // translators: Help text for CSS Class field in form editor
1323 - $css_class_desc = __( 'Custom CSS class(es) for the field wrapper. Separate multiple classes with spaces.', 'contact-forms');
1324 - // translators: Help text for CSS ID field in form editor
1325 - $css_id_desc = __( 'Custom CSS ID for the field wrapper. Must be unique on the page.', 'contact-forms');
1326 - $css_class_field = <<<EOT
1327 - <p><label for="widget-{$istance_data['istance_id']}-css-class">{$css_class_label}:</label><br>
1328 - <input type="text" value="{$istance_data['css_class']}" name="form-field-{$istance_data['istance_id']}-css-class" id="widget-{$istance_data['istance_id']}-css-class" class="widefat"><br>
1329 - <small>{$css_class_desc}</small></p>
1330 -EOT;
1331 - $css_id_field = <<<EOT
1332 - <p><label for="widget-{$istance_data['istance_id']}-css-id">{$css_id_label}:</label><br>
1333 - <input type="text" value="{$istance_data['css_id']}" name="form-field-{$istance_data['istance_id']}-css-id" id="widget-{$istance_data['istance_id']}-css-id" class="widefat"><br>
1334 - <small>{$css_id_desc}</small></p>
1335 -EOT;
1336 -
1337 739 switch ($field_data['type']) {
1338 740 case 'textarea':
1339 741 $content .= <<<EOT
1340 742 <p><label for="widget-{$istance_data['istance_id']}-default-value">{$testi_eot['default_value']}:</label>
@@ -1340,9 +742,8 @@
1340 742 <p><label for="widget-{$istance_data['istance_id']}-default-value">{$testi_eot['default_value']}:</label>
1341 743 {$override_begin}<input type="{$override_type}" name="form-field-{$istance_data['istance_id']}-override-default-value" value="1" {$override_default_value} />{$override_end}<br>
1342 744 <textarea rows="6" cols="50" name="form-field-{$istance_data['istance_id']}-default-value" id="widget-{$istance_data['istance_id']}-default-value" class="widefat">{$istance_data['default_value']}</textarea></p>
1343 745 $required
1344 - $custom_required_msg
1345 746 EOT;
1346 747 break;
1347 748 case 'hidden':
1348 749 $content = $default_value;
@@ -1347,58 +748,26 @@
1347 748 case 'hidden':
1348 749 $content = $default_value;
1349 750 break;
1350 751 case 'checkbox':
1351 - $content .= $default_value . $required . $custom_required_msg;
752 + $content .= $default_value . $required;
1352 753 break;
1353 754 case 'select':
1354 755 case 'radio':
1355 - $content .= $default_value . $allowed_values . $required . $custom_required_msg;
1356 - break;
1357 756 case 'post-select':
1358 - $content .= $default_value . $post_type_selector . $required . $custom_required_msg;
757 + $content .= $default_value . $allowed_values . $required;
1359 758 break;
1360 759 case 'multiselect':
1361 760 case 'multicheckbox':
1362 - $content .= $default_values . $allowed_values . $required . $custom_required_msg;
1363 - break;
1364 761 case 'post-multicheckbox':
1365 - $content .= $default_values . $post_type_selector . $required . $custom_required_msg;
762 + $content .= $default_values . $allowed_values . $required;
1366 763 break;
1367 764 case 'file':
1368 - $content .= $allowed_ext . $required . $custom_required_msg;
1369 - break;
765 + $content .= $allowed_ext . $required;
1370 766 case 'submit':
767 + case 'fieldset-begin':
1371 768 //just the label
1372 769 break;
1373 - case 'fieldset-begin':
1374 - $fs_label_text = __('Border and Title', 'contact-forms');
1375 - $gt_label_text = __('Group Title', 'contact-forms');
1376 - // translators: Help text under the Group Title field for fieldset groups in the form editor
1377 - $gt_desc_text = __('Section heading. Shown in the form when a title option is selected.', 'contact-forms');
1378 - $fs_opts_map = array(
1379 - 'border-off-title-off' => __('Border OFF | Title OFF', 'contact-forms'),
1380 - 'border-on-title-off' => __('Border ON | Title OFF', 'contact-forms'),
1381 - 'border-on-title-inline' => __('Border ON | Title ON (inline)', 'contact-forms'),
1382 - 'border-on-title-outside' => __('Border ON | Title ON (outside)', 'contact-forms'),
1383 - 'border-on-title-inside' => __('Border ON | Title ON (inside)', 'contact-forms'),
1384 - 'border-off-title-on' => __('Border OFF | Title ON', 'contact-forms'),
1385 - );
1386 - $fs_options_html = '';
1387 - foreach ($fs_opts_map as $opt_val => $opt_label) {
1388 - $opt_selected = ($istance_data['fieldset_style'] === $opt_val) ? ' selected="selected"' : '';
1389 - $fs_options_html .= '<option value="' . esc_attr($opt_val) . '"' . $opt_selected . '>' . esc_html($opt_label) . '</option>';
1390 - }
1391 - $content = <<<EOT
1392 - <p><label for="widget-{$istance_data['istance_id']}-label">{$gt_label_text}:</label><br>
1393 - <input type="hidden" name="form-field-{$istance_data['istance_id']}-override-label" value="1">
1394 - <input type="text" value="{$istance_data['label']}" name="form-field-{$istance_data['istance_id']}-label" id="widget-{$istance_data['istance_id']}-label" class="widefat"><br>
1395 - <small>{$gt_desc_text}</small></p>
1396 - <p><label for="widget-{$istance_data['istance_id']}-fieldset-style">{$fs_label_text}:</label><br>
1397 - <select name="form-field-{$istance_data['istance_id']}-fieldset-style" id="widget-{$istance_data['istance_id']}-fieldset-style" class="widefat accua-fieldset-style-select">{$fs_options_html}</select></p>
1398 -EOT;
1399 - $content .= $css_class_field . $css_id_field;
1400 - break;
1401 770 case 'fieldset-end':
1402 771 //Nothing!
1403 772 $content = '';
1404 773 break;
@@ -1406,67 +775,28 @@
1406 775 $content = <<<EOT
1407 776 <p><label for="widget-{$istance_data['istance_id']}-default-value">{$testi_eot['custom_HTML_content']}</label>
1408 777 {$override_begin}<input type="{$override_type}" name="form-field-{$istance_data['istance_id']}-override-default-value" value="1" {$override_default_value} />{$override_end}<br>
1409 778 <textarea rows="6" cols="50" name="form-field-{$istance_data['istance_id']}-default-value" id="widget-{$istance_data['istance_id']}-default-value" class="widefat">{$istance_data['default_value']}</textarea></p>
1410 - <p><a href="#" class="accua-refresh-preview">{$testi_eot['refresh_preview']}</a></p>
1411 779 EOT;
1412 780 break;
1413 781 case 'date':
1414 - $content .= $default_date_value . $min_date . $max_date . $required . $custom_required_msg;
782 + $content .= $default_date_value . $min_date . $max_date . $required;
1415 783 break;
1416 - case 'telephone':
1417 - $content .= $default_value . $country_selector . $required . $custom_required_msg . $custom_format_msg;
1418 - break;
1419 784 case 'email':
1420 785 case 'autoreply_email':
1421 - $content .= $default_value . $required . $custom_required_msg . $custom_format_msg;
1422 - break;
1423 - case 'captcha':
1424 - case 'captcha_v3':
1425 - case 'cap':
1426 - case 'turnstile':
1427 - // Captcha fields consume neither default_value nor the custom required
1428 - // message (their validators are set in the element constructors), so
1429 - // those rows are not offered. The extension-settings action still fires
1430 - // for parity with the default case.
1431 - ob_start();
1432 - do_action( 'accua_forms_field_settings', $field_data['type'], $field_data, $istance_data );
1433 - $extra_settings = ob_get_clean();
1434 - $content .= $extra_settings . $hide_title_field . $score_threshold_field . $spam_action_selector . $required;
1435 - break;
1436 786 case 'textfield':
1437 787 case 'colorpicker':
1438 788 case 'datepicker':
1439 789 case 'dateselect':
1440 790 default:
1441 - /**
1442 - * Action to render additional field settings in the form editor.
1443 - *
1444 - * @param string $field_type The field type identifier.
1445 - * @param array $field_data The field definition.
1446 - * @param array $istance_data The field instance data.
1447 - * @param string $content The current settings HTML (passed by reference via output buffering).
1448 - */
1449 - ob_start();
1450 - do_action( 'accua_forms_field_settings', $field_data['type'], $field_data, $istance_data );
1451 - $extra_settings = ob_get_clean();
1452 - // The captcha-only rows (hide title, score, spam action) render in the
1453 - // dedicated captcha case above and are always empty here.
1454 - $content .= $default_value . $extra_settings . $required . $custom_required_msg;
791 + $content .= $default_value . $required;
1455 792 break;
1456 793 }
1457 -
1458 - // Append CSS Class and CSS ID fields to all types except fieldset-end (which has no settings)
1459 - if ($field_data['type'] !== 'fieldset-end' && $field_data['type'] !== 'fieldset-begin') {
1460 - $content .= $css_class_field . $css_id_field;
1461 - }
1462 -
1463 794 $adminurl = admin_url();
1464 795
1465 796 return <<<EOT
1466 -<div class="widget ui-draggable" id="widget-{$i}_{$istance_data['istance_id']}" data-field-type="{$field_data['type']}" $hidden> <div class="widget-top">
797 +<div class="widget ui-draggable" id="widget-{$i}_{$istance_data['istance_id']}" $hidden> <div class="widget-top">
1467 798 <div class="widget-title-action">
1468 - <a href="#add-field" class="widget-add-action hide-if-no-js" title="{$testi_eot['add']}" aria-label="{$testi_eot['add']}"></a>
1469 799 <a href="#available-widgets" class="widget-action hide-if-no-js"></a>
1470 800 </div>
1471 801 <div class="widget-title"><h4>{$field_data['name']}<span class="in-widget-title"></span></h4></div>
1472 802 </div>
@@ -1490,9 +820,10 @@
1490 820 <a href="#remove" class="widget-control-remove delete">{$testi_eot['remove']}</a> |
1491 821 <a href="#close" class="widget-control-close">{$testi_eot['close']}</a>
1492 822 </div>
1493 823 <div class="alignright">
1494 - <input type="submit" value="{$testi_eot['save']}" class="button button-primary widget-control-save accua-field-save-btn" id="widget-{$istance_data['istance_id']}-savewidget" name="savewidget">
824 + <img alt="" title="" class="ajax-feedback" src="{$adminurl}images/wpspin_light.gif">
825 + <input type="submit" value="{$testi_eot['save']}" class="button-primary widget-control-save" id="widget-{$istance_data['istance_id']}-savewidget" name="savewidget">
1495 826 </div>
1496 827 <br class="clear">
1497 828 </div>
1498 829 </form>
@@ -1503,17 +834,1853 @@
1503 834 </div>-->
1504 835 </div>
1505 836
1506 837 EOT;
1507 - // phpcs:enable PluginCheck.CodeAnalysis.Heredoc.NotAllowed, WordPress.Security.EscapeOutput.HeredocOutputNotEscaped
1508 838 }
1509 839
840 +function accua_forms_add_page($message='') {
841 + $forms_data = get_option('accua_forms_saved_forms', array());
842 + $trash_data = get_option('accua_forms_trash_forms', array());
843 + if (!empty($_GET['fid'])) {
844 + $fid = htmlspecialchars(stripslashes($_GET['fid']), ENT_QUOTES);
845 + } else {
846 + if ($message === '') {
847 + $fid = 1 + ((int) get_option('accua_forms_lastid', 0));
848 + while (isset($forms_data[$fid]) || isset($trash_data[$fid])) {
849 + $fid++;
850 + }
851 + update_option('accua_forms_lastid', $fid);
852 + $message = _accua_forms_test_clonefrom($fid);
853 + if ($message === '') {
854 + return accua_forms_edit_page($fid);
855 + }
856 + } else {
857 + $fid = '';
858 + }
859 + }
860 + if (!empty($_GET['clonefrom'])) {
861 + check_admin_referer('clone_posts');
862 + $clonefrom = stripslashes($_GET['clonefrom']);
863 + } else {
864 + $clonefrom = '';
865 + }
866 +?>
1510 867
1511 -// _accua_forms_get_abs_dest_path() now lives in includes/data-deletion.php, which
1512 -// uninstall.php requires on its own — the deletion needs the same path this file
1513 -// uploads to, and uninstall runs with the plugin unloaded.
868 +<div id="accua_forms_add_page" class="accua_forms_admin_page wrap">
869 +<h2><?php _e( 'Create a form', 'contact-forms'); ?> </h2>
870 +<?php if ($message !== '') {
871 + echo "<div style='border:1px solid; padding: 10px;'>$message</div>";
872 +} ?>
873 +<form action="admin.php" method="GET">
874 +<?php wp_nonce_field('edit_posts', '_wpnonce', false, true) ?>
875 +<input type="hidden" name="page" value="accua_forms_list" />
876 +<p>Form id: <input type="text" name="fid" value="<?php echo $fid; ?>" /></p>
877 +<?php
878 + if ($forms_data) {
879 + echo '<p><select name="clonefrom">
880 + <option value="">'.__( 'Empty form', 'contact-forms').'</option>
881 + <optgroup label="'.__( 'Clone form:', 'contact-forms').'">';
882 + foreach ($forms_data as $i => $formdata) {
883 + $sel = ($i == $clonefrom) ? " selected='selected'" : '';
884 + $i = htmlspecialchars($i, ENT_QUOTES);
885 + if (isset($formdata['title']) && ('' !== trim($formdata['title']))) {
886 + $formtitle = htmlspecialchars($formdata['title']);
887 + } else {
888 + $formtitle = $i;
889 + }
890 + echo "<option value='$i'$sel>$formtitle</option>\n";
891 + }
892 + echo '</optgroup></select></p>';
893 + }
894 +?>
895 +<p><input type="submit" value="<?php _e( 'Create', 'contact-forms'); ?>" /></p>
896 +</form>
897 +</div>
898 +<?php
899 +}
1514 900
1515 -// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- Internal helper function, underscore prefix indicates private
901 +function _accua_forms_test_clonefrom($fid){
902 + $error = '';
903 + if (isset($_GET['clonefrom'])&&$_GET['clonefrom']!=='') {
904 + $clonefrom = stripslashes($_GET['clonefrom']);
905 + $forms_data = get_option('accua_forms_saved_forms', array());
906 + if (isset($forms_data[$fid])){
907 + $error .= "<p>".__( 'Form already exists', 'contact-forms')."</p>";
908 + } else if (empty($forms_data[$clonefrom])) {
909 + $error .= "<p>".__( 'Source form doesn\'t exists.', 'contact-forms')."</p>";
910 + } else {
911 + $forms_data[$fid] = $forms_data[$clonefrom];
912 + if (!isset($forms_data[$fid]['title'])) {
913 + $forms_data[$fid]['title'] = $clonefrom ." ".__( 'clone', 'contact-forms');
914 + } else {
915 + $forms_data[$fid]['title'] .= " ". __( 'clone', 'contact-forms');
916 + }
917 + update_option('accua_forms_saved_forms', $forms_data);
918 + }
919 + }
920 + return $error;
921 +}
922 +
923 +function _accua_forms_form_edit_action() {
924 + static $message = null;
925 + if ($message === null) {
926 + $message = '';
927 + if (isset($_POST['accua-form-edit-action'])){
928 + $post = stripslashes_deep($_POST);
929 + switch ($post['accua-form-edit-action']) {
930 + case 'delete':
931 + $fid = $post['form-id'];
932 + check_admin_referer('contact-forms-delete_'.$fid);
933 + $forms_data = get_option('accua_forms_saved_forms', array());
934 + unset($forms_data[$fid]);
935 + update_option('accua_forms_saved_forms', $forms_data);
936 + $fid = htmlspecialchars($fid);
937 + $message .= sprintf( __( 'Form "%s" deleted','contact-forms' ), $fid );
938 + break;
939 + }
940 + }
941 + }
942 + return $message;
943 +}
944 +
945 +function accua_forms_validate_form_id($fid) {
946 + $error = '';
947 + if (!preg_match('/^[a-z0-9_-]+$/i', $fid)) {
948 + $error .= "<p>".__( 'Only letters, numbers, hyphen and underscores allowed in form identificative name', 'contact-forms')."</p>";
949 + }
950 + if (substr($fid,0,2) == '__') {
951 + $error .= "<p>".__( 'The identificative name can\'t start with two underscores (__)', 'contact-forms')."</p>";
952 + }
953 + if (strlen($fid) > 70) {
954 + $error .= "<p>".__( 'You cannot use more than 70 characters for the identificative name', 'contact-forms')."</p>";
955 + }
956 + return $error;
957 +}
958 +
959 +function accua_forms_list_page() {
960 + $message = '';
961 + if (isset($_POST['accua-form-edit-action'])){
962 + $message = _accua_forms_form_edit_action();
963 + } else if (isset($_GET['fid'])) {
964 + check_admin_referer('edit_posts');
965 + $fid = stripslashes($_GET['fid']);
966 + $error = accua_forms_validate_form_id($fid);
967 + if ($error === '' && (isset($_GET['clonefrom'])&&$_GET['clonefrom']!=='')) {
968 + $error .= _accua_forms_test_clonefrom($fid);
969 + }
970 + if ($error === '') {
971 + return accua_forms_edit_page($fid);
972 + } else {
973 + return accua_forms_add_page($error);
974 + }
975 + }
976 +?>
977 +<div id="accua_forms_list_page" class="accua_forms_admin_page wrap">
978 +<?php if ($message !== '') {
979 + echo "<div style='border:1px solid; padding: 10px;'>$message</div>";
980 +} ?>
981 +<h2><img src="<?php echo ACCUA_FORMS_DIR_URL.'img/cimatti-icon-20.png'; ?>"/> <?php _e( 'Contact Forms', 'contact-forms'); ?>
982 + <a class="add-new-h2" href="<?php echo get_admin_url(); ?>admin.php?page=accua_forms_add"><?php _e('Add New','contact-forms'); ?></a>
983 +</h2>
984 +<div ><?php
985 + echo strtr(__( 'Use the turquoise blue %img_c button in the TinyMCE editor to include the forms in posts, pages or other content types (shortcode and php functions also available)', 'contact-forms'),
986 + array('%img_c'=>'<img alt="C" src="' . plugins_url('img/cimatti-icon-16.png', ACCUA_FORMS_FILE ) . '" />')
987 + );
988 +?></div>
989 +<?php
990 +accua_forms_list_page_table();
991 +?>
992 +</div>
993 +<?php
994 +}
995 +
996 +function accua_forms_edit_page($fid) {
997 + wp_enqueue_script('jquery-ui-tabs','','','',true);
998 + wp_enqueue_script('contact_forms_tabs', plugins_url('accua_tabs.js', ACCUA_FORMS_FILE ), array( 'jquery' ), ACCUA_FORMS_JS_VERSION);
999 +
1000 + if (!class_exists('AccuaFormsHelp')) {
1001 + require_once('accua-forms-help.php');
1002 + }
1003 + $accuaHelp = AccuaFormsHelp::getInstance();
1004 + /*
1005 + $avail_fields = array(
1006 + 'first_name' => array (
1007 + 'id' => "first_name",
1008 + 'name' => "First Name",
1009 + 'type' => "textfield",
1010 + 'description' => 'This is the first name',
1011 + ),
1012 + 'last_name' => array (
1013 + 'id' => "last_name",
1014 + 'name' => "Last Name",
1015 + 'type' => "textfield",
1016 + 'description' => 'This is the last name',
1017 + ),
1018 + 'email' => array (
1019 + 'id' => "email",
1020 + 'name' => "Email",
1021 + 'type' => "email",
1022 + 'description' => 'This is the email',
1023 + ),
1024 + );
1025 + */
1026 +
1027 + $avail_fields = get_option('accua_forms_avail_fields', array());
1028 + $default_form_data = get_option('accua_forms_default_form_data',array());
1029 +
1030 +
1031 +
1032 + $form_data = _accua_forms_get_form_data($fid, true, !empty($_GET['restore']));
1033 + $form_overrided_data = $form_data['_overrided'];
1034 +
1035 + $fid_esc = htmlspecialchars($fid, ENT_QUOTES);
1036 +
1037 + $adminurl = admin_url();
1038 +
1039 + global $wp_version;
1040 + if (version_compare($wp_version, '4') >= 0) {
1041 +?>
1042 +<style>
1043 +#widgets-right .accua-form-widget-scroll-wrapper .widget.ui-draggable {
1044 + height: auto !important;
1045 +}
1046 +</style>
1047 +<?php
1048 + }
1049 +
1050 +?>
1051 +<div id="accua_forms_edit_page" class="accua_forms_admin_page wrap">
1052 +<h2><img src="<?php echo ACCUA_FORMS_DIR_URL.'img/cimatti-icon-20.png'; ?>"/> <?php _e('Contact Forms - Edit Form', 'contact-forms'); ?></h2>
1053 +<div class="accua_form_save_settings_status"></div>
1054 +<?php wp_nonce_field('edit_form', '_nonce_edit_form'); ?>
1055 +<div id="titlediv"><br />
1056 + <label id="title-prompt-text" class="screen-reader-text" for="title"><?php _e( 'Enter title here', 'contact-forms'); ?></label>
1057 + <input id="title" type="text" autocomplete="off" value="<?php echo htmlspecialchars($form_data['title'], ENT_QUOTES) ?>" size="30" name="post_title">
1058 + <script type="text/javascript">
1059 + jQuery(function($){
1060 + if ( jQuery('#titlediv #title').val() == '' )
1061 + jQuery('#title-prompt-text').removeClass('screen-reader-text');
1062 +
1063 + jQuery('#titlediv #title').focus(function() {
1064 + jQuery('#title-prompt-text').addClass('screen-reader-text');
1065 + });
1066 + jQuery('#titlediv #title').blur(function() {
1067 + if ( jQuery('#titlediv #title').val() == '' )
1068 + jQuery('#title-prompt-text').removeClass('screen-reader-text');
1069 + });
1070 + });
1071 + </script>
1072 +</div>
1073 + <div id="accua_tabs">
1074 + <div id="save_settings_top" class="accua_forms_save_settings_top">
1075 + <form id="delete_form" action="admin.php?page=accua_forms_list" method="POST" onsubmit="return confirm(<?php print htmlspecialchars(_accua_forms_json_encode(__('Do you really want to delete this form?', 'contact-forms')), ENT_QUOTES); ?>);">
1076 + <input type="hidden" name="accua-form-edit-action" value="delete" />
1077 + <input type="hidden" name="form-id" value="<?php echo $fid_esc; ?>" />
1078 + <input type="submit" value="<?php _e( 'Delete this form', 'contact-forms'); ?>" />
1079 + <?php wp_nonce_field( 'contact-forms-delete_'.$fid ); ?>
1080 + </form>
1081 + <?php /*<input class="button button-primary button-large accua_form_save_settings_button" id="accua_form_save_settings" type="button" value="<?php echo htmlspecialchars(__( 'Save settings', 'contact-forms'), ENT_QUOTES); ?>" /> */ ?>
1082 + </div>
1083 + <ul id="ul_accua_tabs">
1084 + <li class="tabs"><a href="#accua_tab_fields"><?php _e( 'Fields', 'contact-forms'); ?></a></li>
1085 + <li class="tabs"><a href="#accua_tab_messages"><?php _e( 'Messages', 'contact-forms'); ?></a></li>
1086 + <?php /*<li class="tabs"><a href="#accua_tab_preview"><?php _e( 'Preview/Test', 'contact-forms'); ?></a></li> */ ?>
1087 + </ul>
1088 + <div id="accua_tab_fields" class="content_tab">
1089 + <div style="width:50%; float:left;background: #f4f4f4;">
1090 + <div style="padding: 20px;">
1091 + <input class="button button-primary button-large accua_form_save_settings_button" id="accua_form_save_settings_inside" type="button" value="<?php echo htmlspecialchars(__( 'Save', 'contact-forms'), ENT_QUOTES); ?>" />
1092 + <div id="accua_tabs2">
1093 + <ul>
1094 + <li class="tabs"><a href="#accua_tab_fields2"><?php _e( 'Fields', 'contact-forms'); ?></a></li>
1095 + <li class="tabs"><a href="#accua_tab_customise"><?php _e( 'Appearance', 'contact-forms'); ?></a></li>
1096 + </ul>
1097 + <div id="accua_tab_fields2">
1098 + <h2><?php _e( 'Drag & Drop Form Fields', 'contact-forms'); ?></h2>
1099 + <?php /*<a href="admin.php?page=accua_forms_fields" target="_blank"><strong><?php _e( 'Create new fields here', 'contact-forms'); ?></strong></a></p> */ ?>
1100 + <div style="width:30%; float:left;">
1101 + <!-- Begin available fields -->
1102 +
1103 + <div class="widget-liquid-left" style="margin-right:0">
1104 + <!-- <div id="widgets-left"> -->
1105 + <div id="widgets-left" style="margin-right:5px;">
1106 + <div id="available-widgets" class="widgets-holder-wrap">
1107 + <div class="widget-holder">
1108 + <div id="widget-list">
1109 + <!-- begin fields list -->
1110 +
1111 + <?php
1112 +
1113 + //This block must be executed before the output of available fields so accua_forms_field_text_settings_form() can initialize $html_multi_number for further html and fieldset fields
1114 + $form_fields_html = '';
1115 + foreach ($form_data['fields'] as $field) {
1116 + if (empty($avail_fields[$field['ref']])) {
1117 + $ref = array();
1118 + if (!empty($field['ref'])) {
1119 + if ($field['ref'] == '__fieldset-begin') {
1120 + $ref = array(
1121 + 'id' => '__fieldset-begin',
1122 + 'name' => __('Fieldset begin', 'contact-forms'),
1123 + 'type' => 'fieldset-begin',
1124 + 'description' => '',
1125 + );
1126 + } else if ($field['ref'] == '__fieldset-end') {
1127 + $ref = array(
1128 + 'id' => '__fieldset-end',
1129 + 'name' => __('Fieldset end', 'contact-forms'),
1130 + 'type' => 'fieldset-end',
1131 + 'description' => '',
1132 + );
1133 + }
1134 + }
1135 + } else {
1136 + $ref = $avail_fields[$field['ref']];
1137 + }
1138 +
1139 + //print_r($ref);
1140 + $form_fields_html .= accua_forms_field_text_settings_form($fid, $ref, $field);
1141 + }
1142 +
1143 +
1144 + foreach ($avail_fields as $avail_field) {
1145 + $hidden = (empty($form_data['fields'][$avail_field['id']])) ? false : 'hidden';
1146 + echo accua_forms_field_text_settings_form($fid, $avail_field, $hidden);
1147 + }
1148 + //Custom HTML field
1149 + echo accua_forms_field_text_settings_form($fid);
1150 + //Fieldset begin
1151 + echo accua_forms_field_text_settings_form($fid, array(
1152 + 'id' => '__fieldset-begin',
1153 + 'name' => __( 'Fieldset begin', 'contact-forms'),
1154 + 'type' => 'fieldset-begin',
1155 + 'description' => __('You can use this field multiple times.', 'contact-forms'),
1156 + 'default_value' => '',
1157 + 'allowed_values' => '',
1158 + ));
1159 + //Fieldset end
1160 + echo accua_forms_field_text_settings_form($fid, array(
1161 + 'id' => '__fieldset-end',
1162 + 'name' => __( 'Fieldset end', 'contact-forms'),
1163 + 'type' => 'fieldset-end',
1164 + 'description' => __('You can use this field multiple times.', 'contact-forms'),
1165 + 'default_value' => '',
1166 + 'allowed_values' => '',
1167 + ));
1168 + ?>
1169 +
1170 + <!-- end fields list -->
1171 + </div>
1172 +
1173 + <br class='clear' />
1174 + </div>
1175 + <br class="clear" />
1176 + </div>
1177 +
1178 + </div>
1179 + </div>
1180 + <!-- End available fields -->
1181 + </div>
1182 +
1183 + <div style="width:70%; float:left;" class="container">
1184 + <!--
1185 + <h3>Form Fields</h3>
1186 + <div id="form_fields_container">
1187 + </div>
1188 + -->
1189 +
1190 + <div class="widget-liquid-right" style="width:100%">
1191 + <div id="widgets-right" style="width:100%">
1192 + <div class="widgets-holder-wrap dashed">
1193 + <div class="sidebar-name">
1194 + <div class="sidebar-name-arrow"><br></div>
1195 + <h3><?php _e( 'Drop fields here', 'contact-forms'); ?> <span><img alt="" title="" class="ajax-feedback" src="<?php echo $adminurl;?>images/wpspin_light.gif"></span></h3>
1196 + </div>
1197 + <div class="widgets-sortables ui-sortable" id="cimatti-accua-fields-form-area-<?php echo $fid_esc ?>">
1198 + <?php echo $form_fields_html; ?>
1199 + </div>
1200 + </div>
1201 + </div>
1202 + </div>
1203 +
1204 + </div>
1205 + </div>
1206 + <div id="accua_tab_customise">
1207 + <div style="width: 48%; float:left;">
1208 + <h3><?php _e( 'General', 'contact-forms'); ?></h3>
1209 + <p id="accua_form_use_ajax"><input class="accua_form_value" type="checkbox" value="1" <?php if (!empty($form_data['use_ajax'])) {echo 'checked="checked" ';} ?>/><?php _e('Do not reload the page on form submission', 'contact-forms'); ?></p>
1210 +
1211 + <p id="accua_form_layout"><?php _e( 'Labels', 'contact-forms'); ?> <select name="layout" class="accua_form_value">
1212 + <option value="" <?php if (isset($form_overrided_data['layout'])) { echo 'selected="selected"'; } ?>>default (<?php if($default_form_data['layout']=='sidebyside') _e( 'Labels on the left of the fields', 'contact-forms'); else _e( 'Labels on top of the fields', 'contact-forms'); ?>)</option><option value="sidebyside" <?php if ((isset($form_overrided_data['layout'])) && ($form_data['layout'] == 'sidebyside')) { echo 'selected="selected"'; } ?>><?php _e( 'Labels on the left of the fields', 'contact-forms'); ?></option><option value="toplabel" <?php if ((isset($form_overrided_data['layout'])) && ($form_data['layout'] == 'toplabel')) { echo 'selected="selected"'; } ?>><?php _e( 'Labels on top of the fields', 'contact-forms'); ?></option></select>
1213 + </p>
1214 +
1215 + <div id="accua_form_style_margin" class="label_input" class="label_container">
1216 + <input name="accua_form_style_margin" class="accua_form_check_override" type="checkbox" value="1" <?php if (isset($form_overrided_data['style_margin'])) {echo 'checked="checked" ';} ?>/><strong><?php _e( 'Margin', 'contact-forms'); ?></strong>
1217 + <div class="default_value"><?php echo htmlspecialchars($default_form_data['style_margin']); ?></div>
1218 + <input class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['style_margin'], ENT_QUOTES) ?>" />
1219 +
1220 + </div>
1221 +
1222 + <div class="label_input">
1223 + <div id="accua_form_style_border_color" class="label_container">
1224 + <input name="accua_form_style_border_color" class="accua_form_check_override" type="checkbox" value="1" <?php if (isset($form_overrided_data['style_border_color'])) {echo 'checked="checked" ';} ?>/><strong><?php _e( 'Border color', 'contact-forms'); ?></strong>
1225 + <div class="default_value"><?php echo htmlspecialchars($default_form_data['style_border_color']); ?></div>
1226 + <input class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['style_border_color'], ENT_QUOTES) ?>" />
1227 + </div>
1228 + <div id="accua_form_style_border_width" class="label_container">
1229 + <input name="accua_form_style_border_width" class="accua_form_check_override" type="checkbox" value="1" <?php if (isset($form_overrided_data['style_border_width'])) {echo 'checked="checked" ';} ?>/><?php _e( 'Width', 'contact-forms'); ?>
1230 + <div class="default_value"><?php echo htmlspecialchars($default_form_data['style_border_width']); ?></div>
1231 + <input class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['style_border_width'], ENT_QUOTES) ?>" />
1232 + </div>
1233 + <div id="accua_form_style_border_radius" class="label_container">
1234 + <input name="accua_form_style_border_radius" class="accua_form_check_override" type="checkbox" value="1" <?php if (isset($form_overrided_data['style_border_radius'])) {echo 'checked="checked" ';} ?>/><?php _e( 'Radius', 'contact-forms'); ?>
1235 + <div class="default_value"><?php echo htmlspecialchars($default_form_data['style_border_radius']); ?></div>
1236 + <input class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['style_border_radius'], ENT_QUOTES) ?>" />
1237 + </div>
1238 + </div>
1239 +
1240 + <div class="label_input">
1241 + <div id="accua_form_style_background_color" class="label_container">
1242 + <input name="accua_form_style_background_color" class="accua_form_check_override" type="checkbox" value="1" <?php if (isset($form_overrided_data['style_background_color'])) {echo 'checked="checked" ';} ?>/><strong><?php _e( 'Background', 'contact-forms'); ?></strong>
1243 + <div class="default_value"><?php echo htmlspecialchars($default_form_data['style_background_color']); ?></div>
1244 + <input class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['style_background_color'], ENT_QUOTES) ?>" />
1245 + </div>
1246 +
1247 + <div id="accua_form_style_padding" class="label_container">
1248 + <input name="accua_form_style_padding" class="accua_form_check_override" type="checkbox" value="1" <?php if (isset($form_overrided_data['style_padding'])) {echo 'checked="checked" ';} ?>/><strong><?php _e( 'Padding', 'contact-forms'); ?></strong>
1249 + <div class="default_value"><?php echo htmlspecialchars($default_form_data['style_padding']); ?></div>
1250 + <input class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['style_padding'], ENT_QUOTES) ?>" />
1251 + </div>
1252 + </div>
1253 + <div class="label_input">
1254 + <div id="accua_form_style_color" class="label_container">
1255 + <input name="accua_form_style_color" class="accua_form_check_override" type="checkbox" value="1" <?php if (isset($form_overrided_data['style_color'])) {echo 'checked="checked" ';} ?>/><strong><?php _e( 'Font', 'contact-forms'); ?></strong>
1256 + <div class="default_value"><?php echo htmlspecialchars($default_form_data['style_color']); ?></div>
1257 + <input class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['style_color'], ENT_QUOTES) ?>" />
1258 + </div>
1259 +
1260 + <div id="accua_form_style_font_size" class="label_container">
1261 + <input name="accua_form_style_font_size" class="accua_form_check_override" type="checkbox" value="1" <?php if (isset($form_overrided_data['style_font_size'])) {echo 'checked="checked" ';} ?>/><?php _e( 'Size', 'contact-forms'); ?>
1262 + <div class="default_value"><?php echo htmlspecialchars($default_form_data['style_font_size']); ?></div>
1263 + <input class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['style_font_size'], ENT_QUOTES) ?>" />
1264 + </div>
1265 + </div>
1266 + </div>
1267 + <div style="width: 48%; float:left;">
1268 +
1269 + <h3><?php _e( 'Fields', 'contact-forms'); ?></h3>
1270 +
1271 + <div id="accua_form_style_field_spacing" class="label_input">
1272 + <input name="accua_form_style_field_spacing" class="accua_form_check_override" type="checkbox" value="1" <?php if (isset($form_overrided_data['style_field_spacing'])) {echo 'checked="checked" ';} ?>/><?php _e( 'Spacing', 'contact-forms'); ?>
1273 + <div class="default_value"><?php echo htmlspecialchars($default_form_data['style_field_spacing']); ?></div>
1274 + <input class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['style_field_spacing'], ENT_QUOTES) ?>" />
1275 + </div>
1276 +
1277 + <div id="accua_form_style_field_border_color" class="label_input">
1278 + <input name="accua_form_style_field_border_color" class="accua_form_check_override" type="checkbox" value="1" <?php if (isset($form_overrided_data['style_field_border_color'])) {echo 'checked="checked" ';} ?>/><?php _e( 'Border color', 'contact-forms'); ?>
1279 + <div class="default_value"><?php echo htmlspecialchars($default_form_data['style_field_border_color']); ?></div>
1280 + <input class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['style_field_border_color'], ENT_QUOTES) ?>" />
1281 + </div>
1282 +
1283 + <div id="accua_form_style_field_border_width" class="label_input">
1284 + <input name="accua_form_style_field_border_width" class="accua_form_check_override" type="checkbox" value="1" <?php if (isset($form_overrided_data['style_field_border_width'])) {echo 'checked="checked" ';} ?>/><?php _e( 'Border width', 'contact-forms'); ?>
1285 + <div class="default_value"><?php echo htmlspecialchars($default_form_data['style_field_border_width']); ?></div>
1286 + <input class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['style_field_border_width'], ENT_QUOTES) ?>" />
1287 + </div>
1288 +
1289 + <div id="accua_form_style_field_border_radius" class="label_input">
1290 + <input name="accua_form_style_field_border_radius" class="accua_form_check_override" type="checkbox" value="1" <?php if (isset($form_overrided_data['style_field_border_radius'])) {echo 'checked="checked" ';} ?>/><?php _e( 'Rounded corner radius', 'contact-forms'); ?>
1291 + <div class="default_value"><?php echo htmlspecialchars($default_form_data['style_field_border_radius']); ?></div>
1292 + <input class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['style_field_border_radius'], ENT_QUOTES) ?>" />
1293 + </div>
1294 +
1295 + <div id="accua_form_style_field_background_color" class="label_input">
1296 + <input name="accua_form_style_field_background_color" class="accua_form_check_override" type="checkbox" value="1" <?php if (isset($form_overrided_data['style_field_background_color'])) {echo 'checked="checked" ';} ?>/><?php _e( 'Background color', 'contact-forms'); ?>
1297 + <div class="default_value"><?php echo htmlspecialchars($default_form_data['style_field_background_color']); ?></div>
1298 + <input class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['style_field_background_color'], ENT_QUOTES) ?>" />
1299 + </div>
1300 +
1301 + <div id="accua_form_style_field_padding" class="label_input">
1302 + <input name="accua_form_style_field_padding" class="accua_form_check_override" type="checkbox" value="1" <?php if (isset($form_overrided_data['style_field_padding'])) {echo 'checked="checked" ';} ?>/><?php _e( 'Padding', 'contact-forms'); ?>
1303 + <div class="default_value"><?php echo htmlspecialchars($default_form_data['style_field_padding']); ?></div>
1304 + <input class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['style_field_padding'], ENT_QUOTES) ?>" />
1305 + </div>
1306 +
1307 + <div id="accua_form_style_field_color" class="label_input">
1308 + <input name="accua_form_style_field_color" class="accua_form_check_override" type="checkbox" value="1" <?php if (isset($form_overrided_data['style_field_color'])) {echo 'checked="checked" ';} ?>/><?php _e( 'Text color', 'contact-forms'); ?>
1309 + <div class="default_value"><?php echo htmlspecialchars($default_form_data['style_field_color']); ?></div>
1310 + <input class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['style_field_color'], ENT_QUOTES) ?>" />
1311 + </div>
1312 +
1313 +
1314 + <h3><?php _e( 'Submit button', 'contact-forms'); ?></h3>
1315 +
1316 + <div id="accua_form_style_submit_border_color" class="label_input">
1317 + <input name="accua_form_style_submit_border_color" class="accua_form_check_override" type="checkbox" value="1" <?php if (isset($form_overrided_data['style_submit_border_color'])) {echo 'checked="checked" ';} ?>/><?php _e( 'Border color', 'contact-forms'); ?>
1318 + <div class="default_value"><?php echo htmlspecialchars($default_form_data['style_submit_border_color']); ?></div>
1319 + <input class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['style_submit_border_color'], ENT_QUOTES) ?>" />
1320 + <?php _e( 'Customize', 'contact-forms'); ?>
1321 + </div>
1322 +
1323 + <div id="accua_form_style_submit_border_width" class="label_input">
1324 + <input name="accua_form_style_submit_border_width" class="accua_form_check_override" type="checkbox" value="1" <?php if (isset($form_overrided_data['style_submit_border_width'])) {echo 'checked="checked" ';} ?>/><?php _e( 'Border width', 'contact-forms'); ?>
1325 + <div class="default_value"><?php echo htmlspecialchars($default_form_data['style_submit_border_width']); ?></div>
1326 + <input class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['style_submit_border_width'], ENT_QUOTES) ?>" />
1327 + </div>
1328 +
1329 + <div id="accua_form_style_submit_border_radius" class="label_input">
1330 + <input name="accua_form_style_submit_border_radius" class="accua_form_check_override" type="checkbox" value="1" <?php if (isset($form_overrided_data['style_submit_border_radius'])) {echo 'checked="checked" ';} ?>/><?php _e( 'Rounded corner radius', 'contact-forms'); ?>
1331 + <div class="default_value"><?php echo htmlspecialchars($default_form_data['style_submit_border_radius']); ?></div>
1332 + <input class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['style_submit_border_radius'], ENT_QUOTES) ?>" />
1333 + </div>
1334 +
1335 + <div id="accua_form_style_submit_background_color" class="label_input">
1336 + <input name="accua_form_style_submit_background_color" class="accua_form_check_override" type="checkbox" value="1" <?php if (isset($form_overrided_data['style_submit_background_color'])) {echo 'checked="checked" ';} ?>/><?php _e( 'Background color', 'contact-forms'); ?>
1337 + <div class="default_value"><?php echo htmlspecialchars($default_form_data['style_submit_background_color']); ?></div>
1338 + <input class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['style_submit_background_color'], ENT_QUOTES) ?>" />
1339 + </div>
1340 +
1341 + <div id="accua_form_style_submit_padding" class="label_input">
1342 + <input name="accua_form_style_submit_padding" class="accua_form_check_override" type="checkbox" value="1" <?php if (isset($form_overrided_data['style_submit_padding'])) {echo 'checked="checked" ';} ?>/><?php _e( 'Padding', 'contact-forms'); ?>
1343 + <div class="default_value"><?php echo htmlspecialchars($default_form_data['style_submit_padding']); ?></div>
1344 + <input class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['style_submit_padding'], ENT_QUOTES) ?>" />
1345 + </div>
1346 +
1347 + <div id="accua_form_style_submit_color" class="label_input">
1348 + <input name="accua_form_style_submit_color" class="accua_form_check_override" type="checkbox" value="1" <?php if (isset($form_overrided_data['style_submit_color'])) {echo 'checked="checked" ';} ?>/><?php _e( 'Text color', 'contact-forms'); ?>
1349 + <div class="default_value"><?php echo htmlspecialchars($default_form_data['style_submit_color']); ?></div>
1350 + <input class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['style_submit_color'], ENT_QUOTES) ?>" />
1351 + </div>
1352 +
1353 + <div id="accua_form_style_submit_font_size" class="label_input">
1354 + <input name="accua_form_style_submit_font_size" class="accua_form_check_override" type="checkbox" value="1" <?php if (isset($form_overrided_data['style_submit_font_size'])) {echo 'checked="checked" ';} ?>/><?php _e( 'Font size', 'contact-forms'); ?>
1355 + <div class="default_value"><?php echo htmlspecialchars($default_form_data['style_submit_font_size']); ?></div>
1356 + <input class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['style_submit_font_size'], ENT_QUOTES) ?>" />
1357 + </div>
1358 +
1359 + <br clear="all"/>
1360 + </div>
1361 + </div>
1362 + </div>
1363 +
1364 +
1365 +
1366 + </div>
1367 + </div>
1368 + <div style="width:50%; float:right;">
1369 + <div style="padding: 15px;">
1370 + <h2><?php _e('Preview', 'contact-forms'); ?>
1371 + <?php echo $accuaHelp->add_pointer('form_edit_preview'); ?>
1372 + </h2>
1373 + <div id="accua_form_preview_area_wrapper">
1374 + <?php
1375 + echo "<script>
1376 + function resizeIframe(obj) {
1377 + altezza = obj.contentWindow.document.documentElement.scrollHeight + 200;
1378 + obj.style.height = altezza + 'px';
1379 + }
1380 + </script>";
1381 +
1382 + ?>
1383 + <iframe id="accua_form_preview_area" src="admin-ajax.php?action=accua_forms_preview&fid=<?php echo htmlspecialchars($fid,ENT_QUOTES);?>" frameborder="0" scrolling="no" onload="resizeIframe(this)" ></iframe>
1384 + <?php //todo: posso usare lo stile del sito? font ecc ?>
1385 + </div>
1386 +
1387 + </div>
1388 + </div>
1389 +
1390 + <div style="clear:both;">&nbsp;</div>
1391 +
1392 + <?php /* * / ?>
1393 + <pre>
1394 + accua_forms_form_fields_order_post: <?php echo htmlspecialchars(print_r(get_option('accua_forms_form_fields_order_post'), true)); ?>
1395 +
1396 + accua_forms_save_form_field_post: <?php echo htmlspecialchars(print_r(get_option('accua_forms_save_form_field_post'), true)); ?>
1397 +
1398 + accua_forms_saved_form_data: <?php echo htmlspecialchars(print_r($form_data, true)); ?>
1399 +
1400 + </pre>
1401 + <?php /* */ ?>
1402 +</div>
1403 + <div id="accua_tab_messages" class="content_tab">
1404 + <?php
1405 + $settings_editor = array(
1406 + 'teeny' => true,
1407 + 'editor_class' => 'accua_form_value',
1408 + 'tinymce' => array(
1409 + 'theme_advanced_buttons1' => 'bold,italic,underline,|,bullist,numlist,'));
1410 + ?>
1411 +
1412 + <div class="metabox-holder accua-forms-metabox-holder">
1413 + <div class="postbox ">
1414 + <h3 class="hndle"><span><?php _e('1. On-screen success message', 'contact-forms'); ?></span></h3>
1415 + <div class="inside" id="dashboard_right_now">
1416 + <div id="accua_form_success_message">
1417 + <input class="accua_form_check_override" name="accua_form_success_message" type="radio" value="0" <?php if (!isset($form_overrided_data['success_message'])) {echo ' checked ';} ?>> <?php _e( 'Use the default message', 'contact-forms'); ?>
1418 + <input class="accua_form_check_override" name="accua_form_success_message" type="radio" value="1" <?php if (isset($form_overrided_data['success_message']) && !isset($form_overrided_data['success_message_no_message'])) {echo ' checked ';} ?>/> <?php _e( 'Customize', 'contact-forms'); ?>
1419 + <input class="accua_form_check_override" name="accua_form_success_message" type="radio" value="-1" <?php if (isset($form_overrided_data['success_message_no_message'])) {echo ' checked ';} ?>/> <?php _e( 'Don\'t show any messages', 'contact-forms'); ?><br />
1420 + <div class="defalut_message">
1421 + <?php _e( 'Default Success message', 'contact-forms'); ?>
1422 + <div class="defalut_content_message"><?php echo wpautop($default_form_data['success_message']); ?></div>
1423 + </div>
1424 + <?php wp_editor( $form_data['success_message'] , 'accua_form_success_message_textarea' , $settings_editor); ?>
1425 + <!-- <textarea class="accua_form_value" style="width:95%"; cols="80" rows="8"><?php echo htmlspecialchars($form_data['success_message'], ENT_QUOTES) ?></textarea> -->
1426 + </div>
1427 + </div>
1428 + </div>
1429 + </div>
1430 +
1431 + <div class="metabox-holder accua-forms-metabox-holder">
1432 + <div class="postbox ">
1433 + <h3 class="hndle"><span><?php _e('2. On-screen error message', 'contact-forms'); ?></span></h3>
1434 + <div class="inside" id="dashboard_right_now">
1435 + <div id="accua_form_error_message">
1436 + <input class="accua_form_check_override" name="accua_form_error_message" type="radio" value="0" <?php if (!isset($form_overrided_data['error_message'])) {echo ' checked ';} ?>> <?php _e( 'Use the default message', 'contact-forms'); ?>
1437 + <input class="accua_form_check_override" name="accua_form_error_message" type="radio" value="1" <?php if (isset($form_overrided_data['error_message']) && !isset($form_overrided_data['error_message_no_message'])) {echo ' checked ';} ?>/> <?php _e( 'Customize', 'contact-forms'); ?>
1438 + <input class="accua_form_check_override" name="accua_form_error_message" type="radio" value="-1" <?php if (isset($form_overrided_data['error_message_no_message'])) {echo ' checked ';} ?>/> <?php _e( 'Don\'t show any messages', 'contact-forms'); ?><br />
1439 + <div class="defalut_message">
1440 + <?php _e( 'Default error message', 'contact-forms'); ?> <br />
1441 + <div class="defalut_content_message" ><?php echo wpautop($default_form_data['error_message']); ?></div>
1442 + </div>
1443 + <?php wp_editor( $form_data['error_message'] , 'accua_form_error_message_textarea' , $settings_editor); ?>
1444 + </div>
1445 + </div>
1446 + </div>
1447 + </div>
1448 + <br clear="all"/>
1449 + <div class="metabox-holder accua-forms-metabox-holder">
1450 + <div class="postbox ">
1451 + <h3 class="hndle"><span><?php _e('3. Email to notify administrator', 'contact-forms'); ?></span></h3>
1452 + <div class="inside" id="dashboard_right_now">
1453 + <div id="accua_form_admin_emails_to" class="label_input">
1454 + <label><?php _e('To', 'contact-forms'); ?></label>
1455 + <div class="default_value"><?php echo htmlspecialchars($default_form_data['admin_emails_to']); ?></div>
1456 + <input class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['admin_emails_to'], ENT_QUOTES) ?>" />
1457 + <input name="accua_form_admin_emails_to" class="accua_form_check_override" type="checkbox" value="1" <?php if (isset($form_overrided_data['admin_emails_to'])) {echo 'checked="checked" ';} ?>/><?php _e( 'Customize', 'contact-forms'); ?>
1458 + </div>
1459 + <div id="accua_form_emails_bcc" class="label_input">
1460 + <label><?php _e('Bcc', 'contact-forms'); ?></label>
1461 + <div class="default_value"><?php echo htmlspecialchars($default_form_data['emails_bcc']); ?></div>
1462 + <input class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['emails_bcc'], ENT_QUOTES) ?>" />
1463 + <input name ="accua_form_emails_bcc" class="accua_form_check_override" type="checkbox" value="1" <?php if (isset($form_overrided_data['emails_bcc'])) {echo 'checked="checked" ';} ?>/><?php _e( 'Customize', 'contact-forms'); ?>
1464 + </div>
1465 +
1466 + <div id="accua_form_admin_emails_subject" class="label_input">
1467 + <label><?php _e( 'Subject', 'contact-forms'); ?></label>
1468 + <div class="default_value"><?php echo htmlspecialchars($default_form_data['admin_emails_subject']); ?></div>
1469 + <input class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['admin_emails_subject'], ENT_QUOTES) ?>" />
1470 + <input name="accua_form_admin_emails_subject" class="accua_form_check_override" type="checkbox" value="1" <?php if (isset($form_overrided_data['admin_emails_subject'])) {echo 'checked="checked" ';} ?>/><?php _e( 'Customize', 'contact-forms'); ?>
1471 + </div>
1472 +
1473 + <div id="accua_form_admin_emails_message">
1474 + <input class="accua_form_check_override" name="accua_form_admin_emails_message" type="radio" value="0" <?php if (!isset($form_overrided_data['admin_emails_message'])) {echo ' checked ';} ?>> <?php _e( 'Use the default message', 'contact-forms'); ?>
1475 + <input class="accua_form_check_override" name="accua_form_admin_emails_message" type="radio" value="1" <?php if (isset($form_overrided_data['admin_emails_message']) && !isset($form_overrided_data['admin_emails_message_no_message'])) {echo ' checked ';} ?>/> <?php _e( 'Customize', 'contact-forms'); ?>
1476 + <input class="accua_form_check_override" name="accua_form_admin_emails_message" type="radio" value="-1" <?php if (isset($form_overrided_data['admin_emails_message_no_message'])) {echo ' checked ';} ?>/> <?php _e( 'Don\'t show any messages', 'contact-forms'); ?><br />
1477 + <div class="defalut_message">
1478 + <?php _e( 'Default message', 'contact-forms'); ?>
1479 + <div class="defalut_content_message"><?php echo wpautop($default_form_data['admin_emails_message']); ?></div>
1480 + </div>
1481 + <?php wp_editor( $form_data['admin_emails_message'] , 'accua_form_admin_emails_message_textarea' , $settings_editor); ?>
1482 + </div>
1483 +
1484 + </div>
1485 + </div>
1486 + </div>
1487 +
1488 + <div class="metabox-holder accua-forms-metabox-holder">
1489 + <div class="postbox ">
1490 + <h3 class="hndle"><span><?php _e('4. Email confirmation to the person who completed the form', 'contact-forms'); ?></span></h3>
1491 + <div class="inside" id="dashboard_right_now">
1492 + <div id="accua_form_emails_from_name" class="label_input">
1493 + <label><?php _e( 'From name', 'contact-forms'); ?></label>
1494 + <div class="default_value"><?php echo htmlspecialchars($default_form_data['emails_from_name']); ?></div>
1495 + <input class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['emails_from_name'], ENT_QUOTES) ?>" />
1496 + <input name="accua_form_emails_from_name" class="accua_form_check_override" type="checkbox" value="1" <?php if (isset($form_overrided_data['emails_from_name'])) {echo 'checked="checked" ';} ?>/><?php _e( 'Customize', 'contact-forms'); ?>
1497 + </div>
1498 + <div id="accua_form_emails_from" class="label_input">
1499 + <label><?php _e( 'From email', 'contact-forms'); ?></label>
1500 + <div class="default_value"><?php echo htmlspecialchars($default_form_data['emails_from']); ?></div>
1501 + <input class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['emails_from'], ENT_QUOTES) ?>" />
1502 + <input name="accua_form_emails_from" class="accua_form_check_override" type="checkbox" value="1" <?php if (isset($form_overrided_data['emails_from'])) {echo 'checked="checked" ';} ?>/><?php _e( 'Customize', 'contact-forms'); ?>
1503 + </div>
1504 + <div id="accua_form_confirmation_emails_subject" class="label_input">
1505 + <label><?php _e( 'Subject', 'contact-forms'); ?></label>
1506 + <div class="default_value"><?php echo htmlspecialchars($default_form_data['confirmation_emails_subject']); ?></div>
1507 + <input class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['confirmation_emails_subject'], ENT_QUOTES) ?>" />
1508 + <input name="accua_form_confirmation_emails_subject" class="accua_form_check_override" type="checkbox" value="1" <?php if (isset($form_overrided_data['confirmation_emails_subject'])) {echo 'checked="checked" ';} ?>/><?php _e( 'Customize', 'contact-forms'); ?>
1509 + </div>
1510 +
1511 + <div id="accua_form_confirmation_emails_message">
1512 + <input class="accua_form_check_override" name="accua_form_confirmation_emails_message" type="radio" value="0" <?php if (!isset($form_overrided_data['confirmation_emails_message'])) {echo ' checked ';} ?>> <?php _e( 'Use the default message', 'contact-forms'); ?>
1513 + <input class="accua_form_check_override" name="accua_form_confirmation_emails_message" type="radio" value="1" <?php if (isset($form_overrided_data['confirmation_emails_message']) && !isset($form_overrided_data['confirmation_emails_message_no_message'])) {echo ' checked ';} ?>/> <?php _e( 'Customize', 'contact-forms'); ?>
1514 + <input class="accua_form_check_override" name="accua_form_confirmation_emails_message" type="radio" value="-1" <?php if (isset($form_overrided_data['confirmation_emails_message_no_message'])) {echo ' checked ';} ?>/> <?php _e( 'Don\'t show any messages', 'contact-forms'); ?><br />
1515 + <div class="defalut_message">
1516 + <?php _e( 'Default message', 'contact-forms'); ?>
1517 + <div class="defalut_content_message"><?php echo wpautop($default_form_data['confirmation_emails_message']); ?></div>
1518 + </div>
1519 + <?php wp_editor( $form_data['confirmation_emails_message'] , 'accua_form_confirmation_emails_message_textarea' , $settings_editor); ?>
1520 + </div>
1521 + </div>
1522 + </div>
1523 + </div>
1524 + <br clear="all"/>
1525 +
1526 +<?php accua_forms_print_tokens(); ?>
1527 +
1528 +<input type="hidden" id="accua_form_save_settings_id" value="<?php echo $fid_esc; ?>" />
1529 +</div>
1530 +<?php /*
1531 +<div id="accua_tab_preview" class="content_tab">
1532 +</div> */?>
1533 +<p></p>
1534 +<input class="button button-primary button-large accua_form_save_settings_button" id="accua_form_save_settings_2" type="button" value="<?php _e( 'Save settings', 'contact-forms'); ?>" /> <span class="accua_form_save_settings_status"></span>
1535 +
1536 +</div>
1537 +<script>
1538 +jQuery('input[type=radio]').change(function() {
1539 + var name = jQuery(this).attr('name');
1540 + if (jQuery(this).val() == '1') {
1541 + jQuery('#'+name+' .defalut_message').hide();
1542 + jQuery('#'+name+' .wp-editor-wrap').show();
1543 + }
1544 + else {
1545 + if(jQuery(this).val() != '-1')
1546 + jQuery('#'+name+' .defalut_message').show();
1547 + else
1548 + jQuery('#'+name+' .defalut_message').hide();
1549 + jQuery('#'+name+' .wp-editor-wrap').hide();
1550 + }
1551 +});
1552 +
1553 +jQuery('input[type=checkbox]').click(function() {
1554 + var name = jQuery(this).attr('name');
1555 + if (!this.checked) {
1556 + jQuery('#'+name+' .default_value').show();
1557 + jQuery('#'+name+' .accua_form_value, #'+name+' .cp-color-picker').hide();
1558 + }
1559 + else {
1560 + jQuery('#'+name+' .default_value').hide();
1561 + jQuery('#'+name+' .accua_form_value, #'+name+' .cp-color-picker').show();
1562 + //cp-color-picker
1563 + }
1564 +});
1565 +
1566 +jQuery(".token_link").click(function() {
1567 + jQuery("#dialog_token").dialog("open");
1568 + return false;
1569 +});
1570 +
1571 +//inizializzazione
1572 +jQuery(document).ready(function($){
1573 + $('#accua_form_preview_area_wrapper').resizable({handles: 's'});
1574 + $('#accua_form_preview_area').css({
1575 + 'width': '100%',
1576 + 'height': '100%'
1577 + });
1578 + $.each(
1579 + ['success_message','error_message','admin_emails_message','confirmation_emails_message'],
1580 + function(i,key){
1581 + var value = $('#accua_form_'+key+' .accua_form_check_override:checked').val();
1582 + if(value!=undefined && value!=0) {
1583 + if(value!=-1)
1584 + jQuery('#accua_form_'+key+' .wp-editor-wrap').show();
1585 + else
1586 + jQuery('#accua_form_'+key+' .wp-editor-wrap').hide();
1587 + jQuery('#accua_form_'+key+' .defalut_message').hide();
1588 +
1589 + }
1590 + else {
1591 + jQuery('#accua_form_'+key+' .wp-editor-wrap').hide();
1592 + jQuery('#accua_form_'+key+' .defalut_message').show();
1593 + }
1594 + }
1595 + );
1596 + $.each(
1597 + ['emails_from_name','emails_from','admin_emails_to','emails_bcc','admin_emails_subject','confirmation_emails_subject','style_margin','style_border_color','style_border_width','style_border_radius','style_background_color','style_padding','style_color','style_font_size','style_field_spacing','style_field_border_color','style_field_border_width','style_field_border_radius','style_field_background_color','style_field_padding','style_field_color','style_submit_border_color','style_submit_border_width','style_submit_border_radius','style_submit_background_color','style_submit_padding','style_submit_color','style_submit_font_size'],
1598 + function(i,key){
1599 + if(!$('#accua_form_'+key+' .accua_form_check_override').is(':checked')) {
1600 + jQuery('#accua_form_'+key+' .default_value').show();
1601 + jQuery('#accua_form_'+key+' .accua_form_value, #accua_form_'+key+' .wp-picker-container').hide();
1602 + }
1603 + else {
1604 + jQuery('#accua_form_'+key+' .default_value').hide();
1605 + jQuery('#accua_form_'+key+' .accua_form_value, #accua_form_'+key+' .wp-picker-container').show();
1606 + }
1607 + });
1608 + $("#dialog_token").dialog({ dialogClass:'wp-dialog' ,autoOpen : false, modal : true, show : "blind", hide : "blind"});
1609 +
1610 + $('#accua_token a').appendTo('.wp-media-buttons');
1611 +
1612 +});
1613 +
1614 +jQuery(document).ready(function($){
1615 +
1616 + var originalWidth = $(document).width();
1617 + if(originalWidth <= 883) { //iphone
1618 + $(".metabox-holder").width('98%');
1619 + }
1620 +
1621 + $(window).resize(function (e) {
1622 + var newWidth = $(document).width();
1623 + if(newWidth <= 883) {
1624 + if (originalWidth > 883) {
1625 + $(".metabox-holder").width('98%');
1626 + }
1627 + } else if (originalWidth<=883) {
1628 + $(".metabox-holder").width('47%');
1629 + }
1630 + originalWidth = newWidth;
1631 + });
1632 +});
1633 +
1634 +</script>
1635 +
1636 +<?php
1637 + $accuaHelp->finished();
1638 +}
1639 +
1640 +function accua_forms_fields_page_head() {
1641 +/*
1642 + $baseurl = WP_PLUGIN_URL.'/'.substr(plugin_basename(__FILE__),0,-strlen(basename(__FILE__)));
1643 +?>
1644 + <script type="text/javascript" src="<?php echo $baseurl.'/qtip/jquery.qtip-1.0.0-rc3.js'; ?>"></script>
1645 + <script type="text/javascript">
1646 + var avail_fields = {
1647 + first_name: {
1648 + id: "first_name",
1649 + name: "First Name",
1650 + type: "textfield"
1651 + },
1652 + last_name: {
1653 + id: "last_name",
1654 + name: "Last Name",
1655 + type: "textfield"
1656 + },
1657 + email: {
1658 + id: "email",
1659 + name: "Email",
1660 + type: "email"
1661 + }
1662 + };
1663 +
1664 + jQuery(function($){
1665 + $avail = $('#available_fields_container');
1666 + for(var id in avail_fields) {
1667 + var field = avail_fields[id];
1668 + var el = $('<div></div>').text(field.name);
1669 + el.prepend('<input type="checkbox" />');
1670 + var content = $('<div><span>Id: </span></div>');
1671 + content.append($('<input type="text" />').val(field.id));
1672 + content.append($('<br /><span>Name: </span>'));
1673 + content.append($('<input type="text" />').val(field.name));
1674 + content.append($('<br /><span>Type: </span>'));
1675 + content.append($('<select><option value="textfield">Textfield</option><option value="textarea">Textarea</option><option value="email">Email</option></select>').val(field.type));
1676 + el.qtip({
1677 + content: {
1678 + text: content
1679 + },
1680 + position: {
1681 + target: 'mouse',
1682 + corner: {
1683 + target: 'bottomRight',
1684 + tooltip: 'topLeft'
1685 + },
1686 + adjust: {
1687 + mouse: false
1688 + }
1689 + },
1690 + show: {
1691 + when: {
1692 + event: 'mouseover'
1693 + },
1694 + solo: true
1695 + },
1696 + hide: {
1697 + when: {
1698 + event: 'unfocus'
1699 + }
1700 + }
1701 + });
1702 + $avail.append(el);
1703 + }
1704 + });
1705 + </script>
1706 + <style type="text/css">
1707 + .container > div {
1708 + padding: 0px;
1709 + margin-bottom: 6px;
1710 + }
1711 + </style>
1712 +<?php
1713 +*/
1714 +}
1715 +
1716 +function accua_forms_fields_get_types() {
1717 + return array(
1718 + 'textfield' => __( 'Text Field', 'contact-forms'),
1719 + 'textarea' => __( 'Text Area', 'contact-forms'),
1720 + 'email' => __( 'Email', 'contact-forms'),
1721 + 'autoreply_email' => __( 'Autoreply Email', 'contact-forms'),
1722 + 'checkbox' => __( 'Checkbox','contact-forms'),
1723 + 'select' => __('Select', 'contact-forms'),
1724 + 'radio' => __( 'Radio buttons', 'contact-forms'),
1725 + 'multiselect' => __( 'Multiple selections area', 'contact-forms'),
1726 + 'multicheckbox' => __( 'Multiple checkboxes', 'contact-forms'),
1727 + 'post-select' => __( 'Post select', 'contact-forms'),
1728 + 'post-multicheckbox' => __( 'Multiple post checkboxes', 'contact-forms'),
1729 + 'colorpicker' => __( 'Color picker', 'contact-forms'),
1730 + 'hidden' => __('Hidden value', 'contact-forms'),
1731 + 'file' => __('File upload', 'contact-forms'),
1732 + 'submit' => __( 'Submit button', 'contact-forms'),
1733 + 'html' => __( 'Custom HTML', 'contact-forms'),
1734 + 'captcha' => __( 'Captcha', 'contact-forms'),
1735 + 'password' => 'Password',
1736 + 'password-and-confirm' => __( 'Password and password confirmation','contact-forms'),
1737 + 'date' => __( 'Date','contact-forms'),
1738 + );
1739 +}
1740 +
1741 +function accua_forms_filter_date($value){
1742 + if (($value !== '') && preg_match('/^\d{4}-\d{2}-\d{2}$/', $value)) {
1743 + try {
1744 + $date = new DateTime($value);
1745 + if ($date) {
1746 + return $value;
1747 + }
1748 + } catch (Exception $e) {
1749 + }
1750 + }
1751 + return '';
1752 +}
1753 +
1754 +function accua_forms_fields_filter_values($post, $old_data = array()) {
1755 + //TODO: funzione di validazione dei field
1756 + $data = array(
1757 + 'version' => 2,
1758 + 'id' => $post['form-field-id'],
1759 + 'name' => $post['form-field-name'],
1760 + 'type' => $post['form-field-type'],
1761 + 'description' => $post['form-field-description'],
1762 + 'default_value' => $post['form-field-default-value'],
1763 + 'default_date_value' => $post['form-field-default-date-value'],
1764 + 'allowed_values' => $post['form-field-allowed-values'],
1765 + 'allowed_extensions' => '',
1766 + 'min_date' => $post['form-field-min-of-date'],
1767 + 'max_date' => $post['form-field-max-of-date'],
1768 + );
1769 + $valid = true;
1770 + $message = '';
1771 +
1772 + $types = accua_forms_fields_get_types();
1773 + if (!isset($types[$data['type']])) {
1774 + $message .= "<p>".__('Invalid type', 'contact-forms')."</p>";
1775 + $valid = false;
1776 + $data['type'] = 'textfield';
1777 + }
1778 +
1779 + if (!current_user_can('unfiltered_html')) {
1780 + $filter_fields = array('name', 'description', 'default_value', 'allowed_values');
1781 + foreach ($filter_fields as $k) {
1782 + $data[$k] = wp_kses($data[$k], 'post');
1783 + }
1784 + }
1785 +
1786 + if ($data['type'] == 'file') {
1787 + $data['allowed_extensions'] = accua_forms_filter_extensions($data['allowed_values']);
1788 + }
1789 +
1790 + $dates = array(
1791 + 'default_date_value' => __('Invalid default date', 'contact-forms'),
1792 + 'min_date' => __('Invalid min date', 'contact-forms'),
1793 + 'max_date' => __('Invalid max date', 'contact-forms'),
1794 + );
1795 + foreach ($dates as $k => $errormsg) {
1796 + if ($data[$k] !== '') {
1797 + $data[$k] = accua_forms_filter_date($data[$k]);
1798 + if ($data[$k] === '') {
1799 + $message .= "<p>".$errormsg."</p>";
1800 + $valid = false;
1801 + }
1802 + }
1803 + }
1804 +
1805 + return array(
1806 + 'data' => $data,
1807 + 'valid' => $valid,
1808 + 'message' => $message,
1809 + );
1810 +}
1811 +
1812 +function accua_forms_fields_page() {
1813 +/*
1814 +?>
1815 +<div class="wrap"><h2>Edit Form Fields</h2>
1816 + <div id="available_fields_container" class="container"></div>
1817 +</div>
1818 +<?php
1819 +*/
1820 + $message = '';
1821 + $taxonomy = '';
1822 + $post_type = '';
1823 +
1824 + /*
1825 + $avail_fields = array(
1826 + 'first_name' => array (
1827 + 'id' => "first_name",
1828 + 'name' => "First Name",
1829 + 'type' => "textfield",
1830 + 'description' => 'This is the first name',
1831 + ),
1832 + 'last_name' => array (
1833 + 'id' => "last_name",
1834 + 'name' => "Last Name",
1835 + 'type' => "textfield",
1836 + 'description' => 'This is the last name',
1837 + ),
1838 + 'email' => array (
1839 + 'id' => "email",
1840 + 'name' => "Email",
1841 + 'type' => "email",
1842 + 'description' => 'This is the email',
1843 + ),
1844 + );
1845 + */
1846 +
1847 + $avail_fields = get_option('accua_forms_avail_fields', array());
1848 +
1849 + $default_form_values = array(
1850 + 'version' => 1,
1851 + 'id' => '',
1852 + 'name' => '',
1853 + 'type' => 'textfield',
1854 + 'description' => '',
1855 + 'default_value' => '',
1856 + 'default_date_value' => '',
1857 + 'allowed_values' => '',
1858 + 'allowed_extensions' => '',
1859 + 'min_date' => '',
1860 + 'max_date' => '',
1861 + );
1862 +
1863 + $editing = false;
1864 + $adding = true;
1865 +
1866 + if (!empty($_POST['action'])) {
1867 + check_admin_referer('edit_form_field', '_wpnonce_edit_form_field');
1868 + $post = stripslashes_deep($_POST) + $default_form_values;
1869 + switch($post['action']) {
1870 + case 'edit-form-field':
1871 + if (empty($avail_fields[$post['form-field-id']])) {
1872 + $message .= 'Field "'.htmlspecialchars(sanitize_text_field($post['form-field-id'])).'" doesn\'t exists';
1873 + } else {
1874 + if (empty($post['delete-field'])) {
1875 + $filtered_data = accua_forms_fields_filter_values($post, $avail_fields[$post['form-field-id']]);
1876 + $avail_fields[$post['form-field-id']] = $filtered_data['data'];
1877 + $message .= sprintf( __( 'Field "%s" updated', 'contact-forms'), htmlspecialchars($post['form-field-id']) );
1878 + do_action('accua_forms_field_updated', $avail_fields[$post['form-field-id']]);
1879 + } else {
1880 + $deleting_field = $avail_fields[$post['form-field-id']];
1881 + unset ($avail_fields[$post['form-field-id']]);
1882 + $message .= sprintf( __( 'Field "%s" deleted', 'contact-forms'), htmlspecialchars($post['form-field-id']) );
1883 + do_action('accua_forms_field_deleted', $deleting_field);
1884 + }
1885 + update_option('accua_forms_avail_fields', $avail_fields);
1886 + }
1887 + break;
1888 + case 'add-form-field':
1889 + $fill_form_fields = true;
1890 + $valid = true;
1891 + if (empty($post['form-field-id']) || !preg_match('/^[a-z0-9_-]+$/i', $post['form-field-id'])) {
1892 + $message .= "<p>".__( 'Only letters, numbers, hyphen and underscores allowed in field identificative slug', 'contact-forms')."</p>";
1893 + $valid = false;
1894 + }
1895 + if(substr($post['form-field-id'], 0, 2) == '__') {
1896 + $message .= "<p>".__( 'The field identificative slug can\'t start with two underscores (__)', 'contact-forms')."</p>";
1897 + $valid = false;
1898 + }
1899 + if (!empty($avail_fields[$post['form-field-id']])) {
1900 + $message .= sprintf( __( '<p>A field with identificative slug "%s" already exists</p> Field "%s" deleted', 'contact-forms'), htmlspecialchars($post['form-field-id']) );
1901 + $valid = false;
1902 + }
1903 + if (strlen($post['form-field-id']) > 70) {
1904 + $message .= "<p>".__( 'The identificative slug cannot be longer than 70 characters', 'contact-forms')."</p>";
1905 + $valid = false;
1906 + }
1907 + $filtered_data = accua_forms_fields_filter_values($post);
1908 + $message .= $filtered_data['message'];
1909 + $valid = $valid && $filtered_data['valid'];
1910 + if ($valid) {
1911 + $fill_form_fields = false;
1912 + $avail_fields[$post['form-field-id']] = $filtered_data['data'];
1913 + update_option('accua_forms_avail_fields', $avail_fields);
1914 + $message .= sprintf( __( 'Field "%s" created', 'contact-forms'), htmlspecialchars($post['form-field-id']) );
1915 + do_action('accua_forms_field_added', $avail_fields[$post['form-field-id']]);
1916 + }
1917 + if ($fill_form_fields) {
1918 + $editing = true;
1919 + $default_form_values = $filtered_data['data'];
1920 + }
1921 + break;
1922 + }
1923 + } else if (!empty($_GET['edit-fid'])) {
1924 + $fid = stripslashes($_GET['edit-fid']);
1925 + if (empty($avail_fields[$fid])) {
1926 + $message .= sprintf( __( 'Field "%s" doesn\'t exists', 'contact-forms'), htmlspecialchars($fid) );
1927 + } else {
1928 + $adding = false;
1929 + $editing = true;
1930 + $default_form_values = $avail_fields[$fid] + $default_form_values;
1931 + }
1932 + }
1933 + if ($default_form_values['version'] >= 2 && $default_form_values['type'] == 'file') {
1934 + //Show allowed_extensions value in allowed_values field
1935 + $default_form_values['allowed_values'] = $default_form_values['allowed_extensions'];
1936 + }
1937 +
1938 +?>
1939 +<div id="accua_forms_fields_page" class="accua_forms_admin_page wrap nosubsub">
1940 +<h2><img src="<?php echo ACCUA_FORMS_DIR_URL.'img/cimatti-icon-20.png'; ?>"/> <?php _e('Contact Forms - Fields', 'contact-forms'); ?></h2>
1941 +<?php /* screen_icon(); ?>
1942 +<h2><?php echo esc_html( $title );
1943 +if ( !empty($_REQUEST['s']) )
1944 + printf( '<span class="subtitle">' . __('Search results for &#8220;%s&#8221;') . '</span>', esc_html( stripslashes($_REQUEST['s']) ) ); ?>
1945 +</h2>
1946 +
1947 +<?php if ( isset($_REQUEST['message']) && ( $msg = (int) $_REQUEST['message'] ) ) : ?>
1948 +<div id="message" class="updated"><p><?php echo $messages[$msg]; ?></p></div>
1949 +<?php $_SERVER['REQUEST_URI'] = remove_query_arg(array('message'), $_SERVER['REQUEST_URI']);
1950 +endif; */ ?>
1951 +<div id="ajax-response"><?php echo $message?></div>
1952 +
1953 +<?php /*
1954 +<form class="search-form" action="" method="get">
1955 +<input type="hidden" name="taxonomy" value="<?php echo esc_attr($taxonomy); ?>" />
1956 +<input type="hidden" name="post_type" value="<?php echo esc_attr($post_type); ?>" />
1957 +
1958 +<?php $wp_list_table->search_box( $tax->labels->search_items, 'tag' ); ?>
1959 +
1960 +</form>
1961 +*/ ?>
1962 +
1963 +<br class="clear" />
1964 +
1965 +<div id="col-container">
1966 +
1967 +<div id="col-right">
1968 +<div class="col-wrap">
1969 +<?php if (!$editing) { ?>
1970 +<form id="posts-filter" action="" method="post">
1971 +<input type="hidden" name="taxonomy" value="<?php echo esc_attr($taxonomy); /* TODO: Is this needed? */ ?>" />
1972 +<input type="hidden" name="post_type" value="<?php echo esc_attr($post_type); /* TODO: Is this needed? */ ?>" />
1973 +
1974 +<?php /* $wp_list_table->display(); */ ?>
1975 +
1976 +<table cellspacing="0" class="wp-list-table widefat fixed tags">
1977 + <thead>
1978 + <tr>
1979 + <th style="" class="manage-column column-cb check-column" id="cb" scope="col"><input type="checkbox" /></th>
1980 + <th style="" class="manage-column column-name" id="name" scope="col"><?php _e( 'Label', 'contact-forms'); ?></th>
1981 + <th style="" class="manage-column column-description" id="description" scope="col"><?php _e( 'Description', 'contact-forms'); ?></th>
1982 + <th style="" class="manage-column column-slug" id="slug" scope="col"><?php _e( 'Slug', 'contact-forms'); ?></th>
1983 + <th style="" class="manage-column column-type" id="type" scope="col"><?php _e( 'Type', 'contact-forms'); ?></th>
1984 + </tr>
1985 + </thead>
1986 +
1987 + <tfoot>
1988 + <tr>
1989 + <th style="" class="manage-column column-cb check-column" scope="col"><input type="checkbox" /></th>
1990 + <th style="" class="manage-column column-name" scope="col"><?php _e( 'Label', 'contact-forms'); ?></th>
1991 + <th style="" class="manage-column column-description" scope="col"><?php _e( 'Description', 'contact-forms'); ?></th>
1992 + <th style="" class="manage-column column-slug" scope="col"><?php _e( 'Slug', 'contact-forms'); ?></th>
1993 + <th style="" class="manage-column column-type" scope="col"><?php _e( 'Type', 'contact-forms'); ?></th>
1994 + </tr>
1995 + </tfoot>
1996 +
1997 + <tbody class="list:tag" id="the-list">
1998 +<?php
1999 + foreach ($avail_fields as $id => $field) {
2000 + foreach (array('id', 'name', 'type', 'description') as $i) {
2001 + $field[$i] = htmlspecialchars($field[$i], ENT_QUOTES);
2002 + $field[$i] = sanitize_text_field($field[$i]);
2003 + }
2004 + echo <<<END_OF_ROW
2005 + <tr id="field-{$field['id']}">
2006 + <th class="check-column" scope="row"><input type="checkbox" /></th>
2007 + <td class="name column-name"><strong><a title="Edit “{$field['name']}”" href="admin.php?page=accua_forms_fields&amp;edit-fid={$field['id']}" class="row-title">{$field['name']}</a></strong><br><div class="row-actions"><span class="edit"><a href="admin.php?page=accua_forms_fields&amp;edit-fid={$field['id']}">Edit</a></span></div></td>
2008 + <td class="description column-description">{$field['description']}</td>
2009 + <td class="slug column-slug">{$field['id']}</td>
2010 + <td class="type column-type">{$field['type']}</td>
2011 + </tr>
2012 +END_OF_ROW;
2013 + }
2014 +?>
2015 + </tbody>
2016 +</table>
2017 +
2018 +<br class="clear" />
2019 +</form>
2020 +<?php } ?>
2021 +<?php /* if ( 'category' == $taxonomy ) : ?>
2022 +<div class="form-wrap">
2023 +<p><?php printf(__('<strong>Note:</strong><br />Deleting a category does not delete the posts in that category. Instead, posts that were only assigned to the deleted category are set to the category <strong>%s</strong>.'), apply_filters('the_category', get_cat_name(get_option('default_category')))) ?></p>
2024 +<?php if ( current_user_can( 'import' ) ) : ?>
2025 +<p><?php printf(__('Categories can be selectively converted to tags using the <a href="%s">category to tag converter</a>.'), 'import.php') ?></p>
2026 +<?php endif; ?>
2027 +</div>
2028 +<?php elseif ( 'post_tag' == $taxonomy && current_user_can( 'import' ) ) : ?>
2029 +<div class="form-wrap">
2030 +<p><?php printf(__('Tags can be selectively converted to categories using the <a href="%s">tag to category converter</a>'), 'import.php') ;?>.</p>
2031 +</div>
2032 +<?php endif;
2033 +do_action('after-' . $taxonomy . '-table', $taxonomy);
2034 +*/ ?>
2035 +
2036 +</div>
2037 +</div><!-- /col-right -->
2038 +
2039 +<div id="col-left">
2040 +<div class="col-wrap">
2041 +
2042 +<?php
2043 +/*
2044 +if ( !is_null( $tax->labels->popular_items ) ) {
2045 + if ( current_user_can( $tax->cap->edit_terms ) )
2046 + $tag_cloud = wp_tag_cloud( array( 'taxonomy' => $taxonomy, 'echo' => false, 'link' => 'edit' ) );
2047 + else
2048 + $tag_cloud = wp_tag_cloud( array( 'taxonomy' => $taxonomy, 'echo' => false ) );
2049 +
2050 + if ( $tag_cloud ) :
2051 + ?>
2052 +<div class="tagcloud">
2053 +<h3><?php echo $tax->labels->popular_items; ?></h3>
2054 +<?php echo $tag_cloud; unset( $tag_cloud ); ?>
2055 +</div>
2056 +<?php
2057 +endif;
2058 +}
2059 +*/
2060 +
2061 +/*
2062 +if ( current_user_can($tax->cap->edit_terms) ) {
2063 + // Back compat hooks. Deprecated in preference to {$taxonomy}_pre_add_form
2064 + if ( 'category' == $taxonomy )
2065 + do_action('add_category_form_pre', (object)array('parent' => 0) );
2066 + elseif ( 'link_category' == $taxonomy )
2067 + do_action('add_link_category_form_pre', (object)array('parent' => 0) );
2068 + else
2069 + do_action('add_tag_form_pre', $taxonomy);
2070 +
2071 + do_action($taxonomy . '_pre_add_form', $taxonomy);
2072 +*/
2073 +
2074 +$types = accua_forms_fields_get_types();
2075 +?>
2076 +<div class="form-wrap">
2077 +<h3><?php echo $adding? __( 'Add new field','contact-forms'): __( 'Edit field','contact-forms') ; ?></h3>
2078 +<form id="addtag" method="post" action="admin.php?page=accua_forms_fields" class="validate">
2079 +<input type="hidden" name="action" value="<?php echo $adding?'add':'edit'; ?>-form-field" />
2080 +<?php /*
2081 +<input type="hidden" name="screen" value="<?php echo esc_attr($current_screen->id); ?>" />
2082 +<input type="hidden" name="taxonomy" value="<?php echo esc_attr($taxonomy); ?>" />
2083 +<input type="hidden" name="post_type" value="<?php echo esc_attr($post_type); ?>" />
2084 +*/ ?>
2085 +<?php wp_nonce_field('edit_form_field', '_wpnonce_edit_form_field'); ?>
2086 +
2087 +<div class="form-field form-required">
2088 + <label for="tag-name"><?php _e( 'Field label', 'contact-forms'); ?></label>
2089 + <input name="form-field-name" id="tag-name" type="text" value="<?php echo htmlspecialchars($default_form_values['name'], ENT_QUOTES) ?>" size="40" aria-required="true" />
2090 + <p><?php _e('The name is how it appears on your site.', 'contact-forms'); ?></p>
2091 +</div>
2092 +<?php /* if ( ! global_terms_enabled() ) : */ ?>
2093 +<div class="form-field">
2094 + <label for="tag-slug"><?php _e( 'Field slug (identificative)', 'contact-forms'); ?></label>
2095 + <input name="form-field-id" id="tag-slug" type="text" value="<?php echo htmlspecialchars($default_form_values['id'], ENT_QUOTES) ?>" <?php if (!$adding) { echo 'disabled="disabled"'; } ?> size="40" />
2096 + <?php if (!$adding) { echo '<input type="hidden" name="form-field-id" value="'.htmlspecialchars($default_form_values['id'], ENT_QUOTES).'" />'; } ?>
2097 + <p><?php _e('The &#8220;slug&#8221; is the URL-friendly version of the name. It is used as an identificator, and is unchangeable. It is usually all lowercase and it must contains only letters, numbers, and underscores.', 'contact-forms'); ?></p>
2098 +</div>
2099 +<div class="form-field">
2100 + <label for="parent"><?php _e( 'Field type', 'contact-forms'); ?></label>
2101 + <select class="postform" id="parent" name="form-field-type">
2102 + <?php /*
2103 + <option value="textfield" class="level-0" <?php echo ($default_form_values['type'] == 'textfield')?'selected="selected"':'';?> >Text Field</option>
2104 + <option value="textarea" class="level-0" <?php echo ($default_form_values['type'] == 'textarea')?'selected="selected"':'';?> >Text Area</option>
2105 + <option value="email" class="level-0" <?php echo ($default_form_values['type'] == 'email')?'selected="selected"':'';?> >Email</option>
2106 + <option value="checkbox" class="level-0" <?php echo ($default_form_values['type'] == 'checkbox')?'selected="selected"':'';?> >Checkbox</option>
2107 + <option value="select" class="level-0" <?php echo ($default_form_values['type'] == 'select')?'selected="selected"':'';?> >Select</option>
2108 + */
2109 + foreach ($types as $typeid => $typename) {
2110 + $selected = ($default_form_values['type'] == $typeid)?'selected="selected"':'';
2111 + echo <<<EOT
2112 +<option value="{$typeid}" class="level-0" {$selected} >{$typename}</option>
2113 +EOT;
2114 + }
2115 +
2116 + ?>
2117 + </select>
2118 +</div>
2119 +<?php /* endif; // global_terms_enabled() */ ?>
2120 +<?php /* if ( is_taxonomy_hierarchical($taxonomy) ) : ?>
2121 +<div class="form-field">
2122 + <label for="parent"><?php _ex('Parent', 'Taxonomy Parent'); ?></label>
2123 + <?php wp_dropdown_categories(array('hide_empty' => 0, 'hide_if_empty' => false, 'taxonomy' => $taxonomy, 'name' => 'parent', 'orderby' => 'name', 'hierarchical' => true, 'show_option_none' => __('None'))); ?>
2124 + <?php if ( 'category' == $taxonomy ) : // @todo: Generic text for hierarchical taxonomies ?>
2125 + <p><?php _e('Categories, unlike tags, can have a hierarchy. You might have a Jazz category, and under that have children categories for Bebop and Big Band. Totally optional.'); ?></p>
2126 + <?php endif; ?>
2127 +</div>
2128 +<?php endif; // is_taxonomy_hierarchical() */ ?>
2129 +<div class="form-field">
2130 + <label for="tag-description"><?php _e( 'Field description', 'contact-forms'); ?></label>
2131 + <textarea name="form-field-description" id="tag-description" rows="5" cols="40"><?php echo htmlspecialchars($default_form_values['description'], ENT_QUOTES) ?></textarea>
2132 + <p><?php _e('The description is not prominent by default; however, some themes may show it.', 'contact-forms'); ?></p>
2133 +</div>
2134 +
2135 +<div class="form-field">
2136 + <label for="form-field-default-value"><?php _e( 'Default value(s)', 'contact-forms'); ?>:</label>
2137 + <textarea name="form-field-default-value" id="form-field-default-value" rows="5" cols="40"><?php echo htmlspecialchars($default_form_values['default_value'], ENT_QUOTES) ?></textarea>
2138 + <p><?php _e( 'For multiple default values in multiple select and multiple checkboxes, use | as separator.', 'contact-forms'); ?></p>
2139 +</div>
2140 +
2141 +<div class="form-field">
2142 + <label for="form-field-allowed-values"><?php _e( 'Allowed values', 'contact-forms'); ?>:</label>
2143 + <textarea rows="5" cols="40" name="form-field-allowed-values" id=form-field-allowed-values"><?php echo htmlspecialchars($default_form_values['allowed_values'], ENT_QUOTES) ?></textarea>
2144 + <p><?php _e( 'Options used in select, radio and multiple checkboxes. Enter one value per line, in the format key|label. The key is the value that will be stored in the database. The label is optional, and the key will be used as the label if no label is specified. For file fields, this indicates allowed extensions (one per line without dot)', 'contact-forms'); ?></p>
2145 +</div>
2146 +
2147 +<div class="form-field">
2148 +<?php _e( 'Settings for date fields', 'contact-forms'); ?>
2149 +<div class="form-field">
2150 + <label for="form-field-default-date-value"><?php _e( 'Default value', 'contact-forms'); ?>:</label>
2151 + <input type="date" name="form-field-default-date-value" id="form-field-default-date-value" value="<?php echo htmlspecialchars($default_form_values['default_date_value'], ENT_QUOTES) ?>">
2152 +</div>
2153 +
2154 +
2155 +<label for="form-field-min-of-date"><?php _e( 'Min date', 'contact-forms'); ?>:</label>
2156 +<input type="date" id="form-field-min-of-date" name="form-field-min-of-date" value="<?php echo htmlspecialchars($default_form_values['min_date'], ENT_QUOTES) ?>">
2157 +
2158 +<label for="form-field-max-of-date"><?php _e( 'Max date', 'contact-forms'); ?>:</label>
2159 +<input type="date" id="form-field-max-of-date" name="form-field-max-of-date" value="<?php echo htmlspecialchars($default_form_values['max_date'], ENT_QUOTES) ?>">
2160 +
2161 +</div>
2162 +
2163 +
2164 +<?php
2165 +/*
2166 +if ( ! is_taxonomy_hierarchical($taxonomy) )
2167 + do_action('add_tag_form_fields', $taxonomy);
2168 +do_action($taxonomy . '_add_form_fields', $taxonomy);
2169 +*/
2170 +
2171 +if ($adding) {
2172 + submit_button( __( 'Add new field', 'contact-forms'), 'button' );
2173 +} else {
2174 + submit_button( __( 'Save changes', 'contact-forms'), 'button' );
2175 + submit_button( __( 'Delete field', 'contact-forms'), 'button', 'delete-field');
2176 +}
2177 +
2178 +/*
2179 +// Back compat hooks. Deprecated in preference to {$taxonomy}_add_form
2180 +if ( 'category' == $taxonomy )
2181 + do_action('edit_category_form', (object)array('parent' => 0) );
2182 +elseif ( 'link_category' == $taxonomy )
2183 + do_action('edit_link_category_form', (object)array('parent' => 0) );
2184 +else
2185 + do_action('add_tag_form', $taxonomy);
2186 +
2187 +do_action($taxonomy . '_add_form', $taxonomy);
2188 +*/
2189 +?>
2190 +</form></div>
2191 +<?php /* } */ ?>
2192 +
2193 +</div>
2194 +</div><!-- /col-left -->
2195 +
2196 +</div><!-- /col-container -->
2197 +</div><!-- /wrap -->
2198 +<?php
2199 + /* echo '<pre>accua_forms_avail_fields:', htmlspecialchars(print_r($avail_fields, true)), '</pre>'; */
2200 +}
2201 +
2202 +function accua_forms_settings_page() {
2203 +?>
2204 +<div id="accua_forms_settings_page" class="accua_forms_admin_page wrap">
2205 +<h2><img src="<?php echo ACCUA_FORMS_DIR_URL.'img/cimatti-icon-20.png'; ?>"/> <?php _e('Contact Forms - Default Settings', 'contact-forms'); ?></h2>
2206 +<?php
2207 + $empty_form_data = array(
2208 + 'success_message' => '',
2209 + 'error_message' => '',
2210 + 'emails_from_name' => '',
2211 + 'emails_from' => '',
2212 + 'admin_emails_to' => '',
2213 + 'emails_bcc' => '',
2214 + 'admin_emails_subject' => '',
2215 + 'admin_emails_message' => '',
2216 + 'confirmation_emails_subject' => '',
2217 + 'confirmation_emails_message' => '',
2218 + 'layout' => 'sidebyside',
2219 + 'style_margin' => '',
2220 + 'style_border_color' => '',
2221 + 'style_border_width' => '',
2222 + 'style_border_radius' => '',
2223 + 'style_background_color' => '',
2224 + 'style_padding' => '',
2225 + 'style_color' => '',
2226 + 'style_font_size' => '',
2227 + 'style_field_spacing' => '',
2228 + 'style_field_border_color' => '',
2229 + 'style_field_border_width' => '',
2230 + 'style_field_border_radius' => '',
2231 + 'style_field_background_color' => '',
2232 + 'style_field_padding' => '',
2233 + 'style_field_color' => '',
2234 + 'style_submit_border_color' => '',
2235 + 'style_submit_border_width' => '',
2236 + 'style_submit_border_radius' => '',
2237 + 'style_submit_background_color' => '',
2238 + 'style_submit_padding' => '',
2239 + 'style_submit_color' => '',
2240 + 'style_submit_font_size' => '',
2241 + );
2242 +
2243 + $empty_file_data = array(
2244 + 'valid_extensions' => '',
2245 + 'max_size' => '',
2246 + 'dest_path' => '',
2247 + );
2248 +
2249 + $empty_captcha_data = array(
2250 + 'recaptcha_force_v1' => '',
2251 + 'recaptcha_public_key' => '',
2252 + 'recaptcha_private_key' => '',
2253 + );
2254 +
2255 + $empty_analytics_data = array(
2256 + 'analytics_track_submit' => false,
2257 + 'analytics_track_fields' => false,
2258 + );
2259 +
2260 + $empty_anonymize_ip_data = array(
2261 + 'anonymize_ip_bytes' => 0,
2262 + );
2263 +
2264 + if($_SERVER['REQUEST_METHOD'] == 'POST' && !empty($_POST['accua_form_save_form_settings'])) {
2265 + check_admin_referer('accua_form_save_settings', '_nonce_accua_form_save_settings');
2266 + $post = stripslashes_deep($_POST);
2267 + $post += $empty_form_data;
2268 + $post += $empty_file_data;
2269 + $post += $empty_captcha_data;
2270 + $post += $empty_analytics_data;
2271 + $post += $empty_anonymize_ip_data;
2272 + $form_data = array();
2273 + $file_data = array();
2274 + $captcha_data = array();
2275 + $analytics_data = array();
2276 + $anonymize_ip_data = array();
2277 + foreach($empty_form_data as $key=>$val){
2278 + $form_data[$key] = $post[$key];
2279 + }
2280 + $form_data = accua_forms_filter_settings($form_data);
2281 +
2282 + $file_data['valid_extensions'] = accua_forms_filter_extensions($post['valid_extensions']);
2283 + $file_data['max_size'] = $post['max_size'];
2284 + if (current_user_can('edit_files') || current_user_can('install_plugins')) {
2285 + $file_data['dest_path'] = $post['dest_path'];
2286 + } else {
2287 + $old_file_data = get_option('accua_forms_default_file_field_data',array());
2288 + $file_data['dest_path'] = isset($old_file_data['dest_path']) ? $old_file_data['dest_path'] : '';
2289 + }
2290 +
2291 + $captcha_data['recaptcha_force_v1'] = (bool) $post['recaptcha_force_v1'];
2292 + $captcha_data['recaptcha_public_key'] = sanitize_text_field($post['recaptcha_public_key']);
2293 + $captcha_data['recaptcha_private_key'] = sanitize_text_field($post['recaptcha_private_key']);
2294 +
2295 + foreach($empty_analytics_data as $key=>$val){
2296 + $analytics_data[$key] = (bool) $post[$key];
2297 + }
2298 +
2299 + /* foreach($empty_anonymize_ip_data as $key=>$val){
2300 + $anonymize_ip_data[$key] = $post[$key];
2301 + } */
2302 + $anonymize_ip_bytes = (int) $post['anonymize_ip_bytes'];
2303 + if ($anonymize_ip_bytes < 0) {
2304 + $anonymize_ip_bytes = 0;
2305 + } else if ($anonymize_ip_bytes > 4) {
2306 + $anonymize_ip_bytes = 4;
2307 + }
2308 + $anonymize_ip_data['anonymize_ip_bytes'] = $anonymize_ip_bytes;
2309 +
2310 + update_option('accua_forms_default_form_data', $form_data);
2311 + update_option('accua_forms_default_file_field_data', $file_data);
2312 + update_option('accua_forms_default_captcha_field_data', $captcha_data);
2313 + update_option('accua_forms_default_analytics_data', $analytics_data);
2314 + update_option('accua_forms_anonymize_ip_data', $anonymize_ip_data);
2315 +
2316 + if (!empty($post['delete_previous_ip_values'])) {
2317 + global $wpdb;
2318 + $wpdb->query("UPDATE `{$wpdb->prefix}accua_forms_submissions` SET afs_ip = ''");
2319 + }
2320 + } else {
2321 + $form_data = get_option('accua_forms_default_form_data',array()) + $empty_form_data;
2322 + $file_data = get_option('accua_forms_default_file_field_data',array()) + $empty_file_data;
2323 + $captcha_data = get_option('accua_forms_default_captcha_field_data',array()) + $empty_captcha_data;
2324 + $analytics_data = get_option('accua_forms_default_analytics_data',array()) + $empty_analytics_data;
2325 + $anonymize_ip_data = get_option('accua_forms_anonymize_ip_data',array()) + $empty_anonymize_ip_data;
2326 + }
2327 + if ($captcha_data['recaptcha_force_v1']) {
2328 + $captcha_data = $empty_captcha_data;
2329 + }
2330 +?>
2331 +<form method="post">
2332 +<?php wp_nonce_field('accua_form_save_settings', '_nonce_accua_form_save_settings'); ?>
2333 +<input type="hidden" name="accua_form_save_form_settings" value="1" />
2334 +<?php /*
2335 +<p id="accua_form_layout"><?php _e( 'Layout', 'contact-forms'); ?>: <select name="layout" class="accua_form_value"><option value="sidebyside" <?php if ($form_data['layout'] == 'sidebyside') { echo 'selected="selected"'; } ?>>Labels on the left of the fields</option><option value="toplabel" <?php if ($form_data['layout'] == 'toplabel') { echo 'selected="selected"'; } ?>>Labels on top of the fields</option></select></p>
2336 +<p id="accua_form_success_message"><?php _e( 'Success message', 'contact-forms'); ?>:<br /><textarea name="success_message" class="accua_form_value" style="width:95%"; cols="80" rows="8"><?php echo htmlspecialchars($form_data['success_message'], ENT_QUOTES) ?></textarea></p>
2337 +<p id="accua_form_error_message"><?php _e( 'Error message', 'contact-forms'); ?>:<br /><textarea name="error_message" class="accua_form_value" style="width:95%"; cols="80" rows="8"><?php echo htmlspecialchars($form_data['error_message'], ENT_QUOTES) ?></textarea></p>
2338 +<p id="accua_form_emails_from"><?php _e( 'Emails from', 'contact-forms'); ?>: <input name="emails_from" class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['emails_from'], ENT_QUOTES) ?>" /></p>
2339 +<p id="accua_form_admin_emails_to"><?php _e( 'Admin emails to', 'contact-forms'); ?>: <input name="admin_emails_to" class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['admin_emails_to'], ENT_QUOTES) ?>" /></p>
2340 +<p id="accua_form_emails_bcc"><?php _e( 'Emails bcc', 'contact-forms'); ?>: <input name="emails_bcc" class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['emails_bcc'], ENT_QUOTES) ?>" /></p>
2341 +<p id="accua_form_admin_emails_subject"><?php _e( 'Admin email subject', 'contact-forms'); ?>: <input name="admin_emails_subject" class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['admin_emails_subject'], ENT_QUOTES) ?>" /></p>
2342 +<p id="accua_form_admin_emails_message"><?php _e( 'Admin email message', 'contact-forms'); ?>:<br /><textarea name="admin_emails_message" class="accua_form_value" style="width:95%"; cols="80" rows="8"><?php echo htmlspecialchars($form_data['admin_emails_message'], ENT_QUOTES) ?></textarea></p>
2343 +<p id="accua_form_confirmation_emails_subject"><?php _e( 'Confirmation email subject', 'contact-forms'); ?>: <input name="confirmation_emails_subject" class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['confirmation_emails_subject'], ENT_QUOTES) ?>" /></p>
2344 +<p id="accua_form_confirmation_emails_message"><?php _e( 'Confirmation email message', 'contact-forms'); ?>:<br /><textarea name="confirmation_emails_message" class="accua_form_value" style="width:95%"; cols="80" rows="8"><?php echo htmlspecialchars($form_data['confirmation_emails_message'], ENT_QUOTES) ?></textarea></p>
2345 +*/ ?>
2346 +<div id="accua_tab_messages" class="content_tab">
2347 + <?php
2348 + $settings_editor = array(
2349 + 'teeny' => true,
2350 + 'editor_class' => 'accua_form_value',
2351 + 'tinymce' => array(
2352 + 'theme_advanced_buttons1' => 'bold,italic,underline,|,bullist,numlist,'));
2353 + ?>
2354 + <div class="metabox-holder accua-forms-metabox-holder">
2355 + <div class="postbox ">
2356 + <h3 class="hndle"><span><?php _e('1. On-screen success message', 'contact-forms'); ?></span></h3>
2357 + <div class="inside" id="dashboard_right_now">
2358 + <div id="accua_form_success_message">
2359 + <?php wp_editor( $form_data['success_message'] , 'success_message' , $settings_editor); ?>
2360 + </div>
2361 + </div>
2362 + </div>
2363 + </div>
2364 +
2365 + <div class="metabox-holder accua-forms-metabox-holder">
2366 + <div class="postbox ">
2367 + <h3 class="hndle"><span><?php _e('2. On-screen error message', 'contact-forms'); ?></span></h3>
2368 + <div class="inside" id="dashboard_right_now">
2369 + <div id="accua_form_error_message">
2370 + <?php wp_editor( $form_data['error_message'] , 'error_message' , $settings_editor); ?>
2371 + </div>
2372 + </div>
2373 + </div>
2374 + </div>
2375 + <br clear="all"/>
2376 + <div class="metabox-holder accua-forms-metabox-holder">
2377 + <div class="postbox ">
2378 + <h3 class="hndle"><span><?php _e('3. Email to notify administrator', 'contact-forms'); ?></span></h3>
2379 + <div class="inside" id="dashboard_right_now">
2380 + <div id="accua_form_admin_emails_to" class="label_input">
2381 + <label><?php _e( 'To', 'contact-forms'); ?></label>
2382 + <input name="admin_emails_to" class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['admin_emails_to'], ENT_QUOTES) ?>" />
2383 + </div>
2384 + <br clear="all" />
2385 + <div id="accua_form_emails_bcc" class="label_input">
2386 + <label><?php _e( 'Bcc', 'contact-forms'); ?></label>
2387 + <input name="emails_bcc" class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['emails_bcc'], ENT_QUOTES) ?>" />
2388 + </div>
2389 + <br clear="all" />
2390 + <div id="accua_form_admin_emails_subject" class="label_input">
2391 + <label><?php _e( 'Subject', 'contact-forms'); ?></label>
2392 + <input name="admin_emails_subject" class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['admin_emails_subject'], ENT_QUOTES) ?>" />
2393 + </div>
2394 + <br clear="all" />
2395 + <div id="accua_form_admin_emails_message">
2396 + <?php wp_editor( $form_data['admin_emails_message'] , 'admin_emails_message' , $settings_editor); ?>
2397 + </div>
2398 +
2399 + </div>
2400 + </div>
2401 + </div>
2402 +
2403 + <div class="metabox-holder accua-forms-metabox-holder">
2404 + <div class="postbox ">
2405 + <h3 class="hndle"><span><?php _e('4. Email confirmation to the person who completed the form', 'contact-forms'); ?></span></h3>
2406 + <div class="inside" id="dashboard_right_now">
2407 + <div id="accua_form_emails_from_name" class="label_input">
2408 + <label><?php _e( 'From name', 'contact-forms'); ?></label>
2409 + <input class="accua_form_value" name="emails_from_name" type="text" value="<?php echo htmlspecialchars($form_data['emails_from_name'], ENT_QUOTES) ?>" />
2410 + </div>
2411 + <div id="accua_form_emails_from" class="label_input">
2412 + <label><?php _e( 'From email', 'contact-forms'); ?></label>
2413 + <input class="accua_form_value" name="emails_from" type="text" value="<?php echo htmlspecialchars($form_data['emails_from'], ENT_QUOTES) ?>" />
2414 + </div>
2415 + <br clear="all" />
2416 + <div id="accua_form_confirmation_emails_subject" class="label_input">
2417 + <label><?php _e( 'Subject', 'contact-forms'); ?></label>
2418 + <input class="accua_form_value" type="text" name="confirmation_emails_subject" value="<?php echo htmlspecialchars($form_data['confirmation_emails_subject'], ENT_QUOTES) ?>" />
2419 + </div>
2420 + <br clear="all" />
2421 + <div id="accua_form_confirmation_emails_message">
2422 + <?php wp_editor( $form_data['confirmation_emails_message'] , 'confirmation_emails_message' , $settings_editor); ?>
2423 + </div>
2424 + </div>
2425 + </div>
2426 + </div>
2427 + <br clear="all"/>
2428 +
2429 + <div class="metabox-holder accua-forms-metabox-holder">
2430 + <div class="postbox ">
2431 + <h3 class="hndle"><span><?php _e( 'File upload default settings', 'contact-forms'); ?></span></h3>
2432 + <div class="inside" id="dashboard_right_now">
2433 + <div id="accua_form_valid_extensions"><?php _e( 'Valid extensions', 'contact-forms'); ?> <br /><textarea name="valid_extensions" class="accua_form_value" style="width:95%"; cols="80" rows="8"><?php echo htmlspecialchars($file_data['valid_extensions'], ENT_QUOTES) ?></textarea>
2434 + <small><?php _e( 'List of valid extensions, without dot, one per line.', 'contact-forms'); ?></small>
2435 + </div>
2436 + <div id="accua_form_max_size"><?php _e( 'Maximum file size:', 'contact-forms'); ?> <input name="max_size" class="accua_form_value" type="text" value="<?php echo htmlspecialchars($file_data['max_size'], ENT_QUOTES) ?>" /><br />
2437 + <small><?php _e( 'You can use suffix K, M or G for kilobyte, megabyte or gigabyte.', 'contact-forms'); ?>
2438 + <?php
2439 + $server_max_size = AccuaForm_Element_File::file_upload_max_size();
2440 + if ($server_max_size > 0) {
2441 + _e( 'This value is limited by server upload limits of ', 'contact-forms');
2442 + echo AccuaForm_Element_File::format_size($server_max_size).". ";
2443 + _e( 'If you need a greater limit you should ask to the server administrator.', 'contact-forms');
2444 + }
2445 + ?>
2446 + </small>
2447 + </div>
2448 + <?php if (current_user_can('edit_files') || current_user_can('install_plugins')) { ?>
2449 + <div id="accua_form_dest_path"><?php _e( 'Upload path', 'contact-forms');?> : <input name="dest_path" class="accua_form_value" type="text" value="<?php echo htmlspecialchars($file_data['dest_path'], ENT_QUOTES) ?>" />
2450 + <small><?php _e( 'If it stars with \'/\' an absolute path is used, otherwise a path relative to the WordPress installation directory. Default value is "wp-content/uploads/accua-forms"', 'contact-forms');?>.</small>
2451 + </div>
2452 + <?php } ?>
2453 + </div>
2454 + </div>
2455 +
2456 + <div class="postbox ">
2457 + <h3 class="hndle"><span><?php _e( 'reCaptcha settings', 'contact-forms'); ?></span></h3>
2458 + <div class="inside" id="dashboard_right_now">
2459 + <p><?php _e( 'As reCAPTCHA v1 is discontinued, only reCAPTCHA v2 is supported', 'contact-forms');?></p>
2460 + <p><?php echo strtr(__('Please register this site for reCAPTCHA v2 on %REGISTERURL%, then enter the keys for this site in the following fields', 'contact-forms'), array('%REGISTERURL%' => '<a href="https://www.google.com/recaptcha" target="_blank">google.com/recaptcha</a>'));?></p>
2461 + <div id="accua_form_recaptcha_public_key"><?php _e('Site key', 'contact-forms');?> : <input name="recaptcha_public_key" class="accua_form_value" type="text" value="<?php echo htmlspecialchars($captcha_data['recaptcha_public_key'], ENT_QUOTES) ?>" />
2462 + </div>
2463 + <div id="accua_form_recaptcha_private_key"><?php _e('Secret key', 'contact-forms');?> : <input name="recaptcha_private_key" class="accua_form_value" type="text" value="<?php echo htmlspecialchars($captcha_data['recaptcha_private_key'], ENT_QUOTES) ?>" />
2464 + </div>
2465 + </div>
2466 + </div>
2467 +
2468 + <div class="postbox ">
2469 + <h3 class="hndle"><span><?php _e( 'IP address tracking', 'contact-forms'); ?></span></h3>
2470 + <div class="inside" id="dashboard_accua_form_anonymize_ip_addresses">
2471 + <p>
2472 + <?php _e("Select how many bytes of the visitor's IPs should be masked.", 'contact-forms');?>
2473 + </p>
2474 + <p>
2475 + <input type="radio" name="anonymize_ip_bytes" id="anonymize_ip_bytes_0" value="0" <?php if($anonymize_ip_data['anonymize_ip_bytes'] == 0) { echo 'checked="checked"'; } ?> />
2476 + <label for="anonymize_ip_bytes_0"><?php _e('No mask - e.g. 192.168.1.1', 'contact-forms');?></label><br />
2477 + </p>
2478 + <p>
2479 + <input type="radio" name="anonymize_ip_bytes" id="anonymize_ip_bytes_1" value="1" <?php if($anonymize_ip_data['anonymize_ip_bytes'] == 1) { echo 'checked="checked"'; } ?> />
2480 + <label for="anonymize_ip_bytes_1"><?php _e('1 byte - e.g. 192.168.1.xxx', 'contact-forms');?></label><br />
2481 + </p>
2482 + <p>
2483 + <input type="radio" name="anonymize_ip_bytes" id="anonymize_ip_bytes_2" value="2" <?php if($anonymize_ip_data['anonymize_ip_bytes'] == 2) { echo 'checked="checked"'; } ?> />
2484 + <label for="anonymize_ip_bytes_2"><?php _e('2 byte - e.g. 192.168.xxx.xxx', 'contact-forms');?></label><br />
2485 + </p>
2486 + <p>
2487 + <input type="radio" name="anonymize_ip_bytes" id="anonymize_ip_bytes_3" value="3" <?php if($anonymize_ip_data['anonymize_ip_bytes'] == 3) { echo 'checked="checked"'; } ?> />
2488 + <label for="anonymize_ip_bytes_3"><?php _e('3 byte - e.g. 192.xxx.xxx.xxx', 'contact-forms');?></label><br />
2489 + </p>
2490 + <p>
2491 + <input type="radio" name="anonymize_ip_bytes" id="anonymize_ip_bytes_4" value="4" <?php if($anonymize_ip_data['anonymize_ip_bytes'] == 4) { echo 'checked="checked"'; } ?> />
2492 + <label for="anonymize_ip_bytes_4"><?php _e('Fully mask IP address', 'contact-forms');?></label><br />
2493 + </p>
2494 + <h4><?php _e( 'Delete IP addresses', 'contact-forms'); ?></h4>
2495 + <p>
2496 + <input type="checkbox" id="delete_previous_ip_values" name="delete_previous_ip_values" class="accua_form_value" value="1" />
2497 + <label for="delete_previous_ip_values"><?php _e('Delete all previous IP values', 'contact-forms');?></label><br />
2498 + </p>
2499 + <br clear="all">
2500 + </div>
2501 + </div>
2502 +
2503 + <div class="postbox ">
2504 + <h3 class="hndle"><span><?php _e( 'Track actions with Google Analytics', 'contact-forms'); ?></span></h3>
2505 + <div class="inside" id="dashboard_right_now">
2506 + <p>
2507 + <input type="checkbox" id="accua_form_analytics_track_submit" name="analytics_track_submit" class="accua_form_value" value="1" <?php if($analytics_data['analytics_track_submit']) { echo 'checked="checked"'; } ?> />
2508 + <label for="accua_form_analytics_track_submit"><?php _e('Track submissions', 'contact-forms');?></label>
2509 + </p>
2510 + <p>
2511 + <input type="checkbox" id="accua_form_analytics_track_fields" name="analytics_track_fields" class="accua_form_value" value="1" <?php if($analytics_data['analytics_track_fields']) { echo 'checked="checked"'; } ?> />
2512 + <label for="accua_form_analytics_track_fields"><?php _e('Track fields filled in', 'contact-forms');?></label>
2513 + </p>
2514 + </div>
2515 + </div>
2516 +
2517 + </div>
2518 +
2519 + <div class="metabox-holder accua-forms-metabox-holder">
2520 + <div class="postbox ">
2521 + <h3 class="hndle"><span><?php _e( 'Layout &amp; Styling', 'contact-forms'); ?></span></h3>
2522 + <div class="inside" id="dashboard_right_now">
2523 + <p><?php _e( 'Customize the look and feel of your forms. Leave fields empty if you wish to use the native styles of your WordPress Theme.', 'contact-forms'); ?><p>
2524 + <h4><?php _e( 'Forms', 'contact-forms'); ?></h4>
2525 + <div id="accua_form_layout"> <?php _e( 'Layout', 'contact-forms'); ?>
2526 + <select name="layout" class="accua_form_value"><option value="sidebyside" <?php if ($form_data['layout'] == 'sidebyside') { echo 'selected="selected"'; } ?>>Labels on the left of the fields</option><option value="toplabel" <?php if ($form_data['layout'] == 'toplabel') { echo 'selected="selected"'; } ?>>Labels on top of the fields</option></select>
2527 + </div>
2528 + <div id="accua_form_style_margin" class="label_input">
2529 + <label><?php _e( 'Margin', 'contact-forms'); ?></label>
2530 + <input name="style_margin" class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['style_margin'], ENT_QUOTES) ?>" />
2531 + </div>
2532 + <div id="accua_form_style_border_color" class="label_input">
2533 + <label><?php _e( 'Border color', 'contact-forms'); ?></label>
2534 + <input name="style_border_color" class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['style_border_color'], ENT_QUOTES) ?>" />
2535 + </div>
2536 + <div id="accua_form_style_border_width" class="label_input">
2537 + <label><?php _e( 'Border width', 'contact-forms'); ?></label>
2538 + <input name="style_border_width" class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['style_border_width'], ENT_QUOTES) ?>" />
2539 + </div>
2540 + <div id="accua_form_style_border_radius" class="label_input">
2541 + <label><?php _e( 'Rounded corner radius', 'contact-forms'); ?></label>
2542 + <input name="style_border_radius" class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['style_border_radius'], ENT_QUOTES) ?>" />
2543 + </div>
2544 + <div id="accua_form_style_background_color" class="label_input">
2545 + <label><?php _e( 'Background color', 'contact-forms'); ?></label>
2546 + <input name="style_background_color" class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['style_background_color'], ENT_QUOTES) ?>" />
2547 + </div>
2548 + <div id="accua_form_style_padding" class="label_input">
2549 + <label><?php _e( 'Padding', 'contact-forms'); ?></label>
2550 + <input name="style_padding" class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['style_padding'], ENT_QUOTES) ?>" />
2551 + </div>
2552 + <div id="accua_form_style_color" class="label_input">
2553 + <label><?php _e( 'Text color', 'contact-forms'); ?></label>
2554 + <input name="style_color" class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['style_color'], ENT_QUOTES) ?>" />
2555 + </div>
2556 + <div id="accua_form_style_font_size" class="label_input">
2557 + <label><?php _e( 'Font size', 'contact-forms'); ?></label>
2558 + <input name="style_font_size" class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['style_font_size'], ENT_QUOTES) ?>" />
2559 + </div>
2560 +
2561 + <h4><?php _e( 'Fields', 'contact-forms'); ?></h4>
2562 + <div id="accua_form_style_field_spacing" class="label_input">
2563 + <label><?php _e( 'Spacing', 'contact-forms'); ?></label>
2564 + <input name="style_field_spacing" class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['style_field_spacing'], ENT_QUOTES) ?>" />
2565 + </div>
2566 + <div id="accua_form_style_field_border_color" class="label_input">
2567 + <label><?php _e( 'Border color', 'contact-forms'); ?></label>
2568 + <input name="style_field_border_color" class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['style_field_border_color'], ENT_QUOTES) ?>" />
2569 + </div>
2570 + <div id="accua_form_style_field_border_width" class="label_input">
2571 + <label><?php _e( 'Border width', 'contact-forms'); ?></label>
2572 + <input name="style_field_border_width" class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['style_field_border_width'], ENT_QUOTES) ?>" />
2573 + </div>
2574 + <div id="accua_form_style_field_border_radius" class="label_input">
2575 + <label><?php _e( 'Rounded corner radius', 'contact-forms'); ?></label>
2576 + <input name="style_field_border_radius" class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['style_field_border_radius'], ENT_QUOTES) ?>" />
2577 + </div>
2578 + <div id="accua_form_style_field_background_color" class="label_input">
2579 + <label><?php _e( 'Background color', 'contact-forms'); ?></label>
2580 + <input name="style_field_background_color" class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['style_field_background_color'], ENT_QUOTES) ?>" />
2581 + </div>
2582 + <div id="accua_form_style_field_padding" class="label_input">
2583 + <label><?php _e( 'Padding', 'contact-forms'); ?></label>
2584 + <input name="style_field_padding" class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['style_field_padding'], ENT_QUOTES) ?>" />
2585 + </div>
2586 + <div id="accua_form_style_field_color" class="label_input">
2587 + <label><?php _e( 'Text color', 'contact-forms'); ?></label>
2588 + <input name="style_field_color" class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['style_field_color'], ENT_QUOTES) ?>" />
2589 + </div>
2590 +
2591 + <h4><?php _e( 'Submit button', 'contact-forms'); ?></h4>
2592 + <div id="accua_form_style_submit_border_color" class="label_input">
2593 + <label><?php _e( 'Border color', 'contact-forms'); ?></label>
2594 + <input name="style_submit_border_color" class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['style_submit_border_color'], ENT_QUOTES) ?>" />
2595 + </div>
2596 + <div id="accua_form_style_submit_border_width" class="label_input">
2597 + <label><?php _e( 'Border width', 'contact-forms'); ?></label>
2598 + <input name="style_submit_border_width" class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['style_submit_border_width'], ENT_QUOTES) ?>" />
2599 + </div>
2600 + <div id="accua_form_style_submit_border_radius" class="label_input">
2601 + <label><?php _e( 'Rounded corner radius', 'contact-forms'); ?></label>
2602 + <input name="style_submit_border_radius" class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['style_submit_border_radius'], ENT_QUOTES) ?>" />
2603 + </div>
2604 + <div id="accua_form_style_submit_background_color" class="label_input">
2605 + <label><?php _e( 'Background color', 'contact-forms'); ?></label>
2606 + <input name="style_submit_background_color" class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['style_submit_background_color'], ENT_QUOTES) ?>" />
2607 + </div>
2608 + <div id="accua_form_style_submit_padding" class="label_input">
2609 + <label><?php _e( 'Padding', 'contact-forms'); ?></label>
2610 + <input name="style_submit_padding" class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['style_submit_padding'], ENT_QUOTES) ?>" />
2611 + </div>
2612 + <div id="accua_form_style_submit_color" class="label_input">
2613 + <label><?php _e( 'Text color', 'contact-forms'); ?></label>
2614 + <input name="style_submit_color" class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['style_submit_color'], ENT_QUOTES) ?>" />
2615 + </div>
2616 + <div id="accua_form_style_submit_font_size" class="label_input">
2617 + <label><?php _e( 'Font size', 'contact-forms'); ?></label>
2618 + <input name="style_submit_font_size" class="accua_form_value" type="text" value="<?php echo htmlspecialchars($form_data['style_submit_font_size'], ENT_QUOTES) ?>" />
2619 + </div>
2620 + <br clear="all" />
2621 + </div>
2622 + </div>
2623 + </div>
2624 +
2625 +
2626 + <br clear="all"/>
2627 +
2628 +</div>
2629 +
2630 +<?php /*
2631 +<h3><?php _e( 'File upload default settings', 'contact-forms'); ?></h3>
2632 +<p id="accua_form_valid_extensions"><?php _e( 'Valid extensions', 'contact-forms'); ?> <br /><textarea name="valid_extensions" class="accua_form_value" style="width:95%"; cols="80" rows="8"><?php echo htmlspecialchars($file_data['valid_extensions'], ENT_QUOTES) ?></textarea>
2633 + <small><?php _e( 'List of valid extensions, without dot, one per line.', 'contact-forms'); ?></small>
2634 +</p>
2635 +<p id="accua_form_max_size"><?php _e( 'Maximum file size:', 'contact-forms'); ?> <input name="max_size" class="accua_form_value" type="text" value="<?php echo htmlspecialchars($file_data['max_size'], ENT_QUOTES) ?>" /><br />
2636 + <small><?php _e( 'You can use suffix K, M or G for kilobyte, megabyte or gigabyte.', 'contact-forms'); ?>
2637 +<?php
2638 + $server_max_size = AccuaForm_Element_File::file_upload_max_size();
2639 + if ($server_max_size > 0) {
2640 + _e( 'This value is limited by server upload limits of ', 'contact-forms');
2641 + echo AccuaForm_Element_File::format_size($server_max_size).". ";
2642 + _e( 'If you need a greater limit you should ask to the server administrator.', 'contact-forms');
2643 + }
2644 +?>
2645 + </small></p>
2646 +<p id="accua_form_dest_path"><?php _e( 'Upload path', 'contact-forms');?> : <input name="dest_path" class="accua_form_value" type="text" value="<?php echo htmlspecialchars($file_data['dest_path'], ENT_QUOTES) ?>" />
2647 + <small><?php _e( 'If it stars with \'/\' an absolute path is used, otherwise a path relative to the WordPress installation directory. Default value is "wp-content/uploads/accua-forms"', 'contact-forms');?>.</small>
2648 +</p> */ ?>
2649 +<p><input class="button button-primary button-large" id="accua_form_save_settings" type="submit" value="Save settings" /></p>
2650 +
2651 +<?php accua_forms_print_tokens(); ?>
2652 +
2653 +</form>
2654 +</div>
2655 +
2656 +<script type='text/javascript'>
2657 +jQuery(function($) {
2658 + $('#accua_form_style_border_color .accua_form_value').colorPicker();
2659 + $('#accua_form_style_background_color .accua_form_value').colorPicker();
2660 + $('#accua_form_style_color .accua_form_value').colorPicker();
2661 + $('#accua_form_style_field_border_color .accua_form_value').colorPicker();
2662 + $('#accua_form_style_field_background_color .accua_form_value').colorPicker();
2663 + $('#accua_form_style_field_color .accua_form_value').colorPicker();
2664 + $('#accua_form_style_submit_border_color .accua_form_value').colorPicker();
2665 + $('#accua_form_style_submit_background_color .accua_form_value').colorPicker();
2666 + $('#accua_form_style_submit_color .accua_form_value').colorPicker();
2667 +});
2668 +</script>
2669 +
2670 +<?php
2671 +}
2672 +
2673 +function _accua_forms_get_abs_dest_path($dest_path = '') {
2674 + if ($dest_path === '') {
2675 + return realpath(ABSPATH) . '/wp-content/uploads/accua-forms';
2676 + } else if (substr($dest_path,0,1) === '/') {
2677 + return $dest_path;
2678 + } else {
2679 + return realpath(ABSPATH) . '/' . $dest_path;
2680 + }
2681 +}
2682 +
1516 2683 function _accua_forms_get_form_data($fid = false, $return_empty = true, $restore_trash = false){
1517 2684 $empty_form_data = array(
1518 2685 'fields' => array(),
1519 2686 'title' => '',
@@ -1527,9 +2694,8 @@
1527 2694 'admin_emails_message' => '',
1528 2695 'confirmation_emails_subject' => '',
1529 2696 'confirmation_emails_message' => '',
1530 2697 'use_ajax' => true,
1531 - 'gads_conversion_tracking_code' => '',
1532 2698 'layout' => 'sidebyside',
1533 2699 'style_margin' => '',
1534 2700 'style_border_color' => '',
1535 2701 'style_border_width' => '',
@@ -1551,12 +2717,8 @@
1551 2717 'style_submit_background_color' => '',
1552 2718 'style_submit_padding' => '',
1553 2719 'style_submit_color' => '',
1554 2720 'style_submit_font_size' => '',
1555 - 'submission_retention_override' => false,
1556 - 'submission_retention_value' => 0,
1557 - 'submission_retention_unit' => 'months',
1558 - 'submission_retention_mode' => 'anonymize',
1559 2721 );
1560 2722
1561 2723 if ($fid === false) {
1562 2724 return $empty_form_data;
@@ -1582,10 +2744,17 @@
1582 2744 if (isset($forms_data[$fid])) {
1583 2745 $form_data = array(
1584 2746 '_overrided' => $forms_data[$fid]
1585 2747 ) + $forms_data[$fid] + $default_form_data + $empty_form_data;
2748 + /*
2749 + if ($form_data['fields']) {
2750 + foreach ($form_data['fields'] as $i => $istance_data) {
2751 + // TODO: popuplate default fields data?
2752 + }
2753 + }
2754 + */
1586 2755 return $form_data;
1587 - } elseif ($return_empty) {
2756 + } else if ($return_empty) {
1588 2757 return array(
1589 2758 '_overrided' => array()
1590 2759 ) + $default_form_data + $empty_form_data;
1591 2760 } else {
@@ -1593,149 +2762,8 @@
1593 2762 }
1594 2763
1595 2764 }
1596 2765
1597 -/**
1598 - * Draft System Functions
1599 - *
1600 - * The draft system allows users to make changes to forms in the admin editor
1601 - * without immediately affecting the live/published form. Changes are stored in
1602 - * a transient until the user clicks Save, which publishes the draft.
1603 - *
1604 - * Pattern follows WordPress auto-draft system.
1605 - */
1606 -
1607 -/**
1608 - * Get the transient key for a form's draft data.
1609 - *
1610 - * @param string|int $fid Form ID.
1611 - * @return string Transient key.
1612 - */
1613 -// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- Internal helper function
1614 -function _accua_forms_get_draft_key( $fid ) {
1615 - return 'accua_forms_draft_' . $fid;
1616 -}
1617 -
1618 -/**
1619 - * Initialize or get existing draft for a form.
1620 - * Called when the form editor is loaded.
1621 - *
1622 - * If a draft exists, returns it.
1623 - * If no draft exists, creates one from published data.
1624 - *
1625 - * @param string|int $fid Form ID.
1626 - * @return array Draft data array.
1627 - */
1628 -// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- Internal helper function
1629 -function _accua_forms_init_draft( $fid ) {
1630 - $draft_key = _accua_forms_get_draft_key( $fid );
1631 -
1632 - // Check for existing draft
1633 - $draft_data = get_transient( $draft_key );
1634 -
1635 - if ( $draft_data !== false ) {
1636 - // Draft exists - return it
1637 - return $draft_data;
1638 - }
1639 -
1640 - // No draft - create from published data
1641 - $forms_data = get_option( 'accua_forms_saved_forms', array() );
1642 -
1643 - if ( isset( $forms_data[ $fid ] ) ) {
1644 - $draft_data = $forms_data[ $fid ];
1645 - } else {
1646 - // New form - initialize empty structure
1647 - $draft_data = array( 'fields' => array() );
1648 - }
1649 -
1650 - // Store as draft with 24 hour expiry
1651 - set_transient( $draft_key, $draft_data, DAY_IN_SECONDS );
1652 -
1653 - return $draft_data;
1654 -}
1655 -
1656 -/**
1657 - * Get draft data for a form (creating if necessary).
1658 - * Used by AJAX handlers to read current draft state.
1659 - *
1660 - * @param string|int $fid Form ID.
1661 - * @return array Draft data array.
1662 - */
1663 -// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- Internal helper function
1664 -function _accua_forms_get_draft_data( $fid ) {
1665 - $draft_key = _accua_forms_get_draft_key( $fid );
1666 - $draft_data = get_transient( $draft_key );
1667 -
1668 - if ( $draft_data === false ) {
1669 - // Initialize draft from published data
1670 - $draft_data = _accua_forms_init_draft( $fid );
1671 - }
1672 -
1673 - return $draft_data;
1674 -}
1675 -
1676 -/**
1677 - * Save data to draft transient.
1678 - * Called by AJAX handlers when fields are edited.
1679 - *
1680 - * @param string|int $fid Form ID.
1681 - * @param array $draft_data Complete draft data to save.
1682 - * @return bool True on success.
1683 - */
1684 -// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- Internal helper function
1685 -function _accua_forms_save_draft( $fid, $draft_data ) {
1686 - $draft_key = _accua_forms_get_draft_key( $fid );
1687 - return set_transient( $draft_key, $draft_data, DAY_IN_SECONDS );
1688 -}
1689 -
1690 -/**
1691 - * Publish draft to live data.
1692 - * Called when user clicks Save button.
1693 - *
1694 - * @param string|int $fid Form ID.
1695 - * @return bool True on success.
1696 - */
1697 -// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- Internal helper function
1698 -function _accua_forms_publish_draft( $fid ) {
1699 - $draft_key = _accua_forms_get_draft_key( $fid );
1700 - $draft_data = get_transient( $draft_key );
1701 -
1702 - if ( $draft_data === false ) {
1703 - // No draft to publish - shouldn't happen normally
1704 - return false;
1705 - }
1706 -
1707 - // Get current published data
1708 - $forms_data = get_option( 'accua_forms_saved_forms', array() );
1709 -
1710 - // Update with draft
1711 - $forms_data[ $fid ] = $draft_data;
1712 -
1713 - // Save to database
1714 - $result = update_option( 'accua_forms_saved_forms', $forms_data );
1715 -
1716 - if ( $result ) {
1717 - // Clear draft after successful publish
1718 - delete_transient( $draft_key );
1719 - }
1720 -
1721 - return $result;
1722 -}
1723 -
1724 -/**
1725 - * Delete draft for a form.
1726 - * Called when discarding changes or after successful publish.
1727 - *
1728 - * @param string|int $fid Form ID.
1729 - * @return bool True on success.
1730 - */
1731 -// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- Internal helper function
1732 -function _accua_forms_delete_draft( $fid ) {
1733 - $draft_key = _accua_forms_get_draft_key( $fid );
1734 - return delete_transient( $draft_key );
1735 -}
1736 -
1737 -// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- Internal helper function, underscore prefix indicates private
1738 2766 function _accua_forms_style_parameters($params) {
1739 2767 $ret = '';
1740 2768 foreach ($params as $key => $value) {
1741 2769 $value = trim($value);
@@ -1759,23 +2787,9 @@
1759 2787 add_action('accua_form_alter', 'accua_forms_form_generate', -999, 2);
1760 2788 function accua_forms_form_generate($baseid, $form) {
1761 2789 if (substr($baseid, 0, 14) == '__accua-form__') {
1762 2790 $fid = substr($baseid,14);
1763 -
1764 - // Check if we're in admin preview mode - if so, read from draft
1765 - $use_draft = apply_filters('accua_forms_use_draft_for_preview', false);
1766 - if ($use_draft) {
1767 - // Get draft data and merge with defaults
1768 - $draft_data = _accua_forms_get_draft_data($fid);
1769 - $default_form_data = get_option('accua_forms_default_form_data', array());
1770 - $empty_form_data = _accua_forms_get_form_data(false); // Get empty structure
1771 - $form_data = array(
1772 - '_overrided' => $draft_data
1773 - ) + $draft_data + $default_form_data + $empty_form_data;
1774 - } else {
1775 - // Frontend: read from published data
1776 - $form_data = _accua_forms_get_form_data($fid, false);
1777 - }
2791 + $form_data = _accua_forms_get_form_data($fid, false);
1778 2792 /*
1779 2793 echo '<!-- fid = ';
1780 2794 print_r($fid);
1781 2795 echo "\n\nform_data = ";
@@ -1782,45 +2796,14 @@
1782 2796 print_r($form_data);
1783 2797 echo "\n-->";
1784 2798 */
1785 2799 if ($form_data) {
1786 - // Check for preview order override (allows live preview of field reorder before save)
1787 - $preview_order_override = apply_filters('accua_forms_preview_order_override', null);
1788 - if ($preview_order_override && !empty($form_data['fields'])) {
1789 - // Find the sidebar key for this form (format: cimatti-accua-fields-form-area-{fid})
1790 - $sidebar_key = 'cimatti-accua-fields-form-area-' . $fid;
1791 - if (isset($preview_order_override[$sidebar_key])) {
1792 - $order_string = $preview_order_override[$sidebar_key];
1793 - $order_array = explode(',', $order_string);
1794 -
1795 - // Reorder fields according to preview order
1796 - $old_fields = $form_data['fields'];
1797 - $new_fields = array();;
1798 -
1799 - foreach ($order_array as $widget_id) {
1800 - // Extract instance ID from widget ID (format: widget-{type}_{instance_id})
1801 - $instance_id = preg_replace('/^(new-)?widget-\\d+_/', '', $widget_id);
1802 - if (isset($old_fields[$instance_id])) {
1803 - $new_fields[$instance_id] = $old_fields[$instance_id];
1804 - unset($old_fields[$instance_id]);
1805 - }
1806 - }
1807 -
1808 - // Append any remaining fields not in order
1809 - if ($old_fields) {
1810 - $new_fields += $old_fields;
1811 - }
1812 -
1813 - $form_data['fields'] = $new_fields;
1814 - }
1815 - }
1816 -
1817 2800 $form_style = _accua_forms_style_parameters(array(
1818 2801 'margin' => $form_data['style_margin'],
1819 2802 'border-color' => $form_data['style_border_color'],
1820 2803 'border-width' => $form_data['style_border_width'],
1821 2804 'border-radius' => $form_data['style_border_radius'],
1822 - 'background-color' => $form_data['style_background_color'],
2805 + 'background' => $form_data['style_background_color'],
1823 2806 'padding' => $form_data['style_padding'],
1824 2807 'color' => $form_data['style_color'],
1825 2808 'font-size' => $form_data['style_font_size'],
1826 2809 ));
@@ -1829,9 +2812,9 @@
1829 2812 'margin-bottom' => $form_data['style_field_spacing'],
1830 2813 'border-color' => $form_data['style_field_border_color'],
1831 2814 'border-width' => $form_data['style_field_border_width'],
1832 2815 'border-radius' => $form_data['style_field_border_radius'],
1833 - 'background-color' => $form_data['style_field_background_color'],
2816 + 'background' => (trim($form_data['style_field_background_color']) === '')?'transparent':$form_data['style_field_background_color'],
1834 2817 'padding' => $form_data['style_field_padding'],
1835 2818 'color' => (trim($form_data['style_field_color']) === '')?$form_data['style_color']:$form_data['style_field_color'],
1836 2819 'font-size' => $form_data['style_font_size'],
1837 2820 ));
@@ -1838,17 +2821,14 @@
1838 2821 $field_properties = array();
1839 2822 if ($field_style !== '') {
1840 2823 $field_properties['style'] = $field_style;
1841 2824 }
1842 - // These will be set per-field in the loop below, initialized empty here
1843 - $field_properties['wrapperCssClass'] = '';
1844 - $field_properties['wrapperCssId'] = '';
1845 2825
1846 2826 $submit_style = _accua_forms_style_parameters(array(
1847 2827 'border-color' => $form_data['style_submit_border_color'],
1848 2828 'border-width' => $form_data['style_submit_border_width'],
1849 2829 'border-radius' => $form_data['style_submit_border_radius'],
1850 - 'background-color' => $form_data['style_submit_background_color'],
2830 + 'background' => $form_data['style_submit_background_color'],
1851 2831 'padding' => $form_data['style_submit_padding'],
1852 2832 'color' => $form_data['style_submit_color'],
1853 2833 'font-size' => $form_data['style_submit_font_size'],
1854 2834 ));
@@ -1881,9 +2861,9 @@
1881 2861 'name' => __('Fieldset begin', 'contact-forms'),
1882 2862 'type' => 'fieldset-begin',
1883 2863 'description' => '',
1884 2864 );
1885 - } elseif ($istance_data['ref'] == '__fieldset-end') {
2865 + } else if ($istance_data['ref'] == '__fieldset-end') {
1886 2866 $field_data = array(
1887 2867 'id' => '__fieldset-end',
1888 2868 'name' => __('Fieldset end', 'contact-forms'),
1889 2869 'type' => 'fieldset-end',
@@ -1903,10 +2883,8 @@
1903 2883 'description' => __('Use this special field to inject raw HTML in the form. You can use this multiple times.', 'contact-forms'),
1904 2884 'default_value' => '',
1905 2885 'allowed_values' => '',
1906 2886 'allowed_extensions' => '',
1907 - 'custom_required_message' => '',
1908 - 'custom_format_message' => '',
1909 2887 );
1910 2888
1911 2889 $istance_data += array(
1912 2890 'version' => 1,
@@ -1940,13 +2918,8 @@
1940 2918 'label' => $field_data['name'],
1941 2919 'default_value' => $field_data['default_value'], /* viene impostato il valore di defualt se non è un campo data */
1942 2920 'allowed_values' => $field_data['allowed_values'],
1943 2921 'allowed_extensions' => $field_data['allowed_extensions'],
1944 - 'post_type' => 'page', // Default for post-select fields
1945 - 'css_class' => '',
1946 - 'css_id' => '',
1947 - 'custom_required_message' => '',
1948 - 'custom_format_message' => '',
1949 2922 );
1950 2923
1951 2924 $element = NULL;
1952 2925 $element_conf = NULL;
@@ -1952,45 +2925,15 @@
1952 2925 $element_conf = NULL;
1953 2926
1954 2927 $allowed_val = trim($istance_data['allowed_values']);
1955 2928
1956 - // For post-select fields, we use lazy loading via AJAX, so don't pre-load posts here
1957 - if ($field_data['type'] == 'post-multicheckbox') {
1958 - // Post-multicheckbox still needs pre-loaded options for checkbox rendering
1959 - $post_type = isset($istance_data['post_type']) ? $istance_data['post_type'] : 'page';
1960 - $query_args = array();
1961 - if (!empty($allowed_val)) {
1962 - wp_parse_str($allowed_val, $query_args);
1963 - }
1964 - // Let a post_type in the query parameters override the field's
1965 - // post-type setting, matching post-select. The value comes from the
1966 - // saved field configuration (not a client request) and is validated
1967 - // against public post types.
1968 - if (!empty($query_args['post_type'])) {
1969 - $mc_public_types = get_post_types(array('public' => true));
1970 - $mc_override = sanitize_text_field($query_args['post_type']);
1971 - if (isset($mc_public_types[$mc_override])) {
1972 - $post_type = $mc_override;
1973 - }
1974 - }
1975 - $query_args['post_type'] = $post_type;
1976 - // Only publish/private may be exposed, even if the admin configured other statuses.
1977 - if (!empty($query_args['post_status'])) {
1978 - $mc_statuses = accua_forms_filter_field_post_status($query_args['post_status']);
1979 - if (!empty($mc_statuses)) {
1980 - $query_args['post_status'] = $mc_statuses;
1981 - } else {
1982 - unset($query_args['post_status']);
1983 - }
1984 - }
1985 - $posts = accua_get_pages($query_args);
2929 + if ($field_data['type'] == 'post-multicheckbox' || $field_data['type'] == 'post-select') {
2930 + $posts = accua_get_pages($allowed_val);
1986 2931 $allowed_values = array();
1987 2932 foreach ($posts as $p) {
2933 + //$allowed_values[$p->ID] = apply_filters( 'the_title', $p->post_title, $p->ID );
1988 2934 $allowed_values[$p->ID] = $p->post_title;
1989 2935 }
1990 - } elseif ($field_data['type'] == 'post-select') {
1991 - // Post-select uses lazy loading - just set empty options, JS will fetch
1992 - $allowed_values = array();
1993 2936 } else {
1994 2937 if ($field_data['type'] == 'file') {
1995 2938 $filedata = get_option('accua_forms_default_file_field_data',array());
1996 2939 $filedata += array(
@@ -2024,60 +2967,14 @@
2024 2967 $allowed_values[$val[0]] = $val[1];
2025 2968 }
2026 2969 }
2027 2970
2028 - // Set per-field wrapper CSS class and ID
2029 - $field_properties['wrapperCssClass'] = isset($istance_data['css_class']) ? $istance_data['css_class'] : '';
2030 - $field_properties['wrapperCssId'] = isset($istance_data['css_id']) ? $istance_data['css_id'] : '';
2031 -
2032 - // Captcha fields hide their title by default: the wrapper class makes
2033 - // the label screen-reader only (frontend.css), keeping it available to
2034 - // assistive tech and to the error summary JS label lookup.
2035 - if (in_array($field_data['type'], array('captcha', 'captcha_v3', 'cap'), true)
2036 - && accua_forms_captcha_hide_title($istance_data)) {
2037 - $field_properties['wrapperCssClass'] = trim($field_properties['wrapperCssClass'] . ' accua-captcha-title-hidden');
2038 - }
2039 -
2040 - // Resolve per-field custom validation messages (per-form instance → field definition → default)
2041 - $resolved_required_msg = '';
2042 - if (!empty($istance_data['custom_required_message'])) {
2043 - $resolved_required_msg = $istance_data['custom_required_message'];
2044 - } elseif (!empty($field_data['custom_required_message'])) {
2045 - $resolved_required_msg = $field_data['custom_required_message'];
2046 - }
2047 -
2048 - $resolved_format_msg = '';
2049 - if (!empty($istance_data['custom_format_message'])) {
2050 - $resolved_format_msg = $istance_data['custom_format_message'];
2051 - } elseif (!empty($field_data['custom_format_message'])) {
2052 - $resolved_format_msg = $field_data['custom_format_message'];
2053 - }
2054 -
2055 - // Add data attributes for client-side custom messages (reset each iteration)
2056 - unset($field_properties['data-custom-required-msg']);
2057 - unset($field_properties['data-custom-format-msg']);
2058 - if ($resolved_required_msg !== '') {
2059 - $field_properties['data-custom-required-msg'] = $resolved_required_msg;
2060 - }
2061 - if ($resolved_format_msg !== '') {
2062 - $field_properties['data-custom-format-msg'] = $resolved_format_msg;
2063 - }
2064 -
2065 2971 switch ($field_data['type']) {
2066 2972 case 'textarea':
2067 2973 $element = new Element_Textarea($istance_data['label'], $istance_data['istance_id'], $field_properties+array('cols' => '50', 'value'=>$istance_data['default_value']));
2068 2974 break;
2069 2975 case 'hidden':
2070 - // Hidden inputs render without the .pfbc-element wrapper, so the
2071 - // editor's CSS Class / CSS ID land on the input itself.
2072 - $hidden_props = array();
2073 - if ( !empty($field_properties['wrapperCssId']) ) {
2074 - $hidden_props['id'] = $field_properties['wrapperCssId'];
2075 - }
2076 - if ( !empty($field_properties['wrapperCssClass']) ) {
2077 - $hidden_props['class'] = $field_properties['wrapperCssClass'];
2078 - }
2079 - $element = new Element_Hidden($istance_data['istance_id'], $istance_data['default_value'], !empty($hidden_props) ? $hidden_props : null);
2976 + $element = new Element_Hidden($istance_data['istance_id'], $istance_data['default_value']);
2080 2977 break;
2081 2978 case 'checkbox':
2082 2979 $lab = $istance_data['label'];
2083 2980 if (!empty($istance_data['required'])) {
@@ -2086,17 +2983,18 @@
2086 2983 if ($allowed_values) {
2087 2984 reset($allowed_values);
2088 2985 $val = (string) key($allowed_values);
2089 2986 $defval = trim($istance_data['default_value']);
2090 - } elseif ($istance_data['default_value'] == '1') {
2987 + } else if ($istance_data['default_value'] == '1') {
2091 2988 $defval = $val = '1';
2092 2989 } else {
2093 2990 $val = empty($istance_data['default_value'])?'1':$istance_data['default_value'];
2094 2991 $defval = '';
2095 2992 }
2096 - $element = new AccuaForm_Element_Checkbox('', $istance_data['istance_id'], array($val => $lab), $field_properties+array('value' => $defval));
2993 + $element = new AccuaForm_Element_Checkbox('', $istance_data['istance_id'], array($val => $lab), array('value' => $defval));
2097 2994 break;
2098 2995 case 'select':
2996 + case 'post-select':
2099 2997 if (!isset($allowed_values[''])) {
2100 2998 $allowed_values = array('' => '') + $allowed_values;
2101 2999 }
2102 3000 $defval = trim($istance_data['default_value']);
@@ -2101,17 +2999,11 @@
2101 2999 }
2102 3000 $defval = trim($istance_data['default_value']);
2103 3001 $element = new AccuaForm_Element_Select($istance_data['label'], $istance_data['istance_id'], $allowed_values, $field_properties+array('value'=>$defval));
2104 3002 break;
2105 - case 'post-select':
2106 - $post_type = isset($istance_data['post_type']) ? $istance_data['post_type'] : 'page';
2107 - $extra_args = trim($istance_data['allowed_values']);
2108 - $defval = trim($istance_data['default_value']);
2109 - $element = new AccuaForm_Element_PostSelect($istance_data['label'], $istance_data['istance_id'], $post_type, $extra_args, $field_properties+array('value'=>$defval));
2110 - break;
2111 3003 case 'radio':
2112 3004 $defval = trim($istance_data['default_value']);
2113 - $element = new AccuaForm_Element_Radio($istance_data['label'], $istance_data['istance_id'], $allowed_values, $field_properties+array('value'=>$defval));
3005 + $element = new AccuaForm_Element_Radio($istance_data['label'], $istance_data['istance_id'], $allowed_values, array('value'=>$defval));
2114 3006 break;
2115 3007 case 'multiselect':
2116 3008 $defval = explode('|', $istance_data['default_value']);
2117 3009 foreach ($defval as $k => $v) {
@@ -2124,9 +3016,9 @@
2124 3016 $defval = explode('|', $istance_data['default_value']);
2125 3017 foreach ($defval as $k => $v) {
2126 3018 $defval[$k] = trim($v);
2127 3019 }
2128 - $element = new AccuaForm_Element_Checkbox($istance_data['label'], $istance_data['istance_id'], $allowed_values, $field_properties+array('value'=>$defval));
3020 + $element = new AccuaForm_Element_Checkbox($istance_data['label'], $istance_data['istance_id'], $allowed_values, array('value'=>$defval));
2129 3021 break;
2130 3022 case 'file':
2131 3023 $fdata = array();
2132 3024
@@ -2142,17 +3034,17 @@
2142 3034
2143 3035 $element = new AccuaForm_Element_File($istance_data['label'], $istance_data['istance_id'], $field_properties+$fdata);
2144 3036 break;
2145 3037 case 'html':
2146 - $element = new Element_HTML($istance_data['default_value'], $field_properties);
3038 + $element = new Element_HTML($istance_data['default_value']);
2147 3039 break;
2148 3040 case 'email':
2149 3041 case 'autoreply_email':
2150 - $email_props = $field_properties+array('value'=>$istance_data['default_value']);
2151 - if ($resolved_format_msg !== '') {
2152 - $email_props['custom_format_message'] = $resolved_format_msg;
2153 - }
2154 - $element = new AccuaForm_Element_Email($istance_data['label'], $istance_data['istance_id'], $email_props);
3042 + $element = new AccuaForm_Element_Email($istance_data['label'], $istance_data['istance_id'], $field_properties+array('value'=>$istance_data['default_value']));
3043 + $element->setValidation(new Validation_Email(
3044 + str_replace('%element%', $istance_data['label'], __("Attention: '%element%' must contain an email address.", 'contact-forms'))
3045 + ));
3046 + //"Errore: '{$istance_data['label']}' deve contenere un indirizzo email valido."
2155 3047 break;
2156 3048 case 'colorpicker':
2157 3049 $element = new AccuaForm_Element_ColorPicker($istance_data['label'], $istance_data['istance_id'], $field_properties+array('value'=>$istance_data['default_value']));
2158 3050 break;
@@ -2161,11 +3053,9 @@
2161 3053 $form->addElement(new AccuaForm_Element_FieldsetEnd());
2162 3054 } else {
2163 3055 $fieldset_open = true;
2164 3056 }
2165 - $fs_props = $field_properties;
2166 - $fs_props['fieldset_style'] = isset($istance_data['fieldset_style']) ? $istance_data['fieldset_style'] : 'border-off-title-off';
2167 - $element = new AccuaForm_Element_FieldsetBegin($istance_data['label'], $istance_data['istance_id'], $fs_props);
3057 + $element = new AccuaForm_Element_FieldsetBegin($istance_data['label'], $istance_data['istance_id']);
2168 3058 break;
2169 3059 case 'fieldset-end':
2170 3060 if ($fieldset_open) {
2171 3061 $element = new AccuaForm_Element_FieldsetEnd();
@@ -2173,19 +3063,9 @@
2173 3063 }
2174 3064 break;
2175 3065 case 'submit':
2176 3066 $add_submit = false;
2177 - $submit_extra = array('name' => $istance_data['istance_id'], 'value' => $istance_data['default_value']);
2178 - // Buttons render inside the shared .pfbc-buttons group without a
2179 - // per-element wrapper, so the editor's CSS Class / CSS ID are
2180 - // applied to the button element itself.
2181 - if (!empty($field_properties['wrapperCssClass'])) {
2182 - $submit_extra['class'] = $field_properties['wrapperCssClass'];
2183 - }
2184 - if (!empty($field_properties['wrapperCssId'])) {
2185 - $submit_extra['id'] = $field_properties['wrapperCssId'];
2186 - }
2187 - $element = new Element_Button($istance_data['label'], 'submit', $submit_properties+$submit_extra);
3067 + $element = new Element_Button($istance_data['label'], 'submit', $submit_properties+array('name' => $istance_data['istance_id'], 'value' => $istance_data['default_value']));
2188 3068 break;
2189 3069 case 'captcha':
2190 3070 $empty_captcha_data = array(
2191 3071 'recaptcha_force_v1' => '',
@@ -2192,16 +3072,9 @@
2192 3072 'recaptcha_public_key' => '',
2193 3073 'recaptcha_private_key' => '',
2194 3074 );
2195 3075 $captcha_data = get_option('accua_forms_default_captcha_field_data',array()) + $empty_captcha_data;
2196 - $captcha_properties = array(
2197 - "description" => "",
2198 - // Same accuaform_{fid} key format as v3: it identifies this
2199 - // form in the request-scoped spam-flag registry shared by the
2200 - // captcha validators (AccuaForm_Validation_CaptchaSpam).
2201 - 'captchaAction' => 'accuaform_' . preg_replace('/[^A-Za-z0-9_]/', '_', $fid),
2202 - 'spamAction' => accua_forms_captcha_spam_action($istance_data, 'captcha'),
2203 - );
3076 + $captcha_properties = array("description" => "");
2204 3077 $captcha_use_v1 = true;
2205 3078 if (($captcha_data['recaptcha_public_key'] !== '') && ($captcha_data['recaptcha_private_key'] !== '')) {
2206 3079 $captcha_properties['privateKey'] = $captcha_data['recaptcha_private_key'];
2207 3080 $captcha_properties['publicKey'] = $captcha_data['recaptcha_public_key'];
@@ -2209,60 +3082,17 @@
2209 3082 }
2210 3083 if ($captcha_use_v1) {
2211 3084 $element = new Element_HTML("\n\n<!-- ReCaptcha 1 is discontinued, please go to Contact Forms settings page and set reCaptcha v2 keys -->\n\n");
2212 3085 } else {
2213 - $element = new AccuaForm_Element_Captcha2 ($istance_data['label'], '', $field_properties+$captcha_properties);
3086 + $element = new AccuaForm_Element_Captcha2 ($istance_data['label'], '', $captcha_properties);
2214 3087 }
2215 3088 break;
2216 - case 'captcha_v3':
2217 - $captcha3_empty_data = array(
2218 - 'recaptcha_v3_public_key' => '',
2219 - 'recaptcha_v3_private_key' => '',
2220 - );
2221 - $captcha3_data = get_option('accua_forms_default_captcha_field_data',array()) + $captcha3_empty_data;
2222 - if (($captcha3_data['recaptcha_v3_public_key'] !== '') && ($captcha3_data['recaptcha_v3_private_key'] !== '')) {
2223 - $captcha3_properties = array(
2224 - 'description' => '',
2225 - 'privateKey' => $captcha3_data['recaptcha_v3_private_key'],
2226 - 'publicKey' => $captcha3_data['recaptcha_v3_public_key'],
2227 - // Distinct action per form, restricted to the characters Google allows
2228 - 'captchaAction' => 'accuaform_' . preg_replace('/[^A-Za-z0-9_]/', '_', $fid),
2229 - 'spamAction' => accua_forms_captcha_spam_action($istance_data, 'captcha_v3'),
2230 - 'scoreThreshold' => accua_forms_recaptcha3_score_threshold($istance_data),
2231 - );
2232 - $element = new AccuaForm_Element_Captcha3($istance_data['label'], '', $field_properties+$captcha3_properties);
2233 - } else {
2234 - $element = new Element_HTML("\n\n<!-- reCAPTCHA v3 keys are not configured, please go to Contact Forms settings page and set the reCAPTCHA v3 keys -->\n\n");
2235 - }
2236 - break;
2237 - case 'turnstile':
2238 - $element = new AccuaForm_Element_Turnstile($istance_data['label'], $istance_data['istance_id'], $field_properties+array("description" => ""));
2239 - break;
2240 - case 'cap':
2241 - $cap_empty_data = array(
2242 - 'cap_instance_url' => '',
2243 - 'cap_site_key' => '',
2244 - 'cap_secret_key' => '',
2245 - );
2246 - $cap_data = get_option('accua_forms_default_captcha_field_data',array()) + $cap_empty_data;
2247 - if (($cap_data['cap_instance_url'] !== '') && ($cap_data['cap_site_key'] !== '') && ($cap_data['cap_secret_key'] !== '')) {
2248 - $cap_properties = array(
2249 - 'description' => '',
2250 - 'instanceUrl' => $cap_data['cap_instance_url'],
2251 - 'siteKey' => $cap_data['cap_site_key'],
2252 - 'secretKey' => $cap_data['cap_secret_key'],
2253 - );
2254 - $element = new AccuaForm_Element_Cap($istance_data['label'], '', $field_properties+$cap_properties);
2255 - } else {
2256 - $element = new Element_HTML("\n\n<!-- Cap captcha is not configured, please go to Contact Forms settings page and set the Cap server URL, site key and secret key -->\n\n");
2257 - }
2258 - break;
2259 3089 case 'password':
2260 3090 $element = new Element_Password($istance_data['label'], $istance_data['istance_id'], $field_properties+array('value'=>$istance_data['default_value']));
2261 3091 break;
2262 3092 case 'password-and-confirm':
2263 3093 $id_2 = "___{$istance_data['istance_id']}___confirmpass";
2264 - $element = new Element_Password($istance_data['label'], $istance_data['istance_id'], $field_properties+array('value'=>$istance_data['default_value']));
3094 + $element = new Element_Password(__("Password", 'contact-forms'), $istance_data['istance_id'], $field_properties+array('value'=>$istance_data['default_value']));
2265 3095 $element_conf = new Element_Password(__("Confirm password", 'contact-forms'), $id_2, $field_properties+array('value'=>$istance_data['default_value']));
2266 3096 $element_conf_validator = new AccuaForm_Validation_Password();
2267 3097 $element_conf_validator->configure(array('otherPasswordFieldName'=>$istance_data['istance_id']));
2268 3098 $element_conf->setValidation($element_conf_validator);
@@ -2269,65 +3099,26 @@
2269 3099 break;
2270 3100 case 'date':
2271 3101 $element = new AccuaForm_Element_Date($istance_data['label'], $istance_data['istance_id'], $field_properties+array('value'=>$istance_data['default_value'], 'minDate'=>$istance_data['min_date'], 'maxDate'=>$istance_data['max_date']));
2272 3102 break;
2273 - case 'telephone':
2274 - $phone_country = isset($istance_data['country_code']) ? $istance_data['country_code'] : 'IT';
2275 - $phone_props = $field_properties+array('value'=>$istance_data['default_value'], 'country_code'=>$phone_country);
2276 - if ($resolved_format_msg !== '') {
2277 - $phone_props['custom_format_message'] = $resolved_format_msg;
2278 - }
2279 - $element = new AccuaForm_Element_Telephone($istance_data['label'], $istance_data['istance_id'], $phone_props);
2280 - break;
2281 3103 //case 'textfield':
2282 3104 default:
2283 - /**
2284 - * Filter to create a custom Element for an external field type.
2285 - *
2286 - * @param Element|null $element Null by default; return an Element to override.
2287 - * @param string $field_type The field type identifier.
2288 - * @param array $field_data The field definition from avail_fields.
2289 - * @param array $istance_data The field instance data (label, required, etc.).
2290 - * @param array $field_properties Common properties (description, shortDesc, etc.).
2291 - */
2292 - $element = apply_filters( 'accua_forms_render_field_element', null, $field_data['type'], $field_data, $istance_data, $field_properties );
2293 - if ( ! $element ) {
2294 - $element = new Element_Textbox($istance_data['label'], $istance_data['istance_id'], $field_properties+array('value'=>$istance_data['default_value']));
2295 - }
3105 + $element = new Element_Textbox($istance_data['label'], $istance_data['istance_id'], $field_properties+array('value'=>$istance_data['default_value']));
2296 3106 break;
2297 3107 }
2298 3108 if ($element) {
2299 3109 if (!empty($istance_data['required'])) {
2300 - if (!in_array($field_data['type'], array('captcha_v3', 'cap'), true)) {
2301 - // captcha_v3 and cap must not get this class: the client-side required check
2302 - // would inspect their hidden token input, which is empty until solved
2303 - $element->setClass('accuaforms-field-required');
2304 - }
2305 - if ($field_data['type'] === 'captcha' && empty($captcha_use_v1)) {
3110 + $element->setClass('accuaforms-field-required');
3111 + if($field_data['type'] == 'captcha' && empty($captcha_use_v1)) {
2306 3112 //nothing
2307 - } elseif ($field_data['type'] === 'captcha_v3') {
2308 - //nothing - v3 has its own validation set in the Element constructor
2309 - } elseif ($field_data['type'] === 'turnstile') {
2310 - //nothing - turnstile has its own validation set in the Element constructor
2311 - } elseif ($field_data['type'] === 'cap') {
2312 - //nothing - cap has its own validation set in the Element constructor
2313 - } elseif ($field_data['type'] === 'password-and-confirm') {
2314 - if ($resolved_required_msg !== '') {
2315 - $req_msg = str_replace(array('%s', '%element%'), $istance_data['label'], $resolved_required_msg);
2316 - } else {
2317 - /* translators: Password field required error */
2318 - $req_msg = __( 'Password is required', 'contact-forms' );
2319 - }
2320 - $element->setValidation(new Validation_Required($req_msg));
3113 + } else if($field_data['type'] == 'password-and-confirm') {
3114 + $element->setValidation(new Validation_Required(
3115 + str_replace('%element%', $istance_data['label'], __("Attention: Passwords are required fields.", 'contact-forms'))
3116 + ));
2321 3117 } else {
2322 - if ($resolved_required_msg !== '') {
2323 - $req_msg = str_replace(array('%s', '%element%'), $istance_data['label'], $resolved_required_msg);
2324 - } else {
2325 - /* translators: %element% is the field label, replaced with str_replace() */
2326 - // phpcs:ignore WordPress.WP.I18n.MissingTranslatorsComment -- Translators comment is above
2327 - $req_msg = str_replace('%element%', $istance_data['label'], __( '%element% is required', 'contact-forms' ));
2328 - }
2329 - $element->setValidation(new Validation_Required($req_msg));
3118 + $element->setValidation(new Validation_Required(
3119 + str_replace('%element%', $istance_data['label'], __("Attention: '%element%' is a required field.", 'contact-forms'))
3120 + ));
2330 3121 }
2331 3122 }
2332 3123
2333 3124 if ($elementName = $element->getName()) {
@@ -2348,18 +3139,9 @@
2348 3139 if ($fieldset_open) {
2349 3140 $form->addElement(new AccuaForm_Element_FieldsetEnd());
2350 3141 $fieldset_open = false;
2351 3142 }
2352 - /**
2353 - * Filter to suppress the automatically added submit button.
2354 - *
2355 - * Used by the Fields page live preview, which renders a single field
2356 - * with no use for a submit button. An explicit submit field in the
2357 - * form is unaffected.
2358 - *
2359 - * @param bool $suppress False by default.
2360 - */
2361 - if ($add_submit && !apply_filters('accua_forms_preview_suppress_auto_submit', false)) {
3143 + if ($add_submit) {
2362 3144 $form->addElement(new Element_Button(__('Submit', 'contact-forms'), 'submit', $submit_properties));
2363 3145 }
2364 3146 }
2365 3147
@@ -2379,9 +3161,9 @@
2379 3161 if (!empty($params['txt'])) {
2380 3162 $replace_map['__submitted_txt'] = implode("\n",$replace_map['__submitted_txt_raw']);
2381 3163 }
2382 3164 if (!empty($params['html'])) {
2383 - $replace_map['__submitted_html'] = implode("</td></tr>\n<tr>\n<td style='white-space:nowrap;vertical-align:top;padding:4px 10px 4px 0;'>",$replace_map['__submitted_html_raw']);
3165 + $replace_map['__submitted_html'] = implode('</td></tr><tr><td>',$replace_map['__submitted_html_raw']);
2384 3166 }
2385 3167 if (!empty($params['json'])) {
2386 3168 $replace_map['__submitted_json'] = _accua_forms_json_encode($replace_map['__submitted_json_raw']);
2387 3169 }
@@ -2402,240 +3184,8 @@
2402 3184 }
2403 3185 return $valid;
2404 3186 }
2405 3187
2406 -/**
2407 - * Sanitize a submissions-list column key.
2408 - *
2409 - * The case-preserving counterpart of sanitize_key(): column keys embed the
2410 - * field slug verbatim (`_field_{slug}`), and slugs are case-sensitive, so
2411 - * lowercasing would silently merge two fields whose slugs differ only in case.
2412 - * Allows the same character set the Fields page accepts for a slug.
2413 - *
2414 - * @since 2.3.0
2415 - * @param string $key Raw column key.
2416 - * @return string Sanitized column key.
2417 - */
2418 -function accua_forms_sanitize_column_key($key) {
2419 - return preg_replace('/[^A-Za-z0-9_\-]/', '', (string) $key);
2420 -}
2421 -
2422 -/**
2423 - * Allowed captcha spam actions (reCAPTCHA v2 and v3) and their form-editor
2424 - * labels.
2425 - *
2426 - * 'spam' accepts a submission that fails the captcha check silently (the
2427 - * visitor sees the normal success message, no emails are sent) and marks it
2428 - * with the Spam lead status; 'trash' and 'delete' are the other two silent
2429 - * modes. 'reject' blocks the submission with a visible error - the only
2430 - * behavior before 2.2.38, and the reCAPTCHA v2 default again since 2.3.0.
2431 - *
2432 - * @return array<string, string> action key => translated label.
2433 - */
2434 -function accua_forms_captcha_spam_action_options() {
2435 - return array(
2436 - 'spam' => __('Accept silently and mark as Spam', 'contact-forms'),
2437 - 'trash' => __('Accept silently and move to Trash', 'contact-forms'),
2438 - 'delete' => __('Accept silently and delete immediately', 'contact-forms'),
2439 - 'reject' => __('Reject with an error message', 'contact-forms'),
2440 - );
2441 -}
2442 -
2443 -/**
2444 - * The site-wide default spam action for a captcha type, from the settings page.
2445 - *
2446 - * reCAPTCHA v2 and v3 keep separate defaults because their checks fail for
2447 - * different reasons. A v3 failure is a low score computed invisibly, so
2448 - * absorbing it silently is the sensible default. A v2 failure most often means
2449 - * the visitor did not solve the checkbox they were shown - or took longer than
2450 - * the two minutes a token stays valid, or retried with a token Google had
2451 - * already consumed - and Google's guidance for that case is to surface the
2452 - * error and let them solve it again (the AJAX handler resets the widget, so a
2453 - * retry always carries a fresh token). Accepting those silently would file a
2454 - * real visitor's message as spam and send no notification, so v2 defaults to
2455 - * 'reject'.
2456 - *
2457 - * @since 2.3.0 The $type parameter, and the separate v2 default.
2458 - * @param string $type Field type: 'captcha' (reCAPTCHA v2) or 'captcha_v3'.
2459 - * @return string 'spam', 'trash', 'delete' or 'reject'.
2460 - */
2461 -function accua_forms_captcha_default_spam_action($type = 'captcha_v3') {
2462 - $captcha_data = get_option('accua_forms_default_captcha_field_data', array());
2463 - $is_v2 = ('captcha' === $type);
2464 - $option_key = $is_v2 ? 'captcha_spam_action_v2' : 'captcha_spam_action';
2465 - $fallback = $is_v2 ? 'reject' : 'spam';
2466 - $action = isset($captcha_data[$option_key]) ? $captcha_data[$option_key] : '';
2467 - return isset(accua_forms_captcha_spam_action_options()[$action]) ? $action : $fallback;
2468 -}
2469 -
2470 -/**
2471 - * Resolve the spam action configured on a captcha (v2) or captcha_v3 field
2472 - * instance: instance override, then the site-wide default for its type.
2473 - *
2474 - * @param array $istance_data The field instance data from the saved form.
2475 - * @param string $type Field type: 'captcha' (v2) or 'captcha_v3'.
2476 - * Defaults to the v3 resolution for backward
2477 - * compatibility with pre-2.3.0 callers.
2478 - * @return string 'spam', 'trash', 'delete' or 'reject'.
2479 - */
2480 -function accua_forms_captcha_spam_action($istance_data, $type = 'captcha_v3') {
2481 - $action = isset($istance_data['spam_action']) ? $istance_data['spam_action'] : '';
2482 - return isset(accua_forms_captcha_spam_action_options()[$action]) ? $action : accua_forms_captcha_default_spam_action($type);
2483 -}
2484 -
2485 -/**
2486 - * Find the spam action of the first captcha (v2) or captcha_v3 field of a
2487 - * form, if any.
2488 - *
2489 - * Note: when a submission was actually flagged, the handler follows the action
2490 - * recorded by the validator that failed (AccuaForm_Validation_CaptchaSpam), not
2491 - * this helper - a form can carry both a v2 and a v3 field with different
2492 - * actions. This remains for callers that need a form-level answer up front.
2493 - *
2494 - * @param array $form_data The saved form data (with 'fields').
2495 - * @return string The configured spam action, or the site-wide default if the
2496 - * form has no captcha field or no explicit setting.
2497 - */
2498 -function accua_forms_captcha_form_spam_action($form_data) {
2499 - if (!empty($form_data['fields']) && is_array($form_data['fields'])) {
2500 - $avail_fields = get_option('accua_forms_avail_fields', array());
2501 - foreach ($form_data['fields'] as $istance_data) {
2502 - if (isset($istance_data['ref'], $avail_fields[$istance_data['ref']]['type'])
2503 - && in_array($avail_fields[$istance_data['ref']]['type'], array('captcha', 'captcha_v3'), true)) {
2504 - return accua_forms_captcha_spam_action($istance_data, $avail_fields[$istance_data['ref']]['type']);
2505 - }
2506 - }
2507 - }
2508 - return accua_forms_captcha_default_spam_action();
2509 -}
2510 -
2511 -/**
2512 - * The site-wide default for the captcha "Hide field title" option.
2513 - *
2514 - * @return bool True when captcha titles are hidden by default (ships true).
2515 - */
2516 -function accua_forms_captcha_default_hide_title() {
2517 - $captcha_data = get_option('accua_forms_default_captcha_field_data', array());
2518 - if (!isset($captcha_data['captcha_hide_title'])) {
2519 - return true;
2520 - }
2521 - return !empty($captcha_data['captcha_hide_title']);
2522 -}
2523 -
2524 -/**
2525 - * Whether the title of a captcha field instance (captcha, captcha_v3 or cap)
2526 - * is hidden on the rendered form. Instance override, then the site-wide
2527 - * default (hidden unless the administrator changed it). The label stays in
2528 - * the markup visually hidden (screen-reader only), so error summary links and
2529 - * assistive tech keep working.
2530 - *
2531 - * @param array $istance_data The field instance data from the saved form.
2532 - * @return bool
2533 - */
2534 -function accua_forms_captcha_hide_title($istance_data) {
2535 - if (!isset($istance_data['hide_title'])) {
2536 - return accua_forms_captcha_default_hide_title();
2537 - }
2538 - return !empty($istance_data['hide_title']);
2539 -}
2540 -
2541 -/**
2542 - * Normalize a reCAPTCHA v3 score threshold to the 0.0 - 1.0 range Google
2543 - * uses, rounded to two decimals.
2544 - *
2545 - * @param mixed $value The raw value (string from a form field, float, ...).
2546 - * @param float $fallback Returned when $value is not numeric.
2547 - * @return float
2548 - */
2549 -function accua_forms_recaptcha3_clamp_score($value, $fallback = 0.5) {
2550 - if (!is_numeric($value)) {
2551 - return (float) $fallback;
2552 - }
2553 - $score = round((float) $value, 2);
2554 - if ($score < 0) {
2555 - return 0.0;
2556 - }
2557 - if ($score > 1) {
2558 - return 1.0;
2559 - }
2560 - return $score;
2561 -}
2562 -
2563 -/**
2564 - * The site-wide default minimum reCAPTCHA v3 score, from the settings page.
2565 - *
2566 - * @return float 0.0 - 1.0 (ships 0.5, the value Google suggests).
2567 - */
2568 -function accua_forms_recaptcha3_default_score_threshold() {
2569 - $captcha_data = get_option('accua_forms_default_captcha_field_data', array());
2570 - $stored = isset($captcha_data['recaptcha_v3_score_threshold']) ? $captcha_data['recaptcha_v3_score_threshold'] : null;
2571 - return accua_forms_recaptcha3_clamp_score($stored, 0.5);
2572 -}
2573 -
2574 -/**
2575 - * Resolve the minimum reCAPTCHA v3 score a submission must reach on a given
2576 - * field instance: instance override, then the site-wide default.
2577 - *
2578 - * The accua_forms_recaptcha3_score_threshold filter still runs last, inside
2579 - * the validator, and receives this value as its default.
2580 - *
2581 - * @param array $istance_data The field instance data from the saved form.
2582 - * @return float 0.0 - 1.0.
2583 - */
2584 -function accua_forms_recaptcha3_score_threshold($istance_data) {
2585 - $default = accua_forms_recaptcha3_default_score_threshold();
2586 - if (isset($istance_data['score_threshold']) && is_numeric($istance_data['score_threshold'])) {
2587 - return accua_forms_recaptcha3_clamp_score($istance_data['score_threshold'], $default);
2588 - }
2589 - return $default;
2590 -}
2591 -
2592 -/**
2593 - * Placement options for the floating reCAPTCHA v3 badge.
2594 - *
2595 - * Google allows hiding the badge only if the reCAPTCHA branding is shown
2596 - * elsewhere in the user flow — with 'hidden' the field prints the required
2597 - * notice text under the form itself.
2598 - *
2599 - * @return array<string, string> badge key => translated label.
2600 - */
2601 -function accua_forms_recaptcha3_badge_options() {
2602 - return array(
2603 - 'bottomright' => __('Bottom right', 'contact-forms'),
2604 - 'bottomleft' => __('Bottom left', 'contact-forms'),
2605 - 'hidden' => __('Hidden (the required reCAPTCHA notice is shown in the form instead)', 'contact-forms'),
2606 - );
2607 -}
2608 -
2609 -/**
2610 - * The configured reCAPTCHA v3 badge placement.
2611 - *
2612 - * Site-wide, not per field: the badge is a single floating element shared by
2613 - * every reCAPTCHA on the page.
2614 - *
2615 - * @return string 'bottomright' (default), 'bottomleft' or 'hidden'.
2616 - */
2617 -function accua_forms_recaptcha3_badge() {
2618 - $captcha_data = get_option('accua_forms_default_captcha_field_data', array());
2619 - $badge = isset($captcha_data['recaptcha_v3_badge']) ? $captcha_data['recaptcha_v3_badge'] : '';
2620 - return isset(accua_forms_recaptcha3_badge_options()[$badge]) ? $badge : 'bottomright';
2621 -}
2622 -
2623 -/** @deprecated 2.2.40 Use accua_forms_captcha_spam_action_options(). */
2624 -function accua_forms_recaptcha3_spam_action_options() {
2625 - return accua_forms_captcha_spam_action_options();
2626 -}
2627 -
2628 -/** @deprecated 2.2.40 Use accua_forms_captcha_spam_action(). */
2629 -function accua_forms_recaptcha3_spam_action($istance_data) {
2630 - return accua_forms_captcha_spam_action($istance_data);
2631 -}
2632 -
2633 -/** @deprecated 2.2.40 Use accua_forms_captcha_form_spam_action(). */
2634 -function accua_forms_recaptcha3_form_spam_action($form_data) {
2635 - return accua_forms_captcha_form_spam_action($form_data);
2636 -}
2637 -
2638 3188 function accua_forms_anonymize_ip($ip) {
2639 3189 $ip = (string) $ip;
2640 3190 $anonymize_ip_data = get_option('accua_forms_anonymize_ip_data',array());
2641 3191 if (empty($anonymize_ip_data['anonymize_ip_bytes'])) {
@@ -2674,67 +3224,30 @@
2674 3224 global $wpdb;
2675 3225
2676 3226 $time = time();
2677 3227
2678 - $captcha_flag_key = 'accuaform_' . preg_replace('/[^A-Za-z0-9_]/', '_', $fid);
2679 -
2680 - $stats_data = array(
3228 + $afs_stats = _accua_forms_json_encode(array(
2681 3229 'user_agent' => $form->stats['user_agent'],
2682 3230 'platform' => $form->stats['platform'],
2683 3231 'tentatives' => $form->stats['tentatives'],
2684 3232 'submit_method' => $form->stats['submit_method'],
2685 - );
3233 + ));
2686 3234
2687 - // reCAPTCHA v3 returned a score for this submission: keep it so the
2688 - // administrator can see what the form actually scores and tune the
2689 - // threshold accordingly. Recorded whether the check passed or not.
2690 - if (class_exists('AccuaForm_Validation_Captcha3', false)) {
2691 - $recaptcha3_score = AccuaForm_Validation_Captcha3::getScore($captcha_flag_key);
2692 - if ($recaptcha3_score !== null) {
2693 - $stats_data['recaptcha3_score'] = $recaptcha3_score;
2694 - }
2695 - }
2696 -
2697 - $afs_stats = _accua_forms_json_encode($stats_data);
2698 -
2699 3235 $anonymized_ip = accua_forms_anonymize_ip($form->stats['ip']);
2700 3236
2701 - // Silent captcha classification: when the captcha (v2) or captcha_v3
2702 - // field of this form is configured with a silent spam action, a failed
2703 - // check passed validation but flagged the submission (see
2704 - // Validation/CaptchaSpam.php). The action comes from the validator that
2705 - // actually failed - since 2.3.0 v2 and v3 have different defaults, so a
2706 - // form carrying both must not follow whichever field happens to come
2707 - // first. A 'reject' action never flags, so a flagged key is always one
2708 - // of the three silent actions.
2709 - $spam_action = class_exists('AccuaForm_Validation_CaptchaSpam', false)
2710 - ? AccuaForm_Validation_CaptchaSpam::getSpamAction($captcha_flag_key)
2711 - : '';
2712 - $is_spam = in_array($spam_action, array('spam', 'trash', 'delete'), true);
2713 -
2714 - $insert_data = array (
2715 - 'afs_form_id' => (string) $fid,
2716 - 'afs_post_id' => (string) $form->stats['pid'],
2717 - 'afs_ip' => $anonymized_ip,
2718 - 'afs_uri' => (string) $form->stats['uri'],
2719 - 'afs_referrer' => (string) $form->stats['referrer'],
2720 - 'afs_lang' => (string) $form->stats['lang'],
2721 - 'afs_created' => (string) gmdate('Y-m-d H:i:s', $form->stats['created']),
2722 - 'afs_submitted' => (string) gmdate('Y-m-d H:i:s', $time),
2723 - 'afs_stats' => (string) $afs_stats,
2724 - );
2725 - if ($is_spam) {
2726 - if ($spam_action === 'trash') {
2727 - $insert_data['afs_status'] = -1;
2728 - } elseif ($spam_action === 'spam') {
2729 - $insert_data['afs_lead_status'] = -1;
2730 - }
2731 - }
2732 -
2733 - // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery -- Form submission insert requires direct query
2734 3237 $insert_ret = $wpdb->insert(
2735 3238 $wpdb->prefix . 'accua_forms_submissions',
2736 - $insert_data
3239 + array (
3240 + 'afs_form_id' => (string) $fid,
3241 + 'afs_post_id' => (string) $form->stats['pid'],
3242 + 'afs_ip' => $anonymized_ip,
3243 + 'afs_uri' => (string) $form->stats['uri'],
3244 + 'afs_referrer' => (string) $form->stats['referrer'],
3245 + 'afs_lang' => (string) $form->stats['lang'],
3246 + 'afs_created' => (string) gmdate('Y-m-d H:i:s', $form->stats['created']),
3247 + 'afs_submitted' => (string) gmdate('Y-m-d H:i:s', $time),
3248 + 'afs_stats' => (string) $afs_stats,
3249 + )
2737 3250 );
2738 3251
2739 3252 if ($insert_ret) {
2740 3253 $submission_id = $form->stats['submission_id'] = $wpdb->insert_id;
@@ -2739,10 +3252,9 @@
2739 3252 if ($insert_ret) {
2740 3253 $submission_id = $form->stats['submission_id'] = $wpdb->insert_id;
2741 3254 } else {
2742 3255 $submission_id = $form->stats['submission_id'] = 0;
2743 - // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- Legitimate error logging for failed DB insert
2744 - error_log("[Contact Forms] unable to save submitted form data");
3256 + error_log("[WordPress Contact Forms] unable to save submitted form data");
2745 3257 }
2746 3258
2747 3259 $review_submission_url = admin_url('admin.php').'?page=accua_forms_submissions_list&sid='.$submission_id;
2748 3260
@@ -2757,15 +3269,15 @@
2757 3269 '__referrer' => $form->stats['referrer'],
2758 3270 '__lang' => $form->stats['lang'],
2759 3271 '__locale' => $form->stats['locale'],
2760 3272 '__created' => $form->stats['created'],
2761 - '__created_day' => wp_date('l j F Y', $form->stats['created']),
2762 - '__created_day_month_year' => wp_date('j F Y', $form->stats['created']),
2763 - '__created_hour' => wp_date('G:i', $form->stats['created']),
3273 + '__created_day' => date('l j F Y', $form->stats['created']),
3274 + '__created_day_month_year' => date('j F Y', $form->stats['created']),
3275 + '__created_hour' => date('G:i', $form->stats['created']),
2764 3276 '__submitted' => $time,
2765 - '__submitted_day' => wp_date('l j F Y', $time),
2766 - '__submitted_day_month_year' => wp_date('j F Y', $time),
2767 - '__submitted_hour' => wp_date('G:i', $time),
3277 + '__submitted_day' => date('l j F Y', $time),
3278 + '__submitted_day_month_year' => date('j F Y', $time),
3279 + '__submitted_hour' => date('G:i', $time),
2768 3280 '__confirmation_emails_message' => $form_data['confirmation_emails_message'],
2769 3281 '__user_agent' => $form->stats['user_agent'],
2770 3282 '__platform' => $form->stats['platform'],
2771 3283 '__tentatives' => $form->stats['tentatives'],
@@ -2799,9 +3311,9 @@
2799 3311 'name' => __('Fieldset begin', 'contact-forms'),
2800 3312 'type' => 'fieldset-begin',
2801 3313 'description' => '',
2802 3314 );
2803 - } elseif ($istance_data['ref'] == '__fieldset-end') {
3315 + } else if ($istance_data['ref'] == '__fieldset-end') {
2804 3316 $field_data = array(
2805 3317 'id' => '__fieldset-end',
2806 3318 'name' => __('Fieldset end', 'contact-forms'),
2807 3319 'type' => 'fieldset-end',
@@ -2887,10 +3399,10 @@
2887 3399 $urls = array();
2888 3400 foreach ($value as $val) {
2889 3401 if (isset($opts[$val])) {
2890 3402 $titles[] = $opts[$val];
2891 - $ids[] = $val;
2892 - $urls[] = get_permalink($val);
3403 + $ids[] = $value;
3404 + $urls[] = get_permalink($value);
2893 3405 $value2[] = $val . ': ' . trim(preg_replace('/[\s\n\r]+/', ' ', $opts[$val]));
2894 3406 }
2895 3407 }
2896 3408 $replace_map['__label_'.$istance_data['istance_id']] = $replace_map['__post_title_'.$istance_data['istance_id']] = implode("\n", $titles);
@@ -2905,26 +3417,15 @@
2905 3417 }
2906 3418 break;
2907 3419 case 'post-select':
2908 3420 if ($value !== '') {
2909 - $post = get_post(absint($value));
2910 - // The submitted ID must belong to the post type the field is
2911 - // configured for and have a status the field may expose (publish,
2912 - // plus private when explicitly configured); otherwise any post ID
2913 - // would be accepted.
2914 - $expected_post_type = isset($istance_data['post_type']) ? $istance_data['post_type'] : 'page';
2915 - $ps_allowed_statuses = array('publish');
2916 - $ps_element = $form->getElementByName($istance_id);
2917 - if ($ps_element instanceof AccuaForm_Element_PostSelect) {
2918 - $expected_post_type = $ps_element->getEffectivePostType();
2919 - $ps_allowed_statuses = $ps_element->getAllowedPostStatuses();
2920 - }
2921 - if ($post && in_array($post->post_status, $ps_allowed_statuses, true) && $post->post_type === $expected_post_type) {
2922 - $title = $post->post_title;
2923 - $replace_map['__label_'.$istance_data['istance_id']] = $replace_map['__post_title_'.$istance_data['istance_id']] = $title;
3421 + $el = $form->getElementByName($istance_id);
3422 + $opts = $el->getOptions();
3423 + if (isset($opts[$value])) {
3424 + $replace_map['__label_'.$istance_data['istance_id']] = $replace_map['__post_title_'.$istance_data['istance_id']] = $opts[$value];
2924 3425 $replace_map['__post_id_'.$istance_data['istance_id']] = $value;
2925 3426 $replace_map['__post_url_'.$istance_data['istance_id']] = get_permalink($value);
2926 - $value = $value . ': ' . trim(preg_replace('/[\s\n\r]+/', ' ', $title));
3427 + $value = $value . ': ' . trim(preg_replace('/[\s\n\r]+/', ' ', $opts[$value]));
2927 3428 } else {
2928 3429 $replace_map['__label_'.$istance_data['istance_id']] = $replace_map['__post_title_'.$istance_data['istance_id']] = '';
2929 3430 $replace_map['__post_id_'.$istance_data['istance_id']] = '';
2930 3431 $replace_map['__post_url_'.$istance_data['istance_id']] = '';
@@ -2946,10 +3447,9 @@
2946 3447 if ($value !== null && $value !== '' && $file) {
2947 3448 if ($form->renameFile($istance_id, "{$submission_id}_{$field_data['id']}_{$file['name']}")) {
2948 3449 $urlfield = rawurlencode($istance_data['istance_id']);
2949 3450 $urlfile = rawurlencode($value);
2950 - $token = accua_forms_generate_download_token($submission_id);
2951 - $file_download_url = admin_url('admin-ajax.php') . "?action=accua_forms_download_submitted_file&subid={$submission_id}&field={$urlfield}&file={$urlfile}&nonce=" . wp_create_nonce('accua_forms_download_nonce')."&token={$token}&_wpnonce=" . wp_create_nonce('download_file_' . $submission_id . '_' . $urlfield);
3451 + $file_download_url = admin_url('admin-ajax.php') . "?action=accua_forms_download_submitted_file&subid={$submission_id}&field={$urlfield}&file={$urlfile}";
2952 3452 }
2953 3453 }
2954 3454 $replace_map[$istance_data['istance_id']] = $value;
2955 3455 $replace_map['__download_'.$istance_data['istance_id']] = $file_download_url;
@@ -2968,20 +3468,12 @@
2968 3468 $replace_map[$istance_data['istance_id']] = $value;
2969 3469 }
2970 3470
2971 3471 switch ($field_data['type']) {
2972 - case 'fieldset-begin':
2973 - $fieldset_label = !empty($istance_data['label']) ? esc_html($istance_data['label']) : esc_html($istance_data['istance_id']);
2974 - $replace_map['__submitted_txt_raw'][$istance_data['istance_id']] = "\n--- {$istance_data['label']} ---";
2975 - $replace_map['__submitted_json_raw'][$istance_data['istance_id']] = $value;
2976 - $replace_map['__submitted_html_raw'][$istance_data['istance_id']] = "<strong style='font-size:14px;'>{$fieldset_label}</strong></td><td class='valori_submitted'>";
2977 - break;
2978 - case 'fieldset-end':
2979 - break;
2980 3472 case 'file':
2981 3473 $replace_map['__submitted_txt_raw'][$istance_data['istance_id']] = "{$istance_data['istance_id']}\t$value\t$file_download_url";
2982 3474 $replace_map['__submitted_json_raw'][$istance_data['istance_id']] = "$value\t$file_download_url";
2983 - $replace_map['__submitted_html_raw'][$istance_data['istance_id']] = "<strong>{$istance_data['istance_id']}</strong></td><td class='valori_submitted'><a href='".esc_url($file_download_url)."'>".esc_html($value)."</a>";
3475 + $replace_map['__submitted_html_raw'][$istance_data['istance_id']] = "<strong>{$istance_data['istance_id']}</strong></td><td class='valori_submitted'><a href='".htmlspecialchars($file_download_url,ENT_QUOTES)."'>".htmlspecialchars($value)."</a>";
2984 3476 break;
2985 3477
2986 3478 case 'email':
2987 3479 case 'autoreply_email':
@@ -2986,9 +3478,9 @@
2986 3478 case 'email':
2987 3479 case 'autoreply_email':
2988 3480 $replace_map['__submitted_txt_raw'][$istance_data['istance_id']] = "{$istance_data['istance_id']}\t$value";
2989 3481 $replace_map['__submitted_json_raw'][$istance_data['istance_id']] = $value;
2990 - $replace_map['__submitted_html_raw'][$istance_data['istance_id']] = "<strong>{$istance_data['istance_id']}</strong></td><td class='valori_submitted'><a href='mailto:".esc_attr($value)."'>".esc_html($value)."</a>";
3482 + $replace_map['__submitted_html_raw'][$istance_data['istance_id']] = "<strong>{$istance_data['istance_id']}</strong></td><td class='valori_submitted'><a href='mailto:".htmlspecialchars($value,ENT_QUOTES)."'>".htmlspecialchars($value)."</a>";
2991 3483 break;
2992 3484 case 'submit':
2993 3485 break;
2994 3486 case 'colorpicker':
@@ -2996,9 +3488,9 @@
2996 3488 $replace_map['__submitted_json_raw'][$istance_data['istance_id']] = $value;
2997 3489 if ($value === '') {
2998 3490 $value_html = '';
2999 3491 } else {
3000 - $value_esc = esc_attr($value);
3492 + $value_esc = htmlspecialchars($value, ENT_QUOTES);
3001 3493 $value_html = "<span style='color: $value_esc'><font color='$value_esc'>&#9608;</font></span> $value_esc";
3002 3494 }
3003 3495 $replace_map['__submitted_html_raw'][$istance_data['istance_id']] = "<strong>{$istance_data['istance_id']}</strong></td><td class='valori_submitted'>$value_html";
3004 3496 break;
@@ -3007,14 +3499,12 @@
3007 3499 break;
3008 3500 default:
3009 3501 $replace_map['__submitted_txt_raw'][$istance_data['istance_id']] = "{$istance_data['istance_id']}\t$value";
3010 3502 $replace_map['__submitted_json_raw'][$istance_data['istance_id']] = $value;
3011 - $replace_map['__submitted_html_raw'][$istance_data['istance_id']] = "<strong>{$istance_data['istance_id']}</strong></td><td class='valori_submitted'>".esc_html($value);
3012 - } if ($submission_id) {
3013 - // Ensure value is never NULL to prevent database errors
3014 - $safe_value = $value === null ? '' : $value;
3015 -
3016 - // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery -- Form field values insert requires direct query
3503 + $replace_map['__submitted_html_raw'][$istance_data['istance_id']] = "<strong>{$istance_data['istance_id']}</strong></td><td class='valori_submitted'>".htmlspecialchars($value);
3504 + }
3505 +
3506 + if ($submission_id) {
3017 3507 $wpdb->insert(
3018 3508 $wpdb->prefix . 'accua_forms_submissions_values',
3019 3509 array (
3020 3510 'afsv_sub_id' => $submission_id,
@@ -3019,9 +3509,9 @@
3019 3509 array (
3020 3510 'afsv_sub_id' => $submission_id,
3021 3511 'afsv_field_id' => $istance_data['istance_id'],
3022 3512 'afsv_type' => $type,
3023 - 'afsv_value' => $safe_value,
3513 + 'afsv_value' => $value,
3024 3514 ),
3025 3515 array('%d','%s','%s','%s')
3026 3516 );
3027 3517 }
@@ -3042,10 +3532,9 @@
3042 3532
3043 3533 //Newer filter, with an easier name
3044 3534 $replace_map = apply_filters('accua_forms_submission', $replace_map, $fid, $submittedData, $form, $_field_data, $_istance_data);
3045 3535
3046 - $submitted_html = "<table style='width:100%;border-collapse:collapse;'>\n<tr>\n<td style='white-space:nowrap;vertical-align:top;padding:4px 10px 4px 0;'>" . $replace_map['__submitted_html'] . "</td></tr></table>";
3047 - $submitted_html = str_replace("class='valori_submitted'", "class='valori_submitted' style='vertical-align:top;padding:4px 0;overflow-wrap:break-word;word-break:break-word;'", $submitted_html);
3536 + $submitted_html = '<table><tr><td>' . $replace_map['__submitted_html'] . '</td></tr></table>';
3048 3537 $confirmation_emails_message = $replace_map['__confirmation_emails_message'];
3049 3538 unset($replace_map['__submitted_html'], $replace_map['__confirmation_emails_message'], $replace_map['__submitted_txt_raw'], $replace_map['__submitted_html_raw'], $replace_map['__submitted_json_raw'], $replace_map['__autoreply_email_raw']);
3050 3539
3051 3540 $replace_map_html = array();
@@ -3050,9 +3539,9 @@
3050 3539
3051 3540 $replace_map_html = array();
3052 3541 foreach($replace_map as $key => $value) {
3053 3542 $replace_map_html["!$key"] = wp_kses($value, 'post');
3054 - $replace_map_html[$key] = esc_attr($value);
3543 + $replace_map_html[$key] = htmlspecialchars($value, ENT_QUOTES);
3055 3544 }
3056 3545
3057 3546 $replace_map['__submitted_html'] = $replace_map_html['__submitted_html'] = $replace_map_html['!__submitted_html'] = $submitted_html;
3058 3547 $replacer_html = new AccuaConditionalReplacer($replace_map_html);
@@ -3077,9 +3566,8 @@
3077 3566 }
3078 3567
3079 3568 $settings_html = array(
3080 3569 'success_message',
3081 - 'error_message',
3082 3570 'admin_emails_message',
3083 3571 );
3084 3572
3085 3573 foreach($settings_html as $i) {
@@ -3085,12 +3573,9 @@
3085 3573 foreach($settings_html as $i) {
3086 3574 $form_data_replaced[$i] = $replacer_html->doReplace($form_data[$i]);
3087 3575 }
3088 3576
3089 - // Track mail sending success for showing appropriate message
3090 - $mail_success = true;
3091 - $mail1 = true;
3092 - $mail2 = true;
3577 + AccuaForm::appendSubmittedMessages(wpautop($form_data_replaced['success_message']));
3093 3578
3094 3579 $header = array("Content-Type: text/html; charset=".get_option('blog_charset'));
3095 3580
3096 3581 $emails_from = trim($form_data_replaced['emails_from']);
@@ -3107,10 +3592,9 @@
3107 3592 if ($form_data_replaced['emails_bcc']) {
3108 3593 $header[] = 'Bcc: '.$form_data_replaced['emails_bcc'];
3109 3594 }
3110 3595
3111 - if (!$is_spam
3112 - && $form_data_replaced['admin_emails_to']
3596 + if ($form_data_replaced['admin_emails_to']
3113 3597 && $form_data_replaced['admin_emails_subject']) {
3114 3598 /*
3115 3599 $admin_tos = explode(',', strtr($form_data_replaced['admin_emails_to'], "\n\t\r;", ',,,,'));
3116 3600 foreach ($admin_tos as $admin_to) {
@@ -3116,72 +3600,17 @@
3116 3600 foreach ($admin_tos as $admin_to) {
3117 3601 $mail1 = wp_mail(trim($admin_to), $form_data_replaced['admin_emails_subject'], $form_data_replaced['admin_emails_message'], $header);
3118 3602 }
3119 3603 */
3120 - $mail1 = wp_mail($form_data_replaced['admin_emails_to'], $form_data_replaced['admin_emails_subject'],'<html><head></head><body style="background:#f9f8f8;font-size: 12px;font-family: &quot;Lucida Sans&quot;,&quot;Lucida Grande&quot;, Verdana, Arial, Sans-Serif;">'.wpautop($form_data_replaced['admin_emails_message']).'</body></html>', $header);
3121 - if (!$mail1) {
3122 - $mail_success = false;
3123 - }
3604 + $mail1 = wp_mail($form_data_replaced['admin_emails_to'], $form_data_replaced['admin_emails_subject'],'<html><head></head><body style="background:#f9f8f8;font-size: 12px;font-family: "Lucida Sans","Lucida Grande", Verdana, Arial, Sans-Serif;"">'.wpautop($form_data_replaced['admin_emails_message']).'</body></html>', $header);
3124 3605 }
3125 3606
3126 - if (!$is_spam
3127 - && $replace_map['__autoreply'] && $replace_map['__autoreply_email']
3607 + if ($replace_map['__autoreply'] && $replace_map['__autoreply_email']
3128 3608 && $form_data_replaced['confirmation_emails_subject']
3129 3609 && $confirmation_emails_message) {
3130 3610 $mail2 = wp_mail($replace_map['__autoreply_email'], $form_data_replaced['confirmation_emails_subject'], '<html><head></head><body>'.wpautop($confirmation_emails_message).'</body></html>', $header);
3131 - if (!$mail2) {
3132 - $mail_success = false;
3133 - }
3134 3611 }
3135 3612
3136 - // Determine which message to show based on mail success and user settings
3137 - if ($mail_success) {
3138 - // Show success message unless "Don't show any messages" is selected
3139 - if (empty($form_data['success_message_no_message'])) {
3140 - $message_content = trim($form_data_replaced['success_message']);
3141 - if ($message_content !== '') {
3142 - AccuaForm::appendSubmittedMessages(wpautop($message_content));
3143 - }
3144 - }
3145 - } else {
3146 - // Mail failed - show error message unless "Don't show any messages" is selected
3147 - if (empty($form_data['error_message_no_message'])) {
3148 - $error_content = trim($form_data_replaced['error_message']);
3149 - if ($error_content !== '') {
3150 - AccuaForm::appendSubmittedMessages(wpautop($error_content));
3151 - }
3152 - }
3153 - }
3154 -
3155 - if ($is_spam) {
3156 - if ($spam_action === 'delete' && $submission_id) {
3157 - // Remove the stored rows and any uploaded files; the visitor still
3158 - // saw the normal success message.
3159 - accua_forms_erase_submission($submission_id, 'delete');
3160 - $submission_id = $form->stats['submission_id'] = 0;
3161 - }
3162 - /**
3163 - * Fires when a submission was silently classified as spam by a
3164 - * captcha field (reCAPTCHA v2 or v3).
3165 - *
3166 - * @param int $submission_id The stored submission id (0 when the spam action is 'delete').
3167 - * @param string $spam_action The configured action: 'spam', 'trash' or 'delete'.
3168 - * @param string $fid The form id.
3169 - */
3170 - do_action('accua_forms_captcha_spam_submission', $submission_id, $spam_action, $fid);
3171 -
3172 - /**
3173 - * Deprecated alias of accua_forms_captcha_spam_submission, kept for
3174 - * backward compatibility. Since 2.2.40 it also fires for reCAPTCHA v2
3175 - * classifications, not only v3.
3176 - *
3177 - * @param int $submission_id The stored submission id (0 when the spam action is 'delete').
3178 - * @param string $spam_action The configured action: 'spam', 'trash' or 'delete'.
3179 - * @param string $fid The form id.
3180 - */
3181 - do_action('accua_forms_recaptcha3_spam_submission', $submission_id, $spam_action, $fid);
3182 - }
3183 -
3184 3613 /*
3185 3614 echo "<!-- replace_map: "
3186 3615 , print_r($replace_map, true)
3187 3616 , "\nreplace_map: "
@@ -3209,16 +3638,11 @@
3209 3638 'file_format' => 'name',
3210 3639 );
3211 3640 $ret = array();
3212 3641 if ($options['extra']) {
3213 - // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Submission data lookup requires direct query
3214 - $query1 = $wpdb->prepare(
3215 - "SELECT *
3642 + $query1 = "SELECT *
3216 3643 FROM `{$wpdb->prefix}accua_forms_submissions`
3217 - WHERE afs_id = %d",
3218 - $subid
3219 - );
3220 - // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- $query1 is prepared above, submission lookup requires direct query
3644 + WHERE afs_id = $subid";
3221 3645 $data = $wpdb->get_row($query1);
3222 3646 if (!empty($data)) {
3223 3647 $created = $data->afs_created;
3224 3648 $created[10] = 'T';
@@ -3240,10 +3664,8 @@
3240 3664 'user_agent' => '',
3241 3665 'platform' => '',
3242 3666 'tentatives' => '',
3243 3667 'submit_method' => '',
3244 - // Only present on submissions verified by a reCAPTCHA v3 field.
3245 - 'recaptcha3_score' => '',
3246 3668 );
3247 3669 $ret += array(
3248 3670 '__fid' => $data->afs_form_id,
3249 3671 '__subid' => $subid,
@@ -3253,31 +3675,25 @@
3253 3675 '__uri' => $data->afs_uri,
3254 3676 '__referrer' => $data->afs_referrer,
3255 3677 '__lang' => $data->afs_lang,
3256 3678 '__created' => $created,
3257 - '__created_day' => wp_date('l j F Y', $created),
3258 - '__created_hour' => wp_date('G:i', $created),
3679 + '__created_day' => date('l j F Y', $created),
3680 + '__created_hour' => date('G:i', $created),
3259 3681 '__submitted' => $submitted,
3260 - '__submitted_day' => wp_date('l j F Y', $submitted),
3261 - '__submitted_hour' => wp_date('G:i', $submitted),
3682 + '__submitted_day' => date('l j F Y', $submitted),
3683 + '__submitted_hour' => date('G:i', $submitted),
3262 3684 '__user_agent' => $stats['user_agent'],
3263 3685 '__platform' => $stats['platform'],
3264 3686 '__tentatives' => $stats['tentatives'],
3265 3687 '__submit_method' => $stats['submit_method'],
3266 - '__recaptcha3_score' => $stats['recaptcha3_score'],
3267 3688 );
3268 3689 }
3269 3690 }
3270 3691
3271 - // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Submission values lookup requires direct query
3272 - $query2 = $wpdb->prepare(
3273 - "SELECT *
3274 - FROM `{$wpdb->prefix}accua_forms_submissions_values`
3275 - WHERE afsv_sub_id = %d",
3276 - $subid
3277 - );
3692 + $query2 = "SELECT *
3693 + FROM `{$wpdb->prefix}accua_forms_submissions_values`
3694 + WHERE afsv_sub_id = $subid";
3278 3695
3279 - // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- $query2 is prepared above, submission values lookup requires direct query
3280 3696 $data2 = $wpdb->get_results($query2, OBJECT);
3281 3697
3282 3698 foreach ($data2 as $row) {
3283 3699 switch ($row->afsv_type) {
@@ -3284,15 +3700,12 @@
3284 3700 case 'file' :
3285 3701 if ($options['file_format'] == 'url' || $options['file_format'] == 'link') {
3286 3702 $fieldid = rawurlencode($row->afsv_field_id);
3287 3703 $filename = rawurlencode($row->afsv_value);
3288 - $url = admin_url('admin-ajax.php') . "?action=accua_forms_download_submitted_file&subid={$row->afsv_sub_id}&field={$fieldid}&file={$filename}&nonce=" . wp_create_nonce('accua_forms_download_nonce') . "&_wpnonce=" . wp_create_nonce('download_file_' . $row->afsv_sub_id . '_' . $fieldid);
3289 - if(isset($options['token'])){
3290 - $url .= '&token='.$options['token'];
3291 - }
3704 + $url = admin_url('admin-ajax.php') . "?action=accua_forms_download_submitted_file&subid={$row->afsv_sub_id}&field={$fieldid}&file={$filename}";
3292 3705 if ($options['file_format'] == 'link'){
3293 - $url = esc_url($url);
3294 - $filename = esc_html($row->afsv_value);
3706 + $url = htmlspecialchars($url,ENT_QUOTES);
3707 + $filename = htmlspecialchars($row->afsv_value,ENT_QUOTES);
3295 3708 $fielddata = "<a href='{$url}' target='_blank'>{$filename}</a>";
3296 3709 } else {
3297 3710 $fielddata = $url;
3298 3711 }
@@ -3317,20 +3730,11 @@
3317 3730 $fid = $atts['fid'];
3318 3731 $form_data = _accua_forms_get_form_data($fid, false);
3319 3732
3320 3733 if (! $form_data) {
3321 - // In preview mode, allow unsaved (new) forms to render using draft + defaults
3322 - if (! apply_filters('accua_forms_use_draft_for_preview', false)) {
3323 - return '';
3324 - }
3325 - $default_form_data = get_option('accua_forms_default_form_data', array());
3326 - $empty_form_data = _accua_forms_get_form_data(false);
3327 - $form_data = array('_overrided' => array()) + $default_form_data + $empty_form_data;
3734 + return '';
3328 3735 }
3329 3736
3330 - // Note: Preview field order override is handled in accua_forms_form_generate()
3331 - // which applies the filter there for live preview
3332 -
3333 3737 $fid = '__accua-form__'.$fid;
3334 3738
3335 3739 $out = '';
3336 3740
@@ -3335,26 +3739,12 @@
3335 3739 $out = '';
3336 3740
3337 3741 if (AccuaForm::getSubmittedID() == $fid) {
3338 3742 /* return "<pre>Form submitted.\n\nData: " . print_r(AccuaForm::getSubmittedData(), true) . '</pre>'; */
3339 - // Get per-form messages (supports multiple forms on same page)
3340 - $messages = AccuaForm::getSubmittedMessages($fid);
3341 - if ($messages && trim($messages) !== '') {
3743 + $messages = AccuaForm::getSubmittedMessages();
3744 + if ($messages) {
3342 3745 $out .= '<div id="_response_messages_'.$fid.'" class="accua-form-messages">'.$messages.'</div>';
3343 3746 }
3344 -
3345 - // Non-AJAX fallback: set URL hash and scroll to result messages on page load.
3346 - // The anchor elements are only created by the AJAX JS block (which is not output for
3347 - // non-AJAX forms), so we scroll to the messages div by class instead.
3348 - $anchor_suffix = preg_replace('/[^a-zA-Z0-9]+/', '_', str_replace('__accua-form__', '', $fid));
3349 - $hash_type = AccuaForm::isValid() ? 'formSubmitSuccess' : 'formSubmitInvalid';
3350 - $anchor_full = esc_js($hash_type . '-' . $anchor_suffix);
3351 - $out .= '<script>document.addEventListener("DOMContentLoaded",function(){'
3352 - . 'if(history.replaceState)history.replaceState(null,"","#' . $anchor_full . '");'
3353 - . 'var m=document.querySelector(".accua-form-messages");'
3354 - . 'if(m)m.scrollIntoView({behavior:"smooth",block:"start"})'
3355 - . '});</script>';
3356 -
3357 3747 if (AccuaForm::isValid()) {
3358 3748 return $out;
3359 3749 }
3360 3750 $form = AccuaForm::getSubmittedForm();
@@ -3359,28 +3749,13 @@
3359 3749 }
3360 3750 $form = AccuaForm::getSubmittedForm();
3361 3751 } else {
3362 3752 $analytics_data = get_option('accua_forms_default_analytics_data',array());
3363 -
3364 - // Check for preview layout override (allows live preview of layout changes before save)
3365 - $layout = $form_data['layout'];
3366 - $preview_layout_override = apply_filters('accua_forms_preview_layout_override', '');
3367 - if ($preview_layout_override) {
3368 - $layout = $preview_layout_override;
3369 - }
3370 -
3371 - // If layout is empty (meaning "use default"), resolve to the global default layout
3372 - if (empty($layout)) {
3373 - $default_form_data = get_option('accua_forms_default_form_data', array());
3374 - $layout = !empty($default_form_data['layout']) ? $default_form_data['layout'] : 'sidebyside';
3375 - }
3376 -
3377 3753 $params = array(
3378 - 'layout' => $layout,
3754 + 'layout' => $form_data['layout'],
3379 3755 'title' => $form_data['title'],
3380 3756 'track_submit' => !empty($analytics_data['analytics_track_submit']),
3381 3757 'track_fields' => !empty($analytics_data['analytics_track_fields']),
3382 - 'gads_conversion_tracking_code' => $form_data['gads_conversion_tracking_code'],
3383 3758 );
3384 3759 $form = AccuaForm::create($fid, $params);
3385 3760 }
3386 3761
@@ -3386,10 +3761,9 @@
3386 3761
3387 3762 $out .= $form->render(true);
3388 3763
3389 3764 $doing_ajax = function_exists('wp_doing_ajax') ? wp_doing_ajax() : (defined( 'DOING_AJAX' ) && DOING_AJAX);
3390 - // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only check for Yoast SEO compatibility, strips HTML for preview
3391 - if ($doing_ajax && isset($_REQUEST['action']) && ($_REQUEST['action'] === 'wpseo_filter_shortcodes')) {
3765 + if ($doing_ajax && ($_REQUEST['action'] === 'wpseo_filter_shortcodes')) {
3392 3766 $strip_regexp = '/(<iframe[^>]*>(.*?)<\/iframe>|<script[^>]*>(.*?)<\/script>|<input([^>]*)type="hidden"[^>]*>)/is';
3393 3767 $out = preg_replace($strip_regexp, '', $out);
3394 3768 }
3395 3769
@@ -3398,15 +3772,12 @@
3398 3772 }
3399 3773
3400 3774 function accua_forms_include($fid, $atts=array(), $content = '', $code = '') {
3401 3775 $atts['fid'] = $fid;
3402 - // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Shortcode handler manages its own escaping
3403 3776 echo accua_forms_shortcode_handler($atts, $content, $code);
3404 3777 }
3405 3778
3406 -// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- Internal helper function, double underscore prefix indicates private
3407 3779 function __accua_forms_submissions_list_page(){
3408 - // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only routing, actual actions have nonce checks
3409 3780 if(isset($_GET['sid'])) {
3410 3781 accua_forms_single_submission();
3411 3782 } else {
3412 3783 accua_forms_submissions_list_page();
@@ -3411,191 +3782,32 @@
3411 3782 } else {
3412 3783 accua_forms_submissions_list_page();
3413 3784 }
3414 3785 }
3415 -function accua_forms_submissions_list_page_load(){
3416 - // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only routing for screen option registration
3417 - if(isset($_GET['sid'])) {
3418 - // Handle GET-based trash/restore actions here (before any output is sent)
3419 - require_once __DIR__ . '/admin/single-submission.php';
3420 - $sid = (int) $_GET['sid'];
3421 - // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verified below before processing
3422 - if ( $sid && isset( $_GET['action'] ) ) {
3423 - if ( $_GET['action'] === 'trash' ) {
3424 - check_admin_referer( 'del_sub_form_' . $sid );
3425 - accua_forms_trash_submission( $sid );
3426 - wp_safe_redirect( admin_url( 'admin.php?page=accua_forms_submissions_list&trashed=1' ) );
3427 - exit;
3428 - }
3429 - if ( $_GET['action'] === 'restore' ) {
3430 - check_admin_referer( 'restore_sub_form_' . $sid );
3431 - accua_forms_restore_submission( $sid );
3432 - wp_safe_redirect( admin_url( 'admin.php?page=accua_forms_submissions_list&restored=1' ) );
3433 - exit;
3434 - }
3435 - }
3436 - return;
3437 - }
3438 - add_screen_option('per_page', array(
3439 - 'default' => 100,
3440 - 'option' => 'accua_forms_submissions_per_page',
3441 - ));
3442 -
3443 - // Set default hidden columns for first-time users: hide the field columns
3444 - // not flagged "Show in essential columns" on the Fields page (plus the
3445 - // technical main columns).
3446 - add_filter( 'default_hidden_columns', function( $hidden ) {
3447 - $non_essential = [ 'form_id', 'pid', 'created', 'lead_status' ];
3448 - $avail_fields = get_option( 'accua_forms_avail_fields', [] );
3449 - foreach ( (array) $avail_fields as $slug => $field_data ) {
3450 - if ( empty( $field_data['essential_column'] ) ) {
3451 - $non_essential[] = '_field_' . $slug;
3452 - }
3453 - }
3454 - return array_unique( array_merge( $hidden, $non_essential ) );
3455 - } );
3456 -
3457 - $screen = get_current_screen();
3458 - $screen->add_help_tab( array(
3459 - 'id' => 'accua_forms_lead_statuses',
3460 - 'title' => __( 'Lead Statuses', 'contact-forms' ),
3461 - 'content' => '<p>' . accua_forms_get_lead_statuses_help() . '</p>',
3462 - ) );
3463 -}
3464 -add_filter('set_screen_option_accua_forms_submissions_per_page', function($status, $option, $value) {
3465 - return (int) $value;
3466 -}, 10, 3);
3467 3786 function accua_forms_submissions_list_page_head(){
3468 - // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only routing, actual actions have nonce checks
3469 3787 if(isset($_GET['sid'])) {
3470 - require_once __DIR__ . '/admin/single-submission.php';
3788 + require_once('accua-forms-single-submission.php');
3471 3789 accua_forms_single_submission(true);
3472 3790 } else {
3473 - require_once __DIR__ . '/admin/submissions-list-page.php';
3791 + require_once('accua-forms-submissions-page.php');
3474 3792 accua_forms_submissions_list_page(true);
3475 3793 }
3476 3794
3477 3795 }
3478 3796
3479 -/* Generiamo token di sicurezza per poter accedere anche da anonimo - email */
3480 -function accua_forms_generate_download_token($subid) {
3481 - global $wpdb;
3482 - $token = wp_generate_password(32, false); // Token casuale di 32 caratteri
3483 -
3484 - // Controlla se esiste già un token per questo sub_id
3485 - // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Token lookup requires direct query
3486 - $existing_token = $wpdb->get_var($wpdb->prepare(
3487 - "SELECT afsv_value FROM `{$wpdb->prefix}accua_forms_submissions_values` WHERE afsv_sub_id = %d AND afsv_field_id = '_accua_download_token'",
3488 - $subid
3489 - ));
3490 - if ($existing_token) {
3491 - return $existing_token;
3492 - } else{
3493 - // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery -- Token insert requires direct query
3494 - $wpdb->insert(
3495 - $wpdb->prefix . 'accua_forms_submissions_values',
3496 - [
3497 - 'afsv_sub_id' => $subid,
3498 - 'afsv_field_id' => '_accua_download_token',
3499 - 'afsv_type' => 'token',
3500 - 'afsv_value' => $token
3501 - ],
3502 - ['%d', '%s', '%s', '%s']
3503 - );
3504 - return $token;
3505 - }
3506 -}
3507 -
3508 -function accua_forms_check_download_token($subid, $get_token) {
3509 - global $wpdb;
3510 -
3511 - $subid = (int) $subid; // Cast to integer for security
3512 -
3513 - // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Token verification requires direct query
3514 - $saved_token = $wpdb->get_var($wpdb->prepare(
3515 - "SELECT afsv_value FROM `{$wpdb->prefix}accua_forms_submissions_values` WHERE afsv_sub_id = %d AND afsv_field_id = '_accua_download_token'",
3516 - $subid
3517 - ));
3518 -
3519 - // Debug logging for token verification (comment out in production)
3520 - // error_log("Token check: Submission ID: $subid, Provided token: $get_token, Saved token: $saved_token");
3521 -
3522 - return isset($get_token) && $get_token === $saved_token;
3523 -}
3524 -
3525 -/**
3526 - * Gestisce il download di un file inviato tramite un modulo.
3527 - *
3528 - * Questa funzione viene eseguita tramite una richiesta AJAX e permette agli utenti di scaricare
3529 - * un file precedentemente caricato con un modulo. Controlla i parametri della richiesta per verificare
3530 - * la presenza di un file associato a un determinato ID di invio e campo del modulo.
3531 - *
3532 - * - Se il parametro "html" è presente, genera una pagina HTML con un link di reindirizzamento automatico.
3533 - * - Recupera le informazioni del file dal database per verificarne l'esistenza.
3534 - * - Se il file esiste e può essere letto, restituisce il contenuto con gli appropriati header HTTP.
3535 - * - Se il file non viene trovato, restituisce un errore 404.
3536 - *
3537 - * Sicurezza:
3538 - * - Nonce
3539 - * - Utilizza `stripslashes_deep` per sanificare i dati in ingresso.
3540 - * - Protegge il database utilizzando `wpdb->prepare` per prevenire SQL Injection.
3541 - * - Determina il tipo MIME del file per un download sicuro.
3542 - * - Aggiunto token di verifica per utenti
3543 - */
3544 -
3545 3797 add_action('wp_ajax_accua_forms_download_submitted_file', 'accua_forms_download_submitted_file');
3546 3798 add_action('wp_ajax_nopriv_accua_forms_download_submitted_file', 'accua_forms_download_submitted_file');
3547 3799 function accua_forms_download_submitted_file(){
3548 3800 $get = stripslashes_deep($_GET);
3549 - $token_valid = false;
3550 - $nonce_valid = false;
3551 - $subid = '';
3552 -
3553 - if(isset($get['subid'])){
3554 - $subid = rawurlencode($get['subid']);
3555 - }
3556 -
3557 - // First verify WordPress nonce for CSRF protection (for logged-in users)
3558 - if (isset($get['_wpnonce']) && wp_verify_nonce($get['_wpnonce'], 'download_file_' . $subid . '_' . $get['field'])) {
3559 - $nonce_valid = true;
3560 - }
3561 -
3562 - // For backward compatibility with older URL format that use 'nonce' instead of '_wpnonce'
3563 - if (!$nonce_valid && isset($get['nonce']) && check_ajax_referer('accua_forms_download_nonce', 'nonce', false)) {
3564 - $nonce_valid = true;
3565 - }
3566 -
3567 - // Check for token-based authentication (for email links and unauthenticated users)
3568 - if (isset($get['token']) && $subid != '') {
3569 - if (accua_forms_check_download_token($subid, $get['token']) == 1) {
3570 - $token_valid = true;
3571 - }
3572 - }
3573 -
3574 - // If both authentication methods fail, deny access
3575 - if (!$nonce_valid && !$token_valid) {
3576 - wp_die(esc_html__('Security check failed.', 'contact-forms'), 403);
3577 - }
3578 - // Additional permission check for admin users
3579 - if(!$token_valid && !$nonce_valid && $subid != ''){
3580 - // If neither token nor nonce is valid, check for logged-in admin permissions
3581 - if (!is_user_logged_in() || !current_user_can('manage_options')) {
3582 - wp_die(esc_html__('You do not have sufficient permissions to access this page.', 'contact-forms'));
3583 - }
3584 - }
3585 3801 if (isset($get['subid'],$get['field'],$get['file'])) {
3586 - if (!empty($get['html'])) { /* export xls*/
3802 + if (!empty($get['html'])) {
3587 3803 header("Content-type: text/html");
3588 3804 $subid = rawurlencode($get['subid']);
3589 3805 $fieldid = rawurlencode($get['field']);
3590 3806 $filename = rawurlencode($get['file']);
3591 - $url = admin_url('admin-ajax.php') . "?action=accua_forms_download_submitted_file&subid={$subid}&field={$fieldid}&file={$filename}&nonce=" . wp_create_nonce('accua_forms_download_nonce') . "&_wpnonce=" . wp_create_nonce('download_file_' . $subid . '_' . $fieldid);
3592 - if(isset($get['token'])){
3593 - $url .= '&token='.$get['token'];
3594 - }
3595 - $url = esc_url($url);
3596 - $filename = esc_html($get['file']);
3597 - // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- $filename and $url are pre-escaped above
3807 + $url = admin_url('admin-ajax.php') . "?action=accua_forms_download_submitted_file&subid={$subid}&field={$fieldid}&file={$filename}";
3808 + $url = htmlspecialchars($url,ENT_QUOTES);
3809 + $filename = htmlspecialchars($get['file'],ENT_QUOTES);
3598 3810 die("<html><head><title>{$filename}</title><meta http-equiv='refresh' content='0;URL={$url}'></head><body><a href='{$url}'>{$filename}</a></body></html>");
3599 3811 }
3600 3812 global $wpdb;
3601 3813 $subid = (int) $get['subid'];
@@ -3600,19 +3812,15 @@
3600 3812 global $wpdb;
3601 3813 $subid = (int) $get['subid'];
3602 3814 $field = $get['field'];
3603 3815 $file = $get['file'];
3604 - $query = $wpdb->prepare(
3605 - "SELECT *
3606 - FROM `{$wpdb->prefix}accua_forms_submissions_values`
3607 - WHERE afsv_sub_id = %d
3608 - AND afsv_field_id = %s
3609 - AND afsv_value = %s",
3610 - $subid,
3611 - $field,
3612 - $file
3613 - );
3614 - // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- $query is prepared above, file download verification requires direct query
3816 + $query = "SELECT *
3817 + FROM `{$wpdb->prefix}accua_forms_submissions_values`
3818 + WHERE afsv_sub_id = %d
3819 + AND afsv_field_id = %s
3820 + AND afsv_value = %s
3821 + ";
3822 + $query = $wpdb->prepare($query, $subid, $field, $file);
3615 3823 $subval = $wpdb->get_results($query, OBJECT);
3616 3824 if ($subval) {
3617 3825 $file_data = get_option('accua_forms_default_file_field_data',array()) + array('dest_path' => '');
3618 3826 $dest_path = _accua_forms_get_abs_dest_path($file_data['dest_path']);
@@ -3618,9 +3826,9 @@
3618 3826 $dest_path = _accua_forms_get_abs_dest_path($file_data['dest_path']);
3619 3827 $filename = "{$dest_path}/{$subid}_{$field}_{$file}";
3620 3828 if (is_file($filename) && is_readable($filename)){
3621 3829 if (function_exists('finfo_open')){
3622 - @ $finfo = finfo_open(FILEINFO_MIME_TYPE);
3830 + @ $finfo = finfo_open(FILEINFO_MIME);
3623 3831 if ($finfo) {
3624 3832 @ $filetype = finfo_file($finfo, $filename);
3625 3833 @ finfo_close($finfo);
3626 3834 }
@@ -3630,23 +3838,15 @@
3630 3838 }
3631 3839 if (empty($filetype)) {
3632 3840 $filetype = "application/octet-stream";
3633 3841 }
3634 - // Clean any output buffers to prevent stale content from being sent before the file
3635 - while (ob_get_level()) {
3636 - ob_end_clean();
3637 - }
3638 - // Remove all pre-set headers (admin-ajax.php sets Content-Type: text/html early)
3639 - header_remove();
3640 - nocache_headers();
3641 - header("Content-Type: $filetype");
3642 - header("Content-Length: ".filesize($filename));
3842 + header("Content-type: $filetype");
3843 + header("Content-length: ".filesize($filename));
3643 3844 if (empty($_GET['view'])) {
3644 - header("Content-Disposition: attachment; filename=\"$file\"");
3845 + header("Content-disposition: attachment; filename=\"$file\"");
3645 3846 }
3646 - // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_readfile -- WP_Filesystem not suitable for binary file streaming
3647 3847 readfile($filename);
3648 - exit;
3848 + die('');
3649 3849 }
3650 3850 }
3651 3851 }
3652 3852 header("HTTP/1.0 404 Not Found");
@@ -3666,87 +3866,17 @@
3666 3866 function accua_forms_preview() {
3667 3867 if (!current_user_can('manage_options')){
3668 3868 die ('');
3669 3869 }
3670 -
3671 - // Check nonce for CSRF protection
3672 - $nonce = isset( $_REQUEST['_wpnonce'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['_wpnonce'] ) ) : '';
3673 - if ( ! wp_verify_nonce( $nonce, 'accua_forms_preview' ) ) {
3674 - wp_die( esc_html__( 'Security check failed.', 'contact-forms' ), 403 );
3675 - }
3676 3870
3677 - // Enqueue form styles before printing them
3678 - accua_form_enqueue_scripts_and_styles();
3679 -
3680 - // Accept temporary layout override for live preview (before save)
3681 - // This allows real-time preview when user changes layout dropdown
3682 - $preview_layout = '';
3683 - if ( ! empty( $_REQUEST['preview_layout'] ) ) {
3684 - $layout_input = sanitize_text_field( wp_unslash( $_REQUEST['preview_layout'] ) );
3685 - $allowed_layouts = array( 'toplabel', 'sidebyside', 'inlinelabel' );
3686 - if ( in_array( $layout_input, $allowed_layouts, true ) ) {
3687 - $preview_layout = $layout_input;
3688 - } elseif ( 'default' === $layout_input ) {
3689 - // 'default' means use the global default layout
3690 - $default_form_data = get_option( 'accua_forms_default_form_data', array() );
3691 - $preview_layout = ! empty( $default_form_data['layout'] ) ? $default_form_data['layout'] : 'sidebyside';
3692 - }
3693 - }
3694 -
3695 - // Accept temporary field order for live preview (before save)
3696 - // This allows preview to show reordered fields without saving to database
3697 - $preview_order = null;
3698 - if ( ! empty( $_REQUEST['preview_order'] ) ) {
3699 - // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- JSON decoded and validated below
3700 - $order_json = wp_unslash( $_REQUEST['preview_order'] );
3701 - $preview_order = json_decode( $order_json, true );
3702 - if ( json_last_error() !== JSON_ERROR_NONE ) {
3703 - $preview_order = null;
3704 - }
3705 - }
3706 -
3707 - // Store the preview layout override in a filter so shortcode handler can use it
3708 - if ($preview_layout) {
3709 - add_filter('accua_forms_preview_layout_override', function() use ($preview_layout) {
3710 - return $preview_layout;
3711 - });
3712 - }
3713 -
3714 - // Store the preview order override in a filter so shortcode handler can use it
3715 - if ($preview_order) {
3716 - add_filter('accua_forms_preview_order_override', function() use ($preview_order) {
3717 - return $preview_order;
3718 - });
3719 - }
3720 -
3721 - // Signal that we're in admin preview mode - form generator should read from draft
3722 - add_filter('accua_forms_use_draft_for_preview', '__return_true');
3723 -
3724 3871 echo '<html><head>
3725 3872 <style>
3726 - *, *::before, *::after { box-sizing: border-box; }
3727 - body {
3728 - font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;
3729 - margin: 0;
3730 - padding: 16px;
3731 - background: #fff;
3732 - font-size: 14px;
3733 - line-height: 1.5;
3734 - }
3873 + body {font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;}
3735 3874 </style>';
3736 3875 wp_print_styles();
3737 3876 wp_print_head_scripts();
3738 3877 echo '</head><body>';
3739 - $preview_fid = isset($_REQUEST['fid']) ? sanitize_text_field(wp_unslash($_REQUEST['fid'])) : '';
3740 -
3741 - // Check if the form has any fields — show placeholder if empty
3742 - $draft_data = _accua_forms_get_draft_data($preview_fid);
3743 - if (empty($draft_data['fields'])) {
3744 - echo '<p style="color:#50575e;text-align:center;margin-top:40px;">' . esc_html__('Add fields to the form to see the preview.', 'contact-forms') . '</p>';
3745 - } else {
3746 - // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Shortcode handler manages its own escaping
3747 - echo accua_forms_shortcode_handler(array('fid' => $preview_fid));
3748 - }
3878 + echo accua_forms_shortcode_handler(array('fid'=>$_REQUEST['fid']));
3749 3879 wp_print_footer_scripts();
3750 3880 echo '</body></html>';
3751 3881 die('');
3752 3882 }
@@ -3760,27 +3890,17 @@
3760 3890 header("HTTP/1.0 401 Access Denied");
3761 3891 //header("Status: 401 Access Denied");
3762 3892 die('You are not authorized to access this page.');
3763 3893 }
3764 -
3765 - // Check nonce for CSRF protection
3766 - if (!isset($_REQUEST['_wpnonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_REQUEST['_wpnonce'])), 'accua_forms_export_excel')) {
3767 - wp_die(esc_html__('Security check failed.', 'contact-forms'), 403);
3768 - }
3769 3894
3770 - require_once __DIR__ . '/admin/submissions-list-page.php';
3895 + require_once('accua-forms-submissions-page.php');
3771 3896 $listTable = new Accua_Forms_Submissions_List_Table();
3772 3897 $listTable->export_xls = true;
3773 3898 $listTable->prepare_items(true);
3774 - // Sanitize column selection input. Not sanitize_key(): it lowercases, and
3775 - // column keys carry the field slug verbatim (_field_{slug}), which is
3776 - // case-sensitive — two fields may differ only in case, so lowercasing here
3777 - // dropped one of them from the export.
3778 - $show_col_input = isset($_GET['accua_show_field']) ? sanitize_text_field(wp_unslash($_GET['accua_show_field'])) : '';
3779 - $show_col = array_map('accua_forms_sanitize_column_key', explode(',', $show_col_input));
3899 + $show_col = explode( ',', $_GET['accua_show_field']);
3780 3900 $show_col = array_diff($show_col, array('singlesub'));
3781 - header('Content-disposition: attachment; filename=downloads-report.xls');
3782 - header('Content-type: application/vnd.ms-excel');
3901 + header("Content-disposition: attachment; filename=downloads-report.xls");
3902 + header("Content-type: application/vnd.ms-excel");
3783 3903 accua_forms_submission_page_save_excel_general($listTable,$show_col);
3784 3904 die('');
3785 3905 }
3786 3906
@@ -3795,9 +3915,9 @@
3795 3915 ?><html xmlns:o="urn:schemas-microsoft-com:office:office"
3796 3916 xmlns:x="urn:schemas-microsoft-com:office:excel"
3797 3917 xmlns="http://www.w3.org/TR/REC-html40">
3798 3918 <head>
3799 - <meta http-equiv=Content-Type content="<?php echo esc_attr( $content_type ); ?>" />
3919 + <meta http-equiv=Content-Type content="<?php echo $content_type; ?>" />
3800 3920 <meta name=ProgId content=Excel.Sheet />
3801 3921 <style>
3802 3922 <!--
3803 3923 td {vertical-align:top;}
@@ -3836,9 +3956,9 @@
3836 3956 <?php
3837 3957 $cols = $listTable->get_columns();
3838 3958 foreach($cols as $col_key=>$col_value) {
3839 3959 if(in_array($col_key, $show_col)) { ?>
3840 - <td x:autofilter="all"><?php echo esc_html( $col_value ); ?></td>
3960 + <td x:autofilter="all"><?php echo $col_value; ?></td>
3841 3961 <?php }
3842 3962 } ?>
3843 3963 </tr>
3844 3964
@@ -3845,24 +3965,22 @@
3845 3965 <?php
3846 3966 $lead_statuses = accua_forms_get_lead_statuses();
3847 3967
3848 3968 foreach($listTable->items as $id_submission=>$single_submission) {
3849 - // phpcs:ignore Squiz.PHP.DiscouragedFunctions.Discouraged -- Required to prevent timeout during large exports
3850 3969 @ set_time_limit(10);
3851 3970 echo "<tr>";
3852 3971 foreach($cols as $col_key=>$col_value) {
3853 3972 if(in_array($col_key, $show_col)) {
3854 - echo '<td class="' . esc_attr($col_key) . '">';
3973 + echo "<td class='.$col_key.'>";
3855 3974 if ($col_key == 'lead_status') {
3856 3975 if (isset($lead_statuses[$single_submission['lead_status']])) {
3857 - echo esc_html($lead_statuses[$single_submission['lead_status']]);
3976 + echo htmlspecialchars($lead_statuses[$single_submission['lead_status']]);
3858 3977 }
3859 - } elseif(isset($single_submission[$col_key])) {
3978 + } else if(isset($single_submission[$col_key])) {
3860 3979 if ( method_exists( $listTable, 'column_' . $col_key ) ) {
3861 - // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- List table column methods handle their own escaping
3862 3980 echo call_user_func( array( &$listTable, 'column_' . $col_key ), $single_submission );
3863 - } else {
3864 - // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- List table column_default handles escaping
3981 + }
3982 + else {
3865 3983 echo $listTable->column_default( $single_submission, $col_key );
3866 3984 }
3867 3985 }
3868 3986 echo "</td>";
@@ -3882,36 +4000,34 @@
3882 4000 function accua_forms_print_tokens() {
3883 4001 $avail_fields = get_option('accua_forms_avail_fields', array());
3884 4002 $tokens = '';
3885 4003 foreach($avail_fields as $key=>$value) {
3886 - $field_name = $value['name'] ?? $value['label'] ?? $key;
3887 - $tokens .= $field_name . ": {" . $key . "}\n";
4004 + $tokens .= $value['name'] . ": {" . $key . "}\n";
3888 4005 switch ($value['type']) {
3889 4006 case 'file':
3890 - $tokens .= $field_name . " (download link): {__download_" . $key . "}\n";
4007 + $tokens .= $value['name'] . " (download link): {__download_" . $key . "}\n";
3891 4008 break;
3892 4009 case 'multiselect':
3893 4010 case 'multicheckbox':
3894 - $tokens .= $field_name . " (labels): {__label_" . $key . "}\n";
4011 + $tokens .= $value['name'] . " (labels): {__label_" . $key . "}\n";
3895 4012 break;
3896 4013 case 'select':
3897 4014 case 'radio':
3898 - $tokens .= $field_name . " (label): {__label_" . $key . "}\n";
4015 + $tokens .= $value['name'] . " (label): {__label_" . $key . "}\n";
3899 4016 break;
3900 4017 case 'post-multicheckbox':
3901 - $tokens .= $field_name . " (posts titles): {__label_" . $key . "}\n";
3902 - $tokens .= $field_name . " (posts ids): {__post_id_" . $key . "}\n";
3903 - $tokens .= $field_name . " (posts urls): {__post_url_" . $key . "}\n";
4018 + $tokens .= $value['name'] . " (posts titles): {__label_" . $key . "}\n";
4019 + $tokens .= $value['name'] . " (posts ids): {__post_id_" . $key . "}\n";
4020 + $tokens .= $value['name'] . " (posts urls): {__post_url_" . $key . "}\n";
3904 4021 break;
3905 4022 case 'post-select':
3906 - $tokens .= $field_name . " (post title): {__label_" . $key . "}\n";
3907 - $tokens .= $field_name . " (post id): {__post_id_" . $key . "}\n";
3908 - $tokens .= $field_name . " (post url): {__post_url_" . $key . "}\n";
4023 + $tokens .= $value['name'] . " (post title): {__label_" . $key . "}\n";
4024 + $tokens .= $value['name'] . " (post id): {__post_id_" . $key . "}\n";
4025 + $tokens .= $value['name'] . " (post url): {__post_url_" . $key . "}\n";
3909 4026 break;
3910 4027 }
3911 4028 }
3912 4029
3913 - // phpcs:disable PluginCheck.CodeAnalysis.Heredoc.NotAllowed, WordPress.Security.EscapeOutput.HeredocOutputNotEscaped -- Heredoc for tokens help HTML
3914 4030 echo <<<EOT
3915 4031 <div class="accua_forms_token_list">
3916 4032 <h2>Tokens</h2>
3917 4033 <em>In HTML text, use {!token_name} to insert unfiltered token value</em>
@@ -3940,9 +4056,8 @@
3940 4056 {__user_agent}
3941 4057 {__platform}
3942 4058 {__tentatives}
3943 4059 {__submit_method}
3944 -{__recaptcha3_score}
3945 4060 {__submitted_txt}
3946 4061 {__submitted_html}
3947 4062 {__submitted_json}
3948 4063 {__autoreply}
@@ -3950,432 +4065,356 @@
3950 4065 {__confirmation_emails_message}
3951 4066 {__review_submission_url}</pre>
3952 4067 </div>
3953 4068 EOT;
3954 - // phpcs:enable PluginCheck.CodeAnalysis.Heredoc.NotAllowed, WordPress.Security.EscapeOutput.HeredocOutputNotEscaped
3955 4069 do_action('accua_forms_print_tokens');
3956 4070 }
3957 4071
3958 -/**
3959 - * Get posts/pages for post-select fields using get_posts() for WPML compatibility.
3960 - *
3961 - * Uses WordPress get_posts() instead of direct SQL to ensure WPML and other
3962 - * language plugins can filter results to current language automatically.
3963 - *
3964 - * Performance considerations:
3965 - * - Results are cached using transients (5 minute TTL) to reduce database queries
3966 - * - meta_key/meta_value queries are necessary for filtering by custom fields
3967 - * - post__not_in is used only when exclude is explicitly requested by admin
3968 - * - Default limit of 500 posts prevents runaway queries
3969 - *
3970 - * Hierarchy handling:
3971 - * - child_of returns all descendants of the given post; exclude_tree removes a
3972 - * post and all its descendants. Both are resolved to explicit ID lists via
3973 - * accua_forms_get_post_descendant_ids() before querying, so they remain
3974 - * correct with pagination and search.
3975 - * - hierarchical only affects ordering (parents before children) and only when
3976 - * the result set is complete and title-sorted; it never drops posts whose
3977 - * parent is unavailable (e.g. published children of draft parents).
3978 - *
3979 - * @since 2.0.0-beta.29
3980 - * @param string|array $args Query arguments (backward compatible with old function).
3981 - * @return array Array of post objects.
3982 - */
3983 4072 function accua_get_pages($args = '') {
3984 - // phpcs:disable WordPressVIPMinimum.Performance.WPQueryParams.PostNotIn_exclude, WordPress.DB.SlowDBQuery.slow_db_query_meta_key, WordPress.DB.SlowDBQuery.slow_db_query_meta_value -- These are function parameter defaults, not actual query execution.
4073 + global $wpdb;
4074 +
3985 4075 $defaults = array(
3986 - 'child_of' => 0,
3987 - 'sort_order' => 'ASC',
3988 - 'sort_column' => 'post_title',
3989 - 'hierarchical' => 1,
3990 - 'exclude' => array(),
3991 - 'include' => array(),
3992 - 'meta_key' => '',
3993 - 'meta_value' => '',
3994 - 'meta_value_lt' => '',
3995 - 'meta_value_gt' => '',
3996 - 'meta_value_le' => '',
3997 - 'meta_value_ge' => '',
3998 - 'meta_value_like' => '',
3999 - 'meta_value_format' => 'string',
4000 - 'authors' => '',
4001 - 'parent' => -1,
4002 - 'exclude_tree' => '',
4003 - 'number' => 500, // Default limit for performance
4004 - 'offset' => 0,
4005 - 'post_type' => 'page',
4006 - 'post_status' => 'publish',
4007 - 'suppress_filters' => false, // IMPORTANT: Allow WPML to filter by language
4008 - 's' => '', // Search term (new parameter for AJAX search)
4076 + 'child_of' => 0,
4077 + 'sort_order' => 'ASC',
4078 + 'sort_column' => 'post_title',
4079 + 'hierarchical' => 1,
4080 + 'exclude' => array(),
4081 + 'include' => array(),
4082 + 'meta_key' => '',
4083 + 'meta_value' => '',
4084 + 'meta_value_lt' => '',
4085 + 'meta_value_gt' => '',
4086 + 'meta_value_le' => '',
4087 + 'meta_value_ge' => '',
4088 + 'meta_value_like' => '',
4089 + 'meta_value_format' => 'string',
4090 + 'authors' => '',
4091 + 'parent' => -1,
4092 + 'exclude_tree' => '',
4093 + 'number' => '',
4094 + 'offset' => 0,
4095 + 'post_type' => 'page',
4096 + 'post_status' => 'publish',
4009 4097 );
4010 - // phpcs:enable WordPressVIPMinimum.Performance.WPQueryParams.PostNotIn_exclude, WordPress.DB.SlowDBQuery.slow_db_query_meta_key, WordPress.DB.SlowDBQuery.slow_db_query_meta_value
4011 4098
4012 - $r = wp_parse_args($args, $defaults);
4099 + $r = wp_parse_args( $args, $defaults );
4100 + $child_of = (int) $r['child_of'];
4101 + $sort_order = $r['sort_order'];
4102 + $sort_column = $r['sort_column'];
4103 + $hierarchical = $r['hierarchical'];
4104 + $exclude = $r['exclude'];
4105 + $include = $r['include'];
4106 + $meta_key = $r['meta_key'];
4107 + $meta_value = $r['meta_value'];
4108 + $meta_value_lt = $r['meta_value_lt'];
4109 + $meta_value_gt = $r['meta_value_gt'];
4110 + $meta_value_le = $r['meta_value_le'];
4111 + $meta_value_ge = $r['meta_value_ge'];
4112 + $meta_value_like = $r['meta_value_like'];
4113 + $meta_value_format = $r['meta_value_format'];
4114 + $authors = $r['authors'];
4115 + $parent = $r['parent'];
4116 + $exclude_tree = $r['exclude_tree'];
4117 + $number = (int) $r['number'];
4118 + $offset = (int) $r['offset'];
4119 + $post_type = $r['post_type'];
4120 + $post_status = $r['post_status'];
4013 4121
4014 - // Generate cache key based on arguments and current language
4015 - $cache_key_data = $r;
4016 - // Add current language to cache key for WPML/Polylang compatibility
4017 - if (function_exists('pll_current_language')) {
4018 - $cache_key_data['_lang'] = pll_current_language();
4019 - } elseif (defined('ICL_LANGUAGE_CODE')) {
4020 - $cache_key_data['_lang'] = ICL_LANGUAGE_CODE;
4021 - }
4022 - $cache_key = 'accua_pages_' . md5(wp_json_encode($cache_key_data));
4122 + /*
4123 + // Make sure the post type is hierarchical
4124 + $hierarchical_post_types = get_post_types( array( 'hierarchical' => true ) );
4125 + if ( !in_array( $post_type, $hierarchical_post_types ) )
4126 + return false;
4127 + */
4023 4128
4024 - // Check transient cache first (skip for search queries and random ordering)
4025 - $use_cache = empty($r['s']) && $r['sort_column'] !== 'rand';
4026 - if ($use_cache) {
4027 - $cached = get_transient($cache_key);
4028 - if ($cached !== false) {
4029 - return $cached;
4030 - }
4031 - }
4129 + // Make sure we have a valid post type
4130 + if ( !is_array( $post_type ) )
4131 + $post_type = explode( ',', $post_type );
4132 + if ( array_diff( $post_type, get_post_types() ) )
4133 + return false;
4032 4134
4033 - // Validate post type
4034 - $post_type = $r['post_type'];
4035 - if (!is_array($post_type)) {
4036 - $post_type = array_map('trim', explode(',', $post_type));
4037 - }
4038 - $valid_post_types = get_post_types();
4039 - $post_type = array_filter($post_type, function($pt) use ($valid_post_types) {
4040 - return in_array($pt, $valid_post_types, true);
4041 - });
4042 - if (empty($post_type)) {
4043 - return array();
4044 - }
4135 + // Make sure we have a valid post status
4136 + if ( !is_array( $post_status ) )
4137 + $post_status = explode( ',', $post_status );
4138 + if ( array_diff( $post_status, get_post_stati() ) )
4139 + return false;
4045 4140
4046 - // Validate post status
4047 - $post_status = $r['post_status'];
4048 - if (!is_array($post_status)) {
4049 - $post_status = array_map('trim', explode(',', $post_status));
4141 + /*
4142 + $cache = array();
4143 + $key = md5( serialize( compact(array_keys($defaults)) ) );
4144 + if ( $cache = wp_cache_get( 'get_pages', 'posts' ) ) {
4145 + if ( is_array($cache) && isset( $cache[ $key ] ) ) {
4146 + $pages = apply_filters('get_pages', $cache[ $key ], $r );
4147 + return $pages;
4050 4148 }
4051 - $valid_statuses = get_post_stati();
4052 - $post_status = array_filter($post_status, function($ps) use ($valid_statuses) {
4053 - return in_array($ps, $valid_statuses, true);
4054 - });
4055 - if (empty($post_status)) {
4056 - $post_status = array('publish');
4057 4149 }
4058 4150
4059 - // Map sort_column to orderby
4060 - $orderby_map = array(
4061 - 'post_title' => 'title',
4062 - 'title' => 'title',
4063 - 'post_date' => 'date',
4064 - 'date' => 'date',
4065 - 'post_modified' => 'modified',
4066 - 'modified' => 'modified',
4067 - 'menu_order' => 'menu_order',
4068 - 'post_name' => 'name',
4069 - 'name' => 'name',
4070 - 'post_parent' => 'parent',
4071 - 'parent' => 'parent',
4072 - 'ID' => 'ID',
4073 - 'rand' => 'rand',
4074 - 'comment_count' => 'comment_count',
4075 - 'post_author' => 'author',
4076 - 'author' => 'author',
4077 - );
4078 - $sort_column = $r['sort_column'];
4079 - $orderby = isset($orderby_map[$sort_column]) ? $orderby_map[$sort_column] : 'title';
4151 + if ( !is_array($cache) )
4152 + $cache = array();
4153 + */
4080 4154
4081 - // Build get_posts arguments
4082 - $query_args = array(
4083 - 'post_type' => $post_type,
4084 - 'post_status' => $post_status,
4085 - 'orderby' => $orderby,
4086 - 'order' => strtoupper($r['sort_order']) === 'DESC' ? 'DESC' : 'ASC',
4087 - 'posts_per_page' => !empty($r['number']) ? (int) $r['number'] : 500,
4088 - 'offset' => (int) $r['offset'],
4089 - 'suppress_filters' => (bool) $r['suppress_filters'],
4090 - );
4091 -
4092 - // Search term
4093 - if (!empty($r['s'])) {
4094 - $query_args['s'] = sanitize_text_field($r['s']);
4155 + $inclusions = '';
4156 + if ( !empty($include) ) {
4157 + $child_of = 0; //ignore child_of, parent, exclude, meta_key, and meta_value params if using include
4158 + $parent = -1;
4159 + $exclude = '';
4160 + $meta_key = '';
4161 + $meta_value = '';
4162 + $meta_value_lt = '';
4163 + $meta_value_gt = '';
4164 + $meta_value_le = '';
4165 + $meta_value_ge = '';
4166 + $meta_value_like = '';
4167 + $hierarchical = false;
4168 + $incpages = wp_parse_id_list( $include );
4169 + if ( ! empty( $incpages ) ) {
4170 + foreach ( $incpages as $incpage ) {
4171 + if (empty($inclusions))
4172 + $inclusions = $wpdb->prepare(' AND ( ID = %d ', $incpage);
4173 + else
4174 + $inclusions .= $wpdb->prepare(' OR ID = %d ', $incpage);
4175 + }
4176 + }
4095 4177 }
4178 + if (!empty($inclusions))
4179 + $inclusions .= ')';
4096 4180
4097 - // Include specific posts (overrides other filters)
4098 - if (!empty($r['include'])) {
4099 - $include = wp_parse_id_list($r['include']);
4100 - if (!empty($include)) {
4101 - $query_args['post__in'] = $include;
4102 - $query_args['orderby'] = 'post__in'; // Preserve include order
4181 + $exclusions = '';
4182 + if ( !empty($exclude) ) {
4183 + $expages = wp_parse_id_list( $exclude );
4184 + if ( ! empty( $expages ) ) {
4185 + foreach ( $expages as $expage ) {
4186 + if (empty($exclusions))
4187 + $exclusions = $wpdb->prepare(' AND ( ID <> %d ', $expage);
4188 + else
4189 + $exclusions .= $wpdb->prepare(' AND ID <> %d ', $expage);
4190 + }
4103 4191 }
4104 - } else {
4105 - // Exclude posts - only used when admin explicitly configures exclusions.
4106 - // exclude_tree also removes all descendants of the given post, resolved
4107 - // against the full tree so it works with pagination and search.
4108 - $exclude_ids = array();
4109 - if (!empty($r['exclude'])) {
4110 - $exclude_ids = wp_parse_id_list($r['exclude']);
4111 - }
4112 - if (!empty($r['exclude_tree'])) {
4113 - $exclude_tree = (int) $r['exclude_tree'];
4114 - $exclude_ids = array_merge($exclude_ids, array($exclude_tree), accua_forms_get_post_descendant_ids($exclude_tree, $post_type));
4115 - }
4192 + }
4193 + if (!empty($exclusions))
4194 + $exclusions .= ')';
4116 4195
4117 - // Child of: restrict to all descendants of the given post, like core get_pages().
4118 - // Resolved to an explicit ID list so it stays correct with pagination and search.
4119 - if (!empty($r['child_of'])) {
4120 - $descendant_ids = accua_forms_get_post_descendant_ids((int) $r['child_of'], $post_type);
4121 - // post__in cannot be combined with post__not_in, so exclusions are applied to the list itself.
4122 - $descendant_ids = array_values(array_diff($descendant_ids, $exclude_ids));
4123 - $query_args['post__in'] = !empty($descendant_ids) ? $descendant_ids : array(0);
4124 - } elseif (!empty($exclude_ids)) {
4125 - // phpcs:ignore WordPressVIPMinimum.Performance.WPQueryParams.PostNotIn_post__not_in -- Exclusion is an optional admin-configured feature, not default behavior.
4126 - $query_args['post__not_in'] = $exclude_ids;
4127 - }
4196 + $author_query = '';
4197 + if (!empty($authors)) {
4198 + $post_authors = preg_split('/[\s,]+/',$authors);
4128 4199
4129 - // Parent filter (direct children only)
4130 - if ((int) $r['parent'] >= 0) {
4131 - $query_args['post_parent'] = (int) $r['parent'];
4132 - }
4200 + if ( ! empty( $post_authors ) ) {
4201 + foreach ( $post_authors as $post_author ) {
4202 + //Do we have an author id or an author login?
4203 + if ( 0 == intval($post_author) ) {
4204 + $post_author = get_user_by('login', $post_author);
4205 + if ( empty($post_author) )
4206 + continue;
4207 + if ( empty($post_author->ID) )
4208 + continue;
4209 + $post_author = $post_author->ID;
4210 + }
4133 4211
4134 - // Authors filter
4135 - if (!empty($r['authors'])) {
4136 - $author_ids = array();
4137 - $post_authors = preg_split('/[\s,]+/', $r['authors']);
4138 - foreach ($post_authors as $post_author) {
4139 - $post_author = trim($post_author);
4140 - if (empty($post_author)) {
4141 - continue;
4142 - }
4143 - if (is_numeric($post_author)) {
4144 - $author_ids[] = (int) $post_author;
4145 - } else {
4146 - $user = get_user_by('login', $post_author);
4147 - if ($user && !empty($user->ID)) {
4148 - $author_ids[] = $user->ID;
4149 - }
4150 - }
4212 + if ( '' == $author_query )
4213 + $author_query = $wpdb->prepare(' post_author = %d ', $post_author);
4214 + else
4215 + $author_query .= $wpdb->prepare(' OR post_author = %d ', $post_author);
4151 4216 }
4152 - if (!empty($author_ids)) {
4153 - $query_args['author__in'] = $author_ids;
4154 - }
4217 + if ( '' != $author_query )
4218 + $author_query = " AND ($author_query)";
4155 4219 }
4220 + }
4156 4221
4157 - // Build meta_query for advanced meta comparisons
4158 - $meta_query = array();
4222 + $allowed_keys = array('author', 'post_author', 'date', 'post_date', 'title', 'post_title', 'name', 'post_name', 'modified',
4223 + 'post_modified', 'modified_gmt', 'post_modified_gmt', 'menu_order', 'parent', 'post_parent',
4224 + 'ID', 'rand', 'comment_count');
4159 4225
4160 - // Standard meta_key/meta_value - used for filtering posts by custom field.
4161 - // This is an optional admin-configured feature for advanced post filtering.
4162 - if (!empty($r['meta_key'])) {
4163 - // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key -- Required for custom field filtering feature.
4164 - $query_args['meta_key'] = stripslashes($r['meta_key']);
4165 - if (!empty($r['meta_value'])) {
4166 - // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value -- Required for custom field filtering feature.
4167 - $query_args['meta_value'] = stripslashes($r['meta_value']);
4168 - }
4226 + $join = '';
4227 + $where = "$exclusions $inclusions ";
4228 + if ( ! ( empty( $meta_key ) && empty( $meta_value )
4229 + && empty( $meta_value_lt ) && empty( $meta_value_gt )
4230 + && empty( $meta_value_le ) && empty( $meta_value_ge )
4231 + && empty( $meta_value_like ) ) ) {
4232 + $join = " LEFT JOIN $wpdb->postmeta ON ( $wpdb->posts.ID = $wpdb->postmeta.post_id )";
4233 + $allowed_keys[] = 'meta_key';
4234 + $allowed_keys[] = 'meta_value';
4235 +
4236 + // meta_key and meta_value might be slashed
4237 + $meta_key = stripslashes($meta_key);
4238 + $meta_value = stripslashes($meta_value);
4239 + $meta_value_lt = stripslashes($meta_value_lt);
4240 + $meta_value_gt = stripslashes($meta_value_gt);
4241 + $meta_value_le = stripslashes($meta_value_le);
4242 + $meta_value_ge = stripslashes($meta_value_ge);
4243 + $meta_value_like = stripslashes($meta_value_like);
4244 +
4245 + if ( ! empty( $meta_key ) ) {
4246 + $where .= $wpdb->prepare(" AND $wpdb->postmeta.meta_key = %s", $meta_key);
4169 4247 }
4170 4248
4171 - // Advanced meta comparisons (lt, gt, le, ge, like)
4172 - if (!empty($r['meta_key']) && (
4173 - !empty($r['meta_value_lt']) || !empty($r['meta_value_gt']) ||
4174 - !empty($r['meta_value_le']) || !empty($r['meta_value_ge']) ||
4175 - !empty($r['meta_value_like'])
4176 - )) {
4177 - $meta_key = stripslashes($r['meta_key']);
4178 - $meta_type = 'CHAR';
4179 - switch ($r['meta_value_format']) {
4180 - case 'int':
4181 - $meta_type = 'NUMERIC';
4182 - break;
4183 - case 'float':
4184 - $meta_type = 'DECIMAL';
4185 - break;
4186 - case 'timestamp':
4187 - $meta_type = 'DATETIME';
4188 - break;
4189 - }
4249 + $meta_value_field = "$wpdb->postmeta.meta_value";
4250 + $meta_value_timestamp = false;
4251 + switch($meta_value_format) {
4252 + case 'timestamp':
4253 + $meta_value_field = "TIMESTAMP( $meta_value_field )";
4254 + $meta_value_param = "FROM_UNIXTIME( %s )";
4255 + $meta_value_timestamp = true;
4256 + break;
4257 + case 'int':
4258 + $meta_value_param = "%d";
4259 + break;
4260 + case 'float':
4261 + $meta_value_param = "%f";
4262 + break;
4263 + //case 'string':
4264 + default:
4265 + $meta_value_param = "%s";
4266 + }
4190 4267
4191 - if (!empty($r['meta_value_lt'])) {
4192 - $value = stripslashes($r['meta_value_lt']);
4193 - if ($r['meta_value_format'] === 'timestamp') {
4194 - $value = gmdate('Y-m-d H:i:s', strtotime($value));
4195 - }
4196 - $meta_query[] = array(
4197 - 'key' => $meta_key,
4198 - 'value' => $value,
4199 - 'compare' => '<',
4200 - 'type' => $meta_type,
4201 - );
4268 + if ( ! empty( $meta_value ) ) {
4269 + if ($meta_value_timestamp) {
4270 + $meta_value = strtotime($meta_value);
4202 4271 }
4203 - if (!empty($r['meta_value_gt'])) {
4204 - $value = stripslashes($r['meta_value_gt']);
4205 - if ($r['meta_value_format'] === 'timestamp') {
4206 - $value = gmdate('Y-m-d H:i:s', strtotime($value));
4207 - }
4208 - $meta_query[] = array(
4209 - 'key' => $meta_key,
4210 - 'value' => $value,
4211 - 'compare' => '>',
4212 - 'type' => $meta_type,
4213 - );
4272 + $where .= $wpdb->prepare(" AND $meta_value_field = $meta_value_param", $meta_value);
4273 + }
4274 + if ( ! empty( $meta_value_lt ) ) {
4275 + if ($meta_value_timestamp) {
4276 + $meta_value_lt = strtotime($meta_value_lt);
4214 4277 }
4215 - if (!empty($r['meta_value_le'])) {
4216 - $value = stripslashes($r['meta_value_le']);
4217 - if ($r['meta_value_format'] === 'timestamp') {
4218 - $value = gmdate('Y-m-d H:i:s', strtotime($value));
4219 - }
4220 - $meta_query[] = array(
4221 - 'key' => $meta_key,
4222 - 'value' => $value,
4223 - 'compare' => '<=',
4224 - 'type' => $meta_type,
4225 - );
4278 + $where .= $wpdb->prepare(" AND $meta_value_field < $meta_value_param", $meta_value_lt);
4279 + }
4280 + if ( ! empty( $meta_value_gt ) ) {
4281 + if ($meta_value_timestamp) {
4282 + $meta_value_gt = strtotime($meta_value_gt);
4226 4283 }
4227 - if (!empty($r['meta_value_ge'])) {
4228 - $value = stripslashes($r['meta_value_ge']);
4229 - if ($r['meta_value_format'] === 'timestamp') {
4230 - $value = gmdate('Y-m-d H:i:s', strtotime($value));
4231 - }
4232 - $meta_query[] = array(
4233 - 'key' => $meta_key,
4234 - 'value' => $value,
4235 - 'compare' => '>=',
4236 - 'type' => $meta_type,
4237 - );
4284 + $where .= $wpdb->prepare(" AND $meta_value_field > $meta_value_param", $meta_value_gt);
4285 + }
4286 + if ( ! empty( $meta_value_le ) ) {
4287 + if ($meta_value_timestamp) {
4288 + $meta_value_le = strtotime($meta_value_le);
4238 4289 }
4239 - if (!empty($r['meta_value_like'])) {
4240 - $meta_query[] = array(
4241 - 'key' => $meta_key,
4242 - 'value' => stripslashes($r['meta_value_like']),
4243 - 'compare' => 'LIKE',
4244 - );
4290 + $where .= $wpdb->prepare(" AND $meta_value_field <= $meta_value_param", $meta_value_le);
4291 + }
4292 + if ( ! empty( $meta_value_ge ) ) {
4293 + if ($meta_value_timestamp) {
4294 + $meta_value_ge = strtotime($meta_value_ge);
4245 4295 }
4246 -
4247 - if (!empty($meta_query)) {
4248 - // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query -- Required for advanced meta comparison operators (lt, gt, like, etc.).
4249 - $query_args['meta_query'] = $meta_query;
4250 - // Remove simple meta_value if we're using meta_query
4251 - unset($query_args['meta_value']);
4296 + $where .= $wpdb->prepare(" AND $meta_value_field >= $meta_value_param", $meta_value_ge);
4297 + }
4298 + if ( ! empty( $meta_value_like ) ) {
4299 + if ($meta_value_timestamp) {
4300 + $meta_value_like = strtotime($meta_value_like);
4252 4301 }
4302 + $where .= $wpdb->prepare(" AND $meta_value_field like $meta_value_param", $meta_value_like);
4253 4303 }
4254 4304 }
4255 4305
4256 - // Get posts using WordPress function (WPML automatically filters by current language)
4257 - $pages = get_posts($query_args);
4306 + if ( $parent >= 0 )
4307 + $where .= $wpdb->prepare(' AND post_parent = %d ', $parent);
4258 4308
4259 - if (empty($pages)) {
4260 - // Cache empty results too (5 minutes)
4261 - if ($use_cache) {
4262 - set_transient($cache_key, array(), 5 * MINUTE_IN_SECONDS);
4309 +
4310 + if ( 1 == count ( $post_type ) ) {
4311 + $where_post_type = $wpdb->prepare( "post_type = %s", array_shift( $post_type ) );
4312 + } else {
4313 + $post_type = implode( "', '", $post_type );
4314 + $where_post_type = "post_type IN ('$post_type')";
4315 + }
4316 +
4317 + if ( 1 == count( $post_status ) ) {
4318 + $where_post_type .= $wpdb->prepare( " AND post_status = %s", array_shift( $post_status ) );
4319 + } else {
4320 + $post_status = implode( "', '", $post_status );
4321 + $where_post_type .= " AND post_status IN ('$post_status')";
4322 + }
4323 +
4324 + $orderby_array = array();
4325 + foreach ( explode( ',', $sort_column ) as $orderby ) {
4326 + $orderby = trim( $orderby );
4327 + if ( !in_array( $orderby, $allowed_keys ) )
4328 + continue;
4329 +
4330 + switch ( $orderby ) {
4331 + case 'menu_order':
4332 + break;
4333 + case 'ID':
4334 + $orderby = "$wpdb->posts.ID";
4335 + break;
4336 + case 'rand':
4337 + $orderby = 'RAND()';
4338 + break;
4339 + case 'comment_count':
4340 + $orderby = "$wpdb->posts.comment_count";
4341 + break;
4342 + case 'meta_key':
4343 + case 'meta_value':
4344 + $orderby = "$wpdb->postmeta.$orderby";
4345 + break;
4346 + default:
4347 + if ( 0 === strpos( $orderby, 'post_' ) )
4348 + $orderby = "$wpdb->posts." . $orderby;
4349 + else
4350 + $orderby = "$wpdb->posts.post_" . $orderby;
4263 4351 }
4264 - /**
4265 - * Filters the list of pages retrieved from accua_get_pages.
4266 - *
4267 - * @since 2.0.0-beta.29
4268 - *
4269 - * @param array $pages List of page objects.
4270 - * @param array $r Arguments passed to accua_get_pages.
4271 - */
4272 - return apply_filters('accua_forms_get_pages', array(), $r);
4352 +
4353 + $orderby_array[] = $orderby;
4354 +
4273 4355 }
4356 + $sort_column = ! empty( $orderby_array ) ? implode( ',', $orderby_array ) : "$wpdb->posts.post_title";
4274 4357
4275 - // Hierarchical (tree) ordering: list parents before their children, like core
4276 - // get_pages(). Only applied when the result set is complete (no search, no
4277 - // offset, not truncated by the limit) and title-sorted — reordering a paginated
4278 - // or filtered slice would drop children whose parent is not in the same slice.
4279 - if ($r['hierarchical'] && empty($r['s']) && (int) $r['offset'] === 0
4280 - && count($pages) < (int) $query_args['posts_per_page']
4281 - && $orderby === 'title'
4282 - && function_exists('get_page_children')) {
4283 - $tree_ordered = get_page_children((int) $r['child_of'], $pages);
4284 - if (count($tree_ordered) < count($pages)) {
4285 - // Posts whose ancestors are not part of the result set (e.g. published
4286 - // children of a draft parent) go at the end instead of being dropped.
4287 - $tree_ids = array();
4288 - foreach ($tree_ordered as $page) {
4289 - $tree_ids[$page->ID] = true;
4290 - }
4291 - foreach ($pages as $page) {
4292 - if (!isset($tree_ids[$page->ID])) {
4293 - $tree_ordered[] = $page;
4294 - }
4295 - }
4296 - }
4297 - $pages = $tree_ordered;
4358 + $sort_order = strtoupper( $sort_order );
4359 + if ( '' !== $sort_order && !in_array( $sort_order, array( 'ASC', 'DESC' ) ) )
4360 + $sort_order = 'ASC';
4361 +
4362 + $query = "SELECT * FROM $wpdb->posts $join WHERE ($where_post_type) $where ";
4363 + $query .= $author_query;
4364 + $query .= " ORDER BY " . $sort_column . " " . $sort_order ;
4365 +
4366 + if ( !empty($number) && !empty($offset) ) {
4367 + $query .= $wpdb->prepare(' LIMIT %d, %d', $offset, $number);
4298 4368 }
4299 4369
4300 - // Cache results for 5 minutes to improve performance
4301 - if ($use_cache) {
4302 - set_transient($cache_key, $pages, 5 * MINUTE_IN_SECONDS);
4370 + //echo "<!-- accua_forms_query:\n$query\n-->";
4371 +
4372 + $pages = $wpdb->get_results($query);
4373 +
4374 + if ( empty($pages) ) {
4375 + $pages = apply_filters('get_pages', array(), $r);
4376 + return $pages;
4303 4377 }
4304 4378
4305 - /** This filter is documented above */
4306 - return apply_filters('accua_forms_get_pages', $pages, $r);
4307 -}
4379 + // Sanitize before caching so it'll only get done once
4380 + $num_pages = count($pages);
4381 + for ($i = 0; $i < $num_pages; $i++) {
4382 + $pages[$i] = sanitize_post($pages[$i], 'raw');
4383 + }
4308 4384
4309 -/**
4310 - * Get the IDs of all descendants of a post by traversing the post_parent tree.
4311 - *
4312 - * Used to resolve the child_of and exclude_tree arguments of accua_get_pages()
4313 - * to an explicit ID list, so the main query stays correct with pagination and
4314 - * search. Traverses posts of any status so that e.g. a published grandchild of
4315 - * a draft child is still found (the main query applies its own status filter).
4316 - *
4317 - * @since 2.2.27
4318 - * @param int $parent_id Root post ID (not included in the result).
4319 - * @param string|array $post_type Post type(s) to traverse.
4320 - * @return int[] Descendant post IDs.
4321 - */
4322 -function accua_forms_get_post_descendant_ids($parent_id, $post_type) {
4323 - $descendant_ids = array();
4324 - $level = array((int) $parent_id);
4325 - // Depth guard: hierarchies deeper than 25 levels are treated as data corruption (parent loops).
4326 - for ($depth = 0; $depth < 25 && !empty($level); $depth++) {
4327 - $children = get_posts(array(
4328 - 'post_type' => $post_type,
4329 - 'post_status' => 'any',
4330 - 'post_parent__in' => $level,
4331 - 'posts_per_page' => -1,
4332 - 'fields' => 'ids',
4333 - // phpcs:ignore WordPressVIPMinimum.Performance.WPQueryParams.SuppressFilters_suppress_filters -- Structural traversal: do not let language plugins hide ancestors (also get_posts()'s default).
4334 - 'suppress_filters' => true,
4335 - 'orderby' => 'ID',
4336 - 'order' => 'ASC',
4337 - ));
4338 - $children = array_map('intval', array_diff($children, $descendant_ids, array((int) $parent_id)));
4339 - $descendant_ids = array_merge($descendant_ids, $children);
4340 - $level = $children;
4385 + /*
4386 + // Update cache.
4387 + update_post_cache( $pages );
4388 + */
4389 +
4390 + if ( $child_of || $hierarchical )
4391 + $pages = get_page_children($child_of, $pages);
4392 +
4393 + if ( !empty($exclude_tree) ) {
4394 + $exclude = (int) $exclude_tree;
4395 + $children = get_page_children($exclude, $pages);
4396 + $excludes = array();
4397 + foreach ( $children as $child )
4398 + $excludes[] = $child->ID;
4399 + $excludes[] = $exclude;
4400 + $num_pages = count($pages);
4401 + for ( $i = 0; $i < $num_pages; $i++ ) {
4402 + if ( in_array($pages[$i]->ID, $excludes) )
4403 + unset($pages[$i]);
4404 + }
4341 4405 }
4342 - return $descendant_ids;
4406 +
4407 + $pages = apply_filters('get_pages', $pages, $r);
4408 +
4409 + return $pages;
4343 4410 }
4344 4411
4345 -// phpcs:disable WordPress.DB.DirectDatabaseQuery
4346 4412 function accua_forms_trash_submission($id_sub){
4347 4413 global $wpdb;
4348 4414 return $wpdb->query($wpdb->prepare("UPDATE `{$wpdb->prefix}accua_forms_submissions` SET afs_status = -1 WHERE afs_id = %d", $id_sub)) !== FALSE;
4349 4415 }
4350 4416
4351 -function accua_forms_restore_submission($id_sub){
4352 - global $wpdb;
4353 - return $wpdb->query($wpdb->prepare("UPDATE `{$wpdb->prefix}accua_forms_submissions` SET afs_status = 0 WHERE afs_id = %d", $id_sub)) !== FALSE;
4354 -}
4355 -// phpcs:enable WordPress.DB.DirectDatabaseQuery
4356 -
4357 -/**
4358 - * Clear accua_get_pages cache when posts are modified.
4359 - *
4360 - * Called when posts are created, updated, deleted, or have status changed.
4361 - * This ensures that post-select dropdowns always show fresh data.
4362 - *
4363 - * @since 2.0.0-beta.29
4364 - * @param int $post_id Post ID that was modified.
4365 - */
4366 -function accua_forms_clear_pages_cache($post_id = 0) {
4367 - global $wpdb;
4368 - // Delete all transients that start with 'accua_pages_'
4369 - // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Direct query required to delete transients by prefix, and we're clearing cache not reading data.
4370 - $wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE '_transient_accua_pages_%' OR option_name LIKE '_transient_timeout_accua_pages_%'");
4371 -}
4372 -// Clear cache when posts are modified
4373 -add_action('save_post', 'accua_forms_clear_pages_cache');
4374 -add_action('delete_post', 'accua_forms_clear_pages_cache');
4375 -add_action('trash_post', 'accua_forms_clear_pages_cache');
4376 -add_action('untrash_post', 'accua_forms_clear_pages_cache');
4377 -
4378 4417 function accua_forms_get_lead_statuses() {
4379 4418 static $statuses = NULL;
4380 4419 if ($statuses === NULL) {
4381 4420 $statuses = array(
@@ -4392,34 +4431,24 @@
4392 4431 }
4393 4432 return $statuses;
4394 4433 }
4395 4434
4396 -/**
4397 - * Get lead statuses help text (used in toggletip and Help Tab).
4398 - */
4399 -function accua_forms_get_lead_statuses_help() {
4400 - return '<strong>' . esc_html__( 'Spam', 'contact-forms' ) . '</strong> – ' . esc_html__( 'All submissions that can be discarded immediately, including submission tests', 'contact-forms' ) . '<br>'
4401 - . '<strong>' . esc_html__( 'Job Candidate', 'contact-forms' ) . '</strong> – ' . esc_html__( 'Includes spontaneous and specific job applications', 'contact-forms' ) . '<br>'
4402 - . '<strong>' . esc_html__( 'Lead', 'contact-forms' ) . '</strong> – ' . esc_html__( 'Unclear (general info request)', 'contact-forms' ) . '<br>'
4403 - . '<strong>' . esc_html__( 'Prospect', 'contact-forms' ) . '</strong> – ' . esc_html__( 'A qualified lead passed to Sales', 'contact-forms' ) . '<br>'
4404 - . '<strong>' . esc_html__( 'Opportunity', 'contact-forms' ) . '</strong> – ' . esc_html__( 'Quote / Pricing request that must be followed up', 'contact-forms' ) . '<br>'
4405 - . '<strong>' . esc_html__( 'Customer', 'contact-forms' ) . '</strong> – ' . esc_html__( 'Has already purchased', 'contact-forms' ) . '<br>'
4406 - . '<strong>' . esc_html__( 'Supplier', 'contact-forms' ) . '</strong> – ' . esc_html__( 'Contact whose role is or can only be supplier of goods and services', 'contact-forms' ) . '<br>'
4407 - . '<strong>' . esc_html__( 'Other', 'contact-forms' ) . '</strong> – ' . esc_html__( 'Contact is valid but not within lead generation', 'contact-forms' );
4408 -}
4409 -
4410 4435 function accua_forms_select_lead_status($subid, $original_lead_status) {
4411 - $subid = absint( $subid );
4412 - // (int), not absint(): -1 is the Spam lead status and must not collapse onto 1.
4413 - $original_lead_status = (int) $original_lead_status;
4414 - $nonce = esc_attr( wp_json_encode( wp_create_nonce( "set_lead_status_$subid" ) ) );
4415 - $ret = '<select onchange="accua_forms_set_lead_status(this, ' . $subid . ', ' . $nonce . ', ' . $original_lead_status . ')">';
4436 + static $accuaHelp = NULL;
4437 + if ($accuaHelp === NULL) {
4438 + if (!class_exists('AccuaFormsHelp')) {
4439 + require_once('accua-forms-help.php');
4440 + }
4441 + $accuaHelp = AccuaFormsHelp::getInstance();
4442 + }
4443 + $nonce = htmlspecialchars(_accua_forms_json_encode(wp_create_nonce( "set_lead_status_$subid" )),ENT_QUOTES);
4444 + $ret = "<select onchange=\"accua_forms_set_lead_status(this, $subid, $nonce, $original_lead_status)\">";
4416 4445 $statuses = accua_forms_get_lead_statuses();
4417 4446 foreach ($statuses as $k => $l) {
4418 - $selected = ( (int) $k === $original_lead_status ) ? ' selected="selected" ' : '';
4419 - $ret .= '<option value="' . esc_attr( $k ) . '"' . $selected . '>' . esc_html( $l ) . '</option>';
4447 + $selected = ($k == $original_lead_status) ? ' selected="selected" ' : '';
4448 + $ret .= "<option value=\"$k\"$selected>" . htmlspecialchars($l) . "</option>";
4420 4449 }
4421 - $ret .= '</select>';
4450 + $ret .= "</select>" . $accuaHelp->add_pointer('contact_forms_lead_statuses') . "<span class='accua-forms-select-lead-status-progress'></span>";
4422 4451 return $ret;
4423 4452 }
4424 4453
4425 4454 add_action( 'wp_ajax_accua-forms-set-lead-status' , 'accua_forms_set_lead_status');
@@ -4426,9 +4455,8 @@
4426 4455 function accua_forms_set_lead_status() {
4427 4456 if (!current_user_can('manage_options')){
4428 4457 wp_die(0, 403);
4429 4458 }
4430 - // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce verification happens after subid is extracted via check_ajax_referer()
4431 4459 $post = $_POST + array(
4432 4460 'subid' => 0,
4433 4461 'lead_status' => 0,
4434 4462 );
@@ -4439,62 +4467,16 @@
4439 4467 $lead_status = (int) $post['lead_status'];
4440 4468 $statuses = accua_forms_get_lead_statuses();
4441 4469 if (isset($statuses[$lead_status])) {
4442 4470 global $wpdb;
4443 - // phpcs:disable WordPress.DB.DirectDatabaseQuery
4444 - $ret = $wpdb->update(
4445 - "{$wpdb->prefix}accua_forms_submissions",
4471 + $ret = $wpdb->update("{$wpdb->prefix}accua_forms_submissions",
4446 4472 array('afs_lead_status' => $lead_status),
4447 4473 array('afs_id' => $subid),
4448 - array('%d'),
4449 - array('%d')
4474 + '%d', '%d'
4450 4475 );
4451 - // phpcs:enable WordPress.DB.DirectDatabaseQuery
4452 4476 if ($ret !== FALSE) {
4453 - wp_die(1);
4477 + wp_die(1, 200);
4454 4478 }
4455 4479 }
4456 4480 }
4457 4481 wp_die(0, 500);
4458 4482 }
4459 -
4460 -add_action( 'wp_ajax_accua-forms-add-note', 'accua_forms_ajax_add_note' );
4461 -function accua_forms_ajax_add_note() {
4462 - $sub_id = isset( $_POST['subid'] ) ? (int) $_POST['subid'] : 0;
4463 - $text = isset( $_POST['text'] ) ? sanitize_textarea_field( wp_unslash( $_POST['text'] ) ) : '';
4464 -
4465 - if ( ! $sub_id || ! $text ) {
4466 - wp_send_json_error();
4467 - }
4468 - check_ajax_referer( "submission_{$sub_id}_note_add", '_nonce' );
4469 - if ( ! current_user_can( 'manage_options' ) ) {
4470 - wp_send_json_error();
4471 - }
4472 -
4473 - require_once __DIR__ . '/admin/single-submission.php';
4474 - $result = accua_forms_add_submission_note( $sub_id, $text );
4475 - if ( ! $result ) {
4476 - wp_send_json_error();
4477 - }
4478 - $result['del_nonce'] = wp_create_nonce( "submission_{$sub_id}_note_del" );
4479 - wp_send_json_success( $result );
4480 -}
4481 -
4482 -add_action( 'wp_ajax_accua-forms-delete-note', 'accua_forms_ajax_delete_note' );
4483 -function accua_forms_ajax_delete_note() {
4484 - $sub_id = isset( $_POST['subid'] ) ? (int) $_POST['subid'] : 0;
4485 - $date = isset( $_POST['date'] ) ? sanitize_text_field( wp_unslash( $_POST['date'] ) ) : '';
4486 -
4487 - if ( ! $sub_id || ! $date ) {
4488 - wp_send_json_error();
4489 - }
4490 - check_ajax_referer( "submission_{$sub_id}_note_del", '_nonce' );
4491 - if ( ! current_user_can( 'manage_options' ) ) {
4492 - wp_send_json_error();
4493 - }
4494 -
4495 - require_once __DIR__ . '/admin/single-submission.php';
4496 - if ( ! accua_forms_delete_submission_note( $sub_id, $date ) ) {
4497 - wp_send_json_error();
4498 - }
4499 - wp_send_json_success();
4500 -}