Support

Account

Home Forums Backend Issues (wp-admin) Get_field_objects or get_fields inside acf/load_field causes fatal error

Solved

Get_field_objects or get_fields inside acf/load_field causes fatal error

  • Hi,

    using either of these functions (get_field_objects or get_fields) inside the acf/load_field filter results in a fatal error. All memory gets eaten up when the post in which it’s used is opened.

    I am curious to know why this happens. If someone can explain it would be lovely.

    To explain my reasoning behind doing this. I want to dynamically populate a checkbox field with values from a field group (not the Group field introduced in 5.0). The checkboxes would allow a simple choice of which fields to display when the post excerpt is loaded, as I do not want to load all fields from the field group, but the fields to be loaded are different for each post.

    This was my conceptual solution but seems it will not work out this way.

    Example code:

    function acf_load_choices( $field )
    {
    
    	$field['choices'] = array();
    
    	// Using get_field_objects() or get_fields() here causes the crash
    	$choices = get_field_objects();
    
    	$field['choices'] = $choices;
    
    	foreach ( $choices as  $key => $choice )
    	{
    		$field['choices'][ $key ] = $choice['label'];
    	}
    
    	return $field;
    }
    add_filter( 'acf/load_field/name=checkbox_choices', 'acf_load_choices' );

    Thanks

    EDIT: After thinking a bit more I assume that using a plural function to fetch fields causes an infinite loop upon post update/publish.

    This issue does not occur if a post is opened which was saved before the function is in the codebase. So the issue happens upon save execution.

  • I fixed my issues and if anyone runs into a similar problem here is my solution.

    As using the above-mentioned functions (get_fields & get_field_objects) in any form caused an infinite loop I made a workaround for my problem. Solved it by writing a separate function which uses get_post_meta to fetch all fields using the post ID of the ACF field group. These fields are then quickly filtered to remove metadata. There is also a check for a field value using get_field, which is an optional step to hide fields without a value set. This could potentially cause a lot of queries if you have lots of fields.

    I load the function on admin_init, which is probably not the best hook to use, if someone has any pointers into using a better hook for this I would like to know.

    The fixed code is following.

    function fetch_custom_field_group( $acf_post_id ) {
    
    	$post_meta = get_post_meta($acf_post_id);
    
    	if ( ! is_array($post_meta) ) {
    		return;
    	}
    
    	foreach ( $post_meta as $item ) {
    		
    		// Unserialize get_post_meta data into a usable array
    		$item = unserialize($item[0]);
    
    		// Check whether field has a value set
    		$field = get_field( $item['name'] );
    
    		// Check if unserialize returned and whether the field has a key, filtering out any unnecessary fields
    		// optionally at last add a check to not show fields with empty values
    		if ( $item === false || empty($item['key']) || empty($field) ) {
    			continue;
    		}
    
    		// Fill everything into a new array that can be used
    		$acf_fields[] = $item;
    	}
    
    	return $acf_fields;
    
    }
    add_action('admin_init', 'fetch_custom_field_group');

    The rewritten function for loading field choices is separate from the actual hook and can be reused, just by passing the ACF field group ID into the 2nd function argument.

    function acf_load_field_choices( $field, $acf_post_id ) {
    
    	// Empty the choices array, ensuring nothing is there
    	$field['choices'] = array();
    
    	// Get all fields from the ACF field group we are using
    	$choices = fetch_custom_field_group($acf_post_id);
    
    	// Get names to be used as keys for the input fields
    	$choice_name = array_column( $choices, 'name' );
    
    	// Get labels to be used as labels for the input fields
    	$choice_label = array_column( $choices, 'label' );
    
    	// Combine into key-value pair of names and labels
    	$choices = array_combine( $choice_name, $choice_label );
    
    	$field['choices'] = $choices;
    
    	return $field;
    }

    And finally, for acf/_load_field filter, I just return the previous function passing the ID of the ACF field group I want to use.

    function acf_load_my_checkbox_field( $field ) {
    
    	return acf_load_field_choices($field, 198);
    
    }
    add_filter( 'acf/load_field/name=your_field_name', 'acf_load_my_checkbox_field' );

    Screenshot of result: ACF dynamically generated checkbox field based on other ACF fields

  • I stepped through the code and found an easier way. First parameter I believe can be the group slug string or ID. Didn’t get to the bottom of what was causing the infinite loop.

    $group_fields = acf_get_raw_fields('group_5a18e8e4866e0');

Viewing 3 posts - 1 through 3 (of 3 total)

The topic ‘Get_field_objects or get_fields inside acf/load_field causes fatal error’ is closed to new replies.