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 | contact-forms.php +711 -1331 2.3.51.9.2 View file →
@@ -1,1331 +1,711 @@
1 -<?php
2 -/*
3 -Plugin Name: Contact Forms by Cimatti
4 -Description: Create accessible contact forms with drag-and-drop. WCAG 2.2 compliant with screen reader support, keyboard navigation, and clear error messages.
5 -Version: 2.3.5
6 -Plugin URI: https://www.cimatti.it/en/wordpress-plugins/contact-forms/
7 -Author: Cimatti
8 -Author URI: https://www.cimatti.it
9 -Text Domain: contact-forms
10 -Domain Path: /languages
11 -Requires at least: 5.9
12 -Requires PHP: 7.4
13 -License: GPLv2 or later
14 -License URI: http://www.gnu.org/licenses/gpl-2.0.html
15 -*/
16 -
17 -/*
18 -Contact Forms by Cimatti
19 -Copyright (c) 2011-2026 Andrea Cimatti
20 -
21 -This program is free software; you can redistribute it and/or
22 -modify it under the terms of the GNU General Public License
23 -as published by the Free Software Foundation; either version 2
24 -of the License, or (at your option) any later version.
25 -
26 -This program is distributed in the hope that it will be useful,
27 -but WITHOUT ANY WARRANTY; without even the implied warranty of
28 -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 -GNU General Public License for more details.
30 -
31 -You should have received a copy of the GNU General Public License
32 -along with this program; if not, write to the Free Software
33 -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
34 -
35 -
36 -The full copy of the GNU General Public License is available here: http://www.gnu.org/licenses/gpl.txt
37 -
38 -*/
39 -
40 -if ( ! defined( 'ABSPATH' ) ) exit;
41 -
42 -define('ACCUA_FORMS_DB_VERSION', '19');
43 -define('ACCUA_FORMS_CSS_VERSION', 207);
44 -define('ACCUA_FORMS_JS_VERSION', '137');
45 -define('ACCUA_FORMS_FILE', __FILE__);
46 -define('ACCUA_FORMS_DIR_URL', plugin_dir_url(ACCUA_FORMS_FILE));
47 -define('ACCUA_FORMS_DIR', dirname(ACCUA_FORMS_FILE));
48 -
49 -require_once('accua-form-api.php');
50 -require_once('accua-forms.php');
51 -require_once('admin/shortcode-button.php');
52 -require_once('admin/theme-helper.php');
53 -require_once('block-editor.php');
54 -
55 -function accua_forms_dashboard_page_head()
56 -{
57 - $screen = get_current_screen();
58 - $screen->add_help_tab(array(
59 - 'id' => 'accua_help_tab',
60 - 'title' => __('Contact Forms Dashboard', 'contact-forms'),
61 - 'content' => '<p>' . __('Marketing tools for WordPress', 'contact-forms') . '</p>',
62 - ));
63 -
64 - wp_enqueue_script( 'accua-forms-expandable-cells', plugins_url( 'assets/js/admin/expandable-cells.js', ACCUA_FORMS_FILE ), array(), ACCUA_FORMS_JS_VERSION, true );
65 - wp_enqueue_script('accua-forms-set-lead-status', plugins_url('assets/js/admin/set-lead-status.js', ACCUA_FORMS_FILE), array('jquery'), ACCUA_FORMS_JS_VERSION, true);
66 - wp_enqueue_script('accua_chart_js', plugins_url('assets/vendor/chartjs/chart.umd.min.js', ACCUA_FORMS_FILE), array('jquery'), ACCUA_FORMS_JS_VERSION, true);
67 - wp_enqueue_style('accua-forms-admin', plugins_url('assets/css/admin.css', ACCUA_FORMS_FILE), array(), ACCUA_FORMS_CSS_VERSION);
68 -
69 - /* Tentativo x drag and drop
70 - $page_hook_id = fx_smb_setings_page_id();
71 - /* Load the JavaScript needed for the settings screen. * /
72 - add_action( 'admin_enqueue_scripts', 'fx_smb_enqueue_scripts' );
73 - add_action( "admin_footer-{$page_hook_id}", 'fx_smb_footer_scripts' );
74 -
75 - /* Set number of column available. * /
76 - add_filter( 'screen_layout_columns', 'fx_smb_screen_layout_column', 10, 2 );
77 - */
78 -}
79 -
80 -/**
81 - * Add Contact Forms dashboard widget.
82 - *
83 - * Only visible to users with the 'manage_options' capability, the same
84 - * capability required by the plugin admin pages. wp_dashboard_setup only
85 - * fires on the dashboard screen, and the widget code is loaded on demand
86 - * here, so admin/dashboard-widget.php is never included on the frontend
87 - * or on other admin pages.
88 - */
89 -add_action('wp_dashboard_setup', 'accua_contact_forms_dashboard_add_widgets');
90 -function accua_contact_forms_dashboard_add_widgets()
91 -{
92 - if (!current_user_can('manage_options')) {
93 - return;
94 - }
95 - require_once ACCUA_FORMS_DIR . '/admin/dashboard-widget.php';
96 - wp_add_dashboard_widget('accua_contact_forms_dashboard_widget_news', __('Contact Forms', 'contact-forms'), 'accua_contact_forms_dashboard_widget_news_handler');
97 -}
98 -
99 -function accua_forms_dashboard_page()
100 -{
101 - require_once ACCUA_FORMS_DIR . '/admin/dashboard-page.php';
102 - return _accua_forms_dashboard_page();
103 -}
104 -
105 -
106 -register_activation_hook(ACCUA_FORMS_FILE, 'accua_forms_install');
107 -function accua_forms_install()
108 -{
109 - static $ran = false;
110 - if ( $ran ) {
111 - return;
112 - }
113 - $ran = true;
114 -
115 - $modified = false;
116 - $keys = get_option('accua_form_api_keys', array());
117 - if (!isset($keys['hash'])) {
118 - $modified = true;
119 - $keys['hash'] = wp_generate_password(64, true, true);
120 - }
121 - if (!isset($keys['aes'])) {
122 - $modified = true;
123 - $keys['aes'] = wp_generate_password(64, true, true);
124 - }
125 - if ($modified) {
126 - update_option('accua_form_api_keys', $keys);
127 - }
128 -
129 - global $wpdb;
130 -
131 - require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
132 -
133 - $charset_collate = '';
134 - if (! empty($wpdb->charset))
135 - $charset_collate = "DEFAULT CHARACTER SET $wpdb->charset";
136 - if (! empty($wpdb->collate))
137 - $charset_collate .= " COLLATE $wpdb->collate";
138 -
139 - $old_db_version = (int) get_option('accua_forms_db_version', 0);
140 -
141 - if ($old_db_version < 3) {
142 - $wpdb_suppress_errors_status = $wpdb->suppress_errors();
143 - // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange -- Schema migration, runs once
144 - $wpdb->query("ALTER TABLE `{$wpdb->prefix}accua_forms_submissions` DROP INDEX uri");
145 - // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange -- Schema migration, runs once
146 - $wpdb->query("ALTER TABLE `{$wpdb->prefix}accua_forms_submissions` DROP INDEX referrer");
147 - $wpdb->suppress_errors($wpdb_suppress_errors_status);
148 - }
149 -
150 - $sql = "CREATE TABLE `{$wpdb->prefix}accua_forms_submissions` (
151 - afs_id BIGINT(20) NOT NULL AUTO_INCREMENT,
152 - afs_form_id VARCHAR(77) NOT NULL DEFAULT '',
153 - afs_post_id BIGINT(20) NOT NULL DEFAULT 0,
154 - afs_ip VARCHAR(255) NOT NULL DEFAULT '',
155 - afs_uri TEXT NOT NULL,
156 - afs_referrer TEXT NOT NULL,
157 - afs_lang VARCHAR(60) NOT NULL DEFAULT '',
158 - afs_created TIMESTAMP NOT NULL DEFAULT 0,
159 - afs_submitted TIMESTAMP NOT NULL DEFAULT 0,
160 - afs_status TINYINT(1) NOT NULL DEFAULT 0,
161 - afs_anonymized TINYINT(1) NOT NULL DEFAULT 0,
162 - afs_stats TEXT NOT NULL,
163 - afs_lead_status TINYINT(1) NOT NULL DEFAULT 0,
164 - PRIMARY KEY (afs_id),
165 - KEY form (afs_form_id, afs_status),
166 - KEY uri (afs_uri(190)),
167 - KEY pid (afs_post_id),
168 - KEY referrer (afs_referrer(190)),
169 - KEY status (afs_status, afs_id),
170 - KEY submitted (afs_submitted),
171 - KEY lead_status (afs_lead_status, afs_status)
172 - ) $charset_collate;";
173 - dbDelta($sql);
174 -
175 - $sql = "CREATE TABLE `{$wpdb->prefix}accua_forms_submissions_values` (
176 - afsv_sub_id BIGINT(20) NOT NULL,
177 - afsv_field_id VARCHAR(77) NOT NULL,
178 - afsv_type varchar(255) NOT NULL DEFAULT '',
179 - afsv_value TEXT NOT NULL,
180 - PRIMARY KEY (afsv_sub_id, afsv_field_id),
181 - KEY value_index (afsv_field_id(77), afsv_value(114))
182 - ) $charset_collate;";
183 - dbDelta($sql);
184 -
185 - /* creazione tabella per le note dell'utente
186 - sono relative a una compilazione
187 - possono esserci più note per ogni compilazione in date diverse
188 -
189 - */
190 - $sql = "CREATE TABLE `{$wpdb->prefix}accua_forms_submissions_notes` (
191 - afsn_sub_id BIGINT(20) NOT NULL,
192 - afsn_date TIMESTAMP NOT NULL DEFAULT 0,
193 - afsn_text TEXT NOT NULL,
194 - afsn_user VARCHAR(100) NOT NULL DEFAULT '',
195 - PRIMARY KEY (afsn_sub_id, afsn_date),
196 - KEY afsn_sub_id (afsn_sub_id)
197 - ) $charset_collate;";
198 - dbDelta($sql);
199 -
200 - // DB 18: make field slugs case-sensitive in the submission values table.
201 - // Runs right after dbDelta, so a fresh install (version 0) is converted at
202 - // creation time too.
203 - //
204 - // Deliberately NOT gated on the stored DB version: dbDelta above rewrites
205 - // afsv_field_id back to the table's default (case-insensitive) collation
206 - // whenever it runs, because the column no longer matches the definition it
207 - // compares against. install() runs on every version change AND on every
208 - // activation, so a version check here would leave the column case-insensitive
209 - // again after the next update or a deactivate/reactivate - with the values of
210 - // two case-differing slugs silently colliding once more. The conversion is
211 - // idempotent and returns early when the collation is already binary, so
212 - // re-asserting it on each run costs one information_schema lookup.
213 - accua_forms_make_field_slugs_case_sensitive();
214 -
215 - // Data migration: run after dbDelta so new columns exist
216 - if ($old_db_version < 14) {
217 - // Migrate: afs_status=-2 (old "anonymized" status) → afs_anonymized=1 + restore original active status
218 - // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- One-time migration
219 - $wpdb->query("UPDATE `{$wpdb->prefix}accua_forms_submissions` SET afs_anonymized = 1, afs_status = 0 WHERE afs_status = -2");
220 -
221 - // Migrate saved forms from 1.x format to 2.0 format
222 - $saved_forms = get_option('accua_forms_saved_forms', array());
223 - if (is_array($saved_forms)) {
224 - $forms_updated = false;
225 - foreach ($saved_forms as $fid => &$form) {
226 - // Rename legacy 'name' key to 'title' (changed in 2.0)
227 - if (isset($form['name']) && !isset($form['title'])) {
228 - $form['title'] = $form['name'];
229 - unset($form['name']);
230 - $forms_updated = true;
231 - }
232 - // Convert 'fields' from comma-separated string to array of instances.
233 - // Keyed by instance id, exactly as the form editor writes them: the
234 - // submission handler looks each posted field up as
235 - // $form_data['fields'][$name] (accua-forms.php), so an instance stored
236 - // under a numeric key is never found and its value is dropped.
237 - if (isset($form['fields']) && is_string($form['fields'])) {
238 - $field_slugs = array_filter(array_map('trim', explode(',', $form['fields'])));
239 - $form['fields'] = array();
240 - foreach ($field_slugs as $slug) {
241 - $istance_id = accua_forms_unique_istance_id($slug, $form['fields']);
242 - $form['fields'][$istance_id] = array(
243 - 'version' => 2,
244 - 'istance_id' => $istance_id,
245 - 'widget_number' => '',
246 - 'ref' => $slug,
247 - 'required' => false,
248 - );
249 - }
250 - unset($form['fieldnum']);
251 - $forms_updated = true;
252 - }
253 - }
254 - unset($form);
255 - if ($forms_updated) {
256 - update_option('accua_forms_saved_forms', $saved_forms);
257 - }
258 - }
259 - }
260 -
261 - // DB 19: repair field instances an earlier 1.x -> 2.0 migration left unusable.
262 - // That conversion (in 2.0 through 2.3.0) appended array('ref' => $slug) with
263 - // no instance id, so the instances ended up under numeric keys. Such a form
264 - // still renders - the render loop reads 'ref' - but the submission handler
265 - // matches each posted field by array key, finds nothing, and stores the
266 - // submission with none of its values. Silent, and only on forms that came
267 - // from a pre-2.0 install, which is why it went unnoticed for so long.
268 - if ($old_db_version < 19) {
269 - accua_forms_repair_field_instances('accua_forms_saved_forms');
270 - // Trashed forms can be restored, so they must come back working too.
271 - accua_forms_repair_field_instances('accua_forms_trash_forms');
272 - }
273 -
274 -
275 - // An unreadable field list must never be silently replaced by the defaults:
276 - // try to recover it first, and keep a copy of the original either way.
277 - accua_forms_recover_avail_fields();
278 -
279 - $avail_fields = get_option('accua_forms_avail_fields', array());
280 -
281 - if (!is_array($avail_fields)) {
282 - $avail_fields = array();
283 - }
284 -
285 - if (empty($avail_fields) || ($old_db_version === 0)) {
286 - $avail_fields += array(
287 - // essential_column: shown by the submissions list "Essential Columns"
288 - // button - sensible defaults for a contact form: who wrote (name,
289 - // email) and what they wrote (message).
290 - 'first_name' => array(
291 - 'id' => 'first_name',
292 - 'name' => 'First Name',
293 - 'type' => 'textfield',
294 - 'description' => '',
295 - 'default_value' => '',
296 - 'allowed_values' => '',
297 - 'essential_column' => 1,
298 - ),
299 - 'last_name' => array(
300 - 'id' => 'last_name',
301 - 'name' => 'Last Name',
302 - 'type' => 'textfield',
303 - 'description' => '',
304 - 'default_value' => '',
305 - 'allowed_values' => '',
306 - 'essential_column' => 1,
307 - ),
308 - 'email' => array(
309 - 'id' => 'email',
310 - 'name' => 'Email',
311 - 'type' => 'autoreply_email',
312 - 'description' => '',
313 - 'default_value' => '',
314 - 'allowed_values' => '',
315 - 'essential_column' => 1,
316 - ),
317 - 'address' => array(
318 - 'id' => 'address',
319 - 'name' => 'Address',
320 - 'type' => 'textfield',
321 - 'description' => '',
322 - 'default_value' => '',
323 - 'allowed_values' => '',
324 - ),
325 - 'city' => array(
326 - 'id' => 'city',
327 - 'name' => 'City',
328 - 'type' => 'textfield',
329 - 'description' => '',
330 - 'default_value' => '',
331 - 'allowed_values' => '',
332 - ),
333 - 'state_province' => array(
334 - 'id' => 'state_province',
335 - 'name' => 'State/Province',
336 - 'type' => 'textfield',
337 - 'description' => '',
338 - 'default_value' => '',
339 - 'allowed_values' => '',
340 - ),
341 - 'country' => array(
342 - 'id' => 'country',
343 - 'name' => 'Country',
344 - 'type' => 'select',
345 - 'description' => '',
346 - 'default_value' => '-',
347 - 'allowed_values' => "-|Select...
348 -Afghanistan
349 -Ã…land Islands
350 -Albania
351 -Algeria
352 -American Samoa
353 -Andorra
354 -Angola
355 -Anguilla
356 -Antarctica
357 -Antigua And Barbuda
358 -Argentina
359 -Armenia
360 -Aruba
361 -Australia
362 -Austria
363 -Azerbaijan
364 -Bahamas
365 -Bahrain
366 -Bangladesh
367 -Barbados
368 -Belarus
369 -Belgium
370 -Belize
371 -Benin
372 -Bermuda
373 -Bhutan
374 -Bolivia
375 -Bosnia And Herzegovina
376 -Botswana
377 -Bouvet Island
378 -Brazil
379 -British Indian Ocean Territory
380 -Brunei Darussalam
381 -Bulgaria
382 -Burkina Faso
383 -Burundi
384 -Cambodia
385 -Cameroon
386 -Canada
387 -Cape Verde
388 -Cayman Islands
389 -Central African Republic
390 -Chad
391 -Chile
392 -China
393 -Christmas Island
394 -Cocos (Keeling) Islands
395 -Colombia
396 -Comoros
397 -Congo
398 -Congo, The Democratic Republic Of The
399 -Cook Islands
400 -Costa Rica
401 -Côte D'Ivoire
402 -Croatia
403 -Cuba
404 -Cyprus
405 -Czech Republic
406 -Denmark
407 -Djibouti
408 -Dominica
409 -Dominican Republic
410 -Ecuador
411 -Egypt
412 -El Salvador
413 -Equatorial Guinea
414 -Eritrea
415 -Estonia
416 -Ethiopia
417 -Falkland Islands (Malvinas)
418 -Faroe Islands
419 -Fiji
420 -Finland
421 -France
422 -French Guiana
423 -French Polynesia
424 -French Southern Territories
425 -Gabon
426 -Gambia
427 -Georgia
428 -Germany
429 -Ghana
430 -Gibraltar
431 -Greece
432 -Greenland
433 -Grenada
434 -Guadeloupe
435 -Guam
436 -Guatemala
437 -Guernsey
438 -Guinea
439 -Guinea-Bissau
440 -Guyana
441 -Haiti
442 -Heard Island And Mcdonald Islands
443 -Holy See (Vatican City State)
444 -Honduras
445 -Hong Kong
446 -Hungary
447 -Iceland
448 -India
449 -Indonesia
450 -Iran, Islamic Republic Of
451 -Iraq
452 -Ireland
453 -Isle Of Man
454 -Israel
455 -Italy
456 -Jamaica
457 -Japan
458 -Jersey
459 -Jordan
460 -Kazakhstan
461 -Kenya
462 -Kiribati
463 -Korea, Democratic People'S Republic Of
464 -Korea, Republic Of
465 -Kuwait
466 -Kyrgyzstan
467 -Lao People'S Democratic Republic
468 -Latvia
469 -Lebanon
470 -Lesotho
471 -Liberia
472 -Libyan Arab Jamahiriya
473 -Liechtenstein
474 -Lithuania
475 -Luxembourg
476 -Macao
477 -Macedonia, The Former Yugoslav Republic Of
478 -Madagascar
479 -Malawi
480 -Malaysia
481 -Maldives
482 -Mali
483 -Malta
484 -Marshall Islands
485 -Martinique
486 -Mauritania
487 -Mauritius
488 -Mayotte
489 -Mexico
490 -Micronesia, Federated States Of
491 -Moldova, Republic Of
492 -Monaco
493 -Mongolia
494 -Montenegro
495 -Montserrat
496 -Morocco
497 -Mozambique
498 -Myanmar
499 -Namibia
500 -Nauru
501 -Nepal
502 -Netherlands
503 -Netherlands Antilles
504 -New Caledonia
505 -New Zealand
506 -Nicaragua
507 -Niger
508 -Nigeria
509 -Niue
510 -Norfolk Island
511 -Northern Mariana Islands
512 -Norway
513 -Oman
514 -Pakistan
515 -Palau
516 -Palestinian Territory, Occupied
517 -Panama
518 -Papua New Guinea
519 -Paraguay
520 -Peru
521 -Philippines
522 -Pitcairn
523 -Poland
524 -Portugal
525 -Puerto Rico
526 -Qatar
527 -Réunion
528 -Romania
529 -Russian Federation
530 -Rwanda
531 -Saint Barthélemy
532 -Saint Helena
533 -Saint Kitts And Nevis
534 -Saint Lucia
535 -Saint Martin
536 -Saint Pierre And Miquelon
537 -Saint Vincent And The Grenadines
538 -Samoa
539 -San Marino
540 -Sao Tome And Principe
541 -Saudi Arabia
542 -Senegal
543 -Serbia
544 -Seychelles
545 -Sierra Leone
546 -Singapore
547 -Slovakia
548 -Slovenia
549 -Solomon Islands
550 -Somalia
551 -South Africa
552 -South Georgia And The South Sandwich Islands
553 -Spain
554 -Sri Lanka
555 -Sudan
556 -Suriname
557 -Svalbard And Jan Mayen
558 -Swaziland
559 -Sweden
560 -Switzerland
561 -Syrian Arab Republic
562 -Taiwan, Province Of China
563 -Tajikistan
564 -Tanzania, United Republic Of
565 -Thailand
566 -Timor-Leste
567 -Togo
568 -Tokelau
569 -Tonga
570 -Trinidad And Tobago
571 -Tunisia
572 -Turkey
573 -Turkmenistan
574 -Turks And Caicos Islands
575 -Tuvalu
576 -Uganda
577 -Ukraine
578 -United Arab Emirates
579 -United Kingdom
580 -United States
581 -United States Minor Outlying Islands
582 -Uruguay
583 -Uzbekistan
584 -Vanuatu
585 -Venezuela, Bolivarian Republic Of
586 -Viet Nam
587 -Virgin Islands, British
588 -Virgin Islands, U.S.
589 -Wallis And Futuna
590 -Western Sahara
591 -Yemen
592 -Zambia
593 -Zimbabwe",
594 - ),
595 - 'message' => array(
596 - 'id' => 'message',
597 - 'name' => 'Message',
598 - 'type' => 'textarea',
599 - 'description' => '',
600 - 'default_value' => '',
601 - 'allowed_values' => '',
602 - 'essential_column' => 1,
603 - ),
604 - 'captcha' => array(
605 - 'id' => 'captcha',
606 - 'name' => 'Captcha',
607 - 'type' => 'captcha',
608 - 'description' => '',
609 - 'default_value' => '',
610 - 'allowed_values' => '',
611 - ),
612 - 'turnstile' => array(
613 - 'id' => 'turnstile',
614 - 'name' => 'Turnstile',
615 - 'type' => 'turnstile',
616 - 'description' => '',
617 - 'default_value' => '',
618 - 'allowed_values' => '',
619 - ),
620 - 'captcha_v3' => array(
621 - 'id' => 'captcha_v3',
622 - 'name' => 'Captcha (reCAPTCHA v3)',
623 - 'type' => 'captcha_v3',
624 - 'description' => '',
625 - 'default_value' => '',
626 - 'allowed_values' => '',
627 - ),
628 - 'cap' => array(
629 - 'id' => 'cap',
630 - 'name' => 'Captcha (Cap)',
631 - 'type' => 'cap',
632 - 'description' => '',
633 - 'default_value' => '',
634 - 'allowed_values' => '',
635 - ),
636 - );
637 - update_option('accua_forms_avail_fields', $avail_fields);
638 - }
639 -
640 - // Add Turnstile field for existing installations (backward compatibility)
641 - // Only add if it doesn't exist yet
642 - if (!isset($avail_fields['turnstile'])) {
643 - $avail_fields['turnstile'] = array(
644 - 'id' => 'turnstile',
645 - 'name' => 'Turnstile',
646 - 'type' => 'turnstile',
647 - 'description' => '',
648 - 'default_value' => '',
649 - 'allowed_values' => '',
650 - );
651 - update_option('accua_forms_avail_fields', $avail_fields);
652 - }
653 -
654 - // Add reCAPTCHA v3 field for existing installations (backward compatibility)
655 - // Only add if it doesn't exist yet
656 - if (!isset($avail_fields['captcha_v3'])) {
657 - $avail_fields['captcha_v3'] = array(
658 - 'id' => 'captcha_v3',
659 - 'name' => 'Captcha (reCAPTCHA v3)',
660 - 'type' => 'captcha_v3',
661 - 'description' => '',
662 - 'default_value' => '',
663 - 'allowed_values' => '',
664 - );
665 - update_option('accua_forms_avail_fields', $avail_fields);
666 - }
667 -
668 - // Add Cap field for existing installations (backward compatibility)
669 - // Only add if it doesn't exist yet
670 - if (!isset($avail_fields['cap'])) {
671 - $avail_fields['cap'] = array(
672 - 'id' => 'cap',
673 - 'name' => 'Captcha (Cap)',
674 - 'type' => 'cap',
675 - 'description' => '',
676 - 'default_value' => '',
677 - 'allowed_values' => '',
678 - );
679 - update_option('accua_forms_avail_fields', $avail_fields);
680 - }
681 -
682 - // Add Telephone field for existing installations (backward compatibility)
683 - // Only add if it doesn't exist yet
684 - if (!isset($avail_fields['telephone'])) {
685 - $avail_fields['telephone'] = array(
686 - 'id' => 'telephone',
687 - 'name' => 'Telephone',
688 - 'type' => 'telephone',
689 - 'description' => '',
690 - 'default_value' => '+39 ',
691 - 'allowed_values' => '',
692 - );
693 - update_option('accua_forms_avail_fields', $avail_fields);
694 - }
695 -
696 - // 2.2.47 (DB 17): per-field "Show in essential columns" flag. Existing
697 - // installations keep the previous behavior of the submissions list
698 - // "Essential Columns" button, whose hardcoded list contained one field
699 - // column: email. Guarded by isset so a later uncheck (the Fields page save
700 - // always writes the key) is never overridden on reactivation; fresh
701 - // installs already flag email (and name/message) in the defaults above.
702 - if ($old_db_version < 17 && isset($avail_fields['email']) && !isset($avail_fields['email']['essential_column'])) {
703 - $avail_fields['email']['essential_column'] = 1;
704 - update_option('accua_forms_avail_fields', $avail_fields);
705 - }
706 -
707 - $form_data = get_option('accua_forms_default_form_data', array());
708 - if (!is_array($form_data)) {
709 - $form_data = array();
710 - }
711 -
712 - // Use the centralized defaults function
713 - $form_data += accua_forms_get_default_form_data();
714 -
715 - update_option('accua_forms_default_form_data', $form_data);
716 - update_option('accua_forms_db_version', ACCUA_FORMS_DB_VERSION);
717 -}
718 -
719 -/**
720 - * An instance id that is free in this form's field list.
721 - *
722 - * Field instances are keyed by their instance id, which is normally the field
723 - * slug; a form may hold the same field twice, so a taken slug gets a numeric
724 - * suffix the way the form editor's own widget numbering does.
725 - *
726 - * @since 2.3.0
727 - * @param string $slug Field slug the instance refers to.
728 - * @param array $fields Instances already placed in this form.
729 - * @return string
730 - */
731 -function accua_forms_unique_istance_id($slug, $fields) {
732 - if (!isset($fields[$slug])) {
733 - return $slug;
734 - }
735 - $n = 2;
736 - while (isset($fields[$slug . '-' . $n])) {
737 - $n++;
738 - }
739 - return $slug . '-' . $n;
740 -}
741 -
742 -/**
743 - * Give every field instance of every form a usable instance id.
744 - *
745 - * Instances converted from the pre-2.0 format carry only a 'ref' and sit under
746 - * a numeric key, which makes the submission handler drop their values (it looks
747 - * each posted field up by array key). Rebuilds those keyed by instance id and
748 - * leaves everything else exactly as it is - a normally saved form is untouched,
749 - * so this is safe to run over any install and is idempotent.
750 - *
751 - * @since 2.3.0
752 - * @param string $option Option holding forms ('accua_forms_saved_forms' or the trash).
753 - * @return int Number of forms repaired.
754 - */
755 -function accua_forms_repair_field_instances($option) {
756 - $forms = get_option($option, array());
757 - if (!is_array($forms)) {
758 - return 0;
759 - }
760 -
761 - $repaired = 0;
762 - foreach ($forms as $fid => $form) {
763 - if (empty($form['fields']) || !is_array($form['fields'])) {
764 - continue;
765 - }
766 -
767 - // Nothing to do unless some instance is missing its id.
768 - $needs_repair = false;
769 - foreach ($form['fields'] as $key => $istance_data) {
770 - if (!is_array($istance_data) || empty($istance_data['istance_id'])) {
771 - $needs_repair = true;
772 - break;
773 - }
774 - }
775 - if (!$needs_repair) {
776 - continue;
777 - }
778 -
779 - $rebuilt = array();
780 - foreach ($form['fields'] as $key => $istance_data) {
781 - // A bare slug instead of an instance: another shape old data turns up in,
782 - // and recoverable, so it is rebuilt rather than dropped.
783 - if (is_string($istance_data) && '' !== $istance_data) {
784 - $istance_data = array('ref' => $istance_data);
785 - }
786 - if (!is_array($istance_data)) {
787 - continue;
788 - }
789 - if (!empty($istance_data['istance_id'])) {
790 - // Already valid: keep it under its own instance id.
791 - $rebuilt[$istance_data['istance_id']] = $istance_data;
792 - continue;
793 - }
794 - // The slug is in 'ref'; a numeric key carries no information, but a
795 - // string key was the instance id in some hand-edited data, so prefer it.
796 - $ref = !empty($istance_data['ref'])
797 - ? $istance_data['ref']
798 - : (is_string($key) ? $key : '');
799 - if ('' === $ref) {
800 - continue;
801 - }
802 - $istance_id = accua_forms_unique_istance_id(is_string($key) ? $key : $ref, $rebuilt);
803 - $rebuilt[$istance_id] = array(
804 - 'version' => 2,
805 - 'istance_id' => $istance_id,
806 - 'widget_number' => '',
807 - 'ref' => $ref,
808 - 'required' => !empty($istance_data['required']),
809 - ) + $istance_data;
810 - }
811 -
812 - $forms[$fid]['fields'] = $rebuilt;
813 - $repaired++;
814 - }
815 -
816 - if ($repaired) {
817 - update_option($option, $forms);
818 - }
819 -
820 - return $repaired;
821 -}
822 -
823 -/**
824 - * Repair the string lengths of a serialized value whose text was altered
825 - * without updating them.
826 - *
827 - * The usual cause is a migration or search-and-replace tool that rewrote the
828 - * option text (classically normalising CRLF to LF) without recomputing the
829 - * `s:<length>:` headers. PHP then refuses the whole structure and unserialize()
830 - * returns false, so the value reads as missing even though the data is intact.
831 - *
832 - * Each declared length is trusted first and only shortened when it does not
833 - * land on the closing quote, so a healthy value is returned untouched.
834 - *
835 - * @since 2.3.0
836 - * @param string $data Serialized value.
837 - * @return string|false Repaired serialized string, or false if it cannot be walked.
838 - */
839 -function accua_forms_fix_serialized_lengths( $data ) {
840 - $out = '';
841 - $i = 0;
842 - $len = strlen( $data );
843 -
844 - while ( $i < $len ) {
845 - if ( 's:' === substr( $data, $i, 2 ) && preg_match( '/^s:(\d+):"/', substr( $data, $i, 24 ), $m ) ) {
846 - $declared = (int) $m[1];
847 - $start = $i + strlen( $m[0] );
848 - $actual = null;
849 -
850 - // The declared length wins when it is correct; otherwise take the
851 - // longest shorter run that still terminates the string properly.
852 - for ( $try = $declared; $try >= 0; $try-- ) {
853 - if ( '";' === substr( $data, $start + $try, 2 ) ) {
854 - $actual = $try;
855 - break;
856 - }
857 - }
858 -
859 - if ( null === $actual ) {
860 - return false;
861 - }
862 -
863 - $string = substr( $data, $start, $actual );
864 - $out .= 's:' . strlen( $string ) . ':"' . $string . '";';
865 - $i = $start + $actual + 2;
866 - continue;
867 - }
868 -
869 - $out .= $data[ $i ];
870 - ++$i;
871 - }
872 -
873 - return $out;
874 -}
875 -
876 -/**
877 - * Recover accua_forms_avail_fields when PHP cannot unserialize it.
878 - *
879 - * accua_forms_install() treats an unreadable field list as an empty one and
880 - * writes the shipped defaults over it, which would discard every field the
881 - * site had defined - labels, options and all - with no way back. That only
882 - * bites on an upgrade, because the install routine runs when the stored DB
883 - * version changes, which is exactly when a site carrying such a value meets
884 - * it. Observed in the wild on a site whose option had lost its carriage
885 - * returns while keeping the original lengths.
886 - *
887 - * The repaired value is accepted only when it unserializes into something that
888 - * actually looks like a field list, and the untouched original is copied to
889 - * accua_forms_avail_fields_corrupt_backup either way, so nothing is lost even
890 - * when the repair does not work.
891 - *
892 - * @since 2.3.0
893 - * @return bool True when a broken value was recovered.
894 - */
895 -function accua_forms_recover_avail_fields() {
896 - global $wpdb;
897 -
898 - $stored = get_option( 'accua_forms_avail_fields', array() );
899 - if ( is_array( $stored ) ) {
900 - return false; // Healthy, or genuinely absent.
901 - }
902 -
903 - // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Reading the raw row on purpose: get_option() cannot return a value it fails to unserialize
904 - $raw = $wpdb->get_var(
905 - $wpdb->prepare( "SELECT option_value FROM {$wpdb->options} WHERE option_name = %s", 'accua_forms_avail_fields' )
906 - );
907 -
908 - if ( ! is_string( $raw ) || '' === $raw || 0 !== strpos( $raw, 'a:' ) ) {
909 - return false;
910 - }
911 -
912 - // Keep the original before anything else touches it.
913 - if ( false === get_option( 'accua_forms_avail_fields_corrupt_backup' ) ) {
914 - add_option( 'accua_forms_avail_fields_corrupt_backup', $raw, '', 'no' );
915 - }
916 -
917 - $fixed = accua_forms_fix_serialized_lengths( $raw );
918 - if ( false === $fixed ) {
919 - return false;
920 - }
921 -
922 - $recovered = @unserialize( $fixed ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged -- A failed repair is an expected outcome, handled below
923 - if ( ! is_array( $recovered ) || empty( $recovered ) ) {
924 - return false;
925 - }
926 -
927 - // Only accept something shaped like a field list.
928 - foreach ( $recovered as $slug => $definition ) {
929 - if ( ! is_string( $slug ) || ! is_array( $definition ) || ! isset( $definition['type'] ) ) {
930 - return false;
931 - }
932 - }
933 -
934 - update_option( 'accua_forms_avail_fields', $recovered );
935 -
936 - return true;
937 -}
938 -
939 -/**
940 - * Give afsv_field_id the binary collation of its own charset, so field slugs
941 - * that differ only in case are distinct values.
942 - *
943 - * The table is created with the site's default (case-insensitive) collation,
944 - * under which 'role' and 'Role' are the same string to MySQL. Two field
945 - * definitions differing only in case are perfectly legal - the slugs live in a
946 - * PHP array, where keys are case-sensitive - and the consequences in the
947 - * database were severe: the submissions list built its field columns with
948 - * SELECT DISTINCT afsv_field_id, which collapsed the pair into a single
949 - * column, and the PRIMARY KEY (afsv_sub_id, afsv_field_id) treated the second
950 - * field of a submission as a duplicate and rejected its value outright, losing
951 - * it silently.
952 - *
953 - * Converting only this column keeps its indexes usable (no per-query COLLATE,
954 - * which would prevent the index from being used) and leaves stored values
955 - * untouched. The conversion is also safe in this direction: values that were
956 - * equal under the case-insensitive collation could never both exist, so
957 - * relaxing the comparison cannot produce a duplicate key.
958 - *
959 - * An explicit ALTER TABLE is used because dbDelta does not compare collations;
960 - * WordPress core changes collations the same way (maybe_convert_table_to_utf8mb4).
961 - *
962 - * @since 2.3.0
963 - * @return bool True when the column ends up case-sensitive, false otherwise.
964 - */
965 -function accua_forms_make_field_slugs_case_sensitive() {
966 - global $wpdb;
967 -
968 - $table = $wpdb->prefix . 'accua_forms_submissions_values';
969 -
970 - // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Schema inspection, runs once per upgrade
971 - $column = $wpdb->get_row($wpdb->prepare(
972 - "SELECT CHARACTER_SET_NAME, COLLATION_NAME FROM information_schema.COLUMNS
973 - WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = %s AND COLUMN_NAME = 'afsv_field_id'",
974 - $table
975 - ));
976 -
977 - if (!$column || empty($column->CHARACTER_SET_NAME)) {
978 - return false;
979 - }
980 -
981 - // Already case-sensitive (binary collation): nothing to do.
982 - if (!empty($column->COLLATION_NAME) && substr($column->COLLATION_NAME, -4) === '_bin') {
983 - return true;
984 - }
985 -
986 - $collation = $column->CHARACTER_SET_NAME . '_bin';
987 -
988 - // The collation name goes into the ALTER unquoted, so accept it only when the
989 - // server itself reports it as a real collation of that charset.
990 - // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Schema inspection, runs once per upgrade
991 - $known = $wpdb->get_var($wpdb->prepare(
992 - "SELECT COLLATION_NAME FROM information_schema.COLLATIONS
993 - WHERE COLLATION_NAME = %s AND CHARACTER_SET_NAME = %s",
994 - $collation,
995 - $column->CHARACTER_SET_NAME
996 - ));
997 -
998 - if (!$known || !preg_match('/^[A-Za-z0-9_]+$/', $known)) {
999 - return false;
1000 - }
1001 -
1002 - // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter -- Table name is built from $wpdb->prefix and the collation name is validated against information_schema above; neither can be bound as a parameter
1003 - $wpdb->query("ALTER TABLE `{$table}` MODIFY `afsv_field_id` VARCHAR(77) COLLATE {$known} NOT NULL");
1004 -
1005 - // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Verifying the schema change
1006 - $now = $wpdb->get_var($wpdb->prepare(
1007 - "SELECT COLLATION_NAME FROM information_schema.COLUMNS
1008 - WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = %s AND COLUMN_NAME = 'afsv_field_id'",
1009 - $table
1010 - ));
1011 -
1012 - return (is_string($now) && substr($now, -4) === '_bin');
1013 -}
1014 -
1015 -// Runs at init priority 1 (before accua_form_init at priority 5) so the DB schema
1016 -// is always up to date before form processing begins. Also ensures translations used
1017 -// in accua_forms_get_default_form_data() are loaded when a fresh install is detected.
1018 -add_action('init', 'accua_forms_check_db_version_and_update', 1);
1019 -function accua_forms_check_db_version_and_update()
1020 -{
1021 - if ( get_transient( '_accua_forms_data_deleted' ) ) {
1022 - return;
1023 - }
1024 - $db_version = get_option('accua_forms_db_version', '');
1025 - if (ACCUA_FORMS_DB_VERSION != $db_version) {
1026 - accua_forms_install();
1027 - }
1028 -}
1029 -
1030 -add_filter('robots_txt', 'accua_forms_robots_txt', 10, 2);
1031 -function accua_forms_robots_txt($output, $public)
1032 -{
1033 - if ($public) {
1034 - $site_url = wp_parse_url(site_url());
1035 - $path = (!empty($site_url['path'])) ? $site_url['path'] : '';
1036 - $output .= "\nUser-agent: *\n";
1037 - $output .= "Allow: $path/wp-admin/js/\n";
1038 - $output .= "Allow: $path/wp-admin/css/\n";
1039 - }
1040 - return $output;
1041 -}
1042 -
1043 -// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- Internal helper function with underscore prefix
1044 -function _accua_forms_json_encode($item)
1045 -{
1046 - static $version = NULL;
1047 - if ($version === NULL) {
1048 - $version = version_compare(PHP_VERSION, '5.3.0', '>=');
1049 - }
1050 - if ($version) {
1051 - return json_encode($item, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP);
1052 - } else {
1053 - return strtr(
1054 - json_encode($item),
1055 - array(
1056 - '&' => '\\u0026',
1057 - '<' => '\\u003C',
1058 - '>' => '\\u003E',
1059 - )
1060 - );
1061 - }
1062 -}
1063 -
1064 -/* per ripulire eventuali token impostati nella versione 1.9.4 */
1065 -function accua_forms_cleanup_meta_tokens()
1066 -{
1067 - global $wpdb;
1068 - // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- One-time cleanup on activation
1069 - $post_ids = $wpdb->get_col("SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key = '_accua_download_token'");
1070 -
1071 - if (!empty($post_ids)) {
1072 - // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- One-time cleanup on activation
1073 - $wpdb->query("DELETE FROM {$wpdb->postmeta} WHERE meta_key = '_accua_download_token'");
1074 - }
1075 -}
1076 -register_activation_hook(__FILE__, 'accua_forms_cleanup_meta_tokens');
1077 -
1078 -// Schedule retention cleanup cron on activation
1079 -register_activation_hook( __FILE__, 'accua_forms_activate_retention_cron' );
1080 -function accua_forms_activate_retention_cron() {
1081 - if ( ! wp_next_scheduled( 'accua_forms_retention_cleanup' ) ) {
1082 - wp_schedule_event( time(), 'daily', 'accua_forms_retention_cleanup' );
1083 - }
1084 -}
1085 -
1086 -// Clear retention cleanup cron on deactivation
1087 -register_deactivation_hook( __FILE__, 'accua_forms_deactivate_retention_cron' );
1088 -function accua_forms_deactivate_retention_cron() {
1089 - wp_clear_scheduled_hook( 'accua_forms_retention_cleanup' );
1090 -}
1091 -
1092 -// Add REST API compatibility
1093 -add_action('rest_api_init', 'accua_forms_rest_compatibility');
1094 -
1095 -/**
1096 - * Ensures proper REST API compatibility by closing any open PHP sessions
1097 - * This prevents timeouts when WordPress is making internal REST API requests
1098 - */
1099 -function accua_forms_rest_compatibility()
1100 -{
1101 - // Check if a session is active and close it for REST requests
1102 - if (session_id() && session_status() === PHP_SESSION_ACTIVE) {
1103 - session_write_close();
1104 - }
1105 -
1106 - // Remove hooks that might interfere with REST API requests
1107 - remove_action('init', 'accua_forms_init_session', 1);
1108 -}
1109 -
1110 -/**
1111 - * Get the default form data values.
1112 - *
1113 - * This function returns all default values for form settings including messages,
1114 - * email templates, and styling options. Used during installation and for the
1115 - * "Restore to Default" functionality in the settings page.
1116 - *
1117 - * @since 2.0.0-beta.6
1118 - * @return array Default form data values.
1119 - */
1120 -function accua_forms_get_default_form_data()
1121 -{
1122 - return array(
1123 - 'success_message' => '<div style="font-family: Arial, Helvetica, sans-serif;">
1124 -<h2>' . __('Thank you', 'contact-forms') . ' {first_name} {last_name},</h2>
1125 -' . __('We have received your contact request. Check your inbox for the confirmation message.', 'contact-forms') . '
1126 -
1127 -<strong>' . __('Can\'t find the email?', 'contact-forms') . '</strong>
1128 -
1129 -' . __('It doesn\'t happen often but your mailbox could apply strict spam rules that block our email from reaching your inbox. Try checking your spam folder.', 'contact-forms') . '
1130 -
1131 -' . __('Also check that the email you entered in the form', 'contact-forms') . ' (<strong>{email}</strong>) ' . __('is correct. If it is not, you can submit the form again.', 'contact-forms') . '
1132 -
1133 -' . __('For any other issues, please don\'t hesitate to contact us.', 'contact-forms') . '
1134 -
1135 -</div>',
1136 - 'error_message' => '<div style="font-family: Arial, Helvetica, sans-serif;">
1137 -<h2>' . __('Oops! Something went wrong.', 'contact-forms') . '</h2>
1138 -' . __('Internet is an awfully complex place and even though we take every precaution to make sure things run smoothly every once in a while things can go wrong that are not under our control.', 'contact-forms') . '
1139 -
1140 -' . __('Please try filling in the form again.', 'contact-forms') . '
1141 -
1142 -' . __('For any other issues, please don\'t hesitate to contact us.', 'contact-forms') . '
1143 -
1144 -</div>',
1145 - 'emails_from_name' => '',
1146 - 'emails_from' => '',
1147 - 'admin_emails_to' => get_option('admin_email', ''),
1148 - 'emails_bcc' => '',
1149 - 'admin_emails_subject' => __('New contact request from your site', 'contact-forms'),
1150 - 'admin_emails_message' => '<table style="font-family: Arial, Helvetica, sans-serif; background: #fff; margin-top: 10px; border: 1px solid #DDDDDD; max-width: 700px;" cellspacing="0" cellpadding="0" align="center">
1151 -<tbody>
1152 -<tr>
1153 -<td>
1154 -<table style="max-width:700px;" border="0" cellspacing="0" cellpadding="0" align="center">
1155 -<tbody>
1156 -<tr>
1157 -<td>
1158 -<table style="padding: 10px; border: 1px solid #dfdfdf; max-width:700px;" border="0" cellspacing="0" cellpadding="0" align="center">
1159 -<tbody>
1160 -<tr valign="top">
1161 -<td style="max-width:22px;"></td>
1162 -<td style="font-family: Arial, Helvetica, sans-serif; padding: 0px 30px 10px; max-width: 645px;">
1163 -<table style="width: 100%; table-layout: fixed;">
1164 -<tbody>
1165 -<tr>
1166 -<td>' . __('On', 'contact-forms') . ' {__submitted_day_month_year} ' . __('at', 'contact-forms') . ' {__submitted_hour} ' . __('the following form was filled in.', 'contact-forms') . '
1167 -
1168 -<hr />
1169 -
1170 -<strong>' . __('Page where the form was filled in', 'contact-forms') . '</strong>
1171 -<a href="{__url}" style="word-break: break-all; overflow-wrap: break-word;">{__url}</a></td>
1172 -</tr>
1173 -<tr><td>
1174 -<strong>' . __('Submission review page', 'contact-forms') . '</strong>
1175 -<a href="{__review_submission_url}" style="word-break: break-all; overflow-wrap: break-word;">{__review_submission_url}</a>
1176 -</td></tr>
1177 -<tr>
1178 -<td id="submitted_html" style="overflow-wrap: break-word; word-break: normal;">{__submitted_html}</td>
1179 -</tr>
1180 -<tr>
1181 -<td>[form_if {__referrer} [<strong>' . __('Referrer', 'contact-forms') . '</strong> - ' . __('where the visitor came from', 'contact-forms') . ' <em>' . __('before reaching the page', 'contact-forms') . '</em>:<br /><span style="word-break: break-all; overflow-wrap: break-word;">{__referrer}</span>]]</td>
1182 -</tr>
1183 -<tr>
1184 -<td><strong>' . __('Contact IP', 'contact-forms') . '</strong> {__anonymized_ip}
1185 -<hr />
1186 -</td>
1187 -</tr>
1188 -<tr>
1189 -<td>[form_if {__autoreply} [' . __('A confirmation email was sent to', 'contact-forms') . ' <a href="mailto:{email}">{email}</a> ' . __('with the following message', 'contact-forms') . ':
1190 -<table>
1191 -<tbody>
1192 -<tr>
1193 -<td>{__confirmation_emails_message}</td>
1194 -</tr>
1195 -</tbody>
1196 -</table> ]]
1197 -</td>
1198 -</tr>
1199 -</tbody>
1200 -</table>
1201 -</td>
1202 -<td style="max-width:23px"></td>
1203 -</tr>
1204 -</tbody>
1205 -</table>
1206 -</td>
1207 -</tr>
1208 -</tbody>
1209 -</table>
1210 -</td>
1211 -</tr>
1212 -</tbody>
1213 -</table>',
1214 - 'confirmation_emails_subject' => __('Your message', 'contact-forms'),
1215 - 'confirmation_emails_message' => '<div style="font-family: Arial, Helvetica, sans-serif;">
1216 -
1217 -<h2>' . __('Thank you', 'contact-forms') . ' {first_name} {last_name},</h2>
1218 -' . __('Thank you for your contact request.', 'contact-forms') . '
1219 -
1220 -' . __('We will contact you as soon as possible.', 'contact-forms') . '
1221 -
1222 -' . __('Sincerely,', 'contact-forms') . '
1223 -
1224 -' . __('The Website Team', 'contact-forms') . '
1225 -
1226 -<hr />
1227 -</div>',
1228 -
1229 - 'layout' => 'sidebyside',
1230 - 'style_margin' => '',
1231 - 'style_border_color' => '',
1232 - 'style_border_width' => '',
1233 - 'style_border_radius' => '',
1234 - 'style_background_color' => '',
1235 - 'style_padding' => '',
1236 - 'style_color' => '',
1237 - 'style_font_size' => '',
1238 - 'style_field_spacing' => '',
1239 - 'style_field_border_color' => '',
1240 - 'style_field_border_width' => '',
1241 - 'style_field_border_radius' => '',
1242 - 'style_field_background_color' => '',
1243 - 'style_field_padding' => '',
1244 - 'style_field_color' => '',
1245 - 'style_submit_border_color' => '',
1246 - 'style_submit_border_width' => '',
1247 - 'style_submit_border_radius' => '',
1248 - 'style_submit_background_color' => '',
1249 - 'style_submit_padding' => '',
1250 - 'style_submit_color' => '',
1251 - 'style_submit_font_size' => '',
1252 - );
1253 -}
1254 -
1255 -/**
1256 - * Get all countries with localized names for phone field country selector.
1257 - *
1258 - * Uses PHP Intl extension to generate localized country names from ISO 3166-1 alpha-2 codes.
1259 - * Falls back to country codes if Intl extension is unavailable.
1260 - *
1261 - * @since 2.0.0-beta.34
1262 - * @param string|null $display_locale Locale for display names (default: current WordPress locale).
1263 - * @return array Associative array ['US' => 'United States', 'IT' => 'Italy', ...] sorted alphabetically.
1264 - */
1265 -function accua_forms_get_countries( $display_locale = null ) {
1266 - // ISO 3166-1 alpha-2 codes - complete list (249 countries/territories)
1267 - $country_codes = array(
1268 - 'AF', 'AX', 'AL', 'DZ', 'AS', 'AD', 'AO', 'AI', 'AQ', 'AG', 'AR', 'AM', 'AW', 'AU', 'AT', 'AZ',
1269 - 'BS', 'BH', 'BD', 'BB', 'BY', 'BE', 'BZ', 'BJ', 'BM', 'BT', 'BO', 'BQ', 'BA', 'BW', 'BV', 'BR',
1270 - 'IO', 'BN', 'BG', 'BF', 'BI', 'KH', 'CM', 'CA', 'CV', 'KY', 'CF', 'TD', 'CL', 'CN', 'CX', 'CC',
1271 - 'CO', 'KM', 'CG', 'CD', 'CK', 'CR', 'CI', 'HR', 'CU', 'CW', 'CY', 'CZ', 'DK', 'DJ', 'DM', 'DO',
1272 - 'EC', 'EG', 'SV', 'GQ', 'ER', 'EE', 'ET', 'FK', 'FO', 'FJ', 'FI', 'FR', 'GF', 'PF', 'TF', 'GA',
1273 - 'GM', 'GE', 'DE', 'GH', 'GI', 'GR', 'GL', 'GD', 'GP', 'GU', 'GT', 'GG', 'GN', 'GW', 'GY', 'HT',
1274 - 'HM', 'VA', 'HN', 'HK', 'HU', 'IS', 'IN', 'ID', 'IR', 'IQ', 'IE', 'IM', 'IL', 'IT', 'JM', 'JP',
1275 - 'JE', 'JO', 'KZ', 'KE', 'KI', 'KP', 'KR', 'KW', 'KG', 'LA', 'LV', 'LB', 'LS', 'LR', 'LY', 'LI',
1276 - 'LT', 'LU', 'MO', 'MK', 'MG', 'MW', 'MY', 'MV', 'ML', 'MT', 'MH', 'MQ', 'MR', 'MU', 'YT', 'MX',
1277 - 'FM', 'MD', 'MC', 'MN', 'ME', 'MS', 'MA', 'MZ', 'MM', 'NA', 'NR', 'NP', 'NL', 'NC', 'NZ', 'NI',
1278 - 'NE', 'NG', 'NU', 'NF', 'MP', 'NO', 'OM', 'PK', 'PW', 'PS', 'PA', 'PG', 'PY', 'PE', 'PH', 'PN',
1279 - 'PL', 'PT', 'PR', 'QA', 'RE', 'RO', 'RU', 'RW', 'BL', 'SH', 'KN', 'LC', 'MF', 'PM', 'VC', 'WS',
1280 - 'SM', 'ST', 'SA', 'SN', 'RS', 'SC', 'SL', 'SG', 'SX', 'SK', 'SI', 'SB', 'SO', 'ZA', 'GS', 'SS',
1281 - 'ES', 'LK', 'SD', 'SR', 'SJ', 'SZ', 'SE', 'CH', 'SY', 'TW', 'TJ', 'TZ', 'TH', 'TL', 'TG', 'TK',
1282 - 'TO', 'TT', 'TN', 'TR', 'TM', 'TC', 'TV', 'UG', 'UA', 'AE', 'GB', 'US', 'UM', 'UY', 'UZ', 'VU',
1283 - 'VE', 'VN', 'VG', 'VI', 'WF', 'EH', 'YE', 'ZM', 'ZW',
1284 - );
1285 -
1286 - // Use WordPress locale if not specified
1287 - if ( null === $display_locale ) {
1288 - $display_locale = get_locale();
1289 - }
1290 -
1291 - // Check if Intl extension is available
1292 - if ( ! class_exists( 'Locale' ) ) {
1293 - // Fallback: return codes as both key and value
1294 - return array_combine( $country_codes, $country_codes );
1295 - }
1296 -
1297 - $countries = array();
1298 - foreach ( $country_codes as $code ) {
1299 - // The trick: prepend '-' to convert region code to locale format
1300 - $name = Locale::getDisplayRegion( '-' . $code, $display_locale );
1301 - // If Intl returns the code itself (unknown region), use the code
1302 - $countries[ $code ] = ( $name && $name !== $code ) ? $name : $code;
1303 - }
1304 -
1305 - // Sort alphabetically by localized name
1306 - asort( $countries, SORT_LOCALE_STRING );
1307 -
1308 - return $countries;
1309 -}
1310 -
1311 -/**
1312 - * Get the translated label for a layout value.
1313 - *
1314 - * Returns the human-readable, translated label for a given layout value.
1315 - * Used in layout dropdowns throughout the admin interface.
1316 - *
1317 - * @since 2.0.0-beta.29
1318 - * @param string $layout Layout value: 'sidebyside', 'toplabel', or 'inlinelabel'.
1319 - * @return string Translated layout label.
1320 - */
1321 -function accua_forms_get_layout_label( $layout ) {
1322 - switch ( $layout ) {
1323 - case 'toplabel':
1324 - return __( 'Labels on top of the fields', 'contact-forms' );
1325 - case 'inlinelabel':
1326 - return __( 'Inline labels', 'contact-forms' );
1327 - case 'sidebyside':
1328 - default:
1329 - return __( 'Labels on the left of the fields', 'contact-forms' );
1330 - }
1331 -}
1 +<?php
2 +/*
3 +Plugin Name: WordPress Contact Forms by Cimatti
4 +Description: Quickly create and publish forms in your WordPress powered website.
5 +Version: 1.9.2
6 +Plugin URI: https://www.cimatti.it/wordpress/contact-forms/
7 +Author: Cimatti Consulting
8 +Author URI: https://www.cimatti.it
9 +Text Domain: contact-forms
10 +Domain Path: /languages
11 +Requires at least: 3.5
12 +License: GPLv2 or later
13 +License URI: http://www.gnu.org/licenses/gpl-2.0.html
14 +*/
15 +
16 +/*
17 +WordPress Contact Forms by Cimatti
18 +Copyright (c) 2011-2024 Andrea Cimatti
19 +
20 +This program is free software; you can redistribute it and/or
21 +modify it under the terms of the GNU General Public License
22 +as published by the Free Software Foundation; either version 2
23 +of the License, or (at your option) any later version.
24 +
25 +This program is distributed in the hope that it will be useful,
26 +but WITHOUT ANY WARRANTY; without even the implied warranty of
27 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 +GNU General Public License for more details.
29 +
30 +You should have received a copy of the GNU General Public License
31 +along with this program; if not, write to the Free Software
32 +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
33 +
34 +
35 +The full copy of the GNU General Public License is available here: http://www.gnu.org/licenses/gpl.txt
36 +
37 +*/
38 +
39 +define('ACCUA_FORMS_DB_VERSION', '12');
40 +define('ACCUA_FORMS_CSS_VERSION', '53');
41 +define('ACCUA_FORMS_JS_VERSION', '9');
42 +define('ACCUA_FORMS_FILE', __FILE__);
43 +define('ACCUA_FORMS_DIR_URL', plugin_dir_url( ACCUA_FORMS_FILE ));
44 +define('ACCUA_FORMS_DIR', dirname( ACCUA_FORMS_FILE ));
45 +
46 +require_once('accua-form-api.php');
47 +require_once('accua-forms.php');
48 +require_once('accua-shortcode-button.php');
49 +
50 +function accua_forms_dashboard_page_head(){
51 + $screen = get_current_screen();
52 + $screen->add_help_tab( array(
53 + 'id' => 'accua_help_tab',
54 + 'title' => __('Contact Forms Dashboard'),
55 + 'content' => '<p>' . __( 'Marketing tools for WordPress', 'contact-forms') . '</p>',
56 + ) );
57 +
58 + //wp_enqueue_script('accua', plugins_url('/flot/jquery.flot.js', ACCUA_FORMS_FILE ), array( 'jquery' ));
59 + wp_enqueue_script('accua_chart_js', plugins_url('/chartjs/Chart.min.js', ACCUA_FORMS_FILE ), array( 'jquery' ), ACCUA_FORMS_JS_VERSION);
60 + //wp_enqueue_style('accua_flot', plugins_url('/flot/layout.css', ACCUA_FORMS_FILE ));
61 + wp_enqueue_style('accua', plugins_url('accua.css', ACCUA_FORMS_FILE ), array(), ACCUA_FORMS_CSS_VERSION);
62 +
63 + /* Tentativo x drag and drop
64 + $page_hook_id = fx_smb_setings_page_id();
65 + /* Load the JavaScript needed for the settings screen. * /
66 + add_action( 'admin_enqueue_scripts', 'fx_smb_enqueue_scripts' );
67 + add_action( "admin_footer-{$page_hook_id}", 'fx_smb_footer_scripts' );
68 +
69 + /* Set number of column available. * /
70 + add_filter( 'screen_layout_columns', 'fx_smb_screen_layout_column', 10, 2 );
71 + */
72 +}
73 +
74 +/* COSA CARINA PER AGGIUNGERE WIDGET NELLA DASHBOARD DI WP
75 +todo: posso scegliere la sua posizione di default?
76 +*/
77 +add_action( 'wp_dashboard_setup', 'accua_contact_forms_dashboard_add_widgets' );
78 +function accua_contact_forms_dashboard_add_widgets() {
79 + wp_add_dashboard_widget( 'accua_contact_forms_dashboard_widget_news', __( 'Contact Forms', 'contact-forms' ), 'accua_contact_forms_dashboard_widget_news_handler' );
80 +}
81 +
82 +function accua_contact_forms_dashboard_widget_news_handler() {
83 + global $wpdb; ?>
84 + <table>
85 + <tr class="first">
86 + <?php $forms_data = get_option('accua_forms_saved_forms', array());
87 + $active_forms = count($forms_data); ?>
88 + <td class="first b"><?php echo $active_forms; ?></td><td class="t"><?php _e('Active forms', 'contact-forms'); ?></td>
89 + </tr>
90 + <tr class="first">
91 + <?php $pages = $wpdb->get_var("SELECT COUNT(DISTINCT afs_uri) FROM `{$wpdb->prefix}accua_forms_submissions`"); ?>
92 + <td class="first b"><?php echo $pages; ?></td><td class="t"><?php _e('Pages', 'contact-forms'); ?></td>
93 + </tr>
94 + <tr class="first">
95 + <?php $active_submissions = $wpdb->get_var("SELECT COUNT(*) FROM `{$wpdb->prefix}accua_forms_submissions` WHERE afs_status >= 0"); ?>
96 + <td class="first b"><?php echo $active_submissions; ?></td><td class="t"><?php _e('Submissions', 'contact-forms'); ?></td>
97 + </tr>
98 + <tr class="first">
99 + <?php $emails = $wpdb->get_var("SELECT COUNT(DISTINCT afsv_value) FROM `{$wpdb->prefix}accua_forms_submissions_values` WHERE afsv_type LIKE 'autoreply_email'"); ?>
100 + <td class="first b"><?php echo $emails; ?></td><td class="t"><?php _e('Distinct Emails', 'contact-forms'); ?></td>
101 + </tr>
102 + </table>
103 + <br />
104 + <span id="accua-forms-version"><a href="https://www.cimatti.it/wordpress/contact-forms/"><?php
105 + $plugin_data = get_plugin_data( ACCUA_FORMS_FILE );
106 + _e('Version', 'contact-forms'); echo " ".$plugin_data['Version']; ?></a> | <a href="admin.php?page=accua_forms" title="Contact Forms Dashboard"><?php _e('Dashboard', 'contact-forms'); ?></a>
107 + </span>
108 +
109 + <?php
110 +}
111 +
112 +function accua_forms_dashboard_page(){
113 + require_once ACCUA_FORMS_DIR.'/accua-forms-dashboard.php';
114 + return _accua_forms_dashboard_page();
115 +}
116 +
117 +
118 +register_activation_hook(ACCUA_FORMS_FILE, 'accua_forms_install');
119 +function accua_forms_install(){
120 + load_plugin_textdomain( 'contact-forms', false, ACCUA_FORM_API_PLUGIN_TEXTDOMAIN_PATH);
121 + $modified = false;
122 + $keys = get_option('accua_form_api_keys', array());
123 + if (!isset($keys['hash'])) {
124 + $modified = true;
125 + $keys['hash'] = wp_generate_password(64,true,true);
126 + }
127 + if (!isset($keys['aes'])) {
128 + $modified = true;
129 + $keys['aes'] = wp_generate_password(64,true,true);
130 + }
131 + if ($modified) {
132 + update_option('accua_form_api_keys', $keys);
133 + }
134 +
135 + global $wpdb;
136 +
137 + require_once(ABSPATH.'wp-admin/includes/upgrade.php');
138 +
139 + $charset_collate = '';
140 + if ( ! empty($wpdb->charset) )
141 + $charset_collate = "DEFAULT CHARACTER SET $wpdb->charset";
142 + if ( ! empty($wpdb->collate) )
143 + $charset_collate .= " COLLATE $wpdb->collate";
144 +
145 + $old_db_version = (int) get_option('accua_forms_db_version', 0);
146 +
147 + if ($old_db_version < 3) {
148 + $wpdb_suppress_errors_status = $wpdb->suppress_errors();
149 + $wpdb->query("ALTER TABLE `{$wpdb->prefix}accua_forms_submissions` DROP INDEX uri");
150 + $wpdb->query("ALTER TABLE `{$wpdb->prefix}accua_forms_submissions` DROP INDEX referrer");
151 + $wpdb->suppress_errors($wpdb_suppress_errors_status);
152 + }
153 +
154 + $sql = "CREATE TABLE `{$wpdb->prefix}accua_forms_submissions` (
155 + afs_id BIGINT(20) NOT NULL AUTO_INCREMENT,
156 + afs_form_id VARCHAR(77) NOT NULL DEFAULT '',
157 + afs_post_id BIGINT(20) NOT NULL DEFAULT 0,
158 + afs_ip VARCHAR(255) NOT NULL DEFAULT '',
159 + afs_uri TEXT NOT NULL DEFAULT '',
160 + afs_referrer TEXT NOT NULL DEFAULT '',
161 + afs_lang VARCHAR(60) NOT NULL DEFAULT '',
162 + afs_created TIMESTAMP NOT NULL DEFAULT 0,
163 + afs_submitted TIMESTAMP NOT NULL DEFAULT 0,
164 + afs_status TINYINT(1) NOT NULL DEFAULT 0,
165 + afs_stats TEXT NOT NULL DEFAULT '',
166 + afs_lead_status TINYINT(1) NOT NULL DEFAULT 0,
167 + PRIMARY KEY (afs_id),
168 + KEY form (afs_form_id, afs_status),
169 + KEY uri (afs_uri(190)),
170 + KEY pid (afs_post_id),
171 + KEY referrer (afs_referrer(190)),
172 + KEY status (afs_status, afs_id),
173 + KEY submitted (afs_submitted),
174 + KEY lead_status (afs_lead_status, afs_status)
175 + ) $charset_collate;";
176 + dbDelta($sql);
177 +
178 + $sql = "CREATE TABLE `{$wpdb->prefix}accua_forms_submissions_values` (
179 + afsv_sub_id BIGINT(20) NOT NULL,
180 + afsv_field_id VARCHAR(77) NOT NULL,
181 + afsv_type varchar(255) NOT NULL DEFAULT '',
182 + afsv_value TEXT NOT NULL DEFAULT '',
183 + PRIMARY KEY (afsv_sub_id, afsv_field_id),
184 + KEY value_index (afsv_field_id(77), afsv_value(114))
185 + ) $charset_collate;";
186 + dbDelta($sql);
187 +
188 + /* creazione tabella per le note dell'utente
189 + sono relative a una compilazione
190 + possono esserci più note per ogni compilazione in date diverse
191 +
192 + */
193 + $sql = "CREATE TABLE `{$wpdb->prefix}accua_forms_submissions_notes` (
194 + afsn_sub_id BIGINT(20) NOT NULL,
195 + afsn_date TIMESTAMP NOT NULL DEFAULT 0,
196 + afsn_text TEXT NOT NULL DEFAULT '',
197 + afsn_user VARCHAR(100) NOT NULL DEFAULT '',
198 + PRIMARY KEY (afsn_sub_id, afsn_date),
199 + KEY afsn_sub_id (afsn_sub_id)
200 + ) $charset_collate;";
201 + dbDelta($sql);
202 +
203 +
204 + $avail_fields = get_option('accua_forms_avail_fields', array());
205 +
206 + if (!is_array($avail_fields)) {
207 + $avail_fields = array();
208 + }
209 +
210 + if (empty($avail_fields) || ($old_db_version === 0)) {
211 + $avail_fields += array(
212 + 'first_name' => array(
213 + 'id' => 'first_name',
214 + 'name' => 'First Name',
215 + 'type' => 'textfield',
216 + 'description' => '',
217 + 'default_value' => '',
218 + 'allowed_values' => '',
219 + ),
220 + 'last_name' => array(
221 + 'id' => 'last_name',
222 + 'name' => 'Last Name',
223 + 'type' => 'textfield',
224 + 'description' => '',
225 + 'default_value' => '',
226 + 'allowed_values' => '',
227 + ),
228 + 'email' => array(
229 + 'id' => 'email',
230 + 'name' => 'Email',
231 + 'type' => 'autoreply_email',
232 + 'description' => '',
233 + 'default_value' => '',
234 + 'allowed_values' => '',
235 + ),
236 + 'address' => array(
237 + 'id' => 'address',
238 + 'name' => 'Address',
239 + 'type' => 'textfield',
240 + 'description' => '',
241 + 'default_value' => '',
242 + 'allowed_values' => '',
243 + ),
244 + 'city' => array(
245 + 'id' => 'city',
246 + 'name' => 'City',
247 + 'type' => 'textfield',
248 + 'description' => '',
249 + 'default_value' => '',
250 + 'allowed_values' => '',
251 + ),
252 + 'state_province' => array(
253 + 'id' => 'state_province',
254 + 'name' => 'State/Province',
255 + 'type' => 'textfield',
256 + 'description' => '',
257 + 'default_value' => '',
258 + 'allowed_values' => '',
259 + ),
260 + 'country' => array(
261 + 'id' => 'country',
262 + 'name' => 'Country',
263 + 'type' => 'select',
264 + 'description' => '',
265 + 'default_value' => '-',
266 + 'allowed_values' => "-|Select...
267 +Afghanistan
268 +Ã…land Islands
269 +Albania
270 +Algeria
271 +American Samoa
272 +Andorra
273 +Angola
274 +Anguilla
275 +Antarctica
276 +Antigua And Barbuda
277 +Argentina
278 +Armenia
279 +Aruba
280 +Australia
281 +Austria
282 +Azerbaijan
283 +Bahamas
284 +Bahrain
285 +Bangladesh
286 +Barbados
287 +Belarus
288 +Belgium
289 +Belize
290 +Benin
291 +Bermuda
292 +Bhutan
293 +Bolivia
294 +Bosnia And Herzegovina
295 +Botswana
296 +Bouvet Island
297 +Brazil
298 +British Indian Ocean Territory
299 +Brunei Darussalam
300 +Bulgaria
301 +Burkina Faso
302 +Burundi
303 +Cambodia
304 +Cameroon
305 +Canada
306 +Cape Verde
307 +Cayman Islands
308 +Central African Republic
309 +Chad
310 +Chile
311 +China
312 +Christmas Island
313 +Cocos (Keeling) Islands
314 +Colombia
315 +Comoros
316 +Congo
317 +Congo, The Democratic Republic Of The
318 +Cook Islands
319 +Costa Rica
320 +Côte D'Ivoire
321 +Croatia
322 +Cuba
323 +Cyprus
324 +Czech Republic
325 +Denmark
326 +Djibouti
327 +Dominica
328 +Dominican Republic
329 +Ecuador
330 +Egypt
331 +El Salvador
332 +Equatorial Guinea
333 +Eritrea
334 +Estonia
335 +Ethiopia
336 +Falkland Islands (Malvinas)
337 +Faroe Islands
338 +Fiji
339 +Finland
340 +France
341 +French Guiana
342 +French Polynesia
343 +French Southern Territories
344 +Gabon
345 +Gambia
346 +Georgia
347 +Germany
348 +Ghana
349 +Gibraltar
350 +Greece
351 +Greenland
352 +Grenada
353 +Guadeloupe
354 +Guam
355 +Guatemala
356 +Guernsey
357 +Guinea
358 +Guinea-Bissau
359 +Guyana
360 +Haiti
361 +Heard Island And Mcdonald Islands
362 +Holy See (Vatican City State)
363 +Honduras
364 +Hong Kong
365 +Hungary
366 +Iceland
367 +India
368 +Indonesia
369 +Iran, Islamic Republic Of
370 +Iraq
371 +Ireland
372 +Isle Of Man
373 +Israel
374 +Italy
375 +Jamaica
376 +Japan
377 +Jersey
378 +Jordan
379 +Kazakhstan
380 +Kenya
381 +Kiribati
382 +Korea, Democratic People'S Republic Of
383 +Korea, Republic Of
384 +Kuwait
385 +Kyrgyzstan
386 +Lao People'S Democratic Republic
387 +Latvia
388 +Lebanon
389 +Lesotho
390 +Liberia
391 +Libyan Arab Jamahiriya
392 +Liechtenstein
393 +Lithuania
394 +Luxembourg
395 +Macao
396 +Macedonia, The Former Yugoslav Republic Of
397 +Madagascar
398 +Malawi
399 +Malaysia
400 +Maldives
401 +Mali
402 +Malta
403 +Marshall Islands
404 +Martinique
405 +Mauritania
406 +Mauritius
407 +Mayotte
408 +Mexico
409 +Micronesia, Federated States Of
410 +Moldova, Republic Of
411 +Monaco
412 +Mongolia
413 +Montenegro
414 +Montserrat
415 +Morocco
416 +Mozambique
417 +Myanmar
418 +Namibia
419 +Nauru
420 +Nepal
421 +Netherlands
422 +Netherlands Antilles
423 +New Caledonia
424 +New Zealand
425 +Nicaragua
426 +Niger
427 +Nigeria
428 +Niue
429 +Norfolk Island
430 +Northern Mariana Islands
431 +Norway
432 +Oman
433 +Pakistan
434 +Palau
435 +Palestinian Territory, Occupied
436 +Panama
437 +Papua New Guinea
438 +Paraguay
439 +Peru
440 +Philippines
441 +Pitcairn
442 +Poland
443 +Portugal
444 +Puerto Rico
445 +Qatar
446 +Réunion
447 +Romania
448 +Russian Federation
449 +Rwanda
450 +Saint Barthélemy
451 +Saint Helena
452 +Saint Kitts And Nevis
453 +Saint Lucia
454 +Saint Martin
455 +Saint Pierre And Miquelon
456 +Saint Vincent And The Grenadines
457 +Samoa
458 +San Marino
459 +Sao Tome And Principe
460 +Saudi Arabia
461 +Senegal
462 +Serbia
463 +Seychelles
464 +Sierra Leone
465 +Singapore
466 +Slovakia
467 +Slovenia
468 +Solomon Islands
469 +Somalia
470 +South Africa
471 +South Georgia And The South Sandwich Islands
472 +Spain
473 +Sri Lanka
474 +Sudan
475 +Suriname
476 +Svalbard And Jan Mayen
477 +Swaziland
478 +Sweden
479 +Switzerland
480 +Syrian Arab Republic
481 +Taiwan, Province Of China
482 +Tajikistan
483 +Tanzania, United Republic Of
484 +Thailand
485 +Timor-Leste
486 +Togo
487 +Tokelau
488 +Tonga
489 +Trinidad And Tobago
490 +Tunisia
491 +Turkey
492 +Turkmenistan
493 +Turks And Caicos Islands
494 +Tuvalu
495 +Uganda
496 +Ukraine
497 +United Arab Emirates
498 +United Kingdom
499 +United States
500 +United States Minor Outlying Islands
501 +Uruguay
502 +Uzbekistan
503 +Vanuatu
504 +Venezuela, Bolivarian Republic Of
505 +Viet Nam
506 +Virgin Islands, British
507 +Virgin Islands, U.S.
508 +Wallis And Futuna
509 +Western Sahara
510 +Yemen
511 +Zambia
512 +Zimbabwe",
513 + ),
514 + 'message' => array(
515 + 'id' => 'message',
516 + 'name' => 'Message',
517 + 'type' => 'textarea',
518 + 'description' => '',
519 + 'default_value' => '',
520 + 'allowed_values' => '',
521 + ),
522 + 'captcha' => array(
523 + 'id' => 'captcha',
524 + 'name' => 'Captcha',
525 + 'type' => 'captcha',
526 + 'description' => '',
527 + 'default_value' => '',
528 + 'allowed_values' => '',
529 + ),
530 + );
531 + update_option('accua_forms_avail_fields', $avail_fields);
532 + }
533 +
534 + $form_data = get_option('accua_forms_default_form_data',array());
535 + if (!is_array($form_data)) {
536 + $form_data = array();
537 + }
538 +
539 + $form_data += array(
540 + 'success_message' => '<div style="padding: 0px 30px 10px; background-color: #f4f4f4; border: 1px solid #ddd;">
541 +<h2>Thank you {first_name} {last_name},</h2>
542 +We have received your contact request. Check your inbox for the confirmation message.
543 +
544 +<strong>Can\'t find the email?</strong>
545 +
546 +It doesn\'t happen often but your mailbox could apply strict spam rules that block our email from reaching your inbox. Try checking your spam folder.
547 +
548 +Also check that the email you entered in the form (<strong>{email}</strong>) is correct. If it is not exact you can submit the form again.
549 +
550 +For other possible problems you may have encountered do not hesitate to contact us
551 +
552 +</div>',
553 + 'error_message' => '<div style="padding: 0px 30px 10px; background-color: #f4f4f4; border: 1px solid #ddd;">
554 +<h2>Oops! Something went wrong.</h2>
555 +Internet is an awfully complex place and even though we take every precaution to make sure things run smoothly every once in a while things can go wrong that are not under our control.
556 +
557 +Please try filling in the form again.
558 +
559 +For other possible problems you may have encountered do not hesitate to contact us
560 +
561 +</div>',
562 + 'emails_from_name' => '',
563 + 'emails_from' => '',
564 + 'admin_emails_to' => get_option('admin_email', ''),
565 + 'emails_bcc' => '',
566 + 'admin_emails_subject' => 'A contact from your site',
567 + 'admin_emails_message' => '<table style="font-family: \'Lucida Sans\',\'Lucida Grande\', Verdana, Arial, Sans-Serif !important; background: #fff; margin-top: 10px; border: 1px solid #DDDDDD; max-width: 700px;" cellspacing="0" cellpadding="0" align="center">
568 +<tbody>
569 +<tr>
570 +<td>
571 +<table style="max-width:700px;" border="0" cellspacing="0" cellpadding="0" align="center">
572 +<tbody>
573 +<tr>
574 +<td>
575 +<table style="padding: 10px; background-color: #f4f4f4; border: 1px solid #ddd; max-width:700px;" border="0" cellspacing="0" cellpadding="0" align="center" bgcolor="#FFFFFF">
576 +<tbody>
577 +<tr valign="top">
578 +<td style="max-width:22px;"></td>
579 +<td style="font-family: \'Lucida Sans\',\'Lucida Grande\', Verdana, Arial, Sans-Serif !important; padding: 0px 30px 10px; max-width: 645px;">
580 +<table>
581 +<tbody>
582 +<tr>
583 +<td>On {__submitted_day_month_year} at {__submitted_hour} the following form was filled in.
584 +
585 +<hr />
586 +
587 +<strong>Page where the form was filled in</strong>
588 +<a href="{__url}">{__url}</a></td>
589 +</tr>
590 +<tr><td>
591 +<strong>Submission review page</strong>
592 +<a href="{__review_submission_url}">{__review_submission_url}</a>
593 +</td></tr>
594 +<tr>
595 +<td id="submitted_html">{__submitted_html}</td>
596 +</tr>
597 +<tr>
598 +<td>[form_if {__referrer} [<strong>Referrer</strong> - where did the contact come from <em>before reaching the page</em>: {__referrer}]]</td>
599 +</tr>
600 +<tr>
601 +<td><strong>Contact IP</strong> {__anonymized_ip}
602 +<hr />
603 +</td>
604 +</tr>
605 +<tr>
606 +<td>[form_if {__autoreply} [The contact received in his email <a href="mailto:{email}">{email}</a> the following confirmation message:
607 +<table>
608 +<tbody>
609 +<tr>
610 +<td>{__confirmation_emails_message}</td>
611 +</tr>
612 +</tbody>
613 +</table> ]]
614 +</td>
615 +</tr>
616 +</tbody>
617 +</table>
618 +</td>
619 +<td style="max-width:23px"></td>
620 +</tr>
621 +</tbody>
622 +</table>
623 +</td>
624 +</tr>
625 +</tbody>
626 +</table>
627 +</td>
628 +</tr>
629 +</tbody>
630 +</table>',
631 + 'confirmation_emails_subject' => 'Your message',
632 + 'confirmation_emails_message' => '<div>
633 +
634 +<h2>Thank you {first_name} {last_name},</h2>
635 +Thank Your for your contact request.
636 +
637 +We will contact you as soon as possible.
638 +
639 +Sincerely,
640 +
641 +The Website Team
642 +
643 +<hr />
644 +</div>',
645 +
646 + 'layout' => 'sidebyside',
647 + 'style_margin' => '',
648 + 'style_border_color' => '',
649 + 'style_border_width' => '',
650 + 'style_border_radius' => '',
651 + 'style_background_color' => '',
652 + 'style_padding' => '',
653 + 'style_color' => '',
654 + 'style_font_size' => '',
655 + 'style_field_spacing' => '',
656 + 'style_field_border_color' => '',
657 + 'style_field_border_width' => '',
658 + 'style_field_border_radius' => '',
659 + 'style_field_background_color' => '',
660 + 'style_field_padding' => '',
661 + 'style_field_color' => '',
662 + 'style_submit_border_color' => '',
663 + 'style_submit_border_width' => '',
664 + 'style_submit_border_radius' => '',
665 + 'style_submit_background_color' => '',
666 + 'style_submit_padding' => '',
667 + 'style_submit_color' => '',
668 + 'style_submit_font_size' => '',
669 + );
670 +
671 + update_option('accua_forms_default_form_data', $form_data);
672 + update_option('accua_forms_db_version', ACCUA_FORMS_DB_VERSION);
673 +}
674 +
675 +add_action('plugins_loaded', 'accua_forms_check_db_version_and_update', 9);
676 +function accua_forms_check_db_version_and_update() {
677 + $db_version = get_option('accua_forms_db_version', '');
678 + if (ACCUA_FORMS_DB_VERSION != $db_version) {
679 + accua_forms_install();
680 + }
681 +}
682 +
683 +add_filter( 'robots_txt', 'accua_forms_robots_txt', 10, 2);
684 +function accua_forms_robots_txt($output, $public) {
685 + if ($public) {
686 + $site_url = parse_url( site_url() );
687 + $path = ( !empty( $site_url['path'] ) ) ? $site_url['path'] : '';
688 + $output .= "\nUser-agent: *\n";
689 + $output .= "Allow: $path/wp-admin/js/\n";
690 + $output .= "Allow: $path/wp-admin/css/\n";
691 + }
692 + return $output;
693 +}
694 +
695 +function _accua_forms_json_encode($item) {
696 + static $version = NULL;
697 + if ($version === NULL) {
698 + $version = version_compare(PHP_VERSION, '5.3.0', '>=');
699 + }
700 + if ($version) {
701 + return json_encode($item, JSON_HEX_TAG|JSON_HEX_APOS|JSON_HEX_QUOT|JSON_HEX_AMP);
702 + } else {
703 + return strtr(json_encode($item),
704 + array(
705 + '&' => '\\u0026',
706 + '<' => '\\u003C',
707 + '>' => '\\u003E',
708 + ));
709 + }
710 +}
711 +