get_col() is a WordPress API wrapper method (not direct SQL like ->query()). * It's necessary here because WordPress doesn't provide a get_all_transients_by_pattern() API. * We must retrieve the keys first, then delete each one using the proper delete_transient() API. * * @since 1.0.0 */ function two_factor_extended_delete_all_transients() { global $wpdb; // Get all transient keys using WordPress API wrapper (not direct SQL). // $wpdb->get_col() is a WordPress API method, needed to retrieve transient keys before deletion. // Caching not applicable in uninstall context (plugin being removed). // phpcs:disable WordPress.DB.DirectDatabaseQuery $transient_keys = $wpdb->get_col( $wpdb->prepare( "SELECT option_name FROM {$wpdb->options} WHERE option_name LIKE %s", $wpdb->esc_like( '_transient_two_factor_extended_' ) . '%' ) ); // phpcs:enable WordPress.DB.DirectDatabaseQuery // Delete each transient using WordPress API. foreach ( $transient_keys as $transient_key ) { // Remove the '_transient_' prefix to get the transient name. $transient_name = str_replace( '_transient_', '', $transient_key ); delete_transient( $transient_name ); } } /** * Delete all plugin site transients using WordPress APIs (Multisite). * * Note: $wpdb->get_col() is a WordPress API wrapper method (not direct SQL like ->query()). * It's necessary here because WordPress doesn't provide a get_all_site_transients_by_pattern() API. * We must retrieve the keys first, then delete each one using the proper delete_site_transient() API. * * @since 1.0.0 */ function two_factor_extended_delete_all_site_transients() { global $wpdb; // Get all site transient keys using WordPress API wrapper (not direct SQL). // $wpdb->get_col() is a WordPress API method, needed to retrieve site transient keys before deletion. // Caching not applicable in uninstall context (plugin being removed). // phpcs:disable WordPress.DB.DirectDatabaseQuery $transient_keys = $wpdb->get_col( $wpdb->prepare( "SELECT meta_key FROM {$wpdb->sitemeta} WHERE meta_key LIKE %s", $wpdb->esc_like( '_site_transient_two_factor_extended_' ) . '%' ) ); // phpcs:enable WordPress.DB.DirectDatabaseQuery // Delete each site transient using WordPress API. foreach ( $transient_keys as $transient_key ) { // Remove the '_site_transient_' prefix to get the transient name. $transient_name = str_replace( '_site_transient_', '', $transient_key ); delete_site_transient( $transient_name ); } } /** * Delete all plugin user meta using WordPress APIs. * * This function iterates through all users and removes any meta keys * starting with 'two_factor_extended_'. * * @since 1.0.0 */ function two_factor_extended_delete_all_user_meta() { // Get all user IDs (using WordPress API). $user_ids = get_users( array( 'fields' => 'ID', 'number' => -1, // Get all users. ) ); // For each user, delete all plugin-related meta. foreach ( $user_ids as $user_id ) { // Get all meta keys for this user. $user_meta_keys = get_user_meta( $user_id ); if ( ! is_array( $user_meta_keys ) ) { continue; } // Delete each meta key that belongs to our plugin. foreach ( array_keys( $user_meta_keys ) as $meta_key ) { if ( strpos( $meta_key, 'two_factor_extended_' ) === 0 ) { delete_user_meta( $user_id, $meta_key ); } } } } // Run uninstall. two_factor_extended_uninstall();