diff --git a/src/MprIcons.php b/src/MprIcons.php index 97d3724..0804a14 100644 --- a/src/MprIcons.php +++ b/src/MprIcons.php @@ -379,9 +379,12 @@ class MprIcons /** * Detect which icon set the current theme uses * - * Checks theme config and assets for Material Icons indicators. - * Returns 'fontawesome' for classic and most themes, - * 'material' for Hummingbird and Material-based themes. + * PS 1.6 themes use Font Awesome. + * PS 1.7+ themes (classic, hummingbird, etc.) bundle Material Icons + * inside theme.css — no separate CSS file to scan for. + * + * Strategy: read the first ~50KB of theme.css and check for + * 'Material Icons' font-face. Fast, reliable, works across all versions. */ public static function detectThemeIcons(): string { @@ -390,19 +393,32 @@ class MprIcons } try { - // PS 1.7+ — check theme.yml - $themeYml = _PS_THEME_DIR_ . 'config/theme.yml'; - if (file_exists($themeYml)) { - $content = file_get_contents($themeYml); - if (stripos($content, 'hummingbird') !== false) { - return self::MATERIAL; + // Check compiled theme CSS for Material Icons font-face + // PS 1.7+ bundles icons into theme.css via webpack + $cssFiles = [ + _PS_THEME_DIR_ . 'assets/css/theme.css', + _PS_THEME_DIR_ . 'css/theme.css', + ]; + + foreach ($cssFiles as $cssFile) { + if (!file_exists($cssFile)) { + continue; } - if (stripos($content, 'material-icons') !== false || stripos($content, 'material_icons') !== false) { - return self::MATERIAL; + // Read first 50KB — font-face is always near the top + $handle = fopen($cssFile, 'r'); + if ($handle) { + $chunk = fread($handle, 51200); + fclose($handle); + if (stripos($chunk, 'Material Icons') !== false) { + return self::MATERIAL; + } + if (stripos($chunk, 'FontAwesome') !== false) { + return self::FA; + } } } - // Check theme assets for material-icons CSS + // Fallback: check for separate icon CSS files $dirs = [ _PS_THEME_DIR_ . 'assets/css/', _PS_THEME_DIR_ . 'css/', @@ -416,20 +432,26 @@ class MprIcons if (stripos($file, 'material') !== false) { return self::MATERIAL; } + if (stripos($file, 'fontawesome') !== false || stripos($file, 'font-awesome') !== false) { + return self::FA; + } } } - // PS 1.6 — check for parent theme name - if (defined('_THEME_NAME_')) { - $themeName = _THEME_NAME_; - if (stripos($themeName, 'hummingbird') !== false) { - return self::MATERIAL; - } + // PS 1.6 — check for font-awesome directory + $faDir = _PS_THEME_DIR_ . 'css/font-awesome/'; + if (is_dir($faDir)) { + return self::FA; } } catch (\Exception $e) { // Detection failed — use safe default } + // Safe default: FA for PS 1.6, Material for 1.7+ + if (defined('_PS_VERSION_') && version_compare(_PS_VERSION_, '1.7.0.0', '>=')) { + return self::MATERIAL; + } + return self::FA; } @@ -444,8 +466,30 @@ class MprIcons } $iconSet = self::getIconSet(); + $needle = ($iconSet === self::MATERIAL) ? 'Material Icons' : 'FontAwesome'; try { + // Check compiled theme CSS — icons are typically bundled here + $cssFiles = [ + _PS_THEME_DIR_ . 'assets/css/theme.css', + _PS_THEME_DIR_ . 'css/theme.css', + ]; + + foreach ($cssFiles as $cssFile) { + if (!file_exists($cssFile)) { + continue; + } + $handle = fopen($cssFile, 'r'); + if ($handle) { + $chunk = fread($handle, 51200); + fclose($handle); + if (stripos($chunk, $needle) !== false) { + return true; + } + } + } + + // Check for separate icon CSS files $dirs = [ _PS_THEME_DIR_ . 'assets/css/', _PS_THEME_DIR_ . 'css/', @@ -455,34 +499,25 @@ class MprIcons if (!is_dir($dir)) { continue; } - $files = scandir($dir); foreach ($files as $file) { if ($file === '.' || $file === '..') { continue; } - - if ($iconSet === self::MATERIAL) { - if (stripos($file, 'material') !== false) { - return true; - } - } else { - if (stripos($file, 'fontawesome') !== false || stripos($file, 'font-awesome') !== false) { - return true; - } + if ($iconSet === self::MATERIAL && stripos($file, 'material') !== false) { + return true; + } + if ($iconSet === self::FA && (stripos($file, 'fontawesome') !== false || stripos($file, 'font-awesome') !== false)) { + return true; } } } - // For Font Awesome — most PS 1.6/1.7 themes include it as a dependency - // Check if theme's package.json or theme.yml lists it + // PS 1.6 — check for font-awesome directory if ($iconSet === self::FA) { - $themeYml = _PS_THEME_DIR_ . 'config/theme.yml'; - if (file_exists($themeYml)) { - $content = file_get_contents($themeYml); - if (stripos($content, 'font-awesome') !== false || stripos($content, 'fontawesome') !== false) { - return true; - } + $faDir = _PS_THEME_DIR_ . 'css/font-awesome/'; + if (is_dir($faDir)) { + return true; } } } catch (\Exception $e) {