Fix: Umbrueche bleiben beim Bearbeiten von Legacy-PMs erhalten

Bestehende (importierte) Pressemitteilungen speichern ihren Text als
Plaintext mit \n-Umbruechen. Beim Laden in den HTML-Editor (flux:editor)
kollabierten diese zu einem Fliesssatz, weil HTML Whitespace faltet.

Die Plaintext->HTML-Konvertierung (Doppelumbruch = Absatz, Einzelumbruch
= <br>) lag bisher nur im Anzeige-Pfad (render()). Sie ist jetzt als
toEditorHtml() wiederverwendbar und wird beim Laden des Editors genutzt;
die Link-Policy (rel/target) bleibt dabei dem Anzeige-Pfad vorbehalten.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Kevin Adametz 2026-06-18 12:57:45 +00:00
parent 5feaa8a36a
commit e962cc2213
4 changed files with 93 additions and 4 deletions

View file

@ -61,17 +61,46 @@ class PressReleaseHtmlSanitizer
return new HtmlString($this->linkPolicy->apply($this->clean($text)));
}
return new HtmlString($this->plainTextToParagraphs($text));
}
/**
* Liefert editierbares HTML für den Flux/Tiptap-Editor.
*
* Bereits gespeichertes HTML (Phase 7+) wird nur gesäubert. Legacy-
* Plaintext (ältere Importe) wird in <p>/<br> gewandelt — sonst kollabieren
* die Zeilenumbrüche beim Laden in den HTML-Editor zu einem Fließsatz.
* Anders als render() wird hier KEINE Link-Policy (rel/target) eingebrannt,
* da diese erst beim Anzeigen greift und nicht in den Editor gehört.
*/
public function toEditorHtml(?string $text): string
{
if ($text === null || trim($text) === '') {
return '';
}
if ($this->isHtml($text)) {
return $this->clean($text);
}
return $this->plainTextToParagraphs($text);
}
/**
* Wandelt Plaintext mit \n-Umbrüchen in <p>-Absätze (Doppelumbruch =
* neuer Absatz, Einzelumbruch = <br>) und escaped dabei HTML-Sonderzeichen.
*/
private function plainTextToParagraphs(string $text): string
{
$escaped = e($text);
$withBreaks = nl2br($escaped, false);
$paragraphs = preg_split('/(?:<br\s*\/?>\s*){2,}/i', $withBreaks) ?: [$withBreaks];
$html = collect($paragraphs)
return collect($paragraphs)
->map(fn (string $chunk): string => trim($chunk))
->filter()
->map(fn (string $chunk): string => '<p>'.$chunk.'</p>')
->implode('');
return new HtmlString($html);
}
/**