File: /www/wwwroot/www.cytocare.cn/wp-content/plugins/hummingbird-performance/core/class-utils.php
<?php
/**
* Class Utils holds common functions used by the plugin.
*
* Class has the following structure:
* I. General helper functions
* II. Layout functions
* III. Time and date functions
* IV. Link and url functions
* V. Modules functions
*
* @package Hummingbird\Core
* @since 1.8
*/
namespace Hummingbird\Core;
use Hummingbird\WP_Hummingbird;
use Hummingbird\Core\Modules\Caching\Fast_CGI;
use stdClass;
use WP_User;
use WPMUDEV_Dashboard;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Class Utils
*/
class Utils {
/**
* Store HB plugin discount percent.
*
* @var int
*/
const HB_PLUGIN_DISCOUNT = 80;
/***************************
*
* I. General helper functions
* is_member()
* has_access_to_hub()
* is_free_installed()
* is_dash_logged_in()
* src_to_path()
* enqueue_admin_scripts()
* get_tracking_data()
* get_admin_capability()
* get_current_user_name()
* calculate_sum()
* format_bytes()
* format_interval()
* format_interval_hours()
* is_ajax_network_admin()
***************************/
/**
* Check if user is a paid one in WPMU DEV
*
* @return bool
*/
public static function is_member() {
if ( class_exists( 'WPMUDEV_Dashboard' ) && method_exists( \WPMUDEV_Dashboard::$upgrader, 'user_can_install' ) ) {
return \WPMUDEV_Dashboard::$upgrader->user_can_install( 1081721, true );
}
return false;
}
/**
* Check if plugin has access to API features (full, single and free plans).
*
* @since 3.3.1
*
* @return bool
*/
public static function has_access_to_hub() {
if ( ! class_exists( 'WPMUDEV_Dashboard' ) ) {
return false;
}
if ( ! method_exists( 'WPMUDEV_Dashboard_Api', 'get_membership_status' ) ) {
return self::is_member();
}
// Possible values: full, single, free, expired, paused, unit.
$plan = WPMUDEV_Dashboard::$api->get_membership_status();
return in_array( $plan, array( 'full', 'single', 'free', 'unit' ), true );
}
/**
* Determines whether the WPMUDEV Hosted site is connected to The Free HUB.
*
* @since 3.3.4
*
* @return bool True if connected to The Free HUB, false otherwise.
*/
public static function is_hosted_site_connected_to_free_hub() {
return class_exists( 'WPMUDEV_Dashboard' ) &&
is_object( WPMUDEV_Dashboard::$api ) &&
method_exists( WPMUDEV_Dashboard::$api, 'get_membership_status' ) &&
'free' === WPMUDEV_Dashboard::$api->get_membership_status() &&
isset( $_SERVER['WPMUDEV_HOSTED'] );
}
/**
* Try to cast a source URL to a path
*
* @param string $src Source.
*
* @return string
*/
public static function src_to_path( $src ) {
$path = wp_parse_url( $src );
// Scheme will not be set on a URL.
$url = isset( $path['scheme'] );
if ( ! isset( $path['path'] ) ) {
return '';
}
$path = ltrim( $path['path'], '/' );
/**
* DOCUMENT_ROOT does not always store the correct path. For example, Bedrock appends /wp/ to the default dir.
* So if the source is a URL, we can safely use DOCUMENT_ROOT, else see if ABSPATH is defined.
*/
if ( $url ) {
$path = path_join( $_SERVER['DOCUMENT_ROOT'], $path );
} else {
$root = defined( 'ABSPATH' ) ? ABSPATH : $_SERVER['DOCUMENT_ROOT'];
$path = path_join( $root, $path );
}
$path = wp_normalize_path( $path );
return apply_filters( 'wphb_src_to_path', $path, $src );
}
/**
* Enqueues admin scripts
*
* @param int $ver Current version number of scripts.
*/
public static function enqueue_admin_scripts( $ver ) {
wp_enqueue_script( 'wphb-admin', WPHB_DIR_URL . 'admin/assets/js/wphb-app.min.js', array( 'jquery', 'underscore' ), $ver, true );
$last_report = Modules\Performance::get_last_report();
if ( is_object( $last_report ) && isset( $last_report->data ) ) {
$desktop_score = is_object( $last_report->data->desktop ) ? $last_report->data->desktop->score : '-';
$mobile_score = is_object( $last_report->data->mobile ) ? $last_report->data->mobile->score : '-';
}
$i10n = array(
'cloudflare' => array(
'is' => array(
'connected' => self::get_module( 'cloudflare' )->is_connected() && self::get_module( 'cloudflare' )->is_zone_selected(),
),
),
'nonces' => array(
'HBFetchNonce' => wp_create_nonce( 'wphb-fetch' ),
),
'strings' => array(
/* Performance test strings */
'previousScoreMobile' => isset( $mobile_score ) ? $mobile_score : '-',
'previousScoreDesktop' => isset( $desktop_score ) ? $desktop_score : '-',
'aoStatus' => self::is_ao_processing() ? 'incomplete' : 'complete',
'removeButtonText' => __( 'Remove', 'wphb' ),
'youLabelText' => __( 'You', 'wphb' ),
'scanRunning' => __( 'Running speed test...', 'wphb' ),
'scanAnalyzing' => __( 'Analyzing data and preparing report...', 'wphb' ),
'scanWaiting' => __( 'Test is taking a little longer than expected, hang in there…', 'wphb' ),
'scanComplete' => __( 'Test complete! Reloading...', 'wphb' ),
/* Caching strings */
'errorCachePurge' => __( 'There was an error during the cache purge. Check folder permissions are 755 for /wp-content/wphb-cache or delete directory manually.', 'wphb' ),
'successGravatarPurge' => __( 'Gravatar cache purged.', 'wphb' ),
'successPageCachePurge' => __( 'Page cache purged.', 'wphb' ),
'errorRecheckStatus' => __( 'There was an error re-checking the caching status, please try again later.', 'wphb' ),
'successRecheckStatus' => __( 'Browser caching status updated.', 'wphb' ),
'successCloudflarePurge' => __( 'Cloudflare cache successfully purged. Please wait 30 seconds for the purge to complete.', 'wphb' ),
'successRedisPurge' => __( 'Your cache has been cleared.', 'wphb' ),
'selectZone' => __( 'Select zone', 'wphb' ),
/* Misc */
'errorSettingsUpdate' => __( 'Error updating settings', 'wphb' ),
'errorEmptyName' => __( 'Error: Please enter your name', 'wphb' ),
'successUpdate' => __( 'Settings updated', 'wphb' ),
'deleteAll' => __( 'Delete All Permanently', 'wphb' ),
'dbDeleteButton' => __( 'Delete permanently', 'wphb' ),
'dbDeleteDraftsButton' => __( 'Clear draft posts', 'wphb' ),
'db_delete' => __( 'Are you sure you wish to delete', 'wphb' ),
'dbDeleteDrafts' => __( 'Are you sure you want to clear draft posts and move them to the trash? Trashed posts can be permanently deleted below.', 'wphb' ),
'db_entries' => __( 'database entries', 'wphb' ),
'db_backup' => __( 'Make sure you have a current backup just in case.', 'wphb' ),
'dismissLabel' => __( 'Dismiss', 'wphb' ),
'successAdvPurgeCache' => __( 'Preload cache purged successfully.', 'wphb' ),
'successAdvPurgeMinify' => __( 'All database data and Custom Post Type information related to Asset Optimization has been cleared successfully.', 'wphb' ),
'successAoOrphanedPurge' => __( 'Database entries removed successfully.', 'wphb' ),
/* Cloudflare */
'CloudflareHelpAPItoken' => __( 'Need help getting your API token?', 'wphb' ),
'CloudflareHelpAPIkey' => __( 'Need help getting your Global API key?', 'wphb' ),
/* Notifications */
'removeRecipient' => __( 'Remove recipient', 'wphb' ),
'noRecipients' => __( "You've not added the users. In order to activate the notification you need to add users first.", 'wphb' ),
'noRecipientDisable' => __( "You've removed all recipients. If you save without a recipient, we'll automatically turn off notifications.", 'wphb' ),
'recipientExists' => __( 'Recipient already exists.', 'wphb' ),
'awaitingConfirmation' => __( 'Awaiting confirmation', 'wphb' ),
'resendInvite' => __( 'Resend invite email', 'wphb' ),
'addRecipient' => __( 'Add recipient', 'wphb' ),
'successCriticalCssPurge' => __( 'Cache purged. Regenerating Critical CSS, this could take about a minute.', 'wphb' ),
'criticalGeneratedNotice' => __( 'Critical CSS generated. Please visit the site and let the cache build up before running a test.', 'wphb' ),
'errorCriticalCssPurge' => __( 'There was an error during the critical css files purge. Check folder permissions are 755 for /wp-content/wphb-cache/critical-css or delete directory manually.', 'wphb' ),
'enableCriticalCss' => __( 'Settings updated. Generating Critical CSS, this could take about a minute.', 'wphb' ),
'select2Tags' => __( 'Please type any keywords and press Enter', 'wphb' ),
'exclusionFiles' => __( 'Files', 'wphb' ),
'exclusionPostTypes' => __( 'Post Types', 'wphb' ),
'exclusionPostUrls' => __( 'Post URLs', 'wphb' ),
'exclusionPluginThemes' => __( 'Plugins/Themes', 'wphb' ),
'exclusionKeywords' => __( 'Keywords', 'wphb' ),
'exclusionDefault' => __( 'Default Exclusion', 'wphb' ),
'exclusionAds' => __( 'Ads/Trackers', 'wphb' ),
'exclusionAll' => __( 'All Exclusion', 'wphb' ),
'exclusionWpFile' => __( 'WP File', 'wphb' ),
),
'links' => array(
'audits' => self::get_admin_menu_url( 'performance' ),
'eoUrl' => self::get_admin_menu_url( 'minification' ) . '&view=tools',
'cachingPageURL' => self::get_admin_menu_url( 'caching' ),
'tutorials' => self::get_admin_menu_url( 'tutorials' ),
'tutorialsUTM' => self::get_link( 'tutorials', 'hummingbird_dashboard_tutorials' ),
'notifications' => self::get_admin_menu_url( 'notifications' ),
'disableUptime' => add_query_arg(
array(
'action' => 'disable',
'_wpnonce' => wp_create_nonce( 'wphb-toggle-uptime' ),
),
self::get_admin_menu_url( 'uptime' )
),
'resetSettings' => add_query_arg(
array(
'wphb-clear' => 'all',
'_wpnonce' => wp_create_nonce( 'wphb-clear-cache' ),
),
self::get_admin_menu_url()
),
),
);
$minify_module = self::get_module( 'minify' );
$is_scanning = $minify_module->scanner->is_scanning();
$get_ao_stats = self::get_ao_stats_data();
$minify_options = $minify_module->get_options();
if ( $minify_module->is_on_page() || $is_scanning ) {
$i10n = array_merge_recursive(
$i10n,
array(
'minification' => array(
'criticalStatusForQueue' => self::get_module( 'critical_css' )->critical_css_status_for_queue(),
'gutenbergUpgradeCTAUrl' => self::get_link( 'plugin', 'hummingbird_criticalcss_gutenberg' ),
'is' => array(
'scanning' => $is_scanning,
'scanned' => $minify_module->scanner->is_files_scanned(),
),
'get' => array(
'currentScanStep' => $minify_module->scanner->get_current_scan_step(),
'totalSteps' => $minify_module->scanner->get_scan_steps(),
'showCDNModal' => ! is_multisite(),
'showSwitchModal' => (bool) get_option( 'wphb-minification-show-config_modal' ),
),
),
'strings' => array(
'aoSettingsSaved' => __( 'Your changes have been published. Note: Files queued for compression will generate once someone visits your homepage.', 'wphb' ),
),
'links' => array(
'minification' => self::get_admin_menu_url( 'minification' ),
),
'stats' => array(
'assetsFound' => $get_ao_stats['enqueued_files'],
'type' => $minify_options['type'],
'totalFiles' => self::minified_files_count(),
'filesizeReductions' => absint( $get_ao_stats['compressed_size'] ),
),
'isMinifyPage' => sanitize_text_field( filter_input( INPUT_GET, 'page', FILTER_UNSAFE_RAW ) ),
)
);
}
if ( ! apply_filters( 'wpmudev_branding_hide_doc_link', false ) && $minify_module->is_on_page( true ) ) {
wp_enqueue_script( 'wphb-react-tutorials', WPHB_DIR_URL . 'admin/assets/js/wphb-react-tutorials.min.js', array( 'wp-i18n' ), WPHB_VERSION, true );
}
$i10n = array_merge_recursive(
$i10n,
self::get_tracking_data()
);
wp_localize_script( 'wphb-admin', 'wphb', $i10n );
}
/**
* Generate all tracking data for use in JS/React scripts.
*
* @since 3.3.1 Moved out from enqueue_admin_scripts().
*
* @return array
*/
public static function get_tracking_data() {
return array(
'mixpanel' => array(
'enabled' => Settings::get_setting( 'tracking', 'settings' ),
),
);
}
/**
* Returns Jed-formatted localization data
*
* @since 3.0.0
*
* @return array
*/
public static function get_locale_data() {
$translations = get_translations_for_domain( 'wphb' );
$locale = array(
'' => array(
'domain' => 'wphb',
'lang' => is_admin() ? get_user_locale() : get_locale(),
),
);
if ( ! empty( $translations->headers['Plural-Forms'] ) ) {
$locale['']['plural_forms'] = $translations->headers['Plural-Forms'];
}
foreach ( $translations->entries as $msgid => $entry ) {
$locale[ $msgid ] = $entry->translations;
}
return $locale;
}
/**
* Return the needed capability for admin pages.
*
* @return string
*/
public static function get_admin_capability() {
$cap = 'manage_options';
$is_network_admin = is_network_admin() || self::is_ajax_network_admin();
if ( is_multisite() && $is_network_admin ) {
$cap = 'manage_network';
}
return apply_filters( 'wphb_admin_capability', $cap );
}
/**
* Get Current username info
*/
public static function get_current_user_name() {
$current_user = wp_get_current_user();
if ( ! ( $current_user instanceof WP_User ) ) {
return false;
}
if ( ! empty( $current_user->user_firstname ) ) { // First we try to grab user First Name.
return $current_user->user_firstname;
}
return $current_user->user_nicename;
}
/**
* This function will calculate the sum of file sizes in an array.
*
* We need this, because Asset Optimization module will store 'original_size' and 'compressed_size' values as
* strings, and such strings will contain instead of spaces, thus making it impossible to sum all the
* values with array_sum().
*
* @since 1.9.2
*
* @param array $arr Array of items with sizes as strings.
*
* @return float
*/
public static function calculate_sum( $arr ) {
$sum = 0;
// Get separators from locale. Some Windows servers will return blank values.
$locale = localeconv();
$thousands_sep = isset( $locale['thousands_sep'] ) ? $locale['thousands_sep'] : ',';
$decimal_point = isset( $locale['decimal_point'] ) ? $locale['decimal_point'] : '.';
foreach ( $arr as $value ) {
if ( is_null( $value ) ) {
continue;
}
// Remove spaces.
$sum += (float) str_replace(
array( ' ', $thousands_sep, $decimal_point ),
array( '', '', '.' ),
$value
);
}
return $sum;
}
/**
* Return the file size in a humanly readable format.
*
* Taken from http://www.php.net/manual/en/function.filesize.php#91477
*
* @since 2.0.0
*
* @param int $bytes Number of bytes.
* @param int $precision Precision.
*
* @return string
*/
public static function format_bytes( $bytes, $precision = 1 ) {
$units = array( 'B', 'KB', 'MB', 'GB', 'TB' );
$bytes = max( $bytes, 0 );
$pow = floor( ( $bytes ? log( $bytes ) : 0 ) / log( 1024 ) );
$pow = min( $pow, count( $units ) - 1 );
$bytes /= pow( 1024, $pow );
return round( $bytes, $precision ) . ' ' . $units[ $pow ];
}
/**
* Convert seconds to a readable value.
*
* @since 2.0.0
*
* @param int $seconds Number of seconds.
*
* @return string
*/
public static function format_interval( $seconds ) {
if ( 3600 <= $seconds && 86400 > $seconds ) {
return floor( $seconds / HOUR_IN_SECONDS ) . ' h';
}
if ( 86400 <= $seconds && 2419200 > $seconds ) {
return floor( $seconds / DAY_IN_SECONDS ) . ' d';
}
if ( 2419200 <= $seconds && 31536000 > $seconds ) {
return floor( $seconds / MONTH_IN_SECONDS ) . ' m';
}
if ( 31536000 < $seconds && 26611200 >= $seconds ) {
return floor( $seconds / YEAR_IN_SECONDS ) . ' y';
}
return '-';
}
/**
* Format hours into days.
*
* @since 2.1.0
*
* @param int $hours Number of hours.
*
* @return array
*/
public static function format_interval_hours( $hours ) {
if ( $hours <= 24 ) {
return array( $hours, 'hours' );
}
$days = floor( $hours / 24 );
return array( $days, 'days' );
}
/**
* Check if network admin.
*
* The is_network_admin() check does not work in AJAX calls.
*
* @since 3.0.0
*
* @return bool
*/
public static function is_ajax_network_admin() {
if ( ! is_multisite() ) {
return false;
}
return defined( 'DOING_AJAX' ) && DOING_AJAX && self::is_referrer_network_admin(); // Input var ok.
}
/**
* Check if network admin url in ajax call.
*
* @return bool
*/
public static function is_referrer_network_admin() {
return isset( $_SERVER['HTTP_REFERER'] ) && preg_match( '#^' . network_admin_url() . '#i', wp_unslash( $_SERVER['HTTP_REFERER'] ) ); // Input var ok.
}
/***************************
*
* II. Layout functions
* get_whitelabel_class()
***************************/
/**
* Return rebranded class.
*
* @since 3.1.0
*
* @return string
*/
public static function get_whitelabel_class() {
if ( ! apply_filters( 'wpmudev_branding_hide_branding', false ) ) {
return '';
}
return apply_filters( 'wpmudev_branding_hero_image', '' ) ? 'sui-rebranded' : 'sui-unbranded';
}
/***************************
*
* III. Time and date functions
* human_read_time_diff()
* get_days_of_week()
* get_times()
* get_timezone_string()
***************************/
/**
* Credits to: http://stackoverflow.com/a/11389893/1502521
*
* @param int $seconds Seconds.
*
* @return string
*/
public static function human_read_time_diff( $seconds ) {
if ( ! $seconds ) {
return __( 'Disabled', 'wphb' );
}
$minutes = 0;
$hours = 0;
$days = 0;
$months = 0;
$years = 0;
while ( $seconds >= YEAR_IN_SECONDS ) {
$years ++;
$seconds = $seconds - YEAR_IN_SECONDS;
}
while ( $seconds >= MONTH_IN_SECONDS ) {
$months ++;
$seconds = $seconds - MONTH_IN_SECONDS;
}
while ( $seconds >= DAY_IN_SECONDS ) {
$days ++;
$seconds = $seconds - DAY_IN_SECONDS;
}
while ( $seconds >= HOUR_IN_SECONDS ) {
$hours++;
$seconds = $seconds - HOUR_IN_SECONDS;
}
while ( $seconds >= MINUTE_IN_SECONDS ) {
$minutes++;
$seconds = $seconds - MINUTE_IN_SECONDS;
}
$diff = new stdClass();
$diff->y = $years;
$diff->m = $months;
$diff->d = $days;
$diff->h = $hours;
$diff->i = $minutes;
$diff->s = $seconds;
if ( $diff->y || ( 11 === $diff->m && 30 <= $diff->d ) ) {
$years = $diff->y;
if ( 11 === $diff->m && 30 <= $diff->d ) {
$years++;
}
/* translators: %d: year */
$diff_time = sprintf( _n( '%d year', '%d years', $years, 'wphb' ), $years );
} elseif ( $diff->m ) {
/* translators: %d: month */
$diff_time = sprintf( _n( '%d month', '%d months', $diff->m, 'wphb' ), $diff->m );
} elseif ( $diff->d ) {
/* translators: %d: day */
$diff_time = sprintf( _n( '%d day', '%d days', $diff->d, 'wphb' ), $diff->d );
} elseif ( $diff->h ) {
/* translators: %d: hour */
$diff_time = sprintf( _n( '%d hour', '%d hours', $diff->h, 'wphb' ), $diff->h );
} elseif ( $diff->i ) {
/* translators: %d: minute */
$diff_time = sprintf( _n( '%d minute', '%d minutes', $diff->i, 'wphb' ), $diff->i );
} else {
/* translators: %d: second */
$diff_time = sprintf( _n( '%d second', '%d seconds', $diff->s, 'wphb' ), $diff->s );
}
return $diff_time;
}
/**
* Get days of the week.
*
* @since 1.4.5
*
* @return mixed
*/
public static function get_days_of_week() {
$timestamp = date_create( 'next Monday' );
if ( 7 === get_option( 'start_of_week' ) ) {
$timestamp = date_create( 'next Sunday' );
}
$days = array();
for ( $i = 0; $i < 7; $i ++ ) {
$days[] = date_format( $timestamp, 'l' );
$timestamp = date_modify( $timestamp, '+1 day' );
}
return apply_filters( 'wphb_scan_get_days_of_week', $days );
}
/**
* Return times frame for select box
*
* @since 1.4.5
*
* @return mixed
*/
public static function get_times() {
$data = array();
for ( $i = 0; $i < 24; $i ++ ) {
foreach ( apply_filters( 'wphb_scan_get_times_interval', array( '00' ) ) as $min ) {
$time = $i . ':' . $min;
$data[ $time ] = apply_filters( 'wphb_scan_get_times_hour_min', $time );
}
}
return apply_filters( 'wphb_scan_get_times', $data );
}
/**
* Return time zone string.
*
* @since 3.1.1
*
* @return string
*/
public static function get_timezone_string() {
$current_offset = get_option( 'gmt_offset' );
$tzstring = get_option( 'timezone_string' );
if ( empty( $tzstring ) ) { // Create a UTC+- zone if no timezone string exists.
if ( 0 === $current_offset ) {
$tzstring = 'UTC+0';
} elseif ( $current_offset < 0 ) {
$tzstring = 'UTC' . $current_offset;
} else {
$tzstring = 'UTC+' . $current_offset;
}
}
return $tzstring;
}
/***************************
*
* IV. Link and url functions
* get_link()
* get_documentation_url()
* still_having_trouble_link()
* get_admin_menu_url()
* get_avatar_url()
***************************/
/**
* Return URL link.
*
* @param string $link_for Accepts: 'chat', 'plugin', 'support', 'smush', 'docs'.
* @param string $campaign Utm campaign tag to be used in link. Default: 'hummingbird_pro_modal_upgrade'.
* @param string $hub_campaign Utm campaign tag to be used to redirect to HUb site.
*
* @return string
*/
public static function get_link( $link_for, $campaign = 'hummingbird_pro_modal_upgrade', $hub_campaign = '' ) {
$domain = 'https://wpmudev.com';
$wp_org = 'https://wordpress.org';
$utm_tags = "?utm_source=hummingbird&utm_medium=plugin&utm_campaign=$campaign";
$pro_utm_tags = "?utm_source=hummingbird-pro&utm_medium=plugin&utm_campaign=$campaign";
if ( defined( 'WPMUDEV_CUSTOM_API_SERVER' ) && WPMUDEV_CUSTOM_API_SERVER ) {
$domain = WPMUDEV_CUSTOM_API_SERVER;
}
switch ( $link_for ) {
case 'configs':
$link = "$domain/hub2/configs/my-configs";
break;
case 'hub-welcome':
$link = "$domain/hub-welcome/$utm_tags";
break;
case 'chat':
$link = "$domain/live-support/$utm_tags";
break;
case 'plugin':
$link = "$domain/project/wp-hummingbird/$utm_tags";
break;
case 'support':
if ( self::is_member() ) {
$link = "$domain/hub2/support/#get-support";
} else {
$link = "$wp_org/support/plugin/hummingbird-performance";
}
break;
case 'docs':
$link = "$domain/docs/wpmu-dev-plugins/hummingbird/$utm_tags";
break;
case 'smush':
if ( self::is_member() ) {
// Return the pro plugin URL.
$url = WPMUDEV_Dashboard::$ui->page_urls->plugins_url;
$link = $url . '#pid=912164';
} else {
// Return the free URL.
$link = wp_nonce_url( self_admin_url( 'update.php?action=install-plugin&plugin=wp-smushit' ), 'install-plugin_wp-smushit' );
}
break;
case 'smush-plugin':
$link = "$domain/project/wp-smush-pro/$utm_tags";
break;
case 'hosting':
$link = "$domain/register/$utm_tags&coupon=HUMMINGBIRD-HOSTING-1M&from_checkout=1";
break;
case 'hosting-upsell':
$link = "$domain/hosting/$utm_tags#dev-plans";
break;
case 'wpmudev':
$link = "$domain/$utm_tags";
break;
case 'tutorials':
$link = "$domain/blog/tutorials/tutorial-category/hummingbird-pro/$utm_tags";
break;
case 'tracking':
if ( self::is_member() ) {
$link = "$domain/docs/privacy/our-plugins/#usage-tracking";
} else {
$link = "$domain/docs/privacy/our-plugins/?utm_source=hummingbird&utm_medium=plugin&utm_campaign=hummingbird_tracking_consent_docs#usage-tracking-hb";
}
break;
case 'wpmudev-login':
$link = "$domain/login?signin=$hub_campaign&hummingbird_url=" . site_url();
break;
case 'connect-url':
$link = self::connect_url( $domain, ltrim( $utm_tags, '?' ) );
break;
case 'expert-services':
$link = "$domain/hub2/services/$pro_utm_tags";
break;
case 'get-support':
$link = "$domain/hub2/support/$pro_utm_tags";
break;
default:
$link = '';
break;
}
return $link;
}
/**
* Returns the signup url.
* If Dashboard plugin is active the signup url returned will be the Dashboard signup page. Else Hub signup page.
*
* @param string $domain Domain name.
* @param string $utm_tags UTM Tags.
* @return string
*/
public static function connect_url( $domain, $utm_tags ) {
if ( self::is_dash_plugin_active_and_disconnected() ) {
return add_query_arg(
array(
'page' => 'wpmudev',
),
is_multisite() ? network_admin_url() : get_admin_url()
) . '&' . $utm_tags;
}
return $domain . '/hub2/connect?' . $utm_tags;
}
/**
* Check if Dash plugin is active and disconnected.
*
* @return bool
*/
public static function is_dash_plugin_active_and_disconnected() {
return class_exists( 'WPMUDEV_Dashboard' ) && ! WPMUDEV_Dashboard::$api->has_key();
}
/**
* Get documentation URL.
*
* @since 1.7.0
*
* @param string $page Page slug.
* @param string $view View slug.
*
* @return string
*/
public static function get_documentation_url( $page, $view = '' ) {
switch ( $page ) {
case 'wphb-performance':
if ( 'reports' === $view ) {
$anchor = '#reporting';
} elseif ( 'settings' === $view ) {
$anchor = '#performance-test-settings';
} else {
$anchor = '#performance-test';
}
break;
case 'wphb-caching':
$anchor = '#caching';
break;
case 'wphb-gzip':
$anchor = '#gzip-compression';
break;
case 'wphb-minification':
$anchor = '#asset-optimization';
break;
case 'wphb-advanced':
$anchor = '#advanced-tools';
break;
case 'wphb-uptime':
$anchor = '#uptime';
break;
case 'wphb-settings':
$anchor = '#settings';
break;
case 'wphb-notifications':
$anchor = '#notifications';
break;
default:
$anchor = '';
}
return 'https://wpmudev.com/docs/wpmu-dev-plugins/hummingbird/' . $anchor;
}
/**
* Display start a live chat link for pro user or open support ticket for non-pro user.
*/
public static function still_having_trouble_link() {
esc_html_e( 'Still having trouble? ', 'wphb' );
if ( self::is_member() && ! apply_filters( 'wpmudev_branding_hide_branding', false ) ) :
?>
<a target="_blank" href="<?php echo esc_url( self::get_link( 'chat' ) ); ?>">
<?php esc_html_e( 'Start a live chat.', 'wphb' ); ?>
</a>
<?php else : ?>
<a target="_blank" href="<?php echo esc_url( self::get_link( 'support' ) ); ?>">
<?php esc_html_e( 'Open a support ticket.', 'wphb' ); ?>
</a>
<?php
endif;
}
/**
* Get url for plugin module page.
*
* @param string $page Page.
*
* @return string
*/
public static function get_admin_menu_url( $page = '' ) {
$hummingbird = WP_Hummingbird::get_instance();
if ( is_object( $hummingbird->admin ) ) {
$page_slug = empty( $page ) ? 'wphb' : 'wphb-' . $page;
$page = $hummingbird->admin->get_admin_page( $page_slug );
if ( $page ) {
return $page->get_page_url();
}
}
return '';
}
/**
* Get avatar URL.
*
* @since 1.4.5
*
* @param string $get_avatar User email.
*
* @return mixed
*/
public static function get_avatar_url( $get_avatar ) {
preg_match( "/src='(.*?)'/i", $get_avatar, $matches );
return $matches[1];
}
/***************************
*
* V. Modules functions
* get_api()
* pro()
* admin()
* get_modules()
* get_module()
* get_active_cache_modules()
* get_number_of_issues()
* minified_files_count()
* remove_quick_setup()
***************************/
/**
* Get API.
*
* @return Api\API
*/
public static function get_api() {
$hummingbird = WP_Hummingbird::get_instance();
return $hummingbird->core->api;
}
/**
* Get PRO.
*/
public static function pro() {
$hummingbird = WP_Hummingbird::get_instance();
return $hummingbird->pro;
}
/**
* Get admin.
*
* @since 3.3.1
*/
public static function admin() {
$hummingbird = WP_Hummingbird::get_instance();
return $hummingbird->admin;
}
/**
* Return the list of modules and their object instances
*
* Do not try to load before 'wp_hummingbird_loaded' action has been executed
*
* @return array
*/
private static function get_modules() {
$hummingbird = WP_Hummingbird::get_instance();
return $hummingbird->core->modules;
}
/**
* Get a module instance
*
* @param string $module Module slug.
*
* @return bool|Module|Modules\Page_Cache|Modules\GZip|Modules\Minify|Modules\Cloudflare|Modules\Uptime|Modules\Performance|Modules\Advanced|Modules\Redis|Modules\Caching
*/
public static function get_module( $module ) {
$modules = self::get_modules();
return isset( $modules[ $module ] ) ? $modules[ $module ] : false;
}
/**
* Return human-readable names of active modules that have a cache.
*
* Checks Page, Gravatar & Asset Optimization.
*
* @return array
*/
public static function get_active_cache_modules() {
$modules = array(
'page_cache' => __( 'Page Cache', 'wphb' ),
'cloudflare' => __( 'Cloudflare', 'wphb' ),
'gravatar' => __( 'Gravatar Cache', 'wphb' ),
'minify' => __( 'Asset Optimization Cache', 'wphb' ),
'redis' => __( 'Redis Cache', 'wphb' ),
);
$hb_modules = self::get_modules();
foreach ( $modules as $module => $module_name ) {
// If inactive, skip to next step.
if ( 'cloudflare' !== $module && isset( $hb_modules[ $module ] ) && ! $hb_modules[ $module ]->is_active() ) {
unset( $modules[ $module ] );
}
// Fix Cloudflare clear cache appearing on dashboard if it had been previously enabled but then uninstalled and reinstalled HB.
// TODO: do we need this?
if ( 'cloudflare' === $module && isset( $hb_modules[ $module ] ) && ! $hb_modules[ $module ]->is_connected() && ! $hb_modules[ $module ]->is_zone_selected() ) {
unset( $modules[ $module ] );
}
}
return $modules;
}
/**
* Get the number of issues for selected module
*
* @since 1.8.1 Added $report parameter.
*
* @param string $module Module name.
* @param bool|array $report Current report.
*
* @return int
*/
public static function get_number_of_issues( $module, $report = false ) {
$issues = 0;
switch ( $module ) {
case 'caching':
$mod = self::get_module( $module );
if ( ! $report ) {
$mod->get_analysis_data();
$report = $mod->status;
}
// No report - break.
if ( ! $report ) {
break;
}
$recommended = $mod->get_recommended_caching_values();
foreach ( $report as $type => $value ) {
$t = strtolower( $type );
if ( empty( $value ) || $recommended[ $t ]['value'] > $value ) {
$issues++;
}
unset( $t );
}
break;
case 'gzip':
if ( ! $report ) {
$mod = self::get_module( $module );
$mod->get_analysis_data();
$report = $mod->status;
}
// No report - break.
if ( ! $report ) {
break;
}
$invalid = 0;
foreach ( $report as $type ) {
if ( ! $type || 'privacy' === $type ) {
$invalid++;
}
}
$issues = $invalid;
break;
}
return $issues;
}
/**
* Checks if current page is admin dashboard.
*
* @return boolean
*/
public static function is_admin_dashboard() {
if ( is_network_admin() || is_main_site() ) {
return function_exists( 'get_current_screen' ) && in_array( get_current_screen()->id, array( 'dashboard', 'dashboard-network' ), true );
}
return false;
}
/**
* Return the number of files used by minification.
*
* @since 1.4.5
*
* @param bool $only_minified Only minified files.
*
* @return int
*/
public static function minified_files_count( $only_minified = false ) {
$minify_module = self::get_module( 'minify' );
// Get files count.
$collection = $minify_module->get_resources_collection();
// Remove those assets that we don't want to display.
if ( is_array( $collection['styles'] ) ) {
foreach ( $collection['styles'] as $key => $item ) {
if ( ! apply_filters( 'wphb_minification_display_enqueued_file', true, $item, 'styles' ) ) {
unset( $collection['styles'][ $key ] );
}
// Keep only minified files.
if ( $only_minified && ! preg_match( '/\.min\.(css|js)/', basename( $item['src'] ) ) ) {
unset( $collection['styles'][ $key ] );
}
}
}
if ( is_array( $collection['scripts'] ) ) {
foreach ( $collection['scripts'] as $key => $item ) {
if ( ! apply_filters( 'wphb_minification_display_enqueued_file', true, $item, 'scripts' ) ) {
unset( $collection['scripts'][ $key ] );
}
// Keep only minified files.
if ( $only_minified && ! preg_match( '/\.min\.(css|js)/', basename( $item['src'] ) ) ) {
unset( $collection['scripts'][ $key ] );
}
}
}
return ( self::hb_count( $collection['scripts'] ) + self::hb_count( $collection['styles'] ) );
}
/**
* Returns a list of incompatible plugins if any
*
* @return array
*/
public static function get_incompat_plugin_list() {
$plugins = array();
$caching_plugins = array(
'autoptimize/autoptimize.php' => 'Autoptimize',
'litespeed-cache/litespeed-cache.php' => 'LiteSpeed Cache',
'speed-booster-pack/speed-booster-pack.php' => 'Speed Booster Pack',
'swift-performance-lite/performance.php' => 'Swift Performance Lite',
'w3-total-cache/w3-total-cache.php' => 'W3 Total Cache',
'wp-fastest-cache/wpFastestCache.php' => 'WP Fastest Cache',
'wp-optimize/wp-optimize.php' => 'WP-Optimize',
'wp-performance-score-booster/wp-performance-score-booster.php' => 'WP Performance Score Booster',
'wp-performance/wp-performance.php' => 'WP Performance',
'wp-super-cache/wp-cache.php' => 'WP Super Cache',
);
foreach ( $caching_plugins as $plugin => $plugin_name ) {
if ( is_plugin_active( $plugin ) ) {
$plugins[ $plugin ] = $plugin_name;
}
}
return $plugins;
}
/**
* Returns count of an array.
*
* @param array $countable_array An array element.
*/
public static function hb_count( $countable_array ) {
return is_countable( $countable_array ) ? count( $countable_array ) : 0;
}
/**
* Returns AO stats data.
*
* @return array
*/
public static function get_ao_stats_data() {
$minify_module = self::get_module( 'minify' );
$collection = $minify_module->get_resources_collection();
// Remove those assets that we don't want to display.
if ( is_array( $collection['styles'] ) ) {
foreach ( $collection['styles'] as $key => $item ) {
if ( ! apply_filters( 'wphb_minification_display_enqueued_file', true, $item, 'styles' )
|| ! isset( $item['original_size'], $item['compressed_size'] ) ) {
unset( $collection['styles'][ $key ] );
}
}
}
if ( is_array( $collection['scripts'] ) ) {
foreach ( $collection['scripts'] as $key => $item ) {
if ( ! apply_filters( 'wphb_minification_display_enqueued_file', true, $item, 'scripts' )
|| ! isset( $item['original_size'], $item['compressed_size'] ) ) {
unset( $collection['scripts'][ $key ] );
}
}
}
$enqueued_files = self::hb_count( $collection['scripts'] ) + self::hb_count( $collection['styles'] );
$original_size_styles = self::calculate_sum( wp_list_pluck( $collection['styles'], 'original_size' ) );
$original_size_scripts = self::calculate_sum( wp_list_pluck( $collection['scripts'], 'original_size' ) );
$original_size = $original_size_scripts + $original_size_styles;
$compressed_size_styles = self::calculate_sum( wp_list_pluck( $collection['styles'], 'compressed_size' ) );
$compressed_size_scripts = self::calculate_sum( wp_list_pluck( $collection['scripts'], 'compressed_size' ) );
$compressed_size = $compressed_size_scripts + $compressed_size_styles;
if ( ( $original_size_scripts + $original_size_styles ) <= 0 ) {
$percentage = 0;
} else {
$percentage = 100 - (int) $compressed_size * 100 / (int) $original_size;
}
$percentage = number_format_i18n( $percentage, 1 );
$compressed_size_styles = number_format( $original_size_styles - $compressed_size_styles, 0 );
$compressed_size_scripts = number_format( $original_size_scripts - $compressed_size_scripts, 0 );
// Internalization numbers.
$original_size = number_format_i18n( $original_size, 1 );
$compressed_size = number_format_i18n( $compressed_size, 1 );
$data = compact( 'enqueued_files', 'original_size', 'compressed_size', 'compressed_size_scripts', 'compressed_size_styles', 'percentage' );
return $data;
}
/**
* Returns HB active features.
*
* @return array
*/
public static function get_active_features() {
$active_features = array();
$minify_options = self::get_module( 'minify' )->get_options();
$advanced_options = self::get_module( 'advanced' )->get_options();
$hb_cdn = false;
// CDN.
if ( self::get_module( 'minify' )->is_active() && $minify_options['use_cdn'] ) {
$active_features[] = 'CDN';
$hb_cdn = true;
}
// Critical CSS.
if ( self::get_module( 'minify' )->is_active() && ! empty( $minify_options['critical_css'] ) ) {
if ( 'remove' === $minify_options['critical_css_type'] ) {
$active_features[] = 'user_interaction_with_remove' === $minify_options['critical_css_remove_type'] ? 'criticalcss_fullpage_delay' : 'criticalcss_fullpage_remove';
} elseif ( 'asynchronously' === $minify_options['critical_css_type'] ) {
$active_features[] = 'load_stylesheet_on_user_interaction' === $minify_options['above_fold_load_stylesheet_method'] ? 'criticalcss_abovefold_delay' : 'criticalcss_abovefold_async';
}
}
// Delay.
if ( self::get_module( 'minify' )->is_active() && ! empty( $minify_options['delay_js'] ) ) {
$active_features[] = 'JS Delay';
}
// AO_Speedy','AO_Basic','AO_Manual'.
if ( self::get_module( 'minify' )->is_active() ) {
if ( 'advanced' == $minify_options['view'] ) {
$active_features[] = 'AO_Manual';
} else {
if ( 'speedy' == $minify_options['type'] ) {
$active_features[] = 'AO_Speedy';
} else {
$active_features[] = 'AO_Basic';
}
}
// Font preload feature.
if ( ! empty( $minify_options['critical_css'] ) && ! empty( $minify_options['font_optimization'] ) ) {
$active_features[] = 'font_preload_auto';
} elseif ( ! empty( $minify_options['font_optimization'] ) ) {
$active_features[] = 'font_preload_manual';
}
// Font swap.
if ( ! empty( $minify_options['font_swap'] ) ) {
$active_features[] = 'optional' === $minify_options['font_display_value'] ? 'font_display_optional' : 'font_display_swap';
}
}
// GZip.
if ( self::get_module( 'gzip' )->is_active() ) {
$active_features[] = 'br' === get_option( 'wphb_compression_type' ) || $hb_cdn ? 'Brotli' : 'GZip';
}
// Gravatar.
if ( self::get_module( 'gravatar' )->is_active() ) {
$active_features[] = 'Gravatar';
}
// Page Caching.
if ( self::get_module( 'page_cache' )->is_active() ) {
if ( ! self::get_api()->hosting->has_fast_cgi_header() ) {
$active_features[] = 'Page Caching';
}
$options = self::get_module( 'page_cache' )->get_options();
if ( ! empty( $options['preload'] ) && ! empty( $options['preload_type'] ['home_page'] ) ) {
$active_features[] = 'preload_homepage';
}
}
// Redis Cache.
if ( self::get_module( 'redis' )->is_active() ) {
$active_features[] = 'Redis Cache';
}
// RSS Caching.
if ( self::get_module( 'rss' )->is_active() ) {
$active_features[] = 'RSS Caching';
}
// Cloudflare_integration.
if ( self::get_module( 'cloudflare' )->is_connected() ) {
$active_features[] = 'Cloudflare_integration';
}
// Lazy_comments (Advanced tools).
if ( isset( $advanced_options['lazy_load'] ) && $advanced_options['lazy_load']['enabled'] ) {
$active_features[] = 'lazy_comments';
}
// Remove_query_strings (Advanced tools).
if ( ! empty( $advanced_options['query_string'] ) ) {
$active_features[] = 'remove_query_strings';
}
// Disable_cart_fragments (Advanced tools).
if ( ! empty( $advanced_options['cart_fragments'] ) ) {
$active_features[] = 'disable_cart_fragments';
}
// Remove_emojis (Advanced tools).
if ( ! empty( $advanced_options['emoji'] ) ) {
$active_features[] = 'remove_emojis';
}
// Prefetch_dns (Advanced tools).
if ( ! empty( $advanced_options['prefetch'] ) ) {
$active_features[] = 'prefetch_dns';
}
// Preconnect_domains (Advanced tools).
if ( ! empty( $advanced_options['preconnect'] ) ) {
$active_features[] = 'preconnect_domains';
}
// Track hosting cache.
if ( self::get_api()->hosting->has_fast_cgi_header() ) {
$active_features[] = 'hosting_static_cache';
}
// Track high frequency site.
if ( self::is_site_hosted_on_wpmudev() ) {
$active_features[] = Fast_CGI::is_high_frequency_hosted_site() ? 'hosted_high_frequency' : 'hosted_regular';
}
// Track browser cache status.
$active_features[] = self::wphb_get_browser_status_for_mp();
// Viewport_meta (Advanced tools).
if ( ! empty( $advanced_options['viewport_meta'] ) ) {
$active_features[] = 'viewport_meta';
}
/**
* Filters the HB active features for MP.
*
* @since 3.6.0
*
* @param array $active_features An array of active features.
*
* @return array
*/
$active_features = apply_filters( 'wphb_tracking_active_features', $active_features );
return $active_features;
}
/**
* Returns browser caching status for MP.
*
* @return string
*/
public static function wphb_get_browser_status_for_mp() {
$caching_data = self::get_module( 'caching' )->get_analysis_data( true );
foreach ( $caching_data as $data ) {
if ( empty( $data ) || $data < YEAR_IN_SECONDS ) {
return 'browser_caching_fail';
}
}
return 'browser_caching_pass';
}
/**
* Check if page builder is active.
*
* @return bool
*/
public static function wphb_is_page_builder() {
$page_builders = apply_filters(
'wphb_page_builders',
array(
'elementor-preview', // Elementor.
'cs_preview_state', // Cornerstone Builder.
'fl_builder', // Beaver builder.
'et_fb', // Divi.
'ct_builder', // Oxygen.
'tve', // Thrive.
'app', // flatsome.
'uxb_iframe',
'fb-edit', // fusion builder.
'builder',
'bricks', // bricks.
'vc_editable', // wp bakery.
)
);
if ( ! empty( $page_builders ) ) {
foreach ( $page_builders as $page_builder ) {
if ( isset( $_GET[ $page_builder ] ) ) {
return true;
}
}
}
return false;
}
/**
* Returns current user name to be displayed.
*
* @return string
*/
public static function get_user_name() {
$current_user = wp_get_current_user();
return ! empty( $current_user->first_name ) ? $current_user->first_name : $current_user->display_name;
}
/**
* Display unlock pro upsell link.
*
* @param string $location Location of the unlock pro upsell.
* @param string $utm UTM for Upsell.
* @param string $event_name Event name for MP.
* @param bool $display Whether to echo or return the link. Default true.
* @param bool $is_eo_link Is EO upsell link.
*/
public static function unlock_now_link( $location, $utm, $event_name, $display = true, $is_eo_link = false ) {
$upsell_link = $is_eo_link ? esc_html__( 'Unlock now for Peak Performance ️⚡️ - 80% Off!', 'wphb' ) : esc_html__( 'Unlock now', 'wphb' );
$html = sprintf(
'<a target="_blank" data-location="%1$s" href="%2$s" data-eventname="%3$s" id="%4$s" class="wphb-upsell-link wphb-upsell-eo" onclick="WPHB_Admin.minification.hbTrackEoMPEvent( this )">
%5$s
<span class="sui-icon-open-new-window" aria-hidden="true"></span>
</a>',
esc_attr( $location ),
esc_url( self::get_link( 'plugin', $utm ) ),
$event_name,
'legacy_switch' === $location ? 'manual_css_switch_now' : '',
$upsell_link
);
if ( $display ) {
echo $html;
} else {
return $html;
}
}
/**
* Checks whether AMP content is being served.
*
* @since 3.7.0
*
* @return bool True if an AMP request, false otherwise.
*/
public static function is_amp() {
if ( is_singular( 'web-story' ) ) {
return true;
}
// amp_is_request For AMP plugin v2.0+ and is_amp_endpoint For older/other AMP plugins.
return ( function_exists( 'is_amp_endpoint' ) && is_amp_endpoint() ) || ( function_exists( 'amp_is_request' ) && amp_is_request() );
}
/**
* Returns plugin discount.
*
* @since 3.7.1
*
* @return string
*/
public static function get_plugin_discount() {
return self::HB_PLUGIN_DISCOUNT . '%';
}
/**
* Determines whether the site is Hosted on WPMUDEV and whitelabel is disabled.
*
* @since 3.8.0
*
* @return bool True if the site is Hosted on WPMUDEV and whitelabel is disabled, false otherwise.
*/
public static function is_site_hosted_with_whitelabel_disabled() {
return ! self::is_whitelabel_enabled() && isset( $_SERVER['WPMUDEV_HOSTED'] );
}
/**
* Determines whether whitelabel is enabled.
*
* @since 3.8.0
*
* @return bool True if whitelabel is enabled, false otherwise.
*/
public static function is_whitelabel_enabled() {
return class_exists( 'WPMUDEV_Dashboard' ) &&
is_object( WPMUDEV_Dashboard::$whitelabel ) &&
method_exists( WPMUDEV_Dashboard::$whitelabel, 'is_whitelabel_enabled' ) &&
WPMUDEV_Dashboard::$whitelabel->is_whitelabel_enabled();
}
public static function get_performance_metrics() {
return array(
'speed-index',
'first-contentful-paint',
'largest-contentful-paint',
'total-blocking-time',
'cumulative-layout-shift',
);
}
/**
* Returns Google speed metrics.
*
* @return array
*/
public static function get_performance_metric_for_mp() {
$report = Modules\Performance::get_last_report();
$metrics = array(
'speed-index' => 'speed',
'first-contentful-paint' => 'fcp',
'largest-contentful-paint' => 'lcp',
'total-blocking-time' => 'tbt',
'cumulative-layout-shift' => 'cls',
);
$mobile_report = $report->data->mobile;
$desktop_report = $report->data->desktop;
$mobile_data = array();
$desktop_data = array();
// Historic field data.
$mobile_data['inp_mobile'] = isset( $report->data->mobile->field_data->INTERACTION_TO_NEXT_PAINT->percentile ) ? esc_html( $report->data->mobile->field_data->INTERACTION_TO_NEXT_PAINT->percentile ) : 'N/A';
$desktop_data['inp_desktop'] = isset( $report->data->desktop->field_data->INTERACTION_TO_NEXT_PAINT->percentile ) ? esc_html( $report->data->desktop->field_data->INTERACTION_TO_NEXT_PAINT->percentile ) : 'N/A';
$mobile_data['ttfb_mobile'] = isset( $report->data->mobile->field_data->EXPERIMENTAL_TIME_TO_FIRST_BYTE->percentile ) ? esc_html( $report->data->mobile->field_data->EXPERIMENTAL_TIME_TO_FIRST_BYTE->percentile ) : 'N/A';
$desktop_data['ttfb_desktop'] = isset( $report->data->desktop->field_data->EXPERIMENTAL_TIME_TO_FIRST_BYTE->percentile ) ? esc_html( $report->data->desktop->field_data->EXPERIMENTAL_TIME_TO_FIRST_BYTE->percentile ) : 'N/A';
foreach ( $mobile_report->metrics as $rule => $rule_result ) {
if ( ! array_key_exists( $rule, $metrics ) ) {
continue;
}
$display_value = ! empty( $rule_result->displayValue ) ? preg_replace( '/[^0-9,.]/', '', $rule_result->displayValue ) : 'N/A';
$mobile_data[ $metrics[ $rule ] . '_mobile' ] = $display_value;
}
foreach ( $desktop_report->metrics as $rule => $rule_result ) {
if ( ! array_key_exists( $rule, $metrics ) ) {
continue;
}
$display_value = ! empty( $rule_result->displayValue ) ? preg_replace( '/[^0-9,.]/', '', $rule_result->displayValue ) : 'N/A';
$desktop_data[ $metrics[ $rule ] . '_desktop' ] = $display_value;
}
return array_merge( $mobile_data, $desktop_data );
}
/**
* Checks if AO status bar is enabled.
*
* @since 3.8.0
*
* @return bool True if AO status bar is enabled, false otherwise.
*/
public static function is_ao_status_bar_enabled() {
return defined( 'WPHB_ENABLED_AO_STATUS_BAR' ) && WPHB_ENABLED_AO_STATUS_BAR;
}
/**
* Check if AO is currently processing.
*
* @return bool
*/
public static function is_ao_processing() {
return get_transient( 'wphb-processing' ); // Input var ok.
}
/**
* Get cache page title.
*
* @since 3.9.0
*
* @return string
*/
public static function get_cache_page_title() {
if ( self::get_api()->hosting->has_fast_cgi_header() ) {
return __( 'Page Caching - Static Server Cache', 'wphb' );
}
return self::get_module( 'page_cache' )->is_active() ? __( 'Page Caching - Local Page Cache', 'wphb' ) : __( 'Page Caching', 'wphb' );
}
/**
* Determines whether the site is Hosted on WPMUDEV.
*
* @since 3.9.0
*
* @return bool True if the site is Hosted on WPMUDEV, false otherwise.
*/
public static function is_site_hosted_on_wpmudev() {
return isset( $_SERVER['WPMUDEV_HOSTED'] );
}
/**
* Determines whether the homepage preload is enabled or not.
*
* @since 3.9.0
*
* @return bool
*/
public static function is_homepage_preload_enabled() {
$options = self::get_module( 'page_cache' )->get_options();
return isset( $options['preload_type'] ) && $options['preload_type']['home_page'];
}
/**
* Determines whether the site is subsite or not.
*
* @since 3.9.0
*
* @return bool True if the site is subsite, false otherwise.
*/
public static function is_subsite() {
return is_multisite() && ! is_network_admin();
}
/**
* Determines whether the mobile preload is allowed or not.
*
* @since 3.10.0
*
* @return bool True if the mobile preload is allowed, false otherwise.
*/
public static function is_mobile_preload_allowed() {
$settings = self::get_module( 'page_cache' )->get_settings();
return ! empty( $settings['settings']['mobile'] ) && ! Fast_CGI::is_fast_cgi_enabled();
}
/**
* Returns total amount of autoloaded data.
*
* @since 3.10.0
*
* @return int Autoloaded data in bytes.
*/
public static function get_autoloaded_options_size() {
if ( class_exists( '\WP_Site_Health' ) && method_exists( '\WP_Site_Health', 'get_instance' ) ) {
$site_health = \WP_Site_Health::get_instance();
if ( method_exists( $site_health, 'get_autoloaded_options_size' ) ) {
$bytes = $site_health->get_autoloaded_options_size();
return $bytes > 0 ? intval( $bytes / KB_IN_BYTES ) : 0;
}
}
return 'na';
}
/**
* Returns autoloaded health status.
*
* @since 3.10.0
*
* @return string
*/
public static function get_autoloaded_health() {
if ( class_exists( '\WP_Site_Health' ) && method_exists( '\WP_Site_Health', 'get_instance' ) ) {
$site_health = \WP_Site_Health::get_instance();
if ( method_exists( $site_health, 'get_test_autoloaded_options' ) ) {
$result = $site_health->get_test_autoloaded_options();
$status = isset( $result['status'] ) ? $result['status'] : 'na';
return 'critical' === $status ? 'fail' : ( 'good' === $status ? 'pass' : 'na' );
}
}
return 'na';
}
/**
* Returns page cache description.
*
* @since 3.11.0
*
* @return string
*/
public static function get_page_cache_description() {
return Fast_CGI::is_fast_cgi_enabled() ? __( 'Page Caching stores static HTML copies of your pages and posts to decrease page load time. Server-side page caching allows for an average of 10 times more concurrent visitors than regular page caching.', 'wphb' ) : __( 'Hummingbird stores static HTML copies of your pages and posts to decrease page load time.', 'wphb' );
}
/**
* Clean variables using sanitize_text_field. Arrays are cleaned recursively.
*
* @param string|array $data Data to sanitize.
*
* @return string|array
*/
public static function wphb_sanitize_data( $data ) {
if ( is_array( $data ) ) {
return array_map( array( self::class, 'wphb_sanitize_data' ), $data );
} else {
return is_scalar( $data ) ? sanitize_text_field( $data ) : $data;
}
}
}