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

changelog.txt in Contact Forms by Cimatti 2.2.32, at changelog.txt

891 lines 67.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 == Changelog ==
2
3 = 2.2.32 =
4 * Security: the WordPress dashboard widget is now restricted to users with the `manage_options` capability, the same capability required by all plugin admin pages. Previously it was registered for anyone with `edit_posts` (editors, authors and contributors as well as administrators), exposing submission statistics to roles that cannot access the plugin. The render callback also returns silently when the capability check fails instead of calling `wp_die()`, which killed the whole dashboard page.
5 * Performance: the widget statistics (active forms, pages, submissions, distinct emails) are now computed by the new `accua_contact_forms_dashboard_get_stats()` helper and cached in the `accua_forms_dashboard_stats` transient for 5 minutes, so repeat dashboard loads run zero COUNT queries against the submissions tables (the distinct-emails COUNT scanned the whole `accua_forms_submissions_values` table on every dashboard load). A short TTL was chosen over invalidation hooks because submissions are written, trashed, restored and anonymized from several independent code paths. `get_plugin_data()` is now called with `$markup = false, $translate = false`, skipping markup filtering and header translation on each render.
6 * Coding conventions in the widget: `afsv_type LIKE 'autoreply_email'` replaced with `=` (no wildcard was involved), counts cast to int and displayed through `number_format_i18n()`, the Dashboard link built with `admin_url()` and escaped with `esc_url()` instead of a hardcoded relative `admin.php?page=...` URL, redundant untranslated `title` attribute removed, data fetching moved out of the table markup. The widget id (`accua_contact_forms_dashboard_widget_news`) and function names are unchanged so existing screen-option preferences and any `remove_action()` calls keep working.
7 * Code organization: the widget code (stats helper and render callback) moved from `contact-forms.php` to the new `admin/dashboard-widget.php`, included on demand from the `wp_dashboard_setup` callback after the capability check. Since `wp_dashboard_setup` only fires on the dashboard screen, the widget code is never loaded on the frontend, on other admin pages, or for users who cannot see the widget. Only the registration hook remains in the main plugin file.
8
9 = 2.2.31 =
10 * Fix: the sidebar admin menu icon no longer briefly flashes the brand blue (#15caff) before WordPress recolors it grey on load. `add_menu_page()` shipped the icon as a base64 SVG with the brand fill baked in; WordPress core `wp-admin/js/svg-painter.js` repaints admin-menu SVG icons to the active color scheme's icon color only after JavaScript runs, so the first server paint showed blue and the repaint caused a visible flash. The icon is now rendered server-side in the scheme's base icon color, so the first paint already matches svg-painter's result and there is no flash. Because color schemes register on `admin_init` (after `admin_menu`), the exact color is applied in an `admin_init` (priority 20) pass that rewrites the icon in the `$menu` global: `accua_forms_paint_menu_icon()` calls `accua_forms_admin_menu_icon()` / `accua_forms_admin_menu_icon_color()`, which resolve per active scheme (Default/modern -> #f3f1f1, Classic/fresh -> #a7aaad) and fall back to #a7aaad. The standalone brand icon (`assets/img/accua-contacts-forms.svg`) and the inline colored SVGs in the plugin's page headers are unchanged, so those contexts keep the colored logo. Also removed a stale rule in `assets/css/admin.css` that tried to force the menu icon to stay colored by targeting `.wp-menu-image img` (dead code: base64 SVG menu icons render as a `div` background-image, not an `img`). CSS version 192.
11
12 = 2.2.30 =
13 * Fix: restored the original frontend form DOM id format `accua-form___accua-form__{id}_{uniqid}`. Version 2.2.21 silently changed it to `accua-form_{id}_{uniqid}` (the internal `__accua-form__` prefix was stripped in `AccuaForm::__construct()` to match the then-new E2E selectors), breaking custom CSS/JS, analytics triggers and integrations that target the form element by id. The E2E selector helpers (`tests/helpers/selectors.ts`, now via a shared `formIdPrefix()`) were updated to the restored format instead. Anchor ids (`formSubmitSuccess-{id}` etc.) are unaffected: they are derived from the internal form id by `get_anchor_id()`, which strips the prefix independently of the DOM id.
14
15 = 2.2.29 =
16 * Fix: the reCAPTCHA v2 lazy-load trigger in `classes/Element/Captcha2.php` now uses a delegated `change` handler on `document` instead of binding directly to the elements matched when the first captcha's inline script executes during HTML parsing. With multiple forms on a page, the trigger script only runs once (guarded by `accuaform_recaptcha2_ajax_loaded`), so fields rendered after the first captcha (e.g. a second form in the footer) never got the handler: interacting with them did not load the reCAPTCHA API and the captcha stayed hidden until the first form was touched. The delegated binding also covers fields placed below the captcha within a single form and forms injected after page load.
17
18 = 2.2.28 =
19 * Feature: Multiple post checkboxes now honors a `post_type=` override in its "Additional query parameters" (validated against public post types), matching post-select; previously the render path set the query post_type unconditionally to the field dropdown, discarding the parameter. The value is admin-supplied (saved config, not a client request), so there is no tampering surface. The rest of the post-multicheckbox privacy model already matched post-select (server-rendered opt-in via `post_status=publish,private`, drafts never rendered, submit validated by the options allowlist) and needed no change.
20 * Tests: new E2E spec `tests/e2e/frontend/post-multicheckbox.spec.ts` covering private/draft hidden by default, private rendered+stored only with `post_status=publish,private`, the `post_type=` override, and forged-private-checkbox submit rejection.
21
22 = 2.2.27 =
23 * Feature: post-select / post-multicheckbox "Additional query parameters" now honor `post_status`, limited to publish/private via `accua_forms_filter_field_post_status()`. On the anonymous post-select AJAX endpoint (where extra_args is client-controlled), `post_status=private` is only honored when the received string matches a saved field configuration AND the request's resolved post type matches that configuration's post type (`accua_forms_extra_args_is_saved_config()`), or the user has `read_private_posts` (form editor preview). Binding the post type prevents lifting a private-enabled query string from one post type onto another. The selected-option prefetch, the PostSelect element render (`getAllowedPostStatuses()`), and submit-time validation accept the configured statuses accordingly. Draft/pending/future are never exposed.
24 * Fix: Post select / Multiple post checkboxes fields no longer drop child posts. `accua_get_pages()` applied `get_page_children()` to an already-paginated, publish-only result batch (because `hierarchical` defaults to 1), so any post whose parent was not in the same batch was silently removed: children of draft/private parents never appeared, searching for a child post returned nothing, `parent=`/`include=` filters could return empty lists, and AJAX "load more" pagination ended prematurely (`has_more` was computed on the filtered count).
25 * Fix: `child_of=` now returns all descendants (like core `get_pages()`) via the new `accua_forms_get_post_descendant_ids()` helper, instead of direct children only; `exclude_tree=` excludes the full subtree computed against the whole tree rather than the current batch. Both are resolved to explicit ID lists before querying so they compose correctly with pagination, search and `exclude=`.
26 * Fix: hierarchical (tree) ordering is now applied only when the result set is complete and title-sorted, and posts whose ancestors are unavailable are appended instead of dropped.
27 * Security: the `accua_forms_get_posts` AJAX endpoint (`selected=` prefetch) and the PostSelect element's selected-option rendering no longer disclose titles of draft/private/pending posts; both now require a publicly viewable post of the field's effective post type.
28 * Fix: post-select submitted values are validated against the field's configured post type (honoring the `post_type=` override in extra args, via `AccuaForm_Element_PostSelect::getEffectivePostType()`).
29 * Fix: post-multicheckbox `{__post_id_*}` / `{__post_url_*}` tokens used the whole value array instead of each item, producing "Array"/empty output.
30 * Fix: `AccuaForm_Element_PostSelect` lost its `post_type`/`extra_args` properties when the form instance was serialized into the submission transient (parent `OptionElement::__sleep()` whitelist), so submit-time validation compared against the defaults. Added a `__sleep()` override preserving the element's own properties.
31 * Fix: post-select.js dropped a search typed while the initial option load was still in flight (`isLoading` early return), leaving the unfiltered list; a stale slow response could also overwrite newer search results. Requests now carry a sequence token so the latest request always wins (JS version 118).
32
33 = 2.2.26 =
34 * Plugin Check (PCP) compliance fixes: `esc_sql()` applied to all `$wpdb->prefix` table name assignments in `includes/privacy.php`, with `phpcs:disable/enable` blocks for multi-line prepared queries; dashboard page `orderby`/`order` sort parameters sanitized with `wp_unslash()`/`sanitize_key()`, plus `phpcs:ignore` annotations for nonce-safe GET reads, an underscore-prefixed internal function name, and the block editor render variable.
35 * Removed stale build artifact zip files from the plugin directory.
36
37 = 2.2.25 =
38 * Fix: Translations no longer trigger a `_load_textdomain_just_in_time` notice on WordPress 6.7+. Form processing and the database-version check are now hooked to `init` (priorities 5 and 1 respectively) instead of `plugins_loaded`. This ensures translations are loaded after `after_setup_theme`, as WordPress requires since 6.7.
39 * Translations IT/ES: 49 previously untranslated strings added (lead statuses, border/title style options, form-editor labels, submission detail strings, notes UI, filter dropdowns).
40
41 = 2.2.24 =
42 * Fix: Trashing a submission from the single-submission page now redirects correctly. The previous helper function echoed HTML output before returning, causing `wp_safe_redirect()` to fail (headers already sent). The redirect path now calls the echo-free `accua_forms_trash_submission()` directly.
43
44 = 2.2.23 =
45 * Fix: Validation summary links now point to the field they reference (`href="#fieldId"` instead of `href="#"`), enabling native browser focus-on-click behaviour and fixing keyboard/screen-reader navigation.
46 * Fix: Email format inline error no longer appears twice when the field loses focus after a prior format error was already displayed. The blur handler now checks for an existing non-removing error element instead of the parent's CSS class, preventing a race condition with the required-blur handler.
47
48 = 2.2.22 =
49 * Fix: Non-AJAX form submission now sets the correct URL hash (#formSubmitSuccess-{id}) after page reload. Previously the form action defaulted to "#", causing the URL to show a bare "#". The form action is now set to the current page URL at construction time, and the post-submit DOMContentLoaded script always calls history.replaceState regardless of whether the anchor element exists.
50
51 = 2.2.21 =
52 * Fix: AJAX form submission no longer changes the page URL. The smooth-scroll helper previously called history.replaceState after each successful/invalid submit, updating the URL hash. This was unintended for AJAX mode where the page must not navigate.
53
54 = 2.2.20 =
55 * Admin: consolidated tab component into a single JS file; removed redundant script dependency.
56
57 = 2.2.19 =
58 * Translations IT: fixed "Submissions" noun → "Compilazioni" (was "Compilati"); updated "Forms submissions" and "Contact Forms - Submissions" accordingly.
59 * Translations ES: fixed missing accent "Envíos" (was "Envios"); unified "Unique submissions" / "Total submissions" / "Submissions from all forms" to use "envíos" consistently (was "presentaciones").
60
61 = 2.2.18 =
62 * PCP 2.0.0 compliance: raised minimum WordPress version to 5.9; fixed stable tag mismatch; added translators comments to printf calls; replaced parse_url() with wp_parse_url(); added phpcs:ignore for already-escaped helper output; removed redundant load_plugin_textdomain() call (WordPress auto-loads since 4.6).
63
64 = 2.2.17 =
65 * Fieldset group field: New "Border and Title" dropdown in the form editor with 6 style options: no border/no title, border only, border + inline legend, border + title above, border + title inside, no border + title inside.
66 * Fieldset group field: Group Title input is now always visible and appears first in the settings panel.
67 * Fieldset group field: Widget title bar displays the group title for both the Fieldset Begin and Fieldset End widgets; Fieldset End mirrors the preceding Fieldset Begin label.
68 * Frontend CSS: Fieldset border is now opt-in (removed unconditional `1px solid #ccc`). Existing fieldsets lose their border — users can re-enable it via the new dropdown. Resolves unexpected border appearing after upgrading from v1.9.x.
69 * New CSS helpers: `.accua-fieldset-border`, `.accua-fieldset-title-outer`, `.accua-fieldset-title-inner`.
70
71 = 2.2.16 =
72 * Dashboard: replaced ID column with an Actions column (Open / Move to Trash links); default sort changed to Submitted.
73 * Dashboard: Actions column is always non-wrapping; Move to Trash link is red; translations added (IT: Azioni / Sposta nel cestino, ES: Acciones / Mover a la papelera).
74 * Dashboard & Submissions list: URL columns (Page, Referrer) now use CSS-driven overflow detection instead of a fixed 80-character threshold. Only cells that truly overflow the rendered column width get the [+] expandable widget; short URLs are shown as plain links with no clutter.
75 * Submissions list: Referrer column no longer wraps for medium-length URLs.
76 * New JS: `assets/js/admin/expandable-cells.js` — measures natural link width via `Range.getBoundingClientRect()` and builds `<details>/<summary>` only when needed.
77
78 = 2.2.15 =
79 * Hidden field: the "CSS ID" setting now correctly sets the `id` attribute on the hidden `<input>` element itself (since hidden fields have no wrapper div).
80
81 = 2.2.14 =
82 * Frontend CSS: scoped `button:focus`, `input[type="checkbox"]:focus`, and `input[type="radio"]:focus` focus styles inside `.accua-form` to avoid polluting page-level button styles.
83
84 = 2.2.13 =
85 * **Date field**: Fixed validation error for custom date fields - now correctly extracts minDate/maxDate properties from form configuration.
86
87 = 2.2.12 =
88 * Submissions list: renamed "Review" column to "Open"; updated "Essential Columns" preset (ID, Open, Form, IP, Page, Referrer, Language, Submitted, Email).
89 * Submissions list: new users now see essential columns visible by default.
90 * Form editor: fixed widget Save button alignment (Cancella/Chiudi left, Salva right).
91
92 = 2.2.11 =
93 * Form editor: Added "Default Submit button" informational widget permanently at the bottom of the form area (non-draggable, non-sortable).
94 * Form editor: The widget auto-hides when a custom submit-type field is in the form, and reappears when removed.
95
96 = 2.2.10 =
97 * Single submission page: refactored to the WordPress-standard two-column postbox layout (`#poststuff`, `#post-body.columns-2`). Submitted fields and Details tables on one side; Submission, Lead status and Notes postboxes on the other. Form name shown as a link.
98 * Notes: author display name shown instead of email address.
99 * Removed toggletip, progress icons and custom submitbox styles; simplified `set-lead-status.js` and `single-submission.js`. CSS 185, JS 111.
100
101 = 2.2.9 =
102 * Submissions list: long page URLs and referrers collapse to a 2-line clamp with a `<details>` toggle that expands to the full clickable link; Page and Referrer columns are now clickable links.
103 * Dashboard last 10 submissions: same expandable pattern; column names aligned with the submissions list.
104 * Submissions list: export buttons moved below the description for better discoverability.
105 * Translation fix (IT): page title "Compilazioni" -> "Compilati".
106
107 = 2.2.8 =
108 * Single submission page: replaced the custom table with WordPress `widefat fixed striped` styling; human-readable field labels resolved from field definitions; internal structural fields hidden; line breaks preserved in text values; columns stack responsively at 782px.
109 * Dashboard last 10 submissions: rewritten with sortable columns, ID as primary column with row actions (View | Trash), and a single JOIN query replacing the previous N+1 pattern (30 queries per page load reduced to 1).
110 * Forms list: fixed the misaligned sort indicator on the Submissions column; removed stale inline CSS and float-based sorting hacks.
111 * Cleanup: removed dead `.accua_forms_trash` CSS and dead `del_sub_form` handler.
112
113 = 2.2.7 =
114 * **Refactor**: Extracted settings page into `admin/settings-page.php` (enqueue + render).
115 * **Refactor**: Extracted form list/add/edit pages into `admin/form-editor.php`.
116 * **Refactor**: Extracted privacy/GDPR/data-retention into `includes/privacy.php`.
117
118 = 2.2.6 =
119 * **Refactor**: Extracted fields page into `admin/fields-page.php` with separate JS file.
120 * **Refactor**: Moved submissions pages to `admin/` with separate JS files (`submissions-list.js`, `single-submission.js`).
121 * **Refactor**: Replaced all form editor inline `<script>` blocks with properly enqueued JS in `form-settings.js`.
122 * **Refactor**: Removed redundant color picker inline init (already handled by `form-settings.js`).
123 * **Refactor**: Removed dead Flot chart code from report page (library was removed in 2.1.0).
124 * **Cleanup**: Removed dead commented-out code throughout the codebase.
125
126 = 2.2.5 =
127 * **Fields page**: Replaced hand-crafted table with WordPress `WP_List_Table` (sortable columns, checkbox select, bulk delete).
128 * **Fields page**: Added "Forms" column showing how many forms use each field.
129 * **Fields page**: Client-side validation with accessible error notices and `wp.a11y.speak()` support.
130 * **Fields page**: Row actions (Edit | Delete) with nonce protection and confirmation dialog.
131
132 = 2.2.4 =
133 * **Form editor**: Appearance tab labels are now clickable (native `<label>` elements for accessibility).
134 * **Form editor**: Section headings use proper `<h2>` elements with consistent styling.
135 * **Form editor**: Consistent row heights for style options; color pickers hidden when row is unchecked.
136 * **Form editor**: Labels dropdown no longer overflows its container.
137 * **Form editor**: Responsive 2-column layout at viewports narrower than 1200px with preview below full-width.
138 * **Form editor**: Fixed flash of unstyled content (FOUC) on page load.
139 * **Form editor**: Added note under Labels dropdown explaining automatic responsive stacking at 500px.
140 * **i18n**: Italian and Spanish translations updated.
141
142 = 2.2.3 =
143 * **Form editor**: Added "+" button on each available field to add it to the form with a single click (appends as last field, scrolls into view, and opens settings).
144 * **Form editor**: Hidden the expand caret from available fields list (not needed there).
145 * **Form editor**: Long field names now wrap to multiple lines instead of being truncated with ellipsis. The "+" button and expand caret remain vertically centered and always clickable.
146 * **i18n**: Added Italian translations for new UI strings ("Campi disponibili", "Filtra campi…", "Aggiungi campo").
147
148 = 2.2.2 =
149 * **Form editor**: Added instant search filter in the Available Fields column — type to quickly find fields by name (substring match).
150
151 = 2.2.1 =
152 * **Form editor**: Redesigned Fields tab as a stable three-column CSS Grid layout (available fields, drop zone, live preview). The available fields column has its own scrollbar; the other columns use the main browser scroll. Fixes wrapping issues on high-zoom levels, small screens, and forms with many fields or long labels.
153 * **Form editor**: Each column now has its own heading ("Available Fields", "Drop fields here", "Preview") styled consistently and aligned at the same height.
154 * **Form editor**: Drop zone title moved outside the dashed border for clearer visual hierarchy.
155
156 = 2.2.0 =
157 * Tested up to WordPress 7.0.
158 * Added WordPress Playground blueprint (`blueprint.json`) for live preview on wordpress.org - creates five demo forms showcasing all field types: toplabel, sidebyside, inlinelabel layouts plus fieldsets, checkboxes, multi-select, post-select, HTML blocks, and hidden fields.
159 * **Email notifications**: Long URLs (e.g. Google Ads gclid parameters) no longer break print/PDF layout. Applied `table-layout: fixed` and `word-break: break-all` on URL placeholder links (`{__url}`, `{__review_submission_url}`, `{__referrer}`).
160 * **Email notifications**: Improved vertical spacing between submitted fields - label cells use `white-space: nowrap` with top-aligned padding, value cells get `overflow-wrap: break-word`.
161 * **Email notifications**: Fieldset labels now display correctly in the submitted data section instead of showing raw `__fieldset-begin-*` IDs.
162 * **Email notifications**: Fixed malformed `font-family` quotes in the `<body>` wrapper (now uses `&quot;` entities).
163 * **Single submission page**: Restructured from 3-column to 2-column (30%/70%) grid layout. Details and Lead Status postboxes are now stacked in the left column, submitted fields in the right.
164 * **Single submission page**: Renamed "Stats" postbox to "Details".
165 * **Single submission page**: Long URLs now wrap properly via `table-layout: fixed` and `word-break: break-word` on table cells.
166 * **Submissions list**: Added view links (Active, Trash, Lead Status) for quick filtering.
167 * **Submissions list**: Refactored filter controls (form, page, year, month, search) into `extra_tablenav()` using native `WP_List_Table` pattern.
168 * **Bugfix**: Fieldset (grouped fields) without a label no longer renders an empty `<legend>` element that caused a visual gap in the fieldset border.
169 * **Bugfix**: Essential Columns button - replaced individual checkbox AJAX calls with a single batch save, fixing a race condition that caused column settings to be lost.
170 * **Bugfix**: Fields page - fields stored in legacy format (`label` key instead of `name`/`id`) now display correctly, using the same fallback logic as front-end rendering.
171
172 = 2.1.4 =
173 * **Improvement**: Sidebyside (labels on left) layout now automatically switches to top labels when the form container is narrower than 500px. Uses CSS container queries to respond to the actual form width rather than viewport, so it works correctly across all themes, page builder columns, and sidebar widgets.
174
175 = 2.1.3 =
176 * **Bugfix**: Post select field (`post-select`) value was not saved to database and not included in notification emails. The submission handler relied on `$el->getOptions()` which returns empty for lazy-loaded AJAX fields. Fixed by resolving posts directly via `get_post()` with post type and publish status validation.
177
178 = 2.1.2 =
179 * **Form editor**: Added submission count with link to the submissions list, displayed inline with the page heading using the standard WordPress `page-title-action` pattern.
180 * **Form editor**: Title input now has proper spacing and sizing matching WordPress core post editor styling.
181 * **Form editor**: Google Ads and Tokens tabs now use WordPress postbox markup with `form-table` layout, consistent with Data Retention and Messages tabs.
182 * **Form editor**: Added unsaved changes warning - a `beforeunload` prompt prevents accidental navigation when the form has been modified.
183
184 = 2.1.0 =
185 * **Admin UI modernization** - Comprehensive redesign of the form editor and settings pages for a more coherent design language, aligned with native WordPress admin patterns.
186 * **Form editor**: Flat single-level tab bar replacing the previous nested two-level tab system. Six tabs: Fields, Appearance & General, Messages, Data Retention, Google Ads, Tokens.
187 * **Form editor**: CSS Grid-based layout for the field editor and live preview, replacing the old float-based 50/50 split.
188 * **Form editor**: Native WordPress title markup (`#titlewrap`) for the form title input.
189 * **Settings page**: Tab navigation with ARIA-compliant accessible tabs - Default Messages, Integrations, Privacy, Layout & Styling, Theme Helper, Danger Zone, Tokens.
190 * **Postbox structure**: All settings sections now use native WordPress `.postbox` + `.postbox-header` + `.inside` markup instead of custom wrappers.
191 * **Messages tab**: All four message postboxes displayed in a 2×2 grid layout. Radio buttons wrapped in `<fieldset>` with clickable `<label>` elements for better accessibility.
192 * **Messages tab**: TinyMCE editors now include a font family selector with 10 email-safe fonts (Arial, Arial Black, Comic Sans MS, Courier New, Georgia, Lucida Sans, Tahoma, Times New Roman, Trebuchet MS, Verdana). Link/unlink buttons added to the toolbar.
193 * **Default messages**: Default font changed from Lucida Sans to Arial for new forms. Removed overstylized wrappers (padding, background, border) from success and error message templates. Removed grey background from admin notification email template.
194 * **Default message preview**: Faithful rendering of email content - no longer strips inline styles.
195 * **CSS consolidation**: Merged `dashboard.css` into `admin.css`. Removed dead CSS selectors and legacy rules.
196 * **Bugfix**: Fixed broken CSS selectors caused by `accuaTabs` component renaming panel IDs - replaced `#accua_tab_*` selectors with `[data-tab="*"]` attribute selectors.
197 * **Bugfix**: Fixed Messages, Data Retention, and Tokens panels not properly contained within the tab system on the form editor page (unclosed `<div>` tags).
198
199 = 2.0.0-rc.3 =
200 * **Improvement**: Danger Zone moved to right column on Settings page, visible to administrators only
201 * **Improvement**: Bulk anonymize now shows a per-form preview with submission counts before confirming
202 * **Translation**: Complete Italian and Spanish translations (98% coverage)
203
204 = 2.0.0-rc.2 =
205 * **Bugfix**: Upgrade migration from 1.9.x - added data migration in `$old_db_version < 14` block: renames form `name` key to `title`, converts `fields` from CSV string to array, removes legacy `fieldnum` key.
206 * **Bugfix**: Submissions page - removed column header now uses translatable `%s (removed)` format instead of concatenated slug (e.g. "Email (removed)" instead of "emailrimosso").
207 * **Translation**: Updated Italian translations for removed column label.
208
209 = 2.0.0-rc.1 =
210 * Release candidate. See readme.txt for the full 2.0 feature summary.
211 * **PCP Compliance**: Fixed stable tag mismatch, added translators comments, replaced rmdir() with WP_Filesystem, added phpcs:ignore for shortcode output escaping.
212 * **Improvement**: Deactivation modal - anonymize now asks for confirmation before proceeding, "Just deactivate" button visually prominent.
213 * **Removed**: test-gdpr-deep.php from distribution.
214
215 = 2.0.0-beta.73 =
216 * **Bugfix**: Textdomain loading timing - moved `load_plugin_textdomain()` to `init` hook (was `plugins_loaded`), removed redundant call from `accua_form_init()` and `accua_forms_install()`. Fixes WordPress 6.7+ `_load_textdomain_just_in_time` notice.
217 * **Bugfix**: dbDelta `TEXT DEFAULT` warnings - removed `DEFAULT ''` from TEXT columns in CREATE TABLE statements. MySQL strict mode forbids default values on TEXT/BLOB columns.
218 * **Bugfix**: Deactivation "Delete all data" now properly cleans up - added `accua_forms_lastid` and `accua_form_api_keys` to deletion list, added transient guard to prevent `accua_forms_check_db_version_and_update()` from re-creating data during the deactivation redirect.
219 * **Bugfix**: Prevented double `accua_forms_install()` execution on activation (once from `plugins_loaded` version check + once from activation hook) via static guard.
220 * **Translation**: Added Italian translations for all Danger Zone and deactivation modal strings (25 new strings). Updated custom validation message strings.
221
222 = 2.0.0-beta.72 =
223 * **Bugfix**: File upload field - added `accept` attribute on the native `<input type="file">` so the browser file picker filters by allowed extensions (was only set on the JS wrapper via `data-accept`)
224 * **Bugfix**: File upload field - server-side extension validation is now case-insensitive (e.g. uploading `FILE.PDF` matches allowed extension `pdf`)
225 * **Improvement**: Extension override input now normalizes entries: strips leading dots and lowercases (`.PDF` → `pdf`)
226
227 = 2.0.0-beta.71 =
228 * **Improvement**: Data Retention tab in form editor - moved global default info to a description line below the override checkbox for clarity
229 * **Bugfix**: Danger Zone - fixed vertical alignment of the period dropdown (select) with adjacent input and button
230
231 = 2.0.0-beta.70 =
232 * **Feature**: Deactivation data cleanup modal on the Plugins page
233 - Intercepts the "Deactivate" click and shows a modal with three options:
234 - **Just deactivate** - keep all data, can reactivate later
235 - **Anonymize all submissions** - replace personal data with placeholders, set IPs to 0.0.0.0
236 - **Delete all data** - permanently remove forms, submissions, settings, and uploaded files (with extra confirmation)
237 - Cancel button and overlay click to dismiss
238 * **Refactor**: Extracted `_accua_forms_delete_all_plugin_data()` helper to share deletion logic between Danger Zone and deactivation modal
239
240 = 2.0.0-beta.69 =
241 * **Feature**: Danger Zone section on settings page
242 - Bulk anonymize submissions older than a configurable period (days/months/years) across all forms
243 - Delete all Contact Forms data (settings, forms, submissions, uploaded files) with domain-name confirmation prompt
244 - Both operations use AJAX with clear success/error feedback
245
246 = 2.0.0-beta.68 =
247 * **Bugfix**: Simplified IP anonymization - writes `0.0.0.0` directly instead of read-then-anonymize, eliminating an unnecessary DB query
248
249 = 2.0.0-beta.67 =
250 * **Feature**: All columns in the form list table are now sortable (From Email, From Name, Admin Email, BCC Email, Data Retention, Shortcode, PHP Code)
251 - Retention column sorts by underlying seconds value for correct numeric ordering
252 - Shortcode and PHP Code columns sort by form ID (since values are ID-derived)
253 - Invalid orderby parameters safely fall back to ID sort
254
255 = 2.0.0-beta.66 =
256 * **Feature**: Per-form data retention tab in form editor - new "Data Retention" tab after Fields / Messages
257 - Shows current global default summary
258 - "Override default data retention" checkbox to enable per-form settings
259 - Retention period (days/months/years) and mode (anonymize/delete) controls
260 * **Feature**: Data Retention column in form list - shows effective retention for each form
261 - Displays per-form override or global default with human-readable format
262 * **Bugfix**: Fixed mixed-language dropdown in retention settings ("days, mesi, years" → properly translated)
263 * **Translations**: Italian translations for all data retention and GDPR privacy strings
264
265 = 2.0.0-beta.65 =
266 * **Bugfix**: Anonymized notes now show `[Anonymized]` instead of WordPress's generic `[deleted]` - consistent with field value anonymization
267
268 = 2.0.0-beta.64 =
269 * **Feature**: Submissions list table upgraded to full WP_List_Table native features
270 - All columns sortable (SQL-level sorting with clickable headers)
271 - Custom field columns sort via LEFT JOIN, with NULLs pushed to end regardless of direction
272 - Row actions on ID column: View, Move to Trash / Restore, Permanently Delete (with confirmation dialog)
273 - Per-page screen option: users can set items per page (default 100, saved per-user)
274 - Removed fields separated into collapsible "Removed Fields" section in Screen Options
275 - Primary column set to ID for WordPress responsive table support
276 - Empty state message: "No submissions found."
277 * **Improvement**: Anonymized field values now show `[Anonymized]` instead of WordPress's generic `[deleted]` - clearer intent, properly translatable per-plugin
278 * **Translations**: Italian translations updated for all new strings
279
280 = 2.0.0-beta.63 =
281 * **Feature**: GDPR data anonymization and retention system
282 - WordPress Privacy API integration: personal data exporter and eraser
283 - Configurable data retention: global + per-form override (days/months/years), mode (anonymize or delete)
284 - WP-Cron automated cleanup of expired submissions
285 - Manual anonymization: single submission button (AJAX) + bulk action on submissions list
286 - Privacy policy suggestion text via `wp_add_privacy_policy_content()`
287 - Uses WordPress standard `wp_privacy_anonymize_data()` per field type
288 * **Architecture**: Anonymization stored as independent boolean (`afs_anonymized` column), orthogonal to trash status - anonymized submissions stay in active views and dashboard statistics
289 * **UI**: Single submission page redesigned to WordPress admin standards with 4-state action matrix (Anonymize/Trash/Restore depending on state)
290 * **CSS Version**: 148
291 * **DB Version**: 14
292
293 = 2.0.0-beta.62 =
294 * **Bugfix**: Fixed PHP 8.x "Undefined array key" warnings on the Submissions list page - added missing `isset` check for field `name` key in column headers, and added array bounds guard when parsing `_wp_http_referer` parameters
295
296 = 2.0.0-beta.61 =
297 * **Bugfix**: Sidebyside layout (labels on left) converted from flexbox to float-based layout for backward compatibility - custom JS using `.css('display', 'block')` to show hidden fields no longer breaks the label/field alignment
298 * **Bugfix**: Single checkboxes in sidebyside forms now left-aligned instead of indented at 25% margin - elements without a label div (`.pfbc-fieldwrap:first-child`) skip the label column offset
299 * **Bugfix**: Checkbox inputs (`.accuaform-fieldtype-checkbox`) now have consistent minimum size (`1rem`) and no left margin across all browsers and layouts
300 * **CSS Version**: 147
301
302 = 2.0.0-beta.60 =
303 * **Bugfix**: Fixed client-side validation treating "-" as empty in all field types - now only select dropdowns treat "-" and "Select..." as unselected; text inputs, textareas, and other fields accept "-" as a valid value
304 * **JS Version**: 93
305
306 = 2.0.0-beta.59 =
307 * **Updated Chart.js** from v3.5.0 to v4.5.1 - dashboard charts now use the latest Chart.js release
308 * **JS Version**: 92
309
310 = 2.0.0-beta.58 =
311 * **Custom validation messages**: Override default required and format validation messages at field definition and per-form level
312 - Field-level overrides on the Fields page: set custom required message and custom format message for each field definition - applies everywhere that field is used
313 - Per-form overrides in form editor: checkbox + text input to override at the individual form level (highest priority)
314 - Priority chain: per-form instance → field definition → default i18n translation
315 - Supports `%s` placeholder for the field name in custom messages
316 - Custom messages bypass i18n translations - used as-is regardless of site language
317 - Works on both client-side (inline errors, submit and blur) and server-side (AJAX) validation
318 - Follows the draft system: per-form changes saved to draft until global Save button is clicked
319 * **Bugfix**: Phone field blur validation now uses custom format messages - previously only submit and server-side validation respected custom messages, blur showed the default translated message
320 * **Bugfix**: Phone field required error not shown after clearing a previously invalid value - error state was left inconsistent between phone format cleanup and required blur handler
321 * **JS Version**: 91
322
323 = 2.0.0-beta.57 =
324 * **Block editor support**: Added a native Gutenberg block for inserting contact forms
325 - Search for "Contact Form" in the block inserter or type `/contact`
326 - Select a form from the dropdown - live preview renders in the editor
327 - Sidebar panel with form selector in "Form Settings"
328 - No build tools required - works with plain JavaScript
329 - Fully translatable - Italian translations included
330 * **Bugfix**: Fixed PHP warning "Undefined array key description" on the Fields admin page for fields without a description
331
332 = 2.0.0-beta.56 =
333 * **Insert Contact Form modal overhaul**: Rebuilt the classic editor "Insert Contact Form" TinyMCE button with a WordPress-native modal
334 - Searchable form list with keyboard navigation, matching WP's own link dialog pattern
335 - CSS/JS only loads on post editor screens (not every admin page)
336 - All UI strings translatable via WPML/gettext - Italian translations included
337 - Fixed Cancel/Insert button alignment with flexbox
338 - Removed legacy iframe popup code and unused AJAX handler
339
340 = 2.0.0-beta.55 =
341 * **Dashboard: New "Monthly submissions by page" chart**: Added a second chart to the dashboard showing submissions and unique pages per month, with independent period control
342 * **Dashboard: Post type filtering**: Added content type filter to narrow dashboard statistics by post type (page, post, custom post types)
343 * **Dashboard: Improved content filter**: Page/content filter now shows post type labels, groups options by type, and dynamically filters based on selected content type
344 - Moved page filter from the first chart area to the new second chart section
345 - Post type and content dropdowns are linked: selecting a content type filters the content dropdown options
346
347 = 2.0.0-beta.54 =
348 * **Fix: File Download Rendered as Raw Text Instead of Downloading (improved)**: Improved the file download fix from beta.53 which was not fully effective on all server configurations
349 - Added `header_remove()` to clear all pre-set HTTP headers (including `Content-Type: text/html` set by `admin-ajax.php`) before sending download headers
350 - Added `nocache_headers()` to prevent browser/proxy caching of the download response
351 - Changed `die('')` to `exit` to avoid extra bytes in the output stream
352
353 = 2.0.0-beta.53 =
354 * **Fix: File Download Rendered as Raw Text Instead of Downloading**: On servers with caching plugins, file attachments displayed raw binary in the browser instead of downloading - fixed by clearing output buffers before sending headers and using `FILEINFO_MIME_TYPE` instead of `FILEINFO_MIME` for clean MIME types
355 * **Improvement: Mask Password Values in Submissions List**: Password fields now show `••••` in the list table instead of the stored value
356
357 = 2.0.0-beta.52 =
358 * **Fix: AJAX Form Submission Stuck on "Sending" When Server Returns `submitted: false`**: The form permanently froze in loading state when the server did not recognize the submission (e.g. expired nonce from a cached page)
359 - Added `else` branch for `response.submitted === false` in the AJAX response handler - shows error message, re-enables submit button, unlocks fields, and triggers fallback to direct POST after 3 failures
360 - Fixed `postMessage` handler to accept responses where `buildID` is `null` (server rejection) as long as `jsuuid` matches, so error displays immediately instead of waiting for the polling timeout
361 - Root cause on production: server-side page caching served stale WordPress nonces to non-logged-in visitors
362 * **Fix: Password-and-Confirm Field Ignored Label Override**: Used hardcoded "Password" label instead of user-configured custom label
363 * **Fix: Required Multiselect Validation Bypass**: Required `<select multiple>` fields were not flagged as invalid when empty - `[]` was incorrectly treated as truthy
364 * **JS Version**: 85
365
366 = 2.0.0-beta.51 =
367 * **Fix: Custom CSS Class/ID Not Rendered for Radio, Checkbox, Multicheckbox, Turnstile, and Captcha**: These field types were missing `$field_properties` in their constructor calls, causing custom CSS class and ID to be silently ignored
368 - `accua-forms.php`: Added `$field_properties` to constructor calls for single checkbox, radio, multicheckbox/post-multicheckbox, turnstile, and captcha (v2)
369 * **Per-Option Custom ID and Class for Radio and Checkbox Fields**: Each individual radio/checkbox option now gets a unique ID and class derived from the field's custom CSS ID/class
370 - Format: `{css_id}-option-N` / `{css_class}-option-N` (1-based)
371 - `classes/Element/Radio.php`, `classes/Element/Checkbox.php`: Applied per-option ID and class to option wrapper divs
372
373 = 2.0.0-beta.50 =
374 * **Fix: Custom HTML Field CSS Class and ID Not Rendered**: Custom CSS class and ID set on Custom HTML fields were saved but never applied to the frontend HTML output
375 - `Element/HTML.php`: Extended constructor to accept an optional `$properties` parameter for wrapper CSS class/ID
376 - `accua-forms.php`: Pass `$field_properties` to `Element_HTML` constructor (same pattern as fieldset fix in beta.49)
377 * **Refresh Preview for Custom HTML Fields**: Added "Refresh Preview" link below the Custom HTML textarea in the form editor
378 - Saves the field to draft and refreshes the preview iframe, allowing content changes to be previewed before publishing
379 * **Auto-Preview on Field Changes**: The form preview now updates automatically when any field option is changed in the editor
380 - Checkboxes and selects trigger immediate preview refresh
381 - Text inputs and textareas use an 800ms debounce delay to avoid excessive updates during typing
382 - Uses silent save (saves to draft without replacing widget HTML) to preserve user's in-progress edits
383 * **JS Version**: 83
384
385 = 2.0.0-beta.49 =
386 * **Fix: Fieldset Custom CSS Class and ID Not Rendered**: Custom CSS class and ID set on fieldset (group) fields were saved but never applied to the HTML output
387 - `accua-forms.php`: Pass `$field_properties` to `AccuaForm_Element_FieldsetBegin` constructor so `wrapperCssClass` and `wrapperCssId` are set on the element
388 - `FieldsetBegin.php`: Merge wrapper CSS class into the `class` attribute and override `id` with wrapper CSS ID before rendering, so they appear directly on the `<fieldset>` tag
389
390 = 2.0.0-beta.48 =
391 * **Fix: Duplicate Validation Errors**: Fixed PFBC Element validation accumulating errors across calls instead of resetting them
392 - `Element::isValid()` now clears the errors array before running validators, preventing duplicate messages
393 - Removed redundant `Validation_Email` that was added both in the Email element constructor and in the form builder switch case
394 * **Extension Hooks for External Field Types**: Added five hooks for external plugins to register custom field types without modifying Contact Forms core
395 - `accua_forms_field_types` (filter): Register custom field types in the editor dropdown
396 - `accua_forms_render_field_element` (filter): Return custom Element objects for rendering
397 - `accua_forms_field_settings` (action): Render extra settings HTML in field editor
398 - `accua_forms_save_field_data` (filter): Modify field instance data on save
399 - `accua_forms_enqueue_scripts` (action): Enqueue frontend JS/CSS when a form is rendered
400
401 = 2.0.0-beta.47 =
402 * **Fix: Prefix-Only Telephone Values Treated as Empty**: Values containing only a country prefix (e.g. "+39") are now consistently treated as empty across all validation layers
403 - Required telephone fields with only a prefix now correctly show the "required field" error instead of silently submitting
404 - Optional telephone fields with only a prefix submit without errors (treated as blank)
405 - Client-side: Added `isTelephonePrefixOnly()` helper in `AccuaForm.php` used by both submit and blur required checks
406 - Server-side: `Telephone.php` overrides `isValid()` to normalize prefix-only values to empty before PFBC validators run, so `Required` correctly rejects them
407 - Prefix-only threshold: ≤4 digits starting with `+` (covers all international dialing codes)
408 * **JS Version**: 81
409
410 = 2.0.0-beta.46 =
411 * **Fix: Blurry text on Chromium browsers**: Removed unnecessary `will-change` CSS property from inline error messages that caused GPU-based text rendering, losing subpixel antialiasing. No visual or accessibility regressions - animation and content-flash prevention are handled by the keyframes themselves.
412 * **CSS Version**: 143
413
414 = 2.0.0-beta.45 =
415 * **Custom CSS Class & ID for Field Wrappers**: Added per-field CSS Class and CSS ID settings in the form editor
416 - Each field now has "CSS Class" and "CSS ID" inputs in its settings panel
417 - CSS Class supports multiple space-separated classes
418 - CSS ID adds a unique HTML `id` attribute to the field wrapper `div.pfbc-element`
419 - Available for all field types (except fieldset-end)
420 - Works across all three form layouts: standard, side-by-side, and inline-label
421 - Values are sanitized with `sanitize_html_class()` and escaped with `esc_attr()` on output
422 - Follows the draft system: values are saved to draft until the global Save button is clicked
423 - Fully translatable labels and help text (Italian translation included)
424 * **JS Version**: 78
425
426 = 2.0.0-beta.44 =
427 * **Removed all unnecessary `!important` from frontend CSS**: Improves theme compatibility and prevents forced styling conflicts (e.g., transparent backgrounds on select dropdowns overriding theme styles)
428 - Removed 35 `!important` declarations; only 10 remain (visually-hidden file input, required for accessibility)
429 - Fixed PHP inline styles: changed `background` shorthand to `background-color` to avoid resetting SVG caret on select elements
430 - Removed forced `transparent` default for field backgrounds when no color is configured
431 - All form inputs now use `background-color: inherit` for consistent appearance across any theme background
432 - Increased CSS selector specificity for color picker fields instead of relying on `!important`
433 - Removed PFBC jQuery `outerWidth()` calls that injected inline `style="width: Xpx"` on textboxes and textareas, conflicting with CSS `width: 100%`
434 * **CSS Version**: 142
435
436 = 2.0.0-beta.43 =
437 * **Restored URL Hash on Form Submission**: URL now updates with `#formSubmitSuccess-{formID}`, `#formSubmitInvalid-{formID}`, or `#formSubmitError-{formID}` after form submission (feature originally from v1.4.10, lost during v2.0.0 rewrite)
438 - Uses `history.replaceState()` for clean URL update without page jump or browser history pollution
439 - Works with smooth scrolling introduced in v2.0.0-beta.18 (no regression)
440 - Covers all submission paths: client-side validation failure, AJAX success, AJAX server-side invalid, AJAX error
441 - Non-AJAX fallback: inline script scrolls to result anchor and sets hash on page load
442 - GA/gtag tracking unaffected (event-based, does not read URL fragments)
443 - Bonus: GA4 now automatically captures `page_location` with hash in all subsequent events, enabling URL-based goal/funnel tracking
444 * **JS Version**: 77
445
446 = 2.0.0-beta.41 =
447 * **Preview Layout Fix**: Fixed form preview flashing wrong layout in form editor
448 - Problem: Preview appeared correct for a moment, then switched to wrong layout (sidebyside) regardless of actual setting
449 - Root Cause: `updatePreviewLayout()` ran after each iframe load and hardcoded `sidebyside` as fallback when dropdown was set to "default", ignoring the actual global default
450 - Solution: Removed client-side layout class toggling from `updateFullPreview()` - the server already renders the correct layout; layout changes use `reloadPreviewWithLayout()` which rebuilds the iframe
451 - Also fixed: Save handler now preserves layout in preview reload
452
453 = 2.0.0-beta.27 =
454 * **Critical Bug Fix**: AJAX form submission now correctly returns success/error messages
455 - Problem: Messages were captured BEFORE email sending completed, resulting in empty response messages
456 - Solution: Moved `getSubmittedMessages()` to AFTER `isValid()` and `wp_save()` calls
457 - Impact: Error message "Oops! Something went wrong" now displays when `wp_mail()` fails; success message displays on success
458 * **Project Cleanup**: Moved documentation files to `docs/` subfolder
459 * **Git Hygiene**: Added `.gitignore` to exclude zip files and local-only tools
460
461 = 2.0.0-beta.25 =
462 * **Accessible Loading State**: Replaced hidden summary with visible loading state during AJAX submission
463 - Shows spinner + text "Submitting your form, please wait..." during form submission
464 - Uses `role="status"` with `aria-live="polite"` for screen reader announcement
465 - `aria-busy="true"` indicates ongoing operation
466 - Smooth CSS transitions (0.25s ease-out) between all states (loading → success/error)
467 - Respects `prefers-reduced-motion` user preference (disables animations)
468 - Removed old standalone throbbler spinner (now integrated in summary)
469 * **New CSS Class**: `.pfbc-validation-loading` with blue/neutral color scheme
470 * **CSS/JS Versions**: CSS 103, JS 45
471
472 = 2.0.0-beta.24 =
473 * **UX Fix**: Validation summary no longer shows premature "success" message during AJAX submission
474 - Summary is hidden during server validation, only shows result after server response
475 - Prevents confusing flash of "All fields correct" before server-side validation completes
476 * **JS Version**: 44
477
478 = 2.0.0-beta.23 =
479 * **Phone Validation E.164 Compliance**: Updated to follow ITU-T E.164 standard
480 - Maximum 15 digits (E.164 compliant)
481 - No minimum digit requirement (flexible for all countries)
482 - Lenient formatting: spaces, dashes, dots, slashes, parentheses, plus sign
483 - Rejects invalid characters (letters, special symbols like #, @, etc.)
484 * **Bug Fix**: Phone validation now correctly rejects text characters
485 - Fixed: `+39 dasdsad` was incorrectly accepted as valid
486 - Character validation now runs BEFORE digit count bypass
487 * **JS Version**: 43
488
489 = 2.0.0-beta.22 =
490 * **Phone Field A11y Improvement**: Placeholder-only approach (no prefilled default value)
491 - Removed default value `+39 `, using placeholder only (better for screen readers)
492 * **Phone Validation Made More Lenient**: No minimum digit requirement
493 * **Frontend Performance Optimization**: Removed unused libphonenumber-min.js (171KB saved)
494 * **Simplified phone-validation.js**: Reduced from 166 lines to ~100 lines
495 * **JS Version**: 42
496
497 = 2.0.0-beta.21 =
498 * **Phone Validation Fix for Optional Fields**: Fixed validation failing when only country prefix entered
499 - Treat values with ≤4 digits as "empty" (user hasn't entered actual number beyond prefix)
500 * **W3 Total Cache Compatibility**: Verified working with Page Cache, Minify, and Browser Cache
501 * **JS Version**: 41
502
503 = 2.0.0-beta.20 =
504 * **Critical Bug Fix**: Form no longer disappears after correcting validation errors
505 - Fixed jsuuid transient caching issue in `AccuaForm.php`
506 * **Dead Code Cleanup**: Removed debug statements and commented-out legacy code
507
508 = 2.0.0-beta.19 =
509 * **i18n:** Fixed reCAPTCHA typo (was "reCATPCHA") in 5 validation files
510 * **i18n:** Fixed double space and "re-try" → "retry" in CAPTCHA error messages
511 * **i18n:** Replaced non-standard "identificative" with proper English "identifier" in form/field validation
512 * **i18n:** Fixed "it must contains" → "must contain" grammar error
513 * **i18n:** Improved "identificator" → "unique identifier" and "unchangeable" → "cannot be changed"
514 * **i18n:** Fixed "hyphen and underscores" → "hyphens, and underscores" (Oxford comma)
515 * **i18n:** Improved duplicate field error message clarity
516
517 = 2.0.0-beta.18 =
518 * **Fix:** Success messages now display correctly (was sometimes empty)
519 * **Fix:** Form submission no longer jumps around - smooth scrolling to messages
520 * **Fix:** Multiple forms on same page now handle messages independently
521 * **Fix:** Shows error message when email sending fails (wp_mail returns false)
522 * **UX:** Added CSS animation for success/error messages with reduced-motion support
523 * **Technical:** Changed static $submittedMessages to per-form array keyed by formId
524 * **Technical:** Added all three anchor elements (#formSubmitSuccess, #formSubmitInvalid, #formSubmitError)
525 * **Technical:** Updated CSS version 102, JS version 38
526
527 = 2.0.0-beta.17 =
528 * **Security:** Fixed null byte injection causing 500 server error on form submission
529 * **PHP 8:** Sanitize null bytes from user input to prevent mail() ValueError
530 * **Technical:** Added str_replace("\0", '', ...) sanitization during form value processing
531
532 = 2.0.0-beta.16 =
533 * **Debug:** Removed all debug statements (alert, console.log, error_log) for production release
534 * **Fix:** Server-side validation errors now properly update the validation summary area
535 * **UX:** Turnstile validation message changed to "Please verify you are not a robot."
536
537 = 2.0.0-beta.11 =
538 * **Accessibility:** Enhanced validation summary with clickable field links for easy navigation
539 * **UX:** Error summary now shows "Verifica i seguenti campi per continuare:" with list of invalid fields
540 * **UX:** Each field name in summary is a clickable link that scrolls to and focuses the field
541 * **UX:** Smooth scroll animation with focus after 500ms delay for better user experience
542 * **UX:** Green success state shows "Tutti i campi sono corretti. Pronto per l'invio!" when all fields valid
543 * **UX:** Summary only appears after first submit attempt (not on page load)
544 * **Typography:** Consistent font sizes - 0.9375rem header, 0.875rem list items
545 * **Translation:** Updated Italian and Spanish translations with new summary strings
546 * **Technical:** New JS functions: scrollToFieldAndFocus(), updateSummaryArea(), fieldErrorsList array
547 * **Technical:** New CSS classes: .pfbc-validation-summary, .pfbc-validation-error, .pfbc-validation-success
548 * **Technical:** Updated CSS version 95, JS version 36 for cache busting
549
550 = 2.0.0-beta.10 =
551 * **Feature:** Modern default file extensions for file upload fields
552 * **Feature:** Added docx, xlsx, pptx, odt, ods, odp, csv, gif, webp, svg, heic, rar, 7z, tar extensions
553 * **Removed:** Obsolete bz, bz2 archive formats from defaults
554
555 = 2.0.0-beta.9 =
556 * **UX:** Added prominent visible error message for unsupported file formats in drag & drop upload
557 * **UX:** Red error box with warning icon shows "âš  filename: File type not allowed"
558 * **UX:** Dropzone border turns red on error, clears automatically when valid file uploaded
559 * **Design:** Neutral design update - removed border-radius from dropzone and file list items
560 * **Technical:** Updated CSS version 94, JS version 34 for cache busting
561
562 = 2.0.0-beta.8 =
563 * **NEW:** Accessible drag & drop file upload with modern UI
564 * **Accessibility:** Full WCAG 2.2 AA / European Accessibility Act compliance
565 * **Accessibility:** Keyboard navigation (Enter/Space to open file picker)
566 * **Accessibility:** ARIA attributes and screen reader announcements
567 * **UX:** Dashed border dropzone with folder emoji icon
568 * **UX:** File list with filename, size, and remove button
569 * **Technical:** Progressive enhancement with DataTransfer API
570
571 = 2.0.0-beta.7 =
572 * **UX:** Comprehensive CSS refinements for floating label form view
573 * **UX:** Balanced padding for proper vertical text centering
574 * **UX:** Custom SVG caret for dropdowns with cross-browser consistency
575 * **Accessibility:** Added font-family: inherit to date inputs
576
577 = 2.0.0-beta.6 =
578 * **Feature:** Added "Restore to Default" buttons for form messages 1-4 in Settings page
579 * **UX:** Restore buttons use native WordPress link styling for consistent admin UI
580 * **AJAX:** New `accua_forms_restore_default_message` endpoint for restoring default values
581 * **Technical:** Refactored default form data into reusable `accua_forms_get_default_form_data()` function
582 * **Technical:** Updated CSS version 73, JS version 30 for cache busting
583
584 = 2.0.0-beta.5 =
585 * **UX:** Save button now shows "Saving..." text during save operation instead of empty button
586 * **UX:** Removed redundant bottom "Salva le impostazioni" save button from form editor
587 * **PHP 8:** Fixed "Unsupported operand types: null + array" error when creating new forms
588 * **Translation:** Added "Saving..." string to translation files (.pot regenerated)
589 * **Technical:** Updated CSS version 69, JS version 25 for cache busting
590
591 = 2.0.0-beta.4 =
592 * **Accessibility:** Replaced jqColorPicker library with WordPress native wp-color-picker (Iris)
593 * **Accessibility:** Color picker now fully WCAG 2.2 AA compliant with keyboard navigation and screen reader support
594 * **Accessibility:** Full European Accessibility Act compliance for color selection fields
595 * **UX:** Fixed dropdown caret positioning - added proper right padding (2.5em) for visual clarity
596 * **UX:** WordPress color picker provides familiar interface for administrators and better mobile/touch support
597 * **Performance:** Removed external jqColorPicker dependency - uses WordPress core functionality
598 * **Technical:** Color picker callbacks ensure proper hex color format with # prefix
599 * **Technical:** Updated ColorPicker.php element class to use wpColorPicker() method
600 * **Technical:** Updated admin script enqueues to use wp-color-picker instead of jqColorPicker
601 * **Developer:** WordPress Iris color picker supports RTL languages and theme customization
602
603 = 2.0.0-beta.3 =
604 * **NEW:** Material Design "Inline Labels" layout option for forms
605 * **Accessibility:** Floating labels follow WCAG 2.2 Material Design guidelines
606 * **Accessibility:** Proper vertical centering and font sizing for readability
607 * **UX:** Consistent border styling across all field types (text inputs, textareas, dropdowns)
608 * **UX:** Firefox-compatible date field placeholder behavior (hides dd/mm/yyyy when empty)
609 * **UX:** Symmetric padding for better dropdown caret centering
610 * **Technical:** JavaScript date input value detection with .has-value class
611 * **Technical:** CSS fallbacks for cross-browser compatibility (WebKit + Firefox)
612 * **Translation:** Updated Italian and Spanish translation files
613 * Fixed: Border weight consistency - all fields now use 1px solid borders
614 * Fixed: Label vertical centering using CSS transform translateY(-50%)
615 * Fixed: Font size increased to 1rem for better readability
616
617 = 2.0.0-beta.2 =
618 * Fixed: Error message positioning on mandatory file upload fields
619 * Fixed: Error messages now appear after help text instead of overlapping it
620 * Improved: Correct visual order - Browse button → Help text → Error message
621 * Improved: Reduced excessive padding in file upload fields (1.2rem → 1rem)
622 * Technical: Updated client-side validation in AccuaForm.php (4 locations)
623 * Technical: Updated AJAX validation in Error/Standard.php (2 locations)
624
625 = 2.0.0-beta.1 =
626 * **NEW:** Cloudflare Turnstile Captcha field support (via Simple Cloudflare Turnstile plugin v1.35.0+)
627 * **MAJOR:** Complete file reorganization following WordPress plugin development best practices
628 * **MAJOR:** Comprehensive WCAG 2.2 and WAI-ARIA 1.2 accessibility improvements
629 * **Accessibility:** Added ARIA attributes (aria-required, aria-invalid, aria-describedby)
630 * **Accessibility:** Implemented real-time validation on blur/change events
631 * **Accessibility:** Auto-focus on first invalid field after form submission
632 * **Accessibility:** Inline error messages with role=alert and aria-live=polite
633 * **Accessibility:** Enhanced radio and checkbox field accessibility and error handling
634 * **Accessibility:** Added HTML5 required attributes for dual compliance
635 * **Accessibility:** Added accessible required indicators with aria-label
636 * **Accessibility:** Fixed duplicate id='dashboard_right_now' (13 instances removed)
637 * **UX:** Modernized error styling with clean compact design
638 * **UX:** Improved validation messages - clearer, more direct, field-specific
639 * **UX:** Removed unnecessary 'Attention:' and 'Error:' prefixes from messages
640 * **Translation:** Proper textdomain loading on plugins_loaded hook (WordPress best practice)
641 * **Translation:** Complete Italian translation with all new error messages
642 * **Translation:** Complete Spanish translation with all new error messages
643 * **Translation:** Removed incomplete German translation
644 * **Translation:** Generated new .pot template file
645 * **Files:** Moved all CSS files to `/assets/css/` with descriptive names (admin.css, dashboard.css, frontend.css)
646 * **Files:** Moved all JavaScript files to `/assets/js/admin/` and `/assets/js/frontend/`
647 * **Files:** Moved vendor libraries to `/assets/vendor/` (jqColorPicker, Chart.js, dragtable)
648 * **Files:** Moved all images to `/assets/img/`
649 * **Files:** Updated all asset references across 13 PHP files
650 * **Files:** Removed deprecated Flot charting library (27 files)
651 * **Files:** Added documentation (REORGANIZATION-2025.md, ASSET-LOCATION-REFERENCE.md)
652 * **Technical:** Updated asset version constants for cache busting (CSS v54, JS v15.0)
653 * **Technical:** Added PHP 7.4 minimum requirement
654 * **Technical:** CSS content fix to avoid charset declaration issues
655 * Fixed: Drag-and-drop functionality in form builder after reorganization
656 * Backward compatible with existing forms
657
658 = 1.9.14 =
659 * Added Cloudflare Turnstile field integration
660 * New field-based Turnstile implementation (drag-and-drop control)
661 * Works standalone or enhanced with Simple Cloudflare Turnstile plugin
662 * Backward compatible with existing forms
663
664 = 1.9.13 =
665 * Improved hostname detection for AJAX requests
666
667 = 1.9.12 =
668 * Removed "WordPress" from plugin name to comply with WordPress naming guidelines
669
670 = 1.9.11 =
671 * Improved dashboard widget access control for better security
672 * Enhanced permission checks and capability handling
673
674 = 1.9.10 =
675 * Tiny improvements for SEO and accessibility.
676
677 = 1.9.9 =
678 * Security improvements.
679 * Fixed several deprecation warnings when WP_DEBUG is enabled.
680
681 = 1.9.8 =
682 * Added support for Google Ads.
683 * To set a GADS conversion tracking code, go to Form Name > Appearance and General > fill the dedicated field with a GADS Conversion Code (es: AW-123456789/aaBBccDD)
684
685
686 = 1.9.7 =
687 * Enhance SQL query security following WordPress Best Practices
688 * Resolved path handling issues that prevented file uploads in Windows-based development environments like LocalWP
689 * Enhanced file upload security with proper MIME type validation
690 * Added download links for uploaded files on individual submission pages (previously, these links were only available on the list page)
691
692 = 1.9.6 =
693 * Fixed an issue that could cause PHP sessions to remain open, triggering WordPress Site Health warnings
694
695 = 1.9.5 =
696 * Minor fixes to previous version fix
697
698 = 1.9.4 =
699 * Fixed vulnerability - Missing Authorization to Unauthenticated Form Submission Download
700
701 = 1.9.3 =
702 * Matomo support for tracking field filled in and form submissions as events
703 * Fixed CSRF vulnerability
704
705 = 1.9.2 =
706 * Reverted an incorrect fix in the previous version
707
708 = 1.9.1 =
709 * Hardening for potential SQL injection vulnerabilities
710
711 = 1.9.0 =
712 * Checks for unfiltered_html capability and supports limited admin permissions in WordPress multisite configurations
713 * Filters the list of allowed upload file extensions according get_allowed_mime_types(), and check the maximum upload size with wp_max_upload_size()
714 * Default date fix
715 * Other minor fixes
716
717 = 1.8.0 =
718 * Using tinyColorPicker on frontend
719 * Fixed XSS vulnerability
720
721 = 1.7.0 =
722 * Lead status
723 * Minor fixes
724
725 = 1.6.1 =
726 * Fixed trashed form restore
727 * Fixed CSRF vulnerability
728
729 = 1.6.0 =
730 * IP masking option
731
732 = 1.5.10 =
733 * Fixed plugin icon
734
735 = 1.5.9 =
736 * Fixed adding more custom HTML fields and fieldsets
737
738 = 1.5.8 =
739 * Fixed CSRF vulnerabilities
740 * Fixed some JavaScript errors due to WordPress filters
741 * Fixed many minor bugs
742
743 = 1.5.7 =
744 * tested compatibility with WordPress 6.2.0
745
746 = 1.5.6 =
747 * Fixed CSRF vulnerability
748
749 = 1.5.5 =
750 * Fixed XSS vulnerabilities
751
752 = 1.5.4 =
753 * Graphical changes to default messages
754 * Fixed some minor bugs
755
756 = 1.5.3 =
757 * Removed unused code
758 * Fixed some minor issues
759
760 = 1.5.2 =
761 * Fixed critical error when trying to access the dashboard
762
763 = 1.5.1 =
764 * Renewed UI
765 * Fixing some minor bugs
766
767 = 1.4.14 =
768 * Lazy load reCAPTCHA
769
770 = 1.4.13 =
771 * added html attributes to improve SEO
772
773 = 1.4.12 =
774 * Tested compatibility with PHP up to 8.0 and WordPress up to 5.8.1
775 * reCAPTCHA loaded from recaptcha.net trying to improve accessibility from countries banning google.com domain
776 * Fixed minor XSS vulnerability reported on wpscan.com by Felipe Restrepo Rodriguez and Sebastian Cruz Cardona. Form title was not sanitized in every place it was used in the admin interface, however this is mitigated by the fact that only admin users with manage_options capability can edit it.
777
778 = 1.4.11 =
779 * avoid "headers already sent" warnings during WordPress cron
780
781 = 1.4.10 =
782 * Tested compatibility with PHP up to 7.4
783 * After submission, the fragment #formSubmitSuccess-formID is added to the URL, so the page is scrolled to the top of the message, and it's easier to track the submission with tools like Google Analytics
784 * fragments #formSubmitInvalid-formID and #formSubmitError-formID are added in case of invalid submission or error
785 * improved loading of reCAPTCHA
786 * removed unused resources from PFBC library
787 * colorPicker styles and javascripts now loads only if it's used
788 * other small bugfixes
789
790 = 1.4.9 =
791 * improved compatibility with Google Tag Manager to track field filled in and form submission
792
793 = 1.4.8 =
794 * fixed compatibility issues with php 7.2
795 * option to track field filled in and form submission as events on Google Analytics
796 * workaround to open/download attachments in submissions exported and opened with Microsoft Excel
797
798 = 1.4.7 =
799 * fixed compatibility issue with WordPress 4.8 that made show/hide buttons for field settings in the form editor invisible
800 * fixed compatibility issues with php 7.0 and 7.1
801 * fixed strict standards errors
802
803 = 1.4.6 =
804 * restored compatibility with PHP < 5.3
805 * fixed some strict standards errors
806
807 = 1.4.5 =
808 * Scaled reCAPTCHA 2 area for devices with less than 400px screen width
809 * More informations about senders and receivers of the form emails in the forms list page
810
811 = 1.4.4 =
812 * Changed text domain of translatable strings to match the plugin slug
813 * Bulk action to delete permanently trashed submissions
814
815 = 1.4.3 =
816 * Fixed table index length issue that prevented saving submission values of new user of Contact Forms with recent WordPress versions
817 * Added internationalization info
818
819 = 1.4.2 =
820 * Fixed table definition error that prevented saving submission of new users of Contact Forms 1.4.0
821
822 = 1.4.1 =
823 * Fixed undefined variable in accua-form-api.php on line 29
824
825 = 1.4.0 =
826 * Filter and export by year and month
827 * Added actions accua_forms_field_added, accua_forms_field_updated and accua_forms_field_deleted
828
829 = 1.3.9 =
830 * better support for reCAPTCHA allowing to enter site keys and use version 2
831 * fixed visualization bug of reCAPTCHA 1 with new WordPress themes
832 * fixed bug that prevented editing fields on the page after a form submission
833
834 = 1.3.8 =
835 * fixed incompatibility with WordPress 4.4 that prevented submissions export
836
837 = 1.3.7 =
838 * fixed incompatibility with WordPress 4.4 that caused a PHP error in every page that includes a form
839 * new token for select, checkbox and radio labels
840 * changed database table to allow referrers and urls longer than 255 characters
841
842 = 1.3.6 =
843 * Replaced deprecated user level '10' with capability 'manage_options'
844
845 = 1.3.5 =
846 * fixed incompatibility of form editor with WordPress 4.3 and Chrome
847 * adding rules to robots.txt to allow /wp-admin/js/ and /wp-admin/css/ for styles and scripts included from that folders
848
849 = 1.3.4 =
850 * Password fields now saves the hash value of the password using wp_hash_password
851 * Field to set the emails "From:" name
852 * fixed CAPTCHA field incompatibility with CloudFlare RocketLoader and possibly other JavaScript optimizer
853 * fixed glitch in the "Form fields" area on the "Edit form" page with latest versions of WordPress
854
855 = 1.3.3 =
856 * improved checkboxes, select and radio definition to allow pre-selected options
857 * fixed PHP 5.5 incompatibility issue. Now the plugin works with PHP from version 5.2 to 5.5
858 * fixed default value for email, colorpicker and password fields
859 * allowed removal of elements by a filter after the form generation
860
861 = 1.3.2 =
862 * fixed visualization of color picker field
863 * workaround to have multiple forms with recaptcha on the same page
864
865 = 1.3.1 =
866 * fixed validation of required fields with multiple values
867 * show recipient of admin email in form list
868 * changes in submissions list generation and export to allow usage by other plugins
869
870 = 1.3 =
871 * Spanish translation by Maria Ramos of [WebHostingHub](http://www.webhostinghub.com/)
872 * Color picker field
873 * Possibility to insert raw tokens in html messages
874 * Disabled HTML5 validation of email fields, using JavaScript validation
875
876 = 1.2.1 =
877 * Fixed installation and upgrade process issues introduced in 1.2
878 * Users who installed 1.2 as their first version reported that submissions where not saved. Upgrading to this version will fix this issue
879
880 = 1.2 =
881 * Fieldsets
882 * Submissions trash and restore
883 * Fixed counting of active and deleted forms
884 * Fixed submission bug in Internet Explorer 8 and previous versions
885
886 = 1.1 =
887 * Added interface to set basic form styles (borders, colors, padding)
888 * Fixed captcha validation
889 * Added submission graph by form
890 * Screenshots removed from the package
891 * Other minor fixes