[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-includes/ -> global-styles-and-settings.php (source)

   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  }


Generated : Sun Jun 4 08:20:02 2023 Cross-referenced by PHPXref