[ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * APIs to interact with global settings & styles. 4 * 5 * @package WordPress 6 */ 7 8 /** 9 * Gets the settings resulting of merging core, theme, and user data. 10 * 11 * @since 5.9.0 12 * 13 * @param array $path Path to the specific setting to retrieve. Optional. 14 * If empty, will return all settings. 15 * @param array $context { 16 * Metadata to know where to retrieve the $path from. Optional. 17 * 18 * @type string $block_name Which block to retrieve the settings from. 19 * If empty, it'll return the settings for the global context. 20 * @type string $origin Which origin to take data from. 21 * Valid values are 'all' (core, theme, and user) or 'base' (core and theme). 22 * If empty or unknown, 'all' is used. 23 * } 24 * @return mixed The settings array or individual setting value to retrieve. 25 */ 26 function wp_get_global_settings( $path = array(), $context = array() ) { 27 if ( ! empty( $context['block_name'] ) ) { 28 $new_path = array( 'blocks', $context['block_name'] ); 29 foreach ( $path as $subpath ) { 30 $new_path[] = $subpath; 31 } 32 $path = $new_path; 33 } 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 */ 41 $origin = 'custom'; 42 if ( 43 ! wp_theme_has_theme_json() || 44 ( isset( $context['origin'] ) && 'base' === $context['origin'] ) 45 ) { 46 $origin = 'theme'; 47 } 48 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 } 87 88 return _wp_array_get( $settings, $path, $settings ); 89 } 90 91 /** 92 * Gets the styles resulting of merging core, theme, and user data. 93 * 94 * @since 5.9.0 95 * 96 * @param array $path Path to the specific style to retrieve. Optional. 97 * If empty, will return all styles. 98 * @param array $context { 99 * Metadata to know where to retrieve the $path from. Optional. 100 * 101 * @type string $block_name Which block to retrieve the styles from. 102 * If empty, it'll return the styles for the global context. 103 * @type string $origin Which origin to take data from. 104 * Valid values are 'all' (core, theme, and user) or 'base' (core and theme). 105 * If empty or unknown, 'all' is used. 106 * } 107 * @return mixed The styles array or individual style value to retrieve. 108 */ 109 function wp_get_global_styles( $path = array(), $context = array() ) { 110 if ( ! empty( $context['block_name'] ) ) { 111 $path = array_merge( array( 'blocks', $context['block_name'] ), $path ); 112 } 113 114 $origin = 'custom'; 115 if ( isset( $context['origin'] ) && 'base' === $context['origin'] ) { 116 $origin = 'theme'; 117 } 118 119 $styles = WP_Theme_JSON_Resolver::get_merged_data( $origin )->get_raw_data()['styles']; 120 121 return _wp_array_get( $styles, $path, $styles ); 122 } 123 124 /** 125 * Returns the stylesheet resulting of merging core, theme, and user data. 126 * 127 * @since 5.9.0 128 * @since 6.1.0 Added 'base-layout-styles' support. 129 * 130 * @param array $types Optional. Types of styles to load. 131 * It accepts as values 'variables', 'presets', 'styles', 'base-layout-styles'. 132 * If empty, it'll load the following: 133 * - for themes without theme.json: 'variables', 'presets', 'base-layout-styles'. 134 * - for themes with theme.json: 'variables', 'presets', 'styles'. 135 * @return string Stylesheet. 136 */ 137 function wp_get_global_stylesheet( $types = array() ) { 138 /* 139 * Ignore cache when `WP_DEBUG` is enabled, so it doesn't interfere with the theme 140 * developer's workflow. 141 * 142 * @todo Replace `WP_DEBUG` once an "in development mode" check is available in Core. 143 */ 144 $can_use_cached = empty( $types ) && ! WP_DEBUG; 145 146 /* 147 * By using the 'theme_json' group, this data is marked to be non-persistent across requests. 148 * @see `wp_cache_add_non_persistent_groups()`. 149 * 150 * The rationale for this is to make sure derived data from theme.json 151 * is always fresh from the potential modifications done via hooks 152 * that can use dynamic data (modify the stylesheet depending on some option, 153 * settings depending on user permissions, etc.). 154 * See some of the existing hooks to modify theme.json behavior: 155 * @see https://make.wordpress.org/core/2022/10/10/filters-for-theme-json-data/ 156 * 157 * A different alternative considered was to invalidate the cache upon certain 158 * events such as options add/update/delete, user meta, etc. 159 * It was judged not enough, hence this approach. 160 * @see https://github.com/WordPress/gutenberg/pull/45372 161 */ 162 $cache_group = 'theme_json'; 163 $cache_key = 'wp_get_global_stylesheet'; 164 if ( $can_use_cached ) { 165 $cached = wp_cache_get( $cache_key, $cache_group ); 166 if ( $cached ) { 167 return $cached; 168 } 169 } 170 171 $tree = WP_Theme_JSON_Resolver::get_merged_data(); 172 173 $supports_theme_json = wp_theme_has_theme_json(); 174 if ( empty( $types ) && ! $supports_theme_json ) { 175 $types = array( 'variables', 'presets', 'base-layout-styles' ); 176 } elseif ( empty( $types ) ) { 177 $types = array( 'variables', 'styles', 'presets' ); 178 } 179 180 /* 181 * If variables are part of the stylesheet, then add them. 182 * This is so themes without a theme.json still work as before 5.9: 183 * they can override the default presets. 184 * See https://core.trac.wordpress.org/ticket/54782 185 */ 186 $styles_variables = ''; 187 if ( in_array( 'variables', $types, true ) ) { 188 /* 189 * Only use the default, theme, and custom origins. Why? 190 * Because styles for `blocks` origin are added at a later phase 191 * (i.e. in the render cycle). Here, only the ones in use are rendered. 192 * @see wp_add_global_styles_for_blocks 193 */ 194 $origins = array( 'default', 'theme', 'custom' ); 195 $styles_variables = $tree->get_stylesheet( array( 'variables' ), $origins ); 196 $types = array_diff( $types, array( 'variables' ) ); 197 } 198 199 /* 200 * For the remaining types (presets, styles), we do consider origins: 201 * 202 * - themes without theme.json: only the classes for the presets defined by core 203 * - themes with theme.json: the presets and styles classes, both from core and the theme 204 */ 205 $styles_rest = ''; 206 if ( ! empty( $types ) ) { 207 /* 208 * Only use the default, theme, and custom origins. Why? 209 * Because styles for `blocks` origin are added at a later phase 210 * (i.e. in the render cycle). Here, only the ones in use are rendered. 211 * @see wp_add_global_styles_for_blocks 212 */ 213 $origins = array( 'default', 'theme', 'custom' ); 214 if ( ! $supports_theme_json ) { 215 $origins = array( 'default' ); 216 } 217 $styles_rest = $tree->get_stylesheet( $types, $origins ); 218 } 219 220 $stylesheet = $styles_variables . $styles_rest; 221 if ( $can_use_cached ) { 222 wp_cache_set( $cache_key, $stylesheet, $cache_group ); 223 } 224 225 return $stylesheet; 226 } 227 228 /** 229 * Gets the global styles custom CSS from theme.json. 230 * 231 * @since 6.2.0 232 * 233 * @return string The global styles custom CSS. 234 */ 235 function wp_get_global_styles_custom_css() { 236 if ( ! wp_theme_has_theme_json() ) { 237 return ''; 238 } 239 /* 240 * Ignore cache when `WP_DEBUG` is enabled, so it doesn't interfere with the theme 241 * developer's workflow. 242 * 243 * @todo Replace `WP_DEBUG` once an "in development mode" check is available in Core. 244 */ 245 $can_use_cached = ! WP_DEBUG; 246 247 /* 248 * By using the 'theme_json' group, this data is marked to be non-persistent across requests. 249 * @see `wp_cache_add_non_persistent_groups()`. 250 * 251 * The rationale for this is to make sure derived data from theme.json 252 * is always fresh from the potential modifications done via hooks 253 * that can use dynamic data (modify the stylesheet depending on some option, 254 * settings depending on user permissions, etc.). 255 * See some of the existing hooks to modify theme.json behavior: 256 * @see https://make.wordpress.org/core/2022/10/10/filters-for-theme-json-data/ 257 * 258 * A different alternative considered was to invalidate the cache upon certain 259 * events such as options add/update/delete, user meta, etc. 260 * It was judged not enough, hence this approach. 261 * @see https://github.com/WordPress/gutenberg/pull/45372 262 */ 263 $cache_key = 'wp_get_global_styles_custom_css'; 264 $cache_group = 'theme_json'; 265 if ( $can_use_cached ) { 266 $cached = wp_cache_get( $cache_key, $cache_group ); 267 if ( $cached ) { 268 return $cached; 269 } 270 } 271 272 $tree = WP_Theme_JSON_Resolver::get_merged_data(); 273 $stylesheet = $tree->get_custom_css(); 274 275 if ( $can_use_cached ) { 276 wp_cache_set( $cache_key, $stylesheet, $cache_group ); 277 } 278 279 return $stylesheet; 280 } 281 282 /** 283 * Returns a string containing the SVGs to be referenced as filters (duotone). 284 * 285 * @since 5.9.1 286 * 287 * @return string 288 */ 289 function wp_get_global_styles_svg_filters() { 290 /* 291 * Ignore cache when `WP_DEBUG` is enabled, so it doesn't interfere with the theme 292 * developer's workflow. 293 * 294 * @todo Replace `WP_DEBUG` once an "in development mode" check is available in Core. 295 */ 296 $can_use_cached = ! WP_DEBUG; 297 $cache_group = 'theme_json'; 298 $cache_key = 'wp_get_global_styles_svg_filters'; 299 if ( $can_use_cached ) { 300 $cached = wp_cache_get( $cache_key, $cache_group ); 301 if ( $cached ) { 302 return $cached; 303 } 304 } 305 306 $supports_theme_json = wp_theme_has_theme_json(); 307 308 $origins = array( 'default', 'theme', 'custom' ); 309 if ( ! $supports_theme_json ) { 310 $origins = array( 'default' ); 311 } 312 313 $tree = WP_Theme_JSON_Resolver::get_merged_data(); 314 $svgs = $tree->get_svg_filters( $origins ); 315 316 if ( $can_use_cached ) { 317 wp_cache_set( $cache_key, $svgs, $cache_group ); 318 } 319 320 return $svgs; 321 } 322 323 /** 324 * Adds global style rules to the inline style for each block. 325 * 326 * @since 6.1.0 327 */ 328 function wp_add_global_styles_for_blocks() { 329 $tree = WP_Theme_JSON_Resolver::get_merged_data(); 330 $block_nodes = $tree->get_styles_block_nodes(); 331 foreach ( $block_nodes as $metadata ) { 332 $block_css = $tree->get_styles_for_block( $metadata ); 333 334 if ( ! wp_should_load_separate_core_block_assets() ) { 335 wp_add_inline_style( 'global-styles', $block_css ); 336 continue; 337 } 338 339 $stylesheet_handle = 'global-styles'; 340 if ( isset( $metadata['name'] ) ) { 341 /* 342 * These block styles are added on block_render. 343 * This hooks inline CSS to them so that they are loaded conditionally 344 * based on whether or not the block is used on the page. 345 */ 346 if ( str_starts_with( $metadata['name'], 'core/' ) ) { 347 $block_name = str_replace( 'core/', '', $metadata['name'] ); 348 $stylesheet_handle = 'wp-block-' . $block_name; 349 } 350 wp_add_inline_style( $stylesheet_handle, $block_css ); 351 } 352 353 // The likes of block element styles from theme.json do not have $metadata['name'] set. 354 if ( ! isset( $metadata['name'] ) && ! empty( $metadata['path'] ) ) { 355 $result = array_values( 356 array_filter( 357 $metadata['path'], 358 function ( $item ) { 359 if ( strpos( $item, 'core/' ) !== false ) { 360 return true; 361 } 362 return false; 363 } 364 ) 365 ); 366 if ( isset( $result[0] ) ) { 367 if ( str_starts_with( $result[0], 'core/' ) ) { 368 $block_name = str_replace( 'core/', '', $result[0] ); 369 $stylesheet_handle = 'wp-block-' . $block_name; 370 } 371 wp_add_inline_style( $stylesheet_handle, $block_css ); 372 } 373 } 374 } 375 } 376 377 /** 378 * Checks whether a theme or its parent has a theme.json file. 379 * 380 * @since 6.2.0 381 * 382 * @return bool Returns true if theme or its parent has a theme.json file, false otherwise. 383 */ 384 function wp_theme_has_theme_json() { 385 static $theme_has_support = null; 386 387 if ( 388 null !== $theme_has_support && 389 /* 390 * Ignore static cache when `WP_DEBUG` is enabled. Why? To avoid interfering with 391 * the theme developer's workflow. 392 * 393 * @todo Replace `WP_DEBUG` once an "in development mode" check is available in Core. 394 */ 395 ! WP_DEBUG && 396 /* 397 * Ignore cache when automated test suites are running. Why? To ensure 398 * the static cache is reset between each test. 399 */ 400 ! ( defined( 'WP_RUN_CORE_TESTS' ) && WP_RUN_CORE_TESTS ) 401 ) { 402 return $theme_has_support; 403 } 404 405 // Does the theme have its own theme.json? 406 $theme_has_support = is_readable( get_stylesheet_directory() . '/theme.json' ); 407 408 // Look up the parent if the child does not have a theme.json. 409 if ( ! $theme_has_support ) { 410 $theme_has_support = is_readable( get_template_directory() . '/theme.json' ); 411 } 412 413 return $theme_has_support; 414 } 415 416 /** 417 * Cleans the caches under the theme_json group. 418 * 419 * @since 6.2.0 420 */ 421 function wp_clean_theme_json_cache() { 422 wp_cache_delete( 'wp_get_global_stylesheet', 'theme_json' ); 423 wp_cache_delete( 'wp_get_global_styles_svg_filters', 'theme_json' ); 424 wp_cache_delete( 'wp_get_global_settings_custom', 'theme_json' ); 425 wp_cache_delete( 'wp_get_global_settings_theme', 'theme_json' ); 426 wp_cache_delete( 'wp_get_global_styles_custom_css', 'theme_json' ); 427 WP_Theme_JSON_Resolver::clean_cached_data(); 428 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated : Sun Jun 4 08:20:02 2023 | Cross-referenced by PHPXref |