PluginProbe
Gutenberg / 8.3.0
Gutenberg v8.3.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 / compat.php

compat.php in Gutenberg 8.3.0, at lib/compat.php

294 lines 9.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Temporary compatibility shims for features present in Gutenberg, pending
4 * upstream commit to the WordPress core source repository. Functions here
5 * exist only as long as necessary for corresponding WordPress support, and
6 * each should be associated with a Trac ticket.
7 *
8 * @package gutenberg
9 */
10
11 if ( ! function_exists( 'register_block_type_from_metadata' ) ) {
12 /**
13 * Registers a block type from metadata stored in the `block.json` file.
14 *
15 * @since 7.9.0
16 *
17 * @param string $file_or_folder Path to the JSON file with metadata definition for
18 * the block or path to the folder where the `block.json` file is located.
19 * @param array $args {
20 * Optional. Array of block type arguments. Any arguments may be defined, however the
21 * ones described below are supported by default. Default empty array.
22 *
23 * @type callable $render_callback Callback used to render blocks of this block type.
24 * }
25 * @return WP_Block_Type|false The registered block type on success, or false on failure.
26 */
27 function register_block_type_from_metadata( $file_or_folder, $args = array() ) {
28 $file = ( substr( $file_or_folder, -10 ) !== 'block.json' ) ?
29 trailingslashit( $file_or_folder ) . 'block.json' :
30 $file_or_folder;
31 if ( ! file_exists( $file ) ) {
32 return false;
33 }
34
35 $metadata = json_decode( file_get_contents( $file ), true );
36 if ( ! is_array( $metadata ) ) {
37 return false;
38 }
39
40 return register_block_type(
41 $metadata['name'],
42 array_merge(
43 $metadata,
44 $args
45 )
46 );
47 }
48 }
49
50 /**
51 * Extends block editor settings to include a list of image dimensions per size.
52 *
53 * This can be removed when plugin support requires WordPress 5.4.0+.
54 *
55 * @see https://core.trac.wordpress.org/ticket/49389
56 * @see https://core.trac.wordpress.org/changeset/47240
57 *
58 * @param array $settings Default editor settings.
59 *
60 * @return array Filtered editor settings.
61 */
62 function gutenberg_extend_settings_image_dimensions( $settings ) {
63 /*
64 * Only filter settings if:
65 * 1. `imageDimensions` is not already assigned, in which case it can be
66 * assumed to have been set from WordPress 5.4.0+ default settings.
67 * 2. `imageSizes` is an array. Plugins may run `block_editor_settings`
68 * directly and not provide all properties of the settings array.
69 */
70 if ( ! isset( $settings['imageDimensions'] ) && ! empty( $settings['imageSizes'] ) ) {
71 $image_dimensions = array();
72 $all_sizes = wp_get_registered_image_subsizes();
73 foreach ( $settings['imageSizes'] as $size ) {
74 $key = $size['slug'];
75 if ( isset( $all_sizes[ $key ] ) ) {
76 $image_dimensions[ $key ] = $all_sizes[ $key ];
77 }
78 }
79 $settings['imageDimensions'] = $image_dimensions;
80 }
81
82 return $settings;
83 }
84 add_filter( 'block_editor_settings', 'gutenberg_extend_settings_image_dimensions' );
85
86 /**
87 * Adds a polyfill for the WHATWG URL in environments which do not support it.
88 * The intention in how this action is handled is under the assumption that this
89 * code would eventually be placed at `wp_default_packages_vendor`, which is
90 * called as a result of `wp_default_packages` via the `wp_default_scripts`.
91 *
92 * This can be removed when plugin support requires WordPress 5.4.0+.
93 *
94 * The script registration occurs in `gutenberg_register_vendor_scripts`, which
95 * should be removed in coordination with this function.
96 *
97 * @see gutenberg_register_vendor_scripts
98 * @see https://core.trac.wordpress.org/ticket/49360
99 * @see https://developer.mozilla.org/en-US/docs/Web/API/URL/URL
100 * @see https://developer.wordpress.org/reference/functions/wp_default_packages_vendor/
101 *
102 * @since 7.3.0
103 *
104 * @param WP_Scripts $scripts WP_Scripts object.
105 */
106 function gutenberg_add_url_polyfill( $scripts ) {
107 did_action( 'init' ) && $scripts->add_inline_script(
108 'wp-polyfill',
109 wp_get_script_polyfill(
110 $scripts,
111 array(
112 'window.URL && window.URL.prototype && window.URLSearchParams' => 'wp-polyfill-url',
113 )
114 )
115 );
116 }
117 add_action( 'wp_default_scripts', 'gutenberg_add_url_polyfill', 20 );
118
119 /**
120 * Adds a polyfill for DOMRect in environments which do not support it.
121 *
122 * This can be removed when plugin support requires WordPress 5.4.0+.
123 *
124 * The script registration occurs in `gutenberg_register_vendor_scripts`, which
125 * should be removed in coordination with this function.
126 *
127 * @see gutenberg_register_vendor_scripts
128 * @see gutenberg_add_url_polyfill
129 * @see https://core.trac.wordpress.org/ticket/49360
130 * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMRect
131 * @see https://developer.wordpress.org/reference/functions/wp_default_packages_vendor/
132 *
133 * @since 7.5.0
134 *
135 * @param WP_Scripts $scripts WP_Scripts object.
136 */
137 function gutenberg_add_dom_rect_polyfill( $scripts ) {
138 did_action( 'init' ) && $scripts->add_inline_script(
139 'wp-polyfill',
140 wp_get_script_polyfill(
141 $scripts,
142 array(
143 'window.DOMRect' => 'wp-polyfill-dom-rect',
144 )
145 )
146 );
147 }
148 add_action( 'wp_default_scripts', 'gutenberg_add_dom_rect_polyfill', 20 );
149
150 /**
151 * Sets the current post for usage in template blocks.
152 *
153 * @return WP_Post|null The post if any, or null otherwise.
154 */
155 function gutenberg_get_post_from_context() {
156 // TODO: Without this temporary fix, an infinite loop can occur where
157 // posts with post content blocks render themselves recursively.
158 if ( is_admin() || defined( 'REST_REQUEST' ) ) {
159 return null;
160 }
161
162 _deprecated_function( __FUNCTION__, '8.1.0' );
163
164 if ( ! in_the_loop() ) {
165 rewind_posts();
166 the_post();
167 }
168 return get_post();
169 }
170
171 /**
172 * Filters default block categories to substitute legacy category names with new
173 * block categories.
174 *
175 * This can be removed when plugin support requires WordPress 5.5.0+.
176 *
177 * @see https://core.trac.wordpress.org/ticket/50278
178 *
179 * @param array[] $default_categories Array of block categories.
180 *
181 * @return array[] Filtered block categories.
182 */
183 function gutenberg_replace_default_block_categories( $default_categories ) {
184 $substitution = array(
185 'common' => array(
186 'slug' => 'text',
187 'title' => __( 'Text', 'gutenberg' ),
188 'icon' => null,
189 ),
190 'formatting' => array(
191 'slug' => 'media',
192 'title' => __( 'Media', 'gutenberg' ),
193 'icon' => null,
194 ),
195 'layout' => array(
196 'slug' => 'design',
197 'title' => __( 'Design', 'gutenberg' ),
198 'icon' => null,
199 ),
200 );
201
202 // Loop default categories to perform in-place substitution by legacy slug.
203 foreach ( $default_categories as $i => $default_category ) {
204 $slug = $default_category['slug'];
205 if ( isset( $substitution[ $slug ] ) ) {
206 $default_categories[ $i ] = $substitution[ $slug ];
207 unset( $substitution[ $slug ] );
208 }
209 }
210
211 /*
212 * At this point, `$substitution` should contain only the categories which
213 * could not be in-place substituted with a default category, likely in the
214 * case that core has since been updated to use the default categories.
215 * Check to verify they exist.
216 */
217 $default_category_slugs = wp_list_pluck( $default_categories, 'slug' );
218 foreach ( $substitution as $i => $substitute_category ) {
219 if ( in_array( $substitute_category['slug'], $default_category_slugs, true ) ) {
220 unset( $substitution[ $i ] );
221 }
222 }
223
224 /*
225 * Any substitutes remaining should be appended, as they are not yet
226 * assigned in the default categories array.
227 */
228 return array_merge( $default_categories, array_values( $substitution ) );
229 }
230 add_filter( 'block_categories', 'gutenberg_replace_default_block_categories' );
231
232 /**
233 * Shim that hooks into `pre_render_block` so as to override `render_block` with
234 * a function that assigns block context.
235 *
236 * This can be removed when plugin support requires WordPress 5.5.0+.
237 *
238 * @see https://core.trac.wordpress.org/ticket/49927
239 *
240 * @param string|null $pre_render The pre-rendered content. Defaults to null.
241 * @param array $parsed_block The parsed block being rendered.
242 *
243 * @return string String of rendered HTML.
244 */
245 function gutenberg_render_block_with_assigned_block_context( $pre_render, $parsed_block ) {
246 global $post, $wp_query;
247
248 /*
249 * If a non-null value is provided, a filter has run at an earlier priority
250 * and has already handled custom rendering and should take precedence.
251 */
252 if ( null !== $pre_render ) {
253 return $pre_render;
254 }
255
256 $source_block = $parsed_block;
257
258 /** This filter is documented in src/wp-includes/blocks.php */
259 $parsed_block = apply_filters( 'render_block_data', $parsed_block, $source_block );
260
261 $context = array(
262 'postId' => $post->ID,
263
264 /*
265 * The `postType` context is largely unnecessary server-side, since the
266 * ID is usually sufficient on its own. That being said, since a block's
267 * manifest is expected to be shared between the server and the client,
268 * it should be included to consistently fulfill the expectation.
269 */
270 'postType' => $post->post_type,
271
272 'query' => array( 'categoryIds' => array() ),
273 );
274
275 if ( isset( $wp_query->tax_query->queried_terms['category'] ) ) {
276 foreach ( $wp_query->tax_query->queried_terms['category']['terms'] as $category_slug_or_id ) {
277 $context['query']['categoryIds'][] = 'slug' === $wp_query->tax_query->queried_terms['category']['field'] ? get_cat_ID( $category_slug_or_id ) : $category_slug_or_id;
278 }
279 }
280
281 /**
282 * Filters the default context provided to a rendered block.
283 *
284 * @param array $context Default context.
285 * @param array $parsed_block Block being rendered, filtered by `render_block_data`.
286 */
287 $context = apply_filters( 'render_block_context', $context, $parsed_block );
288
289 $block = new WP_Block( $parsed_block, $context );
290
291 return $block->render();
292 }
293 add_filter( 'pre_render_block', 'gutenberg_render_block_with_assigned_block_context', 9, 2 );
294