<!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>[58291] trunk: Block Hooks: Move ignoredHookedBlocks metadata injection logic.</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/58291">58291</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/58291","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>2024-06-03 12:03:53 +0000 (Mon, 03 Jun 2024)</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'>Block Hooks: Move ignoredHookedBlocks metadata injection logic.

As of <a href="https://core.trac.wordpress.org/changeset/57790">[57790]</a>, the Templates endpoint uses the `rest_pre_insert_*` filter to inject the `ignoredHookedBlocks` metadata attribute into anchor blocks, prior to persisting a template or template part to the database. The same principle was implemented for the Navigation endpoint (where additionally, first and last child blocks added at the top level are store in the `wp_navigation` post object's post meta). The required logic was added to the Navigation block's code, i.e. inside the Gutenberg code repository, and then synchronized to Core.

In order to harmonize the code between the two endpoints, this changeset introduces a new `update_ignored_hooked_blocks_postmeta` function, which is based on the Navigation block's `block_core_navigation_update_ignore_hooked_blocks_meta`, alongside a few helper functions, and hooks it to the `rest_pre_insert_wp_navigation` filter hook. (The Navigation block has been prepared in <a href="https://core.trac.wordpress.org/changeset/58275">[58275]</a> to add an additional conditional to check for the new `update_ignored_hooked_blocks_postmeta` filter so there won't be any collisions.)

Eventually, this will allow to deprecate `block_core_navigation_update_ignore_hooked_blocks_meta` (and some related functions), and remove the relevant code from the Navigation block. It also paves the way for some other future changes, such as inserting a hooked block as a Template Part block's first or last child (<a href="https://core.trac.wordpress.org/ticket/60854">#60854</a>).

