Gatilab Products

Changelogs

Improvements, fixes, and the details behind each release.

All Products

Release history across our plugins and themes.

Stable

Functionalities 1.4.7

Read release notes

What's Changed

  • Added: When "Assign fonts to body text and headings" is enabled, the block editor canvas now receives explicit .editor-styles-wrapper font-family rules (the assigned family plus a system-font fallback) for body and headings, so the editor matches the front end even when the theme.json typography assignment doesn't reach the iframe.
  • Fixed: Custom fonts now render inside the block editor canvas. The editor is an iframe (WP 6.3+/7.x) that ignores src-less inline styles, so @font-face is now injected through the editor styles setting — the same channel the Font Library and add_editor_style() use.
  • Fixed: Variable-font weight ranges with an out-of-spec low bound (e.g. 1 900) are normalized to 100 900. WordPress was silently dropping these faces — and their entry in the editor font picker — when validating theme.json.
  • Fixed: Components module CSS now reaches the block editor canvas reliably via the editor styles setting. The previous inline fallback could not cross into the WP 7 iframe when the generated CSS file was unavailable.
  • Changed: Removed the redundant admin_head font print. It reached only the parent admin document, never the editor iframe, and is superseded by the editor styles channel.
  • Housekeeping: Documented a single source-of-truth matrix for the font-loading paths and removed stale per-file @version docblocks that had drifted from the plugin version.

Commits

  • v1.4.7: block-editor font fixes, weight normalization & housekeeping (468f285)
Stable

Core Forms 4.3.2

Read release notes

Core Forms 4.3.2

  • Optimized frontend asset loading so forms.js, accessibility.js, analytics.js, and form styles load only when a Core Forms block or shortcode is present.
  • Removed redundant Core Form block viewScript metadata because rendered forms enqueue the runtime directly.
  • Added tests for form asset detection, including a poll-only case.
  • Synced release requirements to WordPress 6.4+ and PHP 8.1+.

Zip SHA-256: 1eb8f317ed899596f1df041fa84e501e72a191c9367b4a9adb4c4487557cc052

Stable

Core Forms 4.3.0

Read release notes

Stable release. Marks the end of the v4.3 beta cycle (beta1 → beta6).

Polls — full rework

Tabbed editor (Question / Settings / Schedule / Embed / Results), drag-to-reorder options, "Other" write-in toggle, Duplicate row action.

Vote integrity rewrite: every vote stores a voter_hash (poll + IP + UA + cookie + user) and dedupe queries that one column regardless of mode. Cookie set on render with SameSite=Lax; Secure, persists across AJAX. vote_limit=user rejects anonymous voters at submit. Honeypot on by default, per-IP rate limiter (12/minute).

Scheduling (start date + hourly cf_poll_auto_close cron), change-vote window, Gutenberg block (core-forms/poll) with picker + display-mode, opt-in live results (15s, pauses on hidden tab), bar / columns / percent result styles, container-query-driven adaptive layout, REST API (/cf/v1/polls, /polls/{id}/results public, /polls/{id}/analytics auth), per-poll analytics screen + CSV export.

Accessibility: <fieldset><legend>, role="progressbar" with aria-valuenow, role="status" aria-live="polite", focus moves to result heading on submit, prefers-reduced-motion honored. jQuery removed from poll JS.

Schema migration (cf_db_version → 4.3.0) is additive with backfill so historical dedupe keeps working.

Importers — three new sources

  • Gravity Forms — GFAPI-driven, ~14 field types, notifications → Email actions with per-recipient conditions, confirmations → success message / redirect, conditional logic → data-show-if / data-hide-if. Field IDs resolve through a per-form name map so condition references stay valid.
  • WPForms (Lite + Pro) — Decodes the form JSON, maps notifications, optional entry import from wp_wpforms_entries (Pro) into wp_cf_submissions so admin history survives the cutover.
  • Fluent Forms — Reads wp_fluentform_forms + wp_fluentform_form_meta directly (no plugin dependency), maps fields, notifications, webhooks, and conditional logic.

All three plug into the existing Core Forms → Import page via a new cf_import_sources filter + cf_import_render_section action exposed by CF7Migration, with shared helpers in a BaseMigration abstract class.

Send Email — conditional emails (per recipient)

