Gravity Forms is my go-to forms plugin, mostly because of its rich API. There are plenty of hook and filters right where you need them, enabling you to build third party integrations and make advanced customizations to the form without too much trouble.

Field Mapping Woes

While customizing a Gravity Form is a pleasant experience, dealing with field mapping is not. For example, in order to get a contact’s email address into the client’s CRM you have to first know the precise field ID and form ID where the data is captured. In the simplest of cases you can hard code these values like this:

add_action( 'gform_after_submission_5', function ( $entry, $form ) {
	$name_field_id    = '1';
	$email_field_id   = '2';
	$message_field_id = '3';

	$name    = rgar( $entry, $name_field_id );
	$email   = rgar( $entry, $email_field_id );
	$message = rgar( $entry, $message_field_id );

	// Do more stuff...
}, 10, 2 );

Notice the above snippet is targeting form ID 5, and assumes the name, email, and message field IDs are 1, 2, and 3, respectively. While this works it is not resilient to changes to the form configuration. Form IDs can change when moving between development, staging, and production environments and if a field is inadvertently deleted then re-added its ID will change. In both cases the snippet will no longer work. To avoid this problem you can build an admin interface where the fields can be mapped and saved as an option. However, this approach is time intensive and is probably not be worth the investment in most cases.

Better Field Mapping

A third option is to embed the field mapping in the form itself. This approach requires no additional development time and remains resilient to form configuration changes. Start by adding a hidden field at the top of the form. It’s important that this hidden field is either the first or last field in the form in order to be able to target it in the code.  Next enter a JSON representation of the field mapping as the hidden field’s default value. For example, a form with three fields – name, email, and message – would have a hidden field with a default value of {"update_crm":true,"name":1,"email":2,"message":3}.

With the field mapping in place we can reliably process the values in our code.

add_action( 'gform_after_submission', function ( $entry, $form ) {
	// We expect the first form field will be our mapping field if it exists.
	if ( ! isset( $form['fields'][0]->defaultValue ) ) {
		return;
	}

    $field_mapping = json_decode( $form['fields'][0]->defaultValue, true );

    // Bail if the first form field does not contain valid JSON
    // or if we do not need to update the CRM.
    if ( json_last_error() !== JSON_ERROR_NONE || empty( $field_mapping['update_crm'] ) ) {
        return;
    }

    $name_field_id    = $field_mapping['name'];
    $email_field_id   = $field_mapping['email'];
    $message_field_id = $field_mapping['message'];

    $name    = rgar( $entry, $name_field_id );
    $email   = rgar( $entry, $email_field_id );
    $message = rgar( $entry, $message_field_id );

    // Do more stuff...
    
}, 10, 2 );

Now you can completely reconfigure the form or even add a second form without having to update the code; you only need to make sure the first form field contains the correct field mapping. Be aware that the field mapping will show up in the entry admin columns and admin notifications (not submission confirmations) unless you take steps to disable them. Again, there are hooks and filters to let you do just that.

Reader Interactions

Leave a Reply

Your email address will not be published. Required fields are marked *