Gravity Forms API - Replacing key (field id for Admin field)

Gravity Forms API - Replacing key (field id for Admin field)

Hey team

Been using the field helper up until recently but has become unstable and incompatible with a few plugins - no response from the dev team on WP support.
Looking at alternatives to getting the API cleaned up so we can the admin field as they field key in the JSON.

Found this thread which sorts my webhook beautifully, hoping to achieve something similar for the V2 API

Webhook Send Admin Field Label

Reference:
‘Field Helper for Gravity Forms’

Output field labels instead of API
Custom endpoint

<?php

add_action('rest_api_init', function () {
    register_rest_route('gf/v2', '/entries-labels/(?P<entry_id>\d+)', array(
        'methods' => 'GET',
        'callback' => 'get_entry_with_labels',
        'permission_callback' => function () {
            return current_user_can('edit_posts');
        },
        'args' => array(
            'entry_id' => array(
                'validate_callback' => function($param, $request, $key) {
                    return is_numeric($param);
                }
            ),
        ),
    ));
});

function get_entry_with_labels(WP_REST_Request $request) {
    $entry_id = $request['entry_id'];

    $entry = GFAPI::get_entry($entry_id);
    if (is_wp_error($entry)) {
        return $entry; // Return the error if the entry could not be retrieved
    }

    $form_id = $entry['form_id'];
    $form = GFAPI::get_form($form_id);
    if (!$form) {
        return new WP_Error('form_not_found', 'Form not found', array('status' => 404));
    }

    $labeled_entry = array();
    foreach ($entry as $field_id => $value) {
        // Skip if it's not a field ID
        if (!is_numeric($field_id)) {
            $labeled_entry[$field_id] = $value;
            continue;
        }

        $label = find_field_label_by_id($form, $field_id);
        if ($label) {
            $labeled_entry[$label] = $value;
        } else {
            $labeled_entry[$field_id] = $value; // Fallback to field ID if label not found
        }
    }

    return new WP_REST_Response($labeled_entry, 200);
}

function find_field_label_by_id($form, $field_id) {
    foreach ($form['fields'] as $field) {
        if ($field->id == $field_id) {
            return $field->label;
        }
    }
    return false;
}

Admin labels with label fallback

<?php

add_action('rest_api_init', function () {
    register_rest_route('gf/v2', '/entries-admin-labels/(?P<entry_id>\d+)', array(
        'methods' => 'GET',
        'callback' => 'get_entry_with_labels_using_admin_label',
        'permission_callback' => function () {
            return current_user_can('edit_posts');
        },
        'args' => array(
            'entry_id' => array(
                'validate_callback' => function($param, $request, $key) {
                    return is_numeric($param);
                }
            ),
        ),
    ));
});

function get_entry_with_labels_using_admin_label(WP_REST_Request $request) {
    $entry_id = $request['entry_id'];

    $entry = GFAPI::get_entry($entry_id);
    if (is_wp_error($entry)) {
        return $entry; // Return the error if the entry could not be retrieved
    }

    $form_id = $entry['form_id'];
    $form = GFAPI::get_form($form_id);
    if (!$form) {
        return new WP_Error('form_not_found', 'Form not found', array('status' => 404));
    }

    $labeled_entry = array();
    foreach ($entry as $field_id => $value) {
        // Skip if it's not a field ID
        if (!is_numeric($field_id)) {
            $labeled_entry[$field_id] = $value;
            continue;
        }

        $label = find_field_label_by_id_using_admin_label($form, $field_id);
        if ($label) {
            $labeled_entry[$label] = $value;
        } else {
            $labeled_entry[$field_id] = $value; // Fallback to field ID if label not found
        }
    }

    return new WP_REST_Response($labeled_entry, 200);
}

function find_field_label_by_id_using_admin_label($form, $field_id) {
    foreach ($form['fields'] as $field) {
        if ($field->id == $field_id) {
            // Use admin label if it's set, otherwise fall back to the public label
            return !empty($field->adminLabel) ? $field->adminLabel : $field->label;
        }
    }
    return false;
}

Follow up refinement
Combine the webhook and API to run on the same logic
Also add in a dup check for admin fields, where a duplicate append the field ID to the label

<?php

// Hook for custom REST API endpoint
add_action('rest_api_init', function () {
    register_rest_route('gf/v2', '/entries-admin-labels/(?P<entry_id>\d+)', array(
        'methods' => 'GET',
        'callback' => 'get_entry_with_labels_using_admin_label_with_check',
        'permission_callback' => function () {
            return current_user_can('edit_posts');
        },
        'args' => array(
            'entry_id' => array(
                'validate_callback' => function($param, $request, $key) {
                    return is_numeric($param);
                }
            ),
        ),
    ));
});

// REST API callback
function get_entry_with_labels_using_admin_label_with_check(WP_REST_Request $request) {
    $entry_id = $request['entry_id'];

    $entry = GFAPI::get_entry($entry_id);
    if (is_wp_error($entry)) {
        return $entry;
    }

    $form_id = $entry['form_id'];
    $form = GFAPI::get_form($form_id);
    if (!$form) {
        return new WP_Error('form_not_found', 'Form not found', array('status' => 404));
    }

    // Check for duplicate admin labels
    $label_counts = calculate_label_counts($form);

    $labeled_entry = array();
    foreach ($entry as $field_id => $value) {
        if (!is_numeric($field_id)) {
            $labeled_entry[$field_id] = $value;
            continue;
        }

        $label = find_label_with_duplicate_check($form, $field_id, $label_counts);
        $labeled_entry[$label] = $value;
    }

    return new WP_REST_Response($labeled_entry, 200);
}

// Filter for Webhooks
add_filter('gform_webhooks_request_data', function($request_data, $feed, $entry, $form) {
    if (rgars($feed, 'meta/requestBodyType') === 'all_fields') {
        gf_webhooks()->log_debug('gform_webhooks_request_data: Replacing keys with admin labels.');

        // Check for duplicate admin labels
        $label_counts = calculate_label_counts($form);

        foreach ($form['fields'] as $field) {
            $label = find_label_with_duplicate_check($form, $field->id, $label_counts);

            if (isset($field->inputs) && is_array($field->inputs)) {
                foreach ($field->inputs as $input) {
                    if (!empty($request_data[$input['id']])) {
                        $input_label = $label . '-' . $input['label'];
                        $request_data[$input_label] = rgar($entry, $input['id']);
                        unset($request_data[$input['id']]);
                    }
                }
            } else {
                if (isset($request_data[$field->id])) {
                    $request_data[$label] = rgar($entry, $field->id);
                    unset($request_data[$field->id]);
                }
            }
        }
    }

    return $request_data;
}, 10, 4);

// Helper function to ensure unique labels with duplicate check
function find_label_with_duplicate_check($form, $field_id, $label_counts) {
    foreach ($form['fields'] as $field) {
        if ($field->id == $field_id) {
            $base_label = !empty($field->adminLabel) ? $field->adminLabel : $field->label;
            // Append field ID only if there is a duplicate
            return $label_counts[$base_label] > 1 ? $base_label . '-' . $field_id : $base_label;
        }
    }
    return false;
}

// Helper function to calculate label counts
function calculate_label_counts($form) {
    $counts = [];
    foreach ($form['fields'] as $field) {
        $label = !empty($field->adminLabel) ? $field->adminLabel : $field->label;
        if (!isset($counts[$label])) {
            $counts[$label] = 0;
        }
        $counts[$label]++;
    }
    return $counts;
}

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.