WP_REST_Terms_Controller::get_items( WP_REST_Request $request ): WP_REST_Response|WP_Error

In this article

Retrieves terms associated with a taxonomy.

Parameters

$requestWP_REST_Requestrequired
Full details about the request.

Return

WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.

Source

public function get_items( $request ) {

	// Retrieve the list of registered collection query parameters.
	$registered = $this->get_collection_params();

	/*
	 * This array defines mappings between public API query parameters whose
	 * values are accepted as-passed, and their internal WP_Query parameter
	 * name equivalents (some are the same). Only values which are also
	 * present in $registered will be set.
	 */
	$parameter_mappings = array(
		'exclude'    => 'exclude',
		'include'    => 'include',
		'order'      => 'order',
		'orderby'    => 'orderby',
		'post'       => 'post',
		'hide_empty' => 'hide_empty',
		'per_page'   => 'number',
		'search'     => 'search',
		'slug'       => 'slug',
	);

	$prepared_args = array( 'taxonomy' => $this->taxonomy );

	/*
	 * For each known parameter which is both registered and present in the request,
	 * set the parameter's value on the query $prepared_args.
	 */
	foreach ( $parameter_mappings as $api_param => $wp_param ) {
		if ( isset( $registered[ $api_param ], $request[ $api_param ] ) ) {
			$prepared_args[ $wp_param ] = $request[ $api_param ];
		}
	}

	if ( isset( $prepared_args['orderby'] ) && isset( $request['orderby'] ) ) {
		$orderby_mappings = array(
			'include_slugs' => 'slug__in',
		);

		if ( isset( $orderby_mappings[ $request['orderby'] ] ) ) {
			$prepared_args['orderby'] = $orderby_mappings[ $request['orderby'] ];
		}
	}

	if ( isset( $registered['offset'] ) && ! empty( $request['offset'] ) ) {
		$prepared_args['offset'] = $request['offset'];
	} else {
		$prepared_args['offset'] = ( $request['page'] - 1 ) * $prepared_args['number'];
	}

	$taxonomy_obj = get_taxonomy( $this->taxonomy );

	if ( $taxonomy_obj->hierarchical && isset( $registered['parent'], $request['parent'] ) ) {
		if ( 0 === $request['parent'] ) {
			// Only query top-level terms.
			$prepared_args['parent'] = 0;
		} else {
			if ( $request['parent'] ) {
				$prepared_args['parent'] = $request['parent'];
			}
		}
	}

	/*
	 * When a taxonomy is registered with an 'args' array,
	 * those params override the `$args` passed to this function.
	 *
	 * We only need to do this if no `post` argument is provided.
	 * Otherwise, terms will be fetched using `wp_get_object_terms()`,
	 * which respects the default query arguments set for the taxonomy.
	 */
	if (
		empty( $prepared_args['post'] ) &&
		isset( $taxonomy_obj->args ) &&
		is_array( $taxonomy_obj->args )
	) {
		$prepared_args = array_merge( $prepared_args, $taxonomy_obj->args );
	}

	$is_head_request = $request->is_method( 'HEAD' );
	if ( $is_head_request ) {
		// Force the 'fields' argument. For HEAD requests, only term IDs are required.
		$prepared_args['fields'] = 'ids';
		// Disable priming term meta for HEAD requests to improve performance.
		$prepared_args['update_term_meta_cache'] = false;
	}

	/**
	 * Filters get_terms() arguments when querying terms via the REST API.
	 *
	 * The dynamic portion of the hook name, `$this->taxonomy`, refers to the taxonomy slug.
	 *
	 * Possible hook names include:
	 *
	 *  - `rest_category_query`
	 *  - `rest_post_tag_query`
	 *
	 * Enables adding extra arguments or setting defaults for a terms
	 * collection request.
	 *
	 * @since 4.7.0
	 *
	 * @link https://developer.wordpress.org/reference/functions/get_terms/
	 *
	 * @param array           $prepared_args Array of arguments for get_terms().
	 * @param WP_REST_Request $request       The REST API request.
	 */
	$prepared_args = apply_filters( "rest_{$this->taxonomy}_query", $prepared_args, $request );

	if ( ! empty( $prepared_args['post'] ) ) {
		$query_result = wp_get_object_terms( $prepared_args['post'], $this->taxonomy, $prepared_args );

		// Used when calling wp_count_terms() below.
		$prepared_args['object_ids'] = $prepared_args['post'];
	} else {
		$query_result = get_terms( $prepared_args );
	}

	$count_args = $prepared_args;

	unset( $count_args['number'], $count_args['offset'] );

	$total_terms = wp_count_terms( $count_args );

	// wp_count_terms() can return a falsey value when the term has no children.
	if ( ! $total_terms ) {
		$total_terms = 0;
	}

	if ( ! $is_head_request ) {
		$response = array();
		foreach ( $query_result as $term ) {
			$data       = $this->prepare_item_for_response( $term, $request );
			$response[] = $this->prepare_response_for_collection( $data );
		}
	}

	$response = $is_head_request ? new WP_REST_Response( array() ) : rest_ensure_response( $response );

	// Store pagination values for headers.
	$per_page = (int) $prepared_args['number'];
	$page     = (int) ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 );

	$response->header( 'X-WP-Total', (int) $total_terms );

	$max_pages = (int) ceil( $total_terms / $per_page );

	$response->header( 'X-WP-TotalPages', $max_pages );

	$request_params = $request->get_query_params();
	$collection_url = rest_url( rest_get_route_for_taxonomy_items( $this->taxonomy ) );
	$base           = add_query_arg( urlencode_deep( $request_params ), $collection_url );

	if ( $page > 1 ) {
		$prev_page = $page - 1;

		if ( $prev_page > $max_pages ) {
			$prev_page = $max_pages;
		}

		$prev_link = add_query_arg( 'page', $prev_page, $base );
		$response->link_header( 'prev', $prev_link );
	}
	if ( $max_pages > $page ) {
		$next_page = $page + 1;
		$next_link = add_query_arg( 'page', $next_page, $base );

		$response->link_header( 'next', $next_link );
	}

	return $response;
}

Hooks

apply_filters( “rest_{$this->taxonomy}_query”, array $prepared_args, WP_REST_Request $request )

Filters get_terms() arguments when querying terms via the REST API.

Changelog

VersionDescription
6.8.0Respect default query arguments set for the taxonomy upon registration.
4.7.0Introduced.

User Contributed Notes

You must log in before being able to contribute a note or feedback.