run( ! $network_wide ); delete_transient( self::UPGRADE_ERROR_TRANSIENT ); Permissions::add_capabilities(); }; if ( $network_wide && is_multisite() ) { MultisiteInstaller::for_each_site( $install ); } else { $install(); } } /** * Remove runtime capabilities without deleting merchant data. */ public static function deactivate( $network_wide = false ): void { self::bootstrap(); $deactivate = static function (): void { // A network site may never have initialized Woo's scheduler tables. if ( function_exists( 'as_unschedule_all_actions' ) && ( ! is_multisite() || ! class_exists( 'ActionScheduler_StoreSchema' ) || get_option( 'schema-ActionScheduler_StoreSchema', false ) ) ) { as_unschedule_all_actions( 'ipscmi_order_cart_recovery_tick', [], 'ipscmi_order_cart_recovery' ); } Permissions::remove_capabilities(); }; if ( $network_wide && is_multisite() ) { MultisiteInstaller::for_each_site( $deactivate ); } else { $deactivate(); } } /** * Reconcile additive install tasks after WordPress replaces plugin files. */ public static function maybe_upgrade(): void { self::bootstrap(); $installer = new Installer(); if ( ! $installer->needs_upgrade() ) { delete_transient( self::UPGRADE_ERROR_TRANSIENT ); return; } if ( false !== get_transient( self::UPGRADE_ERROR_TRANSIENT ) ) { self::register_upgrade_failure_notice(); return; } try { $installer->maybe_upgrade(); Permissions::add_capabilities(); delete_transient( self::UPGRADE_ERROR_TRANSIENT ); } catch ( \Throwable $throwable ) { set_transient( self::UPGRADE_ERROR_TRANSIENT, [ 'time' => time(), 'message' => $throwable->getMessage(), ], 5 * MINUTE_IN_SECONDS ); error_log( // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log sprintf( 'IPS Order Cart upgrade failed and will be retried: %s', $throwable->getMessage() ) ); self::register_upgrade_failure_notice(); } } /** * Report a retryable schema problem to managers without breaking the shop. */ private static function register_upgrade_failure_notice(): void { add_action( 'admin_notices', static function (): void { if ( ! current_user_can( 'manage_woocommerce' ) ) { return; } echo '
'; echo esc_html__( 'IPS Order Cart could not complete its database update. Storefront requests remain available, and the update will be retried automatically. Check the WooCommerce logs for details.', 'ips-order-cart' ); echo '