API REST de WP -- ¿Cómo cambiar el código de estado de respuesta HTTP?
Tengo un endpoint personalizado donde quiero cambiar el estado de respuesta HTTP a 404 en ciertos escenarios (por ejemplo, cuando el post no existe). ¿Cómo puedo hacer eso? Aquí hay un ejemplo del endpoint personalizado:
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 { /* ¿Cómo cambiar el código de respuesta? */ }
return [ 'data' => $news ];
}
¿Cómo puedo cambiar el código de respuesta en esta función?

Puedes devolver un objeto WP_Error
donde defines el código de estado. Aquí hay un fragmento de la documentación de la API REST:
function my_awesome_func( $data ) {
$posts = get_posts( array(
'author' => $data['id'],
) );
if ( empty( $posts ) ) {
return new WP_Error( 'awesome_no_author', 'Autor inválido', array( 'status' => 404 ) );
}
return $posts[0]->post_title;
}
En tu caso podrías hacer algo como:
return new WP_Error( 'page_does_not_exist', __('La página que buscas no existe'), array( 'status' => 404 ) );

La forma más sencilla es hacer esto:
return new WP_REST_Response(null, 404);
Nota: esto sigue siendo una respuesta JSON que contiene null
como cuerpo. Puedes devolver una estructura de datos más útil con códigos de error/mensajes, etc., o conectar los filtros de salida REST para mostrar una respuesta en blanco con text/plain
.

No usaría:
return new WP_REST_Response(null, 404);
Tuve un problema con el proveedor de hosting cuando usé códigos de estado en esta función. De alguna manera, establecer el código de estado activó una respuesta de mod_rewrite.
Mensaje: Acceso denegado con código 406 (fase 3). La prueba 'REQUEST_URI|REQUEST_HEADERS|REQUEST_HEADERS_NAMES|ARGS|ARGS_NAMES|REQUEST_BODY' contra '!@validateByteRange 0-31' es verdadera.
Puede que no sea un problema con WordPress, pero usar:
return new WP_REST_Response(null);
resolvió el problema.
Lo dejo aquí por si alguien se encuentra con el mismo problema.
