minify($css); } /** * {@inheritDoc} */ public function extractResponsive(): string { $sourceFile = get_template_directory() . self::SOURCE_RESPONSIVE; if (!file_exists($sourceFile)) { return ''; } $css = file_get_contents($sourceFile); if ($css === false) { return ''; } $criticalCSS = ''; // Extraer solo media queries criticas // Regex: captura @media (...) { contenido con 1 nivel de {} } foreach (self::CRITICAL_BREAKPOINTS as $breakpoint) { $pattern = '/' . preg_quote($breakpoint, '/') . '\s*\{([^{}]*(?:\{[^{}]*\}[^{}]*)*)\}/s'; if (preg_match_all($pattern, $css, $matches)) { foreach ($matches[0] as $match) { $criticalCSS .= $match . "\n"; } } } return $this->minify($criticalCSS); } /** * {@inheritDoc} */ public function generateAll(): array { $results = []; // Variables CSS $variablesCSS = $this->extractVariables(); if (!empty($variablesCSS)) { $this->cache->set('variables', $variablesCSS); $results['variables'] = strlen($variablesCSS); } // Responsive critico $responsiveCSS = $this->extractResponsive(); if (!empty($responsiveCSS)) { $this->cache->set('responsive', $responsiveCSS); $results['responsive'] = strlen($responsiveCSS); } return $results; } /** * {@inheritDoc} */ public function needsRegeneration(): bool { $templateDir = get_template_directory(); return $this->cache->isStale('variables', $templateDir . self::SOURCE_VARIABLES) || $this->cache->isStale('responsive', $templateDir . self::SOURCE_RESPONSIVE); } /** * Minifica CSS eliminando espacios y comentarios innecesarios */ private function minify(string $css): string { // Eliminar comentarios $css = preg_replace('/\/\*[\s\S]*?\*\//', '', $css) ?? $css; // Eliminar espacios innecesarios $css = preg_replace('/\s+/', ' ', $css) ?? $css; $css = preg_replace('/\s*([{};:,>+~])\s*/', '$1', $css) ?? $css; // Eliminar ultimo punto y coma antes de } $css = preg_replace('/;}/', '}', $css) ?? $css; return trim($css); } }