Index Table – Indexing ACF repeater field titles and contents

Using this custom code, you can enable indexing of Advanced Custom Fields repeater field post titles and/or contents for the current post. Change the following parameters in the $arguments variable in the first part of the code as you need them:

  • 'field_names' -> one or more repeater field names, separated by comma

  • 'index_title' -> true or false, to index the post titles found in the repeater field

  • 'index_content' -> true or false, to index the post contents found in the repeater field

  • 'run_shortcodes' -> true or false, to run the shortcodes in the content fields

What is this, and where do I put this custom code?

add_filter(
	'asp_index_cf_contents_before_tokenize', // do not change this
	function ( $content, $post ) {

		// Change these arguments to your needs
		$arguments = array(
			'field_names'    => 'field1, field2', // Comma separated list of field names to index
			'index_title'    => true,     // To index the related post title
			'index_content'  => true, // To index the related post content
			'run_shortcodes' => true, // To run shortcodes within Flex element contents
		);

		// --------------------- WARNING: DO NOT CHANGE ANYTHING BELOW -------------------------
		$o = new class($arguments, $content, $post) {
			/**
			 * @var string
			 */
			private string $field_names = 'field1, field2';
			/**
			 * @var bool
			 */
			private bool $index_title = true;
			/**
			 * @var bool
			 */
			private bool $index_content = true;
			/**
			 * @var bool
			 */
			private bool $run_shortcodes = true;

			/**
			 * @var string
			 */
			private string $content;

			/**
			 * @var WP_Post
			 */
			private WP_Post $post;

			/**
			 * @param array<string, mixed> $args
			 */
			public function __construct( array $args, $content, $post ) {
				$this->field_names    = $args['field_names'] ?? $this->field_names;
				$this->index_title    = $args['index_title'] ?? $this->index_title;
				$this->index_content  = $args['index_content'] ?? $this->index_content;
				$this->run_shortcodes = $args['run_shortcodes'] ?? $this->run_shortcodes;
				$this->content        = $content;
				$this->post           = $post;
			}

			/**
			 * @param mixed $any
			 * @param int   $level
			 * @return string
			 */
			private function anyToString( $any, int $level = 0 ): string {
				$str = '';
				if ( is_array( $any ) ) {
					foreach ( $any as $sub_arr ) {
						$str .= ' ' . $this->anyToString( $sub_arr, $level + 1 );
					}
				} elseif ( !is_object($any) ) {
					$str = (string) $any;
				}

				return $str;
			}

			public function fetchRepeater(): string {
				$content = $this->content;
				$post    = $this->post;
				if ( function_exists('get_field') ) {

					$fn_arr = explode(',', $this->field_names);
					foreach ( $fn_arr as $field_name ) {
						$field_name = trim($field_name);
						if ( empty($field_name) ) {
							continue;
						}

						$args     = array(
							'p'         => $post->ID, // ID of a page, post, or custom type
							'post_type' => 'any',
						);
						$my_query = new WP_Query( $args );
						while ( $my_query->have_posts() ) :
							$my_query->the_post();
							$items = get_field($field_name);
							if ( empty($items) ) {
								continue;
							}
							if ( is_array($items) ) {
								foreach ( $items as $item ) {
									if ( isset($item->ID) ) {
										if ( $this->index_title ) {
											$content .= ' ' . get_the_title($item->ID);
										}
										if ( $this->index_content ) {
											$content .= ' ' . apply_filters('the_content', get_post_field('post_content', $item->ID));
										}
									} elseif ( is_array($item) || is_string($item) ) {
										if ( $this->run_shortcodes ) {
											$content .= ' ' . do_shortcode( $this->anyToString($item));
										} else {
											$content .= ' ' . $this->anyToString($item);
										}
									}
								}
							} elseif ( is_string($items) ) {
								$content .= ' ' . $items;
							}

						endwhile;
					}
				}
				return $content;
			}
		};

		return $o->fetchRepeater();
	},
	10,
	2
);

Last updated