have_rows()ACF 4.3.0

have_rows

Checks if a field (such as Repeater or Flexible Content) has any rows of data to loop over. This function is intended to be used in conjunction with the_row() to step through available values.

Хуков нет.

Возвращает

true|false.

Использование

have_rows( $selector, $post_id );
$selector(строка) (обязательный)
The field name or field key.
$post_id(разное)
The post ID where the value is saved.
По умолчанию: current post

Список изменений

С версии 4.3.0 Введена.

Код have_rows() ACF 5.10.2

function have_rows( $selector, $post_id = false ) {

	// Validate and backup $post_id.
	$_post_id = $post_id;
	$post_id  = acf_get_valid_post_id( $post_id );

	// Vars.
	$key         = "selector={$selector}/post_id={$post_id}";
	$active_loop = acf_get_loop( 'active' );
	$prev_loop   = acf_get_loop( 'previous' );
	$new_loop    = false;
	$sub_field   = false;

	// Check if no active loop.
	if ( ! $active_loop ) {
		$new_loop = 'parent';

		// Detect "change" compared to the active loop.
	} elseif ( $key !== $active_loop['key'] ) {

		// Find sub field and check if a sub value exists.
		$sub_field_exists = false;
		$sub_field        = acf_get_sub_field( $selector, $active_loop['field'] );
		if ( $sub_field ) {
			$sub_field_exists = isset( $active_loop['value'][ $active_loop['i'] ][ $sub_field['key'] ] );
		}

		// Detect change in post_id.
		if ( $post_id != $active_loop['post_id'] ) {

			// Case: Change in $post_id was due to this being a nested loop and not specifying the $post_id.
			// Action: Move down one level into a new loop.
			if ( empty( $_post_id ) && $sub_field_exists ) {
				$new_loop = 'child';

				// Case: Change in $post_id was due to a nested loop ending.
				// Action: move up one level through the loops.
			} elseif ( $prev_loop && $prev_loop['post_id'] == $post_id ) {
				acf_remove_loop( 'active' );
				$active_loop = $prev_loop;

				// Case: Chang in $post_id is the most obvious, used in an WP_Query loop with multiple $post objects.
				// Action: leave this current loop alone and create a new parent loop.
			} else {
				$new_loop = 'parent';
			}

			// Detect change in selector.
		} elseif ( $selector != $active_loop['selector'] ) {

			// Case: Change in $field_name was due to this being a nested loop.
			// Action: move down one level into a new loop.
			if ( $sub_field_exists ) {
				$new_loop = 'child';

				// Case: Change in $field_name was due to a nested loop ending.
				// Action: move up one level through the loops.
			} elseif ( $prev_loop && $prev_loop['selector'] == $selector && $prev_loop['post_id'] == $post_id ) {
				acf_remove_loop( 'active' );
				$active_loop = $prev_loop;

				// Case: Change in $field_name is the most obvious, this is a new loop for a different field within the $post.
				// Action: leave this current loop alone and create a new parent loop.
			} else {
				$new_loop = 'parent';
			}
		}
	}

	// Add loop if required.
	if ( $new_loop ) {
		$args = array(
			'key'      => $key,
			'selector' => $selector,
			'post_id'  => $post_id,
			'name'     => null,
			'value'    => null,
			'field'    => null,
			'i'        => -1,
		);

		// Case: Parent loop.
		if ( $new_loop === 'parent' ) {
			$field = get_field_object( $selector, $post_id, false );
			if ( $field ) {
				$args['field'] = $field;
				$args['value'] = $field['value'];
				$args['name']  = $field['name'];
				unset( $args['field']['value'] );
			}

			// Case: Child loop ($sub_field must exist).
		} else {
			$args['field']   = $sub_field;
			$args['value']   = $active_loop['value'][ $active_loop['i'] ][ $sub_field['key'] ];
			$args['name']    = "{$active_loop['name']}_{$active_loop['i']}_{$sub_field['name']}";
			$args['post_id'] = $active_loop['post_id'];
		}

		// Bail early if value is either empty or a non array.
		if ( ! $args['value'] || ! is_array( $args['value'] ) ) {
			return false;
		}

		// Allow for non repeatable data for Group and Clone fields.
		if ( acf_get_field_type_prop( $args['field']['type'], 'have_rows' ) === 'single' ) {
			$args['value'] = array( $args['value'] );
		}

		// Add loop.
		$active_loop = acf_add_loop( $args );
	}

	// Return true if next row exists.
	if ( $active_loop && isset( $active_loop['value'][ $active_loop['i'] + 1 ] ) ) {
		return true;
	}

	// Return false if no next row.
	acf_remove_loop( 'active' );
	return false;
}