Changeset 52049 for trunk/src/wp-includes/class-wp-theme-json-resolver.php
- Timestamp:
- 11/08/2021 07:18:39 PM (2 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/class-wp-theme-json-resolver.php
r51693 r52049 12 12 * for site-level config and offers an API to work with them. 13 13 * 14 * This class is for internal core usage and is not supposed to be used by extenders (plugins and/or themes). 15 * This is a low-level API that may need to do breaking changes. Please, 16 * use get_global_settings, get_global_styles, and get_global_stylesheet instead. 17 * 14 18 * @access private 15 19 */ … … 41 45 42 46 /** 47 * Container for data coming from the user. 48 * 49 * @since 5.9.0 50 * @var WP_Theme_JSON 51 */ 52 private static $user = null; 53 54 /** 55 * Stores the ID of the custom post type 56 * that holds the user data. 57 * 58 * @since 5.9.0 59 * @var integer 60 */ 61 private static $user_custom_post_type_id = null; 62 63 /** 43 64 * Container to keep loaded i18n schema for `theme.json`. 44 65 * 45 * @since 5.9.0 66 * @since 5.8.0 67 * @since 5.9.0 Renamed from $theme_json_i18n 46 68 * @var array 47 69 */ … … 123 145 * Returns the theme's data. 124 146 * 125 * Data from theme.json can be augmented via the $theme_support_data variable. 126 * This is useful, for example, to backfill the gaps in theme.json that a theme 127 * has declared via add_theme_supports. 128 * 129 * Note that if the same data is present in theme.json and in $theme_support_data, 130 * the theme.json's is not overwritten. 131 * 132 * @since 5.8.0 133 * 134 * @param array $theme_support_data Optional. Theme support data in theme.json format. 135 * Default empty array. 147 * Data from theme.json will be backfilled from existing 148 * theme supports, if any. Note that if the same data 149 * is present in theme.json and in theme supports, 150 * the theme.json takes precendence. 151 * 152 * @since 5.8.0 153 * @since 5.9.0 Theme supports have been inlined and the argument removed. 154 * 136 155 * @return WP_Theme_JSON Entity that holds theme data. 137 156 */ 138 public static function get_theme_data( $theme_support_data = array() ) { 157 public static function get_theme_data( $deprecated = array() ) { 158 if ( ! empty( $deprecated ) ) { 159 _deprecated_argument( __METHOD__, '5.9' ); 160 } 139 161 if ( null === self::$theme ) { 140 162 $theme_json_data = self::read_json_file( self::get_file_path_from_theme( 'theme.json' ) ); 141 163 $theme_json_data = self::translate( $theme_json_data, wp_get_theme()->get( 'TextDomain' ) ); 142 164 self::$theme = new WP_Theme_JSON( $theme_json_data ); 143 } 144 145 if ( empty( $theme_support_data ) ) { 146 return self::$theme; 165 166 if ( wp_get_theme()->parent() ) { 167 // Get parent theme.json. 168 $parent_theme_json_data = self::read_json_file( self::get_file_path_from_theme( 'theme.json', true ) ); 169 $parent_theme_json_data = self::translate( $parent_theme_json_data, wp_get_theme()->parent()->get( 'TextDomain' ) ); 170 $parent_theme = new WP_Theme_JSON( $parent_theme_json_data ); 171 172 // Merge the child theme.json into the parent theme.json. 173 // The child theme takes precedence over the parent. 174 $parent_theme->merge( self::$theme ); 175 self::$theme = $parent_theme; 176 } 147 177 } 148 178 149 179 /* 150 * We want the presets and settings declared in theme.json 151 * to override the ones declared via add_theme_support. 152 */ 180 * We want the presets and settings declared in theme.json 181 * to override the ones declared via theme supports. 182 * So we take theme supports, transform it to theme.json shape 183 * and merge the self::$theme upon that. 184 */ 185 $theme_support_data = WP_Theme_JSON::get_from_editor_settings( get_default_block_editor_settings() ); 153 186 $with_theme_supports = new WP_Theme_JSON( $theme_support_data ); 154 187 $with_theme_supports->merge( self::$theme ); … … 158 191 159 192 /** 160 * There are different sources of data for a site: core and theme. 161 * 162 * While the getters {@link get_core_data}, {@link get_theme_data} return the raw data 163 * from the respective origins, this method merges them all together. 164 * 165 * If the same piece of data is declared in different origins (core and theme), 166 * the last origin overrides the previous. For example, if core disables custom colors 167 * but a theme enables them, the theme config wins. 168 * 169 * @since 5.8.0 170 * 171 * @param array $settings Optional. Existing block editor settings. Default empty array. 193 * Returns the CPT that contains the user's origin config 194 * for the current theme or a void array if none found. 195 * 196 * It can also create and return a new draft CPT. 197 * 198 * @since 5.9.0 199 * 200 * @param bool $should_create_cpt Optional. Whether a new CPT should be created if no one was found. 201 * False by default. 202 * @param array $post_status_filter Filter Optional. CPT by post status. 203 * ['publish'] by default, so it only fetches published posts. 204 * 205 * @return array Custom Post Type for the user's origin config. 206 */ 207 private static function get_user_data_from_custom_post_type( $should_create_cpt = false, $post_status_filter = array( 'publish' ) ) { 208 $user_cpt = array(); 209 $post_type_filter = 'wp_global_styles'; 210 $query = new WP_Query( 211 array( 212 'posts_per_page' => 1, 213 'orderby' => 'date', 214 'order' => 'desc', 215 'post_type' => $post_type_filter, 216 'post_status' => $post_status_filter, 217 'tax_query' => array( 218 array( 219 'taxonomy' => 'wp_theme', 220 'field' => 'name', 221 'terms' => wp_get_theme()->get_stylesheet(), 222 ), 223 ), 224 ) 225 ); 226 227 if ( is_array( $query->posts ) && ( 1 === $query->post_count ) ) { 228 $user_cpt = $query->posts[0]->to_array(); 229 } elseif ( $should_create_cpt ) { 230 $cpt_post_id = wp_insert_post( 231 array( 232 'post_content' => '{"version": ' . WP_Theme_JSON::LATEST_SCHEMA . ', "isGlobalStylesUserThemeJSON": true }', 233 'post_status' => 'publish', 234 'post_title' => __( 'Custom Styles', 'default' ), 235 'post_type' => $post_type_filter, 236 'post_name' => 'wp-global-styles-' . urlencode( wp_get_theme()->get_stylesheet() ), 237 'tax_input' => array( 238 'wp_theme' => array( wp_get_theme()->get_stylesheet() ), 239 ), 240 ), 241 true 242 ); 243 244 if ( is_wp_error( $cpt_post_id ) ) { 245 $user_cpt = array(); 246 } else { 247 $user_cpt = get_post( $cpt_post_id, ARRAY_A ); 248 } 249 } 250 251 return $user_cpt; 252 } 253 254 /** 255 * Returns the user's origin config. 256 * 257 * @since 5.9.0 258 * 259 * @return WP_Theme_JSON Entity that holds user data. 260 */ 261 public static function get_user_data() { 262 if ( null !== self::$user ) { 263 return self::$user; 264 } 265 266 $config = array(); 267 $user_cpt = self::get_user_data_from_custom_post_type(); 268 269 if ( array_key_exists( 'post_content', $user_cpt ) ) { 270 $decoded_data = json_decode( $user_cpt['post_content'], true ); 271 272 $json_decoding_error = json_last_error(); 273 if ( JSON_ERROR_NONE !== $json_decoding_error ) { 274 trigger_error( 'Error when decoding a theme.json schema for user data. ' . json_last_error_msg() ); 275 return new WP_Theme_JSON( $config, 'user' ); 276 } 277 278 // Very important to verify if the flag isGlobalStylesUserThemeJSON is true. 279 // If is not true the content was not escaped and is not safe. 280 if ( 281 is_array( $decoded_data ) && 282 isset( $decoded_data['isGlobalStylesUserThemeJSON'] ) && 283 $decoded_data['isGlobalStylesUserThemeJSON'] 284 ) { 285 unset( $decoded_data['isGlobalStylesUserThemeJSON'] ); 286 $config = $decoded_data; 287 } 288 } 289 self::$user = new WP_Theme_JSON( $config, 'user' ); 290 291 return self::$user; 292 } 293 294 /** 295 * There are three sources of data (origins) for a site: 296 * core, theme, and user. The user's has higher priority 297 * than the theme's, and the theme's higher than core's. 298 * 299 * Unlike the getters {@link get_core_data}, 300 * {@link get_theme_data}, and {@link get_user_data}, 301 * this method returns data after it has been merged 302 * with the previous origins. This means that if the same piece of data 303 * is declared in different origins (user, theme, and core), 304 * the last origin overrides the previous. 305 * 306 * For example, if the user has set a background color 307 * for the paragraph block, and the theme has done it as well, 308 * the user preference wins. 309 * 310 * @since 5.8.0 311 * @since 5.9.0 Add user data and change the arguments. 312 * 313 * @param string $origin Optional. To what level should we merge data. 314 * Valid values are 'theme' or 'user'. 315 * Default is 'user'. 172 316 * @return WP_Theme_JSON 173 317 */ 174 public static function get_merged_data( $settings = array() ) { 175 $theme_support_data = WP_Theme_JSON::get_from_editor_settings( $settings ); 318 public static function get_merged_data( $origin = 'user' ) { 319 if ( is_array( $origin ) ) { 320 _deprecated_argument( __FUNCTION__, '5.9' ); 321 } 176 322 177 323 $result = new WP_Theme_JSON(); 178 324 $result->merge( self::get_core_data() ); 179 $result->merge( self::get_theme_data( $theme_support_data ) ); 325 $result->merge( self::get_theme_data() ); 326 327 if ( 'user' === $origin ) { 328 $result->merge( self::get_user_data() ); 329 } 180 330 181 331 return $result; … … 183 333 184 334 /** 335 * Returns the ID of the custom post type 336 * that stores user data. 337 * 338 * @since 5.9.0 339 * 340 * @return integer|null 341 */ 342 public static function get_user_custom_post_type_id() { 343 if ( null !== self::$user_custom_post_type_id ) { 344 return self::$user_custom_post_type_id; 345 } 346 347 $user_cpt = self::get_user_data_from_custom_post_type( true ); 348 349 if ( array_key_exists( 'ID', $user_cpt ) ) { 350 self::$user_custom_post_type_id = $user_cpt['ID']; 351 } 352 353 return self::$user_custom_post_type_id; 354 } 355 356 /** 185 357 * Whether the current theme has a theme.json file. 186 358 * 187 359 * @since 5.8.0 360 * @since 5.9.0 Also check in the parent theme. 188 361 * 189 362 * @return bool … … 191 364 public static function theme_has_support() { 192 365 if ( ! isset( self::$theme_has_support ) ) { 193 self::$theme_has_support = (bool) self::get_file_path_from_theme( 'theme.json');366 self::$theme_has_support = is_readable( get_theme_file_path( 'theme.json' ) ); 194 367 } 195 368 … … 203 376 * 204 377 * @since 5.8.0 378 * @since 5.9.0 Adapt to work with child themes. 205 379 * 206 380 * @param string $file_name Name of the file. 381 * @param bool $template Optional. Use template theme directory. Default false. 207 382 * @return string The whole file path or empty if the file doesn't exist. 208 383 */ 209 private static function get_file_path_from_theme( $file_name ) { 210 /* 211 * This used to be a locate_template call. However, that method proved problematic 212 * due to its use of constants (STYLESHEETPATH) that threw errors in some scenarios. 213 * 214 * When the theme.json merge algorithm properly supports child themes, 215 * this should also fall back to the template path, as locate_template did. 216 */ 217 $located = ''; 218 $candidate = get_stylesheet_directory() . '/' . $file_name; 219 if ( is_readable( $candidate ) ) { 220 $located = $candidate; 221 } 222 return $located; 384 private static function get_file_path_from_theme( $file_name, $template = false ) { 385 $path = $template ? get_template_directory() : get_stylesheet_directory(); 386 $candidate = $path . '/' . $file_name; 387 388 return is_readable( $candidate ) ? $candidate : ''; 223 389 } 224 390 … … 227 393 * 228 394 * @since 5.8.0 395 * @since 5.9.0 Added new variables to reset. 229 396 */ 230 397 public static function clean_cached_data() { 231 self::$core = null; 232 self::$theme = null; 233 self::$theme_has_support = null; 398 self::$core = null; 399 self::$theme = null; 400 self::$user = null; 401 self::$user_custom_post_type_id = null; 402 self::$theme_has_support = null; 403 self::$i18n_schema = null; 234 404 } 235 405
Note: See TracChangeset
for help on using the changeset viewer.