wp/wp-includes/rest-api/class-wp-rest-server.php
changeset 22 8c2e4d02f4ef
parent 21 48c4eec2b7e6
--- a/wp/wp-includes/rest-api/class-wp-rest-server.php	Fri Sep 05 18:40:08 2025 +0200
+++ b/wp/wp-includes/rest-api/class-wp-rest-server.php	Fri Sep 05 18:52:52 2025 +0200
@@ -636,7 +636,18 @@
 			foreach ( $items as $item ) {
 				$attributes         = $item['attributes'];
 				$attributes['href'] = $item['href'];
-				$data[ $rel ][]     = $attributes;
+
+				if ( 'self' !== $rel ) {
+					$data[ $rel ][] = $attributes;
+					continue;
+				}
+
+				$target_hints = self::get_target_hints_for_link( $attributes );
+				if ( $target_hints ) {
+					$attributes['targetHints'] = $target_hints;
+				}
+
+				$data[ $rel ][] = $attributes;
 			}
 		}
 
@@ -644,6 +655,57 @@
 	}
 
 	/**
+	 * Gets the target links for a REST API Link.
+	 *
+	 * @since 6.7.0
+	 *
+	 * @param array $link
+	 *
+	 * @return array|null
+	 */
+	protected static function get_target_hints_for_link( $link ) {
+		// Prefer targetHints that were specifically designated by the developer.
+		if ( isset( $link['targetHints']['allow'] ) ) {
+			return null;
+		}
+
+		$request = WP_REST_Request::from_url( $link['href'] );
+		if ( ! $request ) {
+			return null;
+		}
+
+		$server = rest_get_server();
+		$match  = $server->match_request_to_handler( $request );
+
+		if ( is_wp_error( $match ) ) {
+			return null;
+		}
+
+		if ( is_wp_error( $request->has_valid_params() ) ) {
+			return null;
+		}
+
+		if ( is_wp_error( $request->sanitize_params() ) ) {
+			return null;
+		}
+
+		$target_hints = array();
+
+		$response = new WP_REST_Response();
+		$response->set_matched_route( $match[0] );
+		$response->set_matched_handler( $match[1] );
+		$headers = rest_send_allow_header( $response, $server, $request )->get_headers();
+
+		foreach ( $headers as $name => $value ) {
+			$name = WP_REST_Request::canonicalize_header_name( $name );
+
+			$target_hints[ $name ] = array_map( 'trim', explode( ',', $value ) );
+		}
+
+		return $target_hints;
+	}
+
+	/**
 	 * Retrieves the CURIEs (compact URIs) used for relations.
 	 *
 	 * Extracts the links from a response into a structured hash, suitable for
@@ -1309,6 +1371,9 @@
 			'home'            => home_url(),
 			'gmt_offset'      => get_option( 'gmt_offset' ),
 			'timezone_string' => get_option( 'timezone_string' ),
+			'page_for_posts'  => (int) get_option( 'page_for_posts' ),
+			'page_on_front'   => (int) get_option( 'page_on_front' ),
+			'show_on_front'   => get_option( 'show_on_front' ),
 			'namespaces'      => array_keys( $this->namespaces ),
 			'authentication'  => array(),
 			'routes'          => $this->get_data_for_routes( $this->get_routes(), $request['context'] ),
@@ -1667,7 +1732,7 @@
 			$single_request = new WP_REST_Request( isset( $args['method'] ) ? $args['method'] : 'POST', $parsed_url['path'] );
 
 			if ( ! empty( $parsed_url['query'] ) ) {
-				$query_args = null; // Satisfy linter.
+				$query_args = array();
 				wp_parse_str( $parsed_url['query'], $query_args );
 				$single_request->set_query_params( $query_args );
 			}