diff --git a/lib/class-wp-theme-json-resolver-gutenberg.php b/lib/class-wp-theme-json-resolver-gutenberg.php index 507876af4952a8..b2fd4405b8a84e 100644 --- a/lib/class-wp-theme-json-resolver-gutenberg.php +++ b/lib/class-wp-theme-json-resolver-gutenberg.php @@ -91,6 +91,14 @@ class WP_Theme_JSON_Resolver_Gutenberg { */ protected static $theme_json_file_cache = array(); + /** + * Cache of parsed and translated style variation theme.json partials. + * + * @since 6.6.0 + * @var array + */ + protected static $style_variations_cache = array(); + /** * Processes a file that adheres to the theme.json schema * and returns an array with its contents, or a void array if none found. @@ -703,7 +711,7 @@ private static function recursively_iterate_json( $dir ) { } /** - * Determines if a supplied style variation matches the provided scope. + * Determines the scope of a style variation. * * For backwards compatibility, if a variation does not define any scope * related property, e.g. `blockTypes`, it is assumed to be a theme style @@ -711,37 +719,25 @@ private static function recursively_iterate_json( $dir ) { * * @since 6.6.0 * - * @param array $variation Theme.json shaped style variation object. - * @param string $scope Scope to check e.g. theme, block etc. + * @param array $variation Theme.json shaped style variation object. * - * @return boolean + * @return string */ - private static function style_variation_has_scope( $variation, $scope ) { - if ( 'block' === $scope ) { - return isset( $variation['blockTypes'] ); - } - - if ( 'theme' === $scope ) { - return ! isset( $variation['blockTypes'] ); + protected static function get_style_variation_scope( $variation ) { + if ( isset( $variation['blockTypes'] ) ) { + return 'block'; } - return false; + return 'theme'; } /** - * Returns the style variations defined by the theme (parent and child). + * Retrieves all style variation partials defined by the theme (parent and child). * - * @since 6.2.0 Returns parent theme variations if theme is a child. - * @since 6.6.0 Added configurable scope parameter to allow filtering - * theme.json partial files by the scope to which they - * can be applied e.g. theme vs block etc. - * - * @param string $scope The scope or type of style variation to retrieve e.g. theme, block etc. - * @return array + * @since 6.6.0 */ - public static function get_style_variations( $scope = 'theme' ) { + protected static function get_style_variation_files() { $variation_files = array(); - $variations = array(); $base_directory = get_stylesheet_directory() . '/styles'; $template_directory = get_template_directory() . '/styles'; if ( is_dir( $base_directory ) ) { @@ -760,18 +756,54 @@ public static function get_style_variations( $scope = 'theme' ) { $variation_files = array_merge( $variation_files, $variation_files_parent ); } ksort( $variation_files ); + + return $variation_files; + } + + /** + * Returns the style variations defined by the theme (parent and child). + * + * @since 6.2.0 Returns parent theme variations if theme is a child. + * @since 6.6.0 Added cache and configurable scope parameter to allow + * filtering theme.json partial files by the scope to + * which they can be applied e.g. theme vs block etc. + * + * @param string $scope The scope or type of style variation to retrieve e.g. theme, block etc. + * @return array + */ + public static function get_style_variations( $scope = 'theme' ) { + $theme_dir = get_stylesheet_directory(); + $locale = get_locale(); + if ( isset( static::$style_variations_cache[ $theme_dir ][ $locale ][ $scope ] ) ) { + return static::$style_variations_cache[ $theme_dir ][ $locale ][ $scope ]; + } + + $variation_files = static::get_style_variation_files(); + $variations = array( + 'theme' => array(), + 'block' => array(), + ); + foreach ( $variation_files as $path => $file ) { $decoded_file = wp_json_file_decode( $path, array( 'associative' => true ) ); - if ( is_array( $decoded_file ) && static::style_variation_has_scope( $decoded_file, $scope ) ) { - $translated = static::translate( $decoded_file, wp_get_theme()->get( 'TextDomain' ) ); - $variation = ( new WP_Theme_JSON_Gutenberg( $translated ) )->get_raw_data(); - if ( empty( $variation['title'] ) ) { - $variation['title'] = basename( $path, '.json' ); + if ( is_array( $decoded_file ) ) { + $variation_scope = static::get_style_variation_scope( $decoded_file ); + + if ( $variation_scope ) { + $translated = static::translate( $decoded_file, wp_get_theme()->get( 'TextDomain' ) ); + $variation = ( new WP_Theme_JSON_Gutenberg( $translated ) )->get_raw_data(); + + if ( empty( $variation['title'] ) ) { + $variation['title'] = basename( $path, '.json' ); + } + + $variations[ $variation_scope ][] = $variation; } - $variations[] = $variation; } } - return $variations; + static::$style_variations_cache[ $theme_dir ][ $locale ] = $variations; + + return static::$style_variations_cache[ $theme_dir ][ $locale ][ $scope ]; }