Advanced. * The pages themselves and the files in the media library are never deleted. * * @link https://www.softvoltai.com/ * @since 1.0.0 * * @package Nexwordx */ // If uninstall not called from WordPress, then exit. if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) { exit; } /** * Remove the plugin's data from the current site. */ function nexwordx_uninstall_site() { global $wpdb; $settings = get_option( 'nexwordx_settings', array() ); if ( is_array( $settings ) && ! empty( $settings['deleteOnUninstall'] ) ) { // Templates, submissions and custom elements, the ones in the Trash included. The post // types are not registered during uninstall; the query needs only their names. $post_ids = get_posts( array( 'post_type' => array( 'nexwordx_library', 'nexwordx_submission', 'nexwordx_font', 'nexwordx_icons', 'nexwordx_code' ), 'post_status' => array( 'any', 'trash', 'auto-draft' ), 'posts_per_page' => -1, 'fields' => 'ids', ) ); foreach ( $post_ids as $post_id ) { wp_delete_post( $post_id, true ); } // The template categories: the taxonomy is registered for this one cleanup. if ( ! taxonomy_exists( 'nexwordx_library_category' ) ) { register_taxonomy( 'nexwordx_library_category', 'nexwordx_library', array( 'public' => false ) ); } $term_ids = get_terms( array( 'taxonomy' => 'nexwordx_library_category', 'hide_empty' => false, 'fields' => 'ids', ) ); if ( is_array( $term_ids ) ) { foreach ( $term_ids as $term_id ) { wp_delete_term( (int) $term_id, 'nexwordx_library_category' ); } } // Every builder meta on every post (the posts themselves stay: they are the owner's pages). // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- One-off cleanup on uninstall; no API deletes meta by prefix. $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->postmeta} WHERE meta_key LIKE %s", $wpdb->esc_like( '_nexwordx_' ) . '%' ) ); } $options = array( 'nexwordx_settings', 'nexwordx_secrets', 'nexwordx_kit', 'nexwordx_version', 'nexwordx_frontend_log', 'nexwordx_widgets_hash', 'nexwordx_posts_widget_pages', 'nexwordx_vercel', 'nexwordx_vercel_job', ); foreach ( $options as $option ) { delete_option( $option ); } // Options the modules keep under the plugin's prefix (transients are handled below). // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- One-off cleanup on uninstall; no API lists options by prefix. $prefixed = $wpdb->get_col( $wpdb->prepare( "SELECT option_name FROM {$wpdb->options} WHERE option_name LIKE %s", $wpdb->esc_like( 'nexwordx_' ) . '%' ) ); foreach ( (array) $prefixed as $option ) { delete_option( (string) $option ); } delete_transient( 'nexwordx_activated' ); delete_transient( 'nexwordx_widgets_hash' ); delete_transient( 'nexwordx_frontend_status' ); delete_transient( 'nexwordx_rollback_versions' ); // Any other short-lived transient with the plugin's prefix. // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- One-off cleanup on uninstall; no API lists transients by prefix. $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->options} WHERE option_name LIKE %s OR option_name LIKE %s", $wpdb->esc_like( '_transient_nexwordx_' ) . '%', $wpdb->esc_like( '_transient_timeout_nexwordx_' ) . '%' ) ); } if ( is_multisite() ) { foreach ( get_sites( array( 'fields' => 'ids', 'number' => 0 ) ) as $nexwordx_site_id ) { switch_to_blog( $nexwordx_site_id ); nexwordx_uninstall_site(); restore_current_blog(); } } else { nexwordx_uninstall_site(); }