Merged in feature/81-dev-dev01 (pull request #5)
auto-patch 81-dev-dev01-2023-12-05T22_45_26 * auto-patch 81-dev-dev01-2023-12-05T22_45_26
This commit is contained in:
@@ -322,24 +322,6 @@ class WP_REST_Server {
|
||||
*/
|
||||
$this->send_header( 'X-Content-Type-Options', 'nosniff' );
|
||||
|
||||
/**
|
||||
* Filters whether to send nocache headers on a REST API request.
|
||||
*
|
||||
* @since 4.4.0
|
||||
*
|
||||
* @param bool $rest_send_nocache_headers Whether to send no-cache headers.
|
||||
*/
|
||||
$send_no_cache_headers = apply_filters( 'rest_send_nocache_headers', is_user_logged_in() );
|
||||
if ( $send_no_cache_headers ) {
|
||||
foreach ( wp_get_nocache_headers() as $header => $header_value ) {
|
||||
if ( empty( $header_value ) ) {
|
||||
$this->remove_header( $header );
|
||||
} else {
|
||||
$this->send_header( $header, $header_value );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters whether the REST API is enabled.
|
||||
*
|
||||
@@ -394,10 +376,12 @@ class WP_REST_Server {
|
||||
* $_GET['_method']. If that is not set, we check for the HTTP_X_HTTP_METHOD_OVERRIDE
|
||||
* header.
|
||||
*/
|
||||
$method_overridden = false;
|
||||
if ( isset( $_GET['_method'] ) ) {
|
||||
$request->set_method( $_GET['_method'] );
|
||||
} elseif ( isset( $_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'] ) ) {
|
||||
$request->set_method( $_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'] );
|
||||
$method_overridden = true;
|
||||
}
|
||||
|
||||
$expose_headers = array( 'X-WP-Total', 'X-WP-TotalPages', 'Link' );
|
||||
@@ -482,6 +466,28 @@ class WP_REST_Server {
|
||||
$code = $result->get_status();
|
||||
$this->set_status( $code );
|
||||
|
||||
/**
|
||||
* Filters whether to send nocache headers on a REST API request.
|
||||
*
|
||||
* @since 4.4.0
|
||||
* @since 6.3.2 Moved the block to catch the filter added on rest_cookie_check_errors() from rest-api.php
|
||||
*
|
||||
* @param bool $rest_send_nocache_headers Whether to send no-cache headers.
|
||||
*/
|
||||
$send_no_cache_headers = apply_filters( 'rest_send_nocache_headers', is_user_logged_in() );
|
||||
|
||||
// send no cache headers if the $send_no_cache_headers is true
|
||||
// OR if the HTTP_X_HTTP_METHOD_OVERRIDE is used but resulted a 4x response code.
|
||||
if ( $send_no_cache_headers || ( true === $method_overridden && strpos( $code, '4' ) === 0 ) ) {
|
||||
foreach ( wp_get_nocache_headers() as $header => $header_value ) {
|
||||
if ( empty( $header_value ) ) {
|
||||
$this->remove_header( $header );
|
||||
} else {
|
||||
$this->send_header( $header, $header_value );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters whether the REST API request has already been served.
|
||||
*
|
||||
@@ -1079,7 +1085,6 @@ class WP_REST_Server {
|
||||
|
||||
foreach ( $handlers as $handler ) {
|
||||
$callback = $handler['callback'];
|
||||
$response = null;
|
||||
|
||||
// Fallback to GET method if no HEAD method is registered.
|
||||
$checked_method = $method;
|
||||
@@ -1273,10 +1278,23 @@ class WP_REST_Server {
|
||||
);
|
||||
|
||||
$response = new WP_REST_Response( $available );
|
||||
$response->add_link( 'help', 'https://developer.wordpress.org/rest-api/' );
|
||||
$this->add_active_theme_link_to_index( $response );
|
||||
$this->add_site_logo_to_index( $response );
|
||||
$this->add_site_icon_to_index( $response );
|
||||
|
||||
$fields = isset( $request['_fields'] ) ? $request['_fields'] : '';
|
||||
$fields = wp_parse_list( $fields );
|
||||
if ( empty( $fields ) ) {
|
||||
$fields[] = '_links';
|
||||
}
|
||||
|
||||
if ( $request->has_param( '_embed' ) ) {
|
||||
$fields[] = '_embedded';
|
||||
}
|
||||
|
||||
if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
|
||||
$response->add_link( 'help', 'https://developer.wordpress.org/rest-api/' );
|
||||
$this->add_active_theme_link_to_index( $response );
|
||||
$this->add_site_logo_to_index( $response );
|
||||
$this->add_site_icon_to_index( $response );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the REST API root index data.
|
||||
|
||||
@@ -731,7 +731,8 @@ class WP_REST_Attachments_Controller extends WP_REST_Posts_Controller {
|
||||
*/
|
||||
public function prepare_item_for_response( $item, $request ) {
|
||||
// Restores the more descriptive, specific name for use within this method.
|
||||
$post = $item;
|
||||
$post = $item;
|
||||
|
||||
$response = parent::prepare_item_for_response( $post, $request );
|
||||
$fields = $this->get_fields_for_response( $request );
|
||||
$data = $response->get_data();
|
||||
@@ -1451,5 +1452,4 @@ class WP_REST_Attachments_Controller extends WP_REST_Posts_Controller {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -65,8 +65,13 @@ class WP_REST_Autosaves_Controller extends WP_REST_Revisions_Controller {
|
||||
$parent_controller = new WP_REST_Posts_Controller( $parent_post_type );
|
||||
}
|
||||
|
||||
$this->parent_controller = $parent_controller;
|
||||
$this->revisions_controller = new WP_REST_Revisions_Controller( $parent_post_type );
|
||||
$this->parent_controller = $parent_controller;
|
||||
|
||||
$revisions_controller = $post_type_object->get_revisions_rest_controller();
|
||||
if ( ! $revisions_controller ) {
|
||||
$revisions_controller = new WP_REST_Revisions_Controller( $parent_post_type );
|
||||
}
|
||||
$this->revisions_controller = $revisions_controller;
|
||||
$this->rest_base = 'autosaves';
|
||||
$this->parent_base = ! empty( $post_type_object->rest_base ) ? $post_type_object->rest_base : $post_type_object->name;
|
||||
$this->namespace = ! empty( $post_type_object->rest_namespace ) ? $post_type_object->rest_namespace : 'wp/v2';
|
||||
@@ -131,7 +136,6 @@ class WP_REST_Autosaves_Controller extends WP_REST_Revisions_Controller {
|
||||
'schema' => array( $this, 'get_public_item_schema' ),
|
||||
)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -206,11 +210,11 @@ class WP_REST_Autosaves_Controller extends WP_REST_Revisions_Controller {
|
||||
*/
|
||||
public function create_item( $request ) {
|
||||
|
||||
if ( ! defined( 'DOING_AUTOSAVE' ) ) {
|
||||
if ( ! defined( 'WP_RUN_CORE_TESTS' ) && ! defined( 'DOING_AUTOSAVE' ) ) {
|
||||
define( 'DOING_AUTOSAVE', true );
|
||||
}
|
||||
|
||||
$post = get_post( $request['id'] );
|
||||
$post = $this->get_parent( $request['id'] );
|
||||
|
||||
if ( is_wp_error( $post ) ) {
|
||||
return $post;
|
||||
@@ -235,8 +239,8 @@ class WP_REST_Autosaves_Controller extends WP_REST_Revisions_Controller {
|
||||
*/
|
||||
$autosave_id = wp_update_post( wp_slash( (array) $prepared_post ), true );
|
||||
} else {
|
||||
// Non-draft posts: create or update the post autosave.
|
||||
$autosave_id = $this->create_post_autosave( (array) $prepared_post );
|
||||
// Non-draft posts: create or update the post autosave. Pass the meta data.
|
||||
$autosave_id = $this->create_post_autosave( (array) $prepared_post, (array) $request->get_param( 'meta' ) );
|
||||
}
|
||||
|
||||
if ( is_wp_error( $autosave_id ) ) {
|
||||
@@ -349,11 +353,13 @@ class WP_REST_Autosaves_Controller extends WP_REST_Revisions_Controller {
|
||||
* From wp-admin/post.php.
|
||||
*
|
||||
* @since 5.0.0
|
||||
* @since 6.4.0 The `$meta` parameter was added.
|
||||
*
|
||||
* @param array $post_data Associative array containing the post data.
|
||||
* @param array $meta Associative array containing the post meta data.
|
||||
* @return mixed The autosave revision ID or WP_Error.
|
||||
*/
|
||||
public function create_post_autosave( $post_data ) {
|
||||
public function create_post_autosave( $post_data, array $meta = array() ) {
|
||||
|
||||
$post_id = (int) $post_data['ID'];
|
||||
$post = get_post( $post_id );
|
||||
@@ -373,6 +379,21 @@ class WP_REST_Autosaves_Controller extends WP_REST_Revisions_Controller {
|
||||
}
|
||||
}
|
||||
|
||||
// Check if meta values have changed.
|
||||
if ( ! empty( $meta ) ) {
|
||||
$revisioned_meta_keys = wp_post_revision_meta_keys( $post->post_type );
|
||||
foreach ( $revisioned_meta_keys as $meta_key ) {
|
||||
// get_metadata_raw is used to avoid retrieving the default value.
|
||||
$old_meta = get_metadata_raw( 'post', $post_id, $meta_key, true );
|
||||
$new_meta = isset( $meta[ $meta_key ] ) ? $meta[ $meta_key ] : '';
|
||||
|
||||
if ( $new_meta !== $old_meta ) {
|
||||
$autosave_is_different = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$user_id = get_current_user_id();
|
||||
|
||||
// Store one autosave per author. If there is already an autosave, overwrite it.
|
||||
@@ -391,11 +412,26 @@ class WP_REST_Autosaves_Controller extends WP_REST_Revisions_Controller {
|
||||
do_action( 'wp_creating_autosave', $new_autosave );
|
||||
|
||||
// wp_update_post() expects escaped array.
|
||||
return wp_update_post( wp_slash( $new_autosave ) );
|
||||
$revision_id = wp_update_post( wp_slash( $new_autosave ) );
|
||||
} else {
|
||||
// Create the new autosave as a special post revision.
|
||||
$revision_id = _wp_put_post_revision( $post_data, true );
|
||||
}
|
||||
|
||||
// Create the new autosave as a special post revision.
|
||||
return _wp_put_post_revision( $post_data, true );
|
||||
if ( is_wp_error( $revision_id ) || 0 === $revision_id ) {
|
||||
return $revision_id;
|
||||
}
|
||||
|
||||
// Attached any passed meta values that have revisions enabled.
|
||||
if ( ! empty( $meta ) ) {
|
||||
foreach ( $revisioned_meta_keys as $meta_key ) {
|
||||
if ( isset( $meta[ $meta_key ] ) ) {
|
||||
update_metadata( 'post', $revision_id, $meta_key, wp_slash( $meta[ $meta_key ] ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $revision_id;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -410,10 +446,10 @@ class WP_REST_Autosaves_Controller extends WP_REST_Revisions_Controller {
|
||||
*/
|
||||
public function prepare_item_for_response( $item, $request ) {
|
||||
// Restores the more descriptive, specific name for use within this method.
|
||||
$post = $item;
|
||||
$response = $this->revisions_controller->prepare_item_for_response( $post, $request );
|
||||
$post = $item;
|
||||
|
||||
$fields = $this->get_fields_for_response( $request );
|
||||
$response = $this->revisions_controller->prepare_item_for_response( $post, $request );
|
||||
$fields = $this->get_fields_for_response( $request );
|
||||
|
||||
if ( in_array( 'preview_link', $fields, true ) ) {
|
||||
$parent_id = wp_is_post_autosave( $post );
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
*/
|
||||
class WP_REST_Block_Types_Controller extends WP_REST_Controller {
|
||||
|
||||
const NAME_PATTERN = '^[a-z][a-z0-9-]*/[a-z][a-z0-9-]*$';
|
||||
|
||||
/**
|
||||
* Instance of WP_Block_Type_Registry.
|
||||
*
|
||||
@@ -246,8 +248,9 @@ class WP_REST_Block_Types_Controller extends WP_REST_Controller {
|
||||
public function prepare_item_for_response( $item, $request ) {
|
||||
// Restores the more descriptive, specific name for use within this method.
|
||||
$block_type = $item;
|
||||
$fields = $this->get_fields_for_response( $request );
|
||||
$data = array();
|
||||
|
||||
$fields = $this->get_fields_for_response( $request );
|
||||
$data = array();
|
||||
|
||||
if ( rest_is_field_included( 'attributes', $fields ) ) {
|
||||
$data['attributes'] = $block_type->get_attributes();
|
||||
@@ -290,6 +293,7 @@ class WP_REST_Block_Types_Controller extends WP_REST_Controller {
|
||||
'editor_style_handles',
|
||||
'style_handles',
|
||||
'variations',
|
||||
'block_hooks',
|
||||
),
|
||||
$deprecated_fields
|
||||
);
|
||||
@@ -400,6 +404,8 @@ class WP_REST_Block_Types_Controller extends WP_REST_Controller {
|
||||
'name' => array(
|
||||
'description' => __( 'The name of the inner block.' ),
|
||||
'type' => 'string',
|
||||
'pattern' => self::NAME_PATTERN,
|
||||
'required' => true,
|
||||
),
|
||||
'attributes' => array(
|
||||
'description' => __( 'The attributes of the inner block.' ),
|
||||
@@ -477,7 +483,8 @@ class WP_REST_Block_Types_Controller extends WP_REST_Controller {
|
||||
'name' => array(
|
||||
'description' => __( 'Unique name identifying the block type.' ),
|
||||
'type' => 'string',
|
||||
'default' => '',
|
||||
'pattern' => self::NAME_PATTERN,
|
||||
'required' => true,
|
||||
'context' => array( 'embed', 'view', 'edit' ),
|
||||
'readonly' => true,
|
||||
),
|
||||
@@ -687,7 +694,8 @@ class WP_REST_Block_Types_Controller extends WP_REST_Controller {
|
||||
'description' => __( 'Parent blocks.' ),
|
||||
'type' => array( 'array', 'null' ),
|
||||
'items' => array(
|
||||
'type' => 'string',
|
||||
'type' => 'string',
|
||||
'pattern' => self::NAME_PATTERN,
|
||||
),
|
||||
'default' => null,
|
||||
'context' => array( 'embed', 'view', 'edit' ),
|
||||
@@ -697,7 +705,8 @@ class WP_REST_Block_Types_Controller extends WP_REST_Controller {
|
||||
'description' => __( 'Ancestor blocks.' ),
|
||||
'type' => array( 'array', 'null' ),
|
||||
'items' => array(
|
||||
'type' => 'string',
|
||||
'type' => 'string',
|
||||
'pattern' => self::NAME_PATTERN,
|
||||
),
|
||||
'default' => null,
|
||||
'context' => array( 'embed', 'view', 'edit' ),
|
||||
@@ -705,6 +714,19 @@ class WP_REST_Block_Types_Controller extends WP_REST_Controller {
|
||||
),
|
||||
'keywords' => $keywords_definition,
|
||||
'example' => $example_definition,
|
||||
'block_hooks' => array(
|
||||
'description' => __( 'This block is automatically inserted near any occurrence of the block types used as keys of this map, into a relative position given by the corresponding value.' ),
|
||||
'type' => 'object',
|
||||
'patternProperties' => array(
|
||||
self::NAME_PATTERN => array(
|
||||
'type' => 'string',
|
||||
'enum' => array( 'before', 'after', 'first_child', 'last_child' ),
|
||||
),
|
||||
),
|
||||
'default' => array(),
|
||||
'context' => array( 'embed', 'view', 'edit' ),
|
||||
'readonly' => true,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -767,5 +789,4 @@ class WP_REST_Block_Types_Controller extends WP_REST_Controller {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* Reusable blocks REST API: WP_REST_Blocks_Controller class
|
||||
* Synced patterns REST API: WP_REST_Blocks_Controller class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage REST_API
|
||||
@@ -9,8 +9,8 @@
|
||||
|
||||
/**
|
||||
* Controller which provides a REST endpoint for the editor to read, create,
|
||||
* edit and delete reusable blocks. Blocks are stored as posts with the wp_block
|
||||
* post type.
|
||||
* edit, and delete synced patterns (formerly called reusable blocks).
|
||||
* Patterns are stored as posts with the wp_block post type.
|
||||
*
|
||||
* @since 5.0.0
|
||||
*
|
||||
@@ -20,12 +20,12 @@
|
||||
class WP_REST_Blocks_Controller extends WP_REST_Posts_Controller {
|
||||
|
||||
/**
|
||||
* Checks if a block can be read.
|
||||
* Checks if a pattern can be read.
|
||||
*
|
||||
* @since 5.0.0
|
||||
*
|
||||
* @param WP_Post $post Post object that backs the block.
|
||||
* @return bool Whether the block can be read.
|
||||
* @return bool Whether the pattern can be read.
|
||||
*/
|
||||
public function check_read_permission( $post ) {
|
||||
// By default the read_post capability is mapped to edit_posts.
|
||||
@@ -50,9 +50,9 @@ class WP_REST_Blocks_Controller extends WP_REST_Posts_Controller {
|
||||
$data = parent::filter_response_by_context( $data, $context );
|
||||
|
||||
/*
|
||||
* Remove `title.rendered` and `content.rendered` from the response. It
|
||||
* doesn't make sense for a reusable block to have rendered content on its
|
||||
* own, since rendering a block requires it to be inside a post or a page.
|
||||
* Remove `title.rendered` and `content.rendered` from the response.
|
||||
* It doesn't make sense for a pattern to have rendered content on its own,
|
||||
* since rendering a block requires it to be inside a post or a page.
|
||||
*/
|
||||
unset( $data['title']['rendered'] );
|
||||
unset( $data['content']['rendered'] );
|
||||
@@ -64,7 +64,7 @@ class WP_REST_Blocks_Controller extends WP_REST_Posts_Controller {
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the block's schema, conforming to JSON Schema.
|
||||
* Retrieves the pattern's schema, conforming to JSON Schema.
|
||||
*
|
||||
* @since 5.0.0
|
||||
*
|
||||
@@ -75,21 +75,20 @@ class WP_REST_Blocks_Controller extends WP_REST_Posts_Controller {
|
||||
return $this->add_additional_fields_schema( $this->schema );
|
||||
}
|
||||
|
||||
// Do not cache this schema because all properties are derived from parent controller.
|
||||
$schema = parent::get_item_schema();
|
||||
|
||||
/*
|
||||
* Allow all contexts to access `title.raw` and `content.raw`. Clients always
|
||||
* need the raw markup of a reusable block to do anything useful, e.g. parse
|
||||
* it or display it in an editor.
|
||||
* Allow all contexts to access `title.raw` and `content.raw`.
|
||||
* Clients always need the raw markup of a pattern to do anything useful,
|
||||
* e.g. parse it or display it in an editor.
|
||||
*/
|
||||
$schema['properties']['title']['properties']['raw']['context'] = array( 'view', 'edit' );
|
||||
$schema['properties']['content']['properties']['raw']['context'] = array( 'view', 'edit' );
|
||||
|
||||
/*
|
||||
* Remove `title.rendered` and `content.rendered` from the schema. It doesn’t
|
||||
* make sense for a reusable block to have rendered content on its own, since
|
||||
* rendering a block requires it to be inside a post or a page.
|
||||
* Remove `title.rendered` and `content.rendered` from the schema.
|
||||
* It doesn't make sense for a pattern to have rendered content on its own,
|
||||
* since rendering a block requires it to be inside a post or a page.
|
||||
*/
|
||||
unset( $schema['properties']['title']['properties']['rendered'] );
|
||||
unset( $schema['properties']['content']['properties']['rendered'] );
|
||||
@@ -98,5 +97,4 @@ class WP_REST_Blocks_Controller extends WP_REST_Posts_Controller {
|
||||
|
||||
return $this->add_additional_fields_schema( $this->schema );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -295,8 +295,9 @@ class WP_REST_Comments_Controller extends WP_REST_Controller {
|
||||
// Out-of-bounds, run the query again without LIMIT for total count.
|
||||
unset( $prepared_args['number'], $prepared_args['offset'] );
|
||||
|
||||
$query = new WP_Comment_Query();
|
||||
$prepared_args['count'] = true;
|
||||
$query = new WP_Comment_Query();
|
||||
$prepared_args['count'] = true;
|
||||
$prepared_args['orderby'] = 'none';
|
||||
|
||||
$total_comments = $query->query( $prepared_args );
|
||||
$max_pages = ceil( $total_comments / $request['per_page'] );
|
||||
@@ -1039,8 +1040,9 @@ class WP_REST_Comments_Controller extends WP_REST_Controller {
|
||||
public function prepare_item_for_response( $item, $request ) {
|
||||
// Restores the more descriptive, specific name for use within this method.
|
||||
$comment = $item;
|
||||
$fields = $this->get_fields_for_response( $request );
|
||||
$data = array();
|
||||
|
||||
$fields = $this->get_fields_for_response( $request );
|
||||
$data = array();
|
||||
|
||||
if ( in_array( 'id', $fields, true ) ) {
|
||||
$data['id'] = (int) $comment->comment_ID;
|
||||
@@ -1187,8 +1189,8 @@ class WP_REST_Comments_Controller extends WP_REST_Controller {
|
||||
// Only grab one comment to verify the comment has children.
|
||||
$comment_children = $comment->get_children(
|
||||
array(
|
||||
'number' => 1,
|
||||
'count' => true,
|
||||
'count' => true,
|
||||
'orderby' => 'none',
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
@@ -625,7 +625,7 @@ abstract class WP_REST_Controller {
|
||||
// Return the list of all requested fields which appear in the schema.
|
||||
return array_reduce(
|
||||
$requested_fields,
|
||||
static function( $response_fields, $field ) use ( $fields ) {
|
||||
static function ( $response_fields, $field ) use ( $fields ) {
|
||||
if ( in_array( $field, $fields, true ) ) {
|
||||
$response_fields[] = $field;
|
||||
return $response_fields;
|
||||
|
||||
@@ -358,7 +358,7 @@ class WP_REST_Global_Styles_Controller extends WP_REST_Controller {
|
||||
* @param WP_REST_Request $request Request object.
|
||||
* @return WP_REST_Response Response object.
|
||||
*/
|
||||
public function prepare_item_for_response( $post, $request ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
|
||||
public function prepare_item_for_response( $post, $request ) {
|
||||
$raw_config = json_decode( $post->post_content, true );
|
||||
$is_global_styles_user_theme_json = isset( $raw_config['isGlobalStylesUserThemeJSON'] ) && true === $raw_config['isGlobalStylesUserThemeJSON'];
|
||||
$config = array();
|
||||
@@ -367,8 +367,8 @@ class WP_REST_Global_Styles_Controller extends WP_REST_Controller {
|
||||
}
|
||||
|
||||
// Base fields for every post.
|
||||
$data = array();
|
||||
$fields = $this->get_fields_for_response( $request );
|
||||
$data = array();
|
||||
|
||||
if ( rest_is_field_included( 'id', $fields ) ) {
|
||||
$data['id'] = $post->ID;
|
||||
@@ -603,8 +603,8 @@ class WP_REST_Global_Styles_Controller extends WP_REST_Controller {
|
||||
}
|
||||
|
||||
$theme = WP_Theme_JSON_Resolver::get_merged_data( 'theme' );
|
||||
$data = array();
|
||||
$fields = $this->get_fields_for_response( $request );
|
||||
$data = array();
|
||||
|
||||
if ( rest_is_field_included( 'settings', $fields ) ) {
|
||||
$data['settings'] = $theme->get_settings();
|
||||
@@ -641,7 +641,7 @@ class WP_REST_Global_Styles_Controller extends WP_REST_Controller {
|
||||
* @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
|
||||
public function get_theme_items_permissions_check( $request ) {
|
||||
/*
|
||||
* Verify if the current user has edit_theme_options capability.
|
||||
* This capability is required to edit/view/delete templates.
|
||||
@@ -663,6 +663,7 @@ class WP_REST_Global_Styles_Controller extends WP_REST_Controller {
|
||||
* Returns the given theme global styles variations.
|
||||
*
|
||||
* @since 6.0.0
|
||||
* @since 6.2.0 Returns parent theme variations, if they exist.
|
||||
*
|
||||
* @param WP_REST_Request $request The request instance.
|
||||
*
|
||||
@@ -679,9 +680,8 @@ class WP_REST_Global_Styles_Controller extends WP_REST_Controller {
|
||||
}
|
||||
|
||||
$variations = WP_Theme_JSON_Resolver::get_style_variations();
|
||||
$response = rest_ensure_response( $variations );
|
||||
|
||||
return $response;
|
||||
return rest_ensure_response( $variations );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -690,11 +690,12 @@ class WP_REST_Global_Styles_Controller extends WP_REST_Controller {
|
||||
* Currently just checks for invalid markup.
|
||||
*
|
||||
* @since 6.2.0
|
||||
* @since 6.4.0 Changed method visibility to protected.
|
||||
*
|
||||
* @param string $css CSS to validate.
|
||||
* @return true|WP_Error True if the input was validated, otherwise WP_Error.
|
||||
*/
|
||||
private function validate_custom_css( $css ) {
|
||||
protected function validate_custom_css( $css ) {
|
||||
if ( preg_match( '#</?\w+#', $css ) ) {
|
||||
return new WP_Error(
|
||||
'rest_custom_css_illegal_markup',
|
||||
|
||||
@@ -57,7 +57,7 @@ class WP_REST_Menu_Items_Controller extends WP_REST_Posts_Controller {
|
||||
* @since 5.9.0
|
||||
*
|
||||
* @param WP_REST_Request $request Full details about the request.
|
||||
* @return bool|WP_Error True if the request has read access for the item, WP_Error object otherwise.
|
||||
* @return bool|WP_Error True if the request has read access for the item, WP_Error object or false otherwise.
|
||||
*/
|
||||
public function get_item_permissions_check( $request ) {
|
||||
$permission_check = parent::get_item_permissions_check( $request );
|
||||
@@ -77,7 +77,7 @@ class WP_REST_Menu_Items_Controller extends WP_REST_Posts_Controller {
|
||||
* @since 5.9.0
|
||||
*
|
||||
* @param WP_REST_Request $request Full details about the request.
|
||||
* @return bool|WP_Error Whether the current user has permission.
|
||||
* @return true|WP_Error True if the request has read access for the item, WP_Error object otherwise.
|
||||
*/
|
||||
protected function check_has_read_only_access( $request ) {
|
||||
if ( current_user_can( 'edit_theme_options' ) ) {
|
||||
|
||||
@@ -120,7 +120,7 @@ class WP_REST_Menu_Locations_Controller extends WP_REST_Controller {
|
||||
* @since 5.9.0
|
||||
*
|
||||
* @param WP_REST_Request $request Full details about the request.
|
||||
* @return WP_Error|bool True if the request has read access for the item, WP_Error object otherwise.
|
||||
* @return true|WP_Error True if the request has read access for the item, WP_Error object otherwise.
|
||||
*/
|
||||
public function get_item_permissions_check( $request ) {
|
||||
if ( ! current_user_can( 'edit_theme_options' ) ) {
|
||||
@@ -168,7 +168,8 @@ class WP_REST_Menu_Locations_Controller extends WP_REST_Controller {
|
||||
*/
|
||||
public function prepare_item_for_response( $item, $request ) {
|
||||
// Restores the more descriptive, specific name for use within this method.
|
||||
$location = $item;
|
||||
$location = $item;
|
||||
|
||||
$locations = get_nav_menu_locations();
|
||||
$menu = isset( $locations[ $location->name ] ) ? $locations[ $location->name ] : 0;
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ class WP_REST_Menus_Controller extends WP_REST_Terms_Controller {
|
||||
* @since 5.9.0
|
||||
*
|
||||
* @param WP_REST_Request $request Full details about the request.
|
||||
* @return bool|WP_Error True if the request has read access for the item, otherwise false or WP_Error object.
|
||||
* @return true|WP_Error True if the request has read access for the item, otherwise WP_Error object.
|
||||
*/
|
||||
public function get_item_permissions_check( $request ) {
|
||||
$has_permission = parent::get_item_permissions_check( $request );
|
||||
@@ -81,7 +81,7 @@ class WP_REST_Menus_Controller extends WP_REST_Terms_Controller {
|
||||
* @since 5.9.0
|
||||
*
|
||||
* @param WP_REST_Request $request Full details about the request.
|
||||
* @return bool|WP_Error Whether the current user has permission.
|
||||
* @return true|WP_Error True if the current user has permission, WP_Error object otherwise.
|
||||
*/
|
||||
protected function check_has_read_only_access( $request ) {
|
||||
if ( current_user_can( 'edit_theme_options' ) ) {
|
||||
|
||||
@@ -40,8 +40,6 @@ class WP_REST_Navigation_Fallback_Controller extends WP_REST_Controller {
|
||||
* Registers the controllers routes.
|
||||
*
|
||||
* @since 6.3.0
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register_routes() {
|
||||
|
||||
|
||||
@@ -106,7 +106,7 @@ class WP_REST_Pattern_Directory_Controller extends WP_REST_Controller {
|
||||
$query_args = array_intersect_key( $request->get_params(), $valid_query_args );
|
||||
|
||||
$query_args['locale'] = get_user_locale();
|
||||
$query_args['wp-version'] = $wp_version; // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable -- it's defined in `version.php` above.
|
||||
$query_args['wp-version'] = $wp_version;
|
||||
$query_args['pattern-categories'] = isset( $request['category'] ) ? $request['category'] : false;
|
||||
$query_args['pattern-keywords'] = isset( $request['keyword'] ) ? $request['keyword'] : false;
|
||||
|
||||
@@ -193,7 +193,8 @@ class WP_REST_Pattern_Directory_Controller extends WP_REST_Controller {
|
||||
*/
|
||||
public function prepare_item_for_response( $item, $request ) {
|
||||
// Restores the more descriptive, specific name for use within this method.
|
||||
$raw_pattern = $item;
|
||||
$raw_pattern = $item;
|
||||
|
||||
$prepared_pattern = array(
|
||||
'id' => absint( $raw_pattern->id ),
|
||||
'title' => sanitize_text_field( $raw_pattern->title->rendered ),
|
||||
|
||||
@@ -381,7 +381,7 @@ class WP_REST_Plugins_Controller extends WP_REST_Controller {
|
||||
$installed_locales = apply_filters( 'plugins_update_check_locales', $installed_locales );
|
||||
|
||||
$language_packs = array_map(
|
||||
static function( $item ) {
|
||||
static function ( $item ) {
|
||||
return (object) $item;
|
||||
},
|
||||
$api->language_packs
|
||||
@@ -389,7 +389,7 @@ class WP_REST_Plugins_Controller extends WP_REST_Controller {
|
||||
|
||||
$language_packs = array_filter(
|
||||
$language_packs,
|
||||
static function( $pack ) use ( $installed_locales ) {
|
||||
static function ( $pack ) use ( $installed_locales ) {
|
||||
return in_array( $pack->language, $installed_locales, true );
|
||||
}
|
||||
);
|
||||
|
||||
@@ -222,6 +222,7 @@ class WP_REST_Post_Statuses_Controller extends WP_REST_Controller {
|
||||
public function prepare_item_for_response( $item, $request ) {
|
||||
// Restores the more descriptive, specific name for use within this method.
|
||||
$status = $item;
|
||||
|
||||
$fields = $this->get_fields_for_response( $request );
|
||||
$data = array();
|
||||
|
||||
@@ -369,5 +370,4 @@ class WP_REST_Post_Statuses_Controller extends WP_REST_Controller {
|
||||
'context' => $this->get_context_param( array( 'default' => 'view' ) ),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -176,7 +176,8 @@ class WP_REST_Post_Types_Controller extends WP_REST_Controller {
|
||||
*/
|
||||
public function prepare_item_for_response( $item, $request ) {
|
||||
// Restores the more descriptive, specific name for use within this method.
|
||||
$post_type = $item;
|
||||
$post_type = $item;
|
||||
|
||||
$taxonomies = wp_list_filter( get_object_taxonomies( $post_type->name, 'objects' ), array( 'show_in_rest' => true ) );
|
||||
$taxonomies = wp_list_pluck( $taxonomies, 'name' );
|
||||
$base = ! empty( $post_type->rest_base ) ? $post_type->rest_base : $post_type->name;
|
||||
|
||||
@@ -475,7 +475,7 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
||||
* @since 4.7.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.
|
||||
* @return bool|WP_Error True if the request has read access for the item, WP_Error object or false otherwise.
|
||||
*/
|
||||
public function get_item_permissions_check( $request ) {
|
||||
$post = $this->get_post( $request['id'] );
|
||||
@@ -1397,7 +1397,6 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
||||
* @param WP_REST_Request $request Request object.
|
||||
*/
|
||||
return apply_filters( "rest_pre_insert_{$this->post_type}", $prepared_post, $request );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1496,7 +1495,6 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
||||
} else {
|
||||
return delete_post_thumbnail( $post_id );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1506,7 +1504,7 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
||||
*
|
||||
* @param string $template Page template filename.
|
||||
* @param WP_REST_Request $request Request.
|
||||
* @return bool|WP_Error True if template is still valid or if the same as existing value, or false if template not supported.
|
||||
* @return true|WP_Error True if template is still valid or if the same as existing value, or a WP_Error if template not supported.
|
||||
*/
|
||||
public function check_template( $template, $request ) {
|
||||
|
||||
@@ -1750,7 +1748,8 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
||||
*/
|
||||
public function prepare_item_for_response( $item, $request ) {
|
||||
// Restores the more descriptive, specific name for use within this method.
|
||||
$post = $item;
|
||||
$post = $item;
|
||||
|
||||
$GLOBALS['post'] = $post;
|
||||
|
||||
setup_postdata( $post );
|
||||
|
||||
@@ -24,6 +24,14 @@ class WP_REST_Revisions_Controller extends WP_REST_Controller {
|
||||
*/
|
||||
private $parent_post_type;
|
||||
|
||||
/**
|
||||
* Instance of a revision meta fields object.
|
||||
*
|
||||
* @since 6.4.0
|
||||
* @var WP_REST_Post_Meta_Fields
|
||||
*/
|
||||
protected $meta;
|
||||
|
||||
/**
|
||||
* Parent controller.
|
||||
*
|
||||
@@ -60,6 +68,7 @@ class WP_REST_Revisions_Controller extends WP_REST_Controller {
|
||||
$this->rest_base = 'revisions';
|
||||
$this->parent_base = ! empty( $post_type_object->rest_base ) ? $post_type_object->rest_base : $post_type_object->name;
|
||||
$this->namespace = ! empty( $post_type_object->rest_namespace ) ? $post_type_object->rest_namespace : 'wp/v2';
|
||||
$this->meta = new WP_REST_Post_Meta_Fields( $parent_post_type );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -128,7 +137,6 @@ class WP_REST_Revisions_Controller extends WP_REST_Controller {
|
||||
'schema' => array( $this, 'get_public_item_schema' ),
|
||||
)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -548,7 +556,8 @@ class WP_REST_Revisions_Controller extends WP_REST_Controller {
|
||||
*/
|
||||
public function prepare_item_for_response( $item, $request ) {
|
||||
// Restores the more descriptive, specific name for use within this method.
|
||||
$post = $item;
|
||||
$post = $item;
|
||||
|
||||
$GLOBALS['post'] = $post;
|
||||
|
||||
setup_postdata( $post );
|
||||
@@ -619,6 +628,10 @@ class WP_REST_Revisions_Controller extends WP_REST_Controller {
|
||||
);
|
||||
}
|
||||
|
||||
if ( rest_is_field_included( 'meta', $fields ) ) {
|
||||
$data['meta'] = $this->meta->get_value( $post->ID, $request );
|
||||
}
|
||||
|
||||
$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
|
||||
$data = $this->add_additional_fields_to_object( $data, $request );
|
||||
$data = $this->filter_response_by_context( $data, $context );
|
||||
@@ -752,6 +765,8 @@ class WP_REST_Revisions_Controller extends WP_REST_Controller {
|
||||
$schema['properties']['guid'] = $parent_schema['properties']['guid'];
|
||||
}
|
||||
|
||||
$schema['properties']['meta'] = $this->meta->get_field_schema();
|
||||
|
||||
$this->schema = $schema;
|
||||
|
||||
return $this->add_additional_fields_schema( $this->schema );
|
||||
|
||||
@@ -195,6 +195,7 @@ class WP_REST_Search_Controller extends WP_REST_Controller {
|
||||
public function prepare_item_for_response( $item, $request ) {
|
||||
// Restores the more descriptive, specific name for use within this method.
|
||||
$item_id = $item;
|
||||
|
||||
$handler = $this->get_search_handler( $request );
|
||||
if ( is_wp_error( $handler ) ) {
|
||||
return new WP_REST_Response();
|
||||
|
||||
@@ -54,7 +54,6 @@ class WP_REST_Settings_Controller extends WP_REST_Controller {
|
||||
'schema' => array( $this, 'get_public_item_schema' ),
|
||||
)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -320,8 +320,9 @@ class WP_REST_Sidebars_Controller extends WP_REST_Controller {
|
||||
|
||||
// Restores the more descriptive, specific name for use within this method.
|
||||
$raw_sidebar = $item;
|
||||
$id = $raw_sidebar['id'];
|
||||
$sidebar = array( 'id' => $id );
|
||||
|
||||
$id = $raw_sidebar['id'];
|
||||
$sidebar = array( 'id' => $id );
|
||||
|
||||
if ( isset( $wp_registered_sidebars[ $id ] ) ) {
|
||||
$registered_sidebar = $wp_registered_sidebars[ $id ];
|
||||
|
||||
@@ -152,8 +152,8 @@ class WP_REST_Site_Health_Controller extends WP_REST_Controller {
|
||||
array(
|
||||
'methods' => 'GET',
|
||||
'callback' => array( $this, 'get_directory_sizes' ),
|
||||
'permission_callback' => function() {
|
||||
return $this->validate_request_permission( 'debug_enabled' ) && ! is_multisite();
|
||||
'permission_callback' => function () {
|
||||
return $this->validate_request_permission( 'directory_sizes' ) && ! is_multisite();
|
||||
},
|
||||
)
|
||||
);
|
||||
@@ -170,7 +170,7 @@ class WP_REST_Site_Health_Controller extends WP_REST_Controller {
|
||||
'methods' => 'GET',
|
||||
'callback' => array( $this, 'test_page_cache' ),
|
||||
'permission_callback' => function () {
|
||||
return $this->validate_request_permission( 'view_site_health_checks' );
|
||||
return $this->validate_request_permission( 'page_cache' );
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
@@ -209,7 +209,8 @@ class WP_REST_Taxonomies_Controller extends WP_REST_Controller {
|
||||
public function prepare_item_for_response( $item, $request ) {
|
||||
// Restores the more descriptive, specific name for use within this method.
|
||||
$taxonomy = $item;
|
||||
$base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name;
|
||||
|
||||
$base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name;
|
||||
|
||||
$fields = $this->get_fields_for_response( $request );
|
||||
$data = array();
|
||||
|
||||
@@ -0,0 +1,276 @@
|
||||
<?php
|
||||
/**
|
||||
* REST API: WP_REST_Template_Autosaves_Controller class.
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage REST_API
|
||||
* @since 6.4.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Core class used to access template autosaves via the REST API.
|
||||
*
|
||||
* @since 6.4.0
|
||||
*
|
||||
* @see WP_REST_Autosaves_Controller
|
||||
*/
|
||||
class WP_REST_Template_Autosaves_Controller extends WP_REST_Autosaves_Controller {
|
||||
/**
|
||||
* Parent post type.
|
||||
*
|
||||
* @since 6.4.0
|
||||
* @var string
|
||||
*/
|
||||
private $parent_post_type;
|
||||
|
||||
/**
|
||||
* Parent post controller.
|
||||
*
|
||||
* @since 6.4.0
|
||||
* @var WP_REST_Controller
|
||||
*/
|
||||
private $parent_controller;
|
||||
|
||||
/**
|
||||
* Revision controller.
|
||||
*
|
||||
* @since 6.4.0
|
||||
* @var WP_REST_Revisions_Controller
|
||||
*/
|
||||
private $revisions_controller;
|
||||
|
||||
/**
|
||||
* The base of the parent controller's route.
|
||||
*
|
||||
* @since 6.4.0
|
||||
* @var string
|
||||
*/
|
||||
private $parent_base;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @since 6.4.0
|
||||
*
|
||||
* @param string $parent_post_type Post type of the parent.
|
||||
*/
|
||||
public function __construct( $parent_post_type ) {
|
||||
parent::__construct( $parent_post_type );
|
||||
$this->parent_post_type = $parent_post_type;
|
||||
$post_type_object = get_post_type_object( $parent_post_type );
|
||||
$parent_controller = $post_type_object->get_rest_controller();
|
||||
|
||||
if ( ! $parent_controller ) {
|
||||
$parent_controller = new WP_REST_Templates_Controller( $parent_post_type );
|
||||
}
|
||||
|
||||
$this->parent_controller = $parent_controller;
|
||||
|
||||
$revisions_controller = $post_type_object->get_revisions_rest_controller();
|
||||
if ( ! $revisions_controller ) {
|
||||
$revisions_controller = new WP_REST_Revisions_Controller( $parent_post_type );
|
||||
}
|
||||
$this->revisions_controller = $revisions_controller;
|
||||
$this->rest_base = 'autosaves';
|
||||
$this->parent_base = ! empty( $post_type_object->rest_base ) ? $post_type_object->rest_base : $post_type_object->name;
|
||||
$this->namespace = ! empty( $post_type_object->rest_namespace ) ? $post_type_object->rest_namespace : 'wp/v2';
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the routes for autosaves.
|
||||
*
|
||||
* @since 6.4.0
|
||||
*
|
||||
* @see register_rest_route()
|
||||
*/
|
||||
public function register_routes() {
|
||||
register_rest_route(
|
||||
$this->namespace,
|
||||
sprintf(
|
||||
'/%s/(?P<id>%s%s)/%s',
|
||||
$this->parent_base,
|
||||
/*
|
||||
* Matches theme's directory: `/themes/<subdirectory>/<theme>/` or `/themes/<theme>/`.
|
||||
* Excludes invalid directory name characters: `/:<>*?"|`.
|
||||
*/
|
||||
'([^\/:<>\*\?"\|]+(?:\/[^\/:<>\*\?"\|]+)?)',
|
||||
// Matches the template name.
|
||||
'[\/\w%-]+',
|
||||
$this->rest_base
|
||||
),
|
||||
array(
|
||||
'args' => array(
|
||||
'id' => array(
|
||||
'description' => __( 'The id of a template' ),
|
||||
'type' => 'string',
|
||||
'sanitize_callback' => array( $this->parent_controller, '_sanitize_template_id' ),
|
||||
),
|
||||
),
|
||||
array(
|
||||
'methods' => WP_REST_Server::READABLE,
|
||||
'callback' => array( $this, 'get_items' ),
|
||||
'permission_callback' => array( $this, 'get_items_permissions_check' ),
|
||||
'args' => $this->get_collection_params(),
|
||||
),
|
||||
array(
|
||||
'methods' => WP_REST_Server::CREATABLE,
|
||||
'callback' => array( $this, 'create_item' ),
|
||||
'permission_callback' => array( $this, 'create_item_permissions_check' ),
|
||||
'args' => $this->parent_controller->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
|
||||
),
|
||||
'schema' => array( $this, 'get_public_item_schema' ),
|
||||
)
|
||||
);
|
||||
|
||||
register_rest_route(
|
||||
$this->namespace,
|
||||
sprintf(
|
||||
'/%s/(?P<parent>%s%s)/%s/%s',
|
||||
$this->parent_base,
|
||||
/*
|
||||
* Matches theme's directory: `/themes/<subdirectory>/<theme>/` or `/themes/<theme>/`.
|
||||
* Excludes invalid directory name characters: `/:<>*?"|`.
|
||||
*/
|
||||
'([^\/:<>\*\?"\|]+(?:\/[^\/:<>\*\?"\|]+)?)',
|
||||
// Matches the template name.
|
||||
'[\/\w%-]+',
|
||||
$this->rest_base,
|
||||
'(?P<id>[\d]+)'
|
||||
),
|
||||
array(
|
||||
'args' => array(
|
||||
'parent' => array(
|
||||
'description' => __( 'The id of a template' ),
|
||||
'type' => 'string',
|
||||
'sanitize_callback' => array( $this->parent_controller, '_sanitize_template_id' ),
|
||||
),
|
||||
'id' => array(
|
||||
'description' => __( 'The ID for the autosave.' ),
|
||||
'type' => 'integer',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'methods' => WP_REST_Server::READABLE,
|
||||
'callback' => array( $this, 'get_item' ),
|
||||
'permission_callback' => array( $this->revisions_controller, 'get_item_permissions_check' ),
|
||||
'args' => array(
|
||||
'context' => $this->get_context_param( array( 'default' => 'view' ) ),
|
||||
),
|
||||
),
|
||||
'schema' => array( $this, 'get_public_item_schema' ),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares the item for the REST response.
|
||||
*
|
||||
* @since 6.4.0
|
||||
*
|
||||
* @param WP_Post $item Post revision object.
|
||||
* @param WP_REST_Request $request Request object.
|
||||
* @return WP_REST_Response Response object.
|
||||
*/
|
||||
public function prepare_item_for_response( $item, $request ) {
|
||||
$template = _build_block_template_result_from_post( $item );
|
||||
$response = $this->parent_controller->prepare_item_for_response( $template, $request );
|
||||
|
||||
$fields = $this->get_fields_for_response( $request );
|
||||
$data = $response->get_data();
|
||||
|
||||
if ( in_array( 'parent', $fields, true ) ) {
|
||||
$data['parent'] = (int) $item->post_parent;
|
||||
}
|
||||
|
||||
$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
|
||||
$data = $this->filter_response_by_context( $data, $context );
|
||||
|
||||
// Wrap the data in a response object.
|
||||
$response = new WP_REST_Response( $data );
|
||||
|
||||
if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
|
||||
$links = $this->prepare_links( $template );
|
||||
$response->add_links( $links );
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the autosave, if the ID is valid.
|
||||
*
|
||||
* @since 6.4.0
|
||||
*
|
||||
* @param WP_REST_Request $request Full details about the request.
|
||||
* @return WP_Post|WP_Error Autosave post object if ID is valid, WP_Error otherwise.
|
||||
*/
|
||||
public function get_item( $request ) {
|
||||
$parent = $this->get_parent( $request['parent'] );
|
||||
if ( is_wp_error( $parent ) ) {
|
||||
return $parent;
|
||||
}
|
||||
|
||||
$autosave = wp_get_post_autosave( $parent->ID );
|
||||
|
||||
if ( ! $autosave ) {
|
||||
return new WP_Error(
|
||||
'rest_post_no_autosave',
|
||||
__( 'There is no autosave revision for this template.' ),
|
||||
array( 'status' => 404 )
|
||||
);
|
||||
}
|
||||
|
||||
$response = $this->prepare_item_for_response( $autosave, $request );
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the parent post.
|
||||
*
|
||||
* @since 6.4.0
|
||||
*
|
||||
* @param int $parent_id Supplied ID.
|
||||
* @return WP_Post|WP_Error Post object if ID is valid, WP_Error otherwise.
|
||||
*/
|
||||
protected function get_parent( $parent_id ) {
|
||||
return $this->revisions_controller->get_parent( $parent_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares links for the request.
|
||||
*
|
||||
* @since 6.4.0
|
||||
*
|
||||
* @param WP_Block_Template $template Template.
|
||||
* @return array Links for the given post.
|
||||
*/
|
||||
protected function prepare_links( $template ) {
|
||||
$links = array(
|
||||
'self' => array(
|
||||
'href' => rest_url( sprintf( '/%s/%s/%s/%s/%d', $this->namespace, $this->parent_base, $template->id, $this->rest_base, $template->wp_id ) ),
|
||||
),
|
||||
'parent' => array(
|
||||
'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->parent_base, $template->id ) ),
|
||||
),
|
||||
);
|
||||
|
||||
return $links;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the autosave's schema, conforming to JSON Schema.
|
||||
*
|
||||
* @since 6.4.0
|
||||
*
|
||||
* @return array Item schema data.
|
||||
*/
|
||||
public function get_item_schema() {
|
||||
if ( $this->schema ) {
|
||||
return $this->add_additional_fields_schema( $this->schema );
|
||||
}
|
||||
|
||||
$this->schema = $this->revisions_controller->get_item_schema();
|
||||
|
||||
return $this->add_additional_fields_schema( $this->schema );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,297 @@
|
||||
<?php
|
||||
/**
|
||||
* REST API: WP_REST_Template_Revisions_Controller class
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage REST_API
|
||||
* @since 6.4.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Core class used to access template revisions via the REST API.
|
||||
*
|
||||
* @since 6.4.0
|
||||
*
|
||||
* @see WP_REST_Controller
|
||||
*/
|
||||
class WP_REST_Template_Revisions_Controller extends WP_REST_Revisions_Controller {
|
||||
/**
|
||||
* Parent post type.
|
||||
*
|
||||
* @since 6.4.0
|
||||
* @var string
|
||||
*/
|
||||
private $parent_post_type;
|
||||
|
||||
/**
|
||||
* Parent controller.
|
||||
*
|
||||
* @since 6.4.0
|
||||
* @var WP_REST_Controller
|
||||
*/
|
||||
private $parent_controller;
|
||||
|
||||
/**
|
||||
* The base of the parent controller's route.
|
||||
*
|
||||
* @since 6.4.0
|
||||
* @var string
|
||||
*/
|
||||
private $parent_base;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @since 6.4.0
|
||||
*
|
||||
* @param string $parent_post_type Post type of the parent.
|
||||
*/
|
||||
public function __construct( $parent_post_type ) {
|
||||
parent::__construct( $parent_post_type );
|
||||
$this->parent_post_type = $parent_post_type;
|
||||
$post_type_object = get_post_type_object( $parent_post_type );
|
||||
$parent_controller = $post_type_object->get_rest_controller();
|
||||
|
||||
if ( ! $parent_controller ) {
|
||||
$parent_controller = new WP_REST_Templates_Controller( $parent_post_type );
|
||||
}
|
||||
|
||||
$this->parent_controller = $parent_controller;
|
||||
$this->rest_base = 'revisions';
|
||||
$this->parent_base = ! empty( $post_type_object->rest_base ) ? $post_type_object->rest_base : $post_type_object->name;
|
||||
$this->namespace = ! empty( $post_type_object->rest_namespace ) ? $post_type_object->rest_namespace : 'wp/v2';
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the routes for revisions based on post types supporting revisions.
|
||||
*
|
||||
* @since 6.4.0
|
||||
*
|
||||
* @see register_rest_route()
|
||||
*/
|
||||
public function register_routes() {
|
||||
|
||||
register_rest_route(
|
||||
$this->namespace,
|
||||
sprintf(
|
||||
'/%s/(?P<parent>%s%s)/%s',
|
||||
$this->parent_base,
|
||||
/*
|
||||
* Matches theme's directory: `/themes/<subdirectory>/<theme>/` or `/themes/<theme>/`.
|
||||
* Excludes invalid directory name characters: `/:<>*?"|`.
|
||||
*/
|
||||
'([^\/:<>\*\?"\|]+(?:\/[^\/:<>\*\?"\|]+)?)',
|
||||
// Matches the template name.
|
||||
'[\/\w%-]+',
|
||||
$this->rest_base
|
||||
),
|
||||
array(
|
||||
'args' => array(
|
||||
'parent' => array(
|
||||
'description' => __( 'The id of a template' ),
|
||||
'type' => 'string',
|
||||
'sanitize_callback' => array( $this->parent_controller, '_sanitize_template_id' ),
|
||||
),
|
||||
),
|
||||
array(
|
||||
'methods' => WP_REST_Server::READABLE,
|
||||
'callback' => array( $this, 'get_items' ),
|
||||
'permission_callback' => array( $this, 'get_items_permissions_check' ),
|
||||
'args' => $this->get_collection_params(),
|
||||
),
|
||||
'schema' => array( $this, 'get_public_item_schema' ),
|
||||
)
|
||||
);
|
||||
|
||||
register_rest_route(
|
||||
$this->namespace,
|
||||
sprintf(
|
||||
'/%s/(?P<parent>%s%s)/%s/%s',
|
||||
$this->parent_base,
|
||||
/*
|
||||
* Matches theme's directory: `/themes/<subdirectory>/<theme>/` or `/themes/<theme>/`.
|
||||
* Excludes invalid directory name characters: `/:<>*?"|`.
|
||||
*/
|
||||
'([^\/:<>\*\?"\|]+(?:\/[^\/:<>\*\?"\|]+)?)',
|
||||
// Matches the template name.
|
||||
'[\/\w%-]+',
|
||||
$this->rest_base,
|
||||
'(?P<id>[\d]+)'
|
||||
),
|
||||
array(
|
||||
'args' => array(
|
||||
'parent' => array(
|
||||
'description' => __( 'The id of a template' ),
|
||||
'type' => 'string',
|
||||
'sanitize_callback' => array( $this->parent_controller, '_sanitize_template_id' ),
|
||||
),
|
||||
'id' => array(
|
||||
'description' => __( 'Unique identifier for the revision.' ),
|
||||
'type' => 'integer',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'methods' => WP_REST_Server::READABLE,
|
||||
'callback' => array( $this, 'get_item' ),
|
||||
'permission_callback' => array( $this, 'get_item_permissions_check' ),
|
||||
'args' => array(
|
||||
'context' => $this->get_context_param( array( 'default' => 'view' ) ),
|
||||
),
|
||||
),
|
||||
array(
|
||||
'methods' => WP_REST_Server::DELETABLE,
|
||||
'callback' => array( $this, 'delete_item' ),
|
||||
'permission_callback' => array( $this, 'delete_item_permissions_check' ),
|
||||
'args' => array(
|
||||
'force' => array(
|
||||
'type' => 'boolean',
|
||||
'default' => false,
|
||||
'description' => __( 'Required to be true, as revisions do not support trashing.' ),
|
||||
),
|
||||
),
|
||||
),
|
||||
'schema' => array( $this, 'get_public_item_schema' ),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the parent post, if the ID is valid.
|
||||
*
|
||||
* @since 6.4.0
|
||||
*
|
||||
* @param int $parent_post_id Supplied ID.
|
||||
* @return WP_Post|WP_Error Post object if ID is valid, WP_Error otherwise.
|
||||
*/
|
||||
protected function get_parent( $parent_post_id ) {
|
||||
$template = get_block_template( $parent_post_id, $this->parent_post_type );
|
||||
|
||||
if ( ! $template ) {
|
||||
return new WP_Error(
|
||||
'rest_post_invalid_parent',
|
||||
__( 'Invalid template parent ID.' ),
|
||||
array( 'status' => 404 )
|
||||
);
|
||||
}
|
||||
|
||||
return get_post( $template->wp_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares the item for the REST response.
|
||||
*
|
||||
* @since 6.4.0
|
||||
*
|
||||
* @param WP_Post $item Post revision object.
|
||||
* @param WP_REST_Request $request Request object.
|
||||
* @return WP_REST_Response Response object.
|
||||
*/
|
||||
public function prepare_item_for_response( $item, $request ) {
|
||||
$template = _build_block_template_result_from_post( $item );
|
||||
$response = $this->parent_controller->prepare_item_for_response( $template, $request );
|
||||
|
||||
$fields = $this->get_fields_for_response( $request );
|
||||
$data = $response->get_data();
|
||||
|
||||
if ( in_array( 'parent', $fields, true ) ) {
|
||||
$data['parent'] = (int) $item->post_parent;
|
||||
}
|
||||
|
||||
$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
|
||||
$data = $this->filter_response_by_context( $data, $context );
|
||||
|
||||
// Wrap the data in a response object.
|
||||
$response = new WP_REST_Response( $data );
|
||||
|
||||
if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
|
||||
$links = $this->prepare_links( $template );
|
||||
$response->add_links( $links );
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a given request has access to delete a revision.
|
||||
*
|
||||
* @since 6.4.0
|
||||
*
|
||||
* @param WP_REST_Request $request Full details about the request.
|
||||
* @return true|WP_Error True if the request has access to delete the item, WP_Error object otherwise.
|
||||
*/
|
||||
public function delete_item_permissions_check( $request ) {
|
||||
$parent = $this->get_parent( $request['parent'] );
|
||||
if ( is_wp_error( $parent ) ) {
|
||||
return $parent;
|
||||
}
|
||||
|
||||
if ( ! current_user_can( 'delete_post', $parent->ID ) ) {
|
||||
return new WP_Error(
|
||||
'rest_cannot_delete',
|
||||
__( 'Sorry, you are not allowed to delete revisions of this post.' ),
|
||||
array( 'status' => rest_authorization_required_code() )
|
||||
);
|
||||
}
|
||||
|
||||
$revision = $this->get_revision( $request['id'] );
|
||||
if ( is_wp_error( $revision ) ) {
|
||||
return $revision;
|
||||
}
|
||||
|
||||
if ( ! current_user_can( 'edit_theme_options' ) ) {
|
||||
return new WP_Error(
|
||||
'rest_cannot_delete',
|
||||
__( 'Sorry, you are not allowed to delete this revision.' ),
|
||||
array( 'status' => rest_authorization_required_code() )
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares links for the request.
|
||||
*
|
||||
* @since 6.4.0
|
||||
*
|
||||
* @param WP_Block_Template $template Template.
|
||||
* @return array Links for the given post.
|
||||
*/
|
||||
protected function prepare_links( $template ) {
|
||||
$links = array(
|
||||
'self' => array(
|
||||
'href' => rest_url( sprintf( '/%s/%s/%s/%s/%d', $this->namespace, $this->parent_base, $template->id, $this->rest_base, $template->wp_id ) ),
|
||||
),
|
||||
'parent' => array(
|
||||
'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->parent_base, $template->id ) ),
|
||||
),
|
||||
);
|
||||
|
||||
return $links;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the item's schema, conforming to JSON Schema.
|
||||
*
|
||||
* @since 6.4.0
|
||||
*
|
||||
* @return array Item schema data.
|
||||
*/
|
||||
public function get_item_schema() {
|
||||
if ( $this->schema ) {
|
||||
return $this->add_additional_fields_schema( $this->schema );
|
||||
}
|
||||
|
||||
$schema = $this->parent_controller->get_item_schema();
|
||||
|
||||
$schema['properties']['parent'] = array(
|
||||
'description' => __( 'The ID for the parent of the revision.' ),
|
||||
'type' => 'integer',
|
||||
'context' => array( 'view', 'edit', 'embed' ),
|
||||
);
|
||||
|
||||
$this->schema = $schema;
|
||||
|
||||
return $this->add_additional_fields_schema( $this->schema );
|
||||
}
|
||||
}
|
||||
@@ -633,7 +633,7 @@ class WP_REST_Templates_Controller extends WP_REST_Controller {
|
||||
* @param WP_REST_Request $request Request object.
|
||||
* @return WP_REST_Response Response object.
|
||||
*/
|
||||
public function prepare_item_for_response( $item, $request ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
|
||||
public function prepare_item_for_response( $item, $request ) {
|
||||
// Restores the more descriptive, specific name for use within this method.
|
||||
$template = $item;
|
||||
|
||||
@@ -760,7 +760,7 @@ class WP_REST_Templates_Controller extends WP_REST_Controller {
|
||||
protected function prepare_links( $id ) {
|
||||
$links = array(
|
||||
'self' => array(
|
||||
'href' => rest_url( rest_get_route_for_post( $id ) ),
|
||||
'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $id ) ),
|
||||
),
|
||||
'collection' => array(
|
||||
'href' => rest_url( rest_get_route_for_post_type_items( $this->post_type ) ),
|
||||
@@ -770,6 +770,27 @@ class WP_REST_Templates_Controller extends WP_REST_Controller {
|
||||
),
|
||||
);
|
||||
|
||||
if ( post_type_supports( $this->post_type, 'revisions' ) ) {
|
||||
$template = get_block_template( $id, $this->post_type );
|
||||
if ( $template instanceof WP_Block_Template && ! empty( $template->wp_id ) ) {
|
||||
$revisions = wp_get_latest_revision_id_and_total_count( $template->wp_id );
|
||||
$revisions_count = ! is_wp_error( $revisions ) ? $revisions['count'] : 0;
|
||||
$revisions_base = sprintf( '/%s/%s/%s/revisions', $this->namespace, $this->rest_base, $id );
|
||||
|
||||
$links['version-history'] = array(
|
||||
'href' => rest_url( $revisions_base ),
|
||||
'count' => $revisions_count,
|
||||
);
|
||||
|
||||
if ( $revisions_count > 0 ) {
|
||||
$links['predecessor-version'] = array(
|
||||
'href' => rest_url( $revisions_base . '/' . $revisions['latest_id'] ),
|
||||
'id' => $revisions['latest_id'],
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $links;
|
||||
}
|
||||
|
||||
|
||||
@@ -179,7 +179,7 @@ class WP_REST_Terms_Controller extends WP_REST_Controller {
|
||||
* @since 4.7.0
|
||||
*
|
||||
* @param WP_REST_Request $request Full details about the request.
|
||||
* @return true|WP_Error True if the request has read access, otherwise false or WP_Error object.
|
||||
* @return bool|WP_Error True if the request has read access, otherwise false or WP_Error object.
|
||||
*/
|
||||
public function get_items_permissions_check( $request ) {
|
||||
$tax_obj = get_taxonomy( $this->taxonomy );
|
||||
@@ -417,7 +417,7 @@ class WP_REST_Terms_Controller extends WP_REST_Controller {
|
||||
* @since 4.7.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, otherwise false or WP_Error object.
|
||||
* @return true|WP_Error True if the request has read access for the item, otherwise WP_Error object.
|
||||
*/
|
||||
public function get_item_permissions_check( $request ) {
|
||||
$term = $this->get_term( $request['id'] );
|
||||
|
||||
@@ -118,7 +118,7 @@ class WP_REST_Themes_Controller extends WP_REST_Controller {
|
||||
* @since 5.7.0
|
||||
*
|
||||
* @param WP_REST_Request $request Full details about the request.
|
||||
* @return bool|WP_Error True if the request has read access for the item, otherwise WP_Error object.
|
||||
* @return true|WP_Error True if the request has read access for the item, otherwise WP_Error object.
|
||||
*/
|
||||
public function get_item_permissions_check( $request ) {
|
||||
if ( current_user_can( 'switch_themes' ) || current_user_can( 'manage_network_themes' ) ) {
|
||||
@@ -144,7 +144,7 @@ class WP_REST_Themes_Controller extends WP_REST_Controller {
|
||||
*
|
||||
* @since 5.7.0
|
||||
*
|
||||
* @return bool|WP_Error Whether the theme can be read.
|
||||
* @return true|WP_Error True if the theme can be read, WP_Error object otherwise.
|
||||
*/
|
||||
protected function check_read_active_theme_permission() {
|
||||
if ( current_user_can( 'edit_posts' ) ) {
|
||||
@@ -231,9 +231,10 @@ class WP_REST_Themes_Controller extends WP_REST_Controller {
|
||||
*/
|
||||
public function prepare_item_for_response( $item, $request ) {
|
||||
// Restores the more descriptive, specific name for use within this method.
|
||||
$theme = $item;
|
||||
$data = array();
|
||||
$theme = $item;
|
||||
|
||||
$fields = $this->get_fields_for_response( $request );
|
||||
$data = array();
|
||||
|
||||
if ( rest_is_field_included( 'stylesheet', $fields ) ) {
|
||||
$data['stylesheet'] = $theme->get_stylesheet();
|
||||
|
||||
@@ -318,6 +318,9 @@ class WP_REST_Users_Controller extends WP_REST_Controller {
|
||||
}
|
||||
|
||||
if ( ! empty( $prepared_args['search'] ) ) {
|
||||
if ( ! current_user_can( 'list_users' ) ) {
|
||||
$prepared_args['search_columns'] = array( 'ID', 'user_login', 'user_nicename', 'display_name' );
|
||||
}
|
||||
$prepared_args['search'] = '*' . $prepared_args['search'] . '*';
|
||||
}
|
||||
/**
|
||||
@@ -984,9 +987,10 @@ class WP_REST_Users_Controller extends WP_REST_Controller {
|
||||
*/
|
||||
public function prepare_item_for_response( $item, $request ) {
|
||||
// Restores the more descriptive, specific name for use within this method.
|
||||
$user = $item;
|
||||
$data = array();
|
||||
$user = $item;
|
||||
|
||||
$fields = $this->get_fields_for_response( $request );
|
||||
$data = array();
|
||||
|
||||
if ( in_array( 'id', $fields, true ) ) {
|
||||
$data['id'] = $user->ID;
|
||||
|
||||
@@ -85,7 +85,7 @@ class WP_REST_Widget_Types_Controller extends WP_REST_Controller {
|
||||
'form_data' => array(
|
||||
'description' => __( 'Serialized widget form data to encode into instance settings.' ),
|
||||
'type' => 'string',
|
||||
'sanitize_callback' => static function( $form_data ) {
|
||||
'sanitize_callback' => static function ( $form_data ) {
|
||||
$array = array();
|
||||
wp_parse_str( $form_data, $array );
|
||||
return $array;
|
||||
@@ -297,8 +297,9 @@ class WP_REST_Widget_Types_Controller extends WP_REST_Controller {
|
||||
public function prepare_item_for_response( $item, $request ) {
|
||||
// Restores the more descriptive, specific name for use within this method.
|
||||
$widget_type = $item;
|
||||
$fields = $this->get_fields_for_response( $request );
|
||||
$data = array(
|
||||
|
||||
$fields = $this->get_fields_for_response( $request );
|
||||
$data = array(
|
||||
'id' => $widget_type['id'],
|
||||
);
|
||||
|
||||
|
||||
@@ -861,7 +861,7 @@ class WP_REST_Widgets_Controller extends WP_REST_Controller {
|
||||
'type' => 'string',
|
||||
'context' => array(),
|
||||
'arg_options' => array(
|
||||
'sanitize_callback' => static function( $form_data ) {
|
||||
'sanitize_callback' => static function ( $form_data ) {
|
||||
$array = array();
|
||||
wp_parse_str( $form_data, $array );
|
||||
return $array;
|
||||
|
||||
@@ -202,5 +202,4 @@ class WP_REST_Post_Search_Handler extends WP_REST_Search_Handler {
|
||||
|
||||
return rest_get_route_for_post( $post );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user