diff --git a/src/wp-includes/blocks.php b/src/wp-includes/blocks.php index 01cc2070ac779..96958eb88783e 100644 --- a/src/wp-includes/blocks.php +++ b/src/wp-includes/blocks.php @@ -750,6 +750,38 @@ function get_hooked_blocks() { return $hooked_blocks; } +function insert_hooked_blocks( &$block, $relative_position, $anchor_block_type, $hooked_blocks, $context ) { + $hooked_block_types = isset( $hooked_blocks[ $anchor_block_type ][ $relative_position ] ) + ? $hooked_blocks[ $anchor_block_type ][ $relative_position ] + : array(); + + $markup = ''; + /** + * Filters the list of hooked block types for a given anchor block type and relative position. + * + * @since 6.4.0 + * + * @param string[] $hooked_block_types The list of hooked block types. + * @param string $relative_position The relative position of the hooked blocks. + * Can be one of 'before', 'after', 'first_child', or 'last_child'. + * @param string $anchor_block_type The anchor block type. + * @param WP_Block_Template|array $context The block template, template part, or pattern that the anchor block belongs to. + */ + $hooked_block_types = apply_filters( 'hooked_block_types', $hooked_block_types, $relative_position, $anchor_block_type, $context ); + foreach ( $hooked_block_types as $hooked_block_type ) { + if ( ! isset( $block['attrs']['blockHooks'] ) || ! in_array( $hooked_block_type, $block['attrs']['blockHooks'] ) ) { + $markup .= get_comment_delimited_block_content( $hooked_block_type, array(), '' ); + } + if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) { + if ( ! isset( $block['attrs']['blockHooks'] ) ) { + $block['attrs']['blockHooks'] = array(); + } + $block['attrs']['blockHooks'][] = $hooked_block_type; + } + } + return $markup; +} + /** * Returns a function that injects the theme attribute into, and hooked blocks before, a given block. * @@ -787,38 +819,12 @@ function make_before_block_visitor( $hooked_blocks, $context ) { // Candidate for first-child insertion. $relative_position = 'first_child'; $anchor_block_type = $parent_block['blockName']; - $hooked_block_types = isset( $hooked_blocks[ $anchor_block_type ][ $relative_position ] ) - ? $hooked_blocks[ $anchor_block_type ][ $relative_position ] - : array(); - - /** - * Filters the list of hooked block types for a given anchor block type and relative position. - * - * @since 6.4.0 - * - * @param string[] $hooked_block_types The list of hooked block types. - * @param string $relative_position The relative position of the hooked blocks. - * Can be one of 'before', 'after', 'first_child', or 'last_child'. - * @param string $anchor_block_type The anchor block type. - * @param WP_Block_Template|array $context The block template, template part, or pattern that the anchor block belongs to. - */ - $hooked_block_types = apply_filters( 'hooked_block_types', $hooked_block_types, $relative_position, $anchor_block_type, $context ); - foreach ( $hooked_block_types as $hooked_block_type ) { - $markup .= get_comment_delimited_block_content( $hooked_block_type, array(), '' ); - } + $markup .= insert_hooked_blocks( $block, $relative_position, $anchor_block_type, $hooked_blocks, $context ); } $relative_position = 'before'; $anchor_block_type = $block['blockName']; - $hooked_block_types = isset( $hooked_blocks[ $anchor_block_type ][ $relative_position ] ) - ? $hooked_blocks[ $anchor_block_type ][ $relative_position ] - : array(); - - /** This filter is documented in wp-includes/blocks.php */ - $hooked_block_types = apply_filters( 'hooked_block_types', $hooked_block_types, $relative_position, $anchor_block_type, $context ); - foreach ( $hooked_block_types as $hooked_block_type ) { - $markup .= get_comment_delimited_block_content( $hooked_block_type, array(), '' ); - } + $markup .= insert_hooked_blocks( $block, $relative_position, $anchor_block_type, $hooked_blocks, $context ); return $markup; }; @@ -856,29 +862,13 @@ function make_after_block_visitor( $hooked_blocks, $context ) { $relative_position = 'after'; $anchor_block_type = $block['blockName']; - $hooked_block_types = isset( $hooked_blocks[ $anchor_block_type ][ $relative_position ] ) - ? $hooked_blocks[ $anchor_block_type ][ $relative_position ] - : array(); - - /** This filter is documented in wp-includes/blocks.php */ - $hooked_block_types = apply_filters( 'hooked_block_types', $hooked_block_types, $relative_position, $anchor_block_type, $context ); - foreach ( $hooked_block_types as $hooked_block_type ) { - $markup .= get_comment_delimited_block_content( $hooked_block_type, array(), '' ); - } + $markup .= insert_hooked_blocks( $block, $relative_position, $anchor_block_type, $hooked_blocks, $context ); if ( $parent_block && ! $next ) { // Candidate for last-child insertion. $relative_position = 'last_child'; $anchor_block_type = $parent_block['blockName']; - $hooked_block_types = isset( $hooked_blocks[ $anchor_block_type ][ $relative_position ] ) - ? $hooked_blocks[ $anchor_block_type ][ $relative_position ] - : array(); - - /** This filter is documented in wp-includes/blocks.php */ - $hooked_block_types = apply_filters( 'hooked_block_types', $hooked_block_types, $relative_position, $anchor_block_type, $context ); - foreach ( $hooked_block_types as $hooked_block_type ) { - $markup .= get_comment_delimited_block_content( $hooked_block_type, array(), '' ); - } + $markup .= insert_hooked_blocks( $block, $relative_position, $anchor_block_type, $hooked_blocks, $context ); } return $markup; diff --git a/src/wp-includes/class-wp-block-type.php b/src/wp-includes/class-wp-block-type.php index b8ffb92e559b2..bac749b4dab2a 100644 --- a/src/wp-includes/class-wp-block-type.php +++ b/src/wp-includes/class-wp-block-type.php @@ -243,10 +243,12 @@ class WP_Block_Type { * Attributes supported by every block. * * @since 6.0.0 + * @since 6.5.0 Added hookedBlocks global attribute. * @var array */ const GLOBAL_ATTRIBUTES = array( - 'lock' => array( 'type' => 'object' ), + 'lock' => array( 'type' => 'object' ), + 'hookedBlocks' => array( 'type' => 'object' ), ); /**