diff --git a/.changeset/sweet-jars-shout.md b/.changeset/sweet-jars-shout.md new file mode 100644 index 00000000..088b0c72 --- /dev/null +++ b/.changeset/sweet-jars-shout.md @@ -0,0 +1,5 @@ +--- +"@wpengine/wp-graphql-content-blocks": patch +--- + +Bug fix. Reusable block isn't resolved inside innerBlocks. diff --git a/includes/Data/ContentBlocksResolver.php b/includes/Data/ContentBlocksResolver.php index 14e98d7f..625a4372 100644 --- a/includes/Data/ContentBlocksResolver.php +++ b/includes/Data/ContentBlocksResolver.php @@ -7,6 +7,7 @@ namespace WPGraphQL\ContentBlocks\Data; +use WPGraphQL\ContentBlocks\Utilities\TraverseHelpers; use WPGraphQL\Model\Post; /** @@ -54,23 +55,6 @@ public static function resolve_content_blocks( $node, $args, $allowed_block_name return []; } - // Resolve reusable blocks - replaces "core/block" with the corresponding block(s) from the reusable ref ID - $new_parsed_blocks = []; - foreach ( $parsed_blocks as $block ) { - if ( 'core/block' === $block['blockName'] && $block['attrs']['ref'] ) { - $post = get_post( $block['attrs']['ref'] ); - $reusable_blocks = ! empty( $post->post_content ) ? parse_blocks( $post->post_content ) : null; - - if ( ! empty( $reusable_blocks ) ) { - array_push( $new_parsed_blocks, ...$reusable_blocks ); - } - } else { - $new_parsed_blocks[] = $block; - } - } - - $parsed_blocks = $new_parsed_blocks; - // 1st Level filtering of blocks that are empty $parsed_blocks = array_filter( $parsed_blocks, @@ -99,12 +83,12 @@ static function ( $parsed_block ) { }, $parsed_blocks ); - + // Resolve reusable blocks - replaces "core/block" with the corresponding block(s) from the reusable ref ID + TraverseHelpers::traverse_blocks( $parsed_blocks, [ TraverseHelpers::class, 'replace_reusable_blocks' ], 0, PHP_INT_MAX ); // Flatten block list here if requested or if 'flat' value is not selected (default) if ( ! isset( $args['flat'] ) || 'true' == $args['flat'] ) { // phpcs:ignore Universal.Operators.StrictComparisons.LooseEqual $parsed_blocks = self::flatten_block_list( $parsed_blocks ); } - // Final level of filtering out blocks not in the allowed list if ( ! empty( $allowed_block_names ) ) { $parsed_blocks = array_filter( diff --git a/includes/Utilities/TraverseHelpers.php b/includes/Utilities/TraverseHelpers.php new file mode 100644 index 00000000..0df8868c --- /dev/null +++ b/includes/Utilities/TraverseHelpers.php @@ -0,0 +1,48 @@ +post_content ) ? parse_blocks( $post->post_content ) : null; + + if ( ! empty( $reusable_blocks ) ) { + $block = array_merge( ...$reusable_blocks ); + } + } + } +} diff --git a/tests/unit/ContentBlocksResolverTest.php b/tests/unit/ContentBlocksResolverTest.php index ba002923..c8cc3e40 100644 --- a/tests/unit/ContentBlocksResolverTest.php +++ b/tests/unit/ContentBlocksResolverTest.php @@ -95,7 +95,7 @@ public function tearDown(): void { public function test_resolve_content_blocks_resolves_reusable_blocks() { $post_model = new Post( get_post( $this->reusable_post_id ) ); $actual = $this->instance->resolve_content_blocks( $post_model, array( 'flat' => true ) ); - + // There should return only the non-empty blocks $this->assertEquals( 3, count( $actual ) ); $this->assertEquals( 'core/columns', $actual[0]['blockName'] ); diff --git a/tests/unit/TraverseHelpersTest.php b/tests/unit/TraverseHelpersTest.php new file mode 100644 index 00000000..ec710462 --- /dev/null +++ b/tests/unit/TraverseHelpersTest.php @@ -0,0 +1,85 @@ +post_id = wp_insert_post( + array( + 'post_title' => 'Post Title', + 'post_content' => preg_replace( + '/\s+/', + ' ', + trim( + ' + +
Test
+ ' + ) + ), + 'post_status' => 'publish', + ) + ); + } + + public function tearDown(): void { + // your tear down methods here + parent::tearDown(); + wp_delete_post( $this->post_id, true ); + } + public function testTraverseBlocks() { + // Sample blocks data + $blocks = [ + [ + 'blockName' => 'core/group', + 'attrs' => [], + 'innerBlocks' => [ + [ + 'blockName' => 'core/block', + 'attrs' => [ 'ref' => $this->post_id ], + 'innerBlocks' => [] + ] + ] + ], + [ + 'blockName' => 'core/block', + 'attrs' => [ 'ref' => $this->post_id ], + 'innerBlocks' => [] + ] + ]; + + // Expected result after replacing reusable blocks + $expected = [ + [ + 'blockName' => 'core/group', + 'attrs' => [], + 'innerBlocks' => [ + [ + 'blockName' => 'core/paragraph', + 'attrs' => [], + 'innerBlocks' => [], + 'innerHTML' => 'Test
', + 'innerContent' => [ 0 => 'Test
'] + ] + ] + ], + [ + 'blockName' => 'core/paragraph', + 'attrs' => [], + 'innerBlocks' => [], + 'innerHTML' => 'Test
', + 'innerContent' => [ 0 => 'Test
'] + ] + ]; + + TraverseHelpers::traverse_blocks( $blocks, [ TraverseHelpers::class, 'replace_reusable_blocks' ], 0, PHP_INT_MAX ); + $this->assertEquals( $expected, $blocks ); + } +} \ No newline at end of file