Changeset 59124
- Timestamp:
- 09/30/2024 12:21:31 PM (16 months ago)
- Location:
- trunk
- Files:
-
- 2 edited
-
src/wp-includes/blocks.php (modified) (1 diff)
-
tests/phpunit/tests/blocks/applyBlockHooksToContent.php (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/blocks.php
r59115 r59124 1057 1057 } 1058 1058 1059 $blocks = parse_blocks( $content ); 1060 1061 return traverse_and_serialize_blocks( $blocks, $before_block_visitor, $after_block_visitor ); 1059 $block_allows_multiple_instances = array(); 1060 /* 1061 * Remove hooked blocks from `$hooked_block_types` if they have `multiple` set to false and 1062 * are already present in `$content`. 1063 */ 1064 foreach ( $hooked_blocks as $anchor_block_type => $relative_positions ) { 1065 foreach ( $relative_positions as $relative_position => $hooked_block_types ) { 1066 foreach ( $hooked_block_types as $index => $hooked_block_type ) { 1067 $hooked_block_type_definition = 1068 WP_Block_Type_Registry::get_instance()->get_registered( $hooked_block_type ); 1069 1070 $block_allows_multiple_instances[ $hooked_block_type ] = 1071 block_has_support( $hooked_block_type_definition, 'multiple', true ); 1072 1073 if ( 1074 ! $block_allows_multiple_instances[ $hooked_block_type ] && 1075 has_block( $hooked_block_type, $content ) 1076 ) { 1077 unset( $hooked_blocks[ $anchor_block_type ][ $relative_position ][ $index ] ); 1078 } 1079 } 1080 if ( empty( $hooked_blocks[ $anchor_block_type ][ $relative_position ] ) ) { 1081 unset( $hooked_blocks[ $anchor_block_type ][ $relative_position ] ); 1082 } 1083 } 1084 if ( empty( $hooked_blocks[ $anchor_block_type ] ) ) { 1085 unset( $hooked_blocks[ $anchor_block_type ] ); 1086 } 1087 } 1088 1089 /* 1090 * We also need to cover the case where the hooked block is not present in 1091 * `$content` at first and we're allowed to insert it once -- but not again. 1092 */ 1093 $suppress_single_instance_blocks = static function ( $hooked_block_types ) use ( &$block_allows_multiple_instances, $content ) { 1094 static $single_instance_blocks_present_in_content = array(); 1095 foreach ( $hooked_block_types as $index => $hooked_block_type ) { 1096 if ( ! isset( $block_allows_multiple_instances[ $hooked_block_type ] ) ) { 1097 $hooked_block_type_definition = 1098 WP_Block_Type_Registry::get_instance()->get_registered( $hooked_block_type ); 1099 1100 $block_allows_multiple_instances[ $hooked_block_type ] = 1101 block_has_support( $hooked_block_type_definition, 'multiple', true ); 1102 } 1103 1104 if ( $block_allows_multiple_instances[ $hooked_block_type ] ) { 1105 continue; 1106 } 1107 1108 // The block doesn't allow multiple instances, so we need to check if it's already present. 1109 if ( 1110 in_array( $hooked_block_type, $single_instance_blocks_present_in_content, true ) || 1111 has_block( $hooked_block_type, $content ) 1112 ) { 1113 unset( $hooked_block_types[ $index ] ); 1114 } else { 1115 // We can insert the block once, but need to remember not to insert it again. 1116 $single_instance_blocks_present_in_content[] = $hooked_block_type; 1117 } 1118 } 1119 return $hooked_block_types; 1120 }; 1121 add_filter( 'hooked_block_types', $suppress_single_instance_blocks, PHP_INT_MAX ); 1122 $content = traverse_and_serialize_blocks( 1123 parse_blocks( $content ), 1124 $before_block_visitor, 1125 $after_block_visitor 1126 ); 1127 remove_filter( 'hooked_block_types', $suppress_single_instance_blocks, PHP_INT_MAX ); 1128 1129 return $content; 1062 1130 } 1063 1131 -
trunk/tests/phpunit/tests/blocks/applyBlockHooksToContent.php
r59101 r59124 28 28 ) 29 29 ); 30 31 register_block_type( 32 'tests/hooked-block-with-multiple-false', 33 array( 34 'block_hooks' => array( 35 'tests/other-anchor-block' => 'after', 36 ), 37 'supports' => array( 38 'multiple' => false, 39 ), 40 ) 41 ); 42 43 register_block_type( 44 'tests/dynamically-hooked-block-with-multiple-false', 45 array( 46 'supports' => array( 47 'multiple' => false, 48 ), 49 ) 50 ); 30 51 } 31 52 … … 39 60 40 61 $registry->unregister( 'tests/hooked-block' ); 62 $registry->unregister( 'tests/hooked-block-with-multiple-false' ); 63 $registry->unregister( 'tests/dynamically-hooked-block-with-multiple-false' ); 41 64 } 42 65 … … 68 91 ); 69 92 } 93 94 /** 95 * @ticket 61902 96 */ 97 public function test_apply_block_hooks_to_content_respect_multiple_false() { 98 $context = new WP_Block_Template(); 99 $context->content = '<!-- wp:tests/hooked-block-with-multiple-false /--><!-- wp:tests/other-anchor-block /-->'; 100 101 $actual = apply_block_hooks_to_content( $context->content, $context, 'insert_hooked_blocks' ); 102 $this->assertSame( 103 '<!-- wp:tests/hooked-block-with-multiple-false /--><!-- wp:tests/other-anchor-block /-->', 104 $actual 105 ); 106 } 107 108 /** 109 * @ticket 61902 110 */ 111 public function test_apply_block_hooks_to_content_respect_multiple_false_after_inserting_once() { 112 $context = new WP_Block_Template(); 113 $context->content = '<!-- wp:tests/other-anchor-block /--><!-- wp:tests/other-block /--><!-- wp:tests/other-anchor-block /-->'; 114 115 $actual = apply_block_hooks_to_content( $context->content, $context, 'insert_hooked_blocks' ); 116 $this->assertSame( 117 '<!-- wp:tests/other-anchor-block /--><!-- wp:tests/hooked-block-with-multiple-false /--><!-- wp:tests/other-block /--><!-- wp:tests/other-anchor-block /-->', 118 $actual 119 ); 120 } 121 122 /** 123 * @ticket 61902 124 */ 125 public function test_apply_block_hooks_to_content_respect_multiple_false_with_filter() { 126 $filter = function ( $hooked_block_types, $relative_position, $anchor_block_type ) { 127 if ( 'tests/yet-another-anchor-block' === $anchor_block_type && 'after' === $relative_position ) { 128 $hooked_block_types[] = 'tests/dynamically-hooked-block-with-multiple-false'; 129 } 130 131 return $hooked_block_types; 132 }; 133 134 $context = new WP_Block_Template(); 135 $context->content = '<!-- wp:tests/dynamically-hooked-block-with-multiple-false /--><!-- wp:tests/yet-another-anchor-block /-->'; 136 137 add_filter( 'hooked_block_types', $filter, 10, 3 ); 138 $actual = apply_block_hooks_to_content( $context->content, $context, 'insert_hooked_blocks' ); 139 remove_filter( 'hooked_block_types', $filter, 10 ); 140 141 $this->assertSame( 142 '<!-- wp:tests/dynamically-hooked-block-with-multiple-false /--><!-- wp:tests/yet-another-anchor-block /-->', 143 $actual 144 ); 145 } 146 147 /** 148 * @ticket 61902 149 */ 150 public function test_apply_block_hooks_to_content_respect_multiple_false_after_inserting_once_with_filter() { 151 $filter = function ( $hooked_block_types, $relative_position, $anchor_block_type ) { 152 if ( 'tests/yet-another-anchor-block' === $anchor_block_type && 'after' === $relative_position ) { 153 $hooked_block_types[] = 'tests/dynamically-hooked-block-with-multiple-false'; 154 } 155 156 return $hooked_block_types; 157 }; 158 159 $context = new WP_Block_Template(); 160 $context->content = '<!-- wp:tests/yet-another-anchor-block /--><!-- wp:tests/other-block /--><!-- wp:tests/yet-another-anchor-block /-->'; 161 162 add_filter( 'hooked_block_types', $filter, 10, 3 ); 163 $actual = apply_block_hooks_to_content( $context->content, $context, 'insert_hooked_blocks' ); 164 remove_filter( 'hooked_block_types', $filter, 10 ); 165 166 $this->assertSame( 167 '<!-- wp:tests/yet-another-anchor-block /--><!-- wp:tests/dynamically-hooked-block-with-multiple-false /--><!-- wp:tests/other-block /--><!-- wp:tests/yet-another-anchor-block /-->', 168 $actual 169 ); 170 } 70 171 }
Note: See TracChangeset
for help on using the changeset viewer.