feat: jedes Divi-Tool und lit/content-create erklärt seine Divi-Fähigkeiten (RequiresDiviFeatures, DeclaresRequirements, FeatureSets); Tabelle Tool → Fähigkeiten als Test
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
e387d8d29e
commit
fdbda8012c
@@ -18,6 +18,8 @@ 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\Release\DiviFeature;
|
||||
use LIT\MCP\Integrations\Divi\Release\RequiresDiviFeatures;
|
||||
use LIT\MCP\Integrations\Divi\ThemeBuilder\DiviThemeBuilder;
|
||||
use LIT\MCP\Integrations\WordPress\PostGuard;
|
||||
use LIT\MCP\Integrations\WordPress\Schema\ContentSchema;
|
||||
@@ -37,7 +39,7 @@ defined('ABSPATH') || exit;
|
||||
* and next_cursor resumes behind it. Needs the library right (canList); a hidden library answers its entries like
|
||||
* missing IDs (LibraryAccess::item, P9/P12). Only hashes and the matched nodes' labels are returned.
|
||||
*/
|
||||
final class LibraryFindSimilarAbility implements Ability
|
||||
final class LibraryFindSimilarAbility implements Ability, RequiresDiviFeatures
|
||||
{
|
||||
public const MAX_POSTS = 200;
|
||||
public const DEFAULT_POSTS = 100;
|
||||
@@ -121,6 +123,15 @@ final class LibraryFindSimilarAbility implements Ability
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scans Divi pages (PageRead) of the types that use the builder (Catalog), after the library right (Roles). A
|
||||
* library entry as reference is read through LibraryAccess (Roles), no Divi call beyond that.
|
||||
*/
|
||||
public function diviFeatures(array $input): array
|
||||
{
|
||||
return [DiviFeature::PageRead, DiviFeature::Catalog, DiviFeature::Roles];
|
||||
}
|
||||
|
||||
public function permission(array $input): bool|WP_Error
|
||||
{
|
||||
return $this->access->canList() ?? true;
|
||||
|
||||
@@ -19,6 +19,7 @@ use LIT\MCP\Integrations\Divi\Pages\DiviPage;
|
||||
use LIT\MCP\Integrations\Divi\Pages\DiviSchema;
|
||||
use LIT\MCP\Integrations\Divi\Pages\DiviWriteAbility;
|
||||
use LIT\MCP\Integrations\Divi\Pages\DiviWriter;
|
||||
use LIT\MCP\Integrations\Divi\Release\DiviFeature;
|
||||
use LIT\MCP\Integrations\WordPress\PostGuard;
|
||||
use WP_Error;
|
||||
use WP_Post;
|
||||
@@ -103,6 +104,23 @@ final class LibraryInsertAbility extends DiviWriteAbility
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Like lit/divi-insert (StoredNodeGuard cleans the entry's nodes: Catalog, DesignRead, DynamicSources), plus the
|
||||
* library entry as source: isGlobal() is a Divi call (LibraryRead), its rights are a Divi role (Roles).
|
||||
*/
|
||||
protected function baseFeatures(): array
|
||||
{
|
||||
return [
|
||||
DiviFeature::PageRead,
|
||||
DiviFeature::PageWrite,
|
||||
DiviFeature::Catalog,
|
||||
DiviFeature::DesignRead,
|
||||
DiviFeature::DynamicSources,
|
||||
DiviFeature::LibraryRead,
|
||||
DiviFeature::Roles,
|
||||
];
|
||||
}
|
||||
|
||||
protected function change(DiviPage $page, array $input, DiviComposition $composition): DiviChange|WP_Error
|
||||
{
|
||||
$mode = $input['mode'] ?? null;
|
||||
|
||||
@@ -13,6 +13,8 @@ use LIT\MCP\Integrations\Divi\BlockTree\Outline;
|
||||
use LIT\MCP\Integrations\Divi\Design\DesignSystemReader;
|
||||
use LIT\MCP\Integrations\Divi\Pages\DiviPage;
|
||||
use LIT\MCP\Integrations\Divi\Pages\DiviPageLoader;
|
||||
use LIT\MCP\Integrations\Divi\Release\DiviFeature;
|
||||
use LIT\MCP\Integrations\Divi\Release\RequiresDiviFeatures;
|
||||
use LIT\MCP\Integrations\WordPress\PostGuard;
|
||||
use WP_Error;
|
||||
use WP_Post;
|
||||
@@ -27,7 +29,7 @@ defined('ABSPATH') || exit;
|
||||
* left out, without title or count). With id,
|
||||
* everything but a library entry the user may read answers like a missing ID (ruling P12).
|
||||
*/
|
||||
final class LibraryListAbility implements Ability
|
||||
final class LibraryListAbility implements Ability, RequiresDiviFeatures
|
||||
{
|
||||
/** Rows looked at per call beyond the entries already shown (the cursor), skipping hidden ones. */
|
||||
public const MAX_SCAN = 500;
|
||||
@@ -121,6 +123,19 @@ final class LibraryListAbility implements Ability
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* describe() asks Divi whether an entry is global (LibraryRead); listing needs the library role (Roles). One
|
||||
* entry (id) is loaded and outlined (PageRead, DesignRead).
|
||||
*/
|
||||
public function diviFeatures(array $input): array
|
||||
{
|
||||
$features = [DiviFeature::LibraryRead, DiviFeature::Roles];
|
||||
|
||||
return isset($input['id'])
|
||||
? array_merge($features, [DiviFeature::PageRead, DiviFeature::DesignRead])
|
||||
: $features;
|
||||
}
|
||||
|
||||
public function permission(array $input): bool|WP_Error
|
||||
{
|
||||
if (isset($input['id'])) {
|
||||
|
||||
@@ -23,6 +23,8 @@ use LIT\MCP\Integrations\Divi\Pages\DiviPage;
|
||||
use LIT\MCP\Integrations\Divi\Pages\DiviSchema;
|
||||
use LIT\MCP\Integrations\Divi\Pages\DiviWriter;
|
||||
use LIT\MCP\Integrations\Divi\Pages\VisibleEdits;
|
||||
use LIT\MCP\Integrations\Divi\Release\DiviFeature;
|
||||
use LIT\MCP\Integrations\Divi\Release\RequiresDiviFeatures;
|
||||
use LIT\MCP\Integrations\WordPress\Content\NewDraft;
|
||||
use LIT\MCP\Integrations\WordPress\PostGuard;
|
||||
use LIT\MCP\Integrations\WordPress\PostSaveFollowUp;
|
||||
@@ -59,7 +61,7 @@ defined('ABSPATH') || exit;
|
||||
* point), page N is rolled back by DiviSaver (or reported partial), pages after N are not attempted – the error
|
||||
* names all three groups (changed_posts with pages, failed_post, unchanged_posts; D10, S10).
|
||||
*/
|
||||
final class LibraryMakeGlobalAbility implements Ability
|
||||
final class LibraryMakeGlobalAbility implements Ability, RequiresDiviFeatures
|
||||
{
|
||||
public const REASON_PAGE = 'Die Seite konnte nicht gespeichert werden; der neue globale Eintrag wurde wieder '
|
||||
. 'entfernt.';
|
||||
@@ -176,6 +178,25 @@ final class LibraryMakeGlobalAbility implements Ability
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Both modes write pages and posts (PageRead, PageWrite, Catalog, DesignRead, DynamicSources) and ask Divi
|
||||
* whether an entry is global (LibraryRead); the first mode also creates the global entry (LibraryWrite).
|
||||
* One upper bound for both modes (the second mode would not reach LibraryWrite): the roles of the library.
|
||||
*/
|
||||
public function diviFeatures(array $input): array
|
||||
{
|
||||
return [
|
||||
DiviFeature::PageRead,
|
||||
DiviFeature::PageWrite,
|
||||
DiviFeature::Catalog,
|
||||
DiviFeature::DesignRead,
|
||||
DiviFeature::DynamicSources,
|
||||
DiviFeature::LibraryRead,
|
||||
DiviFeature::LibraryWrite,
|
||||
DiviFeature::Roles,
|
||||
];
|
||||
}
|
||||
|
||||
public function permission(array $input): bool|WP_Error
|
||||
{
|
||||
return $this->precheck($input) ?? true;
|
||||
|
||||
@@ -17,6 +17,8 @@ use LIT\MCP\Integrations\Divi\Pages\DiviPage;
|
||||
use LIT\MCP\Integrations\Divi\Pages\DiviPageLoader;
|
||||
use LIT\MCP\Integrations\Divi\Pages\DiviSaver;
|
||||
use LIT\MCP\Integrations\Divi\Pages\DiviWriter;
|
||||
use LIT\MCP\Integrations\Divi\Release\DiviFeature;
|
||||
use LIT\MCP\Integrations\Divi\Release\RequiresDiviFeatures;
|
||||
use LIT\MCP\Integrations\Divi\Schema\DiviModules;
|
||||
use LIT\MCP\Integrations\WordPress\Content\NewDraft;
|
||||
use LIT\MCP\Integrations\WordPress\PostSaveFollowUp;
|
||||
@@ -35,7 +37,7 @@ defined('ABSPATH') || exit;
|
||||
* to the entry is lit/library-make-global. All or nothing through NewDraft (ruling P6): any failure
|
||||
* after the insert deletes the new entry, a failed delete is an honest partial_write.
|
||||
*/
|
||||
final class LibrarySaveAbility implements Ability
|
||||
final class LibrarySaveAbility implements Ability, RequiresDiviFeatures
|
||||
{
|
||||
private const TYPE_LABELS = ['section' => 'Abschnitt', 'row' => 'Zeile', 'module' => 'Modul'];
|
||||
|
||||
@@ -112,6 +114,24 @@ final class LibrarySaveAbility implements Ability
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a node of any entry (PageRead), cleans it with StoredNodeGuard (Catalog, DesignRead, DynamicSources) and
|
||||
* saves a new library entry (PageWrite and LibraryWrite: DiviSaver::saveNew with the library scope, D5), after
|
||||
* the library right (Roles). The source is only read: a library entry or Theme Builder layout adds Roles only.
|
||||
*/
|
||||
public function diviFeatures(array $input): array
|
||||
{
|
||||
return [
|
||||
DiviFeature::PageRead,
|
||||
DiviFeature::PageWrite,
|
||||
DiviFeature::Catalog,
|
||||
DiviFeature::DesignRead,
|
||||
DiviFeature::DynamicSources,
|
||||
DiviFeature::LibraryWrite,
|
||||
DiviFeature::Roles,
|
||||
];
|
||||
}
|
||||
|
||||
public function permission(array $input): bool|WP_Error
|
||||
{
|
||||
$refusal = $this->access->canSave(self::isGlobal($input));
|
||||
|
||||
Reference in New Issue
Block a user