prepare() with the %i identifier placeholder. */ // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange -- Uninstall must DROP the custom table; no WP schema API for plugin tables. $wpdb->query( $wpdb->prepare( 'DROP TABLE IF EXISTS %i', $wpdb->prefix . Activitysignature_Helpers::TABLE_SUFFIX ) ); delete_option( Activitysignature_Helpers::OPTION_SETTINGS ); delete_option( Activitysignature_Helpers::OPTION_BACKFILL ); delete_option( Activitysignature_Helpers::OPTION_BACKFILL_RETRY ); delete_option( Activitysignature_Helpers::OPTION_DB_VERSION ); wp_clear_scheduled_hook( Activitysignature_Helpers::HOOK_CLEANUP ); wp_clear_scheduled_hook( Activitysignature_Helpers::HOOK_BACKFILL ); Activitysignature_Helpers::delete_site_transients(); foreach ( array( 'created_date', 'last_update', 'last_login', 'last_login_checked', 'creation_recorded' ) as $name ) { delete_metadata( 'user', 0, Activitysignature_Helpers::get_user_meta_key( $name ), '', true ); } } /** * Remove plugin data for every site. * * Single-site installs run once. Multisite walks sites in bounded batches. * DROP IF EXISTS and delete_option stay safe if a site never activated the plugin. */ public static function uninstall() { if ( ! is_multisite() ) { self::uninstall_site(); return; } $offset = 0; $batch = 100; do { $site_ids = get_sites( array( 'fields' => 'ids', 'number' => $batch, 'offset' => $offset, ) ); foreach ( $site_ids as $site_id ) { switch_to_blog( (int) $site_id ); self::uninstall_site(); restore_current_blog(); } $offset += $batch; } while ( count( $site_ids ) === $batch ); } } Activitysignature_Uninstaller::uninstall();