| @@ -77,43 +77,109 @@ | ||
| 77 | 77 | add_filter( 'render_block', $callback, 10, 2 ); |
| 78 | 78 | } |
| 79 | 79 | } |
| 80 | 80 | |
| 81 | -/** | |
| 82 | - * Registers a new block style for one or more block types. | |
| 83 | - * | |
| 84 | - * WP_Block_Styles_Registry was marked as `final` in core so it cannot be | |
| 85 | - * updated via Gutenberg to allow registration of a style across multiple | |
| 86 | - * block types as well as with an optional style object. This function will | |
| 87 | - * support the desired functionality until the styles registry can be updated | |
| 88 | - * in core. | |
| 89 | - * | |
| 90 | - * @param string|array $block_name Block type name including namespace or array of namespaced block type names. | |
| 91 | - * @param array $style_properties Array containing the properties of the style name, label, | |
| 92 | - * style_handle (name of the stylesheet to be enqueued), | |
| 93 | - * inline_style (string containing the CSS to be added), | |
| 94 | - * style_data (theme.json-like object to generate CSS from). | |
| 95 | - * | |
| 96 | - * @return bool True if all block styles were registered with success and false otherwise. | |
| 97 | - */ | |
| 98 | -function gutenberg_register_block_style( $block_name, $style_properties ) { | |
| 99 | - if ( ! is_string( $block_name ) && ! is_array( $block_name ) ) { | |
| 100 | - _doing_it_wrong( | |
| 101 | - __METHOD__, | |
| 102 | - __( 'Block name must be a string or array.', 'gutenberg' ), | |
| 103 | - '6.6.0' | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | +$gutenberg_experiments = get_option( 'gutenberg-experiments' ); | |
| 85 | +if ( $gutenberg_experiments && array_key_exists( 'gutenberg-connections', $gutenberg_experiments ) ) { | |
| 86 | + /** | |
| 87 | + * Renders the block meta attributes. | |
| 88 | + * | |
| 89 | + * @param string $block_content Block Content. | |
| 90 | + * @param array $block Block attributes. | |
| 91 | + * @param WP_Block $block_instance The block instance. | |
| 92 | + */ | |
| 93 | + function gutenberg_render_block_connections( $block_content, $block, $block_instance ) { | |
| 94 | + $connection_sources = require __DIR__ . '/connection-sources/index.php'; | |
| 95 | + $block_type = $block_instance->block_type; | |
| 96 | + | |
| 97 | + // Allowlist of blocks that support block connections. | |
| 98 | + // Currently, we only allow the following blocks and attributes: | |
| 99 | + // - Paragraph: content. | |
| 100 | + // - Image: url. | |
| 101 | + $blocks_attributes_allowlist = array( | |
| 102 | + 'core/paragraph' => array( 'content' ), | |
| 103 | + 'core/image' => array( 'url' ), | |
| 104 | 104 | ); |
| 105 | 105 | |
| 106 | - return false; | |
| 107 | - } | |
| 106 | + // Whitelist of the block types that support block connections. | |
| 107 | + // Currently, we only allow the Paragraph and Image blocks to use block connections. | |
| 108 | + if ( ! in_array( $block['blockName'], array_keys( $blocks_attributes_allowlist ), true ) ) { | |
| 109 | + return $block_content; | |
| 110 | + } | |
| 108 | 111 | |
| 109 | - $block_names = is_string( $block_name ) ? array( $block_name ) : $block_name; | |
| 110 | - $result = true; | |
| 112 | + // If for some reason, the block type is not found, skip it. | |
| 113 | + if ( null === $block_type ) { | |
| 114 | + return $block_content; | |
| 115 | + } | |
| 111 | 116 | |
| 112 | - foreach ( $block_names as $name ) { | |
| 113 | - if ( ! WP_Block_Styles_Registry::get_instance()->register( $name, $style_properties ) ) { | |
| 114 | - $result = false; | |
| 117 | + // If the block does not have support for block connections, skip it. | |
| 118 | + if ( ! block_has_support( $block_type, array( '__experimentalConnections' ), false ) ) { | |
| 119 | + return $block_content; | |
| 115 | 120 | } |
| 121 | + | |
| 122 | + // Get all the attributes that have a connection. | |
| 123 | + $connected_attributes = $block['attrs']['connections']['attributes'] ?? false; | |
| 124 | + if ( ! $connected_attributes ) { | |
| 125 | + return $block_content; | |
| 126 | + } | |
| 127 | + | |
| 128 | + foreach ( $connected_attributes as $attribute_name => $attribute_value ) { | |
| 129 | + | |
| 130 | + // If the attribute is not in the allowlist, skip it. | |
| 131 | + if ( ! in_array( $attribute_name, $blocks_attributes_allowlist[ $block['blockName'] ], true ) ) { | |
| 132 | + continue; | |
| 133 | + } | |
| 134 | + | |
| 135 | + // If the source value is not "meta_fields", skip it because the only supported | |
| 136 | + // connection source is meta (custom fields) for now. | |
| 137 | + if ( 'meta_fields' !== $attribute_value['source'] ) { | |
| 138 | + continue; | |
| 139 | + } | |
| 140 | + | |
| 141 | + // If the attribute does not have a source, skip it. | |
| 142 | + if ( ! isset( $block_type->attributes[ $attribute_name ]['source'] ) ) { | |
| 143 | + continue; | |
| 144 | + } | |
| 145 | + | |
| 146 | + // If the attribute does not specify the name of the custom field, skip it. | |
| 147 | + if ( ! isset( $attribute_value['value'] ) ) { | |
| 148 | + continue; | |
| 149 | + } | |
| 150 | + | |
| 151 | + // Get the content from the connection source. | |
| 152 | + $custom_value = $connection_sources[ $attribute_value['source'] ]( | |
| 153 | + $block_instance, | |
| 154 | + $attribute_value['value'] | |
| 155 | + ); | |
| 156 | + | |
| 157 | + $tags = new WP_HTML_Tag_Processor( $block_content ); | |
| 158 | + $found = $tags->next_tag( | |
| 159 | + array( | |
| 160 | + // TODO: In the future, when blocks other than Paragraph and Image are | |
| 161 | + // supported, we should build the full query from CSS selector. | |
| 162 | + 'tag_name' => $block_type->attributes[ $attribute_name ]['selector'], | |
| 163 | + ) | |
| 164 | + ); | |
| 165 | + if ( ! $found ) { | |
| 166 | + return $block_content; | |
| 167 | + } | |
| 168 | + $tag_name = $tags->get_tag(); | |
| 169 | + $markup = "<$tag_name>$custom_value</$tag_name>"; | |
| 170 | + $updated_tags = new WP_HTML_Tag_Processor( $markup ); | |
| 171 | + $updated_tags->next_tag(); | |
| 172 | + | |
| 173 | + // Get all the attributes from the original block and add them to the new markup. | |
| 174 | + $names = $tags->get_attribute_names_with_prefix( '' ); | |
| 175 | + foreach ( $names as $name ) { | |
| 176 | + $updated_tags->set_attribute( $name, $tags->get_attribute( $name ) ); | |
| 177 | + } | |
| 178 | + | |
| 179 | + return $updated_tags->get_updated_html(); | |
| 180 | + } | |
| 181 | + | |
| 182 | + return $block_content; | |
| 116 | 183 | } |
| 117 | - | |
| 118 | - return $result; | |
| 184 | + add_filter( 'render_block', 'gutenberg_render_block_connections', 10, 3 ); | |
| 119 | 185 | } |