Changeset 57627
- Timestamp:
- 02/13/2024 03:10:21 PM (9 months ago)
- Location:
- trunk
- Files:
-
- 1 added
- 1 deleted
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/block-template-utils.php
r57594 r57627 1433 1433 return $template_hierarchy; 1434 1434 } 1435 /** 1436 * Inject ignoredHookedBlocks metadata attributes into a template or template part. 1437 * 1438 * Given a `wp_template` or `wp_template_part` post object, locate all blocks that have 1439 * hooked blocks, and inject a `metadata.ignoredHookedBlocks` attribute into the anchor 1440 * blocks to reflect the latter. 1441 * 1442 * @param WP_Post $post A post object with post type set to `wp_template` or `wp_template_part`. 1443 * @return WP_Post The updated post object. 1444 */ 1445 function inject_ignored_hooked_blocks_metadata_attributes( $post ) { 1446 $hooked_blocks = get_hooked_blocks(); 1447 if ( empty( $hooked_blocks ) && ! has_filter( 'hooked_block_types' ) ) { 1448 return; 1449 } 1450 1451 // At this point, the post has already been created. 1452 // We need to build the corresponding `WP_Block_Template` object as context argument for the visitor. 1453 // To that end, we need to suppress hooked blocks from getting inserted into the template. 1454 add_filter( 'hooked_block_types', '__return_empty_array', 99999, 0 ); 1455 $template = _build_block_template_result_from_post( $post ); 1456 remove_filter( 'hooked_block_types', '__return_empty_array', 99999 ); 1457 1458 $before_block_visitor = make_before_block_visitor( $hooked_blocks, $template, 'set_ignored_hooked_blocks_metadata' ); 1459 $after_block_visitor = make_after_block_visitor( $hooked_blocks, $template, 'set_ignored_hooked_blocks_metadata' ); 1460 1461 $blocks = parse_blocks( $template->content ); 1462 $content = traverse_and_serialize_blocks( $blocks, $before_block_visitor, $after_block_visitor ); 1463 1464 wp_update_post( 1465 array( 1466 'ID' => $post->ID, 1467 'post_content' => $content, 1468 ) 1469 ); 1470 } -
trunk/src/wp-includes/blocks.php
r57590 r57627 852 852 853 853 /** 854 * Conditionally returns the markup for a given hooked block.855 *856 * Accepts three arguments: A hooked block, its type, and a reference to an anchor block.857 * If the anchor block has already been processed, and the given hooked block type is in the list858 * of ignored hooked blocks, an empty string is returned.859 *860 * The hooked block type is specified separately as it's possible that a filter might've modified861 * the hooked block such that `$hooked_block['blockName']` does no longer reflect the original type.862 *863 * This function is meant for internal use only.864 *865 * @since 6.5.0866 * @access private867 *868 * @param array $hooked_block The hooked block, represented as a parsed block array.869 * @param string $hooked_block_type The type of the hooked block. This could be different from870 * $hooked_block['blockName'], as a filter might've modified the latter.871 * @param array $anchor_block The anchor block, represented as a parsed block array.872 * Passed by reference.873 * @return string The markup for the given hooked block, or an empty string if the block is ignored.874 */875 function get_hooked_block_markup( $hooked_block, $hooked_block_type, &$anchor_block ) {876 if ( ! isset( $anchor_block['attrs']['metadata']['ignoredHookedBlocks'] ) ) {877 $anchor_block['attrs']['metadata']['ignoredHookedBlocks'] = array();878 }879 880 if ( in_array( $hooked_block_type, $anchor_block['attrs']['metadata']['ignoredHookedBlocks'], true ) ) {881 return '';882 }883 884 // The following is only needed for the REST API endpoint.885 // However, its presence does not affect the frontend.886 $anchor_block['attrs']['metadata']['ignoredHookedBlocks'][] = $hooked_block_type;887 888 return serialize_block( $hooked_block );889 }890 891 /**892 854 * Returns the markup for blocks hooked to the given anchor block in a specific relative position. 893 855 * … … 947 909 948 910 // It's possible that the `hooked_block_{$hooked_block_type}` filter returned a block of a different type, 949 // so we need to pass the original $hooked_block_type as well. 950 $markup .= get_hooked_block_markup( $parsed_hooked_block, $hooked_block_type, $parsed_anchor_block ); 911 // so we explicitly look for the original `$hooked_block_type` in the `ignoredHookedBlocks` metadata. 912 if ( 913 ! isset( $parsed_anchor_block['attrs']['metadata']['ignoredHookedBlocks'] ) || 914 ! in_array( $hooked_block_type, $parsed_anchor_block['attrs']['metadata']['ignoredHookedBlocks'], true ) 915 ) { 916 $markup .= serialize_block( $parsed_hooked_block ); 917 } 951 918 } 952 919 953 920 return $markup; 921 } 922 923 /** 924 * Adds a list of hooked block types to an anchor block's ignored hooked block types. 925 * 926 * This function is meant for internal use only. 927 * 928 * @since 6.5.0 929 * @access private 930 * 931 * @param array $parsed_anchor_block The anchor block, in parsed block array format. 932 * @param string $relative_position The relative position of the hooked blocks. 933 * Can be one of 'before', 'after', 'first_child', or 'last_child'. 934 * @param array $hooked_blocks An array of hooked block types, grouped by anchor block and relative position. 935 * @param WP_Block_Template|array $context The block template, template part, or pattern that the anchor block belongs to. 936 * @return string An empty string. 937 */ 938 function set_ignored_hooked_blocks_metadata( &$parsed_anchor_block, $relative_position, $hooked_blocks, $context ) { 939 $anchor_block_type = $parsed_anchor_block['blockName']; 940 $hooked_block_types = isset( $hooked_blocks[ $anchor_block_type ][ $relative_position ] ) 941 ? $hooked_blocks[ $anchor_block_type ][ $relative_position ] 942 : array(); 943 944 /** This filter is documented in wp-includes/blocks.php */ 945 $hooked_block_types = apply_filters( 'hooked_block_types', $hooked_block_types, $relative_position, $anchor_block_type, $context ); 946 if ( empty( $hooked_block_types ) ) { 947 return ''; 948 } 949 950 $previously_ignored_hooked_blocks = isset( $parsed_anchor_block['attrs']['metadata']['ignoredHookedBlocks'] ) 951 ? $parsed_anchor_block['attrs']['metadata']['ignoredHookedBlocks'] 952 : array(); 953 954 $parsed_anchor_block['attrs']['metadata']['ignoredHookedBlocks'] = array_unique( 955 array_merge( 956 $previously_ignored_hooked_blocks, 957 $hooked_block_types 958 ) 959 ); 960 961 // Markup for the hooked blocks has already been created (in `insert_hooked_blocks`). 962 return ''; 954 963 } 955 964 … … 964 973 * 965 974 * @since 6.4.0 975 * @since 6.5.0 Added $callback argument. 966 976 * @access private 967 977 * … … 969 979 * @param WP_Block_Template|WP_Post|array $context A block template, template part, `wp_navigation` post object, 970 980 * or pattern that the blocks belong to. 981 * @param callable $callback A function that will be called for each block to generate 982 * the markup for a given list of blocks that are hooked to it. 983 * Default: 'insert_hooked_blocks'. 971 984 * @return callable A function that returns the serialized markup for the given block, 972 985 * including the markup for any hooked blocks before it. 973 986 */ 974 function make_before_block_visitor( $hooked_blocks, $context ) {987 function make_before_block_visitor( $hooked_blocks, $context, $callback = 'insert_hooked_blocks' ) { 975 988 /** 976 989 * Injects hooked blocks before the given block, injects the `theme` attribute into Template Part blocks, and returns the serialized markup. … … 985 998 * @return string The serialized markup for the given block, with the markup for any hooked blocks prepended to it. 986 999 */ 987 return function ( &$block, &$parent_block = null, $prev = null ) use ( $hooked_blocks, $context ) {1000 return function ( &$block, &$parent_block = null, $prev = null ) use ( $hooked_blocks, $context, $callback ) { 988 1001 _inject_theme_attribute_in_template_part_block( $block ); 989 1002 … … 992 1005 if ( $parent_block && ! $prev ) { 993 1006 // Candidate for first-child insertion. 994 $markup .= insert_hooked_blocks( $parent_block, 'first_child', $hooked_blocks, $context ); 995 } 996 997 $markup .= insert_hooked_blocks( $block, 'before', $hooked_blocks, $context ); 1007 $markup .= call_user_func_array( 1008 $callback, 1009 array( &$parent_block, 'first_child', $hooked_blocks, $context ) 1010 ); 1011 } 1012 1013 $markup .= call_user_func_array( 1014 $callback, 1015 array( &$block, 'before', $hooked_blocks, $context ) 1016 ); 998 1017 999 1018 return $markup; … … 1011 1030 * 1012 1031 * @since 6.4.0 1032 * @since 6.5.0 Added $callback argument. 1013 1033 * @access private 1014 1034 * … … 1016 1036 * @param WP_Block_Template|WP_Post|array $context A block template, template part, `wp_navigation` post object, 1017 1037 * or pattern that the blocks belong to. 1038 * @param callable $callback A function that will be called for each block to generate 1039 * the markup for a given list of blocks that are hooked to it. 1040 * Default: 'insert_hooked_blocks'. 1018 1041 * @return callable A function that returns the serialized markup for the given block, 1019 1042 * including the markup for any hooked blocks after it. 1020 1043 */ 1021 function make_after_block_visitor( $hooked_blocks, $context ) {1044 function make_after_block_visitor( $hooked_blocks, $context, $callback = 'insert_hooked_blocks' ) { 1022 1045 /** 1023 1046 * Injects hooked blocks after the given block, and returns the serialized markup. … … 1031 1054 * @return string The serialized markup for the given block, with the markup for any hooked blocks appended to it. 1032 1055 */ 1033 return function ( &$block, &$parent_block = null, $next = null ) use ( $hooked_blocks, $context ) { 1034 $markup = insert_hooked_blocks( $block, 'after', $hooked_blocks, $context ); 1056 return function ( &$block, &$parent_block = null, $next = null ) use ( $hooked_blocks, $context, $callback ) { 1057 $markup = call_user_func_array( 1058 $callback, 1059 array( &$block, 'after', $hooked_blocks, $context ) 1060 ); 1035 1061 1036 1062 if ( $parent_block && ! $next ) { 1037 1063 // Candidate for last-child insertion. 1038 $markup .= insert_hooked_blocks( $parent_block, 'last_child', $hooked_blocks, $context ); 1064 $markup .= call_user_func_array( 1065 $callback, 1066 array( &$parent_block, 'last_child', $hooked_blocks, $context ) 1067 ); 1039 1068 } 1040 1069 -
trunk/src/wp-includes/default-filters.php
r57558 r57627 753 753 add_action( 'init', '_wp_register_default_font_collections' ); 754 754 755 // It might be nice to use a filter instead of an action, but the `WP_REST_Templates_Controller` doesn't 756 // provide one (unlike e.g. `WP_REST_Posts_Controller`, which has `rest_pre_insert_{$this->post_type}`). 757 add_action( 'rest_after_insert_wp_template', 'inject_ignored_hooked_blocks_metadata_attributes', 10, 3 ); 758 add_action( 'rest_after_insert_wp_template_part', 'inject_ignored_hooked_blocks_metadata_attributes', 10, 3 ); 759 755 760 unset( $filter, $action ); -
trunk/tests/phpunit/tests/block-templates/base.php
r57594 r57627 40 40 'post_name' => 'my_template', 41 41 'post_title' => 'My Template', 42 'post_content' => '<!-- wp:heading {"level":1 } --><h1>Template</h1><!-- /wp:heading -->',42 'post_content' => '<!-- wp:heading {"level":1,"metadata":{"ignoredHookedBlocks":["tests/ignored"]}} --><h1>Template</h1><!-- /wp:heading -->', 43 43 'post_excerpt' => 'Description of my template', 44 44 'tax_input' => array( … … 58 58 'post_name' => 'my_template_part', 59 59 'post_title' => 'My Template Part', 60 'post_content' => '<!-- wp:heading {"level":2 } --><h2>Template Part</h2><!-- /wp:heading -->',60 'post_content' => '<!-- wp:heading {"level":2,"metadata":{"ignoredHookedBlocks":["tests/ignored"]}} --><h2>Template Part</h2><!-- /wp:heading -->', 61 61 'post_excerpt' => 'Description of my template part', 62 62 'tax_input' => array( -
trunk/tests/phpunit/tests/block-templates/buildBlockTemplateResultFromPost.php
r57594 r57627 19 19 if ( $registry->is_registered( 'tests/my-block' ) ) { 20 20 $registry->unregister( 'tests/my-block' ); 21 } 22 23 if ( $registry->is_registered( 'tests/ignored' ) ) { 24 $registry->unregister( 'tests/ignored' ); 21 25 } 22 26 … … 68 72 /** 69 73 * @ticket 59646 74 * @ticket 60506 70 75 */ 71 76 public function test_should_inject_hooked_block_into_template() { … … 84 89 ); 85 90 $this->assertStringStartsWith( '<!-- wp:tests/my-block /-->', $template->content ); 86 $this->assertStringContainsString( '"metadata":{"ignoredHookedBlocks":["tests/my-block"]}', $template->content );87 91 } 88 92 89 93 /** 90 94 * @ticket 59646 95 * @ticket 60506 91 96 */ 92 97 public function test_should_inject_hooked_block_into_template_part() { … … 105 110 ); 106 111 $this->assertStringEndsWith( '<!-- wp:tests/my-block /-->', $template_part->content ); 107 $this->assertStringContainsString( '"metadata":{"ignoredHookedBlocks":["tests/my-block"]}', $template_part->content ); 112 } 113 114 /** 115 * @ticket 59646 116 * @ticket 60506 117 */ 118 public function test_should_not_inject_ignored_hooked_block_into_template() { 119 register_block_type( 120 'tests/ignored', 121 array( 122 'block_hooks' => array( 123 'core/heading' => 'after', 124 ), 125 ) 126 ); 127 128 $template = _build_block_template_result_from_post( 129 self::$template_post, 130 'wp_template' 131 ); 132 $this->assertStringNotContainsString( '<!-- wp:tests/ignored /-->', $template->content ); 133 } 134 135 /** 136 * @ticket 59646 137 * @ticket 60506 138 */ 139 public function test_should_not_inject_ignored_hooked_block_into_template_part() { 140 register_block_type( 141 'tests/ignored', 142 array( 143 'block_hooks' => array( 144 'core/heading' => 'after', 145 ), 146 ) 147 ); 148 149 $template_part = _build_block_template_result_from_post( 150 self::$template_part_post, 151 'wp_template_part' 152 ); 153 $this->assertStringNotContainsString( '<!-- wp:tests/ignored /-->', $template_part->content ); 108 154 } 109 155 } -
trunk/tests/phpunit/tests/blocks/getHookedBlocks.php
r57172 r57627 137 137 * @ticket 59313 138 138 * @ticket 60008 139 * @ticket 60506 139 140 * 140 141 * @covers ::get_hooked_blocks … … 151 152 ); 152 153 $this->assertStringContainsString( 153 '<!-- wp:post-content {"layout":{"type":"constrained"} ,"metadata":{"ignoredHookedBlocks":["tests/hooked-after"]}} /-->'154 '<!-- wp:post-content {"layout":{"type":"constrained"}} /-->' 154 155 . '<!-- wp:tests/hooked-after /-->', 155 156 $template->content … … 168 169 * @ticket 59313 169 170 * @ticket 60008 171 * @ticket 60506 170 172 * 171 173 * @covers ::get_hooked_blocks … … 179 181 $this->assertStringContainsString( 180 182 '<!-- wp:tests/hooked-before /-->' 181 . '<!-- wp:navigation {"layout":{"type":"flex","setCascadingProperties":true,"justifyContent":"right"} ,"metadata":{"ignoredHookedBlocks":["tests/hooked-before"]}} /-->',183 . '<!-- wp:navigation {"layout":{"type":"flex","setCascadingProperties":true,"justifyContent":"right"}} /-->', 182 184 $template->content 183 185 ); … … 199 201 * @ticket 59313 200 202 * @ticket 60008 203 * @ticket 60506 201 204 * 202 205 * @covers ::get_hooked_blocks … … 219 222 ); 220 223 $this->assertStringContainsString( 221 '<!-- wp:comments {"metadata":{"ignoredHookedBlocks":["tests/hooked-first-child"]}}-->'224 '<!-- wp:comments -->' 222 225 . '<div class="wp-block-comments">' 223 226 . '<!-- wp:tests/hooked-first-child /-->', -
trunk/tests/phpunit/tests/blocks/insertHookedBlocks.php
r57354 r57627 26 26 * @ticket 59572 27 27 * @ticket 60126 28 * @ticket 60506 28 29 * 29 30 * @covers ::insert_hooked_blocks 30 31 */ 31 public function test_insert_hooked_blocks_ adds_metadata() {32 public function test_insert_hooked_blocks_returns_correct_markup() { 32 33 $anchor_block = array( 33 34 'blockName' => self::ANCHOR_BLOCK_TYPE, … … 35 36 36 37 $actual = insert_hooked_blocks( $anchor_block, 'after', self::HOOKED_BLOCKS, array() ); 37 $this->assertSame(38 array( self::HOOKED_BLOCK_TYPE ),39 $anchor_block['attrs']['metadata']['ignoredHookedBlocks'],40 "Hooked block type wasn't added to ignoredHookedBlocks metadata."41 );42 38 $this->assertSame( 43 39 '<!-- wp:' . self::HOOKED_BLOCK_TYPE . ' /-->', … … 50 46 * @ticket 59572 51 47 * @ticket 60126 48 * @ticket 60506 52 49 * 53 50 * @covers ::insert_hooked_blocks 54 51 */ 55 public function test_insert_hooked_blocks_if_block_is_ already_hooked() {52 public function test_insert_hooked_blocks_if_block_is_ignored() { 56 53 $anchor_block = array( 57 54 'blockName' => 'tests/anchor-block', … … 65 62 $actual = insert_hooked_blocks( $anchor_block, 'after', self::HOOKED_BLOCKS, array() ); 66 63 $this->assertSame( 67 array( self::HOOKED_BLOCK_TYPE ),68 $anchor_block['attrs']['metadata']['ignoredHookedBlocks'],69 "ignoredHookedBlocks metadata shouldn't have been modified."70 );71 $this->assertSame(72 64 '', 73 65 $actual, … … 79 71 * @ticket 59572 80 72 * @ticket 60126 73 * @ticket 60506 81 74 * 82 75 * @covers ::insert_hooked_blocks 83 76 */ 84 public function test_insert_hooked_blocks_ adds_to_ignored_hooked_blocks() {77 public function test_insert_hooked_blocks_if_other_block_is_ignored() { 85 78 $anchor_block = array( 86 79 'blockName' => 'tests/anchor-block', … … 94 87 $actual = insert_hooked_blocks( $anchor_block, 'before', self::HOOKED_BLOCKS, array() ); 95 88 $this->assertSame( 96 array( self::HOOKED_BLOCK_TYPE, self::OTHER_HOOKED_BLOCK_TYPE ),97 $anchor_block['attrs']['metadata']['ignoredHookedBlocks'],98 "Newly hooked block should've been added to ignoredHookedBlocks metadata while retaining previously ignored one."99 );100 $this->assertSame(101 89 '<!-- wp:' . self::OTHER_HOOKED_BLOCK_TYPE . ' /-->', 102 90 $actual, … … 108 96 * @ticket 59572 109 97 * @ticket 60126 98 * @ticket 60506 110 99 * 111 100 * @covers ::insert_hooked_blocks … … 141 130 142 131 $this->assertSame( 143 array( self::HOOKED_BLOCK_TYPE ),144 $anchor_block['attrs']['metadata']['ignoredHookedBlocks'],145 "Hooked block type wasn't added to ignoredHookedBlocks metadata."146 );147 $this->assertSame(148 132 '<!-- wp:' . self::HOOKED_BLOCK_TYPE . ' {"layout":{"type":"constrained"}} /-->', 149 133 $actual, … … 155 139 * @ticket 59572 156 140 * @ticket 60126 141 * @ticket 60506 157 142 * 158 143 * @covers ::insert_hooked_blocks … … 191 176 192 177 $this->assertSame( 193 array( self::HOOKED_BLOCK_TYPE ),194 $anchor_block['attrs']['metadata']['ignoredHookedBlocks'],195 "Hooked block type wasn't added to ignoredHookedBlocks metadata."196 );197 $this->assertSame(198 178 '<!-- wp:group --><div class="wp-block-group"><!-- wp:' . self::HOOKED_BLOCK_TYPE . ' /--></div><!-- /wp:group -->', 199 179 $actual, -
trunk/tests/phpunit/tests/blocks/wpBlockPatternsRegistry.php
r57172 r57627 345 345 * @ticket 59476 346 346 * @ticket 60008 347 * @ticket 60506 347 348 * 348 349 * @covers WP_Block_Patterns_Registry::register … … 386 387 $this->assertCount( 3, $registered ); 387 388 $this->assertStringEndsWith( '<!-- wp:tests/my-block /-->', $registered[1]['content'] ); 388 $this->assertStringContainsString( '"metadata":{"ignoredHookedBlocks":["tests/my-block"]}', $registered[1]['content'] );389 389 $this->assertStringEndsWith( '<!-- wp:tests/my-block /-->', $registered[2]['content'] ); 390 $this->assertStringContainsString( '"metadata":{"ignoredHookedBlocks":["tests/my-block"]}', $registered[2]['content'] );391 390 } 392 391 … … 419 418 * @ticket 59476 420 419 * @ticket 60008 420 * @ticket 60506 421 421 * 422 422 * @covers WP_Block_Patterns_Registry::register … … 447 447 $pattern = $this->registry->get_registered( 'test/one' ); 448 448 $this->assertStringStartsWith( '<!-- wp:tests/my-block /-->', $pattern['content'] ); 449 $this->assertStringContainsString( '"metadata":{"ignoredHookedBlocks":["tests/my-block"]}', $pattern['content'] );450 449 } 451 450
Note: See TracChangeset
for help on using the changeset viewer.