From 3bf219c87fe592232cb8022d5e1ee6097c3cbbe4 Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Mon, 7 Oct 2024 17:10:18 +0530 Subject: [PATCH 01/36] Introduce update_available_context() --- src/wp-includes/class-wp-block.php | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/wp-includes/class-wp-block.php b/src/wp-includes/class-wp-block.php index 8cfa996028da2..e075698074728 100644 --- a/src/wp-includes/class-wp-block.php +++ b/src/wp-includes/class-wp-block.php @@ -139,6 +139,23 @@ public function __construct( $block, $available_context = array(), $registry = n $this->block_type = $registry->get_registered( $this->name ); $this->available_context = $available_context; + $this->update_available_context( $block, $available_context ); + + if ( ! empty( $block['innerHTML'] ) ) { + $this->inner_html = $block['innerHTML']; + } + + if ( ! empty( $block['innerContent'] ) ) { + $this->inner_content = $block['innerContent']; + } + } + + public function update_available_context( $block, $available_context ) { + if ( null === $this->available_context ) { + $this->available_context = $available_context; + } else { + $this->available_context = array_merge( $this->available_context, $available_context ); + } if ( ! empty( $this->block_type->uses_context ) ) { foreach ( $this->block_type->uses_context as $context_name ) { @@ -159,15 +176,7 @@ public function __construct( $block, $available_context = array(), $registry = n } } - $this->inner_blocks = new WP_Block_List( $block['innerBlocks'], $child_context, $registry ); - } - - if ( ! empty( $block['innerHTML'] ) ) { - $this->inner_html = $block['innerHTML']; - } - - if ( ! empty( $block['innerContent'] ) ) { - $this->inner_content = $block['innerContent']; + $this->inner_blocks = new WP_Block_List( $block['innerBlocks'], $child_context, $this->registry ); } } @@ -514,6 +523,8 @@ public function render( $options = array() ) { /** This filter is documented in wp-includes/blocks.php */ $inner_block->context = apply_filters( 'render_block_context', $inner_block->context, $inner_block->parsed_block, $parent_block ); + $inner_block->update_available_context( $inner_block->parsed_block, $inner_block->context ); + $block_content .= $inner_block->render(); } From 7b54206ad2bb1354a3129314204d64cceb0aed37 Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Mon, 7 Oct 2024 18:13:15 +0530 Subject: [PATCH 02/36] Apply suggestions from code review --- src/wp-includes/class-wp-block.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/wp-includes/class-wp-block.php b/src/wp-includes/class-wp-block.php index e075698074728..7b7f4f8591f57 100644 --- a/src/wp-includes/class-wp-block.php +++ b/src/wp-includes/class-wp-block.php @@ -151,6 +151,7 @@ public function __construct( $block, $available_context = array(), $registry = n } public function update_available_context( $block, $available_context ) { + $this->context = array(); if ( null === $this->available_context ) { $this->available_context = $available_context; } else { From dbd61265d6b5c93be71f175a388c0d83763287e7 Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Mon, 7 Oct 2024 18:32:28 +0530 Subject: [PATCH 03/36] Add unit tests --- tests/phpunit/tests/blocks/renderBlock.php | 117 +++++++++++++++++++++ 1 file changed, 117 insertions(+) diff --git a/tests/phpunit/tests/blocks/renderBlock.php b/tests/phpunit/tests/blocks/renderBlock.php index 0c1c4ce10a1ee..c0e4f03708a3f 100644 --- a/tests/phpunit/tests/blocks/renderBlock.php +++ b/tests/phpunit/tests/blocks/renderBlock.php @@ -192,4 +192,121 @@ public function test_default_context_is_filterable() { $this->assertSame( array( 'example' => 'ok' ), $provided_context[0] ); } + + /** + * Tests the behavior of the 'render_block_context' filter based on the location of the filtered block. + * + * @ticket 62046 + */ + public function test_render_block_context_inner_blocks() { + $provided_context = array(); + + register_block_type( + 'tests/context-provider', + array( + 'provides_context' => array( 'example' ), + ) + ); + + register_block_type( + 'tests/context-consumer', + array( + 'uses_context' => array( 'example' ), + 'render_callback' => static function ( $attributes, $content, $block ) use ( &$provided_context ) { + $provided_context = $block->context; + + return ''; + }, + ) + ); + + // Filter the context provided by the test block. + add_filter( + 'render_block_context', + function ( $context, $parsed_block ) { + if ( isset( $parsed_block['blockName'] ) && 'tests/context-provider' === $parsed_block['blockName'] ) { + $context['example'] = 'ok'; + } + + return $context; + }, + 10, + 2 + ); + + // Test inner block context when the provider block is a top-level block. + do_blocks( + << + + +HTML + ); + $this->assertTrue( isset( $provided_context['example'] ), 'Test block is top-level block: Context should include "example"' ); + $this->assertSame( 'ok', $provided_context['example'], 'Test block is top-level block: "example" in context should be "ok"' ); + + // Test inner block context when the provider block is an inner block. + do_blocks( + << + + + + +HTML + ); + $this->assertTrue( isset( $provided_context['example'] ), 'Test block is inner block: Block context should include "example"' ); + $this->assertSame( 'ok', $provided_context['example'], 'Test block is inner block: "example" in context should be "ok"' ); + } + + /** + * Tests that the 'render_block_context' filter provides available context, not actual context. + * + * @ticket 62046 + */ + public function test_render_block_context_allowed_context() { + $provided_context = array(); + + register_block_type( + 'tests/context-consumer', + array( + 'uses_context' => array( 'example' ), + 'render_callback' => static function ( $attributes, $content, $block ) use ( &$provided_context ) { + $provided_context = $block->context; + + return ''; + }, + ) + ); + + // Filter the context provided to the test block. + add_filter( + 'render_block_context', + function ( $context, $parsed_block ) { + if ( isset( $parsed_block['blockName'] ) && 'tests/context-consumer' === $parsed_block['blockName'] ) { + $context['invalid'] = 'ok'; + } + + return $context; + }, + 10, + 2 + ); + + do_blocks( + << +HTML + ); + $this->assertFalse( isset( $provided_context['invalid'] ), 'Test block is top-level block: Context should not include unsupported properties"' ); + + do_blocks( + << + + +HTML + ); + $this->assertFalse( isset( $provided_context['invalid'] ), 'Test block is inner block: Context should not include unsupported properties' ); + } } From c229a57d4284f5bdb60b3c0b4e39e5f8eed47629 Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Mon, 7 Oct 2024 18:51:10 +0530 Subject: [PATCH 04/36] Apply suggestions from code review --- tests/phpunit/tests/blocks/renderBlock.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/phpunit/tests/blocks/renderBlock.php b/tests/phpunit/tests/blocks/renderBlock.php index c0e4f03708a3f..71f3784f38729 100644 --- a/tests/phpunit/tests/blocks/renderBlock.php +++ b/tests/phpunit/tests/blocks/renderBlock.php @@ -270,8 +270,8 @@ public function test_render_block_context_allowed_context() { register_block_type( 'tests/context-consumer', array( - 'uses_context' => array( 'example' ), - 'render_callback' => static function ( $attributes, $content, $block ) use ( &$provided_context ) { + 'uses_context' => array( 'example' ), + 'render_callback' => static function ( $attributes, $content, $block ) use ( &$provided_context ) { $provided_context = $block->context; return ''; From a95ca1d7a49e13470df0d33fdb177d5072fc27ab Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Tue, 8 Oct 2024 17:07:07 +0530 Subject: [PATCH 05/36] Pull latest tests --- tests/phpunit/tests/blocks/renderBlock.php | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/tests/phpunit/tests/blocks/renderBlock.php b/tests/phpunit/tests/blocks/renderBlock.php index 71f3784f38729..7bfac371fb328 100644 --- a/tests/phpunit/tests/blocks/renderBlock.php +++ b/tests/phpunit/tests/blocks/renderBlock.php @@ -196,7 +196,7 @@ public function test_default_context_is_filterable() { /** * Tests the behavior of the 'render_block_context' filter based on the location of the filtered block. * - * @ticket 62046 + * @ticket 620426 */ public function test_render_block_context_inner_blocks() { $provided_context = array(); @@ -260,7 +260,7 @@ function ( $context, $parsed_block ) { } /** - * Tests that the 'render_block_context' filter provides available context, not actual context. + * Tests that the 'render_block_context' filter arbitrary context. * * @ticket 62046 */ @@ -273,10 +273,9 @@ public function test_render_block_context_allowed_context() { 'uses_context' => array( 'example' ), 'render_callback' => static function ( $attributes, $content, $block ) use ( &$provided_context ) { $provided_context = $block->context; - return ''; }, - ) + ), ); // Filter the context provided to the test block. @@ -284,7 +283,7 @@ public function test_render_block_context_allowed_context() { 'render_block_context', function ( $context, $parsed_block ) { if ( isset( $parsed_block['blockName'] ) && 'tests/context-consumer' === $parsed_block['blockName'] ) { - $context['invalid'] = 'ok'; + $context['arbitrary'] = 'ok'; } return $context; @@ -298,7 +297,8 @@ function ( $context, $parsed_block ) { HTML ); - $this->assertFalse( isset( $provided_context['invalid'] ), 'Test block is top-level block: Context should not include unsupported properties"' ); + $this->assertTrue( isset( $provided_context['arbitrary'] ), 'Test block is top-level block: Block context should include "arbitrary"' ); + $this->assertSame( 'ok', $provided_context['arbitrary'], 'Test block is top-level block: "arbitrary" in context should be "ok"' ); do_blocks( << HTML ); - $this->assertFalse( isset( $provided_context['invalid'] ), 'Test block is inner block: Context should not include unsupported properties' ); + $this->assertTrue( isset( $provided_context['arbitrary'] ), 'Test block is inner block: Block context should include "arbitrary"' ); + $this->assertSame( 'ok', $provided_context['arbitrary'], 'Test block is inner block: "arbitrary" in context should be "ok"' ); } } From 976d7d69cd17fcdd57ec211f17bf63df84666467 Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Tue, 8 Oct 2024 17:12:11 +0530 Subject: [PATCH 06/36] Update renderBlock.php --- tests/phpunit/tests/blocks/renderBlock.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/tests/blocks/renderBlock.php b/tests/phpunit/tests/blocks/renderBlock.php index 7bfac371fb328..f1dc3143c58d2 100644 --- a/tests/phpunit/tests/blocks/renderBlock.php +++ b/tests/phpunit/tests/blocks/renderBlock.php @@ -196,7 +196,7 @@ public function test_default_context_is_filterable() { /** * Tests the behavior of the 'render_block_context' filter based on the location of the filtered block. * - * @ticket 620426 + * @ticket 62046 */ public function test_render_block_context_inner_blocks() { $provided_context = array(); From adf52a72388738019d331f4b1b2f4ef8e571a217 Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Tue, 8 Oct 2024 17:19:10 +0530 Subject: [PATCH 07/36] Unexpected error --- tests/phpunit/tests/blocks/renderBlock.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/phpunit/tests/blocks/renderBlock.php b/tests/phpunit/tests/blocks/renderBlock.php index f1dc3143c58d2..35f05d9f1ef28 100644 --- a/tests/phpunit/tests/blocks/renderBlock.php +++ b/tests/phpunit/tests/blocks/renderBlock.php @@ -273,6 +273,7 @@ public function test_render_block_context_allowed_context() { 'uses_context' => array( 'example' ), 'render_callback' => static function ( $attributes, $content, $block ) use ( &$provided_context ) { $provided_context = $block->context; + return ''; }, ), From d410a3c25e7c0e6f9c2c9586362464a6761b6690 Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Tue, 8 Oct 2024 17:28:16 +0530 Subject: [PATCH 08/36] Commaaaa --- tests/phpunit/tests/blocks/renderBlock.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/tests/blocks/renderBlock.php b/tests/phpunit/tests/blocks/renderBlock.php index 35f05d9f1ef28..4f8dd543548bd 100644 --- a/tests/phpunit/tests/blocks/renderBlock.php +++ b/tests/phpunit/tests/blocks/renderBlock.php @@ -276,7 +276,7 @@ public function test_render_block_context_allowed_context() { return ''; }, - ), + ) ); // Filter the context provided to the test block. From b0af0426885c3530bb805c73759610b72fa397ca Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Tue, 8 Oct 2024 17:50:41 +0530 Subject: [PATCH 09/36] Add get_block_type_uses_context filter --- tests/phpunit/tests/blocks/renderBlock.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/phpunit/tests/blocks/renderBlock.php b/tests/phpunit/tests/blocks/renderBlock.php index 4f8dd543548bd..405528435c991 100644 --- a/tests/phpunit/tests/blocks/renderBlock.php +++ b/tests/phpunit/tests/blocks/renderBlock.php @@ -279,6 +279,19 @@ public function test_render_block_context_allowed_context() { ) ); + add_filter( + 'get_block_type_uses_context', + function ( $uses_context, $block_type ) { + if ( 'tests/context-consumer' === $block_type->name ) { + // Use array_values to reset the array keys. + return array_values( array_unique( array_merge( $uses_context, array( 'arbitrary' ) ) ) ); + } + return $uses_context; + }, + 10, + 2 + ); + // Filter the context provided to the test block. add_filter( 'render_block_context', From a6db0fdbc27cbd071fafa330967bc27e4b95bc41 Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Wed, 9 Oct 2024 11:51:24 +0530 Subject: [PATCH 10/36] Remove stale condition --- src/wp-includes/class-wp-block.php | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/wp-includes/class-wp-block.php b/src/wp-includes/class-wp-block.php index 7b7f4f8591f57..7d39b827c88a6 100644 --- a/src/wp-includes/class-wp-block.php +++ b/src/wp-includes/class-wp-block.php @@ -152,11 +152,8 @@ public function __construct( $block, $available_context = array(), $registry = n public function update_available_context( $block, $available_context ) { $this->context = array(); - if ( null === $this->available_context ) { - $this->available_context = $available_context; - } else { - $this->available_context = array_merge( $this->available_context, $available_context ); - } + + $this->available_context = array_merge( $this->available_context, $available_context ); if ( ! empty( $this->block_type->uses_context ) ) { foreach ( $this->block_type->uses_context as $context_name ) { From 5cbb114252c844881ed02da768a7b48108768e57 Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Wed, 9 Oct 2024 12:05:10 +0530 Subject: [PATCH 11/36] Call function if filter change the context value --- src/wp-includes/class-wp-block.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/wp-includes/class-wp-block.php b/src/wp-includes/class-wp-block.php index 7d39b827c88a6..3deb901a719f8 100644 --- a/src/wp-includes/class-wp-block.php +++ b/src/wp-includes/class-wp-block.php @@ -513,7 +513,8 @@ public function render( $options = array() ) { if ( ! is_null( $pre_render ) ) { $block_content .= $pre_render; } else { - $source_block = $inner_block->parsed_block; + $source_block = $inner_block->parsed_block; + $inner_block_context = $inner_block->context; /** This filter is documented in wp-includes/blocks.php */ $inner_block->parsed_block = apply_filters( 'render_block_data', $inner_block->parsed_block, $source_block, $parent_block ); @@ -521,7 +522,9 @@ public function render( $options = array() ) { /** This filter is documented in wp-includes/blocks.php */ $inner_block->context = apply_filters( 'render_block_context', $inner_block->context, $inner_block->parsed_block, $parent_block ); - $inner_block->update_available_context( $inner_block->parsed_block, $inner_block->context ); + if ( $inner_block->context !== $inner_block_context ) { + $inner_block->update_available_context( $inner_block->parsed_block, $inner_block->context ); + } $block_content .= $inner_block->render(); } From 898d29c2cdaf66ae0cc2b50ce42960b6cdc14761 Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Wed, 9 Oct 2024 14:29:25 +0530 Subject: [PATCH 12/36] Address review feedbacks and add function docblock --- src/wp-includes/class-wp-block.php | 37 +++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/src/wp-includes/class-wp-block.php b/src/wp-includes/class-wp-block.php index 3deb901a719f8..c02d9773cfc6b 100644 --- a/src/wp-includes/class-wp-block.php +++ b/src/wp-includes/class-wp-block.php @@ -140,16 +140,29 @@ public function __construct( $block, $available_context = array(), $registry = n $this->available_context = $available_context; $this->update_available_context( $block, $available_context ); - - if ( ! empty( $block['innerHTML'] ) ) { - $this->inner_html = $block['innerHTML']; - } - - if ( ! empty( $block['innerContent'] ) ) { - $this->inner_content = $block['innerContent']; - } } + /** + * Updates the available context for the current block and its inner blocks. + * + * @since 6.7.0 + * + * Updates the available context for the current block and its inner blocks. + * + * This method updates the context of the current block instance by merging the provided + * `available_context` with the existing context values. It also processes the block's + * inner blocks by passing the updated context to them. + * + * The available context is an array of key-value pairs that represent the context passed + * down from ancestor blocks in the hierarchy. The block instance's context is only updated + * with the values that it consumes as defined in its registered block type (`uses_context`). + * Additionally, any context provided by the block instance itself is passed to its inner blocks. + * + * @param array $block The associative array of the current parsed block. + * Contains attributes like `blockName`, `attrs`, `innerBlocks`, `innerHTML`, and `innerContent`. + * @param array $available_context Optional. An array of context values inherited from ancestor blocks. + * Default is an empty array. + */ public function update_available_context( $block, $available_context ) { $this->context = array(); @@ -176,6 +189,14 @@ public function update_available_context( $block, $available_context ) { $this->inner_blocks = new WP_Block_List( $block['innerBlocks'], $child_context, $this->registry ); } + + if ( ! empty( $block['innerHTML'] ) ) { + $this->inner_html = $block['innerHTML']; + } + + if ( ! empty( $block['innerContent'] ) ) { + $this->inner_content = $block['innerContent']; + } } /** From fc76e2c289bdd6dd59acd29aaf2cc7a6956163a7 Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Wed, 9 Oct 2024 14:53:59 +0530 Subject: [PATCH 13/36] Remove whitespace --- src/wp-includes/class-wp-block.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/class-wp-block.php b/src/wp-includes/class-wp-block.php index c02d9773cfc6b..e22de61b1cf3c 100644 --- a/src/wp-includes/class-wp-block.php +++ b/src/wp-includes/class-wp-block.php @@ -158,7 +158,7 @@ public function __construct( $block, $available_context = array(), $registry = n * with the values that it consumes as defined in its registered block type (`uses_context`). * Additionally, any context provided by the block instance itself is passed to its inner blocks. * - * @param array $block The associative array of the current parsed block. + * @param array $block The associative array of the current parsed block. * Contains attributes like `blockName`, `attrs`, `innerBlocks`, `innerHTML`, and `innerContent`. * @param array $available_context Optional. An array of context values inherited from ancestor blocks. * Default is an empty array. From 40bfc5e6107e74c16ac92f114e535a1d5965ea35 Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Wed, 9 Oct 2024 15:26:11 +0530 Subject: [PATCH 14/36] Update docblock. --- src/wp-includes/class-wp-block.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/wp-includes/class-wp-block.php b/src/wp-includes/class-wp-block.php index e22de61b1cf3c..d4e436f00aab6 100644 --- a/src/wp-includes/class-wp-block.php +++ b/src/wp-includes/class-wp-block.php @@ -143,10 +143,6 @@ public function __construct( $block, $available_context = array(), $registry = n } /** - * Updates the available context for the current block and its inner blocks. - * - * @since 6.7.0 - * * Updates the available context for the current block and its inner blocks. * * This method updates the context of the current block instance by merging the provided @@ -158,6 +154,8 @@ public function __construct( $block, $available_context = array(), $registry = n * with the values that it consumes as defined in its registered block type (`uses_context`). * Additionally, any context provided by the block instance itself is passed to its inner blocks. * + * @since 6.7.0 + * * @param array $block The associative array of the current parsed block. * Contains attributes like `blockName`, `attrs`, `innerBlocks`, `innerHTML`, and `innerContent`. * @param array $available_context Optional. An array of context values inherited from ancestor blocks. From f50736d1981d19a2a64a105c14856bb478c79739 Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Wed, 9 Oct 2024 15:28:10 +0530 Subject: [PATCH 15/36] Spaceee --- src/wp-includes/class-wp-block.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/class-wp-block.php b/src/wp-includes/class-wp-block.php index d4e436f00aab6..d077ac10880f6 100644 --- a/src/wp-includes/class-wp-block.php +++ b/src/wp-includes/class-wp-block.php @@ -154,7 +154,7 @@ public function __construct( $block, $available_context = array(), $registry = n * with the values that it consumes as defined in its registered block type (`uses_context`). * Additionally, any context provided by the block instance itself is passed to its inner blocks. * - * @since 6.7.0 + * @since 6.7.0 * * @param array $block The associative array of the current parsed block. * Contains attributes like `blockName`, `attrs`, `innerBlocks`, `innerHTML`, and `innerContent`. From e1203bef285efbddf6843c3a8af362c5ab2dd4f7 Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Thu, 10 Oct 2024 13:22:25 +0530 Subject: [PATCH 16/36] Apply suggestions from code review Co-authored-by: Felix Arntz --- src/wp-includes/class-wp-block.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/class-wp-block.php b/src/wp-includes/class-wp-block.php index d077ac10880f6..676003bfb2a50 100644 --- a/src/wp-includes/class-wp-block.php +++ b/src/wp-includes/class-wp-block.php @@ -541,7 +541,7 @@ public function render( $options = array() ) { /** This filter is documented in wp-includes/blocks.php */ $inner_block->context = apply_filters( 'render_block_context', $inner_block->context, $inner_block->parsed_block, $parent_block ); - if ( $inner_block->context !== $inner_block_context ) { + if ( $inner_block->parsed_block !== $source_block || $inner_block->context !== $inner_block_context ) { $inner_block->update_available_context( $inner_block->parsed_block, $inner_block->context ); } From 218b8879362939c27179dc18de7beab3a1dceab4 Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Thu, 10 Oct 2024 16:55:24 +0530 Subject: [PATCH 17/36] Remove `get_block_type_uses_context` filter --- tests/phpunit/tests/blocks/renderBlock.php | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/tests/phpunit/tests/blocks/renderBlock.php b/tests/phpunit/tests/blocks/renderBlock.php index 405528435c991..32b1f39d35b69 100644 --- a/tests/phpunit/tests/blocks/renderBlock.php +++ b/tests/phpunit/tests/blocks/renderBlock.php @@ -270,7 +270,7 @@ public function test_render_block_context_allowed_context() { register_block_type( 'tests/context-consumer', array( - 'uses_context' => array( 'example' ), + 'uses_context' => array( 'arbitrary' ), 'render_callback' => static function ( $attributes, $content, $block ) use ( &$provided_context ) { $provided_context = $block->context; @@ -279,19 +279,6 @@ public function test_render_block_context_allowed_context() { ) ); - add_filter( - 'get_block_type_uses_context', - function ( $uses_context, $block_type ) { - if ( 'tests/context-consumer' === $block_type->name ) { - // Use array_values to reset the array keys. - return array_values( array_unique( array_merge( $uses_context, array( 'arbitrary' ) ) ) ); - } - return $uses_context; - }, - 10, - 2 - ); - // Filter the context provided to the test block. add_filter( 'render_block_context', From 33930ed2183e891d752f2019db169e2fd22dde98 Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Thu, 10 Oct 2024 20:14:01 +0530 Subject: [PATCH 18/36] Initialize property as empty array by default --- src/wp-includes/class-wp-block.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/wp-includes/class-wp-block.php b/src/wp-includes/class-wp-block.php index 676003bfb2a50..8b5e2b2484c46 100644 --- a/src/wp-includes/class-wp-block.php +++ b/src/wp-includes/class-wp-block.php @@ -56,7 +56,7 @@ class WP_Block { * @var array * @access protected */ - protected $available_context; + protected $available_context = array(); /** * Block type registry. @@ -138,7 +138,6 @@ public function __construct( $block, $available_context = array(), $registry = n $this->block_type = $registry->get_registered( $this->name ); - $this->available_context = $available_context; $this->update_available_context( $block, $available_context ); } From 192e5ae219a6e3ee5c07e50f9cb2b7708ed85457 Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Mon, 14 Oct 2024 12:00:21 +0530 Subject: [PATCH 19/36] Revert context change --- tests/phpunit/tests/blocks/renderBlock.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/tests/blocks/renderBlock.php b/tests/phpunit/tests/blocks/renderBlock.php index 32b1f39d35b69..4f8dd543548bd 100644 --- a/tests/phpunit/tests/blocks/renderBlock.php +++ b/tests/phpunit/tests/blocks/renderBlock.php @@ -270,7 +270,7 @@ public function test_render_block_context_allowed_context() { register_block_type( 'tests/context-consumer', array( - 'uses_context' => array( 'arbitrary' ), + 'uses_context' => array( 'example' ), 'render_callback' => static function ( $attributes, $content, $block ) use ( &$provided_context ) { $provided_context = $block->context; From 819e9dbb2c896e4d84065344ce3f6c2bf98efcb7 Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Mon, 14 Oct 2024 13:56:22 +0530 Subject: [PATCH 20/36] Try to fix context --- src/wp-includes/class-wp-block.php | 63 ++++++++++++++++++------------ 1 file changed, 37 insertions(+), 26 deletions(-) diff --git a/src/wp-includes/class-wp-block.php b/src/wp-includes/class-wp-block.php index 8b5e2b2484c46..1d8fa257bab7e 100644 --- a/src/wp-includes/class-wp-block.php +++ b/src/wp-includes/class-wp-block.php @@ -138,32 +138,27 @@ public function __construct( $block, $available_context = array(), $registry = n $this->block_type = $registry->get_registered( $this->name ); - $this->update_available_context( $block, $available_context ); + $this->available_context = $available_context; + + $this->update_block_context(); + $this->update_parsed_block_content(); } /** - * Updates the available context for the current block and its inner blocks. + * Updates the context for the current block and its inner blocks. * - * This method updates the context of the current block instance by merging the provided - * `available_context` with the existing context values. It also processes the block's - * inner blocks by passing the updated context to them. + * This method updates the block's `context` property by merging the available context from ancestor blocks + * with the block's own context values. The block only consumes the context keys specified in its registered + * block type (`uses_context`). After updating its own context, the method also updates the context of the inner + * blocks by passing any context values the block provides (`provides_context`). * - * The available context is an array of key-value pairs that represent the context passed - * down from ancestor blocks in the hierarchy. The block instance's context is only updated - * with the values that it consumes as defined in its registered block type (`uses_context`). - * Additionally, any context provided by the block instance itself is passed to its inner blocks. + * The method recursively processes inner blocks by creating new instances of `WP_Block` for each inner block, + * passing down the updated context. * * @since 6.7.0 - * - * @param array $block The associative array of the current parsed block. - * Contains attributes like `blockName`, `attrs`, `innerBlocks`, `innerHTML`, and `innerContent`. - * @param array $available_context Optional. An array of context values inherited from ancestor blocks. - * Default is an empty array. */ - public function update_available_context( $block, $available_context ) { - $this->context = array(); - - $this->available_context = array_merge( $this->available_context, $available_context ); + public function update_block_context() { + $this->context = array_merge( $this->context, $this->available_context ); if ( ! empty( $this->block_type->uses_context ) ) { foreach ( $this->block_type->uses_context as $context_name ) { @@ -173,7 +168,7 @@ public function update_available_context( $block, $available_context ) { } } - if ( ! empty( $block['innerBlocks'] ) ) { + if ( ! empty( $this->parsed_block['innerBlocks'] ) ) { $child_context = $this->available_context; if ( ! empty( $this->block_type->provides_context ) ) { @@ -184,15 +179,26 @@ public function update_available_context( $block, $available_context ) { } } - $this->inner_blocks = new WP_Block_List( $block['innerBlocks'], $child_context, $this->registry ); + $this->inner_blocks = new WP_Block_List( $this->parsed_block['innerBlocks'], $child_context, $this->registry ); } + } - if ( ! empty( $block['innerHTML'] ) ) { - $this->inner_html = $block['innerHTML']; + /** + * Updates the parsed block content for the current block. + * + * This method sets the `inner_html` and `inner_content` properties of the block based on the parsed + * block content provided during the block's initialization. It ensures that the block instance reflects + * the most up-to-date content for both the inner HTML and any string fragments around inner blocks. + * + * @since 6.7.0 + */ + public function update_parsed_block_content() { + if ( ! empty( $this->parsed_block['innerHTML'] ) ) { + $this->inner_html = $this->parsed_block['innerHTML']; } - if ( ! empty( $block['innerContent'] ) ) { - $this->inner_content = $block['innerContent']; + if ( ! empty( $this->parsed_block['innerContent'] ) ) { + $this->inner_content = $this->parsed_block['innerContent']; } } @@ -540,8 +546,13 @@ public function render( $options = array() ) { /** This filter is documented in wp-includes/blocks.php */ $inner_block->context = apply_filters( 'render_block_context', $inner_block->context, $inner_block->parsed_block, $parent_block ); - if ( $inner_block->parsed_block !== $source_block || $inner_block->context !== $inner_block_context ) { - $inner_block->update_available_context( $inner_block->parsed_block, $inner_block->context ); + if ( $inner_block->context !== $inner_block_context ) { + $inner_block->available_context = array_merge( $this->available_context, $inner_block->context ); + $inner_block->update_block_context(); + } + + if ( $inner_block->parsed_block !== $source_block ) { + $inner_block->update_parsed_block_content(); } $block_content .= $inner_block->render(); From dc6577b3dfde79673d701ab2de67c71a0de93d8b Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Wed, 16 Oct 2024 11:01:23 +0530 Subject: [PATCH 21/36] Update function name and docblock --- src/wp-includes/class-wp-block.php | 50 ++++++++++++++++++------------ 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/src/wp-includes/class-wp-block.php b/src/wp-includes/class-wp-block.php index 1d8fa257bab7e..f02a690ffb262 100644 --- a/src/wp-includes/class-wp-block.php +++ b/src/wp-includes/class-wp-block.php @@ -140,25 +140,32 @@ public function __construct( $block, $available_context = array(), $registry = n $this->available_context = $available_context; - $this->update_block_context(); - $this->update_parsed_block_content(); + $this->refresh_context_dependents(); + $this->refresh_parsed_block_dependents(); } /** * Updates the context for the current block and its inner blocks. * * This method updates the block's `context` property by merging the available context from ancestor blocks - * with the block's own context values. The block only consumes the context keys specified in its registered - * block type (`uses_context`). After updating its own context, the method also updates the context of the inner - * blocks by passing any context values the block provides (`provides_context`). + * with the block's own context values. It removes specific context keys (`postId` and `postType`) that should + * not be carried over. The block only consumes the context keys specified in its registered block type (`uses_context`). * - * The method recursively processes inner blocks by creating new instances of `WP_Block` for each inner block, - * passing down the updated context. + * After updating its own context, the method also updates the context of inner blocks, if any, by passing down + * any context values the block provides (`provides_context`). + * + * If the block has inner blocks, the method recursively processes them by creating new instances of `WP_Block` + * for each inner block and updating their context based on the block's `provides_context` property. * * @since 6.7.0 */ - public function update_block_context() { - $this->context = array_merge( $this->context, $this->available_context ); + public function refresh_context_dependents() { + $this->context = $this->available_context; + + // Remove "postId" and "postType" keys. + if ( isset( $this->context['postId'] ) || isset( $this->context['postType'] ) ) { + unset( $this->context['postId'], $this->context['postType'] ); + } if ( ! empty( $this->block_type->uses_context ) ) { foreach ( $this->block_type->uses_context as $context_name ) { @@ -169,30 +176,33 @@ public function update_block_context() { } if ( ! empty( $this->parsed_block['innerBlocks'] ) ) { - $child_context = $this->available_context; - if ( ! empty( $this->block_type->provides_context ) ) { foreach ( $this->block_type->provides_context as $context_name => $attribute_name ) { if ( array_key_exists( $attribute_name, $this->attributes ) ) { - $child_context[ $context_name ] = $this->attributes[ $attribute_name ]; + $this->available_context[ $context_name ] = $this->attributes[ $attribute_name ]; } } } - - $this->inner_blocks = new WP_Block_List( $this->parsed_block['innerBlocks'], $child_context, $this->registry ); } } /** - * Updates the parsed block content for the current block. + * Updates the parsed block content for the current block and its inner blocks. * * This method sets the `inner_html` and `inner_content` properties of the block based on the parsed - * block content provided during the block's initialization. It ensures that the block instance reflects - * the most up-to-date content for both the inner HTML and any string fragments around inner blocks. + * block content provided during initialization. It ensures that the block instance reflects the + * most up-to-date content for both the inner HTML and any string fragments around inner blocks. + * + * If the block has inner blocks, this method initializes a new `WP_Block_List` for them, ensuring the + * correct content and context are updated for each nested block. * * @since 6.7.0 */ - public function update_parsed_block_content() { + public function refresh_parsed_block_dependents() { + if ( ! empty( $this->parsed_block['innerBlocks'] ) ) { + $this->inner_blocks = new WP_Block_List( $this->parsed_block['innerBlocks'], $this->available_context, $this->registry ); + } + if ( ! empty( $this->parsed_block['innerHTML'] ) ) { $this->inner_html = $this->parsed_block['innerHTML']; } @@ -548,11 +558,11 @@ public function render( $options = array() ) { if ( $inner_block->context !== $inner_block_context ) { $inner_block->available_context = array_merge( $this->available_context, $inner_block->context ); - $inner_block->update_block_context(); + $inner_block->refresh_context_dependents(); } if ( $inner_block->parsed_block !== $source_block ) { - $inner_block->update_parsed_block_content(); + $inner_block->refresh_parsed_block_dependents(); } $block_content .= $inner_block->render(); From 28ce0834c3fb3e9a22b4e9b21c348da9aa15a255 Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Wed, 16 Oct 2024 11:20:24 +0530 Subject: [PATCH 22/36] Fix unit tests for wpBlock.php --- tests/phpunit/tests/blocks/wpBlock.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/phpunit/tests/blocks/wpBlock.php b/tests/phpunit/tests/blocks/wpBlock.php index 8eff0e66d013a..ecd287b2ec794 100644 --- a/tests/phpunit/tests/blocks/wpBlock.php +++ b/tests/phpunit/tests/blocks/wpBlock.php @@ -170,7 +170,7 @@ public function test_constructor_assigns_context_from_block_type() { ); $block = new WP_Block( $parsed_block, $context, $this->registry ); - $this->assertSame( array( 'requested' => 'included' ), $block->context ); + $this->assertSame( $context, $block->context ); } /** @@ -218,9 +218,9 @@ public function test_constructor_prepares_context_for_inner_blocks() { $context = array( 'unrequested' => 'not included' ); $block = new WP_Block( $parsed_block, $context, $this->registry ); - $this->assertCount( 0, $block->context ); + $this->assertCount( 1, $block->context ); $this->assertSame( - array( 'core/recordId' => 10 ), + array( 'unrequested' => 'not included', 'core/recordId' => 10 ), $block->inner_blocks[0]->context ); } From 2c464709de46898929fe6acba593131fcacc625c Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Wed, 16 Oct 2024 11:24:53 +0530 Subject: [PATCH 23/36] PHPCS --- tests/phpunit/tests/blocks/wpBlock.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/phpunit/tests/blocks/wpBlock.php b/tests/phpunit/tests/blocks/wpBlock.php index ecd287b2ec794..6de337bc8f9ea 100644 --- a/tests/phpunit/tests/blocks/wpBlock.php +++ b/tests/phpunit/tests/blocks/wpBlock.php @@ -220,7 +220,10 @@ public function test_constructor_prepares_context_for_inner_blocks() { $this->assertCount( 1, $block->context ); $this->assertSame( - array( 'unrequested' => 'not included', 'core/recordId' => 10 ), + array( + 'unrequested' => 'not included', + 'core/recordId' => 10 + ), $block->inner_blocks[0]->context ); } From 9764c52b0ce92359cbf70c5d76433f35747d5a10 Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Wed, 16 Oct 2024 11:26:03 +0530 Subject: [PATCH 24/36] Apply suggestions from code review --- tests/phpunit/tests/blocks/wpBlock.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/tests/blocks/wpBlock.php b/tests/phpunit/tests/blocks/wpBlock.php index 6de337bc8f9ea..3b0fcb5d95896 100644 --- a/tests/phpunit/tests/blocks/wpBlock.php +++ b/tests/phpunit/tests/blocks/wpBlock.php @@ -222,7 +222,7 @@ public function test_constructor_prepares_context_for_inner_blocks() { $this->assertSame( array( 'unrequested' => 'not included', - 'core/recordId' => 10 + 'core/recordId' => 10, ), $block->inner_blocks[0]->context ); From de703d9d0abd19f53ff5f1627bf1d8f095ca8c5b Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Wed, 16 Oct 2024 11:42:31 +0530 Subject: [PATCH 25/36] Fix unit tests for renderBlock.php --- tests/phpunit/tests/blocks/renderBlock.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/tests/blocks/renderBlock.php b/tests/phpunit/tests/blocks/renderBlock.php index 4f8dd543548bd..dad3cf903c8b2 100644 --- a/tests/phpunit/tests/blocks/renderBlock.php +++ b/tests/phpunit/tests/blocks/renderBlock.php @@ -108,8 +108,8 @@ public function test_provides_block_context() { $this->assertSame( array( - 'tests/contextWithDefault' => 0, 'tests/contextWithAssigned' => 10, + 'tests/contextWithDefault' => 0, ), $provided_context[0] ); From 6c4f6cdc853cf248e4fa3992d1dc8f8b7e0f7d49 Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Wed, 16 Oct 2024 11:51:19 +0530 Subject: [PATCH 26/36] Fix unit tests for render.php --- tests/phpunit/tests/block-bindings/render.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/phpunit/tests/block-bindings/render.php b/tests/phpunit/tests/block-bindings/render.php index 19ee2c412d32f..c7ddc1350f804 100644 --- a/tests/phpunit/tests/block-bindings/render.php +++ b/tests/phpunit/tests/block-bindings/render.php @@ -208,12 +208,12 @@ public function test_blocks_can_just_access_the_specific_uses_context() { $result = $block->render(); $this->assertSame( - 'Value: source two context value', + 'Value: source one context value', $block->attributes['content'], - "The 'content' should be updated with the value of the second source context value." + "The 'content' should be updated with the value of the first source context value." ); $this->assertSame( - '

Value: source two context value

', + '

Value: source one context value

', trim( $result ), 'The block content should be updated with the value of the source context.' ); From c7c54180a55546cf98243e9dd7040274c2f4cbb4 Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Thu, 17 Oct 2024 09:51:37 +0530 Subject: [PATCH 27/36] Move provides_context in to refresh_parsed_block_dependents() --- src/wp-includes/class-wp-block.php | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/wp-includes/class-wp-block.php b/src/wp-includes/class-wp-block.php index f02a690ffb262..c2a4c85a6cdd4 100644 --- a/src/wp-includes/class-wp-block.php +++ b/src/wp-includes/class-wp-block.php @@ -174,16 +174,6 @@ public function refresh_context_dependents() { } } } - - if ( ! empty( $this->parsed_block['innerBlocks'] ) ) { - if ( ! empty( $this->block_type->provides_context ) ) { - foreach ( $this->block_type->provides_context as $context_name => $attribute_name ) { - if ( array_key_exists( $attribute_name, $this->attributes ) ) { - $this->available_context[ $context_name ] = $this->attributes[ $attribute_name ]; - } - } - } - } } /** @@ -200,7 +190,17 @@ public function refresh_context_dependents() { */ public function refresh_parsed_block_dependents() { if ( ! empty( $this->parsed_block['innerBlocks'] ) ) { - $this->inner_blocks = new WP_Block_List( $this->parsed_block['innerBlocks'], $this->available_context, $this->registry ); + $child_context = $this->available_context; + + if ( ! empty( $this->block_type->provides_context ) ) { + foreach ( $this->block_type->provides_context as $context_name => $attribute_name ) { + if ( array_key_exists( $attribute_name, $this->attributes ) ) { + $child_context[ $context_name ] = $this->attributes[ $attribute_name ]; + } + } + } + + $this->inner_blocks = new WP_Block_List( $this->parsed_block['innerBlocks'], $child_context, $this->registry ); } if ( ! empty( $this->parsed_block['innerHTML'] ) ) { From dce8002ed44ebbab39ff5d1709ec26b95bd938ad Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Mon, 28 Oct 2024 14:38:18 +0530 Subject: [PATCH 28/36] Bump the WP version number --- src/wp-includes/class-wp-block.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wp-includes/class-wp-block.php b/src/wp-includes/class-wp-block.php index c2a4c85a6cdd4..5926a3e51a136 100644 --- a/src/wp-includes/class-wp-block.php +++ b/src/wp-includes/class-wp-block.php @@ -157,7 +157,7 @@ public function __construct( $block, $available_context = array(), $registry = n * If the block has inner blocks, the method recursively processes them by creating new instances of `WP_Block` * for each inner block and updating their context based on the block's `provides_context` property. * - * @since 6.7.0 + * @since 6.8.0 */ public function refresh_context_dependents() { $this->context = $this->available_context; @@ -186,7 +186,7 @@ public function refresh_context_dependents() { * If the block has inner blocks, this method initializes a new `WP_Block_List` for them, ensuring the * correct content and context are updated for each nested block. * - * @since 6.7.0 + * @since 6.8.0 */ public function refresh_parsed_block_dependents() { if ( ! empty( $this->parsed_block['innerBlocks'] ) ) { From c83ca8268e3b9db13ad3e17cf0e2a478529dbdc6 Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Tue, 5 Nov 2024 15:17:33 +0530 Subject: [PATCH 29/36] Remove context merging --- src/wp-includes/class-wp-block.php | 13 +------------ tests/phpunit/tests/block-bindings/render.php | 6 +++--- tests/phpunit/tests/blocks/renderBlock.php | 2 +- tests/phpunit/tests/blocks/wpBlock.php | 9 +++------ 4 files changed, 8 insertions(+), 22 deletions(-) diff --git a/src/wp-includes/class-wp-block.php b/src/wp-includes/class-wp-block.php index 5926a3e51a136..bde2359140f01 100644 --- a/src/wp-includes/class-wp-block.php +++ b/src/wp-includes/class-wp-block.php @@ -147,11 +147,7 @@ public function __construct( $block, $available_context = array(), $registry = n /** * Updates the context for the current block and its inner blocks. * - * This method updates the block's `context` property by merging the available context from ancestor blocks - * with the block's own context values. It removes specific context keys (`postId` and `postType`) that should - * not be carried over. The block only consumes the context keys specified in its registered block type (`uses_context`). - * - * After updating its own context, the method also updates the context of inner blocks, if any, by passing down + * The method updates the context of inner blocks, if any, by passing down * any context values the block provides (`provides_context`). * * If the block has inner blocks, the method recursively processes them by creating new instances of `WP_Block` @@ -160,13 +156,6 @@ public function __construct( $block, $available_context = array(), $registry = n * @since 6.8.0 */ public function refresh_context_dependents() { - $this->context = $this->available_context; - - // Remove "postId" and "postType" keys. - if ( isset( $this->context['postId'] ) || isset( $this->context['postType'] ) ) { - unset( $this->context['postId'], $this->context['postType'] ); - } - if ( ! empty( $this->block_type->uses_context ) ) { foreach ( $this->block_type->uses_context as $context_name ) { if ( array_key_exists( $context_name, $this->available_context ) ) { diff --git a/tests/phpunit/tests/block-bindings/render.php b/tests/phpunit/tests/block-bindings/render.php index c7ddc1350f804..19ee2c412d32f 100644 --- a/tests/phpunit/tests/block-bindings/render.php +++ b/tests/phpunit/tests/block-bindings/render.php @@ -208,12 +208,12 @@ public function test_blocks_can_just_access_the_specific_uses_context() { $result = $block->render(); $this->assertSame( - 'Value: source one context value', + 'Value: source two context value', $block->attributes['content'], - "The 'content' should be updated with the value of the first source context value." + "The 'content' should be updated with the value of the second source context value." ); $this->assertSame( - '

Value: source one context value

', + '

Value: source two context value

', trim( $result ), 'The block content should be updated with the value of the source context.' ); diff --git a/tests/phpunit/tests/blocks/renderBlock.php b/tests/phpunit/tests/blocks/renderBlock.php index dad3cf903c8b2..4f8dd543548bd 100644 --- a/tests/phpunit/tests/blocks/renderBlock.php +++ b/tests/phpunit/tests/blocks/renderBlock.php @@ -108,8 +108,8 @@ public function test_provides_block_context() { $this->assertSame( array( - 'tests/contextWithAssigned' => 10, 'tests/contextWithDefault' => 0, + 'tests/contextWithAssigned' => 10, ), $provided_context[0] ); diff --git a/tests/phpunit/tests/blocks/wpBlock.php b/tests/phpunit/tests/blocks/wpBlock.php index 3b0fcb5d95896..8eff0e66d013a 100644 --- a/tests/phpunit/tests/blocks/wpBlock.php +++ b/tests/phpunit/tests/blocks/wpBlock.php @@ -170,7 +170,7 @@ public function test_constructor_assigns_context_from_block_type() { ); $block = new WP_Block( $parsed_block, $context, $this->registry ); - $this->assertSame( $context, $block->context ); + $this->assertSame( array( 'requested' => 'included' ), $block->context ); } /** @@ -218,12 +218,9 @@ public function test_constructor_prepares_context_for_inner_blocks() { $context = array( 'unrequested' => 'not included' ); $block = new WP_Block( $parsed_block, $context, $this->registry ); - $this->assertCount( 1, $block->context ); + $this->assertCount( 0, $block->context ); $this->assertSame( - array( - 'unrequested' => 'not included', - 'core/recordId' => 10, - ), + array( 'core/recordId' => 10 ), $block->inner_blocks[0]->context ); } From 4096831e6f690e1bdab1b5fde7fc661f0c1994af Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Mon, 11 Nov 2024 14:54:04 +0530 Subject: [PATCH 30/36] Update available context in helper function --- src/wp-includes/class-wp-block.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/class-wp-block.php b/src/wp-includes/class-wp-block.php index bb30b0a893f16..d608cc49c5d99 100644 --- a/src/wp-includes/class-wp-block.php +++ b/src/wp-includes/class-wp-block.php @@ -156,6 +156,8 @@ public function __construct( $block, $available_context = array(), $registry = n * @since 6.8.0 */ public function refresh_context_dependents() { + $this->available_context = array_merge( $this->available_context, $this->context ); + if ( ! empty( $this->block_type->uses_context ) ) { foreach ( $this->block_type->uses_context as $context_name ) { if ( array_key_exists( $context_name, $this->available_context ) ) { @@ -546,7 +548,6 @@ public function render( $options = array() ) { $inner_block->context = apply_filters( 'render_block_context', $inner_block->context, $inner_block->parsed_block, $parent_block ); if ( $inner_block->context !== $inner_block_context ) { - $inner_block->available_context = array_merge( $this->available_context, $inner_block->context ); $inner_block->refresh_context_dependents(); } From 4474ad7fd25a8fbcb8f6938cc4f4ce2fea4f6ab2 Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Mon, 6 Jan 2025 14:03:09 +0530 Subject: [PATCH 31/36] Add a comment to clarify the remaining problem Co-authored-by: Felix Arntz --- src/wp-includes/class-wp-block.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/wp-includes/class-wp-block.php b/src/wp-includes/class-wp-block.php index d608cc49c5d99..4a8208afbbc7f 100644 --- a/src/wp-includes/class-wp-block.php +++ b/src/wp-includes/class-wp-block.php @@ -156,6 +156,11 @@ public function __construct( $block, $available_context = array(), $registry = n * @since 6.8.0 */ public function refresh_context_dependents() { + /* + * Merging the `$context` property here is not ideal, but for now needs to happen because of backward compatibility. + * Ideally, the `$context` property itself would not be filterable directly and only the `$available_context` would be filterable. + * However, this needs to be separately explored whether it's possible without breakage. + */ $this->available_context = array_merge( $this->available_context, $this->context ); if ( ! empty( $this->block_type->uses_context ) ) { From dcb4c4a02ab763a82e263cf472800d9f0ca1c475 Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Mon, 6 Jan 2025 15:37:34 +0530 Subject: [PATCH 32/36] Address review feedback --- src/wp-includes/class-wp-block.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/wp-includes/class-wp-block.php b/src/wp-includes/class-wp-block.php index 4a8208afbbc7f..5bea062829ca6 100644 --- a/src/wp-includes/class-wp-block.php +++ b/src/wp-includes/class-wp-block.php @@ -170,6 +170,8 @@ public function refresh_context_dependents() { } } } + + $this->refresh_parsed_block_dependents(); } /** From a36410d56d34271e0fddeb906c3734cafc10adfb Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Thu, 16 Jan 2025 10:31:50 +0530 Subject: [PATCH 33/36] Apply suggestions from code review Co-authored-by: Felix Arntz --- src/wp-includes/class-wp-block.php | 8 +++++--- tests/phpunit/tests/blocks/renderBlock.php | 13 +++++++++++-- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/wp-includes/class-wp-block.php b/src/wp-includes/class-wp-block.php index 5bea062829ca6..9ffd08c3b3e05 100644 --- a/src/wp-includes/class-wp-block.php +++ b/src/wp-includes/class-wp-block.php @@ -554,11 +554,13 @@ public function render( $options = array() ) { /** This filter is documented in wp-includes/blocks.php */ $inner_block->context = apply_filters( 'render_block_context', $inner_block->context, $inner_block->parsed_block, $parent_block ); + /* + * The `refresh_context_dependents()` method already calls `refresh_parsed_block_dependents()`. + * Therefore the second condition is irrelevant if the first one is satisfied. + */ if ( $inner_block->context !== $inner_block_context ) { $inner_block->refresh_context_dependents(); - } - - if ( $inner_block->parsed_block !== $source_block ) { + } elseif ( $inner_block->parsed_block !== $source_block ) { $inner_block->refresh_parsed_block_dependents(); } diff --git a/tests/phpunit/tests/blocks/renderBlock.php b/tests/phpunit/tests/blocks/renderBlock.php index 4f8dd543548bd..3e1b88d5d4d0e 100644 --- a/tests/phpunit/tests/blocks/renderBlock.php +++ b/tests/phpunit/tests/blocks/renderBlock.php @@ -298,8 +298,7 @@ function ( $context, $parsed_block ) { HTML ); - $this->assertTrue( isset( $provided_context['arbitrary'] ), 'Test block is top-level block: Block context should include "arbitrary"' ); - $this->assertSame( 'ok', $provided_context['arbitrary'], 'Test block is top-level block: "arbitrary" in context should be "ok"' ); + $this->assertFalse( isset( $provided_context['arbitrary'] ), 'Test block is top-level block: Block context should not include "arbitrary"' ); do_blocks( << HTML ); + + /* + * These assertions assert something that ideally should not be the case: Inner blocks should respect the + * `uses_context` value just like top-level blocks do. However, due to logic in `WP_Block::render()`, the + * `context` property value itself is filterable when it should rather only apply to the `available_context` + * property. + * However, changing this behavior now would be a backward compatibility break, hence the assertion here. + * Potentially it can be reconsidered in the future, so that these two assertions could be replaced with an + * `assertFalse( isset( $provided_context['arbitrary'] ) )`. + */ $this->assertTrue( isset( $provided_context['arbitrary'] ), 'Test block is inner block: Block context should include "arbitrary"' ); $this->assertSame( 'ok', $provided_context['arbitrary'], 'Test block is inner block: "arbitrary" in context should be "ok"' ); } From 0b8f5f5355b4f5adc9542cbf15e11d79971f6cfc Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Fri, 17 Jan 2025 09:32:57 +0530 Subject: [PATCH 34/36] Update class-wp-block.php --- src/wp-includes/class-wp-block.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/wp-includes/class-wp-block.php b/src/wp-includes/class-wp-block.php index 9ffd08c3b3e05..2533379fcdf7a 100644 --- a/src/wp-includes/class-wp-block.php +++ b/src/wp-includes/class-wp-block.php @@ -141,7 +141,6 @@ public function __construct( $block, $available_context = array(), $registry = n $this->available_context = $available_context; $this->refresh_context_dependents(); - $this->refresh_parsed_block_dependents(); } /** From ddcb2f2b0ae94037b051f8eb52a023a49a93be92 Mon Sep 17 00:00:00 2001 From: Felix Arntz Date: Fri, 17 Jan 2025 10:04:56 -0800 Subject: [PATCH 35/36] Use more suitable assertArrayHasKey and assertArrayNotHasKey assertions. --- tests/phpunit/tests/blocks/renderBlock.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/phpunit/tests/blocks/renderBlock.php b/tests/phpunit/tests/blocks/renderBlock.php index 3e1b88d5d4d0e..7354f316abe82 100644 --- a/tests/phpunit/tests/blocks/renderBlock.php +++ b/tests/phpunit/tests/blocks/renderBlock.php @@ -242,7 +242,7 @@ function ( $context, $parsed_block ) { HTML ); - $this->assertTrue( isset( $provided_context['example'] ), 'Test block is top-level block: Context should include "example"' ); + $this->assertArrayHasKey( 'example', $provided_context, 'Test block is top-level block: Context should include "example"' ); $this->assertSame( 'ok', $provided_context['example'], 'Test block is top-level block: "example" in context should be "ok"' ); // Test inner block context when the provider block is an inner block. @@ -255,7 +255,7 @@ function ( $context, $parsed_block ) { HTML ); - $this->assertTrue( isset( $provided_context['example'] ), 'Test block is inner block: Block context should include "example"' ); + $this->assertArrayHasKey( 'example', $provided_context, 'Test block is inner block: Block context should include "example"' ); $this->assertSame( 'ok', $provided_context['example'], 'Test block is inner block: "example" in context should be "ok"' ); } @@ -298,7 +298,7 @@ function ( $context, $parsed_block ) { HTML ); - $this->assertFalse( isset( $provided_context['arbitrary'] ), 'Test block is top-level block: Block context should not include "arbitrary"' ); + $this->assertArrayNotHasKey( 'arbitrary', $provided_context, 'Test block is top-level block: Block context should not include "arbitrary"' ); do_blocks( <<assertTrue( isset( $provided_context['arbitrary'] ), 'Test block is inner block: Block context should include "arbitrary"' ); + $this->assertArrayHasKey( 'arbitrary', $provided_context, 'Test block is inner block: Block context should include "arbitrary"' ); $this->assertSame( 'ok', $provided_context['arbitrary'], 'Test block is inner block: "arbitrary" in context should be "ok"' ); } } From 688bdb58e27f5b35db1804f8ed801030f46dc786 Mon Sep 17 00:00:00 2001 From: Felix Arntz Date: Fri, 17 Jan 2025 10:06:11 -0800 Subject: [PATCH 36/36] Update comment for assertion. --- tests/phpunit/tests/blocks/renderBlock.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/tests/blocks/renderBlock.php b/tests/phpunit/tests/blocks/renderBlock.php index 7354f316abe82..be251692c5c62 100644 --- a/tests/phpunit/tests/blocks/renderBlock.php +++ b/tests/phpunit/tests/blocks/renderBlock.php @@ -315,7 +315,7 @@ function ( $context, $parsed_block ) { * property. * However, changing this behavior now would be a backward compatibility break, hence the assertion here. * Potentially it can be reconsidered in the future, so that these two assertions could be replaced with an - * `assertFalse( isset( $provided_context['arbitrary'] ) )`. + * `assertArrayNotHasKey( 'arbitrary', $provided_context )`. */ $this->assertArrayHasKey( 'arbitrary', $provided_context, 'Test block is inner block: Block context should include "arbitrary"' ); $this->assertSame( 'ok', $provided_context['arbitrary'], 'Test block is inner block: "arbitrary" in context should be "ok"' );