From 88026a4f3739d1b4fb9dfc0489ad6daed980d4a3 Mon Sep 17 00:00:00 2001 From: youknowriad Date: Tue, 5 Apr 2022 09:52:02 +0000 Subject: [PATCH] Block Editor: Backport the Global Styles Variations endpoint. This include the /global-styles/themes/{theme}/variations rest endpoint into core. The endpoint will be used by the site editor to display alternative theme styles to the user. Props gziolo, oandregal. See #55505. Built from https://develop.svn.wordpress.org/trunk@53072 git-svn-id: http://core.svn.wordpress.org/trunk@52661 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-includes/class-wp-theme-json-resolver.php | 28 ++++++++ ...class-wp-rest-global-styles-controller.php | 67 +++++++++++++++++++ wp-includes/version.php | 2 +- 3 files changed, 96 insertions(+), 1 deletion(-) diff --git a/wp-includes/class-wp-theme-json-resolver.php b/wp-includes/class-wp-theme-json-resolver.php index d7828d727d..ac3d28be6c 100644 --- a/wp-includes/class-wp-theme-json-resolver.php +++ b/wp-includes/class-wp-theme-json-resolver.php @@ -449,4 +449,32 @@ class WP_Theme_JSON_Resolver { static::$i18n_schema = null; } + /** + * Returns the style variations defined by the theme. + * + * @since 6.0.0 + * + * @return array + */ + public static function get_style_variations() { + $variations = array(); + $base_directory = get_stylesheet_directory() . '/styles'; + if ( is_dir( $base_directory ) ) { + $nested_files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $base_directory ) ); + $nested_html_files = iterator_to_array( new RegexIterator( $nested_files, '/^.+\.json$/i', RecursiveRegexIterator::GET_MATCH ) ); + ksort( $nested_html_files ); + foreach ( $nested_html_files as $path => $file ) { + $decoded_file = wp_json_file_decode( $path, array( 'associative' => true ) ); + if ( is_array( $decoded_file ) ) { + $translated = static::translate( $decoded_file, wp_get_theme()->get( 'TextDomain' ) ); + $variation = ( new WP_Theme_JSON( $translated ) )->get_raw_data(); + if ( empty( $variation['title'] ) ) { + $variation['title'] = basename( $path, '.json' ); + } + $variations[] = $variation; + } + } + } + return $variations; + } } diff --git a/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php b/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php index e6771ff851..5d0c4ede2b 100644 --- a/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php +++ b/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-controller.php @@ -38,6 +38,24 @@ class WP_REST_Global_Styles_Controller extends WP_REST_Controller { * @return void */ public function register_routes() { + register_rest_route( + $this->namespace, + '/' . $this->rest_base . '/themes/(?P[\/\s%\w\.\(\)\[\]\@_\-]+)/variations', + array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_theme_items' ), + 'permission_callback' => array( $this, 'get_theme_items_permissions_check' ), + 'args' => array( + 'stylesheet' => array( + 'description' => __( 'The theme identifier' ), + 'type' => 'string', + ), + ), + ), + ) + ); + // List themes global styles. register_rest_route( $this->namespace, @@ -585,4 +603,53 @@ class WP_REST_Global_Styles_Controller extends WP_REST_Controller { return $response; } + + /** + * Checks if a given request has access to read a single theme global styles config. + * + * @since 6.0.0 + * + * @param WP_REST_Request $request Full details about the request. + * @return true|WP_Error True if the request has read access for the item, WP_Error object otherwise. + */ + public function get_theme_items_permissions_check( $request ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable + // Verify if the current user has edit_theme_options capability. + // This capability is required to edit/view/delete templates. + if ( ! current_user_can( 'edit_theme_options' ) ) { + return new WP_Error( + 'rest_cannot_manage_global_styles', + __( 'Sorry, you are not allowed to access the global styles on this site.' ), + array( + 'status' => rest_authorization_required_code(), + ) + ); + } + + return true; + } + + /** + * Returns the given theme global styles variations. + * + * @since 6.0.0 + * + * @param WP_REST_Request $request The request instance. + * + * @return WP_REST_Response|WP_Error + */ + public function get_theme_items( $request ) { + if ( wp_get_theme()->get_stylesheet() !== $request['stylesheet'] ) { + // This endpoint only supports the active theme for now. + return new WP_Error( + 'rest_theme_not_found', + __( 'Theme not found.' ), + array( 'status' => 404 ) + ); + } + + $variations = WP_Theme_JSON_Resolver::get_style_variations(); + $response = rest_ensure_response( $variations ); + + return $response; + } } diff --git a/wp-includes/version.php b/wp-includes/version.php index 62f10f4e93..668746a077 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -16,7 +16,7 @@ * * @global string $wp_version */ -$wp_version = '6.0-alpha-53071'; +$wp_version = '6.0-alpha-53072'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.