diff --git a/src/Integrations/Divi/DiviIntegration.php b/src/Integrations/Divi/DiviIntegration.php index 2702d5f..92bdc1d 100644 --- a/src/Integrations/Divi/DiviIntegration.php +++ b/src/Integrations/Divi/DiviIntegration.php @@ -57,7 +57,7 @@ final class DiviIntegration implements Integration * @param (Closure(): bool)|null $libraryVisible Tools-tab gate for library entries at all (group * "Divi-Bibliothek" not disabled, ruling P9); null = always. * @param (Closure(): bool)|null $diviWritable Whether lit/divi-insert is enabled – lit/divi-node-copy - * follows it (ruling P9, E9); null = always. + * and lit-library-insert follow it (ruling P9, E9, audit M2); null = always. * @param (Closure(): bool)|null $libraryInsertable Whether lit/library-insert is enabled – * lit/divi-node-copy follows it for library entries as source (audit L5); null = always. */ @@ -128,10 +128,10 @@ final class DiviIntegration implements Integration } /** - * The group "Divi-Bibliothek" (lit/library-*), sharing this integration's library access; - * $diviWritable is whether lit/divi-insert is enabled (lit-library-insert follows it, audit M2). + * The group "Divi-Bibliothek" (lit/library-*), sharing this integration's library access and its + * $diviWritable gate (lit-library-insert follows lit/divi-insert, audit M2). */ - public function library(?Closure $diviWritable = null): LibraryIntegration + public function library(): LibraryIntegration { $loader = $this->loader(); @@ -143,7 +143,7 @@ final class DiviIntegration implements Integration new DiviSaver(), $this->log, $this->modules, - $diviWritable + $this->diviWritable ); } diff --git a/src/Integrations/Divi/Library/DiviLibraryStore.php b/src/Integrations/Divi/Library/DiviLibraryStore.php index 363f99f..7da3e2b 100644 --- a/src/Integrations/Divi/Library/DiviLibraryStore.php +++ b/src/Integrations/Divi/Library/DiviLibraryStore.php @@ -34,6 +34,9 @@ class DiviLibraryStore /** Taxonomies every new entry needs (et_pb_submit_layout). */ public const TAXONOMIES = ['scope', 'layout_type', 'module_width']; + /** Client text when the terms or meta of a new entry could not be written. */ + public const REASON_CREATE = 'Der Bibliothekseintrag konnte nicht vollständig angelegt werden.'; + public function isGlobal(int $id): bool { if (method_exists(self::GLOBAL_LAYOUT, 'is_global_layout_template')) { @@ -138,9 +141,6 @@ class DiviLibraryStore ]; } - /** Client text when the terms or meta of a new entry could not be written. */ - public const REASON_CREATE = 'Der Bibliothekseintrag konnte nicht vollständig angelegt werden.'; - /** * A published entry with the terms and meta of $spec and empty content (E4; the layout follows * through DiviSaver::saveNew()). All or nothing through $draft (ruling P6, the transaction of diff --git a/src/Integrations/Divi/Pages/DiviSaver.php b/src/Integrations/Divi/Pages/DiviSaver.php index ac6d639..5cbaa39 100644 --- a/src/Integrations/Divi/Pages/DiviSaver.php +++ b/src/Integrations/Divi/Pages/DiviSaver.php @@ -40,18 +40,19 @@ defined('ABSPATH') || exit; * those hooks except the content itself (already cleaned); anything a third-party hook writes * there is saved without kses, as it would be for an administrator. The rollback write in * restore() uses the same window with the previous stored content; saveNew() (the first layout - * of a new draft, lit/content-create) uses it for its single wp_update_post(). + * of a new post – a draft of lit/content-create or a library entry of lit/library-save) uses it + * for its single wp_update_post(). * * Divi's own save filters are NOT kses and are never removed (ruling S7, defense in depth): * Security::initialize() (Divi 5.2.1 Security.php:74-81) registers on wp_insert_post_data * AttributeSecurity (priority 5, always), HtmlSecurity (priority 6, by capability) and - * DynamicContentFixes (priority 10: strips enable_html for users without unfiltered_html). The first two re-serialize - * the whole page when it holds custom attributes or htmlBefore/htmlAfter/elementType, so on such + * DynamicContentFixes (priority 10: strips enable_html for users without unfiltered_html). The first + * two re-serialize the whole page when it holds custom attributes or htmlBefore/htmlAfter/elementType, so on such * pages the bytes change for every user – reported as CHANGED_ON_SAVE. Finding R2 / rulings * S5, S7: docs/superpowers/notes/2026-09-26-etappe-2-entscheidungen.md. * - * SaveScope: Bibliothekseinträge bekommen keine Divi-Flags; ein globaler Eintrag leert zusätzlich den CSS-Cache - * aller Seiten und den Theme-Builder-Cache. + * SaveScope: library entries get no Divi flags; a global (or referenced) entry additionally clears + * the static CSS of every page and the Theme Builder cache. * * If saving throws, the previous content is written back (WriteFailed: rolled back or not). * Not final so abilities can be tested with a mock. @@ -131,12 +132,13 @@ class DiviSaver } /** - * The first content of a brand-new draft (lit/content-create with divi, which inserted the - * draft with its normal WordPress fields – title and excerpt went through kses as usual). - * Same kses window as save(), holding only this wp_update_post() and its hooks; no restore - * point (the draft has no earlier state) and no static CSS to clear. The Divi flags are part - * of the write here: without them the new entry is no Divi layout. Every failure throws – - * the caller deletes the draft (all or nothing). + * The first content of a brand-new post: a draft of lit/content-create with divi or a library + * entry of lit/library-save, both inserted with their normal WordPress fields first (title and + * excerpt went through kses as usual). Same kses window as save(), holding only this + * wp_update_post() and its hooks; no restore point (the post has no earlier state) and no + * static CSS to clear. With SaveScope::Page the Divi flags are part of the write (without them + * a new page is no Divi layout); SaveScope::LibraryItem sets none. Every failure throws – the + * caller deletes the new post (all or nothing). * * @return list Warnings (CHANGED_ON_SAVE). * @throws RuntimeException diff --git a/src/Plugin.php b/src/Plugin.php index 4bfc0dd..4b4c5d8 100644 --- a/src/Plugin.php +++ b/src/Plugin.php @@ -108,7 +108,7 @@ final class Plugin new WordPressIntegration($schema, $changeLog, $divi->contentComposer($diviWritable)), new MediaIntegration($schema, $changeLog, $limits), $divi, - $divi->library($diviWritable) + $divi->library() ); $policy = ExposurePolicy::fromOption()->withGroups($registry->groupMap(...));