Gatilab Products

Changelogs

Improvements, fixes, and the details behind each release.

All Products

Release history across our plugins and themes.

Stable

Core Forms 4.4.2

Read release notes

Security

  • Enforces the 254-character email limit and each field's declared maxlength on the server.
  • Rejects nested form values and encoded submission metadata above 60 KiB before hooks, storage, or notifications.
  • Keeps uploaded file bytes outside that metadata ceiling; upload size remains controlled by the field and PHP limits.

Fixed

  • Restores single and multiple multipart file uploads by normalizing PHP's $_FILES data into the submission pipeline.
  • Prevents invalid and spam submissions from moving files or persisting temporary upload paths.
  • Fixes per-form rate-limit settings, hourly expiry, and AJAX error visibility.

See CHANGELOG.md for the full release history.

Stable

Core Forms 4.4.1

Read release notes

Fixed

  • Fixed the Gutenberg Core Form block preview taking about 60 seconds to load on busy editor screens by replacing the generic WordPress server-render request with a focused Core Forms preview endpoint, a summary-only form selector, and shared request caching.
Stable

Core Forms 4.4.0

Read release notes

Core Forms 4.4.0 includes the complete feature set originally planned for roadmap versions 4.4 and 4.5.

Added

  • Added inline Stripe Payment Element checkout with server-owned product pricing, idempotent PaymentIntent creation, and signed webhook confirmation.
  • Added first-class Razorpay hosted checkout with payment-link, captured-payment, failure, cancellation, and refund handling.
  • Added one-click importers for Ninja Forms and Formidable Forms alongside the existing CF7, Gravity Forms, WPForms, and Fluent Forms migration tools.
  • Added WP-CLI commands for form import/export/listing, submission maintenance, product and plan administration, license reporting, order reporting, and expiry maintenance.
  • Added native actions for WooCommerce, Easy Digital Downloads, SureCart, WP Simple Pay, MemberPress, LearnDash, Paid Memberships Pro, Groundhogg, Jetpack CRM, WP-CRM System, and SureContact.
  • Added AutomatorWP, Uncanny Automator, and OttoKit triggers and actions with form and submission payloads.
  • Added signed inbound WhatsApp webhooks for Meta Cloud API and Twilio, including reply correlation and delivery-state history in submission conversations.
  • Added a multi-product licensing and lightweight ecommerce system with products, plans, orders, subscriptions, customer accounts, activation limits, refunds, renewals, and audited signed downloads.
  • Added a dedicated customer dashboard for orders, masked/revealable keys, product downloads, activated sites, and subscription controls.
  • Added free, Stripe, Razorpay, and renewal license-form templates with complete payment and fulfillment actions.
  • Added a default Sample Product with free, USD annual, and INR annual plans on new and upgraded sites.
  • Added native Bricks and Elementor integrations plus a per-form WCAG 2.2 audit and conservative one-click repairs.

Changed

  • The form editor now renders only the active tab instead of executing every tab's PHP, JavaScript, analytics, and REST requests on every page load.
  • The visual builder now boots from server-rendered form and schema data, removing its two blocking initial REST requests.
  • Builder saves now persist markup and schema atomically through one endpoint with a bounded timeout and a standard form-post fallback.
  • Tab-specific saves merge with existing form settings, preserving payment and action configuration when saving Fields, Messages, or other individual tabs.
  • Licensing actions are always visible under a dedicated Commerce & Licensing category instead of disappearing when the public activation API is disabled.
  • Product and plan slugs are generated automatically, normalized, and made unique; manually entered slugs remain supported.
  • Plan prices are entered in customer-facing major units such as 49.00 instead of minor units such as 4900.
  • Product packages use the WordPress Media Library picker and uploader instead of requiring an attachment ID.
  • The licensing backend now includes catalog statistics, quick-start guidance, direct Add plan/Add package links, and file names instead of raw attachment IDs.
  • The existing core-forms.com CF Licenser client, option keys, 32-character key format, six-hour heartbeat, and update hooks remain separate from and compatible with the new merchant licensing subsystem.

