PluginProbe
Gutenberg / 23.6.2
Gutenberg v23.6.2
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 / compat / wordpress-7.0 / blocks.php

blocks.php in Gutenberg 23.6.2, at lib/compat/wordpress-7.0/blocks.php

185 lines 6.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Compatibility shims for block APIs for WordPress 7.0.
4 *
5 * @package gutenberg
6 */
7
8 if ( ! function_exists( 'gutenberg_resolve_pattern_blocks' ) ) {
9 /**
10 * Replaces patterns in a block tree with their content.
11 *
12 * @since 6.6.0
13 * @since 7.0.0 Adds metadata to attributes of single-pattern container blocks.
14 *
15 * @param array $blocks An array blocks.
16 *
17 * @return array An array of blocks with patterns replaced by their content.
18 */
19 function gutenberg_resolve_pattern_blocks( $blocks ) {
20 static $inner_content;
21 // Keep track of seen references to avoid infinite loops.
22 static $seen_refs = array();
23 $i = 0;
24 while ( $i < count( $blocks ) ) {
25 if ( 'core/pattern' === $blocks[ $i ]['blockName'] ) {
26 $attrs = $blocks[ $i ]['attrs'];
27
28 if ( empty( $attrs['slug'] ) ) {
29 ++$i;
30 continue;
31 }
32
33 $slug = $attrs['slug'];
34
35 if ( isset( $seen_refs[ $slug ] ) ) {
36 // Skip recursive patterns.
37 array_splice( $blocks, $i, 1 );
38 continue;
39 }
40
41 $registry = WP_Block_Patterns_Registry::get_instance();
42 $pattern = $registry->get_registered( $slug );
43
44 // Skip unknown patterns.
45 if ( ! $pattern ) {
46 ++$i;
47 continue;
48 }
49 //////////////////////////////
50 // START CORE MODIFICATIONS //
51 //////////////////////////////
52 $blocks_to_insert = parse_blocks( trim( $pattern['content'] ) );
53
54 /*
55 * For single-root patterns, add the pattern name to make this a pattern instance in the editor.
56 * If the pattern has metadata, merge it with the existing metadata.
57 */
58 if ( count( $blocks_to_insert ) === 1 ) {
59 $block_metadata = $blocks_to_insert[0]['attrs']['metadata'] ?? array();
60 $block_metadata['patternName'] = $slug;
61
62 /*
63 * Merge pattern metadata with existing block metadata.
64 * Pattern metadata takes precedence, but existing block metadata
65 * is preserved as a fallback when the pattern doesn't define that field.
66 * Only the defined fields (name, description, categories) are updated;
67 * other metadata keys are preserved.
68 */
69 foreach ( array(
70 'name' => 'title', // 'title' is the field in the pattern object 'name' is the field in the block metadata.
71 'description' => 'description',
72 'categories' => 'categories',
73 ) as $key => $pattern_key ) {
74 $value = $pattern[ $pattern_key ] ?? $block_metadata[ $key ] ?? null;
75 if ( $value ) {
76 $block_metadata[ $key ] = is_array( $value )
77 ? array_map( 'sanitize_text_field', $value )
78 : sanitize_text_field( $value );
79 }
80 }
81
82 $blocks_to_insert[0]['attrs']['metadata'] = $block_metadata;
83 }
84 //////////////////////////////
85 // END CORE MODIFICATIONS //
86 //////////////////////////////
87
88 $seen_refs[ $slug ] = true;
89 $prev_inner_content = $inner_content;
90 $inner_content = null;
91 $blocks_to_insert = gutenberg_resolve_pattern_blocks( $blocks_to_insert );
92 $inner_content = $prev_inner_content;
93 unset( $seen_refs[ $slug ] );
94 array_splice( $blocks, $i, 1, $blocks_to_insert );
95
96 // If we have inner content, we need to insert nulls in the
97 // inner content array, otherwise serialize_blocks will skip
98 // blocks.
99 if ( $inner_content ) {
100 $null_indices = array_keys( $inner_content, null, true );
101 $content_index = $null_indices[ $i ];
102 $nulls = array_fill( 0, count( $blocks_to_insert ), null );
103 array_splice( $inner_content, $content_index, 1, $nulls );
104 }
105
106 // Skip inserted blocks.
107 $i += count( $blocks_to_insert );
108 } else {
109 if ( ! empty( $blocks[ $i ]['innerBlocks'] ) ) {
110 $prev_inner_content = $inner_content;
111 $inner_content = $blocks[ $i ]['innerContent'];
112 $blocks[ $i ]['innerBlocks'] = gutenberg_resolve_pattern_blocks(
113 $blocks[ $i ]['innerBlocks']
114 );
115 $blocks[ $i ]['innerContent'] = $inner_content;
116 $inner_content = $prev_inner_content;
117 }
118 ++$i;
119 }
120 }
121 return $blocks;
122 }
123 }
124
125 /**
126 * Update Query Loop's `taxQuery` prop to the new structure.
127 *
128 * @see 'query_loop_block_query_vars'
129 *
130 * @param array $query The query vars.
131 * @param WP_Block $block Block instance.
132 * @return array The filtered query vars.
133 */
134 function gutenberg_update_tax_query_of_query_loop_block( $query, $block ) {
135 if ( empty( $block->context['query']['taxQuery'] ) ) {
136 return $query;
137 }
138
139 // If there are keys other than include/exclude, it's the old
140 // format and has been handled already.
141 if ( ! is_array( $block->context['query']['taxQuery'] ) || ! empty( array_diff( array_keys( $block->context['query']['taxQuery'] ), array( 'include', 'exclude' ) ) ) ) {
142 return $query;
143 }
144
145 // Build with the new structure.
146 $tax_query_input = $block->context['query']['taxQuery'];
147
148 // Helper function to build tax_query conditions from taxonomy terms.
149 $build_conditions = static function ( $terms, $operator = 'IN' ) {
150 $conditions = array();
151 foreach ( $terms as $taxonomy => $terms ) {
152 if ( ! empty( $terms ) && is_taxonomy_viewable( $taxonomy ) ) {
153 $conditions[] = array(
154 'taxonomy' => $taxonomy,
155 'terms' => array_filter( array_map( 'intval', $terms ) ),
156 'operator' => $operator,
157 'include_children' => false,
158 );
159 }
160 }
161 return $conditions;
162 };
163 // Separate exclude from include terms.
164 $exclude_terms = isset( $tax_query_input['exclude'] ) && is_array( $tax_query_input['exclude'] )
165 ? $tax_query_input['exclude']
166 : array();
167 $include_terms = isset( $tax_query_input['include'] ) && is_array( $tax_query_input['include'] )
168 ? $tax_query_input['include']
169 : array();
170
171 $tax_query = array_merge(
172 $build_conditions( $include_terms ),
173 $build_conditions( $exclude_terms, 'NOT IN' )
174 );
175
176 if ( ! empty( $tax_query ) ) {
177 // Merge with any existing `tax_query` conditions.
178 $query['tax_query'] = array_merge( $query['tax_query'], $tax_query );
179 }
180
181 return $query;
182 }
183
184 add_filter( 'query_loop_block_query_vars', 'gutenberg_update_tax_query_of_query_loop_block', 10, 2 );
185