-
Notifications
You must be signed in to change notification settings - Fork 842
Verbum Comments: optimize block filtering performance with Block_Scanner pre-filtering #44996
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
Changes from all commits
9b47e06
62dfa6f
53c34f7
cd78c89
1c1e9d2
b8c6743
c297a3d
6c179ea
4155e35
26776ab
ed7a2b0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| Significance: patch | ||
| Type: changed | ||
|
|
||
| Verbum Comments: optimize block filtering performance using Block_Scanner for fast pre-filtering when all blocks are allowed. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,7 +10,10 @@ | |
| */ | ||
| class Verbum_Block_Utils { | ||
| /** | ||
| * Remove blocks that aren't allowed | ||
| * Remove blocks that aren't allowed using hybrid Block_Scanner optimization | ||
| * | ||
| * Uses Block_Scanner for fast pre-filtering when possible, falling back to | ||
| * parse_blocks approach only when disallowed blocks are detected. | ||
| * | ||
| * @param string $content - Text of the comment. | ||
| * @return string | ||
|
|
@@ -21,12 +24,57 @@ public static function remove_blocks( $content ) { | |
| } | ||
|
|
||
| // The block attributes come slashed and `parse_blocks` won't be able to parse them. | ||
| $content = wp_unslash( $content ); | ||
| $blocks = parse_blocks( $content ); | ||
| $unslashed_content = wp_unslash( $content ); | ||
|
|
||
| $filtered_blocks = self::filter_blocks_recursive( $blocks ); | ||
| if ( ! self::has_disallowed_blocks( $unslashed_content ) ) { | ||
| return $unslashed_content; | ||
| } | ||
|
|
||
| return self::remove_blocks_with_parse_blocks( $unslashed_content ); | ||
| } | ||
|
|
||
| /** | ||
| * Quick verification using Block_Scanner to detect if content contains disallowed blocks | ||
| * | ||
| * This method provides significant performance benefits by avoiding expensive | ||
| * parse_blocks() processing when all blocks are allowed (the common case). | ||
| * | ||
| * @param string $content Unslashed content to scan. | ||
| * @return bool True if disallowed blocks found, false if all blocks are allowed. | ||
| */ | ||
| private static function has_disallowed_blocks( $content ) { | ||
| if ( ! class_exists( '\\Automattic\\Block_Scanner' ) ) { | ||
| return true; | ||
| } | ||
|
|
||
| try { | ||
| $scanner = \Automattic\Block_Scanner::create( $content ); | ||
| $allowed_blocks = self::get_allowed_blocks(); | ||
|
|
||
| while ( $scanner->next_delimiter() ) { | ||
| if ( $scanner->opens_block() ) { | ||
| $block_type = $scanner->get_block_type(); | ||
| if ( ! in_array( $block_type, $allowed_blocks, true ) ) { | ||
| return true; // Found disallowed block | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // Convert the filtered blocks back to string | ||
| return false; // All blocks are allowed | ||
| } catch ( \Exception $e ) { | ||
| return true; | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Remove disallowed blocks using parse_blocks | ||
| * | ||
| * @param string $unslashed_content Content with blocks (already unslashed). | ||
| * @return string Filtered content with disallowed blocks removed. | ||
| */ | ||
| private static function remove_blocks_with_parse_blocks( $unslashed_content ) { | ||
| $blocks = parse_blocks( $unslashed_content ); | ||
| $filtered_blocks = self::filter_blocks_recursive( $blocks ); | ||
| return serialize_blocks( $filtered_blocks ); | ||
| } | ||
|
|
||
|
|
@@ -62,7 +110,8 @@ private static function filter_blocks_recursive( $blocks ) { | |
| $block['innerContent'] = $inner_content; | ||
| } | ||
|
|
||
| $block['innerHTML'] ??= ''; | ||
| $block['innerHTML'] = isset( $block['innerHTML'] ) && is_string( $block['innerHTML'] ) ? $block['innerHTML'] : ''; | ||
|
|
||
| if ( empty( $block['innerContent'] ) ) { | ||
| $block['innerContent'] = array( $block['innerHTML'] ); | ||
| } | ||
|
|
@@ -127,6 +176,12 @@ public static function render_verbum_blocks( $comment_content ) { | |
| public static function get_allowed_blocks() { | ||
| global $allowedtags; | ||
|
|
||
| // Validate $allowedtags integrity - use local variable to avoid override warning | ||
| $validated_allowedtags = $allowedtags; | ||
| if ( ! is_array( $validated_allowedtags ) ) { | ||
| $validated_allowedtags = wp_kses_allowed_html( 'post' ); | ||
| } | ||
|
Comment on lines
+179
to
+183
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is to just make sure that we're working with correct data, right? Just making sure 😅
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yup! Correct, just an extra defensive measure. |
||
|
|
||
| $allowed_blocks = array( 'core/paragraph', 'core/list', 'core/code', 'core/list-item', 'core/quote', 'core/image', 'core/embed' ); | ||
| $convert = array( | ||
| 'blockquote' => 'core/quote', | ||
|
|
@@ -139,7 +194,7 @@ public static function get_allowed_blocks() { | |
| 'pre' => 'core/code', | ||
| ); | ||
|
|
||
| foreach ( array_keys( $allowedtags ) as $tag ) { | ||
| foreach ( array_keys( $validated_allowedtags ) as $tag ) { | ||
| if ( isset( $convert[ $tag ] ) ) { | ||
| $allowed_blocks[] = $convert[ $tag ]; | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| Significance: patch | ||
| Type: changed | ||
| Comment: Verbum Comments: optimize block filtering performance with Block_Scanner pre-filtering | ||
|
|
||
|
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| Significance: patch | ||
| Type: added | ||
| Comment: Add block-delimiter package to jetpack-mu-wpcom package | ||
|
|
||
|
|
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 was going back and forth about the function returning true (has disallowed blocks) but I think it makes sense. This way we default back to always using parse blocks if we can't use the Block_Scanner.