Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pattern Directory: Merge Core locale, caching updates #33052

Merged
merged 4 commits into from
Jul 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 18 additions & 8 deletions lib/block-patterns.php
Original file line number Diff line number Diff line change
Expand Up @@ -200,15 +200,26 @@ function remove_core_patterns() {
}

/**
* Import patterns from wordpress.org/patterns.
* Register Core's official patterns from wordpress.org/patterns.
*
* @since 5.8.0
ryelle marked this conversation as resolved.
Show resolved Hide resolved
*/
function load_remote_patterns() {
// This is the core function that provides the same feature.
if ( function_exists( '_load_remote_block_patterns' ) ) {
return;
}
$patterns = get_transient( 'gutenberg_remote_block_patterns' );
if ( ! $patterns ) {

/**
* Filter to disable remote block patterns.
*
* @since 5.8.0
*
* @param bool $should_load_remote
*/
$should_load_remote = apply_filters( 'should_load_remote_block_patterns', true );

if ( $should_load_remote ) {
$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 );
Expand All @@ -217,12 +228,11 @@ function load_remote_patterns() {
return;
}
$patterns = $response->get_data();
set_transient( 'gutenberg_remote_block_patterns', $patterns, HOUR_IN_SECONDS );
}

foreach ( $patterns as $settings ) {
$pattern_name = 'core/' . sanitize_title( $settings['title'] );
register_block_pattern( $pattern_name, (array) $settings );
foreach ( $patterns as $settings ) {
$pattern_name = 'core/' . sanitize_title( $settings['title'] );
register_block_pattern( $pattern_name, (array) $settings );
}
}
}

Expand Down
104 changes: 77 additions & 27 deletions lib/class-wp-rest-pattern-directory-controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,22 @@ public function get_items_permissions_check( $request ) { // phpcs:ignore Variab
* @return WP_Error|WP_REST_Response Response object on success, or WP_Error object on failure.
*/
public function get_items( $request ) {
$query_args = array();
/*
* 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';
require_once ABSPATH . 'wp-admin/includes/plugin.php';

$gutenberg_data = get_plugin_data( dirname( __DIR__ ) . '/gutenberg.php', false );

$query_args = array(
'locale' => get_user_locale(),
'wp-version' => $wp_version, // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable -- it's defined in `version.php` above.
'gutenberg-version' => $gutenberg_data['Version'],
);

$category_id = $request['category'];
$keyword_id = $request['keyword'];
$search_term = $request['search'];
Expand All @@ -102,38 +117,73 @@ public function get_items( $request ) {
$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 ( ! $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&#8217;s configuration. If you continue to have problems, please try the <a href="%s">support forums</a>.', 'gutenberg' ),
__( 'https://wordpress.org/support/forums/', 'gutenberg' )
),
array(
'response' => wp_remote_retrieve_body( $wporg_response ),
)
);

if ( is_wp_error( $wporg_response ) ) {
$wporg_response->add_data( array( 'status' => 500 ) );
} else {
// Response has valid data.
$cache_ttl = HOUR_IN_SECONDS;
}

return $wporg_response;
set_site_transient( $transient_key, $raw_patterns, $cache_ttl );
}

// 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>.', 'gutenberg' ),
__( 'https://wordpress.org/support/forums/', 'gutenberg' )
),
array(
'status' => 500,
'response' => wp_remote_retrieve_body( $wporg_response ),
)
);
if ( is_wp_error( $raw_patterns ) ) {
$raw_patterns->add_data( array( 'status' => 500 ) );

return $raw_patterns;
}

$response = array();
Expand Down
Loading