WP Reset – Fastest WordPress Reset Plugin - Version 1.55

Version Description

Download this release

Release Info

Developer WebFactory
Plugin Icon 128x128 WP Reset – Fastest WordPress Reset Plugin
Version 1.55
Comparing to
See all releases

Code changes from version 1.50 to 1.55

Files changed (5) hide show
  1. css/wp-reset.css +196 -51
  2. js/wp-reset.js +305 -125
  3. readme.txt +17 -5
  4. wp-reset-cli.php +183 -172
  5. wp-reset.php +538 -169
css/wp-reset.css CHANGED
@@ -30,10 +30,10 @@
30
  }
31
 
32
  .tools_page_wp-reset .plain-list {
33
- margin-top: 5px;
34
- list-style-type: circle;
35
- list-style-position: inside;
36
- }
37
 
38
  .tools_page_wp-reset .plain-list li {
39
  text-indent: -18px;
@@ -73,7 +73,7 @@
73
  }
74
 
75
  .tools_page_wp-reset .swal2-container.swal2-shown {
76
- background-color: rgba(0,0,0,.6);
77
  }
78
 
79
  .tools_page_wp-reset .swal2-popup .swal2-title {
@@ -93,9 +93,9 @@
93
  }
94
 
95
  .tools_page_wp-reset .rotating {
96
- -webkit-animation:spin 1.5s linear infinite;
97
- -moz-animation:spin 1.5s linear infinite;
98
- animation:spin 1.5s linear infinite;
99
  }
100
 
101
  .tools_page_wp-reset .notice-error {
@@ -236,11 +236,11 @@
236
  }
237
 
238
  .wpr-table-container .wpr-table-difference td {
239
- background-color: rgba(255, 166, 0, 0.30);
240
  }
241
 
242
  .wpr-table-container .wpr-table-match td {
243
- background-color: rgba(9, 255, 0, 0.30);
244
  }
245
 
246
  .wpr-table-container table.table_diff tr td {
@@ -256,7 +256,6 @@
256
  width: 100%;
257
  }
258
 
