1

In Advanced Custom Fields: Which function can I use to get the full meta key of a field by its field key?

So, if I have a field with the name some_field and the field key field_sd54hfs5df: How do I get the name by the key?

I found the function acf_get_fields() and acf_get_field(), but when using field types like group, flexibel_content or repeater the names in the returned arrays are not the full names that are stored in the meta database tables.

For example, when a group has the name some_group and the field some_field the mentioned functions only return some_group or some_field, but not the full meta_key, which is some_group_some_field.

Unfortunately subfields of such a field type are not returned, so I don't see an option to reformat the returned arrays to combine the arrays recursively to built up the full meta key names.


I have written the below method to fetch the field name as stored under the _some-field… metadata by ACF, but when working in an environment with trash metadata and old records this is fetching multiple records, so that isn't a solution.

/**
 * Get a meta key name by a ACF field key
 * 
 * @since 1.0.22
 * 
 * @param string $key
 * @return null|string
 */
public function getUserMetaKey(string $key): ?string
{
    global $wpdb;
    $select = "SELECT distinct meta_key FROM $wpdb->usermeta WHERE meta_value = '$key' AND meta_key NOT LIKE 'acfe_form_actions_%'";
    // Debug::log($select);
    $usermeta = $wpdb->get_results($select);
    // Debug::log($usermeta);
    if (count($usermeta) > 0) {
        $metaKey = $usermeta[0]->meta_key;
        $metaKey = ltrim($metaKey, '_');
        return $metaKey;
    }
    return null;
}

1 Answer 1

1

There's a few ways to achieve this but here's one which supports an unknown depth of children, for example where you have nested groups within groups.

Given the field key "field_{some_hash}" of the field, this function will retrieve the field, and its parent most field, and so on until we reach the top of the field tree.


function custom_acf_get_field_name_by_key( $key ) {

    $field = acf_maybe_get_field( $key );

    if ( empty( $field ) || ! isset( $field['parent'], $field['name'] ) ) {
        return $field;
    }

    $ancestors = array();

    while ( ! empty( $field['parent'] ) && ! in_array( $field['name'], $ancestors ) ) {

        $parent = acf_get_field( $field['parent'] );

        $ancestors[] = $field['name'];

        $field = $parent;

    }

    $formatted_key = array_reverse( $ancestors );
    $formatted_key = implode( '_', $formatted_key );

    return "_$formatted_key";

}


Assume a case where I have a nested group:

 - dev_group_test | field_61ecf308ded3e | group
   ∟ title        | field_61ecf316ded3f | text
   ∟ location     | field_61ecf31cded40 | text
   ∟ sub_group    | field_61ecfa1fe5894 | group
     ∣
     ∟ sub_group_title | field_61ecfa2de5895 | text

If I want the full key of sub_group_title:

$meta_key = custom_acf_get_field_name_by_key( 'field_61ecfa2de5895' );
// result = _dev_group_test_sub_group_sub_group_title

If I want the full key of location:

$meta_key = custom_acf_get_field_name_by_key( 'field_61ecf31cded40' );
// result = _dev_group_test_location

NOTE: there may be more efficient ways to do this

3
  • 1
    Legendary, thank you so much! Note that in the while-loop, $field['parent'] > 0 doesn't seem to work for me, but !empty($field['parent']) does the job.
    – David Wolf
    Jan 23 at 9:38
  • @user1134827 You're welcome. I slapped it together quickly so maybe there is an edge case bug there, does your debug.log throw any warnings/errors? $field['parent'] > 0 is probably not needed anyway, I think, because IIRC every field returns a parent include the top most field, i.e. it always belongs to a parent post object that is stored in the *_posts table. So you can probably do away with that.
    – Adam
    Jan 23 at 9:43
  • 1
    Really appreciate it 🙏. debug.log is empty. Seems like when using $field['parent'] > 0 I got a blank _ (only 1 underscore), removing the condition returns a __foo_bar (2 underscores + field name) and using the !empty($field['parent']) returns _foo_bar (1 underscore + field name).
    – David Wolf
    Jan 23 at 9:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.