Existe-t-il quelque chose comme is_rest ()


18

Je commence un peu avec l'API REST. Si je ne suis pas complètement trompé, le inithook d'action est également exécuté lorsqu'il s'agit d'une demande d'API REST. Maintenant, je veux exécuter du code uniquement, lorsqu'il ne s'agit pas d'une demande d'API REST.

Je cherchais donc une commande comme is_rest()pour faire quelque chose comme

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

Mais je n'ai pas pu trouver quelque chose comme ça. Y en a-t-il is_rest()là-bas?


1
Peut-être pouvez-vous expliquer ce que vous voulez faire quand ce n'est pas une demande REST? Le type de demande n'est pas déterminé jusqu'à l'analyse de la requête, qui se produit après init. Notez également que les parties de l'API peuvent être utilisées en interne sur des requêtes qui ne sont pas des requêtes REST, vous risquez donc de casser quelque chose si vous comptez sur cette détection.
Milo

Merci beaucoup à vous deux. @birgire: Pouvez-vous poster ceci comme réponse, donc je peux le vérifier. Fondamentalement, c'est la réponse à ma question :)
Websupporter

Réponses:


14

C'est un bon point par @Milo, la REST_REQUESTconstante est définie comme true, à l'intérieur rest_api_loaded()si $GLOBALS['wp']->query_vars['rest_route']est non vide.

Il est accroché dans parse_requestvia:

add_action( 'parse_request', 'rest_api_loaded' );

mais parse_requesttire plus tard que init- Voir par exemple le Codex ici .

Il y avait une suggestion (par Daniel Bachhuber) dans le ticket # 34373 concernant WP_Query::is_rest(), mais elle a été reportée / annulée.


11

Je suis juste tombé sur le même problème et j'ai écrit une fonction simple is_restqui vous permet de vérifier si la demande actuelle est une demande d'API WP REST.

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

Les références:


4

Pour résoudre ce problème, j'ai écrit une fonction personnalisée simple basée sur l'hypothèse que si l'URI demandée tombe sous l'URL Rest API du site WordPress, il s'ensuit qu'il s'agit d'une requête API Rest.

Qu'il s'agisse d'un point de terminaison valide ou authentifié, ce n'est pas à cette fonction de le déterminer. La question est la suivante: l'URL est-elle une URL potentielle de l'API 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;
}

Si votre $_SERVER['REQUEST_URI']n'est pas correctement renseigné, cette fonction reviendra falsequand même.

Il n'y a pas de codage en dur de l'URL, donc si pour une raison quelconque vous changez la base de votre URL API, cela s'adaptera.


3

Peut-être pas bien, mais je me suis retrouvé avec

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

N'hésitez pas à me faire savoir si ce n'est pas bien. Essayer de créer un plugin utile pour éventuellement partager: https://gitlab.com/ripp.io/wordpress/plugin-starter


1
Je pense que cela échouerait si vous n'aviez pas de jolis permaliens actifs.
Websupporter

Vous avez certainement raison
Charly

Ok ça nécessite un joli permalien ... mais qui n'en veut pas !!!? Cela me semble le moyen le plus sûr de le faire. Toutes les autres solutions sont fantaisistes mais au fil du temps si vous voulez que votre code continue de fonctionner sur les versions wp ultérieures ... cela me semble un moyen sûr !!
Antony Gibbs

1

Deux options ici vraiment,

  1. Vérifiez si REST_REQUESTest défini.
  2. Accrochez- rest_api_initvous là où vous vouliez vous connecter init.

0

Voici ce que j'ai trouvé:

/**
 * 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_requestCependant, je n'ai pas eu beaucoup de temps pour faire en sorte que CLI détecte les demandes REST avant que l' action ne se déclenche. Je suis ouvert aux suggestions!

Je n'ai pas encore écrit de tests sur cette fonctionnalité, je mettrai à jour cette réponse une fois que je le ferai.

-- Éditer

Je viens de découvrir comment WooCommerce gère cela. WooCommerce ne semble pas prendre en compte les permaliens simples:

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 );
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.