259
-
260
  @-moz-keyframes spin {
261
  100% {
262
  -moz-transform: rotate(-360deg);
@@ -269,11 +268,11 @@
269
  }
270
  @keyframes spin {
271
  100% {
272
- -webkit-transform: rotate(-360deg); transform:rotate(-360deg);
 
273
  }
274
  }
275
 
276
-
277
  /* tabs */
278
  .tools_page_wp-reset .ui-tabs {
279
  max-width: 100%;
@@ -292,7 +291,7 @@
292
  list-style: none;
293
  position: relative;
294
  top: 1px;
295
- margin: 0 .2em 1px 0;
296
  padding: 0;
297
  white-space: nowrap;
298
  }
@@ -303,7 +302,7 @@
303
 
304
  .tools_page_wp-reset .ui-tabs .ui-tabs-nav li.ui-tabs-selected {
305
  margin-bottom: 0;
306
- border-bottom: 1px solid #F1F1F1 !important;
307
  }
308
 
309
  .tools_page_wp-reset ul.ui-tabs-nav.wpr-main-tab li.ui-state-active {
@@ -324,7 +323,6 @@
324
  cursor: pointer;
325
  }
326
 
327
-
328
  .tools_page_wp-reset .ui-tabs .ui-tabs-panel {
329
  display: inline-block;
330
  border: none;
@@ -343,7 +341,7 @@
343
  font-size: 14px;
344
  font-weight: 600;
345
  line-height: 32px;
346
- color: #AAAAAA;
347
  padding: 5px 10px;
348
  display: block;
349
  letter-spacing: 1px;
@@ -365,7 +363,7 @@
365
  }
366
 
367
  .tools_page_wp-reset .ui-tabs ul.ui-tabs-nav li {
368
- color: #AAAAAA;
369
  display: inline-block;
370
  font-size: 12px;
371
  line-height: 16px;
@@ -375,7 +373,7 @@
375
  background: rgba(255, 255, 255, 0.7);
376
  padding: 0;
377
  text-align: center;
378
- letter-spacing: .5px;
379
  min-width: 100px;
380
  border-top: 3px solid transparent;
381
  border-bottom: 1px solid #e5e5e5;
@@ -417,89 +415,236 @@
417
  /* diff */
418
 
419
  .Differences {
420
- width: 100%;
421
- border-collapse: collapse;
422
- border-spacing: 0;
423
- empty-cells: show;
424
  }
425
 
426
  .Differences thead th {
427
- text-align: left;
428
- border-bottom: 1px solid #000;
429
- background: #aaa;
430
- color: #000;
431
- padding: 4px;
432
  }
433
  .Differences tbody th {
434
- text-align: right;
435
- background: #ccc;
436
- width: 4em;
437
- padding: 1px 2px;
438
  border-right: 1px solid #00000080;
439
  border-bottom: none;
440
- vertical-align: middle;
441
  font-size: 13px;
442
  font-weight: 400;
443
  }
444
 
445
  .Differences td {
446
- padding: 5px !important;
447
- font-family: Consolas, monospace;
448
- font-size: 13px;
449
  }
450
 
451
  .DifferencesSideBySide .ChangeInsert td.Left {
452
- background: #dfd;
453
  }
454
 
455
  .DifferencesSideBySide .ChangeInsert td.Right {
456
- background: #cfc;
457
  }
458
 
459
  .DifferencesSideBySide .ChangeDelete td.Left {
460
- background: #f88;
461
  }
462
 
463
  .DifferencesSideBySide .ChangeDelete td.Right {
464
- background: #faa;
465
  }
466
 
467
  .DifferencesSideBySide .ChangeReplace .Left {
468
- background: #fe9;
469
  }
470
 
471
  .DifferencesSideBySide .ChangeReplace .Right {
472
- background: #fd8;
473
  }
474
 
475
- .Differences ins, .Differences del {
476
- text-decoration: none;
 
477
  }
478
 
479
- .DifferencesSideBySide .ChangeReplace ins, .DifferencesSideBySide .ChangeReplace del {
480
- background: #fc0;
 
481
  }
482
 
483
  .Differences .Skipped {
484
- background: #f7f7f7;
485
  }
486
 
487
  .DifferencesInline .ChangeReplace .Left,
488
  .DifferencesInline .ChangeDelete .Left {
489
- background: #fdd;
490
  }
491
 
492
  .DifferencesInline .ChangeReplace .Right,
493
  .DifferencesInline .ChangeInsert .Right {
494
- background: #dfd;
495
  }
496
 
497
  .DifferencesInline .ChangeReplace ins {
498
- background: #9e9;
499
  }
500
 
501
  .DifferencesInline .ChangeReplace del {
502
- background: #e99;
503
  }
504
 
505
  /* diff */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  }
31
 
32
  .tools_page_wp-reset .plain-list {
33
+ margin-top: 5px;
34
+ list-style-type: circle;
35
+ list-style-position: inside;
36
+ }
37
 
38
  .tools_page_wp-reset .plain-list li {
39
  text-indent: -18px;
73
  }
74
 
75
  .tools_page_wp-reset .swal2-container.swal2-shown {
76
+ background-color: rgba(0, 0, 0, 0.6);
77
  }
78
 
79
  .tools_page_wp-reset .swal2-popup .swal2-title {
93
  }
94
 
95
  .tools_page_wp-reset .rotating {
96
+ -webkit-animation: spin 1.5s linear infinite;
97
+ -moz-animation: spin 1.5s linear infinite;
98
+ animation: spin 1.5s linear infinite;
99
  }
100
 
101
  .tools_page_wp-reset .notice-error {
236
  }
237
 
238
  .wpr-table-container .wpr-table-difference td {
239
+ background-color: rgba(255, 166, 0, 0.3);
240
  }
241
 
242
  .wpr-table-container .wpr-table-match td {
243
+ background-color: rgba(9, 255, 0, 0.3);
244
  }
245
 
246
  .wpr-table-container table.table_diff tr td {
256
  width: 100%;
257
  }
258
 
 
259
  @-moz-keyframes spin {
260
  100% {
261
  -moz-transform: rotate(-360deg);
268
  }
269
  @keyframes spin {
270
  100% {
271
+ -webkit-transform: rotate(-360deg);
272
+ transform: rotate(-360deg);
273
  }
274
  }
275
 
 
276
  /* tabs */
277
  .tools_page_wp-reset .ui-tabs {
278
  max-width: 100%;
291
  list-style: none;
292
  position: relative;
293
  top: 1px;
294
+ margin: 0 0.2em 1px 0;
295
  padding: 0;
296
  white-space: nowrap;
297
  }
302
 
303
  .tools_page_wp-reset .ui-tabs .ui-tabs-nav li.ui-tabs-selected {
304
  margin-bottom: 0;
305
+ border-bottom: 1px solid #f1f1f1 !important;
306
  }
307
 
308
  .tools_page_wp-reset ul.ui-tabs-nav.wpr-main-tab li.ui-state-active {
323
  cursor: pointer;
324
  }
325
 
 
326
  .tools_page_wp-reset .ui-tabs .ui-tabs-panel {
327
  display: inline-block;
328
  border: none;
341
  font-size: 14px;
342
  font-weight: 600;
343
  line-height: 32px;
344
+ color: #aaaaaa;
345
  padding: 5px 10px;
346
  display: block;
347
  letter-spacing: 1px;
363
  }
364
 
365
  .tools_page_wp-reset .ui-tabs ul.ui-tabs-nav li {
366
+ color: #aaaaaa;
367
  display: inline-block;
368
  font-size: 12px;
369
  line-height: 16px;
373
  background: rgba(255, 255, 255, 0.7);
374
  padding: 0;
375
  text-align: center;
376
+ letter-spacing: 0.5px;
377
  min-width: 100px;
378
  border-top: 3px solid transparent;
379
  border-bottom: 1px solid #e5e5e5;
415
  /* diff */
416
 
417
  .Differences {
418
+ width: 100%;
419
+ border-collapse: collapse;
420
+ border-spacing: 0;
421
+ empty-cells: show;
422
  }
423
 
424
  .Differences thead th {
425
+ text-align: left;
426
+ border-bottom: 1px solid #000;
427
+ background: #aaa;
428
+ color: #000;
429
+ padding: 4px;
430
  }
431
  .Differences tbody th {
432
+ text-align: right;
433
+ background: #ccc;
434
+ width: 4em;
435
+ padding: 1px 2px;
436
  border-right: 1px solid #00000080;
437
  border-bottom: none;
438
+ vertical-align: middle;
439
  font-size: 13px;
440
  font-weight: 400;
441
  }
442
 
443
  .Differences td {
444
+ padding: 5px !important;
445
+ font-family: Consolas, monospace;
446
+ font-size: 13px;
447
  }
448
 
449
  .DifferencesSideBySide .ChangeInsert td.Left {
450
+ background: #dfd;
451
  }
452
 
453
  .DifferencesSideBySide .ChangeInsert td.Right {
454
+ background: #cfc;
455
  }
456
 
457
  .DifferencesSideBySide .ChangeDelete td.Left {
458
+ background: #f88;
459
  }
460
 
461
  .DifferencesSideBySide .ChangeDelete td.Right {
462
+ background: #faa;
463
  }
464
 
465
  .DifferencesSideBySide .ChangeReplace .Left {
466
+ background: #fe9;
467
  }
468
 
469
  .DifferencesSideBySide .ChangeReplace .Right {
470
+ background: #fd8;
471
  }
472
 
473
+ .Differences ins,
474
+ .Differences del {
475
+ text-decoration: none;
476
  }
477
 
478
+ .DifferencesSideBySide .ChangeReplace ins,
479
+ .DifferencesSideBySide .ChangeReplace del {
480
+ background: #fc0;
481
  }
482
 
483
  .Differences .Skipped {
484
+ background: #f7f7f7;
485
  }
486
 
487
  .DifferencesInline .ChangeReplace .Left,
488
  .DifferencesInline .ChangeDelete .Left {
489
+ background: #fdd;
490
  }
491
 
492
  .DifferencesInline .ChangeReplace .Right,
493
  .DifferencesInline .ChangeInsert .Right {
494
+ background: #dfd;
495
  }
496
 
497
  .DifferencesInline .ChangeReplace ins {
498
+ background: #9e9;
499
  }
500
 
501
  .DifferencesInline .ChangeReplace del {
502
+ background: #e99;
503
  }
504
 
505
  /* diff */
506
+
507
+ /* survey */
508
+
509
+ .ui-widget-overlay {
510
+ opacity: 0.85;
511
+ }
512
+
513
+ .ui-dialog {
514
+ z-index: 9998 !important;
515
+ }
516
+
517
+ .survey-dialog .ui-dialog-titlebar {
518
+ text-align: center;
519
+ font-weight: bold;
520
+ }
521
+
522
+ .survey-dialog .ui-dialog-titlebar-close {
523
+ display: none;
524
+ }
525
+
526
+ .survey-dialog .ui-dialog-content {
527
+ padding: 20px 25px;
528
+ font-size: 15px;
529
+ }
530
+
531
+ .wpr-dialog b {
532
+ font-weight: bold;
533
+ }
534
+
535
+ .wpr-dialog .footer {
536
+ margin: 20px 0 0 0;
537
+ text-align: center;
538
+ }
539
+
540
+ .wpr-dialog .footer #emailme {
541
+ margin: 0 5px -3px 0;
542
+ }
543
+
544
+ .wpr-dialog .footer .button-primary {
545
+ font-size: 15px;
546
+ }
547
+
548
+ .wpr-dialog .footer .dismiss-survey {
549
+ display: inline-block;
550
+ margin-left: 10px;
551
+ vertical-align: bottom;
552
+ }
553
+
554
+ .wpr-dialog .ui-dialog-content p {
555
+ margin: 0 0 20px 0;
556
+ font-size: 15px;
557
+ }
558
+
559
+ .wpr-dialog .ui-dialog-titlebar {
560
+ text-align: center;
561
+ }
562
+
563
+ .wpr-dialog .subtitle {
564
+ text-align: center;
565
+ font-size: 15px;
566
+ margin: 0 0 16px 0;
567
+ }
568
+
569
+ .question-wrapper {
570
+ border: 1px solid rgba(0, 0, 0, 0.2);
571
+ padding: 15px 10px;
572
+ background-color: rgba(250, 250, 250, 0.55);
573
+ margin: 0 0 10px 5px;
574
+ opacity: 1;
575
+ width: 46%;
576
+ vertical-align: top;
577
+ display: inline-block;
578
+ text-align: left;
579
+ }
580
+
581
+ .question-wrapper:hover {
582
+ opacity: 1;
583
+ border: 1px solid rgba(0, 142, 194, 1);
584
+ cursor: pointer;
585
+ margin-bottom: 10px;
586
+ }
587
+
588
+ .question-wrapper:hover .dashicons {
589
+ opacity: 0.25;
590
+ }
591
+
592
+ .question-wrapper.selected {
593
+ opacity: 1;
594
+ border: 1px solid rgba(0, 142, 194, 1);
595
+ margin-bottom: 10px;
596
+ }
597
+
598
+ .question-wrapper .dashicons {
599
+ color: rgba(221, 47, 54, 1);
600
+ opacity: 0.25;
601
+ vertical-align: super;
602
+ width: 40px;
603
+ height: 40px;
604
+ }
605
+
606
+ .question-wrapper.selected .dashicons {
607
+ color: rgba(221, 47, 54, 1);
608
+ opacity: 1;
609
+ }
610
+
611
+ .question-wrapper .dashicons:before {
612
+ width: 40px;
613
+ height: 40px;
614
+ font-size: 40px;
615
+ }
616
+
617
+ .question-wrapper .custom-input {
618
+ margin: 4px 0 0 0;
619
+ width: 100%;
620
+ font-size: 12px;
621
+ padding: 5px;
622
+ }
623
+
624
+ .question-wrapper .question {
625
+ margin-left: -40px;
626
+ display: inline-block;
627
+ width: 100%;
628
+ padding-left: 50px;
629
+ box-sizing: border-box;
630
+ }
631
+
632
+ .question-wrapper i {
633
+ padding-top: 5px;
634
+ font-size: 14px;
635
+ display: inline-block;
636
+ }
637
+ /* survey */
638
+
639
+ .webhooks-dialog .ui-dialog-titlebar {
640
+ background-color: rgb(241, 88, 42);
641
+ color: #fefefe;
642
+ }
643
+
644
+ .webhooks-footer {
645
+ text-align: center;
646
+ }
647
+
648
+ .webhooks-dialog .plain-list li {
649
+ text-indent: -21px;
650
+ }
js/wp-reset.js CHANGED
@@ -4,16 +4,16 @@
4
  * (c) WebFactory Ltd, 2017-2019
5
  */
6
 
7
-
8
  jQuery(document).ready(function($) {
9
  // init tabs
10
- $('#wp-reset-tabs').tabs({
11
- activate: function(event, ui) {
12
- localStorage.setItem('wp-reset-tabs', $('#wp-reset-tabs').tabs('option', 'active'));
13
- },
14
- active: localStorage.getItem('wp-reset-tabs') || 0
15
- }).show();
16
-
 
17
 
18
  // delete transients
19
  $('.tools_page_wp-reset').on('click', '#delete-transients', 'click', function(e) {
@@ -24,7 +24,6 @@ jQuery(document).ready(function($) {
24
  return false;
25
  }); // delete transients
26
 
27
-
28
  // delete uploads
29
  $('.tools_page_wp-reset').on('click', '#delete-uploads', 'click', function(e) {
30
  e.preventDefault();
@@ -34,7 +33,6 @@ jQuery(document).ready(function($) {
34
  return false;
35
  }); // delete uploads
36
 
37
-
38
  // delete themes
39
  $('.tools_page_wp-reset').on('click', '#delete-themes', 'click', function(e) {
40
  e.preventDefault();
@@ -44,7 +42,6 @@ jQuery(document).ready(function($) {
44
  return false;
45
  }); // delete themes
46
 
47
-
48
  // delete plugins
49
  $('.tools_page_wp-reset').on('click', '#delete-plugins', 'click', function(e) {
50
  e.preventDefault();
@@ -54,7 +51,6 @@ jQuery(document).ready(function($) {
54
  return false;
55
  }); // delete plugins
56
 
57
-
58
  // drop custom tables
59
  $('.tools_page_wp-reset').on('click', '#drop-custom-tables', 'click', function(e) {
60
  e.preventDefault();
@@ -64,7 +60,6 @@ jQuery(document).ready(function($) {
64
  return false;
65
  }); // drop custom tables
66
 
67
-
68
  // truncate custom tables
69
  $('.tools_page_wp-reset').on('click', '#truncate-custom-tables', 'click', function(e) {
70
  e.preventDefault();
@@ -74,7 +69,6 @@ jQuery(document).ready(function($) {
74
  return false;
75
  }); // truncate custom tables
76
 
77
-
78
  // delete htaccess file
79
  $('.tools_page_wp-reset').on('click', '#delete-htaccess', 'click', function(e) {
80
  e.preventDefault();
@@ -84,7 +78,6 @@ jQuery(document).ready(function($) {
84
  return false;
85
  }); // delete htaccess file
86
 
87
-
88
  // compare snapshot
89
  $('#wpr-snapshots').on('click', '.compare-snapshot', 'click', function(e) {
90
  e.preventDefault();
@@ -100,32 +93,39 @@ jQuery(document).ready(function($) {
100
  tool: 'compare_snapshots',
101
  extra_data: uid
102
  }
103
- }).always(function(data) {
104
- swal.close();
105
- }).done(function(data) {
106
- if (data.success) {
107
- msg = $(button).data('title').replace('%s', $(button).data('name'));
108
- swal({
109
- width: '90%',
110
- title: msg,
111
- html: data.data,
112
- showConfirmButton: false,
113
- allowEnterKey:false,
114
- focusConfirm: false,
115
- showCloseButton: true,
116
- customClass: 'compare-snapshots'
117
- });
118
- } else {
119
- swal({ type: 'error', title: wp_reset.documented_error + ' ' + data.data });
120
- }
121
- }).fail(function(data) {
122
- swal({ type: 'error', title: wp_reset.undocumented_error });
123
- });
 
 
 
 
 
 
 
 
124
 
125
  return false;
126
  }); // compare snapshot
127
 
128
-
129
  // restore snapshot
130
  $('#wpr-snapshots').on('click', '.restore-snapshot', 'click', function(e) {
131
  e.preventDefault();
@@ -136,7 +136,6 @@ jQuery(document).ready(function($) {
136
  return false;
137
  }); // restore snapshot
138
 
139
-
140
  // download snapshot
141
  $('#wpr-snapshots').on('click', '.download-snapshot', 'click', function(e) {
142
  e.preventDefault();
@@ -152,23 +151,30 @@ jQuery(document).ready(function($) {
152
  tool: 'download_snapshot',
153
  extra_data: uid
154
  }
155
- }).always(function(data) {
156
- swal.close();
157
- }).done(function(data) {
158
- if (data.success) {
159
- msg = $(button).data('success-msg').replace('%s', data.data);
160
- swal({ type: 'success', title: msg });
161
- } else {
162
- swal({ type: 'error', title: wp_reset.documented_error + ' ' + data.data });
163
- }
164
- }).fail(function(data) {
165
- swal({ type: 'error', title: wp_reset.undocumented_error });
166
- });
 
 
 
 
 
 
 
 
167
 
168
  return false;
169
  }); // downlod snapshot
170
 
171
-
172
  // delete snapshot
173
  $('#wpr-snapshots').on('click', '.delete-snapshot', 'click', function(e) {
174
  e.preventDefault();
@@ -179,13 +185,13 @@ jQuery(document).ready(function($) {
179
  return false;
180
  }); // delete snapshot
181
 
182
-
183
  // create snapshot
184
  $('.tools_page_wp-reset').on('click', '.create-new-snapshot', 'click', function(e) {
185
  e.preventDefault();
186
  button = $('#create-new-snapshot-primary');
187
 
188
- swal({ title: $(button).data('title'),
 
189
  type: 'question',
190
  text: $(button).data('text'),
191
  input: 'text',
@@ -195,7 +201,7 @@ jQuery(document).ready(function($) {
195
  confirmButtonText: $(button).data('btn-confirm'),
196
  cancelButtonText: wp_reset.cancel_button,
197
  width: 600
198
- }).then((result) => {
199
  if (typeof result.value != 'undefined') {
200
  block = block_ui($(button).data('msg-wait'));
201
  $.get({
@@ -206,19 +212,28 @@ jQuery(document).ready(function($) {
206
  tool: 'create_snapshot',
207
  extra_data: result.value
208
  }
209
- }).always(function(data) {
210
- swal.close();
211
- }).done(function(data) {
212
- if (data.success) {
213
- swal({ type: 'success', title: $(button).data('msg-success') }).then((result) => {
214
- location.reload();
215
- });
216
- } else {
217
- swal({ type: 'error', title: wp_reset.documented_error + ' ' + data.data });
218
- }
219
- }).fail(function(data) {
220
- swal({ type: 'error', title: wp_reset.undocumented_error });
221
- });
 
 
 
 
 
 
 
 
 
222
  } // if confirmed
223
  });
224
 
@@ -232,31 +247,44 @@ jQuery(document).ready(function($) {
232
  parent = $(this).parents('div.wpr-table-container > table > tbody');
233
  $(' > tr:not(.header-row)', parent).toggleClass('hidden');
234
 
235
- $('span.dashicons', parent).toggleClass('dashicons-arrow-down-alt2').toggleClass('dashicons-arrow-up-alt2');
 
 
236
 
237
  return false;
238
  }); // show hide extra info in diff
239
 
240
-
241
  // standard way of running a tool, with confirmation, loading and success message
242
  function run_tool(button, tool_name, extra_data) {
243
- confirm_action(wp_reset.confirm_title, $(button).data('text-confirm'), $(button).data('btn-confirm'), wp_reset.cancel_button)
244
- .then((result) => {
245
- if (result.value) {
246
- block = block_ui($(button).data('text-wait'));
247
- $.get({
248
- url: ajaxurl,
249
- data: {
250
- action: 'wp_reset_run_tool',
251
- _ajax_nonce: wp_reset.nonce_run_tool,
252
- tool: tool_name,
253
- extra_data: extra_data
254
- }
255
- }).always(function(data) {
 
 
 
 
 
256
  swal.close();
257
- }).done(function(data) {
 
258
  if (data.success) {
259
- msg = $(button).data('text-done').replace('%n', data.data);
 
 
 
 
 
 
260
  swal({ type: 'success', title: msg }).then(() => {
261
  if (tool_name == 'restore_snapshot') {
262
  location.reload();
@@ -270,39 +298,44 @@ jQuery(document).ready(function($) {
270
  }
271
  }
272
  } else {
273
- swal({ type: 'error', title: wp_reset.documented_error + ' ' + data.data });
 
 
 
274
  }
275
- }).fail(function(data) {
 
276
  swal({ type: 'error', title: wp_reset.undocumented_error });
277
  });
278
- } // if confirmed
279
- }
280
- );
281
  } // run_tool
282
 
283
-
284
  // display a message while an action is performed
285
  function block_ui(message) {
286
- tmp = swal({ text: message,
 
287
  type: false,
288
  imageUrl: wp_reset.icon_url,
289
- onOpen: () => { $(swal.getImage()).addClass('rotating'); },
 
 
290
  imageWidth: 100,
291
  imageHeight: 100,
292
  imageAlt: message,
293
  allowOutsideClick: false,
294
  allowEscapeKey: false,
295
  allowEnterKey: false,
296
- showConfirmButton: false,
297
  });
298
 
299
  return tmp;
300
  } // block_ui
301
 
302
-
303
  // display dialog to confirm action
304
  function confirm_action(title, question, btn_confirm, btn_cancel) {
305
- tmp = swal({ title: title,
 
306
  type: 'question',
307
  html: question,
308
  showCancelButton: true,
@@ -316,7 +349,6 @@ jQuery(document).ready(function($) {
316
  return tmp;
317
  } // confirm_action
318
 
319
-
320
  $('#wp_reset_form').on('submit', function(e, confirmed) {
321
  if (!confirmed) {
322
  $('#wp_reset_submit').trigger('click');
@@ -324,17 +356,19 @@ jQuery(document).ready(function($) {
324
  return false;
325
  }
326
 
327
- $(this).off('submit').submit();
 
 
328
  return true;
329
  }); // bypass default submit behaviour
330
 
331
-
332
  $('#wp_reset_submit').click(function(e) {
333
  if ($('#wp_reset_confirm').val() !== 'reset') {
334
- swal({ title: wp_reset.invalid_confirmation_title,
335
- text: wp_reset.invalid_confirmation,
336
- type: 'error',
337
- confirmButtonText: wp_reset.ok_button,
 
338
  });
339
 
340
  e.preventDefault();
@@ -342,16 +376,17 @@ jQuery(document).ready(function($) {
342
  } // wrong confirmation code
343
 
344
  message = wp_reset.confirm1 + '<br>' + wp_reset.confirm2;
345
- swal({ title: wp_reset.confirm_title,
346
- type: 'question',
347
- html: message,
348
- showCancelButton: true,
349
- focusConfirm: false,
350
- confirmButtonText: wp_reset.confirm_button,
351
- cancelButtonText: wp_reset.cancel_button,
352
- confirmButtonColor: '#dd3036',
353
- width: 600
354
- }).then((result) => {
 
355
  if (result.value === true) {
356
  block_ui(wp_reset.doing_reset);
357
  $('#wp_reset_form').trigger('submit', true);
@@ -362,13 +397,16 @@ jQuery(document).ready(function($) {
362
  return false;
363
  }); // reset submit
364
 
365
-
366
  // collapse / expand card
367
  $('.card').on('click', '.toggle-card', function(e) {
368
  e.preventDefault();
369
 
370
- card = $(this).parents('.card').toggleClass('collapsed');
371
- $('.dashicons', this).toggleClass('dashicons-arrow-up-alt2').toggleClass('dashicons-arrow-down-alt2');
 
 
 
 
372
  $(this).blur();
373
 
374
  cards = localStorage.getItem('wp-reset-cards');
@@ -388,7 +426,6 @@ jQuery(document).ready(function($) {
388
  return false;
389
  }); // toggle-card
390
 
391
-
392
  // init cards; collapse those that need collapsing
393
  cards = localStorage.getItem('wp-reset-cards');
394
  if (cards != null) {
@@ -400,7 +437,6 @@ jQuery(document).ready(function($) {
400
  }
401
  });
402
 
403
-
404
  // dismiss notice / pointer
405
  $('.wpr-dismiss-notice').on('click', function(e) {
406
  notice_name = $(this).data('notice');
@@ -408,20 +444,164 @@ jQuery(document).ready(function($) {
408
  return true;
409
  }
410
 
411
- if (notice_name == 'geoip_tab') {
412
- $('#wp-reset-tabs').tabs('option', 'active', 0).tabs('disable', 3);
413
- $('#wp-reset-tabs li:eq(3)').remove();
414
- $('#wp-reset-tabs').tabs('refresh');
415
  }
416
 
417
- $.get(ajaxurl, { notice_name: notice_name,
418
- _ajax_nonce: wp_reset.nonce_dismiss_notice,
419
- action: 'wp_reset_dismiss_notice'
 
420
  });
421
 
422
- $(this).parents('.notice-wrapper').fadeOut();
 
 
423
 
424
  e.preventDefault();
425
  return false;
426
  }); // dismiss notice
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
427
  }); // onload
 
 
 
 
 
 
4
  * (c) WebFactory Ltd, 2017-2019
5
  */
6
 
 
7
  jQuery(document).ready(function($) {
8
  // init tabs
9
+ $('#wp-reset-tabs')
10
+ .tabs({
11
+ activate: function(event, ui) {
12
+ localStorage.setItem('wp-reset-tabs', $('#wp-reset-tabs').tabs('option', 'active'));
13
+ },
14
+ active: localStorage.getItem('wp-reset-tabs') || 0
15
+ })
16
+ .show();
17
 
18
  // delete transients
19
  $('.tools_page_wp-reset').on('click', '#delete-transients', 'click', function(e) {
24
  return false;
25
  }); // delete transients
26
 
 
27
  // delete uploads
28
  $('.tools_page_wp-reset').on('click', '#delete-uploads', 'click', function(e) {
29
  e.preventDefault();
33
  return false;
34
  }); // delete uploads
35
 
 
36
  // delete themes
37
  $('.tools_page_wp-reset').on('click', '#delete-themes', 'click', function(e) {
38
  e.preventDefault();
42
  return false;
43
  }); // delete themes
44
 
 
45
  // delete plugins
46
  $('.tools_page_wp-reset').on('click', '#delete-plugins', 'click', function(e) {
47
  e.preventDefault();
51
  return false;
52
  }); // delete plugins
53
 
 
54
  // drop custom tables
55
  $('.tools_page_wp-reset').on('click', '#drop-custom-tables', 'click', function(e) {
56
  e.preventDefault();
60
  return false;
61
  }); // drop custom tables
62
 
 
63
  // truncate custom tables
64
  $('.tools_page_wp-reset').on('click', '#truncate-custom-tables', 'click', function(e) {
65
  e.preventDefault();
69
  return false;
70
  }); // truncate custom tables
71
 
 
72
  // delete htaccess file
73
  $('.tools_page_wp-reset').on('click', '#delete-htaccess', 'click', function(e) {
74
  e.preventDefault();
78
  return false;
79
  }); // delete htaccess file
80
 
 
81
  // compare snapshot
82
  $('#wpr-snapshots').on('click', '.compare-snapshot', 'click', function(e) {
83
  e.preventDefault();
93
  tool: 'compare_snapshots',
94
  extra_data: uid
95
  }
96
+ })
97
+ .always(function(data) {
98
+ swal.close();
99
+ })
100
+ .done(function(data) {
101
+ if (data.success) {
102
+ msg = $(button)
103
+ .data('title')
104
+ .replace('%s', $(button).data('name'));
105
+ swal({
106
+ width: '90%',
107
+ title: msg,
108
+ html: data.data,
109
+ showConfirmButton: false,
110
+ allowEnterKey: false,
111
+ focusConfirm: false,
112
+ showCloseButton: true,
113
+ customClass: 'compare-snapshots'
114
+ });
115
+ } else {
116
+ swal({
117
+ type: 'error',
118
+ title: wp_reset.documented_error + ' ' + data.data
119
+ });
120
+ }
121
+ })
122
+ .fail(function(data) {
123
+ swal({ type: 'error', title: wp_reset.undocumented_error });
124
+ });
125
 
126
  return false;
127
  }); // compare snapshot
128
 
 
129
  // restore snapshot
130
  $('#wpr-snapshots').on('click', '.restore-snapshot', 'click', function(e) {
131
  e.preventDefault();
136
  return false;
137
  }); // restore snapshot
138
 
 
139
  // download snapshot
140
  $('#wpr-snapshots').on('click', '.download-snapshot', 'click', function(e) {
141
  e.preventDefault();
151
  tool: 'download_snapshot',
152
  extra_data: uid
153
  }
154
+ })
155
+ .always(function(data) {
156
+ swal.close();
157
+ })
158
+ .done(function(data) {
159
+ if (data.success) {
160
+ msg = $(button)
161
+ .data('success-msg')
162
+ .replace('%s', data.data);
163
+ swal({ type: 'success', title: msg });
164
+ } else {
165
+ swal({
166
+ type: 'error',
167
+ title: wp_reset.documented_error + ' ' + data.data
168
+ });
169
+ }
170
+ })
171
+ .fail(function(data) {
172
+ swal({ type: 'error', title: wp_reset.undocumented_error });
173
+ });
174
 
175
  return false;
176
  }); // downlod snapshot
177
 
 
178
  // delete snapshot
179
  $('#wpr-snapshots').on('click', '.delete-snapshot', 'click', function(e) {
180
  e.preventDefault();
185
  return false;
186
  }); // delete snapshot
187
 
 
188
  // create snapshot
189
  $('.tools_page_wp-reset').on('click', '.create-new-snapshot', 'click', function(e) {
190
  e.preventDefault();
191
  button = $('#create-new-snapshot-primary');
192
 
193
+ swal({
194
+ title: $(button).data('title'),
195
  type: 'question',
196
  text: $(button).data('text'),
197
  input: 'text',
201
  confirmButtonText: $(button).data('btn-confirm'),
202
  cancelButtonText: wp_reset.cancel_button,
203
  width: 600
204
+ }).then(result => {
205
  if (typeof result.value != 'undefined') {
206
  block = block_ui($(button).data('msg-wait'));
207
  $.get({
212
  tool: 'create_snapshot',
213
  extra_data: result.value
214
  }
215
+ })
216
+ .always(function(data) {
217
+ swal.close();
218
+ })
219
+ .done(function(data) {
220
+ if (data.success) {
221
+ swal({
222
+ type: 'success',
223
+ title: $(button).data('msg-success')
224
+ }).then(result => {
225
+ location.reload();
226
+ });
227
+ } else {
228
+ swal({
229
+ type: 'error',
230
+ title: wp_reset.documented_error + ' ' + data.data
231
+ });
232
+ }
233
+ })
234
+ .fail(function(data) {
235
+ swal({ type: 'error', title: wp_reset.undocumented_error });
236
+ });
237
  } // if confirmed
238
  });
239
 
247
  parent = $(this).parents('div.wpr-table-container > table > tbody');
248
  $(' > tr:not(.header-row)', parent).toggleClass('hidden');
249
 
250
+ $('span.dashicons', parent)
251
+ .toggleClass('dashicons-arrow-down-alt2')
252
+ .toggleClass('dashicons-arrow-up-alt2');
253
 
254
  return false;
255
  }); // show hide extra info in diff
256
 
 
257
  // standard way of running a tool, with confirmation, loading and success message
258
  function run_tool(button, tool_name, extra_data) {
259
+ confirm_action(
260
+ wp_reset.confirm_title,
261
+ $(button).data('text-confirm'),
262
+ $(button).data('btn-confirm'),
263
+ wp_reset.cancel_button
264
+ ).then(result => {
265
+ if (result.value) {
266
+ block = block_ui($(button).data('text-wait'));
267
+ $.get({
268
+ url: ajaxurl,
269
+ data: {
270
+ action: 'wp_reset_run_tool',
271
+ _ajax_nonce: wp_reset.nonce_run_tool,
272
+ tool: tool_name,
273
+ extra_data: extra_data
274
+ }
275
+ })
276
+ .always(function(data) {
277
  swal.close();
278
+ })
279
+ .done(function(data) {
280
  if (data.success) {
281
+ if (data.data == 1) {
282
+ msg = $(button).data('text-done-singular');
283
+ } else {
284
+ msg = $(button)
285
+ .data('text-done')
286
+ .replace('%n', data.data);
287
+ }
288
  swal({ type: 'success', title: msg }).then(() => {
289
  if (tool_name == 'restore_snapshot') {
290
  location.reload();
298
  }
299
  }
300
  } else {
301
+ swal({
302
+ type: 'error',
303
+ title: wp_reset.documented_error + ' ' + data.data
304
+ });
305
  }
306
+ })
307
+ .fail(function(data) {
308
  swal({ type: 'error', title: wp_reset.undocumented_error });
309
  });
310
+ } // if confirmed
311
+ });
 
312
  } // run_tool
313
 
 
314
  // display a message while an action is performed
315
  function block_ui(message) {
316
+ tmp = swal({
317
+ text: message,
318
  type: false,
319
  imageUrl: wp_reset.icon_url,
320
+ onOpen: () => {
321
+ $(swal.getImage()).addClass('rotating');
322
+ },
323
  imageWidth: 100,
324
  imageHeight: 100,
325
  imageAlt: message,
326
  allowOutsideClick: false,
327
  allowEscapeKey: false,
328
  allowEnterKey: false,
329
+ showConfirmButton: false
330
  });
331
 
332
  return tmp;
333
  } // block_ui
334
 
 
335
  // display dialog to confirm action
336
  function confirm_action(title, question, btn_confirm, btn_cancel) {
337
+ tmp = swal({
338
+ title: title,
339
  type: 'question',
340
  html: question,
341
  showCancelButton: true,
349
  return tmp;
350
  } // confirm_action
351
 
 
352
  $('#wp_reset_form').on('submit', function(e, confirmed) {
353
  if (!confirmed) {
354
  $('#wp_reset_submit').trigger('click');
356
  return false;
357
  }
358
 
359
+ $(this)
360
+ .off('submit')
361
+ .submit();
362
  return true;
363
  }); // bypass default submit behaviour
364
 
 
365
  $('#wp_reset_submit').click(function(e) {
366
  if ($('#wp_reset_confirm').val() !== 'reset') {
367
+ swal({
368
+ title: wp_reset.invalid_confirmation_title,
369
+ text: wp_reset.invalid_confirmation,
370
+ type: 'error',
371
+ confirmButtonText: wp_reset.ok_button
372
  });
373
 
374
  e.preventDefault();
376
  } // wrong confirmation code
377
 
378
  message = wp_reset.confirm1 + '<br>' + wp_reset.confirm2;
379
+ swal({
380
+ title: wp_reset.confirm_title,
381
+ type: 'question',
382
+ html: message,
383
+ showCancelButton: true,
384
+ focusConfirm: false,
385
+ confirmButtonText: wp_reset.confirm_button,
386
+ cancelButtonText: wp_reset.cancel_button,
387
+ confirmButtonColor: '#dd3036',
388
+ width: 600
389
+ }).then(result => {
390
  if (result.value === true) {
391
  block_ui(wp_reset.doing_reset);
392
  $('#wp_reset_form').trigger('submit', true);
397
  return false;
398
  }); // reset submit
399
 
 
400
  // collapse / expand card
401
  $('.card').on('click', '.toggle-card', function(e) {
402
  e.preventDefault();
403
 
404
+ card = $(this)
405
+ .parents('.card')
406
+ .toggleClass('collapsed');
407
+ $('.dashicons', this)
408
+ .toggleClass('dashicons-arrow-up-alt2')
409
+ .toggleClass('dashicons-arrow-down-alt2');
410
  $(this).blur();
411
 
412
  cards = localStorage.getItem('wp-reset-cards');
426
  return false;
427
  }); // toggle-card
428
 
 
429
  // init cards; collapse those that need collapsing
430
  cards = localStorage.getItem('wp-reset-cards');
431
  if (cards != null) {
437
  }
438
  });
439
 
 
440
  // dismiss notice / pointer
441
  $('.wpr-dismiss-notice').on('click', function(e) {
442
  notice_name = $(this).data('notice');
444
  return true;
445
  }
446
 
447
+ if ($(this).data('survey')) {
448
+ $('#survey-dialog').dialog('close');
 
 
449
  }
450
 
451
+ $.get(ajaxurl, {
452
+ notice_name: notice_name,
453
+ _ajax_nonce: wp_reset.nonce_dismiss_notice,
454
+ action: 'wp_reset_dismiss_notice'
455
  });
456
 
457
+ $(this)
458
+ .parents('.notice-wrapper')
459
+ .fadeOut();
460
 
461
  e.preventDefault();
462
  return false;
463
  }); // dismiss notice
464
+
465
+ // maybe init survey dialog
466
+ if (wp_reset.open_survey) {
467
+ $('#survey-dialog').dialog({
468
+ dialogClass: 'wp-dialog wpr-dialog wpr-survey-dialog',
469
+ modal: 1,
470
+ resizable: false,
471
+ width: 800,
472
+ height: 'auto',
473
+ show: 'fade',
474
+ hide: 'fade',
475
+ close: function(event, ui) {},
476
+ open: function(event, ui) {
477
+ wpr_fix_dialog_close(event, ui);
478
+ },
479
+ autoOpen: true,
480
+ closeOnEscape: true
481
+ });
482
+ }
483
+
484
+ // turn questions into checkboxes
485
+ $('.question-wrapper').on('click', function(e) {
486
+ if ($(this).hasClass('selected')) {
487
+ $(this).removeClass('selected');
488
+ } else {
489
+ if ($('.question-wrapper.selected').length >= 2) {
490
+ swal({
491
+ type: 'error',
492
+ allowOutsideClick: false,
493
+ text: 'You can choose only up to 2 features at a time.'
494
+ });
495
+ } else {
496
+ $(this).addClass('selected');
497
+ }
498
+ }
499
+
500
+ e.preventDefault();
501
+ return false;
502
+ });
503
+
504
+ // submit and hide survey
505
+ $('.submit-survey').on('click', function(e) {
506
+ if ($('.question-wrapper.selected').length != 2 && $('.question-wrapper.selected').length != 1) {
507
+ swal({
508
+ type: 'error',
509
+ allowOutsideClick: false,
510
+ text: 'Please choose 1 or 2 features you would like us to build next.'
511
+ });
512
+ return false;
513
+ }
514
+
515
+ if (
516
+ $('#survey-dialog .custom-input').val() == '' &&
517
+ $('#survey-dialog .custom-input')
518
+ .parents('div.question-wrapper')
519
+ .hasClass('selected')
520
+ ) {
521
+ swal({
522
+ type: 'error',
523
+ allowOutsideClick: false,
524
+ text: 'Please describe the custom feature you need.'
525
+ });
526
+ return false;
527
+ }
528
+
529
+ answers = '';
530
+ $('.question-wrapper.selected').each(function(i, el) {
531
+ answers += $(el).data('value') + ',';
532
+ });
533
+
534
+ $.post(ajaxurl, {
535
+ survey: 'features',
536
+ answers: answers,
537
+ emailme: $('#survey-dialog #emailme:checked').val(),
538
+ custom_answer: $('#survey-dialog .custom-input').val(),
539
+ _ajax_nonce: wp_reset.nonce_submit_survey,
540
+ action: 'wp_reset_submit_survey'
541
+ });
542
+
543
+ $('#survey-dialog').dialog('close');
544
+ swal({
545
+ type: 'success',
546
+ text: 'Thank you for your time! We appriciate your input!'
547
+ });
548
+
549
+ e.preventDefault();
550
+ return false;
551
+ });
552
+
553
+ $('.tools_page_wp-reset').on('click', '.open-webhooks-dialog', function(e) {
554
+ $(this).blur();
555
+ $('#webhooks-dialog').dialog('open');
556
+
557
+ e.preventDefault();
558
+ return false;
559
+ });
560
+
561
+ // webhooks dialog init
562
+ $('#webhooks-dialog').dialog({
563
+ dialogClass: 'wp-dialog wpr-dialog webhooks-dialog',
564
+ modal: 1,
565
+ resizable: false,
566
+ title: 'WP Webhooks - Connect WordPress to any 3rd party system',
567
+ width: 550,
568
+ height: 'auto',
569
+ show: 'fade',
570
+ hide: 'fade',
571
+ open: function(event, ui) {
572
+ wpr_fix_dialog_close(event, ui);
573
+ $(this)
574
+ .siblings()
575
+ .find('span.ui-dialog-title')
576
+ .html(wp_reset.webhooks_dialog_title);
577
+ },
578
+ close: function(event, ui) {},
579
+ autoOpen: false,
580
+ closeOnEscape: true
581
+ });
582
+ $(window).resize(function(e) {
583
+ $('#webhooks-dialog').dialog('option', 'position', {
584
+ my: 'center',
585
+ at: 'center',
586
+ of: window
587
+ });
588
+ });
589
+
590
+ jQuery('#install-webhooks').on('click', function(e) {
591
+ $('#webhooks-dialog').dialog('close');
592
+ jQuery('body').append(
593
+ '<div style="width:550px;height:450px; position:fixed;top:10%;left:50%;margin-left:-275px; color:#444; background-color: #fbfbfb;border:1px solid #DDD; border-radius:4px;box-shadow: 0px 0px 0px 4000px rgba(0, 0, 0, 0.85);z-index: 9999999;"><iframe src="' +
594
+ wp_reset.webhooks_install_url +
595
+ '" style="width:100%;height:100%;border:none;" /></div>'
596
+ );
597
+ jQuery('#wpwrap').css('pointer-events', 'none');
598
+ e.preventDefault();
599
+ return false;
600
+ });
601
  }); // onload
602
+
603
+ function wpr_fix_dialog_close(event, ui) {
604
+ jQuery('.ui-widget-overlay').bind('click', function() {
605
+ jQuery('#' + event.target.id).dialog('close');
606
+ });
607
+ } // wpr_fix_dialog_close
readme.txt CHANGED
@@ -1,10 +1,10 @@
1
  === WP Reset - Best WordPress Reset Plugin ===
2
- Tags: wordpress reset, reset wordpress, reset database, reset wordpress database, reset, restart wordpress, clean wordpress, default wp, default wordpress, reset wp, wp reset, developer, wp-cli
3
  Contributors: WebFactory, wpreset, googlemapswidget, securityninja, underconstructionpage
4
  Requires at least: 4.0
5
  Requires PHP: 5.2
6
- Tested up to: 5.0
7
- Stable tag: 1.50
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -20,7 +20,7 @@ For support please use the <a href="https://wordpress.org/support/plugin/wp-rese
20
 
21
  Access WP Reset admin page via the "Tools" menu.
22
 
23
- > WP Reset is proudly sponsored by <a target="_blank" href="https://ipgeolocation.io/">IP Geolocation</a>, a **premium GeoIP service for developers**. See how you can use their <a href="https://wpreset.com/geoip-transform-boring-data-better-user-experience/">GeoIP service</a> to make boring IP addresses more interesting for users. They offer <a href="https://ipgeolocation.io/signup">50,000 API requests a month FREE for developers</a>, and keep WP Reset updated & maintained.
24
 
25
 
26
  **Please read carefully before proceeding to understand what WP Reset does**
@@ -72,6 +72,11 @@ WP Reset has yet to be completely tested with multisite! Please be careful when
72
  * Delete .htaccess file - deletes the .htaccess file. If you need to edit .htaccess without FTP use our free <a href="https://wordpress.org/plugins/wp-htaccess-editor/">WP Htaccess Editor</a> plugin.
73
 
74
 
 
 
 
 
 
75
  == Installation ==
76
 
77
  Follow the usual routine;
@@ -97,6 +102,13 @@ Or if needed, upload manually;
97
 
98
  == Changelog ==
99
 
 
 
 
 
 
 
 
100
  = v1.50 =
101
  * 2019/01/08
102
  * new tool: delete .htaccess file
@@ -119,7 +131,7 @@ Or if needed, upload manually;
119
 
120
  = v1.35 =
121
  * 2018/09/18
122
- * WP Reset is proudly sponsored by <a href="https://ipgeolocation.io/">IP Geolocation</a>
123
  * 60k users hit on 2018/09/16 with 323,300 downloads; 35 days for +10k
124
  * added all tools to WP-CLI
125
  * new tool: delete all files in uploads folder
1
  === WP Reset - Best WordPress Reset Plugin ===
2
+ Tags: wordpress reset, reset wordpress, reset database, reset wordpress database, reset, restart wordpress, clean wordpress, default wp, default wordpress, reset wp, wp reset, developer, wp-cli, webhooks
3
  Contributors: WebFactory, wpreset, googlemapswidget, securityninja, underconstructionpage
4
  Requires at least: 4.0
5
  Requires PHP: 5.2
6
+ Tested up to: 5.1
7
+ Stable tag: 1.55
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
20
 
21
  Access WP Reset admin page via the "Tools" menu.
22
 
23
+ WP Reset is fully integrated with <a href="https://wordpress.org/plugins/wp-webhooks/">WP Webhooks</a> plugin - a secure, universal system that connects WP to any 3rd party systems and enables you to initiate actions both from WPs end (for instance start a MailChimp campaign once a new user registers), and from any other application (create a new user in WP when a purchase is made on a 3rd party system). View more <a href="https://underconstructionpage.com/wp-webhooks-connect-integrate-wordpress/" target="_blank">practical use-cases</a> that save hours of repetitive work.
24
 
25
 
26
  **Please read carefully before proceeding to understand what WP Reset does**
72
  * Delete .htaccess file - deletes the .htaccess file. If you need to edit .htaccess without FTP use our free <a href="https://wordpress.org/plugins/wp-htaccess-editor/">WP Htaccess Editor</a> plugin.
73
 
74
 
75
+ #### Friends who helped us translate WP Reset
76
+
77
+ * French - <a href="https://www.infrenchtranslation.com/">Jeff Inho</a>
78
+
79
+
80
  == Installation ==
81
 
82
  Follow the usual routine;
102
 
103
  == Changelog ==
104
 
105
+ = v1.55 =
106
+ * 2019/03/25
107
+ * 100k users hit on 2019/01/15 with 560,300 downloads; 34 days for +10k & 71k downloads
108
+ * bug fixes
109
+ * support for WP Webhooks
110
+ * added features survey
111
+
112
  = v1.50 =
113
  * 2019/01/08
114
  * new tool: delete .htaccess file
131
 
132
  = v1.35 =
133
  * 2018/09/18
134
+ * sponsorship by IP Geolocation
135
  * 60k users hit on 2018/09/16 with 323,300 downloads; 35 days for +10k
136
  * added all tools to WP-CLI
137
  * new tool: delete all files in uploads folder
wp-reset-cli.php CHANGED
@@ -8,16 +8,17 @@
8
 
9
  // include only file
10
  if (!defined('ABSPATH')) {
11
- wp_die(__('Do not open this file directly.', 'wp-error'));
12
  }
13
 
14
 
15
  /**
16
  * Resets the site to the default values without modifying any files.
17
  */
18
- class WP_Reset_CLI extends WP_CLI_Command {
 
19
 
20
- /**
21
  * Reset the site database to default values. No files are modified.
22
  *
23
  * ## OPTIONS
@@ -28,6 +29,9 @@ class WP_Reset_CLI extends WP_CLI_Command {
28
  * [--reactivate-plugins]
29
  * : Reactivate all currently active plugins after reset.
30
  *
 
 
 
31
  * [--deactivate-wp-reset]
32
  * : Deactivate WP Reset plugin after reset. By default it will stay active after reset.
33
  *
@@ -41,46 +45,51 @@ class WP_Reset_CLI extends WP_CLI_Command {
41
  *
42
  * @when after_wp_load
43
  */
44
- function reset( $args, $assoc_args ) {
45
- WP_CLI::confirm( 'Are you sure you want to reset the site? There is NO UNDO!', $assoc_args );
 
46
 
47
- global $wp_reset;
48
- $params = array();
49
 
50
- if ( !empty( $assoc_args['reactivate-theme'] ) ) {
51
- $params['reactivate_theme'] = true;
52
- }
53
- if ( !empty( $assoc_args['disable-wp-reset'] ) ) {
54
- $params['reactivate_wpreset'] = false;
55
- } else {
56
- $params['reactivate_wpreset'] = true;
57
- }
58
- if ( !empty( $assoc_args['reactivate-plugins'] ) ) {
59
- $params['reactivate_plugins'] = true;
60
- }
 
 
 
61
 
62
- $result = $wp_reset->do_reinstall( $params );
63
- if (is_wp_error($result)) {
64
- WP_CLI::error( $result->get_error_message );
65
- } else {
66
- WP_CLI::success( 'Database has been reset.' );
67
- }
68
- } // reset
69
 
70
 
71
- /**
72
  * Display WP Reset version.
73
  *
74
  * @when after_wp_load
75
  */
76
- function version( $args, $assoc_args ) {
77
- global $wp_reset;
 
78
 
79
- WP_CLI::line( 'WP Reset v' . $wp_reset->version );
80
- } // version
81
 
82
 
83
- /**
84
  * Delete selected WordPress objects.
85
  *
86
  * ## OPTIONS
@@ -107,68 +116,69 @@ class WP_Reset_CLI extends WP_CLI_Command {
107
  *
108
  * @when after_wp_load
109
  */
110
- function delete( $args, $assoc_args ) {
111
- global $wp_reset, $wpdb;
 
112
 
113
- if ( empty( $args[0] ) ) {
114
- WP_CLI::error( 'Please choose a subcommand: plugins, themes, transients, uploads, htaccess or custom-tables.' );
115
- return;
116
- } elseif ( false == in_array( $args[0], array( 'themes', 'plugins', 'transients', 'uploads', 'htaccess', 'custom-tables' ) ) ) {
117
- WP_CLI::error( 'Unknown subcommand. Please choose from: plugins, themes, transients, uploads, htaccess or custom tables.' );
118
- } else {
119
- $subcommand = $args[0];
120
- }
121
 
122
- switch ($subcommand) {
123
- case 'themes':
124
- WP_CLI::confirm( 'Are you sure you want to delete all themes?', $assoc_args );
125
- $cnt = $wp_reset->do_delete_themes( false );
126
- WP_CLI::success( $cnt . ' themes have been deleted.' );
127
  break;
128
- case 'plugins':
129
- WP_CLI::confirm( 'Are you sure you want to delete all plugins?', $assoc_args );
130
- $cnt = $wp_reset->do_delete_plugins( true, false );
131
- WP_CLI::success( $cnt . ' plugins have been deleted.' );
132
  break;
133
- case 'transients':
134
- WP_CLI::confirm( 'Are you sure you want to delete all transients?', $assoc_args );
135
- $cnt = $wp_reset->do_delete_transients();
136
- WP_CLI::success( $cnt . ' transient database entries have been deleted.' );
137
  break;
138
- case 'uploads':
139
- WP_CLI::confirm( 'Are you sure you want to delete all files & folders in /uploads/ folder?', $assoc_args );
140
- $cnt = $wp_reset->do_delete_uploads();
141
- WP_CLI::success( $cnt . ' files & folders have been deleted.' );
142
  break;
143
- case 'custom-tables':
144
- if ( !empty( $assoc_args['empty'] ) ) {
145
- WP_CLI::confirm( 'Are you sure you want to empty (truncate) all custom tables (prefix: ' . $wpdb->prefix . ')?', $assoc_args );
146
- $cnt = $wp_reset->do_truncate_custom_tables();
147
- WP_CLI::success( $cnt . ' custom tables have been emptied.' );
148
- } else {
149
- WP_CLI::confirm( 'Are you sure you want to delete (drop) all custom tables (prefix: ' . $wpdb->prefix . ')?', $assoc_args );
150
- $cnt = $wp_reset->do_drop_custom_tables();
151
- WP_CLI::success( $cnt . ' custom tables have been deleted.' );
152
- }
153
  break;
154
- case 'htaccess':
155
- WP_CLI::confirm( 'Are you sure you want to delete the .htaccess file?', $assoc_args );
156
- $tmp = $wp_reset->do_delete_htaccess();
157
- if ( !is_wp_error( $tmp ) ) {
158
- WP_CLI::success( 'Htaccess file has been deleted.' );
159
- } else {
160
- WP_CLI::error( 'Htaccess file has not been deleted. ' . $tmp->get_error_message() );
161
- }
162
  break;
163
- default:
164
- // should never come to this but can't hurt
165
- WP_CLI::error( 'Unknown subcommand. Please choose from: plugins, themes, transients, uploads, htaccess or custom-tables.' );
166
- return;
167
- }
168
- } // delete
169
 
170
 
171
- /**
172
  * List and manipulate DB snapshots.
173
  *
174
  * ## OPTIONS
@@ -198,109 +208,110 @@ class WP_Reset_CLI extends WP_CLI_Command {
198
  *
199
  * @when after_wp_load
200
  */
201
- function snapshots( $args, $assoc_args ) {
202
- global $wp_reset;
 
203
 
204
- if ( empty( $args[0] ) ) {
205
- WP_CLI::error( 'Please choose a subcommand: list, create, restore, export or delete.' );
206
- return;
207
- } elseif ( false == in_array( $args[0], array( 'list', 'create', 'restore', 'export', 'delete' ) ) ) {
208
- WP_CLI::error( 'Unknown subcommand. Please choose from: list, create, restore, export or delete.' );
209
- } else {
210
- $subcommand = $args[0];
211
- }
212
 
213
- switch ($subcommand) {
214
- case 'list':
215
- if ( $snapshots = $wp_reset->get_snapshots() ) {
216
- $table = array();
217
- foreach ( $snapshots as $ss ) {
218
- $tmp = array();
219
- $tmp['id'] = $ss['uid'];
220
- if ( !empty( $ss['name'] ) ) {
221
- $tmp['name'] = $ss['name'];
222
- } else {
223
- $tmp['name'] = 'n/a';
224
- }
225
- $tmp['created'] = date( get_option( 'date_format' ), strtotime( $ss['timestamp'] ) ) . ' @ ' . date( get_option( 'time_format' ), strtotime( $ss['timestamp'] ) );
226
- $tmp['info'] = $ss['tbl_core'] . ' standard & ';
227
- if ( $ss['tbl_custom'] ) {
228
- $tmp['info'] .= $ss['tbl_custom'] . ' custom table' . ( $ss['tbl_custom'] == 1? '': 's' );
229
- } else {
230
- $tmp['info'] .= 'no custom tables';
231
- }
232
- $tmp['info'] .= ' totaling ' . $wp_reset->format_size( $ss['tbl_size'] ) . ' in ' . number_format( $ss['tbl_rows'] ) . ' rows';
233
 
234
- $table[] = $tmp;
235
- } // foreach
236
- WP_CLI\Utils\format_items( 'table', $table, array('id', 'name', 'created', 'info') );
237
- } else {
238
- WP_CLI::line( 'There are no saved snapshots.' );
239
- }
240
  break;
241
- case 'create':
242
- if ( !empty( $assoc_args['name'] ) ) {
243
- $name = trim( $assoc_args['name'] );
244
- } else {
245
- $name = '';
246
- }
247
 
248
- WP_CLI::confirm( 'Are you sure you want to create a new snapshot?', $assoc_args );
249
- $new = $wp_reset->do_create_snapshot( $name );
250
- if ( is_wp_error( $new ) ) {
251
- WP_CLI::error( $new->get_error_message() );
252
- } else {
253
- WP_CLI::success( 'New snapshot with ID ' . $new['uid'] . ' has been created.' );
254
- }
255
  break;
256
- case 'restore':
257
- if ( empty( $assoc_args['id'] ) ) {
258
- WP_CLI::error( 'Please specify the snapshot ID with the "--id=123456" param. Use "wp reset snapshots list" to get a list of all snapshots.' );
259
- break;
 
 
 
 
 
260
  } else {
261
- WP_CLI::confirm( 'Are you sure you want to restore the site to the snapshot with ID ' . $assoc_args['id'] . '?', $assoc_args );
262
- $restore = $wp_reset->do_restore_snapshot( $assoc_args['id'] );
263
- if ( is_wp_error( $restore ) ) {
264
- WP_CLI::error( $restore->get_error_message() );
265
- } else {
266
- WP_CLI::success( 'Site has been restored to the selected snapshot.' );
267
- }
268
  }
 
269
  break;
270
- case 'export':
271
- if ( empty( $assoc_args['id'] ) ) {
272
- WP_CLI::error( 'Please specify the snapshot ID with the "--id=123456" param. Use "wp reset snapshots list" to get a list of all snapshots.' );
273
- break;
 
 
 
 
274
  } else {
275
- $export = $wp_reset->do_export_snapshot( $assoc_args['id'] );
276
- if ( is_wp_error( $export ) ) {
277
- WP_CLI::error( $export->get_error_message() );
278
- } else {
279
- $url = content_url() . '/' . $wp_reset->snapshots_folder . '/' . $export;
280
- WP_CLI::success( 'Snapshot has been exported and saved to: ' . $url );
281
- }
282
  }
 
283
  break;
284
- case 'delete':
285
- if ( empty( $assoc_args['id'] ) ) {
286
- WP_CLI::error( 'Please specify the snapshot ID with the "--id=123456" param. Use "wp reset snapshots list" to get a list of all snapshots.' );
287
- break;
 
 
 
 
 
288
  } else {
289
- WP_CLI::confirm( 'Are you sure you want to delete the snapshot with ID ' . $assoc_args['id'] . '?', $assoc_args );
290
- $del = $wp_reset->do_delete_snapshot( $assoc_args['id'] );
291
- if ( is_wp_error( $del ) ) {
292
- WP_CLI::error( $del->get_error_message() );
293
- } else {
294
- WP_CLI::success( 'Snapshot has been deleted.' );
295
- }
296
  }
 
297
  break;
298
- default:
299
- // it should never come to this but can't hurt
300
- WP_CLI::error( 'Unknown subcommand. Please choose from: list, create, restore, export or delete.' );
301
- return;
302
- }
303
- } // snapshots
304
  } // WP_Reset_CLI
305
 
306
- WP_CLI::add_command( 'reset', 'WP_Reset_CLI' );
8
 
9
  // include only file
10
  if (!defined('ABSPATH')) {
11
+ wp_die(__('Do not open this file directly.', 'wp-error'));
12
  }
13
 
14
 
15
  /**
16
  * Resets the site to the default values without modifying any files.
17
  */
18
+ class WP_Reset_CLI extends WP_CLI_Command
19
+ {
20
 
21
+ /**
22
  * Reset the site database to default values. No files are modified.
23
  *
24
  * ## OPTIONS
29
  * [--reactivate-plugins]
30
  * : Reactivate all currently active plugins after reset.
31
  *
32
+ * [--reactivate-webhooks]
33
+ * : Reactivate WP Webhooks plugin after reset.
34
+ *
35
  * [--deactivate-wp-reset]
36
  * : Deactivate WP Reset plugin after reset. By default it will stay active after reset.
37
  *
45
  *
46
  * @when after_wp_load
47
  */
48
+ function reset($args, $assoc_args)
49
+ {
50
+ WP_CLI::confirm('Are you sure you want to reset the site? There is NO UNDO!', $assoc_args);
51
 
52
+ global $wp_reset;
53
+ $params = array();
54
 
55
+ if (!empty($assoc_args['reactivate-theme'])) {
56
+ $params['reactivate_theme'] = true;
57
+ }
58
+ if (!empty($assoc_args['disable-wp-reset'])) {
59
+ $params['reactivate_wpreset'] = false;
60
+ } else {
61
+ $params['reactivate_wpreset'] = true;
62
+ }
63
+ if (!empty($assoc_args['reactivate-plugins'])) {
64
+ $params['reactivate_plugins'] = true;
65
+ }
66
+ if (!empty($assoc_args['reactivate-webhooks'])) {
67
+ $params['reactivate_webhooks'] = true;
68
+ }
69
 
70
+ $result = $wp_reset->do_reinstall($params);
71
+ if (is_wp_error($result)) {
72
+ WP_CLI::error($result->get_error_message);
73
+ } else {
74
+ WP_CLI::success('Database has been reset.');
75
+ }
76
+ } // reset
77
 
78
 
79
+ /**
80
  * Display WP Reset version.
81
  *
82
  * @when after_wp_load
83
  */
84
+ function version($args, $assoc_args)
85
+ {
86
+ global $wp_reset;
87
 
88
+ WP_CLI::line('WP Reset v' . $wp_reset->version);
89
+ } // version
90
 
91
 
92
+ /**
93
  * Delete selected WordPress objects.
94
  *
95
  * ## OPTIONS
116
  *
117
  * @when after_wp_load
118
  */
119
+ function delete($args, $assoc_args)
120
+ {
121
+ global $wp_reset, $wpdb;
122
 
123
+ if (empty($args[0])) {
124
+ WP_CLI::error('Please choose a subcommand: plugins, themes, transients, uploads, htaccess or custom-tables.');
125
+ return;
126
+ } elseif (false == in_array($args[0], array('themes', 'plugins', 'transients', 'uploads', 'htaccess', 'custom-tables'))) {
127
+ WP_CLI::error('Unknown subcommand. Please choose from: plugins, themes, transients, uploads, htaccess or custom tables.');
128
+ } else {
129
+ $subcommand = $args[0];
130
+ }
131
 
132
+ switch ($subcommand) {
133
+ case 'themes':
134
+ WP_CLI::confirm('Are you sure you want to delete all themes?', $assoc_args);
135
+ $cnt = $wp_reset->do_delete_themes(false);
136
+ WP_CLI::success($cnt . ' themes have been deleted.');
137
  break;
138
+ case 'plugins':
139
+ WP_CLI::confirm('Are you sure you want to delete all plugins?', $assoc_args);
140
+ $cnt = $wp_reset->do_delete_plugins(true, false);
141
+ WP_CLI::success($cnt . ' plugins have been deleted.');
142
  break;
143
+ case 'transients':
144
+ WP_CLI::confirm('Are you sure you want to delete all transients?', $assoc_args);
145
+ $cnt = $wp_reset->do_delete_transients();
146
+ WP_CLI::success($cnt . ' transient database entries have been deleted.');
147
  break;
148
+ case 'uploads':
149
+ WP_CLI::confirm('Are you sure you want to delete all files & folders in /uploads/ folder?', $assoc_args);
150
+ $cnt = $wp_reset->do_delete_uploads();
151
+ WP_CLI::success($cnt . ' files & folders have been deleted.');
152
  break;
153
+ case 'custom-tables':
154
+ if (!empty($assoc_args['empty'])) {
155
+ WP_CLI::confirm('Are you sure you want to empty (truncate) all custom tables (prefix: ' . $wpdb->prefix . ')?', $assoc_args);
156
+ $cnt = $wp_reset->do_truncate_custom_tables();
157
+ WP_CLI::success($cnt . ' custom tables have been emptied.');
158
+ } else {
159
+ WP_CLI::confirm('Are you sure you want to delete (drop) all custom tables (prefix: ' . $wpdb->prefix . ')?', $assoc_args);
160
+ $cnt = $wp_reset->do_drop_custom_tables();
161
+ WP_CLI::success($cnt . ' custom tables have been deleted.');
162
+ }
163
  break;
164
+ case 'htaccess':
165
+ WP_CLI::confirm('Are you sure you want to delete the .htaccess file?', $assoc_args);
166
+ $tmp = $wp_reset->do_delete_htaccess();
167
+ if (!is_wp_error($tmp)) {
168
+ WP_CLI::success('Htaccess file has been deleted.');
169
+ } else {
170
+ WP_CLI::error('Htaccess file has not been deleted. ' . $tmp->get_error_message());
171
+ }
172
  break;
173
+ default:
174
+ // should never come to this but can't hurt
175
+ WP_CLI::error('Unknown subcommand. Please choose from: plugins, themes, transients, uploads, htaccess or custom-tables.');
176
+ return;
177
+ }
178
+ } // delete
179
 
180
 
181
+ /**
182
  * List and manipulate DB snapshots.
183
  *
184
  * ## OPTIONS
208
  *
209
  * @when after_wp_load
210
  */
211
+ function snapshots($args, $assoc_args)
212
+ {
213
+ global $wp_reset;
214
 
215
+ if (empty($args[0])) {
216
+ WP_CLI::error('Please choose a subcommand: list, create, restore, export or delete.');
217
+ return;
218
+ } elseif (false == in_array($args[0], array('list', 'create', 'restore', 'export', 'delete'))) {
219
+ WP_CLI::error('Unknown subcommand. Please choose from: list, create, restore, export or delete.');
220
+ } else {
221
+ $subcommand = $args[0];
222
+ }
223
 
224
+ switch ($subcommand) {
225
+ case 'list':
226
+ if ($snapshots = $wp_reset->get_snapshots()) {
227
+ $table = array();
228
+ foreach ($snapshots as $ss) {
229
+ $tmp = array();
230
+ $tmp['id'] = $ss['uid'];
231
+ if (!empty($ss['name'])) {
232
+ $tmp['name'] = $ss['name'];
233
+ } else {
234
+ $tmp['name'] = 'n/a';
235
+ }
236
+ $tmp['created'] = date(get_option('date_format'), strtotime($ss['timestamp'])) . ' @ ' . date(get_option('time_format'), strtotime($ss['timestamp']));
237
+ $tmp['info'] = $ss['tbl_core'] . ' standard & ';
238
+ if ($ss['tbl_custom']) {
239
+ $tmp['info'] .= $ss['tbl_custom'] . ' custom table' . ($ss['tbl_custom'] == 1 ? '' : 's');
240
+ } else {
241
+ $tmp['info'] .= 'no custom tables';
242
+ }
243
+ $tmp['info'] .= ' totaling ' . $wp_reset->format_size($ss['tbl_size']) . ' in ' . number_format($ss['tbl_rows']) . ' rows';
244
 
245
+ $table[] = $tmp;
246
+ } // foreach
247
+ WP_CLI\Utils\format_items('table', $table, array('id', 'name', 'created', 'info'));
248
+ } else {
249
+ WP_CLI::line('There are no saved snapshots.');
250
+ }
251
  break;
252
+ case 'create':
253
+ if (!empty($assoc_args['name'])) {
254
+ $name = trim($assoc_args['name']);
255
+ } else {
256
+ $name = '';
257
+ }
258
 
259
+ WP_CLI::confirm('Are you sure you want to create a new snapshot?', $assoc_args);
260
+ $new = $wp_reset->do_create_snapshot($name);
261
+ if (is_wp_error($new)) {
262
+ WP_CLI::error($new->get_error_message());
263
+ } else {
264
+ WP_CLI::success('New snapshot with ID ' . $new['uid'] . ' has been created.');
265
+ }
266
  break;
267
+ case 'restore':
268
+ if (empty($assoc_args['id'])) {
269
+ WP_CLI::error('Please specify the snapshot ID with the "--id=123456" param. Use "wp reset snapshots list" to get a list of all snapshots.');
270
+ break;
271
+ } else {
272
+ WP_CLI::confirm('Are you sure you want to restore the site to the snapshot with ID ' . $assoc_args['id'] . '?', $assoc_args);
273
+ $restore = $wp_reset->do_restore_snapshot($assoc_args['id']);
274
+ if (is_wp_error($restore)) {
275
+ WP_CLI::error($restore->get_error_message());
276
  } else {
277
+ WP_CLI::success('Site has been restored to the selected snapshot.');
 
 
 
 
 
 
278
  }
279
+ }
280
  break;
281
+ case 'export':
282
+ if (empty($assoc_args['id'])) {
283
+ WP_CLI::error('Please specify the snapshot ID with the "--id=123456" param. Use "wp reset snapshots list" to get a list of all snapshots.');
284
+ break;
285
+ } else {
286
+ $export = $wp_reset->do_export_snapshot($assoc_args['id']);
287
+ if (is_wp_error($export)) {
288
+ WP_CLI::error($export->get_error_message());
289
  } else {
290
+ $url = content_url() . '/' . $wp_reset->snapshots_folder . '/' . $export;
291
+ WP_CLI::success('Snapshot has been exported and saved to: ' . $url);
 
 
 
 
 
292
  }
293
+ }
294
  break;
295
+ case 'delete':
296
+ if (empty($assoc_args['id'])) {
297
+ WP_CLI::error('Please specify the snapshot ID with the "--id=123456" param. Use "wp reset snapshots list" to get a list of all snapshots.');
298
+ break;
299
+ } else {
300
+ WP_CLI::confirm('Are you sure you want to delete the snapshot with ID ' . $assoc_args['id'] . '?', $assoc_args);
301
+ $del = $wp_reset->do_delete_snapshot($assoc_args['id']);
302
+ if (is_wp_error($del)) {
303
+ WP_CLI::error($del->get_error_message());
304
  } else {
305
+ WP_CLI::success('Snapshot has been deleted.');
 
 
 
 
 
 
306
  }
307
+ }
308
  break;
309
+ default:
310
+ // it should never come to this but can't hurt
311
+ WP_CLI::error('Unknown subcommand. Please choose from: list, create, restore, export or delete.');
312
+ return;
313
+ }
314
+ } // snapshots
315
  } // WP_Reset_CLI
316
 
317
+ WP_CLI::add_command('reset', 'WP_Reset_CLI');
wp-reset.php CHANGED
@@ -1,9 +1,9 @@
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.50
7
  Author: WebFactory Ltd
8
  Author URI: https://www.webfactoryltd.com/
9
  Text Domain: wp-reset
@@ -32,11 +32,12 @@ if (!defined('ABSPATH')) {
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 = '';
@@ -44,6 +45,7 @@ class WP_Reset {
44
  public $snapshots_folder = 'wp-reset-snapshots-export';
45
  protected $options = array();
46
  private $delete_count = 0;
 
47
  private $core_tables = array('commentmeta', 'comments', 'links', 'options', 'postmeta', 'posts', 'term_relationships', 'term_taxonomy', 'termmeta', 'terms', 'usermeta', 'users');
48
 
49
 
@@ -52,7 +54,8 @@ class WP_Reset {
52
  *
53
  * @return WP_Reset
54
  */
55
- static function getInstance() {
 
56
  if (!is_a(self::$instance, 'WP_Reset')) {
57
  self::$instance = new WP_Reset();
58
  }
@@ -66,7 +69,8 @@ class WP_Reset {
66
  *
67
  * @return null
68
  */
69
- private function __construct() {
 
70
  $this->version = $this->get_plugin_version();
71
  $this->plugin_dir = plugin_dir_path(__FILE__);
72
  $this->plugin_url = plugin_dir_url(__FILE__);
@@ -77,13 +81,18 @@ class WP_Reset {
77
  add_action('admin_enqueue_scripts', array($this, 'admin_enqueue_scripts'));
78
  add_action('wp_ajax_wp_reset_dismiss_notice', array($this, 'ajax_dismiss_notice'));
79
  add_action('wp_ajax_wp_reset_run_tool', array($this, 'ajax_run_tool'));
 
 
80
 
81
  add_filter('plugin_action_links_' . plugin_basename(__FILE__), array($this, 'plugin_action_links'));
82
  add_filter('plugin_row_meta', array($this, 'plugin_meta_links'), 10, 2);
83
  add_filter('admin_footer_text', array($this, 'admin_footer_text'));
84
  add_filter('install_plugins_table_api_args_featured', array($this, 'featured_plugins_tab'));
85
 
86
- $this->core_tables = array_map(function($tbl) { global $wpdb; return $wpdb->prefix . $tbl; }, $this->core_tables);
 
 
 
87
  } // __construct
88
 
89
 
@@ -92,7 +101,8 @@ class WP_Reset {
92
  *
93
  * @return string
94
  */
95
- function get_plugin_version() {
 
96
  $plugin_data = get_file_data(__FILE__, array('version' => 'Version'), 'plugin');
97
 
98
  return $plugin_data['version'];
@@ -105,7 +115,8 @@ class WP_Reset {
105
  *
106
  * @return array
107
  */
108
- private function load_options() {
 
109
  $options = get_option('wp-reset', array());
110
  $change = false;
111
 
@@ -139,7 +150,8 @@ class WP_Reset {
139
  *
140
  * @return array
141
  */
142
- function get_meta() {
 
143
  return $this->options['meta'];
144
  } // get_meta
145
 
@@ -151,7 +163,8 @@ class WP_Reset {
151
  *
152
  * @return bool|array
153
  */
154
- function get_dismissed_notices($notice_name = '') {
 
155
  $notices = $this->options['dismissed_notices'];
156
 
157
  if (empty($notice_name)) {
@@ -175,7 +188,8 @@ class WP_Reset {
175
  *
176
  * @return array
177
  */
178
- function get_options($key = '') {
 
179
  return $this->options['options'];
180
  } // get_options
181
 
@@ -190,7 +204,8 @@ class WP_Reset {
190
  *
191
  * @return bool
192
  */
193
- function update_options($key, $data) {
 
194
  $this->options[$key] = $data;
195
  $tmp = update_option('wp-reset', $this->options);
196
 
@@ -203,7 +218,8 @@ class WP_Reset {
203
  *
204
  * @return null
205
  */
206
- function admin_menu() {
 
207
  add_management_page(__('WP Reset', 'wp-reset'), __('WP Reset', 'wp-reset'), 'administrator', 'wp-reset', array($this, 'plugin_page'));
208
  } // admin_menu
209
 
@@ -213,7 +229,8 @@ class WP_Reset {
213
  *
214
  * @return null
215
  */
216
- function ajax_dismiss_notice() {
 
217
  check_ajax_referer('wp-reset_dismiss_notice');
218
 
219
  if (!current_user_can('administrator')) {
@@ -236,7 +253,8 @@ class WP_Reset {
236
  *
237
  * @return bool
238
  */
239
- function dismiss_notice($notice_name) {
 
240
  if ($this->get_dismissed_notices($notice_name)) {
241
  return false;
242
  } else {
@@ -253,10 +271,11 @@ class WP_Reset {
253
  *
254
  * @return array
255
  */
256
- function get_pointers() {
 
257
  $pointers = array();
258
 
259
- $pointers['welcome'] = array('target' => '#menu-tools', 'edge' => 'left', 'align' => 'right', 'content' => 'Thank you for installing the <b style="font-weight: 800;">WP Reset</b> plugin!<br>Open <a href="' . admin_url('tools.php?page=wp-reset'). '">Tools - WP Reset</a> to access resetting tools and start developing &amp; debugging faster.');
260
 
261
  return $pointers;
262
  } // get_pointers
@@ -267,10 +286,12 @@ class WP_Reset {
267
  *
268
  * @return null
269
  */
270
- function admin_enqueue_scripts($hook) {
 
271
  // welcome pointer is shown on all pages except WPR to admins, until dismissed
272
  $pointers = $this->get_pointers();
273
  $dismissed_notices = $this->get_dismissed_notices();
 
274
 
275
  foreach ($dismissed_notices as $notice_name => $tmp) {
276
  if ($tmp) {
@@ -293,29 +314,45 @@ class WP_Reset {
293
  return;
294
  }
295
 
296
- $options = $this->get_options();
297
-
298
- $js_localize = array('undocumented_error' => __('An undocumented error has occurred. Please refresh the page and try again.', 'wp-reset'),
299
- 'documented_error' => __('An error has occurred.', 'wp-reset'),
300
- 'plugin_name' => __('WP Reset', 'wp-reset'),
301
- 'settings_url' => admin_url('tools.php?page=wp-reset'),
302
- 'icon_url' => $this->plugin_url . 'img/wp-reset-icon.png',
303
- 'invalid_confirmation' => __('Please type "reset" in the confirmation field.', 'wp-reset'),
304
- 'invalid_confirmation_title' => __('Invalid confirmation', 'wp-reset'),
305
- 'cancel_button' => __('Cancel', 'wp-reset'),
306
- 'ok_button' => __('OK', 'wp-reset'),
307
- 'confirm_button' => __('Reset WordPress', 'wp-reset'),
308
- 'confirm_title' => __('Are you sure you want to proceed?', 'wp-reset'),
309
- 'confirm1' => __('Clicking "Reset WordPress" will reset your site to default values. All content will be lost. There is NO UNDO.', 'wp-reset'),
310
- 'confirm2' => __('Click "Cancel" to abort.', 'wp-reset'),
311
- 'doing_reset' => __('Resetting in progress. Please wait.', 'wp-reset'),
312
- 'nonce_dismiss_notice' => wp_create_nonce('wp-reset_dismiss_notice'),
313
- 'nonce_run_tool' => wp_create_nonce('wp-reset_run_tool'),
314
- 'nonce_do_reset' => wp_create_nonce('wp-reset_do_reset'));
315
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
316
  wp_enqueue_style('wp-reset', $this->plugin_url . 'css/wp-reset.css', array(), $this->version);
317
  wp_enqueue_style('wp-reset-sweetalert2', $this->plugin_url . 'css/sweetalert2.min.css', array(), $this->version);
318
 
 
319
  wp_enqueue_script('jquery-ui-tabs');
320
  wp_enqueue_script('wp-reset-sweetalert2', $this->plugin_url . 'js/sweetalert2.min.js', array('jquery'), $this->version, true);
321
  wp_enqueue_script('wp-reset', $this->plugin_url . 'js/wp-reset.js', array('jquery'), $this->version, true);
@@ -323,8 +360,8 @@ class WP_Reset {
323
 
324
  // fix for aggressive plugins that include their CSS on all pages
325
  wp_dequeue_style('uiStyleSheet');
326
- wp_dequeue_style('wpcufpnAdmin' );
327
- wp_dequeue_style('unifStyleSheet' );
328
  wp_dequeue_style('wpcufpn_codemirror');
329
  wp_dequeue_style('wpcufpn_codemirrorTheme');
330
  wp_dequeue_style('collapse-admin-css');
@@ -337,12 +374,87 @@ class WP_Reset {
337
  } // admin_enqueue_scripts
338
 
339
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
340
  /**
341
  * Check if WP-CLI is available and running
342
  *
343
  * @return bool
344
  */
345
- static function is_cli_running() {
 
 
 
 
 
346
  if (defined('WP_CLI') && WP_CLI) {
347
  return true;
348
  } else {
@@ -351,12 +463,142 @@ class WP_Reset {
351
  } // is_cli_running
352
 
353
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
354
  /**
355
  * Deletes all transients.
356
  *
357
  * @return int Number of deleted transient DB entries
358
  */
359
- function do_delete_transients() {
 
360
  global $wpdb;
361
 
362
  $count = $wpdb->query("DELETE FROM $wpdb->options WHERE option_name LIKE '\_transient\_%' OR option_name LIKE '\_site\_transient\_%'");
@@ -370,7 +612,8 @@ class WP_Reset {
370
  *
371
  * @return int Number of deleted files and folders.
372
  */
373
- function do_delete_uploads() {
 
374
  $upload_dir = wp_get_upload_dir();
375
 
376
  $this->delete_folder($upload_dir['basedir'], $upload_dir['basedir']);
@@ -387,7 +630,8 @@ class WP_Reset {
387
  *
388
  * @return bool
389
  */
390
- private function delete_folder($folder, $base_folder) {
 
391
  $files = array_diff(scandir($folder), array('.', '..'));
392
 
393
  foreach ($files as $file) {
@@ -395,13 +639,13 @@ class WP_Reset {
395
  $this->delete_folder($folder . DIRECTORY_SEPARATOR . $file, $base_folder);
396
  } else {
397
  $tmp = @unlink($folder . DIRECTORY_SEPARATOR . $file);
398
- $this->delete_count = $this->delete_count + (int) $tmp;
399
  }
400
  } // foreach
401
 
402
  if ($folder != $base_folder) {
403
  $tmp = @rmdir($folder);
404
- $this->delete_count = $this->delete_count + (int) $tmp;
405
  return $tmp;
406
  } else {
407
  return true;
@@ -417,15 +661,19 @@ class WP_Reset {
417
  *
418
  * @return int Number of deleted plugins.
419
  */
420
- function do_delete_plugins($keep_wp_reset = true, $silent_deactivate = false) {
 
421
  if (!function_exists('get_plugins')) {
422
  require_once ABSPATH . 'wp-admin/includes/plugin.php';
423
  }
 
 
 
424
 
425
  $wp_reset_basename = plugin_basename(__FILE__);
426
 
427
  $all_plugins = get_plugins();
428
- $active_plugins = (array) get_option('active_plugins', array());
429
  if (true == $keep_wp_reset) {
430
  if (($key = array_search($wp_reset_basename, $active_plugins)) !== false) {
431
  unset($active_plugins[$key]);
@@ -452,9 +700,18 @@ class WP_Reset {
452
  *
453
  * @return int Number of deleted themes.
454
  */
455
- function do_delete_themes($keep_default_theme = true) {
 
456
  global $wp_version;
457
 
 
 
 
 
 
 
 
 
458
  if (version_compare($wp_version, '5.0', '<') === true) {
459
  $default_theme = 'twentyseventeen';
460
  } else {
@@ -485,7 +742,8 @@ class WP_Reset {
485
  *
486
  * @return int Number of truncated tables.
487
  */
488
- function do_truncate_custom_tables() {
 
489
  global $wpdb;
490
  $custom_tables = $this->get_custom_tables();
491
 
@@ -502,7 +760,8 @@ class WP_Reset {
502
  *
503
  * @return int Number of dropped tables.
504
  */
505
- function do_drop_custom_tables() {
 
506
  global $wpdb;
507
  $custom_tables = $this->get_custom_tables();
508
 
@@ -519,7 +778,8 @@ class WP_Reset {
519
  *
520
  * @return bool|WP_Error Action status.
521
  */
522
- function do_delete_htaccess() {
 
523
  global $wp_filesystem;
524
 
525
  if (empty($wp_filesystem)) {
@@ -551,7 +811,8 @@ class WP_Reset {
551
  *
552
  * @return string
553
  */
554
- function get_htaccess_path() {
 
555
  if (!function_exists('get_home_path')) {
556
  require_once ABSPATH . 'wp-admin/includes/file.php';
557
  }
@@ -571,7 +832,8 @@ class WP_Reset {
571
  *
572
  * @return null
573
  */
574
- function ajax_run_tool() {
 
575
  check_ajax_referer('wp-reset_run_tool');
576
 
577
  if (!current_user_can('administrator')) {
@@ -657,7 +919,8 @@ class WP_Reset {
657
  *
658
  * @return null
659
  */
660
- function do_reinstall($params = array()) {
 
661
  global $current_user, $wpdb;
662
 
663
  // only admins can reset; double-check
@@ -682,6 +945,12 @@ class WP_Reset {
682
  $active_plugins = get_option('active_plugins');
683
  $active_theme = wp_get_theme();
684
 
 
 
 
 
 
 
685
  // for WP-CLI
686
  if (!$current_user->ID) {
687
  $tmp = get_users(array('role' => 'administrator', 'order' => 'ASC', 'order_by' => 'ID'));
@@ -699,7 +968,7 @@ class WP_Reset {
699
  }
700
 
701
  // supress errors for WP_CLI
702
- // todo: do something better
703
  $result = @wp_install($blogname, $current_user->user_login, $current_user->user_email, $blog_public, '', md5(rand()), $wplang);
704
  $user_id = $result['user_id'];
705
 
@@ -718,7 +987,7 @@ class WP_Reset {
718
  update_user_meta($user_id, 'default_password_nag', false);
719
  }
720
  if (get_user_meta($user_id, $wpdb->prefix . 'default_password_nag')) {
721
- update_user_meta($user_id, $wpdb->prefix . 'default_password_nag', false );
722
  }
723
 
724
  $meta = $this->get_meta();
@@ -732,7 +1001,17 @@ class WP_Reset {
732
 
733
  // reactivate WP Reset
734
  if (!empty($params['reactivate_wpreset'])) {
735
- activate_plugin(plugin_basename( __FILE__ ));
 
 
 
 
 
 
 
 
 
 
736
  }
737
 
738
  // reactivate all plugins
@@ -760,14 +1039,15 @@ class WP_Reset {
760
  *
761
  * @return null|bool
762
  */
763
- function do_all_actions() {
 
764
  // only admins can perform actions
765
  if (!current_user_can('administrator')) {
766
  return;
767
  }
768
 
769
  if (!empty($_GET['wp-reset']) && stristr($_SERVER['HTTP_REFERER'], 'wp-reset')) {
770
- add_action('admin_notices', array($this, 'notice_successfull_reset'));
771
  }
772
 
773
  // check nonce
@@ -784,10 +1064,13 @@ class WP_Reset {
784
 
785
  // only one action at the moment
786
  if (true === isset($_POST['wp_reset_confirm']) && 'reset' === $_POST['wp_reset_confirm']) {
787
- $defaults = array('reactivate_theme' => '0',
788
- 'reactivate_plugins' => '0',
789
- 'reactivate_wpreset' => '0');
790
- $params = shortcode_atts($defaults, (array) @$_POST['wpr-post-reset']);
 
 
 
791
 
792
  $this->do_reinstall($params);
793
  }
@@ -801,7 +1084,8 @@ class WP_Reset {
801
  *
802
  * @return array
803
  */
804
- function plugin_action_links($links) {
 
805
  $settings_link = '<a href="' . admin_url('tools.php?page=wp-reset') . '" title="' . __('Open WP Reset Tools', 'wp-reset') . '">' . __('Open WP Reset Tools', 'wp-reset') . '</a>';
806
 
807
  array_unshift($links, $settings_link);
@@ -818,7 +1102,8 @@ class WP_Reset {
818
  *
819
  * @return array
820
  */
821
- function plugin_meta_links($links, $file) {
 
822
  if ($file !== plugin_basename(__FILE__)) {
823
  return $links;
824
  }
@@ -840,7 +1125,8 @@ class WP_Reset {
840
  *
841
  * @return bool
842
  */
843
- function is_plugin_page() {
 
844
  $current_screen = get_current_screen();
845
 
846
  if ($current_screen->id == 'tools_page_wp-reset') {
@@ -858,12 +1144,13 @@ class WP_Reset {
858
  *
859
  * @return string
860
  */
861
- function admin_footer_text($text) {
 
862
  if (!$this->is_plugin_page()) {
863
  return $text;
864
  }
865
 
866
- $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>. Proudly sponsored by <a target="_blank" href="https://ipgeolocation.io/">IP Geolocation</a> - premium GeoIP service for developers.</i>';
867
 
868
  return $text;
869
  } // admin_footer_text
@@ -874,7 +1161,8 @@ class WP_Reset {
874
  *
875
  * @return null
876
  */
877
- function load_textdomain() {
 
878
  load_plugin_textdomain('wp-reset');
879
  } // load_textdomain
880
 
@@ -884,11 +1172,12 @@ class WP_Reset {
884
  *
885
  * @return null
886
  */
887
- function notice_successfull_reset() {
 
888
  global $current_user;
889
 
890
- 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>';
891
- } // notice_successfull_reset
892
 
893
 
894
  /**
@@ -896,20 +1185,20 @@ class WP_Reset {
896
  *
897
  * @return null
898
  */
899
- function plugin_page() {
 
900
  $notice_shown = false;
901
  $meta = $this->get_meta();
902
- $notices = $this->get_dismissed_notices();
903
  $snapshots = $this->get_snapshots();
904
 
905
- // double check for admin priv
906
  if (!current_user_can('administrator')) {
907
  wp_die(__('Sorry, you are not allowed to access this page.', 'wp-reset'));
908
  }
909
 
910
  settings_errors();
911
  echo '<div class="wrap">';
912
- 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') . '"> <span>proudly sponsored by <a href="https://ipgeolocation.io/" target="_blank">IP Geolocation</a></span></h1>';
913
  echo '<form id="wp_reset_form" action="' . admin_url('tools.php?page=wp-reset') . '" method="post" autocomplete="off">';
914
 
915
  if (false === $notice_shown && is_multisite()) {
@@ -920,7 +1209,9 @@ class WP_Reset {
920
  $notice_shown = true;
921
  }
922
 
923
- if ((!empty($meta['reset_count']) || !empty($snapshots)) && false === $notice_shown && false == $this->get_dismissed_notices('rate')) {
 
 
924
  echo '<div class="card notice-wrapper">';
925
  echo '<h2>' . __('Please help us keep the plugin free &amp; up-to-date', 'wp-reset') . '</h2>';
926
  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>';
@@ -948,9 +1239,6 @@ class WP_Reset {
948
  echo '<li><a href="#tab-tools">' . __('Tools', 'wp-reset') . '</a></li>';
949
  echo '<li><a href="#tab-snapshots">' . __('DB Snapshots', 'wp-reset') . '</a></li>';
950
  echo '<li><a href="#tab-support">' . __('Support', 'wp-reset') . '</a></li>';
951
- if (empty($notices['geoip_tab'])) {
952
- echo '<li><a href="#tab-geoip">' . __('IP Geolocation', 'wp-reset') . '</a></li>';
953
- }
954
  echo '</ul>';
955
 
956
  echo '<div style="display: none;" id="tab-reset">';
@@ -969,16 +1257,87 @@ class WP_Reset {
969
  $this->tab_support();
970
  echo '</div>';
971
 
972
- if (empty($notices['geoip_tab'])) {
973
- echo '<div style="display: none;" id="tab-geoip">';
974
- $this->tab_geoip();
975
- echo '</div>';
976
- }
977
-
978
  echo '</div>'; // tabs
979
 
980
  echo '</form>';
981
  echo '</div>'; // wrap
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
982
  } // plugin_page
983
 
984
 
@@ -987,7 +1346,8 @@ class WP_Reset {
987
  *
988
  * @return null
989
  */
990
- private function tab_reset() {
 
991
  global $current_user, $wpdb;
992
 
993
  echo '<div class="card" id="card-description">';
@@ -1018,9 +1378,17 @@ class WP_Reset {
1018
  echo '</ul>';
1019
 
1020
  echo '<b>' . __('WP-CLI Support', 'wp-reset') . '</b>';
1021
- 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>');
1022
  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>';
1023
- echo '</div>';
 
 
 
 
 
 
 
 
1024
 
1025
  $theme = wp_get_theme();
1026
 
@@ -1029,7 +1397,15 @@ class WP_Reset {
1029
  echo '<h2>' . __('Post-reset actions', 'wp-reset') . '</h2>';
1030
  echo '<p><label for="reactivate-theme"><input name="wpr-post-reset[reactivate_theme]" type="checkbox" id="reactivate-theme" value="1"> ' . __('Reactivate current theme', 'wp-reset') . ' - ' . $theme->get('Name') . '</label></p>';
1031
  echo '<p><label for="reactivate-wpreset"><input name="wpr-post-reset[reactivate_wpreset]" type="checkbox" id="reactivate-wpreset" value="1" checked> ' . __('Reactivate WP Reset plugin', 'wp-reset') . '</label></p>';
 
 
 
1032
  echo '<p><label for="reactivate-plugins"><input name="wpr-post-reset[reactivate_plugins]" type="checkbox" id="reactivate-plugins" value="1"> ' . __('Reactivate all currently active plugins', 'wp-reset') . '</label></p>';
 
 
 
 
 
1033
  echo '</div>';
1034
 
1035
  echo '<div class="card">';
@@ -1037,7 +1413,7 @@ class WP_Reset {
1037
  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 WP Reset.</b>', 'wp-reset') . '</p>';
1038
 
1039
  wp_nonce_field('wp-reset');
1040
- echo '<p><input id="wp_reset_confirm" type="text" name="wp_reset_confirm" placeholder="' . esc_attr__('Type in "reset"', 'wp-reset'). '" value="" autocomplete="off"> &nbsp;';
1041
  echo '<input id="wp_reset_submit" type="button" class="button-primary" value="' . __('Reset WordPress', 'wp-reset') . '"></p>';
1042
  echo '</div>';
1043
  } // tab_reset
@@ -1048,13 +1424,14 @@ class WP_Reset {
1048
  *
1049
  * @return null
1050
  */
1051
- private function tab_tools() {
 
1052
  global $wpdb;
1053
 
1054
  echo '<div class="card">';
1055
  echo '<h2>' . __('Delete Transients', 'wp-reset') . '</h2>';
1056
  echo '<p>' . __('All transient related database entries will be deleted. Including expired and non-expired transients, and orphaned transient timeout entries.<br><b>There is NO UNDO. WP Reset does not make any backups.</b>', 'wp-reset') . '</p>';
1057
- echo '<p><a data-btn-confirm="Delete all transients" data-text-wait="Deleting transients. Please wait." data-text-confirm="All database entries related to transients will be deleted. There is NO UNDO. WP Reset will not make any backups." data-text-done="%n transient database entries have been deleted." class="button button-delete" href="#" id="delete-transients">Delete all transients</a></p>';
1058
  echo '</div>';
1059
 
1060
  $upload_dir = wp_upload_dir(date('Y/m'), true);
@@ -1066,7 +1443,7 @@ class WP_Reset {
1066
  if (false != $upload_dir['error']) {
1067
  echo '<p><span style="color:#dd3036;"><b>Tool is not available.</b></span> Folder is not writeable by WordPress. Please check file and folder access rights.</p>';
1068
  } else {
1069
- echo '<p><a data-btn-confirm="Delete everything in uploads folder" data-text-wait="Deleting uploads. Please wait." data-text-confirm="All files and folders in uploads will be deleted. There is NO UNDO. WP Reset will not make any backups." data-text-done="%n files &amp; folders have been deleted." class="button button-delete" href="#" id="delete-uploads">Delete all files &amp; folders in uploads folder</a></p>';
1070
  }
1071
  echo '</div>';
1072
 
@@ -1075,13 +1452,13 @@ class WP_Reset {
1075
  echo '<div class="card">';
1076
  echo '<h2>' . __('Delete Themes', 'wp-reset') . '</h2>';
1077
  echo '<p>' . __('All themes will be deleted. Including the currently active theme - ' . $theme->get('Name') . '.<br><b>There is NO UNDO. WP Reset does not make any backups.</b>', 'wp-reset') . '</p>';
1078
- echo '<p><a data-btn-confirm="Delete all themes" data-text-wait="Deleting all themes. Please wait." data-text-confirm="All themes will be deleted. There is NO UNDO. WP Reset will not make any backups." data-text-done="%n themes have been deleted." class="button button-delete" href="#" id="delete-themes">Delete all themes</a></p>';
1079
  echo '</div>';
1080
 
1081
  echo '<div class="card">';
1082
  echo '<h2>' . __('Delete Plugins', 'wp-reset') . '</h2>';
1083
  echo '<p>' . __('All plugins will be deleted except for WP Reset which will remain active.<br><b>There is NO UNDO. WP Reset does not make any backups.</b>', 'wp-reset') . '</p>';
1084
- echo '<p><a data-btn-confirm="Delete plugins" data-text-wait="Deleting plugins. Please wait." data-text-confirm="All plugins except WP Reset will be deleted. There is NO UNDO. WP Reset will not make any backups." data-text-done="%n plugins have been deleted." class="button button-delete" href="#" id="delete-plugins">Delete plugins</a></p>';
1085
  echo '</div>';
1086
 
1087
  $custom_tables = $this->get_custom_tables();
@@ -1103,8 +1480,8 @@ class WP_Reset {
1103
  echo '<p>' . __('There are no custom tables. There\'s nothing for this tool to empty or delete.', 'wp-reset') . '</p>';
1104
  $custom_tables_btns = ' disabled';
1105
  }
1106
- echo '<p><a data-btn-confirm="Empty custom tables" data-text-wait="Emptying custom tables. Please wait." data-text-confirm="All custom tables with prefix <code>' . $wpdb->prefix . '</code> will be emptied. There is NO UNDO. WP Reset will not make any backups." data-text-done="%n custom tables have been emptied." class="button button-delete' . $custom_tables_btns . '" href="#" id="truncate-custom-tables">Empty (truncate) custom tables</a>&nbsp; &nbsp;';
1107
- echo '<a data-btn-confirm="Delete custom tables" data-text-wait="Deleting custom tables. Please wait." data-text-confirm="All custom tables with prefix <code>' . $wpdb->prefix . '</code> will be deleted. There is NO UNDO. WP Reset will not make any backups." data-text-done="%n custom tables have been deleted." class="button button-delete' . $custom_tables_btns . '" href="#" id="drop-custom-tables">Delete (drop) custom tables</a></p>';
1108
 
1109
  echo '</div>';
1110
 
@@ -1125,7 +1502,8 @@ class WP_Reset {
1125
  *
1126
  * @return null
1127
  */
1128
- private function tab_support() {
 
1129
  echo '<div class="card">';
1130
  echo '<h2>' . __('Public support forum', 'wp-reset') . '</h2>';
1131
  echo '<p>' . __('We are very active on the <a href="https://wordpress.org/support/plugin/wp-reset" target="_blank">official WP Reset support forum</a>. If you found a bug, have a feature idea or just want to say hi - please drop by. We love to hear back from our users.', 'wp-reset') . '</p>';
@@ -1148,7 +1526,8 @@ class WP_Reset {
1148
  *
1149
  * @return null
1150
  */
1151
- private function tab_snapshots() {
 
1152
  global $wpdb;
1153
  $tbl_core = $tbl_custom = $tbl_size = $tbl_rows = 0;
1154
 
@@ -1157,7 +1536,7 @@ class WP_Reset {
1157
  echo '<h2>' . __('Database Snapshots', 'wp-reset') . '</h2>';
1158
  echo '<p>A snapshot is a copy of all WP database tables, standard and custom ones, saved in your database. Files are not saved or included in snapshots in any way.<br>
1159
  Snapshots are primarily a development tool. Although they can be used for backups (and downloaded), we suggest finding a more suitable tool for live sites, such as <a href="https://wordpress.org/plugins/updraftplus/" target="_blank">UpdraftPlus</a>. Use snapshots to find out what changes a plugin made to your database or to quickly restore the dev environment after testing database related changes.<br>Restoring a snapshot does not affect other snapshots, or WP Reset settings.</p>';
1160
- echo '<p>Snapshots are still in development. If you see a bug or just have an idea how to make the tool better, please let us know <a href="https://twitter.com/WebFactoryLtd" target="_blank">@webfactoryltd</a> or <a href="mailto:wpreset@webfactoryltd.com?subject=WPR%20DB%20Snapshots%20Feedback">email us</a>. Thank you!</p>';
1161
 
1162
  $table_status = $wpdb->get_results('SHOW TABLE STATUS');
1163
  if (is_array($table_status)) {
@@ -1180,11 +1559,11 @@ class WP_Reset {
1180
 
1181
  echo '<p><b>Currently used WordPress tables</b>, prefixed with <i>' . $wpdb->prefix . '</i>, consist of ' . $tbl_core . ' standard and ';
1182
  if ($tbl_custom) {
1183
- echo $tbl_custom . ' custom table' . ($tbl_custom == 1? '': 's');
1184
  } else {
1185
  echo 'no custom tables';
1186
  }
1187
- echo ' totaling ' . $this->format_size($tbl_size) .' in ' . number_format($tbl_rows) . ' rows.</p>';
1188
  }
1189
 
1190
  echo '';
@@ -1208,7 +1587,7 @@ class WP_Reset {
1208
  }
1209
  echo '<td>' . $ss['tbl_core'] . ' standard &amp; ';
1210
  if ($ss['tbl_custom']) {
1211
- echo $ss['tbl_custom'] . ' custom table' . ($ss['tbl_custom'] == 1? '': 's');
1212
  } else {
1213
  echo 'no custom tables';
1214
  }
@@ -1230,33 +1609,6 @@ class WP_Reset {
1230
  } // tab_snapshots
1231
 
1232
 
1233
- /**
1234
- * Echoes content for sponsor tab
1235
- *
1236
- * @return null
1237
- */
1238
- private function tab_geoip() {
1239
- echo '<div class="card">';
1240
- echo '<h2>' . __('WP Reset is proudly sponsored by IP Geolocation', 'wp-reset') . '</h2>';
1241
- echo '<p>' . __('Keeping a plugin maintained, supported and free is neither easy nor cheap that\'s why we\'re thrilled that a <a href="https://ipgeolocation.io/" target="_blank">premium GeoIP service</a> decided to sponsor WP Reset. No notifications, no popups, no shady links. They keep the plugin free and clean.', 'wp-reset') . '</p>';
1242
- echo '</div>';
1243
-
1244
- echo '<div class="card">';
1245
- echo '<h2>' . __('Why would I need a GeoIP service?', 'wp-reset') . '</h2>';
1246
- echo '<p>' . __('IP addresses are boring and don\'t mean much to people. However, they can easily be transformed into a huge source of data by using a GeoIP service. From filtering and segmenting users to providing a better UX - geographical data can enhance any web app! See an <a href="https://wpreset.com/geoip-transform-boring-data-better-user-experience/" target="_blank">example</a> we recently wrote about.', 'wp-reset') . '</p>';
1247
- echo '<p><a href="https://ipgeolocation.io/ip-location" target="_blank" class="button">See what data is available for your IP address</a></p>';
1248
- echo '</div>';
1249
-
1250
- echo '<div class="card">';
1251
- echo '<h2>' . __('Get a free account', 'wp-reset') . '</h2>';
1252
- echo '<p>' . __('IP Geolocation knows how difficult it is to start any new project. That\'s why they offer <a href="https://ipgeolocation.io/signup" target="_blank">50,000 API requests per month for free</a>. No credit card required, no tricks - just register for an account and you can use the service. It\'s a great way to add value to any web project.' , 'wp-reset') . '</p>';
1253
- echo '<p><a href="https://ipgeolocation.io/signup" target="_blank" class="button">Get a FREE account with 50,000 API requests a month</a></p>';
1254
- echo '</div>';
1255
-
1256
- echo '<p>Permanently <a href="#" class="wpr-dismiss-notice" data-notice="geoip_tab">remove this tab</a>.</p>';
1257
- } // tab_geoip
1258
-
1259
-
1260
  /**
1261
  * Helper function for generating UTM tagged links
1262
  *
@@ -1267,7 +1619,8 @@ class WP_Reset {
1267
  *
1268
  * @return string
1269
  */
1270
- function generate_web_link($placement = '', $page = '/', $params = array(), $anchor = '') {
 
1271
  $base_url = 'https://wpreset.com';
1272
 
1273
  if ('/' != $page) {
@@ -1294,7 +1647,8 @@ class WP_Reset {
1294
  *
1295
  * @return array
1296
  */
1297
- function get_snapshots() {
 
1298
  $snapshots = get_option('wp-reset-snapshots', array());
1299
 
1300
  return $snapshots;
@@ -1306,7 +1660,8 @@ class WP_Reset {
1306
  *
1307
  * @return array
1308
  */
1309
- function get_custom_tables() {
 
1310
  global $wpdb;
1311
  $custom_tables = array();
1312
 
@@ -1337,7 +1692,8 @@ class WP_Reset {
1337
  *
1338
  * @return string
1339
  */
1340
- function format_size($bytes) {
 
1341
  if ($bytes > 1073741824) {
1342
  return number_format_i18n($bytes / 1073741824, 2) . ' GB';
1343
  } elseif ($bytes > 1048576) {
@@ -1357,7 +1713,8 @@ class WP_Reset {
1357
  *
1358
  * @return array|WP_Error Snapshot details in array on success, or error object on fail.
1359
  */
1360
- function do_create_snapshot($name = '') {
 
1361
  global $wpdb;
1362
  $snapshots = $this->get_snapshots();
1363
  $snapshot = array();
@@ -1395,7 +1752,7 @@ class WP_Reset {
1395
  }
1396
 
1397
  $wpdb->query('OPTIMIZE TABLE ' . $table->Name);
1398
- $wpdb->query('CREATE TABLE ' . $uid . '_' . $table->Name .' LIKE ' . $table->Name);
1399
  $wpdb->query('INSERT ' . $uid . '_' . $table->Name . ' SELECT * FROM ' . $table->Name);
1400
  } // foreach
1401
  } else {
@@ -1422,7 +1779,8 @@ class WP_Reset {
1422
  *
1423
  * @return bool|WP_Error True on success, or error object on fail.
1424
  */
1425
- function do_delete_snapshot($uid = '') {
 
1426
  global $wpdb;
1427
  $snapshots = $this->get_snapshots();
1428
 
@@ -1453,7 +1811,8 @@ class WP_Reset {
1453
  *
1454
  * @return string|WP_Error Export base filename, or error object on fail.
1455
  */
1456
- function do_export_snapshot($uid = '') {
 
1457
  global $wpdb;
1458
  $snapshots = $this->get_snapshots();
1459
 
@@ -1481,7 +1840,7 @@ class WP_Reset {
1481
  }
1482
 
1483
  $world_dumper->dump(trailingslashit(WP_CONTENT_DIR) . $this->snapshots_folder . '/wp-reset-snapshot-' . $uid . '.sql.gz', $uid . '_');
1484
- } catch(Shuttle_Exception $e) {
1485
  return new WP_Error(1, "Couldn't dump snapshot: " . $e->getMessage());
1486
  }
1487
 
@@ -1496,7 +1855,8 @@ class WP_Reset {
1496
  *
1497
  * @return bool|WP_Error True on success, or error object on fail.
1498
  */
1499
- function do_restore_snapshot($uid = '') {
 
1500
  global $wpdb;
1501
  $new_tables = array();
1502
  $snapshots = $this->get_snapshots();
@@ -1555,7 +1915,8 @@ class WP_Reset {
1555
  *
1556
  * @return bool|WP_Error True on success, or error object on fail.
1557
  */
1558
- function verify_snapshot_integrity($uid) {
 
1559
  global $wpdb;
1560
  $tbl_core = $tbl_custom = 0;
1561
  $snapshots = $this->get_snapshots();
@@ -1605,7 +1966,8 @@ class WP_Reset {
1605
  *
1606
  * @return string|WP_Error Formatted table with details on success, or error object on fail.
1607
  */
1608
- function do_compare_snapshots($uid) {
 
1609
  global $wpdb;
1610
  $tbl_core = $tbl_custom = 0;
1611
  $current = $snapshot = array();
@@ -1662,7 +2024,7 @@ class WP_Reset {
1662
  $out .= '</tr>';
1663
  $out .= '<tr class="hidden">';
1664
  $out .= '<td>';
1665
- $out .= '<p>' . number_format($table['rows']) . ' row' . ($table['rows'] == 1? '': 's') . ' totaling ' . $this->format_size($table['size_data']) . ' in data and ' . $this->format_size($table['size_index']) . ' in index.</p>';
1666
  $out .= '<pre>' . $table['schema'] . '</pre>';
1667
  $out .= '</td>';
1668
  $out .= '<td>&nbsp;</td>';
@@ -1681,7 +2043,7 @@ class WP_Reset {
1681
  $out .= '<tr class="hidden">';
1682
  $out .= '<td>&nbsp;</td>';
1683
  $out .= '<td>';
1684
- $out .= '<p>' . number_format($table['rows']) . ' row' . ($table['rows'] == 1? '': 's') . ' totaling ' . $this->format_size($table['size_data']) . ' in data and ' . $this->format_size($table['size_index']) . ' in index.</p>';
1685
  $out .= '<pre>' . $table['schema'] . '</pre>';
1686
  $out .= '</td>';
1687
  $out .= '</tr>';
@@ -1772,14 +2134,14 @@ class WP_Reset {
1772
  foreach ($diff_rows as $row) {
1773
  $out2 .= '<tr>';
1774
  $out2 .= '<td style="width: 100px;">' . $row->option_name . '</td>';
1775
- $out2 .= '<td>' . (empty($row->current_value)? '<i>empty</i>': $row->current_value) . '</td>';
1776
- $out2 .= '<td>' . (empty($row->snapshot_value)? '<i>empty</i>': $row->snapshot_value) . '</td>';
1777
  $out2 .= '</tr>';
1778
  } // foreach
1779
  foreach ($only_current as $row) {
1780
  $out2 .= '<tr>';
1781
  $out2 .= '<td style="width: 100px;">' . $row->option_name . '</td>';
1782
- $out2 .= '<td>' . (empty($row->current_value)? '<i>empty</i>': $row->current_value) . '</td>';
1783
  $out2 .= '<td><i>not found in snapshot</i></td>';
1784
  $out2 .= '</tr>';
1785
  } // foreach
@@ -1787,7 +2149,7 @@ class WP_Reset {
1787
  $out2 .= '<tr>';
1788
  $out2 .= '<td style="width: 100px;">' . $row->option_name . '</td>';
1789
  $out2 .= '<td><i>not found in current tables</i></td>';
1790
- $out2 .= '<td>' . (empty($row->snapshot_value)? '<i>empty</i>': $row->snapshot_value) . '</td>';
1791
  $out2 .= '</tr>';
1792
  } // foreach
1793
  $out2 .= '</table>';
@@ -1811,7 +2173,8 @@ class WP_Reset {
1811
  *
1812
  * @return string
1813
  */
1814
- function generate_snapshot_uid() {
 
1815
  global $wpdb;
1816
  $snapshots = $this->get_snapshots();
1817
  $cnt = 0;
@@ -1837,7 +2200,8 @@ class WP_Reset {
1837
  *
1838
  * @return array
1839
  */
1840
- function featured_plugins_tab($args) {
 
1841
  add_filter('plugins_api_result', array($this, 'plugins_api_result'), 10, 3);
1842
 
1843
  return $args;
@@ -1849,11 +2213,12 @@ class WP_Reset {
1849
  *
1850
  * @return object
1851
  */
1852
- function add_plugin_featured($plugin_slug, $res) {
1853
- // check if plugin is alredy on the list
 
1854
  if (!empty($res->plugins) && is_array($res->plugins)) {
1855
  foreach ($res->plugins as $plugin) {
1856
- if ($plugin->slug == $plugin_slug) {
1857
  return $res;
1858
  }
1859
  } // foreach
@@ -1866,18 +2231,16 @@ class WP_Reset {
1866
  'slug' => $plugin_slug,
1867
  'is_ssl' => is_ssl(),
1868
  'fields' => array(
1869
- 'banners' => true,
1870
- 'reviews' => true,
1871
- 'downloaded' => true,
1872
- 'active_installs' => true,
1873
- 'icons' => true,
1874
- 'short_description' => true,
1875
  )
1876
  ));
1877
  if (!is_wp_error($plugin_info)) {
1878
- $tmp1 = array_slice($res->plugins, 0, 2, false);
1879
- $tmp2 = array_slice($res->plugins, 2, sizeof($res->plugins) - 2, false);
1880
- $res->plugins = array_merge($tmp1, array($plugin_info), $tmp2);
1881
  set_transient('wf-plugin-info-' . $plugin_slug, $plugin_info, DAY_IN_SECONDS * 7);
1882
  }
1883
  }
@@ -1891,10 +2254,12 @@ class WP_Reset {
1891
  *
1892
  * @return object
1893
  */
1894
- function plugins_api_result($res, $action, $args) {
 
1895
  remove_filter('plugins_api_result', array($this, 'plugins_api_result'), 10, 3);
1896
 
1897
  $res = $this->add_plugin_featured('security-ninja', $res);
 
1898
 
1899
  return $res;
1900
  } // plugins_api_result
@@ -1905,7 +2270,8 @@ class WP_Reset {
1905
  *
1906
  * @return null
1907
  */
1908
- static function uninstall() {
 
1909
  delete_option('wp-reset');
1910
  delete_option('wp-reset-snapshots');
1911
  } // uninstall
@@ -1916,7 +2282,8 @@ class WP_Reset {
1916
  *
1917
  * @return null
1918
  */
1919
- private function __clone() {}
 
1920
 
1921
 
1922
  /**
@@ -1924,7 +2291,8 @@ class WP_Reset {
1924
  *
1925
  * @return null
1926
  */
1927
- private function __sleep() {}
 
1928
 
1929
 
1930
  /**
@@ -1932,7 +2300,8 @@ class WP_Reset {
1932
  *
1933
  * @return null
1934
  */
1935
- private function __wakeup() {}
 
1936
  } // WP_Reset class
1937
 
1938
 
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.55
7
  Author: WebFactory Ltd
8
  Author URI: https://www.webfactoryltd.com/
9
  Text Domain: wp-reset
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
+ {
41
  protected static $instance = null;
42
  public $version = 0;
43
  public $plugin_url = '';
45
  public $snapshots_folder = 'wp-reset-snapshots-export';
46
  protected $options = array();
47
  private $delete_count = 0;
48
+ private $licensing_servers = array('https://license1.wpreset.com/', 'https://license2.wpreset.com/');
49
  private $core_tables = array('commentmeta', 'comments', 'links', 'options', 'postmeta', 'posts', 'term_relationships', 'term_taxonomy', 'termmeta', 'terms', 'usermeta', 'users');
50
 
51
 
54
  *
55
  * @return WP_Reset
56
  */
57
+ static function getInstance()
58
+ {
59
  if (!is_a(self::$instance, 'WP_Reset')) {
60
  self::$instance = new WP_Reset();
61
  }
69
  *
70
  * @return null
71
  */
72
+ private function __construct()
73
+ {
74
  $this->version = $this->get_plugin_version();
75
  $this->plugin_dir = plugin_dir_path(__FILE__);
76
  $this->plugin_url = plugin_dir_url(__FILE__);
81
  add_action('admin_enqueue_scripts', array($this, 'admin_enqueue_scripts'));
82
  add_action('wp_ajax_wp_reset_dismiss_notice', array($this, 'ajax_dismiss_notice'));
83
  add_action('wp_ajax_wp_reset_run_tool', array($this, 'ajax_run_tool'));
84
+ add_action('wp_ajax_wp_reset_submit_survey', array($this, 'ajax_submit_survey'));
85
+ add_action('admin_action_install_webhooks', array($this, 'install_webhooks'));
86
 
87
  add_filter('plugin_action_links_' . plugin_basename(__FILE__), array($this, 'plugin_action_links'));
88
  add_filter('plugin_row_meta', array($this, 'plugin_meta_links'), 10, 2);
89
  add_filter('admin_footer_text', array($this, 'admin_footer_text'));
90
  add_filter('install_plugins_table_api_args_featured', array($this, 'featured_plugins_tab'));
91
 
92
+ $this->core_tables = array_map(function ($tbl) {
93
+ global $wpdb;
94
+ return $wpdb->prefix . $tbl;
95
+ }, $this->core_tables);
96
  } // __construct
97
 
98
 
101
  *
102
  * @return string
103
  */
104
+ function get_plugin_version()
105
+ {
106
  $plugin_data = get_file_data(__FILE__, array('version' => 'Version'), 'plugin');
107
 
108
  return $plugin_data['version'];
115
  *
116
  * @return array
117
  */
118
+ private function load_options()
119
+ {
120
  $options = get_option('wp-reset', array());
121
  $change = false;
122
 
150
  *
151
  * @return array
152
  */
153
+ function get_meta()
154
+ {
155
  return $this->options['meta'];
156
  } // get_meta
157
 
163
  *
164
  * @return bool|array
165
  */
166
+ function get_dismissed_notices($notice_name = '')
167
+ {
168
  $notices = $this->options['dismissed_notices'];
169
 
170
  if (empty($notice_name)) {
188
  *
189
  * @return array
190
  */
191
+ function get_options($key = '')
192
+ {
193
  return $this->options['options'];
194
  } // get_options
195
 
204
  *
205
  * @return bool
206
  */
207
+ function update_options($key, $data)
208
+ {
209
  $this->options[$key] = $data;
210
  $tmp = update_option('wp-reset', $this->options);
211
 
218
  *
219
  * @return null
220
  */
221
+ function admin_menu()
222
+ {
223
  add_management_page(__('WP Reset', 'wp-reset'), __('WP Reset', 'wp-reset'), 'administrator', 'wp-reset', array($this, 'plugin_page'));
224
  } // admin_menu
225
 
229
  *
230
  * @return null
231
  */
232
+ function ajax_dismiss_notice()
233
+ {
234
  check_ajax_referer('wp-reset_dismiss_notice');
235
 
236
  if (!current_user_can('administrator')) {
253
  *
254
  * @return bool
255
  */
256
+ function dismiss_notice($notice_name)
257
+ {
258
  if ($this->get_dismissed_notices($notice_name)) {
259
  return false;
260
  } else {
271
  *
272
  * @return array
273
  */
274
+ function get_pointers()
275
+ {
276
  $pointers = array();
277
 
278
+ $pointers['welcome'] = array('target' => '#menu-tools', 'edge' => 'left', 'align' => 'right', 'content' => 'Thank you for installing the <b style="font-weight: 800;">WP Reset</b> plugin!<br>Open <a href="' . admin_url('tools.php?page=wp-reset') . '">Tools - WP Reset</a> to access resetting tools and start developing &amp; debugging faster.');
279
 
280
  return $pointers;
281
  } // get_pointers
286
  *
287
  * @return null
288
  */
289
+ function admin_enqueue_scripts($hook)
290
+ {
291
  // welcome pointer is shown on all pages except WPR to admins, until dismissed
292
  $pointers = $this->get_pointers();
293
  $dismissed_notices = $this->get_dismissed_notices();
294
+ $meta = $this->get_meta();
295
 
296
  foreach ($dismissed_notices as $notice_name => $tmp) {
297
  if ($tmp) {
314
  return;
315
  }
316
 
317
+ // features survey is shown 5min after install or after first reset
318
+ $survey = false;
319
+ if ($this->is_survey_active('features')) {
320
+ $survey = true;
321
+ }
322
+
323
+ $js_localize = array(
324
+ 'undocumented_error' => __('An undocumented error has occurred. Please refresh the page and try again.', 'wp-reset'),
325
+ 'documented_error' => __('An error has occurred.', 'wp-reset'),
326
+ 'plugin_name' => __('WP Reset', 'wp-reset'),
327
+ 'settings_url' => admin_url('tools.php?page=wp-reset'),
328
+ 'icon_url' => $this->plugin_url . 'img/wp-reset-icon.png',
329
+ 'invalid_confirmation' => __('Please type "reset" in the confirmation field.', 'wp-reset'),
330
+ 'invalid_confirmation_title' => __('Invalid confirmation', 'wp-reset'),
331
+ 'cancel_button' => __('Cancel', 'wp-reset'),
332
+ 'open_survey' => $survey,
333
+ 'ok_button' => __('OK', 'wp-reset'),
334
+ 'confirm_button' => __('Reset WordPress', 'wp-reset'),
335
+ 'confirm_title' => __('Are you sure you want to proceed?', 'wp-reset'),
336
+ 'confirm1' => __('Clicking "Reset WordPress" will reset your site to default values. All content will be lost. There is NO UNDO.', 'wp-reset'),
337
+ 'confirm2' => __('Click "Cancel" to abort.', 'wp-reset'),
338
+ 'doing_reset' => __('Resetting in progress. Please wait.', 'wp-reset'),
339
+ 'nonce_dismiss_notice' => wp_create_nonce('wp-reset_dismiss_notice'),
340
+ 'nonce_run_tool' => wp_create_nonce('wp-reset_run_tool'),
341
+ 'nonce_do_reset' => wp_create_nonce('wp-reset_do_reset'),
342
+ );
343
+
344
+ if ($survey) {
345
+ $js_localize['nonce_submit_survey'] = wp_create_nonce('wp-reset_submit_survey');
346
+ }
347
+ if (!$this->is_webhooks_active()) {
348
+ $js_localize['webhooks_install_url'] = add_query_arg(array('action' => 'install_webhooks'), admin_url('admin.php'));
349
+ }
350
+
351
+ wp_enqueue_style('wp-jquery-ui-dialog');
352
  wp_enqueue_style('wp-reset', $this->plugin_url . 'css/wp-reset.css', array(), $this->version);
353
  wp_enqueue_style('wp-reset-sweetalert2', $this->plugin_url . 'css/sweetalert2.min.css', array(), $this->version);
354
 
355
+ wp_enqueue_script('jquery-ui-dialog');
356
  wp_enqueue_script('jquery-ui-tabs');
357
  wp_enqueue_script('wp-reset-sweetalert2', $this->plugin_url . 'js/sweetalert2.min.js', array('jquery'), $this->version, true);
358
  wp_enqueue_script('wp-reset', $this->plugin_url . 'js/wp-reset.js', array('jquery'), $this->version, true);
360
 
361
  // fix for aggressive plugins that include their CSS on all pages
362
  wp_dequeue_style('uiStyleSheet');
363
+ wp_dequeue_style('wpcufpnAdmin');
364
+ wp_dequeue_style('unifStyleSheet');
365
  wp_dequeue_style('wpcufpn_codemirror');
366
  wp_dequeue_style('wpcufpn_codemirrorTheme');
367
  wp_dequeue_style('collapse-admin-css');
374
  } // admin_enqueue_scripts
375
 
376
 
377
+ /**
378
+ * Submit user selected survey answers to WPR servers
379
+ *
380
+ * @return null
381
+ */
382
+ function ajax_submit_survey()
383
+ {
384
+ check_ajax_referer('wp-reset_submit_survey');
385
+
386
+ $meta = $this->get_meta();
387
+
388
+ $vars = wp_parse_args($_POST, array('survey' => '', 'answers' => '', 'custom_answer' => '', 'emailme' => ''));
389
+ $vars['answers'] = trim($vars['answers'], ',');
390
+ $vars['custom_answer'] = substr(trim(strip_tags($vars['custom_answer'])), 0, 256);
391
+
392
+ if (empty($vars['survey']) || empty($vars['answers'])) {
393
+ wp_send_json_error();
394
+ }
395
+
396
+ $request_params = array('sslverify' => false, 'timeout' => 15, 'redirection' => 2);
397
+ $request_args = array(
398
+ 'action' => 'submit_survey',
399
+ 'survey' => $vars['survey'],
400
+ 'email' => $vars['emailme'],
401
+ 'answers' => $vars['answers'],
402
+ 'custom_answer' => $vars['custom_answer'],
403
+ 'first_version' => $meta['first_version'],
404
+ 'version' => $this->version,
405
+ 'codebase' => 'free',
406
+ 'site' => get_home_url()
407
+ );
408
+
409
+ $url = add_query_arg($request_args, $this->licensing_servers[0]);
410
+ $response = wp_remote_get(esc_url_raw($url), $request_params);
411
+
412
+ if (is_wp_error($response) || !wp_remote_retrieve_body($response)) {
413
+ $url = add_query_arg($request_args, $this->licensing_servers[1]);
414
+ $response = wp_remote_get(esc_url_raw($url), $request_params);
415
+ }
416
+
417
+ $this->dismiss_notice('survey-' . $vars['survey']);
418
+
419
+ wp_send_json_success();
420
+ } // ajax_submit_survey
421
+
422
+
423
+ /**
424
+ * Check if named survey should be shown or not
425
+ *
426
+ * @param [string] $survey_name Name of the survey to check
427
+ * @return boolean
428
+ */
429
+ function is_survey_active($survey_name)
430
+ {
431
+ if (empty($survey_name)) {
432
+ return false;
433
+ }
434
+
435
+ if ($this->get_dismissed_notices('survey-' . $survey_name)) {
436
+ return false;
437
+ }
438
+
439
+ $meta = $this->get_meta();
440
+ if (current_time('timestamp', true) - $meta['first_install'] > 300 || $meta['reset_count'] > 0) {
441
+ return true;
442
+ }
443
+
444
+ return false;
445
+ } // is_survey_active
446
+
447
  /**
448
  * Check if WP-CLI is available and running
449
  *
450
  * @return bool
451
  */
452
+ static function is_cli_running()
453
+ {
454
+ if (!is_null($value = apply_filters('wp-reset-override-is-cli-running', null))) {
455
+ return (bool)$value;
456
+ }
457
+
458
  if (defined('WP_CLI') && WP_CLI) {
459
  return true;
460
  } else {
463
  } // is_cli_running
464
 
465
 
466
+ /**
467
+ * Check if core WP Webhooks and WPR addon plugins are installed and activated
468
+ *
469
+ * @return bool
470
+ */
471
+ function is_webhooks_active()
472
+ {
473
+ if (!function_exists('is_plugin_active') || !function_exists('get_plugin_data')) {
474
+ require_once ABSPATH . 'wp-admin/includes/plugin.php';
475
+ }
476
+
477
+ if (false == is_plugin_active('wp-webhooks/wp-webhooks.php')) {
478
+ return false;
479
+ }
480
+
481
+ if (false == is_plugin_active('wpwh-wp-reset-webhook-integration/wpwhpro-wp-reset-webhook-integration.php')) {
482
+ return false;
483
+ }
484
+
485
+ return true;
486
+ } // is_webhooks_active
487
+
488
+
489
+ /**
490
+ * Check if given plugin is installed
491
+ *
492
+ * @param [string] $slug Plugin slug
493
+ * @return boolean
494
+ */
495
+ function is_plugin_installed($slug)
496
+ {
497
+ if (!function_exists('get_plugins')) {
498
+ require_once ABSPATH . 'wp-admin/includes/plugin.php';
499
+ }
500
+ $all_plugins = get_plugins();
501
+
502
+ if (!empty($all_plugins[$slug])) {
503
+ return true;
504
+ } else {
505
+ return false;
506
+ }
507
+ } // is_plugin_installed
508
+
509
+
510
+ /**
511
+ * Auto download/install/upgrade/activate WP Webhooks plugin
512
+ *
513
+ * @return null
514
+ */
515
+ static function install_webhooks()
516
+ {
517
+ $plugin_slug = 'wp-webhooks/wp-webhooks.php';
518
+ $plugin_zip = 'https://downloads.wordpress.org/plugin/wp-webhooks.latest-stable.zip';
519
+
520
+ @include_once ABSPATH . 'wp-admin/includes/plugin.php';
521
+ @include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
522
+ @include_once ABSPATH . 'wp-admin/includes/plugin-install.php';
523
+ @include_once ABSPATH . 'wp-admin/includes/file.php';
524
+ @include_once ABSPATH . 'wp-admin/includes/misc.php';
525
+ echo '<style>
526
+ body{
527
+ font-family: sans-serif;
528
+ font-size: 14px;
529
+ line-height: 1.5;
530
+ color: #444;
531
+ }
532
+ </style>';
533
+
534
+ echo '<div style="margin: 20px; color:#444;">';
535
+ echo 'If things are not done in a minute <a target="_parent" href="' . admin_url('plugin-install.php?s=ironikus&tab=search&type=term') . '">install the plugin manually via Plugins page</a><br><br>';
536
+
537
+ wp_cache_flush();
538
+ $upgrader = new Plugin_Upgrader();
539
+ echo 'Check if WP Webhooks plugin is already installed ... <br />';
540
+ if (self::is_plugin_installed($plugin_slug)) {
541
+ echo 'WP Webhooks is already installed!<br />Making sure it\'s the latest version.<br />';
542
+ $upgrader->upgrade($plugin_slug);
543
+ $installed = true;
544
+ } else {
545
+ echo 'Installing WP Webhooks.<br />';
546
+ $installed = $upgrader->install($plugin_zip);
547
+ }
548
+ wp_cache_flush();
549
+
550
+ if (!is_wp_error($installed) && $installed) {
551
+ echo 'Activating WP Webhooks.<br />';
552
+ $activate = activate_plugin($plugin_slug);
553
+
554
+ if (is_null($activate)) {
555
+ echo 'WP Webhooks activated.<br />';
556
+ }
557
+ } else {
558
+ echo 'Could not install WP Webhooks. You\'ll have to <a target="_parent" href="' . admin_url('plugin-install.php?s=ironikus&tab=search&type=term') . '">download and install manually</a>.';
559
+ }
560
+
561
+ $plugin_slug = 'wpwh-wp-reset-webhook-integration/wpwhpro-wp-reset-webhook-integration.php';
562
+ $plugin_zip = 'https://downloads.wordpress.org/plugin/wpwh-wp-reset-webhook-integration.latest-stable.zip';
563
+
564
+ wp_cache_flush();
565
+ $upgrader = new Plugin_Upgrader();
566
+ echo '<br>Check if WP Webhooks WPR addon plugin is already installed ... <br />';
567
+ if (self::is_plugin_installed($plugin_slug)) {
568
+ echo 'WP Webhooks WPR addon is already installed!<br />Making sure it\'s the latest version.<br />';
569
+ $upgrader->upgrade($plugin_slug);
570
+ $installed = true;
571
+ } else {
572
+ echo 'Installing WP Webhooks WPR addon.<br />';
573
+ $installed = $upgrader->install($plugin_zip);
574
+ }
575
+ wp_cache_flush();
576
+
577
+ if (!is_wp_error($installed) && $installed) {
578
+ echo 'Activating WP Webhooks WPR addon.<br />';
579
+ $activate = activate_plugin($plugin_slug);
580
+
581
+ if (is_null($activate)) {
582
+ echo 'WP Webhooks WPR addon activated.<br />';
583
+
584
+ echo '<script>setTimeout(function() { top.location = "tools.php?page=wp-reset"; }, 1000);</script>';
585
+ echo '<br>If you are not redirected in a few seconds - <a href="tools.php?page=wp-reset" target="_parent">click here</a>.';
586
+ }
587
+ } else {
588
+ echo 'Could not install WP Webhooks WPR addon. You\'ll have to <a target="_parent" href="' . admin_url('plugin-install.php?s=ironikus&tab=search&type=term') . '">download and install manually</a>.';
589
+ }
590
+
591
+ echo '</div>';
592
+ } // install_webhooks
593
+
594
+
595
  /**
596
  * Deletes all transients.
597
  *
598
  * @return int Number of deleted transient DB entries
599
  */
600
+ function do_delete_transients()
601
+ {
602
  global $wpdb;
603
 
604
  $count = $wpdb->query("DELETE FROM $wpdb->options WHERE option_name LIKE '\_transient\_%' OR option_name LIKE '\_site\_transient\_%'");
612
  *
613
  * @return int Number of deleted files and folders.
614
  */
615
+ function do_delete_uploads()
616
+ {
617
  $upload_dir = wp_get_upload_dir();
618
 
619
  $this->delete_folder($upload_dir['basedir'], $upload_dir['basedir']);
630
  *
631
  * @return bool
632
  */
633
+ private function delete_folder($folder, $base_folder)
634
+ {
635
  $files = array_diff(scandir($folder), array('.', '..'));
636
 
637
  foreach ($files as $file) {
639
  $this->delete_folder($folder . DIRECTORY_SEPARATOR . $file, $base_folder);
640
  } else {
641
  $tmp = @unlink($folder . DIRECTORY_SEPARATOR . $file);
642
+ $this->delete_count = $this->delete_count + (int)$tmp;
643
  }
644
  } // foreach
645
 
646
  if ($folder != $base_folder) {
647
  $tmp = @rmdir($folder);
648
+ $this->delete_count = $this->delete_count + (int)$tmp;
649
  return $tmp;
650
  } else {
651
  return true;
661
  *
662
  * @return int Number of deleted plugins.
663
  */
664
+ function do_delete_plugins($keep_wp_reset = true, $silent_deactivate = false)
665
+ {
666
  if (!function_exists('get_plugins')) {
667
  require_once ABSPATH . 'wp-admin/includes/plugin.php';
668
  }
669
+ if (!function_exists('request_filesystem_credentials')) {
670
+ require_once ABSPATH . 'wp-admin/includes/file.php';
671
+ }
672
 
673
  $wp_reset_basename = plugin_basename(__FILE__);
674
 
675
  $all_plugins = get_plugins();
676
+ $active_plugins = (array)get_option('active_plugins', array());
677
  if (true == $keep_wp_reset) {
678
  if (($key = array_search($wp_reset_basename, $active_plugins)) !== false) {
679
  unset($active_plugins[$key]);
700
  *
701
  * @return int Number of deleted themes.
702
  */
703
+ function do_delete_themes($keep_default_theme = true)
704
+ {
705
  global $wp_version;
706
 
707
+ if (!function_exists('delete_theme')) {
708
+ require_once ABSPATH . 'wp-admin/includes/theme.php';
709
+ }
710
+
711
+ if (!function_exists('request_filesystem_credentials')) {
712
+ require_once ABSPATH . 'wp-admin/includes/file.php';
713
+ }
714
+
715
  if (version_compare($wp_version, '5.0', '<') === true) {
716
  $default_theme = 'twentyseventeen';
717
  } else {
742
  *
743
  * @return int Number of truncated tables.
744
  */
745
+ function do_truncate_custom_tables()
746
+ {
747
  global $wpdb;
748
  $custom_tables = $this->get_custom_tables();
749
 
760
  *
761
  * @return int Number of dropped tables.
762
  */
763
+ function do_drop_custom_tables()
764
+ {
765
  global $wpdb;
766
  $custom_tables = $this->get_custom_tables();
767
 
778
  *
779
  * @return bool|WP_Error Action status.
780
  */
781
+ function do_delete_htaccess()
782
+ {
783
  global $wp_filesystem;
784
 
785
  if (empty($wp_filesystem)) {
811
  *
812
  * @return string
813
  */
814
+ function get_htaccess_path()
815
+ {
816
  if (!function_exists('get_home_path')) {
817
  require_once ABSPATH . 'wp-admin/includes/file.php';
818
  }
832
  *
833
  * @return null
834
  */
835
+ function ajax_run_tool()
836
+ {
837
  check_ajax_referer('wp-reset_run_tool');
838
 
839
  if (!current_user_can('administrator')) {
919
  *
920
  * @return null
921
  */
922
+ function do_reinstall($params = array())
923
+ {
924
  global $current_user, $wpdb;
925
 
926
  // only admins can reset; double-check
945
  $active_plugins = get_option('active_plugins');
946
  $active_theme = wp_get_theme();
947
 
948
+ if (!empty($params['reactivate_webhooks'])) {
949
+ $wpwh1 = get_option('wpwhpro_active_webhooks');
950
+ $wpwh2 = get_option('wpwhpro_activate_translations');
951
+ $wpwh3 = get_option('ironikus_webhook_webhooks');
952
+ }
953
+
954
  // for WP-CLI
955
  if (!$current_user->ID) {
956
  $tmp = get_users(array('role' => 'administrator', 'order' => 'ASC', 'order_by' => 'ID'));
968
  }
969
 
970
  // supress errors for WP_CLI
971
+ // todo: find a better way to supress errors and send/not send email on reset
972
  $result = @wp_install($blogname, $current_user->user_login, $current_user->user_email, $blog_public, '', md5(rand()), $wplang);
973
  $user_id = $result['user_id'];
974
 
987
  update_user_meta($user_id, 'default_password_nag', false);
988
  }
989
  if (get_user_meta($user_id, $wpdb->prefix . 'default_password_nag')) {
990
+ update_user_meta($user_id, $wpdb->prefix . 'default_password_nag', false);
991
  }
992
 
993
  $meta = $this->get_meta();
1001
 
1002
  // reactivate WP Reset
1003
  if (!empty($params['reactivate_wpreset'])) {
1004
+ activate_plugin(plugin_basename(__FILE__));
1005
+ }
1006
+
1007
+ // reactivate WP Webhooks
1008
+ if (!empty($params['reactivate_webhooks'])) {
1009
+ activate_plugin('wp-webhooks/wp-webhooks.php');
1010
+ activate_plugin('wpwh-wp-reset-webhook-integration/wpwhpro-wp-reset-webhook-integration.php');
1011
+
1012
+ update_option('wpwhpro_active_webhooks', $wpwh1);
1013
+ update_option('wpwhpro_activate_translations', $wpwh2);
1014
+ update_option('ironikus_webhook_webhooks', $wpwh3);
1015
  }
1016
 
1017
  // reactivate all plugins
1039
  *
1040
  * @return null|bool
1041
  */
1042
+ function do_all_actions()
1043
+ {
1044
  // only admins can perform actions
1045
  if (!current_user_can('administrator')) {
1046
  return;
1047
  }
1048
 
1049
  if (!empty($_GET['wp-reset']) && stristr($_SERVER['HTTP_REFERER'], 'wp-reset')) {
1050
+ add_action('admin_notices', array($this, 'notice_successful_reset'));
1051
  }
1052
 
1053
  // check nonce
1064
 
1065
  // only one action at the moment
1066
  if (true === isset($_POST['wp_reset_confirm']) && 'reset' === $_POST['wp_reset_confirm']) {
1067
+ $defaults = array(
1068
+ 'reactivate_theme' => '0',
1069
+ 'reactivate_plugins' => '0',
1070
+ 'reactivate_wpreset' => '0',
1071
+ 'reactivate_webhooks' => '0'
1072
+ );
1073
+ $params = shortcode_atts($defaults, (array)@$_POST['wpr-post-reset']);
1074
 
1075
  $this->do_reinstall($params);
1076
  }
1084
  *
1085
  * @return array
1086
  */
1087
+ function plugin_action_links($links)
1088
+ {
1089
  $settings_link = '<a href="' . admin_url('tools.php?page=wp-reset') . '" title="' . __('Open WP Reset Tools', 'wp-reset') . '">' . __('Open WP Reset Tools', 'wp-reset') . '</a>';
1090
 
1091
  array_unshift($links, $settings_link);
1102
  *
1103
  * @return array
1104
  */
1105
+ function plugin_meta_links($links, $file)
1106
+ {
1107
  if ($file !== plugin_basename(__FILE__)) {
1108
  return $links;
1109
  }
1125
  *
1126
  * @return bool
1127
  */
1128
+ function is_plugin_page()
1129
+ {
1130
  $current_screen = get_current_screen();
1131
 
1132
  if ($current_screen->id == 'tools_page_wp-reset') {
1144
  *
1145
  * @return string
1146
  */
1147
+ function admin_footer_text($text)
1148
+ {
1149
  if (!$this->is_plugin_page()) {
1150
  return $text;
1151
  }
1152
 
1153
+ $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>. Please help us out by <a target="_blank" href="https://wordpress.org/support/plugin/wp-reset/reviews/#new-post" title="Rate the plugin">rating the plugin ★★★★★</a>.</i>';
1154
 
1155
  return $text;
1156
  } // admin_footer_text
1161
  *
1162
  * @return null
1163
  */
1164
+ function load_textdomain()
1165
+ {
1166
  load_plugin_textdomain('wp-reset');
1167
  } // load_textdomain
1168
 
1172
  *
1173
  * @return null
1174
  */
1175
+ function notice_successful_reset()
1176
+ {
1177
  global $current_user;
1178
 
1179
+ 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>';
1180
+ } // notice_successful_reset
1181
 
1182
 
1183
  /**
1185
  *
1186
  * @return null
1187
  */
1188
+ function plugin_page()
1189
+ {
1190
  $notice_shown = false;
1191
  $meta = $this->get_meta();
 
1192
  $snapshots = $this->get_snapshots();
1193
 
1194
+ // double check for admin privileges
1195
  if (!current_user_can('administrator')) {
1196
  wp_die(__('Sorry, you are not allowed to access this page.', 'wp-reset'));
1197
  }
1198
 
1199
  settings_errors();
1200
  echo '<div class="wrap">';
1201
+ 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>';
1202
  echo '<form id="wp_reset_form" action="' . admin_url('tools.php?page=wp-reset') . '" method="post" autocomplete="off">';
1203
 
1204
  if (false === $notice_shown && is_multisite()) {
1209
  $notice_shown = true;
1210
  }
1211
 
1212
+ // ask for review
1213
+ // disabled due to survey
1214
+ if (false && (!empty($meta['reset_count']) || !empty($snapshots)) && false === $notice_shown && false == $this->get_dismissed_notices('rate')) {
1215
  echo '<div class="card notice-wrapper">';
1216
  echo '<h2>' . __('Please help us keep the plugin free &amp; up-to-date', 'wp-reset') . '</h2>';
1217
  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>';
1239
  echo '<li><a href="#tab-tools">' . __('Tools', 'wp-reset') . '</a></li>';
1240
  echo '<li><a href="#tab-snapshots">' . __('DB Snapshots', 'wp-reset') . '</a></li>';
1241
  echo '<li><a href="#tab-support">' . __('Support', 'wp-reset') . '</a></li>';
 
 
 
1242
  echo '</ul>';
1243
 
1244
  echo '<div style="display: none;" id="tab-reset">';
1257
  $this->tab_support();
1258
  echo '</div>';
1259
 
 
 
 
 
 
 
1260
  echo '</div>'; // tabs
1261
 
1262
  echo '</form>';
1263
  echo '</div>'; // wrap
1264
+
1265
+ // survey
1266
+ if ($this->is_survey_active('features')) {
1267
+ echo '<div id="survey-dialog" style="display: none;" title="Help us make WP Reset better for you"><span class="ui-helper-hidden-accessible"><input type="text"/></span>';
1268
+ echo '<p class="subtitle"><b>What new features do you need the most?</b> Choose one or two;</p>';
1269
+
1270
+ $questions = array();
1271
+ $questions[] = '<div class="question-wrapper" data-value="backup" title="Click to select/unselect answer">' .
1272
+ '<span class="dashicons dashicons-yes"></span>' .
1273
+ '<div class="question"><b>Off-site backups</b><br>' .
1274
+ '<i>Backup the site to Dropbox, FTP or Google Drive before running any tools</i></div>' .
1275
+ '</div>';
1276
+
1277
+ $questions[] = '<div class="question-wrapper" data-value="wpmu" title="Click to select/unselect answer">' .
1278
+ '<span class="dashicons dashicons-yes"></span>' .
1279
+ '<div class="question"><b>WordPress Network (WPMU) compatibility</b><br>' .
1280
+ '<i>Full support &amp; compatibility for all WP Reset tools for all sites in network</i></div>' .
1281
+ '</div>';
1282
+
1283
+ $questions[] = '<div class="question-wrapper" data-value="nothing" title="Click to select/unselect answer">' .
1284
+ '<span class="dashicons dashicons-yes"></span>' .
1285
+ '<div class="question"><b>Don\'t add anything</b><br>' .
1286
+ '<i>WP Reset is perfect as is - I don\'t need any new features</i></div>' .
1287
+ '</div>';
1288
+
1289
+ $questions[] = '<div class="question-wrapper" data-value="nuclear" title="Click to select/unselect answer">' .
1290
+ '<span class="dashicons dashicons-yes"></span>' .
1291
+ '<div class="question"><b>Nuclear reset - run all tools at once</b><br>' .
1292
+ '<i>Besides resetting, delete all files and all other customizations with one click</i></div>' .
1293
+ '</div>';
1294
+
1295
+ $questions[] = '<div class="question-wrapper" data-value="plugin-collections" title="Click to select/unselect answer">' .
1296
+ '<span class="dashicons dashicons-yes"></span>' .
1297
+ '<div class="question"><b>Install a set of plugins/themes after reset</b><br>' .
1298
+ '<i>Save lists of plugins/themes and automatically install them after resetting</i></div>' .
1299
+ '</div>';
1300
+
1301
+ $questions[] = '<div class="question-wrapper" data-value="change-wp-ver" title="Click to select/unselect answer">' .
1302
+ '<span class="dashicons dashicons-yes"></span>' .
1303
+ '<div class="question"><b>Change WordPress version - rollback or upgrade</b><br>' .
1304
+ '<i>Pick a version of WP you need (older or never) and switch to it with one click</i></div>' .
1305
+ '</div>';
1306
+
1307
+ shuffle($questions);
1308
+ $questions[] = '<div class="question-wrapper" data-value="custom" title="Click to select/unselect answer">' .
1309
+ '<span class="dashicons dashicons-yes"></span>' .
1310
+ '<div class="question"><b>Something we missed?</b><br><i>Enter the feature you need below;</i>' .
1311
+ '<input type="text" class="custom-input"></div>' .
1312
+ '</div>';
1313
+
1314
+ echo implode(' ', $questions);
1315
+
1316
+ $current_user = wp_get_current_user();
1317
+ echo '<div class="footer">';
1318
+ echo '<input id="emailme" type="checkbox" value="' . $current_user->user_email . '"> <label for="emailme">Email me on ' . $current_user->user_email . ' when new features are added. We hate SPAM and never send it.</label><br>';
1319
+ echo '<a data-survey="features" class="submit-survey button-primary button button-large" href="#">Add those features ASAP!</a>';
1320
+ echo '<a href="#" class="dismiss-survey wpr-dismiss-notice" data-notice="survey-features" data-survey="features"><i>Close the survey and never show it again</i></a>';
1321
+ echo '</div>';
1322
+
1323
+ echo '</div>';
1324
+ } // survey
1325
+
1326
+ if (!$this->is_webhooks_active()) {
1327
+ echo '<div id="webhooks-dialog" style="display: none;" title="Webhooks"><span class="ui-helper-hidden-accessible"><input type="text"/></span>';
1328
+ echo '<div style="padding: 20px; font-size: 15px;">';
1329
+ echo '<ul class="plain-list">';
1330
+ echo '<li>Standard, platform-independant way of connecting WP to any 3rd party system</li>';
1331
+ echo '<li>Supports actions - WP receives data on 3rd party events</li>';
1332
+ echo '<li>And triggers - WP sends data on its events</li>';
1333
+ echo '<li>Works wonders with Zapier</li>';
1334
+ echo '<li>Compatible with any WordPress theme or plugin</li>';
1335
+ echo '<li>Available from the official <a href="https://wordpress.org/plugins/wp-webhooks/" target="_blank">WP plugins repository</a></li>';
1336
+ echo '</ul>';
1337
+ echo '<p class="webhooks-footer"><a class="button button-primary" id="install-webhooks">Install WP Webhooks &amp; connect WP to any 3rd party system</a></p>';
1338
+ echo '</div>';
1339
+ echo '</div>';
1340
+ }
1341
  } // plugin_page
1342
 
1343
 
1346
  *
1347
  * @return null
1348
  */
1349
+ private function tab_reset()
1350
+ {
1351
  global $current_user, $wpdb;
1352
 
1353
  echo '<div class="card" id="card-description">';
1378
  echo '</ul>';
1379
 
1380
  echo '<b>' . __('WP-CLI Support', 'wp-reset') . '</b>';
1381
+ echo '<p>' . sprintf(__('All tools 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>');
1382
  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>';
1383
+
1384
+ echo '<b>' . __('WP Webhooks Support', 'wp-reset') . '</b>';
1385
+ echo '<p>All WP Reset tools are integrated with <a href="https://wordpress.org/plugins/wp-webhooks/" target="_blank">WP Webhooks</a> and available as (receive data) actions. Webhooks are a standard, platform-independent way of connecting WordPress to any 3rd party system. This <a href="https://underconstructionpage.com/wp-webhooks-connect-integrate-wordpress/" target="_blank">article</a> has more info, videos and use-cases so you can see just how powerful and easy to use webhooks are.<br>';
1386
+ if ($this->is_webhooks_active()) {
1387
+ echo 'WP Webhooks are active. Make sure you enable WP Reset actions in <a href="' . admin_url('options-general.php?page=wp-webhooks-pro&wpwhvrs=settings') . '">settings</a>.';
1388
+ } else {
1389
+ echo '<a href="#" class="open-webhooks-dialog">Install WP Webhooks &amp; WPR addon</a> to automate your workflow, develop faster and connect WordPress to any web app or 3rd party system.';
1390
+ }
1391
+ echo '</p></div>'; // card description
1392
 
1393
  $theme = wp_get_theme();
1394
 
1397
  echo '<h2>' . __('Post-reset actions', 'wp-reset') . '</h2>';
1398
  echo '<p><label for="reactivate-theme"><input name="wpr-post-reset[reactivate_theme]" type="checkbox" id="reactivate-theme" value="1"> ' . __('Reactivate current theme', 'wp-reset') . ' - ' . $theme->get('Name') . '</label></p>';
1399
  echo '<p><label for="reactivate-wpreset"><input name="wpr-post-reset[reactivate_wpreset]" type="checkbox" id="reactivate-wpreset" value="1" checked> ' . __('Reactivate WP Reset plugin', 'wp-reset') . '</label></p>';
1400
+ if ($this->is_webhooks_active()) {
1401
+ echo '<p><label for="reactivate-webhooks"><input name="wpr-post-reset[reactivate_webhooks]" type="checkbox" id="reactivate-webhooks" value="1" checked> ' . __('Reactivate WP Webhooks plugin', 'wp-reset') . '</label></p>';
1402
+ }
1403
  echo '<p><label for="reactivate-plugins"><input name="wpr-post-reset[reactivate_plugins]" type="checkbox" id="reactivate-plugins" value="1"> ' . __('Reactivate all currently active plugins', 'wp-reset') . '</label></p>';
1404
+ if ($this->is_webhooks_active()) {
1405
+ echo '<p><a href="' . admin_url('options-general.php?page=wp-webhooks-pro&wpwhvrs=settings') . '">Configure WP Webhooks</a> to run additional actions after reset, or connect to any 3rd party system.</p>';
1406
+ } else {
1407
+ echo '<p>If you need to run additional actions after reset, or connect to any 3rd party system, <a href="#" class="open-webhooks-dialog">install WP Webhooks &amp; WPR addon</a>. It\'s a standard platform-independent way of connecting WordPress to any other web app. It automates complex workflows and saves time when developing. Have a look at this <a href="https://www.youtube.com/watch?v=m8XDFXCNP9g" target="_blank">short video</a> for a demonstration.</p>';
1408
+ }
1409
  echo '</div>';
1410
 
1411
  echo '<div class="card">';
1413
  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 WP Reset.</b>', 'wp-reset') . '</p>';
1414
 
1415
  wp_nonce_field('wp-reset');
1416
+ echo '<p><input id="wp_reset_confirm" type="text" name="wp_reset_confirm" placeholder="' . esc_attr__('Type in "reset"', 'wp-reset') . '" value="" autocomplete="off"> &nbsp;';
1417
  echo '<input id="wp_reset_submit" type="button" class="button-primary" value="' . __('Reset WordPress', 'wp-reset') . '"></p>';
1418
  echo '</div>';
1419
  } // tab_reset
1424
  *
1425
  * @return null
1426
  */
1427
+ private function tab_tools()
1428
+ {
1429
  global $wpdb;
1430
 
1431
  echo '<div class="card">';
1432
  echo '<h2>' . __('Delete Transients', 'wp-reset') . '</h2>';
1433
  echo '<p>' . __('All transient related database entries will be deleted. Including expired and non-expired transients, and orphaned transient timeout entries.<br><b>There is NO UNDO. WP Reset does not make any backups.</b>', 'wp-reset') . '</p>';
1434
+ echo '<p><a data-btn-confirm="Delete all transients" data-text-wait="Deleting transients. Please wait." data-text-confirm="All database entries related to transients will be deleted. There is NO UNDO. WP Reset will not make any backups." data-text-done="%n transient database entries have been deleted." data-text-done-singular="One transient database entry has been deleted." class="button button-delete" href="#" id="delete-transients">Delete all transients</a></p>';
1435
  echo '</div>';
1436
 
1437
  $upload_dir = wp_upload_dir(date('Y/m'), true);
1443
  if (false != $upload_dir['error']) {
1444
  echo '<p><span style="color:#dd3036;"><b>Tool is not available.</b></span> Folder is not writeable by WordPress. Please check file and folder access rights.</p>';
1445
  } else {
1446
+ echo '<p><a data-btn-confirm="Delete everything in uploads folder" data-text-wait="Deleting uploads. Please wait." data-text-confirm="All files and folders in uploads will be deleted. There is NO UNDO. WP Reset will not make any backups." data-text-done="%n files &amp; folders have been deleted." data-text-done-singular="One file or folder has been deleted." class="button button-delete" href="#" id="delete-uploads">Delete all files &amp; folders in uploads folder</a></p>';
1447
  }
1448
  echo '</div>';
1449
 
1452
  echo '<div class="card">';
1453
  echo '<h2>' . __('Delete Themes', 'wp-reset') . '</h2>';
1454
  echo '<p>' . __('All themes will be deleted. Including the currently active theme - ' . $theme->get('Name') . '.<br><b>There is NO UNDO. WP Reset does not make any backups.</b>', 'wp-reset') . '</p>';
1455
+ echo '<p><a data-btn-confirm="Delete all themes" data-text-wait="Deleting all themes. Please wait." data-text-confirm="All themes will be deleted. There is NO UNDO. WP Reset will not make any backups." data-text-done="%n themes have been deleted." data-text-done-singular="One theme has been deleted." class="button button-delete" href="#" id="delete-themes">Delete all themes</a></p>';
1456
  echo '</div>';
1457
 
1458
  echo '<div class="card">';
1459
  echo '<h2>' . __('Delete Plugins', 'wp-reset') . '</h2>';
1460
  echo '<p>' . __('All plugins will be deleted except for WP Reset which will remain active.<br><b>There is NO UNDO. WP Reset does not make any backups.</b>', 'wp-reset') . '</p>';
1461
+ echo '<p><a data-btn-confirm="Delete plugins" data-text-wait="Deleting plugins. Please wait." data-text-confirm="All plugins except WP Reset will be deleted. There is NO UNDO. WP Reset will not make any backups." data-text-done="%n plugins have been deleted." data-text-done-singular="One plugin has been deleted." class="button button-delete" href="#" id="delete-plugins">Delete plugins</a></p>';
1462
  echo '</div>';
1463
 
1464
  $custom_tables = $this->get_custom_tables();
1480
  echo '<p>' . __('There are no custom tables. There\'s nothing for this tool to empty or delete.', 'wp-reset') . '</p>';
1481
  $custom_tables_btns = ' disabled';
1482
  }
1483
+ echo '<p><a data-btn-confirm="Empty custom tables" data-text-wait="Emptying custom tables. Please wait." data-text-confirm="All custom tables with prefix <code>' . $wpdb->prefix . '</code> will be emptied. There is NO UNDO. WP Reset will not make any backups." data-text-done="%n custom tables have been emptied." data-text-done-singular="One custom table has been emptied." class="button button-delete' . $custom_tables_btns . '" href="#" id="truncate-custom-tables">Empty (truncate) custom tables</a>&nbsp; &nbsp;';
1484
+ echo '<a data-btn-confirm="Delete custom tables" data-text-wait="Deleting custom tables. Please wait." data-text-confirm="All custom tables with prefix <code>' . $wpdb->prefix . '</code> will be deleted. There is NO UNDO. WP Reset will not make any backups." data-text-done="%n custom tables have been deleted." data-text-done-singular="One custom table has been deleted." class="button button-delete' . $custom_tables_btns . '" href="#" id="drop-custom-tables">Delete (drop) custom tables</a></p>';
1485
 
1486
  echo '</div>';
1487
 
1502
  *
1503
  * @return null
1504
  */
1505
+ private function tab_support()
1506
+ {
1507
  echo '<div class="card">';
1508
  echo '<h2>' . __('Public support forum', 'wp-reset') . '</h2>';
1509
  echo '<p>' . __('We are very active on the <a href="https://wordpress.org/support/plugin/wp-reset" target="_blank">official WP Reset support forum</a>. If you found a bug, have a feature idea or just want to say hi - please drop by. We love to hear back from our users.', 'wp-reset') . '</p>';
1526
  *
1527
  * @return null
1528
  */
1529
+ private function tab_snapshots()
1530
+ {
1531
  global $wpdb;
1532
  $tbl_core = $tbl_custom = $tbl_size = $tbl_rows = 0;
1533
 
1536
  echo '<h2>' . __('Database Snapshots', 'wp-reset') . '</h2>';
1537
  echo '<p>A snapshot is a copy of all WP database tables, standard and custom ones, saved in your database. Files are not saved or included in snapshots in any way.<br>
1538
  Snapshots are primarily a development tool. Although they can be used for backups (and downloaded), we suggest finding a more suitable tool for live sites, such as <a href="https://wordpress.org/plugins/updraftplus/" target="_blank">UpdraftPlus</a>. Use snapshots to find out what changes a plugin made to your database or to quickly restore the dev environment after testing database related changes.<br>Restoring a snapshot does not affect other snapshots, or WP Reset settings.</p>';
1539
+ echo '<p>Snapshots are still in development. If you see a bug or just have an idea how to make the tool better, please let us know <a href="https://twitter.com/WebFactoryLtd" target="_blank">@webfactoryltd</a> or <a href="mailto:wpreset@webfactoryltd.com?subject=WPR%20DB%20Snapshots%20Feedback">email us</a>. Thank you!</p>';
1540
 
1541
  $table_status = $wpdb->get_results('SHOW TABLE STATUS');
1542
  if (is_array($table_status)) {
1559
 
1560
  echo '<p><b>Currently used WordPress tables</b>, prefixed with <i>' . $wpdb->prefix . '</i>, consist of ' . $tbl_core . ' standard and ';
1561
  if ($tbl_custom) {
1562
+ echo $tbl_custom . ' custom table' . ($tbl_custom == 1 ? '' : 's');
1563
  } else {
1564
  echo 'no custom tables';
1565
  }
1566
+ echo ' totaling ' . $this->format_size($tbl_size) . ' in ' . number_format($tbl_rows) . ' rows.</p>';
1567
  }
1568
 
1569
  echo '';
1587
  }
1588
  echo '<td>' . $ss['tbl_core'] . ' standard &amp; ';
1589
  if ($ss['tbl_custom']) {
1590
+ echo $ss['tbl_custom'] . ' custom table' . ($ss['tbl_custom'] == 1 ? '' : 's');
1591
  } else {
1592
  echo 'no custom tables';
1593
  }
1609
  } // tab_snapshots
1610
 
1611
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1612
  /**
1613
  * Helper function for generating UTM tagged links
1614
  *
1619
  *
1620
  * @return string
1621
  */
1622
+ function generate_web_link($placement = '', $page = '/', $params = array(), $anchor = '')
1623
+ {
1624
  $base_url = 'https://wpreset.com';
1625
 
1626
  if ('/' != $page) {
1647
  *
1648
  * @return array
1649
  */
1650
+ function get_snapshots()
1651
+ {
1652
  $snapshots = get_option('wp-reset-snapshots', array());
1653
 
1654
  return $snapshots;
1660
  *
1661
  * @return array
1662
  */
1663
+ function get_custom_tables()
1664
+ {
1665
  global $wpdb;
1666
  $custom_tables = array();
1667
 
1692
  *
1693
  * @return string
1694
  */
1695
+ function format_size($bytes)
1696
+ {
1697
  if ($bytes > 1073741824) {
1698
  return number_format_i18n($bytes / 1073741824, 2) . ' GB';
1699
  } elseif ($bytes > 1048576) {
1713
  *
1714
  * @return array|WP_Error Snapshot details in array on success, or error object on fail.
1715
  */
1716
+ function do_create_snapshot($name = '')
1717
+ {
1718
  global $wpdb;
1719
  $snapshots = $this->get_snapshots();
1720
  $snapshot = array();
1752
  }
1753
 
1754
  $wpdb->query('OPTIMIZE TABLE ' . $table->Name);
1755
+ $wpdb->query('CREATE TABLE ' . $uid . '_' . $table->Name . ' LIKE ' . $table->Name);
1756
  $wpdb->query('INSERT ' . $uid . '_' . $table->Name . ' SELECT * FROM ' . $table->Name);
1757
  } // foreach
1758
  } else {
1779
  *
1780
  * @return bool|WP_Error True on success, or error object on fail.
1781
  */
1782
+ function do_delete_snapshot($uid = '')
1783
+ {
1784
  global $wpdb;
1785
  $snapshots = $this->get_snapshots();
1786
 
1811
  *
1812
  * @return string|WP_Error Export base filename, or error object on fail.
1813
  */
1814
+ function do_export_snapshot($uid = '')
1815
+ {
1816
  global $wpdb;
1817
  $snapshots = $this->get_snapshots();
1818
 
1840
  }
1841
 
1842
  $world_dumper->dump(trailingslashit(WP_CONTENT_DIR) . $this->snapshots_folder . '/wp-reset-snapshot-' . $uid . '.sql.gz', $uid . '_');
1843
+ } catch (Shuttle_Exception $e) {
1844
  return new WP_Error(1, "Couldn't dump snapshot: " . $e->getMessage());
1845
  }
1846
 
1855
  *
1856
  * @return bool|WP_Error True on success, or error object on fail.
1857
  */
1858
+ function do_restore_snapshot($uid = '')
1859
+ {
1860
  global $wpdb;
1861
  $new_tables = array();
1862
  $snapshots = $this->get_snapshots();
1915
  *
1916
  * @return bool|WP_Error True on success, or error object on fail.
1917
  */
1918
+ function verify_snapshot_integrity($uid)
1919
+ {
1920
  global $wpdb;
1921
  $tbl_core = $tbl_custom = 0;
1922
  $snapshots = $this->get_snapshots();
1966
  *
1967
  * @return string|WP_Error Formatted table with details on success, or error object on fail.
1968
  */
1969
+ function do_compare_snapshots($uid)
1970
+ {
1971
  global $wpdb;
1972
  $tbl_core = $tbl_custom = 0;
1973
  $current = $snapshot = array();
2024
  $out .= '</tr>';
2025
  $out .= '<tr class="hidden">';
2026
  $out .= '<td>';
2027
+ $out .= '<p>' . number_format($table['rows']) . ' row' . ($table['rows'] == 1 ? '' : 's') . ' totaling ' . $this->format_size($table['size_data']) . ' in data and ' . $this->format_size($table['size_index']) . ' in index.</p>';
2028
  $out .= '<pre>' . $table['schema'] . '</pre>';
2029
  $out .= '</td>';
2030
  $out .= '<td>&nbsp;</td>';
2043
  $out .= '<tr class="hidden">';
2044
  $out .= '<td>&nbsp;</td>';
2045
  $out .= '<td>';
2046
+ $out .= '<p>' . number_format($table['rows']) . ' row' . ($table['rows'] == 1 ? '' : 's') . ' totaling ' . $this->format_size($table['size_data']) . ' in data and ' . $this->format_size($table['size_index']) . ' in index.</p>';
2047
  $out .= '<pre>' . $table['schema'] . '</pre>';
2048
  $out .= '</td>';
2049
  $out .= '</tr>';
2134
  foreach ($diff_rows as $row) {
2135
  $out2 .= '<tr>';
2136
  $out2 .= '<td style="width: 100px;">' . $row->option_name . '</td>';
2137
+ $out2 .= '<td>' . (empty($row->current_value) ? '<i>empty</i>' : $row->current_value) . '</td>';
2138
+ $out2 .= '<td>' . (empty($row->snapshot_value) ? '<i>empty</i>' : $row->snapshot_value) . '</td>';
2139
  $out2 .= '</tr>';
2140
  } // foreach
2141
  foreach ($only_current as $row) {
2142
  $out2 .= '<tr>';
2143
  $out2 .= '<td style="width: 100px;">' . $row->option_name . '</td>';
2144
+ $out2 .= '<td>' . (empty($row->current_value) ? '<i>empty</i>' : $row->current_value) . '</td>';
2145
  $out2 .= '<td><i>not found in snapshot</i></td>';
2146
  $out2 .= '</tr>';
2147
  } // foreach
2149
  $out2 .= '<tr>';
2150
  $out2 .= '<td style="width: 100px;">' . $row->option_name . '</td>';
2151
  $out2 .= '<td><i>not found in current tables</i></td>';
2152
+ $out2 .= '<td>' . (empty($row->snapshot_value) ? '<i>empty</i>' : $row->snapshot_value) . '</td>';
2153
  $out2 .= '</tr>';
2154
  } // foreach
2155
  $out2 .= '</table>';
2173
  *
2174
  * @return string
2175
  */
2176
+ function generate_snapshot_uid()
2177
+ {
2178
  global $wpdb;
2179
  $snapshots = $this->get_snapshots();
2180
  $cnt = 0;
2200
  *
2201
  * @return array
2202
  */
2203
+ function featured_plugins_tab($args)
2204
+ {
2205
  add_filter('plugins_api_result', array($this, 'plugins_api_result'), 10, 3);
2206
 
2207
  return $args;
2213
  *
2214
  * @return object
2215
  */
2216
+ function add_plugin_featured($plugin_slug, $res)
2217
+ {
2218
+ // check if plugin is already on the list
2219
  if (!empty($res->plugins) && is_array($res->plugins)) {
2220
  foreach ($res->plugins as $plugin) {
2221
+ if (is_object($plugin) && !empty($plugin->slug) && $plugin->slug == $plugin_slug) {
2222
  return $res;
2223
  }
2224
  } // foreach
2231
  'slug' => $plugin_slug,
2232
  'is_ssl' => is_ssl(),
2233
  'fields' => array(
2234
+ 'banners' => true,
2235
+ 'reviews' => true,
2236
+ 'downloaded' => true,
2237
+ 'active_installs' => true,
2238
+ 'icons' => true,
2239
+ 'short_description' => true,
2240
  )
2241
  ));
2242
  if (!is_wp_error($plugin_info)) {
2243
+ $res->plugins = array_merge(array($plugin_info), $res->plugins);
 
 
2244
  set_transient('wf-plugin-info-' . $plugin_slug, $plugin_info, DAY_IN_SECONDS * 7);
2245
  }
2246
  }
2254
  *
2255
  * @return object
2256
  */
2257
+ function plugins_api_result($res, $action, $args)
2258
+ {
2259
  remove_filter('plugins_api_result', array($this, 'plugins_api_result'), 10, 3);
2260
 
2261
  $res = $this->add_plugin_featured('security-ninja', $res);
2262
+ $res = $this->add_plugin_featured('under-construction-page', $res);
2263
 
2264
  return $res;
2265
  } // plugins_api_result
2270
  *
2271
  * @return null
2272
  */
2273
+ static function uninstall()
2274
+ {
2275
  delete_option('wp-reset');
2276
  delete_option('wp-reset-snapshots');
2277
  } // uninstall
2282
  *
2283
  * @return null
2284
  */
2285
+ private function __clone()
2286
+ { }
2287
 
2288
 
2289
  /**
2291
  *
2292
  * @return null
2293
  */
2294
+ private function __sleep()
2295
+ { }
2296
 
2297
 
2298
  /**
2300
  *
2301
  * @return null
2302
  */
2303
+ private function __wakeup()
2304
+ { }
2305
  } // WP_Reset class
2306
 
2307