missing(); if ($missing !== []) { self::noticeMissing($missing); return; } $access = new Access(); $access->register(); (new RequestContext())->register(); (new VisibilityFilter())->register(); (new DiscoveryCanonical())->register(); (new AuthorizeGate())->register(); $limits = new Limits(); $changeLog = new ChangeLog(); (new ChangeLogInstaller($changeLog))->maybeInstall(); (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); }; $divi = new DiviIntegration( $schema, $changeLog, $libraryWritable, libraryVisible: $libraryVisible, diviWritable: $diviWritable ); $registry = new IntegrationRegistry( new CoreIntegration(self::pluginDir() . '/docs/guides'), new WordPressIntegration($schema, $changeLog, $divi->contentComposer($diviWritable)), new MediaIntegration($schema, $changeLog, $limits), $divi, $divi->library($diviWritable) ); $policy = ExposurePolicy::fromOption()->withGroups($registry->groupMap(...)); (new AbilityRegistrar($registry, $policy))->register(); (new ServerRegistrar( $registry, new InstructionsBuilder($registry, static fn (): array => $schema->postTypeNames(), $policy), null, null, null, $policy ))->register(); $status = new ConnectionStatus(); (new SiteHealth($status))->register(); $tabs = [ new ConnectionTab($status), new AccessTab($access, new ConnectionRepository()), new ToolsTab($registry, $policy), new LogTab($changeLog, $limits, $registry), new LimitsTab(), ]; self::$settingsPage = new SettingsPage( $tabs, plugins_url('assets/img/loosen-it-logo.svg', self::$pluginFile), plugins_url('assets', self::$pluginFile), self::VERSION ); (new ConnectionUsage())->register(); if (is_admin()) { self::$settingsPage->register(); (new AdminNotices($status))->register(); } \WPMedia\MCP\OAuth\Bootstrap::instance(); } public static function settingsPage(): ?SettingsPage { return self::$settingsPage; } public static function pluginDir(): string { return dirname(self::$pluginFile); } /** * @param list $missing */ public static function noticeMissing(array $missing): void { add_action('admin_notices', static function () use ($missing): void { printf( '

%s

', esc_html(sprintf( /* translators: %s: comma separated list of missing components */ __('WP-LIT-MCP ist inaktiv. Es fehlt: %s', 'wp-lit-mcp'), implode(', ', $missing) )) ); }); } private static function contentSchema(): ContentSchema { $sources = [new RegisteredMetaSource(), new SampledMetaSource()]; if (PodsFieldSource::isAvailable()) { array_unshift($sources, new PodsFieldSource()); } return new ContentSchema($sources); } }