Skip to content

Instantly share code, notes, and snippets.

@thefrosty
Last active June 5, 2020 15:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thefrosty/a1a2da38af4d73eeee09cc87ca24ab3b to your computer and use it in GitHub Desktop.
Save thefrosty/a1a2da38af4d73eeee09cc87ca24ab3b to your computer and use it in GitHub Desktop.
Validate REST API requests by slug, and set proper response 404 status when not found.
<?php declare(strict_types=1);
/**
* Get Post By Slug
* @wordpress-plugin
* Plugin Name: Not Found Posts by Slug to 404
* Description: Validate REST API requests by slug, and set proper response 404 status when not found.
* Author: Austin Passy
* Author URI: https://github.com/thefrosty
* Version: 1.0.0
* Requires at least: 5.2
* Tested up to: 5.4.1
* Requires PHP: 7.3
* @package TheFrosty
*/
namespace TheFrosty;
\add_action('rest_api_init', static function (): void {
/**
* Validate the REST request when querying by key: `slug`.
* WordPress returns proper 404's when no ID is found, but not when querying by slug.
* @param \WP_REST_Response $response Result to send to the client. Usually a WP_REST_Response.
* @param \WP_REST_Server $server Server instance.
* @param \WP_REST_Request $request Request used to generate the response.
* @return \WP_REST_Response
*/
\add_filter('rest_post_dispatch', static function (
\WP_REST_Response $response,
\WP_REST_Server $server,
\WP_REST_Request $request
): \WP_REST_Response {
if (\array_key_exists('slug', $request->get_query_params()) &&
!empty($request->get_param('slug')) &&
$request->get_method() === \WP_REST_Server::READABLE &&
empty($response->get_data())
) {
$data = [
'rest_post_invalid_slug',
\esc_html__('Invalid post slug.', 'thefrosty'),
['status' => \WP_Http::NOT_FOUND],
];
try {
// Access the \WP_REST_Server::error_to_response method.
$error_to_response = (new \ReflectionObject($server))->getMethod('error_to_response');
$error_to_response->setAccessible(true);
return $error_to_response->invoke($server, (new \WP_Error(...$data)));
} catch (\ReflectionException $exception) {
return new \WP_REST_Response($data, \WP_Http::NOT_FOUND);
}
}
return $response;
}, 10, 3);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment