Last active
July 22, 2020 04:41
-
-
Save wpmudev-sls/ed42f35dce9421076b24f5b4938306bf to your computer and use it in GitHub Desktop.
[Smush Pro] - Fix Image resize issue and google font display base on HummingBird test's result
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Plugin Name: [Smush Pro] - Fix Image resize issue and google font display base on HummingBird test's result | |
* Description: [Smush Pro] - Fix Image resize issue and google font display base on HummingBird test's result | |
* Jira: SLS-284/SLS-272 | |
* Author: Thobk @ WPMUDEV | |
* Author URI: https://premium.wpmudev.org | |
* License: GPLv2 or later | |
*/ | |
if ( ! defined( 'ABSPATH' ) ) { | |
exit; | |
} elseif ( defined( 'WP_CLI' ) && WP_CLI ) { | |
return; | |
} | |
/** | |
* This MU plugin detect the issue base on the HummingBird/Google Speed test result. | |
* If you got the proper image size issue after run the performance test, it would be fixed on the next scan. | |
* And the time enough has passed to make another test is 5mins. | |
* Default, when we clear full cache from HummingBird we will trigger a new scan. | |
* If HummingBird does not exists, we can trigger a new scan by access this url: yoursite.com/wp-admin/?wpmudev-flush-cache | |
* define('WPMUDEV_CLEAN_CACHE_AFTER_UPDATE_POST', true); in wp-config.php file to enable scan after update post/page. | |
* | |
* Note: To fix proper image size issue, we would strongly suggest you choose the best image size. | |
*/ | |
add_action( 'after_setup_theme', 'wpmudev_smpro_tempfix_peformance_func', 100 ); | |
function wpmudev_smpro_tempfix_peformance_func() { | |
if( defined('WP_SMUSH_VERSION') && class_exists( 'Smush\Core\Settings' ) ){ | |
// return if disabled cdn | |
if( ! Smush\Core\Settings::get_instance()->get('cdn') || isset( $_GET['wpmudev-disable-mu-plugin']) ){ | |
return; | |
} | |
class WPMUDEV_HMB_Performance{ | |
public $timeout = 15; | |
public $expand_ratio_for_scaled_image_size = 1.2; | |
public $min_width;//set min width, default is thumbnail width | |
public $max_width;//set max width, default is content width | |
public $content_width;//set content width | |
public $recurrence_scan_issue = WEEK_IN_SECONDS; | |
private $api_url = 'https://premium.wpmudev.org/api/performance/v2/'; | |
private static $_test_url; | |
private static $_only_home_page; | |
private $properties = array( | |
'uses-responsive-images', | |
'font-display', | |
'offscreen-images', | |
); | |
public function __construct(){ | |
add_filter( 'wpmudev_performance_uses-responsive-images', array( $this, 'retrive_scaled_images'), 10, 4 ); | |
add_filter( 'wpmudev_performance_font-display', array( $this, 'detect_google_font_issue'), 10, 5 ); | |
add_action( 'wphb_get_performance_report', array( $this, 'populate_report') ); | |
// admin | |
add_action( 'wphb_page_cache_cleared', array( $this, 'clear_page_cache_and_trigger_test' ), 100 ); | |
add_action( 'update_option_wpmudev-wphb-last-reports', array( $this, 'clear_page_cache' ), 100 ); | |
add_action( 'admin_init', array( $this, 'admin_init' ) ); | |
// wp rocket | |
add_action( 'rocket_purge_cache', array( $this, 'clear_page_cache_and_trigger_test' ), 100 ); | |
// clean cache after update post | |
if( defined('WPMUDEV_CLEAN_CACHE_AFTER_UPDATE_POST') && WPMUDEV_CLEAN_CACHE_AFTER_UPDATE_POST ){ | |
add_action( 'clean_post_cache', array( $this, 'after_clean_post_cache' ), 100, 2 ); | |
} | |
} | |
public function exist_hmb(){ | |
return class_exists( 'Hummingbird\\WP_Hummingbird' ); | |
} | |
public function get_api_key() { | |
global $wpmudev_un; | |
if ( ! is_object( $wpmudev_un ) && class_exists( 'WPMUDEV_Dashboard' ) && method_exists( 'WPMUDEV_Dashboard', 'instance' ) ) { | |
$wpmudev_un = WPMUDEV_Dashboard::instance(); | |
} | |
if ( defined( 'WPHB_API_KEY' ) ) { | |
$api_key = WPHB_API_KEY; | |
} elseif ( is_object( $wpmudev_un ) && method_exists( $wpmudev_un, 'get_apikey' ) ) { | |
$api_key = $wpmudev_un->get_apikey(); | |
} elseif ( class_exists( 'WPMUDEV_Dashboard' ) && is_object( WPMUDEV_Dashboard::$api ) && method_exists( WPMUDEV_Dashboard::$api, 'get_key' ) ) { | |
$api_key = WPMUDEV_Dashboard::$api->get_key(); | |
} else { | |
$api_key = ''; | |
} | |
return $api_key; | |
} | |
public static function get_test_url(){ | |
static $test_url; | |
if( ! isset( $test_url ) ){ | |
/** | |
global $wp; | |
$test_url = home_url( $wp->request );// get current page | |
*/ | |
if( self::$_test_url ){ | |
$test_url = self::$_test_url; | |
}else{ | |
$test_url = site_url(); | |
self::$_only_home_page = 1; | |
} | |
$test_url = rtrim($test_url, '/'); | |
} | |
return $test_url; | |
} | |
public function get_api_url( $path ){ | |
return trailingslashit( $this->api_url . $path ); | |
} | |
public function admin_init(){ | |
if( isset( $_GET['wpmudev-flush-cache'] ) || isset( $_GET['wphb-cache-cleared'] ) ){ | |
$this->clear_page_cache_and_trigger_test(); | |
} | |
if( isset( $_GET['wpmudev-clean-data'] ) ){ | |
delete_option( 'wpmudev-wphb-reports-time' ); | |
delete_option( 'wpmudev-wphb-last-reports' ); | |
delete_option( 'wpmudev_global_ms_performance' ); | |
} | |
} | |
public function clear_page_cache(){ | |
if( WPMUDEV_SMHB_Optimize::is_divi() ){ | |
et_core_page_resource_auto_clear(); | |
et_fb_delete_builder_assets(); | |
} | |
} | |
public function clear_page_cache_and_trigger_test(){ | |
// clear divi page cache | |
if( WPMUDEV_SMHB_Optimize::is_divi() ){ | |
et_core_page_resource_auto_clear(); | |
et_fb_delete_builder_assets(); | |
} | |
// wp rocket | |
if( function_exists('rocket_clean_home') ){ | |
rocket_clean_home(); | |
} | |
// reset testing performance | |
if( ! $this->is_doing_report() ){ | |
delete_option( 'wpmudev-wphb-reports-time' ); | |
wp_cache_delete( 'wpmudev-wphb-reports-time', 'options' ); | |
} | |
// test again | |
$this->init_scan(); | |
} | |
/** | |
* Check if performance test has finished on server. | |
* | |
* @return array|mixed|object|WP_Error | |
*/ | |
public function request( $path, $data = array(), $method='post' ){ | |
$url = $this->get_api_url( $path ); | |
$args = array( | |
'headers' => array( | |
'Authorization' => 'Basic '. $this->get_api_key(), | |
), | |
'sslverify' => false, | |
'timeout' => $this->timeout, | |
); | |
switch ( strtolower( $method ) ) { | |
case 'post': | |
$args['body'] = $data; | |
$response = wp_remote_post( $url, $args ); | |
break; | |
default: | |
if( $data ){ | |
$url = add_query_arg( $data, $url ); | |
} | |
$response = wp_remote_get( $url, $args ); | |
break; | |
} | |
return $response; | |
} | |
/** | |
* Implement abstract parent method for clearing cache. | |
* @source Hummingbird\Core\Modules\Performance | |
*/ | |
public function reset_report_option() { | |
delete_option( 'wphb-doing-report' ); | |
delete_option( 'wphb-stop-report' ); | |
delete_transient( 'wphb-doing-report' ); | |
} | |
public function after_clean_post_cache( $post_id, $post ){ | |
// disable auto save | |
if( ! empty( $_POST['action'] ) && $_POST['action'] === 'heartbeat' && isset( $_POST['data']['wp_autosave'] ) ){ | |
return; | |
} | |
if( $post->post_type === 'post' || ( $post->post_type === 'page' && rtrim( get_permalink( $post_id ), '/' ) === self::get_test_url() ) ){ | |
$this->init_scan(); | |
} | |
} | |
/** | |
* Initializes the Performance Scan | |
* @source Hummingbird\Core\Modules\Performance | |
*/ | |
public function init_scan() { | |
if( ! $this->is_doing_report() ){ | |
// Clear the cache. | |
$this->reset_report_option(); | |
// Start the test. | |
$this->set_doing_report(); | |
$this->ping(); | |
// Clear dismissed report. | |
// if ( $this->exist_hmb() && Hummingbird\Core\Modules\Performance::report_dismissed() ) { | |
// Hummingbird\Core\Modules\Performance::dismiss_report( false ); | |
// } | |
} | |
} | |
/** | |
* Ping to Performance Module so it starts to gather data. | |
* | |
* @return array|mixed|object|WP_Error | |
* @source Hummingbird\Core\Api\Service\Performance | |
*/ | |
public function ping() { | |
$this->timeout = 2; | |
return $this->request( | |
'site/check/', | |
array( | |
'domain' => self::get_test_url(), | |
), | |
'post' | |
); | |
} | |
/** | |
* Get the latest performance test results. | |
* | |
* @return array|mixed|object|WP_Error | |
* @source Hummingbird\Core\Api\Service\Performance | |
*/ | |
public function results() { | |
return $this->request( | |
'site/result/latest/', | |
array( | |
'domain' => self::get_test_url(), | |
), | |
'get' | |
); | |
} | |
public function maybe_clear_cache_page(){ | |
if( $this->exist_hmb() ){ | |
$page_cache = Hummingbird\Core\Utils::get_module( 'page_cache' ); | |
if( $page_cache && $page_cache->is_active() ){ | |
$page_cache->clear_cache(); | |
} | |
} | |
if( WPMUDEV_SMHB_Optimize::is_divi() ){ | |
et_core_page_resource_auto_clear(); | |
et_fb_delete_builder_assets(); | |
} | |
if( function_exists('rocket_clean_home') ){ | |
rocket_clean_home(); | |
} | |
} | |
/** | |
* Start a new Performance Scan | |
* | |
* It sets the new status for the report | |
* | |
* @param bool $status If set to true, it will start a new Performance Report, otherwise it will stop the current one. | |
*/ | |
public function set_doing_report( $status = true ) { | |
if ( ! $status ) { | |
// maybe need to clear page cache | |
$this->maybe_clear_cache_page(); | |
delete_option( 'wpmudev-wphb-doing-report' ); | |
wp_cache_delete( 'wpmudev-wphb-doing-report', 'options' ); | |
delete_option( 'wphb-doing-report' ); | |
update_option( 'wphb-stop-report', true ); | |
} else { | |
update_option( 'wpmudev-wphb-doing-report', self::get_test_url() ); | |
// Set time when we started the report. | |
update_option( 'wphb-doing-report', current_time( 'timestamp' ) ); | |
delete_option( 'wphb-stop-report' ); | |
// save lastest doing report time | |
update_option( 'wpmudev-last-doing-report', current_time( 'timestamp' ) ); | |
} | |
} | |
/** | |
* Check if WP Hummingbird is currently doing a Performance Scan | |
* | |
* @return false|int Timestamp when the report started, false if there's no report being executed | |
*/ | |
public function is_doing_report() { | |
static $is_doing_report; | |
if( is_null( $is_doing_report ) ){ | |
$is_doing_report = get_option( 'wpmudev-wphb-doing-report' ); | |
if( ! $is_doing_report ){ | |
$stopped = get_option( 'wphb-stop-report' ); | |
$is_doing_report = $stopped ? false : get_option( 'wphb-doing-report' ); | |
if( ! $is_doing_report ){ | |
$lastest = get_option( 'wpmudev-last-doing-report' ); | |
if( $lastest && ( current_time( 'timestamp' ) - $latest ) < 360 ){ | |
$is_doing_report = 'sleeping'; | |
} | |
} | |
} | |
} | |
return $is_doing_report; | |
} | |
/** | |
* Return the last Performance scan done data | |
* | |
* @return bool|mixed|WP_Error Data of the last scan or false of there's not such data | |
*/ | |
public function get_last_report() { | |
$report = false; | |
$trigger_test = 0; | |
$reports = get_option( 'wpmudev-wphb-last-reports', array() ); | |
// $reports = array(); | |
$reports_time = get_option( 'wpmudev-wphb-reports-time', array() ); | |
$test_url = self::get_test_url(); | |
$this->recurrence_scan_issue = defined('WPMUDEV_RECURRENCE_PERFORMANCE_TEST') ? WPMUDEV_RECURRENCE_PERFORMANCE_TEST : $this->recurrence_scan_issue; | |
// delete_option( 'wpmudev-wphb-doing-report' ); | |
$testing_url = get_option( 'wpmudev-wphb-doing-report' ); | |
if( $testing_url && $testing_url === $test_url ){ | |
// $started_at = $this->is_doing_report(); | |
// if( $started_at ){ | |
$report = $this->results(); | |
// }else{ | |
// delete_option( 'wpmudev-wphb-doing-report' ); | |
// wp_cache_delete( 'wpmudev-wphb-doing-report', 'options' ); | |
// $report = $this->results(); | |
// } | |
}else if( ! isset( $reports[ $test_url ] ) ){ | |
$report = $this->results(); | |
} | |
if( $report && ! is_wp_error( $report ) && ! empty( $report['body'] ) ){ | |
$report = json_decode( $report['body'] ); | |
if( ! empty( $report->error ) ){ | |
$report = false; | |
} | |
}else{ | |
$report = false; | |
} | |
if( $report && isset( $report->code, $report->data ) && 200 === $report->code ){ | |
$old_report = isset( $reports[ $test_url ] ) ? $reports[ $test_url ] : array(); | |
$report = $this->clean_report( $report->data, $old_report ); | |
$reports[ $test_url ] = $report; | |
if( $testing_url && ( ! $old_report || $report['time'] > $old_report['time'] ) ){ | |
$this->set_doing_report( false ); | |
} | |
if( ! isset( $reports_time[ $test_url ] ) ){ | |
$trigger_test = 1; | |
} | |
$reports_time[ $test_url ] = $report['time']; | |
update_option( 'wpmudev-wphb-last-reports', $reports ); | |
update_option( 'wpmudev-wphb-reports-time', $reports_time ); | |
}else if( isset( $reports[ $test_url ] ) ){ | |
$report = $reports[ $test_url ]; | |
if( ! isset( $reports_time[ $test_url ] ) ){ | |
$trigger_test = 1; | |
$reports_time[ $test_url ] = $reports[ $test_url ]['time']; | |
update_option( 'wpmudev-wphb-reports-time', $reports_time ); | |
}else if( ( current_time( 'timestamp', 1 ) - $reports_time[ $test_url ] ) > $this->recurrence_scan_issue ){ | |
$trigger_test = 1; | |
} | |
}else{ | |
$trigger_test = 1; | |
} | |
if( ! $testing_url && ( $trigger_test || isset( $_GET['wpmudev-force-test'] ) ) ){ | |
// trigger a test performance | |
$this->init_scan(); | |
} | |
return $report; | |
} | |
public function populate_report( $data ){ | |
$test_url = site_url(); | |
$reports = get_option( 'wpmudev-wphb-last-reports', array() ); | |
$old_report = isset( $reports[ $test_url ] ) ? $reports[ $test_url ] : array(); | |
$report = $this->clean_report( $data, $old_report ); | |
$reports[ $test_url ] = $report; | |
update_option( 'wpmudev-wphb-last-reports', $reports ); | |
update_option( 'wpmudev-last-doing-report', current_time( 'timestamp' ) ); | |
delete_option( 'wpmudev-wphb-doing-report' ); | |
} | |
public function get_content_width(){ | |
global $content_width; | |
if( ! isset( $this->content_width ) ){ | |
$this->content_width = 1920; | |
if( WPMUDEV_SMHB_Optimize::is_divi() ){ | |
$this->content_width = et_divi_get_content_width(); | |
} | |
// Check to see if we are resizing the images (can not go over that value). | |
$resize_sizes = Smush\Core\Settings::get_instance()->get_setting( WP_SMUSH_PREFIX . 'resize_sizes' ); | |
if ( isset( $resize_sizes['width'] ) && $resize_sizes['width'] < $this->content_width ) { | |
$this->content_width = $resize_sizes['width']; | |
} | |
} | |
// set global | |
if( ! $content_width ){ | |
$content_width = $this->content_width; | |
} | |
return $this->content_width; | |
} | |
/** | |
* Clarify the report data | |
*/ | |
public function clean_report( $data, $old_report ){ | |
$report['time'] = $data->time; | |
$this->min_width = isset( $this->min_width ) ? $this->min_width : get_option( 'thumbnail_size_w' ); | |
if( ! isset( $this->max_width ) ){ | |
$content_width = $this->get_content_width(); | |
$this->max_width = $content_width ? $content_width : get_option( 'large_size_w' ); | |
} | |
foreach( array( 'desktop','mobile' ) as $device ){ | |
$audits = $data->$device->audits; | |
foreach( $this->properties as $issue ){ | |
$value = false; | |
if( isset( $audits->opportunities->$issue ) ){ | |
$value = $audits->opportunities->$issue ; | |
}else if( isset( $audits->diagnostics->$issue ) ){ | |
$value = $audits->diagnostics->$issue; | |
}else if( isset( $audits->passed->$issue ) ){ | |
$value = $audits->passed->$issue; | |
} | |
if( $value && ! empty( $value->details->items ) ){ | |
$report[ $device ][ $issue ] = apply_filters( 'wpmudev_performance_'. $issue, $value->details->items, $value, $audits, $old_report, $device ); | |
} | |
} | |
} | |
if( count( $report ) === 1 ){ | |
$report = $old_report; | |
} | |
return $report; | |
} | |
public static function get_cdn_base(){ | |
static $cdn_base; | |
if( ! $cdn_base ){ | |
$status = Smush\Core\Settings::get_instance()->get_setting( WP_SMUSH_PREFIX . 'cdn_status' ); | |
if( ! empty( $status->cdn_enabled ) ){ | |
$site_id = absint( $status->site_id ); | |
$cdn_base = trailingslashit( "https://{$status->endpoint_url}/{$site_id}" ); | |
} | |
} | |
return $cdn_base; | |
} | |
public function retrive_scaled_images( $items, $value, $audits, $old_report ){ | |
$cdn_base = self::get_cdn_base(); | |
$passed = isset( $audits->passed->{"uses-responsive-images"} ); | |
// Upload directory. | |
$upload_dir = wp_get_upload_dir(); | |
$scaled_images = isset( $old_report['uses-responsive-images'] ) ? $old_report['uses-responsive-images'] : array(); | |
if( $cdn_base ){ | |
$site_url = trailingslashit( site_url() ); | |
foreach( $items as $item ){ | |
if( false !== strpos( $item->url, $cdn_base ) ){ | |
$image_url = str_replace( $cdn_base, $site_url, $item->url ); | |
$pro_args = array( | |
'lossy', | |
'strip', | |
'webp', | |
'size' | |
); | |
$image_url = remove_query_arg( $pro_args, $image_url ); | |
}else if( false !== strpos( $item->url, $site_url ) ){ | |
$image_url = $item->url; | |
}else{ | |
continue; | |
} | |
$original_url = preg_replace('/-[\d]+x[\d]+/', '', $image_url ); | |
$file_path = substr( $original_url, strlen( $upload_dir['baseurl'] ) ); | |
if ( ! file_exists( $upload_dir['basedir'] . $file_path ) ) { | |
$file_path = substr( $image_url, strlen( $upload_dir['baseurl'] ) ); | |
if( ! file_exists( $upload_dir['basedir'] . $file_path ) ){ | |
continue; | |
}else{ | |
$original_url = $image_url; | |
} | |
} | |
if( $passed && isset( $scaled_images[ $original_url ] ) ){ | |
continue; | |
} | |
$scaled_size = $this->retrive_scaled_image_size( $item ); | |
if( $scaled_size ){ | |
$scaled_images[ $original_url ] = $scaled_size; | |
// if( $image_url !== $original_url ){ | |
// $scaled_images[ $image_url ] = $scaled_size; | |
// } | |
}else if( isset( $scaled_images[ $original_url ] ) ){ | |
unset( $scaled_images[ $original_url ] ); | |
if( defined('WP_DEBUG') && WP_DEBUG ){ | |
@file_put_contents( WP_CONTENT_DIR .'/debug.log', "\n-------\nCan't retrive image size info of image: ". $original_url, FILE_APPEND ); | |
} | |
} | |
} | |
} | |
return $scaled_images; | |
} | |
public function retrive_scaled_image_size( $item ){ | |
// fix png resize issue | |
$item->url = str_replace('webp=1', 'webp=0', $item->url ); | |
$info = @getimagesize( $item->url ); | |
if( ! empty( $info[0] ) ){ | |
$width = $info[0]; | |
$height = $info[1]; | |
$filesize = $item->totalBytes; | |
$scaled_filesize = $filesize - $item->wastedBytes; | |
$scaled_width = sqrt( $width * $width * $scaled_filesize / $filesize );//$width * $height * $width/$height. | |
$ratio = $this->expand_ratio_for_scaled_image_size; | |
// if( $scaled_width > 450 ){ | |
// $ratio = 1.2; | |
// } | |
$new_width = $scaled_width * $ratio; | |
$new_width = $new_width > $this->min_width ? $new_width : $this->min_width; | |
$new_width = $new_width < $this->max_width ? $new_width : $this->max_width; | |
return array( intval( $new_width ), intval( $new_width * $height / $width ) ); | |
} | |
return false; | |
} | |
// font-display | |
public function detect_google_font_issue( $items, $value, $audits, $old_report, $device ){ | |
$google_swap_font_issue = 0; | |
foreach( $items as $item ){ | |
if( false !== strpos( $item->url, 'https://fonts.gstatic.com') ){ | |
$google_swap_font_issue = 1; | |
break; | |
} | |
} | |
if( $google_swap_font_issue ){ | |
$global_audits = get_option( 'wpmudev_global_ms_performance' ); | |
$global_audits[ $device ]['font-display'] = 1; | |
update_option( 'wpmudev_global_ms_performance', $global_audits ); | |
} | |
} | |
} | |
class WPMUDEV_SMHB_Optimize{ | |
private $audits = array(); | |
private $original_sizes; | |
private $optimized_sizes; | |
private $hmb; | |
private $global_scaled_images = array(); | |
private $global_area = 0; | |
private $changing_global_images = 0; | |
public function __construct(){ | |
// | |
$this->hmb = new WPMUDEV_HMB_Performance; | |
if( ! is_admin() ){ | |
add_action( 'template_redirect', array( $this, 'run' ), 0 ); | |
} | |
add_filter( 'smush_srcset_additional_multipliers', array( $this, 'custom_additional_multipliers' ) ); | |
add_filter( 'pre_wp_nav_menu', array( $this, 'before_render_menu' ), 0 ); | |
add_filter( 'wp_nav_menu', array( $this, 'after_render_menu'), 999 ); | |
add_action( 'wp_footer', array( $this, 'maybe_update_global_images' ), 999 ); | |
// tempfix resized png issue while enable webp. | |
add_filter( 'smush_cdn_image_tag', array( $this, 'fix_resized_png_webp' ) ); | |
} | |
public function run(){ | |
// if( get_option( 'wpmudev-wphb-doing-report' ) ){ | |
// return; | |
// } | |
$this->audits = $this->hmb->get_last_report(); | |
// maybe set content width | |
$content_width = $this->hmb->get_content_width(); | |
// clean | |
unset( $this->hmb ); | |
$global_audits = get_option( 'wpmudev_global_ms_performance', array() ); | |
$current_device = $this->get_current_device(); | |
global $wp; | |
$test_url = rtrim( home_url( $wp->request ), '/' );// get current page | |
if( $this->audits && WPMUDEV_HMB_Performance::get_test_url() === $test_url ){ | |
$this->audits = isset( $this->audits[ $current_device ] ) ? $this->audits[ $current_device ] : array(); | |
}else{ | |
$this->audits = array(); | |
} | |
if( empty( $this->audits ) && empty( $global_audits ) ){ | |
return; | |
} | |
$this->global_scaled_images = isset( $global_audits[ $current_device ]['uses-responsive-images'] ) ? $global_audits[ $current_device ]['uses-responsive-images'] : array(); | |
if( $this->global_scaled_images ){ | |
if( isset( $this->audits['uses-responsive-images'] ) ){ | |
$this->audits['uses-responsive-images'] += $this->global_scaled_images; | |
}else{ | |
$this->audits['uses-responsive-images'] = $this->global_scaled_images; | |
} | |
} | |
if( isset( $this->audits['uses-responsive-images'] ) ){ | |
// $this->maybe_add_custom_image_size( $this->audits['uses-responsive-images'] ); | |
add_filter( 'wp_calculate_image_srcset', array( $this, 'custom_image_srcset' ), 999999, 3 ); | |
if( self::is_divi() ){ | |
if( et_is_responsive_images_enabled() ){ | |
add_filter( 'wp_calculate_image_sizes', array( $this, 'divi_custom_image_sizes' ) , 100, 4 ); | |
}else{ | |
remove_filter( 'wp_calculate_image_sizes', 'et_filter_wp_calculate_image_sizes', 10, 4 ); | |
} | |
}else{ | |
add_filter( 'wp_calculate_image_sizes', array( $this, 'custom_image_sizes' ) , 100, 4 ); | |
} | |
} | |
if( ! empty( $global_audits[ $current_device ]['font-display'] ) && class_exists('WPMUDEV_Fix_Font_Display_Issue') ){ | |
$fix_google_font_issue = new WPMUDEV_Fix_Font_Display_Issue; | |
} | |
} | |
public function get_current_device(){ | |
static $current_device; | |
if( ! $current_device ){ | |
$current_device = wp_is_mobile() ? 'mobile' : 'desktop'; | |
} | |
return $current_device; | |
} | |
public function custom_additional_multipliers( $sizes ){ | |
return array( | |
0.2, | |
0.4, | |
0.6, | |
0.8, | |
1, | |
); | |
} | |
public function maybe_add_custom_image_size( $scaled_images ){ | |
$all_sizes = wp_get_registered_image_subsizes(); | |
} | |
public function before_render_menu( $nav_menu ){ | |
$this->global_area = 1; | |
return $nav_menu; | |
} | |
public function after_render_menu( $nav_menu ){ | |
$this->global_area = 0; | |
return $nav_menu; | |
} | |
public function save_global_scaled_images( $image_src, $value ){ | |
if( ! isset( $this->global_scaled_images[ $image_src ] ) ){ | |
$this->global_scaled_images[ $image_src ] = $value; | |
$this->changing_global_images = 1; | |
} | |
} | |
public function maybe_update_global_images(){ | |
if( $this->changing_global_images ){ | |
$global_audits = get_option( 'wpmudev_global_ms_performance' ); | |
$current_device = $this->get_current_device(); | |
$global_audits[ $current_device ]['uses-responsive-images'] = $this->global_scaled_images; | |
update_option( 'wpmudev_global_ms_performance', $global_audits ); | |
} | |
return true; | |
} | |
public function should_fix_png_webp_issue(){ | |
static $should_fix; | |
if( ! isset( $should_fix ) ){ | |
$should_fix = false; | |
if( defined('WP_SMUSH_VERSION') && version_compare( WP_SMUSH_VERSION, '3.7.0', '<' ) ){ | |
$should_fix = true; | |
} | |
} | |
return $should_fix; | |
} | |
/** | |
* Add tempfix resized png issue while enable webp: SMUSH-155 | |
* @source Jira: SMUSH-155 | |
*/ | |
public function fix_resized_png_webp( $image ){ | |
if( ! $this->should_fix_png_webp_issue() ){ | |
return $image; | |
} | |
static $enable_webp; | |
// only fix for pnd image. | |
if( false === strpos( $image, '.png?size=') ){ | |
return $image; | |
} | |
if( is_null( $enable_webp ) ){ | |
$enable_webp = Smush\Core\Settings::get_instance()->get('webp'); | |
} | |
if( $enable_webp ){ | |
$image = str_replace( 'webp=1', 'webp=0', $image ); | |
} | |
return $image; | |
} | |
public function custom_image_srcset( $sources, $size_array, $image_src ){ | |
if( ! is_array( $sources ) ){ | |
return $sources; | |
} | |
$image_src = preg_replace('/-[\d]+x[\d]+/', '', $image_src ); | |
if( ! isset( $this->audits['uses-responsive-images'][ $image_src ] ) ){ | |
return $sources; | |
} | |
$max_width = $this->audits['uses-responsive-images'][ $image_src ][0]; | |
if( $max_width ){ | |
$this->original_sizes = array_keys( $sources ); | |
$prev_width = 0; | |
foreach( $sources as $size => $source ){ | |
if( $size > $max_width ){ | |
if( ! $prev_width ){ | |
$prev_width = $size; | |
}else{ | |
unset( $sources[ $size ] ); | |
continue; | |
} | |
}else if( $size === $max_width ){ | |
$prev_width = $size; | |
} | |
// tempfix resized png image issue while enable webp | |
// $sources[ $size ]['url'] = $this->fix_resized_png_webp( $sources[ $size ]['url'] ); | |
} | |
$this->optimized_sizes = array_keys( $sources ); | |
} | |
return $sources; | |
} | |
/** | |
* Divi theme | |
*/ | |
public static function is_divi(){ | |
static $is_divi; | |
if( ! isset( $is_divi ) ){ | |
$is_divi = defined('ET_CORE'); | |
} | |
return $is_divi; | |
} | |
public function divi_custom_image_sizes( $responsive_sizes, $size, $image_src, $image_meta ){ | |
if( is_admin() || is_array( $responsive_sizes ) ){ | |
return $responsive_sizes; | |
} | |
// if it is not custom by divi | |
if( false === strpos( $responsive_sizes, 'min-width') ){ | |
return $this->custom_image_sizes( $responsive_sizes, $size, $image_src, $image_meta ); | |
} | |
$image_src = preg_replace('/-[\d]+x[\d]+/', '', $image_src ); | |
if( ! isset( $this->audits['uses-responsive-images'][ $image_src ] ) ){ | |
return $responsive_sizes; | |
} | |
if( $this->global_area ){ | |
$this->save_global_scaled_images( $image_src, $this->audits['uses-responsive-images'][ $image_src ] ); | |
} | |
$current_max_width = $this->audits['uses-responsive-images'][ $image_src ][0]; | |
if ( $this->original_sizes ) { | |
$max_width = 0; | |
$prev_width = 0; | |
$is_first_max_width = 0; | |
$sizes_temp = array(); | |
foreach ( $this->original_sizes as $max_width ) { | |
if( $max_width > $current_max_width ){ | |
if( ! $is_first_max_width ){ | |
$prev_width = $max_width; | |
$is_first_max_width = 1; | |
} | |
$responsive_sizes = str_replace( "{$max_width}px,", $prev_width .'px,', $responsive_sizes); | |
}else{ | |
$prev_width = $max_width; | |
} | |
} | |
if( $prev_width ){ | |
$responsive_sizes = str_replace( "100vw", $prev_width .'px', $responsive_sizes); | |
} | |
} | |
return $responsive_sizes; | |
} | |
public function custom_image_sizes( $responsive_sizes, $size, $image_src, $image_meta ){ | |
if( is_admin() || is_array( $responsive_sizes ) ){ | |
return $responsive_sizes; | |
} | |
$image_src = preg_replace('/-[\d]+x[\d]+/', '', $image_src ); | |
if( ! isset( $this->audits['uses-responsive-images'][ $image_src ] ) ){ | |
return $responsive_sizes; | |
} | |
if( $this->global_area ){ | |
$this->save_global_scaled_images( $image_src, $this->audits['uses-responsive-images'][ $image_src ] ); | |
} | |
if( $this->optimized_sizes ){ | |
$max_width = 0; | |
$prev_width = 0; | |
$sizes_temp = array(); | |
foreach ( $this->optimized_sizes as $max_width ) { | |
if ( $prev_width ) { | |
$sizes_temp[ $max_width ] = sprintf( '(min-width: %2$dpx) and (max-width: %1$dpx) %1$dpx', $max_width, ( $prev_width + 1 ) ); | |
} else { | |
$sizes_temp[ $max_width ] = sprintf( '(min-width: %2$dpx) and (max-width: %1$dpx) %1$dpx', $max_width, $prev_width ); | |
} | |
$prev_width = $max_width; | |
} | |
$sizes_temp[] = sprintf( '(min-width: %2$dpx) %1$dpx, %1$dpx', $prev_width, ( $prev_width + 1 ) ); | |
$responsive_sizes = implode( ', ', $sizes_temp ); | |
} | |
return $responsive_sizes; | |
} | |
} | |
$run = new WPMUDEV_SMHB_Optimize; | |
} | |
if( defined('WPHB_VERSION') && class_exists( 'Hummingbird\\WP_Hummingbird' ) && class_exists('Hummingbird\Core\Settings') && ! class_exists('WPMUDEV_Fix_Font_Display_Issue') ){ | |
class WPMUDEV_Fix_Font_Display_Issue{ | |
public function __construct(){ | |
if( ! Hummingbird\Core\Settings::get_setting( 'enabled', 'minify' ) || ( is_admin() && ! wp_doing_ajax() ) ){ | |
return; | |
} | |
add_filter( 'print_styles_array', array( $this, 'add_font_display_swap' ), 1 ); | |
// convert custom css font for Kirki Customizer Framework plugin | |
if( class_exists('Kirki_Modules_Webfonts_Embed') ){ | |
add_action( 'kirki_dynamic_css', array( $this, 'enable_http_response_filter'), 0 ); | |
add_action( 'kirki_dynamic_css', array( $this, 'disable_http_response_filter'), 999 ); | |
} | |
// support Revoslider | |
if( class_exists('RevSliderFront') ){ | |
add_filter( 'revslider_printCleanFontImport', array( $this, 'revslider_add_font_display') ); | |
} | |
// Support Kallyas theme | |
if( class_exists('Zn_Framework') ){ | |
add_filter( 'zn_dynamic_css', array( $this, 'add_font_display_swap_for_custom_css' ), 9999 ); | |
} | |
} | |
public function add_font_display_swap( $handles ){ | |
global $wp_styles; | |
if( $wp_styles->queue ){ | |
foreach( $handles as $handle ){ | |
if( isset( $wp_styles->registered[ $handle ] ) ){ | |
$src = $wp_styles->registered[ $handle ]->src; | |
if( is_string( $src ) && strpos( $src, '//fonts.googleapis.com/css?family=') !== false && false === strpos( $src, 'display=') ){ | |
$wp_styles->registered[ $handle ]->src = str_replace( '//fonts.googleapis.com/css?family=', '//fonts.googleapis.com/css?display=swap&family=', $src ); | |
} | |
} | |
} | |
} | |
return $handles; | |
} | |
// add font display wrap for revoslider | |
public function revslider_add_font_display( $ret ){ | |
if( false !== strpos( $ret, '//fonts.googleapis.com/css?family=') ){ | |
$ret = str_replace( '//fonts.googleapis.com/css?family=', '//fonts.googleapis.com/css?display=swap&family=', $ret ); | |
}elseif( $ret ){ | |
$ret = str_replace( 'font-style: normal;', 'font-style: normal;font-display: swap;', $ret ); | |
} | |
return $ret; | |
} | |
public function add_font_display_swap_for_custom_css( $css ){ | |
$css = str_replace( '@font-face {', '@font-face {font-display: swap;', $css ); | |
return $css; | |
} | |
public function enable_http_response_filter(){ | |
add_filter( 'http_response', array( $this, 'add_font_display_swap_for_http_resonse' ), 10, 3 ); | |
} | |
public function add_font_display_swap_for_http_resonse( $response, $parsed_args, $url ){ | |
if( false !== strpos( $url, 'https://fonts.googleapis.com/css') ){ | |
if( ! empty( $response['body'] ) ){ | |
$response['body'] = $this->add_font_display_swap_for_custom_css( $response['body'] ); | |
} | |
} | |
return $response; | |
} | |
public function disable_http_response_filter(){ | |
remove_filter( 'http_response', array( $this, 'add_font_display_swap_for_http_resonse' ), 10, 3 ); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment