-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Pattern Directory]: Allow pattern registration from directory with t…
…heme.json (#38323) * [Pattern Directory]: Allow pattern registration from directory with theme.json * fix php linting issues * identation fix * review feedback * always return an array * Revert changes to existing WP_Theme_JSON_Gutenberg class * Override the parts that this PR needs * fix after rebase Co-authored-by: André <[email protected]>
- Loading branch information
1 parent
c2b5011
commit cab8cc5
Showing
8 changed files
with
253 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
<?php | ||
/** | ||
* Block patterns registration from `theme.json` and Pattern Directory. | ||
* | ||
* @package gutenberg | ||
*/ | ||
|
||
/** | ||
* Registers patterns from Pattern Directory provided by a theme's | ||
* `theme.json` file. | ||
*/ | ||
function gutenberg_register_remote_theme_patterns() { | ||
$should_load_remote = apply_filters( 'should_load_remote_block_patterns', true ); | ||
$theme_has_support = WP_Theme_JSON_Resolver_Gutenberg::theme_has_support(); | ||
if ( ! get_theme_support( 'core-block-patterns' ) || ! $should_load_remote || ! $theme_has_support ) { | ||
return; | ||
} | ||
|
||
$pattern_settings = WP_Theme_JSON_Resolver_Gutenberg::get_theme_data()->get_patterns(); | ||
if ( empty( $pattern_settings ) ) { | ||
return; | ||
} | ||
$request = new WP_REST_Request( 'GET', '/wp/v2/pattern-directory/patterns' ); | ||
$request['slug'] = implode( ',', $pattern_settings ); | ||
$response = rest_do_request( $request ); | ||
if ( $response->is_error() ) { | ||
return; | ||
} | ||
$patterns = $response->get_data(); | ||
$patterns_registry = WP_Block_Patterns_Registry::get_instance(); | ||
foreach ( $patterns as $pattern ) { | ||
$pattern_name = sanitize_title( $pattern['title'] ); | ||
// Some patterns might be already registered as core patterns with the `core` prefix. | ||
$is_registered = $patterns_registry->is_registered( $pattern_name ) || $patterns_registry->is_registered( "core/$pattern_name" ); | ||
if ( ! $is_registered ) { | ||
register_block_pattern( $pattern_name, (array) $pattern ); | ||
} | ||
} | ||
} | ||
|
||
add_action( 'init', 'gutenberg_register_remote_theme_patterns' ); |
141 changes: 141 additions & 0 deletions
141
lib/compat/wordpress-6.0/class-gutenberg-rest-pattern-directory-controller.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
<?php | ||
/** | ||
* REST API: Gutenberg_REST_Global_Styles_Controller class | ||
* | ||
* @package Gutenberg | ||
* @subpackage REST_API | ||
*/ | ||
|
||
/** | ||
* Controller which provides REST endpoint for block patterns. | ||
*/ | ||
class Gutenberg_REST_Pattern_Directory_Controller extends WP_REST_Pattern_Directory_Controller { | ||
/** | ||
* Search and retrieve block patterns metadata | ||
* | ||
* @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. | ||
*/ | ||
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'; | ||
require_once ABSPATH . 'wp-admin/includes/plugin.php'; | ||
|
||
$gutenberg_data = get_plugin_data( dirname( dirname( 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']; | ||
$slug = $request['slug']; | ||
|
||
if ( $category_id ) { | ||
$query_args['pattern-categories'] = $category_id; | ||
} | ||
|
||
if ( $keyword_id ) { | ||
$query_args['pattern-keywords'] = $keyword_id; | ||
} | ||
|
||
if ( $search_term ) { | ||
$query_args['search'] = $search_term; | ||
} | ||
|
||
if ( $slug ) { | ||
$query_args['slug'] = $slug; | ||
} | ||
|
||
/** | ||
* 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 ) ); | ||
|
||
/** | ||
* 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 ); | ||
|
||
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>.', 'gutenberg' ), | ||
__( 'https://wordpress.org/support/forums/', 'gutenberg' ) | ||
), | ||
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(); | ||
|
||
if ( $raw_patterns ) { | ||
foreach ( $raw_patterns as $pattern ) { | ||
$response[] = $this->prepare_response_for_collection( | ||
$this->prepare_item_for_response( $pattern, $request ) | ||
); | ||
} | ||
} | ||
|
||
return new WP_REST_Response( $response ); | ||
} | ||
} |
45 changes: 45 additions & 0 deletions
45
lib/compat/wordpress-6.0/class-wp-theme-json-gutenberg.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
<?php | ||
/** | ||
* WP_Theme_JSON_Gutenberg class | ||
* | ||
* @package gutenberg | ||
*/ | ||
|
||
/** | ||
* Class that encapsulates the processing of structures that adhere to the theme.json spec. | ||
* | ||
* This class is for internal core usage and is not supposed to be used by extenders (plugins and/or themes). | ||
* This is a low-level API that may need to do breaking changes. Please, | ||
* use get_global_settings, get_global_styles, and get_global_stylesheet instead. | ||
* | ||
* @access private | ||
*/ | ||
class WP_Theme_JSON_Gutenberg extends WP_Theme_JSON_5_9 { | ||
|
||
/** | ||
* The top-level keys a theme.json can have. | ||
* | ||
* @var string[] | ||
*/ | ||
const VALID_TOP_LEVEL_KEYS = array( | ||
'customTemplates', | ||
'patterns', | ||
'settings', | ||
'styles', | ||
'templateParts', | ||
'version', | ||
); | ||
|
||
/** | ||
* Returns the current theme's wanted patterns(slugs) to be | ||
* registered from Pattern Directory. | ||
* | ||
* @return array | ||
*/ | ||
public function get_patterns() { | ||
if ( isset( $this->theme_json['patterns'] ) && is_array( $this->theme_json['patterns'] ) ) { | ||
return $this->theme_json['patterns']; | ||
} | ||
return array(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters