diff --git a/apps/editing-toolkit/editing-toolkit-plugin/block-patterns/class-block-patterns-from-api.php b/apps/editing-toolkit/editing-toolkit-plugin/block-patterns/class-block-patterns-from-api.php index 7b112bed82cac..abb178524de24 100644 --- a/apps/editing-toolkit/editing-toolkit-plugin/block-patterns/class-block-patterns-from-api.php +++ b/apps/editing-toolkit/editing-toolkit-plugin/block-patterns/class-block-patterns-from-api.php @@ -44,6 +44,15 @@ class Block_Patterns_From_API { */ private $utils; + /** + * A dictionary to map existing WPCOM pattern categories to core patterns. + * These should match the categories in $patterns_sources, + * which are registered in $this->register_patterns() + * + * @var array + */ + private $core_to_wpcom_categories_dictionary; + /** * Block_Patterns constructor. * @@ -54,6 +63,13 @@ public function __construct( $patterns_sources, Block_Patterns_Utils $utils = nu $patterns_sources = empty( $patterns_sources ) ? array( 'block_patterns' ) : $patterns_sources; $this->patterns_sources = empty( array_diff( $patterns_sources, $this->valid_patterns_sources ) ) ? $patterns_sources : array( 'block_patterns' ); $this->utils = empty( $utils ) ? new \A8C\FSE\Block_Patterns_Utils() : $utils; + // Add categories to this array using the core pattern name as the key for core patterns we wish to "recategorize". + $this->core_to_wpcom_categories_dictionary = array( + 'core/quote' => array( + 'quotes' => __( 'Quotes', 'full-site-editing' ), + 'text' => __( 'Text', 'full-site-editing' ), + ), + ); } /** @@ -62,14 +78,7 @@ public function __construct( $patterns_sources, Block_Patterns_Utils $utils = nu * @return array Results of pattern registration. */ public function register_patterns() { - if ( class_exists( 'WP_Block_Patterns_Registry' ) ) { - // Remove core patterns. - foreach ( \WP_Block_Patterns_Registry::get_instance()->get_all_registered() as $pattern ) { - if ( 'core/' === substr( $pattern['name'], 0, 5 ) ) { - unregister_block_pattern( $pattern['name'] ); - } - } - } + $this->reregister_core_patterns(); // Used to track which patterns we successfully register. $results = array(); @@ -141,6 +150,9 @@ function ( $a, $b ) { } } } + + $this->update_core_patterns_with_wpcom_categories(); + return $results; } @@ -188,21 +200,13 @@ private function get_patterns( $patterns_cache_key, $patterns_source ) { ); $block_patterns = $this->utils->remote_get( $request_url ); + $this->utils->cache_add( $patterns_cache_key, $block_patterns, 'ptk_patterns', DAY_IN_SECONDS ); } return $block_patterns; } - /** - * Get the locale to be used for fetching block patterns - */ - private function get_block_patterns_locale() { - // Make sure to get blog locale, not user locale. - $language = function_exists( 'get_blog_lang_code' ) ? get_blog_lang_code() : get_locale(); - return \A8C\FSE\Common\get_iso_639_locale( $language ); - } - /** * Check that the pattern is allowed to be registered. * @@ -236,5 +240,56 @@ private function can_register_pattern( $pattern ) { return true; } + + /** + * Unregister all core patterns, then reregister core patterns in core WordPress only, + * that is those in wp-includes/block-patterns.php + * Gutenberg adds new and overrides existing core patterns. We don't want these for now. + */ + private function reregister_core_patterns() { + if ( class_exists( 'WP_Block_Patterns_Registry' ) ) { + foreach ( \WP_Block_Patterns_Registry::get_instance()->get_all_registered() as $pattern ) { + // Gutenberg registers patterns with varying prefixes, but categorizes them using `core/*` in a blockTypes array. + // This will ensure we remove `query/*` blocks for example. + // TODO: We need to revisit our usage or $pattern['blockTypes']: they are currently an experimental feature and not guaranteed to reference `core/*` blocks. + $pattern_block_type_or_name = ! empty( $pattern['blockTypes'][0] ) ? $pattern['blockTypes'][0] : $pattern['name']; + if ( 'core/' === substr( $pattern_block_type_or_name, 0, 5 ) ) { + unregister_block_pattern( $pattern['name'] ); + } + } + if ( function_exists( '_register_core_block_patterns_and_categories' ) ) { + $did_switch_locale = switch_to_locale( $this->utils->get_block_patterns_locale() ); + _register_core_block_patterns_and_categories(); + // The site locale might be the same as the current locale so switching could have failed in such instances. + if ( false !== $did_switch_locale ) { + restore_previous_locale(); + } + } + } + } + + /** + * Update categories for core patterns if a records exists in $this->core_to_wpcom_categories_dictionary + * and reregister them. + */ + private function update_core_patterns_with_wpcom_categories() { + if ( class_exists( 'WP_Block_Patterns_Registry' ) ) { + foreach ( \WP_Block_Patterns_Registry::get_instance()->get_all_registered() as $pattern ) { + $wpcom_categories = $this->core_to_wpcom_categories_dictionary[ $pattern['name'] ]; + if ( isset( $wpcom_categories ) ) { + unregister_block_pattern( $pattern['name'] ); + $pattern_properties = array_merge( + $pattern, + array( 'categories' => array_keys( $wpcom_categories ) ) + ); + unset( $pattern_properties['name'] ); + register_block_pattern( + $pattern['name'], + $pattern_properties + ); + } + } + } + } }