Added
- Add console commands to inspect unresolved payments, reconcile gateway status, record verified outcomes and resume submission processing.
- Add extensible TipTap nodes, marks, toolbar controls, and constrained TextStyle definitions across Formie editing, previews, and PHP rendering, including opt-in font family, font size, text/background color, line height, and Small caps controls.
Changed
- Pin Formie's bundled TipTap and ProseMirror graph to
3.22.4so extension code shares one qualified runtime. - Stream all report export formats, including Excel, JSON and XML, and preserve the initial submission order while reading batches.
- Align documentation filenames with page titles and update internal links.
- Manage dashboard chart dependencies through the package lockfile so dependency audits cover shipped widget scripts.
- Improve documentation for submission access, GraphQL clients, saved drafts, report delivery and integration setup; separate detailed reference material from walkthroughs.
- Update frontend and test dependencies to patched releases, and resolve the frontend documentation theme from its published package.
- Normalize CP General Settings to the shared
verbb-basesettings layout (Settings → Plugins → Formie crumbs,pageTabs/pageTitle/pageActionhelpers) and trimpluginNameon save. - Bump transitive
symfony/cacheto6.4.45(CVE-2026-45073 advisory floor).
Fixed
- Preserve dynamic payment amount field selections when saving payment field settings.
- Fix Zoho picklist mappings sending option metadata IDs instead of their API values. (#2959)
- Reject invalid date filters before deleting submissions from console commands.
- Preserve submission edits made while queued field moves are running.
- Preserve form fields and submission data when restoring deleted forms, and clean up child submissions and configured uploads on permanent deletion.
- Preserve zero values in group and repeater value projections.
- Enforce unique values for fields inside groups and repeaters.
- Stop enforcing saved number bounds in server and client validation when limits are disabled.
- Compare and sort Number fields numerically while preserving large values and decimal precision.
- Match blank submission answers correctly in empty filters without confusing them with the text “null”.
- Apply selected submission states consistently to report summaries, tables, charts and exports.
- Load report charts and summaries on PostgreSQL.
- Include the selected End Date in scheduled report delivery windows.
- Skip duplicate scheduled report deliveries from overlapping cron runs.
- Sort report tables and exports by the displayed form name.
- Allow report managers to use report exports and retrieve their queued downloads.
- Preserve configured form availability across sites when an editor has access to only some sites.
- Resolve editable form sites for the requested user instead of the current session.
- Load the form builder consistently with pretty URLs and Craft query routes.
- Preserve group site restrictions when a manager has access to only some sites.
- Keep created-site-only forms on their source site when group availability changes.
- Apply group site policy changes to forms on every site, including forms outside the current editor’s view.
- Honor the selected site when looking up forms that are unavailable on the primary site.
- Keep cached form lookups isolated to the requested site.
- Resolve cached form lookups using the selected control-panel site.
- Include regional forms in permission settings, GraphQL schemas and submission queries.
- Preserve explicit GraphQL form filters when selecting submission fields through inline fragments.
- Preserve unique form handles and recognize shared settings in use across every site.
- Resolve numeric form-status filters correctly.
- Respect form site availability when filtering by form status.
- Restore configured form availability on secondary sites when upgrading existing installations.
- Include regional forms in report choices, summaries and scheduled exports.
- Preserve explicitly selected form sites when loading submission fields in the control panel.
- Preserve historical submission fields and exports after form site availability changes.
- Process regional forms in queued field moves and console export and cleanup commands.
- Re-save regional submissions and return accurate console exit codes.
- Report failed notification and integration deliveries accurately in console commands.
- Keep per-form integration settings isolated when running bulk console commands.
- Apply configured file-upload retention to forms on every site.
- Allow existing fields and notifications to be selected with the keyboard.
- Honor per-form permissions in form and submission indexes and GraphQL operations.
- Load form indexes for users without permission to create forms.
- Require all visible payment fields to be on the final submission page before processing payments.
- Fixed a rate limit bypass vulnerability.
- Fixed a CSRF vulnerability.
- Fixed information disclosure vulnerabilities.
- Preserve every report export column when labels repeat, and retain numeric labels as JSON object keys.
- Keep unresolved earlier payment attempts blocked until their gateway outcome is verified.
- Route users with settings page permissions to a page they can access.
- Fix submission queries on Craft 5.0.
- Create default statuses and the Contact Form stencil when installing on Craft 5.0.
- Save form group settings on all supported Craft 5 versions.
- Configure Stripe payment fields on all supported Craft 5 versions.
- Open form preview slideouts on all supported Craft 5 versions.
- Display custom form and submission statuses on all supported Craft 5 versions.
- Load form condition rules on all supported Craft 5 versions.
- Apply empty and non-empty relation filters consistently to submission queries on all supported Craft 5 versions.
- Preserve queued integration failure events on all supported Craft 5 versions.
- Render notification emails on all supported Craft 5 versions.
- Preserve custom decimal-field query precision on all supported Craft 5 versions.
- Preserve zero, false, and empty submission values when moving fields into or out of groups.
- Preserve submission answers when moving fields between groups or removing their former group, including disabled forms.
- Allow saved submissions to continue through later pages without triggering their own IP throttle.
- Require POST requests when importing forms or migrating from another form plugin.
- Allow settings page permissions to be assigned independently while preserving access to all settings for existing roles.
- Remove all Formie tables when uninstalling the plugin.
- Fixed an XSS vulnerability.
- Make frontend builds work from a clean checkout with published Plugin Kit packages and complete TipTap dependencies.
- Require POST requests for control panel deletion and notification resend actions.
- Allow settings save requests to resolve their posted settings page without an error.
- Return permission errors correctly when integration settings access is denied.
- Supply a document title for every beta settings page so Craft 5 can render them without adding a settings-content heading.
- Keep field error live regions mounted without reserving empty layout space, honour the configured announcement priority, and associate definition-driven errors with their controls. (#2954)
- Preserve payment attempts and gateway receipts across interrupted Moneris, Eway, BPOINT, Opayo, Mollie and Paddle requests, and stop ambiguous outcomes from triggering another purchase.
- Recover Eway payments by invoice reference and Mollie payments from verified webhook results when creation responses are lost.
- Preserve completed report downloads across queue retries, clean up interrupted export workspaces, report progress and reject incomplete output.
- Fix Mollie checkout initialization using the wrong redirect helper, and allow corrected attempts after explicit API rejections.
- Keep payment amounts aligned with their currency precision when retrying or reconciling payments.
- Keep asset rebuild tooling aligned with the current split Plugin Kit packages.
- Avoid charging an extra minor unit for decimal Stripe and Opayo amounts, and use Stripe's required UGX amount format.
- Fixed XSS vulnerabilities.
- Fixed payment verification vulnerabilities.
- Fixed an XML injection vulnerability.
- Include current frontend package fixes in production assets and reject builds that resolve outdated runtime copies.
- Enforce weekly submission limits on Sundays and keep calendar limit periods from overlapping.
- Use the correct currency minor unit when creating Paddle prices.
- Preserve legacy spam, CAPTCHA and field-default settings during upgrades, and refresh schema lookups after migration changes.
- Preserve restricted user and group submission access when upgrading from Formie 2.
- Migrate integration field-handle tokens to stable field references.
- Keep submissions arriving during scheduled report delivery eligible for the next export.
- Recognize array-based wildcard form selections in report field columns.
- Clone localized form layouts without serializing callbacks or mutating canonical form settings and notifications.
- Preserve typed dates when expiring subscriptions and archiving payment plans.
- Block shared-address, multicast, documentation and IPv6 transition networks in outbound automation requests.
- Migrate notification field-handle tokens to stable references when upgrading from Formie 3.
- Reject empty submission form scopes, enforce the requesting user's permissions for queued reports, and consume signed report download tokens atomically.
- Preserve scheduled report delivery cursors when exports or emails fail, and clean up temporary report files after failures and direct downloads.
- Keep successful Stripe payment intents from regressing on delayed webhooks, verify their integration, restore subscription invoice updates, and return retryable responses on processing failures.
- Refresh tokens on cached Twig-rendered forms before submission.
- Preserve saved report date bounds when sending incremental scheduled exports.
- Score submitted quiz answers using current field identities and option values.
- Persist completed submission state when replaying successful payment webhooks.
- Preserve Craft query-string routes in the form builder so saving and reloading keeps the editor available.
- Fix Freeform 5 migration imports and scope submission migration to the selected form ID.
- Give managed text inputs accessible names and focus the first invalid input after submission.
- Read current field structure metadata in managed frontend adapters.
- Allow client form bootstrap to obtain the CSRF token required for subsequent submissions.
- Format date variable presets using their PHP date patterns.
- Preserve field translations on import and field identities when updating existing forms from exports.
- Keep the form builder and existing-field picker available when an HTML field's Twig preview cannot render.
- Discard pending data uploads when a field is cleared, preserve them during partial-page merges, and apply nested field edits over stored UID values.
- Apply file size and detected-type validation to data uploads, and normalize client file payloads consistently with GraphQL uploads.
- Preserve both new and retained files in mixed GraphQL upload requests.
- Reject malformed GraphQL upload data without reusing another file’s contents, and accept files containing only
0. - Fix generic GraphQL submission saves failing to normalize form fields, and validate field and captcha maps against the selected form.
- Include saved nested field layouts in GraphQL input schemas and preserve explicit nulls when clearing nested submission values.
- Handle omitted optional Table column handles and Note styles, and retain values from Table columns without handles when rendering or exporting submissions.
- Fix HubSpot form mapping exposing and submitting only the first communication subscription consent checkbox.
- Fix CRM array mappings including option metadata instead of selected values, apply field-mapping event changes to outgoing payloads, and format Pardot multi-select values consistently.
- Verify PayPal authorization/capture amount, currency, status and submission association; persist request identities and reconcile interrupted or pending captures.
- Reuse PayWay transaction identities within its retry window, verify transaction ownership and amounts, and reconcile pending payments.
- Protect streamed CSV/TSV report values and headings against spreadsheet formula injection.
- Preserve cleared submission values, including empty checkboxes, tables and dates, through serialization and apply hidden-field clearing during CP edits.
- Prevent nested shared-field saves from overwriting updated labels; preserve shared definitions in nested layouts and stencil materialization.
- Duplicate form layout trees without serializing runtime callbacks or mutating the source layout.
- Fix native JSON stencil persistence, date import settings, checkbox coercion, blank password validation and empty Other-option validation.
- Compare encrypted recipient condition payloads rather than randomized ciphertext.
- Fix report date-filter migration, current project-config palette/group updates, and defaultable validation settings.
- Handle missing payment providers during field rendering and return a boolean for unconfigured Mollie settings.
- Resolve stable field references when generating notification preview recipients and isolate cached values between previews.
- Fix missing schema helper import when rendering reCAPTCHA form settings.
- Persist delivery attempt identities before external calls, stop uncertain integration/email retries, and checkpoint individual notifications.
- Reuse Square payment keys; recover Stripe customer, payment intent, subscription and schedule creation; reconcile GoCardless payment/subscription duplicate-key responses.
- Queue status-change notifications atomically with element transactions, even when ordinary notification delivery is synchronous.
- Store integration dispatch context as native JSON and read existing double-encoded context during submission hydration.
- Checkpoint successful queued integration steps so retries skip completed steps and resume failed delivery.
- Ignore stale frontend responses after reset or a newer navigation/refresh operation.
- Fix form factories exhausting automatic handles or generating Craft-reserved handles.
- Fix client-side payment authorize still requiring a Stripe/provider token when the Payment field is hidden by conditional logic (e.g. bank transfer vs card) — authorize and mount now skip fields marked conditionally/row/page hidden, matching server-side payment workflow skips.
- Fix “Restore In-Progress Submissions Automatically” still restoring incomplete submissions on revisit when disabled — server render no longer hydrates from leftover progress, and submit/client continuation ignore bare progress unless the browser already holds that submission (or a resume/continuation token). Resume links are unchanged.
- Fix anonymous File Upload hydrate/delete treating form+field+asset ID as authorization — issue an unguessable upload capability token on upload (and when rendering existing assets), require it for hydrate/delete, and restrict submission-linked hydrate to CP view permission, matching draft progress, or a verified resume/continuation token.
- Fix automation HTTP clients following redirects after the public-endpoint SSRF guard — outbound automation requests no longer follow redirects (shared by Web Request / Zapier / Make / n8n).
- Fix automation outbound requests racing DNS between public-IP validation and connect — absolute automation URLs pin
CURLOPT_RESOLVEto a re-validated public IP (rebinding-resistant with redirects already disabled). - Fix the double-encoded submission content repair migration using MySQL-only
JSON_TYPE— detect double-encoded payloads in PHP so PostgreSQL upgrades succeed. - Fix orchestrated integration queue jobs acknowledging unsuccessful
IntegrationResponseresults as successful —IntegrationExecutornow returns structured results andTriggerIntegrationfails the job on unsuccessful steps. - Fix integration “stop on failure” only applying inside one immediate/queued batch — failure with stop now prevents later phases from running.
- Fix per-notification “after integrations” timing being skipped when the form-wide default is before integrations — the after phase runs whenever any notification needs it.
- Fix dispatch notification/integration/spam stages using check-then-act markers — stages are claimed atomically before side effects (at-most-once on crash after claim).
- Fix replay-protection tokens being consumed only after dispatch — claim the token at dispatch start (
cache->add) so concurrent completes cannot double-deliver notifications/integrations. - Fix payment status polling still requiring a client-supplied
paymentUidafter opaquestatusTokenresolution — the token alone is the capability. - Fix payment and subscription lookups loading the entire history into memory — ID/UID/reference/submission queries are scoped in SQL.
- Fix missing
formie_payments.submissionIdindex for hot payment lookup/poll paths (Install + migration). - Fix questionnaire results re-decoding every submission content blob per question — content is decoded once per aggregation run.
- Fix
@verbb/formie-coreREST transport dropping Craft subdirectory install paths when resolving action URLs from absolute endpoints. - Fix
@verbb/formie-coreform instances accepting concurrent submits and applying transport results afterdestroy()— overlapping submits are rejected and destruction is terminal. - Fix form
csrfInput: falsebeing ignored because Twig??treated explicitnullas missing — null now omits the CSRF field; default CSRF stays sync sodata-formie-csrfis present for Formie refresh JS. - Fix Upload Manager returning “Invalid file upload field” when a File Upload field is nested under a Group (and related nested content-key paths), and writing staged asset ids under the correct nested input names. (#2948)