';
public static function sanitize(mixed $value): ?string
{
if ($value === null) {
return null;
}
$html = trim((string) $value);
if ($html === '') {
return null;
}
if ($html === strip_tags($html)) {
return self::plainToHtml($html);
}
$clean = trim(strip_tags($html, self::ALLOWED_TAGS));
return $clean === '' ? null : $clean;
}
public static function normalizeForEditor(?string $value): string
{
if ($value === null || trim($value) === '') {
return '';
}
if ($value === strip_tags($value)) {
return self::plainToHtml($value) ?? '';
}
return $value;
}
public static function plainToHtml(string $plain): ?string
{
$plain = str_replace(["\r\n", "\r"], "\n", trim($plain));
if ($plain === '') {
return null;
}
$parts = preg_split("/\n\s*\n/", $plain) ?: [];
if (count($parts) === 1 && str_contains($plain, "\n")) {
$parts = explode("\n", $plain);
}
$paragraphs = array_values(array_filter(
array_map('trim', $parts),
fn (string $part) => $part !== '',
));
if ($paragraphs === []) {
return null;
}
return implode('', array_map(
fn (string $paragraph) => ''.self::escape($paragraph).'
',
$paragraphs,
));
}
private static function escape(string $text): string
{
return htmlspecialchars($text, ENT_QUOTES | ENT_HTML5, 'UTF-8');
}
}