Props tomjcafferkey, bernhard-reiter.
Fixes <a href="https://core.trac.wordpress.org/ticket/60759">#60759</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="#trunksrcwpincludesdefaultfiltersphp">trunk/src/wp-includes/default-filters.php</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunktestsphpunittestsblocksupdateIgnoredHookedBlocksPostMetaphp">trunk/tests/phpunit/tests/blocks/updateIgnoredHookedBlocksPostMeta.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    2024-06-03 10:27:35 UTC (rev 58290)
+++ trunk/src/wp-includes/block-template-utils.php      2024-06-03 12:03:53 UTC (rev 58291)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1599,11 +1599,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                return $template;
</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">-        $before_block_visitor = make_before_block_visitor( $hooked_blocks, $template, 'set_ignored_hooked_blocks_metadata' );
-       $after_block_visitor  = make_after_block_visitor( $hooked_blocks, $template, 'set_ignored_hooked_blocks_metadata' );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $changes->post_content = apply_block_hooks_to_content( $changes->post_content, $template, 'set_ignored_hooked_blocks_metadata' );
</ins><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( $changes->post_content );
-       $changes->post_content = traverse_and_serialize_blocks( $blocks, $before_block_visitor, $after_block_visitor );
-
</del><span class="cx" style="display: block; padding: 0 10px">         return $changes;
</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  2024-06-03 10:27:35 UTC (rev 58290)
+++ trunk/src/wp-includes/blocks.php    2024-06-03 12:03:53 UTC (rev 58291)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1003,14 +1003,124 @@
</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">+ * Runs the hooked blocks algorithm on the given content.
+ *
+ * @since 6.6.0
+ * @access private
+ *
+ * @param string $content Serialized content.
+ * @param WP_Block_Template|WP_Post|array $context       A block template, template part, `wp_navigation` post object,
+ *                                                       or pattern that the blocks belong to.
+ * @param callable                        $callback      A function that will be called for each block to generate
+ *                                                       the markup for a given list of blocks that are hooked to it.
+ *                                                       Default: 'insert_hooked_blocks'.
+ * @return string The serialized markup.
+ */
+function apply_block_hooks_to_content( $content, $context, $callback = 'insert_hooked_blocks' ) {
+       $hooked_blocks = get_hooked_blocks();
+       if ( empty( $hooked_blocks ) && ! has_filter( 'hooked_block_types' ) ) {
+               return $content;
+       }
+
+       $blocks = parse_blocks( $content );
+
+       $before_block_visitor = make_before_block_visitor( $hooked_blocks, $context, $callback );
+       $after_block_visitor  = make_after_block_visitor( $hooked_blocks, $context, $callback );
+
+       return traverse_and_serialize_blocks( $blocks, $before_block_visitor, $after_block_visitor );
+}
+
+/**
+ * Accepts the serialized markup of a block and its inner blocks, and returns serialized markup of the inner blocks.
+ *
+ * @since 6.6.0
+ * @access private
+ *
+ * @param string $serialized_block The serialized markup of a block and its inner blocks.
+ * @return string The serialized markup of the inner blocks.
+ */
+function remove_serialized_parent_block( $serialized_block ) {
+       $start = strpos( $serialized_block, '-->' ) + strlen( '-->' );
+       $end   = strrpos( $serialized_block, '<!--' );
+       return substr( $serialized_block, $start, $end - $start );
+}
+
+/**
+ * Updates the wp_postmeta with the list of ignored hooked blocks where the inner blocks are stored as post content.
+ * Currently only supports `wp_navigation` post types.
+ *
+ * @since 6.6.0
+ * @access private
+ *
+ * @param stdClass $post Post object.
+ * @return stdClass The updated post object.
+ */
+function update_ignored_hooked_blocks_postmeta( $post ) {
+       /*
+        * In this scenario the user has likely tried to create a navigation via the REST API.
+        * In which case we won't have a post ID to work with and store meta against.
+        */
+       if ( empty( $post->ID ) ) {
+               return $post;
+       }
+
+       /**
+        * Skip meta generation when consumers intentionally update specific Navigation fields
+        * and omit the content update.
+        */
+       if ( ! isset( $post->post_content ) ) {
+               return $post;
+       }
+
+       /**
+        * Skip meta generation when the post content is not a navigation block.
+        */
+       if ( ! isset( $post->post_type ) || 'wp_navigation' !== $post->post_type ) {
+               return $post;
+       }
+
+       $attributes = array();
+
+       $ignored_hooked_blocks = get_post_meta( $post->ID, '_wp_ignored_hooked_blocks', true );
+       if ( ! empty( $ignored_hooked_blocks ) ) {
+               $ignored_hooked_blocks  = json_decode( $ignored_hooked_blocks, true );
+               $attributes['metadata'] = array(
+                       'ignoredHookedBlocks' => $ignored_hooked_blocks,
+               );
+       }
+
+       $markup = get_comment_delimited_block_content(
+               'core/navigation',
+               $attributes,
+               $post->post_content
+       );
+
+       $serialized_block = apply_block_hooks_to_content( $markup, get_post( $post->ID ), 'set_ignored_hooked_blocks_metadata' );
+       $root_block       = parse_blocks( $serialized_block )[0];
+
+       $ignored_hooked_blocks = isset( $root_block['attrs']['metadata']['ignoredHookedBlocks'] )
+               ? $root_block['attrs']['metadata']['ignoredHookedBlocks']
+               : array();
+
+       if ( ! empty( $ignored_hooked_blocks ) ) {
+               $existing_ignored_hooked_blocks = get_post_meta( $post->ID, '_wp_ignored_hooked_blocks', true );
+               if ( ! empty( $existing_ignored_hooked_blocks ) ) {
+                       $existing_ignored_hooked_blocks = json_decode( $existing_ignored_hooked_blocks, true );
+                       $ignored_hooked_blocks          = array_unique( array_merge( $ignored_hooked_blocks, $existing_ignored_hooked_blocks ) );
+               }
+               update_post_meta( $post->ID, '_wp_ignored_hooked_blocks', json_encode( $ignored_hooked_blocks ) );
+       }
+
+       $post->post_content = remove_serialized_parent_block( $serialized_block );
+       return $post;
+}
+
+/*
</ins><span class="cx" style="display: block; padding: 0 10px">  * Returns the markup for blocks hooked to the given anchor block in a specific relative position and then
</span><span class="cx" style="display: block; padding: 0 10px">  * adds a list of hooked block types to an anchor block's ignored hooked block types.
</span><span class="cx" style="display: block; padding: 0 10px">  *
</span><span class="cx" style="display: block; padding: 0 10px">  * This function is meant for internal use only.
</span><span class="cx" style="display: block; padding: 0 10px">  *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @since 6.6.0
- * @access private
- *
</del><span class="cx" style="display: block; padding: 0 10px">  * @param array                           $parsed_anchor_block The anchor block, in parsed block array format.
</span><span class="cx" style="display: block; padding: 0 10px">  * @param string                          $relative_position   The relative position of the hooked blocks.
</span><span class="cx" style="display: block; padding: 0 10px">  *                                                             Can be one of 'before', 'after', 'first_child', or 'last_child'.
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1019,7 +1129,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">  * @return string
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span><span class="cx" style="display: block; padding: 0 10px"> function insert_hooked_blocks_and_set_ignored_hooked_blocks_metadata( &$parsed_anchor_block, $relative_position, $hooked_blocks, $context ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        $markup = insert_hooked_blocks( $parsed_anchor_block, $relative_position, $hooked_blocks, $context );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $markup  = insert_hooked_blocks( $parsed_anchor_block, $relative_position, $hooked_blocks, $context );
</ins><span class="cx" style="display: block; padding: 0 10px">         $markup .= set_ignored_hooked_blocks_metadata( $parsed_anchor_block, $relative_position, $hooked_blocks, $context );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        return $markup;
</span></span></pre></div>
<a id="trunksrcwpincludesdefaultfiltersphp"></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/default-filters.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/default-filters.php 2024-06-03 10:27:35 UTC (rev 58290)
+++ trunk/src/wp-includes/default-filters.php   2024-06-03 12:03:53 UTC (rev 58291)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -757,4 +757,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> add_filter( 'rest_pre_insert_wp_template', 'inject_ignored_hooked_blocks_metadata_attributes' );
</span><span class="cx" style="display: block; padding: 0 10px"> add_filter( 'rest_pre_insert_wp_template_part', 'inject_ignored_hooked_blocks_metadata_attributes' );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+// Update ignoredHookedBlocks postmeta for wp_navigation post type.
+add_filter( 'rest_pre_insert_wp_navigation', 'update_ignored_hooked_blocks_postmeta' );
+
</ins><span class="cx" style="display: block; padding: 0 10px"> unset( $filter, $action );
</span></span></pre></div>
<a id="trunktestsphpunittestsblocksupdateIgnoredHookedBlocksPostMetaphp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: trunk/tests/phpunit/tests/blocks/updateIgnoredHookedBlocksPostMeta.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/blocks/updateIgnoredHookedBlocksPostMeta.php                            (rev 0)
+++ trunk/tests/phpunit/tests/blocks/updateIgnoredHookedBlocksPostMeta.php      2024-06-03 12:03:53 UTC (rev 58291)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,196 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+/**
+ * Tests for update_ignored_hooked_blocks_postmeta
+ *
+ * @package WordPress
+ * @subpackage Blocks
+ *
+ * @since 6.6.0
+ *
+ * @group blocks
+ * @covers ::update_ignored_hooked_blocks_postmeta
+ */
+class Tests_Blocks_UpdateIgnoredHookedBlocksPostMeta extends WP_UnitTestCase {
+       /**
+        * Post object.
+        *
+        * @var object
+        */
+       protected static $navigation_post;
+
+       /**
+        * Setup method.
+        */
+       public static function wpSetUpBeforeClass() {
+               self::$navigation_post = self::factory()->post->create_and_get(
+                       array(
+                               'post_type'    => 'wp_navigation',
+                               'post_title'   => 'Navigation Menu',
+                               'post_content' => 'Original content',
+                       )
+               );
+       }
+
+       /**
+        * Tear down each test method.
+        */
+       public function tear_down() {
+               $registry = WP_Block_Type_Registry::get_instance();
+
+               if ( $registry->is_registered( 'tests/my-block' ) ) {
+                       $registry->unregister( 'tests/my-block' );
+               }
+
+               parent::tear_down();
+       }
+
+       /**
+        * @ticket 60759
+        */
+       public function test_update_ignored_hooked_blocks_postmeta_preserves_entities() {
+               register_block_type(
+                       'tests/my-block',
+                       array(
+                               'block_hooks' => array(
+                                       'core/navigation' => 'last_child',
+                               ),
+                       )
+               );
+
+               $original_markup    = '<!-- wp:navigation-link {"label":"News & About","type":"page","id":2,"url":"http://localhost:8888/?page_id=2","kind":"post-type"} /-->';
+               $post               = new stdClass();
+               $post->ID           = self::$navigation_post->ID;
+               $post->post_content = $original_markup;
+               $post->post_type    = 'wp_navigation';
+
+               $post = update_ignored_hooked_blocks_postmeta( $post );
+
+               // We expect the '&' character to be replaced with its unicode representation.
+               $expected_markup = str_replace( '&', '\u0026', $original_markup );
+
+               $this->assertSame(
+                       $expected_markup,
+                       $post->post_content,
+                       'Post content did not match expected markup with entities escaped.'
+               );
+               $this->assertSame(
+                       array( 'tests/my-block' ),
+                       json_decode( get_post_meta( self::$navigation_post->ID, '_wp_ignored_hooked_blocks', true ), true ),
+                       'Block was not added to ignored hooked blocks metadata.'
+               );
+       }
+
+       /**
+        * @ticket 60759
+        */
+       public function test_update_ignored_hooked_blocks_postmeta_dont_modify_no_post_id() {
+               register_block_type(
+                       'tests/my-block',
+                       array(
+                               'block_hooks' => array(
+                                       'core/navigation' => 'last_child',
+                               ),
+                       )
+               );
+
+               $original_markup    = '<!-- wp:navigation-link {"label":"News","type":"page","id":2,"url":"http://localhost:8888/?page_id=2","kind":"post-type"} /-->';
+               $post               = new stdClass();
+               $post->post_content = $original_markup;
+               $post->post_type    = 'wp_navigation';
+
+               $post = update_ignored_hooked_blocks_postmeta( $post );
+
+               $this->assertSame(
+                       $original_markup,
+                       $post->post_content,
+                       'Post content did not match the original markup.'
+               );
+       }
+
+       /**
+        * @ticket 60759
+        */
+       public function test_update_ignored_hooked_blocks_postmeta_retains_content_if_not_set() {
+               register_block_type(
+                       'tests/my-block',
+                       array(
+                               'block_hooks' => array(
+                                       'core/navigation' => 'last_child',
+                               ),
+                       )
+               );
+
+               $post             = new stdClass();
+               $post->ID         = self::$navigation_post->ID;
+               $post->post_title = 'Navigation Menu with changes';
+               $post->post_type  = 'wp_navigation';
+
+               $post = update_ignored_hooked_blocks_postmeta( $post );
+
+               $this->assertSame(
+                       'Navigation Menu with changes',
+                       $post->post_title,
+                       'Post title was changed.'
+               );
+
+               $this->assertFalse(
+                       isset( $post->post_content ),
+                       'Post content should not be set.'
+               );
+       }
+
+       /**
+        * @ticket 60759
+        */
+       public function test_update_ignored_hooked_blocks_postmeta_dont_modify_if_not_navigation() {
+               register_block_type(
+                       'tests/my-block',
+                       array(
+                               'block_hooks' => array(
+                                       'core/navigation' => 'last_child',
+                               ),
+                       )
+               );
+
+               $original_markup    = '<!-- wp:navigation-link {"label":"News","type":"page","id":2,"url":"http://localhost:8888/?page_id=2","kind":"post-type"} /-->';
+               $post               = new stdClass();
+               $post->ID           = self::$navigation_post->ID;
+               $post->post_content = $original_markup;
+               $post->post_type    = 'post';
+
+               $post = update_ignored_hooked_blocks_postmeta( $post );
+
+               $this->assertSame(
+                       $original_markup,
+                       $post->post_content,
+                       'Post content did not match the original markup.'
+               );
+       }
+
+       /**
+        * @ticket 60759
+        */
+       public function test_update_ignored_hooked_blocks_postmeta_dont_modify_if_no_post_type() {
+               register_block_type(
+                       'tests/my-block',
+                       array(
+                               'block_hooks' => array(
+                                       'core/navigation' => 'last_child',
+                               ),
+                       )
+               );
+
+               $original_markup    = '<!-- wp:navigation-link {"label":"News","type":"page","id":2,"url":"http://localhost:8888/?page_id=2","kind":"post-type"} /-->';
+               $post               = new stdClass();
+               $post->ID           = self::$navigation_post->ID;
+               $post->post_content = $original_markup;
+
+               $post = update_ignored_hooked_blocks_postmeta( $post );
+
+               $this->assertSame(
+                       $original_markup,
+                       $post->post_content,
+                       'Post content did not match the original markup.'
+               );
+       }
+}
</ins></span></pre>
</div>
</div>

</body>
</html>