• '; public static function sanitize(string $html): string { $html = trim($html); if ($html === '') { return ''; } // Strip all tags except the whitelist $html = strip_tags($html, self::ALLOWED_TAGS); // Sanitize tags: keep only href, add target="_blank" and rel="noopener" $html = preg_replace_callback( '/]*>/i', static function (array $match): string { $tag = $match[0]; // Extract href value if (preg_match('/href\s*=\s*"([^"]*)"/i', $tag, $hrefMatch)) { $href = $hrefMatch[1]; // Block javascript: URLs if (preg_match('/^\s*javascript\s*:/i', $href)) { return ''; } return ''; } return ''; }, $html ) ?? $html; // Remove empty paragraphs that Quill sometimes produces $html = preg_replace('/

      \s*\s*<\/p>/', '', $html) ?? $html; return trim($html); } public static function isHtml(string $text): bool { return $text !== strip_tags($text); } }