From 958fc10e5d056152a855c90fd4cc47944d79fea0 Mon Sep 17 00:00:00 2001 From: Mario Santos Date: Fri, 20 Sep 2024 09:44:21 +0200 Subject: [PATCH 1/8] Push available context when bindings exist --- src/wp-includes/class-wp-block.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/wp-includes/class-wp-block.php b/src/wp-includes/class-wp-block.php index f7fd53dfc9710..201e3d87dc969 100644 --- a/src/wp-includes/class-wp-block.php +++ b/src/wp-includes/class-wp-block.php @@ -301,6 +301,15 @@ private function process_block_bindings() { continue; } + // Add the necessary context. + if ( ! empty( $block_binding_source->uses_context ) ) { + foreach ( $block_binding_source->uses_context as $context_name ) { + if ( array_key_exists( $context_name, $this->available_context ) ) { + $this->context[ $context_name ] = $this->available_context[ $context_name ]; + } + } + } + $source_args = ! empty( $block_binding['args'] ) && is_array( $block_binding['args'] ) ? $block_binding['args'] : array(); $source_value = $block_binding_source->get_value( $source_args, $this, $attribute_name ); From b1d77b2493fa58d18ce3fa30bd9488b8fc6923ce Mon Sep 17 00:00:00 2001 From: Mario Santos Date: Fri, 20 Sep 2024 09:44:21 +0200 Subject: [PATCH 2/8] Remove old filter used to extend `uses_context` --- .../class-wp-block-bindings-registry.php | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/wp-includes/class-wp-block-bindings-registry.php b/src/wp-includes/class-wp-block-bindings-registry.php index 14c1b89229c30..dc065356c5ce4 100644 --- a/src/wp-includes/class-wp-block-bindings-registry.php +++ b/src/wp-includes/class-wp-block-bindings-registry.php @@ -189,20 +189,6 @@ public function register( string $source_name, array $source_properties ) { $this->sources[ $source_name ] = $source; - // Adds `uses_context` defined by block bindings sources. - add_filter( - 'get_block_type_uses_context', - function ( $uses_context, $block_type ) use ( $source ) { - if ( ! in_array( $block_type->name, $this->supported_blocks, true ) || empty( $source->uses_context ) ) { - return $uses_context; - } - // Use array_values to reset the array keys. - return array_values( array_unique( array_merge( $uses_context, $source->uses_context ) ) ); - }, - 10, - 2 - ); - return $source; } From 05917ec440e4b3b82063ac1fa7a421fa68d51f61 Mon Sep 17 00:00:00 2001 From: Mario Santos Date: Fri, 20 Sep 2024 09:44:21 +0200 Subject: [PATCH 3/8] Modify comment --- 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 201e3d87dc969..08eb38c66d5ed 100644 --- a/src/wp-includes/class-wp-block.php +++ b/src/wp-includes/class-wp-block.php @@ -301,7 +301,7 @@ private function process_block_bindings() { continue; } - // Add the necessary context. + // Add the necessary context defined by the source. if ( ! empty( $block_binding_source->uses_context ) ) { foreach ( $block_binding_source->uses_context as $context_name ) { if ( array_key_exists( $context_name, $this->available_context ) ) { From f434d570efb2c1b2d4e7a52826bfdf7556363232 Mon Sep 17 00:00:00 2001 From: Mario Santos Date: Fri, 20 Sep 2024 09:45:27 +0200 Subject: [PATCH 4/8] Modify test to adapt to context changes --- tests/phpunit/tests/block-bindings/render.php | 88 +++++++++++++++++++ .../wpBlockBindingsRegistry.php | 47 ---------- 2 files changed, 88 insertions(+), 47 deletions(-) diff --git a/tests/phpunit/tests/block-bindings/render.php b/tests/phpunit/tests/block-bindings/render.php index 914de02c3c09f..28c9afbbbf283 100644 --- a/tests/phpunit/tests/block-bindings/render.php +++ b/tests/phpunit/tests/block-bindings/render.php @@ -157,6 +157,94 @@ public function test_passing_uses_context_to_source() { ); } + /** + * Tests passing `uses_context` as argument to the source. + * + * @ticket 99999 + * + * @covers ::register_block_bindings_source + */ + public function test_passing_uses_context_to_multiple_sources() { + register_block_bindings_source( + 'test/source-one', + array( + 'label' => 'Test Source One', + 'get_value_callback' => function ( $source_args, $block_instance, $attribute_name ) { + $value = $block_instance->context['sourceOneContext']; + return "Source One value: $value"; + }, + 'uses_context' => array( 'commonContext', 'sourceOneContext' ), + ) + ); + + register_block_bindings_source( + 'test/source-two', + array( + 'label' => 'Test Source Two', + 'get_value_callback' => function ( $source_args, $block_instance, $attribute_name ) { + $value = $block_instance->context['commonContext']; + return "Source Two value: $value"; + }, + 'uses_context' => array( 'commonContext', 'sourceTwoContext' ), + ) + ); + + $block_content = << +

