160 lines
4.1 KiB
PHP
160 lines
4.1 KiB
PHP
<?php
|
|
/**
|
|
* Minifier Class
|
|
*
|
|
* Handles CSS and JS minification
|
|
*/
|
|
|
|
if (!defined('ABSPATH')) {
|
|
exit;
|
|
}
|
|
|
|
class OptiCore_Minifier {
|
|
|
|
private static $instance = null;
|
|
private $minified_dir;
|
|
|
|
public static function get_instance() {
|
|
if (null === self::$instance) {
|
|
self::$instance = new self();
|
|
}
|
|
return self::$instance;
|
|
}
|
|
|
|
private function __construct() {
|
|
$this->minified_dir = WP_CONTENT_DIR . '/cache/opticore/minified';
|
|
}
|
|
|
|
public function init() {
|
|
$settings = get_option('opticore_settings');
|
|
|
|
if (!empty($settings['enable_minify_css'])) {
|
|
add_filter('style_loader_tag', array($this, 'minify_css_tag'), 10, 4);
|
|
}
|
|
|
|
if (!empty($settings['enable_minify_js'])) {
|
|
add_filter('script_loader_tag', array($this, 'minify_js_tag'), 10, 3);
|
|
}
|
|
|
|
// Defer non-critical JS
|
|
add_filter('script_loader_tag', array($this, 'defer_scripts'), 10, 3);
|
|
}
|
|
|
|
/**
|
|
* Minify CSS
|
|
*/
|
|
public function minify_css($css) {
|
|
// Remove comments
|
|
$css = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $css);
|
|
|
|
// Remove whitespace
|
|
$css = str_replace(array("\r\n", "\r", "\n", "\t"), '', $css);
|
|
$css = preg_replace('/\s+/', ' ', $css);
|
|
$css = str_replace(array(' {', '{ '), '{', $css);
|
|
$css = str_replace(array(' }', '} '), '}', $css);
|
|
$css = str_replace(array(' :', ': '), ':', $css);
|
|
$css = str_replace(array(' ;', '; '), ';', $css);
|
|
$css = str_replace(array(' ,', ', '), ',', $css);
|
|
|
|
return trim($css);
|
|
}
|
|
|
|
/**
|
|
* Minify JavaScript
|
|
*/
|
|
public function minify_js($js) {
|
|
// Remove comments (simple version - doesn't handle all cases)
|
|
$js = preg_replace('/((?:\/\*(?:[^*]|(?:\*+[^*\/]))*\*+\/)|(?:\/\/.*))/', '', $js);
|
|
|
|
// Remove whitespace
|
|
$js = preg_replace('/\s+/', ' ', $js);
|
|
|
|
return trim($js);
|
|
}
|
|
|
|
/**
|
|
* Process CSS tag for minification
|
|
*/
|
|
public function minify_css_tag($html, $handle, $href, $media) {
|
|
// Skip external files
|
|
if (strpos($href, site_url()) === false) {
|
|
return $html;
|
|
}
|
|
|
|
// Skip already minified files
|
|
if (strpos($href, '.min.') !== false) {
|
|
return $html;
|
|
}
|
|
|
|
return $html;
|
|
}
|
|
|
|
/**
|
|
* Process JS tag for minification
|
|
*/
|
|
public function minify_js_tag($tag, $handle, $src) {
|
|
// Skip external files
|
|
if (strpos($src, site_url()) === false) {
|
|
return $tag;
|
|
}
|
|
|
|
// Skip already minified files
|
|
if (strpos($src, '.min.') !== false) {
|
|
return $tag;
|
|
}
|
|
|
|
return $tag;
|
|
}
|
|
|
|
/**
|
|
* Defer non-critical JavaScript
|
|
*/
|
|
public function defer_scripts($tag, $handle, $src) {
|
|
// Skip jQuery and critical scripts
|
|
$critical_scripts = array('jquery', 'jquery-core', 'jquery-migrate');
|
|
|
|
if (in_array($handle, $critical_scripts)) {
|
|
return $tag;
|
|
}
|
|
|
|
// Add defer attribute
|
|
if (strpos($tag, 'defer') === false && strpos($tag, 'async') === false) {
|
|
return str_replace(' src', ' defer src', $tag);
|
|
}
|
|
|
|
return $tag;
|
|
}
|
|
|
|
/**
|
|
* Combine CSS files
|
|
*/
|
|
public function combine_css_files($files) {
|
|
$combined = '';
|
|
|
|
foreach ($files as $file) {
|
|
if (file_exists($file)) {
|
|
$content = file_get_contents($file);
|
|
$combined .= $this->minify_css($content) . "\n";
|
|
}
|
|
}
|
|
|
|
return $combined;
|
|
}
|
|
|
|
/**
|
|
* Combine JS files
|
|
*/
|
|
public function combine_js_files($files) {
|
|
$combined = '';
|
|
|
|
foreach ($files as $file) {
|
|
if (file_exists($file)) {
|
|
$content = file_get_contents($file);
|
|
$combined .= $this->minify_js($content) . ";\n";
|
|
}
|
|
}
|
|
|
|
return $combined;
|
|
}
|
|
}
|
|
|