Skip to content

Commit 60370f5

Browse files
committed
A test to allow view context for global styles GET request
Preloads the global styles CPT without edit via filter Check canUser capabilities according to the capabilities set in the CPT wp_global_styles
1 parent 02950de commit 60370f5

File tree

5 files changed

+95
-46
lines changed

5 files changed

+95
-46
lines changed

lib/class-wp-rest-global-styles-controller-gutenberg.php

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -671,23 +671,8 @@ public function get_theme_item( $request ) {
671671
* @param WP_REST_Request $request Full details about the request.
672672
* @return true|WP_Error True if the request has read access for the item, WP_Error object otherwise.
673673
*/
674-
public function get_theme_items_permissions_check( $request ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
675-
676-
/*
677-
* Verify if the current user has edit_theme_options capability.
678-
* This capability is required to edit/view/delete templates.
679-
*/
680-
if ( ! current_user_can( 'edit_theme_options' ) ) {
681-
return new WP_Error(
682-
'rest_cannot_manage_global_styles',
683-
__( 'Sorry, you are not allowed to access the global styles on this site.', 'gutenberg' ),
684-
array(
685-
'status' => rest_authorization_required_code(),
686-
)
687-
);
688-
}
689-
690-
return true;
674+
public function get_theme_items_permissions_check( $request ) {
675+
return $this->get_theme_item_permissions_check( $request );
691676
}
692677

693678
/**

lib/compat/wordpress-6.6/rest-api.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,6 @@ function gutenberg_block_editor_preload_paths_6_6( $paths, $context ) {
170170
$paths[] = '/wp/v2/global-styles/themes/' . get_stylesheet();
171171
$paths[] = '/wp/v2/themes?context=edit&status=active';
172172
$paths[] = '/wp/v2/global-styles/' . WP_Theme_JSON_Resolver_Gutenberg::get_user_global_styles_post_id() . '?context=edit';
173-
$paths[] = '/wp/v2/global-styles/' . WP_Theme_JSON_Resolver_Gutenberg::get_user_global_styles_post_id();
174173
}
175174
return $paths;
176175
}

lib/compat/wordpress-6.7/rest-api.php

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,22 @@ function gutenberg_block_editor_preload_paths_6_7( $paths, $context ) {
4848
if ( false !== $reusable_blocks_key ) {
4949
unset( $paths[ $reusable_blocks_key ] );
5050
}
51-
}
5251

52+
/*
53+
* Removes the `context=edit` query parameter from the global styles preload path added in gutenberg_block_editor_preload_paths_6_6().
54+
* Uses array_filter because it may have been added again in WordPress Core 6.6 in src/wp-admin/edit-form-blocks.php
55+
* Reason: because GET requests to global styles items are accessible to roles with the `edit_posts` capability.
56+
*/
57+
$global_styles_edit_path = '/wp/v2/global-styles/' . WP_Theme_JSON_Resolver_Gutenberg::get_user_global_styles_post_id() . '?context=edit';
58+
$paths = array_filter(
59+
$paths,
60+
function ( $value ) use ( $global_styles_edit_path ) {
61+
return $value !== $global_styles_edit_path;
62+
}
63+
);
64+
65+
$paths[] = '/wp/v2/global-styles/' . WP_Theme_JSON_Resolver_Gutenberg::get_user_global_styles_post_id();
66+
}
5367
return $paths;
5468
}
5569
add_filter( 'block_editor_rest_api_preload_paths', 'gutenberg_block_editor_preload_paths_6_7', 10, 2 );
@@ -114,3 +128,24 @@ function gutenberg_override_default_rest_server() {
114128
return 'Gutenberg_REST_Server';
115129
}
116130
add_filter( 'wp_rest_server_class', 'gutenberg_override_default_rest_server', 1 );
131+
132+
133+
/**
134+
* Filters the arguments for registering a wp_global_styles post type.
135+
* Note when syncing to Core: the capabilities should be updates for `wp_global_styles` in the wp-includes/post.php.
136+
*
137+
* @since 6.7.0
138+
*
139+
* @param array $args Array of arguments for registering a post type.
140+
* See the register_post_type() function for accepted arguments.
141+
* @param string $post_type Post type key.
142+
*/
143+
function gutenberg_register_post_type_args_for_wp_global_styles( $args, $post_type ) {
144+
if ( $post_type === 'wp_global_styles' ) {
145+
$args['capabilities']['read'] = 'edit_posts';
146+
}
147+
148+
return $args;
149+
}
150+
151+
add_filter( 'register_post_type_args', 'gutenberg_register_post_type_args_for_wp_global_styles', 10, 2 );

