blog_id ) ? (int) $site->blog_id : (int) $site; switch_to_blog( $site_id ); self::install(); restore_current_blog(); } /** * Every site id in the network, or just this one. * * @return int[] */ public static function site_ids() { if ( ! is_multisite() ) { return array( get_current_blog_id() ); } return array_map( 'intval', get_sites( array( 'fields' => 'ids', 'number' => 0, ) ) ); } /** * Runs on deactivation. Data is kept: uninstall.php is what removes it. * * A network deactivation is the mirror of a network activation: the hook * fires once, so without the loop every other subsite would keep waking * WP-Cron for a plugin that is no longer running there. * * @param bool $network_wide True when deactivated across a multisite network. * @return void */ public static function deactivate( $network_wide = false ) { if ( $network_wide && is_multisite() ) { foreach ( self::site_ids() as $site_id ) { switch_to_blog( $site_id ); self::unschedule_events(); restore_current_blog(); } return; } self::unschedule_events(); } /** * Remove this site's recurring events. * * @return void */ private static function unschedule_events() { Send4_Cron::unschedule(); Send4_Forms_Sync::unschedule(); } /** * Create or upgrade the schema. * * The version is recorded only once the table is really there. Recording it * regardless meant one failed create (a permissions hiccup, a storage engine * dbDelta misreads) was never retried: maybe_upgrade() saw a current * version and every later lead that needed the queue was dropped. * * Autoloaded, because maybe_upgrade() reads it on every request; not * autoloading it cost a query per page view. The version bump is what * moves existing installs over, since update_option() only applies a new * autoload flag when the value changes. * * @return void */ public static function install() { Send4_Queue::install(); if ( Send4_Queue::table_exists() ) { update_option( self::DB_VERSION_OPTION, self::DB_VERSION, true ); } } /** * Bring an older install up to date on a normal request. * * @return void */ public static function maybe_upgrade() { if ( (int) get_option( self::DB_VERSION_OPTION, 0 ) === self::DB_VERSION ) { return; } self::install(); } /** * Make sure this site's recurring events exist. * * Separate from maybe_upgrade() because cron events are NOT part of the * schema version: updating a plugin runs no activation hook, so a site * activated before an event existed would never schedule it. For the forms * sync that means no automatic discovery at all until somebody deactivates * and reactivates, which nobody would think to do. * * The every-minute queue event is deliberately NOT ensured here. It only * has work while something is pending, so Send4_Delivery schedules it when * it enqueues, requeueing schedules it, process_queue() drops it once the * queue is empty, and the daily sweep re-ensures it if rows are pending. * Ensuring it on every init kept an idle site waking WP-Cron every minute. * * ⚠️ Call this on `init`, never earlier. wp_schedule_event() runs the * `cron_schedules` filter, and Send4_Cron::add_schedule() translates its * display name — doing that before the textdomain is loaded earns a * `_load_textdomain_just_in_time` notice on the customer's site. * * Idempotent, and reads only the one autoloaded `cron` option. * * @return void */ public static function ensure_events() { Send4_Forms_Sync::ensure_scheduled(); } }