First source value placeholder

+ + +

Second source value placeholder

+ +HTML; + [ $first_parsed_block, $second_parsed_block] = array_values( + array_filter( + parse_blocks( $block_content ), + function ( $block ) { + return 'core/paragraph' === $block['blockName']; + } + ) + ); + + $first_block = new WP_Block( + $first_parsed_block, + array( + 'commonContext' => 'common context value', + 'sourceOneContext' => 'source one context value', + ) + ); + $first_block_render = $first_block->render(); + $second_block = new WP_Block( + $second_parsed_block, + array( + 'commonContext' => 'common context value', + 'sourceTwoContext' => 'source two context value', + ) + ); + $second_block_render = $second_block->render(); + + $this->assertSame( + 'Source One value: source one context value', + $first_block->attributes['content'], + "The 'content' should be updated with the value of the first source context value." + ); + $this->assertSame( + '

Source One value: source one context value

', + trim( $first_block_render ), + 'The block content should be updated with the value of the first source context value.' + ); + $this->assertSame( + 'Source Two value: common context value', + $second_block->attributes['content'], + "The 'content' should be updated with the value of the common context value." + ); + $this->assertSame( + '

Source Two value: common context value

', + trim( $second_block_render ), + 'The block content should be updated with the value of the source context.' + ); + } + /** * Tests if the block content is updated with the value returned by the source * for the Image block in the placeholder state. diff --git a/tests/phpunit/tests/block-bindings/wpBlockBindingsRegistry.php b/tests/phpunit/tests/block-bindings/wpBlockBindingsRegistry.php index e4aa415e9af96..9beebaa2c3108 100644 --- a/tests/phpunit/tests/block-bindings/wpBlockBindingsRegistry.php +++ b/tests/phpunit/tests/block-bindings/wpBlockBindingsRegistry.php @@ -344,51 +344,4 @@ public function test_is_registered_for_known_source() { $result = $this->registry->is_registered( self::$test_source_name ); $this->assertTrue( $result ); } - - /** - * Tests merging `uses_context` from multiple sources. - * - * @ticket 60525 - * - * @covers ::register_block_bindings_source - * @covers WP_Block_Type::get_uses_context - */ - public function test_merging_uses_context_from_multiple_sources() { - $get_value_callback = function () { - return 'Anything'; - }; - - $block_registry = WP_Block_Type_Registry::get_instance(); - $original_uses_context = $block_registry->get_registered( 'core/paragraph' )->uses_context; - - register_block_bindings_source( - 'test/source-one', - array( - 'label' => 'Test Source One', - 'get_value_callback' => $get_value_callback, - 'uses_context' => array( 'commonContext', 'sourceOneContext' ), - ) - ); - - register_block_bindings_source( - 'test/source-two', - array( - 'label' => 'Test Source Two', - 'get_value_callback' => $get_value_callback, - 'uses_context' => array( 'commonContext', 'sourceTwoContext' ), - ) - ); - - $new_uses_context = $block_registry->get_registered( 'core/paragraph' )->uses_context; - unregister_block_bindings_source( 'test/source-one' ); - unregister_block_bindings_source( 'test/source-two' ); - // Checks that the resulting `uses_context` contains the values from both sources. - $this->assertContains( 'commonContext', $new_uses_context ); - $this->assertContains( 'sourceOneContext', $new_uses_context ); - $this->assertContains( 'sourceTwoContext', $new_uses_context ); - // Checks that the resulting `uses_context` added 3 unique items. - $this->assertSame( count( $original_uses_context ) + 3, count( $new_uses_context ) ); - // Checks that the array isn't sparse to prevent issues in the editor. - $this->assertSame( array_key_last( $new_uses_context ), count( $new_uses_context ) - 1 ); - } } From 0e5fb3506c2bcbb914b30be0c5d9bc030850e92c Mon Sep 17 00:00:00 2001 From: Mario Santos Date: Fri, 20 Sep 2024 09:45:27 +0200 Subject: [PATCH 5/8] Add uses_context to editor settings --- src/wp-includes/block-bindings.php | 3 +++ .../class-wp-block-bindings-registry.php | 20 +++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/src/wp-includes/block-bindings.php b/src/wp-includes/block-bindings.php index ff8db5f5dd4e9..888cb155545df 100644 --- a/src/wp-includes/block-bindings.php +++ b/src/wp-includes/block-bindings.php @@ -129,3 +129,6 @@ function get_all_registered_block_bindings_sources() { function get_block_bindings_source( string $source_name ) { return WP_Block_Bindings_Registry::get_instance()->get_registered( $source_name ); } + +// Add the `uses_context` to the block editor settings to ensure it can be consumed in the client. +add_filter( 'block_editor_settings_all', array( 'WP_Block_Bindings_Registry', 'add_uses_context_to_editor_settings' ), 10 ); diff --git a/src/wp-includes/class-wp-block-bindings-registry.php b/src/wp-includes/class-wp-block-bindings-registry.php index dc065356c5ce4..8240675d25d0e 100644 --- a/src/wp-includes/class-wp-block-bindings-registry.php +++ b/src/wp-includes/class-wp-block-bindings-registry.php @@ -291,4 +291,24 @@ public static function get_instance() { return self::$instance; } + + /** + * Adds the `uses_context` to the editor settings. + * + * This allows to reuse the `uses_context` definition in the editor. + * + * @since 6.6.0 + * + * @param array $settings The block editor settings from the `block_editor_settings_all` filter. + * @return array The editor settings with extended block bindings `uses_context`. + */ + public static function add_uses_context_to_editor_settings( $settings ) { + $registered_block_bindings_sources = get_all_registered_block_bindings_sources(); + foreach ( $registered_block_bindings_sources as $source ) { + if ( ! empty( $source->uses_context ) ) { + $settings['__experimentalBlockBindings'][ $source->name ]['usesContext'] = $source->uses_context; + } + } + return $settings; + } } From d35e67834c998c74fe13bd1055064250f63aff32 Mon Sep 17 00:00:00 2001 From: Mario Santos Date: Fri, 20 Sep 2024 09:46:54 +0200 Subject: [PATCH 6/8] Don't use filter to add editor settings --- src/wp-includes/block-bindings.php | 3 --- .../class-wp-block-bindings-registry.php | 20 ------------------- 2 files changed, 23 deletions(-) diff --git a/src/wp-includes/block-bindings.php b/src/wp-includes/block-bindings.php index 888cb155545df..ff8db5f5dd4e9 100644 --- a/src/wp-includes/block-bindings.php +++ b/src/wp-includes/block-bindings.php @@ -129,6 +129,3 @@ function get_all_registered_block_bindings_sources() { function get_block_bindings_source( string $source_name ) { return WP_Block_Bindings_Registry::get_instance()->get_registered( $source_name ); } - -// Add the `uses_context` to the block editor settings to ensure it can be consumed in the client. -add_filter( 'block_editor_settings_all', array( 'WP_Block_Bindings_Registry', 'add_uses_context_to_editor_settings' ), 10 ); diff --git a/src/wp-includes/class-wp-block-bindings-registry.php b/src/wp-includes/class-wp-block-bindings-registry.php index 8240675d25d0e..dc065356c5ce4 100644 --- a/src/wp-includes/class-wp-block-bindings-registry.php +++ b/src/wp-includes/class-wp-block-bindings-registry.php @@ -291,24 +291,4 @@ public static function get_instance() { return self::$instance; } - - /** - * Adds the `uses_context` to the editor settings. - * - * This allows to reuse the `uses_context` definition in the editor. - * - * @since 6.6.0 - * - * @param array $settings The block editor settings from the `block_editor_settings_all` filter. - * @return array The editor settings with extended block bindings `uses_context`. - */ - public static function add_uses_context_to_editor_settings( $settings ) { - $registered_block_bindings_sources = get_all_registered_block_bindings_sources(); - foreach ( $registered_block_bindings_sources as $source ) { - if ( ! empty( $source->uses_context ) ) { - $settings['__experimentalBlockBindings'][ $source->name ]['usesContext'] = $source->uses_context; - } - } - return $settings; - } } From f84b778a046a05933b4895ac2cb02531db1250f8 Mon Sep 17 00:00:00 2001 From: Mario Santos Date: Fri, 20 Sep 2024 09:46:54 +0200 Subject: [PATCH 7/8] Test blocks can only access the right context --- tests/phpunit/tests/block-bindings/render.php | 76 ++++++------------- 1 file changed, 25 insertions(+), 51 deletions(-) diff --git a/tests/phpunit/tests/block-bindings/render.php b/tests/phpunit/tests/block-bindings/render.php index 28c9afbbbf283..659b1e40f5044 100644 --- a/tests/phpunit/tests/block-bindings/render.php +++ b/tests/phpunit/tests/block-bindings/render.php @@ -158,22 +158,21 @@ public function test_passing_uses_context_to_source() { } /** - * Tests passing `uses_context` as argument to the source. + * Tests that blocks can only access the context from the specific source. * * @ticket 99999 * * @covers ::register_block_bindings_source */ - public function test_passing_uses_context_to_multiple_sources() { + public function test_blocks_can_just_access_the_specific_uses_context() { register_block_bindings_source( 'test/source-one', array( 'label' => 'Test Source One', - 'get_value_callback' => function ( $source_args, $block_instance, $attribute_name ) { - $value = $block_instance->context['sourceOneContext']; - return "Source One value: $value"; + 'get_value_callback' => function () { + return; }, - 'uses_context' => array( 'commonContext', 'sourceOneContext' ), + 'uses_context' => array( 'contextOne' ), ) ); @@ -182,65 +181,40 @@ public function test_passing_uses_context_to_multiple_sources() { array( 'label' => 'Test Source Two', 'get_value_callback' => function ( $source_args, $block_instance, $attribute_name ) { - $value = $block_instance->context['commonContext']; - return "Source Two value: $value"; + $value = $block_instance->context['contextTwo']; + // Try to use the context from source one, which shouldn't be available. + if ( ! empty( $block_instance->context['contextOne'] ) ) { + $value = $block_instance->context['contextOne']; + } + return "Value: $value"; }, - 'uses_context' => array( 'commonContext', 'sourceTwoContext' ), + 'uses_context' => array( 'contextTwo' ), ) ); - $block_content = << -

First source value placeholder

- + $block_content = << -

Second source value placeholder

+

Default content

HTML; - [ $first_parsed_block, $second_parsed_block] = array_values( - array_filter( - parse_blocks( $block_content ), - function ( $block ) { - return 'core/paragraph' === $block['blockName']; - } - ) - ); - - $first_block = new WP_Block( - $first_parsed_block, - array( - 'commonContext' => 'common context value', - 'sourceOneContext' => 'source one context value', - ) - ); - $first_block_render = $first_block->render(); - $second_block = new WP_Block( - $second_parsed_block, + $parsed_blocks = parse_blocks( $block_content ); + $block = new WP_Block( + $parsed_blocks[0], array( - 'commonContext' => 'common context value', - 'sourceTwoContext' => 'source two context value', + 'contextOne' => 'source one context value', + 'contextTwo' => 'source two context value', ) ); - $second_block_render = $second_block->render(); + $result = $block->render(); $this->assertSame( - 'Source One value: source one context value', - $first_block->attributes['content'], - "The 'content' should be updated with the value of the first source context value." - ); - $this->assertSame( - '

Source One value: source one context value

', - trim( $first_block_render ), - 'The block content should be updated with the value of the first source context value.' - ); - $this->assertSame( - 'Source Two value: common context value', - $second_block->attributes['content'], - "The 'content' should be updated with the value of the common context value." + 'Value: source two context value', + $block->attributes['content'], + "The 'content' should be updated with the value of the second source context value." ); $this->assertSame( - '

Source Two value: common context value

', - trim( $second_block_render ), + '

Value: source two context value

', + trim( $result ), 'The block content should be updated with the value of the source context.' ); } From 757e9b6d86a1f60665c74b682eb6dd577befa7e8 Mon Sep 17 00:00:00 2001 From: Mario Santos Date: Fri, 20 Sep 2024 09:47:28 +0200 Subject: [PATCH 8/8] Add ticket number to test --- tests/phpunit/tests/block-bindings/render.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/tests/block-bindings/render.php b/tests/phpunit/tests/block-bindings/render.php index 659b1e40f5044..6c53ddf99411e 100644 --- a/tests/phpunit/tests/block-bindings/render.php +++ b/tests/phpunit/tests/block-bindings/render.php @@ -160,7 +160,7 @@ public function test_passing_uses_context_to_source() { /** * Tests that blocks can only access the context from the specific source. * - * @ticket 99999 + * @ticket 61642 * * @covers ::register_block_bindings_source */