From cf7401dd73402d1311b9873a81fc1f1dbfd54c9a Mon Sep 17 00:00:00 2001
From: Matthew Reishus <mreishus@users.noreply.github.com>
Date: Thu, 12 Jan 2023 13:08:54 -0600
Subject: [PATCH] respond_to_request: store matched handlers across other
methods
---
src/wp-includes/rest-api.php | 8 ++++--
.../rest-api/class-wp-rest-response.php | 27 +++++++++++++++++++
.../rest-api/class-wp-rest-server.php | 20 +++++++-------
3 files changed, 44 insertions(+), 11 deletions(-)
diff --git a/src/wp-includes/rest-api.php b/src/wp-includes/rest-api.php
index 9898501cba..d7af8aec84 100644
|
a
|
b
|
function rest_send_allow_header( $response, $server, $request ) {
|
| 808 | 808 | return $response; |
| 809 | 809 | } |
| 810 | 810 | |
| 811 | | $routes = $server->get_routes(); |
| | 811 | $all_handlers = $response->get_all_methods_matched_handlers(); |
| | 812 | if ( empty( $all_handlers ) ) { |
| | 813 | $routes = $server->get_routes(); |
| | 814 | $all_handlers = $routes[ $matched_route ]; |
| | 815 | } |
| 812 | 816 | |
| 813 | 817 | $allowed_methods = array(); |
| 814 | 818 | |
| 815 | 819 | // Get the allowed methods across the routes. |
| 816 | | foreach ( $routes[ $matched_route ] as $_handler ) { |
| | 820 | foreach ( $all_handlers as $_handler ) { |
| 817 | 821 | foreach ( $_handler['methods'] as $handler_method => $value ) { |
| 818 | 822 | |
| 819 | 823 | if ( ! empty( $_handler['permission_callback'] ) ) { |
diff --git a/src/wp-includes/rest-api/class-wp-rest-response.php b/src/wp-includes/rest-api/class-wp-rest-response.php
index c6ea11be83..0c90f98ca5 100644
|
a
|
b
|
class WP_REST_Response extends WP_HTTP_Response {
|
| 40 | 40 | */ |
| 41 | 41 | protected $matched_handler = null; |
| 42 | 42 | |
| | 43 | /** |
| | 44 | * All handlers that match the request, even if the method doesn't match. |
| | 45 | * For example, this could include both GET and POST handlers for a route. |
| | 46 | * Used when calculating the Allow header. |
| | 47 | * |
| | 48 | * @var null|array |
| | 49 | */ |
| | 50 | protected $all_methods_matched_handlers = null; |
| | 51 | |
| 43 | 52 | /** |
| 44 | 53 | * Adds a link to the response. |
| 45 | 54 | * |
| … |
… |
class WP_REST_Response extends WP_HTTP_Response {
|
| 204 | 213 | $this->matched_handler = $handler; |
| 205 | 214 | } |
| 206 | 215 | |
| | 216 | /** |
| | 217 | * Retrieves all possible handlers that match the route, even for other HTTP methods. |
| | 218 | * |
| | 219 | * @return null|array Handlers that could be used to |
| | 220 | */ |
| | 221 | public function get_all_methods_matched_handlers() { |
| | 222 | return $this->all_methods_matched_handlers; |
| | 223 | } |
| | 224 | |
| | 225 | /** |
| | 226 | * Sets all possible handlers that match the route. |
| | 227 | * |
| | 228 | * @param array $handlers An array of handlers matching the route across all HTTP methods. |
| | 229 | */ |
| | 230 | public function set_all_methods_matched_handlers( $handlers ) { |
| | 231 | $this->all_methods_matched_handlers = $handlers; |
| | 232 | } |
| | 233 | |
| 207 | 234 | /** |
| 208 | 235 | * Checks if the response is an error, i.e. >= 400 response code. |
| 209 | 236 | * |
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 00c34cd621..b8b8d216ad 100644
|
a
|
b
|
class WP_REST_Server {
|
| 994 | 994 | return $this->error_to_response( $matched ); |
| 995 | 995 | } |
| 996 | 996 | |
| 997 | | list( $route, $handler ) = $matched; |
| | 997 | list( $route, $handler, $handlers_all_methods ) = $matched; |
| 998 | 998 | |
| 999 | 999 | if ( ! is_callable( $handler['callback'] ) ) { |
| 1000 | 1000 | $error = new WP_Error( |
| … |
… |
class WP_REST_Server {
|
| 1016 | 1016 | } |
| 1017 | 1017 | } |
| 1018 | 1018 | |
| 1019 | | return $this->respond_to_request( $request, $route, $handler, $error ); |
| | 1019 | return $this->respond_to_request( $request, $route, $handler, $error, $handlers_all_methods ); |
| 1020 | 1020 | } |
| 1021 | 1021 | |
| 1022 | 1022 | /** |
| … |
… |
class WP_REST_Server {
|
| 1075 | 1075 | } |
| 1076 | 1076 | |
| 1077 | 1077 | if ( ! is_callable( $callback ) ) { |
| 1078 | | return array( $route, $handler ); |
| | 1078 | return array( $route, $handler, $handlers ); |
| 1079 | 1079 | } |
| 1080 | 1080 | |
| 1081 | 1081 | $request->set_url_params( $args ); |
| … |
… |
class WP_REST_Server {
|
| 1091 | 1091 | |
| 1092 | 1092 | $request->set_default_params( $defaults ); |
| 1093 | 1093 | |
| 1094 | | return array( $route, $handler ); |
| | 1094 | return array( $route, $handler, $handlers ); |
| 1095 | 1095 | } |
| 1096 | 1096 | } |
| 1097 | 1097 | |
| … |
… |
class WP_REST_Server {
|
| 1108 | 1108 | * @access private |
| 1109 | 1109 | * @since 5.6.0 |
| 1110 | 1110 | * |
| 1111 | | * @param WP_REST_Request $request The request object. |
| 1112 | | * @param string $route The matched route regex. |
| 1113 | | * @param array $handler The matched route handler. |
| 1114 | | * @param WP_Error|null $response The current error object if any. |
| | 1111 | * @param WP_REST_Request $request The request object. |
| | 1112 | * @param string $route The matched route regex. |
| | 1113 | * @param array $handler The matched route handler. |
| | 1114 | * @param WP_Error|null $response The current error object if any. |
| | 1115 | * @param array $all_methods_handlers The matched route handlers including other methods. |
| 1115 | 1116 | * @return WP_REST_Response |
| 1116 | 1117 | */ |
| 1117 | | protected function respond_to_request( $request, $route, $handler, $response ) { |
| | 1118 | protected function respond_to_request( $request, $route, $handler, $response, $all_methods_handlers ) { |
| 1118 | 1119 | /** |
| 1119 | 1120 | * Filters the response before executing any REST API callbacks. |
| 1120 | 1121 | * |
| … |
… |
class WP_REST_Server {
|
| 1204 | 1205 | |
| 1205 | 1206 | $response->set_matched_route( $route ); |
| 1206 | 1207 | $response->set_matched_handler( $handler ); |
| | 1208 | $response->set_all_methods_matched_handlers( $all_methods_handlers ); |
| 1207 | 1209 | |
| 1208 | 1210 | return $response; |
| 1209 | 1211 | } |