refactor: ToolAvailability ersetzt die sechs Referenz-Closures in Plugin (Frage vor der Verdrahtung wirft statt still false); DiviIntegration bekommt den Tools-Tab-Zustand als Objekt; Plugin::integrations() mit Verdrahtungstest für Reihenfolge, einmaliges Booten und spätes Binden
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
6c59934caa
commit
e6e0f914ba
+35
-58
@@ -6,6 +6,7 @@ namespace LIT\MCP;
|
||||
|
||||
use LIT\MCP\Abilities\AbilityRegistrar;
|
||||
use LIT\MCP\Abilities\ExposurePolicy;
|
||||
use LIT\MCP\Abilities\ToolAvailability;
|
||||
use LIT\MCP\Admin\AccessTab;
|
||||
use LIT\MCP\Admin\AdminNotices;
|
||||
use LIT\MCP\Admin\ConnectionRepository;
|
||||
@@ -23,9 +24,7 @@ use LIT\MCP\ChangeLog\ChangeLogInstaller;
|
||||
use LIT\MCP\Guides\InstructionsBuilder;
|
||||
use LIT\MCP\Integrations\Core\CoreIntegration;
|
||||
use LIT\MCP\Integrations\Divi\DiviIntegration;
|
||||
use LIT\MCP\Integrations\Divi\Library\LibraryAccess;
|
||||
use LIT\MCP\Integrations\Divi\Release\DiviToolGate;
|
||||
use LIT\MCP\Integrations\Divi\ThemeBuilder\ThemeBuilderAccess;
|
||||
use LIT\MCP\Integrations\IntegrationRegistry;
|
||||
use LIT\MCP\Integrations\Media\MediaIntegration;
|
||||
use LIT\MCP\Integrations\Pods\PodsFieldSource;
|
||||
@@ -74,66 +73,14 @@ final class Plugin
|
||||
(new ChangeLogCleanup($changeLog, $limits))->register();
|
||||
|
||||
$schema = self::contentSchema();
|
||||
$registry = null;
|
||||
$policy = null;
|
||||
// Ruling P9: with the group "Divi-Bibliothek" disabled, the Divi tools do not see library entries.
|
||||
$libraryVisible = static function () use (&$policy): bool {
|
||||
return $policy instanceof ExposurePolicy && $policy->groupEnabled(LibraryAccess::GROUP);
|
||||
};
|
||||
// Security M2: content-create's divi input follows lit/divi-insert (asked at execute time,
|
||||
// when registry and policy exist), so the Divi group's switches stop every Divi layout write.
|
||||
$diviWritable = static function () use (&$registry, &$policy): bool {
|
||||
return $registry instanceof IntegrationRegistry
|
||||
&& $policy instanceof ExposurePolicy
|
||||
&& $policy->allows('lit/divi-insert', $registry->abilities());
|
||||
};
|
||||
// The Divi tools write to library entries only while the group "Divi-Bibliothek" may write (E9).
|
||||
$libraryWritable = static function () use (&$policy): bool {
|
||||
return $policy instanceof ExposurePolicy && $policy->groupWritable(LibraryAccess::GROUP);
|
||||
};
|
||||
// Audit L5: lit/divi-node-copy from a library entry follows lit/library-insert's Tools-tab state.
|
||||
$libraryInsertable = static function () use (&$registry, &$policy): bool {
|
||||
return $registry instanceof IntegrationRegistry
|
||||
&& $policy instanceof ExposurePolicy
|
||||
&& $policy->allows('lit/library-insert', $registry->abilities());
|
||||
};
|
||||
// Etappe 3b: the group "Divi Theme Builder" gates TB layouts in the Divi tools like the library group (E9).
|
||||
$themeBuilderVisible = static function () use (&$policy): bool {
|
||||
return $policy instanceof ExposurePolicy && $policy->groupEnabled(ThemeBuilderAccess::GROUP);
|
||||
};
|
||||
$themeBuilderWritable = static function () use (&$policy): bool {
|
||||
return $policy instanceof ExposurePolicy && $policy->groupWritable(ThemeBuilderAccess::GROUP);
|
||||
};
|
||||
$divi = new DiviIntegration(
|
||||
$schema,
|
||||
$changeLog,
|
||||
$libraryWritable,
|
||||
libraryVisible: $libraryVisible,
|
||||
diviWritable: $diviWritable,
|
||||
libraryInsertable: $libraryInsertable,
|
||||
themeBuilderWritable: $themeBuilderWritable,
|
||||
themeBuilderVisible: $themeBuilderVisible
|
||||
);
|
||||
$registry = new IntegrationRegistry(
|
||||
new CoreIntegration(self::pluginDir() . '/docs/guides', [$divi->environmentComponent()]),
|
||||
new WordPressIntegration(
|
||||
$schema,
|
||||
$changeLog,
|
||||
$divi->contentComposer($diviWritable),
|
||||
$divi->libraryIdsVisible(...),
|
||||
$divi->builderDetector()
|
||||
),
|
||||
new MediaIntegration($schema, $changeLog, $limits, $divi->mediaUsageSources()),
|
||||
$divi,
|
||||
$divi->library(),
|
||||
$divi->themeBuilder()
|
||||
);
|
||||
|
||||
$tools = new ToolAvailability();
|
||||
$registry = self::integrations($schema, $changeLog, $limits, $tools);
|
||||
$policy = ExposurePolicy::fromOption()->withGroups($registry->groupMap(...));
|
||||
$tools->bind($registry, $policy);
|
||||
// Integration-owned hooks (Divi: upgrader hook, check route, CLI command, tab "Divi") – before the settings
|
||||
// page reads its tabs.
|
||||
$registry->boot();
|
||||
|
||||
$policy = ExposurePolicy::fromOption()->withGroups($registry->groupMap(...));
|
||||
(new AbilityRegistrar(
|
||||
$registry,
|
||||
$policy,
|
||||
@@ -172,6 +119,36 @@ final class Plugin
|
||||
\WPMedia\MCP\OAuth\Bootstrap::instance();
|
||||
}
|
||||
|
||||
/**
|
||||
* The integrations in registry order – the order of the Tools tab, the guide and the server instructions. The
|
||||
* Divi integration and its groups share $tools, which Plugin binds once registry and policy exist.
|
||||
*
|
||||
* @internal Public for PluginTest only.
|
||||
*/
|
||||
public static function integrations(
|
||||
ContentSchema $schema,
|
||||
ChangeLog $changeLog,
|
||||
Limits $limits,
|
||||
ToolAvailability $tools
|
||||
): IntegrationRegistry {
|
||||
$divi = new DiviIntegration($schema, $changeLog, $tools);
|
||||
|
||||
return new IntegrationRegistry(
|
||||
new CoreIntegration(self::pluginDir() . '/docs/guides', [$divi->environmentComponent()]),
|
||||
new WordPressIntegration(
|
||||
$schema,
|
||||
$changeLog,
|
||||
$divi->contentComposer(),
|
||||
$divi->libraryIdsVisible(...),
|
||||
$divi->builderDetector()
|
||||
),
|
||||
new MediaIntegration($schema, $changeLog, $limits, $divi->mediaUsageSources()),
|
||||
$divi,
|
||||
$divi->library(),
|
||||
$divi->themeBuilder()
|
||||
);
|
||||
}
|
||||
|
||||
public static function settingsPage(): ?SettingsPage
|
||||
{
|
||||
return self::$settingsPage;
|
||||
|
||||
Reference in New Issue
Block a user