PluginProbe
Gutenberg / 23.4.0
Gutenberg v23.4.0
23.9.1 23.9.0 23.8.0 23.7.2 23.7.1 23.7.0 23.6.1 23.6.2 23.6.0 23.5.3 23.5.2 23.5.1 23.5.0 23.4.0 23.3.2 23.3.1 23.3.0 23.2.0 23.2.1 23.2.2 23.1.1 23.1.0 23.0.1 12.6.0 7.4.0 All 402 releases
gutenberg / lib / class-wp-theme-json-schema-gutenberg.php

class-wp-theme-json-schema-gutenberg.php in Gutenberg 23.4.0, at lib/class-wp-theme-json-schema-gutenberg.php

234 lines 7.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * WP_Theme_JSON_Schema_Gutenberg class
4 *
5 * @package gutenberg
6 * @since 5.9.0
7 */
8
9 if ( class_exists( 'WP_Theme_JSON_Schema_Gutenberg' ) ) {
10 return;
11 }
12
13 /**
14 * Class that migrates a given theme.json structure to the latest schema.
15 *
16 * This class is for internal core usage and is not supposed to be used by extenders (plugins and/or themes).
17 * This is a low-level API that may need to do breaking changes. Please,
18 * use get_global_settings, get_global_styles, and get_global_stylesheet instead.
19 *
20 * @since 5.9.0
21 * @access private
22 */
23 #[AllowDynamicProperties]
24 class WP_Theme_JSON_Schema_Gutenberg {
25
26 /**
27 * Maps old properties to their new location within the schema's settings.
28 * This will be applied at both the defaults and individual block levels.
29 */
30 const V1_TO_V2_RENAMED_PATHS = array(
31 'border.customRadius' => 'border.radius',
32 'spacing.customMargin' => 'spacing.margin',
33 'spacing.customPadding' => 'spacing.padding',
34 'typography.customLineHeight' => 'typography.lineHeight',
35 );
36
37 /**
38 * Function that migrates a given theme.json structure to the last version.
39 *
40 * @since 5.9.0
41 * @since 6.6.0 Migrate up to v3.
42 *
43 * @param array $theme_json The structure to migrate.
44 * @param string $origin Optional. What source of data this object represents.
45 * One of 'blocks', 'default', 'theme', or 'custom'. Default 'theme'.
46 *
47 * @return array The structure in the last version.
48 */
49 public static function migrate( $theme_json, $origin = 'theme' ) {
50 if ( ! isset( $theme_json['version'] ) ) {
51 $theme_json = array(
52 'version' => WP_Theme_JSON_Gutenberg::LATEST_SCHEMA,
53 );
54 }
55
56 // Migrate each version in order starting with the current version.
57 switch ( $theme_json['version'] ) {
58 case 1:
59 $theme_json = self::migrate_v1_to_v2( $theme_json );
60 // Deliberate fall through. Once migrated to v2, also migrate to v3.
61 case 2:
62 $theme_json = self::migrate_v2_to_v3( $theme_json, $origin );
63 }
64
65 return $theme_json;
66 }
67
68 /**
69 * Removes the custom prefixes for a few properties
70 * that were part of v1:
71 *
72 * 'border.customRadius' => 'border.radius',
73 * 'spacing.customMargin' => 'spacing.margin',
74 * 'spacing.customPadding' => 'spacing.padding',
75 * 'typography.customLineHeight' => 'typography.lineHeight',
76 *
77 * @since 5.9.0
78 *
79 * @param array $old Data to migrate.
80 *
81 * @return array Data without the custom prefixes.
82 */
83 private static function migrate_v1_to_v2( $old ) {
84 // Copy everything.
85 $new = $old;
86
87 // Overwrite the things that changed.
88 if ( isset( $old['settings'] ) ) {
89 $new['settings'] = self::rename_paths( $old['settings'], self::V1_TO_V2_RENAMED_PATHS );
90 }
91
92 // Set the new version.
93 $new['version'] = 2;
94
95 return $new;
96 }
97
98 /**
99 * Migrates from v2 to v3.
100 *
101 * - Sets settings.typography.defaultFontSizes to false if settings.typography.fontSizes are defined.
102 * - Sets settings.spacing.defaultSpacingSizes to false if settings.spacing.spacingSizes are defined.
103 * - Prevents settings.spacing.spacingSizes from merging with settings.spacing.spacingScale by
104 * unsetting spacingScale when spacingSizes are defined.
105 *
106 * @since 6.6.0
107 *
108 * @param array $old Data to migrate.
109 * @param string $origin What source of data this object represents.
110 * One of 'blocks', 'default', 'theme', or 'custom'.
111 * @return array Data with defaultFontSizes set to false.
112 */
113 private static function migrate_v2_to_v3( $old, $origin ) {
114 // Copy everything.
115 $new = $old;
116
117 // Set the new version.
118 $new['version'] = 3;
119
120 /*
121 * Remaining changes do not need to be applied to the custom origin,
122 * as they should take on the value of the theme origin.
123 */
124 if ( 'custom' === $origin ) {
125 return $new;
126 }
127
128 /*
129 * Even though defaultFontSizes is a new setting, we need to migrate
130 * it as it controls the PRESETS_METADATA prevent_override which was
131 * previously hardcoded to false. This only needs to happen when the
132 * theme provided font sizes as they could match the default ones and
133 * affect the generated CSS. And in v2 we provided default font sizes
134 * when the theme did not provide any.
135 */
136 if ( isset( $old['settings']['typography']['fontSizes'] ) ) {
137 $new['settings']['typography']['defaultFontSizes'] = false;
138 }
139
140 /*
141 * Similarly to defaultFontSizes, we need to migrate defaultSpacingSizes
142 * as it controls the PRESETS_METADATA prevent_override which was
143 * previously hardcoded to false. This only needs to happen when the
144 * theme provided spacing sizes via spacingSizes or spacingScale.
145 */
146 if (
147 isset( $old['settings']['spacing']['spacingSizes'] ) ||
148 isset( $old['settings']['spacing']['spacingScale'] )
149 ) {
150 $new['settings']['spacing']['defaultSpacingSizes'] = false;
151 }
152
153 /*
154 * In v3 spacingSizes is merged with the generated spacingScale sizes
155 * instead of completely replacing them. The v3 behavior is what was
156 * documented for the v2 schema, but the code never actually did work
157 * that way. Instead of surprising users with a behavior change two
158 * years after the fact at the same time as a v3 update is introduced,
159 * we'll continue using the "bugged" behavior for v2 themes. And treat
160 * the "bug fix" as a breaking change for v3.
161 */
162 if ( isset( $old['settings']['spacing']['spacingSizes'] ) ) {
163 unset( $new['settings']['spacing']['spacingScale'] );
164 }
165
166 return $new;
167 }
168
169 /**
170 * Processes the settings subtree.
171 *
172 * @since 5.9.0
173 *
174 * @param array $settings Array to process.
175 * @param array $paths_to_rename Paths to rename.
176 *
177 * @return array The settings in the new format.
178 */
179 private static function rename_paths( $settings, $paths_to_rename ) {
180 $new_settings = $settings;
181
182 // Process any renamed/moved paths within default settings.
183 self::rename_settings( $new_settings, $paths_to_rename );
184
185 // Process individual block settings.
186 if ( isset( $new_settings['blocks'] ) && is_array( $new_settings['blocks'] ) ) {
187 foreach ( $new_settings['blocks'] as &$block_settings ) {
188 self::rename_settings( $block_settings, $paths_to_rename );
189 }
190 }
191
192 return $new_settings;
193 }
194
195 /**
196 * Processes a settings array, renaming or moving properties.
197 *
198 * @since 5.9.0
199 *
200 * @param array $settings Reference to settings either defaults or an individual block's.
201 * @param array $paths_to_rename Paths to rename.
202 */
203 private static function rename_settings( &$settings, $paths_to_rename ) {
204 foreach ( $paths_to_rename as $original => $renamed ) {
205 $original_path = explode( '.', $original );
206 $renamed_path = explode( '.', $renamed );
207 $current_value = _wp_array_get( $settings, $original_path, null );
208
209 if ( null !== $current_value ) {
210 _wp_array_set( $settings, $renamed_path, $current_value );
211 self::unset_setting_by_path( $settings, $original_path );
212 }
213 }
214 }
215
216 /**
217 * Removes a property from within the provided settings by its path.
218 *
219 * @since 5.9.0
220 *
221 * @param array $settings Reference to the current settings array.
222 * @param array $path Path to the property to be removed.
223 */
224 private static function unset_setting_by_path( &$settings, $path ) {
225 $tmp_settings = &$settings; // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
226 $last_key = array_pop( $path );
227 foreach ( $path as $key ) {
228 $tmp_settings = &$tmp_settings[ $key ];
229 }
230
231 unset( $tmp_settings[ $last_key ] );
232 }
233 }
234