fix: find-similar marks replaceable matches and names excluded types (review M-3, M-7, M-8)
Every match carries replaceable: true only when it is identical and in a page or post, the scope lit/library-make-global replaces; the description and the guide say so. An excluded post type is answered like any unavailable one, by its name (PostGuard::unavailableType()), and the excluded list takes the Theme Builder types from DiviThemeBuilder::postTypes(). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01At3V6SjwbMe6eMzVGW3Hs7
This commit is contained in:
@@ -18,6 +18,7 @@ use LIT\MCP\Integrations\Divi\BlockTree\NodeSummary;
|
||||
use LIT\MCP\Integrations\Divi\BlockTree\Parser;
|
||||
use LIT\MCP\Integrations\Divi\Pages\DiviErrors;
|
||||
use LIT\MCP\Integrations\Divi\Pages\DiviPageLoader;
|
||||
use LIT\MCP\Integrations\Divi\ThemeBuilder\DiviThemeBuilder;
|
||||
use LIT\MCP\Integrations\WordPress\PostGuard;
|
||||
use LIT\MCP\Integrations\WordPress\Schema\ContentSchema;
|
||||
use WP_Error;
|
||||
@@ -48,15 +49,6 @@ final class LibraryFindSimilarAbility implements Ability
|
||||
/** Post contents read with one primed cache (bounded memory). */
|
||||
public const CONTENT_CHUNK = 50;
|
||||
|
||||
/** Types with gates of their own (LibraryAccess, ThemeBuilderAccess): never scanned, even if a filter lists them. */
|
||||
private const NOT_SCANNED = [
|
||||
DiviLibraryStore::POST_TYPE,
|
||||
'et_theme_builder',
|
||||
'et_template',
|
||||
'et_header_layout',
|
||||
'et_body_layout',
|
||||
'et_footer_layout',
|
||||
];
|
||||
|
||||
private const LIVING = ['publish', 'draft', 'pending', 'private', 'future'];
|
||||
|
||||
@@ -84,8 +76,8 @@ final class LibraryFindSimilarAbility implements Ability
|
||||
. 'lit-divi-outline) oder ein Bibliothekseintrag (library_id) aufgebaut sind: match "identical" = gleicher '
|
||||
. 'Inhalt (Admin-Labels ausgenommen), "structure" = gleicher Aufbau (Modultypen, Spalten, Presets) mit '
|
||||
. 'anderen Inhalten. Nur Einträge, die dieses Konto bearbeiten darf; höchstens 200 Einträge je Aufruf '
|
||||
. '(limit), weiter mit next_cursor. Inhaltsgleiche Vorkommen ersetzt lit/library-make-global '
|
||||
. '(library_id, targets).';
|
||||
. '(limit), weiter mit next_cursor. Inhaltsgleiche Vorkommen in Seiten und Beiträgen (replaceable: true) '
|
||||
. 'ersetzt lit/library-make-global (library_id, targets).';
|
||||
}
|
||||
|
||||
public function inputSchema(): array
|
||||
@@ -192,7 +184,7 @@ final class LibraryFindSimilarAbility implements Ability
|
||||
}
|
||||
++$scanned;
|
||||
$post = current_user_can('edit_post', $id) ? get_post($id) : null;
|
||||
if ($post instanceof WP_Post && ! in_array((string) $post->post_type, self::NOT_SCANNED, true)) {
|
||||
if ($post instanceof WP_Post && ! in_array((string) $post->post_type, self::notScanned(), true)) {
|
||||
$this->collect($post, $reference, $matches, $nodes);
|
||||
}
|
||||
}
|
||||
@@ -302,19 +294,31 @@ final class LibraryFindSimilarAbility implements Ability
|
||||
return ['block' => $block, 'info' => $info, 'post_id' => $postId, 'id' => $id];
|
||||
}
|
||||
|
||||
/**
|
||||
* Types with gates of their own (LibraryAccess, ThemeBuilderAccess): never scanned, even if a filter lists them
|
||||
* (review M-3: the Theme Builder types from DiviThemeBuilder::postTypes()).
|
||||
*
|
||||
* @return list<string>
|
||||
*/
|
||||
private static function notScanned(): array
|
||||
{
|
||||
return array_merge([DiviLibraryStore::POST_TYPE], DiviThemeBuilder::postTypes());
|
||||
}
|
||||
|
||||
/** @return list<string>|WP_Error */
|
||||
private function postTypes(mixed $postType): array|WP_Error
|
||||
{
|
||||
if ($postType !== null) {
|
||||
$type = in_array($postType, self::NOT_SCANNED, true)
|
||||
? PostGuard::postType('', $this->schema, 'edit_posts')
|
||||
// Review M-7: an excluded type answers like any unavailable one, by its name.
|
||||
$type = in_array($postType, self::notScanned(), true)
|
||||
? PostGuard::unavailableType((string) $postType)
|
||||
: PostGuard::postType($postType, $this->schema, 'edit_posts');
|
||||
|
||||
return $type instanceof WP_Error ? $type : [(string) $postType];
|
||||
}
|
||||
|
||||
$types = array_values(array_filter(
|
||||
array_diff($this->schema->postTypeNames(), self::NOT_SCANNED),
|
||||
array_diff($this->schema->postTypeNames(), self::notScanned()),
|
||||
fn (string $type): bool => $this->schema->diviEnabled($type)
|
||||
));
|
||||
|
||||
@@ -355,6 +359,7 @@ final class LibraryFindSimilarAbility implements Ability
|
||||
continue;
|
||||
}
|
||||
|
||||
$identical = Fingerprint::content($block) === $reference['info']['content'];
|
||||
$matches[] = [
|
||||
'post_id' => (int) $post->ID,
|
||||
'title' => (string) $post->post_title,
|
||||
@@ -363,7 +368,10 @@ final class LibraryFindSimilarAbility implements Ability
|
||||
'id' => $entry['id'],
|
||||
'label' => NodeSummary::label($block),
|
||||
'tree_rev' => Rev::of($content),
|
||||
'match' => Fingerprint::content($block) === $reference['info']['content'] ? 'identical' : 'structure',
|
||||
'match' => $identical ? 'identical' : 'structure',
|
||||
// Review M-8: lit/library-make-global replaces identical occurrences in pages and posts only.
|
||||
'replaceable' => $identical
|
||||
&& in_array((string) $post->post_type, LibraryMakeGlobalAbility::POST_TYPES, true),
|
||||
];
|
||||
if (count($matches) >= self::MAX_MATCHES) {
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user