get_col( $wpdb->prepare( "SELECT option_name FROM {$wpdb->options} WHERE option_name LIKE %s", $wpdb->esc_like( '_transient_' . $prefix ) . '%' ) ); foreach ( (array) $names as $name ) { delete_transient( substr( $name, strlen( '_transient_' ) ) ); } } $tables = array( $wpdb->prefix . 'mybot_messages', $wpdb->prefix . 'mybot_ratelimit', $wpdb->prefix . 'mybot_queue', $wpdb->prefix . 'mybot_cache', // Questions left for a human. Removed with the plugin: they hold visitor contact // details, and leaving personal data behind after an uninstall is not a tidy default. $wpdb->prefix . 'mybot_requests', // The visitor cards (1.17.0). Same reason, and a stronger one: this table is nothing // BUT personal data — a name, a phone number, an email address and the sentence the // visitor agreed to. It is dropped first in spirit and in fact. $wpdb->prefix . 'mybot_contacts', ); foreach ( $tables as $table ) { // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.PreparedSQL.NotPrepared $wpdb->query( $wpdb->prepare( 'DROP TABLE IF EXISTS %i', $table ) ); } // Indexing fingerprints. The knowledge posts themselves are kept on purpose: they are // content the site owner may want to keep, and docs/08 explains how to remove them. // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $wpdb->delete( $wpdb->postmeta, array( 'meta_key' => MYBOT_INDEX_HASH_META ) ); } catch ( Throwable $error ) { // Report to the PHP log and carry on: deletion must still succeed. // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log error_log( 'AI House uninstall: ' . $error->getMessage() ); } } if ( is_multisite() ) { $mybot_site_ids = get_sites( array( 'fields' => 'ids' ) ); foreach ( $mybot_site_ids as $mybot_site_id ) { switch_to_blog( $mybot_site_id ); mybot_uninstall_site(); restore_current_blog(); } } else { mybot_uninstall_site(); }