register(); (new RecheckOnInstall(self::VERSION))->register(); $missing = (new Dependencies())->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(); $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(); (new AbilityRegistrar( $registry, $policy, [new DiviFeatureGate($changeLog)] ))->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(); } /** * 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 { // E3: lit-site-status and the Divi tab name the tools each feature affects; the registry exists only after // the Divi integration, so it is asked at call time. $registry = null; $allAbilities = static function () use (&$registry): array { return $registry instanceof IntegrationRegistry ? $registry->abilities() : []; }; $divi = new DiviIntegration($schema, $changeLog, $tools, $allAbilities); $registry = 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() ); return $registry; } 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 { // Pods active but unusable: its meta keys (sampled, or registered via Pods' register_meta integration) must not // be written past Pods. $podsUnusable = defined('PODS_VERSION') && ! PodsFieldSource::isAvailable(); $sources = [new RegisteredMetaSource(readOnly: $podsUnusable), new SampledMetaSource(readOnly: $podsUnusable)]; if (PodsFieldSource::isAvailable()) { array_unshift($sources, new PodsFieldSource()); } // Divi's post types and builder check come in statically: the schema exists before the Divi integration. return new ContentSchema( $sources, DiviIntegration::builderEnabledFor(...), DiviIntegration::internalPostTypes() ); } }