packages/core-data/src/resolvers.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -645,7 +645,7 @@ export const __experimentalGetCurrentThemeBaseGlobalStyles =
645645
async ( { resolveSelect, dispatch } ) => {
646646
const currentTheme = await resolveSelect.getCurrentTheme();
647647
const themeGlobalStyles = await apiFetch( {
648-
path: `/wp/v2/global-styles/themes/${ currentTheme.stylesheet }`,
648+
path: `/wp/v2/global-styles/themes/${ currentTheme.stylesheet }?context=view`,
649649
} );
650650
dispatch.__experimentalReceiveThemeBaseGlobalStyles(
651651
currentTheme.stylesheet,
@@ -658,7 +658,7 @@ export const __experimentalGetCurrentThemeGlobalStylesVariations =
658658
async ( { resolveSelect, dispatch } ) => {
659659
const currentTheme = await resolveSelect.getCurrentTheme();
660660
const variations = await apiFetch( {
661-
path: `/wp/v2/global-styles/themes/${ currentTheme.stylesheet }/variations`,
661+
path: `/wp/v2/global-styles/themes/${ currentTheme.stylesheet }/variations?context=view`,
662662
} );
663663
dispatch.__experimentalReceiveThemeGlobalStyleVariations(
664664
currentTheme.stylesheet,

packages/editor/src/components/global-styles-provider/index.js

Lines changed: 55 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { useMemo, useCallback } from '@wordpress/element';
1616
* Internal dependencies
1717
*/
1818
import { unlock } from '../../lock-unlock';
19+
import { store as editorStore } from '../../store';
1920

2021
const { GlobalStylesContext, cleanEmptyObject } = unlock(
2122
blockEditorPrivateApis
@@ -46,38 +47,61 @@ export function mergeBaseAndUserConfigs( base, user ) {
4647
function useGlobalStylesUserConfig() {
4748
const { globalStylesId, isReady, settings, styles, _links } = useSelect(
4849
( select ) => {
49-
const { getEditedEntityRecord, hasFinishedResolution, canUser } =
50-
select( coreStore );
50+
const {
51+
getEntityRecord,
52+
getEditedEntityRecord,
53+
hasFinishedResolution,
54+
canUser,
55+
} = select( coreStore );
5156
const _globalStylesId =
5257
select( coreStore ).__experimentalGetCurrentGlobalStylesId();
5358

54-
const record =
55-
_globalStylesId &&
56-
canUser( 'read', {
57-
kind: 'root',
58-
name: 'globalStyles',
59-
id: _globalStylesId,
60-
} )
61-
? getEditedEntityRecord(
62-
'root',
63-
'globalStyles',
64-
_globalStylesId
65-
)
66-
: undefined;
59+
let record;
60+
const userCanEditGlobalStyles = canUser( 'edit', {
61+
kind: 'root',
62+
name: 'globalStyles',
63+
id: _globalStylesId,
64+
} );
65+
66+
if ( _globalStylesId ) {
67+
if ( userCanEditGlobalStyles ) {
68+
record = getEditedEntityRecord(
69+
'root',
70+
'globalStyles',
71+
_globalStylesId
72+
);
73+
} else {
74+
record = getEntityRecord(
75+
'root',
76+
'globalStyles',
77+
_globalStylesId,
78+
{ context: 'view' }
79+
);
80+
}
81+
}
6782

6883
let hasResolved = false;
6984
if (
7085
hasFinishedResolution(
7186
'__experimentalGetCurrentGlobalStylesId'
7287
)
7388
) {
74-
hasResolved = _globalStylesId
75-
? hasFinishedResolution( 'getEditedEntityRecord', [
76-
'root',
77-
'globalStyles',
78-
_globalStylesId,
79-
] )
80-
: true;
89+
if ( _globalStylesId ) {
90+
hasResolved = userCanEditGlobalStyles
91+
? hasFinishedResolution( 'getEditedEntityRecord', [
92+
'root',
93+
'globalStyles',
94+
_globalStylesId,
95+
] )
96+
: hasFinishedResolution( 'getEntityRecord', [
97+
'root',
98+
'globalStyles',
99+
_globalStylesId,
100+
{ context: 'view' },
101+
] );
102+
} else {
103+
hasResolved = true;
104+
}
81105
}
82106

83107
return {
@@ -146,10 +170,16 @@ function useGlobalStylesUserConfig() {
146170

147171
function useGlobalStylesBaseConfig() {
148172
const baseConfig = useSelect( ( select ) => {
149-
const { __experimentalGetCurrentThemeBaseGlobalStyles } =
173+
const { __experimentalGetCurrentThemeBaseGlobalStyles, canUser } =
150174
select( coreStore );
151-
152-
return __experimentalGetCurrentThemeBaseGlobalStyles();
175+
const currentPost = select( editorStore ).getCurrentPost();
176+
return (
177+
canUser( 'read', {
178+
kind: 'postType',
179+
name: currentPost?.type,
180+
id: currentPost?.id,
181+
} ) && __experimentalGetCurrentThemeBaseGlobalStyles()
182+
);
153183
}, [] );
154184

155185
return [ !! baseConfig, baseConfig ];

0 commit comments

Comments
 (0)