diff --git a/src/wp-includes/rest-api.php b/src/wp-includes/rest-api.php index 2c0e8f7e18..5cd7ef8774 100644 --- a/src/wp-includes/rest-api.php +++ b/src/wp-includes/rest-api.php @@ -1311,3 +1311,56 @@ function rest_sanitize_value_from_schema( $value, $args ) { return $value; } + +/** + * Append result of internal request to REST API for purpose of preloading data to be attached to a page. + * Expected to be called in the context of `array_reduce`. + * + * @since 5.0.0 + * + * @param array $memo Reduce accumulator. + * @param string $path REST API path to preload. + * @return array Modified reduce accumulator. + */ +function rest_preload_api_request( $memo, $path ) { + // array_reduce() doesn't support passing an array in PHP 5.2, so we need to make sure we start with one. + if ( ! is_array( $memo ) ) { + $memo = array(); + } + + if ( empty( $path ) ) { + return $memo; + } + + $path_parts = parse_url( $path ); + if ( false === $path_parts ) { + return $memo; + } + + $request = new WP_REST_Request( 'GET', $path_parts['path'] ); + if ( ! empty( $path_parts['query'] ) ) { + parse_str( $path_parts['query'], $query_params ); + $request->set_query_params( $query_params ); + } + + $response = rest_do_request( $request ); + if ( 200 === $response->status ) { + $server = rest_get_server(); + $data = (array) $response->get_data(); + if ( method_exists( $server, 'get_compact_response_links' ) ) { + $links = call_user_func( array( $server, 'get_compact_response_links' ), $response ); + } else { + $links = call_user_func( array( $server, 'get_response_links' ), $response ); + } + if ( ! empty( $links ) ) { + $data['_links'] = $links; + } + + $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 52c30dc471..d20566e15e 100644 --- a/tests/phpunit/tests/rest-api.php +++ b/tests/phpunit/tests/rest-api.php @@ -712,4 +712,13 @@ class Tests_REST_API extends WP_UnitTestCase { $routes = $GLOBALS['wp_rest_server']->get_routes(); $this->assertEquals( $routes['/test-ns/test'][0]['methods'], array( 'GET' => true ) ); } + + /** + * Ensure rest_preload_api_request() works without notices in PHP 5.2. + * + * The array_reduce() function only accepts mixed variables starting with PHP 5.3. + */ + function test_rest_preload_api_request_no_notices_php_52() { + $this->assertTrue( is_array( rest_preload_api_request( 0, '/' ) ) ); + } }