<!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>[50956] trunk: Editor: Extract `block_editor_rest_api_preload` method for use with different editor screens</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/50956">50956</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/50956","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>gziolo</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2021-05-24 07:31:49 +0000 (Mon, 24 May 2021)</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'>Editor: Extract `block_editor_rest_api_preload` method for use with different editor screens

It is going to be used on the new widgets editor screen. This patch also introduced a new class WP_Block_Editor_Context that is going to be used with revised block editor filters to let extenders to keep their existing behavior. It should also allow to provide more settings through the context class as new screens get introduced like the navigation editor.

Props azaozz, chrisvanpatten, timothyblynjacobs, youknowriad.
Fixes <a href="https://core.trac.wordpress.org/ticket/52920">#52920</a>.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunksrcwpadmineditformblocksphp">trunk/src/wp-admin/edit-form-blocks.php</a></li>
<li><a href="#trunksrcwpincludesblockeditorphp">trunk/src/wp-includes/block-editor.php</a></li>
<li><a href="#trunksrcwpsettingsphp">trunk/src/wp-settings.php</a></li>
<li><a href="#trunktestsphpunittestsblocksblockeditorphp">trunk/tests/phpunit/tests/blocks/block-editor.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunksrcwpadmineditformblocksphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-admin/edit-form-blocks.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-admin/edit-form-blocks.php   2021-05-24 06:26:00 UTC (rev 50955)
+++ trunk/src/wp-admin/edit-form-blocks.php     2021-05-24 07:31:49 UTC (rev 50956)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -23,7 +23,8 @@
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span><span class="cx" style="display: block; padding: 0 10px"> global $post_type, $post_type_object, $post, $title, $editor_styles, $wp_meta_boxes;
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-$editor_name = 'post-editor';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+$editor_name          = 'post-editor';
+$block_editor_context = new WP_Block_Editor_Context( array( 'post' => $post ) );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> // Flag that we're loading the block editor.
</span><span class="cx" style="display: block; padding: 0 10px"> $current_screen = get_current_screen();
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -58,42 +59,9 @@
</span><span class="cx" style="display: block; padding: 0 10px">        sprintf( '/wp/v2/%s/%d/autosaves?context=edit', $rest_base, $post->ID ),
</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">+block_editor_rest_api_preload( $preload_paths, $block_editor_context );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-/**
- * Preload common data by specifying an array of REST API paths that will be preloaded.
- *
- * Filters the array of paths that will be preloaded.
- *
- * @since 5.0.0
- *
- * @param string[] $preload_paths Array of paths to preload.
- * @param WP_Post  $post          Post being edited.
- */
-$preload_paths = apply_filters( 'block_editor_preload_paths', $preload_paths, $post );
-
-/*
- * Ensure the global $post remains the same after API data is preloaded.
- * Because API preloading can call the_content and other filters, plugins
- * can unexpectedly modify $post.
- */
-$backup_global_post = clone $post;
-
-$preload_data = array_reduce(
-       $preload_paths,
-       'rest_preload_api_request',
-       array()
-);
-
-// Restore the global $post as it was before API preloading.
-$post = $backup_global_post;
-
</del><span class="cx" style="display: block; padding: 0 10px"> wp_add_inline_script(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        'wp-api-fetch',
-       sprintf( 'wp.apiFetch.use( wp.apiFetch.createPreloadingMiddleware( %s ) );', wp_json_encode( $preload_data ) ),
-       'after'
-);
-
-wp_add_inline_script(
</del><span class="cx" style="display: block; padding: 0 10px">         'wp-blocks',
</span><span class="cx" style="display: block; padding: 0 10px">        sprintf( 'wp.blocks.setCategories( %s );', wp_json_encode( get_block_categories( $post ) ) ),
</span><span class="cx" style="display: block; padding: 0 10px">        'after'
</span></span></pre></div>
<a id="trunksrcwpincludesblockeditorphp"></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-editor.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/block-editor.php    2021-05-24 06:26:00 UTC (rev 50955)
+++ trunk/src/wp-includes/block-editor.php      2021-05-24 07:31:49 UTC (rev 50956)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -269,3 +269,75 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        return $editor_settings;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+/**
+ * Preloads common data used with the block editor by specifying an array of
+ * REST API paths that will be preloaded for a given block editor context.
+ *
+ * @since 5.8.0
+ *
+ * @global WP_Post $post Global post object.
+ *
+ * @param array                   $preload_paths        List of paths to preload.
+ * @param WP_Block_Editor_Context $block_editor_context The current block editor context.
+ *
+ * @return void
+ */
+function block_editor_rest_api_preload( array $preload_paths, $block_editor_context ) {
+       global $post;
+
+       /**
+        * Filters the array of REST API paths that will be used to preloaded common data
+        * to use with the block editor.
+        *
+        * @since 5.8.0
+        *
+        * @param string[] $preload_paths Array of paths to preload.
+        */
+       $preload_paths = apply_filters( 'block_editor_rest_api_preload_paths', $preload_paths, $block_editor_context );
+       if ( ! empty( $block_editor_context->post ) ) {
+               $selected_post = $block_editor_context->post;
+
+               /**
+                * Preload common data by specifying an array of REST API paths that will be preloaded.
+                *
+                * Filters the array of paths that will be preloaded.
+                *
+                * @since 5.0.0
+                * @deprecated 5.8.0 The hook transitioned to support also screens that don't contain $post instance.
+                *
+                * @param string[] $preload_paths Array of paths to preload.
+                * @param WP_Post  $selected_post Post being edited.
+                */
+               $preload_paths = apply_filters_deprecated( 'block_editor_preload_paths', array( $preload_paths, $selected_post ), '5.8.0', 'block_editor_rest_api_preload_paths' );
+       }
+
+       if ( empty( $preload_paths ) ) {
+               return;
+       }
+
+       /*
+        * Ensure the global $post remains the same after API data is preloaded.
+        * Because API preloading can call the_content and other filters, plugins
+        * can unexpectedly modify $post.
+        */
+       $backup_global_post = ! empty( $post ) ? clone $post : $post;
+
+       $preload_data = array_reduce(
+               $preload_paths,
+               'rest_preload_api_request',
+               array()
+       );
+
+       // Restore the global $post as it was before API preloading.
+       $post = $backup_global_post;
+
+       wp_add_inline_script(
+               'wp-api-fetch',
+               sprintf(
+                       'wp.apiFetch.use( wp.apiFetch.createPreloadingMiddleware( %s ) );',
+                       wp_json_encode( $preload_data )
+               ),
+               'after'
+       );
+}
</ins></span></pre></div>
<a id="trunksrcwpsettingsphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-settings.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-settings.php 2021-05-24 06:26:00 UTC (rev 50955)
+++ trunk/src/wp-settings.php   2021-05-24 07:31:49 UTC (rev 50956)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -284,6 +284,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> require ABSPATH . WPINC . '/sitemaps/providers/class-wp-sitemaps-posts.php';
</span><span class="cx" style="display: block; padding: 0 10px"> require ABSPATH . WPINC . '/sitemaps/providers/class-wp-sitemaps-taxonomies.php';
</span><span class="cx" style="display: block; padding: 0 10px"> require ABSPATH . WPINC . '/sitemaps/providers/class-wp-sitemaps-users.php';
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+require ABSPATH . WPINC . '/class-wp-block-editor-context.php';
</ins><span class="cx" style="display: block; padding: 0 10px"> require ABSPATH . WPINC . '/class-wp-block-type.php';
</span><span class="cx" style="display: block; padding: 0 10px"> require ABSPATH . WPINC . '/class-wp-block-pattern-categories-registry.php';
</span><span class="cx" style="display: block; padding: 0 10px"> require ABSPATH . WPINC . '/class-wp-block-patterns-registry.php';
</span></span></pre></div>
<a id="trunktestsphpunittestsblocksblockeditorphp"></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/block-editor.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/blocks/block-editor.php 2021-05-24 06:26:00 UTC (rev 50955)
+++ trunk/tests/phpunit/tests/blocks/block-editor.php   2021-05-24 07:31:49 UTC (rev 50956)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -65,6 +65,24 @@
</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">         * @ticket 52920
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         */
+       function test_block_editor_context_no_settings() {
+               $context = new WP_Block_Editor_Context();
+
+               $this->assertNull( $context->post );
+       }
+
+       /**
+        * @ticket 52920
+        */
+       function test_block_editor_context_post() {
+               $context = new WP_Block_Editor_Context( array( 'post' => $this->post ) );
+
+               $this->assertSame( $this->post, $context->post );
+       }
+
+       /**
+        * @ticket 52920
</ins><span class="cx" style="display: block; padding: 0 10px">          * @expectedDeprecated block_categories
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        function test_get_block_categories_deprecated_filter_post_object() {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -299,4 +317,71 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        $settings
</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">+
+       /**
+        * @ticket 52920
+        */
+       function test_block_editor_rest_api_preload_no_paths() {
+               $context = new WP_Block_Editor_Context();
+               block_editor_rest_api_preload( array(), $context );
+
+               $after = implode( '', wp_scripts()->registered['wp-api-fetch']->extra['after'] );
+               $this->assertNotContains( 'wp.apiFetch.createPreloadingMiddleware', $after );
+       }
+
+       /**
+        * @ticket 52920
+        * @expectedDeprecated block_editor_preload_paths
+        */
+       function test_block_editor_rest_api_preload_deprecated_filter_post_editor() {
+               function filter_remove_preload_paths( $preload_paths, $post ) {
+                       if ( empty( $post ) ) {
+                               return $preload_paths;
+                       }
+                       return array();
+               }
+               add_filter( 'block_editor_preload_paths', 'filter_remove_preload_paths', 10, 2 );
+
+               $context = new WP_Block_Editor_Context( array( 'post' => get_post() ) );
+               block_editor_rest_api_preload(
+                       array(
+                               array( '/wp/v2/blocks', 'OPTIONS' ),
+                       ),
+                       $context
+               );
+
+               remove_filter( 'block_editor_preload_paths', 'filter_remove_preload_paths' );
+
+               $after = implode( '', wp_scripts()->registered['wp-api-fetch']->extra['after'] );
+               $this->assertNotContains( 'wp.apiFetch.createPreloadingMiddleware', $after );
+       }
+
+       /**
+        * @ticket 52920
+        */
+       function test_block_editor_rest_api_preload_filter_all() {
+               function filter_add_preload_paths( $preload_paths, WP_Block_Editor_Context $context ) {
+                       if ( empty( $context->post ) ) {
+                               array_push( $preload_paths, array( '/wp/v2/types', 'OPTIONS' ) );
+                       }
+
+                       return $preload_paths;
+               }
+               add_filter( 'block_editor_rest_api_preload_paths', 'filter_add_preload_paths', 10, 2 );
+
+               $context = new WP_Block_Editor_Context();
+               block_editor_rest_api_preload(
+                       array(
+                               array( '/wp/v2/blocks', 'OPTIONS' ),
+                       ),
+                       $context
+               );
+
+               remove_filter( 'block_editor_rest_api_preload_paths', 'filter_add_preload_paths' );
+
+               $after = implode( '', wp_scripts()->registered['wp-api-fetch']->extra['after'] );
+               $this->assertContains( 'wp.apiFetch.createPreloadingMiddleware', $after );
+               $this->assertContains( '"\/wp\/v2\/blocks"', $after );
+               $this->assertContains( '"\/wp\/v2\/types"', $after );
+       }
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span></span></pre>
</div>
</div>

</body>
</html>