15
15
* @access private
16
16
*/
17
17
class WP_Theme_JSON_Gutenberg extends WP_Theme_JSON_5_9 {
18
-
19
18
/**
20
19
* The top-level keys a theme.json can have.
21
20
*
@@ -32,16 +31,62 @@ class WP_Theme_JSON_Gutenberg extends WP_Theme_JSON_5_9 {
32
31
);
33
32
34
33
/**
35
- * Returns the current theme's wanted patterns(slugs) to be
36
- * registered from Pattern Directory.
34
+ * Sanitizes the input according to the schemas.
37
35
*
38
- * @return array
36
+ * @param array $input Structure to sanitize.
37
+ * @param array $valid_block_names List of valid block names.
38
+ * @param array $valid_element_names List of valid element names.
39
+ * @return array The sanitized output.
39
40
*/
40
- public function get_patterns () {
41
- if ( isset ( $ this ->theme_json ['patterns ' ] ) && is_array ( $ this ->theme_json ['patterns ' ] ) ) {
42
- return $ this ->theme_json ['patterns ' ];
41
+ protected static function sanitize ( $ input , $ valid_block_names , $ valid_element_names ) {
42
+ $ output = array ();
43
+
44
+ if ( ! is_array ( $ input ) ) {
45
+ return $ output ;
43
46
}
44
- return array ();
47
+
48
+ $ output = array_intersect_key ( $ input , array_flip ( static ::VALID_TOP_LEVEL_KEYS ) );
49
+
50
+ // Build the schema based on valid block & element names.
51
+ $ schema = array ();
52
+ $ schema_styles_elements = array ();
53
+ foreach ( $ valid_element_names as $ element ) {
54
+ $ schema_styles_elements [ $ element ] = static ::VALID_STYLES ;
55
+ }
56
+ $ schema_styles_blocks = array ();
57
+ $ schema_settings_blocks = array ();
58
+ foreach ( $ valid_block_names as $ block ) {
59
+ $ schema_settings_blocks [ $ block ] = static ::VALID_SETTINGS ;
60
+ $ schema_styles_blocks [ $ block ] = static ::VALID_STYLES ;
61
+ $ schema_styles_blocks [ $ block ]['elements ' ] = $ schema_styles_elements ;
62
+ }
63
+ $ schema ['styles ' ] = static ::VALID_STYLES ;
64
+ $ schema ['styles ' ]['blocks ' ] = $ schema_styles_blocks ;
65
+ $ schema ['styles ' ]['elements ' ] = $ schema_styles_elements ;
66
+ $ schema ['settings ' ] = static ::VALID_SETTINGS ;
67
+ $ schema ['settings ' ]['blocks ' ] = $ schema_settings_blocks ;
68
+
69
+ // Remove anything that's not present in the schema.
70
+ foreach ( array ( 'styles ' , 'settings ' ) as $ subtree ) {
71
+ if ( ! isset ( $ input [ $ subtree ] ) ) {
72
+ continue ;
73
+ }
74
+
75
+ if ( ! is_array ( $ input [ $ subtree ] ) ) {
76
+ unset( $ output [ $ subtree ] );
77
+ continue ;
78
+ }
79
+
80
+ $ result = static ::remove_keys_not_in_schema ( $ input [ $ subtree ], $ schema [ $ subtree ] );
81
+
82
+ if ( empty ( $ result ) ) {
83
+ unset( $ output [ $ subtree ] );
84
+ } else {
85
+ $ output [ $ subtree ] = $ result ;
86
+ }
87
+ }
88
+
89
+ return $ output ;
45
90
}
46
91
47
92
/**
@@ -62,6 +107,7 @@ public function get_patterns() {
62
107
protected function get_block_classes ( $ style_nodes ) {
63
108
$ block_rules = '' ;
64
109
110
+
65
111
foreach ( $ style_nodes as $ metadata ) {
66
112
if ( null === $ metadata ['selector ' ] ) {
67
113
continue ;
@@ -70,7 +116,7 @@ protected function get_block_classes( $style_nodes ) {
70
116
$ node = _wp_array_get ( $ this ->theme_json , $ metadata ['path ' ], array () );
71
117
$ selector = $ metadata ['selector ' ];
72
118
$ settings = _wp_array_get ( $ this ->theme_json , array ( 'settings ' ) );
73
- $ declarations = static ::compute_style_properties ( $ node , $ settings );
119
+ $ declarations = static ::compute_style_properties ( $ node , $ settings, null , $ metadata [ ' selector ' ] );
74
120
75
121
// 1. Separate the ones who use the general selector
76
122
// and the ones who use the duotone selector.
@@ -119,6 +165,69 @@ protected function get_block_classes( $style_nodes ) {
119
165
return $ block_rules ;
120
166
}
121
167
168
+ /**
169
+ * Given a styles array, it extracts the style properties
170
+ * and adds them to the $declarations array following the format:
171
+ *
172
+ * ```php
173
+ * array(
174
+ * 'name' => 'property_name',
175
+ * 'value' => 'property_value,
176
+ * )
177
+ * ```
178
+ *
179
+ * @param array $styles Styles to process.
180
+ * @param array $settings Theme settings.
181
+ * @param array $properties Properties metadata.
182
+ * @param string|null $selector Current selector.
183
+ * @return array Returns the modified $declarations.
184
+ */
185
+ protected static function compute_style_properties ( $ styles , $ settings = array (), $ properties = null , $ selector = null ) {
186
+ if ( null === $ properties ) {
187
+ $ properties = static ::PROPERTIES_METADATA ;
188
+ }
189
+
190
+ $ declarations = array ();
191
+ if ( empty ( $ styles ) ) {
192
+ return $ declarations ;
193
+ }
194
+
195
+ foreach ( $ properties as $ css_property => $ value_path ) {
196
+ // Some styles such as blockGap are only meant to be available at the top level (ROOT_BLOCK_SELECTOR),
197
+ // hence we only output styles at the top level.
198
+ if ( 'top ' === _wp_array_get ( self ::VALID_STYLES , array ( $ value_path [0 ], $ value_path [1 ] ), null ) && static ::ROOT_BLOCK_SELECTOR !== $ selector ) {
199
+ continue ;
200
+ }
201
+
202
+ $ value = static ::get_property_value ( $ styles , $ value_path );
203
+
204
+ // Look up protected properties, keyed by value path.
205
+ // Skip protected properties that are explicitly set to `null`.
206
+ if ( is_array ( $ value_path ) ) {
207
+ $ path_string = implode ( '. ' , $ value_path );
208
+ if (
209
+ array_key_exists ( $ path_string , static ::PROTECTED_PROPERTIES ) &&
210
+ _wp_array_get ( $ settings , static ::PROTECTED_PROPERTIES [ $ path_string ], null ) === null
211
+ ) {
212
+ continue ;
213
+ }
214
+ }
215
+
216
+ // Skip if empty and not "0" or value represents array of longhand values.
217
+ $ has_missing_value = empty ( $ value ) && ! is_numeric ( $ value );
218
+ if ( $ has_missing_value || is_array ( $ value ) ) {
219
+ continue ;
220
+ }
221
+
222
+ $ declarations [] = array (
223
+ 'name ' => $ css_property ,
224
+ 'value ' => $ value ,
225
+ );
226
+ }
227
+
228
+ return $ declarations ;
229
+ }
230
+
122
231
/**
123
232
* Returns a valid theme.json for a theme.
124
233
* Essentially, it flattens the preset data.
@@ -162,4 +271,16 @@ public function get_data() {
162
271
return $ flattened_theme_json ;
163
272
}
164
273
274
+ /**
275
+ * Returns the current theme's wanted patterns(slugs) to be
276
+ * registered from Pattern Directory.
277
+ *
278
+ * @return array
279
+ */
280
+ public function get_patterns () {
281
+ if ( isset ( $ this ->theme_json ['patterns ' ] ) && is_array ( $ this ->theme_json ['patterns ' ] ) ) {
282
+ return $ this ->theme_json ['patterns ' ];
283
+ }
284
+ return array ();
285
+ }
165
286
}
0 commit comments