PluginProbe
Database Reset / 2.0
Database Reset v2.0
2.3.2 3.0 3.0.1 3.0.2 3.1 3.15 3.16 3.17 3.18 3.19 3.20 3.21 3.22 3.23 3.24 3.25 trunk 1.0 1.2 1.2.1 1.2.2 1.3 1.4 2.0 2.1 All 27 releases
wordpress-database-reset / wp-reset.php

wp-reset.php in Database Reset 2.0, at wp-reset.php

471 lines 14.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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.0
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 * Plugins to reactivate
23 */
24 private $_active_plugins;
25
26 /**
27 * Tables to preserve
28 */
29 private $_tables;
30
31 /**
32 * WordPress database tables
33 */
34 private $_wp_tables;
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('contextual_help', array($this, 'add_contextual_help'), 10, 2);
50 add_filter('wp_mail', array($this, '_fix_mail'));
51 }
52
53 /**
54 * Handles the admin page functionality
55 *
56 * @access public
57 * @uses wp_install Located in includes/upgrade.php (line 22)
58 */
59 function wp_reset_init()
60 {
61 global $wpdb, $current_user, $pagenow;
62
63 // Grab the WordPress database tables
64 $this->_wp_tables = $wpdb->tables();
65
66 // Check for valid input - goes ahead and drops / resets tables
67 if ( isset($_POST['wp-random-value'], $_POST['wp-reset-input']) && $_POST['wp-random-value'] == $_POST['wp-reset-input']
68 && check_admin_referer('wp-nonce-submit', $this->_nonce) )
69 {
70 require_once(ABSPATH . '/wp-admin/includes/upgrade.php');
71
72 // No tables were selected
73 if ( ! isset($_POST['tables']) && empty($_POST['tables']) )
74 {
75 wp_redirect(admin_url($pagenow) . '?page=wp-reset&reset=no-select'); exit();
76 }
77
78 // Get current options
79 $blog_title = get_option('blogname');
80 $public = get_option('blog_public');
81
82 $admin_user = get_userdatabylogin('admin');
83 $user = ( ! $admin_user || ! user_can($admin_user->ID, 'update_core') ) ? $current_user : $admin_user;
84
85 // Get the selected tables
86 $tables = (isset($_POST['tables'])) ? array_flip($_POST['tables']) : array();
87
88 // Compare the selected tables against the ones in the database
89 $this->_tables = array_diff_key($this->_wp_tables, $tables);
90
91 // Preserve the data from the tables that are unique
92 if ( count($this->_tables) > 0 )
93 {
94 $backup_tables = $this->_backup_tables($this->_tables);
95 }
96
97 // Grab the currently active plugins
98 if ( isset($_POST['wp-reset-check']) && $_POST['wp-reset-check'] == 'true' )
99 {
100 $this->_active_plugins = $wpdb->get_var($wpdb->prepare("SELECT option_value FROM $wpdb->options WHERE option_name = %s", 'active_plugins'));
101 }
102
103 // Run through the database columns and drop all the tables
104 if ( $db_tables = $wpdb->get_col("SHOW TABLES LIKE '{$wpdb->prefix}%'") )
105 {
106 foreach ($db_tables as $db_table)
107 {
108 $wpdb->query("DROP TABLE {$db_table}");
109 }
110
111 // Return user keys and import variables
112 $keys = wp_install($blog_title, $user->user_login, $user->user_email, $public);
113 $this->_wp_update_user($user, $keys);
114 }
115
116 // Delete and replace tables with the backed up table data
117 if ( count($this->_tables) > 0 )
118 {
119 foreach ($this->_tables as $table)
120 {
121 $wpdb->query("DELETE FROM " . $table);
122 }
123
124 $this->_backup_tables($backup_tables, 'reset');
125 }
126
127 if ( ! empty($this->_active_plugins) )
128 {
129 $wpdb->update($wpdb->options, array('option_value' => $this->_active_plugins), array('option_name' => 'active_plugins'));
130
131 wp_redirect(admin_url($pagenow) . '?page=wp-reset&reset=success'); exit();
132 }
133
134 // If the wp-reset-check isn't checked just redirect user to dashboard
135 wp_redirect(admin_url()); exit();
136 }
137 }
138
139 /**
140 * Displays the admin page
141 *
142 * @access public
143 * @return void
144 */
145 function show_admin_page()
146 {
147 global $current_user;
148
149 // Return to see if admin object exists
150 $admin_user = get_userdatabylogin('admin');
151
152 // Generate a random value for the input box
153 $random_string = $this->_rand_string();
154 ?>
155 <?php if ( isset($_POST['wp-random-value'], $_POST['wp-reset-input']) && $_POST['wp-random-value'] != $_POST['wp-reset-input'] ) : ?>
156 <div class="error"><p><strong><?php _e('You entered the wrong value - please try again', 'wp-reset') ?>.</strong></p></div>
157 <?php elseif ( isset($_GET['reset']) && $_GET['reset'] == 'no-select') : ?>
158 <div class="error"><p><strong><?php _e('You did not select any database tables', 'wp-reset') ?>.</strong></p></div>
159 <?php elseif ( isset($_GET['reset']) && $_GET['reset'] == 'success' ) : ?>
160 <div class="updated"><p><strong><?php _e('The WordPress database has been reset successfully', 'wp-reset') ?>.</strong></p></div>
161 <?php endif ?>
162
163 <div class="wrap">
164 <?php screen_icon() ?>
165 <h2><?php _e('Database Reset', 'wp-reset') ?></h2>
166 <form action="" method="POST" id="wp-reset-form">
167 <p><?php _e('Please choose from the following database tables the ones you would like to reset', 'wp-reset') ?>:</p>
168 <div id="select-buttons">
169 <span><a href='#' id="select-all"><?php _e('Select All', 'wp-reset') ?></a></span>
170 <select id="wp-tables" multiple="multiple" name="tables[]" onchange="changeHandler()">
171 <?php foreach ($this->_wp_tables as $key => $value) : ?>
172 <option><?php echo $key ?></option>
173 <?php endforeach ?>
174 </select>
175 </div>
176 <p><?php _e('Type in (or copy/paste) the generated value into the text box', 'wp-reset') ?>:&nbsp;&nbsp;<strong><?php echo $random_string ?></strong></p>
177 <?php wp_nonce_field('wp-nonce-submit', $this->_nonce) ?>
178 <input type="hidden" name="wp-random-value" value="<?php echo $random_string ?>" id="wp-random-value" />
179 <input type="text" name="wp-reset-input" value="" id="wp-reset-input" />
180 <input type="submit" name="wp-reset-submit" value="<?php _e('Reset Database', 'wp-reset') ?>" id="wp-reset-submit" class="button-primary" />
181 <img src="<?php echo plugins_url('css/i/ajax-loader.gif', __FILE__) ?>" alt="loader" id="loader" style="display: none" />
182 <div id="reactivate" style="display: none">
183 <p>
184 <label for="wp-reset-check">
185 <input type="checkbox" name="wp-reset-check" id="wp-reset-check" checked="checked" value="true" />
186 <?php _e('Reactivate current plugins after reset?', 'wp-reset') ?>
187 </label>
188 </p>
189 </div>
190 </form>
191
192 <?php if ( ! $admin_user || ! user_can($admin_user->ID, 'update_core') ) : ?>
193 <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>
194 <?php else : ?>
195 <p><?php _e('The default user <strong><u>admin</u></strong> will be recreated with its current password upon resetting', 'wp-reset') ?>.</p>
196 <?php endif; ?>
197
198 <p><?php _e('Note that once you reset the database, all users will be deleted except the initial admin user.', 'wp-reset') ?></p>
199 </div>
200 <?php }
201
202 /**
203 * Add JavaScript to the bottom of the plugin page
204 *
205 * @access public
206 * @return bool TRUE on reset confirmation
207 */
208 function add_admin_javascript()
209 {
210 ?>
211 <script type="text/javascript">
212 /* <![CDATA[ */
213 jQuery(function($) {
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 /* ]]> */
243 </script>
244 <?php
245 }
246
247 /**
248 * Adds our submenu item to the Tools menu
249 *
250 * @access public
251 * @return void
252 */
253 function add_admin_menu()
254 {
255 if ( current_user_can('update_core') )
256 {
257 $this->_hook = add_submenu_page('tools.php', 'Database Reset', 'Database Reset', 'update_core', 'wp-reset', array($this, 'show_admin_page'));
258 }
259 }
260
261 /**
262 * Adds the contextual help for our plugin page
263 *
264 * @access public
265 * @param $contextual_help Hook text to display
266 * @param $screen_id ID of the current admin screen
267 * @return $contextual_help String The help text
268 */
269 function add_contextual_help($contextual_help, $screen_id)
270 {
271 if ($screen_id == $this->_hook)
272 {
273 $contextual_help = '<p>' . __('Have any cool ideas for this plugin? Contact me either by <a href="http://twitter.com/#!/chrisberthe">Twitter</a> or by <a href="https://github.com/chrisberthe">GitHub</a>.', 'wp-reset') . '</p>';
274 $contextual_help .= '<p>' . __('If this plugin becomes non-functional in any way due to WordPress upgrades, rest assured I will update it.', 'wp-reset') . '</p>';
275 $contextual_help .= '<p>' . __('Goodbye for now.', 'wp-reset') . '</p>';
276 }
277
278 return $contextual_help;
279 }
280
281 /**
282 * Adds any plugin styles to our page
283 *
284 * @access public
285 * @return void
286 */
287 function add_plugin_styles_and_scripts()
288 {
289 wp_enqueue_style('wordpress-reset-css', plugins_url('css/wp-reset.css', __FILE__));
290 wp_enqueue_style('bsmselect-css', plugins_url('css/jquery.bsmselect.css', __FILE__));
291
292 wp_enqueue_script('bsmselect', plugins_url('js/jquery.bsmselect.js', __FILE__));
293 wp_enqueue_script('bsmselect-compatibility', plugins_url('js/jquery.bsmselect.compatibility.js', __FILE__));
294 wp_enqueue_script('bsmselect-sortable', plugins_url('js/jquery.bsmselect.sortable.js', __FILE__));
295 }
296
297 /**
298 * Load language path
299 *
300 * @access public
301 * @return void
302 */
303 function init_language()
304 {
305 $language_dir = basename(dirname(__FILE__)) . '/languages';
306 load_plugin_textdomain('wp-reset', FALSE, $language_dir);
307 }
308
309 /**
310 * For activation hook
311 *
312 * @access public
313 * @return void
314 */
315 function plugin_activate()
316 {
317 add_option('wp-reset-activated', true);
318 }
319
320 /**
321 * Redirects the user after the plugin is activated
322 *
323 * @access private
324 * @return void
325 */
326 function _redirect_user()
327 {
328 if ( get_option('wp-reset-activated', false) )
329 {
330 delete_option('wp-reset-activated');
331 wp_redirect(admin_url('tools.php') . '?page=wp-reset');
332 }
333 }
334
335 /**
336 * Changes the password to a sentence rather than
337 * an auto-generated password that is sent by email
338 * right after the installation is complete
339 *
340 * @access private
341 * @return $mail Version with password changed
342 */
343 function _fix_mail($mail)
344 {
345 $subject = __('WordPress Database Reset', 'wp-reset');
346 $message = __('The tables you selected have been successfully reset to their default settings:', 'wp-reset');
347 $password = __('Password: The password you chose during the install.', 'wp-reset');
348
349 if ( stristr($mail['message'], 'Your new WordPress site has been successfully set up at:') )
350 {
351 $mail['subject'] = preg_replace('/New WordPress Site/', $subject, $mail['subject']);
352 $mail['message'] = preg_replace('/Your new WordPress site has been successfully set up at:+/', $message, $mail['message']);
353 $mail['message'] = preg_replace('/Password:\s.+/', $password, $mail['message']);
354 }
355
356 return $mail;
357 }
358
359 /**
360 * Preserves all the results from the tables the user
361 * did not select from the drop-down. Also resets these
362 * results back after reinstalling WordPress.
363 *
364 * @access private
365 * @return array Backed up data if type backup, void if reset
366 */
367 function _backup_tables($tables, $type = 'backup')
368 {
369 global $wpdb;
370
371 if ( is_array($tables) )
372 {
373 switch ($type)
374 {
375 case 'backup':
376 $backup_tables = array();
377
378 foreach ($tables as $table)
379 {
380 $backup_tables[$table] = $wpdb->get_results("SELECT * FROM " . $table);
381 }
382
383 return $backup_tables;
384 break;
385
386 case 'reset':
387 // Outer array of tables
388 foreach ($tables as $table_name => $table_data)
389 {
390 // Array of table rows
391 foreach ($table_data as $row)
392 {
393 $columns = $values = array();
394
395 // Loop through current object row
396 foreach ($row as $column => $value)
397 {
398 $columns[] = $column;
399 $values[] = $wpdb->escape($value);
400 }
401
402 $wpdb->query("INSERT INTO $table_name (" . implode(', ', $columns) . ") VALUES ('" . implode("', '", $values) . "')");
403 }
404 }
405 break;
406 }
407 }
408
409 return;
410 }
411
412 /**
413 * Updates the user password and clears / sets
414 * the authentication cookie for the user
415 *
416 * @access private
417 * @param $user Current or admin user
418 * @param $keys Array returned by wp_install()
419 * @return TRUE on install success, FALSE otherwise
420 */
421 function _wp_update_user($user, $keys)
422 {
423 global $wpdb;
424 extract($keys, EXTR_SKIP);
425
426 // Set the old password back to the user
427 $query = $wpdb->prepare("UPDATE $wpdb->users SET user_pass = '%s', user_activation_key = '' WHERE ID = '%d'", $user->user_pass, $user_id);
428
429 if ( $wpdb->query($query) )
430 {
431 // Delete the default_password_nag
432 // so it doesn't pop up with the password reminder after installing
433 if ( get_user_meta($user_id, 'default_password_nag') ) delete_user_meta($user_id, 'default_password_nag');
434
435 wp_clear_auth_cookie();
436 wp_set_auth_cookie($user_id);
437
438 return TRUE;
439 }
440
441 return FALSE;
442 }
443
444 /**
445 * Generates a random value for our input box
446 *
447 * @access private
448 * @param $length Length of the random string value
449 * @return $random_string
450 */
451 function _rand_string($length = 5)
452 {
453 $random_string = '';
454 $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
455 $size = strlen($chars);
456
457 for ($i = 0; $i < $length; $i++)
458 {
459 $random_string .= $chars[rand(0, $size-1)];
460 }
461
462 return $random_string;
463 }
464
465 }
466
467 $cb_wp_reset = new cb_wp_reset();
468
469 register_activation_hook( __FILE__, array('cb_wp_reset', 'plugin_activate') );
470
471 endif;