I am starting a bit with the REST API. If I am not completly mislead, the init action hook is also executed when its a REST API request. Now, I want to execute some code only, when it is not a REST API request.
So I was looking for a command like is_rest() in order to do something like
<?php if( ! is_rest() ) echo 'no-rest-request'; ?>
But I couldn’t find something like this. Is there a is_rest() out there?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
It’s a good point by @Milo, the REST_REQUEST constant is defined as true, within rest_api_loaded() if $GLOBALS['wp']->query_vars['rest_route'] is non-empty.
It’s hooked into parse_request via:
add_action( 'parse_request', 'rest_api_loaded' );
but parse_request fires later than init – See for example the Codex here.
There was a suggestion (by Daniel Bachhuber) in ticket #34373 regarding WP_Query::is_rest(), but it was postponed/cancelled.
Method 2
Just stumbled over the same problem and wrote a simple function is_rest that allows you to check if the current request is a WP REST API request.
<?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 and check if `rest_route` starts with `/`
* 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() {
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;
}
}
References:
- https://gist.github.com/matzeeable/dfd82239f48c2fedef25141e48c8dc30
- https://twitter.com/matzeeable/status/1052967482737258496
Method 3
Two options here really,
- Check if
REST_REQUESTis defined. - Hook into
rest_api_initwhere you wanted to hook intoinit.
Method 4
If you need it after init has fired:
defined('REST_REQUEST') && REST_REQUEST
If you need it before init, there are two ways:
Use wp_is_json_request(), or try to infer if it’s a REST Request through the URL. Detecting the URL will vary whether the site is using permalinks or plain permalinks.
WooCommerce does it like this, and it’s a good solution:
function is_rest_api_request() {
if ( empty( $_SERVER['REQUEST_URI'] ) ) {
// Probably a CLI request
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 );
}
Method 5
To solve this problem I wrote a simple custom function based on the assumption that if the URI being requested falls under the WordPress site’s Rest API URL, then it follows that it’s a Rest API request.
Whether it’s a valid endpoint, or authenticated, is not for this function to determine. The question is this: is the URL a potential Rest API url?
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;
}
If your $_SERVER['REQUEST_URI'] isn’t properly populated, this function will still return false, regardless.
There is no hard-coding of the URL so if you for some reason change your API URL base, this will adapt.
Method 6
Maybe not right, but I ended up with
if (strpos($_SERVER[ 'REQUEST_URI' ], '/wp-json/') !== false) {
// Cool API stuff here
}
Feel free to let me know if this isn’t right. Trying to make a helpful plugin starter to eventually share: https://gitlab.com/ripp.io/wordpress/plugin-starter
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0