PluginProbe
WP Reset / 1.20
WP Reset v1.20
trunk 1.0 1.1 1.11 1.20 1.25 1.30 1.35 1.40 1.45 1.50 1.55 1.60 1.65 1.70 1.75 1.77 1.80 1.81 1.82 1.83 1.84 1.85 1.86 1.90 All 42 releases
wp-reset / wp-reset.php

wp-reset.php in WP Reset 1.20, at wp-reset.php

653 lines 24.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 Plugin Name: WP Reset
4 Plugin URI: https://wpreset.com/
5 Description: Reset the site to default installation values without modifying any files. Deletes all customizations and content.
6 Version: 1.20
7 Author: WebFactory Ltd
8 Author URI: https://www.webfactoryltd.com/
9 Text Domain: wp-reset
10
11 Copyright 2015 - 2018 Web factory Ltd (email: wpreset@webfactoryltd.com)
12
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License, version 2, as
15 published by the Free Software Foundation.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 */
26
27 // include only file
28 if (!defined('ABSPATH')) {
29 wp_die(__('Do not open this file directly.', 'wp-error'));
30 }
31
32
33 // load WP-CLI commands, if needed
34 if (defined('WP_CLI') && WP_CLI) {
35 require_once dirname( __FILE__ ) . '/wp-reset-cli.php';
36 }
37
38
39 class WP_Reset {
40 protected static $instance = null;
41 public $version = 0;
42 public $plugin_url = '';
43 public $plugin_dir = '';
44 protected $options = array();
45
46
47 /**
48 * Creates a new WP_Reset object and implements singleton
49 *
50 * @return WP_Reset
51 */
52 static function getInstance() {
53 if (!is_a(self::$instance, 'WP_Reset')) {
54 self::$instance = new WP_Reset();
55 }
56
57 return self::$instance;
58 } // getInstance
59
60
61 /**
62 * Initialize properties, hook to filters and actions
63 *
64 * @return null
65 */
66 private function __construct() {
67 $this->version = $this->get_plugin_version();
68 $this->plugin_dir = plugin_dir_path(__FILE__);
69 $this->plugin_url = plugin_dir_url(__FILE__);
70 $this->load_options();
71
72 add_action('admin_menu', array($this, 'admin_menu'));
73 add_action('admin_init', array($this, 'do_all_actions'));
74 add_action('admin_enqueue_scripts', array($this, 'admin_enqueue_scripts'));
75 add_action('wp_ajax_wp_reset_dismiss_notice', array($this, 'ajax_dismiss_notice'));
76
77 add_filter('plugin_action_links_' . plugin_basename(__FILE__), array($this, 'plugin_action_links'));
78 add_filter('plugin_row_meta', array($this, 'plugin_meta_links'), 10, 2);
79 add_filter('admin_footer_text', array($this, 'admin_footer_text'));
80 } // __construct
81
82
83 /**
84 * Get plugin version from file header
85 *
86 * @return string
87 */
88 function get_plugin_version() {
89 $plugin_data = get_file_data(__FILE__, array('version' => 'Version'), 'plugin');
90
91 return $plugin_data['version'];
92 } // get_plugin_version
93
94
95 /**
96 * Load and prepare the options array
97 * If needed create a new DB entry
98 *
99 * @return array
100 */
101 private function load_options() {
102 $options = get_option('wp-reset', array());
103 $change = false;
104
105 if (!isset($options['meta'])) {
106 $options['meta'] = array('first_version' => $this->version, 'first_install' => current_time('timestamp', true), 'reset_count' => 0);
107 $change = true;
108 }
109 if (!isset($options['dismissed_notices'])) {
110 $options['dismissed_notices'] = array();
111 $change = true;
112 }
113 if (!isset($options['last_run'])) {
114 $options['last_run'] = array();
115 $change = true;
116 }
117 if (!isset($options['options'])) {
118 $options['options'] = array();
119 $change = true;
120 }
121 if ($change) {
122 update_option('wp-reset', $options, true);
123 }
124
125 $this->options = $options;
126 return $options;
127 } // load_options
128
129
130 /**
131 * Get meta part of plugin options
132 *
133 * @return array
134 */
135 function get_meta() {
136 return $this->options['meta'];
137 } // get_meta
138
139
140 /**
141 * Get all dismissed notices, or check for one specific notice
142 *
143 * @return bool|array
144 */
145 function get_dismissed_notices($notice_name = '') {
146 $notices = $this->options['dismissed_notices'];
147
148 if (empty($notice_name)) {
149 return $notices;
150 } else {
151 if (empty($notices[$notice_name])) {
152 return false;
153 } else {
154 return true;
155 }
156 }
157 } // get_dismissed_notices
158
159
160 /**
161 * Get options part of plugin options
162 *
163 * todo: not completed
164 *
165 * @return array
166 */
167 function get_options($key = '') {
168 return $this->options['options'];
169 } // get_options
170
171
172 /**
173 * Update plugin options, currently entire array
174 *
175 * todo: this handles the entire options array although it should only do the options part - it's confusing
176 *
177 * @return bool
178 */
179 function update_options($key, $data) {
180 $this->options[$key] = $data;
181 $tmp = update_option('wp-reset', $this->options);
182
183 return $tmp;
184 } // set_options
185
186
187 /**
188 * Add plugin menu entry under Tools menu
189 *
190 * @return null
191 */
192 function admin_menu() {
193 add_management_page(__('WP Reset', 'wp-reset'), __('WP Reset', 'wp-reset'), 'administrator', 'wp-reset', array($this, 'plugin_page'));
194 } // admin_menu
195
196
197 /**
198 * Dismiss notice via AJAX call
199 *
200 * @return null
201 */
202 function ajax_dismiss_notice() {
203 check_ajax_referer('wp-reset_dismiss_notice');
204
205 $notice_name = trim(@$_GET['notice_name']);
206 if (!$this->dismiss_notice($notice_name)) {
207 wp_send_json_error('Notice is already dismissed.');
208 } else {
209 wp_send_json_success();
210 }
211 } // ajax_dismiss_notice
212
213
214 /**
215 * Dismiss notice by adding it to dismissed_notices options array
216 *
217 * @return bool
218 */
219 function dismiss_notice($notice_name) {
220 if ($this->get_dismissed_notices($notice_name)) {
221 return false;
222 } else {
223 $notices = $this->get_dismissed_notices();
224 $notices[$notice_name] = true;
225 $this->update_options('dismissed_notices', $notices);
226 return true;
227 }
228 } // dismiss_notice
229
230
231 /**
232 * Enqueue CSS and JS files
233 *
234 * @return null
235 */
236 function admin_enqueue_scripts($hook) {
237 // exit early if not on WP Reset page
238 if ('tools_page_wp-reset' != $hook) {
239 return;
240 }
241
242 $options = $this->get_options();
243
244 $js_localize = array('undocumented_error' => __('An undocumented error has occured. Please refresh the page and try again.', 'wp-reset'),
245 'plugin_name' => __('WP Reset', 'wp-reset'),
246 'settings_url' => admin_url('tools.php?page=wp-reset'),
247 'icon_url' => $this->plugin_url . 'img/wp-reset-icon.png',
248 'invalid_confirmation' => __('Please type "reset" in the confirmation field.', 'wp-reset'),
249 'invalid_confirmation_title' => __('Invalid confirmation', 'wp-reset'),
250 'cancel_button' => __('Cancel', 'wp-reset'),
251 'ok_button' => __('OK', 'wp-reset'),
252 'confirm_button' => __('Reset WordPress', 'wp-reset'),
253 'confirm_title' => __('Are you sure you want to proceed?', 'wp-reset'),
254 'confirm1' => __('Clicking "Reset WordPress" will reset your site to default values. All content will be lost. There is NO UNDO.', 'wp-reset'),
255 'confirm2' => __('Click "Cancel" to abort.', 'wp-reset'),
256 'doing_reset' => __('Resetting in progress. Please wait.', 'wp-reset'),
257 'nonce_dismiss_notice' => wp_create_nonce('wp-reset_dismiss_notice'),
258 'nonce_do_reset' => wp_create_nonce('wp-reset_do_reset'));
259
260 wp_enqueue_style('wp-reset', $this->plugin_url . 'css/wp-reset.css', array(), $this->version);
261 wp_enqueue_style('wp-reset-sweetalert2', $this->plugin_url . 'css/sweetalert2.min.css', array(), $this->version);
262
263 wp_enqueue_script('wp-reset-sweetalert2', $this->plugin_url . 'js/sweetalert2.min.js', array('jquery'), $this->version, true);
264 wp_enqueue_script('wp-reset', $this->plugin_url . 'js/wp-reset.js', array('jquery'), $this->version, true);
265 wp_localize_script('wp-reset', 'wp_reset', $js_localize);
266
267 // fix for agressive plugins that include their CSS on all pages
268 wp_dequeue_style('uiStyleSheet');
269 wp_dequeue_style('wpcufpnAdmin' );
270 wp_dequeue_style('unifStyleSheet' );
271 wp_dequeue_style('wpcufpn_codemirror');
272 wp_dequeue_style('wpcufpn_codemirrorTheme');
273 wp_dequeue_style('collapse-admin-css');
274 wp_dequeue_style('jquery-ui-css');
275 wp_dequeue_style('tribe-common-admin');
276 wp_dequeue_style('file-manager__jquery-ui-css');
277 wp_dequeue_style('file-manager__jquery-ui-css-theme');
278 wp_dequeue_style('wpmegmaps-jqueryui');
279 wp_dequeue_style('wp-botwatch-css');
280 } // admin_enqueue_scripts
281
282
283 function is_cli_running() {
284 if (defined('WP_CLI') && WP_CLI) {
285 return true;
286 } else {
287 return false;
288 }
289 } // is_cli_running
290
291
292 /**
293 * Reinstall / reset the WP site
294 * There are no failsafes in the function - it reinstalls when called
295 * Redirects when done
296 *
297 * @return null
298 */
299 function do_reinstall($params = array()) {
300 global $current_user, $wpdb;
301
302 // only admins can reset; double-check
303 if (!$this->is_cli_running() && !current_user_can('administrator')) {
304 return false;
305 }
306
307 // make sure the function is available to us
308 if (!function_exists('wp_install')) {
309 require ABSPATH . '/wp-admin/includes/upgrade.php';
310 }
311
312 // save values that need to be restored after reset
313 // todo: use params to determine what gets restored after reset
314 $blogname = get_option('blogname');
315 $blog_public = get_option('blog_public');
316 $wplang = get_option('wplang');
317 $siteurl = get_option('siteurl');
318 $home = get_option('home');
319
320 // for WP-CLI
321 if (!$current_user->ID) {
322 $tmp = get_users(array('role' => 'administrator', 'order' => 'ASC', 'order_by' => 'ID'));
323 if (empty($tmp[0]->user_login)) {
324 return new WP_Error('no_user', 'Reset failed. Unable to find any admin users in database.');
325 }
326 $current_user = $tmp[0];
327 }
328
329 // delete custom tables with WP's prefix
330 $prefix = str_replace('_', '\_', $wpdb->prefix);
331 $tables = $wpdb->get_col("SHOW TABLES LIKE '{$prefix}%'");
332 foreach ($tables as $table) {
333 $wpdb->query("DROP TABLE $table");
334 }
335
336 // supress errors for WP_CLI
337 // todo: do something better
338 $result = @wp_install($blogname, $current_user->user_login, $current_user->user_email, $blog_public, '', md5(rand()), $wplang);
339 $user_id = $result['user_id'];
340
341 // restore user pass
342 $query = $wpdb->prepare("UPDATE {$wpdb->users} SET user_pass = %s, user_activation_key = '' WHERE ID = %d LIMIT 1", array($current_user->user_pass, $user_id));
343 $wpdb->query($query);
344
345 // restore rest of the settings including WP Reset's
346 update_option('siteurl', $siteurl);
347 update_option('home', $home);
348 update_option('wp-reset', $this->options);
349
350 // remove password nag
351 if (get_user_meta($user_id, 'default_password_nag')) {
352 update_user_meta($user_id, 'default_password_nag', false);
353 }
354 if (get_user_meta($user_id, $wpdb->prefix . 'default_password_nag')) {
355 update_user_meta($user_id, $wpdb->prefix . 'default_password_nag', false );
356 }
357
358 $meta = $this->get_meta();
359 $meta['reset_count']++;
360 $this->update_options('meta', $meta);
361
362 // reactivate WP Reset
363 // todo: legacy constant - if nobody complains the constant will be replaced by options
364 if (!defined('REACTIVATE_THE_WP_RESET') || REACTIVATE_THE_WP_RESET !== false) {
365 activate_plugin(plugin_basename( __FILE__ ));
366 }
367
368 if (!$this->is_cli_running()) {
369 // log out and log in the old/new user
370 // since the password doesn't change this is potentially unnecessary
371 wp_clear_auth_cookie();
372 wp_set_auth_cookie($user_id);
373
374 wp_redirect(admin_url() . '?wp-reset=success');
375 exit;
376 }
377 } // do_reinstall
378
379
380 /**
381 * checks wp_reset post value and performs all actions
382 * todo: handle messages for various actions
383 */
384 function do_all_actions() {
385 // only admins can perform actions
386 if (!current_user_can('administrator')) {
387 return;
388 }
389
390 if (!empty($_GET['wp-reset']) && stristr($_SERVER['HTTP_REFERER'], 'wp-reset')) {
391 add_action('admin_notices', array($this, 'notice_successfull_reset'));
392 }
393
394 // check nonce
395 if (true === isset($_POST['wp_reset_confirm']) && false === wp_verify_nonce(@$_POST['_wpnonce'], 'wp-reset')) {
396 add_settings_error('wp-reset', 'bad-nonce', __('Something went wrong. Please refresh the page and try again.', 'wp-reset'), 'error');
397 return false;
398 }
399
400 // check confirmation code
401 if (true === isset($_POST['wp_reset_confirm']) && 'reset' !== $_POST['wp_reset_confirm']) {
402 add_settings_error('wp-reset', 'bad-confirm', __('<b>Invalid confirmation code.</b> Please type "reset" in the confirmation field.', 'wp-reset'), 'error');
403 return false;
404 }
405
406 // only one action at the moment
407 // todo: check action name
408 if (true === isset($_POST['wp_reset_confirm']) && 'reset' === $_POST['wp_reset_confirm']) {
409 $this->do_reinstall();
410 }
411 } // do_reset
412
413
414 /**
415 * Add "Reset WordPress" action link to plugins table, left part
416 *
417 * @return array
418 */
419 function plugin_action_links($links) {
420 $settings_link = '<a href="' . admin_url('tools.php?page=wp-reset') . '" title="' . __('Reset WordPress', 'wp-reset') . '">' . __('Reset WordPress', 'wp-reset') . '</a>';
421
422 array_unshift($links, $settings_link);
423
424 return $links;
425 } // plugin_action_links
426
427
428 /**
429 * Add links to plugin's description in plugins table
430 *
431 * @return array
432 */
433 function plugin_meta_links($links, $file) {
434 if ($file !== plugin_basename(__FILE__)) {
435 return $links;
436 }
437
438 $support_link = '<a target="_blank" href="https://wordpress.org/support/plugin/wp-reset" title="' . __('Get help', 'wp-reset') . '">' . __('Support', 'wp-reset') . '</a>';
439 $home_link = '<a target="_blank" href="' . $this->generate_web_link('plugins-table-right') . '" title="' . __('Plugin Homepage', 'wp-reset') . '">' . __('Plugin Homepage', 'wp-reset') . '</a>';
440
441 $links[] = $support_link;
442 $links[] = $home_link;
443
444 return $links;
445 } // plugin_meta_links
446
447
448 /**
449 * Test if we're on plugin's admin page
450 *
451 * @return bool
452 */
453 function is_plugin_page() {
454 $current_screen = get_current_screen();
455
456 if ($current_screen->id == 'tools_page_wp-reset') {
457 return true;
458 } else {
459 return false;
460 }
461 } // is_plugin_page
462
463
464 /**
465 * Add powered by text in admin footer
466 *
467 * @return bool
468 */
469 function admin_footer_text($text) {
470 if (!$this->is_plugin_page()) {
471 return $text;
472 }
473
474 $text = '<i><a href="' . $this->generate_web_link('admin_footer') . '" title="' . __('Visit WP Reset page for more info', 'wp-reset') . '" target="_blank">WP Reset</a> v' . $this->version . ' by <a href="https://www.webfactoryltd.com/" title="' . __('Visit our site to get more great plugins', 'wp-reset'). '" target="_blank">WebFactory Ltd</a>.</i> '. $text;
475
476 return $text;
477 } // admin_footer_text
478
479
480 /**
481 * Loads a plugin's translated strings
482 *
483 * @return null
484 */
485 function load_textdomain() {
486 load_plugin_textdomain('wp-reset');
487 } // load_textdomain
488
489
490 /**
491 * Inform the user that WordPress has been successfully reset
492 *
493 * @return null
494 */
495 function notice_successfull_reset() {
496 global $current_user;
497
498 echo '<div id="message" class="updated fade"><p>' . sprintf(__( '<b>Site has been reset</b> to default settings. User "%s" was restored with the password unchanged. Open <a href="%s">WP Reset</a> to do another reset.', 'wp-reset'), $current_user->user_login, admin_url('tools.php?page=wp-reset')) . '</p></div>';
499 } // notice_successfull_reset
500
501
502 /**
503 * Outputs complete plugin's admin page
504 *
505 * @return null
506 */
507 function plugin_page() {
508 global $current_user, $wpdb;
509 $notice_shown = false;
510 $meta = $this->get_meta();
511
512 // double check for admin priv
513 if (!current_user_can('administrator')) {
514 wp_die(__('Sorry, you are not allowed to access this page.', 'wp-reset'));
515 }
516
517 settings_errors();
518 echo '<div class="wrap">';
519 echo '<h1><img id="logo-icon" src="' . $this->plugin_url . 'img/wp-reset-logo.png" title="' . __('WP Reset', 'wp-reset') . '" alt="' . __('WP Reset', 'wp-reset') . '"></h1>';
520
521 if (!empty($meta['reset_count']) && false === $notice_shown && false == $this->get_dismissed_notices('rate')) {
522 echo '<div class="card notice-wrapper">';
523 echo '<h2>' . __('Please help us keep the plugin maintained, free &amp; supported', 'wp-reset') . '</h2>';
524 echo '<p>' . __('If you use &amp; enjoy WP Reset, <b>please rate it on WordPress.org</b>. It only takes a second and helps us keep the plugin free and maintained. Thank you!', 'wp-reset') . '</p>';
525 echo '<p><a class="button-primary button" title="' . __('Rate WP Reset', 'wp-reset') . '" target="_blank" href="https://wordpress.org/support/plugin/wp-reset/reviews/#new-post">' . __('Help keep the plugin free - rate it!', 'wp-reset') . '</a> <a href="#" class="wpr-dismiss-notice dismiss-notice-rate" data-notice="rate">' . __('I\'ve already rated it', 'wp-reset') . '</a></p>';
526 echo '</div>';
527 $notice_shown = true;
528 }
529
530 // todo: finish up
531 if (false && false === $notice_shown && false == $this->get_dismissed_notices('tidy')) {
532 echo '<div class="card notice-wrapper">';
533 echo '<h2>' . __('Are you a plugin author? Get your plugin reviewed on Tiny Repo', 'wp-reset') . '</h2>';
534 echo '<p>' . __('If you use &amp; enjoy WP Reset, <b>please rate it on WordPress.org</b>. It only takes a second and helps us keep the plugin free and maintained. Thank you!', 'wp-reset') . '</p>';
535 echo '<p><a class="button-primary button" title="' . __('Rate WP Reset', 'wp-reset') . '" target="_blank" href="https://tidyrepo.com/suggest-plugin/?utm-campaing=wp-reset&utm-medium=banner">' . __('Let Tidy Repo know you have a great plugin', 'wp-reset') . '</a> <a href="#" class="wpr-dismiss-notice dismiss-notice-rate" data-notice="tidy">' . __('Thanks, I\'m not interested', 'wp-reset') . '</a></p>';
536 echo '</div>';
537 $notice_shown = true;
538 }
539
540 echo '<div class="card">';
541 echo '<h2>' . __('Please read carefully before proceeding. There is NO UNDO!', 'wp-reset') . '</h2>';
542 echo '<b class="red">' . __('Resetting will delete:', 'wp-reset') . '</b>';
543 echo '<ul class="plain-list">';
544 echo '<li>' . __('all posts, pages, custom post types, comments, media entries, users', 'wp-reset') . '</li>';
545 echo '<li>' . __('all default WP database tables', 'wp-reset') . '</li>';
546 echo '<li>' . sprintf(__('all custom database tables that have the same prefix "%s" as default tables in this installation', 'wp-reset'), $wpdb->prefix) . '</li>';
547 echo '</ul>';
548
549 echo '<b class="green">' . __('Resetting will not delete:', 'wp-reset') . '</b>';
550 echo '<ul class="plain-list">';
551 echo '<li>' . __('media files - they\'ll remain in the <i>wp-uploads</i> folder but will no longer be listed under Media', 'wp-reset') . '</li>';
552 echo '<li>' . __('no files are touched; plugins, themes, uploads - everything stays', 'wp-reset') . '</li>';
553 echo '<li>' . __('site title, WordPress address, site address, site language and search engine visibility settings', 'wp-reset') . '</li>';
554 echo '<li>' . sprintf(__('logged in user "%s" will be restored with the current password', 'wp-reset'), $current_user->user_login) . '</li>';
555 echo '</ul>';
556
557 echo '<b>' . __('What happens when I click the Reset button?', 'wp-reset') . '</b>';
558 echo '<ul class="plain-list">';
559 echo '<li>' . __('you will have to confirm the action one more time because there is NO UNDO', 'wp-reset') . '</li>';
560 echo '<li>' . __('everything will be reset; see bullets above for details', 'wp-reset') . '</li>';
561 echo '<li>' . __('site title, WordPress address, site address, site language, search engine visibility and current user will be restored', 'wp-reset') . '</li>';
562 echo '<li>' . __('you will be logged out, automatically logged in and taken to the admin dashboard', 'wp-reset') . '</li>';
563 echo '<li>' . __('WP Reset plugin will be reactivated', 'wp-reset') . '</li>';
564 echo '</ul>';
565
566 echo '<b>' . __('WP-CLI Support', 'wp-reset') . '</b>';
567 echo '<p>' . sprintf(__('All features available via GUI are available in WP-CLI as well. To get the list of commands run %s. Instead of the active user, the first user with admin privileges found in the database will be restored.', 'wp-reset'), '<code>wp help reset</code>');
568 echo sprintf(__('All actions have to be confirmed. If you want to skip confirmation use the standard %s option. Please be carefull - there is NO UNDO.', 'wp-reset'), '<code>--yes</code>') . '</p>';
569 echo '</div>';
570
571 echo '<div class="card">';
572 echo '<h2>' . __('Reset', 'wp-reset') . '</h2>';
573 echo '<p>' . __('Type <b>reset</b> in the confirmation field to confirm the reset and then click the "Reset WordPress" button. <b>There is NO UNDO. No backups are made by this plugin.</b>', 'wp-reset') . '</p>';
574 echo '<p>' . sprintf(__('While doing work on your site we recommend installing the free <a href="%s" target="_blank">UnderConstructionPage</a> plugin. It helps with SEO and builds trust with visitors.', 'wp-reset'), 'https://wordpress.org/plugins/under-construction-page/') . '</p>';
575 echo '<form id="wp_reset_form" action="' . admin_url('tools.php?page=wp-reset') . '" method="post" autocomplete="off">';
576 wp_nonce_field('wp-reset');
577 echo '<input id="wp_reset_confirm" type="text" name="wp_reset_confirm" placeholder="' . esc_attr__('Type in "reset"', 'wp-reset'). '" value="" autocomplete="off"> &nbsp;';
578 echo '<input id="wp_reset_submit" type="button" class="button-primary" value="' . __('Reset WordPress', 'wp-reset') . '">';
579 echo '</form>';
580 echo '</div>';
581
582 echo '</div>'; // wrap
583 } // plugin_page
584
585
586 /**
587 * Helper function for generating UTM tagged links
588 *
589 * @return string
590 */
591 function generate_web_link($placement = '', $page = '/', $params = array(), $anchor = '') {
592 $base_url = 'https://wpreset.com';
593
594 if ('/' != $page) {
595 $page = '/' . trim($page, '/') . '/';
596 }
597 if ($page == '//') {
598 $page = '/';
599 }
600
601 $parts = array_merge(array('utm_source' => 'wp-reset-free', 'utm_medium' => 'plugin', 'utm_content' => $placement, 'utm_campaign' => 'wp-reset-free-v' . $this->version), $params);
602
603 if (!empty($anchor)) {
604 $anchor = '#' . trim($anchor, '#');
605 }
606
607 $out = $base_url . $page . '?' . http_build_query($parts, '', '&amp;') . $anchor;
608
609 return $out;
610 } // generate_web_link
611
612
613 /**
614 * Clean up on uninstall; no action on deactive at the moment
615 *
616 * @return null
617 */
618 static function uninstall() {
619 delete_option('wp-reset');
620 } // uninstall
621
622
623 /**
624 * Disabled; we use singleton pattern so magic functions need to be disabled
625 *
626 * @return null
627 */
628 private function __clone() {}
629
630
631 /**
632 * Disabled; we use singleton pattern so magic functions need to be disabled
633 *
634 * @return null
635 */
636 private function __sleep() {}
637
638
639 /**
640 * Disabled; we use singleton pattern so magic functions need to be disabled
641 *
642 * @return null
643 */
644 private function __wakeup() {}
645 } // WP_Reset class
646
647
648 // Create plugin instance and hook things up
649 global $wp_reset;
650 $wp_reset = WP_Reset::getInstance();
651 add_action('plugins_loaded', array($wp_reset, 'load_textdomain'));
652 register_uninstall_hook(__FILE__, array('WP_Reset', 'uninstall'));
653