Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use entity details when calling 'canUser' selectors #63415

Merged
merged 2 commits into from
Jul 15, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion packages/block-library/src/block/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,11 @@ function ReusableBlockEdit( {
getBlockEditingMode: _getBlockEditingMode,
} = select( blockEditorStore );
const { getBlockBindingsSource } = unlock( select( blocksStore ) );
const canEdit = canUser( 'update', 'blocks', ref );
const canEdit = canUser( 'update', {
kind: 'postType',
name: 'wp_block',
id: ref,
} );

// For editing link to the site editor if the theme and user permissions support it.
return {
Expand Down
8 changes: 4 additions & 4 deletions packages/block-library/src/page-list-item/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ import {

function useFrontPageId() {
return useSelect( ( select ) => {
const canReadSettings = select( coreStore ).canUser(
'read',
'settings'
);
const canReadSettings = select( coreStore ).canUser( 'read', {
kind: 'root',
name: 'site',
} );
if ( ! canReadSettings ) {
return undefined;
}
Expand Down
5 changes: 4 additions & 1 deletion packages/block-library/src/query/edit/query-content.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,10 @@ export default function QueryContent( {
const { postsPerPage } = useSelect( ( select ) => {
const { getSettings } = select( blockEditorStore );
const { getEntityRecord, canUser } = select( coreStore );
const settingPerPage = canUser( 'read', 'settings' )
const settingPerPage = canUser( 'read', {
kind: 'root',
name: 'site',
} )
? +getEntityRecord( 'root', 'site' )?.posts_per_page
: +getSettings().postsPerPage;
return {
Expand Down
5 changes: 4 additions & 1 deletion packages/block-library/src/site-logo/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,10 @@ export default function LogoEdit( {
} = useSelect( ( select ) => {
const { canUser, getEntityRecord, getEditedEntityRecord } =
select( coreStore );
const _canUserEdit = canUser( 'update', 'settings' );
const _canUserEdit = canUser( 'update', {
kind: 'root',
name: 'site',
} );
const siteSettings = _canUserEdit
? getEditedEntityRecord( 'root', 'site' )
: undefined;
Expand Down
7 changes: 5 additions & 2 deletions packages/block-library/src/site-tagline/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,15 @@ export default function SiteTaglineEdit( {
const { canUserEdit, tagline } = useSelect( ( select ) => {
const { canUser, getEntityRecord, getEditedEntityRecord } =
select( coreStore );
const canEdit = canUser( 'update', 'settings' );
const canEdit = canUser( 'update', {
kind: 'root',
name: 'site',
} );
const settings = canEdit ? getEditedEntityRecord( 'root', 'site' ) : {};
const readOnlySettings = getEntityRecord( 'root', '__unstableBase' );

return {
canUserEdit: canUser( 'update', 'settings' ),
canUserEdit: canEdit,
tagline: canEdit
? settings?.description
: readOnlySettings?.description,
Expand Down
5 changes: 4 additions & 1 deletion packages/block-library/src/site-title/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@ export default function SiteTitleEdit( {
const { canUserEdit, title } = useSelect( ( select ) => {
const { canUser, getEntityRecord, getEditedEntityRecord } =
select( coreStore );
const canEdit = canUser( 'update', 'settings' );
const canEdit = canUser( 'update', {
kind: 'root',
name: 'site',
} );
const settings = canEdit ? getEditedEntityRecord( 'root', 'site' ) : {};
const readOnlySettings = getEntityRecord( 'root', '__unstableBase' );

Expand Down
8 changes: 5 additions & 3 deletions packages/block-library/src/template-part/edit/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,10 @@ export default function TemplatePartEdit( {
)
: false;

const _canEditTemplate =
select( coreStore ).canUser( 'create', 'templates' ) ?? false;
const _canEditTemplate = select( coreStore ).canUser( 'create', {
kind: 'postType',
name: 'wp_template_part',
} );

return {
hasInnerBlocks: getBlockCount( clientId ) > 0,
Expand All @@ -165,7 +167,7 @@ export default function TemplatePartEdit( {
onNavigateToEntityRecord:
getSettings().onNavigateToEntityRecord,
title: entityRecord?.title,
canEditTemplate: _canEditTemplate,
canEditTemplate: !! _canEditTemplate,
};
},
[ templatePartId, attributes.area, clientId ]
Expand Down
13 changes: 8 additions & 5 deletions packages/block-library/src/template-part/edit/inner-blocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,11 +127,14 @@ export default function TemplatePartInnerBlocks( {
const { canViewTemplatePart, canEditTemplatePart } = useSelect(
( select ) => {
return {
canViewTemplatePart:
select( coreStore ).canUser( 'read', 'templates' ) ?? false,
canEditTemplatePart:
select( coreStore ).canUser( 'create', 'templates' ) ??
false,
canViewTemplatePart: !! select( coreStore ).canUser( 'read', {
kind: 'postType',
name: 'wp_template',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to what @ellatrix suggested about the template part post type, we could use TEMPLATE_POST_TYPE for these.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've updated the part when these constants were available. They're package-specific. Most entity-related blocks hardcode their entity names.

Are we worried that these names might change?

Also, I don't mind defining a couple of constants at the file level, but for the initial run, I tried to change only the selector syntax and leave the rest of the code alone.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Definitely not a blocker for the PR 👍

} ),
canEditTemplatePart: !! select( coreStore ).canUser( 'create', {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not from this PR, but it felt odd that we call this "can edit" but check for whether they can create (POST) and not update (PUT). Haven't checked if that makes more sense in the context it's used.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think introducing the pattern might have been my fault. The WP maps all template CRUD permissions to the same capability, so I reused already existing call for edit capability check to avoid making extra OPTIONS request to the server.

The duplicate requests issue was fixed (#43480). I forgot to update my old code, and the pattern spread into new places.

I will follow up on this in a separate PR.

kind: 'postType',
name: 'wp_template',
} ),
};
},
[]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,10 @@ function useSiteEditorBasicNavigationCommands() {
'site-editor.php'
);
const canCreateTemplate = useSelect( ( select ) => {
return select( coreStore ).canUser( 'create', 'templates' );
return select( coreStore ).canUser( 'create', {
kind: 'postType',
name: 'wp_template',
} );
}, [] );
const isBlockBasedTheme = useIsBlockBasedTheme();
const commands = useMemo( () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,10 @@ export default function SidebarBlockEditor( {
const { get } = select( preferencesStore );
return {
hasUploadPermissions:
select( coreStore ).canUser( 'create', 'media' ) ?? true,
select( coreStore ).canUser( 'create', {
kind: 'root',
name: 'media',
} ) ?? true,
isFixedToolbarActive: !! get(
'core/customize-widgets',
'fixedToolbar'
Expand Down
5 changes: 4 additions & 1 deletion packages/edit-post/src/components/layout/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,10 @@ function Layout( {
const supportsTemplateMode = settings.supportsTemplateMode;
const isViewable =
getPostType( currentPost.postType )?.viewable ?? false;
const canViewTemplate = canUser( 'read', 'templates' );
const canViewTemplate = canUser( 'read', {
kind: 'postType',
name: 'wp_template',
} );

return {
mode: select( editorStore ).getEditorMode(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,12 @@ function ManagePatternsMenuItem() {
// The site editor and templates both check whether the user has
// edit_theme_options capabilities. We can leverage that here and not
// display the manage patterns link if the user can't access it.
return canUser( 'create', 'templates' ) ? patternsUrl : defaultUrl;
return canUser( 'create', {
kind: 'postType',
name: 'wp_template',
} )
? patternsUrl
: defaultUrl;
}, [] );

return (
Expand Down
10 changes: 8 additions & 2 deletions packages/edit-site/src/components/add-new-pattern/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,14 @@ export default function AddNewPattern() {
addNewTemplatePartLabel: getPostType( TEMPLATE_PART_POST_TYPE )
?.labels?.add_new_item,
// Blocks refers to the wp_block post type, this checks the ability to create a post of that type.
canCreatePattern: canUser( 'create', 'blocks' ),
canCreateTemplatePart: canUser( 'create', 'template-parts' ),
canCreatePattern: canUser( 'create', {
kind: 'postType',
name: PATTERN_TYPES.user,
} ),
canCreateTemplatePart: canUser( 'create', {
kind: 'postType',
name: TEMPLATE_PART_POST_TYPE,
} ),
};
}, [] );

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,10 @@ function FontLibraryModal( {
} ) {
const { collections, setNotice } = useContext( FontLibraryContext );
const canUserCreate = useSelect( ( select ) => {
const { canUser } = select( coreStore );
return canUser( 'create', 'font-families' );
return select( coreStore ).canUser( 'create', {
kind: 'postType',
name: 'wp_font_family',
} );
}, [] );

const tabs = [ DEFAULT_TAB ];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,11 @@ function InstalledFonts() {
const { canUser } = select( coreStore );
return (
customFontFamilyId &&
canUser( 'delete', 'font-families', customFontFamilyId )
canUser( 'delete', {
kind: 'postType',
name: 'wp_font_family',
id: customFontFamilyId,
Comment on lines +97 to +99
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I appreciate the explicit syntax, it makes it clearer as to what we're doing. Previously, one had to search what font-families is - is it a taxonomy, is it a post type?

} )
);
},
[ customFontFamilyId ]
Expand Down
9 changes: 4 additions & 5 deletions packages/edit-site/src/components/post-list/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -372,15 +372,14 @@ export default function PostList( { postType } ) {
const { getEntityRecord, getPostType, canUser } =
select( coreStore );
const siteSettings = getEntityRecord( 'root', 'site' );
const postTypeObject = getPostType( postType );
return {
frontPageId: siteSettings?.page_on_front,
postsPageId: siteSettings?.page_for_posts,
labels: getPostType( postType )?.labels,
canCreateRecord: canUser(
'create',
postTypeObject?.rest_base || 'posts'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice simplification 👍

I wonder why the pre-existing indirection and the default `'posts`` was necessary 🤔

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm guessing to avoid passing undefined when postTypeObject hasn't been resolved yet, which would result in sending a request to the general namespace. However, I'm unsure why the posts fallback was selected.

I fixed a similar issue in #63423 (comment).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Back in the day, when we were writing up custom admin menus, for example, and we were displaying labels for custom post types, we were falling back to the default labels for post types - because when registering a custom post type, not all labels are guaranteed to be declared. Maybe this assumed that the rest_base could not be declared, too.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The rest_base should default to the post type slug.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True. But then it can be overridden 🤷‍♂️

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can do almost everything in WP 😅

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup. I'm just trying to understand why this was here. Maybe it was a temporary thing as we were working to make the posts list more flexible in the future? It's a recent addition (#62705), perhaps @ntsekouras could remember.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, the default was to avoid the undefined value. Regarding why we need the resource, it's because we are using the same component for posts and pages and will probably be the base component of other post types too. Finally regarding the default:posts, didn't think it mattered much :).

Aside this, I'm catching up with @Mamaduka's work on these parts and is great! Thank you!

),
canCreateRecord: canUser( 'create', {
kind: 'postType',
name: postType,
} ),
};
},
[ postType ]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,10 @@ export default function WidgetAreasBlockEditorProvider( {
} = useSelect( ( select ) => {
const { canUser, getEntityRecord, getEntityRecords } =
select( coreStore );
const siteSettings = canUser( 'read', 'settings' )
const siteSettings = canUser( 'read', {
kind: 'root',
name: 'site',
} )
? getEntityRecord( 'root', 'site' )
: undefined;
return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,10 @@ function ContentOnlySettingsMenuItems( { clientId, onClose } ) {
);
}
}
const _canEditTemplates = select( coreStore ).canUser(
'create',
'templates'
);
const _canEditTemplates = select( coreStore ).canUser( 'create', {
kind: 'postType',
name: 'wp_template',
} );
return {
canEditTemplates: _canEditTemplates,
entity: record,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ function MaybeCategoryPanel() {
const postType = select( editorStore ).getCurrentPostType();
const { canUser, getEntityRecord, getTaxonomy } = select( coreStore );
const categoriesTaxonomy = getTaxonomy( 'category' );
const defaultCategoryId = canUser( 'read', 'settings' )
const defaultCategoryId = canUser( 'read', {
kind: 'root',
name: 'site',
} )
? getEntityRecord( 'root', 'site' )?.default_category
: undefined;
const defaultCategory = defaultCategoryId
Expand Down
6 changes: 5 additions & 1 deletion packages/editor/src/components/post-template/block-theme.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,11 @@ export default function BlockThemeControl( { id } ) {

const canCreateTemplate = useSelect(
( select ) =>
select( coreStore ).canUser( 'create', 'templates' ) ?? false
select( coreStore ).canUser( 'create', {
kind: 'postType',
name: 'wp_template',
} ),
Mamaduka marked this conversation as resolved.
Show resolved Hide resolved
[]
);

if ( ! hasResolved ) {
Expand Down
11 changes: 8 additions & 3 deletions packages/editor/src/components/post-template/classic-theme.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,10 @@ function PostTemplateToggle( { isOpen, onClick } ) {
return availableTemplates[ templateSlug ];
}
const template =
select( coreStore ).canUser( 'create', 'templates' ) &&
select( editorStore ).getCurrentTemplateId();
select( coreStore ).canUser( 'create', {
kind: 'postType',
name: 'wp_template',
} ) && select( editorStore ).getCurrentTemplateId();
return (
template?.title ||
template?.slug ||
Expand Down Expand Up @@ -78,7 +80,10 @@ function PostTemplateDropdownContent( { onClose } ) {
( select ) => {
const { canUser, getEntityRecords } = select( coreStore );
const editorSettings = select( editorStore ).getEditorSettings();
const canCreateTemplates = canUser( 'create', 'templates' );
const canCreateTemplates = canUser( 'create', {
kind: 'postType',
name: 'wp_template',
} );
const _currentTemplateId =
select( editorStore ).getCurrentTemplateId();
return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ export default function CreateNewTemplate( { onClick } ) {
const { canCreateTemplates } = useSelect( ( select ) => {
const { canUser } = select( coreStore );
return {
canCreateTemplates: canUser( 'create', 'templates' ),
canCreateTemplates: canUser( 'create', {
kind: 'postType',
name: 'wp_template',
} ),
};
}, [] );
const [ isCreateModalOpen, setIsCreateModalOpen ] = useState( false );
Expand Down
12 changes: 10 additions & 2 deletions packages/editor/src/components/post-template/panel.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,20 @@ export default function PostTemplatePanel() {
}

const canCreateTemplates =
select( coreStore ).canUser( 'create', 'templates' ) ?? false;
select( coreStore ).canUser( 'create', {
kind: 'postType',
name: 'wp_template',
} ) ?? false;
return canCreateTemplates;
}, [] );

const canViewTemplates = useSelect( ( select ) => {
return select( coreStore ).canUser( 'read', 'templates' ) ?? false;
return (
select( coreStore ).canUser( 'read', {
kind: 'postType',
name: 'wp_template',
} ) ?? false
);
}, [] );

if ( ( ! isBlockTheme || ! canViewTemplates ) && isVisible ) {
Expand Down
14 changes: 9 additions & 5 deletions packages/editor/src/components/post-trash/check.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,17 @@ export default function PostTrashCheck( { children } ) {
const { canTrashPost } = useSelect( ( select ) => {
const { isEditedPostNew, getCurrentPostId, getCurrentPostType } =
select( editorStore );
const { getPostType, canUser } = select( coreStore );
const postType = getPostType( getCurrentPostType() );
const { canUser } = select( coreStore );
const postType = getCurrentPostType();
const postId = getCurrentPostId();
const isNew = isEditedPostNew();
const resource = postType?.rest_base || ''; // eslint-disable-line camelcase
const canUserDelete =
postId && resource ? canUser( 'delete', resource, postId ) : false;
const canUserDelete = !! postId
? canUser( 'delete', {
kind: 'postType',
name: postType,
id: postId,
} )
: false;

return {
canTrashPost: ( ! isNew || postId ) && canUserDelete,
Expand Down
Loading
Loading