mirror of
git://develop.git.wordpress.org/
synced 2025-03-20 12:00:03 +01:00
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 git-svn-id: https://develop.svn.wordpress.org/trunk@51208 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
parent
41c6786952
commit
83c7cad248
@ -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 ) {
|
||||
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 );
|
||||
|
||||
if ( $supports_core_patterns && $should_load_remote ) {
|
||||
$patterns = get_transient( 'wp_remote_block_patterns' );
|
||||
if ( ! $patterns ) {
|
||||
$request = new WP_REST_Request( 'GET', '/wp/v2/pattern-directory/patterns' );
|
||||
$core_keyword_id = 11; // 11 is the ID for "core".
|
||||
$request->set_param( 'keyword', $core_keyword_id );
|
||||
$response = rest_do_request( $request );
|
||||
if ( $response->is_error() ) {
|
||||
return;
|
||||
}
|
||||
$patterns = $response->get_data();
|
||||
set_transient( 'wp_remote_block_patterns', $patterns, HOUR_IN_SECONDS );
|
||||
$request = new WP_REST_Request( 'GET', '/wp/v2/pattern-directory/patterns' );
|
||||
$core_keyword_id = 11; // 11 is the ID for "core".
|
||||
$request->set_param( 'keyword', $core_keyword_id );
|
||||
$response = rest_do_request( $request );
|
||||
if ( $response->is_error() ) {
|
||||
return;
|
||||
}
|
||||
$patterns = $response->get_data();
|
||||
|
||||
foreach ( $patterns as $settings ) {
|
||||
$pattern_name = 'core/' . sanitize_title( $settings['title'] );
|
||||
|
@ -111,38 +111,73 @@ class WP_REST_Pattern_Directory_Controller extends WP_REST_Controller {
|
||||
$query_args['search'] = $search_term;
|
||||
}
|
||||
|
||||
$api_url = add_query_arg(
|
||||
array_map( 'rawurlencode', $query_args ),
|
||||
'http://api.wordpress.org/patterns/1.0/'
|
||||
);
|
||||
/*
|
||||
* Include a hash of the query args, so that different requests are stored in
|
||||
* 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 );
|
||||
$raw_patterns = json_decode( wp_remote_retrieve_body( $wporg_response ) );
|
||||
|
||||
if ( is_wp_error( $wporg_response ) ) {
|
||||
$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’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 ( ! $raw_patterns ) {
|
||||
$api_url = add_query_arg(
|
||||
array_map( 'rawurlencode', $query_args ),
|
||||
'http://api.wordpress.org/patterns/1.0/'
|
||||
);
|
||||
|
||||
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’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();
|
||||
|
@ -260,6 +260,46 @@ class WP_REST_Pattern_Directory_Controller_Test extends WP_Test_REST_Controller_
|
||||
$this->assertWPError( $response->as_error() );
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers WP_REST_Pattern_Directory_Controller::get_items
|
||||
*
|
||||
* @since 5.8.0
|
||||
*/
|
||||
public function test_get_items_prepare_filter() {
|
||||
wp_set_current_user( self::$contributor_id );
|
||||
self::mock_successful_response( 'browse-all', true );
|
||||
|
||||
// Test that filter changes uncached values.
|
||||
add_filter(
|
||||
'rest_prepare_block_pattern',
|
||||
function( $response ) {
|
||||
return 'initial value';
|
||||
}
|
||||
);
|
||||
|
||||
$request = new WP_REST_Request( 'GET', '/wp/v2/pattern-directory/patterns' );
|
||||
$response = rest_do_request( $request );
|
||||
$patterns = $response->get_data();
|
||||
|
||||
$this->assertSame( 'initial value', $patterns[0] );
|
||||
|
||||
// Test that filter changes cached values (the previous request primed the cache).
|
||||
add_filter(
|
||||
'rest_prepare_block_pattern',
|
||||
function( $response ) {
|
||||
return 'modified the cache';
|
||||
},
|
||||
11
|
||||
);
|
||||
|
||||
// Test that the filter works against cached values.
|
||||
$request = new WP_REST_Request( 'GET', '/wp/v2/pattern-directory/patterns' );
|
||||
$response = rest_do_request( $request );
|
||||
$patterns = $response->get_data();
|
||||
|
||||
$this->assertSame( 'modified the cache', $patterns[0] );
|
||||
}
|
||||
|
||||
public function test_get_item() {
|
||||
$this->markTestSkipped( 'Controller does not have get_item route.' );
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user