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}");
}
});