feat: support GF 3.0 International (formatted) phone numbers - #1689
Merged
Conversation
Gravity Forms 3.0 adds an International (formatted) phone number format
that stores the value as a JSON object in the entry, so PDFs printed the
raw JSON:
{"country":"US","national":"2015551232","formatted":"(201) 555-1232","e164":"+12015551232"}
Field_Phone now renders the ISO country code, the dial code, and the
formatted number. The dial code is omitted when the field's "Show country
dial code" setting is disabled, matching what the user saw on-screen:
US +1 (201) 555-1232 (setting enabled)
US (201) 555-1232 (setting disabled)
Detection is based on the stored entry value being JSON, not on the
field's phoneFormat setting, so entries saved while the field was
International (formatted) still display correctly after the field is
switched to a format that doesn't store JSON.
The dial code is derived by removing the national number from the tail of
the E.164 number rather than looked up. Gravity Forms resolves it from
assets/js/src/theme/fields/international-phone/countries.json, which is
not present in the distributed plugin zip, so GF_Field_Phone::get_dial_code()
returns an empty string in a real install. GF 3.0 also ships
E164Validator::validate(), which returns the dial code, but it is GF 2.9+
only (Gravity PDF supports 2.5+), lives in the global namespace as an
undocumented internal, and loads a 254KB rules array on first use.
$form_data['field'] keeps the displayed number as a string so existing
templates continue to work when a phone field is switched to the new
format. The individual parts are exposed under a new $form_data['phone']
key, following the Field_List and Field_Signature precedent.
Note that, as with the existing 'list' and 'signature_details_id' keys,
$form_data['phone'] is not populated for phone fields inside a Repeater,
because Field_Repeater merges only the 'field' and 'html_id' keys from
its sub-fields.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
jakejackson1
force-pushed
the
fix/gf3-international-phone
branch
from
July 27, 2026 05:52
95ddf77 to
2e666a6
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Gravity Forms 3.0 adds an International (formatted) phone format that stores the value as a JSON object in the entry. Gravity PDF had no support for it, so it printed the raw JSON:
Field_Phonenow renders the ISO country code, the dial code, and the formatted number. The dial code is dropped when the field's Show country dial code setting is off, mirroring what the user saw on screen:US +1 (201) 555-1232US (201) 555-1232Detection keys off the stored entry value being JSON, not the field's
phoneFormatsetting. Entries saved while the field was International (formatted) therefore still display correctly after the field is switched to a format that doesn't store JSON — otherwise those existing entries would revert to showing raw JSON.Why the dial code is derived rather than looked up
It's obtained by removing the national number from the tail of the E.164 number. Two PHP-side alternatives were checked and rejected:
GF_Field_Phone::get_dial_code()readsassets/js/src/theme/fields/international-phone/countries.json. That file is not in the distributed Gravity Forms zip (onlyassets/js/dist/ships), so it returns an empty string in a real install. It's alsoprivate static.E164Validator::validate( $e164, true )does return the dial code, but it's GF 2.9+ while Gravity PDF supports 2.5+, it's an undocumented internal in the global namespace, and the first call loads a 254 KB rules array.$form_data$form_data['field']keeps the displayed number as a string, so templates that echo it keep working if a site switches an existing phone field to the new format. The parts are exposed under a newphonekey:This follows the
Field_List/Field_Signatureprecedent of putting structured data under its own top-level key, and'phone'was added togfpdf_form_data_key_order.listandsignature_details_idkeys,$form_data['phone']is not populated for phone fields inside a Repeater, becauseField_Repeatermerges only thefieldandhtml_idkeys from its sub-fields. Worth a docs note.Testing
11 new tests in
tests/phpunit/unit-tests/Helper/Fields/Test_Field_Phone.php, covering the US and multi-digit (GB+44) dial-code derivation, bothshowCountryCodestates plus the unset default, the format-switch case, non-JSON pass-through, unrecognised JSON, and$form_datafor both shapes. The fixture is built in memory, so it touches no database.Full suite run against the branch: 1162 tests, 3602 assertions. PHPCS and
phpcompat(PHP 7.3 floor) both clean.Notes for review
🤖 Generated with Claude Code