Skip to content

Instantly share code, notes, and snippets.

@nawawi
Last active February 17, 2025 10:02
Show Gist options
  • Save nawawi/1a7b9ff1cf37ff43d77b8882996d3373 to your computer and use it in GitHub Desktop.
Save nawawi/1a7b9ff1cf37ff43d77b8882996d3373 to your computer and use it in GitHub Desktop.
0-wpstg-reset
<?php
add_action('wpstg.clone_first_run', function () {
// Set to false for actual operation
$isDryRun = true;
// Abort if not wp-staging staging site
if (empty($GLOBALS['table_prefix']) || !preg_match('@^wpstg\d+@', $GLOBALS['table_prefix'])) {
return;
}
// Run at shutdown to avoid any issue with loaded plugins
add_action('shutdown', function () use ($isDryRun) {
$logFile = WP_CONTENT_DIR . "/wpstg-reset.log";
$config = (object)[
'dbName' => DB_NAME,
'dbUser' => DB_USER,
'dbPassword' => DB_PASSWORD,
'dbHost' => DB_HOST,
'dbPrefix' => $GLOBALS['table_prefix'],
'rootPath' => rtrim(ABSPATH, '/'),
'parentPath' => rtrim(dirname(ABSPATH), '/')
];
$wpTables = [
'commentmeta',
'comments',
'links',
'options',
'postmeta',
'posts',
'term_relationships',
'term_taxonomy',
'termmeta',
'terms',
'usermeta',
'users',
/*mu*/
'blogs',
'blogmeta',
'signups',
'site',
'sitemeta',
'registration_log'
];
$preservedTables = [
'options',
'users',
'usermeta',
'site',
'sitemeta',
'signups'
];
$wpOptions = [
'siteurl',
'home',
'blogname',
'blogdescription',
'users_can_register',
'admin_email',
'start_of_week',
'use_balanceTags',
'use_smilies',
'require_name_email',
'comments_notify',
'posts_per_rss',
'rss_use_excerpt',
'mailserver_url',
'mailserver_login',
'mailserver_pass',
'mailserver_port',
'default_category',
'default_comment_status',
'default_ping_status',
'default_pingback_flag',
'posts_per_page',
'date_format',
'time_format',
'links_updated_date_format',
'comment_moderation',
'moderation_notify',
'permalink_structure',
'rewrite_rules',
'hack_file',
'blog_charset',
'moderation_keys',
'active_plugins',
'category_base',
'ping_sites',
'comment_max_links',
'gmt_offset',
'default_email_category',
'recently_edited',
'template',
'stylesheet',
'comment_registration',
'html_type',
'use_trackback',
'default_role',
'db_version',
'uploads_use_yearmonth_folders',
'upload_path',
'blog_public',
'default_link_category',
'show_on_front',
'tag_base',
'show_avatars',
'avatar_rating',
'upload_url_path',
'thumbnail_size_w',
'thumbnail_size_h',
'thumbnail_crop',
'medium_size_w',
'medium_size_h',
'avatar_default',
'large_size_w',
'large_size_h',
'image_default_link_type',
'image_default_size',
'image_default_align',
'close_comments_for_old_posts',
'close_comments_days_old',
'thread_comments',
'thread_comments_depth',
'page_comments',
'comments_per_page',
'default_comments_page',
'comment_order',
'sticky_posts',
'widget_categories',
'widget_text',
'widget_rss',
'uninstall_plugins',
'timezone_string',
'page_for_posts',
'page_on_front',
'default_post_format',
'link_manager_enabled',
'finished_splitting_shared_terms',
'site_icon',
'medium_large_size_w',
'medium_large_size_h',
'wp_page_for_privacy_policy',
'show_comments_cookies_opt_in',
'admin_email_lifespan',
'disallowed_keys',
'comment_previously_approved',
'auto_plugin_theme_update_emails',
'auto_update_core_dev',
'auto_update_core_minor',
'auto_update_core_major',
'wp_force_deactivated_plugins',
'wp_attachment_pages_enabled',
];
$wpCoreFiles = [
"index.php",
"license.txt",
"readme.html",
"wp-activate.php",
"wp-admin",
"wp-blog-header.php",
"wp-comments-post.php",
"wp-config.php",
"wp-config-sample.php",
"wp-content",
"wp-cron.php",
"wp-includes",
"wp-links-opml.php",
"wp-load.php",
"wp-login.php",
"wp-mail.php",
"wp-settings.php",
"wp-signup.php",
"wp-trackback.php",
"xmlrpc.php",
];
// avoid db.php dropins
$dbh = new wpdb($config->dbUser, $config->dbPassword, $config->dbName, $config->dbHost);
file_put_contents($logFile, "");
$dbh->query("SET SESSION SQL_MODE = 'NO_AUTO_VALUE_ON_ZERO'");
$dbh->query("SET FOREIGN_KEY_CHECKS = 0");
$dbh->query("SET UNIQUE_CHECKS = 0");
$dbh->query("SET AUTOCOMMIT = 0");
$dbh->query("START TRANSACTION");
// Cleanup tables
$tableArrays = $dbh->get_results("SHOW TABLES LIKE '" . $config->dbPrefix . "%'", ARRAY_N);
if (!empty($tableArrays) && is_array($tableArrays)) {
foreach ($tableArrays as $tables) {
$tableName = substr($tables[0], strlen($config->dbPrefix));
if (!in_array($tableName, $wpTables)) {
$dropQuery = "DROP TABLE `" . $tables[0] . "`";
file_put_contents($logFile, "query: " . $dropQuery . "\n", FILE_APPEND);
if (!$isDryRun) {
$dbh->query($dropQuery);
}
continue;
}
if (!in_array($tableName, $preservedTables)) {
$truncateQuery = "TRUNCATE TABLE `" . $tables[0] . "`";
file_put_contents($logFile, "query: " . $truncateQuery . "\n", FILE_APPEND);
if (!$isDryRun) {
$dbh->query($truncateQuery);
}
}
}
}
// Cleanup options
$tableOptions = $config->dbPrefix . "options";
$optionActivePlugins = [];
$activeTheme = $dbh->get_var("SELECT `option_value` FROM `" . $tableOptions . "` WHERE `option_name`='template' LIMIT 1");
$adminEmail = $dbh->get_var("SELECT `option_value` FROM `" . $tableOptions . "` WHERE `option_name`='admin_email' LIMIT 1");
$optionArrays = $dbh->get_results("SELECT `option_id`,`option_name`,`option_value` FROM `" . $tableOptions . "` WHERE `option_name` NOT LIKE 'wpstg%'", ARRAY_A);
if (!empty($optionArrays) && is_array($optionArrays)) {
foreach ($optionArrays as $options) {
$optionId = $options['option_id'];
$optionName = $options['option_name'];
$optionValue = $options['option_value'];
if (in_array($optionName, $wpOptions) || strpos($optionName, "wpstg") === 0 || strpos($optionName, "_wpstg_") !== false) {
if ($optionName === 'active_plugins' && !empty($optionValue)) {
$optionActivePlugins = maybe_unserialize($optionValue);
}
continue;
}
$deleteQuery = "DELETE FROM `" . $tableOptions . "` WHERE `option_id`='" . $optionId . "'";
file_put_contents($logFile, "query: " . $deleteQuery . "\n", FILE_APPEND);
if (!$isDryRun) {
$dbh->query($deleteQuery);
}
}
}
// Cleanup plugins, preserved wp-staging
if (!empty($optionActivePlugins) && is_array($optionActivePlugins)) {
$optionActivePlugins = array_filter(array_map(function ($a) {
if (strpos($a, "wp-staging") === 0) {
return $a;
}
}, $optionActivePlugins));
$updateQuery = "UPDATE `" . $tableOptions . "` SET `option_value`='" . serialize($optionActivePlugins) . "' WHERE `option_name`='active_plugins'";
file_put_contents($logFile, "query: " . $updateQuery . "\n", FILE_APPEND);
if (!$isDryRun) {
$dbh->query($updateQuery);
}
}
// Cleanup user
$tableUser = $config->dbPrefix . "users";
$tableUsermeta = $config->dbPrefix . "usermeta";
$userArrays = $dbh->get_results("SELECT `ID` FROM `" . $tableUser . "` WHERE `user_email` NOT LIKE '" . $adminEmail . "' and `user_login` NOT LIKE 'wpstg_%'", ARRAY_A);
if (!empty($userArrays) && is_array($userArrays)) {
foreach ($userArrays as $users) {
$userId = $users['ID'];
$deleteQuery = "DELETE FROM `" . $tableUsermeta . "` WHERE `user_id`='" . $userId . "'";
file_put_contents($logFile, "query: " . $deleteQuery . "\n", FILE_APPEND);
if (!$isDryRun) {
$dbh->query($deleteQuery);
}
$deleteQuery = "DELETE FROM `" . $tableUser . "` WHERE `ID`='" . $userId . "'";
file_put_contents($logFile, "query: " . $deleteQuery . "\n", FILE_APPEND);
if (!$isDryRun) {
$dbh->query($deleteQuery);
}
}
}
// Update db
$dbh->query("COMMIT");
// Use parent files
if (!class_exists(WP_Filesystem_Direct::class, false)) {
require_once($config->parentPath . '/wp-admin/includes/class-wp-filesystem-base.php');
require_once($config->parentPath . '/wp-admin/includes/class-wp-filesystem-direct.php');
}
$wpFileSystemDirect = new WP_Filesystem_Direct(false);
// Cleanup wp-content/plugins
$pluginPath = WP_CONTENT_DIR . "/plugins";
if (file_exists($pluginPath) && is_dir($pluginPath) && !is_link($pluginPath)) {
$pluginArrays = glob($pluginPath . "/*");
foreach ($pluginArrays as $plugin) {
if (is_link($plugin)) {
continue;
}
$baseName = basename($plugin);
if ($baseName === "index.php" || strpos($baseName, "wp-staging") === 0) {
continue;
}
if (is_file($plugin)) {
file_put_contents($logFile, "unlink: " . $plugin . "\n", FILE_APPEND);
if (!$isDryRun) {
unlink($plugin);
}
continue;
}
if (is_dir($plugin)) {
file_put_contents($logFile, "rmdir: " . $plugin . "\n", FILE_APPEND);
if (!$isDryRun) {
$wpFileSystemDirect->rmdir($plugin, true);
}
}
}
}
// Cleanup wp-content/themes
$themePath = WP_CONTENT_DIR . "/themes";
if (file_exists($themePath) && is_dir($themePath) && !is_link($themePath)) {
$themeArrays = glob($themePath . "/*");
foreach ($themeArrays as $theme) {
if (is_link($theme)) {
continue;
}
$baseName = basename($theme);
if ($baseName === "index.php" || !empty($activeTheme) && $baseName === $activeTheme) {
continue;
}
if (is_file($theme)) {
file_put_contents($logFile, "unlink: " . $theme . "\n", FILE_APPEND);
if (!$isDryRun) {
unlink($theme);
}
continue;
}
if (is_dir($theme)) {
file_put_contents($logFile, "rmdir: " . $theme . "\n", FILE_APPEND);
if (!$isDryRun) {
$wpFileSystemDirect->rmdir($theme, true);
}
}
}
}
// Cleanup wp-content/uploads
$uploadPath = WP_CONTENT_DIR . "/uploads";
if (file_exists($uploadPath) && is_dir($uploadPath) && !is_link($uploadPath)) {
$uploadArrays = glob($uploadPath . "/*");
foreach ($uploadArrays as $upload) {
if (is_link($upload)) {
continue;
}
$baseName = basename($upload);
if ($baseName === "index.php" || strpos($baseName, "wp-staging") === 0) {
continue;
}
if (is_file($upload)) {
file_put_contents($logFile, "unlink: " . $upload . "\n", FILE_APPEND);
if (!$isDryRun) {
unlink($upload);
}
continue;
}
if (is_dir($upload)) {
file_put_contents($logFile, "rmdir: " . $upload . "\n", FILE_APPEND);
if (!$isDryRun) {
$wpFileSystemDirect->rmdir($upload, true);
}
}
}
}
// Cleanup wp-content/
$wpContentPath = WP_CONTENT_DIR;
if (file_exists($wpContentPath) && is_dir($wpContentPath) && !is_link($wpContentPath)) {
$wpContentArrays = glob($wpContentPath . "/*");
foreach ($wpContentArrays as $wpContent) {
if (is_link($wpContent)) {
continue;
}
$baseName = basename($wpContent);
if ($baseName === "index.php" || strpos($baseName, "wp-staging") === 0 || strpos($baseName, "wpstg-") === 0) {
continue;
}
if (in_array($baseName, ["plugins", "themes", "uploads", "mu-plugins", "languages"])) {
continue;
}
if (is_file($wpContent)) {
file_put_contents($logFile, "unlink: " . $wpContent . "\n", FILE_APPEND);
if (!$isDryRun) {
unlink($wpContent);
}
continue;
}
if (is_dir($wpContent)) {
file_put_contents($logFile, "rmdir: " . $wpContent . "\n", FILE_APPEND);
if (!$isDryRun) {
$wpFileSystemDirect->rmdir($wpContent, true);
}
}
}
}
// Cleanup ABSPATH/
$absRootPath = $config->rootPath;
if (file_exists($absRootPath) && is_dir($absRootPath) && !is_link($absRootPath)) {
$rootPathArrays = glob($absRootPath . "/*");
foreach ($rootPathArrays as $rootPath) {
if (is_link($rootPath)) {
continue;
}
$baseName = basename($rootPath);
if ($baseName === "index.php" || strpos($baseName, "wp-staging") === 0 || strpos($baseName, "wpstg-") === 0) {
continue;
}
if (in_array($baseName, $wpCoreFiles)) {
continue;
}
if (is_file($rootPath)) {
file_put_contents($logFile, "unlink: " . $rootPath . "\n", FILE_APPEND);
if (!$isDryRun) {
unlink($rootPath);
}
continue;
}
if (is_dir($rootPath)) {
file_put_contents($logFile, "rmdir: " . $rootPath . "\n", FILE_APPEND);
if (!$isDryRun) {
$wpFileSystemDirect->rmdir($rootPath, true);
}
}
}
}
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment