Skip to content

Import forms from Gravity Forms - #7

Merged
AllTerrainDeveloper merged 1 commit into
mainfrom
importer/gravity-forms
Aug 16, 2026
Merged

AllTerrainDeveloper merged 1 commit into
mainfrom
importer/gravity-forms

Conversation

@AllTerrainDeveloper

Copy link
Copy Markdown
Owner

The third and final importer: Gravity Forms — the plugin whose users have the most invested, because everything it does well (conditional logic, product pricing, multi-row lists) is exactly what nobody wants to rebuild by hand.

What it does

Forms → Import gains a Gravity Forms section. Gravity keeps its forms in tables of its own — {prefix}gf_form for the list, {prefix}gf_form_meta with display_meta as JSON and the notifications and confirmations in columns beside it — so the importer reads the tables directly, no GFAPI, and works whether the plugin is active, deactivated or already deleted. The availability check is the table's existence; the queries are two bounded reads. Nothing in Gravity's tables is ever written to.

The two conversions that carry the weight

  • Conditional logic is a straight translation. Gravity's logic — a flat rule list, an all/any mode, a show/hide action — is the same shape this plugin evaluates, so it maps rule for rule on fields, notifications and confirmations alike, with the operator table (is, isnot, contains, starts_with, ends_with, >, <) mapping one to one. A rule targeting a composite input (1.3) resolves to its parent field.
  • A List field becomes a real repeater. Gravity's columns become the repeater's sub-fields (a single-column list keeps its own label as the one sub-field), so "add another row" keeps meaning exactly that on the imported form.

Everything else that converts

  • Fields: text, textarea, email, phone, website, number (range bounds), hidden, date, time, file upload (allowed extensions), signature, HTML blocks, section (→ heading), page (→ page break), consent (checkbox label → consent line), name (parts follow Gravity's stable input numbering — 3 is first, 6 is last — hidden parts excluded), address, and the post fields (post_title/post_content/post_excerpt) as the input shapes they are.
  • Products keep their prices. Choice-based products and options become choice fields whose choices carry a price (currency formatting parsed — $25.00 and 10,00 € both come out as numbers); a fixed-price product becomes a number holding its price; the total becomes a calculated total summing them, verified through the real calculation engine (VIP + Parking → 110.00 in the tests). The honest limit: Gravity's quantity-pairing behaviour is not reproduced — the imported form is reviewable in the builder, not a silent approximation.
  • Notifications: only form_submission-event notifications import — a payment-completed or entry-approved mail would fire at the wrong moment entirely, so those are deliberately left behind. toType: field addressing (a bare field id in to) becomes the field's merge tag rather than a mail addressed to the digit three. Subject, message, from-name, reply-to and per-notification logic all carry over.
  • Confirmations: message, page and redirect — including the redirect's query string, merge tags rewritten.
  • Merge tags: {Any Label:3} (with or without input sub-numbers or modifiers) becomes {field:…}; {all_fields}, {admin_email}, {form_title}, {ip}, {embed_url}, {date_mdy}/{date_dmy} map to their equivalents; unknowns stay visible rather than vanishing.
  • The enableOtherChoice flag becomes this plugin's "Other" option; captcha is dropped (spam screening here doesn't charge the visitor); unknown add-on fields become visible text fields.

Verification

  • 6 new PHPUnit tests (suite: 556 green): the contact display_meta field for field including any-match logic and the Other flag; name-part numbering with hidden parts; List → repeater in both column shapes; products/options/total through the real calc engine with both currency formats; notifications (event filtering, field addressing, tag rewriting) and confirmations (redirect query string); and an end-to-end test that creates the real gf_form/gf_form_meta tables, imports through the registry, and asserts the source tables are untouched.
  • Live QA in wp-env: seeded the tables with a "Wedding RSVP" form and imported it through the actual admin page. Result verified in the stored schema: name composite, radio, and a repeater with "Guest name"/"Dietary needs" sub-fields shown only when Attending? is Yes; subject rewrote {Name:1.3} → {field:f1}; submit label carried over. All three importer sections now render side by side on the Import page.
  • PHPCS: clean.

With this, the importer set the readme promised is complete: Contact Form 7, WPForms, Gravity Forms — one PR each, most-used first.

🤖 Generated with Claude Code

https://claude.ai/code/session_0119U4sRRWGcTQdwYreTwpAp

Gravity keeps its forms in tables of its own — gf_form and gf_form_meta,
with display_meta as JSON and the notifications and confirmations in
columns beside it — so the importer reads the tables directly and works
whether the plugin is active, deactivated or deleted. No GFAPI.

Two conversions carry the most weight. Conditional logic is a straight
translation: Gravity's flat rule list with an all/any mode is the same
shape this plugin evaluates, so it maps rule for rule on fields,
notifications and confirmations alike. And a List field becomes a real
repeater — Gravity's columns are the repeater's sub-fields, so "add
another row" keeps meaning exactly that.

Products and options keep their prices ($25.00 and 10,00 € both parse),
the total becomes a calculated total over them, name fields keep the
parts Gravity's input numbering says are visible, field-addressed
notifications keep their address, and non-submission events (payment
completed, entry approved) are deliberately left behind rather than
imported as mails that would fire at the wrong moment.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0119U4sRRWGcTQdwYreTwpAp
@AllTerrainDeveloper
AllTerrainDeveloper merged commit 48c3068 into main Aug 16, 2026
3 checks passed
@AllTerrainDeveloper
AllTerrainDeveloper deleted the importer/gravity-forms branch August 16, 2026 17:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant