diff options
Diffstat (limited to 'wp-includes/class-wp-theme-json-schema.php')
-rw-r--r-- | wp-includes/class-wp-theme-json-schema.php | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/wp-includes/class-wp-theme-json-schema.php b/wp-includes/class-wp-theme-json-schema.php new file mode 100644 index 0000000..46712a0 --- /dev/null +++ b/wp-includes/class-wp-theme-json-schema.php @@ -0,0 +1,151 @@ +<?php +/** + * WP_Theme_JSON_Schema class + * + * @package WordPress + * @subpackage Theme + * @since 5.9.0 + */ + +/** + * Class that migrates a given theme.json structure to the latest schema. + * + * This class is for internal core usage and is not supposed to be used by extenders (plugins and/or themes). + * This is a low-level API that may need to do breaking changes. Please, + * use get_global_settings, get_global_styles, and get_global_stylesheet instead. + * + * @since 5.9.0 + * @access private + */ +#[AllowDynamicProperties] +class WP_Theme_JSON_Schema { + + /** + * Maps old properties to their new location within the schema's settings. + * This will be applied at both the defaults and individual block levels. + */ + const V1_TO_V2_RENAMED_PATHS = array( + 'border.customRadius' => 'border.radius', + 'spacing.customMargin' => 'spacing.margin', + 'spacing.customPadding' => 'spacing.padding', + 'typography.customLineHeight' => 'typography.lineHeight', + ); + + /** + * Function that migrates a given theme.json structure to the last version. + * + * @since 5.9.0 + * + * @param array $theme_json The structure to migrate. + * + * @return array The structure in the last version. + */ + public static function migrate( $theme_json ) { + if ( ! isset( $theme_json['version'] ) ) { + $theme_json = array( + 'version' => WP_Theme_JSON::LATEST_SCHEMA, + ); + } + + if ( 1 === $theme_json['version'] ) { + $theme_json = self::migrate_v1_to_v2( $theme_json ); + } + + return $theme_json; + } + + /** + * Removes the custom prefixes for a few properties + * that were part of v1: + * + * 'border.customRadius' => 'border.radius', + * 'spacing.customMargin' => 'spacing.margin', + * 'spacing.customPadding' => 'spacing.padding', + * 'typography.customLineHeight' => 'typography.lineHeight', + * + * @since 5.9.0 + * + * @param array $old Data to migrate. + * + * @return array Data without the custom prefixes. + */ + private static function migrate_v1_to_v2( $old ) { + // Copy everything. + $new = $old; + + // Overwrite the things that changed. + if ( isset( $old['settings'] ) ) { + $new['settings'] = self::rename_paths( $old['settings'], self::V1_TO_V2_RENAMED_PATHS ); + } + + // Set the new version. + $new['version'] = 2; + + return $new; + } + + /** + * Processes the settings subtree. + * + * @since 5.9.0 + * + * @param array $settings Array to process. + * @param array $paths_to_rename Paths to rename. + * + * @return array The settings in the new format. + */ + private static function rename_paths( $settings, $paths_to_rename ) { + $new_settings = $settings; + + // Process any renamed/moved paths within default settings. + self::rename_settings( $new_settings, $paths_to_rename ); + + // Process individual block settings. + if ( isset( $new_settings['blocks'] ) && is_array( $new_settings['blocks'] ) ) { + foreach ( $new_settings['blocks'] as &$block_settings ) { + self::rename_settings( $block_settings, $paths_to_rename ); + } + } + + return $new_settings; + } + + /** + * Processes a settings array, renaming or moving properties. + * + * @since 5.9.0 + * + * @param array $settings Reference to settings either defaults or an individual block's. + * @param array $paths_to_rename Paths to rename. + */ + private static function rename_settings( &$settings, $paths_to_rename ) { + foreach ( $paths_to_rename as $original => $renamed ) { + $original_path = explode( '.', $original ); + $renamed_path = explode( '.', $renamed ); + $current_value = _wp_array_get( $settings, $original_path, null ); + + if ( null !== $current_value ) { + _wp_array_set( $settings, $renamed_path, $current_value ); + self::unset_setting_by_path( $settings, $original_path ); + } + } + } + + /** + * Removes a property from within the provided settings by its path. + * + * @since 5.9.0 + * + * @param array $settings Reference to the current settings array. + * @param array $path Path to the property to be removed. + */ + private static function unset_setting_by_path( &$settings, $path ) { + $tmp_settings = &$settings; + $last_key = array_pop( $path ); + foreach ( $path as $key ) { + $tmp_settings = &$tmp_settings[ $key ]; + } + + unset( $tmp_settings[ $last_key ] ); + } +} |