postmeta => array_merge( $groups, array( '_billing_checkoutline_', '_shipping_checkoutline_' ) ), // Orders in posts storage (and HPOS sync copies). $wpdb->usermeta => array_merge( $groups, array( 'billing_checkoutline_', 'shipping_checkoutline_' ) ), // Customers. ); $hpos_meta = $wpdb->prefix . 'wc_orders_meta'; if ( $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $hpos_meta ) ) === $hpos_meta ) { // phpcs:ignore WordPress.DB.DirectDatabaseQuery $tables[ $hpos_meta ] = $tables[ $wpdb->postmeta ]; } foreach ( $tables as $table => $prefixes ) { foreach ( $prefixes as $prefix ) { $wpdb->query( $wpdb->prepare( 'DELETE FROM %i WHERE meta_key LIKE %s', $table, $wpdb->esc_like( $prefix ) . '%' ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.SlowDBQuery.slow_db_query_meta_key } } // Drafts of fields that didn't save. Options are deleted by name below, so Checkoutline Pro's // checkoutline_pro_* options stay. One by one through delete_option(), so the object cache forgets them too. $drafts = $wpdb->get_col( $wpdb->prepare( "SELECT option_name FROM {$wpdb->options} WHERE option_name LIKE %s OR option_name LIKE %s", $wpdb->esc_like( '_transient_checkoutline_draft_' ) . '%', $wpdb->esc_like( '_transient_timeout_checkoutline_draft_' ) . '%' ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery foreach ( $drafts as $draft ) { delete_option( $draft ); } // The meta went with direct queries, past the object cache: drop the cached copies of orders, // users and their meta (not the whole cache, which other plugins share). if ( wp_cache_supports( 'flush_group' ) ) { foreach ( array( 'post_meta', 'user_meta', 'orders', 'orders_meta', 'orders_data', 'products', 'product_objects' ) as $group ) { wp_cache_flush_group( $group ); } } delete_option( 'checkoutline_fields' ); delete_option( 'checkoutline_core' ); delete_option( 'checkoutline_uninstall' ); }; if ( ! is_multisite() ) { if ( 'delete' === get_option( 'checkoutline_uninstall' ) ) { $checkoutline_purge(); } return; } // Multisite: each site answered for itself when it deactivated the plugin; a network-wide answer // (set only by a deactivation from Network Admin) decides for every site. $checkoutline_network = get_site_option( 'checkoutline_uninstall' ); foreach ( get_sites( array( 'fields' => 'ids', 'number' => 0 ) ) as $checkoutline_site ) { switch_to_blog( $checkoutline_site ); if ( 'delete' === ( false !== $checkoutline_network ? $checkoutline_network : get_option( 'checkoutline_uninstall' ) ) ) { $checkoutline_purge(); } restore_current_blog(); } delete_site_option( 'checkoutline_uninstall' );