Fixed: “The form has expired” on cached sites — the anti-spam time token is now set client-side, so page caches (WP Rocket, Cloudflare) no longer freeze it.
Fixed: “Security token invalid” on heavily cached sites — the submit nonce is refreshed from an uncached endpoint and auto-retried, so forms keep working even when the page has been cached for over a day.
Fixed: Math CAPTCHA on cached sites — the CAPTCHA token is now cache-safe and no longer fails for every visitor once the page cache outlives the old token.
Fixed: Saving the form title from the builder toolbar — the toolbar Save now persists the title, description and status (previously the toolbar/Ctrl+S save only stored field changes; in some setups it even navigated to a blank page).
Fixed: Success-window check icon not showing — the checkmark is now visible even when its draw animation does not run (power-saver, some mobile browsers).
Fixed: Math CAPTCHA hardening — the answer token is now bound to the form and validated from the form schema, so the check can no longer be skipped by omitting the token field.
Fixed: Clearing the form title in the builder no longer overwrites the saved title with an empty value.
Fixed: Design “Reset” no longer fired a duplicate confirmation dialog.
Fixed: Field widths on mobile — text areas, checkboxes and full-width fields now span the full width like text inputs.
New: Modern success window after submitting — animated checkmark with separate heading + description fields (Settings → After submission).
New: Per-device design tokens — tune font sizes, spacing and button sizes separately for tablet and phone in the Design editor.
Improved: “Save & Continue” now uses sessionStorage with a 12h limit and an opt-out setting (privacy/GDPR).
New: Per-form SMTP routing — assign different mail servers to different forms via Settings → SMTP → “Per-profile SMTP accounts” and the new “Send via” picker in each email profile.
New: Failover SMTP — if a primary account fails, a configured backup account delivers automatically. Recovery events are logged in Settings → Email Settings → Deliverability.
New: Drag any form field directly onto a different step-tab in the form builder toolbar to move it across steps.
New: Colour picker now has a transparency slider that fades the picked colour toward white.
Improved: SMTP account host is now required on save (server-side validation prevents broken rows).
Improved: Mail-error log entries distinguish between hard failures and successful failover recoveries.
Improved: Existing global SMTP settings are automatically migrated into a “Default SMTP” account on update.
Fixed: Stale wp_mail_failed reasons no longer leak between consecutive sends.
2.8.3
Fixed: Elementor widget — removed the broken “field layout / 2 columns” option that forced fields to full width. Forms now render consistently in a single column; use per-field widths (½, ⅓ …) for multi-column rows.
Improved: form is reliably capped to your configured max width and centered, even inside full-width Elementor sections; verified zero horizontal overflow from phone to desktop.
2.8.2
New: 6 refined design presets in the Design Configurator (Ocean Navy, Sky Blue, Cyan Tech, Royal Purple, Sunset Orange, Slate Pro) — Ocean Navy is the default theme.
New: Guided 3-step onboarding on the dashboard to help you set up your first form, email and spam protection.
New: Adjustable textarea height — set the number of rows (1–10) per textarea field in the builder.
Performance: form assets now load only on pages that actually contain a form, and CSS/JS are shipped minified — faster page loads across your whole site.
Improved: single-step forms no longer show a redundant “Step 1” heading.
Improved: import is now available directly from the empty Forms screen (templates & bundles).
Improved: consistent default colour scheme across the form, design and email screens.
Fixed: textarea fields no longer rejected on submit when longer than their row count.
2.8.1
New: Email Profiles — reusable email setups (customer + admin notifications) with a live preview, configurable colours and an optional header gradient picker.
New: Modernised field inspector — settings are now grouped into clean cards (Field basics · Behaviour & display · Custom CSS) with rounded, consistent inputs.
New: Design configurator improvements and a shared custom colour picker across the design and email screens.
Improved: Accessibility — visible keyboard focus rings across the builder, design and frontend form.
Fixed: Form submission reliability — the submission endpoint is now registered independently of optional integrations, so every form submits correctly.
Fixed: the {field:email} placeholder in the email “To” field is now preserved on save.
Fixed: field-palette category icons and several admin UI polish issues.
2.7.4
New: File uploads now work end-to-end — single and multiple file fields upload to your Media library folder (with file-type and size validation) and appear as download links on each entry.
New: Repeater and ZIP lookup fields are now available directly in the builder’s field palette.
Fixed: conditional logic now supports every operator (equals, not equals, contains, greater/less than, starts/ends with, is empty / is not empty) for both field-level and step-level rules, and re-evaluates correctly across steps.
Fixed: required validation for multi-checkbox groups, plus minimum/maximum character-length checks on text fields.
Fixed: Entries screen now supports search, status filtering and pagination, and the CSV export is hardened against spreadsheet formula injection.
Fixed: the Design configurator no longer loses a custom font family on save, and the “Reset” button restores the true defaults again.
Fixed: Save & Continue is now stored per form and clears automatically after a successful submission.
Improved: textarea line breaks are preserved in stored entries; the form focuses the first invalid field; double submissions are blocked; and several remaining hardcoded strings are now translatable.
2.7.3
Fixed: saving the General settings tab no longer wipes the Email-template settings (and vice-versa) — each tab now saves only its own fields. This also stops the admin notification address and the honeypot/analytics toggles from being reset.
Fixed: the “Confirmation message” and “Redirect URL” fields are visible again on the Settings screen (a broken script kept both rows hidden).
Fixed: “Redirect to URL” after submission now actually redirects (the saved option was read under the wrong name).
Fixed: spam protection no longer blocks legitimate submissions on forms that contain an unrelated field whose name ends in “_token”.
Fixed: leaving a field’s min/max length empty in the builder now means “no limit” again instead of forcing it to 0.
Fixed: importing a form/template with incomplete conditional-logic rules no longer creates broken rules or warnings.
Fixed: entry detail no longer double-encodes form titles that contain “&” or special characters.
Improved: a saved global e-mail heading is now used for customer confirmations; hardened a few output paths against PHP 8.1 notices.
2.7.2
Fixed: floating labels now display correctly on the public form — the field label sits inside the field as a placeholder and lifts up on focus/fill (a bulletproof CSS rule was forcing the label to stay bold and static on forms that use the Design configurator).
Fixed: removed a broken script on the form editor screen that threw a JavaScript console error (a stray template artifact).
Fixed: creating a form from a template now generates a clean slug (e.g. “contact”) instead of carrying the internal template prefix (e.g. “tpl_contact”).
Fixed: the form-editor preview button now reads “Submit” instead of a leftover checkout label.
2.7.1
New: Step-abandonment analysis in Form Analytics — a visual funnel showing exactly which step visitors reach before leaving an unfinished form, with the drop-off rate and the field they last touched at each step.
Improved: clearer “where visitors stop” reporting to pinpoint the steps and fields that cost you conversions.
2.7.0
New: Form Analytics — a privacy-first conversion dashboard. See views, start rate, conversion rate, average time-to-complete, a step-by-step funnel, where visitors drop off, which fields throw the most errors, plus device and traffic-source breakdowns. No cookies, no IP, no personal data — anonymous and aggregated, with an automatic data-retention cleanup and a Do-Not-Track option.
New: privacy controls under Settings → “Analytics & privacy” (enable/disable tracking, honour Do-Not-Track, set retention days).
Design: the public-facing form is fully redesigned — modern floating labels that sit inside each field and lift up on focus, softer inputs, a clearer focus ring, and primary buttons with subtle depth and a smooth hover lift.
Added: a trust line under every form (“Spam-protected · GDPR-compliant”).
Improved: the entire plugin (admin + frontend) now shares one consistent brand colour system.
Fixed: the focus ring and the red “invalid field” border are reliably visible again (a defensive style reset was hiding them).
Maintenance: uninstall now also removes view counters, analytics tables, the retention cron and orphaned per-field options.
Note: floating labels apply to text, email, phone, URL, number, password, textarea, select and date/time fields; choice, file, rating and composite fields keep their static labels for clarity and accessibility.
2.5.9
Design: unified the entire admin colour scheme to a single brand blue (previously 5 different blue tones were mixed across screens)
Design: redesigned the “Create New Form” screen — colourful template icons, a feature highlight bar, a clear “start from scratch” entry, hover states and full-width gallery
Improved: template meta now uses correct singular/plural (“1 step” vs “3 steps”) and is fully translatable
Fix: creating a form from a template now opens the editor correctly instead of a blank screen (import routine now returns the new form ID)
Fix: the email template editor now saves all fields — greeting, footer, recipient, CC, BCC, custom HTML and field selection were previously discarded on save
Fix: conditional logic rules are now stored correctly (the save handler read the wrong field keys, so rules were saved empty and never applied on the frontend)
Fix: the password field strength meter now renders and works (a duplicate switch case had disabled it)
Improved: admin notification emails now set Reply-To to the submitter’s address, so replying goes straight to the lead
Improved: deleting a form now also removes its entries, entry fields and view stats (no more orphaned rows)
Security: email From header is stripped of CR/LF to prevent header injection via stored settings
2.5.7
Maintenance: removed non-WordPress.org contributor handle from the Contributors header (silences the import warning shown only to plugin authors)
2.5.6
Compliance: radio-card label now escapes the raw option value via esc_html() at the output site (no longer relies on a pre-escaped variable Plugin Check cannot trace)
Compliance: the TTL-preserving rate-limit counter increment on wp_options now carries an explicit Plugin Check annotation explaining why the transient API cannot be used here
2.5.5
Compliance: added /* translators: */ annotations to every __()/esc_html__() call that uses placeholders (Plugin Check requirement)
Compliance: replaced rand() with wp_rand() in the math-captcha renderer
Compliance: every wp_redirect() in admin page callbacks replaced with wp_safe_redirect()
Compliance: explicit output escaping for $total_unread and radio-card alt attributes
Compliance: error_log() debug calls gated behind WP_DEBUG + WP_DEBUG_LOG (no production logging)
Documentation: class-level PHPCS justifications added to UltimateForm_Admin and UltimateForm_Form_Manager explaining the plugin’s custom-table architecture, the nonce-verification helper indirection, and the intentional cache bypass
2.5.4
Fix: registered the public REST route ultimateform/v1/checkout that the frontend form engine posts submissions to (this route was previously only shipped with the Pro edition, which left the free version unable to submit forms)
Improved: client IP resolution falls back through CF-Connecting-IP, X-Forwarded-For and REMOTE_ADDR, with strict IPv4/IPv6 validation
Improved: confirmation message is now passed through wp_kses_post() before output
2.5.3
Hardened output escaping in the upgrade comparison table (per-cell if/else instead of conditional echo expressions)
Field renderer attribute output split into separate echo statements with explicit per-line phpcs annotations
2.5.2
Security: added nonce verification to the entry-detail admin screen before marking an entry as read (prevents CSRF state changes via crafted GET URLs)
Compliance: removed the Plugin URI header (no broken external link in the directory listing)
Compliance: contributor list now includes the WordPress.org account that owns the plugin
2.5.1
Security: recursive sanitization for all JSON-decoded administrator inputs (logic, conditions, visible_fields, import payloads)
Security: all REST endpoints use a custom permission callback with rate limiting (no __return_true)