WP REST API -- Как изменить код статуса HTTP-ответа?
У меня есть пользовательская конечная точка, где я хочу изменить статус HTTP-ответа на 404 в определенных сценариях (например, когда пост не существует). Как это можно сделать? Вот пример пользовательской конечной точки:
function af_news_single( \WP_REST_Request $data ) {
global $wpdb;
$year = (int) $data['year'];
$month = (int) $data['month'];
$day = (int) $data['day'];
$slug = $data['slug'];
$date = "{$year}-{$month}-{$day}";
$news = $wpdb->get_row(
$wpdb->prepare(
"SELECT
DATE_FORMAT(post_date, %s) as `post_date`,
`post_title`,
`post_name`,
`post_content`
FROM {$wpdb->posts}
WHERE
`post_status` = 'publish' AND
`post_type` = 'post' AND
`post_name` = %s AND
`post_date` BETWEEN %s AND %s + INTERVAL 1 DAY
LIMIT 1
", '%Y-%m-%dT%TZ', $slug, $date, $date
)
);
if ( $news ) {
$news->post_title = qtranxf_translate( $news->post_title );
$news->post_content = wpautop( qtranxf_translate( $news->post_content ) );
} else { /* Как изменить код ответа? */ }
return [ 'data' => $news ];
}
Как я могу изменить код ответа в этой функции?

Вы можете вернуть объект WP_Error
, в котором определите код состояния. Вот пример из документации REST API:
function my_awesome_func( $data ) {
$posts = get_posts( array(
'author' => $data['id'],
) );
if ( empty( $posts ) ) {
return new WP_Error( 'awesome_no_author', 'Неверный автор', array( 'status' => 404 ) );
}
return $posts[0]->post_title;
}
В вашем случае можно сделать так:
return new WP_Error( 'page_does_not_exist', __('Страница, которую вы ищете, не существует'), array( 'status' => 404 ) );

Самый простой способ сделать это:
return new WP_REST_Response(null, 404);
Примечание: это всё ещё JSON-ответ с телом, содержащим null
. Вы можете вернуть более полезную структуру данных с кодами ошибок, сообщениями и т.д., или использовать фильтры вывода REST, чтобы вернуть пустой ответ в формате text/plain
.

Я бы не использовал:
return new WP_REST_Response(null, 404);
У меня возникла проблема с хостинг-провайдером, когда я использовал коды статуса в этой функции. По какой-то причине установка кода статуса вызывала ответ mod_rewrite.
Message: Access denied with code 406 (phase 3). Test 'REQUEST_URI|REQUEST_HEADERS|REQUEST_HEADERS_NAMES|ARGS|ARGS_NAMES|REQUEST_BODY' against '!@validateByteRange 0-31' is true.
Возможно, это не проблема WordPress, но использование:
return new WP_REST_Response(null);
решило проблему.
Оставлю это здесь на случай, если кто-то столкнётся с такой же проблемой.
