1149 lines
44 KiB
PHP
1149 lines
44 KiB
PHP
<?php
|
|
/**
|
|
* MainWP monitor site.
|
|
*
|
|
* @package MainWP/Dashboard
|
|
*/
|
|
|
|
namespace MainWP\Dashboard;
|
|
|
|
/**
|
|
* Class MainWP_Uptime_Monitoring_Connect
|
|
*
|
|
* @package MainWP\Dashboard
|
|
*/
|
|
class MainWP_Uptime_Monitoring_Connect { // phpcs:ignore Generic.Classes.OpeningBraceSameLine.ContentAfterBrace -- NOSONAR.
|
|
// phpcs:disable WordPress.WP.AlternativeFunctions
|
|
const DOWN = 0;
|
|
const UP = 1;
|
|
const PENDING = 2;
|
|
const FIRST = 3;
|
|
|
|
const RETRY = 10;
|
|
const NOTALLOWED = 11;
|
|
|
|
|
|
const TIMEOUTED_ERROR = 20;
|
|
const CERT_ERROR = 21;
|
|
const RESOLVEHOST_ERROR = 22;
|
|
const UNDEFINED_ERROR = 23;
|
|
|
|
/**
|
|
* The single instance of the class
|
|
*
|
|
* @var mixed Default null
|
|
*/
|
|
protected static $instance = null;
|
|
|
|
/**
|
|
* Get instance.
|
|
*
|
|
* @return mixed
|
|
*/
|
|
public static function instance() {
|
|
if ( null === static::$instance ) {
|
|
static::$instance = new self();
|
|
}
|
|
return static::$instance;
|
|
}
|
|
|
|
/**
|
|
* Check multi uptime monitors.
|
|
*
|
|
* @param array $monitors object array monitors.
|
|
* @param array $glo_settings global settings.
|
|
* @return mixed
|
|
*/
|
|
public function check_monitors( &$monitors, $glo_settings ) {
|
|
|
|
$disabled_functions = ini_get( 'disable_functions' );
|
|
|
|
/**
|
|
* Apply disable check multi exec.
|
|
*
|
|
* @since 5.3
|
|
*/
|
|
$disable_multi_exec = apply_filters( 'mainwp_fetch_uptime_disable_check_multi_exec', false );
|
|
|
|
if ( ! $disable_multi_exec && ( empty( $disabled_functions ) || ( false === stristr( $disabled_functions, 'curl_multi_exec' ) ) ) ) {
|
|
$this->check_multi_monitors( $monitors, $glo_settings );
|
|
} else {
|
|
$this->check_uptime_monitors( $monitors, $glo_settings );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check multi uptime monitors.
|
|
*
|
|
* @param array $monitors object array monitors.
|
|
* @param array $glo_settings global settings.
|
|
* @return mixed
|
|
*/
|
|
public function check_multi_monitors( &$monitors, $glo_settings ) {
|
|
$output = new \stdClass();
|
|
$output->global_settings = $glo_settings;
|
|
static::fetch_uptime_urls( $monitors, array( &$this, 'handle_response_fetch_uptime' ), $output );
|
|
}
|
|
|
|
/**
|
|
* Check uptime monitors.
|
|
*
|
|
* @param array $monitors object array monitors.
|
|
* @param array $glo_settings glo settings.
|
|
* @return mixed
|
|
*/
|
|
public function check_uptime_monitors( &$monitors, $glo_settings ) {
|
|
MainWP_System_Utility::set_time_limit( 3600 );
|
|
$chunkSize = apply_filters( 'mainwp_fetch_uptime_chunk_size_urls', 10 );
|
|
$i = 0;
|
|
foreach ( $monitors as $monitor ) {
|
|
++$i;
|
|
$this->fetch_uptime_monitor( $monitor, $glo_settings );
|
|
if ( 0 === $i % $chunkSize ) {
|
|
sleep( 3 );
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Method fetch uptime monitor.
|
|
*
|
|
* @param mixed $monitor monitor.
|
|
* @param mixed $global_settings global settings.
|
|
* @param bool $second_try second try.
|
|
* @param array $params params.
|
|
*
|
|
* @return mixed
|
|
*/
|
|
public function fetch_uptime_monitor( &$monitor, $global_settings = array(), $second_try = false, $params = array() ) { //phpcs:ignore -- NOSONAR - complexity.
|
|
|
|
$mo_url = static::get_apply_monitor_url( $monitor );
|
|
|
|
$start = microtime( true );
|
|
|
|
$agent = static::get_user_agent();
|
|
|
|
// Initialize curl session.
|
|
$ch = curl_init();
|
|
|
|
$proxy = new \WP_HTTP_Proxy();
|
|
|
|
if ( $proxy->is_enabled() && $proxy->send_through_proxy( $mo_url ) ) {
|
|
curl_setopt( $ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTP );
|
|
curl_setopt( $ch, CURLOPT_PROXY, $proxy->host() );
|
|
curl_setopt( $ch, CURLOPT_PROXYPORT, $proxy->port() );
|
|
|
|
if ( $proxy->use_authentication() ) {
|
|
curl_setopt( $ch, CURLOPT_PROXYAUTH, CURLAUTH_ANY );
|
|
curl_setopt( $ch, CURLOPT_PROXYUSERPWD, $proxy->authentication() );
|
|
}
|
|
}
|
|
curl_setopt( $ch, CURLOPT_URL, $mo_url );
|
|
|
|
$mo_apply_type = static::get_apply_setting( 'type', $monitor->type, $global_settings, 'useglobal', 'http' );
|
|
$mo_apply_method = static::get_apply_setting( 'method', $monitor->method, $global_settings, 'useglobal', 'get' );
|
|
$mo_apply_method = strtolower( $mo_apply_method );
|
|
|
|
if ( ! empty( $params['check_http_site'] ) ) {
|
|
$chk_http_method = get_option( 'mainwp_check_http_response_method', 'head' );
|
|
$chk_http_method = in_array( $chk_http_method, array( 'get', 'head' ) ) ? $chk_http_method : 'head';
|
|
$mo_apply_method = $chk_http_method;
|
|
}
|
|
|
|
if ( 'head' !== $mo_apply_method ) {
|
|
curl_setopt( $ch, CURLOPT_POST, 'post' === $mo_apply_method ? true : false );
|
|
}
|
|
|
|
if ( 'post' === $mo_apply_method ) {
|
|
$postdata = array( 'time' => time() );
|
|
$body = http_build_query( $postdata );
|
|
curl_setopt( $ch, CURLOPT_POSTFIELDS, $body );
|
|
|
|
$headers = array( 'Content-Length' => strlen( $body ) );
|
|
$headers = apply_filters( 'mainwp_connect_http_request_headers', $headers, false, $monitor );
|
|
|
|
if ( class_exists( '\WpOrg\Requests\Requests' ) ) {
|
|
$headers = \WpOrg\Requests\Requests::flatten( $headers );
|
|
} else {
|
|
$headers = \Requests::flatten( $headers );
|
|
}
|
|
curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers );
|
|
}
|
|
|
|
if ( 'ping' === $mo_apply_type || 'head' === $mo_apply_method ) {
|
|
curl_setopt( $ch, CURLOPT_NOBODY, true ); // We only care about the response code, not the content.
|
|
}
|
|
|
|
curl_setopt( $ch, CURLOPT_HEADER, true );
|
|
curl_setopt( $ch, CURLOPT_CUSTOMREQUEST, strtoupper( $mo_apply_method ) );
|
|
|
|
if ( 'get' === $mo_apply_method ) {
|
|
// to fix Content-Length.
|
|
curl_setopt(
|
|
$ch,
|
|
CURLOPT_HTTPHEADER,
|
|
array(
|
|
'Content-Length:', // removes the Content-Length header.
|
|
)
|
|
);
|
|
}
|
|
|
|
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true ); // We want to get the output as a string.
|
|
curl_setopt( $ch, CURLOPT_USERAGENT, $agent );
|
|
|
|
$http_user = '';
|
|
$http_pass = '';
|
|
|
|
if ( property_exists( $monitor, 'http_user' ) ) {
|
|
$http_user = $monitor->http_user;
|
|
}
|
|
if ( property_exists( $monitor, 'http_pass' ) ) {
|
|
$http_pass = $monitor->http_pass;
|
|
}
|
|
|
|
if ( ! empty( $http_user ) && ! empty( $http_pass ) ) {
|
|
$http_pass = stripslashes( $http_pass );
|
|
curl_setopt( $ch, CURLOPT_USERPWD, "$http_user:$http_pass" );
|
|
}
|
|
|
|
$ssl_verifyhost = false;
|
|
$verifyCertificate = isset( $monitor->verify_certificate ) ? (int) $monitor->verify_certificate : null;
|
|
if ( null !== $verifyCertificate ) {
|
|
if ( 1 === $verifyCertificate ) {
|
|
$ssl_verifyhost = true;
|
|
} elseif ( 2 === $verifyCertificate ) {
|
|
if ( ( false === get_option( 'mainwp_sslVerifyCertificate' ) ) || ( 1 === (int) get_option( 'mainwp_sslVerifyCertificate' ) ) ) {
|
|
$ssl_verifyhost = true;
|
|
}
|
|
}
|
|
} elseif ( ( false === get_option( 'mainwp_sslVerifyCertificate' ) ) || ( 1 === (int) get_option( 'mainwp_sslVerifyCertificate' ) ) ) {
|
|
$ssl_verifyhost = true;
|
|
}
|
|
|
|
if ( $ssl_verifyhost ) {
|
|
curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, 2 );
|
|
curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, true );
|
|
} else {
|
|
curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, false ); // NOSONAR.
|
|
curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false ); // NOSONAR.
|
|
}
|
|
|
|
curl_setopt( $ch, CURLOPT_SSLVERSION, $monitor->ssl_version );
|
|
|
|
$mo_apply_timeout = static::get_apply_setting( 'timeout', (int) $monitor->timeout, $global_settings, -1, 60 );
|
|
|
|
curl_setopt( $ch, CURLOPT_TIMEOUT, $mo_apply_timeout ); // seconds.
|
|
|
|
MainWP_Utility::end_session();
|
|
|
|
// Execute the curl request.
|
|
$data = curl_exec( $ch );
|
|
|
|
// Get the HTTP response code.
|
|
$http_code = curl_getinfo( $ch, CURLINFO_HTTP_CODE );
|
|
|
|
$http_error = '';
|
|
if ( curl_errno( $ch ) ) {
|
|
$http_error = curl_error( $ch );
|
|
}
|
|
|
|
$realurl = curl_getinfo( $ch, CURLINFO_EFFECTIVE_URL );
|
|
|
|
$host = wp_parse_url( ( empty( $realurl ) ? $mo_url : $realurl ), PHP_URL_HOST );
|
|
$ip = false;
|
|
$target = false;
|
|
|
|
$found = false;
|
|
$dnsRecord = @dns_get_record( $host ); //phpcs:ignore --ok.
|
|
|
|
if ( false !== $dnsRecord && is_array( $dnsRecord ) ) {
|
|
if ( ! isset( $dnsRecord['ip'] ) ) {
|
|
foreach ( $dnsRecord as $dnsRec ) {
|
|
if ( isset( $dnsRec['ip'] ) ) {
|
|
$ip = $dnsRec['ip'];
|
|
break;
|
|
}
|
|
}
|
|
} else {
|
|
$ip = $dnsRecord['ip'];
|
|
}
|
|
|
|
if ( ! isset( $dnsRecord['host'] ) ) {
|
|
foreach ( $dnsRecord as $dnsRec ) {
|
|
if ( $dnsRec['host'] === $host ) {
|
|
if ( 'CNAME' === $dnsRec['type'] ) {
|
|
$target = $dnsRec['target'];
|
|
}
|
|
$found = true;
|
|
break;
|
|
}
|
|
}
|
|
} else {
|
|
$found = ( $dnsRecord['host'] === $host );
|
|
if ( 'CNAME' === $dnsRecord['type'] ) {
|
|
$target = $dnsRecord['target'];
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( false === $ip ) {
|
|
$ip = gethostbynamel( $host );
|
|
}
|
|
if ( ( false !== $target ) && ( $target !== $host ) ) {
|
|
$host .= ' (CNAME: ' . $target . ')';
|
|
}
|
|
|
|
// Close the curl session.
|
|
curl_close( $ch );
|
|
|
|
$down_count = 0;
|
|
$set_retry = false;
|
|
$is_pending = false;
|
|
|
|
$retry_later = static::is_http_code_type( 'retry', $http_code );
|
|
$is_notallowed = static::is_http_code_type( 'notallowed', $http_code );
|
|
|
|
if ( $retry_later ) {
|
|
$max_retries = static::get_apply_setting( 'maxretries', (int) $monitor->maxretries, $global_settings, -1, 0 );
|
|
if ( $max_retries > 0 && $monitor->retries < $max_retries ) {
|
|
$is_pending = true;
|
|
++$down_count;
|
|
$set_retry = true;
|
|
}
|
|
} elseif ( ! $is_notallowed && empty( $data ) && 'ping' !== $mo_apply_type && ! $second_try ) {
|
|
usleep( 200000 );
|
|
$this->fetch_uptime_monitor( $monitor, $global_settings, true, $params );
|
|
}
|
|
|
|
$output = new \stdClass();
|
|
$output->global_settings = $global_settings;
|
|
|
|
$resp_info = array(
|
|
'http_code' => $http_code,
|
|
'http_error' => $http_error,
|
|
'down_count' => $down_count,
|
|
'retry' => $set_retry,
|
|
'is_pendding' => $is_pending ? 1 : 0,
|
|
'start' => $start,
|
|
'end' => microtime( true ),
|
|
'use_monitor_type' => $mo_apply_type,
|
|
'use_method' => $mo_apply_method,
|
|
'use_timeout' => $mo_apply_timeout,
|
|
);
|
|
|
|
$output->requests_info = array();
|
|
$output->requests_info[ $monitor->monitor_id ] = $resp_info;
|
|
|
|
$handle_data = $this->handle_response_fetch_uptime( $data, $monitor, $output, $params );
|
|
|
|
// data compatible with data from try_visit().
|
|
$compatible_data = array(
|
|
'host' => $host,
|
|
'httpCode' => $http_code,
|
|
'httpCodeString' => MainWP_Utility::get_http_codes( $http_code ),
|
|
'check_offline_time' => is_array( $handle_data ) && isset( $handle_data['check_offline_time'] ) ? $handle_data['check_offline_time'] : time(),
|
|
);
|
|
|
|
if ( false !== $ip ) {
|
|
$compatible_data['ip'] = $ip;
|
|
$found = true;
|
|
}
|
|
$compatible_data['error'] = '' === $http_error && false === $found ? 'Invalid host.' : $http_error;
|
|
|
|
if ( is_array( $handle_data ) && isset( $handle_data['new_uptime_status'] ) ) {
|
|
$compatible_data['new_uptime_status'] = $handle_data['new_uptime_status'];
|
|
}
|
|
|
|
return $compatible_data;
|
|
}
|
|
|
|
/**
|
|
* Fetch uptime urls.
|
|
*
|
|
* @param array $websites websites.
|
|
* @param array $handler callable.
|
|
* @param object $output output.
|
|
* @param array $params params.
|
|
* @return mixed
|
|
*/
|
|
public static function fetch_uptime_urls( &$websites, $handler, &$output, $params = array() ) { // phpcs:ignore Generic.Metrics.CyclomaticComplexity -- NOSONAR - complex function. Current complexity is the only way to achieve desired results, pull request solutions appreciated.
|
|
|
|
if ( ! is_array( $websites ) || empty( $websites ) ) {
|
|
return false;
|
|
}
|
|
|
|
if ( ! is_array( $params ) ) {
|
|
$params = array();
|
|
}
|
|
|
|
if ( ! is_object( $output ) ) {
|
|
$output = new \stdClass();
|
|
}
|
|
|
|
$global_settings = $output->global_settings;
|
|
|
|
$chunkSize = apply_filters( 'mainwp_fetch_uptime_chunk_size_urls', 10 );
|
|
|
|
if ( count( $websites ) > $chunkSize ) {
|
|
$total = count( $websites );
|
|
$loops = ceil( $total / $chunkSize );
|
|
for ( $i = 0; $i < $loops; $i++ ) {
|
|
$newSites = array_slice( $websites, $i * $chunkSize, $chunkSize, true );
|
|
static::fetch_uptime_urls( $newSites, $handler, $output, $params );
|
|
sleep( 3 );
|
|
}
|
|
return false;
|
|
}
|
|
|
|
$agent = static::get_user_agent();
|
|
$mh = curl_multi_init();
|
|
|
|
$disabled_functions = ini_get( 'disable_functions' );
|
|
$handleToWebsite = array();
|
|
$requestUrls = array();
|
|
$requestHandles = array();
|
|
$output->requests_info = array();
|
|
|
|
foreach ( $websites as $website ) {
|
|
|
|
$mo_url = static::get_apply_monitor_url( $website );
|
|
|
|
if ( property_exists( $website, 'http_user' ) ) {
|
|
$http_user = $website->http_user;
|
|
}
|
|
if ( property_exists( $website, 'http_pass' ) ) {
|
|
$http_pass = $website->http_pass;
|
|
}
|
|
|
|
$ch = curl_init();
|
|
|
|
$proxy = new \WP_HTTP_Proxy();
|
|
if ( $proxy->is_enabled() && $proxy->send_through_proxy( $mo_url ) ) {
|
|
curl_setopt( $ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTP );
|
|
curl_setopt( $ch, CURLOPT_PROXY, $proxy->host() );
|
|
curl_setopt( $ch, CURLOPT_PROXYPORT, $proxy->port() );
|
|
|
|
if ( $proxy->use_authentication() ) {
|
|
curl_setopt( $ch, CURLOPT_PROXYAUTH, CURLAUTH_ANY );
|
|
curl_setopt( $ch, CURLOPT_PROXYUSERPWD, $proxy->authentication() );
|
|
}
|
|
}
|
|
|
|
curl_setopt( $ch, CURLOPT_URL, $mo_url );
|
|
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
|
|
curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, true );
|
|
|
|
$mo_apply_type = static::get_apply_setting( 'type', $website->type, $global_settings, 'useglobal', 'http' );
|
|
$mo_apply_method = static::get_apply_setting( 'method', $website->method, $global_settings, 'useglobal', 'get' );
|
|
$mo_apply_method = strtolower( $mo_apply_method );
|
|
|
|
if ( 'head' !== $mo_apply_method ) {
|
|
curl_setopt( $ch, CURLOPT_POST, 'post' === $mo_apply_method ? true : false );
|
|
}
|
|
|
|
if ( 'post' === $mo_apply_method ) {
|
|
$postdata = array( 'time' => time() );
|
|
$body = http_build_query( $postdata );
|
|
curl_setopt( $ch, CURLOPT_POSTFIELDS, $body );
|
|
|
|
$headers = array( 'Content-Length' => strlen( $body ) );
|
|
$headers = apply_filters( 'mainwp_connect_http_request_headers', $headers, false, $monitor );
|
|
|
|
if ( class_exists( '\WpOrg\Requests\Requests' ) ) {
|
|
$headers = \WpOrg\Requests\Requests::flatten( $headers );
|
|
} else {
|
|
$headers = \Requests::flatten( $headers );
|
|
}
|
|
curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers );
|
|
}
|
|
|
|
if ( 'ping' === $mo_apply_type || 'head' === $mo_apply_method ) {
|
|
curl_setopt( $ch, CURLOPT_NOBODY, true ); // We only care about the response code, not the content.
|
|
}
|
|
|
|
curl_setopt( $ch, CURLOPT_CUSTOMREQUEST, strtoupper( $mo_apply_method ) );
|
|
|
|
if ( 'get' === $mo_apply_method ) {
|
|
// to fix Content-Length.
|
|
curl_setopt(
|
|
$ch,
|
|
CURLOPT_HTTPHEADER,
|
|
array(
|
|
'Content-Length:', // removes the Content-Length header.
|
|
)
|
|
);
|
|
}
|
|
|
|
curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, 10 );
|
|
curl_setopt( $ch, CURLOPT_USERAGENT, $agent );
|
|
curl_setopt( $ch, CURLOPT_ENCODING, 'none' );
|
|
|
|
if ( ! empty( $http_user ) && ! empty( $http_pass ) ) {
|
|
$http_pass = stripslashes( $http_pass );
|
|
curl_setopt( $ch, CURLOPT_USERPWD, "$http_user:$http_pass" );
|
|
}
|
|
|
|
$ssl_verifyhost = false;
|
|
$verifyCertificate = isset( $website->verify_certificate ) ? (int) $website->verify_certificate : null;
|
|
if ( null !== $verifyCertificate ) {
|
|
if ( 1 === $verifyCertificate ) {
|
|
$ssl_verifyhost = true;
|
|
} elseif ( 2 === $verifyCertificate ) {
|
|
if ( ( false === get_option( 'mainwp_sslVerifyCertificate' ) ) || ( 1 === (int) get_option( 'mainwp_sslVerifyCertificate' ) ) ) {
|
|
$ssl_verifyhost = true;
|
|
}
|
|
}
|
|
} elseif ( ( false === get_option( 'mainwp_sslVerifyCertificate' ) ) || ( 1 === (int) get_option( 'mainwp_sslVerifyCertificate' ) ) ) {
|
|
$ssl_verifyhost = true;
|
|
}
|
|
|
|
if ( $ssl_verifyhost ) {
|
|
curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, 2 );
|
|
curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, true );
|
|
} else {
|
|
curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, false ); // NOSONAR.
|
|
curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false ); // NOSONAR.
|
|
}
|
|
|
|
curl_setopt( $ch, CURLOPT_SSLVERSION, $website->ssl_version );
|
|
|
|
if ( is_object( $website ) && property_exists( $website, 'id' ) ) {
|
|
$http_version = apply_filters( 'mainwp_curl_http_version', false, $website->id );
|
|
if ( false !== $http_version ) {
|
|
curl_setopt( $ch, CURLOPT_HTTP_VERSION, $http_version );
|
|
}
|
|
|
|
$curlopt_resolve = apply_filters( 'mainwp_curl_curlopt_resolve', false, $website->id, $mo_url );
|
|
if ( is_array( $curlopt_resolve ) && ! empty( $curlopt_resolve ) ) {
|
|
curl_setopt( $ch, CURLOPT_RESOLVE, $curlopt_resolve );
|
|
curl_setopt( $ch, CURLOPT_DNS_USE_GLOBAL_CACHE, false );
|
|
}
|
|
}
|
|
|
|
$mo_apply_timeout = static::get_apply_setting( 'timeout', (int) $website->timeout, $global_settings, -1, 60 );
|
|
|
|
curl_setopt( $ch, CURLOPT_TIMEOUT, $mo_apply_timeout ); // seconds.
|
|
|
|
MainWP_System_Utility::set_time_limit( 3600 );
|
|
|
|
if ( empty( $disabled_functions ) || ( false === stristr( $disabled_functions, 'curl_multi_exec' ) ) ) {
|
|
curl_multi_add_handle( $mh, $ch );
|
|
}
|
|
|
|
$resource_id = MainWP_Connect::get_resource_id( $ch );
|
|
|
|
$start = microtime( true );
|
|
$handleToWebsite[ $resource_id ] = $website;
|
|
$requestUrls[ $resource_id ] = $mo_url;
|
|
$requestHandles[ $resource_id ] = $ch;
|
|
$requestMonitorIds[ $resource_id ] = $website->monitor_id;
|
|
$output->requests_info[ $website->monitor_id ] = array(
|
|
'start' => $start,
|
|
'use_monitor_type' => $mo_apply_type,
|
|
'use_method' => $mo_apply_method,
|
|
'use_timeout' => $mo_apply_timeout,
|
|
);
|
|
}
|
|
|
|
if ( empty( $disabled_functions ) || ( false === stristr( $disabled_functions, 'curl_multi_exec' ) ) ) {
|
|
|
|
$lastRun = 0;
|
|
do {
|
|
if ( 20 < time() - $lastRun ) {
|
|
MainWP_System_Utility::set_time_limit( 3600 );
|
|
$lastRun = time();
|
|
}
|
|
|
|
curl_multi_exec( $mh, $running );
|
|
curl_multi_select( $mh );
|
|
while ( $info = curl_multi_info_read( $mh ) ) {
|
|
$data = curl_multi_getcontent( $info['handle'] );
|
|
$resource_id = MainWP_Connect::get_resource_id( $info['handle'] );
|
|
curl_multi_remove_handle( $mh, $info['handle'] );
|
|
$http_code = curl_getinfo( $info['handle'], CURLINFO_HTTP_CODE );
|
|
|
|
$down_count = 0;
|
|
$set_retry = false;
|
|
$is_pending = false;
|
|
|
|
$retry_later = static::is_http_code_type( 'retry', $http_code );
|
|
$is_notallowed = static::is_http_code_type( 'notallowed', $http_code );
|
|
|
|
if ( ! empty( $requestUrls[ $resource_id ] ) ) {
|
|
|
|
$mo_apply_type = static::get_apply_setting( 'type', $website->type, $global_settings, 'useglobal', 'http' );
|
|
|
|
$_try_second = false;
|
|
if ( $retry_later ) {
|
|
$max_retries = static::get_apply_setting( 'maxretries', (int) $website->maxretries, $global_settings, -1, 0 );
|
|
if ( $max_retries > 0 && $website->retries < $max_retries ) {
|
|
$is_pending = true;
|
|
++$down_count;
|
|
$set_retry = true;
|
|
}
|
|
} elseif ( ! $is_notallowed && empty( $data ) && 'ping' !== $mo_apply_type ) {
|
|
curl_setopt( $info['handle'], CURLOPT_URL, $requestUrls[ $resource_id ] );
|
|
$_try_second = true;
|
|
}
|
|
|
|
if ( $_try_second ) {
|
|
curl_multi_add_handle( $mh, $info['handle'] );
|
|
unset( $requestUrls[ $resource_id ] );
|
|
++$running;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if ( isset( $requestMonitorIds[ $resource_id ] ) ) {
|
|
$mo_id = $requestMonitorIds[ $resource_id ];
|
|
$http_error = '';
|
|
if ( curl_errno( $info['handle'] ) ) {
|
|
$http_error = curl_error( $info['handle'] );
|
|
}
|
|
$output->requests_info[ $mo_id ]['http_error'] = $http_error;
|
|
$output->requests_info[ $mo_id ]['http_code'] = $http_code;
|
|
|
|
$output->requests_info[ $mo_id ]['is_pending'] = $is_pending ? 1 : 0;
|
|
$output->requests_info[ $mo_id ]['retry'] = $set_retry ? 1 : 0;
|
|
$output->requests_info[ $mo_id ]['down_count'] = $down_count;
|
|
$output->requests_info[ $mo_id ]['end'] = microtime( true );
|
|
}
|
|
|
|
if ( null !== $handler ) {
|
|
$site = &$handleToWebsite[ $resource_id ];
|
|
call_user_func_array( $handler, array( $data, $site, &$output, $params ) );
|
|
}
|
|
|
|
unset( $handleToWebsite[ $resource_id ] );
|
|
if ( 'resource' === gettype( $info['handle'] ) ) {
|
|
curl_close( $info['handle'] );
|
|
}
|
|
}
|
|
usleep( 10000 );
|
|
} while ( $running > 0 );
|
|
|
|
if ( 'resource' === gettype( $mh ) ) {
|
|
curl_multi_close( $mh );
|
|
}
|
|
} else {
|
|
foreach ( $requestHandles as $ch ) {
|
|
$resource_id = MainWP_Connect::get_resource_id( $ch );
|
|
if ( isset( $handleToWebsite[ $resource_id ] ) ) {
|
|
$site = &$handleToWebsite[ $resource_id ];
|
|
static::fetch_single_uptime_url( $ch, $handler, $site, $output, $params );
|
|
unset( $handleToWebsite[ $resource_id ] );
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Fetch single curl exec.
|
|
*
|
|
* @param mixed $ch ch.
|
|
* @param mixed $handler handler.
|
|
* @param object $website website.
|
|
* @param object $output output.
|
|
* @param array $params params.
|
|
* @param bool $try_second try second.
|
|
* @return mixed
|
|
*/
|
|
public static function fetch_single_uptime_url( $ch, $handler, $website, $output, $params, $try_second = false ) { //phpcs:ignore -- NOSONAR - complexity.
|
|
|
|
$global_settings = $output->global_settings;
|
|
|
|
$data = curl_exec( $ch );
|
|
|
|
$mo_id = $website->monitor_id;
|
|
|
|
$down_count = 0;
|
|
$set_retry = false;
|
|
$is_pending = false;
|
|
|
|
$http_code = curl_getinfo( $ch, CURLINFO_HTTP_CODE );
|
|
|
|
$http_error = '';
|
|
|
|
if ( curl_errno( $ch ) ) {
|
|
$http_error = curl_error( $ch );
|
|
}
|
|
|
|
$retry_later = static::is_http_code_type( 'retry', $http_code );
|
|
$is_notallowed = static::is_http_code_type( 'notallowed', $http_code );
|
|
$mo_apply_type = static::get_apply_setting( 'type', $website->type, $global_settings, 'useglobal', 'http' );
|
|
$mo_apply_method = static::get_apply_setting( 'method', $website->method, $global_settings, 'useglobal', 'get' );
|
|
$mo_apply_timeout = static::get_apply_setting( 'timeout', (int) $website->timeout, $global_settings, -1, 60 );
|
|
|
|
if ( $retry_later ) {
|
|
$max_retries = static::get_apply_setting( 'maxretries', (int) $website->maxretries, $global_settings, -1, 0 );
|
|
if ( $max_retries > 0 && $website->retries < $max_retries ) {
|
|
$is_pending = true;
|
|
++$down_count;
|
|
$set_retry = true;
|
|
}
|
|
}
|
|
|
|
// if is not second try, check to retry now.
|
|
if ( ! $try_second && ! $retry_later && ! $is_notallowed ) {
|
|
|
|
$_try_second = false;
|
|
|
|
$mo_url = static::get_apply_monitor_url( $website );
|
|
|
|
if ( empty( $data ) && 'ping' !== $mo_apply_type ) {
|
|
curl_setopt( $ch, CURLOPT_URL, $mo_url );
|
|
$_try_second = true;
|
|
}
|
|
|
|
if ( $_try_second ) {
|
|
static::fetch_single_uptime_url( $ch, $handler, $website, $output, $params, true );
|
|
}
|
|
}
|
|
|
|
$output->requests_info[ $mo_id ]['http_code'] = $http_code;
|
|
$output->requests_info[ $mo_id ]['http_error'] = $http_error;
|
|
|
|
$output->requests_info[ $mo_id ]['is_pending'] = $is_pending ? 1 : 0;
|
|
$output->requests_info[ $mo_id ]['retry'] = $set_retry ? 1 : 0;
|
|
$output->requests_info[ $mo_id ]['down_count'] = $down_count;
|
|
|
|
$output->requests_info[ $mo_id ]['end'] = microtime( true );
|
|
|
|
$output->requests_info[ $mo_id ]['use_monitor_type'] = $mo_apply_type;
|
|
$output->requests_info[ $mo_id ]['use_method'] = $mo_apply_method;
|
|
$output->requests_info[ $mo_id ]['use_timeout'] = $mo_apply_timeout;
|
|
|
|
if ( ! empty( $handler ) ) {
|
|
call_user_func_array( $handler, array( $data, $website, &$output, $params ) );
|
|
}
|
|
|
|
if ( 'resource' === gettype( $ch ) ) {
|
|
curl_close( $ch );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Method handle response fetch uptime.
|
|
*
|
|
* @param mixed $data data.
|
|
* @param mixed $monitor monitor.
|
|
* @param mixed $output output.
|
|
* @param array $params params.
|
|
* @return mixed
|
|
*/
|
|
public function handle_response_fetch_uptime( $data, $monitor, &$output, $params = array() ) { //phpcs:ignore -- NOSONAR - complexity.
|
|
|
|
$request_info = ! empty( $output->requests_info ) && is_array( $output->requests_info ) ? $output->requests_info : array();
|
|
$resp_info = ! empty( $request_info[ $monitor->monitor_id ] ) && is_array( $request_info[ $monitor->monitor_id ] ) ? $request_info[ $monitor->monitor_id ] : array();
|
|
|
|
$resp_info = apply_filters( 'mainwp_uptime_monitor_check_result', $resp_info, $data, $monitor, $output, $params );
|
|
|
|
$global_settings = $output->global_settings;
|
|
|
|
$http_code = isset( $resp_info['http_code'] ) ? $resp_info['http_code'] : 0;
|
|
$http_error = isset( $resp_info['http_error'] ) ? $resp_info['http_error'] : '';
|
|
$start = isset( $resp_info['start'] ) ? $resp_info['start'] : 0;
|
|
$end = isset( $resp_info['end'] ) ? $resp_info['end'] : 0;
|
|
|
|
$down_count = isset( $resp_info['down_count'] ) ? $resp_info['down_count'] : 0;
|
|
$set_retry = isset( $resp_info['retry'] ) && $resp_info['retry'] ? true : false;
|
|
$use_mo_method = isset( $resp_info['use_method'] ) ? $resp_info['use_method'] : '';
|
|
$use_mo_type = isset( $resp_info['use_monitor_type'] ) ? $resp_info['use_monitor_type'] : '';
|
|
$use_mo_timeout = isset( $resp_info['use_timeout'] ) ? $resp_info['use_timeout'] : '';
|
|
|
|
$ping = $end - $start; // ms - millisecond.
|
|
|
|
$parsed = $this->parse_response_status( $http_code, $http_error );
|
|
|
|
$status = $parsed['status'];
|
|
$error = $parsed['error'];
|
|
$success = $parsed['success'];
|
|
|
|
$up_codes = $this->get_up_codes( $monitor, $global_settings );
|
|
$up_codes = ! empty( $up_codes ) ? explode( ',', $up_codes ) : array();
|
|
|
|
// check up status codes.
|
|
if ( $set_retry ) {
|
|
$status = static::PENDING;
|
|
} elseif ( is_string( $data ) && false !== stripos( $data, 'Briefly unavailable for scheduled maintenance' ) ) {
|
|
$status = static::PENDING;
|
|
} elseif ( ! empty( $http_code ) && is_array( $up_codes ) ) {
|
|
if ( in_array( $http_code, $up_codes ) ) {
|
|
$status = static::UP;
|
|
} elseif ( static::UP === $status ) {
|
|
$status = static::DOWN;
|
|
}
|
|
}
|
|
|
|
if ( empty( $http_code ) ) {
|
|
$status = static::PENDING;
|
|
}
|
|
|
|
$mo_url = static::get_apply_monitor_url( $monitor );
|
|
|
|
$_status_str = '';
|
|
if ( static::UP === $status ) {
|
|
$_status_str = 'up!';
|
|
} elseif ( static::PENDING === $status ) {
|
|
$_status_str = 'pending.';
|
|
} else {
|
|
$_status_str = 'down.';
|
|
$status = static::DOWN; // to fix.
|
|
}
|
|
|
|
$heart_msg = "{$http_code} - " . $_status_str;
|
|
|
|
$code_msg = MainWP_Utility::get_http_codes( $http_code );
|
|
|
|
if ( ! empty( $code_msg ) ) {
|
|
$heart_msg .= " {$code_msg}";
|
|
}
|
|
|
|
$mo_apply_type = static::get_apply_setting( 'type', $monitor->type, $global_settings, 'useglobal', 'http' );
|
|
$use_mo_active = static::get_apply_setting( 'active', (int) $monitor->active, $global_settings, -1, 0 );
|
|
$use_mo_interval = static::get_apply_setting( 'interval', (int) $monitor->interval, $global_settings, -1, 60 );
|
|
|
|
$keywordFound = true; // set it as found.
|
|
|
|
if ( 'keyword' === $mo_apply_type ) {
|
|
if ( ! is_string( $data ) ) {
|
|
$data = wp_json_encode( $data );
|
|
}
|
|
|
|
$keyword = '';
|
|
if ( 'useglobal' === $monitor->type ) {
|
|
$keyword = ! empty( $global_settings['keyword'] ) ? $global_settings['keyword'] : '';
|
|
} else {
|
|
$keyword = $monitor->keyword;
|
|
}
|
|
|
|
if ( ! empty( $keyword ) && ! empty( $data ) ) {
|
|
$keywordFound = false !== stripos( $data, $keyword );
|
|
$heart_msg .= '. Keyword ' . ( $keywordFound ? 'is' : 'not' ) . ' found.';
|
|
}
|
|
}
|
|
|
|
// forced status down.
|
|
if ( ! $keywordFound ) {
|
|
$status = static::DOWN;
|
|
}
|
|
|
|
if ( ! empty( $error ) ) {
|
|
$heart_msg .= " {$error}";
|
|
}
|
|
|
|
$previous_heartbeat = MainWP_DB_Uptime_Monitoring::instance()->get_previous_monitor_heartbeat( $monitor->monitor_id );
|
|
|
|
$previous_status = static::FIRST;
|
|
|
|
if ( $previous_heartbeat ) {
|
|
$previous_status = $previous_heartbeat->status;
|
|
}
|
|
$sec_since_last = $previous_heartbeat && ! empty( $previous_heartbeat->time ) ? (int) $end - strtotime( $previous_heartbeat->time ) : 1;
|
|
|
|
$importance = $this->is_importance_status( (int) $previous_status, (int) $status ) ? 1 : 0;
|
|
|
|
// get this time first.
|
|
$uptime_init_time = mainwp_get_current_utc_datetime_db( false );
|
|
|
|
$db_datetime = mainwp_get_current_utc_datetime_db();
|
|
|
|
$heartbeat = array(
|
|
'monitor_id' => $monitor->monitor_id,
|
|
'status' => $status,
|
|
'importance' => $importance,
|
|
'time' => $db_datetime,
|
|
'ping_ms' => (int) ( $ping * 1000 ), // convert seconds to milliseconds.
|
|
'duration' => $sec_since_last, // milliseconds - timestamp.
|
|
'msg' => $heart_msg,
|
|
'down_count' => $down_count,
|
|
'http_code' => $http_code,
|
|
);
|
|
|
|
$importance = apply_filters( 'mainwp_uptime_monitoring_check_importance', $importance, $heartbeat );
|
|
|
|
$heartbeat['importance'] = $importance;
|
|
|
|
$heartbeat = apply_filters( 'mainwp_uptime_monitoring_uptime_data', $heartbeat, $monitor, $previous_heartbeat );
|
|
|
|
MainWP_DB_Uptime_Monitoring::instance()->update_heartbeat( $heartbeat );
|
|
|
|
$db_timestamp = strtotime( $db_datetime );
|
|
|
|
MainWP_DB_Uptime_Monitoring::instance()->update_wp_monitor(
|
|
array(
|
|
'monitor_id' => $monitor->monitor_id,
|
|
'last_status' => $status,
|
|
'last_http_code' => $http_code,
|
|
'lasttime_check' => $db_timestamp,
|
|
)
|
|
);
|
|
|
|
if ( $importance ) {
|
|
MainWP_Uptime_Monitoring_Handle::instance()->update_process_monitor_notification( $monitor->monitor_id, $uptime_init_time );
|
|
}
|
|
|
|
MainWP_Uptime_Monitoring_Handle::instance()->calc_and_save_site_uptime_stat_hourly_data( $monitor->monitor_id, $heartbeat );
|
|
|
|
if ( ! empty( $monitor->wpid ) && empty( $monitor->issub ) && empty( $params['ignore_compatible_save'] ) ) {
|
|
// legacy compatible.
|
|
MainWP_Uptime_Monitoring_Handle::instance()->handle_update_website_legacy_uptime_status(
|
|
$monitor,
|
|
array(
|
|
'httpCode' => $http_code,
|
|
'new_uptime_status' => $status,
|
|
'importance' => $importance,
|
|
'check_offline_time' => $db_timestamp,
|
|
)
|
|
);
|
|
}
|
|
|
|
MainWP_Uptime_Monitoring_Schedule::instance()->update_monitoring_time( $monitor, $set_retry ); // update monitor check info, and retry or not.
|
|
|
|
do_action( 'mainwp_uptime_monitoring_after_check_uptime', $heartbeat, $monitor, $previous_heartbeat );
|
|
|
|
$debug = 'Check Uptime - ' . ( $success ? 'succeeded' : 'not succeed' );
|
|
$debug .= ' :: [monitor_url=' . $mo_url . ']';
|
|
if ( static::PENDING === $status ) {
|
|
$debug .= ' :: [status=PENDING]';
|
|
} else {
|
|
$debug .= ' :: [status=' . ( static::UP === $status ? 'UP' : 'DOWN' ) . ']';
|
|
}
|
|
$debug .= ' :: [msg=' . $heart_msg . ']';
|
|
MainWP_Logger::instance()->log_uptime_check( $debug );
|
|
|
|
$debug = ' [siteid=' . $monitor->wpid . '] :: [monitor_id=' . $monitor->monitor_id . ']';
|
|
$debug .= ' :: [monitor_active=' . $monitor->active . '] :: [apply_monitor_active=' . $use_mo_active . ']';
|
|
$debug .= ' :: [monitor_type=' . $monitor->type . '] :: [apply_monitor_type=' . $use_mo_type . ']';
|
|
$debug .= ' :: [monitor_interval=' . $monitor->interval . '] :: [apply_monitor_interval=' . $use_mo_interval . ']';
|
|
$debug .= ' :: [monitor_method=' . $monitor->method . '] :: [apply_monitor_method=' . $use_mo_method . ']';
|
|
$debug .= ' :: [monitor_timeout=' . $monitor->timeout . '] :: [apply_monitor_timeout=' . $use_mo_timeout . ']';
|
|
$debug .= ' :: [ping_ms=' . $heartbeat['ping_ms'] . ']';
|
|
$debug .= ' :: [duration_sec=' . $sec_since_last . ']';
|
|
$debug .= ' :: [time=' . $db_datetime . ']';
|
|
|
|
MainWP_Logger::instance()->log_uptime_check( $debug );
|
|
|
|
if ( empty( $data ) ) {
|
|
MainWP_Logger::instance()->log_uptime_check( '[data=EMPTY]' );
|
|
}
|
|
|
|
// for compatible http status data.
|
|
return array(
|
|
'httpCode' => $http_code,
|
|
'new_uptime_status' => $status,
|
|
'importance' => $importance,
|
|
'check_offline_time' => $db_timestamp,
|
|
);
|
|
}
|
|
|
|
|
|
/**
|
|
* Method is_http_code_type
|
|
*
|
|
* @param mixed $type type.
|
|
* @param mixed $code code.
|
|
* @return bool
|
|
*/
|
|
public static function is_http_code_type( $type, $code ) {
|
|
$retry_codes = array( 429, 502, 503, 504 );
|
|
$not_allowed_codes = array( 405 );
|
|
|
|
if ( ( 'retry' === $type && in_array( $code, $retry_codes ) ) || ( 'notallowed' === $type && in_array( $code, $not_allowed_codes ) ) ) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Parse response status.
|
|
*
|
|
* @param mixed $httpCode http code.
|
|
* @param mixed $error error.
|
|
* @return mixed
|
|
*/
|
|
public function parse_response_status( $httpCode, $error = false ) {
|
|
|
|
$httpCode = (int) $httpCode;
|
|
$status = '';
|
|
$status_error = '';
|
|
|
|
if ( ! empty( $error ) ) {
|
|
switch ( $error ) {
|
|
case CURLE_OPERATION_TIMEOUTED:
|
|
$status_error = 'Error: Request timed out.';
|
|
$status = static::TIMEOUTED_ERROR;
|
|
break;
|
|
case CURLE_SSL_CACERT:
|
|
case CURLE_SSL_CERTPROBLEM:
|
|
$status_error = 'Error: SSL certificate expired or invalid.';
|
|
$status = static::CERT_ERROR;
|
|
break;
|
|
case CURLE_COULDNT_RESOLVE_HOST:
|
|
$status_error = 'Error: DNS resolution failed, could not resolve host.';
|
|
$status = static::RESOLVEHOST_ERROR;
|
|
break;
|
|
default:
|
|
$status_error = 'Error: ' . $error;
|
|
$status = static::UNDEFINED_ERROR;
|
|
break;
|
|
}
|
|
} elseif ( $httpCode >= 400 ) {
|
|
$status = static::DOWN;
|
|
} elseif ( static::is_http_code_type( 'notallowed', $httpCode ) ) {
|
|
$status = static::NOTALLOWED;
|
|
} elseif ( static::is_http_code_type( 'retry', $httpCode ) ) {
|
|
$status = static::RETRY;
|
|
} else {
|
|
$status = static::UP;
|
|
}
|
|
|
|
$success = in_array( $status, array( static::DOWN, static::UP, static::RETRY ) );
|
|
|
|
return array(
|
|
'status' => $status,
|
|
'error' => $status_error,
|
|
'success' => $success,
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Method get_mapping_status_code_names
|
|
*
|
|
* @return array
|
|
*/
|
|
public static function get_mapping_status_code_names() {
|
|
return array(
|
|
static::TIMEOUTED_ERROR => 'TIMEOUTED_ERROR',
|
|
static::CERT_ERROR => 'CERT_ERROR',
|
|
static::RESOLVEHOST_ERROR => 'RESOLVEHOST_ERROR',
|
|
static::UNDEFINED_ERROR => 'UNDEFINED_ERROR',
|
|
static::DOWN => 'DOWN',
|
|
static::NOTALLOWED => 'NOTALLOWED',
|
|
static::RETRY => 'RETRY',
|
|
static::UP => 'UP',
|
|
);
|
|
}
|
|
|
|
|
|
/**
|
|
* Get apply monitor url.
|
|
*
|
|
* @param mixed $monitor monitor.
|
|
*
|
|
* @return string
|
|
*/
|
|
public static function get_apply_monitor_url( $monitor ) {
|
|
|
|
if ( ! empty( $monitor ) ) {
|
|
|
|
if ( is_object( $monitor ) ) {
|
|
$url = $monitor->url;
|
|
$suburl = $monitor->suburl;
|
|
$issub = $monitor->issub;
|
|
} elseif ( is_array( $monitor ) ) {
|
|
$url = $monitor['url'];
|
|
$suburl = $monitor['suburl'];
|
|
$issub = $monitor['issub'];
|
|
}
|
|
|
|
if ( '/' !== substr( $url, -1 ) ) {
|
|
$url .= '/';
|
|
}
|
|
|
|
if ( $issub && ! empty( $suburl ) ) {
|
|
$url .= $suburl;
|
|
}
|
|
}
|
|
|
|
return apply_filters( 'mainwp_uptime_monitoring_check_url', $url, $monitor );
|
|
}
|
|
|
|
/**
|
|
* Method is_importance_status
|
|
*
|
|
* @param int $previous previous.
|
|
* @param int $current current.
|
|
* @return mixed
|
|
*/
|
|
public function is_importance_status( $previous, $current ) {
|
|
// * ? -> ANY STATUS | FIRST = not important
|
|
// UP -> PENDING = not important
|
|
// * UP -> DOWN = important
|
|
// UP -> UP = not important
|
|
// PENDING -> PENDING = not important
|
|
// * PENDING -> DOWN = important
|
|
// PENDING -> UP = not important
|
|
// DOWN -> PENDING = this case not exists
|
|
// DOWN -> DOWN = not important
|
|
// * DOWN -> UP = important
|
|
|
|
return ( static::UP === $previous && static::DOWN === $current ) ||
|
|
( static::PENDING === $previous && static::DOWN === $current ) ||
|
|
( static::DOWN === $previous && static::UP === $current );
|
|
}
|
|
|
|
/**
|
|
* Get apply setting.
|
|
*
|
|
* @param mixed $name name.
|
|
* @param mixed $indiv_settings indiv settings.
|
|
* @param mixed $glo_settings glo settings.
|
|
* @param mixed $apply_global_value apply global value.
|
|
* @param mixed $default_value default value.
|
|
* @return mixed value
|
|
*/
|
|
public static function get_apply_setting( $name, $indiv_settings, $glo_settings, $apply_global_value, $default_value ) {
|
|
|
|
if ( false === $glo_settings ) {
|
|
$glo_settings = MainWP_Uptime_Monitoring_Handle::get_global_monitoring_settings();
|
|
}
|
|
|
|
if ( is_object( $indiv_settings ) && property_exists( $indiv_settings, $name ) ) {
|
|
$indi_value = $indiv_settings->{$name};
|
|
} elseif ( is_array( $indiv_settings ) && isset( $indiv_settings[ $name ] ) ) {
|
|
$indi_value = $indiv_settings[ $name ];
|
|
} elseif ( is_scalar( $indiv_settings ) ) {
|
|
$indi_value = $indiv_settings;
|
|
} else {
|
|
$indi_value = $default_value;
|
|
}
|
|
$glo_value = is_array( $glo_settings ) && isset( $glo_settings[ $name ] ) ? $glo_settings[ $name ] : $default_value;
|
|
|
|
// to support allow use global in individual up_status_codes settings.
|
|
if ( 'up_status_codes' === $name && false !== strpos( $indi_value, 'useglobal' ) ) {
|
|
if ( $indi_value === $apply_global_value ) {
|
|
return $glo_value;
|
|
} else {
|
|
return str_replace( 'useglobal', $glo_value, $indi_value );
|
|
}
|
|
}
|
|
// NOTE: need to match type of values.
|
|
return ( $indi_value === $apply_global_value ) ? $glo_value : $indi_value; //phpcs:ignore -- NOSONAR - compatible.
|
|
}
|
|
|
|
/**
|
|
* Method get_up_codes
|
|
*
|
|
* @param mixed $monitor monitor.
|
|
* @param mixed $global_settings global settings.
|
|
* @return mixed
|
|
*/
|
|
public function get_up_codes( $monitor, $global_settings ) {
|
|
return static::get_apply_setting( 'up_status_codes', $monitor, $global_settings, 'useglobal', '' );
|
|
}
|
|
|
|
|
|
/**
|
|
* Method get_user_agent
|
|
*
|
|
* @return string
|
|
*/
|
|
public static function get_user_agent() {
|
|
return 'Mozilla/5.0 (compatible; MainWP/' . MainWP_System::$version . '; +http://mainwp.com)';
|
|
}
|
|
}
|