Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Block Bindings: Add context needed by block bindings sources during its processing #6456

14 changes: 0 additions & 14 deletions src/wp-includes/class-wp-block-bindings-registry.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
gziolo marked this conversation as resolved.
Show resolved Hide resolved
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;
}

Expand Down
9 changes: 9 additions & 0 deletions src/wp-includes/class-wp-block.php
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,15 @@ private function process_block_bindings() {
continue;
}

// Add the necessary context defined by the source.
if ( ! empty( $block_binding_source->uses_context ) ) {
gziolo marked this conversation as resolved.
Show resolved Hide resolved
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 );

Expand Down
62 changes: 62 additions & 0 deletions tests/phpunit/tests/block-bindings/render.php
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,68 @@ public function test_passing_uses_context_to_source() {
);
}

/**
* Tests that blocks can only access the context from the specific source.
*
* @ticket 61642
*
* @covers ::register_block_bindings_source
*/
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 () {
return;
},
'uses_context' => array( 'contextOne' ),
)
);

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['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( 'contextTwo' ),
)
);

$block_content = <<<HTML
<!-- wp:paragraph {"metadata":{"bindings":{"content":{"source":"test/source-two", "args": {"key": "test"}}}}} -->
<p>Default content</p>
<!-- /wp:paragraph -->
HTML;
$parsed_blocks = parse_blocks( $block_content );
$block = new WP_Block(
$parsed_blocks[0],
array(
'contextOne' => 'source one context value',
'contextTwo' => 'source two context value',
)
);
$result = $block->render();

$this->assertSame(
'Value: source two context value',
$block->attributes['content'],
"The 'content' should be updated with the value of the second source context value."
);
$this->assertSame(
'<p>Value: source two context value</p>',
trim( $result ),
'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.
Expand Down
47 changes: 0 additions & 47 deletions tests/phpunit/tests/block-bindings/wpBlockBindingsRegistry.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 );
}
}
Loading