/** * Handle OPTIONS requests for the server * * This is handled outside of the server code, as it doesn't obey normal route * mapping. * * @param mixed $response Current response, either response or `null` to indicate pass-through. * @param WP_REST_Server $handler 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 Modified response, either response or `null` to indicate pass-through. */ function vp_rest_handle_options_request($response, $handler, $request) { if (!empty($response) || $request->get_method() !== 'OPTIONS') { return $response; } $response = new WP_REST_Response(); $accept = array(); foreach ($handler->get_routes() as $route => $endpoints) { $match = preg_match('@^' . $route . '$@i', $request->get_route(), $args); if (!$match) { continue; } foreach ($endpoints as $endpoint) { $accept = array_merge($accept, $endpoint['methods']); } break; } $accept = array_keys($accept); $response->header('Accept', implode(', ', $accept)); return $response; }
/** * Match the request to a callback and call it * * @param WP_REST_Request $request Request to attempt dispatching * @return WP_REST_Response Response returned by the callback */ public function dispatch($request) { $method = $request->get_method(); $path = $request->get_route(); foreach ($this->get_routes() as $route => $handlers) { foreach ($handlers as $handler) { $callback = $handler['callback']; $supported = $handler['methods']; $response = null; if (empty($handler['methods'][$method])) { continue; } $match = preg_match('@^' . $route . '$@i', $path, $args); if (!$match) { continue; } if (!is_callable($callback)) { $response = new WP_Error('vp_rest_invalid_handler', __('The handler for the route is invalid'), array('status' => 500)); } if (!is_wp_error($response)) { $request->set_url_params($args); $request->set_attributes($handler); $request->sanitize_params(); $defaults = array(); foreach ($handler['args'] as $arg => $options) { if (isset($options['default'])) { $defaults[$arg] = $options['default']; } } $request->set_default_params($defaults); $check_required = $request->has_valid_params(); if (is_wp_error($check_required)) { $response = $check_required; } } if (!is_wp_error($response)) { // check permission specified on the route. if (!empty($handler['permission_callback'])) { $permission = call_user_func($handler['permission_callback'], $request); if (is_wp_error($permission)) { $response = $permission; } else { if (false === $permission || null === $permission) { $response = new WP_Error('vp_rest_forbidden', __("You don't have permission to do this."), array('status' => 403)); } } } } if (!is_wp_error($response)) { /** * Allow plugins to override dispatching the request * * @param boolean $dispatch_result Dispatch result, will be used if not empty * @param WP_REST_Request $request */ $dispatch_result = apply_filters('vp_rest_dispatch_request', null, $request); // Allow plugins to halt the request via this filter if (null !== $dispatch_result) { $response = $dispatch_result; } else { $response = call_user_func($callback, $request); } } if (is_wp_error($response)) { $response = $this->error_to_response($response); } else { $response = vp_rest_ensure_response($response); } $response->set_matched_route($route); $response->set_matched_handler($handler); return $response; } } return $this->error_to_response(new WP_Error('vp_rest_no_route', __('No route was found matching the URL and request method'), array('status' => 404))); }