Conversation
There was a problem hiding this comment.
Pull request overview
Fügt ein Auto-Blocking für manuell eingebetteten externen Code (per data-consent-*) hinzu und ergänzt dafür eine neue Editorial-Seite, damit Redakteure Embeds/Skripte datenschutzkonform vorbereiten und wiederverwenden können.
Changes:
- Neue Backend-Seite „Redaktions-Bereich“ inkl. Code-Assistent (Modal) und Snippet-Manager (LocalStorage).
- Frontend-Auto-Blocking per
OUTPUT_FILTER+ neue HTML-Scan/Replace-Logik inInlineConsent. - Dokumentation/i18n/Assets erweitert (Inline-Consent Styling/JS, README, AUTO_BLOCKING.md, Changelog).
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 17 comments.
Show a summary per file
| File | Description |
|---|---|
| pages/editorial.php | Neue Editorial-UI mit Assistant + Snippet-Manager für Redakteure |
| pages/config.php | Neue Settings: auto_blocking_enabled und editorial_info |
| package.yml | Neue Subpage + Perm-Keys für Editorial/Config und weitere Subpages |
| lib/InlineConsent.php | Neue Scan-&-Replace-Funktion für data-consent-block="true" Elemente |
| boot.php | Aktiviert Auto-Blocking im Frontend via OUTPUT_FILTER und injiziert Inline-Consent Assets |
| assets/consent_inline.js | Script-Recreate-/Attribut-Entfernungslogik beim Laden nach Consent |
| assets/consent_inline.css | Optik/Theme-Kompatibilität für Inline-Consent Placeholder verbessert |
| lang/de_de.lang | Neue Übersetzungskeys für Auto-Blocking + Editorial |
| README.md | Doku für Auto-Blocking/Editorial ergänzt |
| CHANGELOG.md | Release Notes für neue Features ergänzt |
| AUTO_BLOCKING.md | Neue Detail-Dokumentation für Auto-Blocking |
| assets/consent_manager_frontend.css | Rebuilt/formatierte Frontend-CSS-Ausgabe |
| assets/consent_manager_backend.css | Rebuilt/formatierte Backend-CSS-Ausgabe |
| pages/config.php.bak | Backup-Datei des Config-Screens (sollte nicht mit ausgeliefert werden) |
| # Auto-Blocking Feature | ||
| consent_manager_config_auto_blocking = Auto-Blocking für manuell eingefügtes HTML | ||
| consent_manager_config_auto_blocking_enable = Auto-Blocking aktivieren | ||
| consent_manager_config_auto_blocking_desc = Scannt HTML-Code automatisch und blockiert Scripts/iframes mit data-consent-Attributen. Scripts müssen mit data-consent-block="true" und data-consent-service="servicekey" markiert sein. | ||
| consent_manager_auto_blocking_assistant_title = Auto-Blocking Code-Assistent |
There was a problem hiding this comment.
Es werden viele neue i18n-Keys hinzugefügt (Auto-Blocking/Editorial). In lang/en_gb.lang und lang/sv_se.lang fehlen diese Keys aktuell (z.B. consent_manager_config_auto_blocking). Bitte die neuen Keys auch in den anderen Sprachdateien ergänzen, damit das Backend nicht mit Raw-Keys/fehlenden Übersetzungen angezeigt wird.
| <label for="original_code"><?= $addon->i18n('consent_manager_auto_blocking_assistant_input_label') ?></label> | ||
| <textarea class="form-control" id="original_code" rows="4" | ||
| placeholder="<?= $addon->i18n('consent_manager_auto_blocking_assistant_input_placeholder') ?>"></textarea> | ||
| <p class="help-block">Fügen Sie hier Ihren externen Script- oder iframe-Code ein</p> | ||
| </div> |
There was a problem hiding this comment.
Im Modal/JS sind mehrere neue User-Texte hart kodiert (z.B. Help-Block/Alerts/Buttons). Damit die Seite vollständig mehrsprachig bleibt, sollten diese Strings in die .lang Dateien ausgelagert und über rex_i18n::msg()/$addon->i18n() genutzt werden.
| if (false !== stripos($content, '</head>')) { | ||
| $assets = \FriendsOfRedaxo\ConsentManager\InlineConsent::getCSS(); | ||
| $assets .= \FriendsOfRedaxo\ConsentManager\InlineConsent::getJavaScript(); | ||
| $content = str_ireplace('</head>', $assets . '</head>', $content); | ||
| } |
There was a problem hiding this comment.
Das automatische Injizieren von InlineConsent::getCSS()/getJavaScript() kann zu doppelten Asset-Includes führen, wenn Projekte bereits das Fragment ConsentManager/inline_cssjs.php (oder eigene Includes) nutzen. Bitte vor dem Inject prüfen, ob consent_inline.css/consent_inline.js bereits im HTML vorhanden sind, um Doppel-Laden und doppelte Handler zu vermeiden.
| $('#save_snippet').on('click', function() { | ||
| console.log('Save snippet clicked'); | ||
| const code = $('#output_code').val(); | ||
| console.log('Code:', code ? code.substring(0, 50) + '...' : 'LEER'); | ||
|
|
There was a problem hiding this comment.
In diesem Block sind mehrere console.log(...) Debug-Ausgaben enthalten (z.B. beim Snippet-Speichern). Das führt in Produktion zu unnötigem Console-Spam. Bitte Logs entfernen oder an einen vorhandenen Debug-Mechanismus koppeln (z.B. nur in Debug-Mode).
| <label for="original_code"><?= $addon->i18n('consent_manager_auto_blocking_assistant_input_label') ?></label> | ||
| <textarea class="form-control" id="original_code" rows="4" | ||
| placeholder="<?= $addon->i18n('consent_manager_auto_blocking_assistant_input_placeholder') ?>"></textarea> | ||
| <p class="help-block">Fügen Sie hier Ihren externen Script- oder iframe-Code ein</p> | ||
| </div> |
There was a problem hiding this comment.
Hier sind neue UI-Texte hart codiert (z.B. Help-Block-Text). Da das AddOn mehrsprachig ist (en_gb/sv_se vorhanden), sollten neue sichtbare Texte über i18n-Keys kommen, damit sie übersetzbar sind.
| public static function scanAndReplaceConsentElements(string $html): string | ||
| { | ||
| // Pattern für script und iframe Tags mit data-consent-block="true" | ||
| $pattern = '/<(script|iframe|div)([^>]*data-consent-block=["\']true["\'][^>]*)>(.*?)<\/\1>/is'; | ||
|
|
There was a problem hiding this comment.
scanAndReplaceConsentElements() führt immer ein preg_replace_callback() über den kompletten HTML-Output aus. Das ist unnötig teuer, wenn auf der Seite gar kein data-consent-block vorkommt. Bitte vorab einen schnellen Check einbauen (z.B. stripos($html, 'data-consent-block') === false → return $html) um die Regex nur bei Bedarf laufen zu lassen.
| use rex; | ||
| use rex_clang; | ||
| use rex_addon; | ||
| use rex_fragment; |
There was a problem hiding this comment.
use rex_addon; ist in dieser Datei ungenutzt (keine Referenz im Code). Bitte entfernen, um die Imports sauber zu halten.
| use rex_fragment; |
| // Original-Tag rekonstruieren | ||
| $originalTag = '<' . $tag . $attributes . '>' . $content . '</' . $tag . '>'; | ||
|
|
||
| // Optionen zusammenstellen | ||
| $options = [ | ||
| 'title' => $title, | ||
| ]; | ||
|
|
||
| if ('' !== $provider) { | ||
| $options['provider_name'] = $provider; | ||
| } | ||
|
|
||
| if ('' !== $privacyUrl) { | ||
| $options['privacy_url'] = $privacyUrl; | ||
| } | ||
|
|
||
| if ('' !== $customText) { | ||
| $options['privacy_notice'] = $customText; | ||
| } | ||
|
|
||
| // Inline-Consent generieren | ||
| return self::doConsent($serviceKey, $originalTag, $options); | ||
| }, $html); |
There was a problem hiding this comment.
scanAndReplaceConsentElements() rekonstruiert das Original-Element als String und übergibt es an doConsent(). Wenn das gefundene Element ein <script>...</script> ist, enthält der String zwangsläufig die Sequenz </script>. Der Inline-Placeholder speichert $content später innerhalb eines <script type="text/plain">…</script>-Containers (Fragment), wodurch </script> den Container vorzeitig schließt → kaputtes Markup und potentiell XSS. Bitte den gespeicherten Content vor dem Einbetten HTML-escapen/encoden (z.B. rex_escape($content, 'html') oder Base64) und im JS wie vorgesehen wieder decoden.
Hilfe bei der Einbindung externe Skripte mitten im Text. Auto-Blocking. Snippetsammlung