initial commit
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
if (!defined('ABSPATH')) die('No direct access allowed');
|
||||
|
||||
class WP_Optimize_Detect_Minify_Plugins {
|
||||
|
||||
/**
|
||||
* Detect list of active most popular WordPress minify plugins.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_active_minify_plugins() {
|
||||
|
||||
$active_minify_plugins = array();
|
||||
|
||||
foreach ($this->get_plugins() as $plugin_slug => $plugin_title) {
|
||||
if ($this->is_plugin_active($plugin_slug) && $this->is_minify_active($plugin_slug)) {
|
||||
$active_minify_plugins[$plugin_slug] = $plugin_title;
|
||||
}
|
||||
}
|
||||
|
||||
return $active_minify_plugins;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the plugins list
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function get_plugins() {
|
||||
return array(
|
||||
'w3-total-cache' => 'W3 Total Cache',
|
||||
'autoptimize' => 'Autoptimize',
|
||||
'fast-velocity-minify' => 'Fast Velocity Minify',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if $plugin is active.
|
||||
*
|
||||
* @param string $plugin - plugin slug
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function is_plugin_active($plugin) {
|
||||
$status = WP_Optimize()->get_db_info()->get_plugin_status($plugin);
|
||||
|
||||
return $status['active'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if minify feature is active
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_minify_active($plugin_slug) {
|
||||
switch ($plugin_slug) {
|
||||
case 'w3-total-cache':
|
||||
return (function_exists('w3tc_config') && w3tc_config()->get_boolean('minify.enabled'));
|
||||
case 'autoptimize':
|
||||
return ('on' == get_option('autoptimize_js', false) || 'on' == get_option('autoptimize_css', false) || 'on' == get_option('autoptimize_html', false));
|
||||
case 'fast-velocity-minify':
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Instance of WP_Optimize_Detect_Minify_Plugins.
|
||||
*
|
||||
* @return WP_Optimize_Detect_Minify_Plugins
|
||||
*/
|
||||
public static function get_instance() {
|
||||
static $instance = null;
|
||||
if (null === $instance) {
|
||||
$instance = new self();
|
||||
}
|
||||
return $instance;
|
||||
}
|
||||
}
|
@@ -0,0 +1,293 @@
|
||||
<?php
|
||||
if (!defined('ABSPATH')) die('No direct access allowed');
|
||||
|
||||
class WP_Optimize_Minify_Admin {
|
||||
|
||||
private $wp_version_required = '4.5';
|
||||
|
||||
/**
|
||||
* Initialize, add actions and filters
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct() {
|
||||
if (WPO_MINIFY_PHP_VERSION_MET) {
|
||||
// exclude processing for editors and administrators (fix editors)
|
||||
add_action('wp_optimize_admin_page_wpo_minify_status', array($this, 'check_permissions_admin_notices'));
|
||||
}
|
||||
|
||||
add_action('wp_optimize_admin_page_wpo_minify_status', array($this, 'admin_notices_activation_errors'));
|
||||
|
||||
add_action('admin_enqueue_scripts', array($this, 'admin_enqueue_scripts'));
|
||||
|
||||
// This function runs when WordPress updates or installs/remove something. Forces new cache
|
||||
add_action('upgrader_process_complete', array('WP_Optimize_Minify_Cache_Functions', 'cache_increment'));
|
||||
// This function runs when an active theme or plugin is updated
|
||||
add_action('wpo_active_plugin_or_theme_updated', array('WP_Optimize_Minify_Cache_Functions', 'reset'));
|
||||
add_action('upgrader_overwrote_package', array('WP_Optimize_Minify_Cache_Functions', 'reset'));
|
||||
add_action('after_switch_theme', array('WP_Optimize_Minify_Cache_Functions', 'cache_increment'));
|
||||
add_action('updraftcentral_version_updated', array('WP_Optimize_Minify_Cache_Functions', 'reset'));
|
||||
add_action('elementor/editor/after_save', array('WP_Optimize_Minify_Cache_Functions', 'reset'));
|
||||
add_action('fusion_cache_reset_after', array('WP_Optimize_Minify_Cache_Functions', 'reset'));
|
||||
// Output asset preload placeholder, replaced by premium
|
||||
add_action('wpo_minify_settings_tabs', array($this, 'output_assets_preload_placeholder'), 10, 1);
|
||||
|
||||
add_action('wp_optimize_register_admin_content', array($this, 'register_content'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the content
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register_content() {
|
||||
add_action('wp_optimize_admin_page_wpo_minify_status', array($this, 'output_status'), 20);
|
||||
add_action('wp_optimize_admin_page_wpo_minify_settings', array($this, 'output_settings'), 20);
|
||||
add_action('wp_optimize_admin_page_wpo_minify_advanced', array($this, 'output_advanced'), 20);
|
||||
add_action('wp_optimize_admin_page_wpo_minify_font', array($this, 'output_font_settings'), 20);
|
||||
add_action('wp_optimize_admin_page_wpo_minify_css', array($this, 'output_css_settings'), 20);
|
||||
add_action('wp_optimize_admin_page_wpo_minify_js', array($this, 'output_js_settings'), 20);
|
||||
add_action('wp_optimize_admin_page_wpo_minify_preload', array($this, 'output_preload_settings'), 20);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load scripts for controlling the admin pages
|
||||
*
|
||||
* @param string $hook
|
||||
* @return void
|
||||
*/
|
||||
public function admin_enqueue_scripts($hook) {
|
||||
$enqueue_version = (defined('WP_DEBUG') && WP_DEBUG) ? WPO_VERSION.'.'.time() : WPO_VERSION;
|
||||
$min_or_not_internal = (defined('SCRIPT_DEBUG') && SCRIPT_DEBUG) ? '' : '-'. str_replace('.', '-', WPO_VERSION). '.min';
|
||||
if (preg_match('/wp\-optimize/i', $hook)) {
|
||||
wp_enqueue_script('wp-optimize-min-js', WPO_PLUGIN_URL.'js/minify' . $min_or_not_internal . '.js', array('jquery', 'wp-optimize-admin-js'), $enqueue_version);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Conditionally runs upon the WP action admin_notices to display errors
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function admin_notices_activation_errors() {
|
||||
global $wp_version;
|
||||
include ABSPATH . WPINC . '/version.php';
|
||||
$errors = array();
|
||||
|
||||
if (!WPO_MINIFY_PHP_VERSION_MET) {
|
||||
$errors[] = sprintf(__('WP-Optimize Minify requires PHP 5.4 or higher. You’re using version %s.', 'wp-optimize'), PHP_VERSION);
|
||||
}
|
||||
|
||||
if (!extension_loaded('mbstring')) {
|
||||
$errors[] = __('WP-Optimize Minify requires the PHP mbstring module to be installed on the server; please ask your web hosting company for advice on how to enable it on your server.', 'wp-optimize');
|
||||
}
|
||||
|
||||
if (version_compare($wp_version, $this->wp_version_required, '<')) {
|
||||
$errors[] = sprintf(__('WP-Optimize Minify requires WordPress version %s or higher. You’re using version %s.', 'wp-optimize'), $this->wp_version_required, $wp_version);
|
||||
}
|
||||
|
||||
foreach ($errors as $error) {
|
||||
?>
|
||||
<div class="notice notice-error wpo-warning">
|
||||
<p><?php echo $error; ?></p>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display an admin notice if the user has inadequate filesystem permissions
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function check_permissions_admin_notices() {
|
||||
// get cache path
|
||||
$cache_path = WP_Optimize_Minify_Cache_Functions::cache_path();
|
||||
$cache_dir = $cache_path['cachedir'];
|
||||
if (is_dir($cache_dir) && !is_writable($cache_dir)) {
|
||||
$chmod = substr(sprintf('%o', fileperms($cache_dir)), -4);
|
||||
?>
|
||||
<div class="notice notice-error wpo-warning">
|
||||
<p>
|
||||
<?php printf(__('WP-Optimize Minify needs write permissions on the folder %s.', 'wp-optimize'), "<strong>".htmlspecialchars($cache_dir)."</strpmg>"); ?>
|
||||
</p>
|
||||
</div>
|
||||
<div class="notice notice-error wpo-warning">
|
||||
<p>
|
||||
<?php printf(__('The current permissions for WP-Optimize Minify are chmod %s.', 'wp-optimize'), "<strong>$chmod</strong>"); ?>
|
||||
</p>
|
||||
</div>
|
||||
<div class="notice notice-error wpo-warning">
|
||||
<p>
|
||||
<?php
|
||||
printf(__('If you need something more than %s for it to work, then your server is probably misconfigured.', 'wp-optimize'), '<strong>775</strong>');
|
||||
echo " ";
|
||||
_e('Please contact your hosting provider.', 'wp-optimize');
|
||||
?>
|
||||
</p>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Minify - Outputs the status tab
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function output_status() {
|
||||
if (!class_exists('WP_Optimize_Detect_Minify_Plugins')) {
|
||||
require_once(WP_OPTIMIZE_MINIFY_DIR.'/class-wp-optimize-detect-minify-plugins.php');
|
||||
}
|
||||
$this->found_incompatible_plugins = WP_Optimize_Detect_Minify_Plugins::get_instance()->get_active_minify_plugins();
|
||||
$wpo_minify_options = wp_optimize_minify_config()->get();
|
||||
$cache_path = WP_Optimize_Minify_Cache_Functions::cache_path();
|
||||
WP_Optimize()->include_template(
|
||||
'minify/status-tab.php',
|
||||
false,
|
||||
array(
|
||||
'wpo_minify_options' => $wpo_minify_options,
|
||||
'show_information_notice' => !get_user_meta(get_current_user_id(), 'wpo-hide-minify-information-notice', true),
|
||||
'cache_dir' => $cache_path['cachedir'],
|
||||
'can_purge_the_cache' => WP_Optimize()->can_purge_the_cache(),
|
||||
'active_minify_plugins' => apply_filters('wpo_minify_found_incompatible_plugins', $this->found_incompatible_plugins),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Minify - Outputs the font settings tab
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function output_font_settings() {
|
||||
$wpo_minify_options = wp_optimize_minify_config()->get();
|
||||
WP_Optimize()->include_template(
|
||||
'minify/font-settings-tab.php',
|
||||
false,
|
||||
array(
|
||||
'wpo_minify_options' => $wpo_minify_options
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Minify - Outputs the CSS settings tab
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function output_css_settings() {
|
||||
$wpo_minify_options = wp_optimize_minify_config()->get();
|
||||
WP_Optimize()->include_template(
|
||||
'minify/css-settings-tab.php',
|
||||
false,
|
||||
array(
|
||||
'wpo_minify_options' => $wpo_minify_options
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Minify - Outputs the JS settings tab
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function output_js_settings() {
|
||||
$wpo_minify_options = wp_optimize_minify_config()->get();
|
||||
WP_Optimize()->include_template(
|
||||
'minify/js-settings-tab.php',
|
||||
false,
|
||||
array(
|
||||
'wpo_minify_options' => $wpo_minify_options
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Minify - Outputs the settings tab
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function output_settings() {
|
||||
$wpo_minify_options = wp_optimize_minify_config()->get();
|
||||
$url = parse_url(get_home_url());
|
||||
WP_Optimize()->include_template(
|
||||
'minify/settings-tab.php',
|
||||
false,
|
||||
array(
|
||||
'wpo_minify_options' => $wpo_minify_options,
|
||||
'default_protocol' => $url['scheme']
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Minify - Outputs the settings tab
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function output_assets_preload_placeholder($wpo_minify_options) {
|
||||
WP_Optimize()->include_template(
|
||||
'minify/asset-preload.php',
|
||||
false,
|
||||
array(
|
||||
'wpo_minify_options' => $wpo_minify_options
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Minify - Outputs the preload tab
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function output_preload_settings() {
|
||||
$wpo_minify_preloader = WP_Optimize_Minify_Preloader::instance();
|
||||
$is_running = $wpo_minify_preloader->is_running();
|
||||
$status = $wpo_minify_preloader->get_status_info();
|
||||
if (!class_exists('WPO_Cache_Config')) require_once(WPO_PLUGIN_MAIN_PATH . '/cache/class-wpo-cache-config.php');
|
||||
$cache_config = WPO_Cache_Config::instance();
|
||||
WP_Optimize()->include_template(
|
||||
'minify/preload-tab.php',
|
||||
false,
|
||||
array(
|
||||
'is_cache_enabled' => $cache_config->get_option('enable_page_caching'),
|
||||
'is_running' => $is_running,
|
||||
'status_message' => isset($status['message']) ? $status['message'] : '',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Minify - Outputs the advanced tab
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function output_advanced() {
|
||||
$wpo_minify_options = wp_optimize_minify_config()->get();
|
||||
$files = false;
|
||||
if (apply_filters('wpo_minify_status_show_files_on_load', true) && WPO_MINIFY_PHP_VERSION_MET) {
|
||||
$files = WP_Optimize_Minify_Cache_Functions::get_cached_files();
|
||||
}
|
||||
|
||||
// WP_Optimize_Minify_Functions is only loaded when Minify is active
|
||||
if (class_exists('WP_Optimize_Minify_Functions')) {
|
||||
$default_ignore = WP_Optimize_Minify_Functions::get_default_ignore();
|
||||
$default_ie_blacklist = WP_Optimize_Minify_Functions::get_default_ie_blacklist();
|
||||
} else {
|
||||
$default_ignore = array();
|
||||
$default_ie_blacklist = array();
|
||||
}
|
||||
|
||||
WP_Optimize()->include_template(
|
||||
'minify/advanced-tab.php',
|
||||
false,
|
||||
array(
|
||||
'wpo_minify_options' => $wpo_minify_options,
|
||||
'files' => $files,
|
||||
'default_ignore' => $default_ignore,
|
||||
'default_ie_blacklist' => $default_ie_blacklist
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
@@ -0,0 +1,495 @@
|
||||
<?php
|
||||
if (!defined('ABSPATH')) die('No direct access allowed');
|
||||
|
||||
if (!defined('WP_OPTIMIZE_MINIFY_DIR')) {
|
||||
die('No direct access.');
|
||||
}
|
||||
|
||||
if (!function_exists('wpo_delete_files')) {
|
||||
include WPO_PLUGIN_MAIN_PATH.'cache/file-based-page-cache-functions.php';
|
||||
}
|
||||
|
||||
class WP_Optimize_Minify_Cache_Functions {
|
||||
|
||||
/**
|
||||
* Fix the permission bits on generated files
|
||||
*
|
||||
* @param String $file - full path to a file
|
||||
*/
|
||||
public static function fix_permission_bits($file) {
|
||||
if (function_exists('stat')) {
|
||||
if ($stat = stat(dirname($file))) {
|
||||
$perms = $stat['mode'] & 0007777;
|
||||
chmod($file, $perms);
|
||||
clearstatcache();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Get permissions from parent directory
|
||||
$perms = 0777;
|
||||
if (function_exists('stat')) {
|
||||
if ($stat = stat(dirname($file))) {
|
||||
$perms = $stat['mode'] & 0007777;
|
||||
}
|
||||
}
|
||||
|
||||
if (file_exists($file)) {
|
||||
if (($perms & ~umask() != $perms)) {
|
||||
$folder_parts = explode('/', substr($file, strlen(dirname($file)) + 1));
|
||||
for ($i = 1, $c = count($folder_parts); $i <= $c; $i++) {
|
||||
chmod(dirname($file) . '/' . implode('/', array_slice($folder_parts, 0, $i)), $perms);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cache directories and urls
|
||||
*
|
||||
* @return Array
|
||||
*/
|
||||
public static function cache_path() {
|
||||
// get latest time stamp
|
||||
$cache_time = wp_optimize_minify_config()->get('last-cache-update');
|
||||
|
||||
$cache_dir_url = WPO_CACHE_MIN_FILES_URL . "/$cache_time/assets";
|
||||
$tmp_dir = WPO_CACHE_MIN_FILES_DIR . "/tmp";
|
||||
$header_dir = WPO_CACHE_MIN_FILES_DIR . "/$cache_time/header";
|
||||
$cache_dir = WPO_CACHE_MIN_FILES_DIR . "/$cache_time/assets";
|
||||
|
||||
// Create directories
|
||||
$dirs = array($cache_dir, $tmp_dir, $header_dir);
|
||||
foreach ($dirs as $target) {
|
||||
$enabled = wp_optimize_minify_config()->get('enabled');
|
||||
if (false === $enabled) break;
|
||||
|
||||
if (!is_dir($target) && !wp_mkdir_p($target)) {
|
||||
error_log('WP_Optimize_Minify_Cache_Functions::cache_path(): The folder "'.$target.'" could not be created.');
|
||||
}
|
||||
}
|
||||
return array(
|
||||
'tmpdir' => $tmp_dir,
|
||||
'cachedir' => $cache_dir,
|
||||
'cachedirurl' => $cache_dir_url,
|
||||
'headerdir' => $header_dir
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment file names
|
||||
*/
|
||||
public static function cache_increment() {
|
||||
$stamp = time();
|
||||
wp_optimize_minify_config()->update(array(
|
||||
'last-cache-update' => $stamp
|
||||
));
|
||||
return $stamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the cache (Increment + purge temp files)
|
||||
*/
|
||||
public static function reset() {
|
||||
self::cache_increment();
|
||||
self::purge_temp_files();
|
||||
}
|
||||
|
||||
/**
|
||||
* Will delete temporary intermediate stuff but leave final css/js alone for compatibility
|
||||
*
|
||||
* @return Array
|
||||
*/
|
||||
public static function purge_temp_files() {
|
||||
// get cache directories and urls
|
||||
$cache_path = self::cache_path();
|
||||
$tmp_dir = $cache_path['tmpdir'];
|
||||
$header_dir = $cache_path['headerdir'];
|
||||
|
||||
// delete temporary directories only
|
||||
if (is_dir($tmp_dir)) {
|
||||
wpo_delete_files($tmp_dir, true);
|
||||
}
|
||||
if (is_dir($header_dir)) {
|
||||
wpo_delete_files($header_dir, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Action triggered after purging temporary files
|
||||
*/
|
||||
do_action('wpo_min_after_purge_temp_files');
|
||||
return array(
|
||||
'tmpdir' => $tmp_dir,
|
||||
'headerdir' => $header_dir,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Purge supported hosting and plugins
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function purge_others() {
|
||||
/**
|
||||
* Action triggered before purging other plugins cache
|
||||
*/
|
||||
do_action('wpo_min_before_purge_others');
|
||||
|
||||
// WordPress default cache
|
||||
if (function_exists('wp_cache_flush')) {
|
||||
wp_cache_flush();
|
||||
}
|
||||
|
||||
// Purge WP-Optimize
|
||||
WP_Optimize()->get_page_cache()->purge();
|
||||
|
||||
// When plugins have a simple method, add them to the array ('Plugin Name' => 'method_name')
|
||||
$others = array(
|
||||
'WP Super Cache' => 'wp_cache_clear_cache',
|
||||
'W3 Total Cache' => 'w3tc_pgcache_flush',
|
||||
'WP Fastest Cache' => 'wpfc_clear_all_cache',
|
||||
'WP Rocket' => 'rocket_clean_domain',
|
||||
'Cachify' => 'cachify_flush_cache',
|
||||
'Comet Cache' => array('comet_cache', 'clear'),
|
||||
'SG Optimizer' => 'sg_cachepress_purge_cache',
|
||||
'Pantheon' => 'pantheon_wp_clear_edge_all',
|
||||
'Zen Cache' => array('zencache', 'clear'),
|
||||
'Breeze' => array('Breeze_PurgeCache', 'breeze_cache_flush'),
|
||||
'Swift Performance' => array('Swift_Performance_Cache', 'clear_all_cache'),
|
||||
);
|
||||
|
||||
foreach ($others as $plugin => $method) {
|
||||
if (is_callable($method)) {
|
||||
call_user_func($method);
|
||||
return sprintf(__('All caches from %s have also been purged.', 'wp-optimize'), '<strong>'.$plugin.'</strong>');
|
||||
}
|
||||
}
|
||||
|
||||
// Purge LiteSpeed Cache
|
||||
if (is_callable(array('LiteSpeed_Cache_Tags', 'add_purge_tag'))) {
|
||||
LiteSpeed_Cache_Tags::add_purge_tag('*');
|
||||
return sprintf(__('All caches from %s have also been purged.', 'wp-optimize'), '<strong>LiteSpeed Cache</strong>');
|
||||
}
|
||||
|
||||
// Purge Hyper Cache
|
||||
if (class_exists('HyperCache')) {
|
||||
do_action('autoptimize_action_cachepurged');
|
||||
return sprintf(__('All caches from %s have also been purged.', 'wp-optimize'), '<strong>Hyper Cache</strong>');
|
||||
}
|
||||
|
||||
// Purge Godaddy Managed WordPress Hosting (Varnish + APC)
|
||||
if (class_exists('WPaaS\Plugin')) {
|
||||
self::godaddy_request('BAN');
|
||||
return sprintf(__('A cache purge request has been sent to %s. Please note that it may not work every time, due to cache rate limiting by your host.', 'wp-optimize'), '<strong>Go Daddy Varnish</strong>');
|
||||
}
|
||||
|
||||
// purge cache enabler
|
||||
if (has_action('ce_clear_cache')) {
|
||||
do_action('ce_clear_cache');
|
||||
return sprintf(__('All caches from %s have also been purged.', 'wp-optimize'), '<strong>Cache Enabler</strong>');
|
||||
}
|
||||
|
||||
// Purge WP Engine
|
||||
if (class_exists("WpeCommon")) {
|
||||
if (method_exists('WpeCommon', 'purge_memcached')) {
|
||||
WpeCommon::purge_memcached();
|
||||
}
|
||||
if (method_exists('WpeCommon', 'clear_maxcdn_cache')) {
|
||||
WpeCommon::clear_maxcdn_cache();
|
||||
}
|
||||
if (method_exists('WpeCommon', 'purge_varnish_cache')) {
|
||||
WpeCommon::purge_varnish_cache();
|
||||
}
|
||||
|
||||
if (method_exists('WpeCommon', 'purge_memcached') || method_exists('WpeCommon', 'clear_maxcdn_cache') || method_exists('WpeCommon', 'purge_varnish_cache')) {
|
||||
return sprintf(__('A cache purge request has been sent to %s. Please note that it may not work every time, due to cache rate limiting by your host.', 'wp-optimize'), '<strong>WP Engine</strong>');
|
||||
}
|
||||
}
|
||||
|
||||
// Purge Kinsta
|
||||
global $kinsta_cache;
|
||||
if (isset($kinsta_cache) && class_exists('\\Kinsta\\CDN_Enabler')) {
|
||||
if (!empty($kinsta_cache->kinsta_cache_purge) && is_callable(array($kinsta_cache->kinsta_cache_purge, 'purge_complete_caches'))) {
|
||||
$kinsta_cache->kinsta_cache_purge->purge_complete_caches();
|
||||
return sprintf(__('A cache purge request was also sent to %s', 'wp-optimize'), '<strong>Kinsta</strong>');
|
||||
}
|
||||
}
|
||||
|
||||
// Purge Pagely
|
||||
if (class_exists('PagelyCachePurge')) {
|
||||
$purge_pagely = new PagelyCachePurge();
|
||||
if (is_callable(array($purge_pagely, 'purgeAll'))) {
|
||||
$purge_pagely->purgeAll();
|
||||
return sprintf(__('A cache purge request was also sent to %s', 'wp-optimize'), '<strong>Pagely</strong>');
|
||||
}
|
||||
}
|
||||
|
||||
// Purge Pressidum
|
||||
if (defined('WP_NINUKIS_WP_NAME') && class_exists('Ninukis_Plugin') && is_callable(array('Ninukis_Plugin', 'get_instance'))) {
|
||||
$purge_pressidum = Ninukis_Plugin::get_instance();
|
||||
if (is_callable(array($purge_pressidum, 'purgeAllCaches'))) {
|
||||
$purge_pressidum->purgeAllCaches();
|
||||
return sprintf(__('A cache purge request was also sent to %s', 'wp-optimize'), '<strong>Pressidium</strong>');
|
||||
}
|
||||
}
|
||||
|
||||
// Purge Savvii
|
||||
if (defined('\Savvii\CacheFlusherPlugin::NAME_DOMAINFLUSH_NOW')) {
|
||||
$purge_savvii = new \Savvii\CacheFlusherPlugin(); // phpcs:ignore PHPCompatibility.LanguageConstructs.NewLanguageConstructs.t_ns_separatorFound
|
||||
if (is_callable(array($purge_savvii, 'domainflush'))) {
|
||||
$purge_savvii->domainflush();
|
||||
return sprintf(__('A cache purge request was also sent to %s', 'wp-optimize'), '<strong>Savvii</strong>');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Action triggered when purging other plugins cache, and nothing was triggered
|
||||
*/
|
||||
do_action('wpo_min_after_purge_others');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Purge all public files on uninstallation
|
||||
* This will break cached pages that ref minified JS/CSS
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public static function purge() {
|
||||
$log = '';
|
||||
if (is_dir(WPO_CACHE_MIN_FILES_DIR)) {
|
||||
if (wpo_delete_files(WPO_CACHE_MIN_FILES_DIR, true)) {
|
||||
$log = "[Minify] files and folders are deleted recursively";
|
||||
} else {
|
||||
$log = "[Minify] recursive files and folders deletion unsuccessful";
|
||||
}
|
||||
if (wp_optimize_minify_config()->get('debug')) {
|
||||
error_log($log);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Purge cache files older than 30 days
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function purge_old() {
|
||||
if (!class_exists('WP_Optimize_Minify_Config')) {
|
||||
include_once WPO_PLUGIN_MAIN_PATH . '/minify/class-wp-optimize-minify-config.php';
|
||||
}
|
||||
$cache_time = wp_optimize_minify_config()->get('last-cache-update');
|
||||
$cache_lifespan = wp_optimize_minify_config()->get('cache_lifespan');
|
||||
|
||||
/**
|
||||
* Minify cache lifespan
|
||||
*
|
||||
* @param int The minify cache expiry timestamp
|
||||
*/
|
||||
$expires = apply_filters('wp_optimize_minify_cache_expiry_time', time() - 86400 * $cache_lifespan);
|
||||
$log = array();
|
||||
|
||||
// get all directories that are a direct child of current directory
|
||||
if (is_dir(WPO_CACHE_MIN_FILES_DIR) && is_writable(dirname(WPO_CACHE_MIN_FILES_DIR))) {
|
||||
if ($handle = opendir(WPO_CACHE_MIN_FILES_DIR)) {
|
||||
while (false !== ($d = readdir($handle))) {
|
||||
if (strcmp($d, '.')==0 || strcmp($d, '..')==0) {
|
||||
continue;
|
||||
}
|
||||
$log[] = "cache expiration time - $expires";
|
||||
$log[] = "checking if cache has expired - $d";
|
||||
if ($d != $cache_time && (is_numeric($d) && $d <= $expires)) {
|
||||
$dir = WPO_CACHE_MIN_FILES_DIR.'/'.$d;
|
||||
if (is_dir($dir)) {
|
||||
$log[] = "deleting cache in $dir";
|
||||
if (wpo_delete_files($dir, true)) {
|
||||
$log[] = "files and folders are deleted recursively - $dir";
|
||||
} else {
|
||||
$log[] = "recursive files and folders deletion unsuccessful - $dir";
|
||||
}
|
||||
if (file_exists($dir)) {
|
||||
if (rmdir($dir)) {
|
||||
$log[] = "folder deleted successfully - $dir";
|
||||
} else {
|
||||
$log[] = "folder deletion unsuccessful - $dir";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir($handle);
|
||||
}
|
||||
}
|
||||
if (wp_optimize_minify_config()->get('debug')) {
|
||||
foreach ($log as $message) {
|
||||
error_log($message);
|
||||
}
|
||||
}
|
||||
|
||||
return $log;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get transients from the disk
|
||||
*
|
||||
* @return String|Boolean
|
||||
*/
|
||||
public static function get_transient($key) {
|
||||
$cache_path = self::cache_path();
|
||||
$tmp_dir = $cache_path['tmpdir'];
|
||||
$f = $tmp_dir.'/'.$key.'.transient';
|
||||
clearstatcache();
|
||||
if (file_exists($f)) {
|
||||
return file_get_contents($f);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set cache on disk
|
||||
*
|
||||
* @param String $key
|
||||
* @param Mixed $code
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public static function set_transient($key, $code) {
|
||||
if (is_null($code) || empty($code)) {
|
||||
return false;
|
||||
}
|
||||
$cache_path = self::cache_path();
|
||||
$tmp_dir = $cache_path['tmpdir'];
|
||||
$f = $tmp_dir.'/'.$key.'.transient';
|
||||
file_put_contents($f, $code);
|
||||
self::fix_permission_bits($f);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the cache size and count
|
||||
*
|
||||
* @param string $folder
|
||||
* @return String
|
||||
*/
|
||||
public static function get_cachestats($folder) {
|
||||
clearstatcache();
|
||||
if (is_dir($folder)) {
|
||||
$dir = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($folder, FilesystemIterator::SKIP_DOTS));
|
||||
$size = 0;
|
||||
$file_count = 0;
|
||||
foreach ($dir as $file) {
|
||||
$size += $file->getSize();
|
||||
$file_count++;
|
||||
}
|
||||
return WP_Optimize()->format_size($size) . ' ('.$file_count.' files)';
|
||||
} else {
|
||||
return sprintf(__('Error: %s is not a directory!', 'wp-optimize'), $folder);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Purge GoDaddy Managed WordPress Hosting (Varnish)
|
||||
*
|
||||
* Source: https://github.com/wp-media/wp-rocket/blob/master/inc/3rd-party/hosting/godaddy.php
|
||||
*
|
||||
* @param String $method
|
||||
* @param String|Null $url
|
||||
*/
|
||||
public static function godaddy_request($method, $url = null) {
|
||||
$url = empty($url) ? home_url() : $url;
|
||||
$host = parse_url($url, PHP_URL_HOST);
|
||||
$url = set_url_scheme(str_replace($host, WPaas\Plugin::vip(), $url), 'http'); // phpcs:ignore PHPCompatibility.LanguageConstructs.NewLanguageConstructs.t_ns_separatorFound
|
||||
wp_cache_flush();
|
||||
update_option('gd_system_last_cache_flush', time()); // purge apc
|
||||
wp_remote_request(esc_url_raw($url), array('method' => $method, 'blocking' => false, 'headers' => array('Host' => $host)));
|
||||
}
|
||||
|
||||
/**
|
||||
* List all cache files
|
||||
*
|
||||
* @param integer $stamp A timestamp
|
||||
* @param boolean $use_cache If true, do not use transient value
|
||||
* @return array
|
||||
*/
|
||||
public static function get_cached_files($stamp = 0, $use_cache = true) {
|
||||
if ($use_cache && $files = get_transient('wpo_minify_get_cached_files')) {
|
||||
return $files;
|
||||
}
|
||||
$cache_path = self::cache_path();
|
||||
$cache_dir = $cache_path['cachedir'];
|
||||
$size = self::get_cachestats($cache_dir);
|
||||
$total_size = self::get_cachestats(WPO_CACHE_MIN_FILES_DIR);
|
||||
$o = wp_optimize_minify_config()->get();
|
||||
$cache_time = (0 == $o['last-cache-update']) ? __('Never.', 'wp-optimize') : self::format_date_time($o['last-cache-update']);
|
||||
$return = array(
|
||||
'js' => array(),
|
||||
'css' => array(),
|
||||
'stamp' => $stamp,
|
||||
'cachesize' => esc_html($size),
|
||||
'total_cache_size' => esc_html($total_size),
|
||||
'cacheTime' => $cache_time,
|
||||
'cachePath' => $cache_path['cachedir']
|
||||
);
|
||||
|
||||
// Inspect directory with opendir, since glob might not be available in some systems
|
||||
clearstatcache();
|
||||
if (is_dir($cache_dir.'/') && $handle = opendir($cache_dir.'/')) {
|
||||
while (false !== ($file = readdir($handle))) {
|
||||
$file = $cache_dir.'/'.$file;
|
||||
$ext = pathinfo($file, PATHINFO_EXTENSION);
|
||||
if (in_array($ext, array('js', 'css'))) {
|
||||
$log = false;
|
||||
if (file_exists($file.'.json')) {
|
||||
$log = json_decode(file_get_contents($file.'.json'));
|
||||
}
|
||||
$min_css = substr($file, 0, -4).'.min.css';
|
||||
$minjs = substr($file, 0, -3).'.min.js';
|
||||
$file_name = basename($file);
|
||||
$file_url = trailingslashit($cache_path['cachedirurl']).$file_name;
|
||||
if ('css' == $ext && file_exists($min_css)) {
|
||||
$file_name = basename($min_css);
|
||||
}
|
||||
if ('js' == $ext && file_exists($minjs)) {
|
||||
$file_name = basename($minjs);
|
||||
}
|
||||
$file_size = WP_Optimize()->format_size(filesize($file));
|
||||
$uid = hash('adler32', $file_name);
|
||||
array_push($return[$ext], array('uid' => $uid, 'filename' => $file_name, 'file_url' => $file_url, 'log' => $log, 'fsize' => $file_size));
|
||||
}
|
||||
}
|
||||
closedir($handle);
|
||||
}
|
||||
set_transient('wpo_minify_get_cached_files', $return, DAY_IN_SECONDS);
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a timestamp using WP's date_format and time_format
|
||||
*
|
||||
* @param integer $timestamp - The timestamp
|
||||
* @return string
|
||||
*/
|
||||
public static function format_date_time($timestamp) {
|
||||
return WP_Optimize()->format_date_time($timestamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the log created when merging assets. Called via array_map
|
||||
*
|
||||
* @param array $files The files array, containing the 'log' object or array.
|
||||
* @return array
|
||||
*/
|
||||
public static function format_file_logs($files) {
|
||||
$files['log'] = WP_Optimize()->include_template(
|
||||
'minify/cached-file-log.php',
|
||||
true,
|
||||
array(
|
||||
'log' => $files['log']
|
||||
)
|
||||
);
|
||||
return $files;
|
||||
}
|
||||
}
|
@@ -0,0 +1,210 @@
|
||||
<?php
|
||||
if (!defined('ABSPATH')) die('No direct access allowed');
|
||||
|
||||
if (!class_exists('WP_Optimize_Minify_Config')) require_once(dirname(__FILE__) . '/class-wp-optimize-minify-config.php');
|
||||
if (!class_exists('WP_Optimize_Minify_Preloader')) require_once(dirname(__FILE__) . '/class-wpo-minify-preloader.php');
|
||||
|
||||
/**
|
||||
* All cache commands that are intended to be available for calling from any sort of control interface (e.g. wp-admin, UpdraftCentral) go in here. All public methods should either return the data to be returned, or a WP_Error with associated error code, message and error data.
|
||||
*/
|
||||
class WP_Optimize_Minify_Commands {
|
||||
|
||||
/**
|
||||
* List all cache files
|
||||
*
|
||||
* @param array $data - The $_POST data
|
||||
* @return array
|
||||
*/
|
||||
public function get_minify_cached_files($data = array()) {
|
||||
if (!WPO_MINIFY_PHP_VERSION_MET) return array('error' => __('WP-Optimize Minify requires a higher PHP version', 'wp-optimize'));
|
||||
$stamp = isset($data['stamp']) ? $data['stamp'] : 0;
|
||||
$files = WP_Optimize_Minify_Cache_Functions::get_cached_files($stamp, false);
|
||||
$files['js'] = array_map(array('WP_Optimize_Minify_Cache_Functions', 'format_file_logs'), $files['js']);
|
||||
$files['css'] = array_map(array('WP_Optimize_Minify_Cache_Functions', 'format_file_logs'), $files['css']);
|
||||
return $files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the entire cache dir.
|
||||
* Use with caution, as cached html may still reference those files.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function purge_all_minify_cache() {
|
||||
if (!WPO_MINIFY_PHP_VERSION_MET) return array('error' => __('WP-Optimize Minify requires a higher PHP version', 'wp-optimize'));
|
||||
WP_Optimize_Minify_Cache_Functions::purge();
|
||||
WP_Optimize_Minify_Cache_Functions::cache_increment();
|
||||
$others = WP_Optimize_Minify_Cache_Functions::purge_others();
|
||||
$files = $this->get_minify_cached_files();
|
||||
$message = array(
|
||||
__('The minification cache was deleted.', 'wp-optimize'),
|
||||
strip_tags($others, '<strong>'),
|
||||
);
|
||||
$message = array_filter($message);
|
||||
return array(
|
||||
'success' => true,
|
||||
'message' => implode("\n", $message),
|
||||
'files' => $files
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Forces a new Cache to be built
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function minify_increment_cache() {
|
||||
if (!WPO_MINIFY_PHP_VERSION_MET) return array('error' => __('WP-Optimize Minify requires a higher PHP version', 'wp-optimize'));
|
||||
WP_Optimize_Minify_Cache_Functions::cache_increment();
|
||||
$files = $this->get_minify_cached_files();
|
||||
return array(
|
||||
'success' => true,
|
||||
'files' => $files
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Purge the cache
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function purge_minify_cache() {
|
||||
if (!WPO_MINIFY_PHP_VERSION_MET) return array('error' => __('WP-Optimize Minify requires a higher PHP version', 'wp-optimize'));
|
||||
if (!WP_Optimize()->can_purge_the_cache()) return array('error' => __('You do not have permission to purge the cache', 'wp-optimize'));
|
||||
|
||||
// deletes temp files and old caches incase CRON isn't working
|
||||
WP_Optimize_Minify_Cache_Functions::cache_increment();
|
||||
if (wp_optimize_minify_config()->always_purge_everything()) {
|
||||
WP_Optimize_Minify_Cache_Functions::purge();
|
||||
$state = array();
|
||||
$old = array();
|
||||
} else {
|
||||
$state = WP_Optimize_Minify_Cache_Functions::purge_temp_files();
|
||||
$old = WP_Optimize_Minify_Cache_Functions::purge_old();
|
||||
}
|
||||
$others = WP_Optimize_Minify_Cache_Functions::purge_others();
|
||||
$files = $this->get_minify_cached_files();
|
||||
|
||||
$notice = array(
|
||||
__('All caches from WP-Optimize Minify have been purged.', 'wp-optimize'),
|
||||
strip_tags($others, '<strong>'),
|
||||
);
|
||||
$notice = array_filter($notice);
|
||||
$notice = json_encode($notice); // encode
|
||||
|
||||
return array(
|
||||
'result' => 'caches cleared',
|
||||
'others' => $others,
|
||||
'state' => $state,
|
||||
'message' => $notice,
|
||||
'old' => $old,
|
||||
'files' => $files
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save options to the config
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
public function save_minify_settings($data) {
|
||||
|
||||
$new_data = array();
|
||||
foreach ($data as $key => $value) {
|
||||
if ('true' === $value) {
|
||||
$new_data[$key] = true;
|
||||
} elseif ('false' === $value) {
|
||||
$new_data[$key] = false;
|
||||
} else {
|
||||
$new_data[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($data['minify_advanced_tab'])) {
|
||||
// Make sure that empty settings are still saved
|
||||
if (!isset($new_data['ignore_list'])) $new_data['ignore_list'] = array();
|
||||
if (!isset($new_data['blacklist'])) $new_data['blacklist'] = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the data before saving it
|
||||
*
|
||||
* @param array $new_data - The original data
|
||||
* @return array The data, altered or not
|
||||
*/
|
||||
$new_data = apply_filters('wpo_save_minify_settings', $new_data);
|
||||
|
||||
if (!class_exists('WP_Optimize_Minify_Config')) return array(
|
||||
'success' => false,
|
||||
'message' => "WP_Optimize_Minify_Config class doesn't exist",
|
||||
);
|
||||
$working = wp_optimize_minify_config()->update($new_data);
|
||||
if (!$working) {
|
||||
return array(
|
||||
'success' => false,
|
||||
'error' => 'failed to save'
|
||||
);
|
||||
}
|
||||
$purged = $this->purge_minify_cache();
|
||||
return array(
|
||||
'success' => true,
|
||||
'files' => $purged['files']
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide the information notice for the current user
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function hide_minify_notice() {
|
||||
return array(
|
||||
'success' => update_user_meta(get_current_user_id(), 'wpo-hide-minify-information-notice', true)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current status
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_status() {
|
||||
$config = wp_optimize_minify_config()->get();
|
||||
return array(
|
||||
'enabled' => $config['enabled'],
|
||||
'js' => $config['enable_js'],
|
||||
'css' => $config['enable_css'],
|
||||
'html' => $config['html_minification'],
|
||||
'stats' => $this->get_minify_cached_files()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run minify preload action.
|
||||
*
|
||||
* @return void|array - Doesn't return anything if run() is successfull (Run() prints a JSON object and closed browser connection) or an array if failed.
|
||||
*/
|
||||
public function run_minify_preload() {
|
||||
return WP_Optimize_Minify_Preloader::instance()->run('manual');
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel minify preload action.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function cancel_minify_preload() {
|
||||
WP_Optimize_Minify_Preloader::instance()->cancel_preload();
|
||||
return WP_Optimize_Minify_Preloader::instance()->get_status_info();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get status of minify preload.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_minify_preload_status() {
|
||||
return WP_Optimize_Minify_Preloader::instance()->get_status_info();
|
||||
}
|
||||
}
|
@@ -0,0 +1,197 @@
|
||||
<?php
|
||||
|
||||
if (!defined('ABSPATH')) die('No direct access allowed');
|
||||
|
||||
/**
|
||||
* Handles cache configuration and related I/O
|
||||
*/
|
||||
|
||||
if (!class_exists('WP_Optimize_Minify_Config')) :
|
||||
|
||||
class WP_Optimize_Minify_Config {
|
||||
|
||||
static protected $_instance = null;
|
||||
|
||||
private $_options = array();
|
||||
|
||||
/**
|
||||
* Construct
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function __construct() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter to see if Minify is enabled
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_enabled() {
|
||||
return $this->get('enabled');
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all Minify settings from the Database if 'preserve_settings_on_uninstall' is false
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function purge() {
|
||||
if (!$this->get('preserve_settings_on_uninstall')) {
|
||||
if (is_multisite()) {
|
||||
delete_site_option('wpo_minify_config');
|
||||
} else {
|
||||
delete_option('wpo_minify_config');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get config from file or cache
|
||||
*
|
||||
* @param string $option - An option name
|
||||
* @param mixed $default - A default for the option
|
||||
* @return array|string
|
||||
*/
|
||||
public function get($option = null, $default = false) {
|
||||
if (empty($this->_options)) {
|
||||
if (is_multisite()) {
|
||||
$config = get_site_option('wpo_minify_config', array());
|
||||
} else {
|
||||
$config = get_option('wpo_minify_config', array());
|
||||
}
|
||||
$this->_options = wp_parse_args($config, $this->get_defaults());
|
||||
}
|
||||
|
||||
if ($option && isset($this->_options[$option])) {
|
||||
return $this->_options[$option];
|
||||
} elseif ($option) {
|
||||
return $default;
|
||||
}
|
||||
return $this->_options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the config
|
||||
*
|
||||
* @param array $config - The new configuration array
|
||||
* @return boolean
|
||||
*/
|
||||
public function update($config) {
|
||||
$prev_settings = $this->get();
|
||||
$prev_settings = wp_parse_args($prev_settings, $this->get_defaults());
|
||||
$new_settings = wp_parse_args($config, $prev_settings);
|
||||
$this->_options = $new_settings;
|
||||
|
||||
if (is_multisite()) {
|
||||
update_site_option('wpo_minify_config', $new_settings);
|
||||
} else {
|
||||
update_option('wpo_minify_config', $new_settings);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return defaults
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_defaults() {
|
||||
$defaults = array(
|
||||
// dev tab checkboxes
|
||||
'debug' => false,
|
||||
'enabled_css_preload' => false,
|
||||
'enabled_js_preload' => false,
|
||||
'hpreconnect' => '',
|
||||
'hpreload' => '',
|
||||
'loadcss' => false,
|
||||
'remove_css' => false,
|
||||
'critical_path_css' => '',
|
||||
'critical_path_css_is_front_page' => '',
|
||||
// settings tab checkboxes
|
||||
'preserve_settings_on_uninstall' => true,
|
||||
'disable_when_logged_in' => false,
|
||||
'default_protocol' => 'dynamic', // dynamic, http, https
|
||||
'html_minification' => true,
|
||||
'clean_header_one' => false,
|
||||
'emoji_removal' => true,
|
||||
'merge_google_fonts' => true,
|
||||
'enable_display_swap' => true,
|
||||
'remove_googlefonts' => false,
|
||||
'gfonts_method' => 'inherit', // inline, async, exclude
|
||||
'fawesome_method' => 'inherit', // inline, async, exclude
|
||||
'enable_css' => true,
|
||||
'enable_css_minification' => true,
|
||||
'enable_merging_of_css' => true,
|
||||
'remove_print_mediatypes' => false,
|
||||
'inline_css' => false,
|
||||
'enable_js' => true,
|
||||
'enable_js_minification' => true,
|
||||
'enable_merging_of_js' => true,
|
||||
'enable_defer_js' => 'individual',
|
||||
'defer_js_type' => 'defer',
|
||||
'defer_jquery' => true,
|
||||
'enable_js_trycatch' => false,
|
||||
'exclude_defer_login' => true,
|
||||
'cdn_url' => '',
|
||||
'cdn_force' => false,
|
||||
|
||||
'async_css' => '',
|
||||
'async_js' => '',
|
||||
'disable_css_inline_merge' => true,
|
||||
'ualist' => array('x11.*fox\/54', 'oid\s4.*xus.*ome\/62', 'x11.*ome\/62', 'oobot', 'ighth', 'tmetr', 'eadles', 'ingdo'),
|
||||
'blacklist' => array(),
|
||||
'ignore_list' => array(),
|
||||
'exclude_js' => '',
|
||||
'exclude_css' => '',
|
||||
'edit_default_exclutions' => false,
|
||||
|
||||
'merge_allowed_urls' => '',
|
||||
|
||||
// internal
|
||||
'enabled' => false,
|
||||
'last-cache-update' => 0,
|
||||
'plugin_version' => '0.0.0',
|
||||
'cache_lifespan' => 30,
|
||||
'merge_inline_extra_css_js' => true,
|
||||
);
|
||||
return apply_filters('wpo_minify_defaults', $defaults);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether everything should be purged instead of just incremented
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function always_purge_everything() {
|
||||
/**
|
||||
* Filters the result of always_purge_everything
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
return apply_filters('wpo_minify_always_purge_everything', 0 === intval($this->get('cache_lifespan')) || (defined('WPO_ADVANCED_CACHE') && defined('WP_CACHE') && WP_CACHE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the instance
|
||||
*
|
||||
* @return WP_Optimize_Minify_Config
|
||||
*/
|
||||
public static function get_instance() {
|
||||
if (!self::$_instance) {
|
||||
self::$_instance = new self();
|
||||
}
|
||||
return self::$_instance;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get WPO Minify instance
|
||||
*
|
||||
* @return WP_Optimize_Minify_Config
|
||||
*/
|
||||
function wp_optimize_minify_config() {
|
||||
return WP_Optimize_Minify_Config::get_instance();
|
||||
}
|
||||
endif;
|
@@ -0,0 +1,298 @@
|
||||
<?php
|
||||
if (!defined('ABSPATH')) die('No direct access allowed');
|
||||
|
||||
class WP_Optimize_Minify_Fonts {
|
||||
|
||||
private static $fonts = array();
|
||||
|
||||
private static $subsets = array();
|
||||
|
||||
/**
|
||||
* Get a list of Google fonts
|
||||
*
|
||||
* @return Array
|
||||
*/
|
||||
public static function get_google_fonts() {
|
||||
// https://www.googleapis.com/webfonts/v1/webfonts?sort=alpha
|
||||
$google_fonts_file = WPO_PLUGIN_MAIN_PATH.'google-fonts.json';
|
||||
if (is_file($google_fonts_file) && is_readable($google_fonts_file)) {
|
||||
return json_decode(file_get_contents($google_fonts_file), true);
|
||||
}
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the google font exist or not
|
||||
*
|
||||
* @param string $font
|
||||
* @return boolean
|
||||
*/
|
||||
public static function concatenate_google_fonts_allowed($font) {
|
||||
$gfonts_whitelist = self::get_google_fonts();
|
||||
|
||||
// normalize
|
||||
$font = str_ireplace('+', ' ', strtolower($font));
|
||||
|
||||
return in_array($font, $gfonts_whitelist);
|
||||
}
|
||||
|
||||
/**
|
||||
* Concatenates Google Fonts tags (http://fonts.googleapis.com/css?...)
|
||||
*
|
||||
* @param array $gfonts_array
|
||||
* @return string|boolean
|
||||
*/
|
||||
public static function concatenate_google_fonts($gfonts_array) {
|
||||
// Loop through fonts array
|
||||
foreach ($gfonts_array as $font) {
|
||||
self::parse_font_url($font);
|
||||
}
|
||||
self::convert_v1_font_specs_to_v2();
|
||||
$merge = self::build();
|
||||
$config = wp_optimize_minify_config();
|
||||
/**
|
||||
* Filters wether to add display=swap to Google fonts urls
|
||||
*
|
||||
* @param boolean $display - Default to true
|
||||
*/
|
||||
if (apply_filters('wpo_minify_gfont_display_swap', $config->get('enable_display_swap'))) {
|
||||
/**
|
||||
* Filters the value of the display parameter.
|
||||
*
|
||||
* @param string $display_value - Default to 'swap'. https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display
|
||||
*/
|
||||
$merge.= '&display='.apply_filters('wpo_minify_gfont_display_type', 'swap');
|
||||
}
|
||||
|
||||
if (!empty($merge)) return 'https://fonts.googleapis.com/css2?' . $merge;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses font url based on whether it is API version 1 or 2
|
||||
*/
|
||||
private static function parse_font_url($font) {
|
||||
if (false !== strpos($font, 'css?')) {
|
||||
self::parse_font_api1_url($font);
|
||||
} else {
|
||||
self::parse_font_api2_url($font);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses google font api version 1 url
|
||||
*/
|
||||
private static function parse_font_api1_url($font) {
|
||||
parse_str(parse_url(rtrim($font, '|'), PHP_URL_QUERY), $font_elements);
|
||||
// Process each font family
|
||||
foreach (explode('|', $font_elements['family']) as $font_family) {
|
||||
// Separate font and sizes
|
||||
$font_family = explode(':', $font_family);
|
||||
// if the family wasn't added yet
|
||||
if (!in_array($font_family[0], array_keys(self::$fonts))) {
|
||||
self::$fonts[$font_family[0]]['specs'] = isset($font_family[1]) ? explode(',', rtrim($font_family[1], ',')) : array();
|
||||
} else {
|
||||
// if the family was already added, and this new one has weights, merge with previous
|
||||
if (isset($font_family[1])) {
|
||||
if (isset(self::$fonts[$font_family[0]]['version']) && 'V2' == self::$fonts[$font_family[0]]['version']) {
|
||||
self::$fonts[$font_family[0]]['specs'] = explode(',', rtrim($font_family[1], ','));
|
||||
} else {
|
||||
self::$fonts[$font_family[0]]['specs'] = array_merge(self::$fonts[$font_family[0]]['specs'], explode(',', rtrim($font_family[1], ',')));
|
||||
}
|
||||
}
|
||||
}
|
||||
self::$fonts[$font_family[0]]['version'] = 'V1';
|
||||
}
|
||||
|
||||
// Add subsets
|
||||
if (isset($font_elements['subset'])) {
|
||||
self::$subsets = array_merge(self::$subsets, explode(',', $font_elements['subset']));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses google font api version 2 url
|
||||
*/
|
||||
private static function parse_font_api2_url($font) {
|
||||
$parsed_url = parse_url($font, PHP_URL_QUERY);
|
||||
$query_elements = explode('&', $parsed_url);
|
||||
foreach ($query_elements as $element) {
|
||||
$family_str = str_replace('family=', '', $element);
|
||||
$family = explode(':', $family_str);
|
||||
if (!empty($family)) {
|
||||
$font_name = $family[0];
|
||||
$font_elements = isset($family[1]) ? explode('@', $family[1]) : '';
|
||||
if (!empty($font_elements) && !empty($font_elements[0]) && !empty($font_elements[1])) {
|
||||
$font_styles = $font_elements[0];
|
||||
$font_units = explode(',', $font_elements[1]);
|
||||
}
|
||||
} else {
|
||||
$font_name = $family_str;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset(self::$fonts[$font_name])) {
|
||||
self::$fonts[$font_name]['specs'] = array(
|
||||
'wght' => array(),
|
||||
'ital' => array(),
|
||||
'ital,wght' => array(),
|
||||
);
|
||||
}
|
||||
|
||||
if (!isset(self::$fonts[$font_name]['version'])) {
|
||||
self::$fonts[$font_name]['version'] = 'V2';
|
||||
}
|
||||
if (isset($font_styles) && isset($font_units) && isset($font_elements[1])) {
|
||||
$font_units = explode(';', $font_elements[1]);
|
||||
switch ($font_styles) {
|
||||
case 'wght':
|
||||
foreach ($font_units as $font_unit) {
|
||||
if (!in_array($font_unit, self::$fonts[$font_name]['specs']['wght'])) {
|
||||
array_push(self::$fonts[$font_name]['specs']['wght'], $font_unit);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'ital':
|
||||
foreach ($font_units as $font_unit) {
|
||||
if (!in_array($font_unit, self::$fonts[$font_name]['specs']['ital'])) {
|
||||
array_push(self::$fonts[$font_name]['specs']['ital'], $font_unit);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'ital,wght':
|
||||
foreach ($font_units as $font_unit) {
|
||||
if (!in_array($font_unit, self::$fonts[$font_name]['specs']['ital,wght'])) {
|
||||
array_push(self::$fonts[$font_name]['specs']['ital,wght'], $font_unit);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts google font api version 1 font specification into API V2
|
||||
*/
|
||||
private static function convert_v1_font_specs_to_v2() {
|
||||
foreach (self::$fonts as $font_name => $font_details) {
|
||||
if ('V2' == $font_details['version']) continue;
|
||||
if (0 == count($font_details['specs'])) {
|
||||
self::$fonts[$font_name]['specs'] = array(
|
||||
'wght' => array(),
|
||||
'ital' => array(),
|
||||
'ital,wght' => array(),
|
||||
);
|
||||
} else {
|
||||
foreach ($font_details['specs'] as $key => $detail) {
|
||||
if (is_array($detail)) $detail = implode('', $detail);
|
||||
switch ($detail) {
|
||||
case 'i':
|
||||
unset(self::$fonts[$font_name]['specs'][$key]);
|
||||
self::$fonts[$font_name]['specs']['ital'] = array(1);
|
||||
break;
|
||||
case 'b':
|
||||
unset(self::$fonts[$font_name]['specs'][$key]);
|
||||
self::$fonts[$font_name]['specs']['wght'] = array();
|
||||
break;
|
||||
case 'bi':
|
||||
unset(self::$fonts[$font_name]['specs'][$key]);
|
||||
self::$fonts[$font_name]['specs']['ital'] = array('0;1');
|
||||
break;
|
||||
default:
|
||||
unset(self::$fonts[$font_name]['specs'][$key]);
|
||||
if (!isset(self::$fonts[$font_name]['specs']['ital,wght'])) {
|
||||
self::$fonts[$font_name]['specs']['ital,wght'] = array();
|
||||
}
|
||||
if (false !== strpos($detail, 'i')) {
|
||||
$detail = str_replace(array('italic', 'i'), '', $detail);
|
||||
$detail = '' === $detail ? 400 : $detail;
|
||||
array_push(self::$fonts[$font_name]['specs']['ital,wght'], '1,' . $detail);
|
||||
} else {
|
||||
$detail = 'regular' === $detail ? 400 : $detail;
|
||||
array_push(self::$fonts[$font_name]['specs']['ital,wght'], '0,' . $detail);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build valid Google font api 2 url string
|
||||
*
|
||||
* @return string $result Url string
|
||||
*/
|
||||
private static function build() {
|
||||
$result = '';
|
||||
foreach (self::$fonts as $font_name => $font_details) {
|
||||
if ('display=swap' == $font_name) continue;
|
||||
if ('' != $result) {
|
||||
$result .= '&';
|
||||
}
|
||||
$result .= 'family=' . str_replace(' ', '+', $font_name);
|
||||
$result .= self::specs_to_string($font_details['specs']);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts font specifications into a valid google font api2 url string
|
||||
*
|
||||
* @param array $font_specs Font style and weight specifications
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function specs_to_string($font_specs) {
|
||||
$result = array();
|
||||
$weights = isset($font_specs['wght']) && count($font_specs['wght']);
|
||||
$italic_weights = isset($font_specs['ital']) && count($font_specs['ital']);
|
||||
$all_weights = isset($font_specs['ital,wght']) && count($font_specs['ital,wght']);
|
||||
|
||||
// Nothing is set, return
|
||||
if (!$weights && !$italic_weights && !$all_weights) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Italic only
|
||||
if ($italic_weights && !$weights && !$all_weights) {
|
||||
if ('1' == $font_specs['ital'][0]) {
|
||||
return ':ital@1';
|
||||
} elseif ('0;1' == $font_specs['ital'][0]) {
|
||||
return ':ital@0;1';
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($font_specs as $style => $units) {
|
||||
switch ($style) {
|
||||
case 'wght':
|
||||
foreach ($units as $unit) {
|
||||
$multiple_units = explode(',', $unit);
|
||||
if (count($multiple_units) > 0) {
|
||||
foreach ($multiple_units as $single_unit) {
|
||||
array_push($result, '0,' . $single_unit);
|
||||
}
|
||||
} else {
|
||||
array_push($result, '0,' . $unit);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'ital':
|
||||
foreach ($units as $unit) {
|
||||
array_push($result, 1 == $unit ? '1,400' : $unit);
|
||||
}
|
||||
break;
|
||||
case 'ital,wght':
|
||||
foreach ($units as $unit) {
|
||||
array_push($result, $unit);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sort($result);
|
||||
return ':ital,wght@' . implode(';', array_unique($result));
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,170 @@
|
||||
<?php
|
||||
if (!defined('ABSPATH')) die('No direct access allowed');
|
||||
|
||||
if (!class_exists('WP_Optimize_Minify_Functions')) {
|
||||
include WP_OPTIMIZE_MINIFY_DIR.'/class-wp-optimize-minify-functions.php';
|
||||
}
|
||||
|
||||
class WP_Optimize_Minify_Print {
|
||||
|
||||
/**
|
||||
* Load the script using loadAsync JavaScript
|
||||
*
|
||||
* @param string $href
|
||||
* @param boolean $print
|
||||
* @return string|void
|
||||
*/
|
||||
public static function async_script($href, $print = true) {
|
||||
$wpo_minify_options = wp_optimize_minify_config()->get();
|
||||
$tag = '<script>if (!navigator.userAgent.match(/'.implode('|', $wpo_minify_options['ualist']).'/i)){' . "\n";
|
||||
$tag .= " loadAsync('$href', null);" . "\n";
|
||||
$tag .= '}</script>' . "\n";
|
||||
|
||||
if ($print) {
|
||||
echo $tag;
|
||||
} else {
|
||||
return $tag;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print a style that will be loaded async using 'preload'
|
||||
*
|
||||
* @param string $href
|
||||
* @param string $media
|
||||
* @return void
|
||||
*/
|
||||
public static function async_style($href, $media = 'all') {
|
||||
echo '<link rel="preload" href="'.$href.'" as="style" media="'.$media.'" onload="this.onload=null;this.rel=\'stylesheet\'" />' . "\n";
|
||||
// fix for firefox not supporting preload
|
||||
echo '<link rel="stylesheet" href="'.$href.'" media="'.$media.'" />' . "\n";
|
||||
echo '<noscript><link rel="stylesheet" href="'.$href.'" media="'.$media.'" /></noscript>' . "\n";
|
||||
echo '<!--[if IE]><link rel="stylesheet" href="'.$href.'" media="'.$media.'" /><![endif]-->' . "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Print a style that will be loaded by JS
|
||||
*
|
||||
* @param string $href
|
||||
* @return void
|
||||
*/
|
||||
public static function exclude_style($href) {
|
||||
$wpo_minify_options = wp_optimize_minify_config()->get();
|
||||
// make a stylesheet, hide from PageSpeedIndex
|
||||
$cssguid = 'wpo_min'.hash('adler32', $href);
|
||||
echo '<script>if (!navigator.userAgent.match(/'.implode('|', $wpo_minify_options['ualist']).'/i)){' . "\n";
|
||||
echo ' var '.$cssguid.'=document.createElement("link");'.$cssguid.'.rel="stylesheet",'.$cssguid.'.type="text/css",'.$cssguid.'.media="async",'.$cssguid.'.href="'.$href.'",'.$cssguid.'.onload=function() {'.$cssguid.'.media="all"},document.getElementsByTagName("head")[0].appendChild('.$cssguid.');' . "\n";
|
||||
echo '}</script>' . "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Inline a single style
|
||||
*
|
||||
* @param string $handle
|
||||
* @param string $href
|
||||
* @return boolean
|
||||
*/
|
||||
public static function inline_style($handle, $href) {
|
||||
$wpo_minify_options = wp_optimize_minify_config()->get();
|
||||
|
||||
// font awesome processing, inline
|
||||
// download, minify, cache
|
||||
$tkey = 'css-'.hash('adler32', $href).'.css';
|
||||
$json = WP_Optimize_Minify_Cache_Functions::get_transient($tkey);
|
||||
if (false === $json) {
|
||||
$json = WP_Optimize_Minify_Functions::download_and_minify($href, null, $wpo_minify_options['enable_css_minification'], 'css', $handle);
|
||||
if ($wpo_minify_options['debug']) {
|
||||
echo "<!-- wpo_min DEBUG: Uncached file processing now for $href -->" . "\n";
|
||||
}
|
||||
WP_Optimize_Minify_Cache_Functions::set_transient($tkey, $json);
|
||||
}
|
||||
|
||||
// decode
|
||||
$res = json_decode($json, true);
|
||||
|
||||
// add font-display
|
||||
// https://developers.google.com/web/updates/2016/02/font-display
|
||||
$res['code'] = str_ireplace('font-style:normal;', 'font-display:block;font-style:normal;', $res['code']);
|
||||
|
||||
// inline css or fail
|
||||
if (false != $res['status']) {
|
||||
echo '<style type="text/css" media="all">' . "\n";
|
||||
echo $res['code'] . "\n";
|
||||
echo '</style>' . "\n";
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print a normal style tag pointing the href
|
||||
*
|
||||
* @param string $href
|
||||
* @return void
|
||||
*/
|
||||
public static function style($href) {
|
||||
echo '<link rel="stylesheet" href="'.$href.'" media="all">' . "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Write header
|
||||
*
|
||||
* @param string $file
|
||||
* @param string $headers
|
||||
* @return void
|
||||
*/
|
||||
public static function write_header($file, $headers) {
|
||||
file_put_contents($file, $headers);
|
||||
WP_Optimize_Minify_Cache_Functions::fix_permission_bits($file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write CSS
|
||||
*
|
||||
* @param string $file
|
||||
* @param string $code
|
||||
* @param string $log
|
||||
* @return void
|
||||
*/
|
||||
public static function write_combined_asset($file, $code, $log) {
|
||||
file_put_contents($file.'.json', json_encode($log));
|
||||
file_put_contents($file, $code);
|
||||
// permissions
|
||||
WP_Optimize_Minify_Cache_Functions::fix_permission_bits($file.'.json');
|
||||
WP_Optimize_Minify_Cache_Functions::fix_permission_bits($file);
|
||||
|
||||
if (function_exists('gzencode')) {
|
||||
file_put_contents($file.'.gz', gzencode(file_get_contents($file), 9));
|
||||
WP_Optimize_Minify_Cache_Functions::fix_permission_bits($file.'.gz');
|
||||
}
|
||||
|
||||
// brotli static support
|
||||
if (function_exists('brotli_compress')) {
|
||||
file_put_contents($file.'.br', brotli_compress(file_get_contents($file), 11));
|
||||
WP_Optimize_Minify_Cache_Functions::fix_permission_bits($file.'.br');
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Load async scripts with callback
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function add_load_async() {
|
||||
$min_or_not_internal = (defined('SCRIPT_DEBUG') && SCRIPT_DEBUG) ? '' : '-'. str_replace('.', '-', WPO_VERSION). '.min';
|
||||
$contents = file_get_contents(trailingslashit(WPO_PLUGIN_MAIN_PATH) . "js/loadAsync$min_or_not_internal.js");
|
||||
echo "<script>$contents</script>\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Defer CSS globally from the header (order matters)
|
||||
* Dev: https://www.filamentgroup.com/lab/async-css.html
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function add_load_css() {
|
||||
$min_or_not_internal = (defined('SCRIPT_DEBUG') && SCRIPT_DEBUG) ? '' : '-'. str_replace('.', '-', WPO_VERSION). '.min';
|
||||
$contents = file_get_contents(trailingslashit(WPO_PLUGIN_MAIN_PATH) . "js/loadCSS$min_or_not_internal.js");
|
||||
echo "<script>$contents</script>" . "\n";
|
||||
}
|
||||
}
|
@@ -0,0 +1,259 @@
|
||||
<?php
|
||||
if (!defined('ABSPATH')) die('No direct access allowed');
|
||||
|
||||
define('WP_OPTIMIZE_MINIFY_VERSION', '2.6.5');
|
||||
define('WP_OPTIMIZE_MINIFY_DIR', dirname(__FILE__));
|
||||
if (!defined('WP_OPTIMIZE_SHOW_MINIFY_ADVANCED')) define('WP_OPTIMIZE_SHOW_MINIFY_ADVANCED', false);
|
||||
|
||||
class WP_Optimize_Minify {
|
||||
/**
|
||||
* Constructor - Initialize actions and filters
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct() {
|
||||
|
||||
if (!class_exists('WP_Optimize_Minify_Commands')) include_once(WPO_PLUGIN_MAIN_PATH . 'minify/class-wp-optimize-minify-commands.php');
|
||||
$this->minify_commands = new WP_Optimize_Minify_Commands();
|
||||
|
||||
if (!class_exists('WP_Optimize_Minify_Config')) {
|
||||
include WP_OPTIMIZE_MINIFY_DIR.'/class-wp-optimize-minify-config.php';
|
||||
}
|
||||
|
||||
$this->enabled = wp_optimize_minify_config()->is_enabled();
|
||||
|
||||
$this->load_admin();
|
||||
|
||||
// Don't run the rest if PHP requirement isn't met
|
||||
if (!WPO_MINIFY_PHP_VERSION_MET) return;
|
||||
|
||||
add_filter('wpo_cache_admin_bar_menu_items', array($this, 'admin_bar_menu'), 30, 1);
|
||||
|
||||
if (WP_Optimize::is_premium()) {
|
||||
$this->load_premium();
|
||||
}
|
||||
|
||||
/**
|
||||
* Directory that stores the cache, including gzipped files and mobile specifc cache
|
||||
*/
|
||||
if (!defined('WPO_CACHE_MIN_FILES_DIR')) define('WPO_CACHE_MIN_FILES_DIR', untrailingslashit(WP_CONTENT_DIR).'/cache/wpo-minify');
|
||||
if (!defined('WPO_CACHE_MIN_FILES_URL')) define('WPO_CACHE_MIN_FILES_URL', untrailingslashit(WP_CONTENT_URL).'/cache/wpo-minify');
|
||||
|
||||
if (!class_exists('WP_Optimize_Minify_Cache_Functions')) {
|
||||
include WP_OPTIMIZE_MINIFY_DIR.'/class-wp-optimize-minify-cache-functions.php';
|
||||
}
|
||||
|
||||
$this->load_frontend();
|
||||
|
||||
// cron job to delete old wpo_min cache
|
||||
add_action('wpo_minify_purge_old_cache', array('WP_Optimize_Minify_Cache_Functions', 'purge_old'));
|
||||
// front-end actions; skip on certain post_types or if there are specific keys on the url or if editor or admin
|
||||
|
||||
// Handle minify cache purging.
|
||||
add_action('wp_loaded', array($this, 'handle_purge_minify_cache'));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Admin toolbar processing
|
||||
*
|
||||
* @param array $menu_items
|
||||
* @return array
|
||||
*/
|
||||
public function admin_bar_menu($menu_items) {
|
||||
$wpo_minify_options = wp_optimize_minify_config()->get();
|
||||
|
||||
if (!$wpo_minify_options['enabled'] || !current_user_can('manage_options') || !($wpo_minify_options['enable_css'] || $wpo_minify_options['enable_js'])) return $menu_items;
|
||||
|
||||
$act_url = remove_query_arg('wpo_minify_cache_purged');
|
||||
$cache_path = WP_Optimize_Minify_Cache_Functions::cache_path();
|
||||
$cache_size_info = '<h4>'.__('Minify cache', 'wp-optimize').'</h4><span><span class="label">'.__('Cache size:', 'wp-optimize').'</span> <span class="stats">'.esc_html(WP_Optimize_Minify_Cache_Functions::get_cachestats($cache_path['cachedir'])).'</span></span>';
|
||||
|
||||
$menu_items[] = array(
|
||||
'id' => 'wpo_minify_cache_stats',
|
||||
'title' => $cache_size_info,
|
||||
'meta' => array(
|
||||
'class' => 'wpo-cache-stats',
|
||||
),
|
||||
'parent' => 'wpo_purge_cache',
|
||||
);
|
||||
|
||||
$menu_items[] = array(
|
||||
'parent' => 'wpo_purge_cache',
|
||||
'id' => 'purge_minify_cache',
|
||||
'title' => __('Purge minify cache', 'wp-optimize'),
|
||||
'href' => add_query_arg('_wpo_purge_minify_cache', wp_create_nonce('wpo_purge_minify_cache'), $act_url),
|
||||
);
|
||||
return $menu_items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if purge single page action sent and purge cache.
|
||||
*/
|
||||
public function handle_purge_minify_cache() {
|
||||
$wpo_minify_options = wp_optimize_minify_config()->get();
|
||||
if (!$wpo_minify_options['enabled'] || !current_user_can('manage_options')) return;
|
||||
|
||||
if (isset($_GET['wpo_minify_cache_purged'])) {
|
||||
if (is_admin()) {
|
||||
add_action('admin_notices', array($this, 'notice_purge_minify_cache_success'));
|
||||
return;
|
||||
} else {
|
||||
$message = __('Minify cache purged', 'wp-optmize');
|
||||
printf('<script>alert("%s");</script>', $message);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($_GET['_wpo_purge_minify_cache'])) return;
|
||||
|
||||
if (wp_verify_nonce($_GET['_wpo_purge_minify_cache'], 'wpo_purge_minify_cache')) {
|
||||
$success = false;
|
||||
|
||||
// Purge minify
|
||||
$results = $this->minify_commands->purge_minify_cache();
|
||||
if ("caches cleared" == $results['result']) $success = true;
|
||||
|
||||
// remove nonce from url and reload page.
|
||||
wp_redirect(add_query_arg('wpo_minify_cache_purged', $success, remove_query_arg('_wpo_purge_minify_cache')));
|
||||
exit;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the admin class
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function load_admin() {
|
||||
if (!is_admin()) return;
|
||||
|
||||
if (!class_exists('WP_Optimize_Minify_Admin')) {
|
||||
include WP_OPTIMIZE_MINIFY_DIR.'/class-wp-optimize-minify-admin.php';
|
||||
}
|
||||
new WP_Optimize_Minify_Admin();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the frontend class
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function load_frontend() {
|
||||
if ($this->enabled) {
|
||||
if (!class_exists('WP_Optimize_Minify_Front_End')) {
|
||||
include WP_OPTIMIZE_MINIFY_DIR.'/class-wp-optimize-minify-front-end.php';
|
||||
}
|
||||
new WP_Optimize_Minify_Front_End();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the premium class
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function load_premium() {
|
||||
if (!class_exists('WP_Optimize_Minify_Premium')) {
|
||||
include WP_OPTIMIZE_MINIFY_DIR.'/class-wp-optimize-minify-premium.php';
|
||||
}
|
||||
$this->premium = new WP_Optimize_Minify_Premium();
|
||||
}
|
||||
|
||||
/**
|
||||
* Run during activation
|
||||
* Increment cache first as it will save files to that dir
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function plugin_activate() {
|
||||
// increment cache time
|
||||
if (class_exists('WP_Optimize_Minify_Cache_Functions')) {
|
||||
WP_Optimize_Minify_Cache_Functions::cache_increment();
|
||||
}
|
||||
|
||||
// old cache purge event cron
|
||||
wp_clear_scheduled_hook('wpo_minify_purge_old_cache');
|
||||
if (!wp_next_scheduled('wpo_minify_purge_old_cache')) {
|
||||
wp_schedule_event(time() + 86400, 'daily', 'wpo_minify_purge_old_cache');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run during plugin deactivation
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function plugin_deactivate() {
|
||||
if (defined('WPO_MINIFY_PHP_VERSION_MET') && !WPO_MINIFY_PHP_VERSION_MET) return;
|
||||
if (class_exists('WP_Optimize_Minify_Cache_Functions')) {
|
||||
WP_Optimize_Minify_Cache_Functions::purge_temp_files();
|
||||
WP_Optimize_Minify_Cache_Functions::purge_old();
|
||||
WP_Optimize_Minify_Cache_Functions::purge_others();
|
||||
}
|
||||
|
||||
// old cache purge event cron
|
||||
wp_clear_scheduled_hook('wpo_minify_purge_old_cache');
|
||||
}
|
||||
|
||||
/**
|
||||
* Run during plugin uninstall
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function plugin_uninstall() {
|
||||
if (defined('WPO_MINIFY_PHP_VERSION_MET') && !WPO_MINIFY_PHP_VERSION_MET) return;
|
||||
// remove options from DB
|
||||
if (!function_exists('wp_optimize_minify_config')) {
|
||||
include WP_OPTIMIZE_MINIFY_DIR.'/class-wp-optimize-minify-config.php';
|
||||
}
|
||||
wp_optimize_minify_config()->purge();
|
||||
// remove minified files
|
||||
if (class_exists('WP_Optimize_Minify_Cache_Functions')) {
|
||||
WP_Optimize_Minify_Cache_Functions::purge();
|
||||
WP_Optimize_Minify_Cache_Functions::purge_others();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows success notice for purge minify cache
|
||||
*/
|
||||
public function notice_purge_minify_cache_success() {
|
||||
$this->show_notice(__('The minify cache was successfully purged.', 'wp-optimize'), 'success');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show notification in WordPress admin.
|
||||
*
|
||||
* @param string $message HTML (no further escaping is performed)
|
||||
* @param string $type error, warning, success, or info
|
||||
*/
|
||||
public function show_notice($message, $type) {
|
||||
global $current_screen;
|
||||
|
||||
if ($current_screen && is_callable(array($current_screen, 'is_block_editor')) && $current_screen->is_block_editor()) :
|
||||
?>
|
||||
<script>
|
||||
window.addEventListener('load', function() {
|
||||
(function(wp) {
|
||||
if (window.wp && wp.hasOwnProperty('data') && 'function' == typeof wp.data.dispatch) {
|
||||
wp.data.dispatch('core/notices').createNotice(
|
||||
'<?php echo $type; ?>',
|
||||
'<?php echo $message; ?>',
|
||||
{
|
||||
isDismissible: true,
|
||||
}
|
||||
);
|
||||
}
|
||||
})(window.wp);
|
||||
});
|
||||
</script>
|
||||
<?php else : ?>
|
||||
<div class="notice wpo-notice notice-<?php echo $type; ?> is-dismissible">
|
||||
<p><?php echo $message; ?></p>
|
||||
</div>
|
||||
<?php
|
||||
endif;
|
||||
}
|
||||
}
|
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
if (!defined('ABSPATH')) die('Access denied.');
|
||||
|
||||
if (!class_exists('Updraft_Task_1_2')) require_once(WPO_PLUGIN_MAIN_PATH . 'vendor/team-updraft/common-libs/src/updraft-tasks/class-updraft-task.php');
|
||||
|
||||
if (!class_exists('WP_Optimize_Minify_Preloader')) require_once(dirname(__FILE__) . '/class-wpo-minify-preloader.php');
|
||||
|
||||
class WP_Optimize_Minify_Load_Url_Task extends Updraft_Task_1_2 {
|
||||
|
||||
/**
|
||||
* Default options.
|
||||
*/
|
||||
public function get_default_options() {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Run preload http requests with different user-agent values to cache pages for different devices.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function run() {
|
||||
$url = $this->get_option('url');
|
||||
|
||||
if (empty($url)) return;
|
||||
|
||||
$minify_preloader = WP_Optimize_Minify_Preloader::instance();
|
||||
|
||||
// load pages with different user-agents values.
|
||||
|
||||
$minify_preloader->preload_desktop($url);
|
||||
$minify_preloader->preload_amp($url);
|
||||
|
||||
if (defined('WP_CLI') && WP_CLI) {
|
||||
WP_CLI::log($url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Action triggered after preloading a single url
|
||||
*
|
||||
* @param string $url The url to preload
|
||||
* @param object $minify_preloader Minify preloader instance
|
||||
*/
|
||||
do_action('wpoptimize_after_minify_preload_url', $url, $minify_preloader);
|
||||
|
||||
/**
|
||||
* Allows to change the delay between each URL preload, to reduce server load.
|
||||
*
|
||||
* @param integer $preload_delay The delay between each request in microseconds (1000000 = 1 second).
|
||||
*/
|
||||
usleep(apply_filters('wpoptimize_minify_preload_delay', 500000));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@@ -0,0 +1,166 @@
|
||||
<?php
|
||||
|
||||
if (!defined('ABSPATH')) die('No direct access allowed');
|
||||
|
||||
|
||||
if (!class_exists('WP_Optimize_Minify_Load_Url_Task')) require_once(dirname(__FILE__) . '/class-wpo-minify-load-url-task.php');
|
||||
|
||||
if (!class_exists('WP_Optimize_Preloader')) require_once(WPO_PLUGIN_MAIN_PATH . 'includes/class-wpo-preloader.php');
|
||||
|
||||
class WP_Optimize_Minify_Preloader extends WP_Optimize_Preloader {
|
||||
|
||||
protected $preload_type = 'minify';
|
||||
|
||||
protected $task_type = 'minify-load-url-task';
|
||||
|
||||
static protected $_instance = null;
|
||||
|
||||
/**
|
||||
* WP_Optimize_Page_Cache_Preloader constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
|
||||
add_filter('cron_schedules', array($this, 'cron_add_intervals'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if minify is active.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_option_active() {
|
||||
if (!function_exists('wp_optimize_minify_config')) {
|
||||
include_once WPO_PLUGIN_MAIN_PATH . '/minify/class-wp-optimize-minify-config.php';
|
||||
}
|
||||
return wp_optimize_minify_config()->get('enabled');
|
||||
}
|
||||
|
||||
/**
|
||||
* Add intervals to cron schedules.
|
||||
*
|
||||
* @param array $schedules
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function cron_add_intervals($schedules) {
|
||||
$interval = $this->get_continue_preload_cron_interval();
|
||||
$schedules['wpo_minify_preload_continue_interval'] = array(
|
||||
'interval' => $interval,
|
||||
'display' => round($interval / 60, 1).' minutes'
|
||||
);
|
||||
|
||||
return $schedules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create tasks (WP_Optimize_Load_Url_Task) for preload all urls from site.
|
||||
*
|
||||
* @param string $type The preload type (currently: scheduled, manual)
|
||||
* @return void
|
||||
*/
|
||||
public function create_tasks_for_preload_site_urls($type = 'manual') {
|
||||
$urls = $this->get_site_urls();
|
||||
|
||||
if (!empty($urls)) {
|
||||
|
||||
$this->log(__('Minify: Creating tasks for preload site urls.', 'wp-optimize'));
|
||||
|
||||
foreach ($urls as $url) {
|
||||
if (wpo_url_in_exceptions($url)) continue;
|
||||
|
||||
// this description is being used for internal purposes.
|
||||
$description = 'Preload - '.$url;
|
||||
$options = array('url' => $url, 'preload_type' => $type, 'anonymous_user_allowed' => (defined('DOING_CRON') && DOING_CRON) || (defined('WP_CLI') && WP_CLI));
|
||||
|
||||
WP_Optimize_Minify_Load_Url_Task::create_task($this->task_type, $description, $options, 'WP_Optimize_Minify_Load_Url_Task');
|
||||
}
|
||||
|
||||
$this->log(__('Minify: Tasks for preload site urls created.', 'wp-optimize'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Instance of WP_Optimize_Minify_Preloader.
|
||||
*
|
||||
* @return WP_Optimize_Minify_Preloader
|
||||
*/
|
||||
public static function instance() {
|
||||
if (empty(self::$_instance)) {
|
||||
self::$_instance = new WP_Optimize_Minify_Preloader();
|
||||
}
|
||||
|
||||
return self::$_instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Option disabled error message
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function get_option_disabled_error() {
|
||||
return array(
|
||||
'success' => false,
|
||||
'error' => __('Minify is disabled.', 'wp-optimize')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get preload already running error message
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function get_preload_already_running_error() {
|
||||
return array(
|
||||
'success' => false,
|
||||
'error' => __('Probably minify preload is running already.', 'wp-optimize')
|
||||
);
|
||||
}
|
||||
|
||||
protected function get_preload_data() {
|
||||
$cache_path = WP_Optimize_Minify_Cache_Functions::cache_path();
|
||||
$cache_dir = $cache_path['cachedir'];
|
||||
$minify_cache_data = array();
|
||||
$minify_cache_data['size'] = esc_html(WP_Optimize_Minify_Cache_Functions::get_cachestats($cache_dir));
|
||||
$minify_cache_data['total_size'] = esc_html(WP_Optimize_Minify_Cache_Functions::get_cachestats(WPO_CACHE_MIN_FILES_DIR));
|
||||
return $minify_cache_data;
|
||||
}
|
||||
|
||||
protected function get_preloading_message($minify_cache_data) {
|
||||
return array(
|
||||
'done' => false,
|
||||
'message' => __('Loading URLs...', 'wp-optimize'),
|
||||
'size' => WP_Optimize()->format_size($minify_cache_data['size']),
|
||||
'total_size' => $minify_cache_data['total_size']
|
||||
);
|
||||
}
|
||||
|
||||
protected function get_last_preload_message($minify_cache_data, $last_preload_time_str) {
|
||||
return array(
|
||||
'done' => true,
|
||||
'message' => sprintf(__('Last preload finished at %s', 'wp-optimize'), $last_preload_time_str),
|
||||
'size' => WP_Optimize()->format_size($minify_cache_data['size']),
|
||||
'total_size' => $minify_cache_data['total_size']
|
||||
);
|
||||
}
|
||||
|
||||
protected function get_preload_success_message($minify_cache_data) {
|
||||
return array(
|
||||
'done' => true,
|
||||
'size' => WP_Optimize()->format_size($minify_cache_data['size']),
|
||||
'total_size' => $minify_cache_data['total_size']
|
||||
);
|
||||
}
|
||||
|
||||
protected function get_preload_progress_message($minify_cache_data, $preloaded_message, $preload_resuming_in) {
|
||||
return array(
|
||||
'done' => false,
|
||||
'message' => $preloaded_message,
|
||||
'size' => WP_Optimize()->format_size($minify_cache_data['size']),
|
||||
'total_size' => $minify_cache_data['total_size'],
|
||||
'resume_in' => $preload_resuming_in
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
WP_Optimize_Minify_Preloader::instance();
|
Reference in New Issue
Block a user