plugin updates
This commit is contained in:
@@ -165,7 +165,7 @@ class WP_REST_Request implements ArrayAccess {
|
||||
* Canonicalizes the header name.
|
||||
*
|
||||
* Ensures that header names are always treated the same regardless of
|
||||
* source. Header names are always case insensitive.
|
||||
* source. Header names are always case-insensitive.
|
||||
*
|
||||
* Note that we treat `-` (dashes) and `_` (underscores) as the same
|
||||
* character, as per header parsing rules in both Apache and nginx.
|
||||
@@ -709,7 +709,7 @@ class WP_REST_Request implements ArrayAccess {
|
||||
* Parses the request body parameters.
|
||||
*
|
||||
* Parses out URL-encoded bodies for request methods that aren't supported
|
||||
* natively by PHP. In PHP 5.x, only POST has these parsed automatically.
|
||||
* natively by PHP.
|
||||
*
|
||||
* @since 4.4.0
|
||||
*/
|
||||
|
||||
@@ -636,13 +636,75 @@ class WP_REST_Server {
|
||||
foreach ( $items as $item ) {
|
||||
$attributes = $item['attributes'];
|
||||
$attributes['href'] = $item['href'];
|
||||
$data[ $rel ][] = $attributes;
|
||||
|
||||
if ( 'self' !== $rel ) {
|
||||
$data[ $rel ][] = $attributes;
|
||||
continue;
|
||||
}
|
||||
|
||||
$target_hints = self::get_target_hints_for_link( $attributes );
|
||||
if ( $target_hints ) {
|
||||
$attributes['targetHints'] = $target_hints;
|
||||
}
|
||||
|
||||
$data[ $rel ][] = $attributes;
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the target links for a REST API Link.
|
||||
*
|
||||
* @since 6.7.0
|
||||
*
|
||||
* @param array $link
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
protected static function get_target_hints_for_link( $link ) {
|
||||
// Prefer targetHints that were specifically designated by the developer.
|
||||
if ( isset( $link['targetHints']['allow'] ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$request = WP_REST_Request::from_url( $link['href'] );
|
||||
if ( ! $request ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$server = rest_get_server();
|
||||
$match = $server->match_request_to_handler( $request );
|
||||
|
||||
if ( is_wp_error( $match ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ( is_wp_error( $request->has_valid_params() ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ( is_wp_error( $request->sanitize_params() ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$target_hints = array();
|
||||
|
||||
$response = new WP_REST_Response();
|
||||
$response->set_matched_route( $match[0] );
|
||||
$response->set_matched_handler( $match[1] );
|
||||
$headers = rest_send_allow_header( $response, $server, $request )->get_headers();
|
||||
|
||||
foreach ( $headers as $name => $value ) {
|
||||
$name = WP_REST_Request::canonicalize_header_name( $name );
|
||||
|
||||
$target_hints[ $name ] = array_map( 'trim', explode( ',', $value ) );
|
||||
}
|
||||
|
||||
return $target_hints;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the CURIEs (compact URIs) used for relations.
|
||||
*
|
||||
@@ -1667,7 +1729,7 @@ class WP_REST_Server {
|
||||
$single_request = new WP_REST_Request( isset( $args['method'] ) ? $args['method'] : 'POST', $parsed_url['path'] );
|
||||
|
||||
if ( ! empty( $parsed_url['query'] ) ) {
|
||||
$query_args = null; // Satisfy linter.
|
||||
$query_args = array();
|
||||
wp_parse_str( $parsed_url['query'], $query_args );
|
||||
$single_request->set_query_params( $query_args );
|
||||
}
|
||||
|
||||
@@ -339,8 +339,7 @@ class WP_REST_Attachments_Controller extends WP_REST_Posts_Controller {
|
||||
*
|
||||
* @since 4.7.0
|
||||
*
|
||||
* @param WP_Post $attachment Inserted or updated attachment
|
||||
* object.
|
||||
* @param WP_Post $attachment Inserted or updated attachment object.
|
||||
* @param WP_REST_Request $request The request sent to the API.
|
||||
* @param bool $creating True when creating an attachment, false when updating.
|
||||
*/
|
||||
@@ -450,7 +449,7 @@ class WP_REST_Attachments_Controller extends WP_REST_Posts_Controller {
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs post processing on an attachment.
|
||||
* Performs post-processing on an attachment.
|
||||
*
|
||||
* @since 5.3.0
|
||||
*
|
||||
@@ -471,7 +470,7 @@ class WP_REST_Attachments_Controller extends WP_REST_Posts_Controller {
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a given request can perform post processing on an attachment.
|
||||
* Checks if a given request can perform post-processing on an attachment.
|
||||
*
|
||||
* @since 5.3.0
|
||||
*
|
||||
@@ -531,7 +530,7 @@ class WP_REST_Attachments_Controller extends WP_REST_Posts_Controller {
|
||||
);
|
||||
}
|
||||
|
||||
$supported_types = array( 'image/jpeg', 'image/png', 'image/gif', 'image/webp', 'image/avif' );
|
||||
$supported_types = array( 'image/jpeg', 'image/png', 'image/gif', 'image/webp', 'image/avif', 'image/heic' );
|
||||
$mime_type = get_post_mime_type( $attachment_id );
|
||||
if ( ! in_array( $mime_type, $supported_types, true ) ) {
|
||||
return new WP_Error(
|
||||
@@ -601,7 +600,7 @@ class WP_REST_Attachments_Controller extends WP_REST_Posts_Controller {
|
||||
$args = $modifier['args'];
|
||||
switch ( $modifier['type'] ) {
|
||||
case 'rotate':
|
||||
// Rotation direction: clockwise vs. counter clockwise.
|
||||
// Rotation direction: clockwise vs. counterclockwise.
|
||||
$rotate = 0 - $args['angle'];
|
||||
|
||||
if ( 0 !== $rotate ) {
|
||||
@@ -661,7 +660,7 @@ class WP_REST_Attachments_Controller extends WP_REST_Posts_Controller {
|
||||
|
||||
$filename = "{$image_name}.{$image_ext}";
|
||||
|
||||
// Create the uploads sub-directory if needed.
|
||||
// Create the uploads subdirectory if needed.
|
||||
$uploads = wp_upload_dir();
|
||||
|
||||
// Make the file name unique in the (new) upload directory.
|
||||
@@ -1207,7 +1206,7 @@ class WP_REST_Attachments_Controller extends WP_REST_Posts_Controller {
|
||||
continue;
|
||||
}
|
||||
|
||||
list( $type, $attr_parts ) = explode( ';', $value, 2 );
|
||||
list( , $attr_parts ) = explode( ';', $value, 2 );
|
||||
|
||||
$attr_parts = explode( ';', $attr_parts );
|
||||
$attributes = array();
|
||||
|
||||
@@ -78,7 +78,7 @@ class WP_REST_Block_Pattern_Categories_Controller extends WP_REST_Controller {
|
||||
* @since 6.0.0
|
||||
*
|
||||
* @param WP_REST_Request $request Full details about the request.
|
||||
* @return WP_Error|WP_REST_Response Response object on success, or WP_Error object on failure.
|
||||
* @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
|
||||
*/
|
||||
public function get_items( $request ) {
|
||||
$response = array();
|
||||
|
||||
@@ -141,7 +141,7 @@ class WP_REST_Block_Types_Controller extends WP_REST_Controller {
|
||||
$namespace = $request['namespace'];
|
||||
}
|
||||
|
||||
foreach ( $block_types as $slug => $obj ) {
|
||||
foreach ( $block_types as $obj ) {
|
||||
if ( $namespace ) {
|
||||
list ( $block_namespace ) = explode( '/', $obj->name );
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ class WP_REST_Edit_Site_Export_Controller extends WP_REST_Controller {
|
||||
*
|
||||
* @since 5.9.0
|
||||
*
|
||||
* @return WP_Error|true True if the request has access, or WP_Error object.
|
||||
* @return true|WP_Error True if the request has access, or WP_Error object.
|
||||
*/
|
||||
public function permissions_check() {
|
||||
if ( current_user_can( 'edit_theme_options' ) ) {
|
||||
@@ -70,7 +70,7 @@ class WP_REST_Edit_Site_Export_Controller extends WP_REST_Controller {
|
||||
*
|
||||
* @since 5.9.0
|
||||
*
|
||||
* @return WP_Error|void
|
||||
* @return void|WP_Error
|
||||
*/
|
||||
public function export() {
|
||||
// Generate the export file.
|
||||
|
||||
@@ -327,10 +327,12 @@ class WP_REST_Global_Styles_Controller extends WP_REST_Posts_Controller {
|
||||
}
|
||||
if ( rest_is_field_included( 'title.rendered', $fields ) ) {
|
||||
add_filter( 'protected_title_format', array( $this, 'protected_title_format' ) );
|
||||
add_filter( 'private_title_format', array( $this, 'protected_title_format' ) );
|
||||
|
||||
$data['title']['rendered'] = get_the_title( $post->ID );
|
||||
|
||||
remove_filter( 'protected_title_format', array( $this, 'protected_title_format' ) );
|
||||
remove_filter( 'private_title_format', array( $this, 'protected_title_format' ) );
|
||||
}
|
||||
|
||||
if ( rest_is_field_included( 'settings', $fields ) ) {
|
||||
@@ -507,26 +509,40 @@ class WP_REST_Global_Styles_Controller extends WP_REST_Posts_Controller {
|
||||
* Checks if a given request has access to read a single theme global styles config.
|
||||
*
|
||||
* @since 5.9.0
|
||||
* @since 6.7.0 Allow users with edit post capabilities to view theme global styles.
|
||||
*
|
||||
* @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_item_permissions_check( $request ) {
|
||||
/*
|
||||
* Verify if the current user has edit_theme_options capability.
|
||||
* This capability is required to edit/view/delete templates.
|
||||
* Verify if the current user has edit_posts capability.
|
||||
* This capability is required to view global styles.
|
||||
*/
|
||||
if ( ! current_user_can( 'edit_theme_options' ) ) {
|
||||
return new WP_Error(
|
||||
'rest_cannot_manage_global_styles',
|
||||
__( 'Sorry, you are not allowed to access the global styles on this site.' ),
|
||||
array(
|
||||
'status' => rest_authorization_required_code(),
|
||||
)
|
||||
);
|
||||
if ( current_user_can( 'edit_posts' ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
foreach ( get_post_types( array( 'show_in_rest' => true ), 'objects' ) as $post_type ) {
|
||||
if ( current_user_can( $post_type->cap->edit_posts ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify if the current user has edit_theme_options capability.
|
||||
*/
|
||||
if ( current_user_can( 'edit_theme_options' ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return new WP_Error(
|
||||
'rest_cannot_read_global_styles',
|
||||
__( 'Sorry, you are not allowed to access the global styles on this site.' ),
|
||||
array(
|
||||
'status' => rest_authorization_required_code(),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -587,26 +603,13 @@ class WP_REST_Global_Styles_Controller extends WP_REST_Posts_Controller {
|
||||
* Checks if a given request has access to read a single theme global styles config.
|
||||
*
|
||||
* @since 6.0.0
|
||||
* @since 6.7.0 Allow users with edit post capabilities to view theme global styles.
|
||||
*
|
||||
* @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 ) {
|
||||
/*
|
||||
* Verify if the current user has edit_theme_options capability.
|
||||
* This capability is required to edit/view/delete templates.
|
||||
*/
|
||||
if ( ! current_user_can( 'edit_theme_options' ) ) {
|
||||
return new WP_Error(
|
||||
'rest_cannot_manage_global_styles',
|
||||
__( 'Sorry, you are not allowed to access the global styles on this site.' ),
|
||||
array(
|
||||
'status' => rest_authorization_required_code(),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
return $this->get_theme_item_permissions_check( $request );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -630,7 +633,7 @@ class WP_REST_Global_Styles_Controller extends WP_REST_Posts_Controller {
|
||||
);
|
||||
}
|
||||
|
||||
$response = array();
|
||||
$response = array();
|
||||
|
||||
// Register theme-defined variations e.g. from block style variation partials under `/styles`.
|
||||
$partials = WP_Theme_JSON_Resolver::get_style_variations( 'block' );
|
||||
|
||||
@@ -102,7 +102,7 @@ class WP_REST_Menu_Items_Controller extends WP_REST_Posts_Controller {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a single post.
|
||||
* Creates a single nav menu item.
|
||||
*
|
||||
* @since 5.9.0
|
||||
*
|
||||
@@ -267,7 +267,7 @@ class WP_REST_Menu_Items_Controller extends WP_REST_Posts_Controller {
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a single menu item.
|
||||
* Deletes a single nav menu item.
|
||||
*
|
||||
* @since 5.9.0
|
||||
*
|
||||
@@ -317,7 +317,7 @@ class WP_REST_Menu_Items_Controller extends WP_REST_Posts_Controller {
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares a single post for create or update.
|
||||
* Prepares a single nav menu item for create or update.
|
||||
*
|
||||
* @since 5.9.0
|
||||
*
|
||||
@@ -482,7 +482,7 @@ class WP_REST_Menu_Items_Controller extends WP_REST_Posts_Controller {
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares a single post output for response.
|
||||
* Prepares a single nav menu item output for response.
|
||||
*
|
||||
* @since 5.9.0
|
||||
*
|
||||
@@ -510,6 +510,7 @@ class WP_REST_Menu_Items_Controller extends WP_REST_Posts_Controller {
|
||||
|
||||
if ( rest_is_field_included( 'title.rendered', $fields ) ) {
|
||||
add_filter( 'protected_title_format', array( $this, 'protected_title_format' ) );
|
||||
add_filter( 'private_title_format', array( $this, 'protected_title_format' ) );
|
||||
|
||||
/** This filter is documented in wp-includes/post-template.php */
|
||||
$title = apply_filters( 'the_title', $menu_item->title, $menu_item->ID );
|
||||
@@ -517,6 +518,7 @@ class WP_REST_Menu_Items_Controller extends WP_REST_Posts_Controller {
|
||||
$data['title']['rendered'] = $title;
|
||||
|
||||
remove_filter( 'protected_title_format', array( $this, 'protected_title_format' ) );
|
||||
remove_filter( 'private_title_format', array( $this, 'protected_title_format' ) );
|
||||
}
|
||||
|
||||
if ( rest_is_field_included( 'status', $fields ) ) {
|
||||
@@ -676,7 +678,7 @@ class WP_REST_Menu_Items_Controller extends WP_REST_Posts_Controller {
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves Link Description Objects that should be added to the Schema for the posts collection.
|
||||
* Retrieves Link Description Objects that should be added to the Schema for the nav menu items collection.
|
||||
*
|
||||
* @since 5.9.0
|
||||
*
|
||||
@@ -703,7 +705,7 @@ class WP_REST_Menu_Items_Controller extends WP_REST_Posts_Controller {
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the term's schema, conforming to JSON Schema.
|
||||
* Retrieves the nav menu item's schema, conforming to JSON Schema.
|
||||
*
|
||||
* @since 5.9.0
|
||||
*
|
||||
@@ -924,7 +926,7 @@ class WP_REST_Menu_Items_Controller extends WP_REST_Posts_Controller {
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the query params for the posts collection.
|
||||
* Retrieves the query params for the nav menu items collection.
|
||||
*
|
||||
* @since 5.9.0
|
||||
*
|
||||
|
||||
@@ -77,7 +77,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, WP_Error object otherwise.
|
||||
* @return true|WP_Error True if the request has read access, WP_Error object otherwise.
|
||||
*/
|
||||
public function get_items_permissions_check( $request ) {
|
||||
if ( ! current_user_can( 'edit_theme_options' ) ) {
|
||||
@@ -97,7 +97,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|WP_REST_Response Response object on success, or WP_Error object on failure.
|
||||
* @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
|
||||
*/
|
||||
public function get_items( $request ) {
|
||||
$data = array();
|
||||
@@ -140,7 +140,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|WP_REST_Response Response object on success, or WP_Error object on failure.
|
||||
* @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
|
||||
*/
|
||||
public function get_item( $request ) {
|
||||
$registered_menus = get_registered_nav_menus();
|
||||
|
||||
@@ -87,13 +87,6 @@ class WP_REST_Pattern_Directory_Controller extends WP_REST_Controller {
|
||||
* @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
|
||||
*/
|
||||
public function get_items( $request ) {
|
||||
/*
|
||||
* Include an unmodified `$wp_version`, so the API can craft a response that's tailored to
|
||||
* it. Some plugins modify the version in a misguided attempt to improve security by
|
||||
* obscuring the version, which can cause invalid requests.
|
||||
*/
|
||||
require ABSPATH . WPINC . '/version.php';
|
||||
|
||||
$valid_query_args = array(
|
||||
'offset' => true,
|
||||
'order' => true,
|
||||
@@ -106,7 +99,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;
|
||||
$query_args['wp-version'] = wp_get_wp_version();
|
||||
$query_args['pattern-categories'] = isset( $request['category'] ) ? $request['category'] : false;
|
||||
$query_args['pattern-keywords'] = isset( $request['keyword'] ) ? $request['keyword'] : false;
|
||||
|
||||
@@ -376,7 +369,7 @@ class WP_REST_Pattern_Directory_Controller extends WP_REST_Controller {
|
||||
return apply_filters( 'rest_pattern_directory_collection_params', $query_params );
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* Include a hash of the query args, so that different requests are stored in
|
||||
* separate caches.
|
||||
*
|
||||
|
||||
@@ -913,7 +913,7 @@ class WP_REST_Plugins_Controller extends WP_REST_Controller {
|
||||
),
|
||||
'author' => array(
|
||||
'description' => __( 'The plugin author.' ),
|
||||
'type' => 'object',
|
||||
'type' => 'string',
|
||||
'readonly' => true,
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
|
||||
@@ -113,7 +113,7 @@ class WP_REST_Post_Statuses_Controller extends WP_REST_Controller {
|
||||
$statuses = get_post_stati( array( 'internal' => false ), 'object' );
|
||||
$statuses['trash'] = get_post_status_object( 'trash' );
|
||||
|
||||
foreach ( $statuses as $slug => $obj ) {
|
||||
foreach ( $statuses as $obj ) {
|
||||
$ret = $this->check_read_permission( $obj );
|
||||
|
||||
if ( ! $ret ) {
|
||||
|
||||
@@ -183,7 +183,7 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
||||
*
|
||||
* @param bool $required Whether the post requires a password check.
|
||||
* @param WP_Post $post The post been password checked.
|
||||
* @return bool Result of password check taking in to account REST API considerations.
|
||||
* @return bool Result of password check taking into account REST API considerations.
|
||||
*/
|
||||
public function check_password_required( $required, $post ) {
|
||||
if ( ! $required ) {
|
||||
@@ -337,8 +337,68 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
isset( $registered['search_semantics'], $request['search_semantics'] )
|
||||
&& 'exact' === $request['search_semantics']
|
||||
) {
|
||||
$args['exact'] = true;
|
||||
}
|
||||
|
||||
$args = $this->prepare_tax_query( $args, $request );
|
||||
|
||||
if ( ! empty( $request['format'] ) ) {
|
||||
$formats = $request['format'];
|
||||
/*
|
||||
* The relation needs to be set to `OR` since the request can contain
|
||||
* two separate conditions. The user may be querying for items that have
|
||||
* either the `standard` format or a specific format.
|
||||
*/
|
||||
$formats_query = array( 'relation' => 'OR' );
|
||||
|
||||
/*
|
||||
* The default post format, `standard`, is not stored in the database.
|
||||
* If `standard` is part of the request, the query needs to exclude all post items that
|
||||
* have a format assigned.
|
||||
*/
|
||||
if ( in_array( 'standard', $formats, true ) ) {
|
||||
$formats_query[] = array(
|
||||
'taxonomy' => 'post_format',
|
||||
'field' => 'slug',
|
||||
'operator' => 'NOT EXISTS',
|
||||
);
|
||||
// Remove the `standard` format, since it cannot be queried.
|
||||
unset( $formats[ array_search( 'standard', $formats, true ) ] );
|
||||
}
|
||||
|
||||
// Add any remaining formats to the formats query.
|
||||
if ( ! empty( $formats ) ) {
|
||||
// Add the `post-format-` prefix.
|
||||
$terms = array_map(
|
||||
static function ( $format ) {
|
||||
return "post-format-$format";
|
||||
},
|
||||
$formats
|
||||
);
|
||||
|
||||
$formats_query[] = array(
|
||||
'taxonomy' => 'post_format',
|
||||
'field' => 'slug',
|
||||
'terms' => $terms,
|
||||
'operator' => 'IN',
|
||||
);
|
||||
}
|
||||
|
||||
// Enable filtering by both post formats and other taxonomies by combining them with `AND`.
|
||||
if ( isset( $args['tax_query'] ) ) {
|
||||
$args['tax_query'][] = array(
|
||||
'relation' => 'AND',
|
||||
$formats_query,
|
||||
);
|
||||
} else {
|
||||
$args['tax_query'] = $formats_query;
|
||||
}
|
||||
}
|
||||
|
||||
// Force the post_type argument, since it's not a user input variable.
|
||||
$args['post_type'] = $this->post_type;
|
||||
|
||||
@@ -497,9 +557,9 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
||||
);
|
||||
}
|
||||
|
||||
if ( $post && ! empty( $request['password'] ) ) {
|
||||
if ( $post && ! empty( $request->get_query_params()['password'] ) ) {
|
||||
// Check post password, and return error if invalid.
|
||||
if ( ! hash_equals( $post->post_password, $request['password'] ) ) {
|
||||
if ( ! hash_equals( $post->post_password, $request->get_query_params()['password'] ) ) {
|
||||
return new WP_Error(
|
||||
'rest_post_incorrect_password',
|
||||
__( 'Incorrect post password.' ),
|
||||
@@ -1809,7 +1869,7 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
||||
* with the site's timezone offset applied.
|
||||
*/
|
||||
if ( '0000-00-00 00:00:00' === $post->post_modified_gmt ) {
|
||||
$post_modified_gmt = gmdate( 'Y-m-d H:i:s', strtotime( $post->post_modified ) - ( get_option( 'gmt_offset' ) * HOUR_IN_SECONDS ) );
|
||||
$post_modified_gmt = gmdate( 'Y-m-d H:i:s', strtotime( $post->post_modified ) - (int) ( (float) get_option( 'gmt_offset' ) * HOUR_IN_SECONDS ) );
|
||||
} else {
|
||||
$post_modified_gmt = $post->post_modified_gmt;
|
||||
}
|
||||
@@ -1844,10 +1904,12 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
||||
}
|
||||
if ( rest_is_field_included( 'title.rendered', $fields ) ) {
|
||||
add_filter( 'protected_title_format', array( $this, 'protected_title_format' ) );
|
||||
add_filter( 'private_title_format', array( $this, 'protected_title_format' ) );
|
||||
|
||||
$data['title']['rendered'] = get_the_title( $post->ID );
|
||||
|
||||
remove_filter( 'protected_title_format', array( $this, 'protected_title_format' ) );
|
||||
remove_filter( 'private_title_format', array( $this, 'protected_title_format' ) );
|
||||
}
|
||||
|
||||
$has_password_filter = false;
|
||||
@@ -2047,15 +2109,15 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
||||
}
|
||||
|
||||
/**
|
||||
* Overwrites the default protected title format.
|
||||
* Overwrites the default protected and private title format.
|
||||
*
|
||||
* By default, WordPress will show password protected posts with a title of
|
||||
* "Protected: %s", as the REST API communicates the protected status of a post
|
||||
* in a machine readable format, we remove the "Protected: " prefix.
|
||||
* By default, WordPress will show password protected or private posts with a title of
|
||||
* "Protected: %s" or "Private: %s", as the REST API communicates the status of a post
|
||||
* in a machine-readable format, we remove the prefix.
|
||||
*
|
||||
* @since 4.7.0
|
||||
*
|
||||
* @return string Protected title format.
|
||||
* @return string Title format.
|
||||
*/
|
||||
public function protected_title_format() {
|
||||
return '%s';
|
||||
@@ -2884,6 +2946,12 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
||||
);
|
||||
}
|
||||
|
||||
$query_params['search_semantics'] = array(
|
||||
'description' => __( 'How to interpret the search input.' ),
|
||||
'type' => 'string',
|
||||
'enum' => array( 'exact' ),
|
||||
);
|
||||
|
||||
$query_params['offset'] = array(
|
||||
'description' => __( 'Offset the result set by a specific number of items.' ),
|
||||
'type' => 'integer',
|
||||
@@ -2977,6 +3045,18 @@ class WP_REST_Posts_Controller extends WP_REST_Controller {
|
||||
);
|
||||
}
|
||||
|
||||
if ( post_type_supports( $this->post_type, 'post-formats' ) ) {
|
||||
$query_params['format'] = array(
|
||||
'description' => __( 'Limit result set to items assigned one or more given formats.' ),
|
||||
'type' => 'array',
|
||||
'uniqueItems' => true,
|
||||
'items' => array(
|
||||
'enum' => array_values( get_post_format_slugs() ),
|
||||
'type' => 'string',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters collection parameters for the posts controller.
|
||||
*
|
||||
|
||||
@@ -149,7 +149,7 @@ class WP_REST_Taxonomies_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 bool|WP_Error True if the request has read access for the item, otherwise false or WP_Error object.
|
||||
*/
|
||||
public function get_item_permissions_check( $request ) {
|
||||
|
||||
|
||||
@@ -326,7 +326,7 @@ class WP_REST_Templates_Controller extends WP_REST_Controller {
|
||||
* @return WP_REST_Response|WP_Error
|
||||
*/
|
||||
public function get_item( $request ) {
|
||||
if ( isset( $request['source'] ) && 'theme' === $request['source'] ) {
|
||||
if ( isset( $request['source'] ) && ( 'theme' === $request['source'] || 'plugin' === $request['source'] ) ) {
|
||||
$template = get_block_file_template( $request['id'], $this->post_type );
|
||||
} else {
|
||||
$template = get_block_template( $request['id'], $this->post_type );
|
||||
@@ -668,8 +668,10 @@ class WP_REST_Templates_Controller extends WP_REST_Controller {
|
||||
* @return WP_REST_Response Response object.
|
||||
*/
|
||||
public function prepare_item_for_response( $item, $request ) {
|
||||
// Resolve pattern blocks so they don't need to be resolved client-side
|
||||
// in the editor, improving performance.
|
||||
/*
|
||||
* Resolve pattern blocks so they don't need to be resolved client-side
|
||||
* in the editor, improving performance.
|
||||
*/
|
||||
$blocks = parse_blocks( $item->content );
|
||||
$blocks = resolve_pattern_blocks( $blocks );
|
||||
$item->content = serialize_blocks( $blocks );
|
||||
@@ -774,6 +776,13 @@ class WP_REST_Templates_Controller extends WP_REST_Controller {
|
||||
$data['original_source'] = self::get_wp_templates_original_source_field( $template );
|
||||
}
|
||||
|
||||
if ( rest_is_field_included( 'plugin', $fields ) ) {
|
||||
$registered_template = WP_Block_Templates_Registry::get_instance()->get_by_slug( $template->slug );
|
||||
if ( $registered_template ) {
|
||||
$data['plugin'] = $registered_template->plugin;
|
||||
}
|
||||
}
|
||||
|
||||
$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
|
||||
$data = $this->add_additional_fields_to_object( $data, $request );
|
||||
$data = $this->filter_response_by_context( $data, $context );
|
||||
@@ -806,11 +815,13 @@ class WP_REST_Templates_Controller extends WP_REST_Controller {
|
||||
*/
|
||||
private static function get_wp_templates_original_source_field( $template_object ) {
|
||||
if ( 'wp_template' === $template_object->type || 'wp_template_part' === $template_object->type ) {
|
||||
// Added by theme.
|
||||
// Template originally provided by a theme, but customized by a user.
|
||||
// Templates originally didn't have the 'origin' field so identify
|
||||
// older customized templates by checking for no origin and a 'theme'
|
||||
// or 'custom' source.
|
||||
/*
|
||||
* Added by theme.
|
||||
* Template originally provided by a theme, but customized by a user.
|
||||
* Templates originally didn't have the 'origin' field so identify
|
||||
* older customized templates by checking for no origin and a 'theme'
|
||||
* or 'custom' source.
|
||||
*/
|
||||
if ( $template_object->has_theme_file &&
|
||||
( 'theme' === $template_object->origin || (
|
||||
empty( $template_object->origin ) && in_array(
|
||||
@@ -827,14 +838,16 @@ class WP_REST_Templates_Controller extends WP_REST_Controller {
|
||||
}
|
||||
|
||||
// Added by plugin.
|
||||
if ( $template_object->has_theme_file && 'plugin' === $template_object->origin ) {
|
||||
if ( 'plugin' === $template_object->origin ) {
|
||||
return 'plugin';
|
||||
}
|
||||
|
||||
// Added by site.
|
||||
// Template was created from scratch, but has no author. Author support
|
||||
// was only added to templates in WordPress 5.9. Fallback to showing the
|
||||
// site logo and title.
|
||||
/*
|
||||
* Added by site.
|
||||
* Template was created from scratch, but has no author. Author support
|
||||
* was only added to templates in WordPress 5.9. Fallback to showing the
|
||||
* site logo and title.
|
||||
*/
|
||||
if ( empty( $template_object->has_theme_file ) && 'custom' === $template_object->source && empty( $template_object->author ) ) {
|
||||
return 'site';
|
||||
}
|
||||
@@ -859,9 +872,41 @@ class WP_REST_Templates_Controller extends WP_REST_Controller {
|
||||
$theme_name = wp_get_theme( $template_object->theme )->get( 'Name' );
|
||||
return empty( $theme_name ) ? $template_object->theme : $theme_name;
|
||||
case 'plugin':
|
||||
$plugins = get_plugins();
|
||||
$plugin = $plugins[ plugin_basename( sanitize_text_field( $template_object->theme . '.php' ) ) ];
|
||||
return empty( $plugin['Name'] ) ? $template_object->theme : $plugin['Name'];
|
||||
if ( ! function_exists( 'get_plugins' ) || ! function_exists( 'get_plugin_data' ) ) {
|
||||
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
||||
}
|
||||
if ( isset( $template_object->plugin ) ) {
|
||||
$plugins = wp_get_active_and_valid_plugins();
|
||||
|
||||
foreach ( $plugins as $plugin_file ) {
|
||||
$plugin_basename = plugin_basename( $plugin_file );
|
||||
// Split basename by '/' to get the plugin slug.
|
||||
list( $plugin_slug, ) = explode( '/', $plugin_basename );
|
||||
|
||||
if ( $plugin_slug === $template_object->plugin ) {
|
||||
$plugin_data = get_plugin_data( $plugin_file );
|
||||
|
||||
if ( ! empty( $plugin_data['Name'] ) ) {
|
||||
return $plugin_data['Name'];
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Fall back to the theme name if the plugin is not defined. That's needed to keep backwards
|
||||
* compatibility with templates that were registered before the plugin attribute was added.
|
||||
*/
|
||||
$plugins = get_plugins();
|
||||
$plugin_basename = plugin_basename( sanitize_text_field( $template_object->theme . '.php' ) );
|
||||
if ( isset( $plugins[ $plugin_basename ] ) && isset( $plugins[ $plugin_basename ]['Name'] ) ) {
|
||||
return $plugins[ $plugin_basename ]['Name'];
|
||||
}
|
||||
return isset( $template_object->plugin ) ?
|
||||
$template_object->plugin :
|
||||
$template_object->theme;
|
||||
case 'site':
|
||||
return get_bloginfo( 'name' );
|
||||
case 'user':
|
||||
@@ -871,6 +916,9 @@ class WP_REST_Templates_Controller extends WP_REST_Controller {
|
||||
}
|
||||
return $author->get( 'display_name' );
|
||||
}
|
||||
|
||||
// Fail-safe to return a string should the original source ever fall through.
|
||||
return '';
|
||||
}
|
||||
|
||||
|
||||
@@ -1125,6 +1173,12 @@ class WP_REST_Templates_Controller extends WP_REST_Controller {
|
||||
'context' => array( 'embed', 'view', 'edit' ),
|
||||
'readonly' => true,
|
||||
);
|
||||
$schema['properties']['plugin'] = array(
|
||||
'type' => 'string',
|
||||
'description' => __( 'Plugin that registered the template.' ),
|
||||
'readonly' => true,
|
||||
'context' => array( 'view', 'edit', 'embed' ),
|
||||
);
|
||||
}
|
||||
|
||||
if ( 'wp_template_part' === $this->post_type ) {
|
||||
|
||||
@@ -164,7 +164,7 @@ class WP_REST_Terms_Controller extends WP_REST_Controller {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Otherwise grant access if the post is readable by the logged in user.
|
||||
// Otherwise grant access if the post is readable by the logged-in user.
|
||||
if ( current_user_can( 'read_post', $post->ID ) ) {
|
||||
return true;
|
||||
}
|
||||
@@ -462,7 +462,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 access to create items, false or WP_Error object otherwise.
|
||||
* @return bool|WP_Error True if the request has access to create items, otherwise false or WP_Error object.
|
||||
*/
|
||||
public function create_item_permissions_check( $request ) {
|
||||
|
||||
|
||||
@@ -201,7 +201,7 @@ class WP_REST_Themes_Controller extends WP_REST_Controller {
|
||||
$current_theme = wp_get_theme();
|
||||
$status = $request['status'];
|
||||
|
||||
foreach ( $active_themes as $theme_name => $theme ) {
|
||||
foreach ( $active_themes as $theme ) {
|
||||
$theme_status = ( $this->is_same_theme( $theme, $current_theme ) ) ? 'active' : 'inactive';
|
||||
if ( is_array( $status ) && ! in_array( $theme_status, $status, true ) ) {
|
||||
continue;
|
||||
|
||||
@@ -192,7 +192,7 @@ class WP_REST_URL_Details_Controller extends WP_REST_Controller {
|
||||
*
|
||||
* @since 5.9.0
|
||||
*
|
||||
* @return WP_Error|bool True if the request has permission, else WP_Error.
|
||||
* @return true|WP_Error True if the request has permission, else WP_Error.
|
||||
*/
|
||||
public function permissions_check() {
|
||||
if ( current_user_can( 'edit_posts' ) ) {
|
||||
@@ -347,7 +347,7 @@ class WP_REST_URL_Details_Controller extends WP_REST_Controller {
|
||||
* @since 5.9.0
|
||||
*
|
||||
* @param array $meta_elements {
|
||||
* A multi-dimensional indexed array on success, else empty array.
|
||||
* A multidimensional indexed array on success, else empty array.
|
||||
*
|
||||
* @type string[] $0 Meta elements with a content attribute.
|
||||
* @type string[] $1 Content attribute's opening quotation mark.
|
||||
@@ -383,7 +383,7 @@ class WP_REST_URL_Details_Controller extends WP_REST_Controller {
|
||||
* @since 5.9.0
|
||||
*
|
||||
* @param array $meta_elements {
|
||||
* A multi-dimensional indexed array on success, else empty array.
|
||||
* A multidimensional indexed array on success, else empty array.
|
||||
*
|
||||
* @type string[] $0 Meta elements with a content attribute.
|
||||
* @type string[] $1 Content attribute's opening quotation mark.
|
||||
@@ -525,7 +525,7 @@ class WP_REST_URL_Details_Controller extends WP_REST_Controller {
|
||||
*
|
||||
* @param string $html The string of HTML to be parsed.
|
||||
* @return array {
|
||||
* A multi-dimensional indexed array on success, else empty array.
|
||||
* A multidimensional indexed array on success, else empty array.
|
||||
*
|
||||
* @type string[] $0 Meta elements with a content attribute.
|
||||
* @type string[] $1 Content attribute's opening quotation mark.
|
||||
@@ -588,7 +588,7 @@ class WP_REST_URL_Details_Controller extends WP_REST_Controller {
|
||||
|
||||
/*
|
||||
* These are the options:
|
||||
* - i : case insensitive
|
||||
* - i : case-insensitive
|
||||
* - s : allows newline characters for the . match (needed for multiline elements)
|
||||
* - U means non-greedy matching
|
||||
*/
|
||||
@@ -637,7 +637,7 @@ class WP_REST_URL_Details_Controller extends WP_REST_Controller {
|
||||
|
||||
/*
|
||||
* These are the options:
|
||||
* - i : case insensitive
|
||||
* - i : case-insensitive
|
||||
* - s : allows newline characters for the . match (needed for multiline elements)
|
||||
* - U means non-greedy matching
|
||||
*/
|
||||
|
||||
@@ -133,7 +133,7 @@ class WP_REST_Widgets_Controller extends WP_REST_Controller {
|
||||
* @since 5.8.0
|
||||
*
|
||||
* @param WP_REST_Request $request Full details about the request.
|
||||
* @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
|
||||
* @return WP_REST_Response Response object.
|
||||
*/
|
||||
public function get_items( $request ) {
|
||||
$this->retrieve_widgets();
|
||||
|
||||
@@ -268,6 +268,7 @@ abstract class WP_REST_Meta_Fields {
|
||||
* Alters the list of values in the database to match the list of provided values.
|
||||
*
|
||||
* @since 4.7.0
|
||||
* @since 6.7.0 Stores values into DB even if provided registered default value.
|
||||
*
|
||||
* @param int $object_id Object ID to update.
|
||||
* @param string $meta_key Key for the custom field.
|
||||
@@ -290,7 +291,7 @@ abstract class WP_REST_Meta_Fields {
|
||||
);
|
||||
}
|
||||
|
||||
$current_values = get_metadata( $meta_type, $object_id, $meta_key, false );
|
||||
$current_values = get_metadata_raw( $meta_type, $object_id, $meta_key, false );
|
||||
$subtype = get_object_subtype( $meta_type, $object_id );
|
||||
|
||||
if ( ! is_array( $current_values ) ) {
|
||||
@@ -367,6 +368,7 @@ abstract class WP_REST_Meta_Fields {
|
||||
* Updates a meta value for an object.
|
||||
*
|
||||
* @since 4.7.0
|
||||
* @since 6.7.0 Stores values into DB even if provided registered default value.
|
||||
*
|
||||
* @param int $object_id Object ID to update.
|
||||
* @param string $meta_key Key for the custom field.
|
||||
@@ -378,7 +380,7 @@ abstract class WP_REST_Meta_Fields {
|
||||
$meta_type = $this->get_meta_type();
|
||||
|
||||
// Do the exact same check for a duplicate value as in update_metadata() to avoid update_metadata() returning false.
|
||||
$old_value = get_metadata( $meta_type, $object_id, $meta_key );
|
||||
$old_value = get_metadata_raw( $meta_type, $object_id, $meta_key );
|
||||
$subtype = get_object_subtype( $meta_type, $object_id );
|
||||
|
||||
if ( is_array( $old_value ) && 1 === count( $old_value )
|
||||
@@ -476,6 +478,7 @@ abstract class WP_REST_Meta_Fields {
|
||||
|
||||
$default_schema = array(
|
||||
'type' => $default_args['type'],
|
||||
'title' => empty( $args['label'] ) ? '' : $args['label'],
|
||||
'description' => empty( $args['description'] ) ? '' : $args['description'],
|
||||
'default' => isset( $args['default'] ) ? $args['default'] : null,
|
||||
);
|
||||
|
||||
@@ -61,7 +61,7 @@ class WP_REST_Post_Format_Search_Handler extends WP_REST_Search_Handler {
|
||||
$query_args = apply_filters( 'rest_post_format_search_query', $query_args, $request );
|
||||
|
||||
$found_ids = array();
|
||||
foreach ( $format_slugs as $index => $format_slug ) {
|
||||
foreach ( $format_slugs as $format_slug ) {
|
||||
if ( ! empty( $query_args['search'] ) ) {
|
||||
$format_string = get_post_format_string( $format_slug );
|
||||
$format_slug_match = stripos( $format_slug, $query_args['search'] ) !== false;
|
||||
|
||||
@@ -132,8 +132,10 @@ class WP_REST_Post_Search_Handler extends WP_REST_Search_Handler {
|
||||
if ( in_array( WP_REST_Search_Controller::PROP_TITLE, $fields, true ) ) {
|
||||
if ( post_type_supports( $post->post_type, 'title' ) ) {
|
||||
add_filter( 'protected_title_format', array( $this, 'protected_title_format' ) );
|
||||
add_filter( 'private_title_format', array( $this, 'protected_title_format' ) );
|
||||
$data[ WP_REST_Search_Controller::PROP_TITLE ] = get_the_title( $post->ID );
|
||||
remove_filter( 'protected_title_format', array( $this, 'protected_title_format' ) );
|
||||
remove_filter( 'private_title_format', array( $this, 'protected_title_format' ) );
|
||||
} else {
|
||||
$data[ WP_REST_Search_Controller::PROP_TITLE ] = '';
|
||||
}
|
||||
@@ -183,15 +185,15 @@ class WP_REST_Post_Search_Handler extends WP_REST_Search_Handler {
|
||||
}
|
||||
|
||||
/**
|
||||
* Overwrites the default protected title format.
|
||||
* Overwrites the default protected and private title format.
|
||||
*
|
||||
* By default, WordPress will show password protected posts with a title of
|
||||
* "Protected: %s". As the REST API communicates the protected status of a post
|
||||
* in a machine readable format, we remove the "Protected: " prefix.
|
||||
* By default, WordPress will show password protected or private posts with a title of
|
||||
* "Protected: %s" or "Private: %s", as the REST API communicates the status of a post
|
||||
* in a machine-readable format, we remove the prefix.
|
||||
*
|
||||
* @since 5.0.0
|
||||
*
|
||||
* @return string Protected title format.
|
||||
* @return string Title format.
|
||||
*/
|
||||
public function protected_title_format() {
|
||||
return '%s';
|
||||
|
||||
Reference in New Issue
Block a user