Fixed

  • Fixed the Fields builder remaining on an indefinite loading spinner when either initial REST request stalled.
  • Fixed inactive Analytics requests and form-builder assets loading on unrelated form tabs.
  • Fixed paid plans being fulfillable from a non-payment form or before verified payment confirmation.
  • Fixed payment fulfillment accepting a mismatched paid amount or currency when validation is enabled.
  • Fixed free plans being incorrectly coupled to a payment requirement.
  • Fixed action-variable references showing a permanent Loading message when the Fields builder was not present.
  • Fixed stale admin asset caches by versioning the main admin stylesheet and licensing script from their file modification times while keeping the plugin version at 4.4.0.

Security

  • License fulfillment is idempotent per submission and product selection, preventing duplicate orders or keys during webhook retries.
  • Signed package links expire, verify the stored SHA-256 digest before streaming, and record downloads in an audit table.
  • Verified refunds disable issued licenses and cancel related subscriptions.
  • Inbound messaging and payment webhooks require provider signatures before they can change submission, payment, or fulfillment state.
Stable

GT ACF Blocks Plugin 2.8.1

Read release notes

What's Changed

Added — Migrator improvements

  • Batched migration: the Migrator now processes 30 posts per run with a Continue — Migrate Next 30 button and a progress bar, instead of one large request — friendlier on big sites and PHP time limits.
  • Affected-post visibility: Scan now lists every affected post (title, status, edit/view links) with colour-coded badges showing exactly what will change; each migration batch shows the same per-post detail for what it just changed.
  • New repair — legacy accordion field schema: acf/accordion blocks whose data used the old acf_accord_heading / acf_accord_content sub-fields (which render blank on the current template) are remapped in place to acf_accord_group_title / acf_accord_group_content, preserving FAQ schema and classes. This is the cause behind blank FAQ sections on older posts.
  • Restore points across batches: revert now covers the whole multi-batch session, and a new Discard restore points action clears backups without changing migrated content. WP-CLI: wp acf-blocks migrate [--limit=<n>] [--dry-run] [--revert] [--discard].

Commits

  • 2.8.1: batched migrator, affected-post visibility, accordion field-schema fix (4a845ab)

Stats

  • Commits: 1
  • Changes: 3 files changed, 460 insertions(+), 138 deletions(-)

Plugin Info

  • Blocks included: 29
  • Requires WordPress: 6.0+
  • Requires PHP: 7.4+
  • Requires: ACF Pro 6.0+ or Secure Custom Fields

Installation

  1. Download acf-blocks-plugin-*.zip from the assets below
  2. Go to Plugins → Add New → Upload Plugin in WordPress admin
  3. Upload the zip file and activate
Stable

GT ACF Blocks Plugin 2.8.0

Read release notes

What's Changed

Fixed

  • Block recovery (all InnerBlocks blocks): Resolved the "This block contains unexpected or invalid content" / Attempt Recovery error that emptied ACF InnerBlocks blocks (Callout, CTA, Hero, Section, Feature Grid, Testimonial, Team Member, Opinion Box, …). The cause was inner content saved as undelimited raw HTML (e.g. a bare <p> instead of <!-- wp:paragraph -->), which the editor treats as invalid InnerBlocks markup. Clicking Attempt Recovery then rebuilt the block from its template default, wiping the author's content.

Added

  • includes/block-recovery.php — a self-healing helper that re-wraps orphaned inner HTML into proper core blocks (paragraph, heading, list, quote; anything unrecognised is preserved verbatim in a core/html block, so no content is ever lost). It is idempotent and runs in two ways:
  • Live self-heal: filters the block editor's REST content.raw (edit context only) so existing posts open cleanly with no action required; saving then persists the repaired markup.
  • Permanent bulk repair: wp acf-blocks repair-content [--dry-run] [--post=<id>] rewrites affected posts in the database.
  • The InnerBlocks block set is derived automatically — unioning each block.json (supports.jsx) with the live block registry (ACF can enable InnerBlocks at runtime without declaring it in block.json) — with a acf_blocks_recovery_innerblock_names filter to customise it.

