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

Add allowed methods to post items #63200

Draft
wants to merge 1 commit into
base: trunk
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
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
49 changes: 49 additions & 0 deletions lib/compat/wordpress-6.6/rest-api.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,55 @@
}
add_action( 'rest_api_init', 'gutenberg_add_class_list_to_public_post_types' );

/**
* Adds the allow methods to the REST API response.
*
* @param array $post The response object data.
*
* @return string
*/
function gutenberg_add_allow_to_api_response( $post ) {
$request = new WP_REST_Request( 'OPTIONS', rest_get_route_for_post( $post['id'] ) );

Check warning on line 88 in lib/compat/wordpress-6.6/rest-api.php

View workflow job for this annotation

GitHub Actions / PHP coding standards

Equals sign not aligned with surrounding assignments; expected 2 spaces but found 1 space
$response = rest_do_request( $request );
$server = rest_get_server();

Check warning on line 90 in lib/compat/wordpress-6.6/rest-api.php

View workflow job for this annotation

GitHub Actions / PHP coding standards

Equals sign not aligned with surrounding assignments; expected 3 spaces but found 1 space
$response = apply_filters( 'rest_post_dispatch', rest_ensure_response( $response ), $server, $request );

if ( is_wp_error( $response ) ) {
return array();
}

return $response->get_headers()["Allow"];

Check failure on line 97 in lib/compat/wordpress-6.6/rest-api.php

View workflow job for this annotation

GitHub Actions / PHP coding standards

String "Allow" does not require double quotes; use single quotes instead
}

/**
* Adds the allow methods to public post types in the REST API.
*/
function gutenberg_add_allow_to_public_post_types() {
$post_types = get_post_types(
array(
'public' => true,
'show_in_rest' => true,
),
'names'
);

if ( ! empty( $post_types ) ) {
register_rest_field(
$post_types,
'allow',
array(
'get_callback' => 'gutenberg_add_allow_to_api_response',
'schema' => array(
'description' => __( 'Allowed methods for the post.', 'gutenberg' ),
'type' => 'string',
),
'context' => array( 'edit' ),
)
);
}
}
add_action( 'rest_api_init', 'gutenberg_add_allow_to_public_post_types' );


/**
* Registers the Global Styles Revisions REST API routes.
Expand Down
93 changes: 62 additions & 31 deletions packages/core-data/src/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,39 +83,70 @@ export function addEntities( entities ) {
* @param {?Object} meta Meta information about pagination.
* @return {Object} Action object.
*/
export function receiveEntityRecords(
kind,
name,
records,
query,
invalidateCache = false,
edits,
meta
) {
// Auto drafts should not have titles, but some plugins rely on them so we can't filter this
// on the server.
if ( kind === 'postType' ) {
records = ( Array.isArray( records ) ? records : [ records ] ).map(
( record ) =>
record.status === 'auto-draft'
? { ...record, title: '' }
: record
);
}
let action;
if ( query ) {
action = receiveQueriedItems( records, query, edits, meta );
} else {
action = receiveItems( records, edits, meta );
}
export const receiveEntityRecords =
( kind, name, records, query, invalidateCache = false, edits, meta ) =>
( { dispatch, select } ) => {
// Auto drafts should not have titles, but some plugins rely on them so we can't filter this
// on the server.
if ( kind === 'postType' ) {
records = ( Array.isArray( records ) ? records : [ records ] ).map(
( record ) =>
record.status === 'auto-draft'
? { ...record, title: '' }
: record
);

return {
...action,
kind,
name,
invalidateCache,
const postTypeObject = select.getPostType( name );
const resource = postTypeObject?.rest_base || '';

for ( const record of records ) {
const allowedMethods = record.allow;

if ( allowedMethods && resource ) {
const resourcePath = `${ resource }/${ record.id }`;
const retrievedActions = [
'create',
'read',
'update',
'delete',
];
const permissions = {};
const methods = {
create: 'POST',
read: 'GET',
update: 'PUT',
delete: 'DELETE',
};
for ( const [ actionName, methodName ] of Object.entries(
methods
) ) {
permissions[ actionName ] =
allowedMethods.includes( methodName );
}

for ( const action of retrievedActions ) {
dispatch.receiveUserPermission(
`${ action }/${ resourcePath }`,
permissions[ action ]
);
}
}
}
}
let action;
if ( query ) {
action = receiveQueriedItems( records, query, edits, meta );
} else {
action = receiveItems( records, edits, meta );
}

return dispatch( {
...action,
kind,
name,
invalidateCache,
} );
};
}

/**
* Returns an action object used in signalling that the current theme has been received.
Expand Down
8 changes: 8 additions & 0 deletions packages/core-data/src/resolvers.js
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,14 @@ export const getEmbedPreview =
export const canUser =
( requestedAction, resource, id ) =>
async ( { dispatch, registry } ) => {
const value = registry
.select( STORE_NAME )
.canUser( requestedAction, resource, id );

if ( value !== undefined ) {
return;
}

const { hasStartedResolution } = registry.select( STORE_NAME );

const resourcePath = id ? `${ resource }/${ id }` : resource;
Expand Down
Loading