| 1 |
<?php |
| 2 |
/* |
| 3 |
Plugin Name: WordPress Database Reset |
| 4 |
Plugin URI: https://github.com/chrisberthe/wordpress-database-reset |
| 5 |
Description: A plugin that allows you to reset the database to WordPress's initial state. |
| 6 |
Version: 2.1 |
| 7 |
Author: Chris Berthe ☻ |
| 8 |
Author URI: https://github.com/chrisberthe |
| 9 |
License: GNU General Public License |
| 10 |
*/ |
| 11 |
|
| 12 |
if ( ! class_exists('cb_wp_reset') && is_admin() ) : |
| 13 |
|
| 14 |
class cb_wp_reset |
| 15 |
{ |
| 16 |
/** |
| 17 |
* Nonce value |
| 18 |
*/ |
| 19 |
private $_nonce = 'wp-reset-nonce'; |
| 20 |
|
| 21 |
/** |
| 22 |
* Tables to preserve |
| 23 |
*/ |
| 24 |
private $_tables; |
| 25 |
|
| 26 |
/** |
| 27 |
* WordPress database tables |
| 28 |
*/ |
| 29 |
private $_wp_tables; |
| 30 |
|
| 31 |
/** |
| 32 |
* WordPress screen object |
| 33 |
*/ |
| 34 |
private $_admin_screen; |
| 35 |
|
| 36 |
/** |
| 37 |
* Loads default options |
| 38 |
* |
| 39 |
* @return void |
| 40 |
*/ |
| 41 |
function __construct() |
| 42 |
{ |
| 43 |
add_action('init', array($this, 'init_language')); |
| 44 |
add_action('admin_init', array($this, 'wp_reset_init')); |
| 45 |
add_action('admin_init', array($this, '_redirect_user')); |
| 46 |
add_action('admin_init', array($this, 'add_plugin_styles_and_scripts')); |
| 47 |
add_action('admin_footer', array($this, 'add_admin_javascript')); |
| 48 |
add_action('admin_menu', array($this, 'add_admin_menu')); |
| 49 |
add_filter('wp_mail', array($this, '_fix_mail')); |
| 50 |
} |
| 51 |
|
| 52 |
/** |
| 53 |
* Handles the admin page functionality |
| 54 |
* |
| 55 |
* @access public |
| 56 |
* @uses wp_install Located in includes/upgrade.php (line 22) |
| 57 |
*/ |
| 58 |
function wp_reset_init() |
| 59 |
{ |
| 60 |
global $wpdb, $current_user, $pagenow; |
| 61 |
|
| 62 |
// Grab the WordPress database tables |
| 63 |
$this->_wp_tables = $wpdb->tables(); |
| 64 |
|
| 65 |
// Check for valid input - goes ahead and drops / resets tables |
| 66 |
if ( isset($_POST['wp-random-value'], $_POST['wp-reset-input']) && $_POST['wp-random-value'] == $_POST['wp-reset-input'] |
| 67 |
&& check_admin_referer('wp-nonce-submit', $this->_nonce) ) |
| 68 |
{ |
| 69 |
require_once(ABSPATH . '/wp-admin/includes/upgrade.php'); |
| 70 |
|
| 71 |
// No tables were selected |
| 72 |
if ( ! isset($_POST['tables']) && empty($_POST['tables']) ) |
| 73 |
{ |
| 74 |
wp_redirect(admin_url($pagenow) . '?page=wp-reset&reset=no-select'); exit(); |
| 75 |
} |
| 76 |
|
| 77 |
// Get current options |
| 78 |
$blog_title = get_option('blogname'); |
| 79 |
$public = get_option('blog_public'); |
| 80 |
|
| 81 |
$admin_user = get_user_by('login', 'admin'); |
| 82 |
$user = ( ! $admin_user || ! user_can($admin_user->ID, 'update_core') ) ? $current_user : $admin_user; |
| 83 |
|
| 84 |
// Get the selected tables |
| 85 |
$tables = (isset($_POST['tables'])) ? array_flip($_POST['tables']) : array(); |
| 86 |
|
| 87 |
// Compare the selected tables against the ones in the database |
| 88 |
$this->_tables = array_diff_key($this->_wp_tables, $tables); |
| 89 |
|
| 90 |
// Preserve the data from the tables that are unique |
| 91 |
if ( count($this->_tables) > 0 ) |
| 92 |
{ |
| 93 |
$backup_tables = $this->_backup_tables($this->_tables); |
| 94 |
} |
| 95 |
|
| 96 |
// Grab the currently active plugins |
| 97 |
if ( isset($_POST['wp-reset-check']) && $_POST['wp-reset-check'] == 'true' ) |
| 98 |
{ |
| 99 |
$active_plugins = $wpdb->get_var($wpdb->prepare("SELECT option_value FROM $wpdb->options WHERE option_name = %s", 'active_plugins')); |
| 100 |
} |
| 101 |
|
| 102 |
// Run through the database columns and drop all the tables |
| 103 |
if ( $db_tables = $wpdb->get_col("SHOW TABLES LIKE '{$wpdb->prefix}%'") ) |
| 104 |
{ |
| 105 |
foreach ($db_tables as $db_table) |
| 106 |
{ |
| 107 |
$wpdb->query("DROP TABLE {$db_table}"); |
| 108 |
} |
| 109 |
|
| 110 |
// Return user keys and import variables |
| 111 |
$keys = wp_install($blog_title, $user->user_login, $user->user_email, $public); |
| 112 |
$this->_wp_update_user($user, $keys); |
| 113 |
} |
| 114 |
|
| 115 |
// Delete and replace tables with the backed up table data |
| 116 |
if ( $backup_tables ) |
| 117 |
{ |
| 118 |
foreach ($this->_tables as $table) |
| 119 |
{ |
| 120 |
$wpdb->query("DELETE FROM " . $table); |
| 121 |
} |
| 122 |
|
| 123 |
$this->_backup_tables($backup_tables, 'reset'); |
| 124 |
} |
| 125 |
|
| 126 |
if ( ! empty($active_plugins) ) |
| 127 |
{ |
| 128 |
$wpdb->update($wpdb->options, array('option_value' => $active_plugins), array('option_name' => 'active_plugins')); |
| 129 |
|
| 130 |
wp_redirect(admin_url($pagenow) . '?page=wp-reset&reset=success'); exit(); |
| 131 |
} |
| 132 |
|
| 133 |
// If the wp-reset-check isn't checked just redirect user to dashboard |
| 134 |
wp_redirect(admin_url()); exit(); |
| 135 |
} |
| 136 |
} |
| 137 |
|
| 138 |
/** |
| 139 |
* Displays the admin page |
| 140 |
* |
| 141 |
* @access public |
| 142 |
* @return void |
| 143 |
*/ |
| 144 |
function show_admin_page() |
| 145 |
{ |
| 146 |
global $current_user; |
| 147 |
|
| 148 |
// Return to see if admin object exists |
| 149 |
$admin_user = get_user_by('login', 'admin'); |
| 150 |
|
| 151 |
// Generate a random value for the input box |
| 152 |
$random_string = wp_generate_password(5, false); |
| 153 |
?> |
| 154 |
<?php if ( isset($_POST['wp-random-value'], $_POST['wp-reset-input']) && $_POST['wp-random-value'] != $_POST['wp-reset-input'] ) : ?> |
| 155 |
<div class="error"><p><strong><?php _e('You entered the wrong value - please try again', 'wp-reset') ?>.</strong></p></div> |
| 156 |
<?php elseif ( isset($_GET['reset']) && $_GET['reset'] == 'no-select') : ?> |
| 157 |
<div class="error"><p><strong><?php _e('You did not select any database tables', 'wp-reset') ?>.</strong></p></div> |
| 158 |
<?php elseif ( isset($_GET['reset']) && $_GET['reset'] == 'success' ) : ?> |
| 159 |
<div class="updated"><p><strong><?php _e('The WordPress database has been reset successfully', 'wp-reset') ?>.</strong></p></div> |
| 160 |
<?php endif ?> |
| 161 |
|
| 162 |
<div class="wrap"> |
| 163 |
<?php screen_icon() ?> |
| 164 |
<h2><?php _e('Database Reset', 'wp-reset') ?></h2> |
| 165 |
<form action="" method="POST" id="wp-reset-form"> |
| 166 |
<p><?php _e('Please choose from the following database tables the ones you would like to reset', 'wp-reset') ?>:</p> |
| 167 |
<div id="select-buttons"> |
| 168 |
<span><a href='#' id="select-all"><?php _e('Select All', 'wp-reset') ?></a></span> |
| 169 |
<select id="wp-tables" multiple="multiple" name="tables[]" onchange="changeHandler()"> |
| 170 |
<?php foreach ($this->_wp_tables as $key => $value) : ?> |
| 171 |
<option><?php echo $key ?></option> |
| 172 |
<?php endforeach ?> |
| 173 |
</select> |
| 174 |
</div> |
| 175 |
<p><?php _e('Type in (or copy/paste) the generated value into the text box', 'wp-reset') ?>: <strong><?php echo $random_string ?></strong></p> |
| 176 |
<?php wp_nonce_field('wp-nonce-submit', $this->_nonce) ?> |
| 177 |
<input type="hidden" name="wp-random-value" value="<?php echo $random_string ?>" id="wp-random-value" /> |
| 178 |
<input type="text" name="wp-reset-input" value="" id="wp-reset-input" /> |
| 179 |
<input type="submit" name="wp-reset-submit" value="<?php _e('Reset Database', 'wp-reset') ?>" id="wp-reset-submit" class="button-primary" /> |
| 180 |
<img src="<?php echo plugins_url('css/i/ajax-loader.gif', __FILE__) ?>" alt="loader" id="loader" style="display: none" /> |
| 181 |
<div id="reactivate" style="display: none"> |
| 182 |
<p> |
| 183 |
<label for="wp-reset-check"> |
| 184 |
<input type="checkbox" name="wp-reset-check" id="wp-reset-check" checked="checked" value="true" /> |
| 185 |
<?php _e('Reactivate current plugins after reset?', 'wp-reset') ?> |
| 186 |
</label> |
| 187 |
</p> |
| 188 |
</div> |
| 189 |
</form> |
| 190 |
|
| 191 |
<?php if ( ! $admin_user || ! user_can($admin_user->ID, 'update_core') ) : ?> |
| 192 |
<p style="margin-top: 25px"><?php printf(__('The default user <strong><u>admin</u></strong> was never created for this WordPress install. So <strong><u>%s</u></strong> will be recreated with its current password instead', 'wp-reset'), $current_user->user_login) ?>.</p> |
| 193 |
<?php else : ?> |
| 194 |
<p><?php _e('The default user <strong><u>admin</u></strong> will be recreated with its current password upon resetting', 'wp-reset') ?>.</p> |
| 195 |
<?php endif; ?> |
| 196 |
|
| 197 |
<p><?php _e('Note that once you reset the database, all users will be deleted except the initial admin user.', 'wp-reset') ?></p> |
| 198 |
</div> |
| 199 |
<?php } |
| 200 |
|
| 201 |
/** |
| 202 |
* Add JavaScript to the bottom of the plugin page |
| 203 |
* |
| 204 |
* @access public |
| 205 |
* @return bool TRUE on reset confirmation |
| 206 |
*/ |
| 207 |
function add_admin_javascript() |
| 208 |
{ |
| 209 |
?> |
| 210 |
<script type="text/javascript"> |
| 211 |
/* <![CDATA[ */ |
| 212 |
(function($) { |
| 213 |
|
| 214 |
$('#wp-tables').bsmSelect({ |
| 215 |
animate: true, |
| 216 |
title: "<?php _e('Select Table', 'wp-reset') ?>", |
| 217 |
plugins: [$.bsmSelect.plugins.compatibility()] |
| 218 |
}); |
| 219 |
|
| 220 |
$("#select-all").click(function() { |
| 221 |
$("#wp-tables").children().attr("selected", "selected").end().change(); |
| 222 |
return false; |
| 223 |
}); |
| 224 |
|
| 225 |
$('#wp-reset-submit').click(function() { |
| 226 |
var message = "<?php _e('Clicking OK will result in your database being reset to its initial settings. Continue?', 'wp-reset') ?>"; |
| 227 |
var reset = confirm(message); |
| 228 |
|
| 229 |
if (reset) { |
| 230 |
$('#wp-reset-form').submit(); |
| 231 |
$('#loader').show(); |
| 232 |
} else { |
| 233 |
return false; |
| 234 |
} |
| 235 |
}); |
| 236 |
|
| 237 |
window.changeHandler = function() { |
| 238 |
var op = $("#wp-tables option[value='options']:selected"); |
| 239 |
$('#reactivate').toggle(op.length > 0); |
| 240 |
} |
| 241 |
|
| 242 |
})(jQuery); |
| 243 |
/* ]]> */ |
| 244 |
</script> |
| 245 |
<?php |
| 246 |
} |
| 247 |
|
| 248 |
/** |
| 249 |
* Adds our submenu item to the Tools menu |
| 250 |
* |
| 251 |
* @access public |
| 252 |
* @return void |
| 253 |
*/ |
| 254 |
function add_admin_menu() |
| 255 |
{ |
| 256 |
if ( current_user_can('update_core') ) |
| 257 |
{ |
| 258 |
$this->_hook = add_submenu_page('tools.php', 'Database Reset', 'Database Reset', 'update_core', 'wp-reset', array($this, 'show_admin_page')); |
| 259 |
|
| 260 |
add_action('load-' . $this->_hook, array($this, '_add_help_screen')); |
| 261 |
} |
| 262 |
} |
| 263 |
|
| 264 |
/** |
| 265 |
* Adds v3.3 style help menu for plugin page |
| 266 |
* |
| 267 |
* @access private |
| 268 |
* @return void |
| 269 |
*/ |
| 270 |
function _add_help_screen() |
| 271 |
{ |
| 272 |
$this->_admin_screen = get_current_screen(); |
| 273 |
|
| 274 |
$help = '<p>' . __( 'Thank you for downloading the WordPress Database Reset plugin.' ) . '</p>'; |
| 275 |
$help .= '<p>' . __( 'This plugin allows you to securely and easily reinitialize the WordPress database back to its default settings without actually having to reinstall WordPress from scratch. This plugin will come in handy for both theme and plugin developers. Two possible use case scenarios would be to:') . '</p>'; |
| 276 |
$help .= '<p>' . __( '<strong>1.</strong> Erase excess junk in the <code>wp_options</code> table that accumulates over time.<br /><strong>2.</strong> Revert back to a fresh install of the WordPress database after experimenting with various back-end options.' ) . '</p>'; |
| 277 |
$help .= '<p>' . __( 'You can learn more on how to use this plugin by clicking the <code>Instructions</code> tab to the left.' ) . '</p>'; |
| 278 |
|
| 279 |
$this->_admin_screen->add_help_tab( array( |
| 280 |
'id' => 'overview', |
| 281 |
'title' => __( 'Overview' ), |
| 282 |
'content' => $help, |
| 283 |
) ); |
| 284 |
|
| 285 |
$help = '<p>' . __( 'Performing a database reset is quite straightforward.' ) . '</p>'; |
| 286 |
$help .= '<p>' . __( 'Select the different tables you would like to reinitialize from the drop down list. You can select any number of tables. If you know you would like to reset the entire database, simply click the <code>Select All</code> button.' ) . '</p>'; |
| 287 |
$help .= '<p>' . __( 'Next you will have to enter the <code>auto generated value</code> into the text box. Clicking on the <code>Reset Database</code> button will result in a pop-up.' ) . '</p>'; |
| 288 |
$help .= '<p>' . __( 'Once you are sure you would like to proceed, click <code>OK</code> to reset.' ) . '</p>'; |
| 289 |
|
| 290 |
$this->_admin_screen->add_help_tab( array( |
| 291 |
'id' => 'instructions', |
| 292 |
'title' => __( 'Instructions' ), |
| 293 |
'content' => $help, |
| 294 |
) ); |
| 295 |
|
| 296 |
unset($help); |
| 297 |
|
| 298 |
$this->_admin_screen->set_help_sidebar( |
| 299 |
'<p><strong>' . __( 'Contact information:' ) . '</strong></p>' . |
| 300 |
'<p>' . __( 'Any ideas on features or ways to improve this plugin? Contact me at <a href="http://github.com/chrisberthe/" target="_blank">GitHub</a> or <a href="http://twitter.com/chrisberthe/" target="_blank">Twitter</a>.' ) . '</p>' |
| 301 |
); |
| 302 |
} |
| 303 |
|
| 304 |
/** |
| 305 |
* Adds any plugin styles to our page |
| 306 |
* |
| 307 |
* @access public |
| 308 |
* @return void |
| 309 |
*/ |
| 310 |
function add_plugin_styles_and_scripts() |
| 311 |
{ |
| 312 |
wp_enqueue_style('wordpress-reset-css', plugins_url('css/wp-reset.css', __FILE__)); |
| 313 |
wp_enqueue_style('bsmselect-css', plugins_url('css/jquery.bsmselect.css', __FILE__)); |
| 314 |
|
| 315 |
wp_enqueue_script('bsmselect', plugins_url('js/jquery.bsmselect.js', __FILE__)); |
| 316 |
wp_enqueue_script('bsmselect-compatibility', plugins_url('js/jquery.bsmselect.compatibility.js', __FILE__)); |
| 317 |
} |
| 318 |
|
| 319 |
/** |
| 320 |
* Load language path |
| 321 |
* |
| 322 |
* @access public |
| 323 |
* @return void |
| 324 |
*/ |
| 325 |
function init_language() |
| 326 |
{ |
| 327 |
$language_dir = basename(dirname(__FILE__)) . '/languages'; |
| 328 |
load_plugin_textdomain('wp-reset', FALSE, $language_dir); |
| 329 |
} |
| 330 |
|
| 331 |
/** |
| 332 |
* For activation hook |
| 333 |
* |
| 334 |
* @access public |
| 335 |
* @return void |
| 336 |
*/ |
| 337 |
function plugin_activate() |
| 338 |
{ |
| 339 |
add_option('wp-reset-activated', true); |
| 340 |
} |
| 341 |
|
| 342 |
/** |
| 343 |
* Redirects the user after the plugin is activated |
| 344 |
* |
| 345 |
* @access private |
| 346 |
* @return void |
| 347 |
*/ |
| 348 |
function _redirect_user() |
| 349 |
{ |
| 350 |
if ( get_option('wp-reset-activated', false) ) |
| 351 |
{ |
| 352 |
delete_option('wp-reset-activated'); |
| 353 |
wp_redirect(admin_url('tools.php') . '?page=wp-reset'); |
| 354 |
} |
| 355 |
} |
| 356 |
|
| 357 |
/** |
| 358 |
* Changes the password to a sentence rather than |
| 359 |
* an auto-generated password that is sent by email |
| 360 |
* right after the installation is complete |
| 361 |
* |
| 362 |
* @access private |
| 363 |
* @return $mail Version with password changed |
| 364 |
*/ |
| 365 |
function _fix_mail($mail) |
| 366 |
{ |
| 367 |
$subject = __('WordPress Database Reset', 'wp-reset'); |
| 368 |
$message = __('The tables you selected have been successfully reset to their default settings:', 'wp-reset'); |
| 369 |
$password = __('Password: The password you chose during the install.', 'wp-reset'); |
| 370 |
|
| 371 |
if ( stristr($mail['message'], 'Your new WordPress site has been successfully set up at:') ) |
| 372 |
{ |
| 373 |
$mail['subject'] = preg_replace('/New WordPress Site/', $subject, $mail['subject']); |
| 374 |
$mail['message'] = preg_replace('/Your new WordPress site has been successfully set up at:+/', $message, $mail['message']); |
| 375 |
$mail['message'] = preg_replace('/Password:\s.+/', $password, $mail['message']); |
| 376 |
} |
| 377 |
|
| 378 |
return $mail; |
| 379 |
} |
| 380 |
|
| 381 |
/** |
| 382 |
* Preserves all the results from the tables the user |
| 383 |
* did not select from the drop-down. Also resets these |
| 384 |
* results back after reinstalling WordPress. |
| 385 |
* |
| 386 |
* @access private |
| 387 |
* @return array Backed up data if type backup, void if reset |
| 388 |
*/ |
| 389 |
function _backup_tables($tables, $type = 'backup') |
| 390 |
{ |
| 391 |
global $wpdb; |
| 392 |
|
| 393 |
if ( is_array($tables) ) |
| 394 |
{ |
| 395 |
switch ($type) |
| 396 |
{ |
| 397 |
case 'backup': |
| 398 |
$backup_tables = array(); |
| 399 |
|
| 400 |
foreach ($tables as $table) |
| 401 |
{ |
| 402 |
$backup_tables[$table] = $wpdb->get_results("SELECT * FROM " . $table); |
| 403 |
} |
| 404 |
|
| 405 |
return $backup_tables; |
| 406 |
break; |
| 407 |
|
| 408 |
case 'reset': |
| 409 |
// Outer array of tables |
| 410 |
foreach ($tables as $table_name => $table_data) |
| 411 |
{ |
| 412 |
// Array of table rows |
| 413 |
foreach ($table_data as $row) |
| 414 |
{ |
| 415 |
$columns = $values = array(); |
| 416 |
|
| 417 |
// Loop through current object row |
| 418 |
foreach ($row as $column => $value) |
| 419 |
{ |
| 420 |
$columns[] = $column; |
| 421 |
$values[] = $wpdb->escape($value); |
| 422 |
} |
| 423 |
|
| 424 |
$wpdb->query("INSERT INTO $table_name (" . implode(', ', $columns) . ") VALUES ('" . implode("', '", $values) . "')"); |
| 425 |
} |
| 426 |
} |
| 427 |
break; |
| 428 |
} |
| 429 |
} |
| 430 |
|
| 431 |
return; |
| 432 |
} |
| 433 |
|
| 434 |
/** |
| 435 |
* Updates the user password and clears / sets |
| 436 |
* the authentication cookie for the user |
| 437 |
* |
| 438 |
* @access private |
| 439 |
* @param $user Current or admin user |
| 440 |
* @param $keys Array returned by wp_install() |
| 441 |
* @return TRUE on install success, FALSE otherwise |
| 442 |
*/ |
| 443 |
function _wp_update_user($user, $keys) |
| 444 |
{ |
| 445 |
global $wpdb; |
| 446 |
extract($keys, EXTR_SKIP); |
| 447 |
|
| 448 |
// Set the old password back to the user |
| 449 |
$query = $wpdb->prepare("UPDATE $wpdb->users SET user_pass = '%s', user_activation_key = '' WHERE ID = '%d'", $user->user_pass, $user_id); |
| 450 |
|
| 451 |
if ( $wpdb->query($query) ) |
| 452 |
{ |
| 453 |
// Delete the default_password_nag |
| 454 |
// so it doesn't pop up with the password reminder after installing |
| 455 |
if ( get_user_meta($user_id, 'default_password_nag') ) delete_user_meta($user_id, 'default_password_nag'); |
| 456 |
|
| 457 |
wp_clear_auth_cookie(); |
| 458 |
wp_set_auth_cookie($user_id); |
| 459 |
|
| 460 |
return TRUE; |
| 461 |
} |
| 462 |
|
| 463 |
return FALSE; |
| 464 |
} |
| 465 |
|
| 466 |
} |
| 467 |
|
| 468 |
$cb_wp_reset = new cb_wp_reset(); |
| 469 |
|
| 470 |
register_activation_hook( __FILE__, array('cb_wp_reset', 'plugin_activate') ); |
| 471 |
|
| 472 |
endif; |