opticore/includes/class-minifier.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;
}
}