From 20e160cb4ba752f5a2d0555caa4ac19a37984759 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Thu, 5 Sep 2024 14:21:23 +0200 Subject: [PATCH 1/7] Tests: Register hooked blocks --- .../tests/blocks/insertHookedBlocks.php | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/tests/phpunit/tests/blocks/insertHookedBlocks.php b/tests/phpunit/tests/blocks/insertHookedBlocks.php index cf99b213e518c..a7c864a4ab9ea 100644 --- a/tests/phpunit/tests/blocks/insertHookedBlocks.php +++ b/tests/phpunit/tests/blocks/insertHookedBlocks.php @@ -22,6 +22,43 @@ class Tests_Blocks_InsertHookedBlocks extends WP_UnitTestCase { ), ); + public function set_up() { + register_block_type( + self::HOOKED_BLOCK_TYPE, + array( + 'block_hooks' => array( + self::ANCHOR_BLOCK_TYPE => 'after', + ), + ) + ); + + register_block_type( + self::OTHER_HOOKED_BLOCK_TYPE, + array( + 'block_hooks' => array( + self::ANCHOR_BLOCK_TYPE => 'before', + ), + ) + ); + } + + /** + * Tear down each test method. + */ + public function tear_down() { + $registry = WP_Block_Type_Registry::get_instance(); + + if ( $registry->is_registered( self::HOOKED_BLOCK_TYPE ) ) { + $registry->unregister( self::HOOKED_BLOCK_TYPE ); + } + + if ( $registry->is_registered( self::OTHER_HOOKED_BLOCK_TYPE ) ) { + $registry->unregister( self::OTHER_HOOKED_BLOCK_TYPE ); + } + + parent::tear_down(); + } + /** * @ticket 59572 * @ticket 60126 From 083c5fc709a93918102f735b6fe4d1e738a01066 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Thu, 5 Sep 2024 14:39:29 +0200 Subject: [PATCH 2/7] Make setup/teardown static --- .../tests/blocks/insertHookedBlocks.php | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/tests/phpunit/tests/blocks/insertHookedBlocks.php b/tests/phpunit/tests/blocks/insertHookedBlocks.php index a7c864a4ab9ea..6adb4731c46cd 100644 --- a/tests/phpunit/tests/blocks/insertHookedBlocks.php +++ b/tests/phpunit/tests/blocks/insertHookedBlocks.php @@ -22,7 +22,12 @@ class Tests_Blocks_InsertHookedBlocks extends WP_UnitTestCase { ), ); - public function set_up() { + /** + * Set up. + * + * @ticket 61902. + */ + public static function wpSetUpBeforeClass() { register_block_type( self::HOOKED_BLOCK_TYPE, array( @@ -43,20 +48,15 @@ public function set_up() { } /** - * Tear down each test method. + * Tear down. + * + * @ticket 61902. */ - public function tear_down() { + public static function wpTearDownAfterClass() { $registry = WP_Block_Type_Registry::get_instance(); - if ( $registry->is_registered( self::HOOKED_BLOCK_TYPE ) ) { - $registry->unregister( self::HOOKED_BLOCK_TYPE ); - } - - if ( $registry->is_registered( self::OTHER_HOOKED_BLOCK_TYPE ) ) { - $registry->unregister( self::OTHER_HOOKED_BLOCK_TYPE ); - } - - parent::tear_down(); + $registry->unregister( self::HOOKED_BLOCK_TYPE ); + $registry->unregister( self::OTHER_HOOKED_BLOCK_TYPE ); } /** From 277ee616525c8753080d4af17167aaac1f9cae6e Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Thu, 5 Sep 2024 14:50:07 +0200 Subject: [PATCH 3/7] Infer hooked blocks via get_hooked_blocks() --- .../tests/blocks/insertHookedBlocks.php | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/tests/phpunit/tests/blocks/insertHookedBlocks.php b/tests/phpunit/tests/blocks/insertHookedBlocks.php index 6adb4731c46cd..f291e3787a086 100644 --- a/tests/phpunit/tests/blocks/insertHookedBlocks.php +++ b/tests/phpunit/tests/blocks/insertHookedBlocks.php @@ -15,13 +15,6 @@ class Tests_Blocks_InsertHookedBlocks extends WP_UnitTestCase { const HOOKED_BLOCK_TYPE = 'tests/hooked-block'; const OTHER_HOOKED_BLOCK_TYPE = 'tests/other-hooked-block'; - const HOOKED_BLOCKS = array( - self::ANCHOR_BLOCK_TYPE => array( - 'after' => array( self::HOOKED_BLOCK_TYPE ), - 'before' => array( self::OTHER_HOOKED_BLOCK_TYPE ), - ), - ); - /** * Set up. * @@ -71,7 +64,7 @@ public function test_insert_hooked_blocks_returns_correct_markup() { 'blockName' => self::ANCHOR_BLOCK_TYPE, ); - $actual = insert_hooked_blocks( $anchor_block, 'after', self::HOOKED_BLOCKS, array() ); + $actual = insert_hooked_blocks( $anchor_block, 'after', get_hooked_blocks(), array() ); $this->assertSame( '', $actual, @@ -96,7 +89,7 @@ public function test_insert_hooked_blocks_if_block_is_ignored() { ), ); - $actual = insert_hooked_blocks( $anchor_block, 'after', self::HOOKED_BLOCKS, array() ); + $actual = insert_hooked_blocks( $anchor_block, 'after', get_hooked_blocks(), array() ); $this->assertSame( '', $actual, @@ -121,7 +114,7 @@ public function test_insert_hooked_blocks_if_other_block_is_ignored() { ), ); - $actual = insert_hooked_blocks( $anchor_block, 'before', self::HOOKED_BLOCKS, array() ); + $actual = insert_hooked_blocks( $anchor_block, 'before', get_hooked_blocks(), array() ); $this->assertSame( '', $actual, @@ -162,7 +155,7 @@ public function test_insert_hooked_blocks_filter_can_set_attributes() { return $parsed_hooked_block; }; add_filter( 'hooked_block_' . self::HOOKED_BLOCK_TYPE, $filter, 10, 4 ); - $actual = insert_hooked_blocks( $anchor_block, 'after', self::HOOKED_BLOCKS, array() ); + $actual = insert_hooked_blocks( $anchor_block, 'after', get_hooked_blocks(), array() ); remove_filter( 'hooked_block_' . self::HOOKED_BLOCK_TYPE, $filter ); $this->assertSame( @@ -208,7 +201,7 @@ public function test_insert_hooked_blocks_filter_can_wrap_block() { ); }; add_filter( 'hooked_block_' . self::HOOKED_BLOCK_TYPE, $filter, 10, 3 ); - $actual = insert_hooked_blocks( $anchor_block, 'after', self::HOOKED_BLOCKS, array() ); + $actual = insert_hooked_blocks( $anchor_block, 'after', get_hooked_blocks(), array() ); remove_filter( 'hooked_block_' . self::HOOKED_BLOCK_TYPE, $filter ); $this->assertSame( @@ -250,7 +243,7 @@ public function test_insert_hooked_blocks_filter_can_suppress_hooked_block() { return $parsed_hooked_block; }; add_filter( 'hooked_block_' . self::HOOKED_BLOCK_TYPE, $filter, 10, 4 ); - $actual = insert_hooked_blocks( $anchor_block, 'after', self::HOOKED_BLOCKS, array() ); + $actual = insert_hooked_blocks( $anchor_block, 'after', get_hooked_blocks(), array() ); remove_filter( 'hooked_block_' . self::HOOKED_BLOCK_TYPE, $filter ); $this->assertSame( '', $actual, "No markup should've been generated for hooked block suppressed by filter." ); From f94e9f46dad32165a617724fb856a726ebfeeee0 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Thu, 5 Sep 2024 15:00:58 +0200 Subject: [PATCH 4/7] Fix setup and teardown in other test --- ...locksAndSetIgnoredHookedBlocksMetadata.php | 53 +++++++++++++++---- 1 file changed, 44 insertions(+), 9 deletions(-) diff --git a/tests/phpunit/tests/blocks/insertHookedBlocksAndSetIgnoredHookedBlocksMetadata.php b/tests/phpunit/tests/blocks/insertHookedBlocksAndSetIgnoredHookedBlocksMetadata.php index 8e88719fee262..cc56f38738cc7 100644 --- a/tests/phpunit/tests/blocks/insertHookedBlocksAndSetIgnoredHookedBlocksMetadata.php +++ b/tests/phpunit/tests/blocks/insertHookedBlocksAndSetIgnoredHookedBlocksMetadata.php @@ -16,12 +16,47 @@ class Tests_Blocks_InsertHookedBlocksAndSetIgnoredHookedBlocksMetadata extends W const HOOKED_BLOCK_TYPE = 'tests/hooked-block'; const OTHER_HOOKED_BLOCK_TYPE = 'tests/other-hooked-block'; - const HOOKED_BLOCKS = array( - self::ANCHOR_BLOCK_TYPE => array( - 'after' => array( self::HOOKED_BLOCK_TYPE ), - 'before' => array( self::OTHER_HOOKED_BLOCK_TYPE ), - ), - ); + /** + * Set up. + * + * @ticket 61902. + */ + public static function wpSetUpBeforeClass() { + register_block_type( + self::HOOKED_BLOCK_TYPE, + array( + 'block_hooks' => array( + self::ANCHOR_BLOCK_TYPE => 'after', + ), + ) + ); + + register_block_type( + self::OTHER_HOOKED_BLOCK_TYPE, + array( + 'block_hooks' => array( + self::ANCHOR_BLOCK_TYPE => 'before', + ), + ) + ); + + register_block_type( 'tests/hooked-block-added-by-filter' ); + register_block_type( 'tests/hooked-block-suppressed-by-filter' ); + } + + /** + * Tear down. + * + * @ticket 61902. + */ + public static function wpTearDownAfterClass() { + $registry = WP_Block_Type_Registry::get_instance(); + + $registry->unregister( self::HOOKED_BLOCK_TYPE ); + $registry->unregister( self::OTHER_HOOKED_BLOCK_TYPE ); + $registry->unregister( 'tests/hooked-block-added-by-filter' ); + $registry->unregister( 'tests/hooked-block-suppressed-by-filter' ); + } /** * @ticket 59574 @@ -47,7 +82,7 @@ public function test_insert_hooked_blocks_and_set_ignored_hooked_blocks_metadata 'blockName' => self::ANCHOR_BLOCK_TYPE, ); - $actual = insert_hooked_blocks_and_set_ignored_hooked_blocks_metadata( $anchor_block, 'after', self::HOOKED_BLOCKS, array() ); + $actual = insert_hooked_blocks_and_set_ignored_hooked_blocks_metadata( $anchor_block, 'after', get_hooked_blocks(), array() ); $this->assertSame( '', $actual, @@ -73,7 +108,7 @@ public function test_insert_hooked_blocks_and_set_ignored_hooked_blocks_metadata ), ); - $actual = insert_hooked_blocks_and_set_ignored_hooked_blocks_metadata( $anchor_block, 'after', self::HOOKED_BLOCKS, array() ); + $actual = insert_hooked_blocks_and_set_ignored_hooked_blocks_metadata( $anchor_block, 'after', get_hooked_blocks(), array() ); $this->assertSame( '', $actual, @@ -147,7 +182,7 @@ public function test_insert_hooked_blocks_and_set_ignored_hooked_blocks_metadata return $parsed_hooked_block; }; add_filter( 'hooked_block_' . self::HOOKED_BLOCK_TYPE, $filter, 10, 4 ); - $actual = insert_hooked_blocks_and_set_ignored_hooked_blocks_metadata( $anchor_block, 'after', self::HOOKED_BLOCKS, array() ); + $actual = insert_hooked_blocks_and_set_ignored_hooked_blocks_metadata( $anchor_block, 'after', get_hooked_blocks(), array() ); remove_filter( 'hooked_block_' . self::HOOKED_BLOCK_TYPE, $filter ); $this->assertSame( '', $actual, "No markup should've been generated for hooked block suppressed by filter." ); From 67ad6480330c4fcd0be1bf6ae6c35f1a7897a211 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Thu, 5 Sep 2024 15:27:07 +0200 Subject: [PATCH 5/7] Don't insert block if multiple:false and another instance is already present --- src/wp-includes/blocks.php | 23 +++++++++++++++++ .../tests/blocks/insertHookedBlocks.php | 25 +++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/src/wp-includes/blocks.php b/src/wp-includes/blocks.php index a53092e04e4d7..0655692010ffc 100644 --- a/src/wp-includes/blocks.php +++ b/src/wp-includes/blocks.php @@ -916,6 +916,29 @@ function insert_hooked_blocks( &$parsed_anchor_block, $relative_position, $hooke $markup = ''; foreach ( $hooked_block_types as $hooked_block_type ) { + $hooked_block_type_definition = WP_Block_Type_Registry::get_instance()->get_registered( $hooked_block_type ); + if ( ! $hooked_block_type_definition ) { + continue; + } + if ( false === block_has_support( $hooked_block_type_definition, 'multiple', true ) ) { + if ( $context instanceof WP_Block_Template ) { + // Template or template part. + $content = $context->content; + } elseif ( $context instanceof WP_Post ) { + // wp_navigation post. + $content = $context->post_content; + } elseif ( is_array( $context ) && isset( $context['content'] ) ) { + // Pattern. + $content = $context['content']; + } else { + $content = ''; + } + + if ( ! empty( $content ) && has_block( $hooked_block_type, $content ) ) { + continue; + } + } + $parsed_hooked_block = array( 'blockName' => $hooked_block_type, 'attrs' => array(), diff --git a/tests/phpunit/tests/blocks/insertHookedBlocks.php b/tests/phpunit/tests/blocks/insertHookedBlocks.php index f291e3787a086..c3aff163d2320 100644 --- a/tests/phpunit/tests/blocks/insertHookedBlocks.php +++ b/tests/phpunit/tests/blocks/insertHookedBlocks.php @@ -36,6 +36,9 @@ public static function wpSetUpBeforeClass() { 'block_hooks' => array( self::ANCHOR_BLOCK_TYPE => 'before', ), + 'supports' => array( + 'multiple' => false, + ), ) ); } @@ -122,6 +125,28 @@ public function test_insert_hooked_blocks_if_other_block_is_ignored() { ); } + /** + * @ticket 61902 + * + * @covers ::insert_hooked_blocks + */ + public function test_insert_hooked_blocks_if_block_has_multiple_false_and_is_already_present() { + $anchor_block = array( + 'blockName' => 'tests/anchor-block', + ); + + $context = new WP_Block_Template(); + $context->content = ''; + $context->content .= ''; + + $actual = insert_hooked_blocks( $anchor_block, 'before', get_hooked_blocks(), $context ); + $this->assertSame( + '', + $actual, + 'Hooked block with "multiple": false should not be inserted if another instance is already present.' + ); + } + /** * @ticket 59572 * @ticket 60126 From 29fbae6ecf5e4741768c37d6211937329b8b235b Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Thu, 5 Sep 2024 16:13:13 +0200 Subject: [PATCH 6/7] Whitespace --- tests/phpunit/tests/blocks/insertHookedBlocks.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/tests/blocks/insertHookedBlocks.php b/tests/phpunit/tests/blocks/insertHookedBlocks.php index c3aff163d2320..77eb09d1a46ec 100644 --- a/tests/phpunit/tests/blocks/insertHookedBlocks.php +++ b/tests/phpunit/tests/blocks/insertHookedBlocks.php @@ -36,7 +36,7 @@ public static function wpSetUpBeforeClass() { 'block_hooks' => array( self::ANCHOR_BLOCK_TYPE => 'before', ), - 'supports' => array( + 'supports' => array( 'multiple' => false, ), ) From b75c0eba2278b277be55b0b6a36882b63e23d174 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Wed, 18 Sep 2024 15:54:35 +0200 Subject: [PATCH 7/7] Add unit test coverage for subsequent insertion --- .../tests/blocks/insertHookedBlocks.php | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/tests/phpunit/tests/blocks/insertHookedBlocks.php b/tests/phpunit/tests/blocks/insertHookedBlocks.php index 77eb09d1a46ec..3849b82784f04 100644 --- a/tests/phpunit/tests/blocks/insertHookedBlocks.php +++ b/tests/phpunit/tests/blocks/insertHookedBlocks.php @@ -145,6 +145,42 @@ public function test_insert_hooked_blocks_if_block_has_multiple_false_and_is_alr $actual, 'Hooked block with "multiple": false should not be inserted if another instance is already present.' ); + $actual = insert_hooked_blocks( $anchor_block, 'before', get_hooked_blocks(), $context ); + $this->assertSame( + '', + $actual, + 'Hooked block with "multiple": false should not be inserted if another instance is already present.' + ); + } + + /** + * @ticket 61902 + * + * @covers ::insert_hooked_blocks + */ + public function test_insert_hooked_blocks_if_block_has_multiple_false_but_is_not_yet_present() { + $anchor_block = array( + 'blockName' => 'tests/anchor-block', + ); + + $context = new WP_Block_Template(); + $context->content = ''; + + $expected = ''; + $actual = insert_hooked_blocks( $anchor_block, 'before', get_hooked_blocks(), $context ); + $this->assertSame( + $expected, + $actual, + 'Hooked block with "multiple": false should be inserted if another instance is not present.' + ); + + $context->content = $expected . $context->content; // Simulate result of first insertion. + $actual = insert_hooked_blocks( $anchor_block, 'before', get_hooked_blocks(), $context ); + $this->assertSame( + '', + $actual, + 'Hooked block with "multiple": false should not be inserted if another instance is already present.' + ); } /**