src/properties/class-papi-property-repeater.php
public function format_value( $values, $repeater_slug, $post_id ) {
		if ( ! is_array( $values ) ) {
			return [];
		}

		$top_property = new Papi_Core_Property;

		foreach ( $values as $index => $row ) {
			if ( ! is_array( $row ) ) {
				continue;
			}

			$top_property->slug = $repeater_slug . '_' . $index;

			foreach ( $row as $slug => $value ) {
				if ( papi_is_property_type_key( $slug ) ) {
					continue;
				}

				// Property type slug may have a prefixed underscore.
				$property_type_slug = papi_get_property_type_key_f( $slug );

				if ( ! isset( $row[$property_type_slug] ) ) {
					// If property type slug isn't prefixed we should try without.
					$property_type_slug = papi_get_property_type_key( $slug );

					if ( ! isset( $row[$property_type_slug] ) ) {
						continue;
					}
				}

				// Get property type.
				$property_type_value = $row[$property_type_slug];
				$property_type       = papi_get_property_type( $property_type_value );

				if ( ! is_object( $property_type ) ) {
					continue;
				}


				// Get property child slug.
				$child_slug = $this->get_child_slug( $repeater_slug, $slug );

				// Set top property.
				$property_type->set_parent_property( $top_property );

				// Create cache key.
				$cache_key = sprintf( '%s_%s', $top_property->slug, $slug );
				if ( $parent_property = $this->get_parent_property() ) {
					$cache_key = sprintf( '%s_%s', $parent_property->get_slug( true ), $cache_key );
				}

				// Get raw value from cache if enabled.
				if ( $this->cache ) {
					$raw_value = papi_cache_get( $cache_key, $post_id, $this->get_meta_type() );
				} else {
					$raw_value = false;
				}

				// Load the value.
				if ( $raw_value === null || $raw_value === false ) {
					$row[$slug] = $property_type->load_value( $value, $child_slug, $post_id );
					$row[$slug] = papi_filter_load_value( $property_type->type, $row[$slug], $child_slug, $post_id, papi_get_meta_type() );

					if ( ! papi_is_empty( $row[$slug] ) && $this->cache ) {
						papi_cache_set( $cache_key, $post_id, $row[$slug], $this->get_meta_type() );
					}
				} else {
					$row[$slug] = $raw_value;
				}

				// Format the value from the property class.
				$row[$slug] = $property_type->format_value( $row[$slug], $child_slug, $post_id );

				if ( ! papi_is_admin() ) {
					$row[$slug] = papi_filter_format_value( $property_type->type, $row[$slug], $child_slug, $post_id, papi_get_meta_type() );
				}

				$row[$property_type_slug] = $property_type_value;

				if ( papi_is_empty( $row[$slug] ) ) {
					$row[$slug] = $property_type_value->get_option( 'default', $property_type_value->default_value );
				}
			}

			if ( ! papi_is_admin() ) {
				foreach ( $row as $slug => $value ) {
					if ( papi_is_property_type_key( $slug ) ) {
						unset( $row[$slug] );
					}
				}
			}

			$values[$index] = $row;
		}

		return $values;
	}
public function format_value( $values, $repeater_slug, $post_id ) {
		if ( ! is_array( $values ) ) {
			return [];
		}

		$top_property = new Papi_Core_Property;

		foreach ( $values as $index => $row ) {
			if ( ! is_array( $row ) ) {
				continue;
			}

			$top_property->slug = $repeater_slug . '_' . $index;

			foreach ( $row as $slug => $value ) {
				if ( papi_is_property_type_key( $slug ) ) {
					continue;
				}

				// Property type slug may have a prefixed underscore.
				$property_type_slug = papi_get_property_type_key_f( $slug );

				if ( ! isset( $row[$property_type_slug] ) ) {
					// If property type slug isn't prefixed we should try without.
					$property_type_slug = papi_get_property_type_key( $slug );

					if ( ! isset( $row[$property_type_slug] ) ) {
						continue;
					}
				}

				// Get property type.
				$property_type_value = $row[$property_type_slug];
				$property_type       = papi_get_property_type( $property_type_value );

				if ( ! is_object( $property_type ) ) {
					continue;
				}


				// Get property child slug.
				$child_slug = $this->get_child_slug( $repeater_slug, $slug );

				// Set top property.
				$property_type->set_parent_property( $top_property );

				// Create cache key.
				$cache_key = sprintf( '%s_%s', $top_property->slug, $slug );
				if ( $parent_property = $this->get_parent_property() ) {
					$cache_key = sprintf( '%s_%s', $parent_property->get_slug( true ), $cache_key );
				}

				// Get raw value from cache if enabled.
				if ( $this->cache ) {
					$raw_value = papi_cache_get( $cache_key, $post_id, $this->get_meta_type() );
				} else {
					$raw_value = false;
				}

				// Load the value.
				if ( $raw_value === null || $raw_value === false ) {
					$row[$slug] = $property_type->load_value( $value, $child_slug, $post_id );
					$row[$slug] = papi_filter_load_value( $property_type->type, $row[$slug], $child_slug, $post_id, papi_get_meta_type() );

					if ( ! papi_is_empty( $row[$slug] ) && $this->cache ) {
						papi_cache_set( $cache_key, $post_id, $row[$slug], $this->get_meta_type() );
					}
				} else {
					$row[$slug] = $raw_value;
				}

				// Format the value from the property class.
				$row[$slug] = $property_type->format_value( $row[$slug], $child_slug, $post_id );

				if ( ! papi_is_admin() ) {
					$row[$slug] = papi_filter_format_value( $property_type->type, $row[$slug], $child_slug, $post_id, papi_get_meta_type() );
				}

				$row[$property_type_slug] = $property_type_value;

				if ( papi_is_empty( $row[$slug] ) ) {
					$row[$slug] = $property_type_value->get_option( 'default', $property_type_value->default_value );
				}
			}

			if ( ! papi_is_admin() ) {
				foreach ( $row as $slug => $value ) {
					if ( papi_is_property_type_key( $slug ) ) {
						unset( $row[$slug] );
					}
				}
			}

			$values[$index] = $row;
		}

		return $values;
	}
Format the value of the property before it's returned
to WordPress admin or the site.

@param  mixed  $values
@param  string $repeater_slug
@param  int    $post_id

@return array