-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
Core Data: Support entities in the 'canUser' selector #63322
Changes from all commits
4ea1c4f
2cf879f
2230256
b99da12
b6aeb12
4e185e1
92b2859
c637582
5ff9407
df1dbd2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -120,6 +120,8 @@ type EntityRecordArgs = | |
| [ string, string, EntityRecordKey ] | ||
| [ string, string, EntityRecordKey, GetRecordsHttpQuery ]; | ||
|
||
type EntityResource = { kind: string; name: string; id?: EntityRecordKey }; | ||
|
||
/** | ||
* Shared reference to an empty object for cases where it is important to avoid | ||
* returning a new object reference on every invocation, as in a connected or | ||
|
@@ -1136,7 +1138,8 @@ export function isPreviewEmbedFallback( state: State, url: string ): boolean { | |
* | ||
* @param state Data state. | ||
* @param action Action to check. One of: 'create', 'read', 'update', 'delete'. | ||
* @param resource REST resource to check, e.g. 'media' or 'posts'. | ||
* @param resource Entity resource to check. Accepts entity object `{ kind: 'root', name: 'media', id: 1 }` | ||
* or REST base as a string - `media`. | ||
* @param id Optional ID of the rest resource to check. | ||
* | ||
* @return Whether or not the user can perform the action, | ||
|
@@ -1145,10 +1148,22 @@ export function isPreviewEmbedFallback( state: State, url: string ): boolean { | |
export function canUser( | ||
state: State, | ||
action: string, | ||
resource: string, | ||
resource: string | EntityResource, | ||
id?: EntityRecordKey | ||
): boolean | undefined { | ||
const key = [ action, resource, id ].filter( Boolean ).join( '/' ); | ||
const isEntity = typeof resource === 'object'; | ||
if ( isEntity && ( ! resource.kind || ! resource.name ) ) { | ||
return false; | ||
} | ||
|
||
const key = ( | ||
isEntity | ||
? [ action, resource.kind, resource.name, resource.id ] | ||
: [ action, resource, id ] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's do some consistency checks on the canUser( 'update', 'posts' );
canUser( 'update', { id: 'posts' } );
canUser( 'update', { name: 'posts' } ); The key should have some prefix ( There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Where is there a benefit for strings? It doesn't look like it's needed for memoization? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm talking about the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess we can return I can add a warning or error, but these are rare in WP stores. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, that's what I meant by "failure", simply returning There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It could also be useful to log an error so the developer knows about unexpected usage. @Mamaduka I see you mentioned those are rare in stores, but at the same time, when debugging store errors one often has to go deep, exactly because errors will often be silent or swallowed. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could throw an error when the resource object is malformed, and the error will be accessible via I don't know the historical reason why resolvers/selectors don't log errors; my best guess is that people often report them as bugs. So basically, support overhead. cc @youknowriad There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not very happy about throwing an error from the selector. It's not forward compatible. It's likely that we will add a new resource type in the future (e.g., for checking capabilities on the site) and then the new code will be failing on an older WordPress. It's better to return There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The error is thrown from resolver b1e5dfc. I think returning Fun fact: Calling There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Oh, I missed that, in resolver it's fine.
It was added in 2010 here: https://core.trac.wordpress.org/ticket/14696#comment:5
|
||
) | ||
.filter( Boolean ) | ||
.join( '/' ); | ||
|
||
return state.userPermissions[ key ]; | ||
} | ||
|
||
|
@@ -1173,13 +1188,12 @@ export function canUserEditEntityRecord( | |
name: string, | ||
recordId: EntityRecordKey | ||
): boolean | undefined { | ||
const entityConfig = getEntityConfig( state, kind, name ); | ||
if ( ! entityConfig ) { | ||
return false; | ||
} | ||
const resource = entityConfig.__unstable_rest_base; | ||
deprecated( `wp.data.select( 'core' ).canUserEditEntityRecord()`, { | ||
since: '6.7', | ||
alternative: `wp.data.select( 'core' ).canUser( 'update', { kind, name, id } )`, | ||
} ); | ||
|
||
return canUser( state, 'update', resource, recordId ); | ||
return canUser( state, 'update', { kind, name, id: recordId } ); | ||
} | ||
|
||
/** | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we log an error in case
kind
orname
don't correspond to an entity type?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No other entity resolver does this; maybe we should re-evaluate missing config cases together?