=' );
}
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(
'
',
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 );
}
);
}
}