|
25 | 25 | */ |
26 | 26 | function wp_get_global_settings( $path = array(), $context = array() ) { |
27 | 27 | if ( ! empty( $context['block_name'] ) ) { |
28 | | - $path = array_merge( array( 'blocks', $context['block_name'] ), $path ); |
| 28 | + $new_path = array( 'blocks', $context['block_name'] ); |
| 29 | + foreach ( $path as $subpath ) { |
| 30 | + $new_path[] = $subpath; |
| 31 | + } |
| 32 | + $path = $new_path; |
29 | 33 | } |
30 | 34 |
|
| 35 | + /* |
| 36 | + * This is the default value when no origin is provided or when it is 'all'. |
| 37 | + * |
| 38 | + * The $origin is used as part of the cache key. Changes here need to account |
| 39 | + * for clearing the cache appropriately. |
| 40 | + */ |
31 | 41 | $origin = 'custom'; |
32 | | - if ( isset( $context['origin'] ) && 'base' === $context['origin'] ) { |
| 42 | + if ( |
| 43 | + ! wp_theme_has_theme_json() || |
| 44 | + ( isset( $context['origin'] ) && 'base' === $context['origin'] ) |
| 45 | + ) { |
33 | 46 | $origin = 'theme'; |
34 | 47 | } |
35 | 48 |
|
36 | | - $settings = WP_Theme_JSON_Resolver::get_merged_data( $origin )->get_settings(); |
| 49 | + /* |
| 50 | + * By using the 'theme_json' group, this data is marked to be non-persistent across requests. |
| 51 | + * See `wp_cache_add_non_persistent_groups` in src/wp-includes/load.php and other places. |
| 52 | + * |
| 53 | + * The rationale for this is to make sure derived data from theme.json |
| 54 | + * is always fresh from the potential modifications done via hooks |
| 55 | + * that can use dynamic data (modify the stylesheet depending on some option, |
| 56 | + * settings depending on user permissions, etc.). |
| 57 | + * See some of the existing hooks to modify theme.json behaviour: |
| 58 | + * https://make.wordpress.org/core/2022/10/10/filters-for-theme-json-data/ |
| 59 | + * |
| 60 | + * A different alternative considered was to invalidate the cache upon certain |
| 61 | + * events such as options add/update/delete, user meta, etc. |
| 62 | + * It was judged not enough, hence this approach. |
| 63 | + * See https://github.com/WordPress/gutenberg/pull/45372 |
| 64 | + */ |
| 65 | + $cache_group = 'theme_json'; |
| 66 | + $cache_key = 'wp_get_global_settings_' . $origin; |
| 67 | + |
| 68 | + /* |
| 69 | + * Ignore cache when `WP_DEBUG` is enabled, so it doesn't interfere with the theme |
| 70 | + * developer's workflow. |
| 71 | + * |
| 72 | + * @todo Replace `WP_DEBUG` once an "in development mode" check is available in Core. |
| 73 | + */ |
| 74 | + $can_use_cached = ! WP_DEBUG; |
| 75 | + |
| 76 | + $settings = false; |
| 77 | + if ( $can_use_cached ) { |
| 78 | + $settings = wp_cache_get( $cache_key, $cache_group ); |
| 79 | + } |
| 80 | + |
| 81 | + if ( false === $settings ) { |
| 82 | + $settings = WP_Theme_JSON_Resolver::get_merged_data( $origin )->get_settings(); |
| 83 | + if ( $can_use_cached ) { |
| 84 | + wp_cache_set( $cache_key, $settings, $cache_group ); |
| 85 | + } |
| 86 | + } |
37 | 87 |
|
38 | 88 | return _wp_array_get( $settings, $path, $settings ); |
39 | 89 | } |
@@ -317,5 +367,7 @@ function wp_theme_has_theme_json() { |
317 | 367 | */ |
318 | 368 | function wp_clean_theme_json_cache() { |
319 | 369 | wp_cache_delete( 'wp_get_global_stylesheet', 'theme_json' ); |
| 370 | + wp_cache_delete( 'wp_get_global_settings_custom', 'theme_json' ); |
| 371 | + wp_cache_delete( 'wp_get_global_settings_theme', 'theme_json' ); |
320 | 372 | WP_Theme_JSON_Resolver::clean_cached_data(); |
321 | 373 | } |
0 commit comments