Чи існує щось на зразок is_rest ()


18

Починаю трохи з API REST. Якщо мене не вводять в оману, initгак дії також виконується, коли його REST API-запит. Тепер я хочу виконати якийсь код лише тоді, коли це не запит REST API.

Тому я шукав таку команду is_rest(), щоб зробити щось подібне

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

Але я не могла знайти щось подібне. Є is_rest()там?


1
Можливо, ви можете детальніше розібратися, що ви хочете зробити, коли це не REST-запит? Тип запиту не визначається до розбору запитів, що відбувається після init. Також зауважте, що частини API можна використовувати внутрішньо для запитів, які не є REST-запитами, тому ви ризикуєте щось зламати, якщо ви покладаєтесь на це виявлення.
Міло,

Дякую вам обом. @birgire: Чи можете ви опублікувати це як відповідь, щоб я міг це перевірити. В основному, це відповідь на моє запитання :)
websupporter

Відповіді:


14

Це хороша точка від @Milo, REST_REQUESTконстанта визначається як true, у межах, rest_api_loaded()якщо $GLOBALS['wp']->query_vars['rest_route']вона не порожня.

Він зачепив в parse_requestчерез:

add_action( 'parse_request', 'rest_api_loaded' );

але parse_requestпожежі пізніше init- Дивіться, наприклад, Кодекс тут .

У квитку 34373 була пропозиція (Даніель Бахубер) щодо WP_Query::is_rest(), але її було відкладено / скасовано.


# 42061 може додати wp_is_rest_request()або wp_doing_rest().
Ян Данн

11

Просто наткнувся на ту ж проблему і написав просту функцію, is_restяка дозволяє перевірити, чи поточний запит є WP REST API-запитом.

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

Список літератури:


4

Щоб вирішити цю проблему, я написав просту функцію користувача, засновану на припущенні, що якщо запитуваний URI потрапляє під URL-адресу API відпочинку WordPress, то випливає, що це запит API відпочинку.

Чи це дійсна кінцева точка, чи автентифікація, ця функція не визначає. Питання таке: чи URL-адреса є потенційним URL-адресою API відпочинку?

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

Якщо ваш $_SERVER['REQUEST_URI']неправильно заселений, ця функція все одно повернеться false, незалежно.

Немає жорсткого кодування URL-адреси, тому якщо ви з якихось причин зміните свою базу URL-адрес API, вона адаптується.


3

Можливо, не так, але я закінчив

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

Сміливо повідомте мене, якщо це неправильно. Намагаючись зробити корисний запуск плагіну, щоб згодом поділитися: https://gitlab.com/ripp.io/wordpress/plugin-starter


1
Я думаю, це не вдасться, якби у вас не було активних постійних посилань.
прихильник

Ви напевно правильні
Чарлі

Гаразд, це вимагає досить постійної посилання ... але хто цього не хоче !!!? Це мені здається найбезпечнішим способом це зробити. Всі інші рішення фантазії, але з часом, якщо ви хочете, щоб ваш код все ще працював на пізніших версіях wp ... це здається мені безпечним способом !!
Антоні Гіббс

1

Тут дійсно два варіанти,

  1. Перевірте, чи REST_REQUESTвизначено.
  2. Зачепити rest_api_initтуди, куди ти хотів зачепитись init.

0

Ось що я придумав:

/**
 * 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_requestОднак у мене не було багато часу, щоб розібратися з тим, щоб CLI виявляв REST-запити до початку дії. Я відкритий для пропозицій!

Я ще мушу написати кілька тестів навколо цієї функції, я оновлю цю відповідь, як тільки це зробити.

- Редагувати

Щойно з’ясували, як WooCommerce справляється з цим. Схоже, WooCommerce не враховує звичайні посилання:

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 );
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.