Skip to Content

is_available()

Check if a remote URL is online or down.

PHP March 30, 2021

Usage

PHP
nebula()->is_available($url, $nocache, $lookup_only, $args)

Parameters

$url
(Required) (String) The URL to check
Default: None

$allow_cache
(Optional) (Boolean) Whether to bypass the cache
Default: true

$allow_remote_request
(Optional) (Boolean) Allow actually calling the requested URL to check availability
Default: true

$args
(Optional) (Array) An array of request arguments
Default: array('redirection' => 5)

Parameter Notes

When false, $allow_remote_request will only check if the resource has been unavailable in the last 10 minutes. If the resource was unavailable, it will return false, otherwise it will return true (even if the resource is not available because it doesn’t actually check). This optimizes some calls because if the resource is available, it won’t need to be accessed twice. To use this properly, the resource must handle setting the “nebula_site_available_” transient manually.

For the $args array, refer to the WordPress documentation for individual parameters.

Request or provide clarification »

Examples

PHP
<?php if ( nebula()->is_available('https://www.example.com/file.txt') ){
    //Do something with the URL (like wp_remote_get).
} ?>

Demo


PinckneyHugo.com is currently online.
SpacerGIF.org is currently offline. Note: This domain shows that is_available() cannot pass "robot checks".
/r/Syracuse is currently online.

http://qdhjomhi.com (a randomly generated domain) does not exist.

Additional Notes

This function caches the hostname (not the full URL) for 10 minutes. So whether the hostname is available or times out, that will be cached for 10 minutes unless the $allow_cache parameter is set to false. This means if a remote server is down, there will be a 5-10 second timeout (typically) once per hostname within 10 minutes.

Nebula’s remote_get() function builds this in so no manual transient needs to be maintained.

Note: This request may not pass “robot checks”, so a remote request may fail with a 503 response code.

Source File

Located in /libs/Utilities/Utilities.php on line 972.

1 Hook

Find these filters and actions in the source code below to hook into them. Use do_action() and add_filter() in your functions file or plugin.

Filters
"pre_nebula_is_available"
Need a new filter hook? Request one here.

Actions
This function has no action hooks available. Request one?

PHP
        public function is_available($url=null, $allow_cache=true, $allow_remote_request=true, $args=array()){
            $override = apply_filters('pre_nebula_is_available', null, $url, $allow_cache, $allow_remote_request);
            if ( isset($override) ){return $override;}

            //Make sure the URL is valid
            if ( empty($url) || strpos($url, 'http') !== 0 ){
                trigger_error('Error: Requested URL is either empty or missing acceptable protocol.', E_USER_ERROR);
                return false;
            }

            $timer_name = $this->timer('Is Available (' . $url . ')', 'start', 'Is Available');
            $hostname = str_replace('.', '_', $this->url_components('hostname', $url)); //The hostname label for transients

            //Check transient first
            $site_available_buffer = get_transient('nebula_site_available_' . $hostname);
            if ( !empty($site_available_buffer) && $allow_cache ){ //If this hostname was found in a transient and specifically allowing a cached response.
                if ( $site_available_buffer === 'Available' ){
                    set_transient('nebula_site_available_' . $hostname, 'Available', MINUTE_IN_SECONDS*30); //Re-up the transient with a 30 minute expiration
                    $this->timer($timer_name, 'end');
                    return true; //This hostname has worked within the last 30 minutes
                }

                set_transient('nebula_site_available_' . $hostname, 'Unavailable', MINUTE_IN_SECONDS*15); //15 minute expiration
                $this->timer($timer_name, 'end');
                return false; //This hostname has not worked within the last 15 minutes
            }

            //Make an actual request to the URL if: the transient was empty or specifically requested a non-cached response, and specifically allowing a lookup
            //Ex: remote_get() prevents this from running the actual request to avoid multiple requests. It handles the transient itself, so just looking up if a request has failed previously.
            if ( $allow_remote_request ){ //If we are actively allowed to make the request to check if the endpoint is actually available
                //Combine default args with passed args. Args docs: https://developer.wordpress.org/reference/classes/WP_Http/request/
                $all_args = array_merge(array(
                    'redirection' => 5, //Follow 5 redirects before quitting
                ), $args);

                //Only get the head data for slight speed improvement.
                $response = wp_remote_head($url, $all_args);
                if ( !is_wp_error($response) && $response['response']['code'] === 200 ){ //If the remote request was successful
                    set_transient('nebula_site_available_' . $hostname, 'Available', MINUTE_IN_SECONDS*20); //20 minute expiration
                    $this->timer($timer_name, 'end');
                    return true;
                }
            }

            if ( !$allow_remote_request ){ //Otherwise, do not actively check and just report that the site was not reportedly down prior
                $this->timer($timer_name, 'end');
                return true; //Resource may not actually be available, but was asked specifically not to check.
            }

            //Finally, if none of the previous checks were true, the site must be unavailable
            set_transient('nebula_site_available_' . $hostname, 'Unavailable', MINUTE_IN_SECONDS*10); //10 minute expiration
            $this->timer($timer_name, 'end');
            return false;
        }

Override

To override this PHP function, use this hook in your child theme or plugin ("my_custom" can be changed):

PHP
add_filter('pre_nebula_is_available', 'my_custom_is_available', 10, 5); //The last integer must be 1 more than the actual parameters
function my_custom_is_available($null, $url, $allow_cache, $allow_remote_request, $args){ //$null is required, but can be ignored
    //Write your own code here

    return true; //Return true to prevent the original function from running afterwords
}

You can completely disable this PHP function with a single line actions:

PHP
 add_filter('pre_nebula_is_available', '__return_false');