wp/wp-includes/rest-api/endpoints/class-wp-rest-themes-controller.php
changeset 21 48c4eec2b7e6
parent 19 3d72ae0968f4
child 22 8c2e4d02f4ef
--- a/wp/wp-includes/rest-api/endpoints/class-wp-rest-themes-controller.php	Thu Sep 29 08:06:27 2022 +0200
+++ b/wp/wp-includes/rest-api/endpoints/class-wp-rest-themes-controller.php	Fri Sep 05 18:40:08 2025 +0200
@@ -118,7 +118,7 @@
 	 * @since 5.7.0
 	 *
 	 * @param WP_REST_Request $request Full details about the request.
-	 * @return bool|WP_Error True if the request has read access for the item, otherwise WP_Error object.
+	 * @return true|WP_Error True if the request has read access for the item, otherwise WP_Error object.
 	 */
 	public function get_item_permissions_check( $request ) {
 		if ( current_user_can( 'switch_themes' ) || current_user_can( 'manage_network_themes' ) ) {
@@ -144,7 +144,7 @@
 	 *
 	 * @since 5.7.0
 	 *
-	 * @return bool|WP_Error Whether the theme can be read.
+	 * @return true|WP_Error True if the theme can be read, WP_Error object otherwise.
 	 */
 	protected function check_read_active_theme_permission() {
 		if ( current_user_can( 'edit_posts' ) ) {
@@ -224,6 +224,7 @@
 	 *
 	 * @since 5.0.0
 	 * @since 5.9.0 Renamed `$theme` to `$item` to match parent class for PHP 8 named parameter support.
+	 * @since 6.6.0 Added `stylesheet_uri` and `template_uri` fields.
 	 *
 	 * @param WP_Theme        $item    Theme object.
 	 * @param WP_REST_Request $request Request object.
@@ -231,9 +232,10 @@
 	 */
 	public function prepare_item_for_response( $item, $request ) {
 		// Restores the more descriptive, specific name for use within this method.
-		$theme  = $item;
+		$theme = $item;
+
+		$fields = $this->get_fields_for_response( $request );
 		$data   = array();
-		$fields = $this->get_fields_for_response( $request );
 
 		if ( rest_is_field_included( 'stylesheet', $fields ) ) {
 			$data['stylesheet'] = $theme->get_stylesheet();
@@ -326,26 +328,33 @@
 			}
 		}
 
+		if ( rest_is_field_included( 'is_block_theme', $fields ) ) {
+			$data['is_block_theme'] = $theme->is_block_theme();
+		}
+
+		if ( rest_is_field_included( 'stylesheet_uri', $fields ) ) {
+			if ( $this->is_same_theme( $theme, $current_theme ) ) {
+				$data['stylesheet_uri'] = get_stylesheet_directory_uri();
+			} else {
+				$data['stylesheet_uri'] = $theme->get_stylesheet_directory_uri();
+			}
+		}
+
+		if ( rest_is_field_included( 'template_uri', $fields ) ) {
+			if ( $this->is_same_theme( $theme, $current_theme ) ) {
+				$data['template_uri'] = get_template_directory_uri();
+			} else {
+				$data['template_uri'] = $theme->get_template_directory_uri();
+			}
+		}
+
 		$data = $this->add_additional_fields_to_object( $data, $request );
 
 		// Wrap the data in a response object.
 		$response = rest_ensure_response( $data );
 
-		$response->add_links( $this->prepare_links( $theme ) );
-
-		if ( $theme->get_stylesheet() === wp_get_theme()->get_stylesheet() ) {
-			// This creates a record for the active theme if not existent.
-			$id = WP_Theme_JSON_Resolver::get_user_global_styles_post_id();
-		} else {
-			$user_cpt = WP_Theme_JSON_Resolver::get_user_data_from_wp_global_styles( $theme );
-			$id       = isset( $user_cpt['ID'] ) ? $user_cpt['ID'] : null;
-		}
-
-		if ( $id ) {
-			$response->add_link(
-				'https://api.w.org/user-global-styles',
-				rest_url( 'wp/v2/global-styles/' . $id )
-			);
+		if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
+			$response->add_links( $this->prepare_links( $theme ) );
 		}
 
 		/**
@@ -369,7 +378,7 @@
 	 * @return array Links for the given block type.
 	 */
 	protected function prepare_links( $theme ) {
-		return array(
+		$links = array(
 			'self'       => array(
 				'href' => rest_url( sprintf( '%s/%s/%s', $this->namespace, $this->rest_base, $theme->get_stylesheet() ) ),
 			),
@@ -377,6 +386,22 @@
 				'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ),
 			),
 		);
+
+		if ( $this->is_same_theme( $theme, wp_get_theme() ) ) {
+			// This creates a record for the active theme if not existent.
+			$id = WP_Theme_JSON_Resolver::get_user_global_styles_post_id();
+		} else {
+			$user_cpt = WP_Theme_JSON_Resolver::get_user_data_from_wp_global_styles( $theme );
+			$id       = isset( $user_cpt['ID'] ) ? $user_cpt['ID'] : null;
+		}
+
+		if ( $id ) {
+			$links['https://api.w.org/user-global-styles'] = array(
+				'href' => rest_url( 'wp/v2/global-styles/' . $id ),
+			);
+		}
+
+		return $links;
 	}
 
 	/**
@@ -439,11 +464,23 @@
 					'type'        => 'string',
 					'readonly'    => true,
 				),
+				'stylesheet_uri' => array(
+					'description' => __( 'The uri for the theme\'s stylesheet directory.' ),
+					'type'        => 'string',
+					'format'      => 'uri',
+					'readonly'    => true,
+				),
 				'template'       => array(
 					'description' => __( 'The theme\'s template. If this is a child theme, this refers to the parent theme, otherwise this is the same as the theme\'s stylesheet.' ),
 					'type'        => 'string',
 					'readonly'    => true,
 				),
+				'template_uri'   => array(
+					'description' => __( 'The uri for the theme\'s template directory. If this is a child theme, this refers to the parent theme, otherwise this is the same as the theme\'s stylesheet directory.' ),
+					'type'        => 'string',
+					'format'      => 'uri',
+					'readonly'    => true,
+				),
 				'author'         => array(
 					'description' => __( 'The theme author.' ),
 					'type'        => 'object',
@@ -491,6 +528,11 @@
 						),
 					),
 				),
+				'is_block_theme' => array(
+					'description' => __( 'Whether the theme is a block-based theme.' ),
+					'type'        => 'boolean',
+					'readonly'    => true,
+				),
 				'name'           => array(
 					'description' => __( 'The name of the theme.' ),
 					'type'        => 'object',