PluginProbe
Gutenberg / 17.5.2
Gutenberg v17.5.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 / experimental / blocks.php

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

201 lines 6.3 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
84 $gutenberg_experiments = get_option( 'gutenberg-experiments' );
85 if ( $gutenberg_experiments && (
86 array_key_exists( 'gutenberg-connections', $gutenberg_experiments ) ||
87 array_key_exists( 'gutenberg-pattern-partial-syncing', $gutenberg_experiments )
88 ) ) {
89 /**
90 * Renders the block meta attributes.
91 *
92 * @param string $block_content Block Content.
93 * @param array $block Block attributes.
94 * @param WP_Block $block_instance The block instance.
95 */
96 function gutenberg_render_block_connections( $block_content, $block, $block_instance ) {
97 $connection_sources = require __DIR__ . '/connection-sources/index.php';
98 $block_type = $block_instance->block_type;
99
100 // Allowlist of blocks that support block connections.
101 // Currently, we only allow the following blocks and attributes:
102 // - Paragraph: content.
103 // - Image: url.
104 $blocks_attributes_allowlist = array(
105 'core/paragraph' => array( 'content' ),
106 'core/image' => array( 'url' ),
107 );
108
109 // Whitelist of the block types that support block connections.
110 // Currently, we only allow the Paragraph and Image blocks to use block connections.
111 if ( ! in_array( $block['blockName'], array_keys( $blocks_attributes_allowlist ), true ) ) {
112 return $block_content;
113 }
114
115 // If for some reason, the block type is not found, skip it.
116 if ( null === $block_type ) {
117 return $block_content;
118 }
119
120 // If the block does not have support for block connections, skip it.
121 if ( ! block_has_support( $block_type, array( '__experimentalConnections' ), false ) ) {
122 return $block_content;
123 }
124
125 // Get all the attributes that have a connection.
126 $connected_attributes = $block['attrs']['connections']['attributes'] ?? false;
127 if ( ! $connected_attributes ) {
128 return $block_content;
129 }
130
131 foreach ( $connected_attributes as $attribute_name => $attribute_value ) {
132
133 // If the attribute is not in the allowlist, skip it.
134 if ( ! in_array( $attribute_name, $blocks_attributes_allowlist[ $block['blockName'] ], true ) ) {
135 continue;
136 }
137
138 // Skip if the source value is not "meta_fields" or "pattern_attributes".
139 if ( 'meta_fields' !== $attribute_value['source'] && 'pattern_attributes' !== $attribute_value['source'] ) {
140 continue;
141 }
142
143 // If the attribute does not have a source, skip it.
144 if ( ! isset( $block_type->attributes[ $attribute_name ]['source'] ) ) {
145 continue;
146 }
147
148 if ( 'pattern_attributes' === $attribute_value['source'] ) {
149 if ( ! _wp_array_get( $block_instance->attributes, array( 'metadata', 'id' ), false ) ) {
150 continue;
151 }
152
153 $custom_value = $connection_sources[ $attribute_value['source'] ]( $block_instance, $attribute_name );
154 } else {
155 // If the attribute does not specify the name of the custom field, skip it.
156 if ( ! isset( $attribute_value['value'] ) ) {
157 continue;
158 }
159
160 // Get the content from the connection source.
161 $custom_value = $connection_sources[ $attribute_value['source'] ](
162 $block_instance,
163 $attribute_value['value']
164 );
165 }
166
167 if ( false === $custom_value ) {
168 continue;
169 }
170
171 $tags = new WP_HTML_Tag_Processor( $block_content );
172 $found = $tags->next_tag(
173 array(
174 // TODO: In the future, when blocks other than Paragraph and Image are
175 // supported, we should build the full query from CSS selector.
176 'tag_name' => $block_type->attributes[ $attribute_name ]['selector'],
177 )
178 );
179 if ( ! $found ) {
180 return $block_content;
181 }
182 $tag_name = $tags->get_tag();
183 $markup = "<$tag_name>$custom_value</$tag_name>";
184 $updated_tags = new WP_HTML_Tag_Processor( $markup );
185 $updated_tags->next_tag();
186
187 // Get all the attributes from the original block and add them to the new markup.
188 $names = $tags->get_attribute_names_with_prefix( '' );
189 foreach ( $names as $name ) {
190 $updated_tags->set_attribute( $name, $tags->get_attribute( $name ) );
191 }
192
193 return $updated_tags->get_updated_html();
194 }
195
196 return $block_content;
197 }
198
199 add_filter( 'render_block', 'gutenberg_render_block_connections', 10, 3 );
200 }
201