File: //var/www/school/wp-content/plugins/simple-site-reset.php
<?php
/**
* Plugin Name: Simple Site Reset (Free)
* Description: Wipes content (posts, pages, CPTs), comments, terms, and uploads; deactivates other plugins; optionally recreates default content. Keeps siteurl/home so you stay logged in.
* Version: 1.0.0
* Author: You
*/
if (!defined('ABSPATH')) exit;
class Simple_Site_Reset {
const SLUG = 'simple-site-reset';
public function __construct() {
add_action('admin_menu', [$this, 'menu']);
add_action('admin_post_simple_site_reset_run', [$this, 'handle_reset']);
}
public function menu() {
add_management_page(
'Simple Site Reset',
'Simple Site Reset',
'manage_options',
self::SLUG,
[$this, 'render_page']
);
}
private function checkbox($name, $label, $checked = true, $desc = '') {
printf(
'<label style="display:block;margin-bottom:8px;"><input type="checkbox" name="%1$s" value="1" %2$s> <strong>%3$s</strong>%4$s</label>',
esc_attr($name),
checked($checked, true, false),
esc_html($label),
$desc ? ' <em style="opacity:.8;">('.esc_html($desc).')</em>' : ''
);
}
public function render_page() {
if (!current_user_can('manage_options')) return;
?>
<div class="wrap">
<h1>Simple Site Reset</h1>
<p><strong style="color:#b32d2e;">Danger zone:</strong> This will permanently delete selected data. Make a full backup first.</p>
<form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>">
<?php wp_nonce_field('simple_site_reset'); ?>
<input type="hidden" name="action" value="simple_site_reset_run" />
<h2>What to reset</h2>
<?php
$this->checkbox('wipe_content', 'Delete all posts/pages/CPTs', true, 'Also deletes post meta.');
$this->checkbox('wipe_comments', 'Delete all comments', true);
$this->checkbox('wipe_terms', 'Delete all categories/tags/terms', true);
$this->checkbox('wipe_uploads', 'Delete all files under wp-content/uploads', false);
$this->checkbox('deactivate_plugins', 'Deactivate all plugins except this one', true);
$this->checkbox('delete_users', 'Delete all users except the current admin', false);
$this->checkbox('recreate_defaults', 'Recreate “Hello world!” post and “Sample Page”', true);
?>
<h2>Type to confirm</h2>
<p>Type <code>reset</code> to confirm: <input type="text" name="confirm" value="" required></p>
<p><button class="button button-primary" type="submit">Run Reset</button></p>
</form>
<p><small>Notes: Does <em>not</em> drop core tables or touch <code>siteurl</code>/<code>home</code>. For a true reinstall, use a host/CLI or phpMyAdmin.</small></p>
</div>
<?php
}
public function handle_reset() {
if (!current_user_can('manage_options')) wp_die('Insufficient permissions.');
check_admin_referer('simple_site_reset');
if (!isset($_POST['confirm']) || trim($_POST['confirm']) !== 'reset') wp_die('Confirmation text mismatch.');
global $wpdb;
$log = [];
// Safeguards
if (is_multisite()) {
// Operate only on current blog. Network-wide "factory reset" is intentionally not supported here.
$log[] = 'Multisite detected: operating on current site only.';
}
// Options
$wipe_content = !empty($_POST['wipe_content']);
$wipe_comments = !empty($_POST['wipe_comments']);
$wipe_terms = !empty($_POST['wipe_terms']);
$wipe_uploads = !empty($_POST['wipe_uploads']);
$deactivate_plugins = !empty($_POST['deactivate_plugins']);
$delete_users = !empty($_POST['delete_users']);
$recreate_defaults = !empty($_POST['recreate_defaults']);
// 1) Deactivate all other plugins
if ($deactivate_plugins) {
$active = (array) get_option('active_plugins', []);
$me = plugin_basename(__FILE__);
$keep = array_filter($active, function($p) use ($me){ return $p === $me; });
update_option('active_plugins', array_values($keep));
$log[] = 'Deactivated all plugins except this one.';
}
// 2) Wipe uploads
if ($wipe_uploads) {
$upload = wp_get_upload_dir();
$base = trailingslashit($upload['basedir']);
$deleted = $this->rrmdir($base);
$log[] = $deleted ? 'Deleted all files under uploads.' : 'Uploads folder already empty or not writable.';
}
// 3) Delete content (posts, pages, CPTs) & postmeta
if ($wipe_content) {
// Faster than wp_delete_post for large sites; we deliberately nuke relationships & meta.
$wpdb->query("DELETE FROM {$wpdb->postmeta}");
$wpdb->query("DELETE FROM {$wpdb->posts}");
$log[] = 'Deleted all posts/pages/custom post types and post meta.';
}
// 4) Comments
if ($wipe_comments) {
$wpdb->query("DELETE FROM {$wpdb->commentmeta}");
$wpdb->query("DELETE FROM {$wpdb->comments}");
$log[] = 'Deleted all comments and comment meta.';
}
// 5) Terms (cats/tags/taxonomies)
if ($wipe_terms) {
$wpdb->query("DELETE FROM {$wpdb->term_relationships}");
$wpdb->query("DELETE FROM {$wpdb->term_taxonomy}");
$wpdb->query("DELETE FROM {$wpdb->terms}");
if ($this->table_exists($wpdb->termmeta)) {
$wpdb->query("DELETE FROM {$wpdb->termmeta}");
}
$log[] = 'Deleted all terms, term taxonomies, and relationships.';
}
// 6) Users (except current)
if ($delete_users) {
$current = get_current_user_id();
$users = get_users(['fields' => ['ID']]);
foreach ($users as $u) {
if ((int)$u->ID === (int)$current) continue;
require_once ABSPATH . 'wp-admin/includes/user.php';
wp_delete_user($u->ID, $current); // reassign to current admin
}
$log[] = 'Deleted all users except the current admin (content reassigned).';
}
// 7) Recreate defaults
if ($recreate_defaults) {
// Hello world
$hello_id = wp_insert_post([
'post_title' => 'Hello world!',
'post_content' => 'Welcome to WordPress. This is your first post. Edit or delete it, then start writing!',
'post_status' => 'publish',
'post_type' => 'post',
]);
// Sample Page
$page_id = wp_insert_post([
'post_title' => 'Sample Page',
'post_content' => "This is an example page. It's different from a blog post...",
'post_status' => 'publish',
'post_type' => 'page',
]);
// Default category (if we nuked terms)
if ($wipe_terms) {
$cat = wp_insert_term('Uncategorized', 'category', ['slug' => 'uncategorized']);
if (!is_wp_error($cat)) update_option('default_category', (int)$cat['term_id']);
}
flush_rewrite_rules();
$log[] = 'Recreated default “Hello world!” post and “Sample Page”; flushed permalinks.';
}
// Redirect back with log
$url = add_query_arg([
'page' => self::SLUG,
'ssr_done' => 1,
'ssr_log' => rawurlencode(base64_encode(wp_json_encode($log)))
], admin_url('tools.php'));
wp_safe_redirect($url);
exit;
}
private function table_exists($table) {
global $wpdb;
$table = esc_sql($table);
return (bool) $wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $table));
}
private function rrmdir($dir) {
// Delete contents of a directory but keep the directory itself.
if (!is_dir($dir)) return false;
$ok = true;
$items = @scandir($dir);
if ($items === false) return false;
foreach ($items as $item) {
if ($item === '.' || $item === '..') continue;
$path = $dir . $item;
if (is_dir($path)) {
$ok = $this->rrmdir(trailingslashit($path)) && @rmdir($path) && $ok;
} else {
$ok = @unlink($path) && $ok;
}
}
return $ok;
}
}
new Simple_Site_Reset();