Există ceva similar cu is_rest()?
Încep să lucrez puțin cu API-ul REST. Dacă nu mă înșel complet, acțiunea init
este executată și atunci când este o cerere REST API. Acum, vreau să execut unele bucăți de cod doar atunci când nu este o cerere REST API.
Așadar, am căutat o comandă precum is_rest()
pentru a face ceva de genul:
<?php
if( ! is_rest() ) echo 'no-rest-request';
?>
Dar nu am găsit așa ceva. Există vreo funcție is_rest()
?

Este un punct bun menționat de @Milo, constanta REST_REQUEST
este definită ca true
în cadrul funcției rest_api_loaded()
dacă $GLOBALS['wp']->query_vars['rest_route']
nu este gol.
Ea este legată la acțiunea parse_request
prin:
add_action( 'parse_request', 'rest_api_loaded' );
dar parse_request
se declanșează mai târziu decât init
- Vezi de exemplu în Codex aici.
A existat o sugestie (de Daniel Bachhuber) în tichetul #34373 referitoare la WP_Query::is_rest()
, dar a fost amânată/anulată.

#42061 ar putea adăuga wp_is_rest_request()
sau wp_doing_rest()
.

Tocmai am dat peste aceeași problemă și am scris o funcție simplă is_rest
care vă permite să verificați dacă cererea curentă este o cerere către WP REST API.
<?php
if ( !function_exists( 'is_rest' ) ) {
/**
* Verifică dacă cererea curentă este o cerere către WP REST API.
*
* Cazul #1: După inițializarea WP_REST_Request
* Cazul #2: Suportă setările "plain" pentru permalinkuri și verifică dacă `rest_route` începe cu `/`
* Cazul #3: Se poate întâmpla ca WP_Rewrite să nu fie încă inițializat,
* așa că facem acest lucru (wp-settings.php)
* Cazul #4: Calea URL începe cu wp-json/ (prefixul tău REST)
* De asemenea, suportă instalări WP în subfoldere
*
* @return boolean
* @author matzeeable
*/
function is_rest() {
if (defined('REST_REQUEST') && REST_REQUEST // (#1)
|| isset($_GET['rest_route']) // (#2)
&& strpos( $_GET['rest_route'], '/', 0 ) === 0)
return true;
// (#3)
global $wp_rewrite;
if ($wp_rewrite === null) $wp_rewrite = new WP_Rewrite();
// (#4)
$rest_url = wp_parse_url( trailingslashit( rest_url( ) ) );
$current_url = wp_parse_url( add_query_arg( array( ) ) );
return strpos( $current_url['path'] ?? '/', $rest_url['path'], 0 ) === 0;
}
}
Referințe:

Aceasta este cea mai bună funcție pentru WordPress scrisă vreodată pe stackoverflow. A trebuit să o folosesc pentru un hook pre_get_posts
care ignoră cererile REST și a funcționat perfect.

Dacă ai nevoie de această verificare după ce hook-ul init
a fost declanșat:
defined('REST_REQUEST') && REST_REQUEST
Dacă ai nevoie să verifici înainte de init
, există două metode:
Folosește wp_is_json_request()
(introdus în WordPress 5.0), sau încearcă să detectezi dacă este o cerere REST prin URL. Detectarea URL-ului va varia în funcție de faptul dacă site-ul folosește permalink-uri sau permalink-uri simple.
WooCommerce folosește următoarea abordare, care este o soluție bună:
function is_rest_api_request() {
if ( empty( $_SERVER['REQUEST_URI'] ) {
// Probabil o cerere CLI
return false;
}
$rest_prefix = trailingslashit( rest_get_url_prefix() );
$is_rest_api_request = strpos( $_SERVER['REQUEST_URI'], $rest_prefix ) !== false;
return apply_filters( 'is_rest_api_request', $is_rest_api_request );
}

Există două opțiuni aici,
- Verifică dacă
REST_REQUEST
este definit. - Conectează-te la
rest_api_init
unde doreai să te conectezi lainit
.

Pentru a rezolva această problemă, am scris o funcție personalizată simplă bazată pe presupunerea că, dacă URI-ul solicitat se încadrează sub URL-ul API-ului Rest al site-ului WordPress, atunci este o cerere către API-ul Rest.
Dacă este un endpoint valid sau autentificat, nu este sarcina acestei funcții să determine. Întrebarea este: URL-ul este un potențial URL al API-ului Rest?
function isRestUrl() {
$bIsRest = false;
if ( function_exists( 'rest_url' ) && !empty( $_SERVER[ 'REQUEST_URI' ] ) {
$sRestUrlBase = get_rest_url( get_current_blog_id(), '/' );
$sRestPath = trim( parse_url( $sRestUrlBase, PHP_URL_PATH ), '/' );
$sRequestPath = trim( $_SERVER[ 'REQUEST_URI' ], '/' );
$bIsRest = ( strpos( $sRequestPath, $sRestPath ) === 0 );
}
return $bIsRest;
}
Dacă $_SERVER['REQUEST_URI']
nu este populat corect, această funcție va returna tot false
, indiferent de situație.
Nu există hard-coding al URL-ului, așa că dacă din anumite motive schimbați baza URL-ului API-ului, aceasta se va adapta automat.

Poate nu este corect, dar am ajuns la
if (strpos($_SERVER[ 'REQUEST_URI' ], '/wp-json/') !== false) {
// Lucruri interesante cu API aici
}
Nu ezitați să-mi spuneți dacă nu este corect. Încerc să creez un starter pentru pluginuri util pentru a-l împărtăși ulterior: https://gitlab.com/ripp.io/wordpress/plugin-starter

Cred că acest lucru ar eșua dacă nu ai avea permalink-uri frumoase activate.

Ok, necesită permalink-uri frumoase... dar cine nu le-ar vrea?! Aceasta mi se pare cea mai sigură metodă de a face asta. Toate celelalte soluții sunt fanteziste, dar pe termen lung, dacă vrei ca codul tău să funcționeze și în versiunile viitoare de WP... aceasta mi se pare o abordare sigură!!

Cu WordPress 6.5, nucleul oferă o funcție precum wp_is_rest_endpoint
pentru a determina în mod fiabil dacă cererea curentă este una îndreptată către un endpoint REST.
Există și o altă funcție wp_is_serving_rest_request
pentru a verifica dacă o cerere de API REST este de fapt servită. Dacă o folosești, asigură-te să o apelezi după acțiunea parse_request
, deoarece va returna întotdeauna false
înainte de aceasta.

Puteți utiliza wp_is_json_request()
în felul următor:
if ( wp_is_json_request() ) {
// executați acțiunile dorite aici
}
Asigurați-vă că setați antetele Accepts
sau Content-Type
ca application/json
, altfel wp_is_json_request()
va returna false.
Mai multe informații în documentație: https://developer.wordpress.org/reference/functions/wp_is_json_request/
