Bulk Remove Themes
Download the plugin uploaded zip file
The Code
Can be added as snippet
<?php /** * Plugin Name: Bulk Remove Themes * Plugin URI: https://peteringersoll.com/ * Description: Adds functionality to bulk remove themes from the WordPress admin under the Appearance menu. * Version: 1.0 * Author: Peter Ingersoll (AI generated) * Author URI: https://peteringersoll.com/ */ add_action('admin_menu', function() { add_submenu_page( 'themes.php', 'Bulk Remove Themes', // Admin Page title 'Bulk Remove Themes', // Admin Menu title 'manage_options', 'bulk-remove-themes', // Menu slug 'bulk_remove_themes_page' // Function name ); }); function bulk_remove_themes_page() { $action = isset($_REQUEST['action']) ? sanitize_text_field($_REQUEST['action']) : ''; $user_id = get_current_user_id(); if ('confirm_delete' === $action && get_transient("themes_to_delete_{$user_id}")) { echo '<div class="wrap"><h1>These themes will be removed:</h1><ul>'; $themes_to_delete = get_transient("themes_to_delete_{$user_id}"); foreach ($themes_to_delete as $theme_stylesheet) { $theme = wp_get_theme($theme_stylesheet); echo '<li>' . esc_html($theme->Name) . '</li>'; } echo '</ul>'; echo '<form action="" method="post">'; wp_nonce_field('confirm-delete-themes'); submit_button('Delete Themes', 'primary', 'confirm_delete'); echo ' <a href="' . esc_url(admin_url('admin.php?page=bulk-remove-themes')) . '" class="button">Abort / Back</a>'; echo '</form></div>'; } else { $themes = wp_get_themes(); $active_theme = wp_get_theme(); echo '<div class="wrap"><h1>Bulk Remove Themes</h1>'; // Changed heading echo '<form method="post" action="'.esc_url(admin_url('admin-post.php')).'">'; wp_nonce_field('bulk-delete-themes'); echo '<input type="hidden" name="action" value="submit_themes_for_deletion">'; echo '<table class="wp-list-table widefat fixed striped">'; echo '<thead><tr><th scope="col" class="check-column"><input type="checkbox" /></th><th scope="col">Theme Name</th></tr></thead>'; echo '<tbody id="the-list">'; foreach ($themes as $theme) { if ($theme->get_stylesheet() != $active_theme->get_stylesheet()) { echo '<tr><th scope="row" class="check-column"><input type="checkbox" name="themes[]" value="' . esc_attr($theme->get_stylesheet()) . '" /></th><td>' . esc_html($theme->get('Name')) . '</td></tr>'; } } echo '</tbody></table>'; submit_button('Delete Selected Themes'); echo '</form></div>'; } } add_action('admin_post_submit_themes_for_deletion', function() { check_admin_referer('bulk-delete-themes'); $user_id = get_current_user_id(); $themes = isset($_POST['themes']) ? array_map('sanitize_text_field', $_POST['themes']) : []; set_transient("themes_to_delete_{$user_id}", $themes, 60 * 60); // Store for 1 hour wp_redirect(admin_url('admin.php?page=bulk-remove-themes&action=confirm_delete')); exit; }); add_action('admin_init', function() { if (isset($_POST['confirm_delete']) && check_admin_referer('confirm-delete-themes')) { $user_id = get_current_user_id(); $themes_to_delete = get_transient("themes_to_delete_{$user_id}"); if ($themes_to_delete) { foreach ($themes_to_delete as $theme_stylesheet) { if (current_user_can('delete_themes') && $theme_stylesheet !== get_stylesheet()) { delete_theme($theme_stylesheet); } } set_transient("themes_deleted_success_{$user_id}", '1', 10); // Short expiry, just for the redirect. delete_transient("themes_to_delete_{$user_id}"); } wp_redirect(admin_url('admin.php?page=bulk-remove-themes')); exit; } // Check for the success transient and add admin notice $user_id = get_current_user_id(); if (get_transient("themes_deleted_success_{$user_id}")) { add_action('admin_notices', function() { echo '<div class="notice notice-success is-dismissible"><p>Selected themes have been deleted.</p></div>'; }); delete_transient("themes_deleted_success_{$user_id}"); } });