/** * Creates a WP_REST_Request and returns it. * * @since 4.4.0 * * @param string $route REST API path to be append to /jetpack/v4/ * @param array $json_params When present, parameters are added to request in JSON format * @param string $method Request method to use, GET or POST * @param array $params Parameters to add to endpoint * * @return WP_REST_Response */ protected function create_and_get_request($route = '', $json_params = array(), $method = 'GET', $params = array()) { $request = new WP_REST_Request($method, "/jetpack/v4/{$route}"); $request->set_header('content-type', 'application/json'); if (!empty($json_params)) { $request->set_body(json_encode($json_params)); } if (!empty($params) && is_array($params)) { foreach ($params as $key => $value) { $request->set_param($key, $value); } } return $this->server->dispatch($request); }
function test_rest_pre_serve_request_headers() { if (!function_exists('xdebug_get_headers')) { $this->markTestSkipped('xdebug is required for this test'); } $post = $this->factory()->post->create_and_get(array('post_title' => 'Hello World')); $request = new WP_REST_Request('GET', '/oembed/1.0/embed'); $request->set_param('url', get_permalink($post->ID)); $request->set_param('format', 'xml'); $server = new WP_REST_Server(); $response = $server->dispatch($request); $output = get_echo('_oembed_rest_pre_serve_request', array(true, $response, $request, $server)); $this->assertNotEmpty($output); $headers = xdebug_get_headers(); $this->assertTrue(in_array('Content-Type: text/xml; charset=' . get_option('blog_charset'), $headers)); }
public function serve_request($path = null) { ob_start(); $result = parent::serve_request($path); $this->sent_body = ob_get_clean(); return $result; }
/** * Test update item. */ function test_delete_item() { wp_set_current_user($this->factory()->user->create(array('role' => 'administrator'))); $post = get_post($this->snapshot_by_status['publish']); $request = new \WP_REST_Request('DELETE', '/wp/v2/customize_snapshots/' . $post->ID); $response = $this->server->dispatch($request); $this->assertErrorResponse('invalid-method', $response); }
/** * Call dispatch() with the rest_post_dispatch filter */ public function dispatch($request) { $result = parent::dispatch($request); $result = rest_ensure_response($result); if (is_wp_error($result)) { $result = $this->error_to_response($result); } return apply_filters('rest_post_dispatch', rest_ensure_response($result), $this, $request); }
/** * Test the rest_pre_serve_request method. */ function test_rest_pre_serve_request_wrong_method() { $post = $this->factory->post->create_and_get(); $request = new WP_REST_Request('HEAD', '/wp/v2/oembed'); $request->set_param('url', get_permalink($post->ID)); $request->set_param('format', 'xml'); $response = $this->server->dispatch($request); $this->assertTrue(_oembed_rest_pre_serve_request(true, $response, $request, $this->server)); }
/** * Test HTTP headers set by the rest_pre_serve_request method. */ function test_rest_pre_serve_request_headers() { if (!function_exists('xdebug_get_headers')) { $this->markTestSkipped('xdebug is required for this test'); } require_once dirname(__FILE__) . '/../vendor/json-rest-api/plugin.php'; require_once dirname(__FILE__) . '/../includes/class-wp-rest-oembed-controller.php'; $user = $this->factory->user->create_and_get(array('display_name' => 'John Doe')); $post = $this->factory->post->create_and_get(array('post_author' => $user->ID, 'post_title' => 'Hello World')); $request = new WP_REST_Request('GET', '/wp/v2/oembed'); $request->set_param('url', get_permalink($post->ID)); $request->set_param('format', 'xml'); $server = new WP_REST_Server(); $response = $server->dispatch($request); ob_start(); _oembed_rest_pre_serve_request(true, $response, $request, $server); $output = ob_get_clean(); $this->assertNotEmpty($output); $headers = xdebug_get_headers(); $this->assertTrue(in_array('Content-Type: text/xml; charset=' . get_option('blog_charset'), $headers)); }
/** * Test endpoint registration * * @since 0.2.0 * * @group rest * @group settings_rest * @group group_rest * @group tracking_rest * @group session_rest * @group variant_rest */ public function test_endpoints() { $the_route = $this->namespaced_route; $routes = $this->server->get_routes(); foreach ($routes as $route => $route_config) { if (0 === strpos($the_route, $route)) { $this->assertTrue(is_array($route_config)); foreach ($route_config as $i => $endpoint) { $this->assertArrayHasKey('callback', $endpoint, get_class($this)); $this->assertArrayHasKey(0, $endpoint['callback'], get_class($this)); $this->assertArrayHasKey(1, $endpoint['callback'], get_class($this)); $this->assertTrue(is_callable(array($endpoint['callback'][0], $endpoint['callback'][1])), get_class($this)); } } } }
/** * Converts a response to data to send. * * @param \WP_REST_Response $response Response object. * @param bool $embed Whether links should be embedded. * * @return array { * Data with sub-requests embedded. * * @type array [$_links] Links. * @type array [$_embedded] Embeddeds. * } */ public function response_to_data($response, $embed) { $data = parent::response_to_data($response, $embed); $server = $this; /** * Filter return value for \CustomizeRESTResources\WP_Customize_REST_Server::response_to_data() * * @param array $data Data. * @param array $args { * Filter args. * * @type \WP_REST_Server $server The server. * @type \WP_REST_Response $response The response. * @type bool $embed Whether to embed. * } */ $data = apply_filters('customize_rest_server_response_data', $data, compact('server', 'response', 'embed')); return $data; }
/** * Test request for a child blog post embed in root blog. * * @group multisite */ function test_request_ms_child_in_root_blog() { if (!is_multisite()) { $this->markTestSkipped(__METHOD__ . ' is a multisite-only test.'); } $child = $this->factory->blog->create(); switch_to_blog($child); $post = $this->factory->post->create_and_get(array('post_title' => 'Hello Child Blog')); $user = $this->factory->user->create_and_get(array('display_name' => 'John Doe')); $post = $this->factory->post->create_and_get(array('post_author' => $user->ID, 'post_title' => 'Hello World')); $request = new WP_REST_Request('GET', '/wp/v2/oembed'); $request->set_param('url', get_permalink($post->ID)); $response = $this->server->dispatch($request); $data = $response->get_data(); $this->assertTrue(is_array($data)); $this->assertArrayHasKey('version', $data); $this->assertArrayHasKey('provider_name', $data); $this->assertArrayHasKey('provider_url', $data); $this->assertArrayHasKey('author_name', $data); $this->assertArrayHasKey('author_url', $data); $this->assertArrayHasKey('title', $data); $this->assertArrayHasKey('type', $data); restore_current_blog(); }
/** * Hooks into the REST API output to print XML instead of JSON. * * This is only done for the oEmbed API endpoint, * which supports both formats. * * @access private * @since 4.4.0 * * @param bool $served Whether the request has already been served. * @param WP_HTTP_ResponseInterface $result Result to send to the client. Usually a WP_REST_Response. * @param WP_REST_Request $request Request used to generate the response. * @param WP_REST_Server $server Server instance. * @return true */ function _oembed_rest_pre_serve_request($served, $result, $request, $server) { $params = $request->get_params(); if ('/oembed/1.0/embed' !== $request->get_route() || 'GET' !== $request->get_method()) { return $served; } if (!isset($params['format']) || 'xml' !== $params['format']) { return $served; } // Embed links inside the request. $data = $server->response_to_data($result, false); if (404 === $result->get_status()) { $data = $data[0]; } if (!class_exists('SimpleXMLElement')) { status_header(501); die(get_status_header_desc(501)); } $result = _oembed_create_xml($data); // Bail if there's no XML. if (!$result) { status_header(501); return get_status_header_desc(501); } if (!headers_sent()) { $server->send_header('Content-Type', 'text/xml; charset=' . get_option('blog_charset')); } echo $result; return true; }
public function test_get_namespaces() { $server = new WP_REST_Server(); $server->register_route('test/example', '/test/example/some-route', array(array('methods' => WP_REST_Server::READABLE, 'callback' => '__return_true'))); $server->register_route('test/another', '/test/another/route', array(array('methods' => WP_REST_Server::READABLE, 'callback' => '__return_false'))); $namespaces = $server->get_namespaces(); $this->assertContains('test/example', $namespaces); $this->assertContains('test/another', $namespaces); }
/** * Attempt to upgrade all Customizer REST API requests to use the edit context. * * @param null|\WP_REST_Response $result Response to replace the requested version with. Can be anything * a normal endpoint can return, or null to not hijack the request. * @param \WP_REST_Server $server Server instance. * @param \WP_REST_Request $request Original request used to generate the response. * @return null|\WP_REST_Response Dispatch result if successful, or null if the upgrade was not possible. */ public function use_edit_context_for_requests($result, \WP_REST_Server $server, \WP_REST_Request $request) { if (null !== $result || 'edit' === $request['context'] || !is_customize_preview()) { return $result; } $edit_request = clone $request; $edit_request['context'] = 'edit'; $edit_result = $server->dispatch($edit_request); if ($edit_result->is_error()) { /* * Return the original $result to prevent the short-circuiting of the * request dispatching since it is found to result in an error, likely * a rest_forbidden_context one. */ return $result; } /* * Now set the context on the original request object to be edit so that * it will match the context that was actually used, and so that the * context will be available in the rest_post_dispatch filter. */ $request['context'] = 'edit'; return $edit_result; }
/** * Prepare a response for inserting into a collection. * * @param WP_REST_Response $response Response object. * @return array Response data, ready for insertion into collection data. */ public function prepare_response_for_collection($response) { if (!$response instanceof WP_REST_Response) { return $response; } $data = (array) $response->get_data(); $links = WP_REST_Server::get_response_links($response); if (!empty($links)) { $data['_links'] = $links; } return $data; }
/** * Hooks into the REST API output to print XML instead of JSON. * * @access private * * @param bool $served Whether the request has already been served. * @param WP_HTTP_ResponseInterface $result Result to send to the client. Usually a WP_REST_Response. * @param WP_REST_Request $request Request used to generate the response. * @param WP_REST_Server $server Server instance. * @return true */ function _oembed_rest_pre_serve_request($served, $result, $request, $server) { $params = $request->get_params(); if ('/wp/v2/oembed' !== $request->get_route() || 'GET' !== $request->get_method()) { return $served; } if (!isset($params['format']) || 'xml' !== $params['format']) { return $served; } // Embed links inside the request. $data = $server->response_to_data($result, false); if (404 === $result->get_status()) { $data = $data[0]; } /** * Filter the XML response. * * @param array $data The original oEmbed response data. */ $result = apply_filters('oembed_xml_response', $data); // Bail if there's no XML. if (!is_string($result)) { status_header(501); die('Not implemented'); } if (!headers_sent()) { $server->send_header('Content-Type', 'text/xml; charset=' . get_option('blog_charset')); } echo $result; return true; }
/** * Sends the "Allow" header to state all methods that can be sent to the current route. * * @since 4.4.0 * * @param WP_REST_Response $response Current response being served. * @param WP_REST_Server $server ResponseHandler instance (usually WP_REST_Server). * @param WP_REST_Request $request The request that was used to make current response. * @return WP_REST_Response Response to be served, with "Allow" header if route has allowed methods. */ function rest_send_allow_header($response, $server, $request) { $matched_route = $response->get_matched_route(); if (!$matched_route) { return $response; } $routes = $server->get_routes(); $allowed_methods = array(); // Get the allowed methods across the routes. foreach ($routes[$matched_route] as $_handler) { foreach ($_handler['methods'] as $handler_method => $value) { if (!empty($_handler['permission_callback'])) { $permission = call_user_func($_handler['permission_callback'], $request); $allowed_methods[$handler_method] = true === $permission; } else { $allowed_methods[$handler_method] = true; } } } // Strip out all the methods that are not allowed (false values). $allowed_methods = array_filter($allowed_methods); if ($allowed_methods) { $response->header('Allow', implode(', ', array_map('strtoupper', array_keys($allowed_methods)))); } return $response; }
/** * Hooks into the REST API output to print XML instead of JSON. * * @param bool $served Whether the request has already been served. * @param WP_HTTP_ResponseInterface $result Result to send to the client. Usually a WP_REST_Response. * @param WP_REST_Request $request Request used to generate the response. * @param WP_REST_Server $server Server instance. * * @return bool */ public function rest_pre_serve_request($served, $result, $request, $server) { $params = $request->get_params(); if ('/wp/v2/oembed' !== $request->get_route() || 'xml' !== $params['format']) { return $served; } if ('HEAD' === $request->get_method()) { return $served; } if (!headers_sent()) { $server->send_header('Content-Type', 'text/xml; charset=' . get_option('blog_charset')); } // Embed links inside the request. $result = $server->response_to_data($result, false); $oembed = new SimpleXMLElement('<oembed></oembed>'); foreach ($result as $key => $value) { if (is_array($value)) { $element = $oembed->addChild($key); foreach ($value as $k => $v) { $element->addChild($k, $v); } continue; } $oembed->addChild($key, $value); } echo $oembed->asXML(); return true; }
/** * If oEmbed request wants XML, return XML instead of JSON. * * Basically a copy of {@link _oembed_rest_pre_serve_request()}. Unfortunate * that we have to duplicate this just for a URL check. * * @since 2.6.0 * * @param bool $served Whether the request has already been served. * @param WP_HTTP_ResponseInterface $result Result to send to the client. Usually a WP_REST_Response. * @param WP_REST_Request $request Request used to generate the response. * @param WP_REST_Server $server Server instance. * @return bool */ public function oembed_xml_request($served, $result, $request, $server) { $params = $request->get_params(); if (!isset($params['format']) || 'xml' !== $params['format']) { return $served; } // Validate URL against our oEmbed endpoint. If not valid, bail. // This is our mod to _oembed_rest_pre_serve_request(). $query_params = $request->get_query_params(); if (false === $this->validate_url_to_item_id($query_params['url'])) { return $served; } // Embed links inside the request. $data = $server->response_to_data($result, false); if (!class_exists('SimpleXMLElement')) { status_header(501); die(get_status_header_desc(501)); } $result = _oembed_create_xml($data); // Bail if there's no XML. if (!$result) { status_header(501); return get_status_header_desc(501); } if (!headers_sent()) { $server->send_header('Content-Type', 'text/xml; charset=' . get_option('blog_charset')); } echo $result; return true; }