Added — Block Migrator

  • includes/block-migrator.php + visual Migrator on the options page (Settings → ACF Blocks License). A new Block Migrator & Repair card with Scan, Dry Run, and Migrate All actions. Every change is saved through wp_update_post() (a revision is stored), so migrations are reversible. WP-CLI parity: wp acf-blocks migrate [--dry-run].
  • Reversible migrations — before each post is migrated, its original content is snapshotted both as a native WordPress revision (visible in the editor's Revisions browser) and as a per-post restore point. A Revert Last Migration button (and wp acf-blocks migrate --revert) rolls the entire batch back to its pre-migration content, byte-for-byte, independent of the site's revision settings.
  • Legacy / renamed block migrations — blocks saved under names the plugin no longer registers are remapped to the current block with field-data translation, not just renamed:
  • acf/table-of-contents, acf/table-of-content → acf/toc
  • acf/productbox → acf/product-box (incl. the legacy features repeater)
  • acf/accordion-item → acf/accordion (consecutive items merged into one block)
  • acf/accordion-group → acf/accordion (wrapper + children merged, FAQ schema preserved)
  • acf/acf-accordion → acf/accordion (acc_question/acc_answer sub-fields remapped)
  • acf/poll has no current equivalent — reported and left untouched for manual handling.
  • Unparseable-markup repair — fixes content the block parser chokes on:
  • Orphaned closing delimiters (e.g. a stray <!-- /wp:post-content --> with no opener) that silently push every following block into freeform text. Removed with a delimiter stack so only genuinely unmatched closers are stripped.
  • Dangling openers (a truncated <!-- wp:… fragment with no -->).
  • Literal --> inside ACF block JSON, HTML-encoded to --> (identical when rendered).

Compatibility

  • WordPress 7.0: Added Tested up to: 7.0 header. Audited for WordPress 7 / ACF Pro 6.x — all 29 blocks already use Block API v3, register via block.json (no deprecated acf_register_block_type), retain the ACF 6.7+ acf_setup_meta compatibility layer, and contain no PHP 8.2–8.5 deprecation patterns (verified against PHP 8.5).

Commits

  • Release 2.8.0: block recovery + migrator with reversible migrations (fc6bc7d)

Stats

  • Commits: 1
  • Changes: 5 files changed, 1684 insertions(+), 2 deletions(-)

Plugin Info

  • Blocks included: 29
  • Requires WordPress: 6.0+
  • Requires PHP: 7.4+
  • Requires: ACF Pro 6.0+ or Secure Custom Fields

Installation

  1. Download acf-blocks-plugin-*.zip from the assets below
  2. Go to Plugins → Add New → Upload Plugin in WordPress admin
  3. Upload the zip file and activate
Stable

GT Page Blocks Builder 2.6.0

Read release notes

What's Changed

Theme building

  • Library blocks can be assigned to theme regions — header, hero, before/after content, sidebar, footer, 404 — and rendered by any theme via gt_pb_region( 'header' ) / gt_pb_has_region(). A blank hybrid theme can be little more than region calls.
  • Hook positions now actually render: wp_head, wp_body_open, wp_footer, loop_start/loop_end, get_header/footer/sidebar, and before/after the content — priority-ordered.

Block rename + migration

  • The block is now gt-page-block/page-block (category: Page Blocks). The legacy marketers-delight/page-block stays registered (hidden from the inserter) so existing content keeps rendering, with a one-click transform to the new block.
  • Migration tool: Settings → Tools → Migrate blocks (with dry run), or WP-CLI wp gt-pb migrate-blocks [--dry-run] — rewrites stored content without touching post modified dates.

REST API (pbb/v1)

  • GET/POST /blocks, GET/PUT/DELETE /blocks/<id> (trash or ?force=true), POST /blocks/<id>/duplicate, GET /blocks/<id>/render — search, status filtering, pagination, and status-count headers. Read = edit_posts, write = manage_options.

Library admin panel

  • New card-grid library with lazy live-preview thumbnails, search, status filter tabs, duplicate / trash / restore / delete-forever, copy-shortcode, and position chips. Classic list table remains at ?view=list.

Block editor

  • Preview-first Page Block: rendered live preview (auto-sizing iframe with theme styles) by default; Preview/Code toggles in the block toolbar.
  • Responsive viewport presets (desktop / 768px / 390px) + dark-scheme preview toggle.
  • Collapsible live preview pane under the CodeMirror editor — server-rendered when PHP/wpautop is enabled.
  • Copy button, Save to library, and a Browse library modal to insert saved blocks.
Stable

Core Forms 4.3.8

Read release notes

Core Forms 4.3.8

New - Field names accept uppercase. The builder's Name field no longer force-lowercases input (HTML `name`/`id` are case-sensitive). Illegal characters are still sanitized. - Textarea options: Rows (height), Resize behaviour (default / vertical / horizontal / both / none), and a live character counter that shows "used / limit" when a Max length is set. An explicit Rows value now wins over the 5-line default height. - Phone (tel) value limits: new Min length, Max length, and Pattern controls to constrain accepted values.

Fixed - The builder's HTML generator silently dropped textarea min/max-length and conditional-logic attributes on save, so those validations were lost. The textarea output now matches the server-side renderer.

Stable

Core Forms 4.3.7

Read release notes

Bug-fix release.

Fixed: critical error after plugin, theme, or core updates and rollbacks.

The upgrader_process_complete migration callback was registered under the plugin namespace (Core_Forms\_cf_on_upgrader_complete), but that function is defined in the global namespace, so it was an invalid callback that triggered a fatal TypeError whenever WordPress finished an update or rollback. It surfaced as "There has been a critical error on this website" on the update/rollback screen. The callback is now registered with the correct name, so updates complete cleanly.

PHPStan had originally flagged this; the error had been suppressed in phpstan-baseline.neon rather than fixed. That stale baseline entry is now removed.

Stable

Core Forms 4.3.6

Read release notes

Accessibility floor for every Core Form (and Core Poll) input.

This release is about making the default Core Form accessible by default — not "accessible if the author remembers to opt in." Whether you load only the skeleton (forms.css), only the themed stylesheet (form-theme.css), or both, the floor holds.

What's in

  • 44 × 44 CSS px touch target on every form control. WCAG 2.5.5 AAA target size. Applied to every text-type input, select, textarea, and button in both stylesheets so the rule survives whether the theme is loaded, disabled, or partially overridden.
  • Windows High Contrast Mode-safe keyboard focus. The themed :focus-visible state used to be outline: none + coloured box-shadow — HCM strips the box-shadow and the ring vanishes. Now :focus-visible pairs the box-shadow with a transparent 2px outline; HCM forces the transparent outline to the system focus colour, so keyboard users on HCM still see a ring.
  • Accessibility baseline in forms.css. Authors who disable the form theme used to drop back to a bare browser stylesheet. The skeleton now ships a tiny accessibility section at the top — 44px target, currentColor focus outline, prefers-reduced-motion transition kill-switch — so disabling the theme doesn't disable accessibility.
  • Textareas are 5 lines tall by default. Browsers ship rows="2" which is comically short for paragraph answers. Both stylesheets now set min-height: calc(5lh + 22px) (with a 140px px fallback for older browsers) — textareas grow with the host theme's line-height instead of being pinned to a px value.

Asset loading

  • Form and poll stylesheets now print at the bottom of <head>. Enqueue priority bumped from 20 → 99 so wp_enqueue_style calls land after the host theme's. WordPress prints in enqueue order → Core Forms styles cascade over theme styles cleanly, no !important, no specificity arms race.
  • Poll CSS is back in <head>. poll-frontend.css used to enqueue inside render_poll_shortcode() during the_content — after wp_head had already printed — so it landed in the footer. PollFrontend::maybe_enqueue_detected_poll_assets() now pre-scans for core-forms/poll blocks and [cf_poll] shortcodes at wp_enqueue_scripts priority 99 and pre-enqueues the stylesheet. Lands in <head> on poll pages, omitted entirely everywhere else.

Upgrading

Just update. If a textarea on a live form previously sat awkwardly between 2 and 4 lines, it'll now be a comfortable 5; everything else is non-visual or strictly additive.

🤖 Generated with Claude Code

Stable

Core Forms 4.3.5

Read release notes

Hotfix release — restores the Gutenberg block editor experience.

Root cause

If you've been running 4.3.3 or 4.3.4 and noticed the Core Forms block in the editor showing a generic blue "CF" square icon and a single dropdown — no live preview, no inspector panels — this release fixes it.

src/admin/class-admin.php was still enqueuing a legacy assets/js/gutenberg-block.js (a pre-4.0 hand-written registerBlockType call) on enqueue_block_editor_assets. That script registered core-forms/form first, so every modern block-form.js bundle — with ServerSideRender, inspector controls, and the correct form icon — was shipping in every zip but never actually loading in the editor.

The legacy wp_enqueue_script() call also passed no version argument, which is why network-tab diagnostics showed gutenberg-block.js?ver=7.0 (the WP core version) instead of the plugin version. Thanks to the user who reported this from their network tab — that's what pinpointed it.

Changes

  • Removed the enqueue_block_editor_assets listener and enqueue_gutenberg_assets() method from class-admin.php.
  • Deleted the orphan assets/js/gutenberg-block.js.
  • block.json now owns the entire editor lifecycle — register_block_type(__DIR__ . '/block.json') loads assets/js/build/block-form.js with the modern Edit component, and the version: "4.3.5" field cache-busts it against CORE_FORMS_VERSION.
  • Reverted the 4.3.4 form-picker label change back to Title (slug) so forms sharing a base title stay distinguishable in the dropdown.

Upgrading

Just update. Hard-refresh the editor once (Cmd/Ctrl+Shift+R) to clear the cached gutenberg-block.js?ver=7.0 from your browser — after that the modern block editor UI is back.

🤖 Generated with Claude Code

Stable

Core Forms 4.3.4

Read release notes

Two performance memoisations and three UX improvements layered on top of the 4.3.3 bug fixes. No breaking changes, no migrations.

Performance

  • cf_get_form() is request-scoped memoised. The same form requested multiple times per page (block render, get_html, action loop, analytics tracker) no longer re-fetches the post + meta and rebuilds the settings/messages arrays. Each call returns a clone so future callers can't poison the cached instance with property mutations. Invalidation: save_post_core-form (always) and *_post_meta hooks gated on get_post_type() so other CPT meta touches don't trash the cache.
  • cf_count_form_submissions() is request-scoped memoised. The forms list table called this per-row — a 50-form admin issued 50 COUNT(*) queries; now it issues one per (form_id, is_spam) pair and the rest are cache hits. Invalidated on cf_submission_inserted.

UX

  • Block-editor preview skeleton. The Gutenberg block preview shows an animated shimmer skeleton (title bar → input rows → submit button) while ServerSideRender is fetching, instead of a bare spinner. Respects prefers-reduced-motion.
  • Cleaner form picker. The block's form-picker dropdown shows just the form title instead of \"Title (slug)\" — much cleaner when titles are distinct. The slug is still surfaced via the Edit Form deep link beneath the picker.
  • / keyboard shortcut on the forms list. Press / or s to focus the search box. Standard list-UI shortcut (GitHub, GitLab, Linear, every modern dashboard). Skipped when an input, textarea, or contenteditable already has focus so it never hijacks typing.

4.3.3 fixes are intact

  • The wp_cf_submission_replies table self-heal and the un-spam action-replay parity from 4.3.3 are untouched — verified 10 call sites still wired.

Upgrade notes

  • No data or schema migrations.
  • No breaking API changes.
  • The cache-invalidation hooks are guarded with function_exists('add_action') to match the existing convention in functions.php, so the file remains autoload-safe for standalone test environments.

Verified

  • 151 unit tests pass.
  • PHPStan reports no errors.
  • Production zip ships at 815 KB with no test framework, no PHPStan, no composer.json.
  • block-form.js rebuilt; bundle still contains wp.serverSideRender and the new cf-block-skeleton styles.
Stable

Core Forms 4.3.3

Read release notes

Bug-fix release.

Fixed: fatal "Table 'wp_cf_submission_replies' doesn't exist" when opening a submission. The reply-history feature queried a table that no installer or migration ever created. The table is now created on activation, on new-blog insert, and on multisite activation, and existing installs are backfilled by a 4.3.3 migration so they self-heal on update.

Fixed: submissions-table "Not Spam" bulk action did not fire form actions. Moving a submission out of spam from the submissions table now replays the form's success and configured actions (notifications, integrations) that were skipped at submit time, matching the behavior of the spam-page single and bulk paths. The replay is centralised in cf_replay_submission_actions() so the three un-spam paths can't drift apart.