One PostIdParser for {{link:}} and select_post; post_link_url_<type> needs a
living, readable, non-attachment target of exactly that type.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Own fixture pod lit_fixture_person (ruling Q1), template and body layout
built through Divi's Theme Builder and Visual Builder UI, brief render with
the template limited to one person (Q5), findings 10-12 in the README.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- G1: every decoded string value of a Divi 5 opener is scanned for shortcodes;
outside the openers only the remaining content is.
- G2: attributes are parsed like shortcode_parse_atts() and global_module is
cast with (int), as Divi does.
- G3: a non-empty global_module other than "0" that casts to 0 makes Divi
render the newest layout, so it counts for every entry (fail closed).
- The prefilter LIKEs use LOWER(post_content), so they are case-insensitive
under any collation.
- The guide describes the fail-closed rule without an absolute claim.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Candidates come from one ID/status/type query: content with globalModule,
global_module or a JSON-escaped letter. Their content is read in chunks of
50 and parsed by UsageMatcher: Divi 5 openers are json-decoded (escaped keys
and values, leading zeros, any depth), and Divi 4 global_module attributes
are read in any quoting. An undecodable escaped opener counts as a possible
reference. Beyond 5000 candidates the rest count unread. The guide names
the formats and the wp_block parity. Also fixes the grammar of the
blocked-hidden count.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
synthetic-divi-filters.html now stores its paragraph as Divi does (unicode
escapes, bytes built with chr(92) and checked with od). A data-provider test
inserts a section as a user without unfiltered_html into every Divi 5 fixture
page read from disk and asserts that every other byte stays.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Per-run editor login and role, deleted only when this run created them (and
refused when they exist); the allowed-roles option is deleted again when it
was absent; the run-token fallback covers pages too; readOnlyHint must be
false, not just missing.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The header says "mit OAuth für KI-Assistenten" like the readme; the spec names
the client neutrally and keeps claude.ai only where the connector is meant.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
search uses search_columns post_title; users without edit_others_posts on
et_pb_layout query their own entries only (PostGuard::ownPostsOnly); the
cursor counts the entries shown, never the rows left out.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
StoredNodeGuard accepts a zero-padded library id (Divi intval()s it) but
refuses instances whose opener holds more than one or an escaped
globalModule, so the entry Divi renders is the one checked. GlobalUsages
matches "globalModule":"0*<id>" with REGEXP behind a cheap LIKE prefilter.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Divi renders any referenced et_pb_layout, whatever its scope term. A normal
entry with usages now gets the dry run, confirm, P8a, backup and the
site-wide GlobalItem scope; lit-divi-delete's notice and the library-list
detail name its pages too. The usage scan is the same single query.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
et_header_layout, et_body_layout, et_footer_layout and et_template showing a
global entry now block a confirmed edit unless et_pb_is_allowed('theme_builder'),
like Divi's own check for TB layouts.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
GlobalUsages runs one query per request (ID, status, type – no content),
checks read_post/edit_post in chunks of 200 with a primed and released post
cache, lists at most 50 readable posts and refuses a confirmed global edit
above 2000 live references (unsupported, edit in the Divi builder). Posts the
caller may not read appear only as hidden_count / blocked_hidden_count;
blocked_ids names readable posts only.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
With the library group disabled the entries stay unreadable and unwritable, but
page outline, node-get and render summary still name global module IDs; full
hiding follows in 3b.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A library entry as source now requires LibraryAccess::canInsert() (add_library,
writable library group) and follows lit-library-insert's Tools-tab state
(disabled -> unsupported). DiviPageLoader::library() gets its caller.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Reuses NewDraft for insert and rollback (P6), requires edit_global_library
for scope global (P7), refuses opaque and global roots before wrapping (P11)
and checks the node with StoredNodeGuard. The source page is never written.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
lottie.innerContent (src → data-lottie-src) makes the frontend load an
animation whose expressions lottie-web runs with eval; it joins the S7 gate
in ValueCleaner, which covers removals and StoredNodeGuard.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A link without scheme and without whitespace, quotes, <, >, backslashes or
control characters passes although esc_url_raw() would prefix http://; every
value with a scheme, and protocol-relative //host, must survive url() unchanged.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
URLs must be sanitizer-stable, keys inside values follow ValueCleaner::VALUE_KEY,
instances need a digits-only globalModule; state keys reuse AttrWriter::STATES.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Divi's frontend applies the interaction effect "Attribute" with setAttribute
(e.g. an onclick handler) and sets cookies; *.decoration.interactions joins
the S7 gate in ValueCleaner, which also covers removals and StoredNodeGuard.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Refuses, for users without unfiltered_html, non-Divi blocks, raw text parts,
unreadable opaque blocks, code modules, builder-only paths (also below the
state value), strings that are not sanitizer-stable and stored $variable
references that VariableRef::canonical() refuses or would change (P2, P3).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Created through Divi's own save paths (Visual Builder add-to-library dialog,
divi/v1/divi-library/create-item, divi/v1/sync-to-server, Theme Builder
admin-ajax create_layout/save) and exported by divi-export-stage3-fixtures.php.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>