wp/wp-includes/rest-api/endpoints/class-wp-rest-terms-controller.php
changeset 22 8c2e4d02f4ef
parent 21 48c4eec2b7e6
--- a/wp/wp-includes/rest-api/endpoints/class-wp-rest-terms-controller.php	Fri Sep 05 18:40:08 2025 +0200
+++ b/wp/wp-includes/rest-api/endpoints/class-wp-rest-terms-controller.php	Fri Sep 05 18:52:52 2025 +0200
@@ -164,7 +164,7 @@
 			return true;
 		}
 
-		// Otherwise grant access if the post is readable by the logged in user.
+		// Otherwise grant access if the post is readable by the logged-in user.
 		if ( current_user_can( 'read_post', $post->ID ) ) {
 			return true;
 		}
@@ -227,6 +227,7 @@
 	 * Retrieves terms associated with a taxonomy.
 	 *
 	 * @since 4.7.0
+	 * @since 6.8.0 Respect default query arguments set for the taxonomy upon registration.
 	 *
 	 * @param WP_REST_Request $request Full details about the request.
 	 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
@@ -295,6 +296,30 @@
 			}
 		}
 
+		/*
+		 * 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.
 		 *
@@ -337,14 +362,15 @@
 			$total_terms = 0;
 		}
 
-		$response = array();
-
-		foreach ( $query_result as $term ) {
-			$data       = $this->prepare_item_for_response( $term, $request );
-			$response[] = $this->prepare_response_for_collection( $data );
+		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 = rest_ensure_response( $response );
+		$response = $is_head_request ? new WP_REST_Response( array() ) : rest_ensure_response( $response );
 
 		// Store pagination values for headers.
 		$per_page = (int) $prepared_args['number'];
@@ -462,7 +488,7 @@
 	 * @since 4.7.0
 	 *
 	 * @param WP_REST_Request $request Full details about the request.
-	 * @return true|WP_Error True if the request has access to create items, false or WP_Error object otherwise.
+	 * @return bool|WP_Error True if the request has access to create items, otherwise false or WP_Error object.
 	 */
 	public function create_item_permissions_check( $request ) {
 
@@ -870,6 +896,12 @@
 	 */
 	public function prepare_item_for_response( $item, $request ) {
 
+		// Don't prepare the response body for HEAD requests.
+		if ( $request->is_method( 'HEAD' ) ) {
+			/** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-terms-controller.php */
+			return apply_filters( "rest_prepare_{$this->taxonomy}", new WP_REST_Response( array() ), $item, $request );
+		}
+
 		$fields = $this->get_fields_for_response( $request );
 		$data   = array();