'ids', 'number' => 0 ) ) ) : array( 0 ); foreach ( $bb_sites as $bb_site ) { $bb_switch = $bb_site > 0 && get_current_blog_id() !== $bb_site; if ( $bb_switch ) { switch_to_blog( $bb_site ); } addon_boss_uninstall_boot_cache(); addon_boss_uninstall_google_feed(); if ( $bb_switch ) { restore_current_blog(); } } // AddOnBoss's OWN options and transients only. The option-set store // (bundle_boss_option_sets / bundle_boss_option_set_groups, historical // names kept at the split) and the per-product options meta // (_bundle_boss_product_options) are the merchant's own configuration, // and a pre-split BundleBoss may still be installed and using them, so // uninstalling AddOnBoss never removes them. No product type is // AddOnBoss's, so nothing is deleted at the post level either. $wpdb->query( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- one-time uninstall cleanup. $wpdb->prepare( "DELETE FROM {$wpdb->options} WHERE option_name LIKE %s OR option_name LIKE %s OR option_name LIKE %s", $wpdb->esc_like( 'addon_boss_' ) . '%', $wpdb->esc_like( '_transient_addon_boss_' ) . '%', $wpdb->esc_like( '_transient_timeout_addon_boss_' ) . '%' ) ); // Each person's "Last used" kind on the new-set screen. delete_metadata( 'user', 0, 'addon_boss_last_set_kind', '', true ); // No background job of ours outlives the plugin. if ( function_exists( 'as_unschedule_all_actions' ) ) { as_unschedule_all_actions( 'addon_boss_sf_run', array(), 'addon-boss' ); } } /** * One site's cached boot scripts: the folder, what was known about the files * in it, and any look at them still scheduled. Only that one folder: the * shoppers' uploads beside it are order records. * * Read with scandir(), not glob(), which sees only the local disk and so * found nothing to delete on uploads behind a stream wrapper (S3, VIP). */ function addon_boss_uninstall_boot_cache() { delete_option( 'addon_boss_boot_files' ); if ( function_exists( 'wp_unschedule_hook' ) ) { wp_unschedule_hook( 'addon_boss_boot_check' ); } $bb_up = wp_upload_dir( null, false ); if ( ! empty( $bb_up['error'] ) || empty( $bb_up['basedir'] ) ) { return; } $bb_dir = trailingslashit( $bb_up['basedir'] ) . 'addon-boss-cache'; if ( ! is_dir( $bb_dir ) ) { return; } foreach ( (array) @scandir( $bb_dir ) as $bb_n ) { // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged -- an unreadable folder has nothing we can take. if ( is_string( $bb_n ) && '.' !== $bb_n && '..' !== $bb_n && is_file( $bb_dir . '/' . $bb_n ) ) { wp_delete_file( $bb_dir . '/' . $bb_n ); } } @rmdir( $bb_dir ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged, WordPress.WP.AlternativeFunctions.file_system_operations_rmdir -- our own, now empty, cache folder. } /** * One site's Google colour and size feed: its options, the built file in its * own folder, and the builds still booked. Run for every site of a network, * where the sweep of options below reaches the main site only. */ function addon_boss_uninstall_google_feed() { foreach ( array( 'addon_boss_google_feed_token', 'addon_boss_google_feed_settings', 'addon_boss_google_feed_state', 'addon_boss_google_feed_audience', 'addon_boss_gfeed_lock', 'addon_boss_gfeed_progress', 'addon_boss_gfeed_dirty', 'addon_boss_gfeed_on', 'addon_boss_gfeed_setup', 'addon_boss_gfeed_fetched', 'addon_boss_gfeed_brands', 'addon_boss_gfeed_quiet' ) as $bb_option ) { delete_option( $bb_option ); } if ( function_exists( 'wp_unschedule_hook' ) ) { foreach ( array( 'addon_boss_google_feed_batch', 'addon_boss_google_feed_rebuild', 'addon_boss_google_feed_daily' ) as $bb_hook ) { wp_unschedule_hook( $bb_hook ); } } $bb_up = wp_upload_dir( null, false ); if ( ! empty( $bb_up['error'] ) || empty( $bb_up['basedir'] ) ) { return; } $bb_dir = trailingslashit( $bb_up['basedir'] ) . 'addon-boss-feed'; if ( ! is_dir( $bb_dir ) ) { return; } foreach ( (array) @scandir( $bb_dir ) as $bb_n ) { // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged -- an unreadable folder has nothing we can take. if ( is_string( $bb_n ) && '.' !== $bb_n && '..' !== $bb_n && is_file( $bb_dir . '/' . $bb_n ) ) { wp_delete_file( $bb_dir . '/' . $bb_n ); } } @rmdir( $bb_dir ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged, WordPress.WP.AlternativeFunctions.file_system_operations_rmdir -- our own, now empty, feed folder. }