--- a/wp/wp-includes/rest-api/endpoints/class-wp-rest-themes-controller.php Wed Sep 21 18:19:35 2022 +0200
+++ b/wp/wp-includes/rest-api/endpoints/class-wp-rest-themes-controller.php Tue Sep 27 16:37:53 2022 +0200
@@ -17,6 +17,12 @@
class WP_REST_Themes_Controller extends WP_REST_Controller {
/**
+ * Matches theme's directory: `/themes/<subdirectory>/<theme>/` or `/themes/<theme>/`.
+ * Excludes invalid directory name characters: `/:<>*?"|`.
+ */
+ const PATTERN = '[^\/:<>\*\?"\|]+(?:\/[^\/:<>\*\?"\|]+)?';
+
+ /**
* Constructor.
*
* @since 5.0.0
@@ -50,12 +56,13 @@
register_rest_route(
$this->namespace,
- '/' . $this->rest_base . '/(?P<stylesheet>[\w-]+)',
+ sprintf( '/%s/(?P<stylesheet>%s)', $this->rest_base, self::PATTERN ),
array(
'args' => array(
'stylesheet' => array(
- 'description' => __( "The theme's stylesheet. This uniquely identifies the theme." ),
- 'type' => 'string',
+ 'description' => __( "The theme's stylesheet. This uniquely identifies the theme." ),
+ 'type' => 'string',
+ 'sanitize_callback' => array( $this, '_sanitize_stylesheet_callback' ),
),
),
array(
@@ -69,6 +76,18 @@
}
/**
+ * Sanitize the stylesheet to decode endpoint.
+ *
+ * @since 5.9.0
+ *
+ * @param string $stylesheet The stylesheet name.
+ * @return string Sanitized stylesheet.
+ */
+ public function _sanitize_stylesheet_callback( $stylesheet ) {
+ return urldecode( $stylesheet );
+ }
+
+ /**
* Checks if a given request has access to read the theme.
*
* @since 5.0.0
@@ -204,12 +223,15 @@
* Prepares a single theme output for response.
*
* @since 5.0.0
+ * @since 5.9.0 Renamed `$theme` to `$item` to match parent class for PHP 8 named parameter support.
*
- * @param WP_Theme $theme Theme object.
+ * @param WP_Theme $item Theme object.
* @param WP_REST_Request $request Request object.
* @return WP_REST_Response Response object.
*/
- public function prepare_item_for_response( $theme, $request ) {
+ public function prepare_item_for_response( $item, $request ) {
+ // Restores the more descriptive, specific name for use within this method.
+ $theme = $item;
$data = array();
$fields = $this->get_fields_for_response( $request );
@@ -311,6 +333,21 @@
$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 )
+ );
+ }
+
/**
* Filters theme data returned from the REST API.
*