<?php
namespace App\EventListener;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Minify_HTML;
class MinifyHTMLListener
{
public function onKernelResponse(ResponseEvent $event)
{
$response = $event->getResponse();
$content = $response->getContent();
if (strpos($content, '<html') !== false || strpos($content, '</html>') !== false) {
$cleanedHtml = $this->cleanJavascripts($content);
$cleanedHtml = Minify_HTML::minify($cleanedHtml);
$cleanedHtml = $this->cleanHTML($cleanedHtml);
$response->setContent($cleanedHtml);
}
}
private function cleanHTML($content)
{
$placeholders = [];
// Remplacer temporairement les contenus <input> et <textarea>
$content = preg_replace_callback(
'~(<input[^>]*>|<textarea[^>]*>.*?</textarea>|<pre[^>]*>.*?</pre>|<code[^>]*>.*?</code>)~is',
function($matches) use (&$placeholders) {
$placeholder = 'PLACEHOLDER_' . uniqid() . '_PLACEHOLDER';
$placeholders[$placeholder] = $matches[0];
return $placeholder;
},
$content
);
// Supprime les commentaires
$content = preg_replace('/<!--.*?-->/ms', '', $content);
// Supprime les espaces blancs répétés et les sauts de ligne
$content = preg_replace('/\s+/ms', ' ', $content);
// Supprime les espaces autour des balises
$content = preg_replace('/> </ms', '><', $content);
// Restaurer les contenus <input> et <textarea> originaux
foreach ($placeholders as $placeholder => $originalContent) {
$content = str_replace($placeholder, $originalContent, $content);
}
return $content;
}
private function cleanJavascripts($htmlContent)
{
$placeholders = [];
// Remplacer temporairement les contenus <input> et <textarea>
$htmlContent = preg_replace_callback(
'~(<input[^>]*>|<textarea[^>]*>.*?</textarea>|<pre[^>]*>.*?</pre>|<code[^>]*>.*?</code>)~is',
function($matches) use (&$placeholders) {
$placeholder = 'PLACEHOLDER_' . uniqid() . '_PLACEHOLDER';
$placeholders[$placeholder] = $matches[0];
return $placeholder;
},
$htmlContent
);
// Votre traitement précédent pour les scripts
$content = preg_replace_callback(
'~<script\b(.*?)>(.*?)<\/script>~is',
function($matches) {
$scriptAttributes = $matches[1];
$scriptContent = $matches[2];
// Supprimer les commentaires unilignes (//) mais éviter de supprimer les URLs
$scriptContent = preg_replace('~(?<!\:|[^ ])//[^\n\r]*[\n\r]~', "", $scriptContent);
// Supprimer les commentaires multilignes (/* ... */)
$scriptContent = preg_replace('~\/\*.*?\*\/~s', '', $scriptContent);
return '<script' . $scriptAttributes . '>' . $scriptContent . '</script>';
},
$htmlContent
);
// Supprime les espaces superflus après et avant les balises
$content = preg_replace('~>\s+<~', '><', $content);
// Restaurer les contenus <input> et <textarea> originaux
foreach ($placeholders as $placeholder => $originalContent) {
$content = str_replace($placeholder, $originalContent, $content);
}
return $content;
}
}