-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
Blocks: Refactor the check against self for block hooks #5218
Blocks: Refactor the check against self for block hooks #5218
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See my comment -- I really think we should keep the check for self-insertion in register_block_type_from_metadata
.
// Avoid infinite recursion in block hooks (hooking to itself). | ||
if ( 'block_hooks' === $property_name ) { | ||
if ( ! is_array( $property_value ) ) { | ||
continue; | ||
} | ||
if ( array_key_exists( $this->name, $property_value ) ) { | ||
_doing_it_wrong( | ||
__METHOD__, | ||
__( 'Cannot hook block to itself.' ), | ||
'6.4.0' | ||
); | ||
unset( $property_value[ $this->name ] ); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I really think we should keep this in register_block_type_from_metadata
😬 AFAICS, no other field is being validated here in WP_Block_Type
-- they're all processed in register_block_type_from_metadata
, so I'd rather keep it consistent.
Note that register_block_type
actually calls register_block_type_from_metadata
for block registration, so any block type registered via register_block_type
will in fact undergo the validation in register_block_type_from_metadata
:
wordpress-develop/src/wp-includes/blocks.php
Lines 584 to 590 in e005108
function register_block_type( $block_type, $args = array() ) { | |
if ( is_string( $block_type ) && file_exists( $block_type ) ) { | |
return register_block_type_from_metadata( $block_type, $args ); | |
} | |
return WP_Block_Type_Registry::get_instance()->register( $block_type, $args ); | |
} |
Finally, note that there's even an "inner" inconsistency with this PR, as validation of the allowed relative positions is still done in register_block_type_from_metadata
😅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left a #5218 (comment) with the details from my debugging after trying to use the test with the version before refactoring.
Finally, note that there's even an "inner" inconsistency with this PR, as validation of the allowed relative positions is still done in register_block_type_from_metadata 😅
Yes, that could get improved, but we first need to settle on the responsibilities of processing block.json
files. So far, it is mostly about mapping the JSON object to the matching fields in WP_Block_Type
.
AFAICS, no other field is being validated here in WP_Block_Type
There are some issues filed in Gutenberg to address it:
array( | ||
'tests/before' => 'before', | ||
'tests/after' => 'after', | ||
'tests/first-child' => 'first_child', | ||
'tests/last-child' => 'last_child', | ||
), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
I tried locally reverting the changes for the code moved to diff --git a/tests/phpunit/tests/blocks/register.php b/tests/phpunit/tests/blocks/register.php
index 55faf297a5..2c1cf64937 100644
--- a/tests/phpunit/tests/blocks/register.php
+++ b/tests/phpunit/tests/blocks/register.php
@@ -1069,4 +1069,29 @@ class Tests_Blocks_Register extends WP_UnitTestCase {
$actual = register_block_style( 'core/query', $block_styles );
$this->assertTrue( $actual );
}
+
+ /**
+ * @ticket 59346
+ *
+ * @covers ::register_block_type
+ *
+ * @expectedIncorrectUsage register_block_type_from_metadata
+ */
+ public function test_register_block_hooks_targeting_itself() {
+ $block_name = 'tests/block-name';
+ $block_type = register_block_type(
+ $block_name,
+ array(
+ 'block_hooks' => array(
+ $block_name => 'first',
+ 'tests/other-block' => 'last',
+ ),
+ )
+ );
+
+ $this->assertSameSets(
+ array( 'tests/other-block' => 'last' ),
+ $block_type->block_hooks
+ );
+ }
} The test fails: No changes get applied. When inspecting the code it turns out that wordpress-develop/src/wp-includes/blocks.php Lines 618 to 624 in 227fdb8
If no path to the wordpress-develop/src/wp-includes/blocks.php Lines 594 to 597 in 227fdb8
We can keep the implementation as it is currently works in |
You're of course right 🤦♂️ My apologies, I'd read that code but totally glossed over the
I think since there's no precedent of doing any processing or validation in |
Thanks for the feedback @ockham, I will refactor the code accordingly. |
6e3aaba
to
2089f54
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you! LGTM
Committed with https://core.trac.wordpress.org/changeset/56607. |
Just a short note: The method we landed on for inserting hooked blocks into their designated positions should make infinite loops of blocks inserting themselves next to each other impossible, if I'm not mistaken. The crux is that we no longer insert parsed hooked blocks into the block tree, where they might be traversed themselves by In other words, while it's nice to prohibit "self-insertion" at block type registration stage, it's not technically required -- things won't break if a block does end up registering itself for "self-insertion". |
That's another excellent side-effect of the revised implementation. I really like how you integrated Block Hooks into WordPress core, taking advantage of the access to all internals. It seems fine to leave the validation as is. By the way, there is an open issue to add validation for every argument to |
Trac ticket: https://core.trac.wordpress.org/ticket/59346
I added some refactorings discussed in #5203 (review):
Block Hooks: Add field to block registration, REST API #5203 (comment) -committed with https://core.trac.wordpress.org/changeset/56592.gutenberg
text domain removeblockHooks
toblock_hooks
when handling metadata. I covered that part in unit tests.WP_Block_Type
class to cover also the case when someone registers the block with a regularregister_block_type
call without using metadata file.This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.