booted ) { return; } $this->booted = true; $checker = new DependencyChecker(); if ( ! $checker->meets_requirements() ) { AdminNotices::register_dependency_failures( $checker->failures() ); return; } // Fail-closed: never mark ready until schema migrates and invariants hold. if ( ! ( new Migrator() )->maybe_upgrade() ) { AdminNotices::register_dependency_failures( array( __( 'MarginBeacon could not verify its database schema. Check database permissions, then deactivate and reactivate the plugin.', 'marginbeacon' ), ) ); return; } $this->ready = true; $this->scheduler = new ActionSchedulerAdapter(); // Persist canonical COGS source for upgrades without rewriting merchant choice. ( new CanonicalCostSource() )->ensure_bootstrapped( false ); ( new Hooks( $this ) )->register(); ( new Menu() )->register(); ( new AdminApp() )->register(); ( new OverviewPage() )->register(); ( new SettingsPage() )->register(); ( new CogsWizardPage() )->register(); ( new CogsMigrationPage() )->register(); ( new CogsSourceNotices() )->register(); ( new CostSourceAdminUi() )->register(); ( new ProductCostFields() )->register(); ( new ProductListCostColumn() )->register(); ( new ProductBulkCostEdit() )->register(); ( new PreflightPage() )->register(); ( new OrderListColumn() )->register(); ( new OrderDetailPanel() )->register(); ( new OrderRiskRetryActions() )->register(); ( new AcknowledgementActions() )->register(); ( new AdminNotices() )->register(); if ( ! DistributionChannel::is_direct() ) { ( new ProUpgradeCta() )->register(); } ( new PrivacyPolicy() )->register(); ( new OrderRiskEnqueueService( $this->scheduler ) )->register(); ( new PriceRevisionObserver() )->register(); ( new StalenessObserver() )->register(); if ( defined( 'WP_CLI' ) && WP_CLI ) { CommandRegistrar::register( new HealthService( $this->scheduler ), $this->scheduler ); } $this->declare_woo_feature_compatibility(); /** * Fires after the Free base plugin is fully ready. * * Pro companion must listen here (or plugins_loaded > 20) and must not * own schema, menus, or scheduler groups. * * @param Plugin $plugin Base plugin instance. */ do_action( 'aksmb_loaded', $this ); } /** * Whether the plugin is fully operational. * * @return bool */ public function is_ready() { return $this->ready; } /** * Scheduler instance. * * @return SchedulerInterface|null */ public function scheduler() { return $this->scheduler; } /** * Entitlement service (Free base). * * @return EntitlementService */ public function entitlement() { return new EntitlementService(); } /** * Declare WooCommerce feature compatibility. * * @return void */ private function declare_woo_feature_compatibility() { add_action( 'before_woocommerce_init', static function () { if ( class_exists( '\Automattic\WooCommerce\Utilities\FeaturesUtil' ) ) { \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'custom_order_tables', AKSMB_PLUGIN_FILE, true ); \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'cart_checkout_blocks', AKSMB_PLUGIN_FILE, true ); } } ); } }