New "Recipient routes" repeater on the Send Email action. Each route has a field + operator + value + recipient address; the first matching route's recipient overrides the default To. The existing action-level conditions block keeps working — that gates whether the action runs at all; routes only re-target where it sends.

Forms list

Fix for the Duplicate row action: it used to drop the user into the editor for the original form because the URL carries a form_id and the overview page short-circuited into the editor before the list table's single-row handler could run.

Build & CI

ESLint inheritance cleared (~80 prettier autofixes + targeted eqeqeq / no-unsafe-wp-apis / no-noninteractive-element-interactions fixes); PHPStan baseline regenerated at level 5; PHP 8.1 / 8.2 / 8.3 unit tests green.

Upgrade notes

  • Migration is automatic on next admin pageload (or on plugin update via upgrader_process_complete).
  • New WP-Cron hook cf_poll_auto_close is scheduled hourly; unscheduled on deactivation.
  • New post meta keys for importer provenance: _cf_gf_source_id, _cf_wpforms_source_id, _cf_fluent_source_id — useful for debugging or re-import workflows.
Beta

Core Forms 4.3.0-beta6

Read release notes

Pre-release. Bug-fix pass on the beta5 importers and conditional emails.

Fixes

  • Per-recipient conditions never actually filtered the recipient. The three new migrators (Gravity, WPForms, Fluent) were saving conditions on Email actions using op / is / isnot, but cf_evaluate_action_conditions() consumes operator / equals / not_equals. Empty-operator rows were being skipped entirely, so every recipient match returned true and every notification fired regardless of the source plugin's conditional logic. Now writes the keys/vocab the engine actually understands.

  • Gravity / WPForms conditional logic referenced nonexistent field names. Both plugins reference fields in their rules by numeric ID. Our import was naively emitting field_<id> references while the rendered HTML used sanitize_key(label) names — so the data-show-if attributes pointed at fields that didn't exist on the page. Each migrator now builds a per-form field-id → rendered-name map up front and translates references through it.

  • Rendered field names collided when two source fields shared a label. sanitize_key('First Name') → firstname for every field labelled "First Name". Names now always carry an _<id> suffix so duplicates stay distinct (and empty labels still get field_<id>).

  • data-show-if attribute syntax was wrong. The runtime parser (in assets/js/forms.js) expects field:value, not field=value, and uses data-hide-if to express inversion rather than != inline. BaseMigration::build_conditional_attr() now emits the syntax the runtime actually parses and flips show↔hide when the rule is negated.

  • WPForms entry count now shows in the success notice. The importer was redirecting back with entries_total in the URL but nothing rendered it. The CF7 importer page now shows "(N entries imported too)" alongside the "Imported X forms" notice.

Install on staging only. Real installs stay on 4.2.10 until stable 4.3.0.

Beta

Core Forms 4.3.0-beta5

Read release notes

Pre-release. Ships the four "Shipping now / v4.3" items from the public roadmap.

What's new

Gravity Forms importer

Reads forms via GFAPI, converts fields (text/email/phone/url/number/date/textarea/select/multiselect/radio/checkbox/file/name/address/consent and friends) to HTML. Every notification becomes a Send Email action — and when the source notification had its own conditional-logic block, that block carries across as per-recipient conditions on the Email action. The default confirmation maps to the success message or redirect URL. Field-level conditional logic carries across as data-show-if / data-hide-if attributes. Source Gravity Forms data is never modified.

WPForms importer (Lite + Pro)

Decodes the form JSON stored in wp_wpforms.post_content, converts the field map to HTML, turns each notification into an Email action (with per-recipient conditions when applicable). When the Pro wp_wpforms_entries table is present, optionally imports stored entries into wp_cf_submissions so admin history isn't lost during the cutover.

Fluent Forms importer

