wp/wp-includes/class-wp-theme-json-schema.php
changeset 19 3d72ae0968f4
child 21 48c4eec2b7e6
equal deleted inserted replaced
18:be944660c56a 19:3d72ae0968f4
       
     1 <?php
       
     2 /**
       
     3  * WP_Theme_JSON_Schema class
       
     4  *
       
     5  * @package WordPress
       
     6  * @subpackage Theme
       
     7  * @since 5.9.0
       
     8  */
       
     9 
       
    10 /**
       
    11  * Class that migrates a given theme.json structure to the latest schema.
       
    12  *
       
    13  * This class is for internal core usage and is not supposed to be used by extenders (plugins and/or themes).
       
    14  * This is a low-level API that may need to do breaking changes. Please,
       
    15  * use get_global_settings, get_global_styles, and get_global_stylesheet instead.
       
    16  *
       
    17  * @since 5.9.0
       
    18  * @access private
       
    19  */
       
    20 class WP_Theme_JSON_Schema {
       
    21 
       
    22 	/**
       
    23 	 * Maps old properties to their new location within the schema's settings.
       
    24 	 * This will be applied at both the defaults and individual block levels.
       
    25 	 */
       
    26 	const V1_TO_V2_RENAMED_PATHS = array(
       
    27 		'border.customRadius'         => 'border.radius',
       
    28 		'spacing.customMargin'        => 'spacing.margin',
       
    29 		'spacing.customPadding'       => 'spacing.padding',
       
    30 		'typography.customLineHeight' => 'typography.lineHeight',
       
    31 	);
       
    32 
       
    33 	/**
       
    34 	 * Function that migrates a given theme.json structure to the last version.
       
    35 	 *
       
    36 	 * @since 5.9.0
       
    37 	 *
       
    38 	 * @param array $theme_json The structure to migrate.
       
    39 	 *
       
    40 	 * @return array The structure in the last version.
       
    41 	 */
       
    42 	public static function migrate( $theme_json ) {
       
    43 		if ( ! isset( $theme_json['version'] ) ) {
       
    44 			$theme_json = array(
       
    45 				'version' => WP_Theme_JSON::LATEST_SCHEMA,
       
    46 			);
       
    47 		}
       
    48 
       
    49 		if ( 1 === $theme_json['version'] ) {
       
    50 			$theme_json = self::migrate_v1_to_v2( $theme_json );
       
    51 		}
       
    52 
       
    53 		return $theme_json;
       
    54 	}
       
    55 
       
    56 	/**
       
    57 	 * Removes the custom prefixes for a few properties
       
    58 	 * that were part of v1:
       
    59 	 *
       
    60 	 * 'border.customRadius'         => 'border.radius',
       
    61 	 * 'spacing.customMargin'        => 'spacing.margin',
       
    62 	 * 'spacing.customPadding'       => 'spacing.padding',
       
    63 	 * 'typography.customLineHeight' => 'typography.lineHeight',
       
    64 	 *
       
    65 	 * @since 5.9.0
       
    66 	 *
       
    67 	 * @param array $old Data to migrate.
       
    68 	 *
       
    69 	 * @return array Data without the custom prefixes.
       
    70 	 */
       
    71 	private static function migrate_v1_to_v2( $old ) {
       
    72 		// Copy everything.
       
    73 		$new = $old;
       
    74 
       
    75 		// Overwrite the things that changed.
       
    76 		if ( isset( $old['settings'] ) ) {
       
    77 			$new['settings'] = self::rename_paths( $old['settings'], self::V1_TO_V2_RENAMED_PATHS );
       
    78 		}
       
    79 
       
    80 		// Set the new version.
       
    81 		$new['version'] = 2;
       
    82 
       
    83 		return $new;
       
    84 	}
       
    85 
       
    86 	/**
       
    87 	 * Processes the settings subtree.
       
    88 	 *
       
    89 	 * @since 5.9.0
       
    90 	 *
       
    91 	 * @param array $settings        Array to process.
       
    92 	 * @param array $paths_to_rename Paths to rename.
       
    93 	 *
       
    94 	 * @return array The settings in the new format.
       
    95 	 */
       
    96 	private static function rename_paths( $settings, $paths_to_rename ) {
       
    97 		$new_settings = $settings;
       
    98 
       
    99 		// Process any renamed/moved paths within default settings.
       
   100 		self::rename_settings( $new_settings, $paths_to_rename );
       
   101 
       
   102 		// Process individual block settings.
       
   103 		if ( isset( $new_settings['blocks'] ) && is_array( $new_settings['blocks'] ) ) {
       
   104 			foreach ( $new_settings['blocks'] as &$block_settings ) {
       
   105 				self::rename_settings( $block_settings, $paths_to_rename );
       
   106 			}
       
   107 		}
       
   108 
       
   109 		return $new_settings;
       
   110 	}
       
   111 
       
   112 	/**
       
   113 	 * Processes a settings array, renaming or moving properties.
       
   114 	 *
       
   115 	 * @since 5.9.0
       
   116 	 *
       
   117 	 * @param array $settings        Reference to settings either defaults or an individual block's.
       
   118 	 * @param array $paths_to_rename Paths to rename.
       
   119 	 */
       
   120 	private static function rename_settings( &$settings, $paths_to_rename ) {
       
   121 		foreach ( $paths_to_rename as $original => $renamed ) {
       
   122 			$original_path = explode( '.', $original );
       
   123 			$renamed_path  = explode( '.', $renamed );
       
   124 			$current_value = _wp_array_get( $settings, $original_path, null );
       
   125 
       
   126 			if ( null !== $current_value ) {
       
   127 				_wp_array_set( $settings, $renamed_path, $current_value );
       
   128 				self::unset_setting_by_path( $settings, $original_path );
       
   129 			}
       
   130 		}
       
   131 	}
       
   132 
       
   133 	/**
       
   134 	 * Removes a property from within the provided settings by its path.
       
   135 	 *
       
   136 	 * @since 5.9.0
       
   137 	 *
       
   138 	 * @param array $settings Reference to the current settings array.
       
   139 	 * @param array $path Path to the property to be removed.
       
   140 	 *
       
   141 	 * @return void
       
   142 	 */
       
   143 	private static function unset_setting_by_path( &$settings, $path ) {
       
   144 		$tmp_settings = &$settings; // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
       
   145 		$last_key     = array_pop( $path );
       
   146 		foreach ( $path as $key ) {
       
   147 			$tmp_settings = &$tmp_settings[ $key ];
       
   148 		}
       
   149 
       
   150 		unset( $tmp_settings[ $last_key ] );
       
   151 	}
       
   152 }