mirror of
https://github.com/gosticks/wordpress-develop.git
synced 2026-06-28 22:30:04 +00:00
Editor: Support deferred block variation initialization on the server.
When registering blocks on the server using `register_block_type()` or similar functions, a set of block type variations can also be registered. However, in some cases building this variation data during block registration can be an expensive process, which is not needed in most contexts. To address this problem, this adds support to the `WP_Block_Type` object for a new property, `variation_callback`, which can be used to register a callback for building variation data only when the block variations data is needed. The `WP_Block_Type::variations` property has been changed to a private property that is now accessed through the magic `__get()` method. The magic getter makes use of a new public method, `WP_Block_Type::get_variations` which will build variations from a registered callback if variations have not already been built. Props spacedmonkey, thekt12, Mamaduka, gaambo, gziolo, mukesh27, joemcgill. Fixes #59969. git-svn-id: https://develop.svn.wordpress.org/trunk@57315 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
@@ -460,4 +460,196 @@ class Tests_Blocks_wpBlockType extends WP_UnitTestCase {
|
||||
array( '<!- - wp:core/separator -->', 0 ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 59969
|
||||
*/
|
||||
public function test_variation_callback() {
|
||||
$block_type = new WP_Block_Type(
|
||||
'test/block',
|
||||
array(
|
||||
'title' => 'Test title',
|
||||
'variation_callback' => array( $this, 'mock_variation_callback' ),
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertSameSets( $this->mock_variation_callback(), $block_type->variations );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 59969
|
||||
* @covers WP_Block_Type::get_variations
|
||||
*/
|
||||
public function test_get_variations() {
|
||||
$block_type = new WP_Block_Type(
|
||||
'test/block',
|
||||
array(
|
||||
'title' => 'Test title',
|
||||
'variation_callback' => array( $this, 'mock_variation_callback' ),
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertSameSets( $this->mock_variation_callback(), $block_type->get_variations() );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 59969
|
||||
*/
|
||||
public function test_variations_precedence_over_callback() {
|
||||
$test_variations = array( 'name' => 'test1' );
|
||||
|
||||
$block_type = new WP_Block_Type(
|
||||
'test/block',
|
||||
array(
|
||||
'title' => 'Test title',
|
||||
'variations' => $test_variations,
|
||||
'variation_callback' => array( $this, 'mock_variation_callback' ),
|
||||
)
|
||||
);
|
||||
|
||||
// If the variations are defined, the callback should not be used.
|
||||
$this->assertSameSets( $test_variations, $block_type->variations );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 59969
|
||||
*/
|
||||
public function test_variations_callback_are_lazy_loaded() {
|
||||
$callback_called = false;
|
||||
|
||||
$block_type = new WP_Block_Type(
|
||||
'test/block',
|
||||
array(
|
||||
'title' => 'Test title',
|
||||
'variation_callback' => function () use ( &$callback_called ) {
|
||||
$callback_called = true;
|
||||
return $this->mock_variation_callback();
|
||||
},
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertSame( false, $callback_called, 'The callback should not be called before the variations are accessed.' );
|
||||
$block_type->variations; // access the variations.
|
||||
$this->assertSame( true, $callback_called, 'The callback should be called when the variations are accessed.' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 59969
|
||||
* @covers WP_Block_Type::get_variations
|
||||
*/
|
||||
public function test_variations_precedence_over_callback_post_registration() {
|
||||
$test_variations = array( 'name' => 'test1' );
|
||||
$callback_called = false;
|
||||
|
||||
$block_type = new WP_Block_Type(
|
||||
'test/block',
|
||||
array(
|
||||
'title' => 'Test title',
|
||||
'variation_callback' => function () use ( &$callback_called ) {
|
||||
$callback_called = true;
|
||||
return $this->mock_variation_callback();
|
||||
},
|
||||
)
|
||||
);
|
||||
$block_type->variations = $test_variations;
|
||||
|
||||
// If the variations are defined after registration but before first access, the callback should not override it.
|
||||
$this->assertSameSets( $test_variations, $block_type->get_variations(), 'Variations are same as variations set' );
|
||||
$this->assertSame( false, $callback_called, 'The callback was never called.' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 59969
|
||||
* @covers WP_Block_Type::get_variations
|
||||
*/
|
||||
public function test_variations_callback_happens_only_once() {
|
||||
$callback_count = 0;
|
||||
|
||||
$block_type = new WP_Block_Type(
|
||||
'test/block',
|
||||
array(
|
||||
'title' => 'Test title',
|
||||
'variation_callback' => function () use ( &$callback_count ) {
|
||||
$callback_count++;
|
||||
return $this->mock_variation_callback();
|
||||
},
|
||||
)
|
||||
);
|
||||
|
||||
$this->assertSame( 0, $callback_count, 'The callback should not be called before the variations are accessed.' );
|
||||
$block_type->get_variations(); // access the variations.
|
||||
$this->assertSame( 1, $callback_count, 'The callback should be called when the variations are accessed.' );
|
||||
$block_type->get_variations(); // access the variations again.
|
||||
$this->assertSame( 1, $callback_count, 'The callback should not be called again.' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test filter function for get_block_type_variations filter.
|
||||
*
|
||||
* @param array $variations Block variations before filter.
|
||||
* @param WP_Block_Type $block_type Block type.
|
||||
*
|
||||
* @return array Block variations after filter.
|
||||
*/
|
||||
public function filter_test_variations( $variations, $block_type ) {
|
||||
return array( array( 'name' => 'test1' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 59969
|
||||
*/
|
||||
public function test_get_block_type_variations_filter_with_variation_callback() {
|
||||
// Filter will override the variations obtained from the callback.
|
||||
add_filter( 'get_block_type_variations', array( $this, 'filter_test_variations' ), 10, 2 );
|
||||
$expected_variations = array( array( 'name' => 'test1' ) );
|
||||
|
||||
$callback_called = false;
|
||||
$block_type = new WP_Block_Type(
|
||||
'test/block',
|
||||
array(
|
||||
'title' => 'Test title',
|
||||
'variation_callback' => function () use ( &$callback_called ) {
|
||||
$callback_called = true;
|
||||
return $this->mock_variation_callback();
|
||||
},
|
||||
)
|
||||
);
|
||||
|
||||
$obtained_variations = $block_type->variations; // access the variations.
|
||||
|
||||
$this->assertSame( true, $callback_called, 'The callback should be called when the variations are accessed.' );
|
||||
$this->assertSameSets( $obtained_variations, $expected_variations, 'The variations obtained from the callback should be filtered.' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 59969
|
||||
*/
|
||||
public function test_get_block_type_variations_filter_variations() {
|
||||
// Filter will override the variations set during registration.
|
||||
add_filter( 'get_block_type_variations', array( $this, 'filter_test_variations' ), 10, 2 );
|
||||
$expected_variations = array( array( 'name' => 'test1' ) );
|
||||
|
||||
$block_type = new WP_Block_Type(
|
||||
'test/block',
|
||||
array(
|
||||
'title' => 'Test title',
|
||||
'variations' => $this->mock_variation_callback(),
|
||||
)
|
||||
);
|
||||
|
||||
$obtained_variations = $block_type->variations; // access the variations.
|
||||
$this->assertSameSets( $obtained_variations, $expected_variations, 'The variations that was initially set should be filtered.' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Mock variation callback.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function mock_variation_callback() {
|
||||
return array(
|
||||
array( 'name' => 'var1' ),
|
||||
array( 'name' => 'var2' ),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -734,6 +734,35 @@ class REST_Block_Type_Controller_Test extends WP_Test_REST_Controller_Testcase {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 59969
|
||||
*/
|
||||
public function test_variation_callback() {
|
||||
$block_type = 'test/block';
|
||||
$settings = array(
|
||||
'title' => true,
|
||||
'variation_callback' => array( $this, 'mock_variation_callback' ),
|
||||
);
|
||||
register_block_type( $block_type, $settings );
|
||||
wp_set_current_user( self::$admin_id );
|
||||
$request = new WP_REST_Request( 'GET', '/wp/v2/block-types/' . $block_type );
|
||||
$response = rest_get_server()->dispatch( $request );
|
||||
$data = $response->get_data();
|
||||
$this->assertSameSets( $this->mock_variation_callback(), $data['variations'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Mock variation callback.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function mock_variation_callback() {
|
||||
return array(
|
||||
array( 'name' => 'var1' ),
|
||||
array( 'name' => 'var2' ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* The create_item() method does not exist for block types.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user