acf_field_relationship::get_ajax_querypublicACF 5.0.9

Returns an array of data formatted for use in a select2 AJAX response.

Method of the class: acf_field_relationship{}

Returns

array|false.

Usage

$acf_field_relationship = new acf_field_relationship();
$acf_field_relationship->get_ajax_query( $options );
$options(array)
An array of options for the query.
Default: array()

Changelog

Since 5.0.9 Introduced.

acf_field_relationship::get_ajax_query() code ACF 6.8.8

public function get_ajax_query( $options = array() ) {
	// defaults
	$options = wp_parse_args(
		$options,
		array(
			'post_id'   => 0,
			's'         => '',
			'field_key' => '',
			'paged'     => 1,
			'post_type' => '',
			'include'   => '',
			'taxonomy'  => '',
		)
	);

	// load field
	$field = acf_get_field( $options['field_key'] );
	if ( ! $field ) {
		return false;
	}

	// vars
	$results   = array();
	$args      = array();
	$s         = false;
	$is_search = false;

	// paged
	$args['posts_per_page'] = 20;
	$args['paged']          = (int) $options['paged'];

	// search
	if ( $options['s'] !== '' && empty( $options['include'] ) ) {
		// strip slashes (search may be integer)
		$s = wp_unslash( strval( $options['s'] ) );

		// update vars
		$args['s'] = $s;
		$is_search = true;
	}

	// post_type - validate user input against field config to prevent bypass.
	if ( ! empty( $field['post_type'] ) ) {
		$allowed_post_types = acf_get_array( $field['post_type'] );

		if ( ! empty( $options['post_type'] ) ) {
			// User is filtering - only allow post types within field config.
			$requested_types   = acf_get_array( $options['post_type'] );
			$args['post_type'] = array_intersect( $requested_types, $allowed_post_types );

			if ( empty( $args['post_type'] ) ) {
				// Requested types not allowed, fall back to field config.
				$args['post_type'] = $allowed_post_types;
			}
		} else {
			$args['post_type'] = $allowed_post_types;
		}
	} elseif ( ! empty( $options['post_type'] ) ) {
		// No field restriction, allow user filter.
		$args['post_type'] = acf_get_array( $options['post_type'] );
	} else {
		$args['post_type'] = acf_get_post_types();
	}

	// Post status - use field config only, don't accept from user input.
	if ( ! empty( $field['post_status'] ) ) {
		$args['post_status'] = acf_get_array( $field['post_status'] );
	}

	// taxonomy - validate user input against field config to prevent bypass.
	if ( ! empty( $field['taxonomy'] ) ) {
		// Field has taxonomy restrictions.
		$allowed_terms = acf_decode_taxonomy_terms( $field['taxonomy'] );

		if ( ! empty( $options['taxonomy'] ) ) {
			// User is filtering - validate both taxonomy AND term are allowed.
			$term = acf_decode_taxonomy_term( $options['taxonomy'] );

			if ( $term && isset( $allowed_terms[ $term['taxonomy'] ] ) && in_array( $term['term'], $allowed_terms[ $term['taxonomy'] ], true ) ) {
				// Taxonomy:term combination is allowed.
				$args['tax_query']   = array();
				$args['tax_query'][] = array(
					'taxonomy' => $term['taxonomy'],
					'field'    => 'slug',
					'terms'    => $term['term'],
				);
			} else {
				// Requested taxonomy:term not allowed, fall back to field config.
				$args['tax_query'] = array( 'relation' => 'OR' );

				foreach ( $allowed_terms as $k => $v ) {
					$args['tax_query'][] = array(
						'taxonomy' => $k,
						'field'    => 'slug',
						'terms'    => $v,
					);
				}
			}
		} else {
			// No user filter, use field config.
			$args['tax_query'] = array( 'relation' => 'OR' );

			foreach ( $allowed_terms as $k => $v ) {
				$args['tax_query'][] = array(
					'taxonomy' => $k,
					'field'    => 'slug',
					'terms'    => $v,
				);
			}
		}
	} elseif ( ! empty( $options['taxonomy'] ) ) {
		// No field restriction, allow user filter.
		$term = acf_decode_taxonomy_term( $options['taxonomy'] );

		if ( $term ) {
			$args['tax_query']   = array();
			$args['tax_query'][] = array(
				'taxonomy' => $term['taxonomy'],
				'field'    => 'slug',
				'terms'    => $term['term'],
			);
		}
	}

	if ( ! empty( $options['include'] ) ) {
		// If we have an include, we need to return only the selected posts.
		$args['post__in'] = array( (int) $options['include'] );
	}

	$args['perm'] = 'readable';
	$args         = acf_ensure_perm_readable_post_status( $args );

	// filters
	$args = apply_filters( 'acf/fields/relationship/query', $args, $field, $options['post_id'] );
	$args = apply_filters( 'acf/fields/relationship/query/name=' . $field['name'], $args, $field, $options['post_id'] );
	$args = apply_filters( 'acf/fields/relationship/query/key=' . $field['key'], $args, $field, $options['post_id'] );

	// Re-normalize in case a filter reset `post_status` to 'any' while leaving `perm=readable`.
	$args = acf_ensure_perm_readable_post_status( $args );

	// get posts grouped by post type
	$groups = acf_get_grouped_posts( $args );

	// bail early if no posts
	if ( empty( $groups ) ) {
		return false;
	}

	// loop
	foreach ( array_keys( $groups ) as $group_title ) {

		// vars
		$posts = acf_extract_var( $groups, $group_title );

		// data
		$data = array(
			'text'     => $group_title,
			'children' => array(),
		);

		// convert post objects to post titles
		foreach ( array_keys( $posts ) as $post_id ) {
			$posts[ $post_id ] = $this->get_post_title( $posts[ $post_id ], $field, $options['post_id'] );
		}

		// order posts by search
		if ( $is_search && empty( $args['orderby'] ) && isset( $args['s'] ) ) {
			$posts = acf_order_by_search( $posts, $args['s'] );
		}

		// append to $data
		foreach ( array_keys( $posts ) as $post_id ) {
			$data['children'][] = $this->get_post_result( $post_id, $posts[ $post_id ] );
		}

		// append to $results
		$results[] = $data;
	}

	// add as optgroup or results
	if ( count( $args['post_type'] ) === 1 ) {
		$results = $results[0]['children'];
	}

	return array(
		'results' => $results,
		'limit'   => $args['posts_per_page'],
	);
}