Reads wp_fluentform_forms + wp_fluentform_form_meta directly — no Fluent API dependency, so the importer also works on sites where the source plugin is deactivated but its data is still in the database. Converts the field map to HTML (recursing into Fluent's container columns), walks the notifications meta_key for Email actions, picks up webhook-shaped meta_keys as Trigger Webhook actions, and maps the form's default confirmation to the success message / redirect URL.

Conditional emails (per recipient)

New Recipient routes repeater under the Send Email action. Each route has a field + operator + value + recipient address; the first matching route wins, otherwise the default "To" address is used. The existing action-level conditions block keeps working — that decides whether the action runs at all; routes only re-target where it sends.

Importer extension point

CF7Migration's source picker is no longer hardcoded. Added cf_import_sources filter + cf_import_render_section action so third-party migrators can plug into the existing Core Forms → Import page. The three new migrators use these hooks via a shared BaseMigration abstract class.

Carried over from earlier 4.3 betas

Polls rework (tabbed editor, vote-integrity rewrite, Gutenberg block, REST, live results, analytics + CSV, accessibility pass, adaptive container-query layout). Duplicate row action fix on the forms list.

Install on staging only. Real installs stay on 4.2.10 until stable 4.3.0.

Beta

Core Forms 4.3.0-beta4

Read release notes

Pre-release. Visual + layout pass on the polls rework.

Changes vs beta3

Editor preview now matches the front of the site. The poll stylesheet only enqueued on the public side, so Gutenberg's ServerSideRender preview fell back to browser-default form styling. Registered the CSS as both style and editor_style on the block so editor and frontend use identical visuals.

Container-driven adaptive layout. Dropped the fixed 560px max-width for width: 100% + container queries. Padding, border radius, and type scale tune to the actual container width (cqi units + clamp), so a sidebar poll on a 4K monitor stays compact and a full-width poll on a phone collapses to a stacked footer. Viewport @media fallback for browsers without container query support.

Options auto-flow. Short option lists like "WordPress / Wix" now sit side-by-side when there's room (auto-fit, minmax(min(240px, 100%), 1fr)); forced single-column inside the bars layout so each bar gets full width.

Layout bug. The radio/checkbox was dropping the option label to a second line on the front-end because the label was display: block with a display: flex child. The label itself is now flex.

Visual polish. Pill result bars (10px instead of 24px), softer card shadow, larger submit hit area with active-state feedback, refined focus rings.

Carried over from earlier betas

Tabbed editor, drag-to-reorder, "Other" write-in, vote-integrity rewrite (voter_hash dedupe, cookie-on-render with SameSite=Lax; Secure, user-mode anon rejection, honeypot, per-IP rate limit), hourly auto-close cron, Gutenberg block, REST endpoints, live results, change-vote window, bar/columns/percent styles, analytics screen + CSV export, accessibility pass, jQuery removed, schema migration with backfill.

Install on staging only. Real installs stay on 4.2.10 until stable 4.3.0.

Beta

Core Forms 4.3.0-beta3

Read release notes

Pre-release. Same scope as beta2 + one access fix.

Fix vs beta2

  • Poll analytics page returned "Sorry, you are not allowed". The hidden analytics screen registered under the core-forms parent and then called remove_submenu_page() to hide the menu entry — but removing from \$submenu also strips the slug from WP's URL allowlist, so user_can_access_admin_page() rejected everyone except super-admins. Switched to an empty parent slug; the page now resolves at admin.php?page=cf-poll-analytics&poll=X and honors the per-page edit_posts cap.

Polls rework (carried over)

Tabbed editor, drag-to-reorder, "Other" write-in, vote-integrity rewrite (voter_hash dedupe, cookie-on-render with SameSite=Lax; Secure, user-mode anon rejection, honeypot, per-IP rate limit), hourly auto-close cron, Gutenberg block, REST endpoints, live results, change-vote window, bar/columns/percent styles, analytics screen + CSV export, accessibility pass, jQuery removed, schema migration with backfill.

Install on staging only. Real installs stay on 4.2.10 until stable 4.3.0.

Beta

Core Forms 4.3.0-beta2

Read release notes

Pre-release. Same scope as v4.3.0-beta1 but pinned to the commit where CI is green (ESLint + PHPStan + PHP 8.1/8.2/8.3 unit tests all pass).

What's new vs beta1

  • ESLint clean: ~80 prettier formatting issues autofixed, eqeqeq != null → explicit !== undefined && !== null, @wordpress/no-unsafe-wp-apis and jsx-a11y/no-noninteractive-element-interactions silenced where intentional.

Polls rework (carried over from beta1)

  • Tabbed editor (Question / Settings / Schedule / Embed / Results), drag-to-reorder options, Duplicate row action, "Other" write-in toggle.
  • Vote integrity rewrite: voter_hash dedupe, cookie set on render (and persisted from AJAX), vote_limit=user rejects anon at submit, honeypot, per-IP rate limit, hourly auto-close cron.
  • Gutenberg block core-forms/poll + REST endpoints (/cf/v1/polls/{id}/results public, list/single/analytics auth).
  • Live results polling (opt-in, 15s, pauses while tab hidden), change-vote window, bar/columns/percent result styles.
  • Per-poll analytics screen + CSV export of raw votes.
  • Accessibility: <fieldset><legend>, role="progressbar" + aria-valuenow, aria-live status region, focus management, prefers-reduced-motion.
  • jQuery removed from poll frontend and admin JS.
  • Schema migration (cf_db_version → 4.3.0) with backfill so historical dedupe keeps working.

Install on staging only. Real installs stay on 4.2.10 until stable 4.3.0.

Beta

Core Forms 4.3.0-beta1

Read release notes

Pre-release. Real installs continue to update to 4.2.10 — opt in to this beta only on staging.

Polls rework

Schema migration (cf_db_version → 4.3.0), tabbed editor, Gutenberg block, REST API, analytics screen, CSV export, hourly auto-close cron, accessibility pass, and a full vote-integrity rewrite.

Editor

  • Tabbed editor (Question / Settings / Schedule / Embed / Results) replaces the metabox screen
  • Drag-to-reorder options, Duplicate row action, "Other" write-in toggle, dedicated type selector (single vs. multiple)

Vote integrity

  • Every vote now stores a voter_hash (poll + IP + UA + cookie + user) and dedupe queries against that single column regardless of mode
  • Cookie set on render with SameSite=Lax; Secure; HttpOnly; AJAX requests persist a fresh cookie too (was previously broken because admin-ajax doesn't fire send_headers)
  • vote_limit=user rejects anonymous voters at submit (was silently letting them vote unlimited times)
  • Honeypot field on by default; per-IP rate limit (12 votes/minute) covers both real submits and honeypot trips
  • Hourly cf_poll_auto_close cron flips status to closed once the end time passes

Frontend & block

  • core-forms/poll Gutenberg block (no-build, vanilla JS) — picker dropdown + display-mode (auto / results-only / form-only); server-render shares code with the shortcode
  • Result styles: bar (default), columns, percent-only
  • Optional live results polling (15 s, opt-in per poll; pauses while tab is hidden)
  • Optional change-vote window (per-poll, in minutes) — re-renders the form pre-checked
  • Accessible markup: <fieldset><legend>, role="progressbar" with aria-valuenow, role="status" aria-live="polite", focus moves to result heading on submit, respects prefers-reduced-motion

Results & analytics

  • REST: GET /cf/v1/polls/{id}/results (public), GET /cf/v1/polls and /polls/{id} and /polls/{id}/analytics (auth)
  • Per-poll analytics screen with totals, unique voters, 30-day SVG line chart, option breakdown
  • CSV export of raw votes (option label, value, voter_hash, IP, user, voted_at, referrer)

JS

  • Removed jQuery from the poll frontend and admin scripts

Schema migration

Adds type, starts_at, allow_other, post_close_behavior, redirect_url, enable_live_results, change_vote_window to wp_cf_polls. Adds option_value, voter_hash, referrer to wp_cf_poll_votes plus a (poll_id, voter_hash) composite index. Existing rows are backfilled so historical dedupe keeps working.

Known follow-ups for stable 4.3.0

  • Donut style currently falls back to bar rendering (CSS hook exists)
  • Image-option polls / NPS / rating types are deferred to 4.4.0
Stable

Core Forms 4.2.10

Read release notes

Fixes

  • Duplicate row action now duplicates the form. Clicking Duplicate on the forms list used to drop the user into the editor for the original form because the duplicate URL carries a form_id and the overview page short-circuited into the editor before the list table could run its single-row action handler. The overview now processes action=duplicate_single first, clones the form, and redirects back to the list with ?duplicated=1.
Stable

Core Forms 4.2.9

Read release notes

Container builder polish

  • Add Field popover redesigned. Fixed 360px width with a 4-column icon grid, header bar, and a dedicated close button. Dismisses on outside-click or Escape.
  • Containers default to a single column. New Containers ship as plain wrappers; opt into a grid via the Layout panel when you actually want one.
  • Column changes preview in real time. The canvas duplicates the .cf-row grid rules locally, so editing column counts updates the preview immediately.
  • Better drop-target affordance. Empty containers and group bodies show a dashed outline at rest and a solid blue highlight while dragging.

Also: fixes two pre-existing PHPStan warnings that were blocking the release pipeline.