PluginProbe
Gutenberg / 16.2.0
Gutenberg v16.2.0
24.0.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 All 403 releases
← All changes | lib/blocks.php +363 -127 7.4.016.2.0 View file →
@@ -1,166 +1,402 @@
1 1 <?php
2 2 /**
3 - * Block and style registration functions.
3 + * Block functions specific for the Gutenberg editor plugin.
4 4 *
5 5 * @package gutenberg
6 6 */
7 7
8 8 /**
9 - * Retrieves registered social link blocks
10 - *
11 - * @return array Array of strings containing the registered social link block names.
9 + * Substitutes the implementation of a core-registered block type, if exists,
10 + * with the built result from the plugin.
12 11 */
13 -function gutenberg_get_registered_social_link_blocks() {
14 - $social_link_prefix = 'core/social-link';
15 - $social_link_prefix_length = strlen( $social_link_prefix );
12 +function gutenberg_reregister_core_block_types() {
13 + // Blocks directory may not exist if working from a fresh clone.
14 + $blocks_dirs = array(
15 + __DIR__ . '/../build/block-library/blocks/' => array(
16 + 'block_folders' => array(
17 + 'audio',
18 + 'button',
19 + 'buttons',
20 + 'freeform',
21 + 'code',
22 + 'column',
23 + 'columns',
24 + 'comments',
25 + 'details',
26 + 'group',
27 + 'footnotes',
28 + 'html',
29 + 'list',
30 + 'list-item',
31 + 'media-text',
32 + 'missing',
33 + 'more',
34 + 'nextpage',
35 + 'paragraph',
36 + 'preformatted',
37 + 'pullquote',
38 + 'quote',
39 + 'separator',
40 + 'social-links',
41 + 'spacer',
42 + 'table',
43 + 'table-of-contents',
44 + 'text-columns',
45 + 'verse',
46 + 'video',
47 + 'embed',
48 + ),
49 + 'block_names' => array(
50 + 'archives.php' => 'core/archives',
51 + 'avatar.php' => 'core/avatar',
52 + 'block.php' => 'core/block',
53 + 'calendar.php' => 'core/calendar',
54 + 'categories.php' => 'core/categories',
55 + 'cover.php' => 'core/cover',
56 + 'comment-author-avatar.php' => 'core/comment-author-avatar',
57 + 'comment-author-name.php' => 'core/comment-author-name',
58 + 'comment-content.php' => 'core/comment-content',
59 + 'comment-date.php' => 'core/comment-date',
60 + 'comment-edit-link.php' => 'core/comment-edit-link',
61 + 'comment-reply-link.php' => 'core/comment-reply-link',
62 + 'comment-template.php' => 'core/comment-template',
63 + 'comments-pagination.php' => 'core/comments-pagination',
64 + 'comments-pagination-next.php' => 'core/comments-pagination-next',
65 + 'comments-pagination-numbers.php' => 'core/comments-pagination-numbers',
66 + 'comments-pagination-previous.php' => 'core/comments-pagination-previous',
67 + 'comments-title.php' => 'core/comments-title',
68 + 'comments.php' => 'core/comments',
69 + 'footnotes.php' => 'core/footnotes',
70 + 'file.php' => 'core/file',
71 + 'home-link.php' => 'core/home-link',
72 + 'image.php' => 'core/image',
73 + 'gallery.php' => 'core/gallery',
74 + 'heading.php' => 'core/heading',
75 + 'latest-comments.php' => 'core/latest-comments',
76 + 'latest-posts.php' => 'core/latest-posts',
77 + 'loginout.php' => 'core/loginout',
78 + 'navigation.php' => 'core/navigation',
79 + 'navigation-link.php' => 'core/navigation-link',
80 + 'navigation-submenu.php' => 'core/navigation-submenu',
81 + 'page-list.php' => 'core/page-list',
82 + 'page-list-item.php' => 'core/page-list-item',
83 + 'pattern.php' => 'core/pattern',
84 + 'post-author.php' => 'core/post-author',
85 + 'post-author-name.php' => 'core/post-author-name',
86 + 'post-author-biography.php' => 'core/post-author-biography',
87 + 'post-comment.php' => 'core/post-comment',
88 + 'post-comments-count.php' => 'core/post-comments-count',
89 + 'post-comments-form.php' => 'core/post-comments-form',
90 + 'post-comments-link.php' => 'core/post-comments-link',
91 + 'post-content.php' => 'core/post-content',
92 + 'post-date.php' => 'core/post-date',
93 + 'post-excerpt.php' => 'core/post-excerpt',
94 + 'post-featured-image.php' => 'core/post-featured-image',
95 + 'post-navigation-link.php' => 'core/post-navigation-link',
96 + 'post-terms.php' => 'core/post-terms',
97 + 'post-time-to-read.php' => 'core/post-time-to-read',
98 + 'post-title.php' => 'core/post-title',
99 + 'query.php' => 'core/query',
100 + 'post-template.php' => 'core/post-template',
101 + 'query-no-results.php' => 'core/query-no-results',
102 + 'query-pagination.php' => 'core/query-pagination',
103 + 'query-pagination-next.php' => 'core/query-pagination-next',
104 + 'query-pagination-numbers.php' => 'core/query-pagination-numbers',
105 + 'query-pagination-previous.php' => 'core/query-pagination-previous',
106 + 'query-title.php' => 'core/query-title',
107 + 'read-more.php' => 'core/read-more',
108 + 'rss.php' => 'core/rss',
109 + 'search.php' => 'core/search',
110 + 'shortcode.php' => 'core/shortcode',
111 + 'social-link.php' => 'core/social-link',
112 + 'site-logo.php' => 'core/site-logo',
113 + 'site-tagline.php' => 'core/site-tagline',
114 + 'site-title.php' => 'core/site-title',
115 + 'tag-cloud.php' => 'core/tag-cloud',
116 + 'template-part.php' => 'core/template-part',
117 + 'term-description.php' => 'core/term-description',
118 + ),
119 + ),
120 + __DIR__ . '/../build/edit-widgets/blocks/' => array(
121 + 'block_folders' => array(
122 + 'widget-area',
123 + ),
124 + 'block_names' => array(),
125 + ),
126 + __DIR__ . '/../build/widgets/blocks/' => array(
127 + 'block_folders' => array(
128 + 'legacy-widget',
129 + 'widget-group',
130 + ),
131 + 'block_names' => array(
132 + 'legacy-widget.php' => 'core/legacy-widget',
133 + 'widget-group.php' => 'core/widget-group',
134 + ),
135 + ),
136 + );
137 + foreach ( $blocks_dirs as $blocks_dir => $details ) {
138 + $block_folders = $details['block_folders'];
139 + $block_names = $details['block_names'];
16 140
17 - $registry = WP_Block_Type_Registry::get_instance();
18 - $block_types = $registry->get_all_registered();
141 + foreach ( $block_folders as $folder_name ) {
142 + $block_json_file = $blocks_dir . $folder_name . '/block.json';
19 143
20 - $registered_social_link_blocks = array();
21 - foreach ( $block_types as $block_type ) {
22 - // Block type name starts with $social_link_prefix.
23 - if ( strncmp( $block_type->name, $social_link_prefix, $social_link_prefix_length ) === 0 ) {
24 - $registered_social_link_blocks[] = $block_type->name;
144 + // Ideally, all paths to block metadata files should be listed in
145 + // WordPress core. In this place we should rather use filter
146 + // to replace paths with overrides defined by the plugin.
147 + $metadata = json_decode( file_get_contents( $block_json_file ), true );
148 + if ( ! is_array( $metadata ) || ! $metadata['name'] ) {
149 + continue;
150 + }
151 +
152 + gutenberg_deregister_core_block_and_assets( $metadata['name'] );
153 + gutenberg_register_core_block_assets( $folder_name );
154 + register_block_type_from_metadata( $block_json_file );
25 155 }
156 +
157 + foreach ( $block_names as $file => $sub_block_names ) {
158 + if ( ! file_exists( $blocks_dir . $file ) ) {
159 + continue;
160 + }
161 +
162 + $sub_block_names_normalized = is_string( $sub_block_names ) ? array( $sub_block_names ) : $sub_block_names;
163 + foreach ( $sub_block_names_normalized as $block_name ) {
164 + gutenberg_deregister_core_block_and_assets( $block_name );
165 + gutenberg_register_core_block_assets( $block_name );
166 + }
167 +
168 + require_once $blocks_dir . $file;
169 + }
26 170 }
27 - return $registered_social_link_blocks;
28 171 }
29 172
173 +add_action( 'init', 'gutenberg_reregister_core_block_types' );
174 +
30 175 /**
31 - * Substitutes the implementation of a core-registered block type, if exists,
32 - * with the built result from the plugin.
176 + * Deregisters the existing core block type and its assets.
177 + *
178 + * @param string $block_name The name of the block.
179 + *
180 + * @return void
33 181 */
34 -function gutenberg_reregister_core_block_types() {
35 - // Blocks directory may not exist if working from a fresh clone.
36 - $blocks_dir = dirname( __FILE__ ) . '/../build/block-library/blocks/';
37 - if ( ! file_exists( $blocks_dir ) ) {
182 +function gutenberg_deregister_core_block_and_assets( $block_name ) {
183 + $registry = WP_Block_Type_Registry::get_instance();
184 + if ( $registry->is_registered( $block_name ) ) {
185 + $block_type = $registry->get_registered( $block_name );
186 + if ( ! empty( $block_type->view_script_handles ) ) {
187 + foreach ( $block_type->view_script_handles as $view_script_handle ) {
188 + if ( str_starts_with( $view_script_handle, 'wp-block-' ) ) {
189 + wp_deregister_script( $view_script_handle );
190 + }
191 + }
192 + }
193 + $registry->unregister( $block_name );
194 + }
195 +}
196 +
197 +/**
198 + * Registers block styles for a core block.
199 + *
200 + * @param string $block_name The block-name.
201 + *
202 + * @return void
203 + */
204 +function gutenberg_register_core_block_assets( $block_name ) {
205 + if ( ! wp_should_load_separate_core_block_assets() ) {
38 206 return;
39 207 }
40 208
41 - $block_names = array(
42 - 'archives.php' => 'core/archives',
43 - 'block.php' => 'core/block',
44 - 'calendar.php' => 'core/calendar',
45 - 'categories.php' => 'core/categories',
46 - 'latest-comments.php' => 'core/latest-comments',
47 - 'latest-posts.php' => 'core/latest-posts',
48 - 'legacy-widget.php' => 'core/legacy-widget',
49 - 'navigation.php' => 'core/navigation',
50 - 'rss.php' => 'core/rss',
51 - 'shortcode.php' => 'core/shortcode',
52 - 'search.php' => 'core/search',
53 - 'social-link.php' => gutenberg_get_registered_social_link_blocks(),
54 - 'tag-cloud.php' => 'core/tag-cloud',
55 - 'site-title.php' => 'core/site-title',
56 - 'template-part.php' => 'core/template-part',
57 - 'post-title.php' => 'core/post-title',
58 - 'post-content.php' => 'core/post-content',
59 - 'post-author.php' => 'core/post-author',
60 - 'post-date.php' => 'core/post-date',
61 - 'post-excerpt.php' => 'core/post-excerpt',
62 - );
209 + $block_name = str_replace( 'core/', '', $block_name );
63 210
64 - $registry = WP_Block_Type_Registry::get_instance();
211 + // When in production, use the plugin's version as the default asset version;
212 + // else (for development or test) default to use the current time.
213 + $default_version = defined( 'GUTENBERG_VERSION' ) && ! SCRIPT_DEBUG ? GUTENBERG_VERSION : time();
65 214
66 - foreach ( $block_names as $file => $block_names ) {
67 - if ( ! file_exists( $blocks_dir . $file ) ) {
68 - return;
215 + $style_path = "build/block-library/blocks/$block_name/";
216 + $stylesheet_url = gutenberg_url( $style_path . 'style.css' );
217 + $stylesheet_path = gutenberg_dir_path() . $style_path . ( is_rtl() ? 'style-rtl.css' : 'style.css' );
218 +
219 + if ( file_exists( $stylesheet_path ) ) {
220 + wp_deregister_style( "wp-block-{$block_name}" );
221 + wp_register_style(
222 + "wp-block-{$block_name}",
223 + $stylesheet_url,
224 + array(),
225 + $default_version
226 + );
227 + wp_style_add_data( "wp-block-{$block_name}", 'rtl', 'replace' );
228 +
229 + // Add a reference to the stylesheet's path to allow calculations for inlining styles in `wp_head`.
230 + wp_style_add_data( "wp-block-{$block_name}", 'path', $stylesheet_path );
231 + } else {
232 + wp_register_style( "wp-block-{$block_name}", false, array() );
233 + }
234 +
235 + // If the current theme supports wp-block-styles, dequeue the full stylesheet
236 + // and instead attach each block's theme-styles to their block styles stylesheet.
237 + if ( current_theme_supports( 'wp-block-styles' ) ) {
238 +
239 + // Dequeue the full stylesheet.
240 + // Make sure this only runs once, it doesn't need to run for every block.
241 + static $stylesheet_removed;
242 + if ( ! $stylesheet_removed ) {
243 + add_action(
244 + 'wp_enqueue_scripts',
245 + static function() {
246 + wp_dequeue_style( 'wp-block-library-theme' );
247 + }
248 + );
249 + $stylesheet_removed = true;
69 250 }
70 251
71 - if ( is_string( $block_names ) ) {
72 - if ( $registry->is_registered( $block_names ) ) {
73 - $registry->unregister( $block_names );
252 + // Get the path to the block's stylesheet.
253 + $theme_style_path = is_rtl()
254 + ? "build/block-library/blocks/$block_name/theme-rtl.css"
255 + : "build/block-library/blocks/$block_name/theme.css";
256 +
257 + // If the file exists, enqueue it.
258 + if ( file_exists( gutenberg_dir_path() . $theme_style_path ) ) {
259 +
260 + if ( file_exists( $stylesheet_path ) ) {
261 + // If there is a main stylesheet for this block, append the theme styles to main styles.
262 + wp_add_inline_style(
263 + "wp-block-{$block_name}",
264 + file_get_contents( gutenberg_dir_path() . $theme_style_path )
265 + );
266 + } else {
267 + // If there is no main stylesheet for this block, register theme style.
268 + wp_register_style(
269 + "wp-block-{$block_name}",
270 + gutenberg_url( $theme_style_path ),
271 + array(),
272 + $default_version
273 + );
274 + wp_style_add_data( "wp-block-{$block_name}", 'path', gutenberg_dir_path() . $theme_style_path );
74 275 }
75 - } elseif ( is_array( $block_names ) ) {
76 - foreach ( $block_names as $block_name ) {
77 - if ( $registry->is_registered( $block_name ) ) {
78 - $registry->unregister( $block_name );
79 - }
80 - }
81 276 }
277 + }
82 278
83 - require $blocks_dir . $file;
279 + $editor_style_path = "build/block-library/blocks/$block_name/style-editor.css";
280 + if ( file_exists( gutenberg_dir_path() . $editor_style_path ) ) {
281 + wp_deregister_style( "wp-block-{$block_name}-editor" );
282 + wp_register_style(
283 + "wp-block-{$block_name}-editor",
284 + gutenberg_url( $editor_style_path ),
285 + array(),
286 + $default_version
287 + );
288 + wp_style_add_data( "wp-block-{$block_name}-editor", 'rtl', 'replace' );
289 + } else {
290 + wp_register_style( "wp-block-{$block_name}-editor", false );
84 291 }
85 292 }
86 -add_action( 'init', 'gutenberg_reregister_core_block_types' );
87 293
88 -if ( ! function_exists( 'register_block_style' ) ) {
89 - /**
90 - * Registers a new block style.
91 - *
92 - * @param string $block_name Block type name including namespace.
93 - * @param array $style_properties Array containing the properties of the style name, label, style (name of the stylesheet to be enqueued), inline_style (string containing the CSS to be added).
94 - *
95 - * @return boolean True if the block style was registered with success and false otherwise.
96 - */
97 - function register_block_style( $block_name, $style_properties ) {
98 - return WP_Block_Styles_Registry::get_instance()->register( $block_name, $style_properties );
99 - }
100 -}
294 +/**
295 + * Complements the implementation of block type `core/social-icon`, whether it
296 + * be provided by core or the plugin, with derived block types for each
297 + * "service" (WordPress, Twitter, etc.) supported by Social Links.
298 + *
299 + * This ensures backwards compatibility for any users running the Gutenberg
300 + * plugin who have used Social Links prior to their conversion to block
301 + * variations.
302 + *
303 + * This shim is INTENTIONALLY left out of core, as Social Links have never
304 + * landed there.
305 + *
306 + * @see https://github.com/WordPress/gutenberg/pull/19887
307 + */
308 +function gutenberg_register_legacy_social_link_blocks() {
309 + $services = array(
310 + 'amazon',
311 + 'bandcamp',
312 + 'behance',
313 + 'chain',
314 + 'codepen',
315 + 'deviantart',
316 + 'dribbble',
317 + 'dropbox',
318 + 'etsy',
319 + 'facebook',
320 + 'feed',
321 + 'fivehundredpx',
322 + 'flickr',
323 + 'foursquare',
324 + 'goodreads',
325 + 'google',
326 + 'github',
327 + 'instagram',
328 + 'lastfm',
329 + 'linkedin',
330 + 'mail',
331 + 'mastodon',
332 + 'meetup',
333 + 'medium',
334 + 'pinterest',
335 + 'pocket',
336 + 'reddit',
337 + 'skype',
338 + 'snapchat',
339 + 'soundcloud',
340 + 'spotify',
341 + 'tumblr',
342 + 'twitch',
343 + 'twitter',
344 + 'vimeo',
345 + 'vk',
346 + 'wordpress',
347 + 'yelp',
348 + 'youtube',
349 + );
101 350
102 -if ( ! function_exists( 'unregister_block_style' ) ) {
103 - /**
104 - * Unregisters a block style.
105 - *
106 - * @param string $block_name Block type name including namespace.
107 - * @param array $block_style_name Block style name.
108 - *
109 - * @return boolean True if the block style was unregistered with success and false otherwise.
110 - */
111 - function unregister_block_style( $block_name, $block_style_name ) {
112 - return WP_Block_Styles_Registry::get_instance()->unregister( $block_name, $block_style_name );
351 + foreach ( $services as $service ) {
352 + register_block_type(
353 + 'core/social-link-' . $service,
354 + array(
355 + 'category' => 'widgets',
356 + 'attributes' => array(
357 + 'url' => array(
358 + 'type' => 'string',
359 + ),
360 + 'service' => array(
361 + 'type' => 'string',
362 + 'default' => $service,
363 + ),
364 + 'label' => array(
365 + 'type' => 'string',
366 + ),
367 + ),
368 + 'render_callback' => 'gutenberg_render_block_core_social_link',
369 + )
370 + );
113 371 }
114 372 }
115 373
116 -if ( ! has_action( 'enqueue_block_assets', 'enqueue_block_styles_assets' ) ) {
117 - /**
118 - * Function responsible for enqueuing the styles required for block styles functionality on the editor and on the frontend.
119 - */
120 - function gutenberg_enqueue_block_styles_assets() {
121 - $block_styles = WP_Block_Styles_Registry::get_instance()->get_all_registered();
374 +add_action( 'init', 'gutenberg_register_legacy_social_link_blocks' );
122 375
123 - foreach ( $block_styles as $styles ) {
124 - foreach ( $styles as $style_properties ) {
125 - if ( isset( $style_properties['style_handle'] ) ) {
126 - wp_enqueue_style( $style_properties['style_handle'] );
127 - }
128 - if ( isset( $style_properties['inline_style'] ) ) {
129 - wp_add_inline_style( 'wp-block-library', $style_properties['inline_style'] );
130 - }
131 - }
132 - }
376 +/**
377 + * Migrate the legacy `sync_status` meta key (added 16.1) to the new `wp_pattern_sync_status` meta key (16.1.1).
378 + *
379 + * This filter is INTENTIONALLY left out of core as the meta key was fist introduced to core in 6.3 as `wp_pattern_sync_status`.
380 + * see https://github.com/WordPress/gutenberg/pull/52232
381 + *
382 + * @param mixed $value The value to return, either a single metadata value or an array of values depending on the value of $single.
383 + * @param int $object_id ID of the object metadata is for.
384 + * @param string $meta_key Metadata key.
385 + * @param bool $single Whether to return only the first value of the specified $meta_key.
386 + */
387 +function gutenberg_legacy_wp_block_post_meta( $value, $object_id, $meta_key, $single ) {
388 + if ( 'wp_pattern_sync_status' !== $meta_key ) {
389 + return $value;
133 390 }
134 - add_action( 'enqueue_block_assets', 'gutenberg_enqueue_block_styles_assets', 30 );
135 -}
136 -if ( ! has_action( 'enqueue_block_editor_assets', 'enqueue_editor_block_styles_assets' ) ) {
137 - /**
138 - * Function responsible for enqueuing the assets required for block styles functionality on the editor.
139 - */
140 - function gutenberg_enqueue_editor_block_styles_assets() {
141 - $block_styles = WP_Block_Styles_Registry::get_instance()->get_all_registered();
142 391
143 - $register_script_lines = array( '( function() {' );
144 - foreach ( $block_styles as $block_name => $styles ) {
145 - foreach ( $styles as $style_properties ) {
146 - $register_script_lines[] = sprintf(
147 - ' wp.blocks.registerBlockStyle( \'%s\', %s );',
148 - $block_name,
149 - wp_json_encode(
150 - array(
151 - 'name' => $style_properties['name'],
152 - 'label' => $style_properties['label'],
153 - )
154 - )
155 - );
156 - }
157 - }
158 - $register_script_lines[] = '} )();';
159 - $inline_script = implode( "\n", $register_script_lines );
392 + $sync_status = get_post_meta( $object_id, 'sync_status', $single );
160 393
161 - wp_register_script( 'wp-block-styles', false, array( 'wp-blocks' ), true, true );
162 - wp_add_inline_script( 'wp-block-styles', $inline_script );
163 - wp_enqueue_script( 'wp-block-styles' );
394 + if ( $single && 'unsynced' === $sync_status ) {
395 + return $sync_status;
396 + } elseif ( isset( $sync_status[0] ) && 'unsynced' === $sync_status[0] ) {
397 + return $sync_status;
164 398 }
165 - add_action( 'enqueue_block_editor_assets', 'gutenberg_enqueue_editor_block_styles_assets' );
399 +
400 + return $value;
166 401 }
402 +add_filter( 'default_post_metadata', 'gutenberg_legacy_wp_block_post_meta', 10, 4 );