From fb2f48d81bda63dbc6a9ebe60f6f84c4a5f27bd2 Mon Sep 17 00:00:00 2001 From: Gary Pendergast Date: Fri, 14 Dec 2018 06:01:24 +0000 Subject: [PATCH] Block Editor: Preload `wp/v2/media` with OPTIONS for caps check. Also introduces a `block_editor_preload_paths` filter for plugins and themes to preload additional data. Merges [43833] from the 5.0 branch to trunk. Props imath, mattheu, danielbachhuber. Fixes #45194. git-svn-id: https://develop.svn.wordpress.org/trunk@44172 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/edit-form-blocks.php | 13 +++++++++++++ src/wp-includes/rest-api.php | 29 ++++++++++++++++++++++++----- tests/phpunit/tests/rest-api.php | 21 +++++++++++++++++++++ 3 files changed, 58 insertions(+), 5 deletions(-) diff --git a/src/wp-admin/edit-form-blocks.php b/src/wp-admin/edit-form-blocks.php index e8f9d73b43..3a0f8a746e 100644 --- a/src/wp-admin/edit-form-blocks.php +++ b/src/wp-admin/edit-form-blocks.php @@ -49,8 +49,21 @@ $preload_paths = array( sprintf( '/wp/v2/%s/%s?context=edit', $rest_base, $post->ID ), sprintf( '/wp/v2/types/%s?context=edit', $post_type ), sprintf( '/wp/v2/users/me?post_type=%s&context=edit', $post_type ), + array( '/wp/v2/media', 'OPTIONS' ), ); +/** + * 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 array $preload_paths Array of paths to preload. + * @param object $post The post resource data. + */ +$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 diff --git a/src/wp-includes/rest-api.php b/src/wp-includes/rest-api.php index f8e97065a9..26593af44a 100644 --- a/src/wp-includes/rest-api.php +++ b/src/wp-includes/rest-api.php @@ -1342,12 +1342,22 @@ function rest_preload_api_request( $memo, $path ) { return $memo; } + $method = 'GET'; + if ( is_array( $path ) && 2 === count( $path ) ) { + $method = end( $path ); + $path = reset( $path ); + + if ( ! in_array( $method, array( 'GET', 'OPTIONS' ), true ) ) { + $method = 'GET'; + } + } + $path_parts = parse_url( $path ); if ( false === $path_parts ) { return $memo; } - $request = new WP_REST_Request( 'GET', $path_parts['path'] ); + $request = new WP_REST_Request( $method, $path_parts['path'] ); if ( ! empty( $path_parts['query'] ) ) { parse_str( $path_parts['query'], $query_params ); $request->set_query_params( $query_params ); @@ -1366,10 +1376,19 @@ function rest_preload_api_request( $memo, $path ) { $data['_links'] = $links; } - $memo[ $path ] = array( - 'body' => $data, - 'headers' => $response->headers, - ); + if ( 'OPTIONS' === $method ) { + $response = rest_send_allow_header( $response, $server, $request ); + + $memo[ $method ][ $path ] = array( + 'body' => $data, + 'headers' => $response->headers, + ); + } else { + $memo[ $path ] = array( + 'body' => $data, + 'headers' => $response->headers, + ); + } } return $memo; diff --git a/tests/phpunit/tests/rest-api.php b/tests/phpunit/tests/rest-api.php index d20566e15e..dc94c7b6dd 100644 --- a/tests/phpunit/tests/rest-api.php +++ b/tests/phpunit/tests/rest-api.php @@ -721,4 +721,25 @@ class Tests_REST_API extends WP_UnitTestCase { function test_rest_preload_api_request_no_notices_php_52() { $this->assertTrue( is_array( rest_preload_api_request( 0, '/' ) ) ); } + + function test_rest_preload_api_request_with_method() { + $rest_server = $GLOBALS['wp_rest_server']; + $GLOBALS['wp_rest_server'] = null; + + $preload_paths = array( + '/wp/v2/types', + array( '/wp/v2/media', 'OPTIONS' ), + ); + + $preload_data = array_reduce( + $preload_paths, + 'rest_preload_api_request', + array() + ); + + $this->assertSame( array_keys( $preload_data ), array( '/wp/v2/types', 'OPTIONS' ) ); + $this->assertTrue( isset( $preload_data['OPTIONS']['/wp/v2/media'] ) ); + + $GLOBALS['wp_rest_server'] = $rest_server; + } }