=' ); } return class_exists( 'WooCommerce' ) && defined( 'WC_VERSION' ) && version_compare( WC_VERSION, APWC_MIN_WC, '>=' ); } /** * `plugins_loaded`: boot, or explain why not. When WooCommerce is missing or below the floor * (e.g. rolled back) while our options still autoload, stop autoloading them (flags only: no * power-up code runs without WooCommerce) and forget the version, so the activation steps run * again on the first admin visit once WooCommerce is fixed. Runs once: afterwards our state * option is no longer autoloaded. When WooCommerce is fine again, the first request finds * that and turns autoloading back on (flags only), so no request pays extra option queries * while waiting for that admin visit. * * @since 1.0.0 * @return void */ public static function load() { if ( self::woocommerce_ok() ) { if ( ! array_key_exists( Settings::STATE, wp_load_alloptions() ) ) { // Back after running below the floor: autoload again now (flags only; activate() // runs on the first admin visit, Registry::maybe_upgrade()). ( new Registry( new Settings() ) )->sync_autoload( true, false ); } self::instance(); return; } add_action( 'admin_notices', array( self::class, 'woocommerce_notice' ) ); add_action( 'network_admin_notices', array( self::class, 'woocommerce_notice' ) ); if ( array_key_exists( Settings::STATE, wp_load_alloptions() ) ) { $store = new Settings(); ( new Registry( $store ) )->sync_autoload( false, false ); $store->forget_version(); } } /** * Screens a requirement notice may show on: the Plugins screen and the Dashboard (site and * network). Never on other admin screens. * * @since 1.0.0 */ const NOTICE_SCREENS = array( 'plugins', 'plugins-network', 'dashboard', 'dashboard-network' ); /** * Whether a requirement notice may show now: only to users who can activate plugins, and only * on the Plugins screen or the Dashboard. * * @since 1.0.0 * @return bool */ public static function may_show_notice() { if ( ! current_user_can( 'activate_plugins' ) ) { return false; } $screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null; return $screen instanceof \WP_Screen && in_array( $screen->id, self::NOTICE_SCREENS, true ); } /** * Admin notice: WooCommerce is missing or too old. Shown only by may_show_notice(), and in the * network admin only while WooCommerce is network-active (otherwise the network admin doesn't * load it, though the sites that use it may). * * @since 1.0.0 * @return void */ public static function woocommerce_notice() { if ( ! self::may_show_notice() ) { return; } if ( is_network_admin() && ! ( function_exists( 'is_plugin_active_for_network' ) && is_plugin_active_for_network( 'woocommerce/woocommerce.php' ) ) ) { return; } printf( '

%s

', esc_html( sprintf( /* translators: %s: minimum WooCommerce version. */ __( 'Admin Powerups for WooCommerce needs WooCommerce %s or newer to be active.', 'admin-powerups-for-woocommerce' ), APWC_MIN_WC ) ) ); } /** * Get the plugin instance, booting it on first call. * * @since 1.0.0 * @return Plugin */ public static function instance() { if ( null === self::$instance ) { self::$instance = new self(); self::$instance->boot(); } return self::$instance; } /** * Boot the plugin. * * @since 1.0.0 * @return void */ private function boot() { $this->registry = new Registry( new Settings() ); // Modules register on `init` so translations are available to their labels. add_action( 'init', array( $this->registry, 'load' ), 5 ); ( new ModulesController( $this->registry ) )->register(); Support\SystemStatus::register(); if ( is_admin() ) { add_action( 'admin_init', array( $this->registry, 'maybe_upgrade' ) ); ( new AdminPage( $this->registry ) )->register(); add_filter( 'plugin_action_links_' . APWC_BASENAME, array( $this, 'action_links' ) ); } } /** * Get the module registry. * * @since 1.0.0 * @return Registry */ public function registry() { return $this->registry; } /** * Add a "Settings" link on the Plugins screen. * * @since 1.0.0 * @param string[] $links Existing links. * @return string[] */ public function action_links( $links ) { array_unshift( $links, sprintf( '%s', esc_url( AdminPage::url() ), esc_html__( 'Settings', 'admin-powerups-for-woocommerce' ) ) ); return $links; } /** * Activation: migrate storage and restore autoload flags. Without WooCommerce at the floor * nothing runs (no jobs or tables whose callbacks couldn't run): the version is forgotten so * Registry::maybe_upgrade() runs these steps once the plugin boots, and the admin notice * explains why. * * @since 1.0.0 * @param bool $network_wide Network activation (multisite): run on every site. * @return void */ public static function activate( $network_wide = false ) { $ok = self::woocommerce_ok(); self::each_site( $network_wide, static function () use ( $ok ) { $store = new Settings(); if ( ! $ok ) { $store->forget_version(); return; } $store->enabled_ids(); // Triggers migration from older storage. ( new Registry( $store ) )->sync_autoload( true ); $store->set_version( APWC_VERSION ); } ); } /** * Run a callback on this site, or on every site for a network (de)activation. * * @param bool $network_wide Network-wide. * @param callable $callback Callback. * @return void */ private static function each_site( $network_wide, callable $callback ) { if ( ! $network_wide || ! is_multisite() ) { $callback(); return; } foreach ( get_sites( array( 'fields' => 'ids', 'number' => 0, ) ) as $site_id ) { switch_to_blog( (int) $site_id ); $callback(); restore_current_blog(); } } /** * Deactivation: keep settings but stop autoloading them (core-recommended). * * @since 1.0.0 * @param bool $network_wide Network deactivation (multisite): run on every site. * @return void */ public static function deactivate( $network_wide = false ) { self::each_site( $network_wide, static function () { ( new Registry( new Settings() ) )->sync_autoload( false ); } ); } }