'ids', 'number' => 0, ) ); foreach ( $site_ids as $site_id ) { switch_to_blog( $site_id ); self::uninstall_site(); restore_current_blog(); } } /** * Uninstalls on the current site. * * @return bool Whether user data was deleted. */ public static function uninstall_site() { global $wpdb; wp_clear_scheduled_hook( Jobs::HOOK ); delete_option( Jobs::LOCK ); delete_option( Migrations::LOCK ); // No core API lists options by prefix; delete_option() keeps the cache consistent. // phpcs:ignore WordPress.DB.DirectDatabaseQuery $job_options = $wpdb->get_col( $wpdb->prepare( "SELECT option_name FROM {$wpdb->options} WHERE option_name LIKE %s", $wpdb->esc_like( Jobs::STATE_PREFIX ) . '%' ) ); foreach ( $job_options as $option ) { delete_option( $option ); } // Scan results are a rebuildable cache, so they always go. Lowering the // schema version makes a reinstall recreate the tables. \Orbitstem\SEO\Diagnostics\Tables::drop(); \Orbitstem\SEO\Diagnostics\Tables::drop_logs(); wp_clear_scheduled_hook( 'orbitstem_seo_daily' ); wp_clear_scheduled_hook( 'orbitstem_seo_monitor' ); wp_clear_scheduled_hook( 'orbitstem_seo_scheduled_scan' ); delete_option( 'orbitstem_seo_autopilot_last' ); delete_option( 'orbitstem_seo_autopilot_user' ); delete_option( 'orbitstem_seo_monitor_alert' ); delete_option( 'orbitstem_seo_guardian_pending' ); delete_option( 'orbitstem_seo_head_scan' ); delete_option( 'orbitstem_seo_last_scan' ); wp_clear_scheduled_hook( 'orbitstem_seo_indexnow_submit' ); wp_clear_scheduled_hook( 'orbitstem_seo_indexnow_send' ); delete_option( 'orbitstem_seo_indexnow_queue' ); delete_option( 'orbitstem_seo_indexnow_log' ); delete_option( 'orbitstem_seo_indexnow_recent' ); wp_clear_scheduled_hook( 'orbitstem_seo_update_guard' ); wp_clear_scheduled_hook( 'orbitstem_seo_guard_baseline_build' ); // The "plain language" view choice on SEO Issues, kept per user. delete_metadata( 'user', 0, 'orbitstem_seo_simple', '', true ); foreach ( array( 'orbitstem_seo_guard_baseline', 'orbitstem_seo_guard_alert', 'orbitstem_seo_guard_pending', 'orbitstem_seo_health_last', 'orbitstem_seo_review_state', 'orbitstem_seo_setup_done' ) as $option ) { delete_option( $option ); } delete_transient( 'orbitstem_seo_issue_summary' ); // Every Orbitstem transient: notices, repair results, CSV previews, counts. // phpcs:ignore WordPress.DB.DirectDatabaseQuery $transients = $wpdb->get_col( $wpdb->prepare( "SELECT option_name FROM {$wpdb->options} WHERE option_name LIKE %s", $wpdb->esc_like( '_transient_orbitstem_seo_' ) . '%' ) ); foreach ( $transients as $option ) { delete_transient( substr( $option, strlen( '_transient_' ) ) ); } delete_transient( 'orbitstem_seo_coverage' ); delete_option( 'orbitstem_seo_snapshot_source' ); if ( (int) get_option( Migrations::OPTION, 0 ) > 1 ) { update_option( Migrations::OPTION, 1, true ); } $settings = get_option( Settings::OPTION, array() ); if ( empty( $settings['delete_data_on_uninstall'] ) ) { return false; } \Orbitstem\SEO\Diagnostics\Tables::drop_user_data(); \Orbitstem\SEO\Diagnostics\Tables::drop_monitor(); delete_option( Settings::OPTION ); delete_option( Migrations::OPTION ); delete_option( 'orbitstem_seo_regex_redirects' ); delete_option( 'orbitstem_seo_import_source' ); delete_option( 'orbitstem_seo_indexnow_key' ); foreach ( array_merge( MetaRepository::meta_keys(), array( '_orbitstem_seo_imported' ) ) as $key ) { delete_metadata( 'post', 0, $key, '', true ); delete_metadata( 'term', 0, $key, '', true ); } return true; } }