When not to use custom fields

I love using Advanced Custom Fields to supercharge WordPress’ custom fields. With ACF, custom fields can be finely tuned to the needs of clients giving them a solid backend website experience. I recently attempted to use a custom field repeater with a large data set which I ended up scrapping due to PHP limitations.

PHP has it’s own limits

While technically there isn’t any limitation with the number of custom fields, there is a very real limit in the number of variables PHP can process. This is known as the PHP max_vars limit. This can be increased however you should really check with your hosting provider to determine what valuable is acceptable. With WP Engine they recommend not increasing above 5000 with their default being 1000.

Huge repeating fields will hit the limits

The following is a project I was working on when I discovered I hit the limit. At around 250+ rows I had trouble add new rows. Rows would be randomly lost when changes were made and updated. This same limit is also most commonly hit when you attempt to do massive menus within Appearances > Menus.

massive-repeater

The solution, use custom post types

Instead of using a repeater field with subfields for this project I switched over to a new custom post type with custom fields. As a custom post type, each former repeater item is managed in a separate posts.

Each post then has a similar set of custom fields which were previously subfields of the repeater field.

Automate when possible

Having 250+ entries as a repeating field, I didn’t want to manually recreate them as custom post types. I used the following code to generate a new custom post type per each custom field.

$count_stations = wp_count_posts('station');
$published_stations = $count_stations->publish;

// If there are no stations then generate them
if( $published_stations < 1) {                      

    echo "Populating stations";

    if( get_field('stations') ) { 

        while( the_repeater_field('stations') ) { 

            // Create post object
            $my_post = array(
              'post_title'    => get_sub_field('call_letters'),
              'post_type'     => 'station',
              'post_status'   => 'publish',
              'post_author'   => 1,
            );

            // insert the post into the database
            $post_id = wp_insert_post( $my_post );

            // save new ACF custom fields from repeater subfields
            $field_key = "field_5782a75254950";
            $value = get_sub_field('frequency');
            update_field( $field_key, $value, $post_id );

            $field_key = "field_5782a75254951";
            $value = get_sub_field('city');
            update_field( $field_key, $value, $post_id );

            $field_key = "field_5782a75254952";
            $value = get_sub_field('state');
            update_field( $field_key, $value, $post_id );

            $field_key = "field_5782a75254953";
            $value = get_sub_field('air_timeday');
            update_field( $field_key, $value, $post_id );

            $field_key = "field_5782a75254954";
            $value = get_sub_field('programs');
            update_field( $field_key, $value, $post_id );

        }
    }
}