Esiste qualcosa come is_rest ()


17

Sto iniziando un po 'con l'API REST. Se non sono completamente fuorviante, l' inithook dell'azione viene eseguito anche quando si tratta di una richiesta API REST. Ora, voglio eseguire solo un po 'di codice, quando non è una richiesta API REST.

Quindi stavo cercando un comando come is_rest()per fare qualcosa del genere

<?php
if( ! is_rest() ) echo 'no-rest-request';
?>

Ma non sono riuscito a trovare qualcosa del genere. C'è un is_rest()là fuori?


1
Forse puoi approfondire cosa vuoi fare quando non è una richiesta REST? Il tipo di richiesta non viene determinato fino all'analisi della query, che si verifica dopo init. Si noti inoltre che le parti dell'API possono essere utilizzate internamente su richieste che non sono richieste REST, quindi si rischia di interrompere qualcosa se si fa affidamento su tale rilevamento.
Milo,

Grazie mille ad entrambi. @birgire: puoi pubblicare questo come risposta, così posso verificarlo. Fondamentalmente, è la risposta alla mia domanda :)
websupporter

Risposte:


14

È un buon punto di @Milo, la REST_REQUESTcostante è definita come true, all'interno rest_api_loaded()se $GLOBALS['wp']->query_vars['rest_route']non è vuota.

E ' agganciato in parse_requestvia:

add_action( 'parse_request', 'rest_api_loaded' );

ma parse_requestspara più tardi di init- Vedi ad esempio il Codice qui .

C'era un suggerimento (da Daniel Bachhuber) nel biglietto # 34373 riguardo WP_Query::is_rest(), ma è stata rinviata / annullata.


11

Mi sono appena imbattuto nello stesso problema e ho scritto una semplice funzione is_restche ti consente di verificare se la richiesta corrente è una richiesta API REST WP.

<?php
if ( !function_exists( 'is_rest' ) ) {
    /**
     * Checks if the current request is a WP REST API request.
     *
     * Case #1: After WP_REST_Request initialisation
     * Case #2: Support "plain" permalink settings
     * Case #3: It can happen that WP_Rewrite is not yet initialized,
     *          so do this (wp-settings.php)
     * Case #4: URL Path begins with wp-json/ (your REST prefix)
     *          Also supports WP installations in subfolders
     *
     * @returns boolean
     * @author matzeeable
     */
    function is_rest() {
        $prefix = rest_get_url_prefix( );
        if (defined('REST_REQUEST') && REST_REQUEST // (#1)
                || isset($_GET['rest_route']) // (#2)
                        && strpos( trim( $_GET['rest_route'], '\\/' ), $prefix , 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;
    }
}

Riferimenti:


4

Per risolvere questo problema ho scritto una semplice funzione personalizzata basata sul presupposto che se l'URI richiesto rientra nell'URL dell'API Rest del sito WordPress, ne consegue che si tratta di una richiesta API Rest.

Che si tratti di un endpoint valido o autenticato, non è possibile determinare questa funzione. La domanda è questa: l'URL è un potenziale URL dell'API di riposo?

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;
}

Se il tuo $_SERVER['REQUEST_URI']non è correttamente popolato, questa funzione tornerà comunque false, indipendentemente.

Non esiste un hard coding dell'URL, quindi se per qualche motivo modifichi la tua base URL API, questo si adatterà.


3

Forse non è giusto, ma ho finito con

if (strpos($_SERVER[ 'REQUEST_URI' ], '/wp-json/') !== false) {
    // Cool API stuff here
}

Sentiti libero di farmi sapere se questo non è giusto. Cercando di creare un utile avviatore di plugin da condividere alla fine: https://gitlab.com/ripp.io/wordpress/plugin-starter


1
Penso che questo fallirebbe, se non avessi abbastanza permalink attivi.
websupporter il

Hai assolutamente ragione
Charly, l'

Ok richiede abbastanza permalink ... ma chi non lo vuole !!!? Questo mi sembra il modo più sicuro per farlo. Tutte le altre soluzioni sono fantasiose ma nel tempo se vuoi che il tuo codice sia ancora in esecuzione su versioni successive di wp ... questo mi sembra un modo sicuro !!
Antony Gibbs,

1

Due opzioni qui davvero,

  1. Controlla se REST_REQUESTè definito.
  2. Aggancia rest_api_initdove volevi agganciare init.

0

Ecco cosa mi è venuto in mente:

/**
 * Determines if the current request we are handling is a REST Request.
 * This function can be called even on mu-plugins.
 *
 * You might want to prefix this function name with
 * something more unique to your project.
 *
 * @return bool
 */
function is_rest(): bool {
    $is_cli              = php_sapi_name() === 'cli';
    $permalink_structure = get_option( 'permalink_structure' );
    $rest_prefix         = rest_get_url_prefix();

    if ( ! empty( $permalink_structure ) && ! $is_cli ) {
        /*
         * HTTP request with Pretty Permalinks.
         */
        if ( substr( $_SERVER['REQUEST_URI'], 0, strlen( $rest_prefix ) ) === $rest_prefix ) {
            return true;
        }
    } elseif ( empty( $permalink_structure ) && ! $is_cli ) {
        /*
         * HTTP Requests with Plain Permalinks
         *
         * We can rely on "?rest_route" for plain permalinks, this value don't change:
         * wp/wp-includes/rest-api.php:145
         *
         * All ?rest_route must start with "/":
         * wp/wp-includes/rest-api.php:159
         */
        if ( isset( $_GET['rest_route'] ) && substr( $_GET['rest_route'], 0, 1 ) === '/' ) {
            return true;
        }
    } elseif ( $is_cli ) {
        /*
         * CLI request
         */
        if ( did_action( 'parse_request' ) ) {
            return defined( 'REST_REQUEST' ) && REST_REQUEST;
        } else {
            throw new RuntimeException( "Maybe someone at StackOverflow can help fill this gap of identifying REST requests on CLI before the parse_request action has fired and the REST_REQUEST constant is available?" );
        }
    }

    return false;
}

parse_requestTuttavia, non ho avuto molto tempo per fare in modo che la CLI rilevi le richieste REST prima che l' azione sia stata attivata. Sono aperto ai suggerimenti!

Devo ancora scrivere alcuni test su questa funzione, aggiornerò questa risposta una volta fatto.

-- Modificare

Ho appena scoperto come WooCommerce gestisce questo. WooCommerce non sembra spiegare i permalink semplici:

public function is_rest_api_request() {
    if ( empty( $_SERVER['REQUEST_URI'] ) ) {
        return false;
    }

    $rest_prefix         = trailingslashit( rest_get_url_prefix() );
    $is_rest_api_request = ( false !== strpos( $_SERVER['REQUEST_URI'], $rest_prefix ) );

    return apply_filters( 'woocommerce_is_rest_api_request', $is_rest_api_request );
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.