From 63d9e57cd3b121710ad1415d8d40f020036f20c3 Mon Sep 17 00:00:00 2001 From: Felix Arntz Date: Fri, 10 Nov 2023 12:31:27 -0800 Subject: [PATCH 1/9] Implement functions to check whether a REST request is being made and whether a REST endpoint request is currently being handled. --- src/wp-includes/blocks/post-excerpt.php | 3 +- src/wp-includes/class-wp-query.php | 2 +- src/wp-includes/deprecated.php | 2 +- src/wp-includes/functions.php | 33 +++++++++++++- src/wp-includes/load.php | 4 ++ src/wp-includes/rest-api.php | 43 ++++++++++++++++++- .../rest-api/class-wp-rest-server.php | 32 +++++++++++++- .../class-wp-rest-attachments-controller.php | 4 +- .../class-wp-rest-url-details-controller.php | 2 +- src/wp-includes/script-loader.php | 2 +- src/wp-includes/user.php | 1 + 11 files changed, 115 insertions(+), 13 deletions(-) diff --git a/src/wp-includes/blocks/post-excerpt.php b/src/wp-includes/blocks/post-excerpt.php index 09d6b6f003d34..c002e1b2dd754 100644 --- a/src/wp-includes/blocks/post-excerpt.php +++ b/src/wp-includes/blocks/post-excerpt.php @@ -83,8 +83,7 @@ function register_block_core_post_excerpt() { * the excerpt length block setting has no effect. * Returns 100 because 100 is the max length in the setting. */ -if ( is_admin() || - defined( 'REST_REQUEST' ) && REST_REQUEST ) { +if ( is_admin() || wp_is_rest_endpoint() ) { add_filter( 'excerpt_length', static function () { diff --git a/src/wp-includes/class-wp-query.php b/src/wp-includes/class-wp-query.php index a9ed269d72244..36ee031fe59cf 100644 --- a/src/wp-includes/class-wp-query.php +++ b/src/wp-includes/class-wp-query.php @@ -1027,7 +1027,7 @@ public function parse_query( $query = '' ) { } if ( ! ( $this->is_singular || $this->is_archive || $this->is_search || $this->is_feed - || ( defined( 'REST_REQUEST' ) && REST_REQUEST && $this->is_main_query() ) + || ( wp_is_rest_request() && $this->is_main_query() ) || $this->is_trackback || $this->is_404 || $this->is_admin || $this->is_robots || $this->is_favicon ) ) { $this->is_home = true; } diff --git a/src/wp-includes/deprecated.php b/src/wp-includes/deprecated.php index e98cad915fd11..a10280870c385 100644 --- a/src/wp-includes/deprecated.php +++ b/src/wp-includes/deprecated.php @@ -5430,7 +5430,7 @@ function _wp_theme_json_webfonts_handler() { $settings = WP_Theme_JSON_Resolver::get_merged_data()->get_settings(); // If in the editor, add webfonts defined in variations. - if ( is_admin() || ( defined( 'REST_REQUEST' ) && REST_REQUEST ) ) { + if ( is_admin() || wp_is_rest_endpoint() ) { $variations = WP_Theme_JSON_Resolver::get_style_variations(); foreach ( $variations as $variation ) { // Skip if fontFamilies are not defined in the variation. diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php index cb490ee1764fa..94be0399cb16f 100644 --- a/src/wp-includes/functions.php +++ b/src/wp-includes/functions.php @@ -3718,7 +3718,7 @@ function wp_die( $message = '', $title = '', $args = array() ) { * @param callable $callback Callback function name. */ $callback = apply_filters( 'wp_die_json_handler', '_json_wp_die_handler' ); - } elseif ( defined( 'REST_REQUEST' ) && REST_REQUEST && wp_is_jsonp_request() ) { + } elseif ( wp_is_rest_request() && wp_is_jsonp_request() ) { /** * Filters the callback for killing WordPress execution for JSONP REST requests. * @@ -4439,7 +4439,7 @@ function _wp_json_prepare_data( $data ) { * @param int $options Optional. Options to be passed to json_encode(). Default 0. */ function wp_send_json( $response, $status_code = null, $options = 0 ) { - if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) { + if ( wp_is_rest_request() ) { _doing_it_wrong( __FUNCTION__, sprintf( @@ -4695,6 +4695,35 @@ function _mce_set_direction( $mce_init ) { return $mce_init; } +/** + * Determines whether the current request is a WordPress REST API request. + * + * The function relies on the 'REST_REQUEST' global. As such, it only returns true when an actual REST _request_ is + * being made. It does not return true when a REST endpoint is hit as part of another request, e.g. for preloading a + * REST response. See {@see wp_is_rest_endpoint()} for that purpose. + * + * This function must not be called until the {@see 'parse_request'} action. + * + * @since 6.5.0 + * + * @return bool True if it's a WordPress REST API request, false otherwise. + */ +function wp_is_rest_request(): bool { + if ( ! defined( 'REST_REQUEST' ) && ! did_action( 'parse_request' ) ) { + _doing_it_wrong( + __FUNCTION__, + sprintf( + /* translators: %s: parse_request */ + __( 'Detecting whether the current request is a REST API request is not possible until the %s hook.' ), + 'parse_request' + ), + '6.5.0' + ); + return false; + } + + return defined( 'REST_REQUEST' ) && REST_REQUEST; +} /** * Converts smiley code to the icon graphic file equivalent. diff --git a/src/wp-includes/load.php b/src/wp-includes/load.php index 520902cdd64ba..0dbbc187cfce2 100644 --- a/src/wp-includes/load.php +++ b/src/wp-includes/load.php @@ -598,6 +598,10 @@ function wp_debug_mode() { error_reporting( E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_ERROR | E_WARNING | E_PARSE | E_USER_ERROR | E_USER_WARNING | E_RECOVERABLE_ERROR ); } + /* + * The 'REST_REQUEST' check here is optimistic as the constant is most + * likely not set at this point even if it is in fact a REST request. + */ if ( defined( 'XMLRPC_REQUEST' ) || defined( 'REST_REQUEST' ) || defined( 'MS_FILES_REQUEST' ) || ( defined( 'WP_INSTALLING' ) && WP_INSTALLING ) || wp_doing_ajax() || wp_is_json_request() diff --git a/src/wp-includes/rest-api.php b/src/wp-includes/rest-api.php index 61e324e801445..4bdc0734e084e 100644 --- a/src/wp-includes/rest-api.php +++ b/src/wp-includes/rest-api.php @@ -209,7 +209,7 @@ function rest_api_register_rewrites() { * @since 4.4.0 */ function rest_api_default_filters() { - if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) { + if ( wp_is_rest_request() ) { // Deprecated reporting. add_action( 'deprecated_function_run', 'rest_handle_deprecated_function', 10, 3 ); add_filter( 'deprecated_function_trigger_error', '__return_false' ); @@ -3389,3 +3389,44 @@ static function ( $status, $error_data ) { return new WP_REST_Response( $data, $status ); } + +/** + * Checks whether a REST API endpoint request is currently being handled. + * + * This may be a standalone REST API request, or an internal request dispatched from within a regular page load. + * + * @since 6.5.0 + * + * @global WP_REST_Server $wp_rest_server REST server instance. + * + * @return bool True if a REST endpoint request is currently being handled, false otherwise. + */ +function wp_is_rest_endpoint(): bool { + /* @var WP_REST_Server $wp_rest_server */ + global $wp_rest_server; + + /* + * Check whether this is a standalone REST request. + * This check is not using the `wp_is_rest_request()` function as it may be called before the constant is actually + * available. Since this is only one way of determining whether a REST endpoint is being handled, there is no need + * to be as strict here as in the check for whether this is an actual standalone REST request. + */ + $is_rest_endpoint = defined( 'REST_REQUEST' ) && REST_REQUEST; + if ( ! $is_rest_endpoint ) { + // Otherwise, check whether an internal REST request is currently being handled. + $is_rest_endpoint = isset( $wp_rest_server ) + && method_exists( $wp_rest_server, 'is_dispatching' ) + && $wp_rest_server->is_dispatching(); + } + + /** + * Filters whether a REST endpoint request is currently being handled. + * + * This may be a standalone REST API request, or an internal request dispatched from within a regular page load. + * + * @since 6.5.0 + * + * @param bool $is_request_endpoint Whether a REST endpoint request is currently being handled. + */ + return (bool) apply_filters( 'wp_is_rest_endpoint', $is_rest_endpoint ); +} diff --git a/src/wp-includes/rest-api/class-wp-rest-server.php b/src/wp-includes/rest-api/class-wp-rest-server.php index 4304881b16fef..1cfed4adf4bd1 100644 --- a/src/wp-includes/rest-api/class-wp-rest-server.php +++ b/src/wp-includes/rest-api/class-wp-rest-server.php @@ -87,6 +87,14 @@ class WP_REST_Server { */ protected $embed_cache = array(); + /** + * Stores request objects that are currently being handled. + * + * @since 6.5.0 + * @var array + */ + protected $dispatching_requests = array(); + /** * Instantiates the REST server. * @@ -981,6 +989,8 @@ public function get_route_options( $route ) { * @return WP_REST_Response Response returned by the callback. */ public function dispatch( $request ) { + $this->dispatching_requests[] = $request; + /** * Filters the pre-calculated result of a REST API dispatch request. * @@ -1006,6 +1016,7 @@ public function dispatch( $request ) { $result = $this->error_to_response( $result ); } + array_pop( $this->dispatching_requests ); return $result; } @@ -1013,7 +1024,9 @@ public function dispatch( $request ) { $matched = $this->match_request_to_handler( $request ); if ( is_wp_error( $matched ) ) { - return $this->error_to_response( $matched ); + $response = $this->error_to_response( $matched ); + array_pop( $this->dispatching_requests ); + return $response; } list( $route, $handler ) = $matched; @@ -1038,7 +1051,22 @@ public function dispatch( $request ) { } } - return $this->respond_to_request( $request, $route, $handler, $error ); + $response = $this->respond_to_request( $request, $route, $handler, $error ); + array_pop( $this->dispatching_requests ); + return $response; + } + + /** + * Returns whether the REST server is currently dispatching / responding to a request. + * + * This may be a standalone REST API request, or an internal request dispatched from within a regular page load. + * + * @since 6.5.0 + * + * @return bool Whether the REST server is currently handling a request. + */ + public function is_dispatching(): bool { + return empty( $this->dispatching_requests ); } /** diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php index 7367c0fc57a07..36387d8be646f 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php @@ -201,7 +201,7 @@ public function create_item( $request ) { wp_after_insert_post( $attachment, false, null ); - if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) { + if ( wp_is_rest_request() ) { /* * Set a custom header with the attachment_id. * Used by the browser/client to resume creating image sub-sizes after a PHP fatal error. @@ -630,7 +630,7 @@ public function edit_media_item( $request ) { update_post_meta( $new_attachment_id, '_wp_attachment_image_alt', wp_slash( $image_alt ) ); } - if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) { + if ( wp_is_rest_request() ) { /* * Set a custom header with the attachment_id. * Used by the browser/client to resume creating image sub-sizes after a PHP fatal error. diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-url-details-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-url-details-controller.php index c9ac6675d093f..7dcc4d79236a1 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-url-details-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-url-details-controller.php @@ -128,7 +128,7 @@ public function get_item_schema() { * * @since 5.9.0 * - * @param WP_REST_REQUEST $request Full details about the request. + * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error The parsed details as a response object. WP_Error if there are errors. */ public function parse_url_details( $request ) { diff --git a/src/wp-includes/script-loader.php b/src/wp-includes/script-loader.php index 41be694281dcd..0692f62ab4f4f 100644 --- a/src/wp-includes/script-loader.php +++ b/src/wp-includes/script-loader.php @@ -2584,7 +2584,7 @@ function wp_should_load_block_editor_scripts_and_styles() { * @return bool Whether separate assets will be loaded. */ function wp_should_load_separate_core_block_assets() { - if ( is_admin() || is_feed() || ( defined( 'REST_REQUEST' ) && REST_REQUEST ) ) { + if ( is_admin() || is_feed() || wp_is_rest_endpoint() ) { return false; } diff --git a/src/wp-includes/user.php b/src/wp-includes/user.php index 5b9dacc20f233..dad96dea70423 100644 --- a/src/wp-includes/user.php +++ b/src/wp-includes/user.php @@ -333,6 +333,7 @@ function wp_authenticate_application_password( $input_user, $username, $password return $input_user; } + // The 'REST_REQUEST' check here may happen too early for the constant to be available. $is_api_request = ( ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST ) || ( defined( 'REST_REQUEST' ) && REST_REQUEST ) ); /** From e251d98747d87b3fef87ca8c73b9caf06682986b Mon Sep 17 00:00:00 2001 From: Felix Arntz Date: Fri, 10 Nov 2023 12:48:44 -0800 Subject: [PATCH 2/9] Get rid of unnecessarily strict _doing_it_wrong(). --- src/wp-includes/functions.php | 16 ++-------------- src/wp-includes/rest-api.php | 9 ++------- 2 files changed, 4 insertions(+), 21 deletions(-) diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php index 94be0399cb16f..874c2591e4995 100644 --- a/src/wp-includes/functions.php +++ b/src/wp-includes/functions.php @@ -4702,26 +4702,14 @@ function _mce_set_direction( $mce_init ) { * being made. It does not return true when a REST endpoint is hit as part of another request, e.g. for preloading a * REST response. See {@see wp_is_rest_endpoint()} for that purpose. * - * This function must not be called until the {@see 'parse_request'} action. + * This function should not be called until the {@see 'parse_request'} action, as the constant is only defined then, + * even for an actual REST request. * * @since 6.5.0 * * @return bool True if it's a WordPress REST API request, false otherwise. */ function wp_is_rest_request(): bool { - if ( ! defined( 'REST_REQUEST' ) && ! did_action( 'parse_request' ) ) { - _doing_it_wrong( - __FUNCTION__, - sprintf( - /* translators: %s: parse_request */ - __( 'Detecting whether the current request is a REST API request is not possible until the %s hook.' ), - 'parse_request' - ), - '6.5.0' - ); - return false; - } - return defined( 'REST_REQUEST' ) && REST_REQUEST; } diff --git a/src/wp-includes/rest-api.php b/src/wp-includes/rest-api.php index 4bdc0734e084e..52d87f4a95475 100644 --- a/src/wp-includes/rest-api.php +++ b/src/wp-includes/rest-api.php @@ -3405,13 +3405,8 @@ function wp_is_rest_endpoint(): bool { /* @var WP_REST_Server $wp_rest_server */ global $wp_rest_server; - /* - * Check whether this is a standalone REST request. - * This check is not using the `wp_is_rest_request()` function as it may be called before the constant is actually - * available. Since this is only one way of determining whether a REST endpoint is being handled, there is no need - * to be as strict here as in the check for whether this is an actual standalone REST request. - */ - $is_rest_endpoint = defined( 'REST_REQUEST' ) && REST_REQUEST; + // Check whether this is a standalone REST request. + $is_rest_endpoint = wp_is_rest_request(); if ( ! $is_rest_endpoint ) { // Otherwise, check whether an internal REST request is currently being handled. $is_rest_endpoint = isset( $wp_rest_server ) From 44a8960434f1f4e29d5eae60d00e201481d8d041 Mon Sep 17 00:00:00 2001 From: Felix Arntz Date: Fri, 10 Nov 2023 13:18:06 -0800 Subject: [PATCH 3/9] Avoid editing Gutenberg block file managed via dependency. --- src/wp-includes/blocks/post-excerpt.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/blocks/post-excerpt.php b/src/wp-includes/blocks/post-excerpt.php index c002e1b2dd754..09d6b6f003d34 100644 --- a/src/wp-includes/blocks/post-excerpt.php +++ b/src/wp-includes/blocks/post-excerpt.php @@ -83,7 +83,8 @@ function register_block_core_post_excerpt() { * the excerpt length block setting has no effect. * Returns 100 because 100 is the max length in the setting. */ -if ( is_admin() || wp_is_rest_endpoint() ) { +if ( is_admin() || + defined( 'REST_REQUEST' ) && REST_REQUEST ) { add_filter( 'excerpt_length', static function () { From a009157b1e5241cad6bd9a379faba40fe657508d Mon Sep 17 00:00:00 2001 From: Felix Arntz Date: Thu, 18 Jan 2024 08:49:13 -0800 Subject: [PATCH 4/9] Fix for wrong merge resolution. --- src/wp-includes/functions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php index e1770e904d743..edb8854792018 100644 --- a/src/wp-includes/functions.php +++ b/src/wp-includes/functions.php @@ -4440,7 +4440,7 @@ function _wp_json_prepare_data( $value ) { * @param int $status_code Optional. The HTTP status code to output. Default null. * @param int $flags Optional. Options to be passed to json_encode(). Default 0. */ -function wp_send_json( $response, $status_code = null, $options = 0 ) { +function wp_send_json( $response, $status_code = null, $flags = 0 ) { if ( wp_is_rest_request() ) { _doing_it_wrong( __FUNCTION__, From 59c8fb131c3c9a450e240ee9205c364a0d467250 Mon Sep 17 00:00:00 2001 From: Felix Arntz Date: Thu, 18 Jan 2024 09:23:02 -0800 Subject: [PATCH 5/9] Remove method_exists() check. --- src/wp-includes/rest-api.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/wp-includes/rest-api.php b/src/wp-includes/rest-api.php index 52d87f4a95475..82e5e8c329597 100644 --- a/src/wp-includes/rest-api.php +++ b/src/wp-includes/rest-api.php @@ -3410,7 +3410,6 @@ function wp_is_rest_endpoint(): bool { if ( ! $is_rest_endpoint ) { // Otherwise, check whether an internal REST request is currently being handled. $is_rest_endpoint = isset( $wp_rest_server ) - && method_exists( $wp_rest_server, 'is_dispatching' ) && $wp_rest_server->is_dispatching(); } From 67c85b7046fd1113edb3aa9293a494058e37d48d Mon Sep 17 00:00:00 2001 From: Felix Arntz Date: Thu, 18 Jan 2024 09:24:41 -0800 Subject: [PATCH 6/9] Rename wp_is_rest_request() to wp_is_serving_rest_request(). --- src/wp-includes/class-wp-query.php | 2 +- src/wp-includes/functions.php | 8 ++++---- src/wp-includes/rest-api.php | 4 ++-- .../endpoints/class-wp-rest-attachments-controller.php | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/wp-includes/class-wp-query.php b/src/wp-includes/class-wp-query.php index 432ac24795a03..f683a52bd1080 100644 --- a/src/wp-includes/class-wp-query.php +++ b/src/wp-includes/class-wp-query.php @@ -1027,7 +1027,7 @@ public function parse_query( $query = '' ) { } if ( ! ( $this->is_singular || $this->is_archive || $this->is_search || $this->is_feed - || ( wp_is_rest_request() && $this->is_main_query() ) + || ( wp_is_serving_rest_request() && $this->is_main_query() ) || $this->is_trackback || $this->is_404 || $this->is_admin || $this->is_robots || $this->is_favicon ) ) { $this->is_home = true; } diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php index edb8854792018..30e92f75098cd 100644 --- a/src/wp-includes/functions.php +++ b/src/wp-includes/functions.php @@ -3718,7 +3718,7 @@ function wp_die( $message = '', $title = '', $args = array() ) { * @param callable $callback Callback function name. */ $callback = apply_filters( 'wp_die_json_handler', '_json_wp_die_handler' ); - } elseif ( wp_is_rest_request() && wp_is_jsonp_request() ) { + } elseif ( wp_is_serving_rest_request() && wp_is_jsonp_request() ) { /** * Filters the callback for killing WordPress execution for JSONP REST requests. * @@ -4441,7 +4441,7 @@ function _wp_json_prepare_data( $value ) { * @param int $flags Optional. Options to be passed to json_encode(). Default 0. */ function wp_send_json( $response, $status_code = null, $flags = 0 ) { - if ( wp_is_rest_request() ) { + if ( wp_is_serving_rest_request() ) { _doing_it_wrong( __FUNCTION__, sprintf( @@ -4698,7 +4698,7 @@ function _mce_set_direction( $mce_init ) { } /** - * Determines whether the current request is a WordPress REST API request. + * Determines whether WordPress is currently serving a REST API request. * * The function relies on the 'REST_REQUEST' global. As such, it only returns true when an actual REST _request_ is * being made. It does not return true when a REST endpoint is hit as part of another request, e.g. for preloading a @@ -4711,7 +4711,7 @@ function _mce_set_direction( $mce_init ) { * * @return bool True if it's a WordPress REST API request, false otherwise. */ -function wp_is_rest_request(): bool { +function wp_is_serving_rest_request(): bool { return defined( 'REST_REQUEST' ) && REST_REQUEST; } diff --git a/src/wp-includes/rest-api.php b/src/wp-includes/rest-api.php index 82e5e8c329597..dfc573c5d8a57 100644 --- a/src/wp-includes/rest-api.php +++ b/src/wp-includes/rest-api.php @@ -209,7 +209,7 @@ function rest_api_register_rewrites() { * @since 4.4.0 */ function rest_api_default_filters() { - if ( wp_is_rest_request() ) { + if ( wp_is_serving_rest_request() ) { // Deprecated reporting. add_action( 'deprecated_function_run', 'rest_handle_deprecated_function', 10, 3 ); add_filter( 'deprecated_function_trigger_error', '__return_false' ); @@ -3406,7 +3406,7 @@ function wp_is_rest_endpoint(): bool { global $wp_rest_server; // Check whether this is a standalone REST request. - $is_rest_endpoint = wp_is_rest_request(); + $is_rest_endpoint = wp_is_serving_rest_request(); if ( ! $is_rest_endpoint ) { // Otherwise, check whether an internal REST request is currently being handled. $is_rest_endpoint = isset( $wp_rest_server ) diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php index 36387d8be646f..c7da6d068b29d 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php @@ -201,7 +201,7 @@ public function create_item( $request ) { wp_after_insert_post( $attachment, false, null ); - if ( wp_is_rest_request() ) { + if ( wp_is_serving_rest_request() ) { /* * Set a custom header with the attachment_id. * Used by the browser/client to resume creating image sub-sizes after a PHP fatal error. @@ -630,7 +630,7 @@ public function edit_media_item( $request ) { update_post_meta( $new_attachment_id, '_wp_attachment_image_alt', wp_slash( $image_alt ) ); } - if ( wp_is_rest_request() ) { + if ( wp_is_serving_rest_request() ) { /* * Set a custom header with the attachment_id. * Used by the browser/client to resume creating image sub-sizes after a PHP fatal error. From 32a27c6e103a8a40f576557e5e8874e768de20dc Mon Sep 17 00:00:00 2001 From: Felix Arntz Date: Thu, 18 Jan 2024 09:44:47 -0800 Subject: [PATCH 7/9] Remove return types. --- src/wp-includes/functions.php | 2 +- src/wp-includes/rest-api.php | 2 +- src/wp-includes/rest-api/class-wp-rest-server.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php index 30e92f75098cd..ff55251d7d760 100644 --- a/src/wp-includes/functions.php +++ b/src/wp-includes/functions.php @@ -4711,7 +4711,7 @@ function _mce_set_direction( $mce_init ) { * * @return bool True if it's a WordPress REST API request, false otherwise. */ -function wp_is_serving_rest_request(): bool { +function wp_is_serving_rest_request() { return defined( 'REST_REQUEST' ) && REST_REQUEST; } diff --git a/src/wp-includes/rest-api.php b/src/wp-includes/rest-api.php index dfc573c5d8a57..2631a6663fe92 100644 --- a/src/wp-includes/rest-api.php +++ b/src/wp-includes/rest-api.php @@ -3401,7 +3401,7 @@ static function ( $status, $error_data ) { * * @return bool True if a REST endpoint request is currently being handled, false otherwise. */ -function wp_is_rest_endpoint(): bool { +function wp_is_rest_endpoint() { /* @var WP_REST_Server $wp_rest_server */ global $wp_rest_server; diff --git a/src/wp-includes/rest-api/class-wp-rest-server.php b/src/wp-includes/rest-api/class-wp-rest-server.php index a807382b186f0..d75c20a8cdd7a 100644 --- a/src/wp-includes/rest-api/class-wp-rest-server.php +++ b/src/wp-includes/rest-api/class-wp-rest-server.php @@ -1067,7 +1067,7 @@ public function dispatch( $request ) { * * @return bool Whether the REST server is currently handling a request. */ - public function is_dispatching(): bool { + public function is_dispatching() { return empty( $this->dispatching_requests ); } From 97ce714c4644619403224649a3cf7d4401295744 Mon Sep 17 00:00:00 2001 From: Felix Arntz Date: Thu, 18 Jan 2024 10:32:17 -0800 Subject: [PATCH 8/9] Add tests and fix critical logic bug. --- .../rest-api/class-wp-rest-server.php | 2 +- .../tests/rest-api/wpIsRestEndpoint.php | 66 +++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 tests/phpunit/tests/rest-api/wpIsRestEndpoint.php diff --git a/src/wp-includes/rest-api/class-wp-rest-server.php b/src/wp-includes/rest-api/class-wp-rest-server.php index d75c20a8cdd7a..ffbd7cfdb1531 100644 --- a/src/wp-includes/rest-api/class-wp-rest-server.php +++ b/src/wp-includes/rest-api/class-wp-rest-server.php @@ -1068,7 +1068,7 @@ public function dispatch( $request ) { * @return bool Whether the REST server is currently handling a request. */ public function is_dispatching() { - return empty( $this->dispatching_requests ); + return ! empty( $this->dispatching_requests ); } /** diff --git a/tests/phpunit/tests/rest-api/wpIsRestEndpoint.php b/tests/phpunit/tests/rest-api/wpIsRestEndpoint.php new file mode 100644 index 0000000000000..b46749310ab7b --- /dev/null +++ b/tests/phpunit/tests/rest-api/wpIsRestEndpoint.php @@ -0,0 +1,66 @@ +assertFalse( wp_is_rest_endpoint() ); + } + + /** + * Tests that `wp_is_rest_endpoint()` relies on whether the global REST server is dispatching. + * + * @ticket 42061 + */ + public function test_wp_is_rest_endpoint_via_global() { + global $wp_rest_server; + + $wp_rest_server = new Spy_REST_Server(); + do_action( 'rest_api_init', $wp_rest_server ); + + // The presence of a REST server itself won't set this to true. + $this->assertFalse( wp_is_rest_endpoint() ); + + // Set up filter to record value during dispatching. + $result_within_request = null; + add_filter( + 'rest_pre_dispatch', + function ( $result ) use ( &$result_within_request ) { + $result_within_request = wp_is_rest_endpoint(); + return $result; + } + ); + + /* + * Dispatch a request (doesn't matter that it's invalid). + * This already is completed after this method call. + */ + $wp_rest_server->dispatch( new WP_REST_Request() ); + + // Within that request, the function should have returned true. + $this->assertTrue( $result_within_request ); + + // After the dispatching, the function should return false again. + $this->assertFalse( wp_is_rest_endpoint() ); + } + + /** + * Tests that `wp_is_rest_endpoint()` returns a result enforced via filter. + * + * @ticket 42061 + */ + public function test_wp_is_rest_endpoint_via_filter() { + add_filter( 'wp_is_rest_endpoint', '__return_true' ); + $this->assertTrue( wp_is_rest_endpoint() ); + } +} From e09b4a0c1d05b9ecd812c2ce0f5a07a300910f5e Mon Sep 17 00:00:00 2001 From: Felix Arntz Date: Fri, 19 Jan 2024 09:24:13 -0800 Subject: [PATCH 9/9] Use bool cast instead of ! empty check. --- src/wp-includes/rest-api/class-wp-rest-server.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/rest-api/class-wp-rest-server.php b/src/wp-includes/rest-api/class-wp-rest-server.php index ffbd7cfdb1531..861f5115e6ae9 100644 --- a/src/wp-includes/rest-api/class-wp-rest-server.php +++ b/src/wp-includes/rest-api/class-wp-rest-server.php @@ -1068,7 +1068,7 @@ public function dispatch( $request ) { * @return bool Whether the REST server is currently handling a request. */ public function is_dispatching() { - return ! empty( $this->dispatching_requests ); + return (bool) $this->dispatching_requests; } /**