';
/**
* Printed in HEAD
*/
const DEL_SCRIPTS_PRELOADS = '';
/**
* @var array
*/
public $preloads = array('styles' => array(), 'scripts' => array());
/**
* @var Preloads|null
*/
private static $singleton;
/**
* @return null|Preloads
*/
public static function instance()
{
if (self::$singleton === null) {
self::$singleton = new self();
}
return self::$singleton;
}
/**
* Preloads constructor.
*/
public function __construct()
{
if (is_admin() || self::preventPreload()) {
return;
}
$this->preloads = $this->getPreloads();
add_filter('wpfc_buffer_callback_filter', static function ($buffer) {
$buffer = str_replace('rel=\'preload\' data-from-rel=\'stylesheet\'', 'rel=\'preload\'', $buffer);
return $buffer;
});
}
/**
*
*/
public function init()
{
if (self::preventPreload()) {
return;
}
if (! is_admin()) { // Trigger only in the front-end
add_filter('style_loader_tag', array($this, 'preloadCss'), 10, 2);
add_filter('script_loader_tag', array($this, 'preloadJs'), 10, 2);
} else { // Trigger only within the Dashboard
if (Misc::getVar('post', 'wpacu_remove_preloaded_assets_nonce')) {
add_action('admin_init', static function() {
Preloads::removePreloadFromChosenAssets();
});
}
// Trigger only in "Bulk Changes" -> "Preloaded CSS/JS"
if (isset($_GET['page']) && $_GET['page'] === WPACU_PLUGIN_ID.'_bulk_unloads'
&& get_transient('wpacu_preloads_just_removed')) {
add_action('wpacu_admin_notices', array($this, 'noticePreloadsRemoved'));
delete_transient('wpacu_preloads_just_removed');
}
}
}
/**
* @param $htmlSource
*
* @return mixed
*/
public function doChanges($htmlSource)
{
if (self::preventPreload()) {
return $htmlSource;
}
$this->preloads = $this->getPreloads();
if (isset($this->preloads['styles']) && ! empty($this->preloads['styles'])) {
$htmlSource = self::appendPreloadsForStylesToHead($htmlSource);
}
return $htmlSource;
}
/**
* @param string $for
* @return bool
*/
public function enablePreloads($for)
{
if (self::preventPreload()) {
return false;
}
$assetType = ($for === 'css') ? 'styles' : 'scripts';
if (! (isset($this->preloads[$assetType]) && ! empty($this->preloads[$assetType]))) {
return false;
}
// Do not use the preloads if "Optimize CSS Delivery" is enabled in WP Rocket
if ($for === 'css' && Misc::isPluginActive('wp-rocket/wp-rocket.php') && function_exists('get_rocket_option') && get_rocket_option('async_css')) {
return false;
}
// WP Fastest Cache: Combine CSS/JS is enabled
if (! Menu::userCanManageAssets() && Misc::isPluginActive('wp-fastest-cache/wpFastestCache.php')) {
$wpfcOptionsJson = get_option('WpFastestCache');
$wpfcOptions = @json_decode($wpfcOptionsJson, ARRAY_A);
if ($for === 'css' && isset($wpfcOptions['wpFastestCacheCombineCss'])) {
return false;
}
if ($for === 'js' && isset($wpfcOptions['wpFastestCacheCombineJs'])) {
return false;
}
}
// W3 Total Cache
if (Misc::isPluginActive('w3-total-cache/w3-total-cache.php')) {
$w3tcConfigMaster = Misc::getW3tcMasterConfig();
if ($for === 'css') {
$w3tcEnableCss = (int)trim(Misc::extractBetween($w3tcConfigMaster, '"minify.css.enable":', ','), '" ');
if ($w3tcEnableCss === 1) {
return false;
}
}
if ($for === 'js') {
$w3tcEnableJs = (int)trim(Misc::extractBetween($w3tcConfigMaster, '"minify.js.enable":', ','), '" ');
if ($w3tcEnableJs === 1) {
return false;
}
}
}
// LiteSpeed Cache
if (Misc::isPluginActive('litespeed-cache/litespeed-cache.php') && ($liteSpeedCacheConf = apply_filters('litespeed_cache_get_options', get_option('litespeed-cache-conf')))) {
if ($for === 'css' && isset($liteSpeedCacheConf['css_minify']) && $liteSpeedCacheConf['css_minify']) {
return false;
}
if ($for === 'js' && isset($liteSpeedCacheConf['js_minify']) && $liteSpeedCacheConf['js_minify']) {
return false;
}
}
return true;
}
/**
* @return array
*/
public function getPreloads()
{
$preloadsListJson = get_option(WPACU_PLUGIN_ID . '_global_data');
if ($preloadsListJson) {
$preloadsList = @json_decode($preloadsListJson, true);
// Issues with decoding the JSON file? Return an empty list
if (Misc::jsonLastError() !== JSON_ERROR_NONE) {
return $this->preloads;
}
// Are new positions set for styles and scripts?
foreach (array('styles', 'scripts') as $assetKey) {
if ( isset( $preloadsList[$assetKey]['preloads'] ) && ! empty( $preloadsList[$assetKey]['preloads'] ) ) {
$this->preloads[$assetKey] = $preloadsList[$assetKey]['preloads'];
}
}
}
return $this->preloads;
}
/**
* @param $htmlTag
* @param $handle
*
* @return string
*/
public function preloadCss($htmlTag, $handle)
{
if (Plugin::preventAnyFrontendOptimization() || self::preventPreload()) {
return $htmlTag;
}
if ($wpacuAsyncPreloadHandle = Misc::getVar('get', 'wpacu_preload_css')) {
// For testing purposes: Check how the page loads with the requested CSS preloaded
$this->preloads['styles'][$wpacuAsyncPreloadHandle] = 'basic';
}
// Only valid for front-end pages with LINKs
if (is_admin() || (! $this->enablePreloads('css')) || strpos($htmlTag,'preventAssetsSettings()) {
return $htmlTag;
}
if (! isset($this->preloads['styles'])) {
return $htmlTag;
}
if (array_key_exists($handle, $this->preloads['styles']) && $this->preloads['styles'][$handle]) {
if (isset($_REQUEST['wpacu_no_css_preload_basic'])) { // do not apply it for debugging purposes
return str_replace('preloads['scripts'][$wpacuJsPreloadHandle] = 1;
}
// Only valid for front-end pages with SCRIPTs
if (is_admin() || (! $this->enablePreloads('js')) || strpos($htmlTag,'