Skip to content

Commit

Permalink
Backport the global styles variations changes from Gutenberg
Browse files Browse the repository at this point in the history
  • Loading branch information
youknowriad committed Apr 4, 2022
1 parent 3cd1a74 commit 7eaf5ac
Show file tree
Hide file tree
Showing 4 changed files with 160 additions and 0 deletions.
28 changes: 28 additions & 0 deletions src/wp-includes/class-wp-theme-json-resolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -449,4 +449,32 @@ public static function clean_cached_data() {
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_Gutenberg( $translated ) )->get_raw_data();
if ( empty( $variation['title'] ) ) {
$variation['title'] = basename( $path, '.json' );
}
$variations[] = $variation;
}
}
}
return $variations;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,24 @@ public function register_routes() {
)
);

register_rest_route(
$this->namespace,
'/' . $this->rest_base . '/themes/(?P<stylesheet>[\/\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', 'gutenberg' ),
'type' => 'string',
),
),
),
)
);

// Lists/updates a single global style variation based on the given id.
register_rest_route(
$this->namespace,
Expand Down Expand Up @@ -585,4 +603,53 @@ public function get_theme_item( $request ) {

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;
}
}
23 changes: 23 additions & 0 deletions tests/phpunit/data/themedir1/theme1/styles/variation.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"version": 2,
"settings": {
"color": {
"palette": [
{
"slug": "foreground",
"color": "#3F67C6",
"name": "Foreground"
}
]
}
},
"styles": {
"blocks": {
"core/post-title": {
"typography": {
"fontWeight": "700"
}
}
}
}
}
42 changes: 42 additions & 0 deletions tests/phpunit/tests/rest-api/rest-global-styles-controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,11 @@ public function test_register_routes() {
$routes['/wp/v2/global-styles/themes/(?P<stylesheet>[^\/:<>\*\?"\|]+(?:\/[^\/:<>\*\?"\|]+)?)'],
'Theme global styles route does not have exactly one element'
);
$this->assertArrayHasKey(
'/wp/v2/global-styles/themes/(?P<stylesheet>[\/\s%\w\.\(\)\[\]\@_\-]+)/variations',
$routes,
'Theme global styles variations route does not exist'
);
}

public function test_context_param() {
Expand Down Expand Up @@ -455,4 +460,41 @@ public function test_get_item_schema() {
$this->assertArrayHasKey( 'settings', $properties, 'Schema properties array does not have "settings" key' );
$this->assertArrayHasKey( 'title', $properties, 'Schema properties array does not have "title" key' );
}


public function test_get_theme_items() {
wp_set_current_user( self::$admin_id );
switch_theme( 'theme1' );
$request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/themes/theme1/variations' );
$response = rest_get_server()->dispatch( $request );
$data = $response->get_data();
$expected = array(
array(
'version' => 2,
'settings' => array(
'color' => array(
'palette' => array(
'theme' => array(
array(
'slug' => 'foreground',
'color' => '#3F67C6',
'name' => 'Foreground',
),
),
),
),
),
'styles' => array(
'blocks' => array(
'core/post-title' => array(
'typography' => array(
'fontWeight' => '700',
),
),
),
),
),
);
$this->assertSameSetsWithIndex( $data, $expected );
}
}

0 comments on commit 7eaf5ac

Please sign in to comment.