Block Editor: Move caching to endpoint for unique responses.

Now that the pattern API request includes the locale and version, the cache key needs to contain a hash of the query args.

Props ocean90, dd32, timothyblynjacobs
Fixes #53435

Built from https://develop.svn.wordpress.org/trunk@51208


git-svn-id: http://core.svn.wordpress.org/trunk@50817 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
iandunn 2021-06-22 21:24:58 +00:00
parent c94c954d02
commit 479e9847ed
3 changed files with 77 additions and 42 deletions

View File

@ -45,7 +45,11 @@ function _register_core_block_patterns_and_categories() {
} }
/** /**
* Import patterns from wordpress.org/patterns. * Register Core's official patterns from wordpress.org/patterns.
*
* @since 5.8.0
*
* @param WP_Screen $current_screen The screen that the current request was triggered from.
*/ */
function _load_remote_block_patterns( $current_screen ) { function _load_remote_block_patterns( $current_screen ) {
if ( ! $current_screen->is_block_editor ) { if ( ! $current_screen->is_block_editor ) {
@ -64,18 +68,14 @@ function _load_remote_block_patterns( $current_screen ) {
$should_load_remote = apply_filters( 'should_load_remote_block_patterns', true ); $should_load_remote = apply_filters( 'should_load_remote_block_patterns', true );
if ( $supports_core_patterns && $should_load_remote ) { if ( $supports_core_patterns && $should_load_remote ) {
$patterns = get_transient( 'wp_remote_block_patterns' ); $request = new WP_REST_Request( 'GET', '/wp/v2/pattern-directory/patterns' );
if ( ! $patterns ) { $core_keyword_id = 11; // 11 is the ID for "core".
$request = new WP_REST_Request( 'GET', '/wp/v2/pattern-directory/patterns' ); $request->set_param( 'keyword', $core_keyword_id );
$core_keyword_id = 11; // 11 is the ID for "core". $response = rest_do_request( $request );
$request->set_param( 'keyword', $core_keyword_id ); if ( $response->is_error() ) {
$response = rest_do_request( $request ); return;
if ( $response->is_error() ) {
return;
}
$patterns = $response->get_data();
set_transient( 'wp_remote_block_patterns', $patterns, HOUR_IN_SECONDS );
} }
$patterns = $response->get_data();
foreach ( $patterns as $settings ) { foreach ( $patterns as $settings ) {
$pattern_name = 'core/' . sanitize_title( $settings['title'] ); $pattern_name = 'core/' . sanitize_title( $settings['title'] );

View File

@ -111,38 +111,73 @@ class WP_REST_Pattern_Directory_Controller extends WP_REST_Controller {
$query_args['search'] = $search_term; $query_args['search'] = $search_term;
} }
$api_url = add_query_arg( /*
array_map( 'rawurlencode', $query_args ), * Include a hash of the query args, so that different requests are stored in
'http://api.wordpress.org/patterns/1.0/' * separate caches.
); *
* MD5 is chosen for its speed, low-collision rate, universal availability, and to stay
* under the character limit for `_site_transient_timeout_{...}` keys.
*
* @link https://stackoverflow.com/questions/3665247/fastest-hash-for-non-cryptographic-uses
*/
$transient_key = 'wp_remote_block_patterns_' . md5( implode( '-', $query_args ) );
if ( wp_http_supports( array( 'ssl' ) ) ) { /*
$api_url = set_url_scheme( $api_url, 'https' ); * Use network-wide transient to improve performance. The locale is the only site
} * configuration that affects the response, and it's included in the transient key.
*/
$raw_patterns = get_site_transient( $transient_key );
$wporg_response = wp_remote_get( $api_url ); if ( ! $raw_patterns ) {
$raw_patterns = json_decode( wp_remote_retrieve_body( $wporg_response ) ); $api_url = add_query_arg(
array_map( 'rawurlencode', $query_args ),
if ( is_wp_error( $wporg_response ) ) { 'http://api.wordpress.org/patterns/1.0/'
$wporg_response->add_data( array( 'status' => 500 ) );
return $wporg_response;
}
// Make sure w.org returned valid data.
if ( ! is_array( $raw_patterns ) ) {
return new WP_Error(
'pattern_api_failed',
sprintf(
/* translators: %s: Support forums URL. */
__( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;s configuration. If you continue to have problems, please try the <a href="%s">support forums</a>.' ),
__( 'https://wordpress.org/support/forums/' )
),
array(
'status' => 500,
'response' => wp_remote_retrieve_body( $wporg_response ),
)
); );
if ( wp_http_supports( array( 'ssl' ) ) ) {
$api_url = set_url_scheme( $api_url, 'https' );
}
/*
* Default to a short TTL, to mitigate cache stampedes on high-traffic sites.
* This assumes that most errors will be short-lived, e.g., packet loss that causes the
* first request to fail, but a follow-up one will succeed. The value should be high
* enough to avoid stampedes, but low enough to not interfere with users manually
* re-trying a failed request.
*/
$cache_ttl = 5;
$wporg_response = wp_remote_get( $api_url );
$raw_patterns = json_decode( wp_remote_retrieve_body( $wporg_response ) );
if ( is_wp_error( $wporg_response ) ) {
$raw_patterns = $wporg_response;
} elseif ( ! is_array( $raw_patterns ) ) {
// HTTP request succeeded, but response data is invalid.
$raw_patterns = new WP_Error(
'pattern_api_failed',
sprintf(
/* translators: %s: Support forums URL. */
__( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;s configuration. If you continue to have problems, please try the <a href="%s">support forums</a>.' ),
__( 'https://wordpress.org/support/forums/' )
),
array(
'response' => wp_remote_retrieve_body( $wporg_response ),
)
);
} else {
// Response has valid data.
$cache_ttl = HOUR_IN_SECONDS;
}
set_site_transient( $transient_key, $raw_patterns, $cache_ttl );
}
if ( is_wp_error( $raw_patterns ) ) {
$raw_patterns->add_data( array( 'status' => 500 ) );
return $raw_patterns;
} }
$response = array(); $response = array();

View File

@ -13,7 +13,7 @@
* *
* @global string $wp_version * @global string $wp_version
*/ */
$wp_version = '5.8-beta2-51207'; $wp_version = '5.8-beta2-51208';
/** /**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema. * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.