fix: link targets never reveal library entries by type (ruling Q14)

WpLinkTargets answers the library, internal "_" types and every type
without a Divi post_link_url option like a missing ID; replace-text strips
library IDs only from global subtrees.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-27 15:13:40 +02:00
co-authored by Claude Opus 5.5
parent c7ce924e5a
commit 82ef69a99c
7 changed files with 154 additions and 19 deletions
@@ -69,8 +69,9 @@ final class DiviTextSearch
/**
* Every hit of $page, computed without changing it. Without $globalIds (ruling P13: no library
* access) the library IDs a global instance stores are no text to find: an opaque node is
* matched without globalModule/globalParent, as if they were not stored.
* access) the library IDs a global instance stores are no text to find: a global node is
* matched without globalModule/globalParent, as if they were not stored; every other opaque
* node (e.g. undecodable attributes) is matched as stored, the same with or without access.
*
* @return array{count: int, samples: list<array<string, string>>,
* blocks: list<array{Block, array<string, mixed>}>, skipped_nodes: list<array{id: string, reason: string}>}
@@ -89,7 +90,9 @@ final class DiviTextSearch
foreach ($page->index->entries() as $entry) {
$block = $entry['block'];
if ($block->isDivi() && $block->isOpaque()) {
$markup = $globalIds ? Serializer::block($block) : self::withoutLibraryIds($block);
$markup = $globalIds || ! $block->isGlobal()
? Serializer::block($block)
: self::withoutLibraryIds($block);
if ($replacer->mentions($markup)) {
$skipped[] = ['id' => (string) $entry['id'], 'reason' => self::opaqueReason($block)];
}
@@ -120,8 +123,9 @@ final class DiviTextSearch
}
/**
* Ruling P13: $block's markup with every globalModule/globalParent left out, at every depth –
* only for matching, never saved.
* Ruling P13: the markup of the global node $block (decodable attributes, as isGlobal() needs)
* with every globalModule/globalParent left out, at every depth – only for matching, never
* saved. Openers are rebuilt from the decoded attributes, so Divi's raw spelling is not kept.
*/
private static function withoutLibraryIds(Block $block): string
{