PluginProbe
Gutenberg / 16.8.1
Gutenberg v16.8.1
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 / experimental / blocks.php

blocks.php in Gutenberg 16.8.1, at lib/experimental/blocks.php

207 lines 6.5 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 block APIs present in Gutenberg.
4 *
5 * @package gutenberg
6 */
7
8 if ( ! function_exists( 'wp_enqueue_block_view_script' ) ) {
9 /**
10 * Enqueues a frontend script for a specific block.
11 *
12 * Scripts enqueued using this function will only get printed
13 * when the block gets rendered on the frontend.
14 *
15 * @since 6.2.0
16 *
17 * @param string $block_name The block name, including namespace.
18 * @param array $args An array of arguments [handle,src,deps,ver,media,textdomain].
19 *
20 * @return void
21 */
22 function wp_enqueue_block_view_script( $block_name, $args ) {
23 $args = wp_parse_args(
24 $args,
25 array(
26 'handle' => '',
27 'src' => '',
28 'deps' => array(),
29 'ver' => false,
30 'in_footer' => false,
31
32 // Additional args to allow translations for the script's textdomain.
33 'textdomain' => '',
34 )
35 );
36
37 /**
38 * Callback function to register and enqueue scripts.
39 *
40 * @param string $content When the callback is used for the render_block filter,
41 * the content needs to be returned so the function parameter
42 * is to ensure the content exists.
43 * @return string Block content.
44 */
45 $callback = static function ( $content, $block ) use ( $args, $block_name ) {
46
47 // Sanity check.
48 if ( empty( $block['blockName'] ) || $block_name !== $block['blockName'] ) {
49 return $content;
50 }
51
52 // Register the stylesheet.
53 if ( ! empty( $args['src'] ) ) {
54 wp_register_script( $args['handle'], $args['src'], $args['deps'], $args['ver'], $args['in_footer'] );
55 }
56
57 // Enqueue the stylesheet.
58 wp_enqueue_script( $args['handle'] );
59
60 // If a textdomain is defined, use it to set the script translations.
61 if ( ! empty( $args['textdomain'] ) && in_array( 'wp-i18n', $args['deps'], true ) ) {
62 wp_set_script_translations( $args['handle'], $args['textdomain'], $args['domainpath'] );
63 }
64
65 return $content;
66 };
67
68 /*
69 * The filter's callback here is an anonymous function because
70 * using a named function in this case is not possible.
71 *
72 * The function cannot be unhooked, however, users are still able
73 * to dequeue the script registered/enqueued by the callback
74 * which is why in this case, using an anonymous function
75 * was deemed acceptable.
76 */
77 add_filter( 'render_block', $callback, 10, 2 );
78 }
79 }
80
81
82 /**
83 * Registers the metadata block attribute for block types.
84 *
85 * @param array $args Array of arguments for registering a block type.
86 * @return array $args
87 */
88 function gutenberg_register_metadata_attribute( $args ) {
89 // Setup attributes if needed.
90 if ( ! isset( $args['attributes'] ) || ! is_array( $args['attributes'] ) ) {
91 $args['attributes'] = array();
92 }
93
94 if ( ! array_key_exists( 'metadata', $args['attributes'] ) ) {
95 $args['attributes']['metadata'] = array(
96 'type' => 'object',
97 );
98 }
99
100 return $args;
101 }
102 add_filter( 'register_block_type_args', 'gutenberg_register_metadata_attribute' );
103
104
105 $gutenberg_experiments = get_option( 'gutenberg-experiments' );
106 if ( $gutenberg_experiments && array_key_exists( 'gutenberg-connections', $gutenberg_experiments ) ) {
107 /**
108 * Renders the block meta attributes.
109 *
110 * @param string $block_content Block Content.
111 * @param array $block Block attributes.
112 * @param WP_Block $block_instance The block instance.
113 */
114 function gutenberg_render_block_connections( $block_content, $block, $block_instance ) {
115 $connection_sources = require __DIR__ . '/connection-sources/index.php';
116 $block_type = $block_instance->block_type;
117
118 // Allowlist of blocks that support block connections.
119 // Currently, we only allow the following blocks and attributes:
120 // - Paragraph: content.
121 // - Image: url.
122 $blocks_attributes_allowlist = array(
123 'core/paragraph' => array( 'content' ),
124 'core/image' => array( 'url' ),
125 );
126
127 // Whitelist of the block types that support block connections.
128 // Currently, we only allow the Paragraph and Image blocks to use block connections.
129 if ( ! in_array( $block['blockName'], array_keys( $blocks_attributes_allowlist ), true ) ) {
130 return $block_content;
131 }
132
133 // If for some reason, the block type is not found, skip it.
134 if ( null === $block_type ) {
135 return $block_content;
136 }
137
138 // If the block does not have support for block connections, skip it.
139 if ( ! block_has_support( $block_type, array( '__experimentalConnections' ), false ) ) {
140 return $block_content;
141 }
142
143 // Get all the attributes that have a connection.
144 $connected_attributes = $block['attrs']['connections']['attributes'] ?? false;
145 if ( ! $connected_attributes ) {
146 return $block_content;
147 }
148
149 foreach ( $connected_attributes as $attribute_name => $attribute_value ) {
150
151 // If the attribute is not in the allowlist, skip it.
152 if ( ! in_array( $attribute_name, $blocks_attributes_allowlist[ $block['blockName'] ], true ) ) {
153 continue;
154 }
155
156 // If the source value is not "meta_fields", skip it because the only supported
157 // connection source is meta (custom fields) for now.
158 if ( 'meta_fields' !== $attribute_value['source'] ) {
159 continue;
160 }
161
162 // If the attribute does not have a source, skip it.
163 if ( ! isset( $block_type->attributes[ $attribute_name ]['source'] ) ) {
164 continue;
165 }
166
167 // If the attribute does not specify the name of the custom field, skip it.
168 if ( ! isset( $attribute_value['value'] ) ) {
169 continue;
170 }
171
172 // Get the content from the connection source.
173 $custom_value = $connection_sources[ $attribute_value['source'] ](
174 $block_instance,
175 $attribute_value['value']
176 );
177
178 $tags = new WP_HTML_Tag_Processor( $block_content );
179 $found = $tags->next_tag(
180 array(
181 // TODO: In the future, when blocks other than Paragraph and Image are
182 // supported, we should build the full query from CSS selector.
183 'tag_name' => $block_type->attributes[ $attribute_name ]['selector'],
184 )
185 );
186 if ( ! $found ) {
187 return $block_content;
188 }
189 $tag_name = $tags->get_tag();
190 $markup = "<$tag_name>$custom_value</$tag_name>";
191 $updated_tags = new WP_HTML_Tag_Processor( $markup );
192 $updated_tags->next_tag();
193
194 // Get all the attributes from the original block and add them to the new markup.
195 $names = $tags->get_attribute_names_with_prefix( '' );
196 foreach ( $names as $name ) {
197 $updated_tags->set_attribute( $name, $tags->get_attribute( $name ) );
198 }
199
200 return $updated_tags->get_updated_html();
201 }
202
203 return $block_content;
204 }
205 add_filter( 'render_block', 'gutenberg_render_block_connections', 10, 3 );
206 }
207