Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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
You can’t perform that action at this time.