ACF Repeater Mapper

Populate all rows from an ACF Repeater into a choice-based field.

Instructions

  1. Enable “Populate choices dynamically” on any choice-based field.
  2. Select the “Post”, “User” or “Term” object type.
  3. Apply any desired filters to determine which post(s) should have their repeater data populated.
  4. Use the “Choice Template” to match each choice property to a repeater subfield. For example, if your repeater is labeled “parts” and you want to populate the “name” subfield as the choice label, select “parts_0_name” for the “Label” template. Screenshot.
  5. Add the “gppa-acf-repeater-mapper” to the field’s CSS Class Name setting.

Code

Filename: gppa-acf-repeater-mapper.php

<?php
/**
 * Gravity Perks // Populate Anything // ACF Repeater Mapper
 * https://gravitywiz.com/documentation/gravity-forms-populate-anything/
 *
 * Populate all rows from an ACF Repeater into a choice-based field.
 *
 * Instructions
 *
 * 1. Enable "Populate choices dynamically" on any choice-based field.
 * 2. Select the "Post", "User" or "Term" object type.
 * 3. Apply any desired filters to determine which post(s) should have their repeater data populated.
 * 4. Use the "Choice Template" to match each choice property to a repeater subfield.
 *    For example, if your repeater is labeled "parts" and you want to populate the "name" subfield as the choice label,
 *    select "parts_0_name" for the "Label" template. [Screenshot](https://gwiz.io/3m4Yq0y).
 * 5. Add the "gppa-acf-repeater-mapper" to the field's CSS Class Name setting.
 *
 * Video
 *
 * https://www.loom.com/share/a375fd3a5e6a4931a55e50d51eaec951
 *
 * Plugin Name:  GP Populate Anything — ACF Repeater Mapper
 * Plugin URI:   https://gravitywiz.com/documentation/gravity-forms-populate-anything/
 * Description:  Populate all rows from an ACF Repeater into a choice-based field.
 * Author:       Gravity Wiz
 * Version:      0.4
 * Author URI:   https://gravitywiz.com
 */
add_filter( 'gppa_input_choices', function( $choices, $field, $objects ) {

	if ( strpos( $field->cssClass, 'gppa-acf-repeater-mapper' ) === false ) {
		return $choices;
	}

	$map        = array();
	$custom_map = array();

	foreach ( $field->{'gppa-choices-templates'} as $template => $key ) {
		/**
		 * Look for ACF repeater meta: repeater_name_0_subfield_name
		 *
		 * Known limitation: This cannot have a number on the repeater field name. For an enumerator, it is
		 * recommended to use alphabets like, repeater_name_a_0_name, repeater_name_b_1_name,etc.
		 */
		if ( preg_match( '/meta_([^0-9]+)_([0-9]+)_(.+)/', $key, $matches ) ) {
			list( , $repeater, $index, $subfield ) = $matches;
			$map[ $template ]                      = $subfield;
		} else {
			$custom_map[ $template ] = $key;
		}
	}

	if ( ! $repeater ) {
		return $choices;
	}

	$choices = array();

	foreach ( $objects as $object ) {
		$rows = get_field( $repeater, $object->ID );
		if ( get_class( $object ) == 'WP_User' ) {
			$rows = get_field( $repeater, 'user_' . $object->ID );
		}
		if ( get_class( $object ) == 'WP_Term' ) {
			$rows = get_field( $repeater, $object->taxonomy . '_' . $object->term_id );
		}

		if ( $rows ) {
			foreach ( $rows as $row ) {
				$choice['text'] = isset( $map['label'] ) ?
					apply_filters( 'gppa_acfrm_label', rgar( $row, $map['label'] ), $row, $map['label'] ) :
					( isset( $custom_map['label'] ) ? str_replace( 'gf_custom:', '', $custom_map['label'] ) : '' );

				$choice['value'] = isset( $map['value'] ) ?
					apply_filters( 'gppa_acfrm_value', rgar( $row, $map['value'] ), $row, $map['value'] ) :
					( isset( $custom_map['value'] ) ? str_replace( 'gf_custom:', '', $custom_map['value'] ) : '' );

				$image = isset( $map['image'] ) ?
					apply_filters( 'gppa_acfrm_image', rgar( $row, $map['image'] ), $row, $map['image'] ) :
					( isset( $custom_map['image'] ) ? str_replace( 'gf_custom:', '', $custom_map['image'] ) : '' );

				if ( $image ) {
					// Get the attachment id from the image url as `Image Choice` field requires `attachment_id` to display image.
					$attachment_id = attachment_url_to_postid( $image );

					if ( $attachment_id ) {
						$choice['attachment_id'] = $attachment_id;
					}
				}

				if ( isset( $map['inventory_limit'] ) ) {
					$choice['inventory_limit'] = apply_filters( 'gppa_acfrm_inventory_limit', rgar( $row, $map['inventory_limit'] ), $row, $map['inventory_limit'] );
				}

				$choice['price'] = isset( $map['price'] ) ?
					apply_filters( 'gppa_acfrm_price', rgar( $row, $map['price'] ), $row, $map['price'] ) :
					( isset( $custom_map['price'] ) ? str_replace( 'gf_custom:', '', $custom_map['price'] ) : '' );

				$choices[] = $choice;
			}
		}
	}

	return $choices;
}, 10, 3 );

Comments

  1. Kenny Waddell
    Kenny Waddell April 29, 2025 at 2:52 pm

    Is there a way to make this work with the database choice, I have an options page that is powering a food menu using ACF repeater fields. I can populate the GF with the choices but the dish name are really long and have another field in the row for a keyword but can’t figure out how to get this to populate another field when the long dish name is selected Would this snippet be able to do it?

    Reply
    1. J Yeager
      J Yeager Staff April 29, 2025 at 5:02 pm

      Hey Kenny,

      This is a bit tricky to answer without seeing your full setup, so let’s dig into this one further via support. I’ve sent you an email with more details.

Leave a Reply

Your email address will not be published. Required fields are marked *

  • Trouble installing this snippet? See our troubleshooting tips.
  • Need to include code? Create a gist and link to it in your comment.
  • Reporting a bug? Provide a URL where this issue can be recreated.

By commenting, I understand that I may receive emails related to Gravity Wiz and can unsubscribe at any time.