Support

Account

Home Forums Bug Reports acf_get_value notice incorrect Reply To: acf_get_value notice incorrect

  • Hi John,

    I’ve tested again with a clean install to make sure it’s not in my codebase.
    I took the latest WP 5.9 + latest ACF 5.11.4 and added the following to the function.php to trigger the error:

    
        acf_add_local_field_group([
            "key" => "group_Feature toggles",
            "title" => "Feature Toggles",
            "fields" => [
                [
                    "type" => "true_false",
                    "name" => "anchor_tags",
                    "label" => "Anchor Tags",
                    "key" => "field_feature_toggles_anchor_tags",
                ],
                ]
            ]);
            
        get_field('anchor_tags', 'option');
    

    Yes wrapping it in acf/init suppresses the notice but as the documentation states it should not be required. acf_maybe_get_field triggers init before it gets the value. So even without wrapping it will always be initialized looking at the code.

    I’ve been digging in the ACF codebase and I think the root cause lies within the acf_maybe_get_field code:

    
    /*
    *  acf_get_object_field
    *
    *  This function will return a field for the given selector.
    *  It will also review the field_reference to ensure the correct field is returned which makes it useful for the template API
    *
    *  @type    function
    *  @date    4/08/2015
    *  @since   5.2.3
    *
    *  @param   $selector (mixed) identifyer of field. Can be an ID, key, name or post object
    *  @param   $post_id (mixed) the post_id of which the value is saved against
    *  @param   $strict (boolean) if true, return a field only when a field key is found.
    *  @return  $field (array)
    */
    function acf_maybe_get_field( $selector, $post_id = false, $strict = true ) {
    
    	// init
    	acf_init();
    
    	// Check if field key was given.
    	if ( acf_is_field_key( $selector ) ) {
    		return acf_get_field( $selector );
    	}
    
    	// Lookup field via reference.
    	$post_id = acf_get_valid_post_id( $post_id );
    	$field   = acf_get_meta_field( $selector, $post_id );
    	if ( $field ) {
    		return $field;
    	}
    
    	// Lookup field loosely via name.
    	if ( ! $strict ) {
    		return acf_get_field( $selector );
    	}
    
    	// Return no result.
    	return false;
    }
    

    When get_field is called the second thing it does is call acf_maybe_get_field.
    So what happens:
    1) init
    2) check if key (it’s not)
    3) try to get the field using the hidden metadata using acf_get_meta_field which will fail because it has not yet been saved to the database.
    4) $strict is true so it will not trigger acf_get_field
    5) now we return false.

    The acf_get_meta_field only looks at the DB so this is where I think it initially goes wrong and because this method runs in strict mode it never calls acf_get_field which would resolve the field just fine.

    Why does acf_get_meta_field only look at the DB if the local store has a mapping between field keys and names?
    Why was this strict mode introduced? Did ACF stop supporting getting a value by name? That would explain a lot.

    How I think this issue should be resolved:
    acf_get_reference which is called by acf_get_meta_field should check the local store to map a name to a key and fall back to the DB when it can’t find one although I think that situation would trigger this new notice. So I wonder if fetching this info from the DB would be needed at all.