<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[56805] trunk: Blocks: Call `get_hooked_blocks` only once per template/part/pattern.</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { white-space: pre-line; overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta" style="font-size: 105%">
<dt style="float: left; width: 6em; font-weight: bold">Revision</dt> <dd><a style="font-weight: bold" href="https://core.trac.wordpress.org/changeset/56805">56805</a><script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","description":"Review this Commit","action":{"@type":"ViewAction","url":"https://core.trac.wordpress.org/changeset/56805","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>Bernhard Reiter</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2023-10-09 16:38:25 +0000 (Mon, 09 Oct 2023)</dd>
</dl>

<pre style='padding-left: 1em; margin: 2em 0; border-left: 2px solid #ccc; line-height: 1.25; font-size: 105%; font-family: sans-serif'>Blocks: Call `get_hooked_blocks` only once per template/part/pattern.

Prior to this changeset, `get_hooked_blocks` was called four times ''for every parsed block'' in each template, template part, and pattern. With this changeset applied, `get_hooked_blocks` is called only once per template, template part, or pattern.

Additionally, `get_hooked_blocks` is called only once when returning the list of all registered patterns. (The latter modification brings the implementation closer to its state prior to Block Hooks.)

Finally, when there are no registered hooked blocks or `hooked_block_types` filters, parsing, hooked block insertion, and re-serializing is skipped altogether.

Props gziolo, flixos90, joemcgill, dmsnell, spacedmonkey, hellofromtonya.
Fixes <a href="https://core.trac.wordpress.org/ticket/59383">#59383</a>.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunksrcwpincludesblocktemplateutilsphp">trunk/src/wp-includes/block-template-utils.php</a></li>
<li><a href="#trunksrcwpincludesblocksphp">trunk/src/wp-includes/blocks.php</a></li>
<li><a href="#trunksrcwpincludesclasswpblockpatternsregistryphp">trunk/src/wp-includes/class-wp-block-patterns-registry.php</a></li>
<li><a href="#trunktestsphpunittestsblocksgetHookedBlocksphp">trunk/tests/phpunit/tests/blocks/getHookedBlocks.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunksrcwpincludesblocktemplateutilsphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/block-template-utils.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/block-template-utils.php    2023-10-09 14:47:57 UTC (rev 56804)
+++ trunk/src/wp-includes/block-template-utils.php      2023-10-09 16:38:25 UTC (rev 56805)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -549,10 +549,15 @@
</span><span class="cx" style="display: block; padding: 0 10px">                $template->area = $template_file['area'];
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        $blocks               = parse_blocks( $template_content );
-       $before_block_visitor = make_before_block_visitor( $template );
-       $after_block_visitor  = make_after_block_visitor( $template );
-       $template->content    = traverse_and_serialize_blocks( $blocks, $before_block_visitor, $after_block_visitor );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $before_block_visitor = '_inject_theme_attribute_in_template_part_block';
+       $after_block_visitor  = null;
+       $hooked_blocks        = get_hooked_blocks();
+       if ( ! empty( $hooked_blocks ) || has_filter( 'hooked_block_types' ) ) {
+               $before_block_visitor = make_before_block_visitor( $hooked_blocks, $template );
+               $after_block_visitor  = make_after_block_visitor( $hooked_blocks, $template );
+       }
+       $blocks            = parse_blocks( $template_content );
+       $template->content = traverse_and_serialize_blocks( $blocks, $before_block_visitor, $after_block_visitor );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        return $template;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span></span></pre></div>
<a id="trunksrcwpincludesblocksphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/blocks.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/blocks.php  2023-10-09 14:47:57 UTC (rev 56804)
+++ trunk/src/wp-includes/blocks.php    2023-10-09 16:38:25 UTC (rev 56805)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -723,14 +723,13 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * Retrieves block types hooked into the given block, grouped by their relative position.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * Retrieves block types hooked into the given block, grouped by anchor block type and the relative position.
</ins><span class="cx" style="display: block; padding: 0 10px">  *
</span><span class="cx" style="display: block; padding: 0 10px">  * @since 6.4.0
</span><span class="cx" style="display: block; padding: 0 10px">  *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @param string $name Block type name including namespace.
- * @return array[] Array of block types grouped by their relative position.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @return array[] Array of block types grouped by anchor block type and the relative position.
</ins><span class="cx" style="display: block; padding: 0 10px">  */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-function get_hooked_blocks( $name ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+function get_hooked_blocks() {
</ins><span class="cx" style="display: block; padding: 0 10px">         $block_types   = WP_Block_Type_Registry::get_instance()->get_all_registered();
</span><span class="cx" style="display: block; padding: 0 10px">        $hooked_blocks = array();
</span><span class="cx" style="display: block; padding: 0 10px">        foreach ( $block_types as $block_type ) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -738,15 +737,16 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        continue;
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><span class="cx" style="display: block; padding: 0 10px">                foreach ( $block_type->block_hooks as $anchor_block_type => $relative_position ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        if ( $anchor_block_type !== $name ) {
-                               continue;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 if ( ! isset( $hooked_blocks[ $anchor_block_type ] ) ) {
+                               $hooked_blocks[ $anchor_block_type ] = array();
</ins><span class="cx" style="display: block; padding: 0 10px">                         }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        if ( ! isset( $hooked_blocks[ $relative_position ] ) ) {
-                               $hooked_blocks[ $relative_position ] = array();
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 if ( ! isset( $hooked_blocks[ $anchor_block_type ][ $relative_position ] ) ) {
+                               $hooked_blocks[ $anchor_block_type ][ $relative_position ] = array();
</ins><span class="cx" style="display: block; padding: 0 10px">                         }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        $hooked_blocks[ $relative_position ][] = $block_type->name;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 $hooked_blocks[ $anchor_block_type ][ $relative_position ][] = $block_type->name;
</ins><span class="cx" style="display: block; padding: 0 10px">                 }
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
</ins><span class="cx" style="display: block; padding: 0 10px">         return $hooked_blocks;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -760,11 +760,12 @@
</span><span class="cx" style="display: block; padding: 0 10px">  * @since 6.4.0
</span><span class="cx" style="display: block; padding: 0 10px">  * @access private
</span><span class="cx" style="display: block; padding: 0 10px">  *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @param WP_Block_Template|array $context A block template, template part, or pattern that the blocks belong to.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @param array                   $hooked_blocks An array of blocks hooked to another given block.
+ * @param WP_Block_Template|array $context       A block template, template part, or pattern that the blocks belong to.
</ins><span class="cx" style="display: block; padding: 0 10px">  * @return callable A function that returns the serialized markup for the given block,
</span><span class="cx" style="display: block; padding: 0 10px">  *                  including the markup for any hooked blocks before it.
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-function make_before_block_visitor( $context ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+function make_before_block_visitor( $hooked_blocks, $context ) {
</ins><span class="cx" style="display: block; padding: 0 10px">         /**
</span><span class="cx" style="display: block; padding: 0 10px">         * Injects hooked blocks before the given block, injects the `theme` attribute into Template Part blocks, and returns the serialized markup.
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -777,7 +778,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">         * @param array $prev         The previous sibling block of the given block.
</span><span class="cx" style="display: block; padding: 0 10px">         * @return string The serialized markup for the given block, with the markup for any hooked blocks prepended to it.
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        return function ( &$block, $parent_block = null, $prev = null ) use ( $context ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ return function ( &$block, $parent_block = null, $prev = null ) use ( $hooked_blocks, $context ) {
</ins><span class="cx" style="display: block; padding: 0 10px">                 _inject_theme_attribute_in_template_part_block( $block );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                $markup = '';
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -786,9 +787,8 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        // Candidate for first-child insertion.
</span><span class="cx" style="display: block; padding: 0 10px">                        $relative_position  = 'first_child';
</span><span class="cx" style="display: block; padding: 0 10px">                        $anchor_block_type  = $parent_block['blockName'];
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        $hooked_block_types = get_hooked_blocks( $anchor_block_type );
-                       $hooked_block_types = isset( $hooked_block_types[ $relative_position ] )
-                               ? $hooked_block_types[ $relative_position ]
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 $hooked_block_types = isset( $hooked_blocks[ $anchor_block_type ][ $relative_position ] )
+                               ? $hooked_blocks[ $anchor_block_type ][ $relative_position ]
</ins><span class="cx" style="display: block; padding: 0 10px">                                 : array();
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                        /**
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -810,9 +810,8 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                $relative_position  = 'before';
</span><span class="cx" style="display: block; padding: 0 10px">                $anchor_block_type  = $block['blockName'];
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $hooked_block_types = get_hooked_blocks( $anchor_block_type );
-               $hooked_block_types = isset( $hooked_block_types[ $relative_position ] )
-                       ? $hooked_block_types[ $relative_position ]
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $hooked_block_types = isset( $hooked_blocks[ $anchor_block_type ][ $relative_position ] )
+                       ? $hooked_blocks[ $anchor_block_type ][ $relative_position ]
</ins><span class="cx" style="display: block; padding: 0 10px">                         : array();
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                /** This filter is documented in wp-includes/blocks.php */
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -835,11 +834,12 @@
</span><span class="cx" style="display: block; padding: 0 10px">  * @since 6.4.0
</span><span class="cx" style="display: block; padding: 0 10px">  * @access private
</span><span class="cx" style="display: block; padding: 0 10px">  *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @param WP_Block_Template|array $context A block template, template part, or pattern that the blocks belong to.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @param array                   $hooked_blocks An array of blocks hooked to another block.
+ * @param WP_Block_Template|array $context       A block template, template part, or pattern that the blocks belong to.
</ins><span class="cx" style="display: block; padding: 0 10px">  * @return callable A function that returns the serialized markup for the given block,
</span><span class="cx" style="display: block; padding: 0 10px">  *                  including the markup for any hooked blocks after it.
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-function make_after_block_visitor( $context ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+function make_after_block_visitor( $hooked_blocks, $context ) {
</ins><span class="cx" style="display: block; padding: 0 10px">         /**
</span><span class="cx" style="display: block; padding: 0 10px">         * Injects hooked blocks after the given block, and returns the serialized markup.
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -851,15 +851,14 @@
</span><span class="cx" style="display: block; padding: 0 10px">         * @param array $next         The next sibling block of the given block.
</span><span class="cx" style="display: block; padding: 0 10px">         * @return string The serialized markup for the given block, with the markup for any hooked blocks appended to it.
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        return function ( &$block, $parent_block = null, $next = null ) use ( $context ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ return function ( &$block, $parent_block = null, $next = null ) use ( $hooked_blocks, $context ) {
</ins><span class="cx" style="display: block; padding: 0 10px">                 $markup = '';
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                $relative_position  = 'after';
</span><span class="cx" style="display: block; padding: 0 10px">                $anchor_block_type  = $block['blockName'];
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $hooked_block_types = get_hooked_blocks( $anchor_block_type );
-               $hooked_block_types = isset( $hooked_block_types[ $relative_position ] )
-                       ? $hooked_block_types[ $relative_position ]
-                       : array();
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $hooked_block_types = isset( $hooked_blocks[ $anchor_block_type ][ $relative_position ] )
+                               ? $hooked_blocks[ $anchor_block_type ][ $relative_position ]
+                               : array();
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                /** This filter is documented in wp-includes/blocks.php */
</span><span class="cx" style="display: block; padding: 0 10px">                $hooked_block_types = apply_filters( 'hooked_block_types', $hooked_block_types, $relative_position, $anchor_block_type, $context );
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -871,9 +870,8 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        // Candidate for last-child insertion.
</span><span class="cx" style="display: block; padding: 0 10px">                        $relative_position  = 'last_child';
</span><span class="cx" style="display: block; padding: 0 10px">                        $anchor_block_type  = $parent_block['blockName'];
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        $hooked_block_types = get_hooked_blocks( $anchor_block_type );
-                       $hooked_block_types = isset( $hooked_block_types[ $relative_position ] )
-                               ? $hooked_block_types[ $relative_position ]
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 $hooked_block_types = isset( $hooked_blocks[ $anchor_block_type ][ $relative_position ] )
+                               ? $hooked_blocks[ $anchor_block_type ][ $relative_position ]
</ins><span class="cx" style="display: block; padding: 0 10px">                                 : array();
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                        /** This filter is documented in wp-includes/blocks.php */
</span></span></pre></div>
<a id="trunksrcwpincludesclasswpblockpatternsregistryphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/class-wp-block-patterns-registry.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/class-wp-block-patterns-registry.php        2023-10-09 14:47:57 UTC (rev 56804)
+++ trunk/src/wp-includes/class-wp-block-patterns-registry.php  2023-10-09 16:38:25 UTC (rev 56805)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -153,6 +153,28 @@
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        /**
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         * Prepares the content of a block pattern. If hooked blocks are registered, they get injected into the pattern,
+        * when they met the defined criteria.
+        *
+        * @since 6.4.0
+        *
+        * @param array $pattern       Registered pattern properties.
+        * @param array $hooked_blocks The list of hooked blocks.
+        * @return string The content of the block pattern.
+        */
+       private function prepare_content( $pattern, $hooked_blocks ) {
+               $content = $pattern['content'];
+               if ( ! empty( $hooked_blocks ) || has_filter( 'hooked_block_types' ) ) {
+                       $blocks               = parse_blocks( $content );
+                       $before_block_visitor = make_before_block_visitor( $hooked_blocks, $pattern );
+                       $after_block_visitor  = make_after_block_visitor( $hooked_blocks, $pattern );
+                       $content              = traverse_and_serialize_blocks( $blocks, $before_block_visitor, $after_block_visitor );
+               }
+
+               return $content;
+       }
+
+       /**
</ins><span class="cx" style="display: block; padding: 0 10px">          * Retrieves an array containing the properties of a registered block pattern.
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><span class="cx" style="display: block; padding: 0 10px">         * @since 5.5.0
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -165,11 +187,8 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        return null;
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $pattern              = $this->registered_patterns[ $pattern_name ];
-               $blocks               = parse_blocks( $pattern['content'] );
-               $before_block_visitor = make_before_block_visitor( $pattern );
-               $after_block_visitor  = make_after_block_visitor( $pattern );
-               $pattern['content']   = traverse_and_serialize_blocks( $blocks, $before_block_visitor, $after_block_visitor );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $pattern            = $this->registered_patterns[ $pattern_name ];
+               $pattern['content'] = $this->prepare_content( $pattern, get_hooked_blocks() );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                return $pattern;
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -184,17 +203,14 @@
</span><span class="cx" style="display: block; padding: 0 10px">         *                 and per style.
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        public function get_all_registered( $outside_init_only = false ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $patterns = array_values(
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $patterns      = array_values(
</ins><span class="cx" style="display: block; padding: 0 10px">                         $outside_init_only
</span><span class="cx" style="display: block; padding: 0 10px">                                ? $this->registered_patterns_outside_init
</span><span class="cx" style="display: block; padding: 0 10px">                                : $this->registered_patterns
</span><span class="cx" style="display: block; padding: 0 10px">                );
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $hooked_blocks = get_hooked_blocks();
</ins><span class="cx" style="display: block; padding: 0 10px">                 foreach ( $patterns as $index => $pattern ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        $blocks                        = parse_blocks( $pattern['content'] );
-                       $before_block_visitor          = make_before_block_visitor( $pattern );
-                       $after_block_visitor           = make_after_block_visitor( $pattern );
-                       $patterns[ $index ]['content'] = traverse_and_serialize_blocks( $blocks, $before_block_visitor, $after_block_visitor );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 $patterns[ $index ]['content'] = $this->prepare_content( $pattern, $hooked_blocks );
</ins><span class="cx" style="display: block; padding: 0 10px">                 }
</span><span class="cx" style="display: block; padding: 0 10px">                return $patterns;
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span></span></pre></div>
<a id="trunktestsphpunittestsblocksgetHookedBlocksphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/tests/phpunit/tests/blocks/getHookedBlocks.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/blocks/getHookedBlocks.php      2023-10-09 14:47:57 UTC (rev 56804)
+++ trunk/tests/phpunit/tests/blocks/getHookedBlocks.php        2023-10-09 16:38:25 UTC (rev 56805)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -62,7 +62,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">         * @covers ::get_hooked_blocks
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        public function test_get_hooked_blocks_no_match_found() {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $result = get_hooked_blocks( 'tests/no-hooked-blocks' );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $result = get_hooked_blocks();
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                $this->assertSame( array(), $result );
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -98,53 +98,38 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                $this->assertSame(
</span><span class="cx" style="display: block; padding: 0 10px">                        array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                'before' => array(
-                                       'tests/injected-one',
-                                       'tests/injected-two',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         'tests/hooked-at-before'           => array(
+                                       'before' => array(
+                                               'tests/injected-one',
+                                               'tests/injected-two',
+                                       ),
</ins><span class="cx" style="display: block; padding: 0 10px">                                 ),
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        ),
-                       get_hooked_blocks( 'tests/hooked-at-before' ),
-                       'block hooked at the before position'
-               );
-               $this->assertSame(
-                       array(
-                               'after' => array(
-                                       'tests/injected-one',
-                                       'tests/injected-two',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         'tests/hooked-at-after'            => array(
+                                       'after' => array(
+                                               'tests/injected-one',
+                                               'tests/injected-two',
+                                       ),
</ins><span class="cx" style="display: block; padding: 0 10px">                                 ),
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        ),
-                       get_hooked_blocks( 'tests/hooked-at-after' ),
-                       'block hooked at the after position'
-               );
-               $this->assertSame(
-                       array(
-                               'first_child' => array(
-                                       'tests/injected-two',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         'tests/hooked-at-before-and-after' => array(
+                                       'before' => array(
+                                               'tests/injected-one',
+                                       ),
+                                       'after'  => array(
+                                               'tests/injected-two',
+                                       ),
</ins><span class="cx" style="display: block; padding: 0 10px">                                 ),
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        ),
-                       get_hooked_blocks( 'tests/hooked-at-first-child' ),
-                       'block hooked at the first child position'
-               );
-               $this->assertSame(
-                       array(
-                               'last_child' => array(
-                                       'tests/injected-two',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         'tests/hooked-at-first-child'      => array(
+                                       'first_child' => array(
+                                               'tests/injected-two',
+                                       ),
</ins><span class="cx" style="display: block; padding: 0 10px">                                 ),
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        ),
-                       get_hooked_blocks( 'tests/hooked-at-last-child' ),
-                       'block hooked at the last child position'
-               );
-               $this->assertSame(
-                       array(
-                               'before' => array(
-                                       'tests/injected-one',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         'tests/hooked-at-last-child'       => array(
+                                       'last_child' => array(
+                                               'tests/injected-two',
+                                       ),
</ins><span class="cx" style="display: block; padding: 0 10px">                                 ),
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                'after'  => array(
-                                       'tests/injected-two',
-                               ),
</del><span class="cx" style="display: block; padding: 0 10px">                         ),
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        get_hooked_blocks( 'tests/hooked-at-before-and-after' ),
-                       'block hooked before one block and after another'
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 get_hooked_blocks()
</ins><span class="cx" style="display: block; padding: 0 10px">                 );
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span></span></pre>
</div>
</div>

</body>
</html>