2.0 #1
@@ -9,7 +9,7 @@ use DOMElement;
|
|||||||
class HtmlCleaner
|
class HtmlCleaner
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Render a DOM node into safe HTML, preserving allowed block and inline tags.
|
* Renders a DOM node into safe HTML, preserving only allowed tags.
|
||||||
*/
|
*/
|
||||||
public static function renderNode(DOMNode $node, array $allowedTags, array $allowedInline, string $parentTag = ''): ?string
|
public static function renderNode(DOMNode $node, array $allowedTags, array $allowedInline, string $parentTag = ''): ?string
|
||||||
{
|
{
|
||||||
@@ -23,7 +23,6 @@ class HtmlCleaner
|
|||||||
|
|
||||||
$tag = $node->nodeName;
|
$tag = $node->nodeName;
|
||||||
|
|
||||||
// Special case: handle <br> within <p>
|
|
||||||
if ($tag === 'br') {
|
if ($tag === 'br') {
|
||||||
if ($parentTag === 'p') {
|
if ($parentTag === 'p') {
|
||||||
$prev = $node->previousSibling;
|
$prev = $node->previousSibling;
|
||||||
@@ -36,13 +35,11 @@ class HtmlCleaner
|
|||||||
return '<br>';
|
return '<br>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip all other <br>
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recursively render children
|
|
||||||
$inner = '';
|
$inner = '';
|
||||||
|
|
||||||
foreach ($node->childNodes as $child) {
|
foreach ($node->childNodes as $child) {
|
||||||
$rendered = self::renderNode($child, $allowedTags, $allowedInline, $tag);
|
$rendered = self::renderNode($child, $allowedTags, $allowedInline, $tag);
|
||||||
if ($rendered !== null) {
|
if ($rendered !== null) {
|
||||||
@@ -50,7 +47,6 @@ class HtmlCleaner
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle block tags
|
|
||||||
if (in_array($tag, $allowedTags)) {
|
if (in_array($tag, $allowedTags)) {
|
||||||
if ($tag === 'p') {
|
if ($tag === 'p') {
|
||||||
$html = $node->C14N();
|
$html = $node->C14N();
|
||||||
@@ -58,31 +54,24 @@ class HtmlCleaner
|
|||||||
$class = $isItalic ? ' class="italic"' : '';
|
$class = $isItalic ? ' class="italic"' : '';
|
||||||
return "<p{$class}>" . trim($inner) . "</p>";
|
return "<p{$class}>" . trim($inner) . "</p>";
|
||||||
}
|
}
|
||||||
|
|
||||||
return "<{$tag}>" . trim($inner) . "</{$tag}>";
|
return "<{$tag}>" . trim($inner) . "</{$tag}>";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle inline tags
|
|
||||||
if (in_array($tag, $allowedInline)) {
|
if (in_array($tag, $allowedInline)) {
|
||||||
return "<{$tag}>{$inner}</{$tag}>";
|
return "<{$tag}>{$inner}</{$tag}>";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unknown tags are ignored but their content is preserved
|
|
||||||
return $inner;
|
return $inner;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clean a raw HTML string: remove unwanted tags, empty elements, garbage phrases, and excessive whitespace.
|
* Cleans a raw HTML string: removes unwanted content, empty tags, and excess whitespace.
|
||||||
*/
|
*/
|
||||||
public static function clean(string $html): string
|
public static function clean(string $html): string
|
||||||
{
|
{
|
||||||
// Remove first <h1>
|
|
||||||
$html = preg_replace('/<h1\b[^>]*>.*?<\/h1>/i', '', $html, 1);
|
$html = preg_replace('/<h1\b[^>]*>.*?<\/h1>/i', '', $html, 1);
|
||||||
|
|
||||||
// Remove empty tags like <i></i>, <span></span>
|
|
||||||
$html = preg_replace('/<(\w+)[^>]*>\s*<\/\1>/', '', $html);
|
$html = preg_replace('/<(\w+)[^>]*>\s*<\/\1>/', '', $html);
|
||||||
|
|
||||||
// Remove specific garbage strings
|
|
||||||
$unwantedStrings = [
|
$unwantedStrings = [
|
||||||
'Report this content',
|
'Report this content',
|
||||||
'<p><strong>Taggar:</strong></p>',
|
'<p><strong>Taggar:</strong></p>',
|
||||||
@@ -92,16 +81,12 @@ class HtmlCleaner
|
|||||||
$html = str_replace($str, '', $html);
|
$html = str_replace($str, '', $html);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove localized date lines like: fre, jul 04, 2025 09:55 CET
|
|
||||||
$html = preg_replace('/\b[a-z]{3},\s[a-z]{3}\s\d{2},\s\d{4}\s\d{2}:\d{2}\sCET\b/i', '', $html);
|
$html = preg_replace('/\b[a-z]{3},\s[a-z]{3}\s\d{2},\s\d{4}\s\d{2}:\d{2}\sCET\b/i', '', $html);
|
||||||
|
$html = str_replace(["\u{A0}", "\t", "\r"], ' ', $html);
|
||||||
|
$html = preg_replace('/[ ]{2,}/', ' ', $html);
|
||||||
|
$html = preg_replace("/(\n\s*){2,}/", "\n", $html);
|
||||||
|
$html = str_replace([' ', ' \n'], '', $html);
|
||||||
|
|
||||||
// Normalize whitespace
|
return trim($html);
|
||||||
$html = str_replace(["\u{A0}", "\t", "\r"], ' ', $html); // Remove non-breaking spaces and tabs
|
|
||||||
$html = preg_replace('/[ ]{2,}/', ' ', $html); // Collapse double spaces
|
|
||||||
$html = preg_replace("/(\n\s*){2,}/", "\n", $html); // Collapse multiple newlines
|
|
||||||
$html = str_replace([' ', ' \n'], '', $html); // Additional spacing clean
|
|
||||||
$html = trim($html);
|
|
||||||
|
|
||||||
return $html;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user