get_col( $wpdb->prepare( "SELECT option_name FROM {$wpdb->options} WHERE option_name LIKE %s OR option_name LIKE %s OR option_name LIKE %s", $wpdb->esc_like( 'signsealer_' ) . '%', $wpdb->esc_like( '_transient_signsealer_' ) . '%', $wpdb->esc_like( '_transient_timeout_signsealer_' ) . '%' ) ); // phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching foreach ( $rows as $row ) { if ( 0 === strpos( $row, '_transient_timeout_' ) ) { /* Either half of a transient is enough to name it; deleting it takes both. */ delete_transient( substr( $row, strlen( '_transient_timeout_' ) ) ); } elseif ( 0 === strpos( $row, '_transient_' ) ) { delete_transient( substr( $row, strlen( '_transient_' ) ) ); } else { delete_option( $row ); } } } /* On a network, every site's. WordPress runs this file once, on the site the network admin deleted the plugin from, and each site keeps its own options table and its own corner of the object cache: a sweep of that site alone would leave every other site's connection, webhook secret and mappings behind (Codex, on #372). That holds whether the plugin was network-activated or switched on site by site, so every site is swept, including ones that never used it -- on those the sweep finds nothing. `switch_to_blog` moves both `$wpdb->options` and the object cache to the site being swept. The plugin keeps nothing network-wide (no site options), so there is nothing to sweep above the sites. */ if ( is_multisite() ) { foreach ( get_sites( array( 'fields' => 'ids', 'number' => 0, ) ) as $signsealer_site ) { switch_to_blog( (int) $signsealer_site ); signsealer_uninstall_site(); restore_current_blog(); } } else { signsealer_uninstall_site(); }