Total Upkeep – WordPress Backup Plugin plus Restore & Migrate by BoldGrid - Version tmp-transfer-log

Version Description

Download this release

Release Info

Developer boldgrid
Plugin Icon 128x128 Total Upkeep – WordPress Backup Plugin plus Restore & Migrate by BoldGrid
Version tmp-transfer-log
Comparing to
See all releases

Code changes from version 1.6.1-rc.2 to tmp-transfer-log

Files changed (194) hide show
  1. admin/card/class-amazon-s3.php +50 -0
  2. admin/card/class-backups.php +46 -0
  3. admin/card/class-database-encryption.php +50 -0
  4. admin/card/class-dream-objects.php +51 -0
  5. admin/card/class-find-modified-files.php +41 -0
  6. admin/card/class-google-drive.php +51 -0
  7. admin/card/class-historical-versions.php +51 -0
  8. admin/card/class-history.php +51 -0
  9. admin/card/class-one-click-restoration.php +51 -0
  10. admin/card/class-plugin-editor-tools.php +51 -0
  11. admin/card/class-premium.php +70 -0
  12. admin/card/class-updates.php +44 -0
  13. admin/card/feature/class-auto-rollback.php +52 -0
  14. admin/card/feature/class-auto-update-backup.php +56 -0
  15. admin/card/feature/class-central.php +40 -0
  16. admin/card/feature/class-cloud-wordpress.php +34 -0
  17. admin/card/feature/class-database-encryption.php +45 -0
  18. admin/card/feature/class-more-backup.php +52 -0
  19. admin/card/feature/class-more-boldgrid.php +34 -0
  20. admin/card/feature/class-more-central.php +40 -0
  21. admin/card/feature/class-remote-storage.php +66 -0
  22. admin/card/feature/class-scheduled-backups.php +86 -0
  23. admin/card/feature/class-sign-up.php +36 -0
  24. admin/card/feature/class-speed-coach.php +34 -0
  25. admin/card/feature/class-versions.php +63 -0
  26. admin/class-boldgrid-backup-admin-archive-actions.php +140 -47
  27. admin/class-boldgrid-backup-admin-archive-browser.php +123 -41
  28. admin/class-boldgrid-backup-admin-archive-details.php +66 -26
  29. admin/class-boldgrid-backup-admin-archive-fail.php +11 -12
  30. admin/class-boldgrid-backup-admin-archive-log.php +39 -22
  31. admin/class-boldgrid-backup-admin-archive.php +368 -23
  32. admin/class-boldgrid-backup-admin-archiver-utility.php +70 -0
  33. admin/class-boldgrid-backup-admin-archives-all.php +25 -26
  34. admin/class-boldgrid-backup-admin-archives.php +176 -70
  35. admin/class-boldgrid-backup-admin-auto-rollback.php +248 -80
  36. admin/class-boldgrid-backup-admin-backup-dir.php +219 -30
  37. admin/class-boldgrid-backup-admin-cli.php +242 -0
  38. admin/class-boldgrid-backup-admin-compressor.php +59 -8
  39. admin/class-boldgrid-backup-admin-compressors.php +43 -12
  40. admin/class-boldgrid-backup-admin-config.php +35 -26
  41. admin/class-boldgrid-backup-admin-core-files.php +12 -14
  42. admin/class-boldgrid-backup-admin-core.php +897 -606
  43. admin/class-boldgrid-backup-admin-cron-log.php +256 -0
  44. admin/class-boldgrid-backup-admin-cron-test.php +246 -0
  45. admin/class-boldgrid-backup-admin-cron.php +415 -293
  46. admin/class-boldgrid-backup-admin-crypt.php +10 -10
  47. admin/class-boldgrid-backup-admin-dashboard-widget.php +74 -0
  48. admin/class-boldgrid-backup-admin-dashboard.php +84 -0
  49. admin/class-boldgrid-backup-admin-db-dump.php +134 -23
  50. admin/class-boldgrid-backup-admin-db-get.php +95 -13
  51. admin/class-boldgrid-backup-admin-db-import.php +30 -24
  52. admin/class-boldgrid-backup-admin-db-omit.php +37 -36
  53. admin/class-boldgrid-backup-admin-email.php +106 -28
  54. admin/class-boldgrid-backup-admin-filelist.php +9 -11
  55. admin/class-boldgrid-backup-admin-folder-exclusion.php +74 -50
  56. admin/class-boldgrid-backup-admin-go-pro.php +120 -46
  57. admin/class-boldgrid-backup-admin-home-dir.php +6 -7
  58. admin/class-boldgrid-backup-admin-in-progress-data.php +124 -0
  59. admin/class-boldgrid-backup-admin-in-progress-tmp.php +164 -0
  60. admin/class-boldgrid-backup-admin-in-progress.php +96 -27
  61. admin/class-boldgrid-backup-admin-jobs.php +19 -25
  62. admin/class-boldgrid-backup-admin-log-page.php +96 -0
  63. admin/class-boldgrid-backup-admin-log.php +301 -0
  64. admin/class-boldgrid-backup-admin-notice.php +112 -46
  65. admin/class-boldgrid-backup-admin-plugin-notices.php +55 -0
  66. admin/class-boldgrid-backup-admin-plugins.php +53 -0
  67. admin/class-boldgrid-backup-admin-premium-features.php +114 -0
  68. admin/class-boldgrid-backup-admin-remote.php +55 -22
  69. admin/class-boldgrid-backup-admin-restore-git.php +14 -8
  70. admin/class-boldgrid-backup-admin-restore-helper.php +83 -34
  71. admin/class-boldgrid-backup-admin-scheduler.php +11 -14
  72. admin/class-boldgrid-backup-admin-settings.php +391 -237
  73. admin/class-boldgrid-backup-admin-support.php +249 -0
  74. admin/class-boldgrid-backup-admin-test.php +244 -92
  75. admin/class-boldgrid-backup-admin-time.php +41 -29
  76. admin/class-boldgrid-backup-admin-tools.php +25 -13
  77. admin/class-boldgrid-backup-admin-transfers.php +59 -0
  78. admin/class-boldgrid-backup-admin-upload.php +174 -28
  79. admin/class-boldgrid-backup-admin-usage.php +130 -0
  80. admin/class-boldgrid-backup-admin-utility.php +88 -46
  81. admin/class-boldgrid-backup-admin-wp-cron.php +33 -39
  82. admin/class-boldgrid-backup-admin-wpcli.php +247 -0
  83. admin/class-boldgrid-backup-admin-xhprof.php +19 -15
  84. admin/class-boldgrid-backup-admin.php +57 -18
  85. admin/class-cron.php +110 -0
  86. admin/compressor/{pcl_zip.php → class-boldgrid-backup-admin-compressor-pcl-zip.php} +92 -53
  87. admin/compressor/class-boldgrid-backup-admin-compressor-php-zip.php +352 -0
  88. admin/compressor/class-boldgrid-backup-admin-compressor-system-zip-temp-folder.php +82 -0
  89. admin/compressor/class-boldgrid-backup-admin-compressor-system-zip-test.php +303 -0
  90. admin/compressor/class-boldgrid-backup-admin-compressor-system-zip.php +227 -0
  91. admin/compressor/php_zip.php +0 -212
  92. admin/cron/class-crontab.php +142 -0
  93. admin/cron/entry/class-base.php +58 -0
  94. admin/cron/entry/class-crontab.php +161 -0
  95. admin/cron/entry/class-entry.php +29 -0
  96. admin/cron/entry/class-wpcron.php +86 -0
  97. admin/css/boldgrid-backup-admin-dashboard.css +27 -0
  98. admin/css/boldgrid-backup-admin-folder-exclude.css +0 -1
  99. admin/css/boldgrid-backup-admin-hide-all.css +8 -1
  100. admin/css/boldgrid-backup-admin-home.css +5 -1
  101. admin/css/boldgrid-backup-admin-premium.css +110 -0
  102. admin/css/boldgrid-backup-admin-settings.css +9 -1
  103. admin/css/boldgrid-backup-admin-test.css +1 -0
  104. admin/css/boldgrid-backup-admin.css +226 -5
  105. admin/image/db-lock-64.png +0 -0
  106. admin/image/remote/amazon-s3-logo.png +0 -0
  107. admin/image/remote/dreamhost-logo.png +0 -0
  108. admin/image/remote/google-drive-logo.png +0 -0
  109. admin/image/remote/google-drive.png +0 -0
  110. admin/index.php +6 -0
  111. admin/js/boldgrid-backup-admin-archive-actions.js +121 -21
  112. admin/js/boldgrid-backup-admin-archive-details.js +77 -7
  113. admin/js/boldgrid-backup-admin-backup-now.js +36 -101
  114. admin/js/boldgrid-backup-admin-customizer.js +2 -3
  115. admin/js/boldgrid-backup-admin-folder-exclude.js +12 -12
  116. admin/js/boldgrid-backup-admin-ftp-settings.js +19 -11
  117. admin/js/boldgrid-backup-admin-home.js +115 -3
  118. admin/js/boldgrid-backup-admin-in-progress.js +616 -0
  119. admin/js/boldgrid-backup-admin-logs.js +98 -0
  120. admin/js/boldgrid-backup-admin-rollback.js +4 -4
  121. admin/js/boldgrid-backup-admin-settings-autoupdate.js +201 -0
  122. admin/js/boldgrid-backup-admin-settings.js +23 -22
  123. admin/js/boldgrid-backup-admin-table-include.js +8 -8
  124. admin/js/boldgrid-backup-admin-update-selectors.js +6 -3
  125. admin/js/boldgrid-backup-admin-zip-browser.js +5 -5
  126. admin/js/boldgrid-backup-admin.js +8 -71
  127. admin/partials/archive-details/browser-entry.php +7 -4
  128. admin/partials/archive-details/browser.php +8 -6
  129. admin/partials/archive-details/db.php +28 -14
  130. admin/partials/archive-details/details.php +38 -24
  131. admin/partials/archive-details/not-found.php +9 -5
  132. admin/partials/archive-details/only-remote.php +25 -9
  133. admin/partials/archive-details/remote-storage.php +82 -18
  134. admin/partials/archives/add-new.php +47 -18
  135. admin/partials/archives/note-pre-backup.php +28 -12
  136. admin/partials/backup-now-modal/title.php +28 -0
  137. admin/partials/boldgrid-backup-admin-archive-details.php +248 -69
  138. admin/partials/boldgrid-backup-admin-backup-button.php +55 -23
  139. admin/partials/boldgrid-backup-admin-backup-modal.php +16 -8
  140. admin/partials/boldgrid-backup-admin-backup.php +64 -45
  141. admin/partials/boldgrid-backup-admin-dashboard.php +34 -0
  142. admin/partials/boldgrid-backup-admin-home.php +32 -17
  143. admin/partials/boldgrid-backup-admin-mail-restore.php +24 -9
  144. admin/partials/boldgrid-backup-admin-nav.php +62 -24
  145. admin/partials/boldgrid-backup-admin-premium.php +57 -0
  146. admin/partials/boldgrid-backup-admin-settings.php +96 -67
  147. admin/partials/boldgrid-backup-admin-support.php +164 -0
  148. admin/partials/boldgrid-backup-admin-test.php +116 -34
  149. admin/partials/boldgrid-backup-admin-tools.php +26 -12
  150. admin/partials/boldgrid-backup-admin-transfers.php +74 -0
  151. admin/partials/remote/ftp.php +65 -34
  152. admin/partials/remote/local.php +33 -0
  153. admin/partials/settings/auto-backup.php +98 -0
  154. admin/partials/settings/auto-updates.php +0 -155
  155. admin/partials/settings/backup-directory.php +28 -12
  156. admin/partials/settings/backup-security.php +124 -0
  157. admin/partials/settings/compressor.php +44 -30
  158. admin/partials/settings/connect-key.php +18 -53
  159. admin/partials/settings/days-of-week.php +75 -17
  160. admin/partials/settings/db.php +17 -8
  161. admin/partials/settings/folders.php +34 -21
  162. admin/partials/settings/notifications.php +29 -7
  163. admin/partials/settings/premium-message.php +46 -19
  164. admin/partials/settings/retention.php +28 -35
  165. admin/partials/settings/scheduler.php +21 -11
  166. admin/partials/settings/site-check.php +117 -0
  167. admin/partials/settings/storage-location.php +25 -11
  168. admin/partials/settings/storage.php +54 -22
  169. admin/partials/settings/time-of-day.php +36 -24
  170. admin/partials/tools/local-remote.php +157 -55
  171. admin/partials/tools/view-logs.php +84 -0
  172. admin/partials/transfers/destination.php +104 -0
  173. admin/partials/transfers/overview.php +27 -0
  174. admin/partials/transfers/source.php +101 -0
  175. admin/remote/{ftp-hooks.php → class-boldgrid-backup-admin-ftp-hooks.php} +75 -44
  176. admin/remote/class-boldgrid-backup-admin-ftp-page.php +237 -0
  177. admin/remote/class-boldgrid-backup-admin-ftp.php +1172 -0
  178. admin/remote/class-boldgrid-backup-admin-remote-settings.php +235 -0
  179. admin/remote/ftp-page.php +0 -190
  180. admin/remote/ftp.php +0 -858
  181. admin/remote/sftp.php +0 -553
  182. admin/storage/class-boldgrid-backup-admin-storage-local.php +310 -0
  183. admin/storage/local.php +0 -100
  184. boldgrid-backup-cron.php +44 -15
  185. boldgrid-backup.php +40 -37
  186. cli/bgbkup-cli.php +52 -0
  187. cli/class-email.php +67 -0
  188. cli/class-info.php +897 -0
  189. cli/class-log.php +122 -0
  190. cli/class-site-check.php +251 -0
  191. cli/class-site-restore.php +366 -0
  192. cli/env-info.php +28 -0
  193. cli/wp-test.php +131 -0
  194. coverage.xml +621 -0
admin/card/class-amazon-s3.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Amazon_S3 class.
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.13.0
7
+ *
8
+ * @package Boldgrid\Backup
9
+ * @subpackage Boldgrid\Backup\Card
10
+ * @copyright BoldGrid
11
+ * @author BoldGrid <support@boldgrid.com>
12
+ */
13
+
14
+ namespace Boldgrid\Backup\Admin\Card;
15
+
16
+ /**
17
+ * Class: Amazon_S3
18
+ *
19
+ * This class is responsible for rendering the "Amazon S3" card on this plugin's Premium Features page.
20
+ *
21
+ * @since 1.13.0
22
+ */
23
+ class Amazon_S3 extends \Boldgrid\Library\Library\Ui\Card {
24
+ /**
25
+ * Init.
26
+ *
27
+ * @since 1.13.0
28
+ */
29
+ public function init() {
30
+ $this->id = 'bgbkup_amazon_s3';
31
+
32
+ $this->title = esc_html__( 'Amazon S3', 'boldgrid-backup' );
33
+
34
+ $this->footer = '
35
+ <p>' .
36
+ esc_html__(
37
+ 'Safely store backups in the cloud via Amazon S3. Compatible with automated remote backups feature.',
38
+ 'boldgrid-backup' ) .
39
+ '</p>';
40
+
41
+ $url = esc_url( 'https://www.boldgrid.com/support/total-upkeep/backup-wordpress-to-amazon-s3/?source=amazon-s3' );
42
+
43
+ $this->links = '
44
+ <a target="_blank" href="' . $url . '">' .
45
+ esc_html__( 'Setup Guide' ) . '
46
+ </a>';
47
+
48
+ $this->icon = '<img src="' . plugin_dir_url( __FILE__ ) . '../image/remote/amazon-s3-logo.png"></img>';
49
+ }
50
+ }
admin/card/class-backups.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Backups class.
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.11.0
7
+ *
8
+ * @package Boldgrid\Backup
9
+ * @subpackage Boldgrid\Backup\Card
10
+ * @copyright BoldGrid
11
+ * @author BoldGrid <support@boldgrid.com>
12
+ */
13
+
14
+ namespace Boldgrid\Backup\Admin\Card;
15
+
16
+ /**
17
+ * Class: Backups
18
+ *
19
+ * This class is responsible for rendering the "Backups" card on this plugin's dashboard.
20
+ *
21
+ * @since 1.11.0
22
+ */
23
+ class Backups extends \Boldgrid\Library\Library\Ui\Card {
24
+ /**
25
+ * Init.
26
+ *
27
+ * @since 1.11.0
28
+ */
29
+ public function init() {
30
+ $this->id = 'bgbkup_backups';
31
+
32
+ $this->title = esc_html__( 'Backups', 'boldgrid-backup' );
33
+
34
+ $this->subTitle = esc_html__( 'It\'s website insurance. Make sure you have a backup.', 'boldgrid-backup' ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.NotSnakeCaseMemberVar
35
+
36
+ $this->icon = '<span class="dashicons dashicons-vault"></span>';
37
+
38
+ $this->features = [
39
+ new Feature\Scheduled_Backups(),
40
+ new Feature\Remote_Storage(),
41
+ ];
42
+ if ( ! get_option( 'boldgrid_backup_settings' )['encrypt_db'] ) {
43
+ $this->features[] = new Feature\Database_Encryption();
44
+ }
45
+ }
46
+ }
admin/card/class-database-encryption.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Database Encryption class.
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.13.0
7
+ *
8
+ * @package Boldgrid\Backup
9
+ * @subpackage Boldgrid\Backup\Card
10
+ * @copyright BoldGrid
11
+ * @author BoldGrid <support@boldgrid.com>
12
+ */
13
+
14
+ namespace Boldgrid\Backup\Admin\Card;
15
+
16
+ /**
17
+ * Class: Encryption
18
+ *
19
+ * This class is responsible for rendering the "Encryption" card on this plugin's Premium Features page.
20
+ *
21
+ * @since 1.13.0
22
+ */
23
+ class Database_Encryption extends \Boldgrid\Library\Library\Ui\Card {
24
+ /**
25
+ * Init.
26
+ *
27
+ * @since 1.13.0
28
+ */
29
+ public function init() {
30
+ $this->id = 'bgbkup_database_encryption';
31
+
32
+ $this->title = esc_html__( 'Database Encryption', 'boldgrid-backup' );
33
+
34
+ $this->footer = '
35
+ <p>' .
36
+ esc_html__(
37
+ 'Provides another level of protection by preventing unauthorized access to your database backup archives.',
38
+ 'boldgrid-backup' ) .
39
+ '</p>';
40
+
41
+ $url = esc_url( 'https://www.boldgrid.com/support/total-upkeep/encrypt-database-backups/?source=encrypt-database-backups' );
42
+
43
+ $this->links = '
44
+ <a target="_blank" href="' . $url . '">' .
45
+ esc_html__( 'Setup Guide' ) . '
46
+ </a>';
47
+
48
+ $this->icon = '<img src="' . plugin_dir_url( __FILE__ ) . '../image/db-lock-64.png" />';
49
+ }
50
+ }
admin/card/class-dream-objects.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Dream_Objects class.
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.13.0
7
+ *
8
+ * @package Boldgrid\Backup
9
+ * @subpackage Boldgrid\Backup\Card
10
+ * @copyright BoldGrid
11
+ * @author BoldGrid <support@boldgrid.com>
12
+ */
13
+
14
+ namespace Boldgrid\Backup\Admin\Card;
15
+
16
+ /**
17
+ * Class: Dream_Objects
18
+ *
19
+ * This class is responsible for rendering the "Dream Objects" card
20
+ * on this plugin's Premium Features Page.
21
+ *
22
+ * @since 1.13.0
23
+ */
24
+ class Dream_Objects extends \Boldgrid\Library\Library\Ui\Card {
25
+ /**
26
+ * Init.
27
+ *
28
+ * @since 1.13.0
29
+ */
30
+ public function init() {
31
+ $this->id = 'bgbkup_dream_objects';
32
+
33
+ $this->title = esc_html__( 'DreamObjects', 'boldgrid-backup' );
34
+
35
+ $this->footer = '
36
+ <p>' .
37
+ esc_html__(
38
+ 'Safely store backups in the cloud via DreamObjects by DreamHost. Compatible with automated backups feature.',
39
+ 'boldgrid-backup' ) .
40
+ '</p>';
41
+
42
+ $url = esc_url( 'https://www.boldgrid.com/support/total-upkeep/dreamobjects-storage/?source=dreamobjects' );
43
+
44
+ $this->links = '
45
+ <a target="_blank" href="' . $url . '">' .
46
+ esc_html__( 'Setup Guide' ) . '
47
+ </a>';
48
+
49
+ $this->icon = '<img src="' . plugin_dir_url( __FILE__ ) . '../image/remote/dreamhost-logo.png"></img>';
50
+ }
51
+ }
admin/card/class-find-modified-files.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Find Modified Files class.
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.13.1
7
+ *
8
+ * @package Boldgrid\Backup
9
+ * @subpackage Boldgrid\Backup\Card
10
+ * @copyright BoldGrid
11
+ * @author BoldGrid <support@boldgrid.com>
12
+ */
13
+
14
+ namespace Boldgrid\Backup\Admin\Card;
15
+
16
+ /**
17
+ * Class: Find Modified Files
18
+ *
19
+ * @since 1.13.1
20
+ */
21
+ class Find_Modified_Files extends \Boldgrid\Library\Library\Ui\Card {
22
+ /**
23
+ * Init.
24
+ *
25
+ * @since 1.13.1
26
+ */
27
+ public function init() {
28
+ $this->id = 'bgbkup_find_modified_files';
29
+
30
+ $this->title = esc_html__( 'Find Modified Files', 'boldgrid-backup' );
31
+
32
+ $this->icon = '<span class="dashicons dashicons-search"></span>';
33
+
34
+ $this->footer = '
35
+ <p>' .
36
+ esc_html__(
37
+ 'Search for all files modified within a certain time period. You can also look for other versions of that file within your backups.',
38
+ 'boldgrid-backup' ) .
39
+ '</p>';
40
+ }
41
+ }
admin/card/class-google-drive.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Google Drive class.
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.13.0
7
+ *
8
+ * @package Boldgrid\Backup
9
+ * @subpackage Boldgrid\Backup\Card
10
+ * @copyright BoldGrid
11
+ * @author BoldGrid <support@boldgrid.com>
12
+ */
13
+
14
+ namespace Boldgrid\Backup\Admin\Card;
15
+
16
+ /**
17
+ * Class: Google Drive
18
+ *
19
+ * This class is responsible for rendering the "Google drive" card on this
20
+ * plugin's Premium Features Page.
21
+ *
22
+ * @since 1.13.0
23
+ */
24
+ class Google_Drive extends \Boldgrid\Library\Library\Ui\Card {
25
+ /**
26
+ * Init.
27
+ *
28
+ * @since 1.13.0
29
+ */
30
+ public function init() {
31
+ $this->id = 'bgbkup_google_drive';
32
+
33
+ $this->title = esc_html__( 'Google Drive', 'boldgrid-backup' );
34
+
35
+ $this->icon = '<img src="' . plugin_dir_url( __FILE__ ) . '../image/remote/google-drive.png"></img>';
36
+
37
+ $this->footer = '
38
+ <p>' .
39
+ esc_html__(
40
+ 'Keep your backup archives safe and secure with remote, automated backups to Google Drive.',
41
+ 'boldgrid-backup' ) .
42
+ '</p>';
43
+
44
+ $url = esc_url( 'https://www.boldgrid.com/support/total-upkeep/auto-backup-to-google-drive/?source=google-drive' );
45
+
46
+ $this->links = '
47
+ <a target="_blank" href=" ' . $url . '">' .
48
+ esc_html__( 'Setup Guide' ) . '
49
+ </a>';
50
+ }
51
+ }
admin/card/class-historical-versions.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * HistoricalVersions class.
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.13.0
7
+ *
8
+ * @package Boldgrid\Backup
9
+ * @subpackage Boldgrid\Backup\Card
10
+ * @copyright BoldGrid
11
+ * @author BoldGrid <support@boldgrid.com>
12
+ */
13
+
14
+ namespace Boldgrid\Backup\Admin\Card;
15
+
16
+ /**
17
+ * Class: Historical_Versions
18
+ *
19
+ * This class is responsible for rendering the "Historical Versions" card on this
20
+ * plugin's Premium Features Page.
21
+ *
22
+ * @since 1.13.0
23
+ */
24
+ class Historical_Versions extends \Boldgrid\Library\Library\Ui\Card {
25
+ /**
26
+ * Init.
27
+ *
28
+ * @since 1.13.0
29
+ */
30
+ public function init() {
31
+ $this->id = 'bgbkup_historical_versions';
32
+
33
+ $this->title = esc_html__( 'Historical Versions', 'boldgrid-backup' );
34
+
35
+ $this->icon = '<span class="dashicons dashicons-images-alt2"></span>';
36
+
37
+ $this->footer = '
38
+ <p>' .
39
+ esc_html__(
40
+ 'Search through all backup archives for a particular, individual file and restore it.',
41
+ 'boldgrid-backup' ) .
42
+ '</p>';
43
+
44
+ $url = esc_url( 'https://www.boldgrid.com/support/total-upkeep/restore-historical-files/?source=historical-versions' );
45
+
46
+ $this->links = '
47
+ <a target="_blank" href="' . $url . '">' .
48
+ esc_html__( 'Setup Guide' ) . '
49
+ </a>';
50
+ }
51
+ }
admin/card/class-history.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * History class.
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.13.0
7
+ *
8
+ * @package Boldgrid\Backup
9
+ * @subpackage Boldgrid\Backup\Card
10
+ * @copyright BoldGrid
11
+ * @author BoldGrid <support@boldgrid.com>
12
+ */
13
+
14
+ namespace Boldgrid\Backup\Admin\Card;
15
+
16
+ /**
17
+ * Class: History
18
+ *
19
+ * This class is responsible for rendering the "History" card on this plugin's
20
+ * Premium Features Page.
21
+ *
22
+ * @since 1.13.0
23
+ */
24
+ class History extends \Boldgrid\Library\Library\Ui\Card {
25
+ /**
26
+ * Init.
27
+ *
28
+ * @since 1.13.0
29
+ */
30
+ public function init() {
31
+ $this->id = 'bgbkup_history';
32
+
33
+ $this->title = esc_html__( 'Update History', 'boldgrid-backup' );
34
+
35
+ $this->icon = '<span class="dashicons dashicons-media-text"></span>';
36
+
37
+ $this->footer = '
38
+ <p>' .
39
+ esc_html__(
40
+ 'View a running log of significant actions to your WordPress site, including which users updated a plugin, theme, or WordPress itself.',
41
+ 'boldgrid-backup' ) .
42
+ '</p>';
43
+
44
+ $url = esc_url( 'https://www.boldgrid.com/support/total-upkeep/backup-changed-files-history/?source=update-history' );
45
+
46
+ $this->links = '
47
+ <a target="_blank" href="' . $url . '">' .
48
+ esc_html__( 'Setup Guide' ) . '
49
+ </a>';
50
+ }
51
+ }
admin/card/class-one-click-restoration.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * One_Click_Restoration class.
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.13.0
7
+ *
8
+ * @package Boldgrid\Backup
9
+ * @subpackage Boldgrid\Backup\Card
10
+ * @copyright BoldGrid
11
+ * @author BoldGrid <support@boldgrid.com>
12
+ */
13
+
14
+ namespace Boldgrid\Backup\Admin\Card;
15
+
16
+ /**
17
+ * Class: One_Click_Restoration
18
+ *
19
+ * This class is responsible for rendering the "One Click Restoration" card
20
+ * on this plugin's Premium Features Page.
21
+ *
22
+ * @since 1.13.0
23
+ */
24
+ class One_Click_Restoration extends \Boldgrid\Library\Library\Ui\Card {
25
+ /**
26
+ * Init.
27
+ *
28
+ * @since 1.13.0
29
+ */
30
+ public function init() {
31
+ $this->id = 'bgbkup_one_click_restoration';
32
+
33
+ $this->title = esc_html__( 'One Click File Restorations', 'boldgrid-backup' );
34
+
35
+ $this->icon = '<span class="dashicons dashicons-undo"></span>';
36
+
37
+ $this->footer = '
38
+ <p>' .
39
+ esc_html__(
40
+ 'Restore a single file within the backup browser. Helpful when modifying individual files.',
41
+ 'boldgrid-backup' ) .
42
+ '</p>';
43
+
44
+ $url = esc_url( 'https://www.boldgrid.com/support/total-upkeep/individual-file-restorations/?source=one-click-restore' );
45
+
46
+ $this->links = '
47
+ <a target="_blank" href="' . $url . '">' .
48
+ esc_html__( 'Setup Guide' ) . '
49
+ </a>';
50
+ }
51
+ }
admin/card/class-plugin-editor-tools.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * PluginEditorTools class.
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.13.0
7
+ *
8
+ * @package Boldgrid\Backup
9
+ * @subpackage Boldgrid\Backup\Card
10
+ * @copyright BoldGrid
11
+ * @author BoldGrid <support@boldgrid.com>
12
+ */
13
+
14
+ namespace Boldgrid\Backup\Admin\Card;
15
+
16
+ /**
17
+ * Class: Plugin_Editor_Tools
18
+ *
19
+ * This class is responsible for rendering the "Plugin Editor Tools"
20
+ * card on this plugin's Premium Features Page.
21
+ *
22
+ * @since 1.13.0
23
+ */
24
+ class Plugin_Editor_Tools extends \Boldgrid\Library\Library\Ui\Card {
25
+ /**
26
+ * Init.
27
+ *
28
+ * @since 1.13.0
29
+ */
30
+ public function init() {
31
+ $this->id = 'bgbkup_plugin_editor_tools';
32
+
33
+ $this->title = esc_html__( 'Plugin Editor Tools', 'boldgrid-backup' );
34
+
35
+ $this->icon = '<span class="dashicons dashicons-media-code"></span>';
36
+
37
+ $this->footer = '
38
+ <p>' .
39
+ esc_html__(
40
+ 'When using the WordPress Plugin Editor, Total Upkeep Premium will save a copy of the file in case you need to undo any changes.',
41
+ 'boldgrid-backup' ) .
42
+ '</p>';
43
+
44
+ $url = esc_url( 'https://www.boldgrid.com/support/total-upkeep/plugin-editor-backup/?source=plugin-editor-tools' );
45
+
46
+ $this->links = '
47
+ <a target="_blank" href="' . $url . '">' .
48
+ esc_html__( 'Setup Guide' ) . '
49
+ </a>';
50
+ }
51
+ }
admin/card/class-premium.php ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Premium class.
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.11.0
7
+ *
8
+ * @package Boldgrid\Backup
9
+ * @subpackage Boldgrid\Backup\Card
10
+ * @copyright BoldGrid
11
+ * @author BoldGrid <support@boldgrid.com>
12
+ */
13
+
14
+ namespace Boldgrid\Backup\Admin\Card;
15
+
16
+ /**
17
+ * Class: Premium
18
+ *
19
+ * This class is responsible for rendering the "Premium" card on this plugin's dashboard.
20
+ *
21
+ * @since 1.11.0
22
+ */
23
+ class Premium extends \Boldgrid\Library\Library\Ui\Card {
24
+ /**
25
+ * Init.
26
+ *
27
+ * @since 1.11.0
28
+ */
29
+ public function init() {
30
+ $core = apply_filters( 'boldgrid_backup_get_core', null );
31
+
32
+ $api_key = apply_filters( 'Boldgrid\Library\License\getApiKey', '' ); // phpcs:ignore
33
+
34
+ $this->id = 'bgbkup_get_premium';
35
+
36
+ $this->icon = '<span class="dashicons dashicons-admin-network"></span>';
37
+
38
+ $features = [];
39
+
40
+ if ( empty( $api_key ) ) {
41
+ $this->title = esc_html__( 'Build Better Websites With BoldGrid Central', 'boldgrid-backup' );
42
+
43
+ $this->subTitle = esc_html__( 'All the tools and services you need to succeed.', 'boldgrid-backup' ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.NotSnakeCaseMemberVar
44
+
45
+ $this->features = [
46
+ new Feature\Cloud_Wordpress(),
47
+ new Feature\Speed_Coach(),
48
+ new Feature\Sign_Up(),
49
+ ];
50
+ } elseif ( ! $core->config->get_is_premium() ) {
51
+ $this->title = esc_html__( 'Enjoying your free account?', 'boldgrid-backup' );
52
+
53
+ $this->subTitle = esc_html__( 'We hope so. There\'s more available by upgrading now!', 'boldgrid-backup' ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.NotSnakeCaseMemberVar
54
+
55
+ $this->features = [
56
+ new Feature\More_Backup(),
57
+ new Feature\More_Boldgrid(),
58
+ new Feature\More_Central(),
59
+ ];
60
+ } else {
61
+ $this->title = esc_html__( 'BoldGrid Premium', 'boldgrid-backup' );
62
+
63
+ $this->subTitle = esc_html__( 'Thank you for running BoldGrid Premium!', 'boldgrid-backup' ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.NotSnakeCaseMemberVar
64
+
65
+ $this->features = [
66
+ new Feature\Central(),
67
+ ];
68
+ }
69
+ }
70
+ }
admin/card/class-updates.php ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Updates class.
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.11.0
7
+ *
8
+ * @package Boldgrid\Backup
9
+ * @subpackage Boldgrid\Backup\Card
10
+ * @copyright BoldGrid
11
+ * @author BoldGrid <support@boldgrid.com>
12
+ */
13
+
14
+ namespace Boldgrid\Backup\Admin\Card;
15
+
16
+ /**
17
+ * Class: Updates
18
+ *
19
+ * This class is responsible for rendering the "Update Management" card on this plugin's dashboard.
20
+ *
21
+ * @since 1.11.0
22
+ */
23
+ class Updates extends \Boldgrid\Library\Library\Ui\Card {
24
+ /**
25
+ * Init.
26
+ *
27
+ * @since 1.11.0
28
+ */
29
+ public function init() {
30
+ $this->id = 'bgbkup_updates';
31
+
32
+ $this->title = esc_html__( 'Update Management', 'boldgrid-backup' );
33
+
34
+ $this->subTitle = esc_html__( 'Keep everything tidy and up to date.', 'boldgrid-backup' ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.NotSnakeCaseMemberVar
35
+
36
+ $this->icon = '<span class="dashicons dashicons-plugins-checked"></span>';
37
+
38
+ $this->features = [
39
+ new Feature\Versions(),
40
+ new Feature\Auto_Rollback(),
41
+ new Feature\Auto_Update_Backup(),
42
+ ];
43
+ }
44
+ }
admin/card/feature/class-auto-rollback.php ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Auto_Rollback class.
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.11.0
7
+ *
8
+ * @package Boldgrid\Backup
9
+ * @subpackage Boldgrid\Backup\Card
10
+ * @copyright BoldGrid
11
+ * @author BoldGrid <support@boldgrid.com>
12
+ */
13
+
14
+ namespace Boldgrid\Backup\Admin\Card\Feature;
15
+
16
+ /**
17
+ * Class: Auto_Rollback
18
+ *
19
+ * This class is responsible for rendering the "Auto Rollback" feature on this plugin's dashboard.
20
+ *
21
+ * @since 1.11.0
22
+ */
23
+ class Auto_Rollback extends \Boldgrid\Library\Library\Ui\Feature {
24
+ /**
25
+ * Init.
26
+ *
27
+ * @since 1.11.0
28
+ */
29
+ public function init() {
30
+ $core = apply_filters( 'boldgrid_backup_get_core', null );
31
+
32
+ $this->icon = '<span class="dashicons dashicons-controls-back"></span>';
33
+
34
+ $this->title = __( 'Auto Rollback', 'boldgrid-backup' );
35
+
36
+ if ( $core->auto_rollback->is_enabled() ) {
37
+ $this->content = '<p>' . esc_html__( 'Auto Rollback is enabled!', 'boldgrid-backup' ) . '</p>';
38
+ } else {
39
+ $this->content = '<p>' . esc_html__( 'With Auto Rollback, we can help fix your site if anything goes wrong while performing updates.', 'boldgrid-backup' ) . '</p>';
40
+ $this->content .= '<div class="notice notice-error inline"><p>' .
41
+ wp_kses(
42
+ sprintf(
43
+ // translators: 1 An opening anchor tag to the "Auto Updates" settings page, 2 its closing tag.
44
+ __( 'Auto Rollback is not enabled. %1$sFix this%2$s.', 'boldgrid-backup' ),
45
+ '<a href="' . esc_url( $core->settings->get_settings_url( 'section_auto_updates' ) ) . '">',
46
+ '</a>'
47
+ ),
48
+ [ 'a' => [ 'href' => [] ] ]
49
+ ) . '</p></div>';
50
+ }
51
+ }
52
+ }
admin/card/feature/class-auto-update-backup.php ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Auto_Update_Backup class.
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.11.0
7
+ *
8
+ * @package Boldgrid\Backup
9
+ * @subpackage Boldgrid\Backup\Feature
10
+ * @copyright BoldGrid
11
+ * @author BoldGrid <support@boldgrid.com>
12
+ */
13
+
14
+ namespace Boldgrid\Backup\Admin\Card\Feature;
15
+
16
+ /**
17
+ * Class: Auto_Update_Backup
18
+ *
19
+ * This class is responsible for rendering the, "Auto Backup Before Updates" feature on the BoldGrid
20
+ * Backup Dashboard.
21
+ *
22
+ * @since 1.11.0
23
+ */
24
+ class Auto_Update_Backup extends \Boldgrid\Library\Library\Ui\Feature {
25
+ /**
26
+ * Init.
27
+ *
28
+ * @since 1.11.0
29
+ */
30
+ public function init() {
31
+ $core = apply_filters( 'boldgrid_backup_get_core', null );
32
+
33
+ $this->icon = '<span class="dashicons dashicons-update-alt"></span>';
34
+
35
+ $this->title = __( 'Auto Backup Before Updates', 'boldgrid-backup' );
36
+
37
+ // Determine whether or not this feature is enabled.
38
+ $setting_value = $core->settings->get_setting( 'auto_backup' );
39
+ $is_enabled = ! empty( $setting_value );
40
+
41
+ if ( $is_enabled ) {
42
+ $this->content = '<p>' . esc_html__( 'Auto Backup Before Updates is enabled!', 'boldgrid-backup' ) . '</p>';
43
+ } else {
44
+ $this->content = '<p>' . esc_html__( 'When Auto Backup is enabled, we will backup your site before any auto-updates occur.', 'boldgrid-backup' ) . '</p>';
45
+ $this->content .= '<div class="notice notice-error inline"><p>' . wp_kses(
46
+ sprintf(
47
+ // translators: 1 Opening anchor tag to "Auto Updates" settings page, 2 its closing tag.
48
+ __( 'Auto Backup Before Updates is not enabled. %1$sFix this%2$s.', 'boldgrid-backup' ),
49
+ '<a href="' . esc_url( $core->settings->get_settings_url( 'section_auto_updates' ) ) . '">',
50
+ '</a>'
51
+ ),
52
+ [ 'a' => [ 'href' => [] ] ]
53
+ ) . '</p></div>';
54
+ }
55
+ }
56
+ }
admin/card/feature/class-central.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Central class.
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.11.0
7
+ *
8
+ * @package Boldgrid\Backup
9
+ * @subpackage Boldgrid\Backup\Card
10
+ * @copyright BoldGrid
11
+ * @author BoldGrid <support@boldgrid.com>
12
+ */
13
+
14
+ namespace Boldgrid\Backup\Admin\Card\Feature;
15
+
16
+ /**
17
+ * Class: Central
18
+ *
19
+ * This class is responsible for initializing a BoldGrid Central "feature" for use within a card.
20
+ *
21
+ * @since 1.11.0
22
+ */
23
+ class Central extends \Boldgrid\Library\Library\Ui\Feature {
24
+ /**
25
+ * Init.
26
+ *
27
+ * @since 1.11.0
28
+ */
29
+ public function init() {
30
+ $reseller = new \Boldgrid\Library\Library\Reseller();
31
+
32
+ $this->icon = '<span class="dashicons boldgrid-icon"></span>';
33
+
34
+ $this->title = esc_html__( 'BoldGrid Central', 'boldgrid-backup' );
35
+
36
+ $this->content = '<p>' . esc_html__( 'Manage your account, Run Automated Website Speed Tests, and more within BoldGrid Central.', 'boldgrid-backup' ) . '</p>';
37
+
38
+ $this->content .= '<p style="text-align:right;"><a href="' . esc_url( $reseller->centralUrl ) . '">' . esc_html__( 'BoldGrid Central Login', 'boldgrid-backup' ) . '</a></p>'; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.NotSnakeCaseMemberVar
39
+ }
40
+ }
admin/card/feature/class-cloud-wordpress.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Cloud_WordPress class.
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.11.0
7
+ *
8
+ * @package Boldgrid\Backup
9
+ * @subpackage Boldgrid\Backup\Card
10
+ * @copyright BoldGrid
11
+ * @author BoldGrid <support@boldgrid.com>
12
+ */
13
+
14
+ namespace Boldgrid\Backup\Admin\Card\Feature;
15
+
16
+ /**
17
+ * Class: Cloud_WordPress
18
+ *
19
+ * @since 1.11.0
20
+ */
21
+ class Cloud_Wordpress extends \Boldgrid\Library\Library\Ui\Feature { //phpcs:ignore
22
+ /**
23
+ * Init.
24
+ *
25
+ * @since 1.11.0
26
+ */
27
+ public function init() {
28
+ $this->icon = '<span class="dashicons dashicons-cloud"></span>';
29
+
30
+ $this->title = __( 'Cloud WordPress', 'boldgrid-backup' );
31
+
32
+ $this->content = '<p>' . __( 'Create a fully functional free WordPress demo in just a few clicks. Easily design, build, test and share your WordPress website with clients or teams.', 'boldgrid-backup' ) . '</p>';
33
+ }
34
+ }
admin/card/feature/class-database-encryption.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Database_Encryption class.
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.13.0
7
+ *
8
+ * @package Boldgrid\Backup
9
+ * @subpackage Boldgrid\Backup\Card
10
+ * @copyright BoldGrid
11
+ * @author BoldGrid <support@boldgrid.com>
12
+ */
13
+
14
+ namespace Boldgrid\Backup\Admin\Card\Feature;
15
+
16
+ /**
17
+ * Class: Database_Encryption
18
+ *
19
+ * @since 1.13.0
20
+ */
21
+ class Database_Encryption extends \Boldgrid\Library\Library\Ui\Feature {
22
+ /**
23
+ * Init.
24
+ *
25
+ * @since 1.13.0
26
+ */
27
+ public function init() {
28
+ $core = apply_filters( 'boldgrid_backup_get_core', null );
29
+
30
+ $this->icon = '<img class="feature-icon" src="' . plugin_dir_url( BOLDGRID_BACKUP_PATH ) . 'boldgrid-backup/admin/image/db-lock-64.png" />';
31
+
32
+ $this->title = esc_html__( 'Database Encryption', 'boldgrid-backup' );
33
+
34
+ $this->content = '<p>' . esc_html__( 'Secure your sensitive data with database encryption.', 'boldgrid-backup' ) . '</p>';
35
+ $this->content .= '<div class="notice notice-warning inline"><p>' . wp_kses(
36
+ sprintf(
37
+ // translators: 1 An opening anchor tag to the Remote Storage settings, 2 its closing anchor tag.
38
+ __( 'Database Encryption is not configured. %1$sFix this%2$s', 'boldgrid-backup' ),
39
+ '<a href="' . esc_url( $core->settings->get_settings_url( 'section_security' ) ) . '">',
40
+ '</a>'
41
+ ),
42
+ [ 'a' => [ 'href' => [] ] ]
43
+ ) . '</p></div>';
44
+ }
45
+ }
admin/card/feature/class-more-backup.php ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * More_Backup class.
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.11.0
7
+ *
8
+ * @package Boldgrid\Backup
9
+ * @subpackage Boldgrid\Backup\Card
10
+ * @copyright BoldGrid
11
+ * @author BoldGrid <support@boldgrid.com>
12
+ */
13
+
14
+ namespace Boldgrid\Backup\Admin\Card\Feature;
15
+
16
+ /**
17
+ * Class: More_Backup
18
+ *
19
+ * @since 1.11.0
20
+ */
21
+ class More_Backup extends \Boldgrid\Library\Library\Ui\Feature {
22
+ /**
23
+ * Init.
24
+ *
25
+ * @since 1.11.0
26
+ */
27
+ public function init() {
28
+ $this->icon = '<span class="dashicons dashicons-vault"></span>';
29
+
30
+ $this->title = sprintf(
31
+ // translators: 1: Plugin title.
32
+ esc_html__( 'More %1$s Features', 'boldgrid-backup' ),
33
+ BOLDGRID_BACKUP_TITLE
34
+ );
35
+
36
+ $this->content = '<p>' . wp_kses(
37
+ sprintf(
38
+ // translators: 1 A span displaying the Google Drive logo, 2 a span displaying the Amazon S3 logo.
39
+ esc_html__( '%3$s can store backups on %1$s and %2$s, restore individual files with just a click, and more!', 'boldgrid-backup' ),
40
+ '<span class="bgbkup-remote-logo bgbkup-gdrive-logo" title="Google Drive"></span>',
41
+ '<span class="bgbkup-remote-logo amazon-s3-logo" title="Amazon S3"></span>',
42
+ BOLDGRID_BACKUP_TITLE . ' Premium'
43
+ ),
44
+ [
45
+ 'span' => [
46
+ 'class' => [],
47
+ 'title' => [],
48
+ ],
49
+ ]
50
+ ) . '</p>';
51
+ }
52
+ }
admin/card/feature/class-more-boldgrid.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * More_Boldgrid class.
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.11.0
7
+ *
8
+ * @package Boldgrid\Backup
9
+ * @subpackage Boldgrid\Backup\Card
10
+ * @copyright BoldGrid
11
+ * @author BoldGrid <support@boldgrid.com>
12
+ */
13
+
14
+ namespace Boldgrid\Backup\Admin\Card\Feature;
15
+
16
+ /**
17
+ * Class: More_Boldgrid
18
+ *
19
+ * @since 1.11.0
20
+ */
21
+ class More_Boldgrid extends \Boldgrid\Library\Library\Ui\Feature {
22
+ /**
23
+ * Init.
24
+ *
25
+ * @since 1.11.0
26
+ */
27
+ public function init() {
28
+ $this->icon = '<span class="dashicons dashicons-admin-plugins"></span>';
29
+
30
+ $this->title = esc_html__( 'More Premium BoldGrid Plugins', 'boldgrid-backup' );
31
+
32
+ $this->content = '<p>' . esc_html__( 'Gain access to all BoldGrid premium plugins and services. This includes Post and Page Builder Premium, which offers premium Blocks and native sliders.', 'boldgrid-backup' ) . '</p>';
33
+ }
34
+ }
admin/card/feature/class-more-central.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * More_Central class.
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.11.0
7
+ *
8
+ * @package Boldgrid\Backup
9
+ * @subpackage Boldgrid\Backup\Card
10
+ * @copyright BoldGrid
11
+ * @author BoldGrid <support@boldgrid.com>
12
+ */
13
+
14
+ namespace Boldgrid\Backup\Admin\Card\Feature;
15
+
16
+ /**
17
+ * Class: More_Central
18
+ *
19
+ * @since 1.11.0
20
+ */
21
+ class More_Central extends \Boldgrid\Library\Library\Ui\Feature {
22
+ /**
23
+ * Init.
24
+ *
25
+ * @since 1.11.0
26
+ */
27
+ public function init() {
28
+ $core = apply_filters( 'boldgrid_backup_get_core', null );
29
+
30
+ $get_premium_url = $core->go_pro->get_premium_url( 'bgbkup-dashboard' );
31
+
32
+ $this->icon = '<span class="dashicons boldgrid-icon"></span>';
33
+
34
+ $this->title = esc_html__( 'More BoldGrid Central Features', 'boldgrid-backup' );
35
+
36
+ $this->content = '<p>' . esc_html__( 'Unlock more features within BoldGrid Central, including Cloud WordPress Advanced Controls and Automated Website Speed Tests.', 'boldgrid-backup' ) . '</p>';
37
+
38
+ $this->content .= '<p style="text-align:right;"><a href="' . esc_url( $get_premium_url ) . '" class="button button-primary boldgrid-orange">' . __( 'Get Premium', 'boldgrid-backup' ) . '</a></p>';
39
+ }
40
+ }
admin/card/feature/class-remote-storage.php ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Remote_Storage class.
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.11.0
7
+ *
8
+ * @package Boldgrid\Backup
9
+ * @subpackage Boldgrid\Backup\Card
10
+ * @copyright BoldGrid
11
+ * @author BoldGrid <support@boldgrid.com>
12
+ */
13
+
14
+ namespace Boldgrid\Backup\Admin\Card\Feature;
15
+
16
+ /**
17
+ * Class: Remote_Storage
18
+ *
19
+ * @since 1.11.0
20
+ */
21
+ class Remote_Storage extends \Boldgrid\Library\Library\Ui\Feature {
22
+ /**
23
+ * Init.
24
+ *
25
+ * @since 1.11.0
26
+ */
27
+ public function init() {
28
+ $core = apply_filters( 'boldgrid_backup_get_core', null );
29
+
30
+ $this->icon = '<span class="dashicons dashicons-networking"></span>';
31
+
32
+ $this->title = esc_html__( 'Remote Storage', 'boldgrid-backup' );
33
+
34
+ if ( $core->settings->has_remote_configured() ) {
35
+ $storage_locations = $core->remote->get_enabled( 'title' );
36
+
37
+ $this->content = '<p>' .
38
+ wp_kses(
39
+ sprintf(
40
+ // translators: 1 An opening span tag, A list of remote backup storage locations (csv), its closing span tag.
41
+ __( 'Backups saved to: %1$s%2$s%3$s', 'boldgrid-bakcup' ),
42
+ '<span class="bglib-feature-value">',
43
+ esc_html( implode( ', ', $storage_locations ) ),
44
+ '</span>'
45
+ ),
46
+ [
47
+ 'span' => [
48
+ 'class' => [],
49
+ ],
50
+ ]
51
+ ) .
52
+ '</p>';
53
+ } else {
54
+ $this->content = '<p>' . esc_html__( 'Don\'t put all of your eggs in one basket! Store your backups remotely.', 'boldgrid-backup' ) . '</p>';
55
+ $this->content .= '<div class="notice notice-error inline"><p>' . wp_kses(
56
+ sprintf(
57
+ // translators: 1 An opening anchor tag to the Remote Storage settings, 2 its closing anchor tag.
58
+ __( 'Remote storage is not configured. %1$sFix this%2$s', 'boldgrid-backup' ),
59
+ '<a href="' . esc_url( $core->settings->get_settings_url( 'section_storage' ) ) . '">',
60
+ '</a>'
61
+ ),
62
+ [ 'a' => [ 'href' => [] ] ]
63
+ ) . '</p></div>';
64
+ }
65
+ }
66
+ }
admin/card/feature/class-scheduled-backups.php ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Scheduled_Backups class.
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.11.0
7
+ *
8
+ * @package Boldgrid\Backup
9
+ * @subpackage Boldgrid\Backup\Card
10
+ * @copyright BoldGrid
11
+ * @author BoldGrid <support@boldgrid.com>
12
+ */
13
+
14
+ namespace Boldgrid\Backup\Admin\Card\Feature;
15
+
16
+ /**
17
+ * Class: Scheduled_Backups
18
+ *
19
+ * This class is responsible for displaying the scheduled backups feature on this plugin's dashboard.
20
+ *
21
+ * @since 1.11.0
22
+ */
23
+ class Scheduled_Backups extends \Boldgrid\Library\Library\Ui\Feature {
24
+ /**
25
+ * Init.
26
+ *
27
+ * @since 1.11.0
28
+ */
29
+ public function init() {
30
+ $core = apply_filters( 'boldgrid_backup_get_core', null );
31
+
32
+ $this->icon = '<span class="dashicons dashicons-clock"></span>';
33
+
34
+ $this->title = esc_html__( 'Scheduled Backups', 'boldgrid-backup' );
35
+
36
+ $cron = new \Boldgrid\Backup\Admin\Cron();
37
+ $backup_entry = $cron->get_entry( 'backup' );
38
+
39
+ /*
40
+ * If a user does not have backups scheduled, suggest they schedule them.
41
+ *
42
+ * As of 1.11.4, in addition to checking if a schedule is saved in the settings, we also ensure
43
+ * that the backup cron can be found. We need to check for the scenario in which the user has
44
+ * manually deleted the cron entry yet the settings say backups are scheduled.
45
+ *
46
+ * In some cases where the settings say backups are scheduled but the cron doesn't actually
47
+ * exist, false positives may be given or errors triggered. We may want to explore the idea
48
+ * of showing an admin notice. For now, if this scenario exists, the dashboard will tell the
49
+ * user to schedule backups, and resaving the settings will resave the cron entry.
50
+ */
51
+ if ( $core->settings->has_scheduled_backups() && $backup_entry->is_set() ) {
52
+ $next_runtime = $backup_entry->get_next_runtime();
53
+
54
+ $this->content = '<p>' . wp_kses(
55
+ sprintf(
56
+ // Translators: 1 An opening span tag, 2 the date of the next backup, 3 its closing span tag.
57
+ __( 'Next backup in: %1$s%2$s%3$s', 'boldgrid-backup' ),
58
+ '<span class="bglib-feature-value" title="' . esc_attr( date( 'M j, Y h:i a', $next_runtime ) ) . '">',
59
+ human_time_diff( time(), $next_runtime ),
60
+ '</span>'
61
+ ),
62
+ [
63
+ 'span' => [
64
+ 'class' => [],
65
+ 'title' => [],
66
+ ],
67
+ ]
68
+ ) . '</p>';
69
+ } else {
70
+ $this->content = '<p>' . esc_html__( 'It\'s easy to forget to make a backup. Schedule automatic backups so they\'re made for you.', 'boldgrid-backup' ) . '</p>';
71
+ $this->content .= '<div class="notice notice-error inline"><p>' . wp_kses(
72
+ sprintf(
73
+ // translators: 1 An opening anchor tag to the settings page, 2 its closing tag.
74
+ __( 'Scheduled backups not configured. %1$sFix this%2$s.', 'boldgrid-backup' ),
75
+ '<a href="' . esc_url( $core->settings->get_settings_url() ) . '">',
76
+ '</a>'
77
+ ),
78
+ [
79
+ 'a' => [
80
+ 'href' => [],
81
+ ],
82
+ ]
83
+ ) . '</p></div>';
84
+ }
85
+ }
86
+ }
admin/card/feature/class-sign-up.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Sign_Up class.
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.11.0
7
+ *
8
+ * @package Boldgrid\Backup
9
+ * @subpackage Boldgrid\Backup\Card
10
+ * @copyright BoldGrid
11
+ * @author BoldGrid <support@boldgrid.com>
12
+ */
13
+
14
+ namespace Boldgrid\Backup\Admin\Card\Feature;
15
+
16
+ /**
17
+ * Class: Sign_Up
18
+ *
19
+ * @since 1.11.0
20
+ */
21
+ class Sign_Up extends \Boldgrid\Library\Library\Ui\Feature {
22
+ /**
23
+ * Init.
24
+ *
25
+ * @since 1.11.0
26
+ */
27
+ public function init() {
28
+ $new_key_url = \Boldgrid\Library\Library\Key\PostNewKey::getCentralUrl( admin_url( 'admin.php?page=boldgrid-backup-dashboard' ) );
29
+
30
+ $this->icon = '<span class="dashicons dashicons-clipboard"></span>';
31
+
32
+ $this->content = '<p>' . esc_html__( 'There’s more waiting for you in BoldGrid Central. Download the full-featured community versions of ALL our plugins for FREE. It’s just a click away.', 'boldgrid-backup' ) . '</p>';
33
+
34
+ $this->content .= '<p style="text-align:right;"><a href="' . esc_url( $new_key_url ) . '" class="button button-primary boldgrid-orange">' . __( 'Sign Up for Free!', 'boldgrid-backup' ) . '</a></p>';
35
+ }
36
+ }
admin/card/feature/class-speed-coach.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Speed_Coach class.
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.11.0
7
+ *
8
+ * @package Boldgrid\Backup
9
+ * @subpackage Boldgrid\Backup\Card
10
+ * @copyright BoldGrid
11
+ * @author BoldGrid <support@boldgrid.com>
12
+ */
13
+
14
+ namespace Boldgrid\Backup\Admin\Card\Feature;
15
+
16
+ /**
17
+ * Class: Speed_Coach
18
+ *
19
+ * @since 1.11.0
20
+ */
21
+ class Speed_Coach extends \Boldgrid\Library\Library\Ui\Feature {
22
+ /**
23
+ * Init.
24
+ *
25
+ * @since 1.11.0
26
+ */
27
+ public function init() {
28
+ $this->icon = '<span class="dashicons dashicons-chart-line"></span>';
29
+
30
+ $this->title = esc_html__( 'Speed Coach', 'boldgrid-backup' );
31
+
32
+ $this->content = '<p>' . esc_html__( 'A faster website means happier visitors and higher rankings on the search engines. Simply type in your website’s URL and receive detailed advice on making your site lightning fast.', 'boldgrid-backup' ) . '</p>';
33
+ }
34
+ }
admin/card/feature/class-versions.php ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * My Backups class.
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.11.0
7
+ *
8
+ * @package Boldgrid\Backup
9
+ * @subpackage Boldgrid\Backup\Card
10
+ * @copyright BoldGrid
11
+ * @author BoldGrid <support@boldgrid.com>
12
+ */
13
+
14
+ namespace Boldgrid\Backup\Admin\Card\Feature;
15
+
16
+ /**
17
+ * Class: Versions
18
+ *
19
+ * @since 1.11.0
20
+ */
21
+ class Versions extends \Boldgrid\Library\Library\Ui\Feature {
22
+ /**
23
+ *
24
+ */
25
+ public function init() {
26
+ $data = wp_get_update_data();
27
+
28
+ $has_updates = ! empty( $data['counts']['plugins'] ) || ! empty( $data['counts']['themes'] ) || ! empty( $data['counts']['wordpress'] );
29
+
30
+ $this->icon = '<span class="dashicons dashicons-wordpress"></span>';
31
+
32
+ $this->title = esc_html__( 'WordPress, Plugins, & Theme Version', 'boldgrid-backup' );
33
+
34
+ if ( $has_updates ) {
35
+ $this->content = '<p>' . wp_kses(
36
+ sprintf(
37
+ // translators: 1 A description of what updates are available (such as plugins, themes, or core).
38
+ __( 'The following updates are available: %1$s', 'boldgrid-backup' ),
39
+ $data['title']
40
+ ),
41
+ []
42
+ ) . '</p>';
43
+
44
+ $this->content .= '<div class="notice notice-error inline"><p>' .
45
+ wp_kses(
46
+ sprintf(
47
+ // translators: 1 An opening anchor tag to the update-core.php page, 2 its closing tag.
48
+ __( 'Not everything is up to date. %1$sFix this%2$s.', 'boldgrid-backup' ),
49
+ '<a href="' . esc_url( admin_url( 'update-core.php' ) ) . '">',
50
+ '</a>'
51
+ ),
52
+ [
53
+ 'a' => [
54
+ 'href' => [],
55
+ ],
56
+ ]
57
+ ) .
58
+ '</p></div>';
59
+ } else {
60
+ $this->content = '<p>' . esc_html__( 'Everything is up to date!', 'boldgrid-backup' ) . '</p>';
61
+ }
62
+ }
63
+ }
admin/class-boldgrid-backup-admin-archive-actions.php CHANGED
@@ -1,28 +1,28 @@
1
  <?php
2
  /**
3
- * Archive Actions class.
4
  *
5
- * @link http://www.boldgrid.com
6
- * @since 1.5.4
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
- * @copyright BoldGrid.com
11
  * @version $Id$
12
- * @author BoldGrid.com <wpb@boldgrid.com>
13
  */
14
 
15
  /**
16
- * BoldGrid Backup Admin Archive Actions Class.
17
  *
18
- * @since 1.5.4
19
  */
20
  class Boldgrid_Backup_Admin_Archive_Actions {
21
 
22
  /**
23
  * The core class object.
24
  *
25
- * @since 1.5.4
26
  * @access private
27
  * @var Boldgrid_Backup_Admin_Core
28
  */
@@ -31,7 +31,7 @@ class Boldgrid_Backup_Admin_Archive_Actions {
31
  /**
32
  * Constructor.
33
  *
34
- * @since 1.5.4
35
  *
36
  * @param Boldgrid_Backup_Admin_Core $core Core class object.
37
  */
@@ -42,45 +42,72 @@ class Boldgrid_Backup_Admin_Archive_Actions {
42
  /**
43
  * Enqueue scripts.
44
  *
45
- * @since 1.5.4
46
  */
47
  public function enqueue_scripts() {
48
- $access_type = get_filesystem_method();
49
- $archive_nonce = wp_create_nonce( 'archive_auth' );
50
- $delete_confirm_text = esc_html__(
51
- 'Please confirm the deletion of the archive file:' . PHP_EOL,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  'boldgrid-backup'
53
  );
54
- $restore_confirm_text = esc_html__(
55
- 'Please confirm the restoration of this WordPress installation from the archive file:' .
56
- PHP_EOL . '"%s"' . PHP_EOL . PHP_EOL .
57
- 'Please be aware that you may get logged-out if your session token does not exist in the database restored.',
58
  'boldgrid-backup'
59
  );
60
 
61
  $handle = 'boldgrid-backup-admin-archive-actions';
62
- wp_register_script( $handle,
 
 
63
  plugin_dir_url( __FILE__ ) . 'js/' . $handle . '.js',
64
  array( 'jquery' ),
65
  BOLDGRID_BACKUP_VERSION,
66
  false
67
  );
 
68
  $translation = array(
69
- 'accessType' => $access_type,
70
- 'archiveNonce' => $archive_nonce,
71
- 'deleteConfirmText' => $delete_confirm_text,
72
  'restoreConfirmText' => $restore_confirm_text,
 
 
 
 
 
 
 
73
  );
 
74
  wp_localize_script( $handle, 'BoldGridBackupAdminArchiveActions', $translation );
75
  wp_enqueue_script( $handle );
 
 
76
  }
77
 
78
  /**
79
  * Return a link to delete an archive.
80
  *
81
- * @since 1.5.4
82
  *
83
- * @param string $filename
84
  * @return string
85
  */
86
  public function get_delete_link( $filename ) {
@@ -89,7 +116,8 @@ class Boldgrid_Backup_Admin_Archive_Actions {
89
  if ( empty( $archive ) ) {
90
  $link = '';
91
  } else {
92
- $link = sprintf( '
 
93
  <form method="post" id="delete-action" >
94
  <input type="hidden" name="delete_now" value="1" />
95
  <input type="hidden" name="archive_key" value="%2$s" />
@@ -112,9 +140,9 @@ class Boldgrid_Backup_Admin_Archive_Actions {
112
  /**
113
  * Return a link to download an archive.
114
  *
115
- * @since 1.5.4
116
  *
117
- * @param string $filename
118
  * @return string
119
  */
120
  public function get_download_button( $filename ) {
@@ -123,7 +151,8 @@ class Boldgrid_Backup_Admin_Archive_Actions {
123
  if ( empty( $archive ) ) {
124
  $button = '';
125
  } else {
126
- $button = sprintf( '
 
127
  <a
128
  id="backup-archive-download-%1$s"
129
  class="button button-primary action-download"
@@ -146,16 +175,16 @@ class Boldgrid_Backup_Admin_Archive_Actions {
146
  /**
147
  * Return a link to restore an archive.
148
  *
149
- * @since 1.5.4
150
  *
151
- * @param string $filename
152
- * @param array $args
153
  * @return string
154
  */
155
- public function get_restore_button( $filename, $args = array() ) {
156
- $defaults = array(
157
- 'button_text' => __( 'Restore' ),
158
- );
159
 
160
  $args = wp_parse_args( $args, $defaults );
161
 
@@ -164,26 +193,90 @@ class Boldgrid_Backup_Admin_Archive_Actions {
164
  if ( empty( $archive ) ) {
165
  $button = '';
166
  } else {
167
- $button = sprintf('
 
168
  <a
169
  data-restore-now="1"
170
- data-archive-key="%2$s"
171
- data-archive-filename="%3$s"
172
- data-nonce="%4$s"
173
  class="button restore-now"
174
  href="">
175
- %5$s
176
  </a>
177
- %6$s',
178
- /* 1 */ get_admin_url( null, 'admin.php?page=boldgrid-backup' ),
179
- /* 2 */ $archive['key'],
180
- /* 3 */ $filename,
181
- /* 4 */ wp_create_nonce( 'boldgrid_backup_restore_archive' ),
182
- /* 5 */ $args['button_text'],
183
- /* 6 */ $this->core->lang['spinner']
184
  );
185
  }
186
 
187
  return $button;
188
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
189
  }
1
  <?php
2
  /**
3
+ * File: class-boldgrid-backup-admin-archive-actions.php
4
  *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.5.4
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
  * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
  */
14
 
15
  /**
16
+ * Class: Boldgrid_Backup_Admin_Archive_Actions
17
  *
18
+ * @since 1.6.0
19
  */
20
  class Boldgrid_Backup_Admin_Archive_Actions {
21
 
22
  /**
23
  * The core class object.
24
  *
25
+ * @since 1.6.0
26
  * @access private
27
  * @var Boldgrid_Backup_Admin_Core
28
  */
31
  /**
32
  * Constructor.
33
  *
34
+ * @since 1.6.0
35
  *
36
  * @param Boldgrid_Backup_Admin_Core $core Core class object.
37
  */
42
  /**
43
  * Enqueue scripts.
44
  *
45
+ * @since 1.6.0
46
  */
47
  public function enqueue_scripts() {
48
+ $access_type = get_filesystem_method();
49
+ $archive_nonce = wp_create_nonce( 'archive_auth' );
50
+ $delete_confirm_text = __(
51
+ 'Please confirm the deletion of the archive file:',
52
+ 'boldgrid-backup'
53
+ ) . PHP_EOL;
54
+
55
+ // translators: 1: Archive filename.
56
+ $restore_confirm_text = __(
57
+ "Please confirm the restoration of this WordPress installation from the archive file:\n\"%s\"\n\nPlease be aware that you may get logged-out if your session token does not exist in the database restored.",
58
+ 'boldgrid-backup'
59
+ );
60
+
61
+ $link_error_text = __( 'Could not generate link.', 'boldgrid-backup' );
62
+ $unknown_error_text = __( 'Unknown error.', 'boldgrid-backup' );
63
+ $copy_text = __( 'Copy Link', 'boldgrid-backup' );
64
+ $copied_text = __( 'Copied!', 'boldgrid-backup' );
65
+ $expires_text = __( 'This link expires in:', 'boldgrid-backup' );
66
+ $link_disclaimer_text = __(
67
+ 'Please keep this link private, as the download file contains sensitive data.',
68
  'boldgrid-backup'
69
  );
70
+ $token_mismatch_text = __(
71
+ 'The database was encrypted with a token that does not match the one saved in your settings and cannot be imported. In order to restore the encrypted database, the matching encryption token is required. If you have the matching token, then go to the Backup Security settings page to save it.',
 
 
72
  'boldgrid-backup'
73
  );
74
 
75
  $handle = 'boldgrid-backup-admin-archive-actions';
76
+
77
+ wp_register_script(
78
+ $handle,
79
  plugin_dir_url( __FILE__ ) . 'js/' . $handle . '.js',
80
  array( 'jquery' ),
81
  BOLDGRID_BACKUP_VERSION,
82
  false
83
  );
84
+
85
  $translation = array(
86
+ 'accessType' => $access_type,
87
+ 'archiveNonce' => $archive_nonce,
88
+ 'deleteConfirmText' => $delete_confirm_text,
89
  'restoreConfirmText' => $restore_confirm_text,
90
+ 'linkErrorText' => $link_error_text,
91
+ 'unknownErrorText' => $unknown_error_text,
92
+ 'copyText' => $copy_text,
93
+ 'copiedText' => $copied_text,
94
+ 'expiresText' => $expires_text,
95
+ 'linkDisclaimerText' => $link_disclaimer_text,
96
+ 'tokenMismatchText' => $token_mismatch_text,
97
  );
98
+
99
  wp_localize_script( $handle, 'BoldGridBackupAdminArchiveActions', $translation );
100
  wp_enqueue_script( $handle );
101
+
102
+ wp_enqueue_script( 'clipboard' );
103
  }
104
 
105
  /**
106
  * Return a link to delete an archive.
107
  *
108
+ * @since 1.6.0
109
  *
110
+ * @param string $filename Filename.
111
  * @return string
112
  */
113
  public function get_delete_link( $filename ) {
116
  if ( empty( $archive ) ) {
117
  $link = '';
118
  } else {
119
+ $link = sprintf(
120
+ '
121
  <form method="post" id="delete-action" >
122
  <input type="hidden" name="delete_now" value="1" />
123
  <input type="hidden" name="archive_key" value="%2$s" />
140
  /**
141
  * Return a link to download an archive.
142
  *
143
+ * @since 1.6.0
144
  *
145
+ * @param string $filename Filename.
146
  * @return string
147
  */
148
  public function get_download_button( $filename ) {
151
  if ( empty( $archive ) ) {
152
  $button = '';
153
  } else {
154
+ $button = sprintf(
155
+ '
156
  <a
157
  id="backup-archive-download-%1$s"
158
  class="button button-primary action-download"
175
  /**
176
  * Return a link to restore an archive.
177
  *
178
+ * @since 1.6.0
179
  *
180
+ * @param string $filename Filename.
181
+ * @param array $args Arguments for the link/button.
182
  * @return string
183
  */
184
+ public function get_restore_button( $filename, $args = [] ) {
185
+ $defaults = [
186
+ 'button_text' => __( 'Restore', 'boldgrid-backup' ),
187
+ ];
188
 
189
  $args = wp_parse_args( $args, $defaults );
190
 
193
  if ( empty( $archive ) ) {
194
  $button = '';
195
  } else {
196
+ $button = sprintf(
197
+ '
198
  <a
199
  data-restore-now="1"
200
+ data-archive-key="%1$s"
201
+ data-archive-filename="%2$s"
202
+ data-nonce="%3$s"
203
  class="button restore-now"
204
  href="">
205
+ %4$s
206
  </a>
207
+ %5$s',
208
+ /* 1 */ $archive['key'],
209
+ /* 2 */ $filename,
210
+ /* 3 */ wp_create_nonce( 'boldgrid_backup_restore_archive' ),
211
+ /* 4 */ esc_html( $args['button_text'] ),
212
+ /* 5 */ $this->core->lang['spinner']
 
213
  );
214
  }
215
 
216
  return $button;
217
  }
218
+
219
+ /**
220
+ * Return a button link to request to generate a public link to download an archive file.
221
+ *
222
+ * @since 1.7.0
223
+ *
224
+ * @param string $filename Filename.
225
+ * @return string
226
+ */
227
+ public function get_download_link_button( $filename ) {
228
+ $link = '';
229
+ $archive = $this->core->archive->get_by_name( $filename );
230
+
231
+ if ( ! empty( $archive ) ) {
232
+ $link = sprintf(
233
+ '<a
234
+ id="download-link-button"
235
+ class="button"
236
+ href="#"
237
+ data-filename="%1$s"
238
+ data-nonce="%2$s"
239
+ >
240
+ %3$s
241
+ </a>
242
+ <span class="spinner"></span>
243
+ ',
244
+ /* 1 */ $archive['filename'],
245
+ /* 2 */ wp_create_nonce( 'boldgrid_backup_download_link' ),
246
+ /* 3 */ __( 'Get Download Link', 'boldgrid-backup' )
247
+ );
248
+ }
249
+
250
+ return $link;
251
+ }
252
+
253
+ /**
254
+ * Callback function for generating a public link to download an archive file.
255
+ *
256
+ * Used on the backup archive details page. The link is only valid for a limited time, which
257
+ * is configurable in a configuration file.
258
+ *
259
+ * @since 1.7.0
260
+ *
261
+ * @see Boldgrid_Backup_Admin_Archive::generate_download_link()
262
+ *
263
+ * @uses $_POST['archive_filename'] Backup archive filename.
264
+ *
265
+ * @return string
266
+ */
267
+ public function wp_ajax_generate_download_link() {
268
+ $archive_filename = ! empty( $_POST['archive_filename'] ) ?
269
+ sanitize_file_name( $_POST['archive_filename'] ) : null;
270
+
271
+ if ( check_admin_referer( 'boldgrid_backup_download_link', 'archive_auth' ) &&
272
+ current_user_can( 'update_plugins' ) && $archive_filename ) {
273
+ wp_send_json_success(
274
+ $this->core->archive->generate_download_link(
275
+ $archive_filename
276
+ )
277
+ );
278
+ } else {
279
+ wp_send_json_error();
280
+ }
281
+ }
282
  }
admin/class-boldgrid-backup-admin-archive-browser.php CHANGED
@@ -1,24 +1,29 @@
1
  <?php
2
  /**
3
- * Archive Browser class.
4
  *
5
- * @link http://www.boldgrid.com
6
- * @since 1.5.2
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
- * @copyright BoldGrid.com
11
  * @version $Id$
12
- * @author BoldGrid.com <wpb@boldgrid.com>
 
 
 
 
 
 
13
  */
14
 
15
  /**
16
- * BoldGrid Backup Admin Archive Browser Class.
17
  *
18
  * @since 1.5.2
19
  */
20
  class Boldgrid_Backup_Admin_Archive_Browser {
21
-
22
  /**
23
  * The core class object.
24
  *
@@ -45,7 +50,7 @@ class Boldgrid_Backup_Admin_Archive_Browser {
45
  * Many of the ajax handlers in this method require the same
46
  * current_user_can() and check_ajax_referer() checks.
47
  *
48
- * @since 1.5.4
49
  */
50
  public function authorize() {
51
  if ( ! current_user_can( 'update_plugins' ) ) {
@@ -53,7 +58,7 @@ class Boldgrid_Backup_Admin_Archive_Browser {
53
  }
54
 
55
  if ( ! check_ajax_referer( 'boldgrid_backup_remote_storage_upload', 'security', false ) ) {
56
- wp_send_json_error( __( 'Invalid nonce.', 'boldgrid-backup' ) );
57
  }
58
  }
59
 
@@ -63,7 +68,9 @@ class Boldgrid_Backup_Admin_Archive_Browser {
63
  * When a user clicks to "View details" of a database dump, this
64
  * method will create a table showing all the tables in that backup.
65
  *
66
- * @since 1.5.4
 
 
67
  *
68
  * @param string $filepath Zip file.
69
  * @param string $file Sql file name.
@@ -71,12 +78,11 @@ class Boldgrid_Backup_Admin_Archive_Browser {
71
  */
72
  public function get_sql_details( $filepath, $file ) {
73
  $tables_with_records = $this->core->db_dump->get_insert_count( $filepath, $file );
74
- $prefixed_tables = $this->core->db_get->prefixed_count();
75
-
76
- $in_backup = __( '# Records in this backup', 'boldgrid-backup' );
77
- $in_current = __( '# Records in current database', 'boldgrid-backup' );
78
-
79
- $return = sprintf( '
80
  <table class="wp-list-table fixed striped widefat">
81
  <thead>
82
  <tr>
@@ -93,21 +99,92 @@ class Boldgrid_Backup_Admin_Archive_Browser {
93
  /* 2 */ $in_current
94
  );
95
 
96
- foreach ( $prefixed_tables as $table => $record_count ) {
97
- $return .= sprintf(
98
- '<tr>
99
- <td>%1$s</td>
100
- <td>%2$s</td>
101
- <td>%3$s</td>
102
- </tr>',
103
- esc_html( $table ),
104
- isset( $tables_with_records[ $table ] ) ? $tables_with_records[ $table ] : '0',
105
- esc_html( $record_count )
106
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
  }
108
 
109
  $return .= '</tbody></table>';
110
 
 
 
 
 
 
 
 
 
 
 
 
111
  return $return;
112
  }
113
 
@@ -133,13 +210,12 @@ class Boldgrid_Backup_Admin_Archive_Browser {
133
 
134
  $dump_file = $this->core->get_dump_file( $filepath );
135
 
136
- // An array of files not to show in the archive browser.
 
 
 
 
137
  $no_show = array(
138
- /*
139
- * If this is our database dump file, skip over it. We have another
140
- * section of the archive details page that will help with restoring
141
- * a dump file.
142
- */
143
  basename( $dump_file ),
144
  basename( $this->core->archive->log_filepath ),
145
  );
@@ -150,7 +226,7 @@ class Boldgrid_Backup_Admin_Archive_Browser {
150
 
151
  $contents = $zip->browse( $filepath, $dir );
152
 
153
- $tr = '';
154
  $empty_directory = '<tr><td colspan="3">' . __( 'Empty directory', 'boldgrid-backup' ) . '</td></tr>';
155
 
156
  $table = sprintf(
@@ -200,13 +276,17 @@ class Boldgrid_Backup_Admin_Archive_Browser {
200
 
201
  $filename = ! empty( $_POST['filename'] ) ? sanitize_file_name( $_POST['filename'] ) : false;
202
  $filepath = $this->core->backup_dir->get_path_to( $filename );
203
- $file = ! empty( $_POST['file'] ) ? trim( strip_tags( $_POST['file'] ) ) : false;
204
  if ( empty( $filepath ) || empty( $file ) ) {
205
  wp_send_json_error( __( 'Invalid file / filepath.', 'boldgrid-backup' ) );
206
  }
207
 
208
  // Here's the default message.
209
- $upgrade_message = __( 'With BoldGrid Backup Premium, you can view and restore files from here.', 'boldgrid-backup' );
 
 
 
 
210
 
211
  /**
212
  * Allow other plugins to add functionality.
@@ -227,28 +307,30 @@ class Boldgrid_Backup_Admin_Archive_Browser {
227
  * This handles an ajax call for restoring a dump from the archive details
228
  * page.
229
  *
230
- * @since 1.5.4
231
  */
232
  public function wp_ajax_restore_db() {
233
  $this->authorize();
234
 
235
  $filename = ! empty( $_POST['filename'] ) ? sanitize_file_name( $_POST['filename'] ) : false;
236
  $filepath = $this->core->backup_dir->get_path_to( $filename );
237
- $file = ! empty( $_POST['file'] ) ? trim( strip_tags( $_POST['file'] ) ) : false;
238
  if ( empty( $filepath ) || empty( $file ) ) {
239
  wp_send_json_error( __( 'Invalid file / filepath.', 'boldgrid-backup' ) );
240
  }
241
 
242
  $importer = new Boldgrid_Backup_Admin_Db_Import( $this->core );
243
- $success = $importer->import_from_archive( $filepath, $file );
244
 
245
  if ( ! $success ) {
246
  $this->core->notice->add_user_notice(
 
247
  sprintf( __( 'Error, unable to import database %1$s from %2$s.', 'boldgrid-backup' ), $file, $filepath ),
248
  $this->core->notice->lang['dis_error']
249
  );
250
  } else {
251
  $this->core->notice->add_user_notice(
 
252
  sprintf( __( 'Success! Database %1$s imported from %2$s.', 'boldgrid-backup' ), $file, $filepath ),
253
  $this->core->notice->lang['dis_success']
254
  );
@@ -261,14 +343,14 @@ class Boldgrid_Backup_Admin_Archive_Browser {
261
  * This method handles the ajax call of "View details" for a database on the
262
  * archive details page.
263
  *
264
- * @since 1.5.4
265
  */
266
  public function wp_ajax_view_db() {
267
  $this->authorize();
268
 
269
  $filename = ! empty( $_POST['filename'] ) ? sanitize_file_name( $_POST['filename'] ) : false;
270
  $filepath = $this->core->backup_dir->get_path_to( $filename );
271
- $file = ! empty( $_POST['file'] ) ? trim( strip_tags( $_POST['file'] ) ) : false;
272
  if ( empty( $filename ) || empty( $filepath ) || empty( $file ) ) {
273
  wp_send_json_error( __( 'Invalid file / filepath.', 'boldgrid-backup' ) );
274
  }
1
  <?php
2
  /**
3
+ * File: class-boldgrid-backup-admin-archive-browser.php
4
  *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.5.2
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
  * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
+ */
14
+
15
+ /*
16
+ * AJAX callback functions in this class have their nonce verified by authorize() in this class.
17
+ *
18
+ * phpcs:disable WordPress.VIP, WordPress.CSRF.NonceVerification.NoNonceVerification, WordPress.Security.NonceVerification.NoNonceVerification
19
  */
20
 
21
  /**
22
+ * Class: Boldgrid_Backup_Admin_Archive_Browser
23
  *
24
  * @since 1.5.2
25
  */
26
  class Boldgrid_Backup_Admin_Archive_Browser {
 
27
  /**
28
  * The core class object.
29
  *
50
  * Many of the ajax handlers in this method require the same
51
  * current_user_can() and check_ajax_referer() checks.
52
  *
53
+ * @since 1.6.0
54
  */
55
  public function authorize() {
56
  if ( ! current_user_can( 'update_plugins' ) ) {
58
  }
59
 
60
  if ( ! check_ajax_referer( 'boldgrid_backup_remote_storage_upload', 'security', false ) ) {
61
+ wp_send_json_error( __( 'Invalid nonce; security check failed.', 'boldgrid-backup' ) );
62
  }
63
  }
64
 
68
  * When a user clicks to "View details" of a database dump, this
69
  * method will create a table showing all the tables in that backup.
70
  *
71
+ * @since 1.6.0
72
+ *
73
+ * @see Boldgrid_Backup_Admin_Archive_Log::get_by_zip()
74
  *
75
  * @param string $filepath Zip file.
76
  * @param string $file Sql file name.
78
  */
79
  public function get_sql_details( $filepath, $file ) {
80
  $tables_with_records = $this->core->db_dump->get_insert_count( $filepath, $file );
81
+ $is_encrypted_other = isset( $tables_with_records['encrypted_other'] );
82
+ $in_backup = __( '# Records in this backup', 'boldgrid-backup' );
83
+ $in_current = __( '# Records in current database', 'boldgrid-backup' );
84
+ $return = sprintf(
85
+ '
 
86
  <table class="wp-list-table fixed striped widefat">
87
  <thead>
88
  <tr>
99
  /* 2 */ $in_current
100
  );
101
 
102
+ // If the database dump file is encrypted and the premium plugin or license is missing, then show a notice.
103
+ $archive_info = ( new Boldgrid_Backup_Admin_Archive_Log( $this->core ) )->get_by_zip( $filepath );
104
+ $is_premium = $this->core->config->get_is_premium();
105
+ $is_premium_active = $this->core->config->is_premium_active;
106
+
107
+ if ( ! empty( $archive_info['encrypt_db'] ) && ( ! $is_premium || ! $is_premium_active ) ) {
108
+ $return .= '<tr><td colspan="3">
109
+ <p>' .
110
+ sprintf(
111
+ // translators: 1: Premium plugin title.
112
+ __( 'The database dump file in this archive has been encrypted with %1$s.', 'boldgrid-backup' ) . '</p>',
113
+ BOLDGRID_BACKUP_TITLE . ' Premium'
114
+ );
115
+
116
+ if ( ! $is_premium ) {
117
+ $return .= '<p>' .
118
+ sprintf(
119
+ // translators: 1: HTML anchor link open tag, 2: HTML anchor closing tag, 3: Premium plugin title.
120
+ __( 'A %3$s license is required for decryption. %1$sGet Premium%2$s', 'boldgrid-backup' ),
121
+ '<a class="button button-success" href="' .
122
+ esc_url( 'https://www.boldgrid.com/update-backup?source=bgbkup-archive-browser' ) .
123
+ '" target="_blank">',
124
+ '</a>',
125
+ BOLDGRID_BACKUP_TITLE . ' Premium'
126
+ ) .
127
+ '</p>';
128
+ }
129
+
130
+ if ( ! $is_premium_active ) {
131
+ $return .= '<p>' .
132
+ sprintf(
133
+ // translators: 1: HTML anchor link open tag, 2: HTML anchor closing tag, 3: Premium plugin title.
134
+ __( '%3$s is not active. Please go to the %1$sPlugins%2$s page to activate it.', 'boldgrid-backup' ),
135
+ '<a href="' .
136
+ esc_url( admin_url( 'plugins.php?s=Boldgrid%20Backup%20Premium&plugin_status=inactive' ) ) .
137
+ '">',
138
+ '</a>',
139
+ BOLDGRID_BACKUP_TITLE . ' Premium'
140
+ ) .
141
+ '</p>';
142
+ }
143
+
144
+ $return .= '</td></tr>';
145
+ } elseif ( $is_encrypted_other ) {
146
+ // The database dump file was encrypted with other settings.
147
+ $return .= '<tr><td colspan="3">' .
148
+ sprintf(
149
+ // translators: 1: HTML anchor link open tag, 2: HTML anchor closing tag.
150
+ __( 'The database in this backup archive was encrypted with a token that does not match the one saved in your settings. In order to access the encrypted database, the matching encryption token is required. If you have the matching token, then go to the %1$sBackup Security%2$s settings page to save it.', 'boldgrid-backup' ),
151
+ '<a href="' .
152
+ esc_url( admin_url( 'admin.php?page=boldgrid-backup-settings&section=section_security' ) ) .
153
+ '">',
154
+ '</a>'
155
+ ) .
156
+ '</td></tr>';
157
+ } else {
158
+ // Show database table record counts.
159
+ $prefixed_tables = $this->core->db_get->prefixed_count();
160
+
161
+ foreach ( $prefixed_tables as $table => $record_count ) {
162
+ $return .= sprintf(
163
+ '<tr>
164
+ <td>%1$s</td>
165
+ <td>%2$s</td>
166
+ <td>%3$s</td>
167
+ </tr>',
168
+ esc_html( $table ),
169
+ isset( $tables_with_records[ $table ] ) ? $tables_with_records[ $table ] : '0',
170
+ esc_html( $record_count )
171
+ );
172
+ }
173
  }
174
 
175
  $return .= '</tbody></table>';
176
 
177
+ if ( ! $this->core->config->is_premium_done ) {
178
+ $get_plugins_url = $this->core->go_pro->get_premium_url( 'bgbkup-db-browser-encrypt' );
179
+ $return .= '<tr><td colspan="2"><div class="bg-box-bottom premium wp-clearfix">' .
180
+ $this->core->go_pro->get_premium_button( $get_plugins_url, __( 'Unlock Feature', 'boldgrid-backup' ) ) .
181
+ sprintf(
182
+ // translators: 1: Premium plugin title.
183
+ esc_html__( 'Secure your sesitive data with the %1$s plugin.', 'boldgrid-backup' ),
184
+ BOLDGRID_BACKUP_TITLE . ' Premium'
185
+ ) . '</div></div></td></tr>';
186
+ }
187
+
188
  return $return;
189
  }
190
 
210
 
211
  $dump_file = $this->core->get_dump_file( $filepath );
212
 
213
+ /*
214
+ * An array of files not to show in the archive browser.
215
+ * If this is our database dump file, skip over it. We have another section of the archive
216
+ * details page that will help with restoring a dump file.
217
+ */
218
  $no_show = array(
 
 
 
 
 
219
  basename( $dump_file ),
220
  basename( $this->core->archive->log_filepath ),
221
  );
226
 
227
  $contents = $zip->browse( $filepath, $dir );
228
 
229
+ $tr = '';
230
  $empty_directory = '<tr><td colspan="3">' . __( 'Empty directory', 'boldgrid-backup' ) . '</td></tr>';
231
 
232
  $table = sprintf(
276
 
277
  $filename = ! empty( $_POST['filename'] ) ? sanitize_file_name( $_POST['filename'] ) : false;
278
  $filepath = $this->core->backup_dir->get_path_to( $filename );
279
+ $file = ! empty( $_POST['file'] ) ? trim( strip_tags( $_POST['file'] ) ) : false;
280
  if ( empty( $filepath ) || empty( $file ) ) {
281
  wp_send_json_error( __( 'Invalid file / filepath.', 'boldgrid-backup' ) );
282
  }
283
 
284
  // Here's the default message.
285
+ $upgrade_message = sprintf(
286
+ // translators: 1: Plugin title.
287
+ __( 'With %1$s, you can view and restore files from here.', 'boldgrid-backup' ),
288
+ BOLDGRID_BACKUP_TITLE . ' Premium'
289
+ );
290
 
291
  /**
292
  * Allow other plugins to add functionality.
307
  * This handles an ajax call for restoring a dump from the archive details
308
  * page.
309
  *
310
+ * @since 1.6.0
311
  */
312
  public function wp_ajax_restore_db() {
313
  $this->authorize();
314
 
315
  $filename = ! empty( $_POST['filename'] ) ? sanitize_file_name( $_POST['filename'] ) : false;
316
  $filepath = $this->core->backup_dir->get_path_to( $filename );
317
+ $file = ! empty( $_POST['file'] ) ? trim( strip_tags( $_POST['file'] ) ) : false;
318
  if ( empty( $filepath ) || empty( $file ) ) {
319
  wp_send_json_error( __( 'Invalid file / filepath.', 'boldgrid-backup' ) );
320
  }
321
 
322
  $importer = new Boldgrid_Backup_Admin_Db_Import( $this->core );
323
+ $success = $importer->import_from_archive( $filepath, $file );
324
 
325
  if ( ! $success ) {
326
  $this->core->notice->add_user_notice(
327
+ // translators: 1: Filename 2: File path.
328
  sprintf( __( 'Error, unable to import database %1$s from %2$s.', 'boldgrid-backup' ), $file, $filepath ),
329
  $this->core->notice->lang['dis_error']
330
  );
331
  } else {
332
  $this->core->notice->add_user_notice(
333
+ // translators: 1: Filename 2: File path.
334
  sprintf( __( 'Success! Database %1$s imported from %2$s.', 'boldgrid-backup' ), $file, $filepath ),
335
  $this->core->notice->lang['dis_success']
336
  );
343
  * This method handles the ajax call of "View details" for a database on the
344
  * archive details page.
345
  *
346
+ * @since 1.6.0
347
  */
348
  public function wp_ajax_view_db() {
349
  $this->authorize();
350
 
351
  $filename = ! empty( $_POST['filename'] ) ? sanitize_file_name( $_POST['filename'] ) : false;
352
  $filepath = $this->core->backup_dir->get_path_to( $filename );
353
+ $file = ! empty( $_POST['file'] ) ? trim( strip_tags( $_POST['file'] ) ) : false;
354
  if ( empty( $filename ) || empty( $filepath ) || empty( $file ) ) {
355
  wp_send_json_error( __( 'Invalid file / filepath.', 'boldgrid-backup' ) );
356
  }
admin/class-boldgrid-backup-admin-archive-details.php CHANGED
@@ -1,24 +1,25 @@
1
  <?php
2
  /**
3
- * Archive Details class.
4
  *
5
- * @link http://www.boldgrid.com
6
- * @since 1.5.1
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
- * @copyright BoldGrid.com
11
  * @version $Id$
12
- * @author BoldGrid.com <wpb@boldgrid.com>
13
  */
14
 
 
 
15
  /**
16
- * BoldGrid Backup Admin Archive Details Class.
17
  *
18
  * @since 1.5.1
19
  */
20
  class Boldgrid_Backup_Admin_Archive_Details {
21
-
22
  /**
23
  * The core class object.
24
  *
@@ -31,7 +32,7 @@ class Boldgrid_Backup_Admin_Archive_Details {
31
  /**
32
  * An array of remote storage locations.
33
  *
34
- * @since 1.5.4
35
  * @access public
36
  * @var array
37
  */
@@ -53,7 +54,7 @@ class Boldgrid_Backup_Admin_Archive_Details {
53
  *
54
  * @since 1.6.0
55
  *
56
- * @param string $filename
57
  * @return string
58
  */
59
  public function get_url( $filename ) {
@@ -63,7 +64,7 @@ class Boldgrid_Backup_Admin_Archive_Details {
63
  /**
64
  * Enqueue scripts.
65
  *
66
- * @since 1.5.4
67
  */
68
  public function enqueue_scripts() {
69
  wp_enqueue_style(
@@ -81,8 +82,8 @@ class Boldgrid_Backup_Admin_Archive_Details {
81
  BOLDGRID_BACKUP_VERSION
82
  );
83
  $translations = array(
84
- 'uploading' => __( 'Uploading', 'boldgrid-backup' ),
85
- 'uploaded' => __( 'Uploaded', 'boldgrid-backup' ),
86
  'failUpload' => __( 'Unable to upload backup file.', 'boldgrid-backup' ),
87
  );
88
  wp_localize_script( 'boldgrid-backup-admin-archive-details', 'boldgrid_backup_archive_details', $translations );
@@ -95,13 +96,13 @@ class Boldgrid_Backup_Admin_Archive_Details {
95
  BOLDGRID_BACKUP_VERSION
96
  );
97
  $unknown_error = __( 'An unknown error has occurred.', 'boldgrid-backup' );
98
- $translations = array(
99
- 'loading' => __( 'Loading', 'boldgrid-backup' ),
100
- 'home' => __( 'Home', 'boldgrid-backup' ),
101
- 'restoring' => __( 'Restoring', 'boldgrid-backup' ),
102
- 'confirmDbRestore' => __( 'Are you sure you want to restore this database backup?', 'boldgrid-backup' ),
103
  'unknownBrowseError' => __( 'An unknown error has occurred when trying to get a listing of the files in this archive.', 'boldgrid-backup' ),
104
- 'unknownError' => $unknown_error,
105
  'unknownErrorNotice' => sprintf( '<div class="%1$s"><p>%2$s</p></div>', $this->core->notice->lang['dis_error'], $unknown_error ),
106
  );
107
  wp_localize_script( 'boldgrid-backup-admin-zip-browser', 'boldgrid_backup_zip_browser', $translations );
@@ -109,6 +110,9 @@ class Boldgrid_Backup_Admin_Archive_Details {
109
 
110
  wp_enqueue_style( 'bglib-ui-css' );
111
 
 
 
 
112
  /**
113
  * Allow other plugins to enqueue scripts on this page.
114
  *
@@ -123,7 +127,7 @@ class Boldgrid_Backup_Admin_Archive_Details {
123
  * @since 1.5.1
124
  */
125
  public function render_archive() {
126
- if ( ! empty( $_POST['delete_now'] ) ) {
127
  $this->core->delete_archive_file();
128
  }
129
 
@@ -132,28 +136,30 @@ class Boldgrid_Backup_Admin_Archive_Details {
132
 
133
  $archive_found = false;
134
 
135
- $filename = ! empty( $_GET['filename'] ) ? sanitize_file_name( $_GET['filename'] ) : false;
136
  if ( ! $filename ) {
137
- echo __( 'No archive specified.', 'boldgrid-backup' );
138
  return;
139
  }
140
 
141
  // Get our archive.
142
  $archive = $this->core->archive->get_by_name( $filename );
143
  if ( $archive ) {
144
- $log = $this->core->archive_log->get_by_zip( $archive['filepath'] );
145
- $archive = array_merge( $log, $archive );
146
  $archive_found = true;
147
- $dump_file = $this->core->get_dump_file( $archive['filepath'] );
148
  } else {
149
  $archive = array(
150
  'filename' => $filename,
151
- 'filepath' => $this->core->backup_dir->get_path_to( $archive['filename'] ),
152
  );
153
  }
154
 
155
  // Initialize the archive. We will need it in our included template below.
156
  $this->core->archive->init( $archive['filepath'] );
 
 
157
 
158
  include BOLDGRID_BACKUP_PATH . '/admin/partials/boldgrid-backup-admin-archive-details.php';
159
  }
@@ -168,9 +174,43 @@ class Boldgrid_Backup_Admin_Archive_Details {
168
  * The nonce can be added to an ajax request's data via:
169
  * 'security' : $( '#_wpnonce' ).val()
170
  *
171
- * @since 1.5.4
172
  */
173
  public function validate_nonce() {
174
  return check_ajax_referer( 'boldgrid_backup_remote_storage_upload', 'security', false );
175
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
176
  }
1
  <?php
2
  /**
3
+ * File: class-boldgrid-backup-admin-archive-details.php
4
  *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.5.1
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
  * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
  */
14
 
15
+ // phpcs:disable WordPress.VIP
16
+
17
  /**
18
+ * Class: Boldgrid_Backup_Admin_Archive_Details
19
  *
20
  * @since 1.5.1
21
  */
22
  class Boldgrid_Backup_Admin_Archive_Details {
 
23
  /**
24
  * The core class object.
25
  *
32
  /**
33
  * An array of remote storage locations.
34
  *
35
+ * @since 1.6.0
36
  * @access public
37
  * @var array
38
  */
54
  *
55
  * @since 1.6.0
56
  *
57
+ * @param string $filename Filename.
58
  * @return string
59
  */
60
  public function get_url( $filename ) {
64
  /**
65
  * Enqueue scripts.
66
  *
67
+ * @since 1.6.0
68
  */
69
  public function enqueue_scripts() {
70
  wp_enqueue_style(
82
  BOLDGRID_BACKUP_VERSION
83
  );
84
  $translations = array(
85
+ 'uploading' => __( 'Uploading', 'boldgrid-backup' ),
86
+ 'uploaded' => __( 'Uploaded', 'boldgrid-backup' ),
87
  'failUpload' => __( 'Unable to upload backup file.', 'boldgrid-backup' ),
88
  );
89
  wp_localize_script( 'boldgrid-backup-admin-archive-details', 'boldgrid_backup_archive_details', $translations );
96
  BOLDGRID_BACKUP_VERSION
97
  );
98
  $unknown_error = __( 'An unknown error has occurred.', 'boldgrid-backup' );
99
+ $translations = array(
100
+ 'loading' => __( 'Loading', 'boldgrid-backup' ),
101
+ 'home' => __( 'Home', 'boldgrid-backup' ),
102
+ 'restoring' => __( 'Restoring', 'boldgrid-backup' ),
103
+ 'confirmDbRestore' => __( 'Are you sure you want to restore this database backup?', 'boldgrid-backup' ),
104
  'unknownBrowseError' => __( 'An unknown error has occurred when trying to get a listing of the files in this archive.', 'boldgrid-backup' ),
105
+ 'unknownError' => $unknown_error,
106
  'unknownErrorNotice' => sprintf( '<div class="%1$s"><p>%2$s</p></div>', $this->core->notice->lang['dis_error'], $unknown_error ),
107
  );
108
  wp_localize_script( 'boldgrid-backup-admin-zip-browser', 'boldgrid_backup_zip_browser', $translations );
110
 
111
  wp_enqueue_style( 'bglib-ui-css' );
112
 
113
+ wp_enqueue_script( 'bglib-attributes-js' );
114
+ wp_enqueue_style( 'bglib-attributes-css' );
115
+
116
  /**
117
  * Allow other plugins to enqueue scripts on this page.
118
  *
127
  * @since 1.5.1
128
  */
129
  public function render_archive() {
130
+ if ( ! empty( $_POST['delete_now'] ) ) { // phpcs:ignore WordPress.CSRF.NonceVerification.NoNonceVerification
131
  $this->core->delete_archive_file();
132
  }
133
 
136
 
137
  $archive_found = false;
138
 
139
+ $filename = ! empty( $_GET['filename'] ) ? sanitize_file_name( $_GET['filename'] ) : false; // phpcs:ignore WordPress.CSRF.NonceVerification.NoNonceVerification
140
  if ( ! $filename ) {
141
+ esc_html_e( 'No archive specified.', 'boldgrid-backup' );
142
  return;
143
  }
144
 
145
  // Get our archive.
146
  $archive = $this->core->archive->get_by_name( $filename );
147
  if ( $archive ) {
148
+ $log = $this->core->archive_log->get_by_zip( $archive['filepath'] );
149
+ $archive = array_merge( $log, $archive );
150
  $archive_found = true;
151
+ $dump_file = $this->core->get_dump_file( $archive['filepath'] );
152
  } else {
153
  $archive = array(
154
  'filename' => $filename,
155
+ 'filepath' => $this->core->backup_dir->get_path_to( $filename ),
156
  );
157
  }
158
 
159
  // Initialize the archive. We will need it in our included template below.
160
  $this->core->archive->init( $archive['filepath'] );
161
+ $title = $this->core->archive->get_attribute( 'title' );
162
+ $description = $this->core->archive->get_attribute( 'description' );
163
 
164
  include BOLDGRID_BACKUP_PATH . '/admin/partials/boldgrid-backup-admin-archive-details.php';
165
  }
174
  * The nonce can be added to an ajax request's data via:
175
  * 'security' : $( '#_wpnonce' ).val()
176
  *
177
+ * @since 1.6.0
178
  */
179
  public function validate_nonce() {
180
  return check_ajax_referer( 'boldgrid_backup_remote_storage_upload', 'security', false );
181
  }
182
+
183
+ /**
184
+ * Handle the ajax request to "Update" from a backup archive page.
185
+ *
186
+ * @since 1.7.0
187
+ */
188
+ public function wp_ajax_update() {
189
+ if ( ! $this->validate_nonce() ) {
190
+ wp_send_json_error( __( 'Permission denied.', 'boldgrid-backup' ) );
191
+ }
192
+
193
+ $attributes = ! empty( $_POST['attributes'] ) && is_array( $_POST['attributes'] ) ? $_POST['attributes'] : []; // phpcs:ignore WordPress.CSRF.NonceVerification
194
+ $filename = ! empty( $_POST['filename'] ) ? sanitize_file_name( $_POST['filename'] ) : false; // phpcs:ignore WordPress.CSRF.NonceVerification
195
+ $filepath = $this->core->backup_dir->get_path_to( $filename );
196
+
197
+ if ( empty( $filename ) || ! $this->core->wp_filesystem->exists( $filepath ) ) {
198
+ wp_send_json_error( __( 'Invalid archive filepath.', 'boldgrid-backup' ) );
199
+ }
200
+
201
+ $this->core->archive->init( $filepath );
202
+
203
+ foreach ( $attributes as $key => $value ) {
204
+ $this->core->archive->set_attribute( $key, stripslashes( $value ) );
205
+ }
206
+
207
+ // Take action if we've updated either the backup's title or description.
208
+ $title_description_update = ! empty( $attributes['title'] ) || ! empty( $attributes['description'] );
209
+
210
+ if ( $title_description_update && isset( $this->core->activity ) ) {
211
+ $this->core->activity->add( 'update_title_description', 1, $this->core->rating_prompt_config );
212
+ }
213
+
214
+ wp_send_json_success();
215
+ }
216
  }
admin/class-boldgrid-backup-admin-archive-fail.php CHANGED
@@ -1,19 +1,19 @@
1
  <?php
2
  /**
3
- * BoldGrid Backup Admin Archive Fail.
4
  *
5
- * @link http://www.boldgrid.com
6
- * @since 1.5.2
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
- * @copyright BoldGrid.com
11
  * @version $Id$
12
- * @author BoldGrid.com <wpb@boldgrid.com>
13
  */
14
 
15
  /**
16
- * BoldGrid Backup Admin Archive Fail Class.
17
  *
18
  * @since 1.5.1
19
  */
@@ -40,7 +40,7 @@ class Boldgrid_Backup_Admin_Archive_Fail {
40
  /**
41
  * Generic lang string stating unable to backup.
42
  *
43
- * @since 1.5.4
44
  * @access public
45
  * @var string
46
  */
@@ -85,7 +85,7 @@ class Boldgrid_Backup_Admin_Archive_Fail {
85
  * # NO .10 MB shutdown function fails early on when calling
86
  * error_get_last().
87
  */
88
- $mb = 1000000;
89
  $this->memory = str_repeat( '0', ( 0.35 * $mb ) );
90
  }
91
 
@@ -105,7 +105,7 @@ class Boldgrid_Backup_Admin_Archive_Fail {
105
  /**
106
  * Create a "backup failed" email and schedule it to be sent via jobs.
107
  *
108
- * @since 1.5.4
109
  *
110
  * @param string $message Error message.
111
  */
@@ -118,8 +118,8 @@ class Boldgrid_Backup_Admin_Archive_Fail {
118
  $email_body = $this->core->email->fill_generic_template( $message, false );
119
 
120
  $args = array(
121
- 'action' => 'boldgrid_backup_cron_fail_email',
122
- 'action_data' => array(
123
  'message' => $email_body,
124
  ),
125
  'action_title' => __( 'Send warning email because backup failed', 'boldgrid-backup' ),
@@ -134,7 +134,6 @@ class Boldgrid_Backup_Admin_Archive_Fail {
134
  * @since 1.5.2
135
  */
136
  public function shutdown() {
137
-
138
  // Free up memory so we have enough to complete this method.
139
  $this->memory = null;
140
 
1
  <?php
2
  /**
3
+ * File: class-boldgrid-backup-admin-archive-fail.php
4
  *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.5.2
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
  * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
  */
14
 
15
  /**
16
+ * Class: Boldgrid_Backup_Admin_Archive_Fail
17
  *
18
  * @since 1.5.1
19
  */
40
  /**
41
  * Generic lang string stating unable to backup.
42
  *
43
+ * @since 1.6.0
44
  * @access public
45
  * @var string
46
  */
85
  * # NO .10 MB shutdown function fails early on when calling
86
  * error_get_last().
87
  */
88
+ $mb = 1000000;
89
  $this->memory = str_repeat( '0', ( 0.35 * $mb ) );
90
  }
91
 
105
  /**
106
  * Create a "backup failed" email and schedule it to be sent via jobs.
107
  *
108
+ * @since 1.6.0
109
  *
110
  * @param string $message Error message.
111
  */
118
  $email_body = $this->core->email->fill_generic_template( $message, false );
119
 
120
  $args = array(
121
+ 'action' => 'boldgrid_backup_cron_fail_email',
122
+ 'action_data' => array(
123
  'message' => $email_body,
124
  ),
125
  'action_title' => __( 'Send warning email because backup failed', 'boldgrid-backup' ),
134
  * @since 1.5.2
135
  */
136
  public function shutdown() {
 
137
  // Free up memory so we have enough to complete this method.
138
  $this->memory = null;
139
 
admin/class-boldgrid-backup-admin-archive-log.php CHANGED
@@ -1,24 +1,23 @@
1
  <?php
2
  /**
3
- * Archive Log class.
4
  *
5
- * @link http://www.boldgrid.com
6
- * @since 1.5.1
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
- * @copyright BoldGrid.com
11
  * @version $Id$
12
- * @author BoldGrid.com <wpb@boldgrid.com>
13
  */
14
 
15
  /**
16
- * BoldGrid Backup Admin Archive Log Class.
17
  *
18
  * @since 1.5.1
19
  */
20
  class Boldgrid_Backup_Admin_Archive_Log {
21
-
22
  /**
23
  * The core class object.
24
  *
@@ -44,7 +43,7 @@ class Boldgrid_Backup_Admin_Archive_Log {
44
  *
45
  * @since 1.5.1
46
  *
47
- * @param string $zip_filepath
48
  * @return bool
49
  */
50
  public function delete_by_zip( $zip_filepath ) {
@@ -63,7 +62,7 @@ class Boldgrid_Backup_Admin_Archive_Log {
63
  *
64
  * @since 1.5.1
65
  *
66
- * @param string $zip_filepath
67
  * @return array
68
  */
69
  public function get_by_zip( $zip_filepath ) {
@@ -89,7 +88,7 @@ class Boldgrid_Backup_Admin_Archive_Log {
89
  *
90
  * @since 1.5.1
91
  *
92
- * @param string $zip_filepath
93
  * @return bool
94
  */
95
  public function path_from_zip( $zip_filepath ) {
@@ -103,11 +102,11 @@ class Boldgrid_Backup_Admin_Archive_Log {
103
  *
104
  * @since 1.6.0
105
  *
106
- * @param array $info
107
  */
108
  public function post_restore( $info ) {
109
  $path_backup_dir = $this->path_from_zip( $info['filepath'] );
110
- $path_abspath = ABSPATH . basename( $path_backup_dir );
111
 
112
  // If this backup did not restore a log file to ABSPATH, then we can abort.
113
  if ( ! $this->core->wp_filesystem->exists( $path_abspath ) ) {
@@ -128,20 +127,23 @@ class Boldgrid_Backup_Admin_Archive_Log {
128
  * extract backup.log from backup.zip if it exists. This was, we have all
129
  * of the meta data about the backup.
130
  *
131
- * @since 1.5.4
132
  *
133
- * @param string $filepath
 
134
  */
135
- public function restore_by_zip( $filepath ) {
136
  $log_filepath = $this->path_from_zip( $filepath );
137
- $log_filename = basename( $log_filepath );
138
 
139
  if ( $this->core->wp_filesystem->exists( $log_filepath ) ) {
140
  return true;
141
  }
142
 
 
 
 
143
  // Extract the log file to ABSPATH.
144
- $zip = new Boldgrid_Backup_Admin_Compressor_Pcl_Zip( $this->core );
145
  $status = $zip->extract_one( $filepath, $log_filename );
146
  if ( ! $status ) {
147
  return false;
@@ -149,8 +151,9 @@ class Boldgrid_Backup_Admin_Archive_Log {
149
 
150
  // Move the log file from the ABSPATH to the backup dir.
151
  $old_path = ABSPATH . $log_filename;
152
- $new_path = $this->core->backup_dir->get_path_to( $log_filename );
153
- return $this->core->wp_filesystem->move( $old_path, $new_path );
 
154
  }
155
 
156
  /**
@@ -158,7 +161,9 @@ class Boldgrid_Backup_Admin_Archive_Log {
158
  *
159
  * @since 1.5.1
160
  *
161
- * @param $info array
 
 
162
  * @return bool
163
  */
164
  public function write( $info ) {
@@ -173,16 +178,25 @@ class Boldgrid_Backup_Admin_Archive_Log {
173
  return false;
174
  }
175
 
176
- $written = $this->core->wp_filesystem->put_contents( $log_filepath, json_encode( $info ) );
177
  if ( ! $written ) {
178
  return false;
179
  }
180
 
181
  // Add the log file to the archive file, as of 1.5.4.
182
- $archive = new PclZip( $info['filepath'] );
 
 
 
 
 
183
  if ( 0 === $archive ) {
184
  return false;
185
  }
 
 
 
 
186
  /*
187
  * The log file is being added to the root of the archive. If the user
188
  * restores the archive, the log will be restored to the ABSPATH. The
@@ -194,6 +208,9 @@ class Boldgrid_Backup_Admin_Archive_Log {
194
  return false;
195
  }
196
 
 
 
 
197
  return true;
198
  }
199
  }
1
  <?php
2
  /**
3
+ * File: class-boldgrid-backup-admin-archive-log.php
4
  *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.5.1
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
  * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
  */
14
 
15
  /**
16
+ * Class: Boldgrid_Backup_Admin_Archive_Log
17
  *
18
  * @since 1.5.1
19
  */
20
  class Boldgrid_Backup_Admin_Archive_Log {
 
21
  /**
22
  * The core class object.
23
  *
43
  *
44
  * @since 1.5.1
45
  *
46
+ * @param string $zip_filepath Archive file path.
47
  * @return bool
48
  */
49
  public function delete_by_zip( $zip_filepath ) {
62
  *
63
  * @since 1.5.1
64
  *
65
+ * @param string $zip_filepath Archive file path.
66
  * @return array
67
  */
68
  public function get_by_zip( $zip_filepath ) {
88
  *
89
  * @since 1.5.1
90
  *
91
+ * @param string $zip_filepath Archive file path.
92
  * @return bool
93
  */
94
  public function path_from_zip( $zip_filepath ) {
102
  *
103
  * @since 1.6.0
104
  *
105
+ * @param array $info Archive information.
106
  */
107
  public function post_restore( $info ) {
108
  $path_backup_dir = $this->path_from_zip( $info['filepath'] );
109
+ $path_abspath = ABSPATH . basename( $path_backup_dir );
110
 
111
  // If this backup did not restore a log file to ABSPATH, then we can abort.
112
  if ( ! $this->core->wp_filesystem->exists( $path_abspath ) ) {
127
  * extract backup.log from backup.zip if it exists. This was, we have all
128
  * of the meta data about the backup.
129
  *
130
+ * @since 1.6.0
131
  *
132
+ * @param string $filepath Archive file path.
133
+ * @param string $alt_log_filename Optional log file path. Default is to get from filepath.
134
  */
135
+ public function restore_by_zip( $filepath, $alt_log_filename = null ) {
136
  $log_filepath = $this->path_from_zip( $filepath );
 
137
 
138
  if ( $this->core->wp_filesystem->exists( $log_filepath ) ) {
139
  return true;
140
  }
141
 
142
+ $log_filename = ! empty( $alt_log_filename ) ?
143
+ $alt_log_filename : basename( $log_filepath );
144
+
145
  // Extract the log file to ABSPATH.
146
+ $zip = new Boldgrid_Backup_Admin_Compressor_Pcl_Zip( $this->core );
147
  $status = $zip->extract_one( $filepath, $log_filename );
148
  if ( ! $status ) {
149
  return false;
151
 
152
  // Move the log file from the ABSPATH to the backup dir.
153
  $old_path = ABSPATH . $log_filename;
154
+ $new_path = $this->core->backup_dir->get_path_to( basename( $log_filepath ) );
155
+
156
+ return $this->core->wp_filesystem->move( $old_path, $new_path, true );
157
  }
158
 
159
  /**
161
  *
162
  * @since 1.5.1
163
  *
164
+ * @see Boldgrid_Backup_Admin_Archive::delete_from_archive()
165
+ *
166
+ * @param array $info Archive information.
167
  * @return bool
168
  */
169
  public function write( $info ) {
178
  return false;
179
  }
180
 
181
+ $written = $this->core->wp_filesystem->put_contents( $log_filepath, wp_json_encode( $info ) );
182
  if ( ! $written ) {
183
  return false;
184
  }
185
 
186
  // Add the log file to the archive file, as of 1.5.4.
187
+ if ( ! class_exists( 'PclZip' ) ) {
188
+ require_once ABSPATH . 'wp-admin/includes/class-pclzip.php';
189
+ }
190
+
191
+ // Open the archive.
192
+ $archive = new \PclZip( $info['filepath'] );
193
  if ( 0 === $archive ) {
194
  return false;
195
  }
196
+
197
+ // Delete the old log file(s).
198
+ $this->core->archive->delete_from_archive( $archive, basename( $log_filepath ) );
199
+
200
  /*
201
  * The log file is being added to the root of the archive. If the user
202
  * restores the archive, the log will be restored to the ABSPATH. The
208
  return false;
209
  }
210
 
211
+ // Ensure the act updating the log file does not change the backup file's timestamp.
212
+ $this->core->wp_filesystem->touch( $info['filepath'], $info['lastmodunix'] );
213
+
214
  return true;
215
  }
216
  }
admin/class-boldgrid-backup-admin-archive.php CHANGED
@@ -1,24 +1,23 @@
1
  <?php
2
  /**
3
- * Archive class.
4
  *
5
- * @link http://www.boldgrid.com
6
- * @since 1.5.3
7
  *
8
  * @package Boldgrid_Backup
9
- * @subpackage Boldgrid_Backup/admin
10
- * @copyright BoldGrid.com
11
  * @version $Id$
12
- * @author BoldGrid.com <wpb@boldgrid.com>
13
  */
14
 
15
  /**
16
- * BoldGrid Backup Admin Archive Browser Class.
17
  *
18
  * @since 1.5.3
19
  */
20
  class Boldgrid_Backup_Admin_Archive {
21
-
22
  /**
23
  * The core class object.
24
  *
@@ -84,6 +83,18 @@ class Boldgrid_Backup_Admin_Archive {
84
  */
85
  public $log_filepath = null;
86
 
 
 
 
 
 
 
 
 
 
 
 
 
87
  /**
88
  * URL to the details page of this backup.
89
  *
@@ -122,14 +133,26 @@ class Boldgrid_Backup_Admin_Archive {
122
  return $deleted;
123
  }
124
 
 
 
 
 
 
 
 
 
 
 
 
 
125
  /**
126
  * Get an archive by name.
127
  *
128
  * Please see @return for more information on what an archive actually is.
129
  *
130
- * @since 1.5.4
131
  *
132
- * @param string $filename
133
  * @return array {
134
  * Details about an archive.
135
  *
@@ -183,15 +206,42 @@ class Boldgrid_Backup_Admin_Archive {
183
  return $file_contents;
184
  }
185
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
186
  /**
187
  * Init.
188
  *
189
  * @since 1.6.0
190
  *
191
- * @param string $filepath
192
  */
193
  public function init( $filepath ) {
194
-
195
  $filepath = strip_tags( $filepath );
196
 
197
  if ( ! empty( $this->filepath ) && $filepath === $this->filepath ) {
@@ -200,8 +250,6 @@ class Boldgrid_Backup_Admin_Archive {
200
 
201
  $this->reset();
202
 
203
- $zip = new Boldgrid_Backup_Admin_Compressor_Pcl_Zip( $this->core );
204
-
205
  $this->filepath = $filepath;
206
  $this->filename = basename( $this->filepath );
207
 
@@ -214,9 +262,10 @@ class Boldgrid_Backup_Admin_Archive {
214
  $have_log = $this->core->archive_log->restore_by_zip( $this->filepath );
215
  }
216
 
217
- // Init our log.
218
  if ( $have_log ) {
219
  $this->log = $this->core->archive_log->get_by_zip( $this->filepath );
 
 
220
  }
221
 
222
  /*
@@ -228,8 +277,66 @@ class Boldgrid_Backup_Admin_Archive {
228
  $this->compressor = ! empty( $this->log['compressor'] ) ? $this->log['compressor'] : 'php_zip';
229
 
230
  $this->view_details_url = admin_url( 'admin.php?page=boldgrid-backup-archive-details&filename=' . $this->filename );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
231
 
232
- unset( $zip );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
233
  }
234
 
235
  /**
@@ -237,7 +344,7 @@ class Boldgrid_Backup_Admin_Archive {
237
  *
238
  * @since 1.5.3
239
  *
240
- * @param string $filepath
241
  * @return bool
242
  */
243
  public function is_archive( $filepath ) {
@@ -264,7 +371,7 @@ class Boldgrid_Backup_Admin_Archive {
264
  *
265
  * @since 1.6.0
266
  *
267
- * @param string $filename
268
  * @return bool
269
  */
270
  public function is_site_archive( $filename ) {
@@ -330,12 +437,49 @@ class Boldgrid_Backup_Admin_Archive {
330
  * @since 1.6.0
331
  */
332
  public function reset() {
333
- $this->filename = null;
334
- $this->filepath = null;
335
  $this->log_filepath = null;
336
  $this->log_filename = null;
337
- $this->log = array();
338
- $this->compressor = null;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
339
  }
340
 
341
  /**
@@ -348,7 +492,6 @@ class Boldgrid_Backup_Admin_Archive {
348
  * timestamp from the log and configure the last modified appropriately.
349
  */
350
  public function update_timestamp() {
351
-
352
  // If we don't have what we need, abort.
353
  if ( empty( $this->filepath ) || empty( $this->log['lastmodunix'] ) ) {
354
  return false;
@@ -356,4 +499,206 @@ class Boldgrid_Backup_Admin_Archive {
356
 
357
  return $this->core->wp_filesystem->touch( $this->filepath, $this->log['lastmodunix'] );
358
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
359
  }
1
  <?php
2
  /**
3
+ * File: class-boldgrid-backup-admin-archive.php
4
  *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.5.3
7
  *
8
  * @package Boldgrid_Backup
9
+ * @subpackage Boldgrid_Backup/cron
10
+ * @copyright BoldGrid
11
  * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
  */
14
 
15
  /**
16
+ * Class: Boldgrid_Backup_Admin_Archive
17
  *
18
  * @since 1.5.3
19
  */
20
  class Boldgrid_Backup_Admin_Archive {
 
21
  /**
22
  * The core class object.
23
  *
83
  */
84
  public $log_filepath = null;
85
 
86
+ /**
87
+ * The unix timestamp of the backup file.
88
+ *
89
+ * The timestamp of when the backup was created. This value is set in the self::init() method by
90
+ * reading the 'lastmodunix' value from the logs. The 'lastmodunix' value was saved to the archive's
91
+ * log when the archive was made in Boldgrid_Backup_Admin_Core::archive_files().
92
+ *
93
+ * @since 1.7.3
94
+ * @var string
95
+ */
96
+ public $timestamp = 0;
97
+
98
  /**
99
  * URL to the details page of this backup.
100
  *
133
  return $deleted;
134
  }
135
 
136
+ /**
137
+ * Get an attribute from the log.
138
+ *
139
+ * @since 1.7.0
140
+ *
141
+ * @param string $key Attributes are key / value pairs.
142
+ * @return mixed
143
+ */
144
+ public function get_attribute( $key ) {
145
+ return ! empty( $this->log[ $key ] ) ? $this->log[ $key ] : null;
146
+ }
147
+
148
  /**
149
  * Get an archive by name.
150
  *
151
  * Please see @return for more information on what an archive actually is.
152
  *
153
+ * @since 1.6.0
154
  *
155
+ * @param string $filename Filename.
156
  * @return array {
157
  * Details about an archive.
158
  *
206
  return $file_contents;
207
  }
208
 
209
+ /**
210
+ * Get the database dump file from an archive.
211
+ *
212
+ * @since 1.12.0
213
+ *
214
+ * @param string $file The file to get.
215
+ * @return array
216
+ */
217
+ public function get_dump_file( $file ) {
218
+ /**
219
+ * Handle encryption.
220
+ *
221
+ * @since 1.12.0
222
+ */
223
+ return apply_filters( 'boldgrid_backup_post_get_dump_file', $this->get_file( $file ) );
224
+ }
225
+
226
+ /**
227
+ * Get the filesize of the backup file itself.
228
+ *
229
+ * IE the size of the zip file, not the size of everything before compression.
230
+ *
231
+ * @since 1.11.0
232
+ */
233
+ public function get_filesize() {
234
+ return $this->core->wp_filesystem->size( $this->filepath );
235
+ }
236
+
237
  /**
238
  * Init.
239
  *
240
  * @since 1.6.0
241
  *
242
+ * @param string $filepath File path.
243
  */
244
  public function init( $filepath ) {
 
245
  $filepath = strip_tags( $filepath );
246
 
247
  if ( ! empty( $this->filepath ) && $filepath === $this->filepath ) {
250
 
251
  $this->reset();
252
 
 
 
253
  $this->filepath = $filepath;
254
  $this->filename = basename( $this->filepath );
255
 
262
  $have_log = $this->core->archive_log->restore_by_zip( $this->filepath );
263
  }
264
 
 
265
  if ( $have_log ) {
266
  $this->log = $this->core->archive_log->get_by_zip( $this->filepath );
267
+
268
+ $this->timestamp = empty( $this->log['lastmodunix'] ) ? 0 : $this->log['lastmodunix'];
269
  }
270
 
271
  /*
277
  $this->compressor = ! empty( $this->log['compressor'] ) ? $this->log['compressor'] : 'php_zip';
278
 
279
  $this->view_details_url = admin_url( 'admin.php?page=boldgrid-backup-archive-details&filename=' . $this->filename );
280
+ }
281
+
282
+ /**
283
+ * Init an archive based on filename.
284
+ *
285
+ * This method's init() function requires a full filepath. This method is a helper function that
286
+ * inits based on filename instead.
287
+ *
288
+ * @since 1.7.3
289
+ *
290
+ * @param string $filename Filename.
291
+ */
292
+ public function init_by_filename( $filename ) {
293
+ $filepath = $this->core->backup_dir->get_path_to( $filename );
294
+
295
+ $this->init( $filepath );
296
+ }
297
+
298
+ /**
299
+ * Init this class based upon an archive key.
300
+ *
301
+ * @since 1.11.0
302
+ *
303
+ * @param int $key The archive key.
304
+ * @return bool Whether or not this archive was initialized successfully.
305
+ */
306
+ public function init_by_key( $key ) {
307
+ $this->reset();
308
+
309
+ $archives = $this->core->get_archive_list();
310
 
311
+ if ( empty( $archives[ $key ] ) ) {
312
+ return false;
313
+ }
314
+
315
+ $archive = $archives[ $key ];
316
+
317
+ if ( ! empty( $archive['filename'] ) ) {
318
+ $this->init_by_filename( $archive['filename'] );
319
+ }
320
+
321
+ /*
322
+ * Return whether or not this init method was successful. If we don't have a filename, then
323
+ * it was not succesful.
324
+ */
325
+ return ! empty( $this->filename );
326
+ }
327
+
328
+ /**
329
+ * Init this class using the last backup created.
330
+ *
331
+ * The last backup created is that defined by the boldgrid_backup_latest_backup option. This option
332
+ * is set at the end of Boldgrid_Backup_Admin_Core::archive_files.
333
+ */
334
+ public function init_by_latest() {
335
+ $option = get_option( 'boldgrid_backup_latest_backup' );
336
+
337
+ if ( ! empty( $option['filepath'] ) ) {
338
+ $this->init( $option['filepath'] );
339
+ }
340
  }
341
 
342
  /**
344
  *
345
  * @since 1.5.3
346
  *
347
+ * @param string $filepath File path.
348
  * @return bool
349
  */
350
  public function is_archive( $filepath ) {
371
  *
372
  * @since 1.6.0
373
  *
374
+ * @param string $filename Filename.
375
  * @return bool
376
  */
377
  public function is_site_archive( $filename ) {
437
  * @since 1.6.0
438
  */
439
  public function reset() {
440
+ $this->filename = null;
441
+ $this->filepath = null;
442
  $this->log_filepath = null;
443
  $this->log_filename = null;
444
+ $this->log = array();
445
+ $this->compressor = null;
446
+ }
447
+
448
+ /**
449
+ * Set an attribute in the log.
450
+ *
451
+ * @since 1.7.0
452
+ *
453
+ * @param string $key The key.
454
+ * @param string $value The value.
455
+ * @return bool
456
+ */
457
+ public function set_attribute( $key, $value ) {
458
+ $old_value = isset( $this->log[ $key ] ) ? $this->log[ $key ] : null;
459
+
460
+ // If the value is not changing, then return success.
461
+ if ( $value === $old_value ) {
462
+ return true;
463
+ }
464
+
465
+ /**
466
+ * Filter archive attribute value.
467
+ *
468
+ * Allows operations to be performed on attribute changes and alter the value depending on results.
469
+ *
470
+ * @since 1.12.2
471
+ *
472
+ * @param string $value New value.
473
+ * @param string $old_value Old value.
474
+ * @param string $key Key name.
475
+ * @param string $filepath Archive filepath.
476
+ * @return string
477
+ */
478
+ $value = apply_filters( 'boldgrid_backup_archive_update_attribute', $value, $old_value, $key, $this->filepath );
479
+
480
+ $this->log[ $key ] = $value;
481
+
482
+ return $this->core->archive_log->write( $this->log );
483
  }
484
 
485
  /**
492
  * timestamp from the log and configure the last modified appropriately.
493
  */
494
  public function update_timestamp() {
 
495
  // If we don't have what we need, abort.
496
  if ( empty( $this->filepath ) || empty( $this->log['lastmodunix'] ) ) {
497
  return false;
499
 
500
  return $this->core->wp_filesystem->touch( $this->filepath, $this->log['lastmodunix'] );
501
  }
502
+
503
+ /**
504
+ * Validate a download link request.
505
+ *
506
+ * @since 1.7.0
507
+ *
508
+ * @see Boldgrid_Backup_Admin_Archive::get_by_name()
509
+ *
510
+ * @param string $filename Filename.
511
+ * @return array
512
+ */
513
+ public function validate_link_request( $filename ) {
514
+ $result['is_valid'] = true;
515
+
516
+ // Verify access permissions.
517
+ if ( ! current_user_can( 'update_plugins' ) ) {
518
+ $result['errors'][] = __( 'Insufficient permission', 'boldgrid-backup' );
519
+ }
520
+
521
+ // Validate archive filename.
522
+ if ( empty( $filename ) ) {
523
+ $result['errors'][] = __( 'Invalid archive filename', 'boldgrid-backup' );
524
+ }
525
+
526
+ // Check WP_Filesystem method; ensure it is "direct".
527
+ if ( 'direct' !== get_filesystem_method() ) {
528
+ $result['errors'][] = __(
529
+ 'Filesystem access method is not "direct"',
530
+ 'boldgrid-backup'
531
+ );
532
+ }
533
+
534
+ // Get archive details.
535
+ $archive = $this->get_by_name( $filename );
536
+
537
+ // Check if archive file was found.
538
+ if ( empty( $archive ) ) {
539
+ $result['errors'][] = __( 'Archive file not found', 'boldgrid-backup' );
540
+ }
541
+
542
+ $expires = strtotime( '+' . $this->core->configs['public_link_lifetime'] );
543
+
544
+ if ( ! $expires || $expires < time() ) {
545
+ $result['errors'][] = __(
546
+ 'Invalid "public_link_lifetime" configuration setting',
547
+ 'boldgrid-backup'
548
+ );
549
+ }
550
+
551
+ if ( ! empty( $result['errors'] ) ) {
552
+ $result['is_valid'] = false;
553
+ }
554
+
555
+ return $result;
556
+ }
557
+
558
+ /**
559
+ * Generate a public link to download an archive file.
560
+ *
561
+ * The link is only valid for a limited time, which is configurable in a configuration file.
562
+ *
563
+ * @since 1.7.0
564
+ *
565
+ * @see Boldgrid_Backup_Admin_Archive::validate_link_request()
566
+ * @see Boldgrid_Backup_Authentication::create_token()
567
+ *
568
+ * @param string $filename Filename.
569
+ * @return string
570
+ */
571
+ public function generate_download_link( $filename ) {
572
+ $validation_results = $this->validate_link_request( $filename );
573
+
574
+ if ( $validation_results['is_valid'] ) {
575
+ $expires = strtotime( '+' . $this->core->configs['public_link_lifetime'] );
576
+ $token = Boldgrid_Backup_Authentication::create_token( $filename, $expires );
577
+
578
+ $response['download_url'] = get_site_url(
579
+ null,
580
+ 'wp-admin/admin-ajax.php?action=boldgrid_backup_download&t=' . $token
581
+ );
582
+
583
+ $response['expires_when'] = human_time_diff(
584
+ $expires,
585
+ current_time( 'timestamp', true )
586
+ );
587
+ } else {
588
+ $response['error'] = implode( '<br />', $validation_results['errors'] );
589
+ }
590
+
591
+ return $response;
592
+ }
593
+
594
+ /**
595
+ * Save backup information to a JSON file.
596
+ *
597
+ * The emergency restoration process will read the JSON file to discover the information about
598
+ * the last full backup created. Since the standalone restoration process does not know about
599
+ * the WordPress installation or the backup archives created, the contents of this file created
600
+ * will provide the facts.
601
+ * This method is called by Boldgrid_Backup_Admin_Core::archive_files().
602
+ *
603
+ * @since 1.8.0
604
+ *
605
+ * @see Boldgrid_Backup_Admin_Backup_Dir::get()
606
+ * @see Boldgrid_Backup_Admin_Cron::get_cron_secret()
607
+ * @see Boldgrid_Backup_Admin_Core::archive_files()
608
+ *
609
+ * @param array $info {
610
+ * An array of info about the backup just created.
611
+ *
612
+ * @type string $mode backup
613
+ * @type bool $dryrun
614
+ * @type string $compressor pcl_zip
615
+ * @type int $filesize 30992482
616
+ * @type bool $save
617
+ * @type int $total_size
618
+ * @type string $filepath C:\file.zip
619
+ * @type int $lastmodunix 1506602959
620
+ * @type int $duration 57.08
621
+ * @type int $db_duration 0.35
622
+ * @type bool $mail_success
623
+ * }
624
+ * @return bool
625
+ */
626
+ public function write_results_file( $info ) {
627
+ $success = false;
628
+ $archive_filepath = ! empty( $info['filepath'] ) ? $info['filepath'] : null;
629
+ $results_filepath = BOLDGRID_BACKUP_PATH . '/cron/restore-info.json';
630
+ $is_dir_writable = $this->core->wp_filesystem->is_writable( dirname( $results_filepath ) );
631
+
632
+ if ( $archive_filepath && $is_dir_writable ) {
633
+ $results_filepath = wp_normalize_path( $results_filepath );
634
+ $archive_filename = basename( $archive_filepath );
635
+ $archive_info = $this->core->archive->get_by_name( $archive_filename );
636
+ $archive_key = isset( $archive_info['key'] ) ? $archive_info['key'] : null;
637
+ $encrypt_db = ! empty( $archive_info['encrypt_db'] );
638
+ $encrypt_sig = isset( $archive_info['encrypt_sig'] ) ? $archive_info['encrypt_sig'] : null;
639
+ $cron_secret = $this->core->cron->get_cron_secret();
640
+ $siteurl = site_url();
641
+ $site_title = get_bloginfo( 'name' );
642
+ $restore_cmd = http_build_query(
643
+ [
644
+ 'mode' => 'restore',
645
+ 'siteurl' => $siteurl,
646
+ 'id' => $this->core->get_backup_identifier(),
647
+ 'secret' => $cron_secret,
648
+ 'archive_key' => $archive_key,
649
+ 'archive_filename' => $archive_filename,
650
+ 'site_title' => $site_title,
651
+ ],
652
+ '',
653
+ ' '
654
+ );
655
+
656
+ $results = array(
657
+ 'ABSPATH' => ABSPATH,
658
+ 'archive_key' => $archive_key,
659
+ 'cron_secret' => $cron_secret,
660
+ 'filepath' => $archive_filepath,
661
+ 'siteurl' => $siteurl,
662
+ 'site_title' => $site_title,
663
+ 'restore_cmd' => $this->core->cron->get_cron_command() . ' "' . dirname( __DIR__ ) .
664
+ '/boldgrid-backup-cron.php" ' . $restore_cmd,
665
+ 'timestamp' => time(),
666
+ );
667
+
668
+ $success = $this->core->wp_filesystem->put_contents(
669
+ $results_filepath,
670
+ wp_json_encode( $results ),
671
+ 0600
672
+ );
673
+ }
674
+
675
+ return $success;
676
+ }
677
+
678
+ /**
679
+ * Delete a file from an archive.
680
+ *
681
+ * @since 1.12.0
682
+ *
683
+ * @param \PclZip $archive PCLZip achive object.
684
+ * @param string $filename Filename to delete.
685
+ * @param array $list Content list from the archive object.
686
+ */
687
+ public function delete_from_archive( &$archive, $filename, $list = null ) {
688
+ if ( is_a( $archive, '\PclZip' ) && empty( $list ) ) {
689
+ $list = $archive->listContent();
690
+ }
691
+
692
+ if ( is_a( $archive, '\PclZip' ) && ! empty( $filename ) && ! empty( $list ) ) {
693
+ foreach ( $list as $index => $filedata ) {
694
+ if ( $filename === $filedata['filename'] ) {
695
+ $remaining = $archive->deleteByIndex( $index );
696
+
697
+ if ( ! empty( $remaining[1] ) ) {
698
+ $this->delete_from_archive( $archive, $filename, $remaining );
699
+ }
700
+ }
701
+ }
702
+ }
703
+ }
704
  }
admin/class-boldgrid-backup-admin-archiver-utility.php ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File: class-boldgrid-backup-admin-archiver-utility.php
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.9.0
7
+ *
8
+ * @package Boldgrid_Backup
9
+ * @copyright BoldGrid
10
+ * @version $Id$
11
+ * @author BoldGrid <support@boldgrid.com>
12
+ */
13
+
14
+ /**
15
+ * Class: Boldgrid_Backup_Admin_Archiver_Utility
16
+ *
17
+ * This class is a utility class designed to help during the archiving process.
18
+ *
19
+ * @since 1.9.0
20
+ */
21
+ class Boldgrid_Backup_Admin_Archiver_Utility {
22
+ /**
23
+ * The core class object.
24
+ *
25
+ * @since 1.9.0
26
+ * @access private
27
+ * @var Boldgrid_Backup_Admin_Core
28
+ */
29
+ private $core;
30
+
31
+ /**
32
+ * Constructor.
33
+ *
34
+ * @since 1.9.0
35
+ *
36
+ * @param Boldgrid_Backup_Admin_Core $core Core class object.
37
+ */
38
+ public function __construct( $core ) {
39
+ $this->core = $core;
40
+ }
41
+
42
+ /**
43
+ * Determine whether or not we are making a full backup.
44
+ *
45
+ * A full backup, in this case, is a backup meant for full restoration purposes.
46
+ *
47
+ * @since 1.9.0
48
+ *
49
+ * @return bool
50
+ */
51
+ public function is_full_backup() {
52
+ if ( $this->core->pre_auto_update ) {
53
+ return true;
54
+ }
55
+
56
+ if ( $this->core->is_archiving_update_protection ) {
57
+ return true;
58
+ }
59
+
60
+ if ( $this->core->is_backup_full ) {
61
+ return true;
62
+ }
63
+
64
+ if ( $this->core->is_scheduled_backup && $this->core->settings->is_all_files() && $this->core->settings->is_all_tables() ) {
65
+ return true;
66
+ }
67
+
68
+ return false;
69
+ }
70
+ }
admin/class-boldgrid-backup-admin-archives-all.php CHANGED
@@ -1,28 +1,27 @@
1
  <?php
2
  /**
3
- * Archives All class.
4
  *
5
- * @link http://www.boldgrid.com
6
- * @since 1.5.4
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
- * @copyright BoldGrid.com
11
  * @version $Id$
12
- * @author BoldGrid.com <wpb@boldgrid.com>
13
  */
14
 
15
  /**
16
- * BoldGrid Backup Admin Archives All Class.
17
  *
18
- * @since 1.5.4
19
  */
20
  class Boldgrid_Backup_Admin_Archives_All {
21
-
22
  /**
23
  * An array of all archives.
24
  *
25
- * @since 1.5.4
26
  * @access public
27
  * @var array
28
  */
@@ -31,7 +30,7 @@ class Boldgrid_Backup_Admin_Archives_All {
31
  /**
32
  * The core class object.
33
  *
34
- * @since 1.5.4
35
  * @access private
36
  * @var Boldgrid_Backup_Admin_Core
37
  */
@@ -40,7 +39,7 @@ class Boldgrid_Backup_Admin_Archives_All {
40
  /**
41
  * Whether or not we have initialized all backups.
42
  *
43
- * @since 1.5.4
44
  * @access public
45
  * @var bool
46
  */
@@ -49,7 +48,7 @@ class Boldgrid_Backup_Admin_Archives_All {
49
  /**
50
  * Local server title, such as "Web server".
51
  *
52
- * @since 1.5.4
53
  * @access public
54
  * @var string
55
  */
@@ -58,7 +57,7 @@ class Boldgrid_Backup_Admin_Archives_All {
58
  /**
59
  * An array of data about remote locations and how many backups at each.
60
  *
61
- * @since 1.5.4
62
  * @access public
63
  * @var array
64
  */
@@ -91,22 +90,22 @@ class Boldgrid_Backup_Admin_Archives_All {
91
  /**
92
  * Constructor.
93
  *
94
- * @since 1.5.4
95
  *
96
  * @param Boldgrid_Backup_Admin_Core $core Core class object.
97
  */
98
  public function __construct( $core ) {
99
  $this->core = $core;
100
 
101
- $this->local_title = __( 'Web Server', 'BoldGrid Backup' );
102
  }
103
 
104
  /**
105
  * Add a backup to the list of all backups.
106
  *
107
- * @since 1.5.4
108
  *
109
- * @param array $backup
110
  */
111
  public function add( $backup ) {
112
  $in_all = false;
@@ -121,7 +120,7 @@ class Boldgrid_Backup_Admin_Archives_All {
121
  if ( $backup['filename'] === $all_backup['filename'] ) {
122
 
123
  // Once we found our backup, flag that we found it.
124
- $in_all = true;
125
  $all_backup['locations'][] = $backup['locations'][0];
126
  }
127
  }
@@ -137,8 +136,8 @@ class Boldgrid_Backup_Admin_Archives_All {
137
  *
138
  * @since 1.6.0
139
  *
140
- * @param array $archive
141
- * @param string $location_type
142
  * @return bool
143
  */
144
  public function has_location_type( $archive, $location_type ) {
@@ -154,7 +153,7 @@ class Boldgrid_Backup_Admin_Archives_All {
154
  /**
155
  * Init the $location_count property.
156
  *
157
- * @since 1.5.4
158
  */
159
  public function init_location_count() {
160
 
@@ -183,7 +182,7 @@ class Boldgrid_Backup_Admin_Archives_All {
183
  /**
184
  * Init and get a list of all backups (local and remote).
185
  *
186
- * @since 1.5.4
187
  */
188
  public function init() {
189
  if ( $this->is_init ) {
@@ -194,12 +193,12 @@ class Boldgrid_Backup_Admin_Archives_All {
194
 
195
  foreach ( $archives as $archive ) {
196
  $this->all[] = array(
197
- 'filename' => $archive['filename'],
198
  'last_modified' => $archive['lastmodunix'],
199
- 'size' => $archive['filesize'],
200
- 'locations' => array(
201
  array(
202
- 'title' => $this->local_title,
203
  'on_web_server' => true,
204
  ),
205
  ),
1
  <?php
2
  /**
3
+ * File: class-boldgrid-backup-admin-archives-all.php
4
  *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.6.0
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
  * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
  */
14
 
15
  /**
16
+ * Class: Boldgrid_Backup_Admin_Archives_All
17
  *
18
+ * @since 1.6.0
19
  */
20
  class Boldgrid_Backup_Admin_Archives_All {
 
21
  /**
22
  * An array of all archives.
23
  *
24
+ * @since 1.6.0
25
  * @access public
26
  * @var array
27
  */
30
  /**
31
  * The core class object.
32
  *
33
+ * @since 1.6.0
34
  * @access private
35
  * @var Boldgrid_Backup_Admin_Core
36
  */
39
  /**
40
  * Whether or not we have initialized all backups.
41
  *
42
+ * @since 1.6.0
43
  * @access public
44
  * @var bool
45
  */
48
  /**
49
  * Local server title, such as "Web server".
50
  *
51
+ * @since 1.6.0
52
  * @access public
53
  * @var string
54
  */
57
  /**
58
  * An array of data about remote locations and how many backups at each.
59
  *
60
+ * @since 1.6.0
61
  * @access public
62
  * @var array
63
  */
90
  /**
91
  * Constructor.
92
  *
93
+ * @since 1.6.0
94
  *
95
  * @param Boldgrid_Backup_Admin_Core $core Core class object.
96
  */
97
  public function __construct( $core ) {
98
  $this->core = $core;
99
 
100
+ $this->local_title = __( 'Web Server', 'boldgrid-backup' );
101
  }
102
 
103
  /**
104
  * Add a backup to the list of all backups.
105
  *
106
+ * @since 1.6.0
107
  *
108
+ * @param array $backup Backup archive information.
109
  */
110
  public function add( $backup ) {
111
  $in_all = false;
120
  if ( $backup['filename'] === $all_backup['filename'] ) {
121
 
122
  // Once we found our backup, flag that we found it.
123
+ $in_all = true;
124
  $all_backup['locations'][] = $backup['locations'][0];
125
  }
126
  }
136
  *
137
  * @since 1.6.0
138
  *
139
+ * @param array $archive Archive information.
140
+ * @param string $location_type Location type.
141
  * @return bool
142
  */
143
  public function has_location_type( $archive, $location_type ) {
153
  /**
154
  * Init the $location_count property.
155
  *
156
+ * @since 1.6.0
157
  */
158
  public function init_location_count() {
159
 
182
  /**
183
  * Init and get a list of all backups (local and remote).
184
  *
185
+ * @since 1.6.0
186
  */
187
  public function init() {
188
  if ( $this->is_init ) {
193
 
194
  foreach ( $archives as $archive ) {
195
  $this->all[] = array(
196
+ 'filename' => $archive['filename'],
197
  'last_modified' => $archive['lastmodunix'],
198
+ 'size' => $archive['filesize'],
199
+ 'locations' => array(
200
  array(
201
+ 'title' => $this->local_title,
202
  'on_web_server' => true,
203
  ),
204
  ),
admin/class-boldgrid-backup-admin-archives.php CHANGED
@@ -1,28 +1,27 @@
1
  <?php
2
  /**
3
- * Archives class.
4
  *
5
- * @link http://www.boldgrid.com
6
- * @since 1.5.4
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
  * @copyright BoldGrid.com
11
  * @version $Id$
12
- * @author BoldGrid.com <wpb@boldgrid.com>
13
  */
14
 
15
  /**
16
- * BoldGrid Backup Admin Archives Class.
17
  *
18
- * @since 1.5.4
19
  */
20
  class Boldgrid_Backup_Admin_Archives {
21
-
22
  /**
23
  * The core class object.
24
  *
25
- * @since 1.5.4
26
  * @access private
27
  * @var Boldgrid_Backup_Admin_Core
28
  */
@@ -31,7 +30,7 @@ class Boldgrid_Backup_Admin_Archives {
31
  /**
32
  * Constructor.
33
  *
34
- * @since 1.5.4
35
  *
36
  * @param Boldgrid_Backup_Admin_Core $core Core class object.
37
  */
@@ -44,7 +43,7 @@ class Boldgrid_Backup_Admin_Archives {
44
  *
45
  * @since 1.6.0
46
  *
47
- * @param $location array {
48
  * A location.
49
  *
50
  * @type string $title Such as "Web Server".
@@ -67,7 +66,7 @@ class Boldgrid_Backup_Admin_Archives {
67
  *
68
  * @since 1.6.0
69
  *
70
- * @param string $type
71
  * @return string
72
  */
73
  public function get_location_type_title( $type ) {
@@ -90,6 +89,7 @@ class Boldgrid_Backup_Admin_Archives {
90
  *
91
  * @since 1.6.0
92
  *
 
93
  * @return string
94
  */
95
  public function get_locations( $archive ) {
@@ -103,11 +103,21 @@ class Boldgrid_Backup_Admin_Archives {
103
 
104
  $title_attr = ! empty( $location['title_attr'] ) ? sprintf( 'title="%1$s"', esc_attr( $location['title_attr'] ) ) : '';
105
 
 
 
 
 
 
 
 
 
 
106
  $locations[] = sprintf(
107
- '<span %2$s %3$s>%1$s</span>',
108
  esc_html( $location['title'] ),
109
  $data_attr,
110
- $title_attr
 
111
  );
112
  }
113
 
@@ -122,14 +132,14 @@ class Boldgrid_Backup_Admin_Archives {
122
  * Returns a string such as:
123
  * All (5) | Web Server (4) | Remote (2)
124
  *
125
- * @since 1.5.4
126
  *
127
  * @return string
128
  */
129
  public function get_mine_count() {
130
  $this->core->archives_all->init();
131
 
132
- // An array of locations, each array item simliar to: <a>All<a/> (5)
133
  $locations = array();
134
 
135
  foreach ( $this->core->archives_all->location_count as $location => $count ) {
@@ -139,7 +149,8 @@ class Boldgrid_Backup_Admin_Archives {
139
 
140
  $title = $this->get_location_type_title( $location );
141
 
142
- $locations[] = sprintf('
 
143
  %3$s %1$s %4$s (%2$s)
144
  ',
145
  /* 1 */ $title,
@@ -155,7 +166,8 @@ class Boldgrid_Backup_Admin_Archives {
155
  $markup = '<p class="subsubsub">' . implode( ' | ', $locations ) . '</p>';
156
 
157
  // Create help text to go along with help icon.
158
- $markup .= sprintf('
 
159
  <p class="help" data-id="mine-count">
160
  %1$s
161
  </p>',
@@ -170,68 +182,162 @@ class Boldgrid_Backup_Admin_Archives {
170
  *
171
  * This table is displayed on the Backup Archives page.
172
  *
173
- * @since 1.5.4
 
 
 
174
  *
 
 
 
175
  * @return string
176
  */
177
- public function get_table() {
178
  $this->core->archives_all->init();
179
- $backup = __( 'Backup', 'boldgrid-backup' );
180
  $view_details = __( 'View details', 'boldgrid-backup' );
181
 
182
- $table = $this->get_mine_count();
183
-
184
- $table .= sprintf( '
185
- <table class="wp-list-table widefat fixed striped pages">
186
- <thead>
187
- <td>%1$s</td>
188
- <td>%2$s</td>
189
- <td></td>
190
- <tbody id="backup-archive-list-body">',
191
- __( 'Date', 'boldgrid-backup' ),
192
- __( 'Size', 'boldgrid-backup' )
193
- );
194
 
195
- foreach ( $this->core->archives_all->all as $archive ) {
196
- $locations = $this->get_locations( $archive );
197
-
198
- // dirlist -> lastmodunix -> mtime (last_modified in unix time).
199
- $this->core->time->init( $archive['last_modified'], 'utc' );
200
-
201
- $table .= sprintf( '
202
- <tr>
203
- <td>
204
- %2$s
205
- <p class="description">%6$s</p>
206
- </td>
207
- <td>
208
- %3$s
209
- </td>
210
- <td>
211
- <a
212
- class="button"
213
- href="admin.php?page=boldgrid-backup-archive-details&filename=%4$s"
214
- >%5$s</a>
215
- </td>
216
- </tr>
217
- ',
218
- /* 1 */ $backup,
219
- /* 2 */ $this->core->time->get_span(),
220
- /* 3 */ Boldgrid_Backup_Admin_Utility::bytes_to_human( $archive['size'] ),
221
- /* 4 */ $archive['filename'],
222
- /* 5 */ $view_details,
223
- /* 6 */ $locations
224
  );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
225
  }
226
- $table .= '</tbody>
227
- </table>
228
- ';
229
-
230
- if ( empty( $this->core->archives_all->all ) ) {
231
- $table = sprintf( '
232
- <p>%1$s</p>',
233
- __( 'You currently do not have any backups.', 'boldgrid-backup' )
234
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
235
  }
236
 
237
  return $table;
1
  <?php
2
  /**
3
+ * File: class-boldgrid-backup-admin-archives.php
4
  *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.6.0
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
  * @copyright BoldGrid.com
11
  * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
  */
14
 
15
  /**
16
+ * Class: Boldgrid_Backup_Admin_Archives
17
  *
18
+ * @since 1.6.0
19
  */
20
  class Boldgrid_Backup_Admin_Archives {
 
21
  /**
22
  * The core class object.
23
  *
24
+ * @since 1.6.0
25
  * @access private
26
  * @var Boldgrid_Backup_Admin_Core
27
  */
30
  /**
31
  * Constructor.
32
  *
33
+ * @since 1.6.0
34
  *
35
  * @param Boldgrid_Backup_Admin_Core $core Core class object.
36
  */
43
  *
44
  * @since 1.6.0
45
  *
46
+ * @param array $location {
47
  * A location.
48
  *
49
  * @type string $title Such as "Web Server".
66
  *
67
  * @since 1.6.0
68
  *
69
+ * @param string $type Location type.
70
  * @return string
71
  */
72
  public function get_location_type_title( $type ) {
89
  *
90
  * @since 1.6.0
91
  *
92
+ * @param array $archive Archive information.
93
  * @return string
94
  */
95
  public function get_locations( $archive ) {
103
 
104
  $title_attr = ! empty( $location['title_attr'] ) ? sprintf( 'title="%1$s"', esc_attr( $location['title_attr'] ) ) : '';
105
 
106
+ /*
107
+ * As of 1.7.0, the user can flag an archive as protected (exluded from retention
108
+ * process). Show a padlock next to those backups.
109
+ */
110
+ $icon = '';
111
+ if ( 'on_web_server' === $location_type && '1' === $this->core->archive->get_attribute( 'protect' ) ) {
112
+ $icon = '<span class="dashicons dashicons-lock" title="' . esc_attr__( 'This backup will not be deleted automatically from your Web Server due to your retention settings.', 'boldgrid-backup' ) . '"></span>';
113
+ }
114
+
115
  $locations[] = sprintf(
116
+ '<span %2$s %3$s>%1$s%4$s</span>',
117
  esc_html( $location['title'] ),
118
  $data_attr,
119
+ $title_attr,
120
+ $icon
121
  );
122
  }
123
 
132
  * Returns a string such as:
133
  * All (5) | Web Server (4) | Remote (2)
134
  *
135
+ * @since 1.6.0
136
  *
137
  * @return string
138
  */
139
  public function get_mine_count() {
140
  $this->core->archives_all->init();
141
 
142
+ // An array of locations, each array item simliar to: <a>All<a/> (5).
143
  $locations = array();
144
 
145
  foreach ( $this->core->archives_all->location_count as $location => $count ) {
149
 
150
  $title = $this->get_location_type_title( $location );
151
 
152
+ $locations[] = sprintf(
153
+ '
154
  %3$s %1$s %4$s (%2$s)
155
  ',
156
  /* 1 */ $title,
166
  $markup = '<p class="subsubsub">' . implode( ' | ', $locations ) . '</p>';
167
 
168
  // Create help text to go along with help icon.
169
+ $markup .= sprintf(
170
+ '
171
  <p class="help" data-id="mine-count">
172
  %1$s
173
  </p>',
182
  *
183
  * This table is displayed on the Backup Archives page.
184
  *
185
+ * @since 1.6.0
186
+ *
187
+ * @param array $options {
188
+ * Display options.
189
  *
190
+ * @type bool $show_link_button Display the "Get Download Link" button. Optional.
191
+ * @type bool $transfers_mode Alters messages for the transfers pages. Optional.
192
+ * }
193
  * @return string
194
  */
195
+ public function get_table( array $options = [] ) {
196
  $this->core->archives_all->init();
197
+ $backup = __( 'Backup', 'boldgrid-backup' );
198
  $view_details = __( 'View details', 'boldgrid-backup' );
199
 
200
+ $table = '';
201
+
202
+ /*
203
+ * If a user has backups, either locally or remote, create a $table showing a list of all their
204
+ * backups.
205
+ */
206
+ if ( ! empty( $this->core->archives_all->all ) ) {
207
+ // If showing a "Get Download Link" button, we need a container to show the results.
208
+ $table = (
209
+ ! empty( $options['show_link_button'] ) ?
210
+ '<div id="download-link-copy" class="notice notice-info inline"></div>' : ''
211
+ );
212
 
213
+ $table .= $this->get_mine_count();
214
+
215
+ $table .= sprintf(
216
+ '
217
+ <table class="wp-list-table widefat fixed striped pages">
218
+ <thead>
219
+ <td>%1$s</td>
220
+ <td>%2$s</td>
221
+ <td></td>' .
222
+ ( ! empty( $options['show_link_button'] ) ? '<td></td>' : '' ) . '
223
+ <tbody id="backup-archive-list-body">',
224
+ __( 'Date', 'boldgrid-backup' ),
225
+ __( 'Size', 'boldgrid-backup' )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
226
  );
227
+
228
+ foreach ( $this->core->archives_all->all as $archive ) {
229
+ $this->core->time->init( $archive['last_modified'], 'utc' );
230
+
231
+ // Get the title of the backup.
232
+ $filepath = $this->core->backup_dir->get_path_to( $archive['filename'] );
233
+ $this->core->archive->init( $filepath );
234
+ $title = $this->core->archive->get_attribute( 'title' );
235
+
236
+ $locations = $this->get_locations( $archive );
237
+
238
+ $db_encrypted = $this->core->archive->get_attribute( 'encrypt_db' ) ?
239
+ '<span class="bgbkup-db-encrypted"></span>' : '';
240
+
241
+ $table .= sprintf(
242
+ '
243
+ <tr>
244
+ <td>
245
+ %2$s
246
+ %7$s<br />
247
+ <p class="description">%6$s</p>
248
+ </td>
249
+ <td>
250
+ %3$s%8$s
251
+ </td>
252
+ <td>
253
+ <a
254
+ class="button"
255
+ href="admin.php?page=boldgrid-backup-archive-details&filename=%4$s"
256
+ >%5$s</a>
257
+ </td>
258
+ ' . (
259
+ // Show a "Get Download Link" button.
260
+ ! empty( $options['show_link_button'] ) ?
261
+ '<td>' . $this->core->archive_actions->get_download_link_button( $archive['filename'] ) . '</td>' : ''
262
+ ) . '</tr>',
263
+ /* 1 */ $backup,
264
+ /* 2 */ empty( $title ) ? '' : '<strong>' . esc_html( $title ) . '</strong><br />',
265
+ /* 3 */ Boldgrid_Backup_Admin_Utility::bytes_to_human( $archive['size'] ),
266
+ /* 4 */ $archive['filename'],
267
+ /* 5 */ $view_details,
268
+ /* 6 */ $locations,
269
+ /* 7 */ $this->core->time->get_span(),
270
+ /* 8 */ $db_encrypted
271
+ );
272
+ }
273
+
274
+ $table .= '</tbody>
275
+ </table>
276
+ ';
277
  }
278
+
279
+ /*
280
+ * Create message for users who have no backups.
281
+ *
282
+ * If a user has no backups, instead of saying, "Hey, you have no backups", we should inform
283
+ * the user (1) how they can create their first backup and (2) how they can schedule backups.
284
+ *
285
+ * In edition to checking whether or not the user has any backups, make sure they're not currently
286
+ * backing up their site. We don't want to tell the user to create their first backup if there
287
+ * is a backup currently in progress.
288
+ */
289
+ if ( ! $this->core->in_progress->get() && empty( $this->core->archives_all->all ) ) {
290
+ $table = '
291
+ <div class="notice notice-warning inline" style="margin:15px 0">
292
+ <p>
293
+ <strong>
294
+ ' . esc_html( 'It looks like you don\'t have any backups! That\'s ok, let\'s fix that now. Here\'s what we recommend you do:', 'boldgrid-backup' ) . '
295
+ </strong>
296
+ </p>
297
+ <ol>
298
+ <li>';
299
+
300
+ if ( ! empty( $options['transfers_mode'] ) ) {
301
+ $table .= wp_kses(
302
+ sprintf(
303
+ // translators: 1 an opening strong tag, 2 its closing strong tag.
304
+ __( 'Go to the %1$sBackups%2$s page to create a backup of your site, and then come back here for further instruction.', 'boldgrid-backup' ),
305
+ '<em>',
306
+ '</em>'
307
+ ),
308
+ [ 'em' => [] ]
309
+ );
310
+ } else {
311
+ $table .= wp_kses(
312
+ sprintf(
313
+ // translators: 1 an opening strong tag, 2 its closing strong tag.
314
+ __( 'Create a backup of your site right now by clicking the %1$sBackup Site Now%2$s button at the top of the page.', 'boldgrid-backup' ),
315
+ '<strong>',
316
+ '</strong>'
317
+ ),
318
+ array( 'strong' => array() )
319
+ );
320
+ }
321
+
322
+ $table .= '</li>';
323
+
324
+ if ( empty( $options['transfers_mode'] ) ) {
325
+ $table .= '<li>';
326
+ $table .= wp_kses(
327
+ sprintf(
328
+ // translators: 1 the opening anchor tag linking to the settings page, 2 its closing anchor tag.
329
+ __( 'After the backup is created, go to your %1$ssettings%2$s page and setup backups so they\'re create automatically on a set schedule.', 'boldgrid-backup' ),
330
+ '<a href="' . $this->core->settings->get_settings_url() . '">',
331
+ '</a>'
332
+ ),
333
+ array( 'a' => array( 'href' => array() ) )
334
+ );
335
+ $table .= '</li>';
336
+ }
337
+
338
+ $table .= '
339
+ </ol>
340
+ </div>';
341
  }
342
 
343
  return $table;
admin/class-boldgrid-backup-admin-auto-rollback.php CHANGED
@@ -1,19 +1,21 @@
1
  <?php
2
  /**
3
- * Boldgrid Backup Admin Auto Rollback.
4
  *
5
- * @link http://www.boldgrid.com
6
  * @since 1.5.2
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
- * @copyright BoldGrid.com
11
  * @version $Id$
12
- * @author BoldGrid.com <wpb@boldgrid.com>
13
  */
14
 
 
 
15
  /**
16
- * Boldgrid Backup Admin Auto Rollback class.
17
  *
18
  * We hook into "the upgrader_process_complete" (run when the download process
19
  * for a plugin install or update finishes). If the user has enabled auto
@@ -47,7 +49,6 @@
47
  * @since 1.5.1
48
  */
49
  class Boldgrid_Backup_Admin_Auto_Rollback {
50
-
51
  /**
52
  * The core class object.
53
  *
@@ -57,6 +58,23 @@ class Boldgrid_Backup_Admin_Auto_Rollback {
57
  */
58
  private $core;
59
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  /**
61
  * Whether or not we are on an update page.
62
  *
@@ -116,13 +134,13 @@ class Boldgrid_Backup_Admin_Auto_Rollback {
116
  *
117
  * @since 1.5.1
118
  *
119
- * @param Boldgrid_Backup_Admin_Core $core
120
  */
121
  public function __construct( $core ) {
122
  $this->core = $core;
123
 
124
  $this->updating_core = 'update-core.php' === $this->core->pagenow &&
125
- ! empty( $_GET['action'] ) && 'do-core-upgrade' === $_GET['action'];
126
 
127
  $this->on_update_page = in_array( $this->core->pagenow, $this->update_pages, true );
128
  }
@@ -153,7 +171,7 @@ class Boldgrid_Backup_Admin_Auto_Rollback {
153
  return;
154
  }
155
 
156
- $archives = $this->core->get_archive_list();
157
  $archive_count = count( $archives );
158
 
159
  // If there are no archives, then abort.
@@ -207,20 +225,6 @@ class Boldgrid_Backup_Admin_Auto_Rollback {
207
  false
208
  );
209
 
210
- $access_type = get_filesystem_method();
211
- $archive_nonce = wp_create_nonce( 'archive_auth' );
212
- $localize_script_data = array(
213
- 'archiveNonce' => $archive_nonce,
214
- 'accessType' => $access_type,
215
- 'updateProtectionActivated' => $this->core->elements['update_protection_activated'],
216
- 'backupCreated' => $this->core->lang['backup_created'],
217
- 'errorText' => esc_html__(
218
- 'There was an error processing your request. Please reload the page and try again.',
219
- 'boldgrid-backup'
220
- ),
221
- );
222
- wp_localize_script( $handle, 'localizeScriptData', $localize_script_data );
223
-
224
  wp_enqueue_script( $handle );
225
  }
226
 
@@ -251,9 +255,9 @@ class Boldgrid_Backup_Admin_Auto_Rollback {
251
  );
252
 
253
  $translations = array(
254
- 'update_data' => wp_get_update_data(),
255
- 'in_progress_notice' => $this->core->in_progress->get_notice_markup(),
256
- 'nonce' => wp_create_nonce( 'boldgrid_backup_customizer' ),
257
  'is_rollback_enabled' => $this->is_enabled(),
258
  );
259
  wp_localize_script( $handle, 'boldgridBackupCustomizer', $translations );
@@ -272,13 +276,29 @@ class Boldgrid_Backup_Admin_Auto_Rollback {
272
  * @since 1.6.0
273
  */
274
  public function enqueue_home_scripts() {
275
- wp_enqueue_script(
276
- 'boldgrid-backup-admin-home',
 
 
277
  plugin_dir_url( __FILE__ ) . 'js/boldgrid-backup-admin-home.js',
278
  array( 'jquery' ),
279
  BOLDGRID_BACKUP_VERSION,
280
  false
281
  );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
282
  }
283
 
284
  /**
@@ -338,7 +358,7 @@ class Boldgrid_Backup_Admin_Auto_Rollback {
338
  * @since 1.6.0
339
  */
340
  public function enqueue_update_selectors() {
341
- if ( $this->on_update_page ) {
342
  $handle = 'boldgrid-backup-admin-update-selectors';
343
 
344
  wp_register_script(
@@ -352,7 +372,7 @@ class Boldgrid_Backup_Admin_Auto_Rollback {
352
  $localize_script_data = array(
353
  // Generally used as the title attr of a disable update button.
354
  'backupInProgress' => __( 'Your website is currently being backed up. You can perform updates when the backup is complete.', 'boldgrid-backup' ),
355
- 'waitClass' => 'bgbu-wait',
356
  );
357
 
358
  wp_localize_script( $handle, 'boldgrid_backup_admin_update_selectors', $localize_script_data );
@@ -373,14 +393,13 @@ class Boldgrid_Backup_Admin_Auto_Rollback {
373
  * @return null
374
  */
375
  public function notice_countdown_show() {
376
-
377
  // Process GET / POST info.
378
- $action = ! empty( $_GET['action'] ) ? sanitize_key( $_GET['action'] ) : null;
379
- $restore_now = ! empty( $_POST['restore_now'] );
380
 
381
  $pending_rollback = get_site_option( 'boldgrid_backup_pending_rollback' );
382
- $deadline = ! empty( $pending_rollback['deadline'] ) ? $pending_rollback['deadline'] : null;
383
- $deadline_passed = ! empty( $deadline ) && $deadline <= time();
384
 
385
  if ( $this->on_update_page ) {
386
  $this->enqueue_rollback_scripts();
@@ -422,7 +441,7 @@ class Boldgrid_Backup_Admin_Auto_Rollback {
422
  return;
423
  }
424
 
425
- $archives = $this->core->get_archive_list();
426
  $archive_count = count( $archives );
427
 
428
  /*
@@ -465,8 +484,6 @@ class Boldgrid_Backup_Admin_Auto_Rollback {
465
  */
466
  $notice_markup = $this->notice_countdown_get();
467
  do_action( 'boldgrid_backup_notice', $notice_markup, 'notice notice-warning is-dismissible boldgrid-backup-countdown' );
468
-
469
- return;
470
  }
471
 
472
  /**
@@ -478,10 +495,10 @@ class Boldgrid_Backup_Admin_Auto_Rollback {
478
  * @access private
479
  *
480
  * @param array $args {
481
- * An array of arguments.
482
  *
483
- * @type int $restore_key Key index used for restoration.
484
- * @type string $restore_filename Filename of the backup archive to be restored.
485
  * }
486
  * @return string The resulting markup.
487
  */
@@ -489,28 +506,28 @@ class Boldgrid_Backup_Admin_Auto_Rollback {
489
 
490
  // By default we will restore the newest backup.
491
  if ( empty( $args ) ) {
492
- $key = 0;
493
  $archives = $this->core->get_archive_list();
494
- $args = array(
495
- 'restore_key' => $key,
496
  'restore_filename' => $archives[ $key ]['filename'],
497
  );
498
  }
499
 
500
  $pending_rollback = get_site_option( 'boldgrid_backup_pending_rollback' );
501
- $deadline = ! empty( $pending_rollback['deadline'] ) ? sprintf( '(<em>%1$s</em>)', date( 'g:i a', $this->core->utility->time( $pending_rollback['deadline'] ) ) ) : '';
502
 
503
  $update_trigger = $this->notice_trigger_get();
504
  $update_trigger = ! empty( $update_trigger ) ? sprintf( '<p>%1$s</p>', $update_trigger ) : '';
505
 
506
  $nonce = wp_nonce_field( 'boldgrid_rollback_notice', 'cancel_rollback_auth', true, false );
507
 
508
- $button_args = array(
509
  'button_text' => __( 'Rollback Site Now', 'boldgrid-backup' ),
510
  );
511
  $restore_button = $this->core->archive_actions->get_restore_button( $args['restore_filename'], $button_args );
512
 
513
- $iso_time = ! empty( $pending_rollback['deadline'] ) ? date( 'c', $pending_rollback['deadline'] ) : null;
514
  $rollback_deadline = sprintf( '<input type="hidden" id="rollback-deadline" value="%1$s" />', $iso_time );
515
 
516
  $notice_markup = '
@@ -528,7 +545,15 @@ class Boldgrid_Backup_Admin_Auto_Rollback {
528
  </p>
529
 
530
  <p>
531
- ' . sprintf( __( '<strong>Update Protection</strong> for <em>future updates</em> can be configured on your <a href="%1$s">Settings</a> page.', 'boldgrid-backup' ), admin_url( 'admin.php?page=boldgrid-backup-settings&section=section_updates' ) ) . '
 
 
 
 
 
 
 
 
532
  </p>
533
 
534
  <p>
@@ -574,6 +599,63 @@ class Boldgrid_Backup_Admin_Auto_Rollback {
574
  }
575
  }
576
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
577
  /**
578
  * Return a bool indicating whether or not auto_rollback is enabled.
579
  *
@@ -596,8 +678,8 @@ class Boldgrid_Backup_Admin_Auto_Rollback {
596
  */
597
  public function notice_trigger_get() {
598
  $pending_rollback = get_site_option( 'boldgrid_backup_pending_rollback' );
599
- $notice = false;
600
- $li = array();
601
 
602
  if ( empty( $pending_rollback['update_trigger'] ) ) {
603
  return false;
@@ -612,22 +694,31 @@ class Boldgrid_Backup_Admin_Auto_Rollback {
612
  switch ( $trigger['type'] ) {
613
  case 'core':
614
  $wordpress_version = get_bloginfo( 'version' );
615
- $notice = sprintf( __( 'WordPress was recently updated to version %1$s.', 'boldgrid-backup' ), $wordpress_version );
 
 
 
 
 
 
 
616
  break;
617
  case 'theme':
618
  foreach ( $trigger['themes'] as $theme ) {
619
  $data = wp_get_theme( $theme );
620
  $li[] = sprintf( '<strong>%1$s</strong> to version %2$s', $data->get( 'Name' ), $data->get( 'Version' ) );
621
  }
622
- $notice = __( 'The following theme(s) were recently updated:', 'boldgrid-backup' ) . '<br />';
623
  $notice .= implode( '<br />', $li );
624
  break;
625
  case 'plugin':
626
- foreach ( $trigger['plugins'] as $plugin ) {
 
 
627
  $data = $this->core->utility->get_plugin_data( $plugin );
628
  $li[] = sprintf( '<strong>%1$s</strong> to version %2$s', $data['Name'], $data['Version'] );
629
  }
630
- $notice = __( 'The following plugin(s) were recently updated:', 'boldgrid-backup' ) . '<br />';
631
  $notice .= implode( '<br />', $li );
632
  break;
633
  }
@@ -643,7 +734,10 @@ class Boldgrid_Backup_Admin_Auto_Rollback {
643
  * @return string
644
  */
645
  public function notice_backup_get() {
646
- $notice_text = sprintf( '<h2 class="header-notice">%1$s</h2>', __( 'BoldGrid Backup - Update Protection', 'boldgrid-backup' ) );
 
 
 
647
 
648
  $notice_text .= '<p>';
649
 
@@ -679,6 +773,21 @@ class Boldgrid_Backup_Admin_Auto_Rollback {
679
  * @global string $pagenow
680
  */
681
  public function notice_backup_show() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
682
 
683
  /*
684
  * This method is hooked into admin_notices. If we don't have auto_rollback
@@ -688,20 +797,33 @@ class Boldgrid_Backup_Admin_Auto_Rollback {
688
  return;
689
  }
690
 
 
 
 
 
 
 
 
 
 
 
 
 
 
691
  $display = false;
692
 
693
  $configs = array(
694
  array(
695
  'pagenow' => 'plugins.php',
696
- 'check' => 'plugins',
697
  ),
698
  array(
699
  'pagenow' => 'themes.php',
700
- 'check' => 'themes',
701
  ),
702
  array(
703
  'pagenow' => 'update-core.php',
704
- 'check' => 'total',
705
  ),
706
  );
707
 
@@ -743,9 +865,10 @@ class Boldgrid_Backup_Admin_Auto_Rollback {
743
  return;
744
  }
745
 
746
- // If there is a pending rollback, then abort.
747
  if ( ! empty( $pending_rollback['lastmodunix'] ) ) {
748
  $this->notice_activated_show();
 
749
  return;
750
  }
751
 
@@ -758,8 +881,9 @@ class Boldgrid_Backup_Admin_Auto_Rollback {
758
  * 1.6.0 so that we can uniquely identify this notice on the page.
759
  */
760
  $backup_button = include BOLDGRID_BACKUP_PATH . '/admin/partials/boldgrid-backup-admin-backup-button.php';
761
- $notice = $this->notice_backup_get();
762
- do_action( 'boldgrid_backup_notice', $notice . $backup_button, 'notice notice-warning is-dismissible boldgrid-backup-protect-now' );
 
763
  }
764
 
765
  /**
@@ -771,12 +895,12 @@ class Boldgrid_Backup_Admin_Auto_Rollback {
771
  *
772
  * @link https://developer.wordpress.org/reference/hooks/upgrader_process_complete/
773
  * @see Boldgrid_Backup_Admin_Cron::add_restore_cron().
 
774
  *
775
- * @param object $upgrader_object Plugin_Upgrader Object
776
- * @param array $options See https://pastebin.com/ah4E048B
777
  */
778
  public function notice_deadline_show( $upgrader_object, $options ) {
779
-
780
  /*
781
  * This method is ran both when a plugin/theme/WP is updated, and when
782
  * a plugin is simply uploaded. As of 1.6.0, this plugin does not offer
@@ -806,11 +930,10 @@ class Boldgrid_Backup_Admin_Auto_Rollback {
806
  return;
807
  }
808
 
809
- // Get the ISO time (in ISO 8601 format).
810
- $iso_time = date( 'c', $deadline );
811
-
812
- // Print a hidden div with the time, so that JavaScript can read it.
813
- printf( '<div class="hidden" id="rollback-deadline">%1$s</div>', $iso_time );
814
  }
815
 
816
  /**
@@ -818,7 +941,9 @@ class Boldgrid_Backup_Admin_Auto_Rollback {
818
  *
819
  * @since 1.5.3
820
  *
821
- * @param array $options https://pastebin.com/ah4E048B
 
 
822
  */
823
  public function set_update_trigger( $options ) {
824
  if ( empty( $options ) || ! is_array( $options ) ) {
@@ -858,6 +983,7 @@ class Boldgrid_Backup_Admin_Auto_Rollback {
858
  $message .= '<p>';
859
 
860
  $message .= sprintf(
 
861
  __( 'You last made a backup %1$s ago.', 'boldgrid-backup' ),
862
  human_time_diff( $pending_rollback['lastmodunix'], time() )
863
  ) . ' ';
@@ -875,7 +1001,8 @@ class Boldgrid_Backup_Admin_Auto_Rollback {
875
  }
876
 
877
  // Customize our message for the "update theme" feature within the customizer.
878
- $path = parse_url( wp_get_referer(), PHP_URL_PATH );
 
879
  if ( defined( 'DOING_AJAX' ) && DOING_AJAX && 'customize.php' === substr( $path, -1 * strlen( 'customize.php' ) ) ) {
880
  $message .= $theme_message;
881
  }
@@ -883,7 +1010,7 @@ class Boldgrid_Backup_Admin_Auto_Rollback {
883
  $message .= '</p>';
884
 
885
  $message = array(
886
- 'html' => $message,
887
  'class' => 'notice notice-success is-dismissible boldgrid-backup-protected',
888
  );
889
 
@@ -902,13 +1029,12 @@ class Boldgrid_Backup_Admin_Auto_Rollback {
902
  * @since 1.5.3
903
  */
904
  public function notice_activated_show() {
905
-
906
  /*
907
  * If we're in the middle of upgrading something, such as:
908
  * update-core.php?action=do-theme-upgrade
909
  * Then there's no need to show a message.
910
  */
911
- if ( ! empty( $_GET['action'] ) ) {
912
  return;
913
  }
914
 
@@ -976,8 +1102,7 @@ class Boldgrid_Backup_Admin_Auto_Rollback {
976
  }
977
 
978
  // Convert the deadline to ISO time (in ISO 8601 format).
979
- $iso_time = date( 'c', $deadline );
980
- wp_die( $iso_time );
981
  }
982
 
983
  /**
@@ -1012,7 +1137,7 @@ class Boldgrid_Backup_Admin_Auto_Rollback {
1012
  * @since 1.6.0
1013
  */
1014
  public function wp_ajax_get_protect_notice() {
1015
- if ( ! current_user_can( 'update_plugins' ) ) {
1016
  wp_send_json_error();
1017
  }
1018
 
@@ -1020,14 +1145,57 @@ class Boldgrid_Backup_Admin_Auto_Rollback {
1020
  if ( ! empty( $pending_rollback ) ) {
1021
  // You're protected, go ahead and update.
1022
  $message = $this->notice_activated_get();
1023
- $notice = sprintf( '<div class="%1$s">%2$s</div>', $message['class'], $message['html'] );
1024
  } else {
1025
  // You're not protected, make a backup first.
1026
- $notice = $this->notice_backup_get();
1027
  $backup_button = include BOLDGRID_BACKUP_PATH . '/admin/partials/boldgrid-backup-admin-backup-button.php';
1028
- $notice = '<div class="notice notice-warning is-dismissible boldgrid-backup-protect-now">' . $notice . $backup_button . '</div>';
 
1029
  }
1030
 
1031
  wp_send_json_success( $notice );
1032
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1033
  }
1
  <?php
2
  /**
3
+ * File: class-boldgrid-backup-admin-auto-rollback.php
4
  *
5
+ * @link https://www.boldgrid.com
6
  * @since 1.5.2
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
  * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
  */
14
 
15
+ // phpcs:disable WordPress.VIP
16
+
17
  /**
18
+ * Class: Boldgrid_Backup_Admin_Auto_Rollback
19
  *
20
  * We hook into "the upgrader_process_complete" (run when the download process
21
  * for a plugin install or update finishes). If the user has enabled auto
49
  * @since 1.5.1
50
  */
51
  class Boldgrid_Backup_Admin_Auto_Rollback {
 
52
  /**
53
  * The core class object.
54
  *
58
  */
59
  private $core;
60
 
61
+ /**
62
+ * Time data.
63
+ *
64
+ * An array of time about when our auto rollback needs to occur.
65
+ *
66
+ * When we are setting our auto rollback cron, we need to get the time for 15 minutes from now
67
+ * (or whatever time limit is set in the config). When we parse that time, we split out the minute,
68
+ * hour, etc, to help build the cron command.
69
+ *
70
+ * After parsing the time, we save it in this class property.
71
+ *
72
+ * @since 1.11.0
73
+ * @access private
74
+ * @var array
75
+ */
76
+ private $time_data = [];
77
+
78
  /**
79
  * Whether or not we are on an update page.
80
  *
134
  *
135
  * @since 1.5.1
136
  *
137
+ * @param Boldgrid_Backup_Admin_Core $core Boldgrid_Backup_Admin_Core object.
138
  */
139
  public function __construct( $core ) {
140
  $this->core = $core;
141
 
142
  $this->updating_core = 'update-core.php' === $this->core->pagenow &&
143
+ ! empty( $_GET['action'] ) && 'do-core-upgrade' === $_GET['action']; // phpcs:ignore WordPress.CSRF.NonceVerification.NoNonceVerification
144
 
145
  $this->on_update_page = in_array( $this->core->pagenow, $this->update_pages, true );
146
  }
171
  return;
172
  }
173
 
174
+ $archives = $this->core->get_archive_list();
175
  $archive_count = count( $archives );
176
 
177
  // If there are no archives, then abort.
225
  false
226
  );
227
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
228
  wp_enqueue_script( $handle );
229
  }
230
 
255
  );
256
 
257
  $translations = array(
258
+ 'update_data' => wp_get_update_data(),
259
+ 'in_progress_notice' => $this->core->in_progress->get_notice_markup(),
260
+ 'nonce' => wp_create_nonce( 'boldgrid_backup_customizer' ),
261
  'is_rollback_enabled' => $this->is_enabled(),
262
  );
263
  wp_localize_script( $handle, 'boldgridBackupCustomizer', $translations );
276
  * @since 1.6.0
277
  */
278
  public function enqueue_home_scripts() {
279
+ $handle = 'boldgrid-backup-admin-home';
280
+
281
+ wp_register_script(
282
+ $handle,
283
  plugin_dir_url( __FILE__ ) . 'js/boldgrid-backup-admin-home.js',
284
  array( 'jquery' ),
285
  BOLDGRID_BACKUP_VERSION,
286
  false
287
  );
288
+
289
+ $translation = array(
290
+ 'savedTo' => __( 'File saved to: ', 'boldgrid-backup' ),
291
+ 'viewDetails' => __( 'View details', 'boldgrid-backup' ),
292
+ 'invalidUrl' => __( 'You must enter valid a URL address.', 'boldgrid-backup' ),
293
+ 'notZip' => __( 'The URL address is not a ZIP file.', 'boldgrid-backup' ),
294
+ 'unknownError' => __( 'Unknown error.', 'boldgrid-backup' ),
295
+ 'ajaxError' => __( 'Could not reach the URL address. HTTP error: ', 'boldgrid-backup' ),
296
+ 'urlRegex' => $this->core->configs['url_regex'],
297
+ 'restore' => __( 'Restore', 'boldgrid-backup' ),
298
+ );
299
+
300
+ wp_localize_script( $handle, 'BoldGridBackupAdminHome', $translation );
301
+ wp_enqueue_script( $handle );
302
  }
303
 
304
  /**
358
  * @since 1.6.0
359
  */
360
  public function enqueue_update_selectors() {
361
+ if ( $this->on_update_page || $this->core->utility->is_admin_page( 'boldgrid-backup' ) ) {
362
  $handle = 'boldgrid-backup-admin-update-selectors';
363
 
364
  wp_register_script(
372
  $localize_script_data = array(
373
  // Generally used as the title attr of a disable update button.
374
  'backupInProgress' => __( 'Your website is currently being backed up. You can perform updates when the backup is complete.', 'boldgrid-backup' ),
375
+ 'waitClass' => 'bgbu-wait',
376
  );
377
 
378
  wp_localize_script( $handle, 'boldgrid_backup_admin_update_selectors', $localize_script_data );
393
  * @return null
394
  */
395
  public function notice_countdown_show() {
 
396
  // Process GET / POST info.
397
+ $action = ! empty( $_GET['action'] ) ? sanitize_key( $_GET['action'] ) : null; // phpcs:ignore WordPress.CSRF.NonceVerification.NoNonceVerification
398
+ $restore_now = ! empty( $_POST['restore_now'] ); // phpcs:ignore WordPress.CSRF.NonceVerification.NoNonceVerification
399
 
400
  $pending_rollback = get_site_option( 'boldgrid_backup_pending_rollback' );
401
+ $deadline = ! empty( $pending_rollback['deadline'] ) ? $pending_rollback['deadline'] : null;
402
+ $deadline_passed = ! empty( $deadline ) && $deadline <= time();
403
 
404
  if ( $this->on_update_page ) {
405
  $this->enqueue_rollback_scripts();
441
  return;
442
  }
443
 
444
+ $archives = $this->core->get_archive_list();
445
  $archive_count = count( $archives );
446
 
447
  /*
484
  */
485
  $notice_markup = $this->notice_countdown_get();
486
  do_action( 'boldgrid_backup_notice', $notice_markup, 'notice notice-warning is-dismissible boldgrid-backup-countdown' );
 
 
487
  }
488
 
489
  /**
495
  * @access private
496
  *
497
  * @param array $args {
498
+ * An array of arguments.
499
  *
500
+ * @type int $restore_key Key index used for restoration.
501
+ * @type string $restore_filename Filename of the backup archive to be restored.
502
  * }
503
  * @return string The resulting markup.
504
  */
506
 
507
  // By default we will restore the newest backup.
508
  if ( empty( $args ) ) {
509
+ $key = 0;
510
  $archives = $this->core->get_archive_list();
511
+ $args = array(
512
+ 'restore_key' => $key,
513
  'restore_filename' => $archives[ $key ]['filename'],
514
  );
515
  }
516
 
517
  $pending_rollback = get_site_option( 'boldgrid_backup_pending_rollback' );
518
+ $deadline = ! empty( $pending_rollback['deadline'] ) ? sprintf( '(<em>%1$s</em>)', date( 'g:i a', $this->core->utility->time( $pending_rollback['deadline'] ) ) ) : '';
519
 
520
  $update_trigger = $this->notice_trigger_get();
521
  $update_trigger = ! empty( $update_trigger ) ? sprintf( '<p>%1$s</p>', $update_trigger ) : '';
522
 
523
  $nonce = wp_nonce_field( 'boldgrid_rollback_notice', 'cancel_rollback_auth', true, false );
524
 
525
+ $button_args = array(
526
  'button_text' => __( 'Rollback Site Now', 'boldgrid-backup' ),
527
  );
528
  $restore_button = $this->core->archive_actions->get_restore_button( $args['restore_filename'], $button_args );
529
 
530
+ $iso_time = ! empty( $pending_rollback['deadline'] ) ? date( 'c', $pending_rollback['deadline'] ) : null;
531
  $rollback_deadline = sprintf( '<input type="hidden" id="rollback-deadline" value="%1$s" />', $iso_time );
532
 
533
  $notice_markup = '
545
  </p>
546
 
547
  <p>
548
+ ' .
549
+ sprintf(
550
+ // translators: 1: URL address.
551
+ __(
552
+ '<strong>Update Protection</strong> for <em>future updates</em> can be configured on your <a href="%1$s">Settings</a> page.',
553
+ 'boldgrid-backup'
554
+ ),
555
+ admin_url( 'admin.php?page=boldgrid-backup-settings&section=section_updates' )
556
+ ) . '
557
  </p>
558
 
559
  <p>
599
  }
600
  }
601
 
602
+ /**
603
+ * Get our auto rollback time data.
604
+ *
605
+ * This code was originally contained within Boldgrid_Backup_Admin_Cron::add_restore_cron, but
606
+ * has since been separated out for reusability.
607
+ *
608
+ * @since 1.11.0
609
+ *
610
+ * @return array
611
+ */
612
+ public function get_time_data() {
613
+ if ( ! empty( $this->time_data ) ) {
614
+ return $this->time_data;
615
+ }
616
+
617
+ $time = [];
618
+
619
+ // Get the unix time for 5 minutes from now.
620
+ $time_5_minutes_later = strtotime( $this->testing_time );
621
+
622
+ // Get the system's localized current time (HH:MM:SS), 5 minutes in the future.
623
+ $system_time = $this->core->execute_command(
624
+ 'date "+%H|%M|%S|%a %d %b %Y %I:%M:00 %p %Z" -d "' . $this->testing_time . '"'
625
+ );
626
+
627
+ // Split the time into hour, minute, and second.
628
+ if ( ! empty( $system_time ) ) {
629
+ list(
630
+ $time['hour'],
631
+ $time['minute'],
632
+ $time['second'],
633
+ $time['system_time_iso']
634
+ ) = explode( '|', $system_time );
635
+ }
636
+
637
+ // Validate hour; use system hour, or the date code for hour ("G").
638
+ if ( ! isset( $time['hour'] ) ) {
639
+ $time['hour'] = 'G';
640
+ }
641
+
642
+ // Validate hour; use system hour, or the date code for minute ("i").
643
+ if ( ! isset( $time['minute'] ) ) {
644
+ $time['minute'] = 'i';
645
+ }
646
+
647
+ // Mark the deadline.
648
+ if ( ! empty( $time['system_time_iso'] ) ) {
649
+ $time['deadline'] = strtotime( $time['system_time_iso'] );
650
+ } else {
651
+ $time['deadline'] = $time_5_minutes_later;
652
+ }
653
+
654
+ $this->time_data = $time;
655
+
656
+ return $this->time_data;
657
+ }
658
+
659
  /**
660
  * Return a bool indicating whether or not auto_rollback is enabled.
661
  *
678
  */
679
  public function notice_trigger_get() {
680
  $pending_rollback = get_site_option( 'boldgrid_backup_pending_rollback' );
681
+ $notice = false;
682
+ $li = array();
683
 
684
  if ( empty( $pending_rollback['update_trigger'] ) ) {
685
  return false;
694
  switch ( $trigger['type'] ) {
695
  case 'core':
696
  $wordpress_version = get_bloginfo( 'version' );
697
+ $notice = sprintf(
698
+ // translators: 1: WordPress version string.
699
+ __(
700
+ 'WordPress was recently updated to version %1$s.',
701
+ 'boldgrid-backup'
702
+ ),
703
+ $wordpress_version
704
+ );
705
  break;
706
  case 'theme':
707
  foreach ( $trigger['themes'] as $theme ) {
708
  $data = wp_get_theme( $theme );
709
  $li[] = sprintf( '<strong>%1$s</strong> to version %2$s', $data->get( 'Name' ), $data->get( 'Version' ) );
710
  }
711
+ $notice = __( 'The following theme(s) were recently updated:', 'boldgrid-backup' ) . '<br />';
712
  $notice .= implode( '<br />', $li );
713
  break;
714
  case 'plugin':
715
+ $plugins = ! empty( $trigger['plugins'] ) ? $trigger['plugins'] : array( $trigger['plugin'] );
716
+
717
+ foreach ( $plugins as $plugin ) {
718
  $data = $this->core->utility->get_plugin_data( $plugin );
719
  $li[] = sprintf( '<strong>%1$s</strong> to version %2$s', $data['Name'], $data['Version'] );
720
  }
721
+ $notice = __( 'The following plugin(s) were recently updated:', 'boldgrid-backup' ) . '<br />';
722
  $notice .= implode( '<br />', $li );
723
  break;
724
  }
734
  * @return string
735
  */
736
  public function notice_backup_get() {
737
+ $notice_text = sprintf(
738
+ '<h2 class="header-notice">%1$s</h2>',
739
+ BOLDGRID_BACKUP_TITLE . ' - ' . __( 'Update Protection', 'boldgrid-backup' )
740
+ );
741
 
742
  $notice_text .= '<p>';
743
 
773
  * @global string $pagenow
774
  */
775
  public function notice_backup_show() {
776
+ $action = ! empty( $_GET['action'] ) ? $_GET['action'] : null; // phpcs:ignore
777
+
778
+ /*
779
+ * The $_GET action that specifies an update has just occurred. These generally happen from
780
+ * Dashboard > Updates > Update.
781
+ */
782
+ $update_actions = [
783
+ 'do-theme-upgrade',
784
+ 'do-plugin-upgrade',
785
+ 'do-core-reinstall',
786
+ 'do-core-upgrade',
787
+ ];
788
+
789
+ // Whether or not we just updated something.
790
+ $just_updated = 'update-core.php' === $this->core->pagenow && in_array( $action, $update_actions, true );
791
 
792
  /*
793
  * This method is hooked into admin_notices. If we don't have auto_rollback
797
  return;
798
  }
799
 
800
+ /*
801
+ * If we just activated the plugin, we'll be showing a, "Thanks for installing!" notice. We
802
+ * don't want to bombard the user with notices, so don't show this notice too.
803
+ */
804
+ if ( Boldgrid_Backup_Activator::on_post_activate() ) {
805
+ return;
806
+ }
807
+
808
+ // Don't show notice if we just updated.
809
+ if ( $just_updated ) {
810
+ return;
811
+ }
812
+
813
  $display = false;
814
 
815
  $configs = array(
816
  array(
817
  'pagenow' => 'plugins.php',
818
+ 'check' => 'plugins',
819
  ),
820
  array(
821
  'pagenow' => 'themes.php',
822
+ 'check' => 'themes',
823
  ),
824
  array(
825
  'pagenow' => 'update-core.php',
826
+ 'check' => 'total',
827
  ),
828
  );
829
 
865
  return;
866
  }
867
 
868
+ // If there is a pending rollback (backup within the last hour), then abort.
869
  if ( ! empty( $pending_rollback['lastmodunix'] ) ) {
870
  $this->notice_activated_show();
871
+
872
  return;
873
  }
874
 
881
  * 1.6.0 so that we can uniquely identify this notice on the page.
882
  */
883
  $backup_button = include BOLDGRID_BACKUP_PATH . '/admin/partials/boldgrid-backup-admin-backup-button.php';
884
+ $in_progress = Boldgrid_Backup_Admin_In_Progress_Data::get_markup();
885
+ $notice = $this->notice_backup_get();
886
+ do_action( 'boldgrid_backup_notice', $notice . $backup_button . $in_progress, 'notice notice-warning is-dismissible boldgrid-backup-protect-now' );
887
  }
888
 
889
  /**
895
  *
896
  * @link https://developer.wordpress.org/reference/hooks/upgrader_process_complete/
897
  * @see Boldgrid_Backup_Admin_Cron::add_restore_cron().
898
+ * @link https://pastebin.com/ah4E048B
899
  *
900
+ * @param object $upgrader_object Plugin_Upgrader Object.
901
+ * @param array $options Options array.
902
  */
903
  public function notice_deadline_show( $upgrader_object, $options ) {
 
904
  /*
905
  * This method is ran both when a plugin/theme/WP is updated, and when
906
  * a plugin is simply uploaded. As of 1.6.0, this plugin does not offer
930
  return;
931
  }
932
 
933
+ // Print a hidden div with the time (in ISO 8601 format), so that JavaScript can read it.
934
+ ?>
935
+ <div class="hidden" id="rollback-deadline"><?php echo esc_html( date( 'c', $deadline ) ); ?></div>
936
+ <?php
 
937
  }
938
 
939
  /**
941
  *
942
  * @since 1.5.3
943
  *
944
+ * @link https://pastebin.com/ah4E048B
945
+ *
946
+ * @param array $options Option array.
947
  */
948
  public function set_update_trigger( $options ) {
949
  if ( empty( $options ) || ! is_array( $options ) ) {
983
  $message .= '<p>';
984
 
985
  $message .= sprintf(
986
+ // translators: 1: Time difference.
987
  __( 'You last made a backup %1$s ago.', 'boldgrid-backup' ),
988
  human_time_diff( $pending_rollback['lastmodunix'], time() )
989
  ) . ' ';
1001
  }
1002
 
1003
  // Customize our message for the "update theme" feature within the customizer.
1004
+ $path = wp_parse_url( wp_get_referer(), PHP_URL_PATH );
1005
+
1006
  if ( defined( 'DOING_AJAX' ) && DOING_AJAX && 'customize.php' === substr( $path, -1 * strlen( 'customize.php' ) ) ) {
1007
  $message .= $theme_message;
1008
  }
1010
  $message .= '</p>';
1011
 
1012
  $message = array(
1013
+ 'html' => $message,
1014
  'class' => 'notice notice-success is-dismissible boldgrid-backup-protected',
1015
  );
1016
 
1029
  * @since 1.5.3
1030
  */
1031
  public function notice_activated_show() {
 
1032
  /*
1033
  * If we're in the middle of upgrading something, such as:
1034
  * update-core.php?action=do-theme-upgrade
1035
  * Then there's no need to show a message.
1036
  */
1037
+ if ( ! empty( $_GET['action'] ) ) { // phpcs:ignore WordPress.CSRF.NonceVerification.NoNonceVerification
1038
  return;
1039
  }
1040
 
1102
  }
1103
 
1104
  // Convert the deadline to ISO time (in ISO 8601 format).
1105
+ wp_die( esc_html( date( 'c', $deadline ) ) );
 
1106
  }
1107
 
1108
  /**
1137
  * @since 1.6.0
1138
  */
1139
  public function wp_ajax_get_protect_notice() {
1140
+ if ( ! current_user_can( 'update_plugins' ) || ! $this->core->test->run_functionality_tests() ) {
1141
  wp_send_json_error();
1142
  }
1143
 
1145
  if ( ! empty( $pending_rollback ) ) {
1146
  // You're protected, go ahead and update.
1147
  $message = $this->notice_activated_get();
1148
+ $notice = sprintf( '<div class="%1$s">%2$s</div>', $message['class'], $message['html'] );
1149
  } else {
1150
  // You're not protected, make a backup first.
1151
+ $notice = $this->notice_backup_get();
1152
  $backup_button = include BOLDGRID_BACKUP_PATH . '/admin/partials/boldgrid-backup-admin-backup-button.php';
1153
+ $in_progress = Boldgrid_Backup_Admin_In_Progress_Data::get_markup();
1154
+ $notice = '<div class="notice notice-warning is-dismissible boldgrid-backup-protect-now">' . $notice . $backup_button . $in_progress . '</div>';
1155
  }
1156
 
1157
  wp_send_json_success( $notice );
1158
  }
1159
+
1160
+ /**
1161
+ * Validate the rollback option when retrieved.
1162
+ *
1163
+ * @since 1.7.0
1164
+ *
1165
+ * @param array|false $value WordPress option value for "boldgrid_backup_pending_rollback".
1166
+ * @param string $option Option name.
1167
+ * @return array|false
1168
+ */
1169
+ public function validate_rollback_option( $value, $option ) {
1170
+ $is_coutdown_active = ! empty( $value['deadline'] );
1171
+ $is_recent_backup = ! empty( $value['lastmodunix'] ) &&
1172
+ strtotime( '-1 HOUR' ) <= $value['lastmodunix'];
1173
+
1174
+ if ( ! $is_recent_backup && ! $is_coutdown_active ) {
1175
+ delete_site_option( $option );
1176
+ $value = false;
1177
+ }
1178
+
1179
+ return $value;
1180
+ }
1181
+
1182
+ /**
1183
+ * Callback function for canceling a pending rollback from the cli process.
1184
+ *
1185
+ * This admin-ajax call is unprovileged, so that the CLI script can make the call.
1186
+ * The only validation that we use is the backup identifier.
1187
+ * Nobody will be trying to cancel rollbacks (with a 15-minute window) anyways.
1188
+ *
1189
+ * @since 1.10.7
1190
+ */
1191
+ public function wp_ajax_cli_cancel() {
1192
+ $backup_id_match = ! empty( $_GET['backup_id'] ) && $this->core->get_backup_identifier() === sanitize_key( $_GET['backup_id'] ); // phpcs:ignore WordPress.CSRF.NonceVerification.NoNonceVerification
1193
+
1194
+ if ( $backup_id_match ) {
1195
+ $this->cancel();
1196
+ wp_send_json_success( __( 'Rollback canceled', 'boldgrid-backup' ) );
1197
+ } else {
1198
+ wp_send_json_error( __( 'Invalid arguments', 'boldgrid-backup' ), 400 );
1199
+ }
1200
+ }
1201
  }
admin/class-boldgrid-backup-admin-backup-dir.php CHANGED
@@ -1,24 +1,24 @@
1
  <?php
2
  /**
3
- * Boldgrid Backup Admin Backup Dir.
4
  *
5
- * @link http://www.boldgrid.com
6
  * @since 1.5.1
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
  * @copyright BoldGrid.com
11
- * @version $Id$
12
  * @author BoldGrid.com <wpb@boldgrid.com>
 
 
13
  */
14
 
15
  /**
16
- * Boldgrid Backup Admin Backup Dir class.
17
  *
18
  * @since 1.5.1
19
  */
20
  class Boldgrid_Backup_Admin_Backup_Dir {
21
-
22
  /**
23
  * Backup directory.
24
  *
@@ -59,41 +59,64 @@ class Boldgrid_Backup_Admin_Backup_Dir {
59
  *
60
  * @since 1.5.1
61
  *
62
- * @param Boldgrid_Backup_Admin_Core $core
63
  */
64
  public function __construct( $core ) {
65
  $this->core = $core;
66
  }
67
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
  /**
69
  * Create our backup directory and necessary files.
70
  *
71
  * @since 1.5.1
72
  *
73
- * @param string $backup_dir
74
  * @return mixed False on failure, trailingslashed $backup_dir on success.
75
  */
76
  public function create( $backup_dir ) {
77
  $check_permissions = __( 'Please ensure your backup directory exists and has the proper read, write, and modify permissions.', 'boldgrid-backup' );
78
 
 
79
  $cannot_create = __( 'Unable to create necessary file: %1$s<br />%2$s', 'boldgrid-backup' );
 
 
80
  $cannot_write = __( 'Unable to write to necessary file: %1$s<br />%2$s', 'boldgrid-backup' );
81
 
82
  $backup_dir = untrailingslashit( $backup_dir );
83
 
84
- $htaccess_path = $backup_dir . DIRECTORY_SEPARATOR . '.htaccess';
 
 
85
  $index_html_path = $backup_dir . DIRECTORY_SEPARATOR . 'index.html';
86
- $index_php_path = $backup_dir . DIRECTORY_SEPARATOR . 'index.php';
87
 
88
  $files = array(
89
  array(
90
- 'type' => 'dir',
91
- 'path' => $backup_dir,
92
  'chmod' => 0700,
93
  ),
94
  array(
95
- 'type' => 'file',
96
- 'path' => $htaccess_path,
 
 
 
 
 
97
  'contents' => "<IfModule mod_access_compat.c>\nOrder Allow,Deny\nDeny from all\n</IfModule>\nOptions -Indexes\n",
98
  ),
99
  array(
@@ -120,7 +143,7 @@ class Boldgrid_Backup_Admin_Backup_Dir {
120
  switch ( $file['type'] ) {
121
  case 'dir':
122
  if ( ! $this->core->wp_filesystem->exists( $file['path'] ) ) {
123
- $chmod = ! empty( $file['chmod'] ) ? $file['chmod'] : false;
124
  $created = $this->core->wp_filesystem->mkdir( $file['path'], $chmod );
125
  if ( ! $created ) {
126
  $this->errors[] = sprintf( $cannot_create, $file['path'], $check_permissions );
@@ -151,6 +174,47 @@ class Boldgrid_Backup_Admin_Backup_Dir {
151
  return $backup_dir;
152
  }
153
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
154
  /**
155
  * Get and return the backup directory path.
156
  *
@@ -167,14 +231,72 @@ class Boldgrid_Backup_Admin_Backup_Dir {
167
 
168
  // If we have it in the settings, then use it.
169
  $settings = $this->core->settings->get_settings();
170
- if ( ! empty( $settings['backup_directory'] ) ) {
171
- $this->set( $settings['backup_directory'] );
 
 
172
  return $this->backup_directory;
173
  }
174
 
175
  return $this->guess_and_set();
176
  }
177
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
178
  /**
179
  * Get an array of possible backup directories.
180
  *
@@ -188,7 +310,7 @@ class Boldgrid_Backup_Admin_Backup_Dir {
188
  $dirs[] = $this->core->config->get_home_directory();
189
 
190
  if ( $this->core->test->is_windows() ) {
191
- // C:\Users\user\AppData\Local
192
  $dirs[] = $this->core->config->get_home_directory() . DIRECTORY_SEPARATOR . 'AppData' . DIRECTORY_SEPARATOR . 'Local';
193
 
194
  if ( ! empty( $_SERVER['DOCUMENT_ROOT'] ) ) {
@@ -203,7 +325,7 @@ class Boldgrid_Backup_Admin_Backup_Dir {
203
  * there won't be downloadable.
204
  */
205
  $app_data = $_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . 'App_Data';
206
- $dirs[] = str_replace( '\\\\', '\\', $app_data );
207
  }
208
  }
209
 
@@ -218,9 +340,9 @@ class Boldgrid_Backup_Admin_Backup_Dir {
218
  *
219
  * Returns backup_dir/$file.
220
  *
221
- * @since 1.5.4
222
  *
223
- * @param string $file
224
  * @return string
225
  */
226
  public function get_path_to( $file ) {
@@ -228,6 +350,24 @@ class Boldgrid_Backup_Admin_Backup_Dir {
228
  return Boldgrid_Backup_Admin_Utility::trailingslashit( $backup_dir ) . $file;
229
  }
230
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
231
  /**
232
  * Set our backup directory.
233
  *
@@ -236,6 +376,8 @@ class Boldgrid_Backup_Admin_Backup_Dir {
236
  *
237
  * @since 1.5.2
238
  *
 
 
239
  * @return mixed Backup directory on success, false on failure.
240
  */
241
  public function guess_and_set() {
@@ -253,9 +395,14 @@ class Boldgrid_Backup_Admin_Backup_Dir {
253
  /*
254
  * Create the directory and all applicable files needed within for security,
255
  * such as .htaccess / etc.
 
 
 
256
  */
257
- $possible_dir .= DIRECTORY_SEPARATOR . 'boldgrid_backup';
 
258
  $backup_directory = $this->create( $possible_dir );
 
259
  if ( ! $backup_directory ) {
260
  continue;
261
  }
@@ -276,7 +423,10 @@ class Boldgrid_Backup_Admin_Backup_Dir {
276
 
277
  $this->set( $backup_directory );
278
 
 
 
279
  $settings['backup_directory'] = $backup_directory;
 
280
  $this->core->settings->save( $settings );
281
 
282
  return $this->backup_directory;
@@ -298,7 +448,7 @@ class Boldgrid_Backup_Admin_Backup_Dir {
298
  *
299
  * @since 1.5.1
300
  *
301
- * @param string $file
302
  * @param bool $use_abspath Bool determining whether or not to use the
303
  * backup directory in its absolute path.
304
  * @return bool
@@ -316,7 +466,9 @@ class Boldgrid_Backup_Admin_Backup_Dir {
316
  *
317
  * Make sure it exists, it's writable, etc.
318
  *
319
- * @param string $backup_dir
 
 
320
  * @return bool
321
  */
322
  public function is_valid( $backup_dir ) {
@@ -328,23 +480,52 @@ class Boldgrid_Backup_Admin_Backup_Dir {
328
  $perms = $this->core->test->extensive_dir_test( $backup_dir );
329
 
330
  if ( ! $perms['exists'] ) {
331
- $this->errors[] = sprintf( __( 'Backup Directory does not exists: %1$s', 'boldgrid-backup' ), $backup_dir );
 
 
 
 
332
  }
333
 
334
  if ( ! $perms['read'] ) {
335
- $this->errors[] = sprintf( __( 'Backup Directory does not have read permission: %1$s', 'boldgrid-backup' ), $backup_dir );
 
 
 
 
336
  }
337
 
338
  if ( ! $perms['rename'] ) {
339
- $this->errors[] = sprintf( __( 'Backup Directory does not have permission to rename files: %1$s', 'boldgrid-backup' ), $backup_dir );
 
 
 
 
 
 
 
340
  }
341
 
342
  if ( ! $perms['delete'] ) {
343
- $this->errors[] = sprintf( __( 'Backup Directory does not have permission to delete files: %1$s', 'boldgrid-backup' ), $backup_dir );
 
 
 
 
 
 
 
344
  }
345
 
346
  if ( ! $perms['dirlist'] ) {
347
- $this->errors[] = sprintf( __( 'Backup Directory does not have permission to retrieve directory listing: %1$s', 'boldgrid-backup' ), $backup_dir );
 
 
 
 
 
 
 
348
  }
349
 
350
  /*
@@ -354,11 +535,15 @@ class Boldgrid_Backup_Admin_Backup_Dir {
354
  * In the above example, we will create /home/user/.htaccess to prevent
355
  * browsing of backups, and this would prevent all traffic to the ABSPATH.
356
  */
357
- $backup_dir = Boldgrid_Backup_Admin_Utility::trailingslashit( $backup_dir );
358
  $abspath_in_dir = 0 === strpos( ABSPATH, $backup_dir );
359
  if ( $abspath_in_dir ) {
360
  $this->errors[] = sprintf(
361
- __( 'Your <strong>WordPress directory</strong> <em>%1$s</em> cannot be within your <strong>backup directory</strong> %2$s.', 'boldgrid-backup' ),
 
 
 
 
362
  ABSPATH,
363
  $backup_dir
364
  );
@@ -371,6 +556,10 @@ class Boldgrid_Backup_Admin_Backup_Dir {
371
  * Even in a Windows environment, wp_filesystem->dirlist retrieves paths
372
  * with a / instead of \. Fix $without_abspath so we can properly check if
373
  * files are in the backup directory.
 
 
 
 
374
  */
375
  public function set( $backup_directory ) {
376
 
1
  <?php
2
  /**
3
+ * File: class-boldgrid-backup-admin-backup-dir.php
4
  *
5
+ * @link https://www.boldgrid.com
6
  * @since 1.5.1
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
  * @copyright BoldGrid.com
 
11
  * @author BoldGrid.com <wpb@boldgrid.com>
12
+ *
13
+ * phpcs:disable WordPress.VIP
14
  */
15
 
16
  /**
17
+ * Class: Boldgrid_Backup_Admin_Backup_Dir
18
  *
19
  * @since 1.5.1
20
  */
21
  class Boldgrid_Backup_Admin_Backup_Dir {
 
22
  /**
23
  * Backup directory.
24
  *
59
  *
60
  * @since 1.5.1
61
  *
62
+ * @param Boldgrid_Backup_Admin_Core $core Boldgrid_Backup_Admin_Core object.
63
  */
64
  public function __construct( $core ) {
65
  $this->core = $core;
66
  }
67
 
68
+ /**
69
+ * Determine if exec can write to our backup directory.
70
+ *
71
+ * @since 1.6.5
72
+ *
73
+ * @return bool
74
+ */
75
+ public function can_exec_write() {
76
+ $backup_dir = $this->get();
77
+
78
+ return $this->core->test->can_exec_write( $backup_dir );
79
+ }
80
+
81
  /**
82
  * Create our backup directory and necessary files.
83
  *
84
  * @since 1.5.1
85
  *
86
+ * @param string $backup_dir Backup directory path.
87
  * @return mixed False on failure, trailingslashed $backup_dir on success.
88
  */
89
  public function create( $backup_dir ) {
90
  $check_permissions = __( 'Please ensure your backup directory exists and has the proper read, write, and modify permissions.', 'boldgrid-backup' );
91
 
92
+ // translators: 1: File path, 2: Informational message above ($check_permissions).
93
  $cannot_create = __( 'Unable to create necessary file: %1$s<br />%2$s', 'boldgrid-backup' );
94
+
95
+ // translators: 1: File path, 2: Informational message above ($check_permissions).
96
  $cannot_write = __( 'Unable to write to necessary file: %1$s<br />%2$s', 'boldgrid-backup' );
97
 
98
  $backup_dir = untrailingslashit( $backup_dir );
99
 
100
+ $logs_dir = $this->get_logs_dir( $backup_dir );
101
+
102
+ $htaccess_path = $backup_dir . DIRECTORY_SEPARATOR . '.htaccess';
103
  $index_html_path = $backup_dir . DIRECTORY_SEPARATOR . 'index.html';
104
+ $index_php_path = $backup_dir . DIRECTORY_SEPARATOR . 'index.php';
105
 
106
  $files = array(
107
  array(
108
+ 'type' => 'dir',
109
+ 'path' => $backup_dir,
110
  'chmod' => 0700,
111
  ),
112
  array(
113
+ 'type' => 'dir',
114
+ 'path' => $logs_dir,
115
+ 'chmod' => 0700,
116
+ ),
117
+ array(
118
+ 'type' => 'file',
119
+ 'path' => $htaccess_path,
120
  'contents' => "<IfModule mod_access_compat.c>\nOrder Allow,Deny\nDeny from all\n</IfModule>\nOptions -Indexes\n",
121
  ),
122
  array(
143
  switch ( $file['type'] ) {
144
  case 'dir':
145
  if ( ! $this->core->wp_filesystem->exists( $file['path'] ) ) {
146
+ $chmod = ! empty( $file['chmod'] ) ? $file['chmod'] : false;
147
  $created = $this->core->wp_filesystem->mkdir( $file['path'], $chmod );
148
  if ( ! $created ) {
149
  $this->errors[] = sprintf( $cannot_create, $file['path'], $check_permissions );
174
  return $backup_dir;
175
  }
176
 
177
+ /**
178
+ * Get a directory listing of our backup directory.
179
+ *
180
+ * @since 1.7.0
181
+ *
182
+ * @return array
183
+ */
184
+ public function dirlist() {
185
+ $this->get();
186
+
187
+ $files = array();
188
+
189
+ if ( $this->backup_directory ) {
190
+ $files = $this->core->wp_filesystem->dirlist( $this->backup_directory );
191
+ }
192
+
193
+ return $files;
194
+ }
195
+
196
+ /**
197
+ * Find files in backup directory where filename contains search string.
198
+ *
199
+ * @since 1.7.0
200
+ *
201
+ * @param string $search The search string / needle.
202
+ * @return array
203
+ */
204
+ public function dirlist_containing( $search ) {
205
+ $matches = array();
206
+ $dirlist = $this->dirlist();
207
+
208
+ // Find all the files including $search in their filename.
209
+ foreach ( $dirlist as $filename => $filedata ) {
210
+ if ( false !== strpos( $filename, $search ) ) {
211
+ $matches[ $filename ] = $filedata;
212
+ }
213
+ }
214
+
215
+ return $matches;
216
+ }
217
+
218
  /**
219
  * Get and return the backup directory path.
220
  *
231
 
232
  // If we have it in the settings, then use it.
233
  $settings = $this->core->settings->get_settings();
234
+ if ( ! empty( $settings['backup_directory'] ) &&
235
+ $this->core->wp_filesystem->is_writable( $settings['backup_directory'] ) ) {
236
+ $this->set( $settings['backup_directory'] );
237
+
238
  return $this->backup_directory;
239
  }
240
 
241
  return $this->guess_and_set();
242
  }
243
 
244
+ /**
245
+ * Get the directory to our logs folder.
246
+ *
247
+ * @since 1.12.5
248
+ *
249
+ * @param string $backup_dir Backup directory path.
250
+ * @return string The filepath to the logs directory.
251
+ */
252
+ public function get_logs_dir( $backup_dir = null ) {
253
+ $backup_dir = ! empty( $backup_dir ) ? $backup_dir : $this->get();
254
+
255
+ $logs_dir = '';
256
+
257
+ // When looking for an existing logs dir, we'll be looking for a dir beginning with this prefix.
258
+ $prefix = 'logs-' . $this->core->get_backup_identifier() . '-';
259
+
260
+ /*
261
+ * Check to see if we already have a logs directory created.
262
+ *
263
+ * We'll do this by getting a dir list of the backup directory, and then looking for a folder
264
+ * named in this format: logs-[BACKUP IDENTIFIER]-[16 CHARS]
265
+ */
266
+
267
+ // Get directory listing of backup directory.
268
+ $dirlist = $this->core->wp_filesystem->dirlist( $backup_dir );
269
+ $dirlist = is_array( $dirlist ) ? $dirlist : array();
270
+
271
+ // Look for a logs directory.
272
+ foreach ( $dirlist as $file ) {
273
+ if ( 'd' !== $file['type'] ) {
274
+ continue;
275
+ }
276
+
277
+ preg_match( '/^' . $prefix . '[a-zA-Z0-9]{16}$/', $file['name'], $matches );
278
+
279
+ if ( ! empty( $matches ) ) {
280
+ $logs_dir = Boldgrid_Backup_Admin_Utility::trailingslashit( $backup_dir ) . $matches[0];
281
+ break;
282
+ }
283
+ }
284
+
285
+ /*
286
+ * If we need to, create our log directory.
287
+ *
288
+ * We're using the 16 random characters at the end of the folder name to stay consistent with
289
+ * Total Upkeep Premium.
290
+ *
291
+ * @link https://github.com/BoldGrid/boldgrid-backup-premium/blob/ea33c7fc1b9a184d17ee50b2e61e665967595e85/admin/class-boldgrid-backup-premium-admin-historical.php#L165-L175
292
+ */
293
+ if ( empty( $logs_dir ) ) {
294
+ $logs_dir = $backup_dir . DIRECTORY_SEPARATOR . $prefix . substr( md5( time() ), -16 );
295
+ }
296
+
297
+ return $logs_dir;
298
+ }
299
+
300
  /**
301
  * Get an array of possible backup directories.
302
  *
310
  $dirs[] = $this->core->config->get_home_directory();
311
 
312
  if ( $this->core->test->is_windows() ) {
313
+ // Example: "C:\Users\user\AppData\Local".
314
  $dirs[] = $this->core->config->get_home_directory() . DIRECTORY_SEPARATOR . 'AppData' . DIRECTORY_SEPARATOR . 'Local';
315
 
316
  if ( ! empty( $_SERVER['DOCUMENT_ROOT'] ) ) {
325
  * there won't be downloadable.
326
  */
327
  $app_data = $_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . 'App_Data';
328
+ $dirs[] = str_replace( '\\\\', '\\', $app_data );
329
  }
330
  }
331
 
340
  *
341
  * Returns backup_dir/$file.
342
  *
343
+ * @since 1.6.0
344
  *
345
+ * @param string $file Filename.
346
  * @return string
347
  */
348
  public function get_path_to( $file ) {
350
  return Boldgrid_Backup_Admin_Utility::trailingslashit( $backup_dir ) . $file;
351
  }
352
 
353
+ /**
354
+ * Generate a random string of characters for a directory suffix.
355
+ *
356
+ * @since 1.11.7
357
+ *
358
+ * @return string
359
+ */
360
+ public function generate_suffix() {
361
+ $suffix = '';
362
+ $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
363
+
364
+ for ( $i = 0; $i < 12; $i++ ) {
365
+ $suffix .= $chars[ mt_rand( 0, strlen( $chars ) - 1 ) ];
366
+ }
367
+
368
+ return $suffix;
369
+ }
370
+
371
  /**
372
  * Set our backup directory.
373
  *
376
  *
377
  * @since 1.5.2
378
  *
379
+ * @see self::generate_suffix()
380
+ *
381
  * @return mixed Backup directory on success, false on failure.
382
  */
383
  public function guess_and_set() {
395
  /*
396
  * Create the directory and all applicable files needed within for security,
397
  * such as .htaccess / etc.
398
+ *
399
+ * If directory is the wp-content directory, add additional random characters so that
400
+ * the backup directory is not simply wp-content/boldgrid_backup.
401
  */
402
+ $append = WP_CONTENT_DIR !== $possible_dir ? '' : '_' . $this->generate_suffix();
403
+ $possible_dir .= DIRECTORY_SEPARATOR . 'boldgrid_backup' . $append;
404
  $backup_directory = $this->create( $possible_dir );
405
+
406
  if ( ! $backup_directory ) {
407
  continue;
408
  }
423
 
424
  $this->set( $backup_directory );
425
 
426
+ $settings = $this->core->settings->get_settings();
427
+
428
  $settings['backup_directory'] = $backup_directory;
429
+
430
  $this->core->settings->save( $settings );
431
 
432
  return $this->backup_directory;
448
  *
449
  * @since 1.5.1
450
  *
451
+ * @param string $file Filename.
452
  * @param bool $use_abspath Bool determining whether or not to use the
453
  * backup directory in its absolute path.
454
  * @return bool
466
  *
467
  * Make sure it exists, it's writable, etc.
468
  *
469
+ * @since 1.5.1
470
+ *
471
+ * @param string $backup_dir Backup directory path.
472
  * @return bool
473
  */
474
  public function is_valid( $backup_dir ) {
480
  $perms = $this->core->test->extensive_dir_test( $backup_dir );
481
 
482
  if ( ! $perms['exists'] ) {
483
+ $this->errors[] = sprintf(
484
+ // translators: 1: Backup directory path.
485
+ __( 'Backup Directory does not exists: %1$s', 'boldgrid-backup' ),
486
+ $backup_dir
487
+ );
488
  }
489
 
490
  if ( ! $perms['read'] ) {
491
+ $this->errors[] = sprintf(
492
+ // translators: 1: Backup directory path.
493
+ __( 'Backup Directory does not have read permission: %1$s', 'boldgrid-backup' ),
494
+ $backup_dir
495
+ );
496
  }
497
 
498
  if ( ! $perms['rename'] ) {
499
+ $this->errors[] = sprintf(
500
+ // translators: 1: Backup directory path.
501
+ __(
502
+ 'Backup Directory does not have permission to rename files: %1$s',
503
+ 'boldgrid-backup'
504
+ ),
505
+ $backup_dir
506
+ );
507
  }
508
 
509
  if ( ! $perms['delete'] ) {
510
+ $this->errors[] = sprintf(
511
+ // translators: 1: Backup directory path.
512
+ __(
513
+ 'Backup Directory does not have permission to delete files: %1$s',
514
+ 'boldgrid-backup'
515
+ ),
516
+ $backup_dir
517
+ );
518
  }
519
 
520
  if ( ! $perms['dirlist'] ) {
521
+ $this->errors[] = sprintf(
522
+ // translators: 1: Backup directory path.
523
+ __(
524
+ 'Backup Directory does not have permission to retrieve directory listing: %1$s',
525
+ 'boldgrid-backup'
526
+ ),
527
+ $backup_dir
528
+ );
529
  }
530
 
531
  /*
535
  * In the above example, we will create /home/user/.htaccess to prevent
536
  * browsing of backups, and this would prevent all traffic to the ABSPATH.
537
  */
538
+ $backup_dir = Boldgrid_Backup_Admin_Utility::trailingslashit( $backup_dir );
539
  $abspath_in_dir = 0 === strpos( ABSPATH, $backup_dir );
540
  if ( $abspath_in_dir ) {
541
  $this->errors[] = sprintf(
542
+ // translators: 1: WordPress installation directory path, 2: Backup directory path.
543
+ __(
544
+ 'Your <strong>WordPress directory</strong> <em>%1$s</em> cannot be within your <strong>backup directory</strong> %2$s.',
545
+ 'boldgrid-backup'
546
+ ),
547
  ABSPATH,
548
  $backup_dir
549
  );
556
  * Even in a Windows environment, wp_filesystem->dirlist retrieves paths
557
  * with a / instead of \. Fix $without_abspath so we can properly check if
558
  * files are in the backup directory.
559
+ *
560
+ * @since 1.5.2
561
+ *
562
+ * @param string $backup_directory Backup directory.
563
  */
564
  public function set( $backup_directory ) {
565
 
admin/class-boldgrid-backup-admin-cli.php ADDED
@@ -0,0 +1,242 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File: class-boldgrid-backup-admin-cli.php
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.8.0
7
+ *
8
+ * @package Boldgrid_Backup
9
+ * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
+ * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
+ */
14
+
15
+ /**
16
+ * Class: Boldgrid_Backup_Admin_Cli
17
+ *
18
+ * @since 1.8.0
19
+ */
20
+ class Boldgrid_Backup_Admin_Cli {
21
+ /**
22
+ * Available execution functions.
23
+ *
24
+ * @since 1.8.0
25
+ * @access private
26
+ * @static
27
+ * @var array
28
+ */
29
+ private static $available_exec_functions;
30
+
31
+ /**
32
+ * Get the available execution functions.
33
+ *
34
+ * @since 1.8.0
35
+ * @static
36
+ *
37
+ * @see Boldgrid_Backup_Admin_Test::is_php_safemode()
38
+ *
39
+ * @return array
40
+ */
41
+ public static function get_execution_functions() {
42
+ // If the array already has elements, then return the array.
43
+ if ( self::$available_exec_functions ) {
44
+ return self::$available_exec_functions;
45
+ }
46
+
47
+ // If PHP is in safe mode, then return an empty array.
48
+ if ( ini_get( 'safe_mode' ) ) {
49
+ return array();
50
+ }
51
+
52
+ // Get the PHP disable_functions list.
53
+ $disabled = explode( ',', ini_get( 'disable_functions' ) );
54
+
55
+ // Make an array of execution functions.
56
+ $exec_functions = array(
57
+ 'popen',
58
+ 'proc_open',
59
+ 'exec',
60
+ 'shell_exec',
61
+ 'passthru',
62
+ 'system',
63
+ );
64
+
65
+ // Iterate through the array and remove disabled functions.
66
+ foreach ( $exec_functions as $key => $exec_function ) {
67
+ if ( in_array( $exec_function, $disabled, true ) ) {
68
+ unset( $exec_functions[ $key ] );
69
+ }
70
+ }
71
+
72
+ // Save the array of execution functions.
73
+ self::$available_exec_functions = $exec_functions;
74
+
75
+ return $exec_functions;
76
+ }
77
+
78
+ /**
79
+ * Call an execute command.
80
+ *
81
+ * To be used by Boldgrid_Backup_Admin_Core::execute_command() and some others.
82
+ *
83
+ * @since 1.8.0
84
+ *
85
+ * @param string $command A command string to be executed.
86
+ * @param bool $success Success or failure of the operation, passed back.
87
+ * @param int $return_var If present, the return_var, passed back.
88
+ * @return string Returns the command output
89
+ */
90
+ public static function call_command( $command, &$success = false, &$return_var = 0 ) {
91
+ $success = false;
92
+
93
+ // phpcs:disable WordPress.PHP.DiscouragedPHPFunctions, WordPress.WP.AlternativeFunctions
94
+
95
+ // Test getting output using available execution functions, until one is successful.
96
+ $available_exec_functions = self::get_execution_functions();
97
+
98
+ foreach ( $available_exec_functions as $exec_function ) {
99
+ switch ( $exec_function ) {
100
+ case 'exec':
101
+ exec( $command, $out, $return_var );
102
+
103
+ // If the exit status is int(0), then it was successful.
104
+ if ( 0 === $return_var ) {
105
+ $output = implode( PHP_EOL, $out );
106
+
107
+ $success = true;
108
+
109
+ break 2;
110
+ }
111
+
112
+ break 2;
113
+
114
+ case 'passthru':
115
+ // If output buffering is enabled, then use passthru.
116
+ if ( ob_start() ) {
117
+ passthru( $command, $return_var );
118
+
119
+ // Get current buffer contents and delete current output buffer.
120
+ $output = ob_get_clean();
121
+
122
+ // If the exit status is int(0), then it was successful.
123
+ if ( 0 === $return_var ) {
124
+ $success = true;
125
+
126
+ break 2;
127
+ }
128
+ }
129
+
130
+ break 2;
131
+
132
+ case 'popen':
133
+ $handle = popen( $command, 'r' );
134
+
135
+ $output = fread( $handle, 4096 );
136
+
137
+ /*
138
+ * If handle is a valid resource, then check for success.
139
+ */
140
+ if ( false !== $handle ) {
141
+ // Close the process handle and get the return status.
142
+ $return_var = pclose( $handle );
143
+
144
+ // If the exit status is int(0), then it was successful.
145
+ if ( 0 === $return_var ) {
146
+ $success = true;
147
+
148
+ break 2;
149
+ }
150
+ }
151
+
152
+ break 2;
153
+
154
+ case 'proc_open':
155
+ // Create the descriptor spec array.
156
+ $descriptorspec = array(
157
+ 0 => array(
158
+ 'pipe',
159
+ 'r',
160
+ ),
161
+ 1 => array(
162
+ 'pipe',
163
+ 'w',
164
+ ),
165
+ 2 => array(
166
+ 'pipe',
167
+ 'w',
168
+ ),
169
+ );
170
+
171
+ // Open a process handle.
172
+ $handle = proc_open( $command, $descriptorspec, $pipes );
173
+
174
+ if ( is_resource( $handle ) ) {
175
+ // Close unused pipes[0].
176
+ fclose( $pipes[0] );
177
+
178
+ // Read output from pipes[1].
179
+ $output = stream_get_contents( $pipes[1] );
180
+
181
+ // Close pipes[1].
182
+ fclose( $pipes[1] );
183
+
184
+ // Close unused pipes[0].
185
+ fclose( $pipes[2] );
186
+
187
+ // Close the process handle and get the return status.
188
+ $return_var = proc_close( $handle );
189
+
190
+ // If the exit status is int(0), then it was successful.
191
+ if ( 0 === $return_var ) {
192
+ $success = true;
193
+
194
+ break 2;
195
+ }
196
+ }
197
+
198
+ break 2;
199
+
200
+ case 'shell_exec':
201
+ $output = shell_exec( $command );
202
+
203
+ if ( false === strpos( $output, 'command not found' ) ) {
204
+ $success = true;
205
+
206
+ break 2;
207
+ }
208
+
209
+ break 2;
210
+
211
+ case 'system':
212
+ // If output buffering is enabled, then use system.
213
+ if ( ob_start() ) {
214
+ system( $command, $return_var );
215
+
216
+ // Get current buffer contents and delete current output buffer.
217
+ $output = ob_get_clean();
218
+
219
+ // If the exit status is int(0), then it was successful.
220
+ if ( 0 === $return_var ) {
221
+ $success = true;
222
+
223
+ break 2;
224
+ }
225
+ }
226
+
227
+ break 2;
228
+
229
+ default:
230
+ break;
231
+ }
232
+ }
233
+
234
+ // phpcs:enable WordPress.PHP.DiscouragedPHPFunctions, WordPress.WP.AlternativeFunctions
235
+
236
+ if ( ! empty( $output ) ) {
237
+ $output = trim( $output );
238
+ }
239
+
240
+ return $output;
241
+ }
242
+ }
admin/class-boldgrid-backup-admin-compressor.php CHANGED
@@ -1,24 +1,23 @@
1
  <?php
2
  /**
3
- * Compressor.
4
  *
5
- * @link http://www.boldgrid.com
6
  * @since 1.5.1
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
- * @copyright BoldGrid.com
11
  * @version $Id$
12
- * @author BoldGrid.com <wpb@boldgrid.com>
13
  */
14
 
15
  /**
16
- * Base Compressor class for which other compressors extend.
17
  *
18
  * @since 1.5.1
19
  */
20
  class Boldgrid_Backup_Admin_Compressor {
21
-
22
  /**
23
  * An instance of Boldgrid_Backup_Admin_Core.
24
  *
@@ -42,7 +41,7 @@ class Boldgrid_Backup_Admin_Compressor {
42
  *
43
  * @global $wp_filesystem
44
  *
45
- * @param Boldgrid_Backup_Admin_Core $core
46
  */
47
  public function __construct( $core ) {
48
  global $wp_filesystem;
@@ -58,7 +57,9 @@ class Boldgrid_Backup_Admin_Compressor {
58
  *
59
  * @since 1.5.1
60
  *
61
- * @param array $filelist See Boldgrid_Backup_Admin_Filelist::get_total_size
 
 
62
  * @param array $info {
63
  * An array of data about the backup archive we are generating.
64
  *
@@ -73,4 +74,54 @@ class Boldgrid_Backup_Admin_Compressor {
73
  public function archive_files( $filelist, &$info ) {
74
  return false;
75
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76
  }
1
  <?php
2
  /**
3
+ * File: class-boldgrid-backup-admin-compressor.php
4
  *
5
+ * @link https://www.boldgrid.com
6
  * @since 1.5.1
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
  * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
  */
14
 
15
  /**
16
+ * Class: Boldgrid_Backup_Admin_Compressor
17
  *
18
  * @since 1.5.1
19
  */
20
  class Boldgrid_Backup_Admin_Compressor {
 
21
  /**
22
  * An instance of Boldgrid_Backup_Admin_Core.
23
  *
41
  *
42
  * @global $wp_filesystem
43
  *
44
+ * @param Boldgrid_Backup_Admin_Core $core Boldgrid_Backup_Admin_Core object.
45
  */
46
  public function __construct( $core ) {
47
  global $wp_filesystem;
57
  *
58
  * @since 1.5.1
59
  *
60
+ * @see Boldgrid_Backup_Admin_Filelist::get_total_size()
61
+ *
62
+ * @param array $filelist A file list.
63
  * @param array $info {
64
  * An array of data about the backup archive we are generating.
65
  *
74
  public function archive_files( $filelist, &$info ) {
75
  return false;
76
  }
77
+
78
+ /**
79
+ * Determine whether or not this compressor is available.
80
+ *
81
+ * @since 1.13.0
82
+ *
83
+ * @param string $compressor A compressor.
84
+ * @return bool True if is available.
85
+ */
86
+ public function is_available() {
87
+ return in_array( $this->key, $this->core->compressors->get_available(), true );
88
+ }
89
+
90
+ /**
91
+ * Determine whether or not the given compressor is the default.
92
+ *
93
+ * @since 1.13.0
94
+ *
95
+ * @param string $compressor A compressor.
96
+ * @return bool True if is default compressor.
97
+ */
98
+ public function is_default() {
99
+ return $this->key === $this->core->compressors->get_default();
100
+ }
101
+
102
+ /**
103
+ * Determine whether or not the given compressor is the one saved in the settings.
104
+ *
105
+ * @since 1.13.0
106
+ *
107
+ * @param string $compressor A compressor.
108
+ * @return bool True if compressor is saved in settings.
109
+ */
110
+ public function is_saved_compressor() {
111
+ return $this->key === $this->core->settings->get_setting( 'compressor' );
112
+ }
113
+
114
+ /**
115
+ * Whether or not this compressor should be selected if it is in an array of available compressors.
116
+ *
117
+ * Used in a <select> element.
118
+ *
119
+ * @return bool
120
+ */
121
+ public function maybe_selected_compressor() {
122
+ $setting = $this->core->settings->get_setting( 'compressor' );
123
+
124
+ return $this->is_saved_compressor() ||
125
+ ( empty( $setting ) && $this->is_default() );
126
+ }
127
  }
admin/class-boldgrid-backup-admin-compressors.php CHANGED
@@ -1,24 +1,23 @@
1
  <?php
2
  /**
3
- * Compressors.
4
  *
5
- * @link http://www.boldgrid.com
6
  * @since 1.5.1
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
- * @copyright BoldGrid.com
11
  * @version $Id$
12
- * @author BoldGrid.com <wpb@boldgrid.com>
13
  */
14
 
15
  /**
16
- * BoldGrid Backup Admin Compressors class.
17
  *
18
  * @since 1.5.1
19
  */
20
  class Boldgrid_Backup_Admin_Compressors {
21
-
22
  /**
23
  * The core class object.
24
  *
@@ -29,10 +28,12 @@ class Boldgrid_Backup_Admin_Compressors {
29
  private $core;
30
 
31
  /**
32
- * The default compressors.
33
  *
34
  * WordPress ships out of the box with pcl_zip.
35
  *
 
 
36
  * @since 1.5.1
37
  * @access public
38
  * @var string
@@ -53,7 +54,7 @@ class Boldgrid_Backup_Admin_Compressors {
53
  * If ZipArchive is available, make it the default. Tests show it is
54
  * superior to PclZip.
55
  */
56
- if ( class_exists( 'Boldgrid_Backup_Admin_Compressor_Php_Zip' ) && Boldgrid_Backup_Admin_Compressor_Php_Zip::is_available() ) {
57
  $this->default = 'php_zip';
58
  }
59
  }
@@ -66,7 +67,7 @@ class Boldgrid_Backup_Admin_Compressors {
66
  * @return string
67
  */
68
  public function get() {
69
- $settings = $this->core->settings->get_settings();
70
  $available_compressors = $this->get_available();
71
 
72
  /*
@@ -92,6 +93,36 @@ class Boldgrid_Backup_Admin_Compressors {
92
  return $this->core->config->get_available_compressors();
93
  }
94
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
  /**
96
  * Set php_zip (ZipArchive) as our compressor/extractor.
97
  *
@@ -100,10 +131,10 @@ class Boldgrid_Backup_Admin_Compressors {
100
  * @return bool True on success.
101
  */
102
  public function set_php_zip() {
103
- if ( Boldgrid_Backup_Admin_Compressor_Php_Zip::is_available() ) {
104
- $settings = $this->core->settings->get_settings();
105
  $settings['compressor'] = 'php_zip';
106
- $settings['extractor'] = 'php_zip';
107
  return $this->core->settings->save( $settings );
108
  }
109
 
1
  <?php
2
  /**
3
+ * File: class-boldgrid-backup-admin-compressors.php
4
  *
5
+ * @link https://www.boldgrid.com
6
  * @since 1.5.1
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
  * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
  */
14
 
15
  /**
16
+ * File: Boldgrid_Backup_Admin_Compressors
17
  *
18
  * @since 1.5.1
19
  */
20
  class Boldgrid_Backup_Admin_Compressors {
 
21
  /**
22
  * The core class object.
23
  *
28
  private $core;
29
 
30
  /**
31
+ * The default compressor.
32
  *
33
  * WordPress ships out of the box with pcl_zip.
34
  *
35
+ * In the contructor, if php_zip is available, it will be set as the default.
36
+ *
37
  * @since 1.5.1
38
  * @access public
39
  * @var string
54
  * If ZipArchive is available, make it the default. Tests show it is
55
  * superior to PclZip.
56
  */
57
+ if ( class_exists( 'Boldgrid_Backup_Admin_Compressor_Php_Zip' ) && Boldgrid_Backup_Admin_Compressor_Php_Zip::is_extension_available() ) {
58
  $this->default = 'php_zip';
59
  }
60
  }
67
  * @return string
68
  */
69
  public function get() {
70
+ $settings = $this->core->settings->get_settings();
71
  $available_compressors = $this->get_available();
72
 
73
  /*
93
  return $this->core->config->get_available_compressors();
94
  }
95
 
96
+ /**
97
+ * Get the default compressor.
98
+ *
99
+ * @since 1.13.0
100
+ *
101
+ * @return string
102
+ */
103
+ public function get_default() {
104
+ return $this->default;
105
+ }
106
+
107
+ /**
108
+ * Get our compressor object.
109
+ *
110
+ * @since 1.13.0
111
+ *
112
+ * @param string $compressor The id of a compressor to get.
113
+ * @return mixed
114
+ */
115
+ public function get_object( $compressor ) {
116
+ switch ( $compressor ) {
117
+ case 'pcl_zip':
118
+ return new Boldgrid_Backup_Admin_Compressor_Pcl_Zip( $this->core );
119
+ case 'php_zip':
120
+ return new Boldgrid_Backup_Admin_Compressor_Php_Zip( $this->core );
121
+ case 'system_zip':
122
+ return new Boldgrid_Backup_Admin_Compressor_System_Zip( $this->core );
123
+ }
124
+ }
125
+
126
  /**
127
  * Set php_zip (ZipArchive) as our compressor/extractor.
128
  *
131
  * @return bool True on success.
132
  */
133
  public function set_php_zip() {
134
+ if ( Boldgrid_Backup_Admin_Compressor_Php_Zip::is_extension_available() ) {
135
+ $settings = $this->core->settings->get_settings();
136
  $settings['compressor'] = 'php_zip';
137
+ $settings['extractor'] = 'php_zip';
138
  return $this->core->settings->save( $settings );
139
  }
140
 
admin/class-boldgrid-backup-admin-config.php CHANGED
@@ -1,19 +1,21 @@
1
  <?php
2
  /**
3
- * The admin-specific configuration class for the plugin
4
  *
5
- * @link http://www.boldgrid.com
6
  * @since 1.0
7
  *
8
- * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
- * @copyright BoldGrid.com
11
- * @version $Id$
12
- * @author BoldGrid.com <wpb@boldgrid.com>
13
  */
14
 
 
 
15
  /**
16
- * BoldGrid Backup admin configuration class.
17
  *
18
  * @since 1.0
19
  */
@@ -75,7 +77,7 @@ class Boldgrid_Backup_Admin_Config {
75
  /**
76
  * Whether or not the premium plugin is activated.
77
  *
78
- * @since 1.5.4
79
  * @access public
80
  * @var bool
81
  */
@@ -85,7 +87,7 @@ class Boldgrid_Backup_Admin_Config {
85
  * Whether or not we have a premium license and the premium extension is
86
  * installed.
87
  *
88
- * @since 1.5.4
89
  * @access public
90
  * @var bool
91
  */
@@ -95,7 +97,7 @@ class Boldgrid_Backup_Admin_Config {
95
  * Whether or not the premium extension is installed (we didn't say activated,
96
  * just installed, the files exist on the server).
97
  *
98
- * @since 1.5.4
99
  * @access public
100
  * @var bool
101
  */
@@ -133,7 +135,7 @@ class Boldgrid_Backup_Admin_Config {
133
  }
134
 
135
  if ( class_exists( '\Boldgrid\Library\Library\License' ) ) {
136
- $this->license = new \Boldgrid\Library\Library\License();
137
  $this->is_premium = $this->license->isPremium( 'boldgrid-backup' );
138
  }
139
 
@@ -166,7 +168,7 @@ class Boldgrid_Backup_Admin_Config {
166
  } elseif ( $this->core->test->is_windows() ) {
167
  // Windows.
168
  $home_drive = ( ! empty( $_SERVER['HOMEDRIVE'] ) ? $_SERVER['HOMEDRIVE'] : null );
169
- $home_path = ( ! empty( $_SERVER['HOMEPATH'] ) ? $_SERVER['HOMEPATH'] : null );
170
 
171
  if ( ! ( empty( $home_drive ) || empty( $home_path ) ) ) {
172
  $home_dir = $home_drive . $home_path;
@@ -179,7 +181,7 @@ class Boldgrid_Backup_Admin_Config {
179
  } else {
180
  // Linux. Try posix_getpwuid and posix_getuid.
181
  if ( function_exists( 'posix_getuid' ) && function_exists( 'posix_getpwuid' ) ) {
182
- $user = posix_getpwuid( posix_getuid() );
183
  $home_dir = ( ! empty( $user['dir'] ) ? $user['dir'] : null );
184
  }
185
 
@@ -232,6 +234,8 @@ class Boldgrid_Backup_Admin_Config {
232
  /**
233
  * Get is_premium.
234
  *
 
 
235
  * @since 1.3.1
236
  *
237
  * @return bool
@@ -272,10 +276,15 @@ class Boldgrid_Backup_Admin_Config {
272
  */
273
  public function set_lang() {
274
  $this->lang = array(
275
- 'website_size' => esc_html__( 'Website Size:', 'boldgrid-backup' ),
276
- 'database_size' => esc_html__( 'Database Size:', 'boldgrid-backup' ),
277
- 'of' => esc_html__( 'of', 'boldgrid-backup' ),
278
- 'xmark' => '&#10007;',
 
 
 
 
 
279
  );
280
  }
281
 
@@ -351,25 +360,22 @@ class Boldgrid_Backup_Admin_Config {
351
  * @access private
352
  *
353
  * @param string $compressor A name of a compressor.
354
- * @return null
355
  */
356
  private function add_compressor( $compressor = null ) {
357
  if ( ! empty( $compressor ) &&
358
  ! in_array( $compressor, $this->available_compressors, true ) ) {
359
  $this->available_compressors[] = $compressor;
360
  }
361
-
362
- return;
363
  }
364
 
365
  /**
366
  * Actions to take during the admin_init hook.
367
  *
368
- * @since 1.5.4
369
  */
370
  public function admin_init() {
371
  $relative_path = 'boldgrid-backup-premium/boldgrid-backup-premium.php';
372
- $abs_path = dirname( BOLDGRID_BACKUP_PATH ) . '/' . $relative_path;
373
 
374
  // Function is_plugin_active only available in and after admin_init.
375
  $this->is_premium_active = is_plugin_active( $relative_path );
@@ -407,6 +413,8 @@ class Boldgrid_Backup_Admin_Config {
407
  *
408
  * @since 1.0
409
  *
 
 
410
  * @return array
411
  */
412
  public function get_available_compressors() {
@@ -416,18 +424,18 @@ class Boldgrid_Backup_Admin_Config {
416
  }
417
 
418
  if ( ! class_exists( 'PclZip' ) ) {
419
- require_once( ABSPATH . '/wp-admin/includes/class-pclzip.php' );
420
  }
421
 
422
  // Initialize $this->available_compressors to an empty array.
423
  $this->available_compressors = array();
424
 
425
  // PHP zip (ZipArchive).
426
- if ( Boldgrid_Backup_Admin_Compressor_Php_Zip::is_available() ) {
427
  $this->add_compressor( 'php_zip' );
428
  }
429
 
430
- // PclZip
431
  if ( class_exists( 'PclZip' ) ) {
432
  $this->add_compressor( 'pcl_zip' );
433
  }
@@ -457,7 +465,8 @@ class Boldgrid_Backup_Admin_Config {
457
  }
458
 
459
  // System zip.
460
- if ( $this->core->execute_command( '/usr/bin/zip -v ' ) ) {
 
461
  $this->add_compressor( 'system_zip' );
462
  }
463
 
1
  <?php
2
  /**
3
+ * File: class-boldgrid-backup-admin-config.php
4
  *
5
+ * @link https://www.boldgrid.com
6
  * @since 1.0
7
  *
8
+ * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
+ * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
  */
14
 
15
+ // phpcs:disable WordPress.VIP
16
+
17
  /**
18
+ * Class: Boldgrid_Backup_Admin_Config
19
  *
20
  * @since 1.0
21
  */
77
  /**
78
  * Whether or not the premium plugin is activated.
79
  *
80
+ * @since 1.6.0
81
  * @access public
82
  * @var bool
83
  */
87
  * Whether or not we have a premium license and the premium extension is
88
  * installed.
89
  *
90
+ * @since 1.6.0
91
  * @access public
92
  * @var bool
93
  */
97
  * Whether or not the premium extension is installed (we didn't say activated,
98
  * just installed, the files exist on the server).
99
  *
100
+ * @since 1.6.0
101
  * @access public
102
  * @var bool
103
  */
135
  }
136
 
137
  if ( class_exists( '\Boldgrid\Library\Library\License' ) ) {
138
+ $this->license = new \Boldgrid\Library\Library\License();
139
  $this->is_premium = $this->license->isPremium( 'boldgrid-backup' );
140
  }
141
 
168
  } elseif ( $this->core->test->is_windows() ) {
169
  // Windows.
170
  $home_drive = ( ! empty( $_SERVER['HOMEDRIVE'] ) ? $_SERVER['HOMEDRIVE'] : null );
171
+ $home_path = ( ! empty( $_SERVER['HOMEPATH'] ) ? $_SERVER['HOMEPATH'] : null );
172
 
173
  if ( ! ( empty( $home_drive ) || empty( $home_path ) ) ) {
174
  $home_dir = $home_drive . $home_path;
181
  } else {
182
  // Linux. Try posix_getpwuid and posix_getuid.
183
  if ( function_exists( 'posix_getuid' ) && function_exists( 'posix_getpwuid' ) ) {
184
+ $user = posix_getpwuid( posix_getuid() );
185
  $home_dir = ( ! empty( $user['dir'] ) ? $user['dir'] : null );
186
  }
187
 
234
  /**
235
  * Get is_premium.
236
  *
237
+ * The is_premium class property is set within the constructor.
238
+ *
239
  * @since 1.3.1
240
  *
241
  * @return bool
276
  */
277
  public function set_lang() {
278
  $this->lang = array(
279
+ 'website_size' => esc_html__( 'Website Size:', 'boldgrid-backup' ),
280
+ 'database_size' => esc_html__( 'Database Size:', 'boldgrid-backup' ),
281
+ 'of' => esc_html__( 'of', 'boldgrid-backup' ),
282
+ 'xmark' => '&#10007;',
283
+ 'update' => esc_html__( 'Update', 'boldgrid-backup' ),
284
+ 'updating' => esc_html__( 'Updating...', 'boldgrid-backup' ),
285
+ 'updated' => esc_html__( 'Updated!', 'boldgrid-backup' ),
286
+ 'failed_to_update' => esc_html__( 'Failed to update: ', 'boldgrid-backup' ),
287
+ 'unknown_error' => esc_html__( 'Unknown error.', 'boldgrid-backup' ),
288
  );
289
  }
290
 
360
  * @access private
361
  *
362
  * @param string $compressor A name of a compressor.
 
363
  */
364
  private function add_compressor( $compressor = null ) {
365
  if ( ! empty( $compressor ) &&
366
  ! in_array( $compressor, $this->available_compressors, true ) ) {
367
  $this->available_compressors[] = $compressor;
368
  }
 
 
369
  }
370
 
371
  /**
372
  * Actions to take during the admin_init hook.
373
  *
374
+ * @since 1.6.0
375
  */
376
  public function admin_init() {
377
  $relative_path = 'boldgrid-backup-premium/boldgrid-backup-premium.php';
378
+ $abs_path = dirname( BOLDGRID_BACKUP_PATH ) . '/' . $relative_path;
379
 
380
  // Function is_plugin_active only available in and after admin_init.
381
  $this->is_premium_active = is_plugin_active( $relative_path );
413
  *
414
  * @since 1.0
415
  *
416
+ * @see Boldgrid_Backup_Admin_Core::execute_command()
417
+ *
418
  * @return array
419
  */
420
  public function get_available_compressors() {
424
  }
425
 
426
  if ( ! class_exists( 'PclZip' ) ) {
427
+ require_once ABSPATH . '/wp-admin/includes/class-pclzip.php';
428
  }
429
 
430
  // Initialize $this->available_compressors to an empty array.
431
  $this->available_compressors = array();
432
 
433
  // PHP zip (ZipArchive).
434
+ if ( Boldgrid_Backup_Admin_Compressor_Php_Zip::is_extension_available() ) {
435
  $this->add_compressor( 'php_zip' );
436
  }
437
 
438
+ // PclZip.
439
  if ( class_exists( 'PclZip' ) ) {
440
  $this->add_compressor( 'pcl_zip' );
441
  }
465
  }
466
 
467
  // System zip.
468
+ $system_zip_test = new Boldgrid_Backup_Admin_Compressor_System_Zip_Test( $this->core );
469
+ if ( $system_zip_test->run() ) {
470
  $this->add_compressor( 'system_zip' );
471
  }
472
 
admin/class-boldgrid-backup-admin-core-files.php CHANGED
@@ -1,28 +1,27 @@
1
  <?php
2
  /**
3
- * Core files.
4
  *
5
- * @link http://www.boldgrid.com
6
- * @since 1.5.4
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
- * @copyright BoldGrid.com
11
  * @version $Id$
12
- * @author BoldGrid.com <wpb@boldgrid.com>
13
  */
14
 
15
  /**
16
- * BoldGrid Backup Admin Core Files Class.
17
  *
18
- * @since 1.5.4
19
  */
20
  class Boldgrid_Backup_Admin_Core_Files {
21
-
22
  /**
23
  * The core class object.
24
  *
25
- * @since 1.5.4
26
  * @access private
27
  * @var Boldgrid_Backup_Admin_Core
28
  */
@@ -35,7 +34,7 @@ class Boldgrid_Backup_Admin_Core_Files {
35
  * # The wp-content folder is not included.
36
  * # .htaccess.bgb is included, but it is not a core file.
37
  *
38
- * @since 1.5.4
39
  * @access public
40
  * @var array
41
  */
@@ -65,7 +64,7 @@ class Boldgrid_Backup_Admin_Core_Files {
65
  /**
66
  * Constructor.
67
  *
68
- * @since 1.5.4
69
  *
70
  * @param Boldgrid_Backup_Admin_Core $core Core class object.
71
  */
@@ -76,9 +75,9 @@ class Boldgrid_Backup_Admin_Core_Files {
76
  /**
77
  * Determine if a given $file (relative to ABSPATH) is a core file.
78
  *
79
- * @since 1.5.4
80
  *
81
- * @param string $file
82
  * @return bool
83
  */
84
  public function is_core_file( $file ) {
@@ -94,5 +93,4 @@ class Boldgrid_Backup_Admin_Core_Files {
94
 
95
  return false;
96
  }
97
-
98
  }
1
  <?php
2
  /**
3
+ * File: class-boldgrid-backup-admin-core-files.php
4
  *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.6.0
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
  * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
  */
14
 
15
  /**
16
+ * Class: Boldgrid_Backup_Admin_Core_Files
17
  *
18
+ * @since 1.6.0
19
  */
20
  class Boldgrid_Backup_Admin_Core_Files {
 
21
  /**
22
  * The core class object.
23
  *
24
+ * @since 1.6.0
25
  * @access private
26
  * @var Boldgrid_Backup_Admin_Core
27
  */
34
  * # The wp-content folder is not included.
35
  * # .htaccess.bgb is included, but it is not a core file.
36
  *
37
+ * @since 1.6.0
38
  * @access public
39
  * @var array
40
  */
64
  /**
65
  * Constructor.
66
  *
67
+ * @since 1.6.0
68
  *
69
  * @param Boldgrid_Backup_Admin_Core $core Core class object.
70
  */
75
  /**
76
  * Determine if a given $file (relative to ABSPATH) is a core file.
77
  *
78
+ * @since 1.6.0
79
  *
80
+ * @param string $file File path.
81
  * @return bool
82
  */
83
  public function is_core_file( $file ) {
93
 
94
  return false;
95
  }
 
96
  }
admin/class-boldgrid-backup-admin-core.php CHANGED
@@ -1,37 +1,61 @@
1
  <?php
2
  /**
3
- * The admin-specific core functionality of the plugin
4
  *
5
- * @link http://www.boldgrid.com
6
- * @since 1.0
7
  *
8
- * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
- * @copyright BoldGrid.com
11
- * @version $Id$
12
- * @author BoldGrid.com <wpb@boldgrid.com>
 
 
13
  */
14
 
15
  /**
16
- * BoldGrid Backup admin core class.
17
  *
18
  * @since 1.0
19
  */
20
  class Boldgrid_Backup_Admin_Core {
 
 
 
 
 
 
 
 
21
  /**
22
  * Auto Rollback class.
23
  *
24
  * @since 1.5.2
25
- * @access public
26
  * @var Boldgrid_Backup_Admin_Auto_Rollback
27
  */
28
  public $auto_rollback;
29
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  /**
31
  * The settings class object.
32
  *
33
  * @since 1.0
34
- * @access public
35
  * @var Boldgrid_Backup_Admin_Settings
36
  */
37
  public $settings;
@@ -40,7 +64,6 @@ class Boldgrid_Backup_Admin_Core {
40
  * The configuration class object.
41
  *
42
  * @since 1.0
43
- * @access public
44
  * @var Boldgrid_Backup_Admin_Config
45
  */
46
  public $config;
@@ -49,16 +72,22 @@ class Boldgrid_Backup_Admin_Core {
49
  * Plugin configs.
50
  *
51
  * @since 1.3.4
52
- * @access plublic
53
  * @var array
54
  */
55
  public $configs;
56
 
 
 
 
 
 
 
 
 
57
  /**
58
  * Core Files class.
59
  *
60
- * @since 1.5.4
61
- * @access public
62
  * @var Boldgrid_Backup_Admin_Core_Files
63
  */
64
  public $core_files;
@@ -70,7 +99,6 @@ class Boldgrid_Backup_Admin_Core {
70
  * this->archive_files runs, it reports doing_ajax as true.
71
  *
72
  * @since 1.5.2
73
- * @access public
74
  * @var bool
75
  */
76
  public $doing_ajax;
@@ -78,11 +106,9 @@ class Boldgrid_Backup_Admin_Core {
78
  /**
79
  * Whether or not we're doing cron.
80
  *
81
- * When we're generating a backup, both via cron and wpcron, doing_cron is
82
- * true.
83
  *
84
  * @since 1.5.1
85
- * @access public
86
  * @var bool
87
  */
88
  public $doing_cron;
@@ -92,12 +118,14 @@ class Boldgrid_Backup_Admin_Core {
92
  *
93
  * In WordPress' wp-cron.php DOING_CRON is defined as true. In several of
94
  * our files, we define DOING_CRON as well. When we want to tell the
95
- * difference between (1)wp-cron.php and (2)cron / cli, it's difficult. This
96
- * property is soley to know if we're in wp-cron.php
97
  *
98
  * @todo Within our plugins, DOING_CRON should be cleaned up.
99
  *
100
- * @since 1.5.4
 
 
101
  */
102
  public $doing_wp_cron;
103
 
@@ -105,7 +133,6 @@ class Boldgrid_Backup_Admin_Core {
105
  * Email.
106
  *
107
  * @since 1.5.2
108
- * @access public
109
  * @var Boldgrid_Backup_Admin_Email
110
  */
111
  public $email;
@@ -117,16 +144,14 @@ class Boldgrid_Backup_Admin_Core {
117
  * language strings.
118
  *
119
  * @since 1.5.3
120
- * @access public
121
  * @var Boldgrid_Backup_Admin_Email
122
  */
123
- public $elements = array();
124
 
125
  /**
126
  * The functionality test class object.
127
  *
128
  * @since 1.0
129
- * @access public
130
  * @var Boldgrid_Backup_Admin_Test
131
  */
132
  public $test;
@@ -135,7 +160,6 @@ class Boldgrid_Backup_Admin_Core {
135
  * The Time class object.
136
  *
137
  * @since 1.6.0
138
- * @access public
139
  * @var Boldgrid_Backup_Admin_Time
140
  */
141
  public $time;
@@ -143,17 +167,39 @@ class Boldgrid_Backup_Admin_Core {
143
  /**
144
  * An instance of Boldgrid_Backup_Admin_Tools.
145
  *
146
- * @since 1.5.4
147
- * @access public
148
  * @var Boldgrid_Backup_Admin_Tools
149
  */
150
  public $tools;
151
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
152
  /**
153
  * An instance of Boldgrid_Backup_Admin_Utility.
154
  *
155
  * @since 1.5.3
156
- * @access public
157
  * @var Boldgrid_Backup_Admin_Utility
158
  */
159
  public $utility;
@@ -162,7 +208,6 @@ class Boldgrid_Backup_Admin_Core {
162
  * The admin notice class object.
163
  *
164
  * @since 1.0
165
- * @access public
166
  * @var Boldgrid_Backup_Admin_Notice
167
  */
168
  public $notice;
@@ -171,7 +216,6 @@ class Boldgrid_Backup_Admin_Core {
171
  * WordPress' global pagenow.
172
  *
173
  * @since 1.6.0
174
- * @access public
175
  * @var string
176
  */
177
  public $pagenow;
@@ -182,7 +226,6 @@ class Boldgrid_Backup_Admin_Core {
182
  * WordPress does an auto upgrade).
183
  *
184
  * @since 1.6.0
185
- * @access public
186
  * @var bool
187
  */
188
  public $pre_auto_update = false;
@@ -191,16 +234,30 @@ class Boldgrid_Backup_Admin_Core {
191
  * The admin cron class object.
192
  *
193
  * @since 1.0
194
- * @access public
195
  * @var Boldgrid_Backup_Admin_Cron
196
  */
197
  public $cron;
198
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
199
  /**
200
  * The admin xhprof class object.
201
  *
202
  * @since 1.2
203
- * @access public
204
  * @var Boldgrid_Backup_Admin_Xhprof
205
  */
206
  public $xhprof;
@@ -209,7 +266,6 @@ class Boldgrid_Backup_Admin_Core {
209
  * WP Cron class.
210
  *
211
  * @since 1.5.1
212
- * @access public
213
  * @var Boldgrid_Backup_Admin_WP_Cron
214
  */
215
  public $wp_cron;
@@ -218,7 +274,6 @@ class Boldgrid_Backup_Admin_Core {
218
  * An instance of the filesystem.
219
  *
220
  * @since 1.5.1
221
- * @access public
222
  * @var WP_Filesystem
223
  */
224
  public $wp_filesystem;
@@ -227,7 +282,6 @@ class Boldgrid_Backup_Admin_Core {
227
  * An instance of the Boldgrid_Backup_Admin_Archive class.
228
  *
229
  * @since 1.5.3
230
- * @access public
231
  * @var Boldgrid_Backup_Admin_Archive
232
  */
233
  public $archive;
@@ -235,8 +289,7 @@ class Boldgrid_Backup_Admin_Core {
235
  /**
236
  * An instance of the Boldgrid_Backup_Admin_Archives class.
237
  *
238
- * @since 1.5.4
239
- * @access public
240
  * @var Boldgrid_Backup_Admin_Archives
241
  */
242
  public $archives;
@@ -244,8 +297,7 @@ class Boldgrid_Backup_Admin_Core {
244
  /**
245
  * An instance of the Boldgrid_Backup_Admin_Archives_All class.
246
  *
247
- * @since 1.5.4
248
- * @access public
249
  * @var Boldgrid_Backup_Admin_Archives_All
250
  */
251
  public $archives_all;
@@ -253,8 +305,7 @@ class Boldgrid_Backup_Admin_Core {
253
  /**
254
  * An instance of the Boldgrid_Backup_Admin_Archive_Actions class.
255
  *
256
- * @since 1.5.4
257
- * @access public
258
  * @var Boldgrid_Backup_Admin_Archive_Actions
259
  */
260
  public $archive_actions;
@@ -263,7 +314,6 @@ class Boldgrid_Backup_Admin_Core {
263
  * An instance of the Boldgrid_Backup_Admin_Archive_Browser class.
264
  *
265
  * @since 1.5.2
266
- * @access public
267
  * @var Boldgrid_Backup_Admin_Archive_Browser
268
  */
269
  public $archive_browser;
@@ -272,7 +322,6 @@ class Boldgrid_Backup_Admin_Core {
272
  * An instance of the Archive Log class.
273
  *
274
  * @since 1.5.1
275
- * @access public
276
  * @var Boldgrid_Backup_Admin_Archive_Log
277
  */
278
  public $archive_log;
@@ -281,7 +330,6 @@ class Boldgrid_Backup_Admin_Core {
281
  * An instance of the Archive Details class.
282
  *
283
  * @since 1.5.1
284
- * @access public
285
  * @var Boldgrid_Backup_Admin_Archive_Details
286
  */
287
  public $archive_details;
@@ -290,25 +338,24 @@ class Boldgrid_Backup_Admin_Core {
290
  * An instance of the Archive Fail class.
291
  *
292
  * @since 1.5.2
293
- * @access public
294
  * @var Boldgrid_Backup_Admin_Archive_Fail
295
  */
296
  public $archive_fail;
297
 
298
  /**
299
- * Available execution functions.
300
  *
301
- * @since 1.0
302
- * @access private
303
- * @var array
 
304
  */
305
- private $available_exec_functions = null;
306
 
307
  /**
308
  * Db Dump.
309
  *
310
  * @since 1.5.3
311
- * @access public
312
  * @var Boldgrid_Backup_Admin_Db_Dump
313
  */
314
  public $db_dump;
@@ -317,7 +364,6 @@ class Boldgrid_Backup_Admin_Core {
317
  * Database backup file path.
318
  *
319
  * @since 1.0
320
- * @access public
321
  * @var string
322
  */
323
  public $db_dump_filepath = '';
@@ -326,7 +372,6 @@ class Boldgrid_Backup_Admin_Core {
326
  * Db Get.
327
  *
328
  * @since 1.5.3
329
- * @access public
330
  * @var Boldgrid_Backup_Admin_Db_Dump
331
  */
332
  public $db_get;
@@ -335,16 +380,15 @@ class Boldgrid_Backup_Admin_Core {
335
  * An instance of Boldgrid_Backup_Admin_Db_Omit.
336
  *
337
  * @since 1.5.3
338
- * @access public
339
  * @var Boldgrid_Backup_Admin_Db_Omit
340
  */
341
  public $db_omit;
342
 
343
  /**
344
- * An instance of the Boldgrid Backup Admin Filelist Class.
345
  *
346
  * @since 1.5.1
347
- * @var Boldgrid_Backup_Admin_Filelist object
348
  */
349
  public $filelist;
350
 
@@ -360,7 +404,7 @@ class Boldgrid_Backup_Admin_Core {
360
  /**
361
  * An instance of the Boldgrid_Backup_Admin_Folder_Exclusion class.
362
  *
363
- * @since 1.5.4
364
  * @var Boldgrid_Backup_Admin_Folder_Exclusion
365
  */
366
  public $folder_exclusion;
@@ -368,7 +412,7 @@ class Boldgrid_Backup_Admin_Core {
368
  /**
369
  * An instance of the Boldgrid_Backup_Admin_Ftp class.
370
  *
371
- * @since 1.5.4
372
  * @var Boldgrid_Backup_Admin_Ftp
373
  */
374
  public $ftp;
@@ -376,16 +420,16 @@ class Boldgrid_Backup_Admin_Core {
376
  /**
377
  * An instance of the Boldgrid_Backup_Admin_Go_Pro class.
378
  *
379
- * @since 1.5.4
380
  * @var Boldgrid_Backup_Admin_Go_Pro
381
  */
382
  public $go_pro;
383
 
384
  /**
385
- * An instance of the Boldgrid Backup Admin Backup Dir class.
386
  *
387
  * @since 1.5.1
388
- * @var Boldgrid_Backup_Admin_Backup_Dir object.
389
  */
390
  public $backup_dir;
391
 
@@ -402,8 +446,7 @@ class Boldgrid_Backup_Admin_Core {
402
  * Value indicating we are in the Backup Site Now callback and the user is
403
  * choosing a full backup.
404
  *
405
- * @since 1.5.4
406
- * @access public
407
  * @var bool
408
  */
409
  public $is_backup_full = false;
@@ -411,24 +454,23 @@ class Boldgrid_Backup_Admin_Core {
411
  /**
412
  * Value indicating we are in the Backup Site Now callback.
413
  *
414
- * @since 1.5.4
415
- * @access public
416
  * @var bool
417
  */
418
  public $is_backup_now = false;
419
 
420
  /**
421
- * An instance of the Boldgrid Backup Admin Home Dir class.
422
  *
423
  * @since 1.5.1
424
- * @var Boldgrid_Backup_Admin_Home_Dir object.
425
  */
426
  public $home_dir;
427
 
428
  /**
429
  * An instance of the In Progress class.
430
  *
431
- * @since 1.5.4
432
  * @var Boldgrid_Backup_Admin_In_Progress object.
433
  */
434
  public $in_progress;
@@ -437,64 +479,126 @@ class Boldgrid_Backup_Admin_Core {
437
  * Value indicating whether or not we're creating a backup for update
438
  * protection.
439
  *
440
- * @since 1.5.4
441
  * @var bool
442
  */
443
  public $is_archiving_update_protection = false;
444
 
 
 
 
 
 
 
 
 
445
  /**
446
  * Common elements.
447
  *
448
  * @since 1.5.3
449
  * @var array
450
  */
451
- public $lang = array();
452
 
453
  /**
454
  * Local storage.
455
  *
456
  * @since 1.5.2
457
- * @access public
458
  * @var Boldgrid_Backup_Admin_Storage_Local
459
  */
460
  public $local;
461
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
462
  /**
463
  * The Restore Helper class.
464
  *
465
  * @since 1.6.1
466
- * @access public
467
  * @var Boldgrid_Backup_Admin_Restore_Helper
468
  */
469
  public $restore_helper;
470
 
 
 
 
 
 
 
 
 
 
 
471
  /**
472
  * The scheduler class object.
473
  *
474
  * @since 1.5.1
475
- * @access public
476
  * @var Boldgrid_Backup_Admin_Scheduler
477
  */
478
  public $scheduler;
479
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
480
  /**
481
  * Constructor.
482
  *
483
  * @since 1.0
484
  *
485
- * @global $wp_filesystem.
486
  */
487
  public function __construct() {
 
488
  global $wp_filesystem;
489
  global $pagenow;
490
 
491
- $this->doing_cron = ( defined( 'DOING_CRON' ) && DOING_CRON ) || isset( $_GET['doing_wp_cron'] );
492
- $this->doing_ajax = is_admin() && defined( 'DOING_AJAX' ) && DOING_AJAX;
493
- $this->doing_wp_cron = ! empty( $_SERVER['SCRIPT_FILENAME'] ) && $_SERVER['SCRIPT_FILENAME'] === trailingslashit( ABSPATH ) . 'wp-cron.php';
 
 
494
 
495
  $this->wp_filesystem = $wp_filesystem;
 
496
  $this->pagenow = $pagenow;
497
 
 
 
 
498
  // Instantiate Boldgrid_Backup_Admin_Settings.
499
  $this->settings = new Boldgrid_Backup_Admin_Settings( $this );
500
 
@@ -545,6 +649,8 @@ class Boldgrid_Backup_Admin_Core {
545
 
546
  $this->archive_fail = new Boldgrid_Backup_Admin_Archive_Fail( $this );
547
 
 
 
548
  $this->wp_cron = new Boldgrid_Backup_Admin_WP_Cron( $this );
549
 
550
  $this->scheduler = new Boldgrid_Backup_Admin_Scheduler( $this );
@@ -579,19 +685,48 @@ class Boldgrid_Backup_Admin_Core {
579
 
580
  $this->tools = new Boldgrid_Backup_Admin_Tools( $this );
581
 
 
 
 
 
582
  $this->time = new Boldgrid_Backup_Admin_Time( $this );
583
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
584
  // Ensure there is a backup identifier.
585
  $this->get_backup_identifier();
586
 
587
- $this->configs = Boldgrid_Backup_Admin::get_configs();
588
-
589
  $this->set_lang();
590
 
 
 
 
 
591
  // Need to construct class so necessary filters are added.
592
  if ( class_exists( '\Boldgrid\Library\Library\Ui' ) ) {
593
  $ui = new \Boldgrid\Library\Library\Ui();
594
  }
 
 
 
 
 
 
 
 
 
595
  }
596
 
597
  /**
@@ -643,12 +778,29 @@ class Boldgrid_Backup_Admin_Core {
643
  return $backup_identifier;
644
  }
645
 
 
 
 
 
 
 
 
 
 
 
 
 
 
646
  /**
647
  * Initialize the premium version of the plugin.
648
  *
649
  * @since 1.5.2
 
 
650
  */
651
  public function init_premium() {
 
 
652
  $premium_class = 'Boldgrid_Backup_Premium';
653
 
654
  /*
@@ -659,52 +811,52 @@ class Boldgrid_Backup_Admin_Core {
659
  return;
660
  }
661
 
662
- $this->premium = new $premium_class( $this );
663
- $this->premium->run();
664
- }
665
-
666
- /**
667
- * Get the available execution functions.
668
- *
669
- * @since 1.0
670
- *
671
- * @return array An array of function names.
672
- */
673
- public function get_execution_functions() {
674
- // If the array already has elements, then return the array.
675
- if ( $this->available_exec_functions ) {
676
- return $this->available_exec_functions;
677
- }
678
-
679
- // If PHP is in safe mode, then return an empty array.
680
- if ( $this->test->is_php_safemode() ) {
681
- return array();
682
- }
683
-
684
- // Get the PHP disable_functions list.
685
- $disabled = explode( ',', ini_get( 'disable_functions' ) );
 
 
 
 
 
 
686
 
687
- // Make an array of execution functions.
688
- $exec_functions = array(
689
- 'popen',
690
- 'proc_open',
691
- 'exec',
692
- 'shell_exec',
693
- 'passthru',
694
- 'system',
695
- );
696
 
697
- // Iterate through the array and remove disabled functions.
698
- foreach ( $exec_functions as $exec_function ) {
699
- if ( in_array( $exec_function, $disabled, true ) ) {
700
- unset( $exec_functions[ $exec_function ] );
701
  }
702
- }
703
 
704
- // Save the array of execution functions.
705
- $this->available_exec_functions = $exec_functions;
706
 
707
- return $exec_functions;
 
708
  }
709
 
710
  /**
@@ -712,21 +864,23 @@ class Boldgrid_Backup_Admin_Core {
712
  *
713
  * @since 1.0
714
  *
715
- * @param string $command A command string to be executed.
716
- * @param array $available_exec_functions An array of available execution functions.
717
- * @param bool $success or failure of the operation, passed back to the caller.
718
- * @param int $return_var If present, the return_var, passed back to the caller.
 
 
719
  * @return string|bool Returns the command output or FALSE on error.
720
  */
721
- public function execute_command( $command, $available_exec_functions = array(), &$success = false, &$return_var = 0 ) {
722
  // If no command was passed, then fail.
723
  if ( empty( $command ) ) {
724
  return false;
725
  }
726
 
727
- // If there are no supplied execution functions, then retrieve available ones.
728
- if ( empty( $available_exec_functions ) ) {
729
- $available_exec_functions = $this->get_execution_functions();
730
  }
731
 
732
  // Disable stderr.
@@ -734,173 +888,8 @@ class Boldgrid_Backup_Admin_Core {
734
  $command .= ' 2>/dev/null';
735
  }
736
 
737
- // Initialize $success.
738
- $success = false;
739
-
740
- // Test getting output using available execution functions, until one is successful.
741
- foreach ( $available_exec_functions as $exec_function ) {
742
- switch ( $exec_function ) {
743
- case 'exec' :
744
- exec( $command, $out, $return_var );
745
-
746
- // If the exit status is int(0), then it was successful.
747
- if ( 0 === $return_var ) {
748
- $output = implode( PHP_EOL, $out );
749
-
750
- $success = true;
751
-
752
- break 2;
753
- } else {
754
- $output = false;
755
- }
756
-
757
- break 2;
758
-
759
- case 'passthru' :
760
- // If output buffering is enabled, then use passthru.
761
- if ( ob_start() ) {
762
- passthru( $command, $return_var );
763
-
764
- // Get current buffer contents and delete current output buffer.
765
- $output = ob_get_clean();
766
-
767
- // If the exit status is int(0), then it was successful.
768
- if ( 0 === $return_var ) {
769
- $success = true;
770
-
771
- break 2;
772
- } else {
773
- $output = false;
774
- }
775
- }
776
-
777
- break 2;
778
-
779
- case 'popen' :
780
- $handle = popen( $command, 'r' );
781
 
782
- $output = fread( $handle, 4096 );
783
-
784
- /*
785
- * If handle is a valid resource, then check for success.
786
- */
787
- if ( false !== $handle ) {
788
- // Close the process handle and get the return status.
789
- $return_var = pclose( $handle );
790
-
791
- // If the exit status is int(0), then it was successful.
792
- if ( 0 === $return_var ) {
793
- $success = true;
794
-
795
- break 2;
796
- } else {
797
- // Bad exit status code (non-zero).
798
- $output = false;
799
- }
800
- } else {
801
- // Failed to create a process handle.
802
- $output = false;
803
- }
804
-
805
- break 2;
806
-
807
- case 'proc_open' :
808
- // Create the descriptor spec array.
809
- $descriptorspec = array(
810
- 0 => array(
811
- 'pipe',
812
- 'r',
813
- ),
814
- 1 => array(
815
- 'pipe',
816
- 'w',
817
- ),
818
- 2 => array(
819
- 'pipe',
820
- 'w',
821
- ),
822
- );
823
-
824
- // Open a process handle.
825
- $handle = proc_open( $command, $descriptorspec, $pipes );
826
-
827
- if ( is_resource( $handle ) ) {
828
- // Close unused pipes[0].
829
- fclose( $pipes[0] );
830
-
831
- // Read output from pipes[1].
832
- $output = stream_get_contents( $pipes[1] );
833
-
834
- // Close pipes[1].
835
- fclose( $pipes[1] );
836
-
837
- // Close unused pipes[0].
838
- fclose( $pipes[2] );
839
-
840
- // Close the process handle and get the return status.
841
- $return_var = proc_close( $handle );
842
-
843
- // If the exit status is int(0), then it was successful.
844
- if ( 0 === $return_var ) {
845
- $success = true;
846
-
847
- break 2;
848
- } else {
849
- $output = false;
850
- }
851
- }
852
-
853
- break 2;
854
-
855
- case 'shell_exec' :
856
- $output = shell_exec( $command );
857
-
858
- if ( false === strpos( $output, 'command not found' ) ) {
859
- $success = true;
860
-
861
- break 2;
862
- } else {
863
- $output = false;
864
- }
865
-
866
- break 2;
867
-
868
- case 'system' :
869
- // If output buffering is enabled, then use system.
870
- if ( ob_start() ) {
871
- system( $command, $return_var );
872
-
873
- // Get current buffer contents and delete current output buffer.
874
- $output = ob_get_clean();
875
-
876
- // If the exit status is int(0), then it was successful.
877
- if ( 0 === $return_var ) {
878
- $success = true;
879
-
880
- break 2;
881
- } else {
882
- $output = false;
883
- }
884
- }
885
-
886
- break 2;
887
-
888
- default :
889
- break;
890
- }
891
- }
892
-
893
- // If there is output, then trim it.
894
- if ( ! empty( $output ) ) {
895
- $output = trim( $output );
896
- }
897
-
898
- // If the command was not successful, then return FALSE.
899
- if ( ! $success ) {
900
- return false;
901
- }
902
-
903
- // Success.
904
  return $output;
905
  }
906
 
@@ -910,67 +899,109 @@ class Boldgrid_Backup_Admin_Core {
910
  * @since 1.0
911
  *
912
  * @global array $submenu
913
- *
914
- * @return null
915
  */
916
  public function add_menu_items() {
917
  global $submenu;
918
 
919
- $lang = array(
920
- 'backup_archive' => __( 'Backup Archive', 'boldgrid-backup' ),
921
- 'boldgrid_backup' => __( 'BoldGrid Backup', 'boldgrid-backup' ),
922
- 'get_premium' => __( 'Get Premium', 'boldgrid-bacukp' ),
923
- 'preflight_check' => __( 'Preflight Check', 'boldgrid-backup' ),
924
- 'settings' => __( 'Settings', 'boldgrid-backup' ),
925
- 'tools' => __( 'Tools', 'boldgrid-backup' ),
926
- );
 
 
 
927
 
928
  // The main slug all sub menu items are children of.
929
- $main_slug = 'boldgrid-backup-settings';
930
-
931
- // The callable function for the settings page.
932
- $settings_page = array(
933
- $this->settings,
934
- 'page_backup_settings',
935
- );
936
 
937
  // The capability required for these menu items to be displayed to the user.
938
  $capability = 'administrator';
939
 
 
940
  add_menu_page(
941
  $lang['boldgrid_backup'],
 
942
  $lang['boldgrid_backup'],
943
  $capability,
944
  $main_slug,
945
- $settings_page,
 
 
 
946
  'none'
947
  );
948
 
949
- /*
950
- * Add "Settings", formally known as "Backup Settings".
951
- *
952
- * @link http://wordpress.stackexchange.com/questions/66498/add-menu-page-with-different-name-for-first-submenu-item
953
- */
954
  add_submenu_page(
955
  $main_slug,
956
- $lang['boldgrid_backup'] . ' ' . $lang['settings'],
957
- $lang['settings'],
958
  $capability,
959
- $main_slug,
960
- $settings_page
 
 
 
961
  );
962
 
963
- // Add "Backup Archive", formally known as "BoldGrid Backup".
964
  add_submenu_page(
965
  $main_slug,
966
  'BoldGrid ' . $lang['backup_archive'],
967
  $lang['backup_archive'],
968
  $capability,
969
  'boldgrid-backup',
970
- array(
971
  $this,
972
  'page_archives',
973
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
974
  );
975
 
976
  // Add "Preflight Check" page, formally know as "Functionality Test".
@@ -980,35 +1011,50 @@ class Boldgrid_Backup_Admin_Core {
980
  $lang['preflight_check'],
981
  $capability,
982
  'boldgrid-backup-test',
983
- array(
984
  $this,
985
  'page_backup_test',
986
- )
987
  );
988
 
 
989
  add_submenu_page(
990
  null,
991
  'BoldGrid ' . $lang['backup_archive'],
992
  $lang['backup_archive'],
993
  $capability,
994
  'boldgrid-backup-archive-details',
995
- array(
996
  $this->archive_details,
997
  'render_archive',
998
- )
999
  );
1000
 
1001
- // Add "Preflight Check" page, formally know as "Functionality Test".
1002
  add_submenu_page(
1003
  $main_slug,
1004
- $lang['boldgrid_backup'] . ' ' . $lang['tools'],
1005
- $lang['tools'],
1006
  $capability,
1007
- 'boldgrid-backup-tools',
1008
- array(
1009
- $this->tools,
1010
  'page',
1011
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1012
  );
1013
 
1014
  /*
@@ -1027,15 +1073,20 @@ class Boldgrid_Backup_Admin_Core {
1027
  $menu_slug
1028
  );
1029
 
1030
- // Change the url (2 is key of the menu item's slug / url).
1031
- foreach ( $submenu[ $main_slug ] as &$item ) {
1032
- if ( $menu_slug === $item[2] ) {
1033
- $item[2] = Boldgrid_Backup_Admin_Go_Pro::$url;
 
 
 
 
 
 
 
1034
  }
1035
  }
1036
  }
1037
-
1038
- return;
1039
  }
1040
 
1041
  /**
@@ -1049,14 +1100,14 @@ class Boldgrid_Backup_Admin_Core {
1049
  wp_register_style(
1050
  'boldgrid-backup-admin-new-thickbox-style',
1051
  plugin_dir_url( __FILE__ ) . 'css/boldgrid-backup-admin-new-thickbox-style.css',
1052
- array(),
1053
  BOLDGRID_BACKUP_VERSION
1054
  );
1055
 
1056
  wp_register_style(
1057
  'boldgrid-backup-admin-hide-all',
1058
  plugin_dir_url( __FILE__ ) . 'css/boldgrid-backup-admin-hide-all.css',
1059
- array(),
1060
  BOLDGRID_BACKUP_VERSION
1061
  );
1062
  }
@@ -1072,7 +1123,6 @@ class Boldgrid_Backup_Admin_Core {
1072
  * @return bool Status of the operation.
1073
  */
1074
  private function backup_database() {
1075
-
1076
  /*
1077
  * If we're omitting all the tables, we can skip trying to backup the
1078
  * database.
@@ -1085,7 +1135,7 @@ class Boldgrid_Backup_Admin_Core {
1085
  if ( ! $this->test->run_functionality_tests() ) {
1086
  // Display an error notice.
1087
  $this->notice->functionality_fail_notice();
1088
- return array( 'error' => __( 'Unable to create backup, functionality test failed.', 'boldgrid_backup' ) );
1089
  }
1090
 
1091
  // Get the backup directory path.
@@ -1096,7 +1146,13 @@ class Boldgrid_Backup_Admin_Core {
1096
 
1097
  // Check if the backup directory is writable.
1098
  if ( ! $wp_filesystem->is_writable( $backup_directory ) ) {
1099
- return array( 'error' => sprintf( __( 'The backup directory is not writable: %1$s.', 'boldgrid-backup' ), $backup_directory ) );
 
 
 
 
 
 
1100
  }
1101
 
1102
  // Create a file path for the dump file.
@@ -1110,17 +1166,29 @@ class Boldgrid_Backup_Admin_Core {
1110
  // Create a dump of our database.
1111
  $status = $this->db_dump->dump( $db_dump_filepath );
1112
  if ( ! empty( $status['error'] ) ) {
1113
- return array( 'error' => $status['error'] );
1114
  }
1115
 
1116
  // Ensure file is written and is over 100 bytes.
1117
  $exists = $this->test->exists( $db_dump_filepath );
1118
  if ( ! $exists ) {
1119
- return array( 'error' => sprintf( __( 'mysqldump file does not exist: %1$s', 'boldgrid-backup' ), $db_dump_filepath ) );
 
 
 
 
 
 
1120
  }
1121
  $dump_file_size = $this->wp_filesystem->size( $db_dump_filepath );
1122
  if ( 100 > $dump_file_size ) {
1123
- return array( 'error' => sprintf( __( 'mysqldump file was not written to: %1$s', 'boldgrid-backup' ), $db_dump_filepath ) );
 
 
 
 
 
 
1124
  }
1125
 
1126
  // Limit file permissions to the dump file.
@@ -1138,16 +1206,16 @@ class Boldgrid_Backup_Admin_Core {
1138
  *
1139
  * @see Boldgrid_Backup_Admin_Test::run_functionality_tests()
1140
  * @see Boldgrid_Backup_Admin_Backup_Dir::get()
1141
- * @see Boldgrid_Backup_Admin_Core::execute_command()
1142
  * @see Boldgrid_Backup_Admin_Utility::update_siteurl()
1143
  * @global WP_Filesystem $wp_filesystem The WordPress Filesystem API global object.
1144
  * @global wpdb $wpdb The WordPress database class object.
1145
  *
1146
- * @param string $db_dump_filepath File path to the mysql dump file.
1147
- * @param string $db_prefix The database prefix to use, if restoring and it changed.
 
1148
  * @return bool Status of the operation.
1149
  */
1150
- private function restore_database( $db_dump_filepath, $db_prefix = null ) {
1151
  // Check input.
1152
  if ( empty( $db_dump_filepath ) ) {
1153
  // Display an error notice.
@@ -1176,12 +1244,22 @@ class Boldgrid_Backup_Admin_Core {
1176
 
1177
  // Get the WP Options for "siteurl" and "home", to restore later.
1178
  $wp_siteurl = get_option( 'siteurl' );
1179
- $wp_home = get_option( 'home' );
1180
 
1181
  $this->set_time_limit();
1182
 
 
 
 
 
 
 
 
 
 
 
1183
  $importer = new Boldgrid_Backup_Admin_Db_Import();
1184
- $status = $importer->import( $db_dump_filepath );
1185
 
1186
  if ( ! empty( $status['error'] ) ) {
1187
  do_action( 'boldgrid_backup_notice', $status['error'], 'notice notice-error is-dismissible' );
@@ -1202,7 +1280,7 @@ class Boldgrid_Backup_Admin_Core {
1202
 
1203
  // Get the restored "siteurl" and "home".
1204
  $restored_wp_siteurl = get_option( 'siteurl' );
1205
- $restored_wp_home = get_option( 'home' );
1206
 
1207
  // If changed, then update the siteurl in the database.
1208
  if ( $restored_wp_siteurl !== $wp_siteurl ) {
@@ -1224,10 +1302,11 @@ class Boldgrid_Backup_Admin_Core {
1224
 
1225
  // If changed, then restore the WP Option for "home".
1226
  if ( $restored_wp_home !== $wp_home ) {
1227
- // Ensure there are no trailing slashes in siteurl.
1228
- $wp_home = untrailingslashit( $wp_home );
1229
 
1230
- update_option( 'home', $wp_home );
 
 
 
1231
  }
1232
 
1233
  // Return success.
@@ -1246,7 +1325,7 @@ class Boldgrid_Backup_Admin_Core {
1246
 
1247
  // If this is a node_modules folder, do not iterate through it.
1248
  if ( false !== strpos( $dirpath, '/node_modules' ) ) {
1249
- return array();
1250
  }
1251
 
1252
  // Connect to the WordPress Filesystem API.
@@ -1254,7 +1333,7 @@ class Boldgrid_Backup_Admin_Core {
1254
 
1255
  // Validate input.
1256
  if ( empty( $dirpath ) || ! $wp_filesystem->is_readable( $dirpath ) ) {
1257
- return array();
1258
  }
1259
 
1260
  // Remove any training slash in dirpath.
@@ -1269,7 +1348,7 @@ class Boldgrid_Backup_Admin_Core {
1269
  $dirlist = $wp_filesystem->dirlist( $dirpath, true, false );
1270
 
1271
  // Initialize $filelist.
1272
- $filelist = array();
1273
 
1274
  /*
1275
  * Add empty directory.
@@ -1281,20 +1360,18 @@ class Boldgrid_Backup_Admin_Core {
1281
  * to add all empty directories, but that method is no longer needed.
1282
  */
1283
  if ( empty( $dirlist ) ) {
1284
- $filelist[] = array(
1285
  $dirpath,
1286
  str_replace( ABSPATH, '', $dirpath ),
1287
  0,
1288
- /*
1289
- * @since 1.5.4, this 4th key represetnts 'type', as in a file
1290
- * or a directory.
1291
- */
1292
  'd',
1293
- );
1294
  }
1295
 
1296
  // Sort the dirlist array by filename.
1297
- uasort( $dirlist,
 
1298
  function ( $a, $b ) {
1299
  if ( $a['name'] < $b['name'] ) {
1300
  return - 1;
@@ -1326,11 +1403,11 @@ class Boldgrid_Backup_Admin_Core {
1326
  $relative_path = substr( $filepath, strlen( $this->filelist_basedir ) + 1 );
1327
 
1328
  // For files, add to the filelist array.
1329
- $filelist[] = array(
1330
  $filepath,
1331
  $relative_path,
1332
  $fileinfo['size'],
1333
- );
1334
  }
1335
 
1336
  // Return the array.
@@ -1354,7 +1431,7 @@ class Boldgrid_Backup_Admin_Core {
1354
 
1355
  // Validate input.
1356
  if ( empty( $dirpath ) || ! $this->wp_filesystem->is_readable( $dirpath ) ) {
1357
- return array();
1358
  }
1359
 
1360
  // Get the recursive directory listing for the specified path.
@@ -1362,17 +1439,17 @@ class Boldgrid_Backup_Admin_Core {
1362
 
1363
  // If no files were found, then return an empty array.
1364
  if ( empty( $filelist ) ) {
1365
- return array();
1366
  }
1367
 
1368
  // Initialize $new_filelist.
1369
- $new_filelist = array();
1370
 
1371
  // Filter the filelist array.
1372
  foreach ( $filelist as $fileinfo ) {
1373
 
1374
  // @todo The user needs a way to specifiy what to skip in the backups.
1375
- $is_node_modules = false !== strpos( $fileinfo[1], '/node_modules/' );
1376
  $is_backup_directory = $this->backup_dir->file_in_dir( $fileinfo[1] );
1377
 
1378
  if ( $is_node_modules || $is_backup_directory ) {
@@ -1423,7 +1500,8 @@ class Boldgrid_Backup_Admin_Core {
1423
  // Create a site identifier.
1424
  $site_id = Boldgrid_Backup_Admin_Utility::create_site_id();
1425
 
1426
- $filename = sprintf( 'boldgrid-backup-%1$s-%2$s-%3$s',
 
1427
  $site_id,
1428
  $backup_identifier,
1429
  date( 'Ymd-His' )
@@ -1449,15 +1527,31 @@ class Boldgrid_Backup_Admin_Core {
1449
  *
1450
  * @since 1.0
1451
  *
1452
- * @see Boldgrid_Backup_Admin_Core::backup_database().
 
1453
  *
1454
  * @param bool $save A switch to save the archive file. Default is FALSE.
1455
  * @param bool $dryrun An optional switch to perform a dry run test.
1456
  * @return array An array of archive file information.
1457
  */
1458
  public function archive_files( $save = false, $dryrun = false ) {
 
 
 
 
 
1459
  $this->pre_auto_update = 'pre_auto_update' === current_filter();
1460
 
 
 
 
 
 
 
 
 
 
 
1461
  /**
1462
  * Actions to take before any archiving begins.
1463
  *
@@ -1469,8 +1563,6 @@ class Boldgrid_Backup_Admin_Core {
1469
  $this->in_progress->set();
1470
  }
1471
 
1472
- $is_scheduled_backup = $this->doing_cron && ! $this->pre_auto_update;
1473
-
1474
  /*
1475
  * If this is a scheduled backup and no location is selected to save the
1476
  * backup to, abort.
@@ -1480,69 +1572,83 @@ class Boldgrid_Backup_Admin_Core {
1480
  * wanted to change their retention settings but did not want to schedule
1481
  * backups, validating storage locations would be problematic.
1482
  */
1483
- if ( $is_scheduled_backup && ! $this->remote->any_enabled() ) {
1484
- $error = __( 'No backup locations selected! While we could create a backup archive, you have not selected where the backup archive should be saved to. Please choose a storage location in your BoldGrid Backup Settings to save this backup archive to.', 'boldgrid-backup' );
1485
  $this->archive_fail->schedule_fail_email( $error );
1486
- return array(
1487
- 'error' => $error,
1488
- );
1489
  }
1490
 
1491
  // Check if functional.
1492
  if ( ! $this->test->run_functionality_tests() ) {
1493
  // Display an error notice, if not already on the test page.
1494
- if ( ! isset( $_GET['page'] ) || 'boldgrid-backup-test' !== $_GET['page'] ) {
1495
  // Display an error notice.
1496
  $this->notice->functionality_fail_notice();
1497
  }
1498
 
1499
- return array(
1500
- 'error' => 'Functionality tests fail.',
1501
- );
1502
  }
1503
 
1504
  // Close any PHP session, so that another session can open during the backup operation.
1505
  session_write_close();
1506
 
1507
- // Initialize return array and add "compressor" and "save" keys.
1508
- $info = array(
1509
- 'mode' => 'backup',
1510
- 'dryrun' => $dryrun,
1511
- 'compressor' => null,
1512
- 'filesize' => 0,
1513
- 'save' => $save,
1514
- 'total_size' => 0,
1515
- /*
1516
- * As of 1.6.0, the folder include and exclude settings below are
1517
- * for informational purposes only. This array cannot be filtered to
1518
- * adjust which folders are actually included / excluded.
1519
- */
1520
- 'folder_include' => $this->folder_exclusion->from_settings( 'include' ),
1521
- 'folder_exclude' => $this->folder_exclusion->from_settings( 'exclude' ),
1522
- 'table_exclude' => $this->db_omit->get_excluded_tables(),
1523
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1524
 
1525
  // Determine how this backup was triggered.
1526
  if ( $this->pre_auto_update ) {
1527
- $info['trigger'] = __( 'Auto update', 'boldgrid-bakcup' );
1528
  } elseif ( $this->doing_ajax && is_user_logged_in() ) {
1529
- $current_user = wp_get_current_user();
1530
  $info['trigger'] = $current_user->user_login . ' (' . $current_user->user_email . ')';
1531
  } elseif ( $this->doing_wp_cron ) {
1532
  $info['trigger'] = 'WP cron';
1533
  } elseif ( $this->doing_cron ) {
1534
  $info['trigger'] = 'Cron';
1535
  } else {
1536
- $info['trigger'] = __( 'Unknown', 'boldgrid-backup' );
1537
  }
1538
 
1539
  $info['compressor'] = $this->compressors->get();
1540
 
1541
  // If there is no available compressor, then fail.
1542
  if ( null === $info['compressor'] ) {
1543
- return array(
1544
- 'error' => 'No available compressor.',
1545
- );
1546
  }
1547
 
1548
  // Enforce retention setting.
@@ -1556,12 +1662,19 @@ class Boldgrid_Backup_Admin_Core {
1556
 
1557
  // Backup the database, if saving an archive file and not a dry run.
1558
  if ( $save && ! $dryrun ) {
 
 
 
1559
  $status = $this->backup_database();
1560
 
 
 
 
1561
  if ( false === $status || ! empty( $status['error'] ) ) {
1562
- return array(
1563
- 'error' => ! empty( $status['error'] ) ? $status['error'] : __( 'An unknown error occurred when backing up the database.', 'boldgrid-backup' ),
1564
- );
 
1565
  }
1566
  }
1567
 
@@ -1594,13 +1707,24 @@ class Boldgrid_Backup_Admin_Core {
1594
 
1595
  // Add the database dump file to the beginning of file list.
1596
  if ( ! empty( $this->db_dump_filepath ) ) {
1597
- $db_file_array = array(
 
 
1598
  $this->db_dump_filepath,
1599
  substr( $this->db_dump_filepath, strlen( $backup_directory ) + 1 ),
1600
- $this->wp_filesystem->size( $this->db_dump_filepath ),
1601
- );
1602
 
1603
  array_unshift( $filelist, $db_file_array );
 
 
 
 
 
 
 
 
 
1604
  }
1605
 
1606
  $this->set_time_limit();
@@ -1610,56 +1734,90 @@ class Boldgrid_Backup_Admin_Core {
1610
  *
1611
  * @since 1.5.1
1612
  *
1613
- * @param array $info See Boldgrid_Backup_Admin_Compressor_Php_Zip::archive_files.
 
 
 
1614
  */
1615
  $info = apply_filters( 'boldgrid_backup_pre_archive_info', $info );
1616
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1617
  /*
1618
  * Use the chosen compressor to build an archive.
1619
  * If the is no available compressor, then return an error.
1620
  */
1621
  switch ( $info['compressor'] ) {
1622
- case 'php_zip' :
1623
  $compressor = new Boldgrid_Backup_Admin_Compressor_Php_Zip( $this );
1624
- $status = $compressor->archive_files( $filelist, $info );
1625
  break;
1626
- case 'pcl_zip' :
1627
  $compressor = new Boldgrid_Backup_Admin_Compressor_Pcl_Zip( $this );
1628
- $status = $compressor->archive_files( $filelist, $info );
1629
  break;
1630
- case 'php_bz2' :
1631
  // Generate a new archive file path.
1632
  $info['filepath'] = $this->generate_archive_path( 'b2z' );
1633
  break;
1634
- case 'php_zlib' :
1635
  // Generate a new archive file path.
1636
  $info['filepath'] = $this->generate_archive_path( 'zlib' );
1637
  break;
1638
- case 'php_lzf' :
1639
  // Generate a new archive file path.
1640
  $info['filepath'] = $this->generate_archive_path( 'lzf' );
1641
  break;
1642
- case 'system_tar' :
1643
  // Generate a new archive file path.
1644
  $info['filepath'] = $this->generate_archive_path( 'tar.gz' );
1645
  break;
1646
- case 'system_zip' :
1647
- // Generate a new archive file path.
1648
- $info['filepath'] = $this->generate_archive_path( 'zip' );
1649
  break;
1650
- default :
1651
- $status = array(
1652
- 'error' => 'No available compressor',
1653
- );
1654
  break;
1655
  }
1656
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1657
  $info['total_size'] += $this->filelist->get_total_size( $filelist );
1658
 
1659
- if ( true === $status && ! $this->wp_filesystem->exists( $info['filepath'] ) ) {
1660
- $status = array(
1661
- 'error' => 'The archive file "' . $info['filepath'] . '" was not written.',
1662
- );
1663
  }
1664
 
1665
  if ( ! empty( $status['error'] ) ) {
@@ -1683,8 +1841,9 @@ class Boldgrid_Backup_Admin_Core {
1683
  $time_stop = microtime( true );
1684
 
1685
  // Calculate duration.
1686
- $info['duration'] = number_format( ( $time_stop - $time_start ), 2, '.', '' );
1687
  $info['db_duration'] = number_format( ( $db_time_stop - $time_start ), 2, '.', '' );
 
1688
 
1689
  /**
1690
  * Actions to take after a backup has been created.
@@ -1697,7 +1856,7 @@ class Boldgrid_Backup_Admin_Core {
1697
  *
1698
  * @since 1.5.2
1699
  *
1700
- * @param array $info{
1701
  * An array of info about the backup just created.
1702
  *
1703
  * @type string $mode backup
@@ -1715,11 +1874,23 @@ class Boldgrid_Backup_Admin_Core {
1715
  */
1716
  do_action( 'boldgrid_backup_post_archive_files', $info );
1717
 
1718
- // Send an email.
1719
- if ( $this->email->user_wants_notification( 'backup' ) && $this->doing_ajax ) {
1720
- $email_parts = $this->email->post_archive_parts( $info );
1721
- $email_body = $email_parts['body']['main'] . $email_parts['body']['signature'];
 
 
 
 
 
 
 
 
 
 
1722
  $info['mail_success'] = $this->email->send( $email_parts['subject'], $email_body );
 
 
1723
  }
1724
 
1725
  // If not a dry-run test, update the last backup option and enforce retention.
@@ -1735,6 +1906,22 @@ class Boldgrid_Backup_Admin_Core {
1735
  update_option( 'boldgrid_backup_latest_backup', $info );
1736
  }
1737
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1738
  // Return the array of archive information.
1739
  return $info;
1740
  }
@@ -1749,12 +1936,12 @@ class Boldgrid_Backup_Admin_Core {
1749
  * @param string $download_filename A filename to match to get info.
1750
  * @param string $backup_directory Specify a directory to look within for backups.
1751
  * @return array {
1752
- * A numbered array of arrays containing the following indexes.
1753
- * @type string $filepath Archive file path.
1754
- * @type string $filename Archive filename.
1755
- * @type string $filedate Localized file modification date.
1756
- * @type int $filesize The archive file size in bytes.
1757
- * @type int $lastmodunix The archive file modification time in unix seconds.
1758
  * }
1759
  */
1760
  public function get_archive_list( $download_filename = null, $backup_directory = null ) {
@@ -1762,7 +1949,7 @@ class Boldgrid_Backup_Admin_Core {
1762
  global $wp_filesystem;
1763
 
1764
  // Initialize $archive_files array.
1765
- $archive_files = array();
1766
 
1767
  // Get the backup directory.
1768
  if ( is_null( $backup_directory ) ) {
@@ -1771,7 +1958,7 @@ class Boldgrid_Backup_Admin_Core {
1771
 
1772
  // If the backup directory is not configured, then return an empty array.
1773
  if ( ! $backup_directory ) {
1774
- return array();
1775
  }
1776
 
1777
  // Find all backups.
@@ -1779,11 +1966,12 @@ class Boldgrid_Backup_Admin_Core {
1779
 
1780
  // If no files were found, then return an empty array.
1781
  if ( empty( $dirlist ) ) {
1782
- return array();
1783
  }
1784
 
1785
  // Sort the dirlist array by "lastmodunix" descending.
1786
- uasort( $dirlist,
 
1787
  function ( $a, $b ) {
1788
  if ( $a['lastmodunix'] < $b['lastmodunix'] ) {
1789
  return 1;
@@ -1813,15 +2001,15 @@ class Boldgrid_Backup_Admin_Core {
1813
 
1814
  // Create the return array.
1815
  // @todo Should we use the data and time from the filename, or rely on lastmodunix?
1816
- $archive_files[ $index ] = array(
1817
- 'filepath' => $backup_directory . '/' . $fileinfo['name'],
1818
- 'filename' => $fileinfo['name'],
1819
- 'filedate' => get_date_from_gmt(
1820
  date( 'Y-m-d H:i:s', $fileinfo['lastmodunix'] ), 'n/j/Y g:i A'
1821
  ),
1822
- 'filesize' => $fileinfo['size'],
1823
  'lastmodunix' => $fileinfo['lastmodunix'],
1824
- );
1825
 
1826
  // If looking for info on one file and we found the match, then break the loop.
1827
  if ( ! empty( $download_filename ) ) {
@@ -1913,7 +2101,8 @@ class Boldgrid_Backup_Admin_Core {
1913
  // Verify specified filename.
1914
  if ( $archive_filename !== $filename ) {
1915
  // Fail with a notice.
1916
- do_action( 'boldgrid_backup_notice',
 
1917
  esc_html__( 'The selected archive file was not found.', 'boldgrid-backup' ),
1918
  'notice notice-error is-dismissible'
1919
  );
@@ -1986,7 +2175,7 @@ class Boldgrid_Backup_Admin_Core {
1986
  * restore (the first applicable one it can find).
1987
  */
1988
  $pcl_zip = new Boldgrid_Backup_Admin_Compressor_Pcl_Zip( $this );
1989
- $sqls = $pcl_zip->get_sqls( $filepath );
1990
  if ( 1 === count( $sqls ) ) {
1991
  return ABSPATH . $sqls[0];
1992
  }
@@ -2003,7 +2192,8 @@ class Boldgrid_Backup_Admin_Core {
2003
  }
2004
 
2005
  // Sort the dirlist array by "name" descending.
2006
- uasort( $dirlist,
 
2007
  function ( $a, $b ) {
2008
  if ( $a['name'] < $b['name'] ) {
2009
  return 1;
@@ -2017,11 +2207,13 @@ class Boldgrid_Backup_Admin_Core {
2017
  }
2018
  );
2019
 
2020
- // Find the first occurrence of a MySQL dump file.
2021
- // Format: *.########-######.sql
2022
- // An example filename: joec_wrdp2.20160919-162431.sql
 
 
2023
  foreach ( $dirlist as $fileinfo ) {
2024
- if ( 1 === preg_match( '/\.[\d]+-[\d]+\.sql$/',$fileinfo['name'] ) ) {
2025
  $db_dump_filepath = ABSPATH . $fileinfo['name'];
2026
  break;
2027
  }
@@ -2042,42 +2234,51 @@ class Boldgrid_Backup_Admin_Core {
2042
  * @return array An array of archive file information.
2043
  */
2044
  public function restore_archive_file( $dryrun = false ) {
 
 
 
 
 
 
 
 
 
2045
  $restore_ok = true;
2046
 
2047
  // If a restoration was not requested, then abort.
2048
- if ( empty( $_POST['restore_now'] ) ) {
2049
- return array(
2050
- 'error' => esc_html__( 'Invalid restore_now value.', 'boldgrid-backup' ),
2051
- );
2052
  }
2053
 
2054
  // Check if functional.
2055
  if ( ! $this->test->run_functionality_tests() ) {
2056
- return array(
2057
- 'error' => esc_html__( 'Functionality tests fail.', 'boldgrid-backup' ),
2058
- );
2059
  }
2060
 
2061
  // Initialize variables.
2062
- $archive_key = null;
2063
  $archive_filename = null;
2064
 
2065
  // Validate archive_key.
2066
- if ( isset( $_POST['archive_key'] ) && is_numeric( $_POST['archive_key'] ) ) {
2067
  $archive_key = (int) $_POST['archive_key'];
2068
  } else {
2069
- return array(
2070
- 'error' => esc_html__( 'Invalid key for the selected archive file.', 'boldgrid-backup' ),
2071
- );
2072
  }
2073
 
2074
  // Validate archive_filename.
2075
- if ( ! empty( $_POST['archive_filename'] ) ) {
2076
  $archive_filename = sanitize_file_name( $_POST['archive_filename'] );
2077
  } else {
2078
- return array(
2079
- 'error' => esc_html__( 'Invalid filename for the selected archive file.', 'boldgrid-backup' ),
2080
- );
2081
  }
2082
 
2083
  // Close any PHP session, so that another session can open during this restore operation.
@@ -2085,17 +2286,17 @@ class Boldgrid_Backup_Admin_Core {
2085
 
2086
  $archives = $this->get_archive_list( $archive_filename );
2087
  if ( empty( $archives ) ) {
2088
- return array(
2089
- 'error' => esc_html__( 'No archive files were found.', 'boldgrid-backup' ),
2090
- );
2091
  }
2092
 
2093
  $filename = ! empty( $archives[ $archive_key ]['filename'] ) ? $archives[ $archive_key ]['filename'] : null;
2094
 
2095
  if ( $archive_filename !== $filename ) {
2096
- return array(
2097
- 'error' => esc_html__( 'The selected archive file was not found.', 'boldgrid-backup' ),
2098
- );
2099
  }
2100
 
2101
  $filepath = ! empty( $archives[ $archive_key ]['filepath'] ) ? $archives[ $archive_key ]['filepath'] : null;
@@ -2103,21 +2304,22 @@ class Boldgrid_Backup_Admin_Core {
2103
  if ( ! empty( $filepath ) && $this->wp_filesystem->exists( $filepath ) ) {
2104
  $filesize = $this->wp_filesystem->size( $filepath );
2105
  } else {
2106
- return array(
2107
- 'error' => esc_html__( 'The selected archive file is empty.', 'boldgrid-backup' ),
2108
- );
2109
  }
2110
 
2111
  // Populate $info.
2112
- $info = array(
2113
- 'mode' => 'restore',
2114
- 'dryrun' => $dryrun,
2115
- 'filename' => $archive_filename,
2116
- 'filepath' => $filepath,
2117
- 'filesize' => $filesize,
2118
  'archive_key' => $archive_key,
2119
- 'restore_ok' => $restore_ok,
2120
- );
 
2121
 
2122
  // Prevent this script from dying.
2123
  ignore_user_abort( true );
@@ -2133,9 +2335,25 @@ class Boldgrid_Backup_Admin_Core {
2133
  */
2134
  do_action( 'boldgrid_backup_pre_restore', $info );
2135
 
2136
- $this->restore_helper->set_writable_permissions( $info['filepath'] );
 
 
 
 
 
 
 
 
 
 
 
 
2137
 
 
 
2138
  $unzip_status = ! $dryrun ? unzip_file( $info['filepath'], ABSPATH ) : null;
 
 
2139
 
2140
  if ( is_wp_error( $unzip_status ) ) {
2141
  $error = false;
@@ -2152,13 +2370,11 @@ class Boldgrid_Backup_Admin_Core {
2152
 
2153
  if ( empty( $error ) ) {
2154
  $message = $unzip_status->get_error_message();
2155
- $data = $unzip_status->get_error_data();
2156
- $error = sprintf( '%1$s%2$s', $message, is_string( $data ) && ! empty( $data ) ? ': ' . $data : '' );
2157
  }
2158
 
2159
- return array(
2160
- 'error' => $error,
2161
- );
2162
  }
2163
 
2164
  /**
@@ -2178,6 +2394,8 @@ class Boldgrid_Backup_Admin_Core {
2178
  * will contain a database dump, so we may be able to skip this step.
2179
  */
2180
  $db_dump_filepath = $this->get_dump_file( $filepath );
 
 
2181
  if ( ! $dryrun && ! empty( $db_dump_filepath ) ) {
2182
  $db_prefix = null;
2183
 
@@ -2194,17 +2412,23 @@ class Boldgrid_Backup_Admin_Core {
2194
  }
2195
  }
2196
 
 
 
 
 
2197
  // Restore the database and then delete the dump.
2198
- $restore_ok = $this->restore_database( $db_dump_filepath, $db_prefix );
2199
  $this->wp_filesystem->delete( $db_dump_filepath, false, 'f' );
2200
 
2201
  // Display notice of deletion status.
2202
  if ( ! $restore_ok ) {
2203
- return array(
2204
- 'error' => esc_html__( 'Could not restore database.', 'boldgrid-backup' ),
2205
- );
2206
  }
2207
  }
 
 
2208
 
2209
  // Clear rollback information and restoration cron jobs that may be present.
2210
  $this->auto_rollback->cancel();
@@ -2214,12 +2438,16 @@ class Boldgrid_Backup_Admin_Core {
2214
 
2215
  // If enabled, send email notification for restoration completed.
2216
  if ( ! empty( $settings['notifications']['restore'] ) ) {
 
 
2217
  // Include the mail template.
2218
  include BOLDGRID_BACKUP_PATH . '/admin/partials/boldgrid-backup-admin-mail-restore.php';
2219
 
2220
  // Send the notification.
2221
  // Parameters come from the included mail template file.
2222
  $info['mail_success'] = $this->email->send( $subject, $body );
 
 
2223
  }
2224
 
2225
  // Update status.
@@ -2228,6 +2456,10 @@ class Boldgrid_Backup_Admin_Core {
2228
  // Check backup directory.
2229
  $info['backup_directory_set'] = $this->backup_dir->get();
2230
 
 
 
 
 
2231
  // Return info array.
2232
  return $info;
2233
  }
@@ -2263,6 +2495,7 @@ class Boldgrid_Backup_Admin_Core {
2263
 
2264
  $this->auto_rollback->enqueue_home_scripts();
2265
  $this->auto_rollback->enqueue_backup_scripts();
 
2266
 
2267
  $this->folder_exclusion->enqueue_scripts();
2268
  $this->db_omit->enqueue_scripts();
@@ -2299,8 +2532,6 @@ class Boldgrid_Backup_Admin_Core {
2299
 
2300
  // Include the home page template.
2301
  include BOLDGRID_BACKUP_PATH . '/admin/partials/boldgrid-backup-admin-home.php';
2302
-
2303
- return;
2304
  }
2305
 
2306
  /**
@@ -2332,26 +2563,32 @@ class Boldgrid_Backup_Admin_Core {
2332
 
2333
  $this->is_backup_now = true;
2334
 
2335
- $key = 'folder_exclusion_type';
2336
- $this->is_backup_full = isset( $_POST[ $key ] ) && 'full' === $_POST[ $key ];
 
2337
 
2338
  $this->is_archiving_update_protection = ! empty( $_POST['is_updating'] ) &&
2339
  'true' === $_POST['is_updating'];
2340
 
2341
  $archive_info = $this->archive_files( true );
2342
 
2343
- if ( ! $this->is_archiving_update_protection ) {
2344
- $message = include BOLDGRID_BACKUP_PATH . '/admin/partials/boldgrid-backup-admin-backup.php';
2345
- $this->notice->add_user_notice( $message['message'], $message['class'] );
2346
- wp_send_json_success( array(
2347
- 'callback' => 'reload',
2348
- ));
2349
- } else {
2350
  update_site_option( 'boldgrid_backup_pending_rollback', $archive_info );
2351
- wp_send_json_success( array(
2352
- 'callback' => 'updateProtectionEnabled',
2353
- ));
2354
  }
 
 
 
 
 
 
 
 
 
2355
  }
2356
 
2357
  /**
@@ -2361,6 +2598,8 @@ class Boldgrid_Backup_Admin_Core {
2361
  * a message should be displayed with the path to download using an alternate method.
2362
  *
2363
  * @since 1.0
 
 
2364
  */
2365
  public function download_archive_file_callback() {
2366
  // Verify nonce, or die.
@@ -2422,25 +2661,12 @@ class Boldgrid_Backup_Admin_Core {
2422
 
2423
  $filesize = $archives[ $download_key ]['filesize'];
2424
 
2425
- // Send header.
2426
- header( 'Content-Disposition: attachment; filename="' . $filename . '"' );
2427
- header( 'Content-Transfer-Encoding: binary' );
2428
- header( 'Content-Type: binary/octet-stream' );
2429
- header( 'Content-Length: ' . $filesize );
2430
-
2431
- // Check and flush output buffer if needed.
2432
- if ( 0 !== ob_get_level() ) {
2433
- ob_end_flush();
2434
  }
2435
 
2436
- // Close any PHP session, so another session can open during the download.
2437
- session_write_close();
2438
-
2439
- // Send the file. Not finding a replacement in $wp_filesystem.
2440
- readfile( $filepath );
2441
-
2442
- // Exit.
2443
- wp_die();
2444
  }
2445
 
2446
  /**
@@ -2450,8 +2676,6 @@ class Boldgrid_Backup_Admin_Core {
2450
  *
2451
  * @global string $wp_version The WordPress version string.
2452
  * @global wpdb $wpdb The WordPress database class object.
2453
- *
2454
- * @return null
2455
  */
2456
  public function page_backup_test() {
2457
  // Perform functionality tests.
@@ -2488,6 +2712,18 @@ class Boldgrid_Backup_Admin_Core {
2488
 
2489
  $disk_space = $this->test->get_disk_space();
2490
 
 
 
 
 
 
 
 
 
 
 
 
 
2491
  // Get our crons and ready them for display.
2492
  $our_crons = $this->cron->get_our_crons();
2493
  foreach ( $our_crons as &$cron ) {
@@ -2498,16 +2734,35 @@ class Boldgrid_Backup_Admin_Core {
2498
  $cron = esc_html( $cron );
2499
  }
2500
 
 
 
2501
  // Enqueue CSS for the test page.
2502
- wp_enqueue_style( 'boldgrid-backup-admin-test',
2503
- plugin_dir_url( __FILE__ ) . 'css/boldgrid-backup-admin-test.css', array(),
 
 
2504
  BOLDGRID_BACKUP_VERSION, 'all'
2505
  );
2506
 
2507
  // Load template view.
2508
  include BOLDGRID_BACKUP_PATH . '/admin/partials/boldgrid-backup-admin-test.php';
 
2509
 
2510
- return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2511
  }
2512
 
2513
  /**
@@ -2516,29 +2771,53 @@ class Boldgrid_Backup_Admin_Core {
2516
  * @since 1.5.3
2517
  */
2518
  public function set_lang() {
2519
- $this->lang = array(
 
 
 
 
2520
  // Mine count, total number of backups.
2521
- 'All' => __( 'All', 'boldgrid-backup' ),
2522
- 'backup_created' => __( 'Backup created successfully!', 'boldgrid-backup' ),
2523
- 'Checking_credentials' => __( 'Checking credentials', 'boldgrid-backup' ),
2524
- 'checkmark' => '&#10003;',
2525
- 'icon_success' => '<span class="dashicons dashicons-yes green"></span> ',
2526
- 'icon_warning' => '<span class="dashicons dashicons-warning yellow"></span> ',
2527
- 'heading_update_protection' => __( 'BoldGrid Backup - Update Protection', 'boldgrid-backup' ),
 
 
 
 
 
 
 
 
 
2528
  // Mine count, number of backups on remote storage providers.
2529
- 'Remote' => __( 'Remote', 'boldgrid-backup' ),
2530
- 'spinner' => '<span class="spinner"></span>',
2531
- 'spinner_inline' => '<span class="spinner inline"></span>',
2532
- 'want_to' => __( 'Want to store your backups on Amazon S3, restore individual files with just a click, and have access to more tools? Get <strong>BoldGrid Backup Premium</strong>!', 'boldgrid-backup' ),
 
 
 
 
 
 
 
 
 
 
 
2533
  // Mine count, number of backups on local web server.
2534
- 'Web_Server' => __( 'Web Server', 'boldgrid-backup' ),
2535
- );
2536
 
2537
- $this->elements = array(
2538
- 'update_protection_activated' => sprintf( '%1$s %2$s', $this->lang['icon_success'], __( 'Update protection activated!', 'boldgrid-backup' ) ),
2539
  // Use on long loading pages. Javascript will remove this on page load.
2540
- 'long_checking_creds' => sprintf( '<div class="bgbu-remove-load">%1$s %2$s</div>', $this->lang['Checking_credentials'], $this->lang['spinner_inline'] ),
2541
- );
2542
  }
2543
 
2544
  /**
@@ -2552,20 +2831,19 @@ class Boldgrid_Backup_Admin_Core {
2552
  * @param int $time_limit Limit in seconds.
2553
  */
2554
  public function set_time_limit( $time_limit = 900 ) {
2555
- set_time_limit( ( ( $max_execution_time = ini_get( 'max_execution_time' ) ) > $time_limit ?
2556
- $max_execution_time :
2557
- $time_limit
2558
- ) );
2559
  }
2560
 
2561
  /**
2562
  * Handle ajax request to restore a file.
2563
  *
2564
- * @since 1.5.4
2565
  */
2566
  public function wp_ajax_restore() {
2567
- $error = __( 'Unable to restore backup: ', 'boldgrid-backup' );
2568
- $redirect_url = admin_url( 'admin.php?page=boldgrid-backup' );
2569
 
2570
  // Validate user role.
2571
  if ( ! current_user_can( 'update_plugins' ) ) {
@@ -2600,23 +2878,21 @@ class Boldgrid_Backup_Admin_Core {
2600
  */
2601
  $is_success = ! empty( $archive_info ) && empty( $archive_info['error'] );
2602
  if ( $is_success ) {
2603
- $message = array(
2604
  'message' => esc_html__( 'The selected archive file has been successfully restored.', 'boldgrid-backup' ),
2605
- 'class' => 'notice notice-success is-dismissible',
2606
- 'header' => __( 'BoldGrid Backup - Restoration complete' ),
2607
- );
2608
  } else {
2609
- $message = array(
2610
- 'message' => ! empty( $archive_info['error'] ) ? $archive_info['error'] : __( 'Unknown error when attempting to restore archive.', 'bolcgrid-backup' ),
2611
- 'class' => 'notice notice-error is-dismissible',
2612
- 'header' => __( 'BoldGrid Backup - Restoration failed' ),
2613
- );
2614
  }
2615
  $this->notice->add_user_notice( $message['message'], $message['class'], $message['header'] );
2616
 
2617
- wp_send_json_success( array(
2618
- 'redirect_url' => $redirect_url,
2619
- ));
2620
  }
2621
 
2622
  /**
@@ -2651,9 +2927,7 @@ class Boldgrid_Backup_Admin_Core {
2651
  }
2652
 
2653
  // Perform the backup operation.
2654
- $archive_info = $this->archive_files( true );
2655
-
2656
- return;
2657
  }
2658
 
2659
  /**
@@ -2666,23 +2940,37 @@ class Boldgrid_Backup_Admin_Core {
2666
  * @return null
2667
  */
2668
  public function enforce_retention() {
2669
- // Get backup settings.
 
 
 
2670
  $settings = $this->settings->get_settings();
 
2671
 
2672
- // Get archive list.
2673
  $archives = $this->get_archive_list();
 
 
 
 
 
 
 
 
 
 
 
 
 
2674
 
2675
  // Get the archives file count.
2676
  $archives_count = count( $archives );
2677
 
2678
  // If the archive count is not beyond the set retention count, then return.
2679
  if ( empty( $settings['retention_count'] ) || $archives_count <= $settings['retention_count'] ) {
 
2680
  return;
2681
  }
2682
 
2683
- // Connect to the WordPress Filesystem API.
2684
- global $wp_filesystem;
2685
-
2686
  // Initialize $counter.
2687
  $counter = $archives_count - 1;
2688
 
@@ -2696,27 +2984,30 @@ class Boldgrid_Backup_Admin_Core {
2696
 
2697
  // Delete the specified archive file.
2698
  $deleted = $this->archive->delete( $filepath );
2699
- if ( ! $deleted ) {
2700
- // Something went wrong.
2701
- break;
2702
- }
2703
-
2704
- /**
2705
- * Take action after a backup has been deleted due to retention.
2706
- *
2707
- * @since 1.5.3
2708
- *
2709
- * @param string $filepath
2710
- */
2711
- do_action( 'boldgrid_backup_retention_deleted', $filepath );
2712
 
2713
  // Decrease the archive count.
2714
  $archives_count --;
2715
 
2716
  // Increment the counter.
2717
  $counter --;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2718
  }
2719
 
2720
- return;
 
2721
  }
2722
  }
1
  <?php
2
  /**
3
+ * File: class-boldgrid-backup-admin-core.php
4
  *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.0
7
  *
8
+ * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
+ * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
+ *
14
+ * phpcs:disable WordPress.VIP
15
  */
16
 
17
  /**
18
+ * Class: Boldgrid_Backup_Admin_Core
19
  *
20
  * @since 1.0
21
  */
22
  class Boldgrid_Backup_Admin_Core {
23
+ /**
24
+ * Archiver Utility class.
25
+ *
26
+ * @since 1.9.0
27
+ * @var Boldgrid_Backup_Admin_Archiver_Utility
28
+ */
29
+ public $archiver_utility;
30
+
31
  /**
32
  * Auto Rollback class.
33
  *
34
  * @since 1.5.2
 
35
  * @var Boldgrid_Backup_Admin_Auto_Rollback
36
  */
37
  public $auto_rollback;
38
 
39
+ /**
40
+ * An instance of Boldgrid_Backup_Admin_Dashboard
41
+ *
42
+ * @since 1.11.0
43
+ * @var Boldgrid_Backup_Admin_Dashboard
44
+ */
45
+ public $dashboard;
46
+
47
+ /**
48
+ * Dashboard widget.
49
+ *
50
+ * @since 1.10.0
51
+ * @var Boldgrid_Backup_Admin_Dashboard_Widget
52
+ */
53
+ public $dashboard_widget;
54
+
55
  /**
56
  * The settings class object.
57
  *
58
  * @since 1.0
 
59
  * @var Boldgrid_Backup_Admin_Settings
60
  */
61
  public $settings;
64
  * The configuration class object.
65
  *
66
  * @since 1.0
 
67
  * @var Boldgrid_Backup_Admin_Config
68
  */
69
  public $config;
72
  * Plugin configs.
73
  *
74
  * @since 1.3.4
 
75
  * @var array
76
  */
77
  public $configs;
78
 
79
+ /**
80
+ * Plugin class.
81
+ *
82
+ * @since 1.13.0
83
+ * @var Boldgrid\Library\Library\Plugin\Plugin
84
+ */
85
+ public $plugin;
86
+
87
  /**
88
  * Core Files class.
89
  *
90
+ * @since 1.6.0
 
91
  * @var Boldgrid_Backup_Admin_Core_Files
92
  */
93
  public $core_files;
99
  * this->archive_files runs, it reports doing_ajax as true.
100
  *
101
  * @since 1.5.2
 
102
  * @var bool
103
  */
104
  public $doing_ajax;
106
  /**
107
  * Whether or not we're doing cron.
108
  *
109
+ * Please see $this->set_doing_cron() for further clarification.
 
110
  *
111
  * @since 1.5.1
 
112
  * @var bool
113
  */
114
  public $doing_cron;
118
  *
119
  * In WordPress' wp-cron.php DOING_CRON is defined as true. In several of
120
  * our files, we define DOING_CRON as well. When we want to tell the
121
+ * difference between (1)wp-cron.php and (2)cron / cli, it's difficult.
122
+ * This property is solely to know if we're in wp-cron.php.
123
  *
124
  * @todo Within our plugins, DOING_CRON should be cleaned up.
125
  *
126
+ * @since 1.6.0
127
+ *
128
+ * @var bool
129
  */
130
  public $doing_wp_cron;
131
 
133
  * Email.
134
  *
135
  * @since 1.5.2
 
136
  * @var Boldgrid_Backup_Admin_Email
137
  */
138
  public $email;
144
  * language strings.
145
  *
146
  * @since 1.5.3
 
147
  * @var Boldgrid_Backup_Admin_Email
148
  */
149
+ public $elements = [];
150
 
151
  /**
152
  * The functionality test class object.
153
  *
154
  * @since 1.0
 
155
  * @var Boldgrid_Backup_Admin_Test
156
  */
157
  public $test;
160
  * The Time class object.
161
  *
162
  * @since 1.6.0
 
163
  * @var Boldgrid_Backup_Admin_Time
164
  */
165
  public $time;
167
  /**
168
  * An instance of Boldgrid_Backup_Admin_Tools.
169
  *
170
+ * @since 1.6.0
 
171
  * @var Boldgrid_Backup_Admin_Tools
172
  */
173
  public $tools;
174
 
175
+ /**
176
+ * An instance of Boldgrid_Backup_Admin_Transfers.
177
+ *
178
+ * @since 1.11.0
179
+ * @var Boldgrid_Backup_Admin_Transfers
180
+ */
181
+ public $transfers;
182
+
183
+ /**
184
+ * An instance of Boldgrid_Backup_Admin_Support.
185
+ *
186
+ * @since 1.10.1
187
+ * @var Boldgrid_Backup_Admin_Support
188
+ */
189
+ public $support;
190
+
191
+ /**
192
+ * An instance of Boldgrid_Backup_Admin_Premium.
193
+ *
194
+ * @since 1.12.4
195
+ * @var Boldgrid_Backup_Admin_Premium_Features
196
+ */
197
+ public $premium_page;
198
+
199
  /**
200
  * An instance of Boldgrid_Backup_Admin_Utility.
201
  *
202
  * @since 1.5.3
 
203
  * @var Boldgrid_Backup_Admin_Utility
204
  */
205
  public $utility;
208
  * The admin notice class object.
209
  *
210
  * @since 1.0
 
211
  * @var Boldgrid_Backup_Admin_Notice
212
  */
213
  public $notice;
216
  * WordPress' global pagenow.
217
  *
218
  * @since 1.6.0
 
219
  * @var string
220
  */
221
  public $pagenow;
226
  * WordPress does an auto upgrade).
227
  *
228
  * @since 1.6.0
 
229
  * @var bool
230
  */
231
  public $pre_auto_update = false;
234
  * The admin cron class object.
235
  *
236
  * @since 1.0
 
237
  * @var Boldgrid_Backup_Admin_Cron
238
  */
239
  public $cron;
240
 
241
+ /**
242
+ * Cron log class.
243
+ *
244
+ * @since 1.6.5
245
+ * @var Boldgrid_Backup_Admin_Cron_Log
246
+ */
247
+ public $cron_log;
248
+
249
+ /**
250
+ * Cron test class.
251
+ *
252
+ * @since 1.6.5
253
+ * @var Boldgrid_Backup_Admin_Cron_Test
254
+ */
255
+ public $cron_test;
256
+
257
  /**
258
  * The admin xhprof class object.
259
  *
260
  * @since 1.2
 
261
  * @var Boldgrid_Backup_Admin_Xhprof
262
  */
263
  public $xhprof;
266
  * WP Cron class.
267
  *
268
  * @since 1.5.1
 
269
  * @var Boldgrid_Backup_Admin_WP_Cron
270
  */
271
  public $wp_cron;
274
  * An instance of the filesystem.
275
  *
276
  * @since 1.5.1
 
277
  * @var WP_Filesystem
278
  */
279
  public $wp_filesystem;
282
  * An instance of the Boldgrid_Backup_Admin_Archive class.
283
  *
284
  * @since 1.5.3
 
285
  * @var Boldgrid_Backup_Admin_Archive
286
  */
287
  public $archive;
289
  /**
290
  * An instance of the Boldgrid_Backup_Admin_Archives class.
291
  *
292
+ * @since 1.6.0
 
293
  * @var Boldgrid_Backup_Admin_Archives
294
  */
295
  public $archives;
297
  /**
298
  * An instance of the Boldgrid_Backup_Admin_Archives_All class.
299
  *
300
+ * @since 1.6.0
 
301
  * @var Boldgrid_Backup_Admin_Archives_All
302
  */
303
  public $archives_all;
305
  /**
306
  * An instance of the Boldgrid_Backup_Admin_Archive_Actions class.
307
  *
308
+ * @since 1.6.0
 
309
  * @var Boldgrid_Backup_Admin_Archive_Actions
310
  */
311
  public $archive_actions;
314
  * An instance of the Boldgrid_Backup_Admin_Archive_Browser class.
315
  *
316
  * @since 1.5.2
 
317
  * @var Boldgrid_Backup_Admin_Archive_Browser
318
  */
319
  public $archive_browser;
322
  * An instance of the Archive Log class.
323
  *
324
  * @since 1.5.1
 
325
  * @var Boldgrid_Backup_Admin_Archive_Log
326
  */
327
  public $archive_log;
330
  * An instance of the Archive Details class.
331
  *
332
  * @since 1.5.1
 
333
  * @var Boldgrid_Backup_Admin_Archive_Details
334
  */
335
  public $archive_details;
338
  * An instance of the Archive Fail class.
339
  *
340
  * @since 1.5.2
 
341
  * @var Boldgrid_Backup_Admin_Archive_Fail
342
  */
343
  public $archive_fail;
344
 
345
  /**
346
+ * Whether or not we're in the middle of archiving files.
347
  *
348
+ * This is set at the beginning and end of self::archive_files().
349
+ *
350
+ * @since 1.13.4
351
+ * @var bool
352
  */
353
+ public $archiving_files = false;
354
 
355
  /**
356
  * Db Dump.
357
  *
358
  * @since 1.5.3
 
359
  * @var Boldgrid_Backup_Admin_Db_Dump
360
  */
361
  public $db_dump;
364
  * Database backup file path.
365
  *
366
  * @since 1.0
 
367
  * @var string
368
  */
369
  public $db_dump_filepath = '';
372
  * Db Get.
373
  *
374
  * @since 1.5.3
 
375
  * @var Boldgrid_Backup_Admin_Db_Dump
376
  */
377
  public $db_get;
380
  * An instance of Boldgrid_Backup_Admin_Db_Omit.
381
  *
382
  * @since 1.5.3
 
383
  * @var Boldgrid_Backup_Admin_Db_Omit
384
  */
385
  public $db_omit;
386
 
387
  /**
388
+ * An instance of Boldgrid_Backup_Admin_Filelist.
389
  *
390
  * @since 1.5.1
391
+ * @var Boldgrid_Backup_Admin_Filelist
392
  */
393
  public $filelist;
394
 
404
  /**
405
  * An instance of the Boldgrid_Backup_Admin_Folder_Exclusion class.
406
  *
407
+ * @since 1.6.0
408
  * @var Boldgrid_Backup_Admin_Folder_Exclusion
409
  */
410
  public $folder_exclusion;
412
  /**
413
  * An instance of the Boldgrid_Backup_Admin_Ftp class.
414
  *
415
+ * @since 1.6.0
416
  * @var Boldgrid_Backup_Admin_Ftp
417
  */
418
  public $ftp;
420
  /**
421
  * An instance of the Boldgrid_Backup_Admin_Go_Pro class.
422
  *
423
+ * @since 1.6.0
424
  * @var Boldgrid_Backup_Admin_Go_Pro
425
  */
426
  public $go_pro;
427
 
428
  /**
429
+ * An instance of Boldgrid_Backup_Admin_Backup_Dir.
430
  *
431
  * @since 1.5.1
432
+ * @var Boldgrid_Backup_Admin_Backup_Dir
433
  */
434
  public $backup_dir;
435
 
446
  * Value indicating we are in the Backup Site Now callback and the user is
447
  * choosing a full backup.
448
  *
449
+ * @since 1.6.0
 
450
  * @var bool
451
  */
452
  public $is_backup_full = false;
454
  /**
455
  * Value indicating we are in the Backup Site Now callback.
456
  *
457
+ * @since 1.6.0
 
458
  * @var bool
459
  */
460
  public $is_backup_now = false;
461
 
462
  /**
463
+ * An instance of Boldgrid_Backup_Admin_Home_Dir.
464
  *
465
  * @since 1.5.1
466
+ * @var Boldgrid_Backup_Admin_Home_Dir
467
  */
468
  public $home_dir;
469
 
470
  /**
471
  * An instance of the In Progress class.
472
  *
473
+ * @since 1.6.0
474
  * @var Boldgrid_Backup_Admin_In_Progress object.
475
  */
476
  public $in_progress;
479
  * Value indicating whether or not we're creating a backup for update
480
  * protection.
481
  *
482
+ * @since 1.6.0
483
  * @var bool
484
  */
485
  public $is_archiving_update_protection = false;
486
 
487
+ /**
488
+ * Whether or not we are in a scheduled backup (IE a cron backup).
489
+ *
490
+ * @since 1.9.0
491
+ * @var bool
492
+ */
493
+ public $is_scheduled_backup;
494
+
495
  /**
496
  * Common elements.
497
  *
498
  * @since 1.5.3
499
  * @var array
500
  */
501
+ public $lang = [];
502
 
503
  /**
504
  * Local storage.
505
  *
506
  * @since 1.5.2
 
507
  * @var Boldgrid_Backup_Admin_Storage_Local
508
  */
509
  public $local;
510
 
511
+ /**
512
+ * Log page.
513
+ *
514
+ * @since 1.12.5
515
+ * @var Boldgrid_Backup_Admin_Log_Page
516
+ */
517
+ public $log_page;
518
+
519
+ /**
520
+ * Logger.
521
+ *
522
+ * @since 1.12.5
523
+ * @var Boldgrid_Backup_Admin_Log
524
+ */
525
+ public $logger;
526
+
527
+ /**
528
+ * Path to our config.rating-prompt.php file.
529
+ *
530
+ * @since 1.7.2
531
+ * @var string
532
+ */
533
+ public $rating_prompt_config;
534
+
535
  /**
536
  * The Restore Helper class.
537
  *
538
  * @since 1.6.1
 
539
  * @var Boldgrid_Backup_Admin_Restore_Helper
540
  */
541
  public $restore_helper;
542
 
543
+ /**
544
+ * Whether or not we are in the middle of restoring an archive.
545
+ *
546
+ * @since 1.13.5
547
+ * @var bool
548
+ *
549
+ * @see self::archiving_files
550
+ */
551
+ public $restoring_archive_file = false;
552
+
553
  /**
554
  * The scheduler class object.
555
  *
556
  * @since 1.5.1
 
557
  * @var Boldgrid_Backup_Admin_Scheduler
558
  */
559
  public $scheduler;
560
 
561
+ /**
562
+ * The public download class object.
563
+ *
564
+ * @since 1.7.0
565
+ * @var Boldgrid_Backup_Download
566
+ */
567
+ public $download;
568
+
569
+ /**
570
+ * An instance of the Boldgrid\Library\Library\Activity class.
571
+ *
572
+ * @since 1.7.2
573
+ * @var Boldgrid\Library\Library\Activity
574
+ */
575
+ public $activity;
576
+
577
  /**
578
  * Constructor.
579
  *
580
  * @since 1.0
581
  *
582
+ * @global $wp_filesystem
583
  */
584
  public function __construct() {
585
+ WP_Filesystem();
586
  global $wp_filesystem;
587
  global $pagenow;
588
 
589
+ $this->set_doing_cron();
590
+
591
+ $this->doing_ajax = is_admin() && defined( 'DOING_AJAX' ) && DOING_AJAX;
592
+ $this->doing_wp_cron = ! empty( $_SERVER['SCRIPT_FILENAME'] ) &&
593
+ trailingslashit( ABSPATH ) . 'wp-cron.php' === $_SERVER['SCRIPT_FILENAME'];
594
 
595
  $this->wp_filesystem = $wp_filesystem;
596
+
597
  $this->pagenow = $pagenow;
598
 
599
+ // Instantiate Configs Array
600
+ $this->configs = Boldgrid_Backup_Admin::get_configs();
601
+
602
  // Instantiate Boldgrid_Backup_Admin_Settings.
603
  $this->settings = new Boldgrid_Backup_Admin_Settings( $this );
604
 
649
 
650
  $this->archive_fail = new Boldgrid_Backup_Admin_Archive_Fail( $this );
651
 
652
+ $this->archiver_utility = new Boldgrid_Backup_Admin_Archiver_Utility( $this );
653
+
654
  $this->wp_cron = new Boldgrid_Backup_Admin_WP_Cron( $this );
655
 
656
  $this->scheduler = new Boldgrid_Backup_Admin_Scheduler( $this );
685
 
686
  $this->tools = new Boldgrid_Backup_Admin_Tools( $this );
687
 
688
+ $this->transfers = new Boldgrid_Backup_Admin_Transfers( $this );
689
+
690
+ $this->support = new Boldgrid_Backup_Admin_Support( $this );
691
+
692
  $this->time = new Boldgrid_Backup_Admin_Time( $this );
693
 
694
+ $this->cron_test = new Boldgrid_Backup_Admin_Cron_Test( $this );
695
+
696
+ $this->cron_log = new Boldgrid_Backup_Admin_Cron_Log( $this );
697
+
698
+ $this->download = new Boldgrid_Backup_Download( $this );
699
+
700
+ $this->dashboard_widget = new Boldgrid_Backup_Admin_Dashboard_Widget( $this );
701
+
702
+ $this->dashboard = new Boldgrid_Backup_Admin_Dashboard( $this );
703
+
704
+ // Instantiate Boldgrid\Library\Library\Plugin\Plugin.
705
+ $this->plugin = new \Boldgrid\Library\Library\Plugin\Plugin( 'boldgrid-backup', $this->configs );
706
+ $this->premium_page = new Boldgrid_Backup_Admin_Premium_Features( $this );
707
+
708
  // Ensure there is a backup identifier.
709
  $this->get_backup_identifier();
710
 
 
 
711
  $this->set_lang();
712
 
713
+ // Log system.
714
+ $this->logger = new Boldgrid_Backup_Admin_Log( $this );
715
+ $this->log_page = new Boldgrid_Backup_Admin_Log_Page( $this );
716
+
717
  // Need to construct class so necessary filters are added.
718
  if ( class_exists( '\Boldgrid\Library\Library\Ui' ) ) {
719
  $ui = new \Boldgrid\Library\Library\Ui();
720
  }
721
+
722
+ // Setup library's Activity and RatingPrompt classes; init RatingPrompt to add necessary filters.
723
+ $this->rating_prompt_config = BOLDGRID_BACKUP_PATH . '/includes/config/config.rating-prompt.php';
724
+ if ( class_exists( '\Boldgrid\Library\Library\RatingPrompt' ) ) {
725
+ new \Boldgrid\Library\Library\RatingPrompt();
726
+ }
727
+ if ( class_exists( '\Boldgrid\Library\Library\Activity' ) ) {
728
+ $this->activity = new \Boldgrid\Library\Library\Activity( BOLDGRID_BACKUP_KEY );
729
+ }
730
  }
731
 
732
  /**
778
  return $backup_identifier;
779
  }
780
 
781
+ /**
782
+ * Get core.
783
+ *
784
+ * Callable via the boldgrid_backup_get_core filter.
785
+ *
786
+ * @since 1.7.2
787
+ *
788
+ * @return Boldgrid_Backup_Admin_Core object.
789
+ */
790
+ public function get_core() {
791
+ return $this;
792
+ }
793
+
794
  /**
795
  * Initialize the premium version of the plugin.
796
  *
797
  * @since 1.5.2
798
+ *
799
+ * @global string $pagenow
800
  */
801
  public function init_premium() {
802
+ global $pagenow;
803
+
804
  $premium_class = 'Boldgrid_Backup_Premium';
805
 
806
  /*
811
  return;
812
  }
813
 
814
+ /*
815
+ * If this version of the backup plugin is not compatible with the premium version:
816
+ * 1. Don't init the premium extension.
817
+ * 2. Display an admin notice telling the user to upgrade.
818
+ */
819
+ if ( ! $this->support->is_premium_compatible() ) {
820
+ if ( 'update-core.php' !== $pagenow ) {
821
+ add_action( 'admin_notices', function() {
822
+ $message = wp_kses(
823
+ sprintf(
824
+ // Translators: 1 The minimum version required, 2 an opening strong tag, 3 its closing strong tag, 4 an opening anchor to the updates page, 5 its closing anchor, 6: Plugin title, 7: Premium plugin title.
825
+ __(
826
+ 'The version of the %2$s%7$s%3$s plugin you have installed requires %2$s%6$s%3$s version %1$s or higher. Don\'t worry, the fix is simple. Please go to your %4$sUpdates page%5$s and update the %2$s%6$s%3$s plugin.',
827
+ 'boldgrid-backup'
828
+ ),
829
+ BOLDGRID_BACKUP_MIN_VERSION_FOR_PREMIUM,
830
+ '<strong>',
831
+ '</strong>',
832
+ '<a href="' . esc_url( admin_url( 'update-core.php' ) ) . '">',
833
+ '</a>',
834
+ BOLDGRID_BACKUP_TITLE,
835
+ BOLDGRID_BACKUP_TITLE . ' Premium'
836
+ ),
837
+ [
838
+ 'strong' => [],
839
+ 'a' => [
840
+ 'href' => [],
841
+ ],
842
+ ]
843
+ );
844
 
845
+ $notice_markup = $this->notice->get_notice_markup(
846
+ 'notice notice-error is-dismissible',
847
+ $message,
848
+ BOLDGRID_BACKUP_TITLE . ' - ' . esc_html__( 'Update required', 'boldgrid-backup' )
849
+ );
 
 
 
 
850
 
851
+ echo $notice_markup; // phpcs:ignore
852
+ });
 
 
853
  }
 
854
 
855
+ return;
856
+ }
857
 
858
+ $this->premium = new $premium_class( $this );
859
+ $this->premium->run();
860
  }
861
 
862
  /**
864
  *
865
  * @since 1.0
866
  *
867
+ * @see Boldgrid_Backup_Admin_Cli::call_command()
868
+ *
869
+ * @param string $command A command string to be executed.
870
+ * @param bool $success Success or failure of the operation, passed back.
871
+ * @param int $return_var If present, the return_var, passed back.
872
+ * @param string $filepath An optional file path to write the output.
873
  * @return string|bool Returns the command output or FALSE on error.
874
  */
875
+ public function execute_command( $command, &$success = false, &$return_var = 0, $filepath = null ) {
876
  // If no command was passed, then fail.
877
  if ( empty( $command ) ) {
878
  return false;
879
  }
880
 
881
+ // If an output filepath is supplied, and the directory is writable, then write to file.
882
+ if ( $filepath && $this->wp_filesystem->is_writable( dirname( $filepath ) ) ) {
883
+ $command .= ' > ' . wp_normalize_path( $filepath );
884
  }
885
 
886
  // Disable stderr.
888
  $command .= ' 2>/dev/null';
889
  }
890
 
891
+ $output = Boldgrid_Backup_Admin_Cli::call_command( $command, $success, $return_var );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
892
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
893
  return $output;
894
  }
895
 
899
  * @since 1.0
900
  *
901
  * @global array $submenu
 
 
902
  */
903
  public function add_menu_items() {
904
  global $submenu;
905
 
906
+ $lang = [
907
+ 'backup_archive' => esc_html__( 'Backup Archives', 'boldgrid-backup' ),
908
+ 'boldgrid_backup' => BOLDGRID_BACKUP_TITLE,
909
+ 'get_premium' => esc_html__( 'Get Premium', 'boldgrid-bacukp' ),
910
+ 'preflight_check' => esc_html__( 'Preflight Check', 'boldgrid-backup' ),
911
+ 'settings' => esc_html__( 'Settings', 'boldgrid-backup' ),
912
+ 'tools' => esc_html__( 'Tools', 'boldgrid-backup' ),
913
+ 'transfers' => esc_html__( 'Transfers', 'boldgrid-backup' ),
914
+ 'support' => esc_html__( 'Support', 'boldgrid-backup' ),
915
+ 'premium' => esc_html__( 'Premium Features', 'boldgrid-backup' ),
916
+ ];
917
 
918
  // The main slug all sub menu items are children of.
919
+ $main_slug = 'boldgrid-backup-dashboard';
 
 
 
 
 
 
920
 
921
  // The capability required for these menu items to be displayed to the user.
922
  $capability = 'administrator';
923
 
924
+ // Add the main menu item.
925
  add_menu_page(
926
  $lang['boldgrid_backup'],
927
+ // This value is escaped already by Library\Plugin\Page::getUnreadMarkup
928
  $lang['boldgrid_backup'],
929
  $capability,
930
  $main_slug,
931
+ [
932
+ $this->dashboard,
933
+ 'page',
934
+ ],
935
  'none'
936
  );
937
 
938
+ // Add our "Dashboard" page.
 
 
 
 
939
  add_submenu_page(
940
  $main_slug,
941
+ __( 'Dashboard', 'boldgrid-backup' ),
942
+ __( 'Dashboard', 'boldgrid-backup' ),
943
  $capability,
944
+ 'boldgrid-backup-dashboard',
945
+ [
946
+ $this->dashboard,
947
+ 'page',
948
+ ]
949
  );
950
 
951
+ // Add "Backup Archive page".
952
  add_submenu_page(
953
  $main_slug,
954
  'BoldGrid ' . $lang['backup_archive'],
955
  $lang['backup_archive'],
956
  $capability,
957
  'boldgrid-backup',
958
+ [
959
  $this,
960
  'page_archives',
961
+ ]
962
+ );
963
+
964
+ // Add "Transfers" page.
965
+ add_submenu_page(
966
+ $main_slug,
967
+ $lang['boldgrid_backup'] . ' ' . $lang['transfers'],
968
+ $lang['transfers'],
969
+ $capability,
970
+ 'boldgrid-backup-transfers',
971
+ [
972
+ $this->transfers,
973
+ 'page',
974
+ ]
975
+ );
976
+
977
+ // Add "Tools" page.
978
+ add_submenu_page(
979
+ $main_slug,
980
+ $lang['boldgrid_backup'] . ' ' . $lang['tools'],
981
+ $lang['tools'],
982
+ $capability,
983
+ 'boldgrid-backup-tools',
984
+ [
985
+ $this->tools,
986
+ 'page',
987
+ ]
988
+ );
989
+
990
+ /*
991
+ * Add "Settings", formally known as "Backup Settings".
992
+ *
993
+ * @link http://wordpress.stackexchange.com/questions/66498/add-menu-page-with-different-name-for-first-submenu-item
994
+ */
995
+ add_submenu_page(
996
+ $main_slug,
997
+ $lang['boldgrid_backup'] . ' ' . $lang['settings'],
998
+ $lang['settings'],
999
+ $capability,
1000
+ 'boldgrid-backup-settings',
1001
+ [
1002
+ $this->settings,
1003
+ 'page_backup_settings',
1004
+ ]
1005
  );
1006
 
1007
  // Add "Preflight Check" page, formally know as "Functionality Test".
1011
  $lang['preflight_check'],
1012
  $capability,
1013
  'boldgrid-backup-test',
1014
+ [
1015
  $this,
1016
  'page_backup_test',
1017
+ ]
1018
  );
1019
 
1020
+ // Add "Backup Archive Details" page.
1021
  add_submenu_page(
1022
  null,
1023
  'BoldGrid ' . $lang['backup_archive'],
1024
  $lang['backup_archive'],
1025
  $capability,
1026
  'boldgrid-backup-archive-details',
1027
+ [
1028
  $this->archive_details,
1029
  'render_archive',
1030
+ ]
1031
  );
1032
 
1033
+ // Add "Support" page.
1034
  add_submenu_page(
1035
  $main_slug,
1036
+ $lang['boldgrid_backup'] . ' ' . $lang['support'],
1037
+ $lang['support'],
1038
  $capability,
1039
+ 'boldgrid-backup-support',
1040
+ [
1041
+ $this->support,
1042
  'page',
1043
+ ]
1044
+ );
1045
+
1046
+ // Add "Premium" page.
1047
+ add_submenu_page(
1048
+ $main_slug,
1049
+ $lang['boldgrid_backup'] . ' ' . $lang['premium'],
1050
+ // Count value is escaped already by Library\Plugin\Page::getUnreadMarkup
1051
+ $lang['premium'],
1052
+ $capability,
1053
+ 'boldgrid-backup-premium-features',
1054
+ [
1055
+ $this->premium_page,
1056
+ 'page',
1057
+ ]
1058
  );
1059
 
1060
  /*
1073
  $menu_slug
1074
  );
1075
 
1076
+ /*
1077
+ * Change the url (2 is key of the menu item's slug / url).
1078
+ *
1079
+ * The ! empty check is to ensure the submenu exists. In some cases, such as when a user
1080
+ * is logged in as an editor, it will not exist.
1081
+ */
1082
+ if ( ! empty( $submenu[ $main_slug ] ) ) {
1083
+ foreach ( $submenu[ $main_slug ] as &$item ) {
1084
+ if ( $menu_slug === $item[2] ) {
1085
+ $item[2] = $this->go_pro->get_premium_url( 'bgbkup-nav' );
1086
+ }
1087
  }
1088
  }
1089
  }
 
 
1090
  }
1091
 
1092
  /**
1100
  wp_register_style(
1101
  'boldgrid-backup-admin-new-thickbox-style',
1102
  plugin_dir_url( __FILE__ ) . 'css/boldgrid-backup-admin-new-thickbox-style.css',
1103
+ [],
1104
  BOLDGRID_BACKUP_VERSION
1105
  );
1106
 
1107
  wp_register_style(
1108
  'boldgrid-backup-admin-hide-all',
1109
  plugin_dir_url( __FILE__ ) . 'css/boldgrid-backup-admin-hide-all.css',
1110
+ [],
1111
  BOLDGRID_BACKUP_VERSION
1112
  );
1113
  }
1123
  * @return bool Status of the operation.
1124
  */
1125
  private function backup_database() {
 
1126
  /*
1127
  * If we're omitting all the tables, we can skip trying to backup the
1128
  * database.
1135
  if ( ! $this->test->run_functionality_tests() ) {
1136
  // Display an error notice.
1137
  $this->notice->functionality_fail_notice();
1138
+ return [ 'error' => esc_html__( 'Unable to create backup, functionality test failed.', 'boldgrid_backup' ) ];
1139
  }
1140
 
1141
  // Get the backup directory path.
1146
 
1147
  // Check if the backup directory is writable.
1148
  if ( ! $wp_filesystem->is_writable( $backup_directory ) ) {
1149
+ return [
1150
+ 'error' => sprintf(
1151
+ // translators: 1: Backup directory path.
1152
+ __( 'The backup directory is not writable: %1$s.', 'boldgrid-backup' ),
1153
+ $backup_directory
1154
+ ),
1155
+ ];
1156
  }
1157
 
1158
  // Create a file path for the dump file.
1166
  // Create a dump of our database.
1167
  $status = $this->db_dump->dump( $db_dump_filepath );
1168
  if ( ! empty( $status['error'] ) ) {
1169
+ return [ 'error' => $status['error'] ];
1170
  }
1171
 
1172
  // Ensure file is written and is over 100 bytes.
1173
  $exists = $this->test->exists( $db_dump_filepath );
1174
  if ( ! $exists ) {
1175
+ return [
1176
+ 'error' => sprintf(
1177
+ // translators: 1: MySQL dump file path.
1178
+ __( 'mysqldump file does not exist: %1$s', 'boldgrid-backup' ),
1179
+ $db_dump_filepath
1180
+ ),
1181
+ ];
1182
  }
1183
  $dump_file_size = $this->wp_filesystem->size( $db_dump_filepath );
1184
  if ( 100 > $dump_file_size ) {
1185
+ return [
1186
+ 'error' => sprintf(
1187
+ // translators: 1: MySQL dump file path.
1188
+ __( 'mysqldump file was not written to: %1$s', 'boldgrid-backup' ),
1189
+ $db_dump_filepath
1190
+ ),
1191
+ ];
1192
  }
1193
 
1194
  // Limit file permissions to the dump file.
1206
  *
1207
  * @see Boldgrid_Backup_Admin_Test::run_functionality_tests()
1208
  * @see Boldgrid_Backup_Admin_Backup_Dir::get()
 
1209
  * @see Boldgrid_Backup_Admin_Utility::update_siteurl()
1210
  * @global WP_Filesystem $wp_filesystem The WordPress Filesystem API global object.
1211
  * @global wpdb $wpdb The WordPress database class object.
1212
  *
1213
+ * @param string $db_dump_filepath File path to the mysql dump file.
1214
+ * @param string $db_prefix The database prefix to use, if restoring and it changed.
1215
+ * @param bool $db_encrypted Is the database dump file encrypted.
1216
  * @return bool Status of the operation.
1217
  */
1218
+ private function restore_database( $db_dump_filepath, $db_prefix = null, $db_encrypted = false ) {
1219
  // Check input.
1220
  if ( empty( $db_dump_filepath ) ) {
1221
  // Display an error notice.
1244
 
1245
  // Get the WP Options for "siteurl" and "home", to restore later.
1246
  $wp_siteurl = get_option( 'siteurl' );
1247
+ $wp_home = get_option( 'home' );
1248
 
1249
  $this->set_time_limit();
1250
 
1251
+ if ( $db_encrypted ) {
1252
+ /**
1253
+ * If BGBP is activated, then check for encryption and decrypt the file.
1254
+ *
1255
+ * @since 1.12.0
1256
+ */
1257
+ do_Action( 'boldgrid_backup_crypt_file', $db_dump_filepath, 'd' );
1258
+ }
1259
+
1260
+ // Import the dump file.
1261
  $importer = new Boldgrid_Backup_Admin_Db_Import();
1262
+ $status = $importer->import( $db_dump_filepath );
1263
 
1264
  if ( ! empty( $status['error'] ) ) {
1265
  do_action( 'boldgrid_backup_notice', $status['error'], 'notice notice-error is-dismissible' );
1280
 
1281
  // Get the restored "siteurl" and "home".
1282
  $restored_wp_siteurl = get_option( 'siteurl' );
1283
+ $restored_wp_home = get_option( 'home' );
1284
 
1285
  // If changed, then update the siteurl in the database.
1286
  if ( $restored_wp_siteurl !== $wp_siteurl ) {
1302
 
1303
  // If changed, then restore the WP Option for "home".
1304
  if ( $restored_wp_home !== $wp_home ) {
 
 
1305
 
1306
+ // There may be a filter, so remove it.
1307
+ remove_all_filters( 'pre_update_option_home' );
1308
+
1309
+ update_option( 'home', untrailingslashit( $wp_home ) );
1310
  }
1311
 
1312
  // Return success.
1325
 
1326
  // If this is a node_modules folder, do not iterate through it.
1327
  if ( false !== strpos( $dirpath, '/node_modules' ) ) {
1328
+ return [];
1329
  }
1330
 
1331
  // Connect to the WordPress Filesystem API.
1333
 
1334
  // Validate input.
1335
  if ( empty( $dirpath ) || ! $wp_filesystem->is_readable( $dirpath ) ) {
1336
+ return [];
1337
  }
1338
 
1339
  // Remove any training slash in dirpath.
1348
  $dirlist = $wp_filesystem->dirlist( $dirpath, true, false );
1349
 
1350
  // Initialize $filelist.
1351
+ $filelist = [];
1352
 
1353
  /*
1354
  * Add empty directory.
1360
  * to add all empty directories, but that method is no longer needed.
1361
  */
1362
  if ( empty( $dirlist ) ) {
1363
+ $filelist[] = [
1364
  $dirpath,
1365
  str_replace( ABSPATH, '', $dirpath ),
1366
  0,
1367
+ // Since 1.6.0, this 4th key represetnts 'type', as in a file or a directory.
 
 
 
1368
  'd',
1369
+ ];
1370
  }
1371
 
1372
  // Sort the dirlist array by filename.
1373
+ uasort(
1374
+ $dirlist,
1375
  function ( $a, $b ) {
1376
  if ( $a['name'] < $b['name'] ) {
1377
  return - 1;
1403
  $relative_path = substr( $filepath, strlen( $this->filelist_basedir ) + 1 );
1404
 
1405
  // For files, add to the filelist array.
1406
+ $filelist[] = [
1407
  $filepath,
1408
  $relative_path,
1409
  $fileinfo['size'],
1410
+ ];
1411
  }
1412
 
1413
  // Return the array.
1431
 
1432
  // Validate input.
1433
  if ( empty( $dirpath ) || ! $this->wp_filesystem->is_readable( $dirpath ) ) {
1434
+ return [];
1435
  }
1436
 
1437
  // Get the recursive directory listing for the specified path.
1439
 
1440
  // If no files were found, then return an empty array.
1441
  if ( empty( $filelist ) ) {
1442
+ return [];
1443
  }
1444
 
1445
  // Initialize $new_filelist.
1446
+ $new_filelist = [];
1447
 
1448
  // Filter the filelist array.
1449
  foreach ( $filelist as $fileinfo ) {
1450
 
1451
  // @todo The user needs a way to specifiy what to skip in the backups.
1452
+ $is_node_modules = false !== strpos( $fileinfo[1], '/node_modules/' );
1453
  $is_backup_directory = $this->backup_dir->file_in_dir( $fileinfo[1] );
1454
 
1455
  if ( $is_node_modules || $is_backup_directory ) {
1500
  // Create a site identifier.
1501
  $site_id = Boldgrid_Backup_Admin_Utility::create_site_id();
1502
 
1503
+ $filename = sprintf(
1504
+ 'boldgrid-backup-%1$s-%2$s-%3$s',
1505
  $site_id,
1506
  $backup_identifier,
1507
  date( 'Ymd-His' )
1527
  *
1528
  * @since 1.0
1529
  *
1530
+ * @see Boldgrid_Backup_Admin_Core::backup_database()
1531
+ * @see Boldgrid_Backup_Admin_Archive::write_results_file()
1532
  *
1533
  * @param bool $save A switch to save the archive file. Default is FALSE.
1534
  * @param bool $dryrun An optional switch to perform a dry run test.
1535
  * @return array An array of archive file information.
1536
  */
1537
  public function archive_files( $save = false, $dryrun = false ) {
1538
+ $this->archiving_files = true;
1539
+
1540
+ $this->logger->init( 'archive-' . time() . '.log' );
1541
+ $this->logger->add( 'Backup process initialized.' );
1542
+
1543
  $this->pre_auto_update = 'pre_auto_update' === current_filter();
1544
 
1545
+ /*
1546
+ * A scheduled backup is a backup triggered by the user's Settings > Backup Schedule. If the user clicked
1547
+ * "Backup Site Now" or this is a backup before an auto update occurs, this is not a scheduled backup.
1548
+ */
1549
+ $this->is_scheduled_backup = $this->doing_cron && ! $this->pre_auto_update;
1550
+
1551
+ Boldgrid_Backup_Admin_In_Progress_Data::set_args(
1552
+ [ 'status' => esc_html__( 'Initializing backup', 'boldgrid-backup' ) ]
1553
+ );
1554
+
1555
  /**
1556
  * Actions to take before any archiving begins.
1557
  *
1563
  $this->in_progress->set();
1564
  }
1565
 
 
 
1566
  /*
1567
  * If this is a scheduled backup and no location is selected to save the
1568
  * backup to, abort.
1572
  * wanted to change their retention settings but did not want to schedule
1573
  * backups, validating storage locations would be problematic.
1574
  */
1575
+ if ( $this->is_scheduled_backup && ! $this->remote->any_enabled() ) {
1576
+ $error = esc_html__( 'No backup locations selected! While we could create a backup archive, you have not selected where the backup archive should be saved. Please choose a storage location in your settings for where to save this backup archive.', 'boldgrid-backup' );
1577
  $this->archive_fail->schedule_fail_email( $error );
1578
+ return [ 'error' => $error ];
 
 
1579
  }
1580
 
1581
  // Check if functional.
1582
  if ( ! $this->test->run_functionality_tests() ) {
1583
  // Display an error notice, if not already on the test page.
1584
+ if ( ! isset( $_GET['page'] ) || 'boldgrid-backup-test' !== $_GET['page'] ) { // phpcs:ignore WordPress.CSRF.NonceVerification.NoNonceVerification
1585
  // Display an error notice.
1586
  $this->notice->functionality_fail_notice();
1587
  }
1588
 
1589
+ return [ 'error' => 'Functionality tests fail.' ];
 
 
1590
  }
1591
 
1592
  // Close any PHP session, so that another session can open during the backup operation.
1593
  session_write_close();
1594
 
1595
+ /*
1596
+ * Initialize return array and add "compressor" and "save" keys.
1597
+ * Since 1.6.0, the folder include and exclude settings below are
1598
+ * for informational purposes only. This array cannot be filtered to
1599
+ * adjust which folders are actually included / excluded.
1600
+ */
1601
+ $info = [
1602
+ 'mode' => 'backup',
1603
+ 'dryrun' => $dryrun,
1604
+ 'compressor' => null,
1605
+ 'filesize' => 0,
1606
+ 'save' => $save,
1607
+ 'total_size' => 0,
1608
+ 'folder_include' => $this->folder_exclusion->from_settings( 'include' ),
1609
+ 'folder_exclude' => $this->folder_exclusion->from_settings( 'exclude' ),
1610
+ 'table_exclude' => $this->db_omit->get_excluded_tables(),
1611
+ 'title' => ! empty( $_POST['backup_title'] ) ? stripslashes( $_POST['backup_title'] ) : null, // phpcs:ignore WordPress.CSRF.NonceVerification,WordPress.Arrays.ArrayDeclarationSpacing.ArrayItemNoNewLine
1612
+ 'description' => ! empty( $_POST['backup_description'] ) ? stripslashes( $_POST['backup_description'] ) : null, // phpcs:ignore WordPress.CSRF.NonceVerification,WordPress.Arrays.ArrayDeclarationSpacing.ArrayItemNoNewLine
1613
+ // Information used for the emergency restoration process.
1614
+ 'ABSPATH' => ABSPATH,
1615
+ 'backup_id' => $this->get_backup_identifier(),
1616
+ 'siteurl' => site_url(),
1617
+ 'timestamp' => time(), // @todo Is this a duplicate value? $info['lastmodunix'] is added below.
1618
+ // Environment information.
1619
+ 'gateway_interface' => getenv( 'GATEWAY_INTERFACE' ),
1620
+ 'http_host' => getenv( 'HTTP_HOST' ),
1621
+ 'php_sapi_name' => php_sapi_name(),
1622
+ 'php_uname' => php_uname(),
1623
+ 'php_version' => phpversion(),
1624
+ 'server_addr' => getenv( 'SERVER_ADDR' ) ? getenv( 'SERVER_ADDR' ) : getenv( 'LOCAL_ADDR' ),
1625
+ 'server_name' => getenv( 'SERVER_NAME' ),
1626
+ 'server_protocol' => getenv( 'SERVER_PROTOCOL' ),
1627
+ 'server_software' => getenv( 'SERVER_SOFTWARE' ),
1628
+ 'uid' => getmyuid(),
1629
+ 'username' => get_current_user(),
1630
+ 'encrypt_db' => false,
1631
+ ];
1632
 
1633
  // Determine how this backup was triggered.
1634
  if ( $this->pre_auto_update ) {
1635
+ $info['trigger'] = esc_html__( 'Auto update', 'boldgrid-bakcup' );
1636
  } elseif ( $this->doing_ajax && is_user_logged_in() ) {
1637
+ $current_user = wp_get_current_user();
1638
  $info['trigger'] = $current_user->user_login . ' (' . $current_user->user_email . ')';
1639
  } elseif ( $this->doing_wp_cron ) {
1640
  $info['trigger'] = 'WP cron';
1641
  } elseif ( $this->doing_cron ) {
1642
  $info['trigger'] = 'Cron';
1643
  } else {
1644
+ $info['trigger'] = esc_html__( 'Unknown', 'boldgrid-backup' );
1645
  }
1646
 
1647
  $info['compressor'] = $this->compressors->get();
1648
 
1649
  // If there is no available compressor, then fail.
1650
  if ( null === $info['compressor'] ) {
1651
+ return [ 'error' => 'No available compressor.' ];
 
 
1652
  }
1653
 
1654
  // Enforce retention setting.
1662
 
1663
  // Backup the database, if saving an archive file and not a dry run.
1664
  if ( $save && ! $dryrun ) {
1665
+ $this->logger->add( 'Starting dump of database...' );
1666
+ $this->logger->add_memory();
1667
+
1668
  $status = $this->backup_database();
1669
 
1670
+ $this->logger->add( 'Dump of database complete! $status = ' . print_r( $status, 1 ) ); // phpcs:ignore
1671
+ $this->logger->add_memory();
1672
+
1673
  if ( false === $status || ! empty( $status['error'] ) ) {
1674
+ return [
1675
+ 'error' => ! empty( $status['error'] ) ? $status['error'] :
1676
+ __( 'An unknown error occurred when backing up the database.', 'boldgrid-backup' ),
1677
+ ];
1678
  }
1679
  }
1680
 
1707
 
1708
  // Add the database dump file to the beginning of file list.
1709
  if ( ! empty( $this->db_dump_filepath ) ) {
1710
+ $db_dump_size = $this->wp_filesystem->size( $this->db_dump_filepath );
1711
+
1712
+ $db_file_array = [
1713
  $this->db_dump_filepath,
1714
  substr( $this->db_dump_filepath, strlen( $backup_directory ) + 1 ),
1715
+ $db_dump_size,
1716
+ ];
1717
 
1718
  array_unshift( $filelist, $db_file_array );
1719
+
1720
+ $this->logger->add(
1721
+ sprintf(
1722
+ 'Database dump file added to file list: %1$s / %2$s (%3$s)',
1723
+ $this->db_dump_filepath,
1724
+ $db_dump_size,
1725
+ size_format( $db_dump_size, 2 )
1726
+ )
1727
+ );
1728
  }
1729
 
1730
  $this->set_time_limit();
1734
  *
1735
  * @since 1.5.1
1736
  *
1737
+ * @see Boldgrid_Backup_Admin_Compressor_Php_Zip::archive_files
1738
+ * @see \Boldgrid\Backup\Premium\Admin\Crypt::post_dump()
1739
+ *
1740
+ * @param array $info Archive information.
1741
  */
1742
  $info = apply_filters( 'boldgrid_backup_pre_archive_info', $info );
1743
 
1744
+ $this->logger->add( 'Starting archiving of files. Chosen compressor: ' . $info['compressor'] );
1745
+ $this->logger->add_memory();
1746
+
1747
+ // Determine the path to our zip file.
1748
+ $info['filepath'] = $this->generate_archive_path( 'zip' );
1749
+
1750
+ Boldgrid_Backup_Admin_In_Progress_Data::set_args(
1751
+ [
1752
+ 'total_files_todo' => count( $filelist ),
1753
+ 'filepath' => $info['filepath'],
1754
+ 'compressor' => $info['compressor'],
1755
+ ]
1756
+ );
1757
+
1758
  /*
1759
  * Use the chosen compressor to build an archive.
1760
  * If the is no available compressor, then return an error.
1761
  */
1762
  switch ( $info['compressor'] ) {
1763
+ case 'php_zip':
1764
  $compressor = new Boldgrid_Backup_Admin_Compressor_Php_Zip( $this );
1765
+ $status = $compressor->archive_files( $filelist, $info );
1766
  break;
1767
+ case 'pcl_zip':
1768
  $compressor = new Boldgrid_Backup_Admin_Compressor_Pcl_Zip( $this );
1769
+ $status = $compressor->archive_files( $filelist, $info );
1770
  break;
1771
+ case 'php_bz2':
1772
  // Generate a new archive file path.
1773
  $info['filepath'] = $this->generate_archive_path( 'b2z' );
1774
  break;
1775
+ case 'php_zlib':
1776
  // Generate a new archive file path.
1777
  $info['filepath'] = $this->generate_archive_path( 'zlib' );
1778
  break;
1779
+ case 'php_lzf':
1780
  // Generate a new archive file path.
1781
  $info['filepath'] = $this->generate_archive_path( 'lzf' );
1782
  break;
1783
+ case 'system_tar':
1784
  // Generate a new archive file path.
1785
  $info['filepath'] = $this->generate_archive_path( 'tar.gz' );
1786
  break;
1787
+ case 'system_zip':
1788
+ $compressor = new Boldgrid_Backup_Admin_Compressor_System_Zip( $this );
1789
+ $status = $compressor->archive_files( $filelist, $info );
1790
  break;
1791
+ default:
1792
+ $status = [ 'error' => 'No available compressor' ];
 
 
1793
  break;
1794
  }
1795
 
1796
+ $archive_exists = ! empty( $info['filepath'] ) && $this->wp_filesystem->exists( $info['filepath'] );
1797
+ $archive_size = ! $archive_exists ? 0 : $this->wp_filesystem->size( $info['filepath'] );
1798
+
1799
+ // Add additional info to the logs.
1800
+ $this->logger->add( 'Archiving of files complete!' );
1801
+ if ( true !== $status ) {
1802
+ $this->logger->add( 'Archiving of files did not complete successfully: ' . print_r( $status, 1 ) ); // phpcs:ignore
1803
+ }
1804
+ $this->logger->add(
1805
+ sprintf(
1806
+ 'Archive filepath / size: %1$s / %2$s (%3$s)',
1807
+ ( empty( $info['filepath'] ) ? 'MISSING FILEPATH' : $info['filepath'] ),
1808
+ $archive_size,
1809
+ size_format( $archive_size, 2 )
1810
+ )
1811
+ );
1812
+ $this->logger->add_memory();
1813
+
1814
+ Boldgrid_Backup_Admin_In_Progress_Data::set_arg( 'status', esc_html__( 'Wrapping things up...', 'boldgrid-backup' ) );
1815
+ Boldgrid_Backup_Admin_In_Progress_Data::set_arg( 'percentage', 100 );
1816
+
1817
  $info['total_size'] += $this->filelist->get_total_size( $filelist );
1818
 
1819
+ if ( true === $status && ! $archive_exists ) {
1820
+ $status = [ 'error' => 'The archive file "' . $info['filepath'] . '" was not written.' ];
 
 
1821
  }
1822
 
1823
  if ( ! empty( $status['error'] ) ) {
1841
  $time_stop = microtime( true );
1842
 
1843
  // Calculate duration.
1844
+ $info['duration'] = number_format( ( $time_stop - $time_start ), 2, '.', '' );
1845
  $info['db_duration'] = number_format( ( $db_time_stop - $time_start ), 2, '.', '' );
1846
+ $info['db_filename'] = basename( $this->db_dump_filepath );
1847
 
1848
  /**
1849
  * Actions to take after a backup has been created.
1856
  *
1857
  * @since 1.5.2
1858
  *
1859
+ * @param array $info {
1860
  * An array of info about the backup just created.
1861
  *
1862
  * @type string $mode backup
1874
  */
1875
  do_action( 'boldgrid_backup_post_archive_files', $info );
1876
 
1877
+ /*
1878
+ * Send an email to the user, RIGHT NOW.
1879
+ *
1880
+ * Only send an email to the user now IF they are manually creating a backup. If this backup
1881
+ * was created during a scheduled backup, the user will get an email from the jobs queue.
1882
+ * Scheduled backups receive email notifications from the jobs queue because that email will
1883
+ * not only include the standard info about the backup (which we're sending now), it will
1884
+ * also include info about other jobs that were run (such as uploading the backup remotely).
1885
+ */
1886
+ if ( $this->email->user_wants_notification( 'backup' ) && ! $this->is_scheduled_backup ) {
1887
+ $this->logger->add( 'Starting sending of email...' );
1888
+
1889
+ $email_parts = $this->email->post_archive_parts( $info );
1890
+ $email_body = $email_parts['body']['main'] . $email_parts['body']['signature'];
1891
  $info['mail_success'] = $this->email->send( $email_parts['subject'], $email_body );
1892
+
1893
+ $this->logger->add( 'Sending of email complete! Status: ' . $info['mail_success'] );
1894
  }
1895
 
1896
  // If not a dry-run test, update the last backup option and enforce retention.
1906
  update_option( 'boldgrid_backup_latest_backup', $info );
1907
  }
1908
 
1909
+ // Actions to take if we're creating a full site backup.
1910
+ if ( ! $dryrun && $this->archiver_utility->is_full_backup() ) {
1911
+ $this->archive->write_results_file( $info );
1912
+ }
1913
+
1914
+ Boldgrid_Backup_Admin_In_Progress_Data::set_args( [ 'status' => esc_html__( 'Backup complete!', 'boldgrid-backup' ) ] );
1915
+
1916
+ if ( isset( $this->activity ) ) {
1917
+ $this->activity->add( 'any_backup_created', 1, $this->rating_prompt_config );
1918
+ }
1919
+
1920
+ $this->logger->add( 'Backup complete!' );
1921
+ $this->logger->add_memory();
1922
+
1923
+ $this->archiving_files = false;
1924
+
1925
  // Return the array of archive information.
1926
  return $info;
1927
  }
1936
  * @param string $download_filename A filename to match to get info.
1937
  * @param string $backup_directory Specify a directory to look within for backups.
1938
  * @return array {
1939
+ * A numbered array of arrays containing the following indexes.
1940
+ * @type string $filepath Archive file path.
1941
+ * @type string $filename Archive filename.
1942
+ * @type string $filedate Localized file modification date.
1943
+ * @type int $filesize The archive file size in bytes.
1944
+ * @type int $lastmodunix The archive file modification time in unix seconds.
1945
  * }
1946
  */
1947
  public function get_archive_list( $download_filename = null, $backup_directory = null ) {
1949
  global $wp_filesystem;
1950
 
1951
  // Initialize $archive_files array.
1952
+ $archive_files = [];
1953
 
1954
  // Get the backup directory.
1955
  if ( is_null( $backup_directory ) ) {
1958
 
1959
  // If the backup directory is not configured, then return an empty array.
1960
  if ( ! $backup_directory ) {
1961
+ return [];
1962
  }
1963
 
1964
  // Find all backups.
1966
 
1967
  // If no files were found, then return an empty array.
1968
  if ( empty( $dirlist ) ) {
1969
+ return [];
1970
  }
1971
 
1972
  // Sort the dirlist array by "lastmodunix" descending.
1973
+ uasort(
1974
+ $dirlist,
1975
  function ( $a, $b ) {
1976
  if ( $a['lastmodunix'] < $b['lastmodunix'] ) {
1977
  return 1;
2001
 
2002
  // Create the return array.
2003
  // @todo Should we use the data and time from the filename, or rely on lastmodunix?
2004
+ $archive_files[ $index ] = [
2005
+ 'filepath' => $backup_directory . '/' . $fileinfo['name'],
2006
+ 'filename' => $fileinfo['name'],
2007
+ 'filedate' => get_date_from_gmt(
2008
  date( 'Y-m-d H:i:s', $fileinfo['lastmodunix'] ), 'n/j/Y g:i A'
2009
  ),
2010
+ 'filesize' => $fileinfo['size'],
2011
  'lastmodunix' => $fileinfo['lastmodunix'],
2012
+ ];
2013
 
2014
  // If looking for info on one file and we found the match, then break the loop.
2015
  if ( ! empty( $download_filename ) ) {
2101
  // Verify specified filename.
2102
  if ( $archive_filename !== $filename ) {
2103
  // Fail with a notice.
2104
+ do_action(
2105
+ 'boldgrid_backup_notice',
2106
  esc_html__( 'The selected archive file was not found.', 'boldgrid-backup' ),
2107
  'notice notice-error is-dismissible'
2108
  );
2175
  * restore (the first applicable one it can find).
2176
  */
2177
  $pcl_zip = new Boldgrid_Backup_Admin_Compressor_Pcl_Zip( $this );
2178
+ $sqls = $pcl_zip->get_sqls( $filepath );
2179
  if ( 1 === count( $sqls ) ) {
2180
  return ABSPATH . $sqls[0];
2181
  }
2192
  }
2193
 
2194
  // Sort the dirlist array by "name" descending.
2195
+ uasort(
2196
+ $dirlist,
2197
  function ( $a, $b ) {
2198
  if ( $a['name'] < $b['name'] ) {
2199
  return 1;
2207
  }
2208
  );
2209
 
2210
+ /*
2211
+ * Find the first occurrence of a MySQL dump file.
2212
+ * Format: "*.########-######.sql".
2213
+ * An example filename: joec_wrdp2.20160919-162431.sql".
2214
+ */
2215
  foreach ( $dirlist as $fileinfo ) {
2216
+ if ( 1 === preg_match( '/\.[\d]+-[\d]+\.sql$/', $fileinfo['name'] ) ) {
2217
  $db_dump_filepath = ABSPATH . $fileinfo['name'];
2218
  break;
2219
  }
2234
  * @return array An array of archive file information.
2235
  */
2236
  public function restore_archive_file( $dryrun = false ) {
2237
+ $this->restoring_archive_file = true;
2238
+
2239
+ $this->logger->init( 'restore-' . time() . '.log' );
2240
+ $this->logger->add( 'Restoration process initialized.' );
2241
+ $this->logger->add_memory();
2242
+
2243
+ // Using pcl_zip (ZipArchive unavailable), a 400MB+ zip used over 500MB+ of memory to restore.
2244
+ Boldgrid_Backup_Admin_Utility::bump_memory_limit( '1G' );
2245
+
2246
  $restore_ok = true;
2247
 
2248
  // If a restoration was not requested, then abort.
2249
+ if ( empty( $_POST['restore_now'] ) ) { // phpcs:ignore WordPress.CSRF.NonceVerification.NoNonceVerification
2250
+ $error_message = esc_html__( 'Invalid restore_now value.', 'boldgrid-backup' );
2251
+ $this->logger->add( $error_message );
2252
+ return [ 'error' => $error_message ];
2253
  }
2254
 
2255
  // Check if functional.
2256
  if ( ! $this->test->run_functionality_tests() ) {
2257
+ $error_message = esc_html__( 'Functionality tests fail.', 'boldgrid-backup' );
2258
+ $this->logger->add( $error_message );
2259
+ return [ 'error' => $error_message ];
2260
  }
2261
 
2262
  // Initialize variables.
2263
+ $archive_key = null;
2264
  $archive_filename = null;
2265
 
2266
  // Validate archive_key.
2267
+ if ( isset( $_POST['archive_key'] ) && is_numeric( $_POST['archive_key'] ) ) { // phpcs:ignore WordPress.CSRF.NonceVerification.NoNonceVerification
2268
  $archive_key = (int) $_POST['archive_key'];
2269
  } else {
2270
+ $error_message = esc_html__( 'Invalid key for the selected archive file.', 'boldgrid-backup' );
2271
+ $this->logger->add( $error_message );
2272
+ return [ 'error' => $error_message ];
2273
  }
2274
 
2275
  // Validate archive_filename.
2276
+ if ( ! empty( $_POST['archive_filename'] ) ) { // phpcs:ignore WordPress.CSRF.NonceVerification.NoNonceVerification
2277
  $archive_filename = sanitize_file_name( $_POST['archive_filename'] );
2278
  } else {
2279
+ $error_message = esc_html__( 'Invalid filename for the selected archive file.', 'boldgrid-backup' );
2280
+ $this->logger->add( $error_message );
2281
+ return [ 'error' => $error_message ];
2282
  }
2283
 
2284
  // Close any PHP session, so that another session can open during this restore operation.
2286
 
2287
  $archives = $this->get_archive_list( $archive_filename );
2288
  if ( empty( $archives ) ) {
2289
+ $error_message = esc_html__( 'No archive files were found.', 'boldgrid-backup' );
2290
+ $this->logger->add( $error_message );
2291
+ return [ 'error' => $error_message ];
2292
  }
2293
 
2294
  $filename = ! empty( $archives[ $archive_key ]['filename'] ) ? $archives[ $archive_key ]['filename'] : null;
2295
 
2296
  if ( $archive_filename !== $filename ) {
2297
+ $error_message = esc_html__( 'The selected archive file was not found.', 'boldgrid-backup' );
2298
+ $this->logger->add( $error_message );
2299
+ return [ 'error' => $error_message ];
2300
  }
2301
 
2302
  $filepath = ! empty( $archives[ $archive_key ]['filepath'] ) ? $archives[ $archive_key ]['filepath'] : null;
2304
  if ( ! empty( $filepath ) && $this->wp_filesystem->exists( $filepath ) ) {
2305
  $filesize = $this->wp_filesystem->size( $filepath );
2306
  } else {
2307
+ $error_message = esc_html__( 'The selected archive file is empty.', 'boldgrid-backup' );
2308
+ $this->logger->add( $error_message );
2309
+ return [ 'error' => $error_message ];
2310
  }
2311
 
2312
  // Populate $info.
2313
+ $info = [
2314
+ 'mode' => 'restore',
2315
+ 'dryrun' => $dryrun,
2316
+ 'filename' => $archive_filename,
2317
+ 'filepath' => $filepath,
2318
+ 'filesize' => $filesize,
2319
  'archive_key' => $archive_key,
2320
+ 'restore_ok' => $restore_ok,
2321
+ ];
2322
+ $this->logger->add( 'Restore info: ' . print_r( $info, 1 ) ); // phpcs:ignore
2323
 
2324
  // Prevent this script from dying.
2325
  ignore_user_abort( true );
2335
  */
2336
  do_action( 'boldgrid_backup_pre_restore', $info );
2337
 
2338
+ /*
2339
+ * Attempt to fix any permissions related issues before the restoration begins. If we're
2340
+ * unable to, the restoration may not continue.
2341
+ */
2342
+ if ( class_exists( 'ZipArchive' ) ) {
2343
+ if ( ! $this->restore_helper->set_writable_permissions( $info['filepath'] ) ) {
2344
+ $error_message = $this->restore_helper->get_last_error();
2345
+ $this->logger->add( $error_message );
2346
+ return [ 'error' => $error_message ];
2347
+ }
2348
+ } else {
2349
+ $this->logger->add( 'ZipArchive not available. Unable to set_writable_permissions. Trying restore anyways...' );
2350
+ }
2351
 
2352
+ $this->logger->add( 'Unzipping archive... filepath / ABSPATH: ' . $info['filepath'] . ' / ' . ABSPATH );
2353
+ $this->logger->add_memory();
2354
  $unzip_status = ! $dryrun ? unzip_file( $info['filepath'], ABSPATH ) : null;
2355
+ $this->logger->add( 'Unzip complete! Status: ' . print_r( $unzip_status, 1 ) ); // phpcs:ignore
2356
+ $this->logger->add_memory();
2357
 
2358
  if ( is_wp_error( $unzip_status ) ) {
2359
  $error = false;
2370
 
2371
  if ( empty( $error ) ) {
2372
  $message = $unzip_status->get_error_message();
2373
+ $data = $unzip_status->get_error_data();
2374
+ $error = sprintf( '%1$s%2$s', $message, is_string( $data ) && ! empty( $data ) ? ': ' . $data : '' );
2375
  }
2376
 
2377
+ return [ 'error' => $error ];
 
 
2378
  }
2379
 
2380
  /**
2394
  * will contain a database dump, so we may be able to skip this step.
2395
  */
2396
  $db_dump_filepath = $this->get_dump_file( $filepath );
2397
+ $this->logger->add( 'Attempting database restoration... $db_dump_filepath = ' . $db_dump_filepath );
2398
+ $this->logger->add_memory();
2399
  if ( ! $dryrun && ! empty( $db_dump_filepath ) ) {
2400
  $db_prefix = null;
2401
 
2412
  }
2413
  }
2414
 
2415
+ // Determine if the dump file is encrypted.
2416
+ $this->archive->init( $filepath );
2417
+ $db_encrypted = $this->archive->get_attribute( 'encrypt_db' );
2418
+
2419
  // Restore the database and then delete the dump.
2420
+ $restore_ok = $this->restore_database( $db_dump_filepath, $db_prefix, $db_encrypted );
2421
  $this->wp_filesystem->delete( $db_dump_filepath, false, 'f' );
2422
 
2423
  // Display notice of deletion status.
2424
  if ( ! $restore_ok ) {
2425
+ $error_message = esc_html__( 'Could not restore database.', 'boldgrid-backup' );
2426
+ $this->logger->add( $error_message );
2427
+ return [ 'error' => $error_message ];
2428
  }
2429
  }
2430
+ $this->logger->add( 'Database restoration complete.' );
2431
+ $this->logger->add_memory();
2432
 
2433
  // Clear rollback information and restoration cron jobs that may be present.
2434
  $this->auto_rollback->cancel();
2438
 
2439
  // If enabled, send email notification for restoration completed.
2440
  if ( ! empty( $settings['notifications']['restore'] ) ) {
2441
+ $this->logger->add( 'Sending "restoration complete" email notification...' );
2442
+
2443
  // Include the mail template.
2444
  include BOLDGRID_BACKUP_PATH . '/admin/partials/boldgrid-backup-admin-mail-restore.php';
2445
 
2446
  // Send the notification.
2447
  // Parameters come from the included mail template file.
2448
  $info['mail_success'] = $this->email->send( $subject, $body );
2449
+
2450
+ $this->logger->add( 'Email sent. Status: ' . ( empty( $info['mail_success'] ) ? 'Fail' : 'Success' ) );
2451
  }
2452
 
2453
  // Update status.
2456
  // Check backup directory.
2457
  $info['backup_directory_set'] = $this->backup_dir->get();
2458
 
2459
+ $this->logger->add( 'Restoration complete!' );
2460
+
2461
+ $this->restoring_archive_file = false;
2462
+
2463
  // Return info array.
2464
  return $info;
2465
  }
2495
 
2496
  $this->auto_rollback->enqueue_home_scripts();
2497
  $this->auto_rollback->enqueue_backup_scripts();
2498
+ $this->archive_actions->enqueue_scripts();
2499
 
2500
  $this->folder_exclusion->enqueue_scripts();
2501
  $this->db_omit->enqueue_scripts();
2532
 
2533
  // Include the home page template.
2534
  include BOLDGRID_BACKUP_PATH . '/admin/partials/boldgrid-backup-admin-home.php';
 
 
2535
  }
2536
 
2537
  /**
2563
 
2564
  $this->is_backup_now = true;
2565
 
2566
+ $is_all_files = isset( $_POST['folder_exclusion_type'] ) && 'full' === $_POST['folder_exclusion_type'];
2567
+ $is_all_tables = isset( $_POST['table_inclusion_type'] ) && 'full' === $_POST['table_inclusion_type'];
2568
+ $this->is_backup_full = $is_all_files && $is_all_tables;
2569
 
2570
  $this->is_archiving_update_protection = ! empty( $_POST['is_updating'] ) &&
2571
  'true' === $_POST['is_updating'];
2572
 
2573
  $archive_info = $this->archive_files( true );
2574
 
2575
+ // If there were any errors encountered during the backup, save them to the In Progress data.
2576
+ if ( ! empty( $archive_info['error'] ) ) {
2577
+ Boldgrid_Backup_Admin_In_Progress_Data::set_arg( 'error', $archive_info['error'] );
2578
+ }
2579
+
2580
+ if ( $this->is_archiving_update_protection ) {
 
2581
  update_site_option( 'boldgrid_backup_pending_rollback', $archive_info );
 
 
 
2582
  }
2583
+
2584
+ /*
2585
+ * Finish.
2586
+ *
2587
+ * Normally we'd give the user a notice that the backup has been completed. However, since
2588
+ * 1.11.2, we are no longer waiting for this ajax call to complete. The "in progress" bar
2589
+ * will give the user any updates they need.
2590
+ */
2591
+ wp_send_json_success();
2592
  }
2593
 
2594
  /**
2598
  * a message should be displayed with the path to download using an alternate method.
2599
  *
2600
  * @since 1.0
2601
+ *
2602
+ * @see Boldgrid_Backup_File::send_file()
2603
  */
2604
  public function download_archive_file_callback() {
2605
  // Verify nonce, or die.
2661
 
2662
  $filesize = $archives[ $download_key ]['filesize'];
2663
 
2664
+ if ( isset( $this->activity ) ) {
2665
+ $this->activity->add( 'download_to_local_machine', 1, $this->rating_prompt_config );
 
 
 
 
 
 
 
2666
  }
2667
 
2668
+ // Send the file and die nicely.
2669
+ Boldgrid_Backup_File::send_file( $filepath, $filesize );
 
 
 
 
 
 
2670
  }
2671
 
2672
  /**
2676
  *
2677
  * @global string $wp_version The WordPress version string.
2678
  * @global wpdb $wpdb The WordPress database class object.
 
 
2679
  */
2680
  public function page_backup_test() {
2681
  // Perform functionality tests.
2712
 
2713
  $disk_space = $this->test->get_disk_space();
2714
 
2715
+ /*
2716
+ * Cron time zone testing.
2717
+ *
2718
+ * This set of code may modify cron jobs. Be sure to run before we get the cron jobs below
2719
+ * so that we give the user accurate info about which cron jobs are set.
2720
+ */
2721
+ if ( ! empty( $_POST['cron_timezone_test'] ) && check_admin_referer( 'cron_timezone_test' ) ) { // Input var okay.
2722
+ $this->cron_test->setup();
2723
+ } elseif ( ! $this->cron_test->is_running() ) {
2724
+ $this->cron_test->clean_up();
2725
+ }
2726
+
2727
  // Get our crons and ready them for display.
2728
  $our_crons = $this->cron->get_our_crons();
2729
  foreach ( $our_crons as &$cron ) {
2734
  $cron = esc_html( $cron );
2735
  }
2736
 
2737
+ $cli_support = $this->test->get_cli_support();
2738
+
2739
  // Enqueue CSS for the test page.
2740
+ wp_enqueue_style(
2741
+ 'boldgrid-backup-admin-test',
2742
+ plugin_dir_url( __FILE__ ) . 'css/boldgrid-backup-admin-test.css',
2743
+ [],
2744
  BOLDGRID_BACKUP_VERSION, 'all'
2745
  );
2746
 
2747
  // Load template view.
2748
  include BOLDGRID_BACKUP_PATH . '/admin/partials/boldgrid-backup-admin-test.php';
2749
+ }
2750
 
2751
+ /**
2752
+ * Set doing_cron.
2753
+ *
2754
+ * $this->doing_cron specifies whether or not we're doing cron.
2755
+ *
2756
+ * When we're generating a backup, both via cron and wpcron, doing_cron is true.
2757
+ *
2758
+ * @uses $_GET['doing_wp_cron'] The timestamp the cron has been triggered. Please see:
2759
+ * @link https://github.com/WordPress/WordPress/blob/5.1.1/wp-cron.php#L84-L96
2760
+ * @link https://github.com/WordPress/WordPress/blob/5.1.1/wp-includes/cron.php#L635-L639
2761
+ *
2762
+ * @since 1.9.2
2763
+ */
2764
+ public function set_doing_cron() {
2765
+ $this->doing_cron = ( defined( 'DOING_CRON' ) && DOING_CRON ) || isset( $_GET['doing_wp_cron'] ); // phpcs:ignore WordPress.CSRF.NonceVerification.NoNonceVerification
2766
  }
2767
 
2768
  /**
2771
  * @since 1.5.3
2772
  */
2773
  public function set_lang() {
2774
+ /*
2775
+ * The "want_to" string is a generic "why you should upgrade" string used for general
2776
+ * purposes. For example, it's currently used at the bottom of the backups page.
2777
+ */
2778
+ $this->lang = [
2779
  // Mine count, total number of backups.
2780
+ 'All' => esc_html__( 'All', 'boldgrid-backup' ),
2781
+ 'backup_created' => esc_html__( 'Backup created successfully!', 'boldgrid-backup' ),
2782
+ 'Checking_credentials' => esc_html__( 'Checking credentials', 'boldgrid-backup' ),
2783
+ 'checkmark' => '&#10003;',
2784
+ 'get_support' => wp_kses(
2785
+ sprintf(
2786
+ // translators: 1 The opening anchor tag to the support tab, 2 its closing anchor tag.
2787
+ esc_html__( 'Please try again. If you continue to experience problems, please %1$scontact us for additional support%2$s.', 'boldgrid-backup' ),
2788
+ '<a href="' . esc_url( admin_url( 'admin.php?page=boldgrid-backup-support' ) ) . '">',
2789
+ '</a>'
2790
+ ),
2791
+ [ 'a' => [ 'href' => [] ] ]
2792
+ ),
2793
+ 'icon_success' => '<span class="dashicons dashicons-yes green"></span> ',
2794
+ 'icon_warning' => '<span class="dashicons dashicons-warning yellow"></span> ',
2795
+ 'heading_update_protection' => BOLDGRID_BACKUP_TITLE . ' - ' . esc_html__( 'Update Protection', 'boldgrid-backup' ),
2796
  // Mine count, number of backups on remote storage providers.
2797
+ 'Remote' => esc_html__( 'Remote', 'boldgrid-backup' ),
2798
+ 'spinner' => '<span class="spinner"></span>',
2799
+ 'spinner_inline' => '<span class="spinner inline"></span>',
2800
+
2801
+ /*
2802
+ * The "want_to" string is a generic "why you should upgrade" string used for general
2803
+ * purposes. For example, it's currently used at the bottom of the backups page.
2804
+ */
2805
+ 'want_to' => sprintf(
2806
+ // translators: 1 Markup showing a "Google Drive" logo, 2 Markup showing an "Amazon S3" logo.
2807
+ __( 'Catastrophic data loss can happen at any time. Storing your archives in multiple secure locations will keep your website data safe and put your mind at ease. Upgrade to %3$s to enable automated remote backups to %1$s and %2$s', 'boldgrid-backup' ),
2808
+ '<span class="bgbkup-remote-logo bgbkup-gdrive-logo" title="Google Drive"></span>',
2809
+ '<span class="bgbkup-remote-logo amazon-s3-logo" title="Amazon S3"></span>',
2810
+ BOLDGRID_BACKUP_TITLE . ' Premium'
2811
+ ),
2812
  // Mine count, number of backups on local web server.
2813
+ 'Web_Server' => esc_html__( 'Web Server', 'boldgrid-backup' ),
2814
+ ];
2815
 
2816
+ $this->elements = [
2817
+ 'update_protection_activated' => sprintf( '%1$s %2$s', $this->lang['icon_success'], esc_html__( 'Update protection activated!', 'boldgrid-backup' ) ),
2818
  // Use on long loading pages. Javascript will remove this on page load.
2819
+ 'long_checking_creds' => sprintf( '<div class="bgbu-remove-load">%1$s %2$s</div>', $this->lang['Checking_credentials'], $this->lang['spinner_inline'] ),
2820
+ ];
2821
  }
2822
 
2823
  /**
2831
  * @param int $time_limit Limit in seconds.
2832
  */
2833
  public function set_time_limit( $time_limit = 900 ) {
2834
+ $max_execution_time = ini_get( 'max_execution_time' );
2835
+
2836
+ set_time_limit( ( $max_execution_time > $time_limit ? $max_execution_time : $time_limit ) );
 
2837
  }
2838
 
2839
  /**
2840
  * Handle ajax request to restore a file.
2841
  *
2842
+ * @since 1.6.0
2843
  */
2844
  public function wp_ajax_restore() {
2845
+ $error = esc_html__( 'Unable to restore backup: ', 'boldgrid-backup' );
2846
+ $redirect_url = esc_url( admin_url( 'admin.php?page=boldgrid-backup' ) );
2847
 
2848
  // Validate user role.
2849
  if ( ! current_user_can( 'update_plugins' ) ) {
2878
  */
2879
  $is_success = ! empty( $archive_info ) && empty( $archive_info['error'] );
2880
  if ( $is_success ) {
2881
+ $message = [
2882
  'message' => esc_html__( 'The selected archive file has been successfully restored.', 'boldgrid-backup' ),
2883
+ 'class' => 'notice notice-success is-dismissible',
2884
+ 'header' => BOLDGRID_BACKUP_TITLE . ' - ' . esc_html__( 'Restoration complete' ),
2885
+ ];
2886
  } else {
2887
+ $message = [
2888
+ 'message' => ! empty( $archive_info['error'] ) ? $archive_info['error'] : esc_html__( 'Unknown error when attempting to restore archive.', 'bolcgrid-backup' ),
2889
+ 'class' => 'notice notice-error is-dismissible',
2890
+ 'header' => BOLDGRID_BACKUP_TITLE . ' - ' . esc_html__( 'Restoration failed' ),
2891
+ ];
2892
  }
2893
  $this->notice->add_user_notice( $message['message'], $message['class'], $message['header'] );
2894
 
2895
+ wp_send_json_success( [ 'redirect_url' => $redirect_url ] );
 
 
2896
  }
2897
 
2898
  /**
2927
  }
2928
 
2929
  // Perform the backup operation.
2930
+ $this->archive_files( true );
 
 
2931
  }
2932
 
2933
  /**
2940
  * @return null
2941
  */
2942
  public function enforce_retention() {
2943
+ $logger = new Boldgrid_Backup_Admin_Log( $this );
2944
+ $logger->init( 'retention-local.log' );
2945
+ $logger->add( 'Beginning core::enforce_retention...' );
2946
+
2947
  $settings = $this->settings->get_settings();
2948
+ $logger->add( 'Retention count: ' . $settings['retention_count'] );
2949
 
 
2950
  $archives = $this->get_archive_list();
2951
+ $logger->add( 'Number of archives found: ' . count( $archives ) );
2952
+
2953
+ // Remove from the list of archives any that have been flagged as being protected.
2954
+ $protected_count = 0;
2955
+ foreach ( $archives as $key => $archive ) {
2956
+ $this->archive->init( $archive['filepath'] );
2957
+ if ( '1' === $this->archive->get_attribute( 'protect' ) ) {
2958
+ unset( $archives[ $key ] );
2959
+ $protected_count++;
2960
+ }
2961
+ }
2962
+ $logger->add( 'Number of protected archives found: ' . $protected_count );
2963
+ $archives = array_values( $archives );
2964
 
2965
  // Get the archives file count.
2966
  $archives_count = count( $archives );
2967
 
2968
  // If the archive count is not beyond the set retention count, then return.
2969
  if ( empty( $settings['retention_count'] ) || $archives_count <= $settings['retention_count'] ) {
2970
+ $logger->add( 'No backups to delete at this time due to retention settings.' );
2971
  return;
2972
  }
2973
 
 
 
 
2974
  // Initialize $counter.
2975
  $counter = $archives_count - 1;
2976
 
2984
 
2985
  // Delete the specified archive file.
2986
  $deleted = $this->archive->delete( $filepath );
 
 
 
 
 
 
 
 
 
 
 
 
 
2987
 
2988
  // Decrease the archive count.
2989
  $archives_count --;
2990
 
2991
  // Increment the counter.
2992
  $counter --;
2993
+
2994
+ if ( $deleted ) {
2995
+ $logger->add( 'Deleted ' . $filepath );
2996
+
2997
+ /**
2998
+ * Take action after a backup has been deleted due to retention.
2999
+ *
3000
+ * @since 1.5.3
3001
+ *
3002
+ * @param string $filepath
3003
+ */
3004
+ do_action( 'boldgrid_backup_retention_deleted', $filepath );
3005
+ } else {
3006
+ $logger->add( 'Failed to delete ' . $filepath );
3007
+ }
3008
  }
3009
 
3010
+ $logger->add( 'Completed core::enforce_retention.' );
3011
+ $logger->add_separator();
3012
  }
3013
  }
admin/class-boldgrid-backup-admin-cron-log.php ADDED
@@ -0,0 +1,256 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File: class-boldgrid-backup-admin-cron-log.php
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.6.5
7
+ *
8
+ * @package Boldgrid_Backup
9
+ * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
+ * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
+ */
14
+
15
+ /**
16
+ * Class: Boldgrid_Backup_Admin_Cron_Log
17
+ *
18
+ * @since 1.6.5
19
+ */
20
+ class Boldgrid_Backup_Admin_Cron_Log {
21
+
22
+ /**
23
+ * The core class object.
24
+ *
25
+ * @since 1.6.5
26
+ * @access private
27
+ * @var Boldgrid_Backup_Admin_Core
28
+ */
29
+ private $core;
30
+
31
+ /**
32
+ * The full path to the log file.
33
+ *
34
+ * @since 1.6.5
35
+ * @access private
36
+ * @var string
37
+ */
38
+ private $log_path;
39
+
40
+ /**
41
+ * The name of our log file.
42
+ *
43
+ * @since 1.6.5
44
+ * @access static
45
+ * @var string
46
+ */
47
+ public static $log_name = 'boldgrid-backup-cron.log';
48
+
49
+ /**
50
+ * Constructor.
51
+ *
52
+ * @since 1.6.5
53
+ *
54
+ * @param Boldgrid_Backup_Admin_Core $core Core class object.
55
+ */
56
+ public function __construct( $core ) {
57
+ $this->core = $core;
58
+
59
+ $this->log_path = trailingslashit( BOLDGRID_BACKUP_PATH ) . self::$log_name;
60
+ }
61
+
62
+ /**
63
+ * Add an entry to the log.
64
+ *
65
+ * This is a static method accessed outside of the scope of WordPress (boldgrid-backup-cron.php).
66
+ * Therefore, we do not have access to any WordPress specific functions.
67
+ *
68
+ * @since 1.6.5
69
+ *
70
+ * @param string $message A message to add to the log.
71
+ */
72
+ public static function add_log( $message ) {
73
+ $file = dirname( __DIR__ ) . '/' . self::$log_name;
74
+ $data = array();
75
+
76
+ // Get data already in the file.
77
+ if ( file_exists( $file ) && is_readable( $file ) ) {
78
+ $current_contents = file_get_contents( $file ); // phpcs:ignore
79
+ $data = empty( $current_contents ) ? array() : json_decode( $current_contents, true );
80
+ }
81
+
82
+ $data[] = array(
83
+ 'time' => time(),
84
+ 'message' => $message,
85
+ 'read' => false,
86
+ );
87
+
88
+ // Only keep the last 10 entries.
89
+ $data = array_slice( $data, -10, 10 );
90
+
91
+ file_put_contents( $file, json_encode( $data ) ); // phpcs:ignore
92
+ }
93
+
94
+ /**
95
+ * Display an admin notice to the user informing them of new cron notices.
96
+ *
97
+ * @since 1.6.5
98
+ */
99
+ public function admin_notice() {
100
+ if ( ! current_user_can( 'update_plugins' ) || ! $this->has_unread() || $this->on_log_page() ) {
101
+ return;
102
+ }
103
+
104
+ $message = sprintf(
105
+ wp_kses(
106
+ /* translators: %1$s is the URL to view the cron log. */
107
+ __( 'Your latest <em>scheduled backup</em> may not have finished successfully. For more info, please <a href="%1$s">click here</a> to see your latest <em>cron notices</em>.', 'boldgrid-backup' ),
108
+ array(
109
+ 'a' => array(
110
+ 'href' => array(),
111
+ ),
112
+ 'em' => array(),
113
+ 'strong' => array(),
114
+ )
115
+ ), esc_url( 'admin.php?page=boldgrid-backup-tools&section=section_cron_log' )
116
+ );
117
+
118
+ $this->core->notice->boldgrid_backup_notice( $message );
119
+ }
120
+
121
+ /**
122
+ * Get our log.
123
+ *
124
+ * @since 1.6.5
125
+ *
126
+ * @return array An array of log entries.
127
+ */
128
+ public function get_log() {
129
+ $log = array();
130
+
131
+ if ( ! $this->core->wp_filesystem->exists( $this->log_path ) || ! $this->core->wp_filesystem->is_readable( $this->log_path ) ) {
132
+ return $log;
133
+ }
134
+
135
+ $contents = $this->core->wp_filesystem->get_contents( $this->log_path );
136
+ return json_decode( $contents, true );
137
+ }
138
+
139
+ /**
140
+ * Generate and return the markup displaying our log entries.
141
+ *
142
+ * @since 1.6.5
143
+ */
144
+ public function get_markup() {
145
+
146
+ // If we're getting the markup, the user is looking at it. Mark it as read.
147
+ $this->set_as_read();
148
+
149
+ $log = $this->get_log();
150
+
151
+ $markup = '<h2>' . __( 'Latest Cron Notices', 'boldgrid-backup' ) . '</h2>
152
+ <p>' . __( 'If a scheduled backup cron fails, an error message will be logged to the <em>cron notices</em> log file. You can view those log entries below:', 'boldgrid-backup' ) . '</p>';
153
+
154
+ if ( empty( $log ) ) {
155
+ $markup .= '<p><em>' . __( 'No entries in the log.', 'boldgrid-backup' ) . '</em></p>';
156
+ } else {
157
+ $markup .= '<table class="wp-list-table widefat fixed striped">
158
+ <thead>
159
+ <tr>
160
+ <th style="width:150px;">' . __( 'Time', 'boldgrid-backup' ) . '</th>
161
+ <th>' . __( 'Message', 'boldgrid-backup' ) . '</th>
162
+ </tr>
163
+ </thead>';
164
+
165
+ foreach ( $log as $item ) {
166
+ $this->core->time->init( $item['time'] );
167
+ $time = $this->core->time->get_span();
168
+ $message = esc_html( $item['message'] );
169
+
170
+ $markup .= sprintf( '<tr><th>%1$s</th><td>%2$s</td></tr>', $time, $message );
171
+ }
172
+
173
+ $markup .= '</table>';
174
+ }
175
+
176
+ return $markup;
177
+ }
178
+
179
+ /**
180
+ * Whether or not there are unread messages.
181
+ *
182
+ * @since 1.6.5
183
+ *
184
+ * @return bool
185
+ */
186
+ public function has_unread() {
187
+ $log = $this->get_log();
188
+
189
+ if ( empty( $log ) ) {
190
+ return false;
191
+ }
192
+
193
+ foreach ( $log as $item ) {
194
+ if ( empty( $item['read'] ) ) {
195
+ return true;
196
+ }
197
+ }
198
+
199
+ return false;
200
+ }
201
+
202
+ /**
203
+ * Whether or not we are on the logs page.
204
+ *
205
+ * Specifically, if the user clicked "click here" to be taken to
206
+ * admin.php?page=boldgrid-backup-tools&section=section_cron_log
207
+ *
208
+ * @since 1.6.5
209
+ *
210
+ * @return bool
211
+ */
212
+ public function on_log_page() {
213
+ global $pagenow;
214
+
215
+ $on_login_page = 'admin.php' === $pagenow;
216
+
217
+ $params = array(
218
+ array(
219
+ 'key' => 'page',
220
+ 'value' => 'boldgrid-backup-tools',
221
+ ),
222
+ array(
223
+ 'key' => 'section',
224
+ 'value' => 'section_cron_log',
225
+ ),
226
+ );
227
+
228
+ foreach ( $params as $param ) {
229
+ if ( empty( $_GET[ $param['key'] ] ) || $param['value'] !== $_GET[ $param['key'] ] ) { // phpcs:ignore
230
+ $on_login_page = false;
231
+ }
232
+ }
233
+
234
+ return $on_login_page;
235
+ }
236
+
237
+ /**
238
+ * Set the log as being read.
239
+ *
240
+ * @since 1.6.5
241
+ *
242
+ * @return bool Whether or not the log file was updated successfully.
243
+ */
244
+ public function set_as_read() {
245
+ $log = $this->get_log();
246
+ if ( empty( $log ) ) {
247
+ return true;
248
+ }
249
+
250
+ foreach ( $log as &$item ) {
251
+ $item['read'] = true;
252
+ }
253
+
254
+ return $this->core->wp_filesystem->put_contents( $this->log_path, wp_json_encode( $log ) );
255
+ }
256
+ }
admin/class-boldgrid-backup-admin-cron-test.php ADDED
@@ -0,0 +1,246 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File: class-boldgrid-backup-admin-cron-test.php
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.6.5
7
+ *
8
+ * @package Boldgrid_Backup
9
+ * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
+ * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
+ */
14
+
15
+ /**
16
+ * Class: Boldgrid_Backup_Admin_Cron_Test
17
+ *
18
+ * @since 1.6.5
19
+ */
20
+ class Boldgrid_Backup_Admin_Cron_Test {
21
+
22
+ /**
23
+ * The core class object.
24
+ *
25
+ * @since 1.6.5
26
+ * @access private
27
+ * @var Boldgrid_Backup_Admin_Core
28
+ */
29
+ private $core;
30
+
31
+ /**
32
+ * Path to config file.
33
+ *
34
+ * @since 1.6.5
35
+ * @access private
36
+ * @var string
37
+ */
38
+ private $cron_config_path;
39
+
40
+ /**
41
+ * Path to php file, which is ran via cron.
42
+ *
43
+ * @since 1.6.5
44
+ * @access private
45
+ * @var string
46
+ */
47
+ private $cron_path;
48
+
49
+ /**
50
+ * Path to results.
51
+ *
52
+ * @since 1.6.5
53
+ * @access private
54
+ * @var string
55
+ */
56
+ private $cron_result_path;
57
+
58
+ /**
59
+ * Constructor.
60
+ *
61
+ * @since 1.6.5
62
+ *
63
+ * @param Boldgrid_Backup_Admin_Core $core Core class object.
64
+ */
65
+ public function __construct( $core ) {
66
+ $this->core = $core;
67
+
68
+ $this->cron_path = BOLDGRID_BACKUP_PATH . '/cron/cron-test.php';
69
+ $this->cron_config_path = BOLDGRID_BACKUP_PATH . '/cron/cron-test.config';
70
+ $this->cron_result_path = BOLDGRID_BACKUP_PATH . '/cron/cron-test.result';
71
+ }
72
+
73
+ /**
74
+ * Clean up the test.
75
+ *
76
+ * Delete the config file and remove the cron entries.
77
+ *
78
+ * @since 1.6.5
79
+ */
80
+ public function clean_up() {
81
+ wp_delete_file( $this->cron_config_path );
82
+ $this->core->cron->entry_delete_contains( $this->cron_path );
83
+ }
84
+
85
+ /**
86
+ * Generate the markup used on the prefligh check page.
87
+ *
88
+ * Ensure markup generated by this method are compatible with $allowed_tags configured in
89
+ * admin/partials/boldgrid-backup-admin-test.php.
90
+ *
91
+ * @since 1.6.5
92
+ *
93
+ * @return string
94
+ */
95
+ public function get_preflight_markup() {
96
+ $server_offset = $this->core->time->get_server_offset();
97
+ $cron_offset = $this->get_offset();
98
+ $offset_match = (int) $server_offset === (int) $cron_offset;
99
+ $markup = '';
100
+
101
+ $run_test = '<p>
102
+ <form method="post" action="admin.php?page=boldgrid-backup-test">
103
+ <input type="hidden" name="cron_timezone_test" value="1" />
104
+ <input type="submit" value="%1$s" class="button" style="vertical-align:baseline;" /> (' . __( 'Test may take up to 25 minutes to complete', 'boldgrid-backup' ) . ')
105
+ ' . wp_nonce_field( 'cron_timezone_test', '_wpnonce', true, false ) . '
106
+ </form>
107
+ </p>';
108
+
109
+ $no = sprintf(
110
+ '<span class="warning">%1$s</span><br />%2$s',
111
+ __( 'No', 'boldgrid-backup' ),
112
+ __( 'Please contact your server administrator for assistance with troubleshooting.' )
113
+ );
114
+
115
+ if ( $this->is_running() ) {
116
+ $markup .= '<p><span class="spinner inline"></span>' . __( 'This test is in progress, and may take up to 25 minutes to complete. Refresh this page for an update.', 'boldgrid-backup' ) . '</p>';
117
+ } elseif ( false === $cron_offset ) {
118
+ $markup .= sprintf( $run_test, esc_attr( __( 'Run test', 'boldgrid-backup' ) ) );
119
+ } else {
120
+ $match_markup = ( $offset_match ? __( 'Yes', 'boldgrid-backup' ) : $no );
121
+ $markup = $match_markup . $markup;
122
+
123
+ $markup .= '<p>' . __( 'Server offset', 'boldgrid-backup' ) . ': ' . $server_offset . '<br />';
124
+ $markup .= __( 'Cron offset' ) . ': ' . $cron_offset . '</p>';
125
+
126
+ $markup .= sprintf( $run_test, esc_attr( __( 'Run test again', 'boldgrid-backup' ) ) );
127
+ }
128
+
129
+ // Help info, displayed by clicking the help icon.
130
+ $markup .= '<p class="help" data-id="cron-time-zone">' . __( 'Cron should run in the same time zone as your server. For example, if your server timezone is EST, setting a cron to run at 5am should run it at 5am EST. This test runs a series of cron jobs to determine which timezone is used by Cron.', 'boldgrid-backup' ) . '</p>';
131
+
132
+ return $markup;
133
+ }
134
+
135
+ /**
136
+ * Get the cron offset.
137
+ *
138
+ * This looks in the cron-test.result file for the data.
139
+ *
140
+ * @since 1.6.5
141
+ *
142
+ * @return mixed
143
+ */
144
+ public function get_offset() {
145
+ $result = $this->core->wp_filesystem->get_contents( $this->cron_result_path );
146
+ if ( ! $result ) {
147
+ return false;
148
+ }
149
+
150
+ $result = json_decode( $result, true );
151
+
152
+ return isset( $result['offset'] ) ? $result['offset'] : false;
153
+ }
154
+
155
+ /**
156
+ * Whether or not the test is currently running.
157
+ *
158
+ * @since 1.6.5
159
+ *
160
+ * @return bool
161
+ */
162
+ public function is_running() {
163
+ $config_file_exists = $this->core->wp_filesystem->exists( $this->cron_config_path );
164
+
165
+ $matching_crons = $this->core->cron->entry_search( $this->cron_path );
166
+
167
+ return false === $this->get_offset() && $config_file_exists && ! empty( $matching_crons );
168
+ }
169
+
170
+ /**
171
+ * Setup the tests.
172
+ *
173
+ * HERE'S THE PROBLEM:
174
+ * Cron is supposed to run using the server's timezone. In one scenario, the crons were not running
175
+ * when we expected them to. Further troubleshooting found that the server was set to PDT and the
176
+ * Crons were running at EDT times. So, our 5am PDT cron was actually running at 5am EDT. It took
177
+ * a while to figure this out, so this test was built.
178
+ *
179
+ * HERE'S HOW THIS TEST WORKS:
180
+ * We get the current UTC time. Let's say it's 3:15 pm. We then setup the following crons:
181
+ *
182
+ * # 3:18 pm (UTC)
183
+ * # 4:19 pm (UTC+1)
184
+ * # 5:20 pm (UTC+2)
185
+ *
186
+ * We don't know when each of these crons will actually run, but they're basically 1 hour and
187
+ * 1 minute apart. When the first of these crons actually does run, the script it triggers (cron-test.php)
188
+ * will look at the current MINUTE. Using the example above, if the minute is 19, then we know cron
189
+ * is running on UTC+1 time. If the minute is 20, then we know we're running at UTC+2.
190
+ *
191
+ * The array of times to offsets (like 4:19 pm = UTC+1) is stored in the cron-test.config file.
192
+ *
193
+ * @since 1.6.5
194
+ */
195
+ public function setup() {
196
+
197
+ // Delete the log, the config file, and all existing crons.
198
+ $this->clean_up();
199
+ wp_delete_file( $this->cron_result_path );
200
+
201
+ $time_data = array();
202
+ $unix_time = time();
203
+ $minutes_ahead = 3;
204
+ // When looping through offsets, begin at the user's offset so test completes faster.
205
+ $server_offset = (int) $this->core->time->get_server_offset();
206
+
207
+ /*
208
+ * Add our cron jobs.
209
+ *
210
+ * Currently, we are only doing hour increments. A few 30 & 45 minute offsets exist, but this
211
+ * test is really for edge cases, and those 30/45 offsets are edge cases too. We'll get to those
212
+ * later.
213
+ *
214
+ * @see https://www.timeanddate.com/time/time-zones-interesting.html
215
+ */
216
+ for ( $x = 1; $x <= 25; $x++ ) {
217
+ $cron_time = $unix_time + ( $server_offset * 60 * 60 ) + ( $minutes_ahead * 60 );
218
+
219
+ $time_data[] = array(
220
+ 'time' => $cron_time,
221
+ 'offset' => $server_offset,
222
+ );
223
+
224
+ // Add our cron. Use (int) to make sure our minutes do not have leading zero's.
225
+ $cron_command = (int) date( 'i', $cron_time ) . ' ' . date( 'G * * *', $cron_time ) . ' php -d register_argc_argv=1 -qf ' . $this->cron_path . ' > /dev/null 2>&1';
226
+ $all_crons_added = $this->core->cron->update_cron( $cron_command );
227
+
228
+ if ( ! $all_crons_added ) {
229
+ break;
230
+ }
231
+
232
+ $minutes_ahead++;
233
+ // Server offset must be between -12 and 12.
234
+ $server_offset++;
235
+ $server_offset = $server_offset > 12 ? -12 : $server_offset;
236
+ }
237
+
238
+ if ( $all_crons_added ) {
239
+ $this->core->wp_filesystem->put_contents( $this->cron_config_path, wp_json_encode( $time_data ) );
240
+ } else {
241
+ $error = __( 'Failed to setup Cron time zone test.', 'boldgrid-backup' );
242
+ $this->core->notice->boldgrid_backup_notice( $error );
243
+ $this->clean_up();
244
+ }
245
+ }
246
+ }
admin/class-boldgrid-backup-admin-cron.php CHANGED
@@ -1,19 +1,21 @@
1
  <?php
2
  /**
3
- * The admin-specific cron functionality of the plugin
4
  *
5
- * @link http://www.boldgrid.com
6
  * @since 1.2
7
  *
8
- * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
- * @copyright BoldGrid.com
11
- * @version $Id$
12
- * @author BoldGrid.com <wpb@boldgrid.com>
13
  */
14
 
 
 
15
  /**
16
- * BoldGrid Backup admin cron class.
17
  *
18
  * @since 1.2
19
  */
@@ -28,12 +30,34 @@ class Boldgrid_Backup_Admin_Cron {
28
  private $core;
29
 
30
  /**
31
- * Path to run_jobs.php
32
  *
33
  * @since 1.5.2
34
  * @var string
35
  */
36
- public $run_jobs = 'cron/run_jobs.php';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
 
38
  /**
39
  * A cron secret used to validate unauthenticated crontab jobs.
@@ -51,7 +75,7 @@ class Boldgrid_Backup_Admin_Cron {
51
  *
52
  * @var string
53
  */
54
- public $crontab_version = '1.6.1';
55
 
56
  /**
57
  * Constructor.
@@ -65,6 +89,15 @@ class Boldgrid_Backup_Admin_Cron {
65
  $this->core = $core;
66
  }
67
 
 
 
 
 
 
 
 
 
 
68
  /**
69
  * Add cron entry for backups from stored settings.
70
  *
@@ -75,29 +108,29 @@ class Boldgrid_Backup_Admin_Cron {
75
  * @see BoldGrid_Backup_Admin_Core::get_backup_identifier()
76
  * @see BoldGrid_Backup_Admin_Cron::get_cron_secret()
77
  *
78
- * @param array $settings
79
  * @return bool Success.
80
  */
81
- public function add_cron_entry( $settings = array() ) {
82
  if ( empty( $settings ) ) {
83
  $settings = $this->core->settings->get_settings();
84
  }
85
 
86
  // Delete existing backup cron jobs.
87
- $cron_status = $this->delete_cron_entries();
88
 
89
  // Initialize $days_scheduled_list.
90
  $days_scheduled_list = '';
91
 
92
  // Create an array of days index names.
93
  $days = array(
94
- 'dow_sunday' => 0,
95
- 'dow_monday' => 1,
96
- 'dow_tuesday' => 2,
97
  'dow_wednesday' => 3,
98
- 'dow_thursday' => 4,
99
- 'dow_friday' => 5,
100
- 'dow_saturday' => 6,
101
  );
102
 
103
  // Add scheduled days to the list.
@@ -130,7 +163,7 @@ class Boldgrid_Backup_Admin_Cron {
130
  // Build cron job line in crontab format.
131
  $entry = $date->format( 'i G' ) . ' * * ';
132
 
133
- $entry .= $days_scheduled_list . ' php -qf "' . dirname( dirname( __FILE__ ) ) .
134
  '/boldgrid-backup-cron.php" mode=backup siteurl=' . get_site_url() . ' id=' .
135
  $this->core->get_backup_identifier() . ' secret=' . $this->get_cron_secret();
136
 
@@ -157,26 +190,30 @@ class Boldgrid_Backup_Admin_Cron {
157
  *
158
  * @since 1.6.0
159
  *
160
- * @param array $settings
161
  * @return bool
162
  */
163
- public function add_all_crons( $settings ) {
164
  $success = false;
165
 
166
  $scheduler = ! empty( $settings['scheduler'] ) ? $settings['scheduler'] : null;
167
- $schedule = ! empty( $settings['schedule'] ) ? $settings['schedule'] : null;
168
 
169
- if ( 'cron' === $scheduler && $this->core->scheduler->is_available( $scheduler ) && ! empty( $schedule ) ) {
170
  $this->core->scheduler->clear_all_schedules();
171
 
172
- $scheduled = $this->add_cron_entry( $settings );
 
 
 
173
  $jobs_scheduled = $this->schedule_jobs();
 
174
 
175
  $success = $scheduled && $jobs_scheduled;
176
 
177
  if ( $success ) {
178
  $settings['crontab_version'] = $this->crontab_version;
179
- $settings['cron_secret'] = $this->get_cron_secret();
180
  update_site_option( 'boldgrid_backup_settings', $settings );
181
  }
182
  }
@@ -196,76 +233,23 @@ class Boldgrid_Backup_Admin_Cron {
196
  * @see Boldgrid_Backup_Admin_Test::is_windows()
197
  * @see BoldGrid_Backup_Admin_Core::get_backup_identifier()
198
  * @see BoldGrid_Backup_Admin_Cron::get_cron_secret()
199
- *
200
- * @return null
201
  */
202
  public function add_restore_cron() {
203
- $pending_rollback = get_site_option( 'boldgrid_backup_pending_rollback' );
204
- $archives = $this->core->get_archive_list();
205
-
206
- // Use the first key to get info on the most recent archive.
207
- $archive_key = 0;
208
-
209
- $archive = $archives[ $archive_key ];
210
-
211
- $archive_filename = $archive['filename'];
212
-
213
  // Remove existing restore cron jobs.
214
  $this->delete_cron_entries( 'restore' );
215
 
216
- // Get the unix time for 5 minutes from now.
217
- $time_5_minutes_later = strtotime( $this->core->auto_rollback->testing_time );
218
-
219
- // Get the system's localized current time (HH:MM:SS), 5 minutes in the future.
220
- $system_time = $this->core->execute_command(
221
- 'date "+%H|%M|%S|%a %d %b %Y %I:%M:00 %p %Z" -d "' . $this->core->auto_rollback->testing_time . '"'
222
- );
223
-
224
- // Split the time into hour, minute, and second.
225
- if ( ! empty( $system_time ) ) {
226
- list( $hour, $minute, $second, $system_time_iso ) = explode( '|', $system_time );
227
- }
228
-
229
- // Validate hour; use system hour, or the date code for hour ("G").
230
- if ( ! isset( $hour ) ) {
231
- $hour = 'G';
232
- }
233
-
234
- // Validate hour; use system hour, or the date code for minute ("i").
235
- if ( ! isset( $minute ) ) {
236
- $minute = 'i';
237
- }
238
-
239
- // Mark the deadline.
240
- if ( ! empty( $system_time_iso ) ) {
241
- $deadline = strtotime( $system_time_iso );
242
- } else {
243
- $deadline = $time_5_minutes_later;
244
- }
245
-
246
- // Build cron job line in crontab format.
247
- $entry = date( $minute . ' ' . $hour, $deadline ) . ' * * ' . date( 'w' ) . ' php -qf "' .
248
- dirname( dirname( __FILE__ ) ) . '/boldgrid-backup-cron.php" mode=restore siteurl=' .
249
- get_site_url() . ' id=' . $this->core->get_backup_identifier() . ' secret=' .
250
- $this->get_cron_secret() . ' archive_key=' . $archive_key .
251
- ' archive_filename=' . $archive_filename;
252
-
253
- // If not Windows, then also silence the cron job.
254
- if ( ! $this->core->test->is_windows() ) {
255
- $entry .= ' > /dev/null 2>&1';
256
- }
257
-
258
- // Update cron.
259
  $status = $this->update_cron( $entry );
 
260
 
261
  // If cron job was added, then update the boldgrid_backup_pending_rollback option with time.
262
  if ( $status ) {
263
- $pending_rollback['deadline'] = $deadline;
 
 
264
 
265
  update_site_option( 'boldgrid_backup_pending_rollback', $pending_rollback );
266
  }
267
-
268
- return;
269
  }
270
 
271
  /**
@@ -320,23 +304,70 @@ class Boldgrid_Backup_Admin_Cron {
320
  * This hook will run every 5 minutes and run one job at a time, such as
321
  * upload to a remote storage provider.
322
  *
323
- * This method is usually ran after saving the BoldGrid Backup settings. If
324
- * after save cron is our scheduler, then we need to make sure we have
325
- * the "run_jobs" wp-cron scheduled.
326
  *
327
  * @since 1.5.2
328
  *
329
  * @see BoldGrid_Backup_Admin_Core::get_backup_identifier()
330
  * @see BoldGrid_Backup_Admin_Cron::get_cron_secret()
 
 
331
  */
332
  public function schedule_jobs() {
333
  $entry = sprintf(
334
- '*/5 * * * * php -qf "%1$s/%2$s" siteurl=%3$s id=%4$s secret=%5$s > /dev/null 2>&1',
335
  dirname( dirname( __FILE__ ) ),
336
  $this->run_jobs,
337
  get_site_url(),
338
  $this->core->get_backup_identifier(),
339
- $this->get_cron_secret()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
340
  );
341
 
342
  return $this->update_cron( $entry );
@@ -347,6 +378,8 @@ class Boldgrid_Backup_Admin_Cron {
347
  *
348
  * @since 1.2
349
  *
 
 
350
  * @global WP_Filesystem $wp_filesystem The WordPress Filesystem API global object.
351
  *
352
  * @param string $entry A cron entry.
@@ -372,56 +405,91 @@ class Boldgrid_Backup_Admin_Cron {
372
 
373
  $crontab .= "\n" . $entry . "\n";
374
 
375
- $crontab_written = $this->write_crontab( $crontab );
376
 
377
  return $crontab_written && $this->entry_exists( $entry );
378
  }
379
 
380
  /**
381
- * Write the crontab.
382
  *
383
- * @since 1.6.0
384
  *
385
- * @param string $crontab A string of crons, similar to raw output of crontab -l.
386
- * @return bool
387
  */
388
- public function write_crontab( $crontab ) {
389
- // Strip extra line breaks.
390
- $crontab = str_replace( "\n\n", "\n", $crontab );
391
-
392
- // Trim the crontab.
393
- $crontab = trim( $crontab );
394
-
395
- // Add a line break at the end of the file.
396
- $crontab .= "\n";
397
-
398
- // Get the backup directory path.
399
- $backup_directory = $this->core->backup_dir->get();
 
 
 
 
400
 
401
- // Check if the backup directory is writable.
402
- if ( ! $this->core->wp_filesystem->is_writable( $backup_directory ) ) {
403
- return false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
404
  }
405
 
406
- // Save the temp crontab to file.
407
- $temp_crontab_path = $backup_directory . '/crontab.' . microtime( true ) . '.tmp';
 
408
 
409
- $this->core->wp_filesystem->put_contents( $temp_crontab_path, $crontab, 0600 );
 
410
 
411
- // Check if the defaults file was written.
412
- if ( ! $this->core->wp_filesystem->exists( $temp_crontab_path ) ) {
413
- return false;
414
- }
415
-
416
- // Write crontab.
417
- $command = 'crontab ' . $temp_crontab_path;
418
 
419
- $crontab = $this->core->execute_command( $command, null, $success );
 
 
 
 
 
 
 
 
 
 
 
420
 
421
- // Remove temp crontab file.
422
- $deleted = $this->core->wp_filesystem->delete( $temp_crontab_path, false, 'f' );
 
 
 
 
423
 
424
- return $success && $deleted;
425
  }
426
 
427
  /**
@@ -429,111 +497,41 @@ class Boldgrid_Backup_Admin_Cron {
429
  *
430
  * @since 1.2
431
  *
432
- * @global WP_Filesystem $wp_filesystem The WordPress Filesystem API global object.
 
 
 
433
  *
434
- * @param string $mode Please see in-method comments when the $pattern is
435
- * configured.
436
- * @return bool Success.
437
  */
438
  public function delete_cron_entries( $mode = '' ) {
439
- // Check if crontab is available.
440
- $is_crontab_available = $this->core->test->is_crontab_available();
441
-
442
- // If crontab is not available, then abort.
443
- if ( ! $is_crontab_available ) {
444
  return false;
445
  }
446
 
447
- // Check if the backup directory is configured.
448
  if ( ! $this->core->backup_dir->get() ) {
449
  return false;
450
  }
451
 
452
- /*
453
- * Configure our pattern.
454
- *
455
- * When this method was initially written, $mode was either
456
- * empty (defaulting to "backup") or "restore", hence the first two
457
- * conditionals below.
458
- *
459
- * As of @1.5.2, you can pass any other string to this method, such as
460
- * "cron/run_jobs.php", so that the pattern will become
461
- * /home/user/public_html/wp-content/plugins/boldgrid-backup/cron/run_jobs.php
462
- *
463
- * As of @1.6.0 you can pass true as the $mode so that nothing else is
464
- * added to the pattern and ALL crons for this site will be removed.
465
- */
466
- $pattern = BOLDGRID_BACKUP_PATH . '/';
467
- if ( '' === $mode ) {
468
- $pattern .= 'boldgrid-backup-cron.php" mode=';
469
- } elseif ( 'restore' === $mode ) {
470
- $pattern .= 'boldgrid-backup-cron.php" mode=restore';
471
- } elseif ( true !== $mode ) {
472
- $pattern .= $mode;
473
- }
474
-
475
- // Use either crontab or wp-cron.
476
- if ( $is_crontab_available ) {
477
- // Use crontab.
478
- // Read crontab.
479
- $command = 'crontab -l';
480
-
481
- $crontab = $this->core->execute_command( $command, null, $success );
482
-
483
- // If the command to retrieve crontab failed, then abort.
484
- if ( ! $success ) {
485
- return false;
486
- }
487
-
488
- // If no entries exist, then return success.
489
- if ( false === strpos( $crontab, $pattern ) ) {
490
- return true;
491
- }
492
-
493
- // Remove lines matching the pattern.
494
- $crontab_exploded = explode( "\n", $crontab );
495
-
496
- $crontab = '';
497
-
498
- foreach ( $crontab_exploded as $line ) {
499
- if ( false === strpos( $line, $pattern ) ) {
500
- $line = trim( $line );
501
- $crontab .= $line . "\n";
502
- }
503
- }
504
 
505
- // Get the backup directory path.
506
- $backup_directory = $this->core->backup_dir->get();
507
-
508
- // Connect to the WordPress Filesystem API.
509
- global $wp_filesystem;
510
-
511
- // Check if the backup directory is writable.
512
- if ( ! $wp_filesystem->is_writable( $backup_directory ) ) {
513
- return false;
514
- }
515
-
516
- // Save the temp crontab to file.
517
- $temp_crontab_path = $backup_directory . '/crontab.' . microtime( true ) . '.tmp';
518
-
519
- // Save a temporary file for crontab.
520
- $wp_filesystem->put_contents( $temp_crontab_path, $crontab, 0600 );
521
-
522
- // Check if the defaults file was written.
523
- if ( ! $wp_filesystem->exists( $temp_crontab_path ) ) {
524
- return false;
525
- }
526
 
527
- // Write crontab.
528
- $command = 'crontab ' . $temp_crontab_path;
 
529
 
530
- $crontab = $this->core->execute_command( $command, null, $success );
531
 
532
- // Remove temp crontab file.
533
- $wp_filesystem->delete( $temp_crontab_path, false, 'f' );
 
534
  }
535
 
536
- return true;
 
 
537
  }
538
 
539
  /**
@@ -541,8 +539,11 @@ class Boldgrid_Backup_Admin_Cron {
541
  *
542
  * @since 1.6.0
543
  *
544
- * @param string $entry
545
- * @return bool True if the entry does not exist or was deleted successfully.
 
 
 
546
  */
547
  public function entry_delete( $entry ) {
548
  if ( ! $this->entry_exists( $entry ) ) {
@@ -551,13 +552,37 @@ class Boldgrid_Backup_Admin_Cron {
551
 
552
  $all_entries = $this->get_all();
553
 
554
- if ( ( $key = array_search( $entry, $all_entries ) ) !== false ) {
 
 
555
  unset( $all_entries[ $key ] );
556
  }
557
 
558
- $all_entries = implode( "\n", $all_entries );
 
559
 
560
- return $this->write_crontab( $all_entries ) && ! $this->entry_exists( $entry );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
561
  }
562
 
563
  /**
@@ -565,13 +590,42 @@ class Boldgrid_Backup_Admin_Cron {
565
  *
566
  * @since 1.6.0
567
  *
568
- * @param string $entry
569
  * @return bool
570
  */
571
  public function entry_exists( $entry ) {
572
  $all_entries = $this->get_all();
573
 
574
- return false !== array_search( $entry, $all_entries );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
575
  }
576
 
577
  /**
@@ -579,11 +633,12 @@ class Boldgrid_Backup_Admin_Cron {
579
  *
580
  * @since 1.5.2
581
  *
 
 
582
  * @param bool $raw Return a string of crons when true, an array when false.
583
  * @return mixed
584
  */
585
  public function get_all( $raw = false ) {
586
-
587
  /*
588
  * Cron is not available on Windows.
589
  *
@@ -594,8 +649,31 @@ class Boldgrid_Backup_Admin_Cron {
594
  return false;
595
  }
596
 
597
- $command = 'crontab -l';
598
- $crontab = $this->core->execute_command( $command, null, $success );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
599
 
600
  if ( ! $success ) {
601
  return false;
@@ -631,6 +709,61 @@ class Boldgrid_Backup_Admin_Cron {
631
  return $our;
632
  }
633
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
634
  /**
635
  * Read a line from the cron and return the schedule.
636
  *
@@ -642,16 +775,16 @@ class Boldgrid_Backup_Admin_Cron {
642
  public function get_schedule( $cron_line ) {
643
  // Initialize $schedule.
644
  $schedule = array(
645
- 'dow_sunday' => 0,
646
- 'dow_monday' => 0,
647
- 'dow_tuesday' => 0,
648
  'dow_wednesday' => 0,
649
- 'dow_thursday' => 0,
650
- 'dow_friday' => 0,
651
- 'dow_saturday' => 0,
652
- 'tod_h' => null,
653
- 'tod_m' => null,
654
- 'tod_a' => null,
655
  );
656
 
657
  if ( empty( $cron_line ) ) {
@@ -686,28 +819,28 @@ class Boldgrid_Backup_Admin_Cron {
686
  $days = explode( ',', $matches[0][4] );
687
  foreach ( $days as $day ) {
688
  switch ( $day ) {
689
- case 0 :
690
  $schedule['dow_sunday'] = 1;
691
  break;
692
- case 1 :
693
  $schedule['dow_monday'] = 1;
694
  break;
695
- case 2 :
696
  $schedule['dow_tuesday'] = 1;
697
  break;
698
- case 3 :
699
  $schedule['dow_wednesday'] = 1;
700
  break;
701
- case 4 :
702
  $schedule['dow_thursday'] = 1;
703
  break;
704
- case 5 :
705
  $schedule['dow_friday'] = 1;
706
  break;
707
- case 6 :
708
  $schedule['dow_saturday'] = 1;
709
  break;
710
- default :
711
  break;
712
  }
713
  }
@@ -726,8 +859,7 @@ class Boldgrid_Backup_Admin_Cron {
726
  public function print_cron_report( $archive_info ) {
727
  // Validate mode.
728
  if ( empty( $archive_info['mode'] ) ) {
729
- esc_html_e( 'Error: A mode was not specified.', 'boldgrid-backup' );
730
- wp_die();
731
  }
732
 
733
  $valid_modes = array(
@@ -737,23 +869,24 @@ class Boldgrid_Backup_Admin_Cron {
737
 
738
  if ( ! in_array( $archive_info['mode'], $valid_modes, true ) ) {
739
  printf(
 
740
  esc_html__( 'Error: Invalid mode "%s".', 'boldgrid-backup' ),
741
- $archive_info['mode']
742
  );
743
  wp_die();
744
  }
745
 
746
  // Create action name.
747
  switch ( $archive_info['mode'] ) {
748
- case 'backup' :
749
  $action_name = 'creating';
750
  break;
751
 
752
- case 'restore' :
753
  $action_name = 'restoring';
754
  break;
755
 
756
- default :
757
  $action_name = 'handling';
758
  break;
759
  }
@@ -763,96 +896,88 @@ class Boldgrid_Backup_Admin_Cron {
763
  // Error.
764
  printf(
765
  esc_html__( 'There was an error $s backup archive file.', 'boldgrid-backup' ),
766
- $action_name
767
- );
768
-
769
- echo PHP_EOL;
770
 
771
  printf(
 
772
  esc_html__( 'Error: %s', 'boldgrid-backup' ),
773
- $archive_info['error']
774
- );
775
-
776
- echo PHP_EOL;
777
 
778
  if ( isset( $archive_info['error_message'] ) ) {
779
  printf(
 
780
  esc_html__( 'Error Message: %s', 'boldgrid-backup' ),
781
- $archive_info['error_message']
782
  );
783
  }
784
 
785
  if ( isset( $archive_info['error_code'] ) ) {
786
  printf(
787
  ' (%s)',
788
- $archive_info['error_code']
789
- );
790
  }
791
-
792
- echo PHP_EOL;
793
  } elseif ( ! empty( $archive_info['filesize'] ) || ! empty( $archive_info['dryrun'] ) ) {
794
  // Dry run.
795
  if ( ! empty( $archive_info['filepath'] ) ) {
796
  printf(
 
797
  esc_html__( 'File Path: %s', 'boldgrid-backup' ),
798
- $archive_info['filepath']
799
- );
800
-
801
- echo PHP_EOL;
802
  }
803
 
804
  if ( ! empty( $archive_info['filesize'] ) ) {
805
  printf(
 
806
  esc_html__( 'File Size: %s', 'boldgrid-backup' ),
807
- Boldgrid_Backup_Admin_Utility::bytes_to_human( $archive_info['filesize'] )
808
- );
809
-
810
- echo PHP_EOL;
811
  }
812
 
813
  if ( ! empty( $archive_info['total_size'] ) ) {
814
  printf(
 
815
  esc_html__( 'Total size: %s', 'boldgrid-backup' ),
816
- Boldgrid_Backup_Admin_Utility::bytes_to_human( $archive_info['total_size'] )
817
- );
818
-
819
- echo PHP_EOL;
820
  }
821
 
822
  if ( ! empty( $archive_info['compressor'] ) ) {
823
  printf(
 
824
  esc_html__( 'Compressor: %s', 'boldgrid-backup' ),
825
- $archive_info['compressor']
826
- );
827
-
828
- echo PHP_EOL;
829
  }
830
 
831
  // Show how long the website was paused for.
832
  if ( isset( $archive_info['db_duration'] ) ) {
833
- printf( $this->core->configs['lang']['est_pause'], $archive_info['db_duration'] );
834
- echo PHP_EOL;
 
 
835
  }
836
 
837
  if ( isset( $archive_info['duration'] ) ) {
838
  printf(
 
839
  esc_html__( 'Duration: %s seconds', 'boldgrid-backup' ),
840
- $archive_info['duration']
841
- );
842
-
843
- echo PHP_EOL;
844
  }
845
  } else {
846
  // Unknown error.
847
  printf(
 
848
  esc_html__(
849
  'There was an unknown error %s a backup archive file.',
850
  'boldgrid-backup'
851
  ),
852
- $action_name
853
- );
854
-
855
- echo PHP_EOL;
856
  }
857
  }
858
 
@@ -896,12 +1021,15 @@ class Boldgrid_Backup_Admin_Cron {
896
  * @return bool
897
  */
898
  public function is_valid_call() {
 
899
  $backup_id_match = ! empty( $_GET['id'] ) &&
900
- $this->core->get_backup_identifier() === $_GET['id'];
901
 
902
  $cron_secret_match = ! empty( $_GET['secret'] ) &&
903
  $this->get_cron_secret() === $_GET['secret'];
904
 
 
 
905
  return current_user_can( 'update_plugins' ) || ( $backup_id_match && $cron_secret_match );
906
  }
907
 
@@ -953,10 +1081,7 @@ class Boldgrid_Backup_Admin_Cron {
953
  */
954
  public function backup() {
955
  if ( ! $this->is_valid_call() ) {
956
- wp_die(
957
- __( 'Error: Invalid request.' ),
958
- 'boldgrid-backup'
959
- );
960
  }
961
 
962
  $archive_info = $this->core->archive_files( true );
@@ -975,10 +1100,7 @@ class Boldgrid_Backup_Admin_Cron {
975
  */
976
  public function restore() {
977
  if ( ! $this->is_valid_call() ) {
978
- wp_die(
979
- __( 'Error: Invalid request.' ),
980
- 'boldgrid-backup'
981
- );
982
  }
983
 
984
  $archive_info = array(
1
  <?php
2
  /**
3
+ * File: class-boldgrid-backup-admin-cron.php
4
  *
5
+ * @link https://www.boldgrid.com
6
  * @since 1.2
7
  *
8
+ * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
+ * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
  */
14
 
15
+ // phpcs:disable WordPress.VIP
16
+
17
  /**
18
+ * Class: Boldgrid_Backup_Admin_Cron
19
  *
20
  * @since 1.2
21
  */
30
  private $core;
31
 
32
  /**
33
+ * Path to run-jobs.php.
34
  *
35
  * @since 1.5.2
36
  * @var string
37
  */
38
+ public $run_jobs = 'cron/run-jobs.php';
39
+
40
+ /**
41
+ * Path to the bgbkup-cli script.
42
+ *
43
+ * @since 1.10.0
44
+ * @var string
45
+ */
46
+ public $site_check = 'cli/bgbkup-cli.php';
47
+
48
+ /**
49
+ * Cron command.
50
+ *
51
+ * This is the base of most of our cron commands.
52
+ *
53
+ * The following was added as of 1.6.5 for those hosts that have register_argc_argv disabled:
54
+ * -d register_argc_argv="1"
55
+ *
56
+ * @since 1.6.5
57
+ * @access private
58
+ * @var string
59
+ */
60
+ private $cron_command = 'php -d register_argc_argv="1" -qf';
61
 
62
  /**
63
  * A cron secret used to validate unauthenticated crontab jobs.
75
  *
76
  * @var string
77
  */
78
+ public $crontab_version = '1.6.4';
79
 
80
  /**
81
  * Constructor.
89
  $this->core = $core;
90
  }
91
 
92
+ /**
93
+ * Get the cron command prefix.
94
+ *
95
+ * @return string
96
+ */
97
+ public function get_cron_command() {
98
+ return $this->cron_command;
99
+ }
100
+
101
  /**
102
  * Add cron entry for backups from stored settings.
103
  *
108
  * @see BoldGrid_Backup_Admin_Core::get_backup_identifier()
109
  * @see BoldGrid_Backup_Admin_Cron::get_cron_secret()
110
  *
111
+ * @param array $settings Settings.
112
  * @return bool Success.
113
  */
114
+ public function add_cron_entry( array $settings = [] ) {
115
  if ( empty( $settings ) ) {
116
  $settings = $this->core->settings->get_settings();
117
  }
118
 
119
  // Delete existing backup cron jobs.
120
+ $cron_status = $this->delete_cron_entries( 'backup' );
121
 
122
  // Initialize $days_scheduled_list.
123
  $days_scheduled_list = '';
124
 
125
  // Create an array of days index names.
126
  $days = array(
127
+ 'dow_sunday' => 0,
128
+ 'dow_monday' => 1,
129
+ 'dow_tuesday' => 2,
130
  'dow_wednesday' => 3,
131
+ 'dow_thursday' => 4,
132
+ 'dow_friday' => 5,
133
+ 'dow_saturday' => 6,
134
  );
135
 
136
  // Add scheduled days to the list.
163
  // Build cron job line in crontab format.
164
  $entry = $date->format( 'i G' ) . ' * * ';
165
 
166
+ $entry .= $days_scheduled_list . ' ' . $this->cron_command . ' "' . dirname( dirname( __FILE__ ) ) .
167
  '/boldgrid-backup-cron.php" mode=backup siteurl=' . get_site_url() . ' id=' .
168
  $this->core->get_backup_identifier() . ' secret=' . $this->get_cron_secret();
169
 
190
  *
191
  * @since 1.6.0
192
  *
193
+ * @param array $settings Settings.
194
  * @return bool
195
  */
196
+ public function add_all_crons( array $settings ) {
197
  $success = false;
198
 
199
  $scheduler = ! empty( $settings['scheduler'] ) ? $settings['scheduler'] : null;
200
+ $schedule = ! empty( $settings['schedule'] ) ? $settings['schedule'] : null;
201
 
202
+ if ( 'cron' === $scheduler && $this->core->scheduler->is_available( $scheduler ) ) {
203
  $this->core->scheduler->clear_all_schedules();
204
 
205
+ if ( ! empty( $schedule ) ) {
206
+ $scheduled = $this->add_cron_entry( $settings );
207
+ }
208
+
209
  $jobs_scheduled = $this->schedule_jobs();
210
+ $site_check = $this->schedule_site_check( $settings );
211
 
212
  $success = $scheduled && $jobs_scheduled;
213
 
214
  if ( $success ) {
215
  $settings['crontab_version'] = $this->crontab_version;
216
+ $settings['cron_secret'] = $this->get_cron_secret();
217
  update_site_option( 'boldgrid_backup_settings', $settings );
218
  }
219
  }
233
  * @see Boldgrid_Backup_Admin_Test::is_windows()
234
  * @see BoldGrid_Backup_Admin_Core::get_backup_identifier()
235
  * @see BoldGrid_Backup_Admin_Cron::get_cron_secret()
 
 
236
  */
237
  public function add_restore_cron() {
 
 
 
 
 
 
 
 
 
 
238
  // Remove existing restore cron jobs.
239
  $this->delete_cron_entries( 'restore' );
240
 
241
+ $entry = $this->get_restore_command();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
242
  $status = $this->update_cron( $entry );
243
+ $time = $this->core->auto_rollback->get_time_data();
244
 
245
  // If cron job was added, then update the boldgrid_backup_pending_rollback option with time.
246
  if ( $status ) {
247
+ $pending_rollback = get_site_option( 'boldgrid_backup_pending_rollback' );
248
+
249
+ $pending_rollback['deadline'] = $time['deadline'];
250
 
251
  update_site_option( 'boldgrid_backup_pending_rollback', $pending_rollback );
252
  }
 
 
253
  }
254
 
255
  /**
304
  * This hook will run every 5 minutes and run one job at a time, such as
305
  * upload to a remote storage provider.
306
  *
307
+ * This method is usually ran after saving the settings. If after save cron is our scheduler,
308
+ * then we need to make sure we have the "run_jobs" wp-cron scheduled.
 
309
  *
310
  * @since 1.5.2
311
  *
312
  * @see BoldGrid_Backup_Admin_Core::get_backup_identifier()
313
  * @see BoldGrid_Backup_Admin_Cron::get_cron_secret()
314
+ *
315
+ * @return bool Success.
316
  */
317
  public function schedule_jobs() {
318
  $entry = sprintf(
319
+ '*/5 * * * * %6$s "%1$s/%2$s" siteurl=%3$s id=%4$s secret=%5$s > /dev/null 2>&1',
320
  dirname( dirname( __FILE__ ) ),
321
  $this->run_jobs,
322
  get_site_url(),
323
  $this->core->get_backup_identifier(),
324
+ $this->get_cron_secret(),
325
+ $this->cron_command
326
+ );
327
+
328
+ return $this->update_cron( $entry );
329
+ }
330
+
331
+ /**
332
+ * Schedule Site Check.
333
+ *
334
+ * This method is usually ran after saving the settings. If (after save) cron is our scheduler,
335
+ * then we need to make sure we have the "site_check" wp-cron scheduled.
336
+ *
337
+ * @since 1.10.0
338
+ *
339
+ * @see BoldGrid_Backup_Admin_Core::get_backup_identifier()
340
+ * @see BoldGrid_Backup_Admin_Cron::get_cron_secret()
341
+ *
342
+ * @param array $settings Settings.
343
+ * @return bool
344
+ */
345
+ public function schedule_site_check( array $settings = [] ) {
346
+ if ( empty( $settings ) ) {
347
+ $settings = $this->core->settings->get_settings();
348
+ }
349
+
350
+ if ( ! $settings['site_check']['enabled'] ) {
351
+ return false;
352
+ }
353
+
354
+ $args = implode(
355
+ ' ',
356
+ [
357
+ 'auto_recovery=' . ( ! empty( $settings['site_check']['auto_recovery'] ) ? 1 : 0 ),
358
+ 'email=' . $settings['notification_email'],
359
+ 'log=' . ( ! empty( $settings['site_check']['logger'] ) ? 1 : 0 ),
360
+ 'notify=' . ( ! empty( $settings['notifications']['site_check'] ) ? 1 : 0 ),
361
+ ]
362
+ );
363
+
364
+ $entry = sprintf(
365
+ '*/%1$u * * * * %2$s "%3$s/%4$s" check %5$s >/dev/null 2>&1',
366
+ $settings['site_check']['interval'],
367
+ $this->cron_command,
368
+ dirname( dirname( __FILE__ ) ),
369
+ $this->site_check,
370
+ $args
371
  );
372
 
373
  return $this->update_cron( $entry );
378
  *
379
  * @since 1.2
380
  *
381
+ * @see \Boldgrid\Backup\Admin\Cron\Crontab::write_crontab()
382
+ *
383
  * @global WP_Filesystem $wp_filesystem The WordPress Filesystem API global object.
384
  *
385
  * @param string $entry A cron entry.
405
 
406
  $crontab .= "\n" . $entry . "\n";
407
 
408
+ $crontab_written = ( new \Boldgrid\Backup\Admin\Cron\Crontab() )->write_crontab( $crontab );
409
 
410
  return $crontab_written && $this->entry_exists( $entry );
411
  }
412
 
413
  /**
414
+ * Get the pattern determined by mode passed.
415
  *
416
+ * @since 1.11.1
417
  *
418
+ * @param string|bool $mode Please see in-method comments below when $pattern is configured.
419
+ * @return string
420
  */
421
+ public function get_mode_pattern( $mode = '' ) {
422
+ /*
423
+ * Configure our regex pattern.
424
+ *
425
+ * When this method was initially written, $mode was either
426
+ * empty (defaulting to "backup") or "restore", hence the first two
427
+ * conditionals below.
428
+ *
429
+ * As of @1.5.2, you can pass any other string to this method, such as
430
+ * "cron/run-jobs.php", so that the pattern will become
431
+ * /home/user/public_html/wp-content/plugins/boldgrid-backup/cron/run-jobs.php
432
+ *
433
+ * As of @1.6.0 you can pass true as the $mode so that nothing else is
434
+ * added to the pattern and ALL crons for this site will be removed.
435
+ */
436
+ $pattern = BOLDGRID_BACKUP_PATH . '/';
437
 
438
+ switch ( true ) {
439
+ case '' === $mode:
440
+ case 'backup' === $mode:
441
+ $pattern .= 'boldgrid-backup-cron.php" mode=backup';
442
+ break;
443
+ case 'restore' === $mode:
444
+ // Match "boldgrid-backup-cron.php" (old) and "cli/bgbkup-cli.php" (new) in the pattern.
445
+ $pattern .= '(boldgrid-backup-cron|cli/bgbkup-cli).php" mode=restore';
446
+ break;
447
+ case 'jobs' === $mode:
448
+ // Match "run_jobs" (old) and "run-jobs" (new) filenames in the pattern.
449
+ $pattern .= '(cron/run_jobs.php|' . $this->run_jobs . ')';
450
+ break;
451
+ case 'site_check' === $mode:
452
+ $pattern .= $this->site_check . '" check';
453
+ break;
454
+ case 'all' === $mode:
455
+ case true === $mode:
456
+ break;
457
+ default:
458
+ $pattern .= $mode;
459
+ break;
460
  }
461
 
462
+ // Format the periods in the pattern for regex; ensure a backslash before periods.
463
+ $pattern = str_replace( '\.', '.', $pattern );
464
+ $pattern = str_replace( '.', '\.', $pattern );
465
 
466
+ // Escape the regex delimited that we will use.
467
+ $pattern = str_replace( '~', '\~', $pattern );
468
 
469
+ return $pattern;
470
+ }
 
 
 
 
 
471
 
472
+ /**
473
+ * Remove lines matching the pattern.
474
+ *
475
+ * @since 1.11.1
476
+ *
477
+ * @param string $pattern Regex pattern, without delimiter "~".
478
+ * @param string $crontab The crontab contents.
479
+ * @return string
480
+ */
481
+ public function filter_crontab( $pattern, $crontab ) {
482
+ $crontab_exploded = explode( "\n", $crontab );
483
+ $crontab = '';
484
 
485
+ foreach ( $crontab_exploded as $line ) {
486
+ if ( ! empty( $line ) && ! preg_match( '~' . $pattern . '~', $line ) ) {
487
+ $line = trim( $line );
488
+ $crontab .= $line . "\n";
489
+ }
490
+ }
491
 
492
+ return $crontab;
493
  }
494
 
495
  /**
497
  *
498
  * @since 1.2
499
  *
500
+ * @see \Boldgrid\Backup\Admin\Cron\Crontab::read_crontab()
501
+ * @see \Boldgrid_Backup_Admin_Cron::get_mode_pattern()
502
+ * @see \Boldgrid_Backup_Admin_Cron::filter_crontab()
503
+ * @see \Boldgrid\Backup\Admin\Cron\Crontab::write_crontab()
504
  *
505
+ * @param string|bool $mode Please see in-method comments below when $pattern is configured.
506
+ * @return bool
 
507
  */
508
  public function delete_cron_entries( $mode = '' ) {
509
+ if ( ! $this->core->test->is_crontab_available() ) {
 
 
 
 
510
  return false;
511
  }
512
 
 
513
  if ( ! $this->core->backup_dir->get() ) {
514
  return false;
515
  }
516
 
517
+ $crontab_helper = new \Boldgrid\Backup\Admin\Cron\Crontab();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
518
 
519
+ $crontab = $crontab_helper->read_crontab();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
520
 
521
+ if ( false === $crontab ) {
522
+ return false;
523
+ }
524
 
525
+ $pattern = $this->get_mode_pattern( $mode );
526
 
527
+ // If no entries exist, then return success.
528
+ if ( ! preg_match( '~' . $pattern . '~', $crontab ) ) {
529
+ return true;
530
  }
531
 
532
+ $crontab = $this->filter_crontab( $pattern, $crontab );
533
+
534
+ return $crontab_helper->write_crontab( $crontab );
535
  }
536
 
537
  /**
539
  *
540
  * @since 1.6.0
541
  *
542
+ * @see \Boldgrid\Backup\Admin\Cron\Crontab::write_crontab()
543
+ * @see \Boldgrid_Backup_Admin_Cron::entry_exists()
544
+ *
545
+ * @param string $entry Crontab entry.
546
+ * @return bool True if the entry does not exist or was deleted successfully.
547
  */
548
  public function entry_delete( $entry ) {
549
  if ( ! $this->entry_exists( $entry ) ) {
552
 
553
  $all_entries = $this->get_all();
554
 
555
+ $key = array_search( $entry, $all_entries, true );
556
+
557
+ if ( false !== $key ) {
558
  unset( $all_entries[ $key ] );
559
  }
560
 
561
+ $all_entries = implode( "\n", $all_entries );
562
+ $crontab_written = ( new \Boldgrid\Backup\Admin\Cron\Crontab() )->write_crontab( $all_entries );
563
 
564
+ return $crontab_written && ! $this->entry_exists( $entry );
565
+ }
566
+
567
+ /**
568
+ * Delete all cron entries that contain a string.
569
+ *
570
+ * @since 1.6.5
571
+ *
572
+ * @param string $string The string to look for.
573
+ */
574
+ public function entry_delete_contains( $string ) {
575
+ $all_entries = $this->get_all();
576
+
577
+ if ( ! is_array( $all_entries ) ) {
578
+ return;
579
+ }
580
+
581
+ foreach ( $all_entries as $entry ) {
582
+ if ( false !== strpos( $entry, $string ) ) {
583
+ $this->entry_delete( $entry );
584
+ }
585
+ }
586
  }
587
 
588
  /**
590
  *
591
  * @since 1.6.0
592
  *
593
+ * @param string $entry Crontab entry.
594
  * @return bool
595
  */
596
  public function entry_exists( $entry ) {
597
  $all_entries = $this->get_all();
598
 
599
+ if ( empty( $all_entries ) ) {
600
+ return false;
601
+ }
602
+
603
+ return false !== array_search( $entry, $all_entries, true );
604
+ }
605
+
606
+ /**
607
+ * Search for cron entries that contain a specfic string.
608
+ *
609
+ * @since 1.6.5
610
+ *
611
+ * @param string $search String to search for.
612
+ * @return array An array of matches.
613
+ */
614
+ public function entry_search( $search ) {
615
+ $matches = array();
616
+ $entries = $this->get_all();
617
+
618
+ if ( empty( $entries ) ) {
619
+ return $matches;
620
+ }
621
+
622
+ foreach ( $entries as $entry ) {
623
+ if ( false !== strpos( $entry, $search ) ) {
624
+ $matches[] = $entry;
625
+ }
626
+ }
627
+
628
+ return $matches;
629
  }
630
 
631
  /**
633
  *
634
  * @since 1.5.2
635
  *
636
+ * @see Boldgrid_Backup_Admin_Core::execute_command()
637
+ *
638
  * @param bool $raw Return a string of crons when true, an array when false.
639
  * @return mixed
640
  */
641
  public function get_all( $raw = false ) {
 
642
  /*
643
  * Cron is not available on Windows.
644
  *
649
  return false;
650
  }
651
 
652
+ /*
653
+ * Attempt to read the crontab.
654
+ *
655
+ * Historically, we just read the output of "crontab -l". In certain scenarious, this does
656
+ * not return the full output of the command. Another solution would be to output that command
657
+ * to a file, and then read the file.
658
+ *
659
+ * As of 1.6.5, we'll first try the latter option.
660
+ */
661
+ if ( $this->core->backup_dir->can_exec_write() ) {
662
+ $crontab_file_path = $this->core->backup_dir->get_path_to( 'crontab' );
663
+
664
+ // Write crontab to temp file.
665
+ $command = sprintf( 'crontab -l > %1$s', $crontab_file_path );
666
+ $this->core->execute_command( $command, $success );
667
+
668
+ // Read the crontab from temp file.
669
+ $crontab = $this->core->wp_filesystem->get_contents( $crontab_file_path );
670
+ $success = false !== $crontab;
671
+
672
+ $this->core->wp_filesystem->delete( $crontab_file_path );
673
+ } else {
674
+ $command = 'crontab -l';
675
+ $crontab = $this->core->execute_command( $command, $success );
676
+ }
677
 
678
  if ( ! $success ) {
679
  return false;
709
  return $our;
710
  }
711
 
712
+ /**
713
+ * Get restore command.
714
+ *
715
+ * Create the cron markup (creates the markup, does not actually add to crontab) to restore a
716
+ * backup archive.
717
+ *
718
+ * Before @since xxx, this method was in add_cron_entry. It has since been moved to its own
719
+ * method here for reusability.
720
+ *
721
+ * @since xxx
722
+ *
723
+ * return string
724
+ */
725
+ public function get_restore_command() {
726
+ $entry = '';
727
+
728
+ // Use the first key to get info on the most recent archive.
729
+ if ( ! $this->core->archive->init_by_key( 0 ) ) {
730
+ return $entry;
731
+ }
732
+
733
+ $time = $this->core->auto_rollback->get_time_data();
734
+ $settings = $this->core->settings->get_settings();
735
+ $backup_id = $this->core->get_backup_identifier();
736
+
737
+ $entry_parts = [
738
+ date( $time['minute'] . ' ' . $time['hour'], $time['deadline'] ) . ' * * ' . date( 'w' ),
739
+ $this->cron_command,
740
+ '"' . dirname( dirname( __FILE__ ) ) . '/cli/bgbkup-cli.php"',
741
+
742
+ /*
743
+ * Info on mode=restore and restore:
744
+ *
745
+ * The "mode=restore" property is for the cron remove function (it's a pattern searched for),
746
+ * and "plain" is used by CLI. If you take out "mode=restore", it will still do the
747
+ * restoration but it won't be able to find and delete the cron.
748
+ *
749
+ * @todo simplify this.
750
+ */
751
+ 'mode=restore restore',
752
+ 'notify email=' . $settings['notification_email'],
753
+ 'backup_id=' . $backup_id,
754
+ 'zip=' . $this->core->archive->filepath,
755
+ ];
756
+
757
+ // If not Windows, then also silence the cron job.
758
+ if ( ! $this->core->test->is_windows() ) {
759
+ $entry_parts[] = '> /dev/null 2>&1';
760
+ }
761
+
762
+ $entry = implode( ' ', $entry_parts );
763
+
764
+ return $entry;
765
+ }
766
+
767
  /**
768
  * Read a line from the cron and return the schedule.
769
  *
775
  public function get_schedule( $cron_line ) {
776
  // Initialize $schedule.
777
  $schedule = array(
778
+ 'dow_sunday' => 0,
779
+ 'dow_monday' => 0,
780
+ 'dow_tuesday' => 0,
781
  'dow_wednesday' => 0,
782
+ 'dow_thursday' => 0,
783
+ 'dow_friday' => 0,
784
+ 'dow_saturday' => 0,
785
+ 'tod_h' => null,
786
+ 'tod_m' => null,
787
+ 'tod_a' => null,
788
  );
789
 
790
  if ( empty( $cron_line ) ) {
819
  $days = explode( ',', $matches[0][4] );
820
  foreach ( $days as $day ) {
821
  switch ( $day ) {
822
+ case 0:
823
  $schedule['dow_sunday'] = 1;
824
  break;
825
+ case 1:
826
  $schedule['dow_monday'] = 1;
827
  break;
828
+ case 2:
829
  $schedule['dow_tuesday'] = 1;
830
  break;
831
+ case 3:
832
  $schedule['dow_wednesday'] = 1;
833
  break;
834
+ case 4:
835
  $schedule['dow_thursday'] = 1;
836
  break;
837
+ case 5:
838
  $schedule['dow_friday'] = 1;
839
  break;
840
+ case 6:
841
  $schedule['dow_saturday'] = 1;
842
  break;
843
+ default:
844
  break;
845
  }
846
  }
859
  public function print_cron_report( $archive_info ) {
860
  // Validate mode.
861
  if ( empty( $archive_info['mode'] ) ) {
862
+ wp_die( esc_html__( 'Error: A mode was not specified.', 'boldgrid-backup' ) );
 
863
  }
864
 
865
  $valid_modes = array(
869
 
870
  if ( ! in_array( $archive_info['mode'], $valid_modes, true ) ) {
871
  printf(
872
+ // translators: 1: Archive mode ("backup" or "restore").
873
  esc_html__( 'Error: Invalid mode "%s".', 'boldgrid-backup' ),
874
+ $archive_info['mode'] // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
875
  );
876
  wp_die();
877
  }
878
 
879
  // Create action name.
880
  switch ( $archive_info['mode'] ) {
881
+ case 'backup':
882
  $action_name = 'creating';
883
  break;
884
 
885
+ case 'restore':
886
  $action_name = 'restoring';
887
  break;
888
 
889
+ default:
890
  $action_name = 'handling';
891
  break;
892
  }
896
  // Error.
897
  printf(
898
  esc_html__( 'There was an error $s backup archive file.', 'boldgrid-backup' ),
899
+ $action_name // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
900
+ ) . PHP_EOL;
 
 
901
 
902
  printf(
903
+ // translators: 1: Error message.
904
  esc_html__( 'Error: %s', 'boldgrid-backup' ),
905
+ $archive_info['error'] // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
906
+ ) . PHP_EOL;
 
 
907
 
908
  if ( isset( $archive_info['error_message'] ) ) {
909
  printf(
910
+ // translators: 1: Error message.
911
  esc_html__( 'Error Message: %s', 'boldgrid-backup' ),
912
+ $archive_info['error_message'] // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
913
  );
914
  }
915
 
916
  if ( isset( $archive_info['error_code'] ) ) {
917
  printf(
918
  ' (%s)',
919
+ esc_html( $archive_info['error_code'] )
920
+ ) . PHP_EOL;
921
  }
 
 
922
  } elseif ( ! empty( $archive_info['filesize'] ) || ! empty( $archive_info['dryrun'] ) ) {
923
  // Dry run.
924
  if ( ! empty( $archive_info['filepath'] ) ) {
925
  printf(
926
+ // translators: 1: File path.
927
  esc_html__( 'File Path: %s', 'boldgrid-backup' ),
928
+ $archive_info['filepath'] // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
929
+ ) . PHP_EOL;
 
 
930
  }
931
 
932
  if ( ! empty( $archive_info['filesize'] ) ) {
933
  printf(
934
+ // translators: 1: File size.
935
  esc_html__( 'File Size: %s', 'boldgrid-backup' ),
936
+ Boldgrid_Backup_Admin_Utility::bytes_to_human( $archive_info['filesize'] ) // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
937
+ ) . PHP_EOL;
 
 
938
  }
939
 
940
  if ( ! empty( $archive_info['total_size'] ) ) {
941
  printf(
942
+ // translators: 1: Total backup size.
943
  esc_html__( 'Total size: %s', 'boldgrid-backup' ),
944
+ Boldgrid_Backup_Admin_Utility::bytes_to_human( $archive_info['total_size'] ) // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
945
+ ) . PHP_EOL;
 
 
946
  }
947
 
948
  if ( ! empty( $archive_info['compressor'] ) ) {
949
  printf(
950
+ // translators: 1: Compressor name.
951
  esc_html__( 'Compressor: %s', 'boldgrid-backup' ),
952
+ $archive_info['compressor'] // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
953
+ ) . PHP_EOL;
 
 
954
  }
955
 
956
  // Show how long the website was paused for.
957
  if ( isset( $archive_info['db_duration'] ) ) {
958
+ printf(
959
+ esc_html( $this->core->configs['lang']['est_pause'] ),
960
+ $archive_info['db_duration'] // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
961
+ ) . PHP_EOL;
962
  }
963
 
964
  if ( isset( $archive_info['duration'] ) ) {
965
  printf(
966
+ // translators: 1: Backup duration.
967
  esc_html__( 'Duration: %s seconds', 'boldgrid-backup' ),
968
+ $archive_info['duration'] // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
969
+ ) . PHP_EOL;
 
 
970
  }
971
  } else {
972
  // Unknown error.
973
  printf(
974
+ // translators: 1: Backup action name.
975
  esc_html__(
976
  'There was an unknown error %s a backup archive file.',
977
  'boldgrid-backup'
978
  ),
979
+ $action_name // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
980
+ ) . PHP_EOL;
 
 
981
  }
982
  }
983
 
1021
  * @return bool
1022
  */
1023
  public function is_valid_call() {
1024
+ // phpcs:disable WordPress.CSRF.NonceVerification.NoNonceVerification
1025
  $backup_id_match = ! empty( $_GET['id'] ) &&
1026
+ $this->core->get_backup_identifier() === sanitize_key( $_GET['id'] );
1027
 
1028
  $cron_secret_match = ! empty( $_GET['secret'] ) &&
1029
  $this->get_cron_secret() === $_GET['secret'];
1030
 
1031
+ // phpcs:enable WordPress.CSRF.NonceVerification.NoNonceVerification
1032
+
1033
  return current_user_can( 'update_plugins' ) || ( $backup_id_match && $cron_secret_match );
1034
  }
1035
 
1081
  */
1082
  public function backup() {
1083
  if ( ! $this->is_valid_call() ) {
1084
+ wp_die( esc_html__( 'Error: Invalid request.', 'boldgrid-backup' ) );
 
 
 
1085
  }
1086
 
1087
  $archive_info = $this->core->archive_files( true );
1100
  */
1101
  public function restore() {
1102
  if ( ! $this->is_valid_call() ) {
1103
+ wp_die( esc_html__( 'Error: Invalid request.', 'boldgrid-backup' ) );
 
 
 
1104
  }
1105
 
1106
  $archive_info = array(
admin/class-boldgrid-backup-admin-crypt.php CHANGED
@@ -1,19 +1,19 @@
1
  <?php
2
  /**
3
- * Crypt class.
4
  *
5
- * @link http://www.boldgrid.com
6
  * @since 1.6.0
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
- * @copyright BoldGrid.com
11
  * @version $Id$
12
- * @author BoldGrid.com <wpb@boldgrid.com>
13
  */
14
 
15
  /**
16
- * BoldGrid Backup Admin Crypt Class.
17
  *
18
  * @since 1.6.0
19
  */
@@ -37,15 +37,15 @@ class Boldgrid_Backup_Admin_Crypt {
37
  return $string;
38
  }
39
 
40
- $output = false;
41
  $encrypt_method = 'AES-256-CBC';
42
- $key = hash( 'sha256', AUTH_KEY );
43
- $iv = substr( hash( 'sha256', SECURE_AUTH_KEY ), 0, 16 );
44
 
45
  if ( 'e' === $action ) {
46
- $output = base64_encode( openssl_encrypt( $string, $encrypt_method, $key, 0, $iv ) );
47
  } elseif ( 'd' === $action ) {
48
- $output = openssl_decrypt( base64_decode( $string ), $encrypt_method, $key, 0, $iv );
49
  }
50
 
51
  return $output;
1
  <?php
2
  /**
3
+ * File: class-boldgrid-backup-admin-crypt.php
4
  *
5
+ * @link https://www.boldgrid.com
6
  * @since 1.6.0
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
  * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
  */
14
 
15
  /**
16
+ * Class: Boldgrid_Backup_Admin_Crypt
17
  *
18
  * @since 1.6.0
19
  */
37
  return $string;
38
  }
39
 
40
+ $output = false;
41
  $encrypt_method = 'AES-256-CBC';
42
+ $key = hash( 'sha256', AUTH_KEY );
43
+ $iv = substr( hash( 'sha256', SECURE_AUTH_KEY ), 0, 16 );
44
 
45
  if ( 'e' === $action ) {
46
+ $output = base64_encode( openssl_encrypt( $string, $encrypt_method, $key, 0, $iv ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
47
  } elseif ( 'd' === $action ) {
48
+ $output = openssl_decrypt( base64_decode( $string ), $encrypt_method, $key, 0, $iv ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode
49
  }
50
 
51
  return $output;
admin/class-boldgrid-backup-admin-dashboard-widget.php ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File: class-boldgrid-backup-admin-dashboard-widget.php
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.10.0
7
+ *
8
+ * @package Boldgrid_Backup
9
+ * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
+ * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
+ */
14
+
15
+ /**
16
+ * Class: Boldgrid_Backup_Admin_Dashboard_Widget
17
+ *
18
+ * @since 1.10.0
19
+ */
20
+ class Boldgrid_Backup_Admin_Dashboard_Widget {
21
+ /**
22
+ * The core class object.
23
+ *
24
+ * @since 1.10.0
25
+ * @access private
26
+ * @var Boldgrid_Backup_Admin_Core
27
+ */
28
+ private $core;
29
+
30
+ /**
31
+ * Constructor.
32
+ *
33
+ * @since 1.10.1
34
+ *
35
+ * @param Boldgrid_Backup_Admin_Core $core Boldgrid_Backup_Admin_Core object.
36
+ */
37
+ public function __construct( Boldgrid_Backup_Admin_Core $core ) {
38
+ $this->core = $core;
39
+ }
40
+
41
+ /**
42
+ * Filter the item in the dashboard widget.
43
+ *
44
+ * @since 1.10.0
45
+ *
46
+ * @param \Boldgrid\Library\Library\Ui\Feature $feature The feature object.
47
+ * @param \Boldgrid\Library\Library\Plugin\Plugin $plugin The plugin object.
48
+ * @return \Boldgrid\Library\Library\Ui\Feature
49
+ */
50
+ public function filter_feature( Boldgrid\Library\Library\Ui\Feature $feature, \Boldgrid\Library\Library\Plugin\Plugin $plugin ) {
51
+ // Full site protection.
52
+ if ( ! $this->core->settings->has_full_protection() ) {
53
+ $feature->content .= '<div class="notice notice-error inline"><p>' . wp_kses(
54
+ sprintf(
55
+ // translators: 1 The opening anchor tag to the Inspirations page, 2 its closing tag.
56
+ __( 'Not fully protected. %1$sFix this%2$s.', 'boldgrid-backup' ),
57
+ '<a href="' . esc_url( admin_url( 'admin.php?page=boldgrid-backup-dashboard' ) ) . '">',
58
+ '</a>'
59
+ ),
60
+ array( 'a' => array( 'href' => array() ) )
61
+ ) . '</p></div>';
62
+ }
63
+
64
+ // Show notices if the user has the premium plugin but needs to enable it, or a similar situation.
65
+ $notices = $this->core->go_pro->get_admin_notices();
66
+ foreach ( $notices as $notice ) {
67
+ if ( $notice['show'] ) {
68
+ $feature->content .= '<div class="' . $notice['class'] . ' inline">' . $notice['message'] . '</div>';
69
+ }
70
+ }
71
+
72
+ return $feature;
73
+ }
74
+ }
admin/class-boldgrid-backup-admin-dashboard.php ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File: class-boldgrid-backup-admin-dashboard.php
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.11.0
7
+ *
8
+ * @package Boldgrid_Backup
9
+ * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
+ * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
+ */
14
+
15
+ /**
16
+ * Class: Boldgrid_Backup_Admin_Dashboard
17
+ *
18
+ * @since 1.11.0
19
+ */
20
+ class Boldgrid_Backup_Admin_Dashboard {
21
+ /**
22
+ * The core class object.
23
+ *
24
+ * @since 1.11.0
25
+ * @access private
26
+ * @var Boldgrid_Backup_Admin_Core
27
+ */
28
+ private $core;
29
+
30
+ /**
31
+ * Constructor.
32
+ *
33
+ * @since 1.11.0
34
+ *
35
+ * @param Boldgrid_Backup_Admin_Core $core Core class object.
36
+ */
37
+ public function __construct( Boldgrid_Backup_Admin_Core $core ) {
38
+ $this->core = $core;
39
+ }
40
+
41
+ /**
42
+ * Enqueue scripts.
43
+ *
44
+ * @since 1.11.0
45
+ *
46
+ * @param string $hook Hook name.
47
+ */
48
+ public function admin_enqueue_scripts( $hook ) {
49
+ if ( 'toplevel_page_boldgrid-backup-dashboard' === $hook ) {
50
+ wp_enqueue_style(
51
+ 'boldgrid-backup-admin-dashboard',
52
+ plugin_dir_url( __FILE__ ) . 'css/boldgrid-backup-admin-dashboard.css',
53
+ array(),
54
+ BOLDGRID_BACKUP_VERSION
55
+ );
56
+ }
57
+ }
58
+
59
+ /**
60
+ * Get cards needed for the dashboard.
61
+ *
62
+ * @since 1.11.0
63
+ *
64
+ * @return array
65
+ */
66
+ public function get_cards() {
67
+ $cards = [
68
+ new \Boldgrid\Backup\Admin\Card\Premium(),
69
+ new \Boldgrid\Backup\Admin\Card\Backups(),
70
+ new \Boldgrid\Backup\Admin\Card\Updates(),
71
+ ];
72
+
73
+ return $cards;
74
+ }
75
+
76
+ /**
77
+ * Render the dashboard page.
78
+ *
79
+ * @since 1.11.0
80
+ */
81
+ public function page() {
82
+ include BOLDGRID_BACKUP_PATH . '/admin/partials/boldgrid-backup-admin-dashboard.php';
83
+ }
84
+ }
admin/class-boldgrid-backup-admin-db-dump.php CHANGED
@@ -1,26 +1,25 @@
1
  <?php
2
  /**
3
- * Database Dump.
4
  *
5
- * @link http://www.boldgrid.com
6
  * @since 1.5.1
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
- * @copyright BoldGrid.com
11
  * @version $Id$
12
- * @author BoldGrid.com <wpb@boldgrid.com>
13
  */
14
 
15
  use Ifsnop\Mysqldump as IMysqldump;
16
 
17
  /**
18
- * BoldGrid Backup Admin Database Dump class.
19
  *
20
  * @since 1.5.1
21
  */
22
  class Boldgrid_Backup_Admin_Db_Dump {
23
-
24
  /**
25
  * The core class object.
26
  *
@@ -46,38 +45,76 @@ class Boldgrid_Backup_Admin_Db_Dump {
46
  *
47
  * @since 1.5.1
48
  *
 
 
49
  * @param string $file The filepath to our file.
50
  * @return bool True on success.
51
  */
52
  public function dump( $file ) {
 
 
53
  $include_tables = $this->core->db_omit->get_filtered_tables();
54
  if ( empty( $include_tables ) ) {
55
  return array( 'error' => esc_html__( 'No tables selected to backup.', 'boldgrid-backup' ) );
56
  }
57
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
  /**
59
  * Take action before a database is dumped.
60
  *
61
  * @since 1.6.0
62
  */
63
- do_action( 'boldgrid_backup_pre_dump' );
64
 
65
- // Some hosts may configure the DB_HOST as localhost:3306. Strip out the port.
66
- $db_host = explode( ':', DB_HOST );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
 
68
  try {
69
  $dump = new IMysqldump\Mysqldump(
70
- sprintf( 'mysql:host=%1$s;dbname=%2$s', $db_host[0], DB_NAME ),
71
  DB_USER,
72
  DB_PASSWORD,
73
- array(
74
- 'include-tables' => $include_tables,
75
- 'add-drop-table' => true,
76
- 'no-autocommit' => false,
77
- )
78
  );
79
  $dump->start( $file );
80
- } catch (\Exception $e) {
81
  return array( 'error' => $e->getMessage() );
82
  }
83
 
@@ -86,11 +123,76 @@ class Boldgrid_Backup_Admin_Db_Dump {
86
  *
87
  * @since 1.6.0
88
  */
89
- do_action( 'boldgrid_backup_post_dump' );
90
 
91
  return true;
92
  }
93
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  /**
95
  * Get data on all tables and the number of records in the backup file.
96
  *
@@ -101,11 +203,20 @@ class Boldgrid_Backup_Admin_Db_Dump {
101
  * @return array
102
  */
103
  public function get_insert_count( $filepath, $file ) {
104
- $return = array();
 
105
 
106
- $tables = $this->get_insert_tables( $filepath, $file );
107
 
108
- $file_contents = $this->core->archive->get_file( $file );
 
 
 
 
 
 
 
 
109
 
110
  foreach ( $tables as $table ) {
111
  /*
@@ -140,7 +251,7 @@ class Boldgrid_Backup_Admin_Db_Dump {
140
  * of records.
141
  */
142
  $insert_command = str_replace( '\\\'', '', $line );
143
- $exploded = explode( '\'', $insert_command );
144
  foreach ( $exploded as $k => $v ) {
145
  // Odd numbers are what was between quotes.
146
  if ( 0 !== $k % 2 ) {
@@ -169,7 +280,7 @@ class Boldgrid_Backup_Admin_Db_Dump {
169
  */
170
  public function get_insert_tables( $filepath, $file ) {
171
  $this->core->archive->init( $filepath );
172
- $file_contents = $this->core->archive->get_file( $file );
173
 
174
  /*
175
  * Get a list of all tables within the dump that we are inserting
@@ -184,7 +295,7 @@ class Boldgrid_Backup_Admin_Db_Dump {
184
  *
185
  * For now, we'll go with the handy explode technique.
186
  */
187
- $tables = array();
188
  $exploded = explode( 'INSERT INTO `', $file_contents[0]['content'] );
189
  unset( $exploded[0] );
190
  foreach ( $exploded as $table ) {
1
  <?php
2
  /**
3
+ * File: class-boldgrid-backup-admin-db-dump.php
4
  *
5
+ * @link https://www.boldgrid.com
6
  * @since 1.5.1
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
  * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
  */
14
 
15
  use Ifsnop\Mysqldump as IMysqldump;
16
 
17
  /**
18
+ * Class: Boldgrid_Backup_Admin_Db_Dump
19
  *
20
  * @since 1.5.1
21
  */
22
  class Boldgrid_Backup_Admin_Db_Dump {
 
23
  /**
24
  * The core class object.
25
  *
45
  *
46
  * @since 1.5.1
47
  *
48
+ * @global wpdb $wpdb
49
+ *
50
  * @param string $file The filepath to our file.
51
  * @return bool True on success.
52
  */
53
  public function dump( $file ) {
54
+ global $wpdb;
55
+
56
  $include_tables = $this->core->db_omit->get_filtered_tables();
57
  if ( empty( $include_tables ) ) {
58
  return array( 'error' => esc_html__( 'No tables selected to backup.', 'boldgrid-backup' ) );
59
  }
60
 
61
+ /*
62
+ * Create separate arrays for the "tables" and "views" that we want to dump.
63
+ *
64
+ * When dumping our database, we need to send a separate list of tables to dump, and a separate
65
+ * one for views to dump. $include_tables is an array possibly containing both tables and views,
66
+ * so we'll split it up now.
67
+ *
68
+ * In the list below, it is important that $include_tables is processed last.
69
+ */
70
+ $include_views = $this->core->db_get->filter_by_type( $include_tables, 'VIEW' );
71
+ $include_tables = $this->core->db_get->filter_by_type( $include_tables, 'BASE TABLE' );
72
+
73
+ Boldgrid_Backup_Admin_In_Progress_Data::set_args(
74
+ array(
75
+ 'status' => __( 'Backing up database...', 'boldgrid-backup' ),
76
+ 'tables' => $include_tables,
77
+ 'step' => 1,
78
+ )
79
+ );
80
+
81
  /**
82
  * Take action before a database is dumped.
83
  *
84
  * @since 1.6.0
85
  */
86
+ do_action( 'boldgrid_backup_pre_dump', $file );
87
 
88
+ $settings = array(
89
+ 'include-tables' => $include_tables,
90
+ 'include-views' => $include_views,
91
+ 'add-drop-table' => true,
92
+ 'no-autocommit' => false,
93
+ );
94
+
95
+ /*
96
+ * Set default character set.
97
+ *
98
+ * By default, IMysqldump\Mysqldump uses utf8.
99
+ *
100
+ * By default, WordPress sets CHARSET to utf8 in wp-config but will default to utf8mb4
101
+ * if it's available.
102
+ *
103
+ * @see wpdb::determine_charset
104
+ */
105
+ if ( ! empty( $wpdb->charset ) ) {
106
+ $settings['default-character-set'] = $wpdb->charset;
107
+ }
108
 
109
  try {
110
  $dump = new IMysqldump\Mysqldump(
111
+ $this->get_connection_string(),
112
  DB_USER,
113
  DB_PASSWORD,
114
+ $settings
 
 
 
 
115
  );
116
  $dump->start( $file );
117
+ } catch ( \Exception $e ) {
118
  return array( 'error' => $e->getMessage() );
119
  }
120
 
123
  *
124
  * @since 1.6.0
125
  */
126
+ do_action( 'boldgrid_backup_post_dump', $file );
127
 
128
  return true;
129
  }
130
 
131
+ /**
132
+ * Get our PDO DSN connection string.
133
+ *
134
+ * @since 1.13.3
135
+ *
136
+ * @param string $db_host DB hostname.
137
+ * @param string $db_name DB name.
138
+ * @return string
139
+ */
140
+ public function get_connection_string( $db_host = null, $db_name = null ) {
141
+ $params = array();
142
+
143
+ // Configure parameters passed in.
144
+ $db_name = empty( $db_name ) ? DB_NAME : $db_name;
145
+ $db_host = empty( $db_host ) ? DB_HOST : $db_host;
146
+ $db_host = explode( ':', $db_host );
147
+
148
+ // Parse info and get hostname, port, and socket. Not all required. See comments below.
149
+ switch ( count( $db_host ) ) {
150
+ /*
151
+ * Examples:
152
+ *
153
+ * # localhost
154
+ * # /var/lib/mysql/mysql.sock
155
+ */
156
+ case 1:
157
+ $has_socket = 'sock' === pathinfo( $db_host[0], PATHINFO_EXTENSION );
158
+
159
+ if ( $has_socket ) {
160
+ $params['unix_socket'] = $db_host[0];
161
+ } else {
162
+ $params['host'] = $db_host[0];
163
+ }
164
+
165
+ break;
166
+ /*
167
+ * Examples:
168
+ *
169
+ * # localhost:/var/lib/mysql/mysql.sock
170
+ * # localhost:3306
171
+ */
172
+ case 2:
173
+ $has_socket = 'sock' === pathinfo( $db_host[1], PATHINFO_EXTENSION );
174
+ $has_port = is_numeric( $db_host[1] );
175
+
176
+ $params['host'] = $db_host[0];
177
+
178
+ if ( $has_socket ) {
179
+ $params['unix_socket'] = $db_host[1];
180
+ } elseif ( $has_port ) {
181
+ $params['port'] = $db_host[1];
182
+ }
183
+
184
+ break;
185
+ }
186
+
187
+ $connection_string = 'mysql:';
188
+ foreach ( $params as $key => $value ) {
189
+ $connection_string .= $key . '=' . $value . ';';
190
+ }
191
+ $connection_string .= 'dbname=' . $db_name;
192
+
193
+ return $connection_string;
194
+ }
195
+
196
  /**
197
  * Get data on all tables and the number of records in the backup file.
198
  *
203
  * @return array
204
  */
205
  public function get_insert_count( $filepath, $file ) {
206
+ $return = [];
207
+ $tables = [];
208
 
209
+ $this->core->archive->init( $filepath );
210
 
211
+ $file_contents = $this->core->archive->get_dump_file( $file );
212
+
213
+ // Check for the dump file header.
214
+ if ( false !== strpos( $file_contents[0]['content'], '-- mysqldump-php' ) ) {
215
+ $tables = $this->get_insert_tables( $filepath, $file );
216
+ } else {
217
+ // The file header is missing; the file may have been encrypted with other settings.
218
+ $return = [ 'encrypted_other' => true ];
219
+ }
220
 
221
  foreach ( $tables as $table ) {
222
  /*
251
  * of records.
252
  */
253
  $insert_command = str_replace( '\\\'', '', $line );
254
+ $exploded = explode( '\'', $insert_command );
255
  foreach ( $exploded as $k => $v ) {
256
  // Odd numbers are what was between quotes.
257
  if ( 0 !== $k % 2 ) {
280
  */
281
  public function get_insert_tables( $filepath, $file ) {
282
  $this->core->archive->init( $filepath );
283
+ $file_contents = $this->core->archive->get_dump_file( $file );
284
 
285
  /*
286
  * Get a list of all tables within the dump that we are inserting
295
  *
296
  * For now, we'll go with the handy explode technique.
297
  */
298
+ $tables = array();
299
  $exploded = explode( 'INSERT INTO `', $file_contents[0]['content'] );
300
  unset( $exploded[0] );
301
  foreach ( $exploded as $table ) {
admin/class-boldgrid-backup-admin-db-get.php CHANGED
@@ -1,24 +1,25 @@
1
  <?php
2
  /**
3
- * Db Get class.
4
  *
5
- * @link http://www.boldgrid.com
6
- * @since 1.5.3
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
- * @copyright BoldGrid.com
11
  * @version $Id$
12
- * @author BoldGrid.com <wpb@boldgrid.com>
13
  */
14
 
 
 
15
  /**
16
- * BoldGrid Backup Admin Db Get Class.
17
  *
18
  * @since 1.5.3
19
  */
20
  class Boldgrid_Backup_Admin_Db_Get {
21
-
22
  /**
23
  * The core class object.
24
  *
@@ -39,23 +40,101 @@ class Boldgrid_Backup_Admin_Db_Get {
39
  $this->core = $core;
40
  }
41
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  /**
43
  * Get a list of all tables based on system prefix.
44
  *
45
  * @since 1.5.3
46
  *
47
- * @global $wpdb;
48
  *
49
  * @return array
50
  */
51
  public function prefixed() {
52
  global $wpdb;
 
53
  $prefix_tables = array();
54
 
55
- $sql = sprintf( 'SHOW TABLES LIKE "%1$s%%"', $wpdb->prefix );
56
- $results = $wpdb->get_results( $sql, ARRAY_N );
 
 
 
 
 
57
 
58
- foreach ( $results as $k => $v ) {
59
  $prefix_tables[] = $v[0];
60
  }
61
 
@@ -70,17 +149,20 @@ class Boldgrid_Backup_Admin_Db_Get {
70
  *
71
  * @since 1.5.3
72
  *
 
 
73
  * @return array
74
  */
75
  public function prefixed_count() {
76
  global $wpdb;
 
77
  $return = array();
78
 
79
  $tables = $this->prefixed();
80
 
81
  foreach ( $tables as $table ) {
82
- $sql = sprintf( 'SELECT COUNT(*) FROM %1$s;', $table );
83
- $num = $wpdb->get_var( $sql );
84
  $return[ $table ] = $num;
85
  }
86
 
1
  <?php
2
  /**
3
+ * File: class-boldgrid-backup-admin-db-get.php
4
  *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.5.3
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
  * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
  */
14
 
15
+ // phpcs:disable WordPress.VIP
16
+
17
  /**
18
+ * Class: Boldgrid_Backup_Admin_Db_Get
19
  *
20
  * @since 1.5.3
21
  */
22
  class Boldgrid_Backup_Admin_Db_Get {
 
23
  /**
24
  * The core class object.
25
  *
40
  $this->core = $core;
41
  }
42
 
43
+ /**
44
+ * Get an array of all tables by table type.
45
+ *
46
+ * Types must be either "BASE TABLE" or "VIEW".
47
+ *
48
+ * This method does not filter the list of tables based on prefix.
49
+ *
50
+ * @since 1.12.4
51
+ *
52
+ * @param string $type The table type to get.
53
+ * @return array
54
+ */
55
+ public function get_by_type( $type ) {
56
+ global $wpdb;
57
+
58
+ $tables = [];
59
+
60
+ // Validate our table type.
61
+ $types = [ 'BASE TABLE', 'VIEW' ];
62
+ if ( ! in_array( $type, $types, true ) ) {
63
+ return [];
64
+ }
65
+
66
+ /*
67
+ * Get our list of tables by type.
68
+ *
69
+ * $results will be an array of arrays, with the latter arrays containing [0] table name and
70
+ * [1] table type.
71
+ */
72
+ $results = $wpdb->get_results(
73
+ $wpdb->prepare(
74
+ 'SHOW FULL TABLES WHERE TABLE_TYPE = %s;',
75
+ $type
76
+ ),
77
+ ARRAY_N
78
+ );
79
+
80
+ // Convert results to an array of table names (rather than an array of arrays).
81
+ foreach ( $results as $result ) {
82
+ $tables[] = $result[0];
83
+ }
84
+
85
+ return $tables;
86
+ }
87
+
88
+ /**
89
+ * Filter an array of table names by table type.
90
+ *
91
+ * For example, pass in an array of tables that include both "tables" and "views", and this method
92
+ * allows you get back only those that match $type.
93
+ *
94
+ * @since 1.12.4
95
+ *
96
+ * @param array $tables An array of table names.
97
+ * @param string $type A table type, such as "BASE TABLE" or "VIEW".
98
+ * @return array
99
+ */
100
+ public function filter_by_type( $tables, $type ) {
101
+ // The filtered list of tables that we will return.
102
+ $tables_by_type = [];
103
+
104
+ $all_of_type = $this->get_by_type( $type );
105
+
106
+ foreach ( $tables as $table ) {
107
+ if ( in_array( $table, $all_of_type, true ) ) {
108
+ $tables_by_type[] = $table;
109
+ }
110
+ }
111
+
112
+ return $tables_by_type;
113
+ }
114
+
115
  /**
116
  * Get a list of all tables based on system prefix.
117
  *
118
  * @since 1.5.3
119
  *
120
+ * @global wpdb $wpdb The WordPress database class object.
121
  *
122
  * @return array
123
  */
124
  public function prefixed() {
125
  global $wpdb;
126
+
127
  $prefix_tables = array();
128
 
129
+ $results = $wpdb->get_results(
130
+ $wpdb->prepare(
131
+ 'SHOW TABLES LIKE %s;',
132
+ $wpdb->esc_like( $wpdb->prefix ) . '%'
133
+ ),
134
+ ARRAY_N
135
+ );
136
 
137
+ foreach ( $results as $v ) {
138
  $prefix_tables[] = $v[0];
139
  }
140
 
149
  *
150
  * @since 1.5.3
151
  *
152
+ * @global wpdb $wpdb The WordPress database class object.
153
+ *
154
  * @return array
155
  */
156
  public function prefixed_count() {
157
  global $wpdb;
158
+
159
  $return = array();
160
 
161
  $tables = $this->prefixed();
162
 
163
  foreach ( $tables as $table ) {
164
+ $num = $wpdb->get_var( 'SELECT COUNT(*) FROM `' . $table . '`;' ); // phpcs:ignore WordPress.WP.PreparedSQL.NotPrepared
165
+
166
  $return[ $table ] = $num;
167
  }
168
 
admin/class-boldgrid-backup-admin-db-import.php CHANGED
@@ -1,27 +1,27 @@
1
  <?php
2
  /**
3
- * Database Import.
4
  *
5
- * @link http://www.boldgrid.com
6
  * @since 1.5.1
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
- * @copyright BoldGrid.com
11
  * @version $Id$
12
- * @author BoldGrid.com <wpb@boldgrid.com>
13
  */
 
14
  /**
15
- * BoldGrid Backup Admin Database Import class.
16
  *
17
  * @since 1.5.1
18
  */
19
  class Boldgrid_Backup_Admin_Db_Import {
20
-
21
  /**
22
  * The core class object.
23
  *
24
- * @since 1.5.4
25
  * @access private
26
  * @var Boldgrid_Backup_Admin_Core
27
  */
@@ -30,7 +30,7 @@ class Boldgrid_Backup_Admin_Db_Import {
30
  /**
31
  * Errors.
32
  *
33
- * @since 1.5.4
34
  * @var array
35
  */
36
  public $errors = array();
@@ -38,12 +38,11 @@ class Boldgrid_Backup_Admin_Db_Import {
38
  /**
39
  * Constructor.
40
  *
41
- * @since 1.5.4
42
  *
43
- * @param Boldgrid_Backup_Admin_Core $core
44
  */
45
  public function __construct( $core = false ) {
46
-
47
  // We don't always require $core for this class.
48
  if ( $core ) {
49
  $this->core = $core;
@@ -55,13 +54,20 @@ class Boldgrid_Backup_Admin_Db_Import {
55
  *
56
  * @since 1.5.1
57
  *
58
- * @param string $file The filepath to our file.
59
- * @return bool True on success.
60
  */
61
  public function import( $file ) {
62
  $lines = file( $file );
 
63
  if ( false === $lines ) {
64
- return array( 'error' => sprintf( __( 'Unable to open mysqldump, %1$s.', 'boldgrid-backup' ), $file ) );
 
 
 
 
 
 
65
  }
66
 
67
  $success = $this->import_lines( $lines );
@@ -75,17 +81,17 @@ class Boldgrid_Backup_Admin_Db_Import {
75
  * Pass in "file.zip" and "backup.sql" and we'll find "backup.sql" in the
76
  * "file.zip" file and restore it.
77
  *
78
- * @since 1.5.4
79
  *
80
- * @param string $archive_filepath
81
- * @param string $file
82
  * @return bool
83
  */
84
  public function import_from_archive( $archive_filepath, $file ) {
85
  $this->core->archive->init( $archive_filepath );
86
- $file_from_archive = $this->core->archive->get_file( $file );
87
 
88
- $sql = ! empty( $file_from_archive[0]['content'] ) ? $file_from_archive[0]['content'] : null;
89
  if ( empty( $sql ) ) {
90
  $this->errors[] = __( 'Unable to get contents of file.', 'boldgrid-backup' );
91
  return false;
@@ -108,9 +114,9 @@ class Boldgrid_Backup_Admin_Db_Import {
108
  * The functionality in this method use to be in the main import method,
109
  * however it was broken away to make more reusable.
110
  *
111
- * @since 1.5.4
112
  *
113
- * @param array $lines
114
  * @return bool
115
  */
116
  public function import_lines( $lines ) {
@@ -118,6 +124,7 @@ class Boldgrid_Backup_Admin_Db_Import {
118
  return false;
119
  }
120
 
 
121
  $db = new PDO( sprintf( 'mysql:host=%1$s;dbname=%2$s;', DB_HOST, DB_NAME ), DB_USER, DB_PASSWORD );
122
 
123
  $templine = '';
@@ -151,9 +158,9 @@ class Boldgrid_Backup_Admin_Db_Import {
151
  * file and import it. Instead of saving the .sql file then importing, it
152
  * comes straight from the .zip file as a string to here.
153
  *
154
- * @since 1.5.4
155
  *
156
- * @param string $string
157
  * @return bool
158
  */
159
  public function import_string( $string ) {
@@ -164,4 +171,3 @@ class Boldgrid_Backup_Admin_Db_Import {
164
  return $success;
165
  }
166
  }
167
-
1
  <?php
2
  /**
3
+ * File: class-boldgrid-backup-admin-db-import.php
4
  *
5
+ * @link https://www.boldgrid.com
6
  * @since 1.5.1
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
  * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
  */
14
+
15
  /**
16
+ * Class: Boldgrid_Backup_Admin_Db_Import
17
  *
18
  * @since 1.5.1
19
  */
20
  class Boldgrid_Backup_Admin_Db_Import {
 
21
  /**
22
  * The core class object.
23
  *
24
+ * @since 1.6.0
25
  * @access private
26
  * @var Boldgrid_Backup_Admin_Core
27
  */
30
  /**
31
  * Errors.
32
  *
33
+ * @since 1.6.0
34
  * @var array
35
  */
36
  public $errors = array();
38
  /**
39
  * Constructor.
40
  *
41
+ * @since 1.6.0
42
  *
43
+ * @param Boldgrid_Backup_Admin_Core $core Boldgrid_Backup_Admin_Core object.
44
  */
45
  public function __construct( $core = false ) {
 
46
  // We don't always require $core for this class.
47
  if ( $core ) {
48
  $this->core = $core;
54
  *
55
  * @since 1.5.1
56
  *
57
+ * @param string $file File path.
58
+ * @return bool TRUE on success.
59
  */
60
  public function import( $file ) {
61
  $lines = file( $file );
62
+
63
  if ( false === $lines ) {
64
+ return array(
65
+ 'error' => sprintf(
66
+ // translators: 1: File path.
67
+ __( 'Unable to open mysqldump, %1$s.', 'boldgrid-backup' ),
68
+ $file
69
+ ),
70
+ );
71
  }
72
 
73
  $success = $this->import_lines( $lines );
81
  * Pass in "file.zip" and "backup.sql" and we'll find "backup.sql" in the
82
  * "file.zip" file and restore it.
83
  *
84
+ * @since 1.6.0
85
  *
86
+ * @param string $archive_filepath Archive file path.
87
+ * @param string $file Filename.
88
  * @return bool
89
  */
90
  public function import_from_archive( $archive_filepath, $file ) {
91
  $this->core->archive->init( $archive_filepath );
92
+ $file_contents = $this->core->archive->get_dump_file( $file );
93
 
94
+ $sql = ! empty( $file_contents[0]['content'] ) ? $file_contents[0]['content'] : null;
95
  if ( empty( $sql ) ) {
96
  $this->errors[] = __( 'Unable to get contents of file.', 'boldgrid-backup' );
97
  return false;
114
  * The functionality in this method use to be in the main import method,
115
  * however it was broken away to make more reusable.
116
  *
117
+ * @since 1.6.0
118
  *
119
+ * @param array $lines MySQL dump file lines.
120
  * @return bool
121
  */
122
  public function import_lines( $lines ) {
124
  return false;
125
  }
126
 
127
+ /* phpcs:disable WordPress.DB.RestrictedClasses */
128
  $db = new PDO( sprintf( 'mysql:host=%1$s;dbname=%2$s;', DB_HOST, DB_NAME ), DB_USER, DB_PASSWORD );
129
 
130
  $templine = '';
158
  * file and import it. Instead of saving the .sql file then importing, it
159
  * comes straight from the .zip file as a string to here.
160
  *
161
+ * @since 1.6.0
162
  *
163
+ * @param string $string MySQL dump file as a string.
164
  * @return bool
165
  */
166
  public function import_string( $string ) {
171
  return $success;
172
  }
173
  }
 
admin/class-boldgrid-backup-admin-db-omit.php CHANGED
@@ -1,24 +1,25 @@
1
  <?php
2
  /**
3
- * Database Omit class.
4
  *
5
- * @link http://www.boldgrid.com
6
  * @since 1.5.3
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
- * @copyright BoldGrid.com
11
  * @version $Id$
12
- * @author BoldGrid.com <wpb@boldgrid.com>
13
  */
14
 
 
 
15
  /**
16
- * BoldGrid Backup Admin Db Omit Class.
17
  *
18
  * @since 1.5.3
19
  */
20
  class Boldgrid_Backup_Admin_Db_Omit {
21
-
22
  /**
23
  * The core class object.
24
  *
@@ -33,7 +34,7 @@ class Boldgrid_Backup_Admin_Db_Omit {
33
  *
34
  * Usually 'full' or 'custom' backup.
35
  *
36
- * @since 1.5.4
37
  * @access public
38
  * @var string
39
  */
@@ -44,7 +45,7 @@ class Boldgrid_Backup_Admin_Db_Omit {
44
  *
45
  * Usually 'full' or 'custom' backup.
46
  *
47
- * @since 1.5.4
48
  * @access public
49
  * @var array
50
  */
@@ -65,9 +66,9 @@ class Boldgrid_Backup_Admin_Db_Omit {
65
  * Generate a section for email alerts including information about tables
66
  * excluded.
67
  *
68
- * @since 1.5.4
69
  *
70
- * @param array $info
71
  * @return string
72
  */
73
  public function email_part( $info ) {
@@ -78,7 +79,14 @@ class Boldgrid_Backup_Admin_Db_Omit {
78
  $body .= "\n" . __( 'DATABASE SETTINGS', 'boldgrid-backup' ) . "\n";
79
 
80
  $tables_excluded = empty( $info['table_exclude'] ) ? __( 'None', 'boldgrid-backup' ) : implode( ',', $info['table_exclude'] );
81
- $body .= sprintf( esc_html__( 'Tables Excluded: %1$s', 'boldgrid-backup' ), $tables_excluded ) . "\n";
 
 
 
 
 
 
 
82
  }
83
 
84
  return $body;
@@ -87,11 +95,12 @@ class Boldgrid_Backup_Admin_Db_Omit {
87
  /**
88
  * Enqueue scripts.
89
  *
90
- * @since 1.5.4
91
  */
92
  public function enqueue_scripts() {
93
  $handle = 'boldgrid-backup-admin-table-include';
94
- wp_register_script( $handle,
 
95
  plugin_dir_url( __FILE__ ) . 'js/boldgrid-backup-admin-table-include.js',
96
  array( 'jquery' ),
97
  BOLDGRID_BACKUP_VERSION,
@@ -100,13 +109,6 @@ class Boldgrid_Backup_Admin_Db_Omit {
100
  $translation = array();
101
  wp_localize_script( $handle, 'BoldGridBackupAdminTableInclude', $translation );
102
  wp_enqueue_script( $handle );
103
-
104
- // Enqueue CSS for folder exclude functionality.
105
- // wp_enqueue_style(
106
- // $handle,
107
- // plugin_dir_url( __FILE__ ) . 'css/boldgrid-backup-admin-folder-exclude.css', array(),
108
- // BOLDGRID_BACKUP_VERSION
109
- // );
110
  }
111
 
112
  /**
@@ -123,7 +125,6 @@ class Boldgrid_Backup_Admin_Db_Omit {
123
  * @return array
124
  */
125
  public function get_excluded_tables() {
126
-
127
  /*
128
  * Determine if the user is doing "backup site now" and they selected to
129
  * backup all tables (full backup).
@@ -132,7 +133,7 @@ class Boldgrid_Backup_Admin_Db_Omit {
132
 
133
  if ( $this->core->is_archiving_update_protection || $backup_now_full || $this->core->pre_auto_update ) {
134
  $excluded_tables = array();
135
- } elseif ( $this->core->is_backup_now && isset( $_POST['include_tables'] ) ) {
136
  $excluded_tables = $this->get_from_post();
137
  } else {
138
  $settings = $this->core->settings->get_settings();
@@ -168,7 +169,7 @@ class Boldgrid_Backup_Admin_Db_Omit {
168
  $exclude_tables = $this->get_excluded_tables();
169
 
170
  foreach ( $prefixed_tables as $key => $table ) {
171
- if ( in_array( $table, $exclude_tables ) ) {
172
  unset( $prefixed_tables[ $key ] );
173
  }
174
  }
@@ -182,14 +183,14 @@ class Boldgrid_Backup_Admin_Db_Omit {
182
  * We are submitting via post "include_tables", however we use this data to
183
  * then calculate "exclude_tables".
184
  *
185
- * @since 1.5.4
186
  *
187
  * @return array
188
  */
189
  public function get_from_post() {
190
  $exclude_tables = array();
191
 
192
- $include_tables = ! empty( $_POST['include_tables'] ) ?
193
  array_map( 'sanitize_text_field', $_POST['include_tables'] ) : array();
194
 
195
  $all_tables = $this->core->db_get->prefixed();
@@ -200,7 +201,7 @@ class Boldgrid_Backup_Admin_Db_Omit {
200
  * If the table we want to
201
  */
202
  foreach ( $all_tables as $table ) {
203
- if ( ! in_array( $table, $include_tables ) ) {
204
  $exclude_tables[] = $table;
205
  }
206
  }
@@ -211,14 +212,14 @@ class Boldgrid_Backup_Admin_Db_Omit {
211
  /**
212
  * Get value of 'table_inclusion_type' from $_POST.
213
  *
214
- * @since 1.5.4
215
  *
216
  * @return string
217
  */
218
  public function get_post_type() {
219
  $key = 'table_inclusion_type';
220
 
221
- return ! empty( $_POST[ $key ] ) && in_array( $_POST[ $key ], $this->valid_types, true ) ?
222
  sanitize_key( $_POST[ $key ] ) : null;
223
  }
224
 
@@ -227,12 +228,12 @@ class Boldgrid_Backup_Admin_Db_Omit {
227
  *
228
  * If no exclude_tables are set, return an empty array.
229
  *
230
- * @since 1.5.4
231
  *
232
- * @param array $settings
233
  * @return bool
234
  */
235
- public function get_settings_excluded( $settings = array() ) {
236
  if ( empty( $settings ) ) {
237
  $settings = $this->core->settings->get_settings();
238
  }
@@ -241,7 +242,7 @@ class Boldgrid_Backup_Admin_Db_Omit {
241
  $key = 'exclude_tables';
242
 
243
  return ! isset( $settings[ $key ] ) || ! is_array( $settings[ $key ] ) ?
244
- array() : array_map( 'sanitize_text_field', $settings[ $key ] );
245
  }
246
 
247
  /**
@@ -252,9 +253,9 @@ class Boldgrid_Backup_Admin_Db_Omit {
252
  *
253
  * Return null if we do not have a type saved in the settings.
254
  *
255
- * @since 1.5.4
256
  *
257
- * @param array $settings
258
  * @return bool
259
  */
260
  public function get_settings_type( $settings = array() ) {
@@ -283,7 +284,7 @@ class Boldgrid_Backup_Admin_Db_Omit {
283
  $return = '';
284
 
285
  foreach ( $tables as $table ) {
286
- $checked = in_array( $table, $exclude_tables ) ? '' : 'checked';
287
  $return .= sprintf(
288
  '<div title="%1$s"><input value="%1$s" name="include_tables[]" type="checkbox" %2$s /> %1$s</div>',
289
  esc_html( $table ),
@@ -302,7 +303,7 @@ class Boldgrid_Backup_Admin_Db_Omit {
302
  * @return bool
303
  */
304
  public function is_omit_all() {
305
- $exclude_tables = $this->get_excluded_tables();
306
  $prefixed_tables = $this->core->db_get->prefixed();
307
 
308
  $diff = array_diff( $prefixed_tables, $exclude_tables );
1
  <?php
2
  /**
3
+ * File: class-boldgrid-backup-admin-db-omit.php
4
  *
5
+ * @link https://www.boldgrid.com
6
  * @since 1.5.3
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
  * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
  */
14
 
15
+ // phpcs:disable WordPress.VIP
16
+
17
  /**
18
+ * Class: Boldgrid_Backup_Admin_Db_Omit
19
  *
20
  * @since 1.5.3
21
  */
22
  class Boldgrid_Backup_Admin_Db_Omit {
 
23
  /**
24
  * The core class object.
25
  *
34
  *
35
  * Usually 'full' or 'custom' backup.
36
  *
37
+ * @since 1.6.0
38
  * @access public
39
  * @var string
40
  */
45
  *
46
  * Usually 'full' or 'custom' backup.
47
  *
48
+ * @since 1.6.0
49
  * @access public
50
  * @var array
51
  */
66
  * Generate a section for email alerts including information about tables
67
  * excluded.
68
  *
69
+ * @since 1.6.0
70
  *
71
+ * @param array $info Database table information.
72
  * @return string
73
  */
74
  public function email_part( $info ) {
79
  $body .= "\n" . __( 'DATABASE SETTINGS', 'boldgrid-backup' ) . "\n";
80
 
81
  $tables_excluded = empty( $info['table_exclude'] ) ? __( 'None', 'boldgrid-backup' ) : implode( ',', $info['table_exclude'] );
82
+
83
+ $body .= sprintf(
84
+ // translators: 1: Database tables excluded.
85
+ __(
86
+ 'Tables Excluded: %1$s', 'boldgrid-backup'
87
+ ),
88
+ $tables_excluded
89
+ ) . "\n";
90
  }
91
 
92
  return $body;
95
  /**
96
  * Enqueue scripts.
97
  *
98
+ * @since 1.6.0
99
  */
100
  public function enqueue_scripts() {
101
  $handle = 'boldgrid-backup-admin-table-include';
102
+ wp_register_script(
103
+ $handle,
104
  plugin_dir_url( __FILE__ ) . 'js/boldgrid-backup-admin-table-include.js',
105
  array( 'jquery' ),
106
  BOLDGRID_BACKUP_VERSION,
109
  $translation = array();
110
  wp_localize_script( $handle, 'BoldGridBackupAdminTableInclude', $translation );
111
  wp_enqueue_script( $handle );
 
 
 
 
 
 
 
112
  }
113
 
114
  /**
125
  * @return array
126
  */
127
  public function get_excluded_tables() {
 
128
  /*
129
  * Determine if the user is doing "backup site now" and they selected to
130
  * backup all tables (full backup).
133
 
134
  if ( $this->core->is_archiving_update_protection || $backup_now_full || $this->core->pre_auto_update ) {
135
  $excluded_tables = array();
136
+ } elseif ( $this->core->is_backup_now ) {
137
  $excluded_tables = $this->get_from_post();
138
  } else {
139
  $settings = $this->core->settings->get_settings();
169
  $exclude_tables = $this->get_excluded_tables();
170
 
171
  foreach ( $prefixed_tables as $key => $table ) {
172
+ if ( in_array( $table, $exclude_tables, true ) ) {
173
  unset( $prefixed_tables[ $key ] );
174
  }
175
  }
183
  * We are submitting via post "include_tables", however we use this data to
184
  * then calculate "exclude_tables".
185
  *
186
+ * @since 1.6.0
187
  *
188
  * @return array
189
  */
190
  public function get_from_post() {
191
  $exclude_tables = array();
192
 
193
+ $include_tables = ! empty( $_POST['include_tables'] ) ? // phpcs:ignore WordPress.CSRF.NonceVerification.NoNonceVerification
194
  array_map( 'sanitize_text_field', $_POST['include_tables'] ) : array();
195
 
196
  $all_tables = $this->core->db_get->prefixed();
201
  * If the table we want to
202
  */
203
  foreach ( $all_tables as $table ) {
204
+ if ( ! in_array( $table, $include_tables, true ) ) {
205
  $exclude_tables[] = $table;
206
  }
207
  }
212
  /**
213
  * Get value of 'table_inclusion_type' from $_POST.
214
  *
215
+ * @since 1.6.0
216
  *
217
  * @return string
218
  */
219
  public function get_post_type() {
220
  $key = 'table_inclusion_type';
221
 
222
+ return ! empty( $_POST[ $key ] ) && in_array( $_POST[ $key ], $this->valid_types, true ) ? // phpcs:ignore WordPress.CSRF.NonceVerification.NoNonceVerification
223
  sanitize_key( $_POST[ $key ] ) : null;
224
  }
225
 
228
  *
229
  * If no exclude_tables are set, return an empty array.
230
  *
231
+ * @since 1.6.0
232
  *
233
+ * @param array $settings Settings.
234
  * @return bool
235
  */
236
+ public function get_settings_excluded( $settings = [] ) {
237
  if ( empty( $settings ) ) {
238
  $settings = $this->core->settings->get_settings();
239
  }
242
  $key = 'exclude_tables';
243
 
244
  return ! isset( $settings[ $key ] ) || ! is_array( $settings[ $key ] ) ?
245
+ [] : array_map( 'sanitize_text_field', $settings[ $key ] );
246
  }
247
 
248
  /**
253
  *
254
  * Return null if we do not have a type saved in the settings.
255
  *
256
+ * @since 1.6.0
257
  *
258
+ * @param array $settings Settings.
259
  * @return bool
260
  */
261
  public function get_settings_type( $settings = array() ) {
284
  $return = '';
285
 
286
  foreach ( $tables as $table ) {
287
+ $checked = in_array( $table, $exclude_tables, true ) ? '' : 'checked';
288
  $return .= sprintf(
289
  '<div title="%1$s"><input value="%1$s" name="include_tables[]" type="checkbox" %2$s /> %1$s</div>',
290
  esc_html( $table ),
303
  * @return bool
304
  */
305
  public function is_omit_all() {
306
+ $exclude_tables = $this->get_excluded_tables();
307
  $prefixed_tables = $this->core->db_get->prefixed();
308
 
309
  $diff = array_diff( $prefixed_tables, $exclude_tables );
admin/class-boldgrid-backup-admin-email.php CHANGED
@@ -1,28 +1,29 @@
1
  <?php
2
  /**
3
- * Email.
4
  *
5
- * @link http://www.boldgrid.com
 
 
6
  * @since 1.5.2
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
- * @copyright BoldGrid.com
11
  * @version $Id$
12
- * @author BoldGrid.com <wpb@boldgrid.com>
13
  */
14
 
15
  /**
16
- * Email.
17
  *
18
  * @since 1.5.2
19
  */
20
  class Boldgrid_Backup_Admin_Email {
21
-
22
  /**
23
  * An array of ads.
24
  *
25
- * @since 1.5.4
26
  * @access private
27
  * @var array
28
  */
@@ -42,7 +43,7 @@ class Boldgrid_Backup_Admin_Email {
42
  *
43
  * @since 1.5.2
44
  *
45
- * @param Boldgrid_Backup_Admin_Core $core
46
  */
47
  public function __construct( $core ) {
48
  $this->core = $core;
@@ -53,7 +54,7 @@ class Boldgrid_Backup_Admin_Email {
53
  *
54
  * @since 1.5.2
55
  *
56
- * @param string $message
57
  * @param bool $add_ad Allow ads to be added to the email. In some cases,
58
  * like when we have bad news (something failed), we
59
  * may not want to ask the user to upgrade (bad timing).
@@ -71,7 +72,11 @@ class Boldgrid_Backup_Admin_Email {
71
  }
72
 
73
  $email_body .= __( 'Best regards', 'boldgrid-backup' ) . ",\n\n";
74
- $email_body .= __( 'The BoldGrid Backup plugin', 'boldgrid-backup' ) . "\n\n";
 
 
 
 
75
 
76
  return $email_body;
77
  }
@@ -79,15 +84,20 @@ class Boldgrid_Backup_Admin_Email {
79
  /**
80
  * Init our ads.
81
  *
82
- * @since 1.5.4
83
  */
84
  public function init_ads() {
85
- $this->ads = array(
86
  'generic' => $this->core->config->get_is_premium() ? '' : sprintf(
87
- __( 'Want to store your backups on Amazon S3, restore individual files with just a click, and have access to more tools? Get BoldGrid Backup Premium! - %1$s', 'boldgrid-backup' ),
88
- Boldgrid_Backup_Admin_Go_Pro::$url
 
 
 
 
 
89
  ) . "\n\n",
90
- );
91
  }
92
 
93
  /**
@@ -95,7 +105,7 @@ class Boldgrid_Backup_Admin_Email {
95
  *
96
  * @since 1.5.2
97
  *
98
- * @param array $info
99
  * @return array
100
  */
101
  public function post_archive_parts( $info ) {
@@ -105,22 +115,40 @@ class Boldgrid_Backup_Admin_Email {
105
 
106
  $site_id = Boldgrid_Backup_Admin_Utility::create_site_id();
107
 
108
- $parts['subject'] = sprintf( __( 'Backup completed for %s', 'boldgrid-backup' ), $site_id );
 
109
 
110
  $parts['body']['main'] = esc_html__( 'Hello', 'boldgrid-backup' ) . ",\n\n";
 
111
  if ( $info['dryrun'] ) {
112
  $body['main'] .= esc_html__( 'THIS OPERATION WAS A DRY-RUN TEST', 'boldgrid-backup' ) . ".\n\n";
113
  }
114
- $parts['body']['main'] .= sprintf( esc_html__( 'A backup archive has been created for %s', 'boldgrid-backup' ), $site_id ) . ".\n\n";
 
 
 
 
 
115
  $parts['body']['main'] .= esc_html__( 'Backup details', 'boldgrid-backup' ) . ":\n";
116
  $parts['body']['main'] .= sprintf( $this->core->configs['lang']['est_pause'], $info['db_duration'] ) . "\n";
117
- $parts['body']['main'] .= sprintf( esc_html__( 'Duration: %s seconds', 'boldgrid-backup' ), $info['duration'] ) . "\n";
118
- $parts['body']['main'] .= sprintf( esc_html__( 'Total size: %s', 'boldgrid-backup' ), Boldgrid_Backup_Admin_Utility::bytes_to_human( $info['total_size'] ) ) . "\n";
119
- $parts['body']['main'] .= sprintf( esc_html__( 'Archive file path: %s', 'boldgrid-backup' ), $info['filepath'] ) . "\n";
120
- $parts['body']['main'] .= sprintf( esc_html__( 'Archive file size: %s', 'boldgrid-backup' ), Boldgrid_Backup_Admin_Utility::bytes_to_human( $info['filesize'] ) ) . "\n";
121
- $parts['body']['main'] .= sprintf( esc_html__( 'Compressor used: %s', 'boldgrid-backup' ), $info['compressor'] ) . "\n";
 
 
 
 
 
 
 
 
 
 
122
 
123
  if ( ! empty( $info['trigger'] ) ) {
 
124
  $parts['body']['main'] .= sprintf( esc_html__( 'Backup triggered by: %1$s', 'boldgrid-backup' ), $info['trigger'] ) . "\n";
125
  }
126
 
@@ -130,13 +158,30 @@ class Boldgrid_Backup_Admin_Email {
130
 
131
  $parts['body']['main'] .= "\n";
132
 
133
- $parts['body']['signature'] = esc_html__( 'You can manage notifications in your WordPress admin panel, under BoldGrid Backup Settings', 'boldgrid-backup' ) . ".\n\n";
134
- $parts['body']['signature'] .= sprintf( esc_html__( 'For help with restoring a BoldGrid Backup archive file, please visit: %s', 'boldgrid-backup' ), esc_url( $this->core->configs['urls']['restore'] ) ) . "\n\n";
 
 
 
 
 
 
 
 
 
 
 
 
 
135
 
136
  $parts['body']['signature'] .= $this->ads['generic'];
137
 
138
  $parts['body']['signature'] .= esc_html__( 'Best regards', 'boldgrid-backup' ) . ",\n\n";
139
- $parts['body']['signature'] .= esc_html__( 'The BoldGrid Backup plugin', 'boldgrid-backup' ) . "\n\n";
 
 
 
 
140
 
141
  return $parts;
142
  }
@@ -169,8 +214,22 @@ class Boldgrid_Backup_Admin_Email {
169
  $headers = 'From: ' . $site_title . ' <' . $admin_email . '>' . "\r\n" . 'X-Mailer: PHP/' .
170
  phpversion() . "\r\n";
171
 
172
- // Send mail.
173
- $status = wp_mail( $admin_email, $subject, $body, $headers );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
174
 
175
  // Return status.
176
  return $status;
@@ -188,4 +247,23 @@ class Boldgrid_Backup_Admin_Email {
188
 
189
  return ! empty( $settings['notifications'][ $task ] );
190
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
191
  }
1
  <?php
2
  /**
3
+ * File: class-boldgrid-backup-admin-email.php
4
  *
5
+ * Email helper.
6
+ *
7
+ * @link https://www.boldgrid.com
8
  * @since 1.5.2
9
  *
10
  * @package Boldgrid_Backup
11
  * @subpackage Boldgrid_Backup/admin
12
+ * @copyright BoldGrid
13
  * @version $Id$
14
+ * @author BoldGrid <support@boldgrid.com>
15
  */
16
 
17
  /**
18
+ * Class: Boldgrid_Backup_Admin_Email
19
  *
20
  * @since 1.5.2
21
  */
22
  class Boldgrid_Backup_Admin_Email {
 
23
  /**
24
  * An array of ads.
25
  *
26
+ * @since 1.6.0
27
  * @access private
28
  * @var array
29
  */
43
  *
44
  * @since 1.5.2
45
  *
46
+ * @param Boldgrid_Backup_Admin_Core $core Boldgrid_Backup_Admin_Core object.
47
  */
48
  public function __construct( $core ) {
49
  $this->core = $core;
54
  *
55
  * @since 1.5.2
56
  *
57
+ * @param string $message Message to send.
58
  * @param bool $add_ad Allow ads to be added to the email. In some cases,
59
  * like when we have bad news (something failed), we
60
  * may not want to ask the user to upgrade (bad timing).
72
  }
73
 
74
  $email_body .= __( 'Best regards', 'boldgrid-backup' ) . ",\n\n";
75
+ $email_body .= sprintf(
76
+ // translators: 1: Plugin title.
77
+ __( 'The %1$s plugin', 'boldgrid-backup' ) . "\n\n",
78
+ BOLDGRID_BACKUP_TITLE
79
+ );
80
 
81
  return $email_body;
82
  }
84
  /**
85
  * Init our ads.
86
  *
87
+ * @since 1.6.0
88
  */
89
  public function init_ads() {
90
+ $this->ads = [
91
  'generic' => $this->core->config->get_is_premium() ? '' : sprintf(
92
+ // translators: 1: URL address, 2: Premium plugin title.
93
+ __(
94
+ 'Want to store your backups on Google Drive and Amazon S3, restore individual files with just a click, and have access to more tools? Get %2$s! - %1$s',
95
+ 'boldgrid-backup'
96
+ ),
97
+ $this->core->go_pro->get_premium_url( 'bgbkup-email' ),
98
+ BOLDGRID_BACKUP_TITLE . ' Premium'
99
  ) . "\n\n",
100
+ ];
101
  }
102
 
103
  /**
105
  *
106
  * @since 1.5.2
107
  *
108
+ * @param array $info Archive process information.
109
  * @return array
110
  */
111
  public function post_archive_parts( $info ) {
115
 
116
  $site_id = Boldgrid_Backup_Admin_Utility::create_site_id();
117
 
118
+ // translators: 1: Site identifier.
119
+ $parts['subject'] = sprintf( __( 'Backup completed for %1$s', 'boldgrid-backup' ), $site_id );
120
 
121
  $parts['body']['main'] = esc_html__( 'Hello', 'boldgrid-backup' ) . ",\n\n";
122
+
123
  if ( $info['dryrun'] ) {
124
  $body['main'] .= esc_html__( 'THIS OPERATION WAS A DRY-RUN TEST', 'boldgrid-backup' ) . ".\n\n";
125
  }
126
+
127
+ $parts['body']['main'] .= sprintf(
128
+ // translators: 1: Site identifier/name.
129
+ esc_html__( 'A backup archive has been created for %1$s', 'boldgrid-backup' ),
130
+ $site_id
131
+ ) . ".\n\n";
132
  $parts['body']['main'] .= esc_html__( 'Backup details', 'boldgrid-backup' ) . ":\n";
133
  $parts['body']['main'] .= sprintf( $this->core->configs['lang']['est_pause'], $info['db_duration'] ) . "\n";
134
+
135
+ // translators: 1: Backup duration.
136
+ $parts['body']['main'] .= sprintf( esc_html__( 'Duration: %1$s seconds', 'boldgrid-backup' ), $info['duration'] ) . "\n";
137
+
138
+ // translators: 1: Total backup size.
139
+ $parts['body']['main'] .= sprintf( esc_html__( 'Total size: %1$s', 'boldgrid-backup' ), Boldgrid_Backup_Admin_Utility::bytes_to_human( $info['total_size'] ) ) . "\n";
140
+
141
+ // translators: 1: Archive file path.
142
+ $parts['body']['main'] .= sprintf( esc_html__( 'Archive file path: %1$s', 'boldgrid-backup' ), $info['filepath'] ) . "\n";
143
+
144
+ // translators: 1: Archive file size.
145
+ $parts['body']['main'] .= sprintf( esc_html__( 'Archive file size: %1$s', 'boldgrid-backup' ), Boldgrid_Backup_Admin_Utility::bytes_to_human( $info['filesize'] ) ) . "\n";
146
+
147
+ // translators: 1: Archive compressor name.
148
+ $parts['body']['main'] .= sprintf( esc_html__( 'Compressor used: %1$s', 'boldgrid-backup' ), $info['compressor'] ) . "\n";
149
 
150
  if ( ! empty( $info['trigger'] ) ) {
151
+ // translators: 1: What triggered the backup process.
152
  $parts['body']['main'] .= sprintf( esc_html__( 'Backup triggered by: %1$s', 'boldgrid-backup' ), $info['trigger'] ) . "\n";
153
  }
154
 
158
 
159
  $parts['body']['main'] .= "\n";
160
 
161
+ $parts['body']['signature'] = sprintf(
162
+ // translators: 1: Plugin title.
163
+ __(
164
+ 'You can manage notifications in your WordPress admin panel, under %1$s settings',
165
+ 'boldgrid-backup'
166
+ ),
167
+ BOLDGRID_BACKUP_TITLE
168
+ ) . ".\n\n";
169
+
170
+ $parts['body']['signature'] .= sprintf(
171
+ // translators: 1: Plugin title, 2: URL address for help restoring a backup archive file.
172
+ esc_html__( 'For help with restoring a %1$s archive file, please visit: %2$s', 'boldgrid-backup' ),
173
+ BOLDGRID_BACKUP_TITLE,
174
+ esc_url( $this->core->configs['urls']['restore'] )
175
+ ) . "\n\n";
176
 
177
  $parts['body']['signature'] .= $this->ads['generic'];
178
 
179
  $parts['body']['signature'] .= esc_html__( 'Best regards', 'boldgrid-backup' ) . ",\n\n";
180
+ $parts['body']['signature'] .= sprintf(
181
+ // translators: 1: Plugin title.
182
+ esc_html__( 'The %1$s plugin', 'boldgrid-backup' ),
183
+ BOLDGRID_BACKUP_TITLE
184
+ ) . "\n\n";
185
 
186
  return $parts;
187
  }
214
  $headers = 'From: ' . $site_title . ' <' . $admin_email . '>' . "\r\n" . 'X-Mailer: PHP/' .
215
  phpversion() . "\r\n";
216
 
217
+ /*
218
+ * Send mail.
219
+ *
220
+ * The default behaviour is to include $headers in our call to wp_mail. In very rare circumstances,
221
+ * this will cause the following error:
222
+ *
223
+ * # Could not instantiate mail function.
224
+ * # phpmailer_exception_code 2
225
+ *
226
+ * In those rare cases, the user can define BGBKUP_SKIP_EMAIL_HEADERS to skip adding the headers.
227
+ */
228
+ if ( defined( 'BGBKUP_SKIP_EMAIL_HEADERS' ) ) {
229
+ $status = wp_mail( $admin_email, $subject, $body );
230
+ } else {
231
+ $status = wp_mail( $admin_email, $subject, $body, $headers );
232
+ }
233
 
234
  // Return status.
235
  return $status;
247
 
248
  return ! empty( $settings['notifications'][ $task ] );
249
  }
250
+
251
+ /**
252
+ * Hook into the wp_mail_failed action.
253
+ *
254
+ * @since 1.13.4
255
+ *
256
+ * @param WP_Error $wp_error A WP error object.
257
+ */
258
+ public function wp_mail_failed( $wp_error ) {
259
+ // If in the middle of archiving files and an email failed, add info about it to the log.
260
+ if ( $this->core->archiving_files || $this->core->restoring_archive_file ) {
261
+ $errors = array(
262
+ 'wp_error' => $wp_error,
263
+ 'last_error' => error_get_last(),
264
+ );
265
+
266
+ $this->core->logger->add( 'wp_mail_failed: ' . print_r( $errors, 1 ) ); // phpcs:ignore
267
+ }
268
+ }
269
  }
admin/class-boldgrid-backup-admin-filelist.php CHANGED
@@ -1,28 +1,27 @@
1
  <?php
2
  /**
3
- * Boldgrid Backup Admin Filelist.
4
  *
5
- * @link http://www.boldgrid.com
6
  * @since 1.5.1
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
- * @copyright BoldGrid.com
11
  * @version $Id$
12
- * @author BoldGrid.com <wpb@boldgrid.com>
13
  */
14
 
15
  /**
16
- * BoldGrid Backup Admin Filelist Class.
17
  *
18
  * @since 1.5.1
19
  */
20
  class Boldgrid_Backup_Admin_Filelist {
21
-
22
  /**
23
  * The core class object.
24
  *
25
- * @since 1.5.4
26
  * @access private
27
  * @var Boldgrid_Backup_Admin_Core
28
  */
@@ -36,7 +35,7 @@ class Boldgrid_Backup_Admin_Filelist {
36
  * This array primarily exists to help get the total size of your website.
37
  * We loop through this list and calculate the disk space of each item.
38
  *
39
- * @since 1.5.4
40
  * @access public
41
  * @var array
42
  */
@@ -67,7 +66,7 @@ class Boldgrid_Backup_Admin_Filelist {
67
  /**
68
  * Constructor.
69
  *
70
- * @since 1.5.4
71
  *
72
  * @param Boldgrid_Backup_Admin_Core $core Core class object.
73
  */
@@ -78,12 +77,11 @@ class Boldgrid_Backup_Admin_Filelist {
78
  /**
79
  * Get the total size of WordPress core and the wp-content directory.
80
  *
81
- * @since 1.5.4
82
  *
83
  * @return int
84
  */
85
  public function get_size() {
86
-
87
  /*
88
  * Include wp-includes/ms-functions.php.
89
  *
1
  <?php
2
  /**
3
+ * File: class-boldgrid-backup-admin-filelist.php
4
  *
5
+ * @link https://www.boldgrid.com
6
  * @since 1.5.1
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
  * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
  */
14
 
15
  /**
16
+ * Class: Boldgrid_Backup_Admin_Filelist
17
  *
18
  * @since 1.5.1
19
  */
20
  class Boldgrid_Backup_Admin_Filelist {
 
21
  /**
22
  * The core class object.
23
  *
24
+ * @since 1.6.0
25
  * @access private
26
  * @var Boldgrid_Backup_Admin_Core
27
  */
35
  * This array primarily exists to help get the total size of your website.
36
  * We loop through this list and calculate the disk space of each item.
37
  *
38
+ * @since 1.6.0
39
  * @access public
40
  * @var array
41
  */
66
  /**
67
  * Constructor.
68
  *
69
+ * @since 1.6.0
70
  *
71
  * @param Boldgrid_Backup_Admin_Core $core Core class object.
72
  */
77
  /**
78
  * Get the total size of WordPress core and the wp-content directory.
79
  *
80
+ * @since 1.6.0
81
  *
82
  * @return int
83
  */
84
  public function get_size() {
 
85
  /*
86
  * Include wp-includes/ms-functions.php.
87
  *
admin/class-boldgrid-backup-admin-folder-exclusion.php CHANGED
@@ -1,28 +1,29 @@
1
  <?php
2
  /**
3
- * Folder Exclusion class.
4
  *
5
- * @link http://www.boldgrid.com
6
- * @since 1.5.4
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
- * @copyright BoldGrid.com
11
  * @version $Id$
12
- * @author BoldGrid.com <wpb@boldgrid.com>
13
  */
14
 
 
 
15
  /**
16
- * BoldGrid Backup Admin Folder Exclusion Class.
17
  *
18
- * @since 1.5.4
19
  */
20
  class Boldgrid_Backup_Admin_Folder_Exclusion {
21
-
22
  /**
23
  * The default exclude value.
24
  *
25
- * @since 1.5.4
26
  * @var string
27
  */
28
  public $default_exclude = '.git,node_modules';
@@ -30,7 +31,7 @@ class Boldgrid_Backup_Admin_Folder_Exclusion {
30
  /**
31
  * The default include value.
32
  *
33
- * @since 1.5.4
34
  * @var string
35
  */
36
  public $default_include = 'WPCORE,/wp-content';
@@ -38,7 +39,7 @@ class Boldgrid_Backup_Admin_Folder_Exclusion {
38
  /**
39
  * By default, backup all files and folders (use default settings).
40
  *
41
- * @since 1.5.4
42
  * @var string
43
  */
44
  public $default_type = 'full';
@@ -46,7 +47,7 @@ class Boldgrid_Backup_Admin_Folder_Exclusion {
46
  /**
47
  * Our exclude value.
48
  *
49
- * @since 1.5.4
50
  * @var string|null
51
  */
52
  public $exclude = null;
@@ -54,7 +55,7 @@ class Boldgrid_Backup_Admin_Folder_Exclusion {
54
  /**
55
  * Our include value.
56
  *
57
- * @since 1.5.4
58
  * @var string|null
59
  */
60
  public $include = null;
@@ -62,7 +63,7 @@ class Boldgrid_Backup_Admin_Folder_Exclusion {
62
  /**
63
  * Whether or not we're in the ajax preview.
64
  *
65
- * @since 1.5.4
66
  * @var bool
67
  */
68
  public $in_ajax_preview = false;
@@ -72,7 +73,7 @@ class Boldgrid_Backup_Admin_Folder_Exclusion {
72
  *
73
  * Usually it will be 'full' or 'custom'.
74
  *
75
- * @since 1.5.4
76
  * @var null|string
77
  */
78
  public $type = null;
@@ -80,7 +81,7 @@ class Boldgrid_Backup_Admin_Folder_Exclusion {
80
  /**
81
  * Allowable types.
82
  *
83
- * @since 1.5.4
84
  * @var array
85
  */
86
  public $types = array( 'include', 'exclude', 'type' );
@@ -88,7 +89,7 @@ class Boldgrid_Backup_Admin_Folder_Exclusion {
88
  /**
89
  * Valid backup types.
90
  *
91
- * @since 1.5.4
92
  * @var array
93
  */
94
  public $valid_types = array( 'full', 'custom' );
@@ -96,7 +97,7 @@ class Boldgrid_Backup_Admin_Folder_Exclusion {
96
  /**
97
  * The core class object.
98
  *
99
- * @since 1.5.4
100
  * @access private
101
  * @var Boldgrid_Backup_Admin_Core
102
  */
@@ -105,7 +106,7 @@ class Boldgrid_Backup_Admin_Folder_Exclusion {
105
  /**
106
  * Constructor.
107
  *
108
- * @since 1.5.4
109
  *
110
  * @param Boldgrid_Backup_Admin_Core $core Core class object.
111
  */
@@ -134,9 +135,9 @@ class Boldgrid_Backup_Admin_Folder_Exclusion {
134
  /**
135
  * Determine if we should allow a file in the backup.
136
  *
137
- * @since 1.5.4
138
  *
139
- * @param string $file
140
  * @return bool
141
  */
142
  public function allow_file( $file ) {
@@ -145,6 +146,11 @@ class Boldgrid_Backup_Admin_Folder_Exclusion {
145
  return false;
146
  }
147
 
 
 
 
 
 
148
  // Get comma-delimited lists from user input or settings. Sanitizing is done below.
149
  $include = $this->in_ajax_preview ? $_POST['include'] : $this->from_settings( 'include' );
150
  $exclude = $this->in_ajax_preview ? $_POST['exclude'] : $this->from_settings( 'exclude' );
@@ -186,9 +192,9 @@ class Boldgrid_Backup_Admin_Folder_Exclusion {
186
  * Generate a section for email alerts including information about files and
187
  * folders excluded.
188
  *
189
- * @since 1.5.4
190
  *
191
- * @param array $info
192
  * @return string
193
  */
194
  public function email_part( $info ) {
@@ -202,11 +208,19 @@ class Boldgrid_Backup_Admin_Folder_Exclusion {
202
  }
203
 
204
  if ( $has_folder_included ) {
205
- $body .= sprintf( esc_html__( 'Included: %1$s', 'boldgrid-backup' ), $info['folder_include'] ) . "\n";
 
 
 
 
206
  }
207
 
208
  if ( $has_folder_excluded ) {
209
- $body .= sprintf( esc_html__( 'Excluded: %1$s', 'boldgrid-backup' ), $info['folder_exclude'] ) . "\n";
 
 
 
 
210
  }
211
 
212
  return $body;
@@ -216,7 +230,7 @@ class Boldgrid_Backup_Admin_Folder_Exclusion {
216
  * Create our regex pattern.
217
  *
218
  * If the user enters wp-* for their include / exclude value, then we need
219
- * to convert that into a propper regex pattern.
220
  *
221
  * When we look for matches, we want to keep it specific to one folder.
222
  * For example, if we're given wp-adm*n, the expectation is that we want
@@ -225,12 +239,11 @@ class Boldgrid_Backup_Admin_Folder_Exclusion {
225
  * To prevent this false positive:
226
  * wp-admin/images/media-button.png
227
  * wp-adm************************ng
228
- * ... we will set the wildcard to match everything except a directory
229
- * separator.
230
  *
231
- * @since 1.5.4
232
  *
233
- * @param string $value
234
  * @return string
235
  */
236
  public function create_pattern( $value ) {
@@ -272,11 +285,12 @@ class Boldgrid_Backup_Admin_Folder_Exclusion {
272
  /**
273
  * Enqueue scripts.
274
  *
275
- * @since 1.5.4
276
  */
277
  public function enqueue_scripts() {
278
  $handle = 'boldgrid-backup-admin-folder-exclude';
279
- wp_register_script( $handle,
 
280
  plugin_dir_url( __FILE__ ) . 'js/boldgrid-backup-admin-folder-exclude.js',
281
  array( 'jquery' ),
282
  BOLDGRID_BACKUP_VERSION,
@@ -285,9 +299,9 @@ class Boldgrid_Backup_Admin_Folder_Exclusion {
285
  $translation = array(
286
  'default_include' => $this->default_include,
287
  'default_exclude' => $this->default_exclude,
288
- 'items' => __( 'items', 'boldgrid-backup' ),
289
- 'no_results' => __( 'No results', 'boldgrid-backup' ),
290
- 'of' => __( 'of', 'boldgrid-backup' ),
291
  );
292
  wp_localize_script( $handle, 'BoldGridBackupAdminFolderExclude', $translation );
293
  wp_enqueue_script( $handle );
@@ -306,10 +320,10 @@ class Boldgrid_Backup_Admin_Folder_Exclusion {
306
  /**
307
  * Get our include or exclude value from the settings.
308
  *
309
- * @since 1.5.4
310
  *
311
- * @param string $type Either 'include' or 'exclude'.
312
- * @param array $settings
313
  * @return string
314
  */
315
  public function from_settings( $type, $settings = false ) {
@@ -317,7 +331,7 @@ class Boldgrid_Backup_Admin_Folder_Exclusion {
317
  return false;
318
  }
319
 
320
- $key = 'folder_exclusion_' . $type;
321
  $default = 'default_' . $type;
322
 
323
  /*
@@ -347,14 +361,20 @@ class Boldgrid_Backup_Admin_Folder_Exclusion {
347
 
348
  if ( $this->core->settings->is_saving_settings ) {
349
  $this->$type = $this->from_post( $type );
 
350
  /*
351
- * Is there value for this in the settings?
352
- *
353
- * Initially, we checked to make sure $settings[$key] wasn't empty and
354
- * it was a string. Now, we'll simply see if it is set. This will allow
355
- * for the user to enter nothing in the exclude field.
356
- */
357
  } elseif ( isset( $settings[ $key ] ) ) {
 
 
 
 
 
 
 
358
  $this->$type = $settings[ $key ];
359
  } elseif ( ! $settings ) {
360
  $settings = $this->core->settings->get_settings();
@@ -377,9 +397,9 @@ class Boldgrid_Backup_Admin_Folder_Exclusion {
377
  * wp-content/file.php as a $file, it should match. If I pass in "joec" as a
378
  * $value and wp-content/file.php as a $file, it should not match.
379
  *
380
- * @param string $value
381
- * @param string $file Filepath relative to ABSPATH, such as
382
- * wp-content/plugins/boldgrid-backup/boldgrid-backup.php
383
  * @return bool
384
  */
385
  public function is_match( $value, $file ) {
@@ -406,7 +426,11 @@ class Boldgrid_Backup_Admin_Folder_Exclusion {
406
  }
407
 
408
  /**
 
409
  *
 
 
 
410
  */
411
  public function is_using_defaults() {
412
  $type = $this->from_settings( 'type' );
@@ -417,7 +441,7 @@ class Boldgrid_Backup_Admin_Folder_Exclusion {
417
  /**
418
  * Get our include / exclude settings from $_POST.
419
  *
420
- * @since 1.5.4
421
  *
422
  * @param string $type Either include or exclude.
423
  * @return string
@@ -459,7 +483,7 @@ class Boldgrid_Backup_Admin_Folder_Exclusion {
459
  /**
460
  * Handle the ajax request to preview the filters.
461
  *
462
- * @since 1.5.4
463
  */
464
  public function wp_ajax_preview() {
465
  if ( ! check_ajax_referer( 'folder_exclusion_preview', 'security', false ) ) {
1
  <?php
2
  /**
3
+ * File: class-boldgrid-backup-admin-folder-exclusion.php
4
  *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.6.0
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
  * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
  */
14
 
15
+ // phpcs:disable WordPress.VIP, WordPress.CSRF.NonceVerification.NoNonceVerification
16
+
17
  /**
18
+ * Class: Boldgrid_Backup_Admin_Folder_Exclusion
19
  *
20
+ * @since 1.6.0
21
  */
22
  class Boldgrid_Backup_Admin_Folder_Exclusion {
 
23
  /**
24
  * The default exclude value.
25
  *
26
+ * @since 1.6.0
27
  * @var string
28
  */
29
  public $default_exclude = '.git,node_modules';
31
  /**
32
  * The default include value.
33
  *
34
+ * @since 1.6.0
35
  * @var string
36
  */
37
  public $default_include = 'WPCORE,/wp-content';
39
  /**
40
  * By default, backup all files and folders (use default settings).
41
  *
42
+ * @since 1.6.0
43
  * @var string
44
  */
45
  public $default_type = 'full';
47
  /**
48
  * Our exclude value.
49
  *
50
+ * @since 1.6.0
51
  * @var string|null
52
  */
53
  public $exclude = null;
55
  /**
56
  * Our include value.
57
  *
58
+ * @since 1.6.0
59
  * @var string|null
60
  */
61
  public $include = null;
63
  /**
64
  * Whether or not we're in the ajax preview.
65
  *
66
+ * @since 1.6.0
67
  * @var bool
68
  */
69
  public $in_ajax_preview = false;
73
  *
74
  * Usually it will be 'full' or 'custom'.
75
  *
76
+ * @since 1.6.0
77
  * @var null|string
78
  */
79
  public $type = null;
81
  /**
82
  * Allowable types.
83
  *
84
+ * @since 1.6.0
85
  * @var array
86
  */
87
  public $types = array( 'include', 'exclude', 'type' );
89
  /**
90
  * Valid backup types.
91
  *
92
+ * @since 1.6.0
93
  * @var array
94
  */
95
  public $valid_types = array( 'full', 'custom' );
97
  /**
98
  * The core class object.
99
  *
100
+ * @since 1.6.0
101
  * @access private
102
  * @var Boldgrid_Backup_Admin_Core
103
  */
106
  /**
107
  * Constructor.
108
  *
109
+ * @since 1.6.0
110
  *
111
  * @param Boldgrid_Backup_Admin_Core $core Core class object.
112
  */
135
  /**
136
  * Determine if we should allow a file in the backup.
137
  *
138
+ * @since 1.6.0
139
  *
140
+ * @param string $file File path.
141
  * @return bool
142
  */
143
  public function allow_file( $file ) {
146
  return false;
147
  }
148
 
149
+ // Do not allow the "cron/restore-info.json" file used for emergency restorations.
150
+ if ( $this->is_match( 'cron/restore-info.json', $file ) ) {
151
+ return false;
152
+ }
153
+
154
  // Get comma-delimited lists from user input or settings. Sanitizing is done below.
155
  $include = $this->in_ajax_preview ? $_POST['include'] : $this->from_settings( 'include' );
156
  $exclude = $this->in_ajax_preview ? $_POST['exclude'] : $this->from_settings( 'exclude' );
192
  * Generate a section for email alerts including information about files and
193
  * folders excluded.
194
  *
195
+ * @since 1.6.0
196
  *
197
+ * @param array $info File and folder settings.
198
  * @return string
199
  */
200
  public function email_part( $info ) {
208
  }
209
 
210
  if ( $has_folder_included ) {
211
+ $body .= sprintf(
212
+ // translators: 1: Included folder list.
213
+ esc_html__( 'Included: %1$s', 'boldgrid-backup' ),
214
+ $info['folder_include']
215
+ ) . "\n";
216
  }
217
 
218
  if ( $has_folder_excluded ) {
219
+ $body .= sprintf(
220
+ // translators: 1: Excluded folder list.
221
+ esc_html__( 'Excluded: %1$s', 'boldgrid-backup' ),
222
+ $info['folder_exclude']
223
+ ) . "\n";
224
  }
225
 
226
  return $body;
230
  * Create our regex pattern.
231
  *
232
  * If the user enters wp-* for their include / exclude value, then we need
233
+ * to convert that into a proper regex pattern.
234
  *
235
  * When we look for matches, we want to keep it specific to one folder.
236
  * For example, if we're given wp-adm*n, the expectation is that we want
239
  * To prevent this false positive:
240
  * wp-admin/images/media-button.png
241
  * wp-adm************************ng
242
+ * ... we will set the wildcard to match everything except a directory separator.
 
243
  *
244
+ * @since 1.6.0
245
  *
246
+ * @param string $value Input string.
247
  * @return string
248
  */
249
  public function create_pattern( $value ) {
285
  /**
286
  * Enqueue scripts.
287
  *
288
+ * @since 1.6.0
289
  */
290
  public function enqueue_scripts() {
291
  $handle = 'boldgrid-backup-admin-folder-exclude';
292
+ wp_register_script(
293
+ $handle,
294
  plugin_dir_url( __FILE__ ) . 'js/boldgrid-backup-admin-folder-exclude.js',
295
  array( 'jquery' ),
296
  BOLDGRID_BACKUP_VERSION,
299
  $translation = array(
300
  'default_include' => $this->default_include,
301
  'default_exclude' => $this->default_exclude,
302
+ 'items' => __( 'items', 'boldgrid-backup' ),
303
+ 'no_results' => __( 'No results', 'boldgrid-backup' ),
304
+ 'of' => __( 'of', 'boldgrid-backup' ),
305
  );
306
  wp_localize_script( $handle, 'BoldGridBackupAdminFolderExclude', $translation );
307
  wp_enqueue_script( $handle );
320
  /**
321
  * Get our include or exclude value from the settings.
322
  *
323
+ * @since 1.6.0
324
  *
325
+ * @param string $type Either 'include' or 'exclude'.
326
+ * @param array $settings File and folder settings.
327
  * @return string
328
  */
329
  public function from_settings( $type, $settings = false ) {
331
  return false;
332
  }
333
 
334
+ $key = 'folder_exclusion_' . $type;
335
  $default = 'default_' . $type;
336
 
337
  /*
361
 
362
  if ( $this->core->settings->is_saving_settings ) {
363
  $this->$type = $this->from_post( $type );
364
+ } elseif ( isset( $settings['folder_exclusion_type'] ) && 'full' === $settings['folder_exclusion_type'] ) {
365
  /*
366
+ * If the user configured "Backup all files" as the "Files and Folders" settings, then
367
+ * use the default values.
368
+ */
369
+ $this->$default;
 
 
370
  } elseif ( isset( $settings[ $key ] ) ) {
371
+ /*
372
+ * Is there value for this in the settings?
373
+ *
374
+ * Initially, we checked to make sure $settings[$key] wasn't empty and
375
+ * it was a string. Now, we'll simply see if it is set. This will allow
376
+ * for the user to enter nothing in the exclude field.
377
+ */
378
  $this->$type = $settings[ $key ];
379
  } elseif ( ! $settings ) {
380
  $settings = $this->core->settings->get_settings();
397
  * wp-content/file.php as a $file, it should match. If I pass in "joec" as a
398
  * $value and wp-content/file.php as a $file, it should not match.
399
  *
400
+ * @param string $value Input string.
401
+ * @param string $file File path relative to ABSPATH, such as:
402
+ * "wp-content/plugins/boldgrid-backup/boldgrid-backup.php".
403
  * @return bool
404
  */
405
  public function is_match( $value, $file ) {
426
  }
427
 
428
  /**
429
+ * Is using default settings?
430
  *
431
+ * @since 1.6.0
432
+ *
433
+ * @return bool
434
  */
435
  public function is_using_defaults() {
436
  $type = $this->from_settings( 'type' );
441
  /**
442
  * Get our include / exclude settings from $_POST.
443
  *
444
+ * @since 1.6.0
445
  *
446
  * @param string $type Either include or exclude.
447
  * @return string
483
  /**
484
  * Handle the ajax request to preview the filters.
485
  *
486
+ * @since 1.6.0
487
  */
488
  public function wp_ajax_preview() {
489
  if ( ! check_ajax_referer( 'folder_exclusion_preview', 'security', false ) ) {
admin/class-boldgrid-backup-admin-go-pro.php CHANGED
@@ -1,28 +1,27 @@
1
  <?php
2
  /**
3
- * Go Pro class.
4
  *
5
- * @link http://www.boldgrid.com
6
- * @since 1.5.4
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
- * @copyright BoldGrid.com
11
  * @version $Id$
12
- * @author BoldGrid.com <wpb@boldgrid.com>
13
  */
14
 
15
  /**
16
- * BoldGrid Backup Admin Go Pro Class.
17
  *
18
- * @since 1.5.4
19
  */
20
  class Boldgrid_Backup_Admin_Go_Pro {
21
-
22
  /**
23
  * The core class object.
24
  *
25
- * @since 1.5.4
26
  * @access private
27
  * @var Boldgrid_Backup_Admin_Core
28
  */
@@ -31,16 +30,16 @@ class Boldgrid_Backup_Admin_Go_Pro {
31
  /**
32
  * Generic upgrade link.
33
  *
34
- * @since 1.5.4
35
  * @access public
36
  * @var string
37
  */
38
- public static $url = 'https://boldgrid.com/update-backup';
39
 
40
  /**
41
  * Constructor.
42
  *
43
- * @since 1.5.4
44
  *
45
  * @param Boldgrid_Backup_Admin_Core $core Core class object.
46
  */
@@ -49,61 +48,118 @@ class Boldgrid_Backup_Admin_Go_Pro {
49
  }
50
 
51
  /**
52
- * Display "setup" admin notices.
53
  *
54
- * This method is currently used to display admin notices to help guide the
55
- * user to getting a premium key and getting / activating the premium extension.
 
 
56
  *
57
- * @since 1.5.4
58
  */
59
- public function admin_notice_setup() {
 
60
 
61
  // If the premium plugin is installed and all is good, abort!
62
  if ( $this->core->config->is_premium_done ) {
63
- return;
64
  }
65
 
66
  // Check user role.
67
  if ( ! current_user_can( 'update_plugins' ) ) {
68
- return;
69
  }
70
 
71
  if ( ! class_exists( '\Boldgrid\Library\Library\Notice' ) ) {
72
- return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
  }
74
 
75
  $is_premium = $this->core->config->get_is_premium();
76
 
77
- $notices = array(
78
- array(
79
- 'id' => 'boldgrid_backup_activate_premium',
80
- 'show' => $is_premium && $this->core->config->is_premium_installed,
 
 
81
  'message' => '<p>' . sprintf(
82
- __( 'You have a <strong>Premium BoldGrid Connect Key</strong> and you have the <strong>BoldGrid Backup Premium Extension installed</strong>. Please go to your <a href="%1$s">plugins page</a> and activate your premium extension!', 'boldgrid-backup' ),
83
- admin_url( 'plugins.php' )
 
 
 
 
 
84
  ) . '</p>',
85
- ),
86
- array(
87
- 'id' => 'boldgrid_backup_upgrade_premium',
88
- 'show' => ! $is_premium && $this->core->config->is_premium_active,
 
89
  'message' => '<p>' . sprintf(
90
- __( 'Thank you for activating the <strong>BoldGrid Backup Premium Extension</strong>! Before you can begin using all of the premium features, please visit <a href="%1$s" target="_blank">BoldGrid Central</a> and upgrade your BoldGrid Connect Key.', 'boldgrid-backup' ),
91
- self::$url
 
 
 
92
  ) . '</p>',
93
- ),
94
- array(
95
- 'id' => 'boldgrid_backup_download_premium',
96
- 'show' => $is_premium && ! $this->core->config->is_premium_installed,
 
97
  'message' => '<p>' . sprintf(
98
- __( 'Hello there! We see that you have a <strong>Premium BoldGrid Connect Key</strong> and you have the <strong>BoldGrid Backup Plugin</strong> activated! Be sure to download the <strong>BoldGrid Backup Premium Extension</strong> from <a href="%1$s">BoldGrid Central</a> to gain access to more features!', 'boldgrid-backup' ),
99
- 'https://www.boldgrid.com/central'
 
 
 
 
 
 
 
100
  ) . '</p>',
101
- ),
102
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103
 
104
  foreach ( $notices as $notice ) {
105
  if ( $notice['show'] ) {
106
- \Boldgrid\Library\Library\Notice::show( $notice['message'], $notice['id'] );
107
  break;
108
  }
109
  }
@@ -112,17 +168,35 @@ class Boldgrid_Backup_Admin_Go_Pro {
112
  /**
113
  * Get a "Get Premium" button.
114
  *
115
- * @since 1.5.4
116
  *
117
- * @param string $url
118
- * @param string $text
119
  * @return string
120
  */
121
- public function get_premium_button( $url = 'https://boldgrid.com/update-backup', $text = 'Get Premium' ) {
122
- return sprintf( '
 
 
 
123
  <a href="%1$s" class="button button-success" target="_blank">%2$s</a>',
124
  esc_url( $url ),
125
  $text
126
  );
127
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
128
  }
1
  <?php
2
  /**
3
+ * File: class-boldgrid-backup-admin-go-pro.php
4
  *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.6.0
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
  * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
  */
14
 
15
  /**
16
+ * Class: Boldgrid_Backup_Admin_Go_Pro
17
  *
18
+ * @since 1.6.0
19
  */
20
  class Boldgrid_Backup_Admin_Go_Pro {
 
21
  /**
22
  * The core class object.
23
  *
24
+ * @since 1.6.0
25
  * @access private
26
  * @var Boldgrid_Backup_Admin_Core
27
  */
30
  /**
31
  * Generic upgrade link.
32
  *
33
+ * @since 1.6.0
34
  * @access public
35
  * @var string
36
  */
37
+ public static $url = 'https://www.boldgrid.com/update-backup';
38
 
39
  /**
40
  * Constructor.
41
  *
42
+ * @since 1.6.0
43
  *
44
  * @param Boldgrid_Backup_Admin_Core $core Core class object.
45
  */
48
  }
49
 
50
  /**
51
+ * Get "setup" admin notices.
52
  *
53
+ * This method is currently used to create the admin notices to help guide the user to getting a
54
+ * premium key and getting / activating the premium extension.
55
+ *
56
+ * @since 1.11.0
57
  *
58
+ * @return array
59
  */
60
+ public function get_admin_notices() {
61
+ $notices = [];
62
 
63
  // If the premium plugin is installed and all is good, abort!
64
  if ( $this->core->config->is_premium_done ) {
65
+ return $notices;
66
  }
67
 
68
  // Check user role.
69
  if ( ! current_user_can( 'update_plugins' ) ) {
70
+ return $notices;
71
  }
72
 
73
  if ( ! class_exists( '\Boldgrid\Library\Library\Notice' ) ) {
74
+ return $notices;
75
+ }
76
+
77
+ // Avoid a fatal error.
78
+ if ( ! class_exists( '\Boldgrid\Library\Library\Plugin\Plugin' ) ) {
79
+ $notices = [
80
+ [
81
+ 'id' => 'boldgrid_backup_missing_library',
82
+ 'show' => true,
83
+ 'message' => '<p>' . __( 'Class "Boldgrid\Library\Library\Plugin\Plugin" not found. Please ensure you are running the lastest version of the BoldGrid Library.', 'boldgrid-backup' ) . '</p>',
84
+ 'class' => 'notice notice-error',
85
+ ],
86
+ ];
87
+
88
+ return $notices;
89
  }
90
 
91
  $is_premium = $this->core->config->get_is_premium();
92
 
93
+ $premium_plugin = new \Boldgrid\Library\Library\Plugin\Plugin( 'boldgrid-backup-premium' );
94
+
95
+ $notices = [
96
+ [
97
+ 'id' => 'boldgrid_backup_activate_premium',
98
+ 'show' => $is_premium && $this->core->config->is_premium_installed,
99
  'message' => '<p>' . sprintf(
100
+ // translators: 1: URL address for the wp-admin plugins page, 2: Plugin/extension title.
101
+ __(
102
+ 'You have a <strong>Premium BoldGrid Connect Key</strong> and you have the <strong>%2$s Extension installed</strong>. Please go to your <a href="%1$s">plugins page</a> and activate your premium extension!',
103
+ 'boldgrid-backup'
104
+ ),
105
+ admin_url( 'plugins.php' ),
106
+ BOLDGRID_BACKUP_TITLE . ' Premium'
107
  ) . '</p>',
108
+ 'class' => 'notice notice-warning',
109
+ ],
110
+ [
111
+ 'id' => 'boldgrid_backup_upgrade_premium',
112
+ 'show' => ! $is_premium && $this->core->config->is_premium_active,
113
  'message' => '<p>' . sprintf(
114
+ // translators: 1: URL address for the upgrade page, 2: Premium plugin title.
115
+ __( 'Thank you for activating the <strong>%3$s</strong> plugin! Before you can begin using all of the premium features, you must <a href="%2$s">add your premium key</a>. If you are using an Official BoldGrid Host, contact them or login to their management system to retrieve your Premium key. Otherwise, please visit <a href="%1$s" target="_blank">BoldGrid Central</a> to upgrade.', 'boldgrid-backup' ),
116
+ $this->get_premium_url( 'bgbkup-premium-activate' ),
117
+ admin_url( 'options-general.php?page=boldgrid-connect.php' ),
118
+ BOLDGRID_BACKUP_TITLE . ' Premium'
119
  ) . '</p>',
120
+ 'class' => 'notice notice-warning',
121
+ ],
122
+ [
123
+ 'id' => 'boldgrid_backup_download_premium',
124
+ 'show' => $is_premium && ! $this->core->config->is_premium_installed,
125
  'message' => '<p>' . sprintf(
126
+ // translators: 1: URL address to download plugin 2: URL to plugin-installer.php, 3: Plugin title, 4: Premium plugin title.
127
+ __(
128
+ 'Hello there! We see that you have a <strong>Premium BoldGrid Connect Key</strong> and you have the <strong>%3$s</strong> plugin activated! <a href="%1$s">Click here</a> to download the <strong>%4$s</strong> plugin and gain access to more features! After the download completes, go to <a href="%2$s">Plugins &raquo; Add New</a> and click the <em>Upload Plugin</em> button at the top of the page to upload your new plugin.',
129
+ 'boldgrid-backup'
130
+ ),
131
+ $premium_plugin->getDownloadUrl(),
132
+ admin_url( 'plugin-install.php' ),
133
+ BOLDGRID_BACKUP_TITLE,
134
+ BOLDGRID_BACKUP_TITLE . ' Premium'
135
  ) . '</p>',
136
+ 'class' => 'notice notice-warning',
137
+ ],
138
+ ];
139
+
140
+ return $notices;
141
+ }
142
+
143
+ /**
144
+ * Display "setup" admin notices.
145
+ *
146
+ * This method is currently used to display admin notices to help guide the
147
+ * user to getting a premium key and getting / activating the premium extension.
148
+ *
149
+ * @since 1.6.0
150
+ */
151
+ public function admin_notice_setup() {
152
+ // Don't bombard the user with admin notices. Only show these notices if the user is on a page for this plugin.
153
+ $page = ! empty( $_GET['page'] ) ? $_GET['page'] : ''; // phpcs:ignore
154
+ if ( substr( $page, 0, strlen( 'boldgrid-backup' ) ) !== 'boldgrid-backup' ) {
155
+ return;
156
+ }
157
+
158
+ $notices = $this->get_admin_notices();
159
 
160
  foreach ( $notices as $notice ) {
161
  if ( $notice['show'] ) {
162
+ \Boldgrid\Library\Library\Notice::show( $notice['message'], $notice['id'], $notice['class'] );
163
  break;
164
  }
165
  }
168
  /**
169
  * Get a "Get Premium" button.
170
  *
171
+ * @since 1.6.0
172
  *
173
+ * @param string $url URL address for the upgrade page.
174
+ * @param string $text Button text.
175
  * @return string
176
  */
177
+ public function get_premium_button( $url = null, $text = 'Get Premium' ) {
178
+ $url = ! empty( $url ) ? $url : $this->get_premium_url();
179
+
180
+ return sprintf(
181
+ '
182
  <a href="%1$s" class="button button-success" target="_blank">%2$s</a>',
183
  esc_url( $url ),
184
  $text
185
  );
186
  }
187
+
188
+ /**
189
+ * Get a "Get Premium" url.
190
+ *
191
+ * @since 1.7.0
192
+ *
193
+ * @param string $source Source to append to url.
194
+ * @param string $url URL address for the upgrade page.
195
+ * @return string
196
+ */
197
+ public function get_premium_url( $source = 'bgbkup', $url = 'https://www.boldgrid.com/update-backup' ) {
198
+ $url = add_query_arg( 'source', $source, $url );
199
+
200
+ return $url;
201
+ }
202
  }
admin/class-boldgrid-backup-admin-home-dir.php CHANGED
@@ -1,24 +1,23 @@
1
  <?php
2
  /**
3
- * Boldgrid Backup Admin Home Dir.
4
  *
5
- * @link http://www.boldgrid.com
6
  * @since 1.5.1
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
- * @copyright BoldGrid.com
11
  * @version $Id$
12
- * @author BoldGrid.com <wpb@boldgrid.com>
13
  */
14
 
15
  /**
16
- * Boldgrid Backup Admin Home Dir class.
17
  *
18
  * @since 1.5.1
19
  */
20
  class Boldgrid_Backup_Admin_Home_Dir {
21
-
22
  /**
23
  * The core class object.
24
  *
@@ -33,7 +32,7 @@ class Boldgrid_Backup_Admin_Home_Dir {
33
  *
34
  * @since 1.5.1
35
  *
36
- * @param Boldgrid_Backup_Admin_Core $core
37
  */
38
  public function __construct( $core ) {
39
  $this->core = $core;
1
  <?php
2
  /**
3
+ * File: class-boldgrid-backup-admin-home-dir.php
4
  *
5
+ * @link https://www.boldgrid.com
6
  * @since 1.5.1
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
  * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
  */
14
 
15
  /**
16
+ * Class: Boldgrid_Backup_Admin_Home_Dir
17
  *
18
  * @since 1.5.1
19
  */
20
  class Boldgrid_Backup_Admin_Home_Dir {
 
21
  /**
22
  * The core class object.
23
  *
32
  *
33
  * @since 1.5.1
34
  *
35
+ * @param Boldgrid_Backup_Admin_Core $core Boldgrid_Backup_Admin_Core object.
36
  */
37
  public function __construct( $core ) {
38
  $this->core = $core;
admin/class-boldgrid-backup-admin-in-progress-data.php ADDED
@@ -0,0 +1,124 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Class: Boldgrid_Backup_Admin_In_Progress_Data
4
+ *
5
+ * This class used for managing the data used by the Boldgrid_Backup_Admin_In_Progress class.
6
+ *
7
+ * @link https://www.boldgrid.com
8
+ * @since 1.7.0
9
+ *
10
+ * @package Boldgrid_Backup
11
+ * @subpackage Boldgrid_Backup/admin
12
+ * @copyright BoldGrid
13
+ * @author BoldGrid <support@boldgrid.com>
14
+ */
15
+
16
+ /**
17
+ * Class: Boldgrid_Backup_Admin_In_Progress_Data
18
+ *
19
+ * @since 1.7.0
20
+ */
21
+ class Boldgrid_Backup_Admin_In_Progress_Data {
22
+ /**
23
+ * Option name in which data is stored.
24
+ *
25
+ * @since 1.7.0
26
+ * @var string
27
+ */
28
+ public static $option_name = 'boldgrid_backup_in_progress_data';
29
+
30
+ /**
31
+ * Delete one arguement.
32
+ *
33
+ * @since 1.7.0
34
+ *
35
+ * @param string $arg The key.
36
+ */
37
+ public static function delete_arg( $arg ) {
38
+ $args = self::get_args();
39
+
40
+ if ( isset( $args[ $arg ] ) ) {
41
+ unset( $args[ $arg ] );
42
+ }
43
+
44
+ update_option( self::$option_name, $args );
45
+ }
46
+
47
+ /**
48
+ * Get one argument.
49
+ *
50
+ * @since 1.7.0
51
+ *
52
+ * @param string $key Index/key.
53
+ * @return mixed
54
+ */
55
+ public static function get_arg( $key ) {
56
+ $args = get_option( self::$option_name );
57
+
58
+ return isset( $args[ $key ] ) ? $args[ $key ] : false;
59
+ }
60
+
61
+ /**
62
+ * Get all arguments.
63
+ *
64
+ * @since 1.7.0
65
+ *
66
+ * @return array
67
+ */
68
+ public static function get_args() {
69
+ return get_option( self::$option_name );
70
+ }
71
+
72
+ /**
73
+ * Get required markup to show the progress bar.
74
+ *
75
+ * Generally displayed under a "Backup Now" button.
76
+ *
77
+ * @since 1.7.0
78
+ *
79
+ * @param string $label Progress label.
80
+ */
81
+ public static function get_markup( $label = null ) {
82
+ $label = ! empty( $label ) ? $label : __( 'Initializing backup...', 'boldgrid-backup' );
83
+
84
+ $steps = '<div id="boldgrid_backup_in_progress_steps">
85
+ <div class="step" data-step="1">' . esc_html__( 'Backing up database...', 'boldgrid-backup' ) . '</div>
86
+ <div class="step" data-step="2">' . esc_html__( 'Adding files to archive...', 'boldgrid-backup' ) . '</div>
87
+ <div class="step" data-step="3">' . esc_html__( 'Saving archive to disk...', 'boldgrid-backup' ) . '</div>
88
+ </div>';
89
+
90
+ $progress_bar = '<div id="boldgrid-backup-in-progress-bar">
91
+ <div class="progress-label">' . esc_html( $label ) . '</div>
92
+ <div id="last_file_archived"></div>
93
+ </div>';
94
+
95
+ return '<div id="boldgrid_backup_in_progress_container" class="hidden">' . $steps . $progress_bar . '</div>';
96
+ }
97
+
98
+ /**
99
+ * Set one arguement, a key / value pair.
100
+ *
101
+ * @since 1.7.0
102
+ *
103
+ * @param string $arg The key.
104
+ * @param string $value The value.
105
+ */
106
+ public static function set_arg( $arg, $value ) {
107
+ $args = self::get_args();
108
+
109
+ $args[ $arg ] = $value;
110
+
111
+ update_option( self::$option_name, $args );
112
+ }
113
+
114
+ /**
115
+ * Set arguments.
116
+ *
117
+ * @since 1.7.0
118
+ *
119
+ * @param array $args Arguments.
120
+ */
121
+ public static function set_args( $args ) {
122
+ update_option( self::$option_name, $args );
123
+ }
124
+ }
admin/class-boldgrid-backup-admin-in-progress-tmp.php ADDED
@@ -0,0 +1,164 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File: class-boldgrid-backup-admin-in-progress-tmp.php
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.13.0
7
+ *
8
+ * @package Boldgrid_Backup
9
+ * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
+ * @author BoldGrid <support@boldgrid.com>
12
+ */
13
+
14
+ /**
15
+ * Class: Boldgrid_Backup_Admin_In_Progress_Tmp
16
+ *
17
+ * When an archive is being created, it is first created in a temporary file, then finally moved to
18
+ * the ending .zip file.
19
+ *
20
+ * This is a utility class used for getting information about these temporary files. They differ based
21
+ * on the compressor that is being used.
22
+ *
23
+ * Examples of the different compressors' tmp files:
24
+ * pcl_zip: /backup_dir/backup.zip Does not create a temporary file.
25
+ * php_zip: /backup_dir/backup.zip.Evubai
26
+ * system_zip: /backup_dir/system_zip_temp/zigWlkvV The "system_zip_temp" folder is optional and
27
+ * created by us.
28
+ *
29
+ * @since 1.13.0
30
+ */
31
+ class Boldgrid_Backup_Admin_In_Progress_Tmp {
32
+ /**
33
+ * An instance of core.
34
+ *
35
+ * @since 1.13.0
36
+ * @access private
37
+ * @var Boldgrid_Backup_Admin_Core
38
+ */
39
+ private $core;
40
+
41
+ /**
42
+ * Constructor.
43
+ *
44
+ * @since 1.13.0
45
+ *
46
+ * @param Boldgrid_Backup_Admin_Core $core
47
+ */
48
+ public function __construct( $core = null ) {
49
+ $this->core = ! empty( $core ) ? $core : apply_filters( 'boldgrid_backup_get_core', null );
50
+ }
51
+
52
+ /**
53
+ * Get an array of data for the temporary .zip file.
54
+ *
55
+ * @since 1.13.0
56
+ *
57
+ * @return array
58
+ */
59
+ public function get() {
60
+ $data = [];
61
+
62
+ $compressor = Boldgrid_Backup_Admin_In_Progress_Data::get_arg( 'compressor' );
63
+
64
+ switch ( $compressor ) {
65
+ case 'system_zip':
66
+ $data = $this->get_system_zip();
67
+ break;
68
+ case 'php_zip':
69
+ $data = $this->get_php_zip();
70
+ break;
71
+ case 'pcl_zip':
72
+ $data = $this->get_pcl_zip();
73
+ break;
74
+ }
75
+
76
+ return $data;
77
+ }
78
+
79
+ /**
80
+ * Get temporary .zip file info for system_zip compressor.
81
+ *
82
+ * @since 1.13.0
83
+ *
84
+ * @return array
85
+ */
86
+ private function get_system_zip() {
87
+ $dir = Boldgrid_Backup_Admin_Compressor_System_Zip_Temp_Folder::get_path();
88
+ $dirlist = $this->core->wp_filesystem->dirlist( $dir );
89
+ $dirlist = is_array( $dirlist ) ? $dirlist : [];
90
+ $size = 0;
91
+ $lastmodunix = 0;
92
+
93
+ foreach ( $dirlist as $file ) {
94
+ $size += ! empty( $file['size'] ) ? $file['size'] : 0;
95
+
96
+ $lastmodunix = ! empty( $file['lastmodunix'] ) ? $file['lastmodunix'] : $lastmodunix;
97
+ }
98
+
99
+ return [
100
+ 'size' => $size,
101
+ 'lastmodunix' => $lastmodunix,
102
+ 'size_format' => size_format( $size, 2 ),
103
+ ];
104
+ }
105
+
106
+ /**
107
+ * Get data for pcl_zip.
108
+ *
109
+ * @since 1.13.0
110
+ *
111
+ * @return array
112
+ */
113
+ private function get_pcl_zip() {
114
+ $data = [];
115
+
116
+ $filepath = Boldgrid_Backup_Admin_In_Progress_Data::get_arg( 'filepath' );
117
+ $filename = basename( $filepath );
118
+
119
+ $dirlist = $this->core->backup_dir->dirlist_containing( $filename );
120
+
121
+ if ( ! empty( $dirlist[ $filename ] ) ) {
122
+ $data = [
123
+ 'size' => $dirlist[ $filename ]['size'],
124
+ 'lastmodunix' => $dirlist[ $filename ]['lastmodunix'],
125
+ 'size_format' => size_format( $dirlist[ $filename ]['size'], 2 ),
126
+ ];
127
+ }
128
+
129
+ return $data;
130
+ }
131
+
132
+ /**
133
+ * Get temporary .zip file info for system_zip compressor.
134
+ *
135
+ * This method originally lived in the Boldgrid_Backup_Admin_In_Progress class and handled getting
136
+ * data for the php_zip compressor. It was moved to this new class in order to more effecitvely
137
+ * account for system_zip and other compressors (in the future).
138
+ *
139
+ * @since 1.7.0
140
+ *
141
+ * @return array
142
+ */
143
+ private function get_php_zip() {
144
+ $data = [];
145
+
146
+ $filepath = Boldgrid_Backup_Admin_In_Progress_Data::get_arg( 'filepath' );
147
+ $filename = basename( $filepath );
148
+
149
+ $dirlist = $this->core->backup_dir->dirlist_containing( $filename . '.' );
150
+
151
+ // We're looping, but there should only be one item in the array.
152
+ foreach ( $dirlist as $info ) {
153
+ $data = [
154
+ 'size' => $info['size'],
155
+ 'lastmodunix' => $info['lastmodunix'],
156
+ 'size_format' => size_format( $info['size'], 2 ),
157
+ ];
158
+
159
+ break;
160
+ }
161
+
162
+ return $data;
163
+ }
164
+ }
admin/class-boldgrid-backup-admin-in-progress.php CHANGED
@@ -1,33 +1,40 @@
1
  <?php
2
  /**
3
- * In Progress class.
4
  *
5
- * @link http://www.boldgrid.com
6
- * @since 1.5.4
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
- * @copyright BoldGrid.com
11
- * @version $Id$
12
- * @author BoldGrid.com <wpb@boldgrid.com>
13
  */
14
 
15
  /**
16
- * BoldGrid Backup Admin In Progress Class.
17
  *
18
- * @since 1.5.4
19
  */
20
  class Boldgrid_Backup_Admin_In_Progress {
21
-
22
  /**
23
  * The core class object.
24
  *
25
- * @since 1.5.4
26
  * @access private
27
  * @var Boldgrid_Backup_Admin_Core
28
  */
29
  private $core;
30
 
 
 
 
 
 
 
 
 
 
31
  /**
32
  * A unix timestamp indicating when a backup was started.
33
  *
@@ -43,20 +50,22 @@ class Boldgrid_Backup_Admin_In_Progress {
43
  /**
44
  * Constructor.
45
  *
46
- * @since 1.5.4
47
  *
48
  * @param Boldgrid_Backup_Admin_Core $core Core class object.
49
  */
50
  public function __construct( $core ) {
51
  $this->core = $core;
 
 
52
  }
53
 
54
  /**
55
  * Add a notice telling the user there's a backup in progress.
56
  *
57
- * @since 1.5.4
58
  *
59
- * @param array $notices
60
  * @return array
61
  */
62
  public function add_notice( $notices ) {
@@ -73,8 +82,10 @@ class Boldgrid_Backup_Admin_In_Progress {
73
  */
74
  wp_enqueue_script( 'heartbeat' );
75
 
 
 
76
  $elapsed = time() - $in_progress;
77
- $limit = 15 * MINUTE_IN_SECONDS;
78
 
79
  $notice = $this->get_notice();
80
  if ( false === $notice ) {
@@ -86,7 +97,11 @@ class Boldgrid_Backup_Admin_In_Progress {
86
  * help with troubleshooting.
87
  */
88
  if ( $elapsed > $limit ) {
89
- $notice['message'] .= __( ' Most backups usually finish before this amount of time, so we will stop displaying this notice.', 'boldgrid-backup' );
 
 
 
 
90
  $this->end();
91
  }
92
 
@@ -100,7 +115,7 @@ class Boldgrid_Backup_Admin_In_Progress {
100
  *
101
  * Specify that we are no longer backing up a website.
102
  *
103
- * @since 1.5.4
104
  */
105
  public function end() {
106
  $settings = $this->core->settings->get_settings( true );
@@ -117,7 +132,7 @@ class Boldgrid_Backup_Admin_In_Progress {
117
  *
118
  * The value is the time we started the backup.
119
  *
120
- * @since 1.5.4
121
  *
122
  * @return int
123
  */
@@ -129,6 +144,32 @@ class Boldgrid_Backup_Admin_In_Progress {
129
  return $in_progress;
130
  }
131
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132
  /**
133
  * Get our in progress notice.
134
  *
@@ -143,11 +184,25 @@ class Boldgrid_Backup_Admin_In_Progress {
143
  return false;
144
  }
145
 
146
- $notice = array(
147
- 'class' => 'notice notice-warning boldgrid-backup-in-progress',
148
- 'message' => sprintf( __( 'BoldGrid Backup began archiving your website %1$s ago.', 'boldgrid-backup' ), human_time_diff( $in_progress, time() ) ),
149
- 'heading' => __( 'BoldGrid Backup - Backup in progress', 'boldgrid-backup' ),
150
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
151
 
152
  return $notice;
153
  }
@@ -179,8 +234,8 @@ class Boldgrid_Backup_Admin_In_Progress {
179
  *
180
  * @since 1.6.0
181
  *
182
- * @param array $response
183
- * @param array $data
184
  * @return array
185
  */
186
  public function heartbeat_received( $response, $data ) {
@@ -196,6 +251,22 @@ class Boldgrid_Backup_Admin_In_Progress {
196
  // Our "backup complete!" admin notice.
197
  $response['boldgrid_backup_complete'] = $this->core->notice->get_backup_complete();
198
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
199
  return $response;
200
  }
201
 
@@ -205,7 +276,6 @@ class Boldgrid_Backup_Admin_In_Progress {
205
  * @since 1.6.0
206
  */
207
  public function post_dump() {
208
-
209
  /*
210
  * After the database has been dumped, restore the flag stating a backup
211
  * is still in progress.
@@ -223,7 +293,6 @@ class Boldgrid_Backup_Admin_In_Progress {
223
  * @since 1.6.0
224
  */
225
  public function pre_dump() {
226
-
227
  /*
228
  * Cancel any "Backup in progress" statuses.
229
  *
@@ -241,7 +310,7 @@ class Boldgrid_Backup_Admin_In_Progress {
241
  /**
242
  * Set that we are in progress of backing up a website.
243
  *
244
- * @since 1.5.4
245
  *
246
  * @param int $time A unix timestamp indicating the time a backup started.
247
  */
1
  <?php
2
  /**
3
+ * File: class-boldgrid-backup-admin-in-progress.php
4
  *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.6.0
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
+ * @author BoldGrid <support@boldgrid.com>
 
12
  */
13
 
14
  /**
15
+ * Class: Boldgrid_Backup_Admin_In_Progress
16
  *
17
+ * @since 1.6.0
18
  */
19
  class Boldgrid_Backup_Admin_In_Progress {
 
20
  /**
21
  * The core class object.
22
  *
23
+ * @since 1.6.0
24
  * @access private
25
  * @var Boldgrid_Backup_Admin_Core
26
  */
27
  private $core;
28
 
29
+ /**
30
+ * Our tmp class.
31
+ *
32
+ * @since 1.13.0
33
+ * @access private
34
+ * @var Boldgrid_Backup_Admin_In_Progress_Tmp
35
+ */
36
+ private $tmp;
37
+
38
  /**
39
  * A unix timestamp indicating when a backup was started.
40
  *
50
  /**
51
  * Constructor.
52
  *
53
+ * @since 1.6.0
54
  *
55
  * @param Boldgrid_Backup_Admin_Core $core Core class object.
56
  */
57
  public function __construct( $core ) {
58
  $this->core = $core;
59
+
60
+ $this->tmp = new Boldgrid_Backup_Admin_In_Progress_Tmp( $this->core );
61
  }
62
 
63
  /**
64
  * Add a notice telling the user there's a backup in progress.
65
  *
66
+ * @since 1.6.0
67
  *
68
+ * @param array $notices Array of notices to display.
69
  * @return array
70
  */
71
  public function add_notice( $notices ) {
82
  */
83
  wp_enqueue_script( 'heartbeat' );
84
 
85
+ wp_enqueue_script( 'jquery-ui-progressbar' );
86
+
87
  $elapsed = time() - $in_progress;
88
+ $limit = 15 * MINUTE_IN_SECONDS;
89
 
90
  $notice = $this->get_notice();
91
  if ( false === $notice ) {
97
  * help with troubleshooting.
98
  */
99
  if ( $elapsed > $limit ) {
100
+ $notice['message'] .= __(
101
+ ' Most backups usually finish before this amount of time, so we will stop displaying this notice.',
102
+ 'boldgrid-backup'
103
+ );
104
+
105
  $this->end();
106
  }
107
 
115
  *
116
  * Specify that we are no longer backing up a website.
117
  *
118
+ * @since 1.6.0
119
  */
120
  public function end() {
121
  $settings = $this->core->settings->get_settings( true );
132
  *
133
  * The value is the time we started the backup.
134
  *
135
+ * @since 1.6.0
136
  *
137
  * @return int
138
  */
144
  return $in_progress;
145
  }
146
 
147
+ /**
148
+ * Get the markup of an error message.
149
+ *
150
+ * This method is similar to self::get_notice() and self::get_notice_markup(), except those methods
151
+ * are for success and this one for errors.
152
+ *
153
+ * @since 1.11.2
154
+ *
155
+ * @return string
156
+ */
157
+ public function get_error_markup() {
158
+ $error = Boldgrid_Backup_Admin_In_Progress_Data::get_arg( 'error' );
159
+
160
+ $notice = [
161
+ 'class' => 'notice notice-error boldgrid-backup-in-progress',
162
+ 'message' => '<div class="notice"><p><strong>' . __( 'Error:', 'boldgrid-backup' ) . '</strong><br />' .
163
+ '<em>' . esc_html( $error ) . '</em></p></div>' .
164
+ '<p>' . $this->core->lang['get_support'] . '</p>',
165
+ 'heading' => BOLDGRID_BACKUP_TITLE . ' - ' . __( 'Error creating backup', 'boldgrid-backup' ),
166
+ ];
167
+
168
+ $markup = $this->core->notice->get_notice_markup( $notice['class'], $notice['message'], $notice['heading'] );
169
+
170
+ return $markup;
171
+ }
172
+
173
  /**
174
  * Get our in progress notice.
175
  *
184
  return false;
185
  }
186
 
187
+ /*
188
+ * Create our notice for atop the page.
189
+ *
190
+ * Initially started out as "backup in progress". Has expanded to include a progress bar.
191
+ */
192
+ $loading = __( 'Loading...', 'bgtfw' );
193
+ $message = '<p>' . sprintf(
194
+ // translators: 1: Plugin title, 2: Time since the last backup was initiated.
195
+ __( '%1$s began archiving your website %2$s ago.', 'boldgrid-backup' ),
196
+ BOLDGRID_BACKUP_TITLE,
197
+ human_time_diff( $in_progress, time() )
198
+ ) . '</p>';
199
+
200
+ $message .= Boldgrid_Backup_Admin_In_Progress_Data::get_markup( $loading );
201
+ $notice = [
202
+ 'class' => 'notice notice-warning boldgrid-backup-in-progress',
203
+ 'message' => $message,
204
+ 'heading' => BOLDGRID_BACKUP_TITLE . ' - ' . __( 'Backup in progress', 'boldgrid-backup' ),
205
+ ];
206
 
207
  return $notice;
208
  }
234
  *
235
  * @since 1.6.0
236
  *
237
+ * @param array $response Response.
238
+ * @param array $data Data in heartbeat.
239
  * @return array
240
  */
241
  public function heartbeat_received( $response, $data ) {
251
  // Our "backup complete!" admin notice.
252
  $response['boldgrid_backup_complete'] = $this->core->notice->get_backup_complete();
253
 
254
+ $response['in_progress_data'] = Boldgrid_Backup_Admin_In_Progress_Data::get_args();
255
+
256
+ // If we have an error message, add an "error message notice".
257
+ $response['boldgrid_backup_error'] = '';
258
+ if ( ! empty( $response['in_progress_data']['error'] ) ) {
259
+ $response['boldgrid_backup_error'] = $this->get_error_markup();
260
+ }
261
+
262
+ // Steps to take if we're on the last step, step 3, closing the archive.
263
+ if ( 3 === Boldgrid_Backup_Admin_In_Progress_Data::get_arg( 'step' ) ) {
264
+ $tmp = $this->tmp->get();
265
+ if ( ! empty( $tmp ) ) {
266
+ $response['in_progress_data']['tmp'] = $tmp;
267
+ }
268
+ }
269
+
270
  return $response;
271
  }
272
 
276
  * @since 1.6.0
277
  */
278
  public function post_dump() {
 
279
  /*
280
  * After the database has been dumped, restore the flag stating a backup
281
  * is still in progress.
293
  * @since 1.6.0
294
  */
295
  public function pre_dump() {
 
296
  /*
297
  * Cancel any "Backup in progress" statuses.
298
  *
310
  /**
311
  * Set that we are in progress of backing up a website.
312
  *
313
+ * @since 1.6.0
314
  *
315
  * @param int $time A unix timestamp indicating the time a backup started.
316
  */
admin/class-boldgrid-backup-admin-jobs.php CHANGED
@@ -1,19 +1,19 @@
1
  <?php
2
  /**
3
- * Boldgrid Backup Admin Jobs.
4
  *
5
- * @link http://www.boldgrid.com
6
  * @since 1.5.2
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
- * @copyright BoldGrid.com
11
  * @version $Id$
12
- * @author BoldGrid.com <wpb@boldgrid.com>
13
  */
14
 
15
  /**
16
- * Boldgrid Backup Admin Jobs class.
17
  *
18
  * Option $boldgrid_backup_jobs array {
19
  * An array of jobs that need to be ran.
@@ -32,7 +32,6 @@
32
  * @since 1.5.2
33
  */
34
  class Boldgrid_Backup_Admin_Jobs {
35
-
36
  /**
37
  * The core class object.
38
  *
@@ -64,7 +63,7 @@ class Boldgrid_Backup_Admin_Jobs {
64
  *
65
  * @since 1.5.2
66
  *
67
- * @param Boldgrid_Backup_Admin_Core $core
68
  */
69
  public function __construct( $core ) {
70
  $this->core = $core;
@@ -98,7 +97,7 @@ class Boldgrid_Backup_Admin_Jobs {
98
  *
99
  * @since 1.5.2
100
  *
101
- * @param int $delete_key
102
  */
103
  public function delete_all_prior( $delete_key ) {
104
 
@@ -146,15 +145,15 @@ class Boldgrid_Backup_Admin_Jobs {
146
  *
147
  * @since 1.5.2
148
  *
149
- * @param array $info
150
  */
151
  public function post_archive_files( $info ) {
152
  /*
153
  * We only want to add this to the jobs queue if we're in the middle of
154
- * an automatic backup. If the user simply clicked on "Backup site now",
155
- * we don't want to email the user, we'll already be doing that.
156
  */
157
- if ( ! $this->core->doing_cron ) {
158
  return;
159
  }
160
 
@@ -163,8 +162,8 @@ class Boldgrid_Backup_Admin_Jobs {
163
  }
164
 
165
  $args = array(
166
- 'filepath' => $info['filepath'],
167
- 'action' => 'boldgrid_backup_post_jobs_email',
168
  'action_data' => $info,
169
  'post_action' => 'delete_all_prior',
170
  );
@@ -174,13 +173,17 @@ class Boldgrid_Backup_Admin_Jobs {
174
 
175
  /**
176
  * Send an email after all jobs have been ran.
 
 
 
 
177
  */
178
  public function post_jobs_email( $info ) {
179
  $post_jobs = 0;
180
 
181
  $job_summary = array();
182
 
183
- $job_summary[] = __( 'The following tasks were ran after creating the backup:', 'boldgrid-backup' );
184
 
185
  $email_parts = $this->core->email->post_archive_parts( $info );
186
 
@@ -229,19 +232,10 @@ class Boldgrid_Backup_Admin_Jobs {
229
  * call this method, which will handle the rest.
230
  *
231
  * @since 1.5.2
232
- *
233
- * @see Boldgrid_Backup_Admin_Cron::is_valid_call()
234
- *
235
- * @return null
236
  */
237
  public function run() {
238
  $this->set_jobs();
239
 
240
- // If not logged-in, then require a matching "id".
241
- if ( ! $this->core->cron->is_valid_call() ) {
242
- wp_die( __( 'Error: Invalid request.' ), 'boldgrid-backup' );
243
- }
244
-
245
  // If there are no jobs or already running, then abort.
246
  if ( empty( $this->jobs ) || $this->is_running() ) {
247
  wp_die();
@@ -258,7 +252,7 @@ class Boldgrid_Backup_Admin_Jobs {
258
  $status = apply_filters( $job['action'], $job['action_data'] );
259
 
260
  $job['end_time'] = time();
261
- $job['status'] = $status ? 'success' : 'fail';
262
  $this->save_jobs();
263
 
264
  break;
1
  <?php
2
  /**
3
+ * File: class-boldgrid-backup-admin-jobs.php
4
  *
5
+ * @link https://www.boldgrid.com
6
  * @since 1.5.2
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
  * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
  */
14
 
15
  /**
16
+ * Class: Boldgrid_Backup_Admin_Jobs
17
  *
18
  * Option $boldgrid_backup_jobs array {
19
  * An array of jobs that need to be ran.
32
  * @since 1.5.2
33
  */
34
  class Boldgrid_Backup_Admin_Jobs {
 
35
  /**
36
  * The core class object.
37
  *
63
  *
64
  * @since 1.5.2
65
  *
66
+ * @param Boldgrid_Backup_Admin_Core $core Boldgrid_Backup_Admin_Core Object.
67
  */
68
  public function __construct( $core ) {
69
  $this->core = $core;
97
  *
98
  * @since 1.5.2
99
  *
100
+ * @param int $delete_key Archive list key index number.
101
  */
102
  public function delete_all_prior( $delete_key ) {
103
 
145
  *
146
  * @since 1.5.2
147
  *
148
+ * @param array $info Archive information.
149
  */
150
  public function post_archive_files( $info ) {
151
  /*
152
  * We only want to add this to the jobs queue if we're in the middle of
153
+ * an automatic backup (one that has been scheduled). If the user simply clicked on
154
+ * "Backup site now", we don't want to email the user, we'll already be doing that.
155
  */
156
+ if ( ! $this->core->is_scheduled_backup ) {
157
  return;
158
  }
159
 
162
  }
163
 
164
  $args = array(
165
+ 'filepath' => $info['filepath'],
166
+ 'action' => 'boldgrid_backup_post_jobs_email',
167
  'action_data' => $info,
168
  'post_action' => 'delete_all_prior',
169
  );
173
 
174
  /**
175
  * Send an email after all jobs have been ran.
176
+ *
177
+ * @since 1.5.2
178
+ *
179
+ * @param array $info Archive information.
180
  */
181
  public function post_jobs_email( $info ) {
182
  $post_jobs = 0;
183
 
184
  $job_summary = array();
185
 
186
+ $job_summary[] = __( 'The following tasks were run after creating the backup:', 'boldgrid-backup' );
187
 
188
  $email_parts = $this->core->email->post_archive_parts( $info );
189
 
232
  * call this method, which will handle the rest.
233
  *
234
  * @since 1.5.2
 
 
 
 
235
  */
236
  public function run() {
237
  $this->set_jobs();
238
 
 
 
 
 
 
239
  // If there are no jobs or already running, then abort.
240
  if ( empty( $this->jobs ) || $this->is_running() ) {
241
  wp_die();
252
  $status = apply_filters( $job['action'], $job['action_data'] );
253
 
254
  $job['end_time'] = time();
255
+ $job['status'] = $status ? 'success' : 'fail';
256
  $this->save_jobs();
257
 
258
  break;
admin/class-boldgrid-backup-admin-log-page.php ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File: class-boldgrid-backup-admin-log-page.php
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.12.5
7
+ *
8
+ * @package Boldgrid_Backup
9
+ * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
+ * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
+ */
14
+
15
+ /**
16
+ * Class: Boldgrid_Backup_Admin_Log_page
17
+ *
18
+ * @since 1.12.5
19
+ */
20
+ class Boldgrid_Backup_Admin_Log_Page {
21
+ /**
22
+ * Admin enqueue scripts.
23
+ *
24
+ * @since 1.12.5
25
+ *
26
+ * @param string $hook The current admin page hook.
27
+ */
28
+ public function admin_enqueue_scripts( $hook ) {
29
+ if ( 'total-upkeep_page_boldgrid-backup-tools' === $hook ) {
30
+ $handle = 'boldgrid-backup-admin-logs';
31
+
32
+ wp_register_script(
33
+ $handle,
34
+ plugin_dir_url( __FILE__ ) . 'js/' . $handle . '.js',
35
+ array( 'jquery' ),
36
+ BOLDGRID_BACKUP_VERSION,
37
+ false
38
+ );
39
+
40
+ $translation = array(
41
+ 'loading' => esc_html__( 'Loading log file', 'boldgrid-backup' ),
42
+ 'unknownError' => esc_html__( 'An unknown error occurred. Please close this modal and try again.', 'boldgrid-backup' ),
43
+ );
44
+
45
+ wp_localize_script( $handle, 'BoldGridBackupAdminLogs', $translation );
46
+
47
+ wp_enqueue_script( $handle );
48
+ }
49
+ }
50
+
51
+ /**
52
+ * Render the page for a specific log.
53
+ *
54
+ * @since 1.12.5
55
+ */
56
+ public function wp_ajax_boldgrid_backup_view_log() {
57
+ // Validate permissions.
58
+ if ( ! current_user_can( 'update_plugins' ) ) {
59
+ $markup = '<div class="notice notice-error"><p>' . esc_html__( 'Permission denied.', 'boldgrid-backup' ) . '</p></div>';
60
+ wp_send_json_error( $markup );
61
+ }
62
+
63
+ // Validate nonce.
64
+ if ( ! wp_verify_nonce( $_POST['nonce'], 'boldgrid_backup_view_log' ) ) {
65
+ $markup = '<div class="notice notice-error"><p>' . esc_html__( 'Invalid nonce. Please refresh the page and try again.', 'boldgrid-backup' ) . '</p></div>';
66
+ wp_send_json_error( $markup );
67
+ }
68
+
69
+ $core = apply_filters( 'boldgrid_backup_get_core', null );
70
+
71
+ // Make sure a filename was passsed.
72
+ $filename = ! empty( $_POST['filename'] ) ? sanitize_file_name( $_POST['filename'] ) : null; // phpcs:ignore
73
+ if ( empty( $filename ) ) {
74
+ $markup = '<div class="notice notice-error"><p>' . esc_html__( 'Error: No log filename provided.', 'boldgrid-backup' ) . '</p></div>';
75
+ wp_send_json_error( $markup );
76
+ }
77
+
78
+ // Make sure the log file exists.
79
+ $filepath = $core->backup_dir->get_logs_dir() . DIRECTORY_SEPARATOR . $filename;
80
+ if ( ! $core->wp_filesystem->exists( $filepath ) ) {
81
+ $markup = '<div class="notice notice-error"><p>' . esc_html__( 'Error: Log file does not exist.', 'boldgrid-backup' ) . '</p></div>';
82
+ wp_send_json_error( $markup );
83
+ }
84
+
85
+ // Make sure we don't have an empty file.
86
+ $contents = $core->wp_filesystem->get_contents( $filepath );
87
+ if ( empty( $contents ) ) {
88
+ $markup = '<div class="notice notice-warning"><p>' . esc_html__( 'Log file is empty.', 'boldgrid-backup' ) . '</p></div>';
89
+ wp_send_json_error( $markup );
90
+ }
91
+
92
+ // Good to go.
93
+ $markup = '<div style="overflow:auto;white-space:pre-wrap;font-family:\'Courier New\';">' . esc_html( $contents ) . '</div>';
94
+ wp_send_json_success( $markup );
95
+ }
96
+ }
admin/class-boldgrid-backup-admin-log.php ADDED
@@ -0,0 +1,301 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File: class-boldgrid-backup-admin-log.php
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.12.5
7
+ *
8
+ * @package Boldgrid_Backup
9
+ * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
+ * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
+ */
14
+
15
+ /**
16
+ * Class: Boldgrid_Backup_Admin_Log
17
+ *
18
+ * @since 1.12.5
19
+ */
20
+ class Boldgrid_Backup_Admin_Log {
21
+ /**
22
+ * The core class object.
23
+ *
24
+ * @since 1.10.0
25
+ * @access private
26
+ * @var Boldgrid_Backup_Admin_Core
27
+ */
28
+ private $core;
29
+
30
+ /**
31
+ * Log file filename.
32
+ *
33
+ * @since 1.12.5
34
+ * @var string
35
+ * @access private
36
+ */
37
+ private $filename;
38
+
39
+ /**
40
+ * Log file filepath.
41
+ *
42
+ * @since 1.12.5
43
+ * @var string
44
+ * @access private
45
+ */
46
+ private $filepath;
47
+
48
+ /**
49
+ * The last error, as per error_get_last().
50
+ *
51
+ * @since 1.13.5
52
+ * @var array
53
+ * @access private
54
+ */
55
+ private $last_error;
56
+
57
+ /**
58
+ * Constructor.
59
+ *
60
+ * @since 1.10.1
61
+ *
62
+ * @param Boldgrid_Backup_Admin_Core $core Boldgrid_Backup_Admin_Core object.
63
+ */
64
+ public function __construct( Boldgrid_Backup_Admin_Core $core ) {
65
+ $this->core = $core;
66
+ }
67
+
68
+ /**
69
+ * Add a message to the log.
70
+ *
71
+ * @since 1.12.5
72
+ *
73
+ * @param string $message The message to add to the log.
74
+ * @param bool $log_last_error Whether or not to log the last error. Most useful for self::add_last_error
75
+ * to avoid infinite loop when calling this method.
76
+ */
77
+ public function add( $message, $log_last_error = true ) {
78
+ /*
79
+ * Before we do anything, log the last error. This is important to go first because when looking
80
+ * at the log, the error should come first because it was triggered before whatever it is we're
81
+ * adding a message about right now.
82
+ */
83
+ if ( $log_last_error ) {
84
+ $this->add_last_error();
85
+ }
86
+
87
+ // Add a timestamp to the message.
88
+ $message = date( '[Y-m-d H:i:s e]' ) . ' ' . $message;
89
+
90
+ /*
91
+ * Append the message to the log.
92
+ *
93
+ * WP_Filesystem does not have a way to append to a file, so we're rewriting the file each
94
+ * time. Best route would be to fopen the file and append. This may need to be revisited.
95
+ */
96
+ $file_content = $this->core->wp_filesystem->get_contents( $this->filepath );
97
+ $file_content .= PHP_EOL . $message;
98
+ $this->core->wp_filesystem->put_contents( $this->filepath, $file_content );
99
+ }
100
+
101
+ /**
102
+ * Add generic info for all logs.
103
+ *
104
+ * @since 1.12.6
105
+ */
106
+ public function add_generic() {
107
+ $this->add( 'PHP Version: ' . phpversion() );
108
+
109
+ $this->add( 'WordPress Version: ' . get_bloginfo( 'version' ) );
110
+
111
+ $this->add( 'Total Upkeep version: ' . BOLDGRID_BACKUP_VERSION );
112
+ }
113
+
114
+ /**
115
+ * Add the last error to the log.
116
+ *
117
+ * The error is only added to the log if it hasn't been logged before.
118
+ *
119
+ * @since 1.13.5
120
+ */
121
+ public function add_last_error() {
122
+ $current_error = error_get_last();
123
+
124
+ // Only new errors are logged.
125
+ if ( $current_error !== $this->last_error ) {
126
+ $this->add( 'Last error: ' . print_r( $current_error, 1 ), false ); // phpcs:ignore
127
+ }
128
+
129
+ // This method will be called often, so keep track of errors to avoid logging duplicates.
130
+ $this->last_error = $current_error;
131
+ }
132
+
133
+
134
+ /**
135
+ * Add info to the log about memory usage.
136
+ *
137
+ * @since 1.12.5
138
+ */
139
+ public function add_memory() {
140
+ $limit = ini_get( 'memory_limit' );
141
+ $memory = memory_get_usage();
142
+ $memory_peak = memory_get_peak_usage();
143
+
144
+ $message = sprintf(
145
+ 'Memory usage - limit / current / peak memory usage: %1$s / %2$s (%3$s) / %4$s (%5$s)',
146
+ $limit,
147
+ $memory,
148
+ size_format( $memory, 2 ),
149
+ $memory_peak,
150
+ size_format( $memory_peak )
151
+ );
152
+
153
+ $this->add( $message );
154
+ }
155
+
156
+ /**
157
+ * Add a separator in the log.
158
+ *
159
+ * @since 1.13.7
160
+ */
161
+ public function add_separator() {
162
+ $this->add( '--------------------------------------------------------------------------------' );
163
+ }
164
+
165
+ /**
166
+ * Delete old log files.
167
+ *
168
+ * @since 1.12.5
169
+ */
170
+ public function clean_up() {
171
+ // Get a dirlist of our logs dir.
172
+ $logs_dir = $this->core->backup_dir->get_logs_dir();
173
+ $dirlist = $this->core->wp_filesystem->dirlist( $logs_dir );
174
+
175
+ foreach ( $dirlist as $item ) {
176
+ // Skip if this is not a log file.
177
+ if ( 'log' !== pathinfo( $item['name'], PATHINFO_EXTENSION ) ) {
178
+ continue;
179
+ }
180
+
181
+ // Skip if this file is not old enough to delete.
182
+ $is_too_old = time() - $item['lastmodunix'] > $this->core->configs['max_log_age'];
183
+ if ( ! $is_too_old ) {
184
+ continue;
185
+ }
186
+
187
+ $filepath = Boldgrid_Backup_Admin_Utility::trailingslashit( $logs_dir ) . $item['name'];
188
+
189
+ $this->core->wp_filesystem->delete( $filepath );
190
+ }
191
+ }
192
+
193
+ /**
194
+ * Init.
195
+ *
196
+ * @since 1.12.5
197
+ *
198
+ * @param string $filename The filename of the log to create.
199
+ * @return bool Whether or not the log file was created successfully.
200
+ */
201
+ public function init( $filename ) {
202
+ // Purging of old log files is done here, when we're creating a new one.
203
+ $this->clean_up();
204
+
205
+ $this->filename = sanitize_file_name( $filename );
206
+
207
+ $this->filepath = $this->core->backup_dir->get_logs_dir() . DIRECTORY_SEPARATOR . $this->filename;
208
+
209
+ $this->init_signal_handler();
210
+
211
+ $log_exists = $this->core->wp_filesystem->exists( $this->filepath );
212
+
213
+ if ( ! $log_exists ) {
214
+ $log_created = $this->core->wp_filesystem->touch( $this->filepath );
215
+
216
+ if ( $log_created ) {
217
+ $this->add_generic();
218
+ }
219
+ }
220
+
221
+ return $log_exists || $log_created;
222
+ }
223
+
224
+ /**
225
+ * Add signal handlers.
226
+ *
227
+ * The one signal we can't handle is SIGFILL (kill -9).
228
+ *
229
+ * @since 1.12.6
230
+ */
231
+ private function init_signal_handler() {
232
+ /*
233
+ * Available only on php >= 7.1
234
+ *
235
+ * With PHP 7.1, pcntl_async_signals was added to enable asynchronous signal handling, and it
236
+ * works great.
237
+ *
238
+ * Using ticks in php 5.6 not working as expected.
239
+ */
240
+ if ( ! version_compare( phpversion(), '7.1', '>=' ) ) {
241
+ return;
242
+ }
243
+
244
+ if ( ! function_exists( 'pcntl_async_signals' ) ) {
245
+ $this->add( 'Cannot add signal handlers, pcntl_async_signals function does not exist.' );
246
+ return;
247
+ }
248
+
249
+ // Enable asynchronous signal handling.
250
+ pcntl_async_signals( true );
251
+
252
+ $signals = [
253
+ // Ctrl+C.
254
+ SIGINT,
255
+ // Ctrl+\ (similiar to SIGINT, generates a core dump if necessary).
256
+ SIGQUIT,
257
+ // kill.
258
+ SIGTERM,
259
+ // Terminal log-out.
260
+ SIGHUP,
261
+ /*
262
+ * Apache graceful stop.
263
+ *
264
+ * @link https://stackoverflow.com/questions/780853/what-is-in-apache-2-a-caught-sigwinch-error
265
+ */
266
+ SIGWINCH,
267
+ ];
268
+
269
+ foreach ( $signals as $signal ) {
270
+ pcntl_signal( $signal, [ $this, 'signal_handler' ] );
271
+ }
272
+ }
273
+
274
+ /**
275
+ * Hook into shutdown.
276
+ *
277
+ * @since 1.13.5
278
+ */
279
+ public function shutdown() {
280
+ /*
281
+ * This method is always added to the shutdown. Only log errors if we've initialized and are
282
+ * using this logging system (IE don't log errors unrelated to this plugin).
283
+ */
284
+ if ( ! empty( $this->filename ) ) {
285
+ $this->add_last_error();
286
+ }
287
+ }
288
+
289
+ /**
290
+ * Signal handler.
291
+ *
292
+ * @since 1.12.6
293
+ *
294
+ * @param int The signal being handled.
295
+ */
296
+ public function signal_handler( $signo ) {
297
+ $this->add( 'Signal received: ' . $signo );
298
+
299
+ exit;
300
+ }
301
+ }
admin/class-boldgrid-backup-admin-notice.php CHANGED
@@ -1,28 +1,29 @@
1
  <?php
2
  /**
3
- * The admin-specific notice methods for the plugin
4
  *
5
- * @link http://www.boldgrid.com
6
- * @since 1.2
7
  *
8
- * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
- * @copyright BoldGrid.com
11
- * @version $Id$
12
- * @author BoldGrid.com <wpb@boldgrid.com>
13
  */
14
 
 
 
15
  /**
16
- * BoldGrid Backup admin notice class.
17
  *
18
  * @since 1.2
19
  */
20
  class Boldgrid_Backup_Admin_Notice {
21
-
22
  /**
23
  * The core class object.
24
  *
25
- * @since 1.5.4
26
  * @access private
27
  * @var Boldgrid_Backup_Admin_Core
28
  */
@@ -31,18 +32,26 @@ class Boldgrid_Backup_Admin_Notice {
31
  /**
32
  * Common strings used in notices.
33
  *
34
- * @since 1.5.4
35
  * @var array
36
  */
37
- public $lang = array(
38
- 'dis_error' => 'notice notice-error is-dismissible',
39
  'dis_success' => 'notice notice-success is-dismissible',
40
- );
 
 
 
 
 
 
 
 
41
 
42
  /**
43
  * Constructor.
44
  *
45
- * @since 1.5.4
46
  *
47
  * @param Boldgrid_Backup_Admin_Core $core Core class object.
48
  */
@@ -53,45 +62,37 @@ class Boldgrid_Backup_Admin_Notice {
53
  /**
54
  * Add a notice for a user.
55
  *
56
- * @since 1.5.4
57
  *
58
- * @param string $message
59
- * @param string $class
60
- * @param string $heading
61
  */
62
  public function add_user_notice( $message, $class, $heading = null ) {
63
  $option = $this->get_user_option();
64
 
65
- $notices = get_option( $option, array() );
66
 
67
  $message = $this->add_container( $message );
68
 
69
- $notices[] = array(
70
  'message' => $message,
71
- 'class' => $class,
72
  'heading' => $heading,
73
- );
74
 
75
  update_option( $option, $notices );
76
  }
77
 
78
- /**
79
- * An array of messages we've already printed to the current page.
80
- *
81
- * @since 1.5.1
82
- * @var array
83
- */
84
- public $displayed_messages = array();
85
-
86
  /**
87
  * Display notices for user.
88
  *
89
- * @since 1.5.4
90
  */
91
  public function display_user_notice() {
92
  $option = $this->get_user_option();
93
 
94
- $notices = get_option( $option, array() );
95
 
96
  $notices = $this->core->in_progress->add_notice( $notices );
97
 
@@ -100,14 +101,16 @@ class Boldgrid_Backup_Admin_Notice {
100
  }
101
 
102
  foreach ( $notices as $notice ) {
103
- printf( '
 
104
  <div class="%1$s is-dismissible">
105
  %3$s
106
  %2$s
107
  </div>',
108
  /* 1 */ $notice['class'],
109
  /* 2 */ $this->add_container( $notice['message'] ),
110
- /* 3 */ ! empty( $notice['heading'] ) ? sprintf( '<h2 class="header-notice">%1$s</h2>', $notice['heading'] ) : ''
 
111
  );
112
  }
113
 
@@ -127,9 +130,7 @@ class Boldgrid_Backup_Admin_Notice {
127
  return;
128
  }
129
 
130
- $markup = $this->get_notice_markup( $class, $message );
131
-
132
- echo $markup;
133
 
134
  $this->displayed_messages[] = $message;
135
  }
@@ -142,7 +143,6 @@ class Boldgrid_Backup_Admin_Notice {
142
  * @return mixed String (html markup) of admin notice on success, false on failure.
143
  */
144
  public function get_backup_complete() {
145
-
146
  // Assume that this "backup complete!" notice is for the last backup made.
147
  $archive_info = get_option( 'boldgrid_backup_latest_backup' );
148
  if ( empty( $archive_info ) ) {
@@ -159,13 +159,14 @@ class Boldgrid_Backup_Admin_Notice {
159
  /**
160
  * Get the entire html markup for a notice, including the .notice container.
161
  *
162
- * @param string $class
163
- * @param string $message
164
- * @param string $heading
165
  * @return string
166
  */
167
  public function get_notice_markup( $class, $message, $heading = null ) {
168
- return sprintf( '
 
169
  <div class="%1$s">
170
  %2$s
171
  %3$s
@@ -186,6 +187,7 @@ class Boldgrid_Backup_Admin_Notice {
186
  public function functionality_fail_notice( $use_link = true ) {
187
  if ( $use_link ) {
188
  $message = sprintf(
 
189
  esc_html__(
190
  'Functionality test has failed. You can go to %1$sFunctionality Test%2$s to view a report.',
191
  'boldgrid-backup'
@@ -203,7 +205,7 @@ class Boldgrid_Backup_Admin_Notice {
203
  /**
204
  * Get user_notices option name for current user.
205
  *
206
- * @since 1.5.4
207
  */
208
  public function get_user_option() {
209
  $user_id = get_current_user_id();
@@ -215,9 +217,9 @@ class Boldgrid_Backup_Admin_Notice {
215
  *
216
  * If it is not within a p or div, wrap it in a p tag.
217
  *
218
- * @since 1.5.4
219
  *
220
- * @param string $message
221
  * @return string
222
  */
223
  public function add_container( $message ) {
@@ -227,4 +229,68 @@ class Boldgrid_Backup_Admin_Notice {
227
 
228
  return $message;
229
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
230
  }
1
  <?php
2
  /**
3
+ * File: class-boldgrid-backup-admin-notice.php
4
  *
5
+ * @link http://www.boldgrid.com
6
+ * @since 1.2
7
  *
8
+ * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid.com
11
+ * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
  */
14
 
15
+ use \Boldgrid\Library\Library\Notice;
16
+
17
  /**
18
+ * Class: Boldgrid_Backup_Admin_Notice
19
  *
20
  * @since 1.2
21
  */
22
  class Boldgrid_Backup_Admin_Notice {
 
23
  /**
24
  * The core class object.
25
  *
26
+ * @since 1.6.0
27
  * @access private
28
  * @var Boldgrid_Backup_Admin_Core
29
  */
32
  /**
33
  * Common strings used in notices.
34
  *
35
+ * @since 1.6.0
36
  * @var array
37
  */
38
+ public $lang = [
39
+ 'dis_error' => 'notice notice-error is-dismissible',
40
  'dis_success' => 'notice notice-success is-dismissible',
41
+ ];
42
+
43
+ /**
44
+ * An array of messages we've already printed to the current page.
45
+ *
46
+ * @since 1.5.1
47
+ * @var array
48
+ */
49
+ public $displayed_messages = [];
50
 
51
  /**
52
  * Constructor.
53
  *
54
+ * @since 1.6.0
55
  *
56
  * @param Boldgrid_Backup_Admin_Core $core Core class object.
57
  */
62
  /**
63
  * Add a notice for a user.
64
  *
65
+ * @since 1.6.0
66
  *
67
+ * @param string $message Message.
68
+ * @param string $class Class.
69
+ * @param string $heading Heading.
70
  */
71
  public function add_user_notice( $message, $class, $heading = null ) {
72
  $option = $this->get_user_option();
73
 
74
+ $notices = get_option( $option, [] );
75
 
76
  $message = $this->add_container( $message );
77
 
78
+ $notices[] = [
79
  'message' => $message,
80
+ 'class' => $class,
81
  'heading' => $heading,
82
+ ];
83
 
84
  update_option( $option, $notices );
85
  }
86
 
 
 
 
 
 
 
 
 
87
  /**
88
  * Display notices for user.
89
  *
90
+ * @since 1.6.0
91
  */
92
  public function display_user_notice() {
93
  $option = $this->get_user_option();
94
 
95
+ $notices = get_option( $option, [] );
96
 
97
  $notices = $this->core->in_progress->add_notice( $notices );
98
 
101
  }
102
 
103
  foreach ( $notices as $notice ) {
104
+ printf(
105
+ '
106
  <div class="%1$s is-dismissible">
107
  %3$s
108
  %2$s
109
  </div>',
110
  /* 1 */ $notice['class'],
111
  /* 2 */ $this->add_container( $notice['message'] ),
112
+ /* 3 */ ! empty( $notice['heading'] ) ?
113
+ sprintf( '<h2 class="header-notice">%1$s</h2>', $notice['heading'] ) : '' // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
114
  );
115
  }
116
 
130
  return;
131
  }
132
 
133
+ echo $this->get_notice_markup( $class, $message ); // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
 
 
134
 
135
  $this->displayed_messages[] = $message;
136
  }
143
  * @return mixed String (html markup) of admin notice on success, false on failure.
144
  */
145
  public function get_backup_complete() {
 
146
  // Assume that this "backup complete!" notice is for the last backup made.
147
  $archive_info = get_option( 'boldgrid_backup_latest_backup' );
148
  if ( empty( $archive_info ) ) {
159
  /**
160
  * Get the entire html markup for a notice, including the .notice container.
161
  *
162
+ * @param string $class Class.
163
+ * @param string $message Message.
164
+ * @param string $heading Heading.
165
  * @return string
166
  */
167
  public function get_notice_markup( $class, $message, $heading = null ) {
168
+ return sprintf(
169
+ '
170
  <div class="%1$s">
171
  %2$s
172
  %3$s
187
  public function functionality_fail_notice( $use_link = true ) {
188
  if ( $use_link ) {
189
  $message = sprintf(
190
+ // translators: 1: HTML anchor opening tag, 2: HTML anchor closing tag.
191
  esc_html__(
192
  'Functionality test has failed. You can go to %1$sFunctionality Test%2$s to view a report.',
193
  'boldgrid-backup'
205
  /**
206
  * Get user_notices option name for current user.
207
  *
208
+ * @since 1.6.0
209
  */
210
  public function get_user_option() {
211
  $user_id = get_current_user_id();
217
  *
218
  * If it is not within a p or div, wrap it in a p tag.
219
  *
220
+ * @since 1.6.0
221
  *
222
+ * @param string $message Message.
223
  * @return string
224
  */
225
  public function add_container( $message ) {
229
 
230
  return $message;
231
  }
232
+
233
+ /**
234
+ * Display a notice for auto-update settings.
235
+ *
236
+ * @since 1.7.0
237
+ */
238
+ public function display_autoupdate_notice() {
239
+ $message = sprintf(
240
+ // translators: 1: HTML anchor opening tag, 2: HTML anchor closing tag, 3: Plugin title.
241
+ esc_html__(
242
+ 'Auto Updates can be configured in the %1$s%3$s Settings%2$s.',
243
+ 'boldgrid-backup'
244
+ ),
245
+ '<a href="' . admin_url( 'admin.php?page=boldgrid-backup-settings&section=section_auto_updates' ) . '">',
246
+ '</a>',
247
+ BOLDGRID_BACKUP_TITLE
248
+ );
249
+
250
+ do_action( 'boldgrid_backup_notice', $message, 'notice notice-info is-dismissible' );
251
+ }
252
+
253
+ /**
254
+ * Display a notice for this plugin being renamed.
255
+ *
256
+ * The notice is displayed to all admin users, dismissible per user.
257
+ *
258
+ * @since 1.12.0
259
+ *
260
+ * @see \Boldgrid\Library\Library\Notice::isDismissed()
261
+ * @see \Boldgrid\Library\Library\Notice::show()
262
+ */
263
+ public function plugin_renamed_notice() {
264
+ $plugin = new \Boldgrid\Library\Library\Plugin\Plugin( 'boldgrid-backup' );
265
+
266
+ /*
267
+ * Only show to existing users.
268
+ *
269
+ * If the first version of this plugin is not less than 1.12.0 (the version when the rename
270
+ * occurred), abort.
271
+ */
272
+ if ( ! $plugin->firstVersionCompare( '1.12.0', '<' ) ) {
273
+ return;
274
+ }
275
+
276
+ $notice_id = 'boldgrid_backup_renamed';
277
+
278
+ if ( ! Notice::isDismissed( $notice_id ) ) {
279
+ $message = sprintf(
280
+ // translators: 1: HTML anchor open tag, 2: HTML anchor close tag, 3: HTML H3 open tag, 4: HTML H3 close tag, 5: HTML p open tag, 6: HTML p close tag, 7: Plugin title.
281
+ esc_html__(
282
+ '%3$sBoldGrid Backup has become Total Upkeep!%4$s%5$sDifferent name with the same great features. For more information on the change, please go to %1$sour website%2$s.%6$s',
283
+ 'boldgrid-backup'
284
+ ),
285
+ '<a target="_blank" href="' . esc_url( $this->core->configs['urls']['plugin_renamed'] ) . '">',
286
+ '</a>',
287
+ '<h3>',
288
+ '</h3>',
289
+ '<p>',
290
+ '</p>'
291
+ );
292
+
293
+ Notice::show( $message, $notice_id, 'notice notice-info' );
294
+ }
295
+ }
296
  }
admin/class-boldgrid-backup-admin-plugin-notices.php ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File: class-boldgrid-backup-admin-plugin-notices.php
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.13.1
7
+ *
8
+ * @package Boldgrid_Backup
9
+ * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
+ * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
+ */
14
+
15
+ /**
16
+ * Class: Boldgrid_Backup_Admin_Plugin_Notices
17
+ *
18
+ * @since 1.13.1
19
+ */
20
+ class Boldgrid_Backup_Admin_Plugin_Notices {
21
+ /**
22
+ * Filter the plugin notice counts.
23
+ *
24
+ * @since 1.13.1
25
+ *
26
+ * @param array $translation An array of plugin notice info.
27
+ * @return array
28
+ */
29
+ public function filter( $translation ) {
30
+ $core = apply_filters( 'boldgrid_backup_get_core', null );
31
+
32
+ // Setup the plugin notice count for the main menu item.
33
+ $plugin_count = $core->plugin->getUnreadCount();
34
+ if ( $plugin_count ) {
35
+ $translation['counts'][] = [
36
+ 'href' => 'admin.php?page=boldgrid-backup-dashboard',
37
+ 'count' => $plugin_count,
38
+ ];
39
+ }
40
+
41
+ // Setup plugin notice counts for sub menu items.
42
+ foreach ( $core->configs['pages'] as $page ) {
43
+ $page_count = $core->plugin->getPageBySlug( $page )->getUnreadCount();
44
+
45
+ if ( $page_count ) {
46
+ $translation['counts'][] = [
47
+ 'href' => 'admin.php?page=' . $page,
48
+ 'count' => $page_count,
49
+ ];
50
+ }
51
+ }
52
+
53
+ return $translation;
54
+ }
55
+ }
admin/class-boldgrid-backup-admin-plugins.php ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File: class-boldgrid-backup-admin-plugins.php
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.10.1
7
+ *
8
+ * @package Boldgrid_Backup
9
+ * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
+ * @author BoldGrid <support@boldgrid.com>
12
+ */
13
+
14
+ /**
15
+ * Class: Boldgrid_Backup_Admin_Plugins
16
+ *
17
+ * This is a generic class designed to help manage how this plugin behaves within the scope of
18
+ * "WordPress Dashboard > Plugins > *".
19
+ *
20
+ * @since 1.10.1
21
+ */
22
+ class Boldgrid_Backup_Admin_Plugins {
23
+ /**
24
+ * Filter this plugin's links within Plugins > Installed Plugins.
25
+ *
26
+ * @since 1.10.1
27
+ *
28
+ * @param array $actions An array of plugin action links. By default this can include 'activate',
29
+ * 'deactivate', and 'delete'. With Multisite active this can also include
30
+ * 'network_active' and 'network_only' items.
31
+ * @param string $plugin_file Path to the plugin file relative to the plugins directory.
32
+ * @param array $plugin_data An array of plugin data. See `get_plugin_data()`.
33
+ * @param string $context The plugin context. By default this can include 'all', 'active', 'inactive',
34
+ * 'recently_activated', 'upgrade', 'mustuse', 'dropins', and 'search'.
35
+ */
36
+ public function plugin_action_links( $actions, $plugin_file, $plugin_data, $context ) {
37
+ $core = apply_filters( 'boldgrid_backup_get_core', null );
38
+
39
+ $row_actions = [
40
+ 'settings' => '<a href="' . esc_url( $core->settings->get_settings_url() ) . '">' .
41
+ esc_html__( 'Settings', 'boldgrid-backup' ) . '</a>',
42
+ ];
43
+
44
+ if ( ! $core->config->get_is_premium() ) {
45
+ $row_actions[] = '<a href="' . esc_url( $core->go_pro->get_premium_url( 'bgbkup-plugin-actions' ) ) .
46
+ '" target="_blank">' . esc_html__( 'Get Premium', 'boldgrid-backup' ) . '</a>';
47
+ }
48
+
49
+ $actions = array_merge( $row_actions, $actions );
50
+
51
+ return $actions;
52
+ }
53
+ }
admin/class-boldgrid-backup-admin-premium-features.php ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File: class-boldgrid-backup-admin-premium-features.php
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.13.0
7
+ *
8
+ * @package Boldgrid_Backup
9
+ * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
+ * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
+ */
14
+
15
+ use Boldgrid\Backup\Admin\Card;
16
+
17
+ /**
18
+ * Class: Boldgrid_Backup_Admin_Premium_Features
19
+ *
20
+ * @since 1.13.0
21
+ */
22
+ class Boldgrid_Backup_Admin_Premium_Features {
23
+
24
+ /**
25
+ * The core class object.
26
+ *
27
+ * @since 1.13.0
28
+ * @var Boldgrid_Backup_Admin_Core
29
+ */
30
+ public $core;
31
+
32
+ /**
33
+ * The page's Boldgrid\Library\Library\Plugin\Page Object.
34
+ *
35
+ * @since 1.13.0
36
+ * @access private
37
+ * @var Boldgrid\Library\Library\Plugin\Page
38
+ */
39
+ private $page;
40
+
41
+ /**
42
+ * Constructor.
43
+ *
44
+ * @since 1.13.0
45
+ *
46
+ * @param Boldgrid_Backup_Admin_Core $core Core class object.
47
+ */
48
+ public function __construct( Boldgrid_Backup_Admin_Core $core ) {
49
+ $this->core = $core;
50
+ }
51
+
52
+ /**
53
+ * Enqueue scripts.
54
+ *
55
+ * @since 1.13.0
56
+ *
57
+ * @param string $hook Hook name.
58
+ */
59
+ public function admin_enqueue_scripts( $hook ) {
60
+ if ( isset( $_REQUEST['page'] ) && 'boldgrid-backup-premium-features' === $_REQUEST['page'] ) { // phpcs:ignore WordPress.CSRF.NonceVerification.NoNonceVerification
61
+ wp_enqueue_style(
62
+ 'boldgrid-backup-admin-premium-features',
63
+ plugin_dir_url( __FILE__ ) . 'css/boldgrid-backup-admin-premium.css', array(),
64
+ BOLDGRID_BACKUP_VERSION
65
+ );
66
+ }
67
+ }
68
+
69
+ /**
70
+ * Get cards needed for the dashboard.
71
+ *
72
+ * @since 1.13.0
73
+ *
74
+ * @return array
75
+ */
76
+ public function get_cards() {
77
+ $plugin = $this->core->plugin;
78
+
79
+ $this->page = $plugin->getPageBySlug( 'boldgrid-backup-premium-features' );
80
+ $cards = [
81
+ new Card\Database_Encryption( $this->page ),
82
+ new Card\Google_Drive( $this->page ),
83
+ new Card\Amazon_S3( $this->page ),
84
+ new Card\Dream_Objects( $this->page ),
85
+ new Card\One_Click_Restoration( $this->page ),
86
+ new Card\History( $this->page ),
87
+ new Card\Historical_Versions( $this->page ),
88
+ new Card\Plugin_Editor_Tools( $this->page ),
89
+ new Card\Find_Modified_Files( $this->page ),
90
+ ];
91
+
92
+ return $cards;
93
+ }
94
+
95
+ /**
96
+ * Render the dashboard page.
97
+ *
98
+ * @since 1.13.0
99
+ *
100
+ * @return array returns an array of the $nav, $dashboard, and $premium_box for validation.
101
+ */
102
+ public function page() {
103
+ wp_enqueue_style( 'bglib-ui-css' );
104
+
105
+ $this->admin_enqueue_scripts( 'boldgrid-backup-admin-premium-features' );
106
+ include BOLDGRID_BACKUP_PATH . '/admin/partials/boldgrid-backup-admin-premium.php';
107
+ $this->page->setAllNoticesRead();
108
+ return array(
109
+ 'nav' => $nav,
110
+ 'dashboard' => $dashboard,
111
+ 'premium_box' => $premium_box,
112
+ );
113
+ }
114
+ }
admin/class-boldgrid-backup-admin-remote.php CHANGED
@@ -1,24 +1,23 @@
1
  <?php
2
  /**
3
- * Boldgrid Backup Admin Remote.
4
  *
5
- * @link http://www.boldgrid.com
6
  * @since 1.5.2
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
- * @copyright BoldGrid.com
11
  * @version $Id$
12
- * @author BoldGrid.com <wpb@boldgrid.com>
13
  */
14
 
15
  /**
16
- * Boldgrid Backup Admin Remote class.
17
  *
18
  * @since 1.5.2
19
  */
20
  class Boldgrid_Backup_Admin_Remote {
21
-
22
  /**
23
  * The core class object.
24
  *
@@ -33,7 +32,7 @@ class Boldgrid_Backup_Admin_Remote {
33
  *
34
  * @since 1.5.2
35
  *
36
- * @param Boldgrid_Backup_Admin_Core $core
37
  */
38
  public function __construct( $core ) {
39
  $this->core = $core;
@@ -42,7 +41,7 @@ class Boldgrid_Backup_Admin_Remote {
42
  /**
43
  * Determine if any storage locations are enabled.
44
  *
45
- * @since 1.5.4
46
  *
47
  * @return bool
48
  */
@@ -62,37 +61,71 @@ class Boldgrid_Backup_Admin_Remote {
62
  return false;
63
  }
64
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
  /**
66
  * Return whether or not a remote storage provider is enabled.
67
  *
68
  * @since 1.5.2
69
  *
70
- * @param string $id amazon_s3
71
  * @return bool
72
  */
73
  public function is_enabled( $id ) {
74
  $settings = $this->core->settings->get_settings();
75
 
76
- return ! empty( $settings['remote'][ $id ]['enabled'] ) && true === $settings['remote'][ $id ]['enabled'] ;
77
  }
78
 
79
  /**
80
  * Take action after a backup has been downloaded remotely.
81
  *
82
- * @since 1.5.4
 
 
 
 
 
83
  */
84
  public function post_download( $filepath ) {
85
-
86
- /*
87
- * Restore the log file from the archive so we can get all the juicy
88
- * meta data about the archive.
89
- */
90
- $this->core->archive_log->restore_by_zip( $filepath );
91
-
92
- /*
93
- * Now that we have the log, update the archive's timestamp based upon
94
- * time last modified time in the log.
95
- */
96
  $this->core->archive->reset();
97
  $this->core->archive->init( $filepath );
98
  $this->core->archive->update_timestamp();
1
  <?php
2
  /**
3
+ * File: class-boldgrid-backup-admin-remote.php
4
  *
5
+ * @link https://www.boldgrid.com
6
  * @since 1.5.2
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
  * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
  */
14
 
15
  /**
16
+ * Class: Boldgrid_Backup_Admin_Remote
17
  *
18
  * @since 1.5.2
19
  */
20
  class Boldgrid_Backup_Admin_Remote {
 
21
  /**
22
  * The core class object.
23
  *
32
  *
33
  * @since 1.5.2
34
  *
35
+ * @param Boldgrid_Backup_Admin_Core $core Boldgrid_Backup_Admin_Core object.
36
  */
37
  public function __construct( $core ) {
38
  $this->core = $core;
41
  /**
42
  * Determine if any storage locations are enabled.
43
  *
44
+ * @since 1.6.0
45
  *
46
  * @return bool
47
  */
61
  return false;
62
  }
63
 
64
+ /**
65
+ * Get enabled remote storage providers.
66
+ *
67
+ * @since 1.11.0
68
+ *
69
+ * @param string $key If a key is passed in, only that key from the array of providers will be
70
+ * returned. For example, if we only need the title of the providers, set
71
+ * $key = 'title' and you'll only get an array of titles.
72
+ * @return array
73
+ */
74
+ public function get_enabled( $key = '' ) {
75
+ $enabled = [];
76
+
77
+ // Example: https://pastebin.com/w09Kea9B
78
+ $storage_locations = apply_filters( 'boldgrid_backup_register_storage_location', [] );
79
+
80
+ foreach ( $storage_locations as $location ) {
81
+ if ( ! empty( $location['enabled'] ) ) {
82
+ $enabled[] = $location;
83
+ }
84
+ }
85
+
86
+ // Filter the remote storage providers if a $key was passed in.
87
+ if ( ! empty( $key ) ) {
88
+ $keys = [];
89
+
90
+ foreach ( $enabled as $storage_location ) {
91
+ if ( ! empty( $storage_location[ $key ] ) ) {
92
+ $keys[] = $storage_location[ $key ];
93
+ }
94
+ }
95
+
96
+ $enabled = $keys;
97
+ }
98
+
99
+ return $enabled;
100
+ }
101
+
102
+
103
  /**
104
  * Return whether or not a remote storage provider is enabled.
105
  *
106
  * @since 1.5.2
107
  *
108
+ * @param string $id A remote storage id, such as "amazon_s3".
109
  * @return bool
110
  */
111
  public function is_enabled( $id ) {
112
  $settings = $this->core->settings->get_settings();
113
 
114
+ return ! empty( $settings['remote'][ $id ]['enabled'] ) && true === $settings['remote'][ $id ]['enabled'];
115
  }
116
 
117
  /**
118
  * Take action after a backup has been downloaded remotely.
119
  *
120
+ * @since 1.6.0
121
+ *
122
+ * @see Boldgrid_Backup_Admin_Archive::init()
123
+ * @see Boldgrid_Backup_Admin_Archive::update_timestamp()
124
+ *
125
+ * @param string $filepath A file path.
126
  */
127
  public function post_download( $filepath ) {
128
+ // Update the archive's timestamp based upon time last modified time in the log.
 
 
 
 
 
 
 
 
 
 
129
  $this->core->archive->reset();
130
  $this->core->archive->init( $filepath );
131
  $this->core->archive->update_timestamp();
admin/class-boldgrid-backup-admin-restore-git.php CHANGED
@@ -1,24 +1,23 @@
1
  <?php
2
  /**
3
- * BoldGrid Backup Admin Restore Git.
4
  *
5
- * @link http://www.boldgrid.com
6
  * @since 1.5.1
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
- * @copyright BoldGrid.com
11
  * @version $Id$
12
- * @author BoldGrid.com <wpb@boldgrid.com>
13
  */
14
 
15
  /**
16
- * BoldGrid Backup Admin Restore Git.
17
  *
18
  * @since 1.5.1
19
  */
20
  class Boldgrid_Backup_Admin_Restore_Git {
21
-
22
  /**
23
  * Chmod .git/objects so that we can restore without file permission issues.
24
  *
@@ -26,13 +25,20 @@ class Boldgrid_Backup_Admin_Restore_Git {
26
  *
27
  * @global $wp_filesystem
28
  *
29
- * @param string $dir
30
  * @return string
31
  */
32
  public function chmod_objects( $dir ) {
33
  global $wp_filesystem;
34
 
35
- $message = sprintf( __( 'A file permissions error was encountered when attempting to restore files in "%1$s".', 'boldgrid-backup' ), ABSPATH . $dir );
 
 
 
 
 
 
 
36
 
37
  $chmodded = $wp_filesystem->chmod( ABSPATH . $dir, FS_CHMOD_FILE, true );
38
 
1
  <?php
2
  /**
3
+ * File: class-boldgrid-backup-admin-restore-git.php
4
  *
5
+ * @link https://www.boldgrid.com
6
  * @since 1.5.1
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
  * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
  */
14
 
15
  /**
16
+ * Class: Boldgrid_Backup_Admin_Restore_Git
17
  *
18
  * @since 1.5.1
19
  */
20
  class Boldgrid_Backup_Admin_Restore_Git {
 
21
  /**
22
  * Chmod .git/objects so that we can restore without file permission issues.
23
  *
25
  *
26
  * @global $wp_filesystem
27
  *
28
+ * @param string $dir Directory path.
29
  * @return string
30
  */
31
  public function chmod_objects( $dir ) {
32
  global $wp_filesystem;
33
 
34
+ $message = sprintf(
35
+ // translators: 1: Directory path.
36
+ __(
37
+ 'A file permissions error was encountered when attempting to restore files in "%1$s".',
38
+ 'boldgrid-backup'
39
+ ),
40
+ ABSPATH . $dir
41
+ );
42
 
43
  $chmodded = $wp_filesystem->chmod( ABSPATH . $dir, FS_CHMOD_FILE, true );
44
 
admin/class-boldgrid-backup-admin-restore-helper.php CHANGED
@@ -1,23 +1,31 @@
1
  <?php
2
  /**
3
- * BoldGrid Backup Admin Restore Helper Class.
4
  *
5
- * @link http://www.boldgrid.com
6
  * @since 1.5.1
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
- * @copyright BoldGrid.com
11
  * @version $Id$
12
- * @author BoldGrid.com <wpb@boldgrid.com>
13
  */
14
 
15
  /**
16
- * BoldGrid Backup Admin Restore Helper Class.
17
  *
18
  * @since 1.5.1
19
  */
20
  class Boldgrid_Backup_Admin_Restore_Helper {
 
 
 
 
 
 
 
 
21
 
22
  /**
23
  * Whether or not we are doing cron.
@@ -36,19 +44,19 @@ class Boldgrid_Backup_Admin_Restore_Helper {
36
  public $monitor_files = array(
37
  'htaccess' => array(
38
  // Filename, relative to ABSPATH.
39
- 'filename' => '.htaccess',
40
  // Whether or not to make a copy of the file before restoration.
41
- 'copy' => true,
42
  // Whether or not to keep the copy after restoration.
43
  'keep_copy' => true,
44
  // Whether or not the file has been copied.
45
- 'copied' => false,
46
  ),
47
  'wpconfig' => array(
48
- 'filename' => 'wp-config.php',
49
- 'copy' => true,
50
  'keep_copy' => false,
51
- 'copied' => false,
52
  ),
53
  );
54
 
@@ -61,6 +69,23 @@ class Boldgrid_Backup_Admin_Restore_Helper {
61
  $this->doing_cron = defined( 'DOING_CRON' ) && DOING_CRON;
62
  }
63
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  /**
65
  * Action to take when a .htaccess file has been restored.
66
  *
@@ -74,18 +99,19 @@ class Boldgrid_Backup_Admin_Restore_Helper {
74
  * Action to take when the wp-config.php file has been restored.
75
  *
76
  * @since 1.5.1
 
 
77
  */
78
  public function post_restore_wpconfig() {
79
- $result = Boldgrid_Backup_Admin_Utility::fix_wpconfig();
80
-
81
- if ( ! $result ) {
82
- $message = esc_html__( 'Could not update the WordPress configuration file.', 'boldgrid-backup' );
83
-
84
- error_log( __METHOD__ . ': ' . $message );
85
-
86
- if ( ! $this->doing_cron ) {
87
- do_action( 'boldgrid_backup_notice', $message, 'notice notice-error is-dismissible' );
88
- }
89
  }
90
  }
91
 
@@ -96,7 +122,7 @@ class Boldgrid_Backup_Admin_Restore_Helper {
96
  *
97
  * @global wp_filesystem
98
  *
99
- * @param array $info
100
  */
101
  public function post_restore( $info ) {
102
  if ( $info['dryrun'] ) {
@@ -107,7 +133,7 @@ class Boldgrid_Backup_Admin_Restore_Helper {
107
 
108
  foreach ( $this->monitor_files as $key => $file ) {
109
  $original = ABSPATH . $file['filename'];
110
- $new = $original . '.bgb';
111
 
112
  // Determine if the file was restored from backup.
113
  $file_restored = false;
@@ -139,7 +165,7 @@ class Boldgrid_Backup_Admin_Restore_Helper {
139
  *
140
  * @global wp_filesystem
141
  *
142
- * @param array $info
143
  */
144
  public function pre_restore( $info ) {
145
  if ( $info['dryrun'] ) {
@@ -150,7 +176,7 @@ class Boldgrid_Backup_Admin_Restore_Helper {
150
 
151
  foreach ( $this->monitor_files as $key => $file ) {
152
  $original = ABSPATH . $file['filename'];
153
- $new = $original . '.bgb';
154
 
155
  if ( $file['copy'] && $wp_filesystem->exists( $original ) ) {
156
  $wp_filesystem->copy( $original, $new, true, 0644 );
@@ -165,14 +191,17 @@ class Boldgrid_Backup_Admin_Restore_Helper {
165
  /**
166
  * Prepare for a restoration via cron job.
167
  *
 
 
168
  * @since 1.6.1
169
  *
170
  * @return bool
171
  */
172
  public function prepare_restore() {
 
173
  $pending_rollback = get_site_option( 'boldgrid_backup_pending_rollback' );
174
 
175
- if ( empty( $pending_rollback ) ) {
176
  return false;
177
  }
178
 
@@ -181,17 +210,20 @@ class Boldgrid_Backup_Admin_Restore_Helper {
181
  *
182
  * The archive_key and the archive_filename must match.
183
  */
184
- $_POST['restore_now'] = 1;
185
- $_POST['archive_key'] = 0;
186
- $_POST['archive_filename'] = basename( $pending_rollback['filepath'] );
 
 
187
 
 
188
  return true;
189
  }
190
 
191
  /**
192
  * Update permissions so an archive is safe to restore.
193
  *
194
- * The most common failure thus for when extracting an archive is file
195
  * permissions related. If WordPress cannot restore a file because the current
196
  * file's permissions don't allow editing, then the restoration both (1) fails
197
  * and (2) gives us a half restored site.
@@ -202,6 +234,7 @@ class Boldgrid_Backup_Admin_Restore_Helper {
202
  * @since 1.6.0
203
  *
204
  * @param string $archive_filepath Full path to an archive file.
 
205
  */
206
  public function set_writable_permissions( $archive_filepath ) {
207
  global $wp_filesystem;
@@ -209,16 +242,32 @@ class Boldgrid_Backup_Admin_Restore_Helper {
209
  $zip = new ZipArchive();
210
 
211
  if ( $zip->open( $archive_filepath ) ) {
212
- for ( $i = 0; $i < $zip->numFiles; $i++ ) {
213
  $data = $zip->statIndex( $i );
214
 
215
  if ( empty( $data['name'] ) ) {
216
  continue;
217
  }
218
 
219
- $wp_filesystem->chmod( ABSPATH . $data['name'] );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
220
  }
221
  }
 
 
222
  }
223
 
224
  /**
@@ -271,7 +320,7 @@ class Boldgrid_Backup_Admin_Restore_Helper {
271
  *
272
  * @since 1.5.1
273
  *
274
- * @param WP_Error $error
275
  * @return mixed False if no action is taken, otherwise a string containing
276
  * a description of the action.
277
  */
@@ -279,7 +328,7 @@ class Boldgrid_Backup_Admin_Restore_Helper {
279
  global $wp_filesystem;
280
 
281
  $message = $error->get_error_message();
282
- $data = $error->get_error_data();
283
 
284
  if ( __( 'Could not copy file.' ) === $message ) {
285
 
1
  <?php
2
  /**
3
+ * FIle: class-boldgrid-backup-admin-restore-helper.php
4
  *
5
+ * @link https://www.boldgrid.com
6
  * @since 1.5.1
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
  * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
  */
14
 
15
  /**
16
+ * Class: Boldgrid_Backup_Admin_Restore_Helper
17
  *
18
  * @since 1.5.1
19
  */
20
  class Boldgrid_Backup_Admin_Restore_Helper {
21
+ /**
22
+ * An array of error messages.
23
+ *
24
+ * @since 1.9.3
25
+ * @access private
26
+ * @var array
27
+ */
28
+ private $errors;
29
 
30
  /**
31
  * Whether or not we are doing cron.
44
  public $monitor_files = array(
45
  'htaccess' => array(
46
  // Filename, relative to ABSPATH.
47
+ 'filename' => '.htaccess',
48
  // Whether or not to make a copy of the file before restoration.
49
+ 'copy' => true,
50
  // Whether or not to keep the copy after restoration.
51
  'keep_copy' => true,
52
  // Whether or not the file has been copied.
53
+ 'copied' => false,
54
  ),
55
  'wpconfig' => array(
56
+ 'filename' => 'wp-config.php',
57
+ 'copy' => true,
58
  'keep_copy' => false,
59
+ 'copied' => false,
60
  ),
61
  );
62
 
69
  $this->doing_cron = defined( 'DOING_CRON' ) && DOING_CRON;
70
  }
71
 
72
+ /**
73
+ * Get the last error message.
74
+ *
75
+ * @since 1.9.3
76
+ *
77
+ * @return string
78
+ */
79
+ public function get_last_error() {
80
+ $last_error = '';
81
+
82
+ if ( ! empty( $this->errors ) ) {
83
+ $last_error = end( $this->errors );
84
+ }
85
+
86
+ return $last_error;
87
+ }
88
+
89
  /**
90
  * Action to take when a .htaccess file has been restored.
91
  *
99
  * Action to take when the wp-config.php file has been restored.
100
  *
101
  * @since 1.5.1
102
+ *
103
+ * @see Boldgrid_Backup_Admin_Utility::fix_wpconfig()
104
  */
105
  public function post_restore_wpconfig() {
106
+ if ( ! Boldgrid_Backup_Admin_Utility::fix_wpconfig() && ! $this->doing_cron ) {
107
+ do_action(
108
+ 'boldgrid_backup_notice',
109
+ esc_html__(
110
+ 'Could not update the WordPress configuration file.',
111
+ 'boldgrid-backup'
112
+ ),
113
+ 'notice notice-error is-dismissible'
114
+ );
 
115
  }
116
  }
117
 
122
  *
123
  * @global wp_filesystem
124
  *
125
+ * @param array $info Archive information.
126
  */
127
  public function post_restore( $info ) {
128
  if ( $info['dryrun'] ) {
133
 
134
  foreach ( $this->monitor_files as $key => $file ) {
135
  $original = ABSPATH . $file['filename'];
136
+ $new = $original . '.bgb';
137
 
138
  // Determine if the file was restored from backup.
139
  $file_restored = false;
165
  *
166
  * @global wp_filesystem
167
  *
168
+ * @param array $info Archive information.
169
  */
170
  public function pre_restore( $info ) {
171
  if ( $info['dryrun'] ) {
176
 
177
  foreach ( $this->monitor_files as $key => $file ) {
178
  $original = ABSPATH . $file['filename'];
179
+ $new = $original . '.bgb';
180
 
181
  if ( $file['copy'] && $wp_filesystem->exists( $original ) ) {
182
  $wp_filesystem->copy( $original, $new, true, 0644 );
191
  /**
192
  * Prepare for a restoration via cron job.
193
  *
194
+ * The restoration request is validated elsewhere.
195
+ *
196
  * @since 1.6.1
197
  *
198
  * @return bool
199
  */
200
  public function prepare_restore() {
201
+ // phpcs:disable WordPress.CSRF.NonceVerification.NoNonceVerification,WordPress.VIP
202
  $pending_rollback = get_site_option( 'boldgrid_backup_pending_rollback' );
203
 
204
+ if ( empty( $pending_rollback ) && empty( $_GET['archive_filename'] ) ) {
205
  return false;
206
  }
207
 
210
  *
211
  * The archive_key and the archive_filename must match.
212
  */
213
+ $_POST['restore_now'] = 1;
214
+ $_POST['archive_key'] = ( ! empty( $_GET['archive_key'] ) && is_numeric( $_GET['archive_key'] ) ) ?
215
+ (int) $_GET['archive_key'] : 0;
216
+ $_POST['archive_filename'] = ! empty( $pending_rollback['filepath'] ) ?
217
+ basename( $pending_rollback['filepath'] ) : $_GET['archive_filename'];
218
 
219
+ // phpcs:enable WordPress.CSRF.NonceVerification.NoNonceVerification,WordPress.VIP
220
  return true;
221
  }
222
 
223
  /**
224
  * Update permissions so an archive is safe to restore.
225
  *
226
+ * The most common failure thus far when extracting an archive is file
227
  * permissions related. If WordPress cannot restore a file because the current
228
  * file's permissions don't allow editing, then the restoration both (1) fails
229
  * and (2) gives us a half restored site.
234
  * @since 1.6.0
235
  *
236
  * @param string $archive_filepath Full path to an archive file.
237
+ * @return bool True if permissions were able to be updated successfully.
238
  */
239
  public function set_writable_permissions( $archive_filepath ) {
240
  global $wp_filesystem;
242
  $zip = new ZipArchive();
243
 
244
  if ( $zip->open( $archive_filepath ) ) {
245
+ for ( $i = 0; $i < $zip->numFiles; $i++ ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName
246
  $data = $zip->statIndex( $i );
247
 
248
  if ( empty( $data['name'] ) ) {
249
  continue;
250
  }
251
 
252
+ $full_path = ABSPATH . $data['name'];
253
+
254
+ // If the file does not exists, no need to check its permissions.
255
+ if ( ! $wp_filesystem->exists( $full_path ) ) {
256
+ continue;
257
+ }
258
+
259
+ if ( ! $wp_filesystem->chmod( $full_path ) ) {
260
+ $this->errors[] = sprintf(
261
+ // translators: 1 The path to a file that cannot be restored due to file permissions.
262
+ __( 'Permission denied. Unable to restore the following file: %1$s', 'boldgrid-backup' ),
263
+ $full_path
264
+ );
265
+ return false;
266
+ }
267
  }
268
  }
269
+
270
+ return true;
271
  }
272
 
273
  /**
320
  *
321
  * @since 1.5.1
322
  *
323
+ * @param WP_Error $error WP_Error object.
324
  * @return mixed False if no action is taken, otherwise a string containing
325
  * a description of the action.
326
  */
328
  global $wp_filesystem;
329
 
330
  $message = $error->get_error_message();
331
+ $data = $error->get_error_data();
332
 
333
  if ( __( 'Could not copy file.' ) === $message ) {
334
 
admin/class-boldgrid-backup-admin-scheduler.php CHANGED
@@ -1,24 +1,23 @@
1
  <?php
2
  /**
3
- * Scheduler.
4
  *
5
- * @link http://www.boldgrid.com
6
- * @since 1.5.1
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
- * @copyright BoldGrid.com
11
  * @version $Id$
12
- * @author BoldGrid.com <wpb@boldgrid.com>
13
  */
14
 
15
  /**
16
- * BoldGrid Backup Admin Scheduler class.
17
  *
18
  * @since 1.5.1
19
  */
20
  class Boldgrid_Backup_Admin_Scheduler {
21
-
22
  /**
23
  * Available schedulers.
24
  *
@@ -55,9 +54,7 @@ class Boldgrid_Backup_Admin_Scheduler {
55
  */
56
  public function clear_all_schedules() {
57
  $this->core->wp_cron->clear_schedules();
58
-
59
- $this->core->cron->delete_cron_entries();
60
- $this->core->cron->delete_cron_entries( $this->core->cron->run_jobs );
61
  }
62
 
63
  /**
@@ -103,9 +100,10 @@ class Boldgrid_Backup_Admin_Scheduler {
103
  }
104
 
105
  $is_crontab_available = $this->core->test->is_crontab_available();
 
106
 
107
- // We schedule crontab jobs requiring the PHP setting "allow_url_fopen" be enabled.
108
- if ( $is_crontab_available && ini_get( 'allow_url_fopen' ) ) {
109
  $this->available['cron'] = array(
110
  'title' => 'Cron',
111
  );
@@ -127,7 +125,7 @@ class Boldgrid_Backup_Admin_Scheduler {
127
  *
128
  * @since 1.5.1
129
  *
130
- * @param string
131
  * @return bool
132
  */
133
  public function is_available( $scheduler ) {
@@ -135,5 +133,4 @@ class Boldgrid_Backup_Admin_Scheduler {
135
 
136
  return array_key_exists( $scheduler, $available );
137
  }
138
-
139
  }
1
  <?php
2
  /**
3
+ * File: class-boldgrid-backup-admin-scheduler.php
4
  *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.5.1
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
  * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
  */
14
 
15
  /**
16
+ * Class: Boldgrid_Backup_Admin_Scheduler
17
  *
18
  * @since 1.5.1
19
  */
20
  class Boldgrid_Backup_Admin_Scheduler {
 
21
  /**
22
  * Available schedulers.
23
  *
54
  */
55
  public function clear_all_schedules() {
56
  $this->core->wp_cron->clear_schedules();
57
+ $this->core->cron->delete_cron_entries( 'all' );
 
 
58
  }
59
 
60
  /**
100
  }
101
 
102
  $is_crontab_available = $this->core->test->is_crontab_available();
103
+ $cli_support = $this->core->test->get_cli_support();
104
 
105
+ // We schedule crontab jobs requiring fetching a url (curl or file_get_contents).
106
+ if ( $is_crontab_available && $cli_support['can_remote_get'] ) {
107
  $this->available['cron'] = array(
108
  'title' => 'Cron',
109
  );
125
  *
126
  * @since 1.5.1
127
  *
128
+ * @param string $scheduler Scheduler type ("cron" or "wp-cron").
129
  * @return bool
130
  */
131
  public function is_available( $scheduler ) {
133
 
134
  return array_key_exists( $scheduler, $available );
135
  }
 
136
  }
admin/class-boldgrid-backup-admin-settings.php CHANGED
@@ -1,19 +1,23 @@
1
  <?php
2
  /**
3
- * The admin-specific utilities methods for the plugin
4
  *
5
- * @link http://www.boldgrid.com
6
  * @since 1.0
7
  *
8
- * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
- * @copyright BoldGrid.com
11
- * @version $Id$
12
- * @author BoldGrid.com <wpb@boldgrid.com>
13
  */
14
 
 
 
 
 
15
  /**
16
- * BoldGrid Backup admin settings class.
17
  *
18
  * @since 1.0
19
  */
@@ -30,7 +34,7 @@ class Boldgrid_Backup_Admin_Settings {
30
  /**
31
  * Whether or not we're in the middle of saving settings from $_POST.
32
  *
33
- * @since 1.5.4
34
  * @access public
35
  * @var bool
36
  */
@@ -47,7 +51,7 @@ class Boldgrid_Backup_Admin_Settings {
47
  // Save the Boldgrid_Backup_Admin_Core object as a class property.
48
  $this->core = $core;
49
 
50
- $this->is_saving_settings = isset( $_POST['save_time'] );
51
  }
52
 
53
  /**
@@ -63,12 +67,12 @@ class Boldgrid_Backup_Admin_Settings {
63
  public function get_dow_count() {
64
  $count = 0;
65
 
66
- if ( ! isset( $_POST ) || ! is_array( $_POST ) ) {
67
  return 0;
68
  }
69
 
70
  // Loop through each $_POST value and check if the key begins with dow_.
71
- foreach ( $_POST as $k => $v ) {
72
  if ( substr( $k, 0, 4 ) === 'dow_' ) {
73
  $count++;
74
  }
@@ -77,6 +81,20 @@ class Boldgrid_Backup_Admin_Settings {
77
  return $count;
78
  }
79
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80
  /**
81
  * Get settings using defaults.
82
  *
@@ -89,7 +107,7 @@ class Boldgrid_Backup_Admin_Settings {
89
  */
90
  public function get_settings( $raw = false ) {
91
  // Get settings.
92
- $settings = get_site_option( 'boldgrid_backup_settings', array() );
93
 
94
  if ( $raw ) {
95
  return $settings;
@@ -103,25 +121,25 @@ class Boldgrid_Backup_Admin_Settings {
103
  if ( ! empty( $settings['schedule'] ) ) {
104
  // Update schedule format.
105
  // Days of the week.
106
- $settings['schedule']['dow_sunday'] = (
107
  ! empty( $settings['schedule']['dow_sunday'] ) ? 1 : 0
108
  );
109
- $settings['schedule']['dow_monday'] = (
110
  ! empty( $settings['schedule']['dow_monday'] ) ? 1 : 0
111
  );
112
- $settings['schedule']['dow_tuesday'] = (
113
  ! empty( $settings['schedule']['dow_tuesday'] ) ? 1 : 0
114
  );
115
  $settings['schedule']['dow_wednesday'] = (
116
  ! empty( $settings['schedule']['dow_wednesday'] ) ? 1 : 0
117
  );
118
- $settings['schedule']['dow_thursday'] = (
119
  ! empty( $settings['schedule']['dow_thursday'] ) ? 1 : 0
120
  );
121
- $settings['schedule']['dow_friday'] = (
122
  ! empty( $settings['schedule']['dow_friday'] ) ? 1 : 0
123
  );
124
- $settings['schedule']['dow_saturday'] = (
125
  ! empty( $settings['schedule']['dow_saturday'] ) ? 1 : 0
126
  );
127
 
@@ -140,7 +158,7 @@ class Boldgrid_Backup_Admin_Settings {
140
  );
141
 
142
  // Notification settings.
143
- $settings['notifications']['backup'] = (
144
  ! isset( $settings['notifications']['backup'] ) ||
145
  ! empty( $settings['notifications']['backup'] ) ? 1 : 0
146
  );
@@ -158,20 +176,30 @@ class Boldgrid_Backup_Admin_Settings {
158
  $settings['auto_backup'] = (
159
  ! isset( $settings['auto_backup'] ) || ! empty( $settings['auto_backup'] ) ? 1 : 0
160
  );
 
161
  $settings['auto_rollback'] = (
162
  ! isset( $settings['auto_rollback'] ) || ! empty( $settings['auto_rollback'] ) ?
163
  1 : 0
164
  );
 
 
 
 
 
 
 
 
 
165
  } else {
166
  // Define defaults.
167
  // Days of the week.
168
- $settings['schedule']['dow_sunday'] = 0;
169
- $settings['schedule']['dow_monday'] = 0;
170
- $settings['schedule']['dow_tuesday'] = 0;
171
  $settings['schedule']['dow_wednesday'] = 0;
172
- $settings['schedule']['dow_thursday'] = 0;
173
- $settings['schedule']['dow_friday'] = 0;
174
- $settings['schedule']['dow_saturday'] = 0;
175
 
176
  // Time of day.
177
  $settings['schedule']['tod_h'] = mt_rand( 1, 5 );
@@ -179,43 +207,16 @@ class Boldgrid_Backup_Admin_Settings {
179
  $settings['schedule']['tod_a'] = 'AM';
180
 
181
  // Other settings.
182
- $settings['retention_count'] = 5;
183
- $settings['notification_email'] = $this->core->config->get_admin_email();
184
- $settings['notifications']['backup'] = 1;
185
  $settings['notifications']['restore'] = 1;
186
- $settings['auto_backup'] = 1;
187
- $settings['auto_rollback'] = 1;
188
- }
189
 
190
- /*
191
- * If a cron schedule was found, then merge the settings.
192
- *
193
- * @todo As of 1.6.0, this feature is on hold. We need to take into
194
- * account timezones, and possibly tell the user their settings don't
195
- * actually match what's in the crontab.
196
- */
197
- /*
198
- // If not updating the settings, then check cron for schedule.
199
- if ( ! isset( $_POST['save_time'] ) ) {
200
- $cron_schedule = $this->core->cron->read_cron_entry();
201
  }
202
 
203
- // If a cron schedule was found, then merge the settings.
204
- if ( ! empty( $cron_schedule ) ) {
205
- $settings['schedule'] = array_merge( $settings['schedule'], $cron_schedule );
206
- }
207
- */
208
-
209
- $boldgrid_settings = get_site_option( 'boldgrid_settings' );
210
-
211
- $settings['plugin_autoupdate'] = (
212
- ! empty( $boldgrid_settings['plugin_autoupdate'] ) ? 1 : 0
213
- );
214
-
215
- $settings['theme_autoupdate'] = (
216
- ! empty( $boldgrid_settings['theme_autoupdate'] ) ? 1 : 0
217
- );
218
-
219
  if ( empty( $settings['remote'] ) ) {
220
  $settings['remote'] = array();
221
  }
@@ -233,18 +234,173 @@ class Boldgrid_Backup_Admin_Settings {
233
  $settings['folder_exclusion_include'] = $this->core->folder_exclusion->from_settings( 'include', $settings );
234
  $settings['folder_exclusion_exclude'] = $this->core->folder_exclusion->from_settings( 'exclude', $settings );
235
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
236
  // Return the settings array.
237
  return $settings;
238
  }
239
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
240
  /**
241
  * Move backups from one directory to another.
242
  *
243
  * @since 1.3.2
244
  *
245
- * @param string $old_dir
246
- * @param string $new_dir
247
- * @return bool True on success / no backups needed to be moved.
248
  */
249
  private function move_backups( $old_dir, $new_dir ) {
250
  $fail_count = 0;
@@ -258,10 +414,10 @@ class Boldgrid_Backup_Admin_Settings {
258
 
259
  // Loop through each archive and move it.
260
  foreach ( $archives as $archive ) {
261
- $source = $archive['filepath'];
262
  $destination = $new_dir . $archive['filename'];
263
 
264
- $success = @$this->core->wp_filesystem->move( $source, $destination );
265
 
266
  if ( ! $success ) {
267
  $fail_count++;
@@ -285,14 +441,13 @@ class Boldgrid_Backup_Admin_Settings {
285
  private function update_settings() {
286
  $update_errors = array();
287
 
288
- // Verify nonce.
289
- check_admin_referer( 'boldgrid-backup-settings', 'settings_auth' );
290
-
291
- // Get the retention count.
292
- if ( isset( $_POST['retention_count'] ) ) {
293
- $retention_count = intval( $_POST['retention_count'] );
294
- } else {
295
- $retention_count = $this->core->config->get_default_retention();
296
  }
297
 
298
  // Check for settings update.
@@ -338,7 +493,7 @@ class Boldgrid_Backup_Admin_Settings {
338
  if ( ! empty( $_POST[ $index ] ) ) {
339
  // Validate by type.
340
  switch ( $type ) {
341
- case 'day' :
342
  // Convert to integer.
343
  $_POST[ $index ] = (int) $_POST[ $index ];
344
 
@@ -348,7 +503,7 @@ class Boldgrid_Backup_Admin_Settings {
348
  }
349
 
350
  break;
351
- case 'h' :
352
  if ( $_POST[ $index ] < 1 || $_POST[ $index ] > 12 ) {
353
  // Error in input.
354
  $update_error = true;
@@ -359,7 +514,7 @@ class Boldgrid_Backup_Admin_Settings {
359
  $_POST[ $index ] = (int) $_POST[ $index ];
360
 
361
  break;
362
- case 'm' :
363
  if ( $_POST[ $index ] < 0 || $_POST[ $index ] > 59 ) {
364
  // Error in input.
365
  $update_error = true;
@@ -373,7 +528,7 @@ class Boldgrid_Backup_Admin_Settings {
373
  $_POST[ $index ] = str_pad( $_POST[ $index ], 2, '0', STR_PAD_LEFT );
374
 
375
  break;
376
- case 'a' :
377
  if ( 'AM' !== $_POST[ $index ] && 'PM' !== $_POST[ $index ] ) {
378
  // Error in input; unknown type.
379
  $update_error = true;
@@ -381,7 +536,7 @@ class Boldgrid_Backup_Admin_Settings {
381
  }
382
 
383
  break;
384
- default :
385
  // Error in input; unknown type.
386
  $update_error = true;
387
  break 2;
@@ -401,105 +556,42 @@ class Boldgrid_Backup_Admin_Settings {
401
  }
402
 
403
  // Validate input for other settings.
404
- $settings['retention_count'] = (
405
- isset( $_POST['retention_count'] ) ? (int) $_POST['retention_count'] : 5
406
- );
407
 
408
- $settings['notifications']['backup'] = (
409
- ( isset( $_POST['notify_backup'] ) && '1' === $_POST['notify_backup'] ) ? 1 : 0
410
- );
411
-
412
- $settings['notifications']['restore'] = (
413
- ( isset( $_POST['notify_restore'] ) && '1' === $_POST['notify_restore'] ) ? 1 : 0
414
- );
415
-
416
- $settings['auto_backup'] = (
417
- ( ! isset( $_POST['auto_backup'] ) || '1' === $_POST['auto_backup'] ) ? 1 : 0
418
- );
419
 
420
- $settings['auto_rollback'] = (
421
- ( ! isset( $_POST['auto_rollback'] ) || '1' === $_POST['auto_rollback'] ) ? 1 : 0
422
- );
423
 
424
- // Update notification email address, if changed.
425
- if ( isset( $settings['notification_email'] ) &&
426
- sanitize_email( $_POST['notification_email'] ) !== $settings['notification_email'] ) {
427
- $settings['notification_email'] = sanitize_email( $_POST['notification_email'] );
428
- }
429
 
430
- $boldgrid_settings['plugin_autoupdate'] = (
431
- ( isset( $_POST['plugin_autoupdate'] ) && '1' === $_POST['plugin_autoupdate'] ) ?
432
- 1 : 0
433
- );
434
 
435
- $boldgrid_settings['theme_autoupdate'] = (
436
- ( isset( $_POST['theme_autoupdate'] ) && '1' === $_POST['theme_autoupdate'] ) ?
437
- 1 : 0
438
- );
439
 
440
- unset( $settings['plugin_autoupdate'], $settings['theme_autoupdate'] );
 
 
441
 
442
- // Get the current backup directory path.
443
- $backup_dir_changed = false;
444
- $original_backup_directory = ! empty( $settings['backup_directory'] ) ? $settings['backup_directory'] : false;
445
 
446
- if ( ! empty( $_POST['backup_directory'] ) ) {
447
- $post_backup_directory = trim( $_POST['backup_directory'] );
448
- $post_backup_directory = untrailingslashit( $post_backup_directory );
449
- $post_backup_directory = str_replace( '\\\\', '\\', $post_backup_directory );
450
- }
451
 
452
- /*
453
- * Create the backup directory.
454
- *
455
- * Allow the user to submit a blank backup directory if they want
456
- * to set the backup directory to the default.
457
- */
458
- if ( empty( $_POST['backup_directory'] ) ) {
459
- // The get method validates and creates the backup directory.
460
- $backup_directory = $this->core->backup_dir->guess_and_set();
461
-
462
- $backup_dir_changed = $original_backup_directory !== $backup_directory;
463
- } elseif ( $post_backup_directory !== $original_backup_directory ) {
464
- $backup_directory = $post_backup_directory;
465
-
466
- /*
467
- * Create the backup directory.
468
- *
469
- * Even if the backup directory already exists, we still want to
470
- * run the create method so that the necessary .htaccess and other
471
- * files are created to protect the directory.
472
- */
473
- $backup_directory = $this->core->backup_dir->create( $backup_directory );
474
-
475
- // Make sure that the backup directory has proper permissions.
476
- $valid = $this->core->backup_dir->is_valid( $backup_directory );
477
- if ( ! $valid ) {
478
- $backup_directory = false;
479
- }
480
-
481
- $backup_dir_changed = true;
482
- }
483
-
484
- if ( $backup_dir_changed ) {
485
- if ( false === $backup_directory ) {
486
- $update_error = true;
487
- $backup_dir_changed = false;
488
- $update_errors = array_merge( $update_errors, $this->core->backup_dir->errors );
489
- } else {
490
- $settings['backup_directory'] = $backup_directory;
491
- }
492
  }
493
 
494
- // Move backups to the new directory.
495
- if ( $backup_dir_changed && isset( $_POST['move-backups'] ) && 'on' === $_POST['move-backups'] ) {
496
- $backups_moved = $this->move_backups( $original_backup_directory, $backup_directory );
497
-
498
- if ( ! $backups_moved ) {
499
- $update_error = true;
500
- $update_errors[] = sprintf( __( 'Unable to move backups from %1$s to %2$s', 'boldgrid-backup' ), $original_backup_directory, $backup_directory );
501
- }
502
- }
503
 
504
  /*
505
  * Save compressor settings.
@@ -508,11 +600,11 @@ class Boldgrid_Backup_Admin_Settings {
508
  */
509
  if ( ! empty( $_POST['compressor'] ) ) {
510
  $available_compressors = $this->core->compressors->get_available();
511
- $selected_compressor = $_POST['compressor'];
512
  if ( in_array( $selected_compressor, $available_compressors, true ) ) {
513
  $settings['compressor'] = $selected_compressor;
514
  } else {
515
- $update_error = true;
516
  $update_errors[] = __( 'The compressor you seleted is unavailable. Please select another.', 'boldgrid-backup' );
517
  }
518
  }
@@ -520,6 +612,8 @@ class Boldgrid_Backup_Admin_Settings {
520
  /*
521
  * Save extractor settings.
522
  *
 
 
523
  * @since 1.5.1
524
  */
525
  if ( ! empty( $_POST['extractor'] ) ) {
@@ -527,7 +621,7 @@ class Boldgrid_Backup_Admin_Settings {
527
  if ( in_array( $selected_extractor, $available_compressors, true ) ) {
528
  $settings['extractor'] = $selected_extractor;
529
  } else {
530
- $update_error = true;
531
  $update_errors[] = __( 'The extractor you seleted is unavailable. Please select another.', 'boldgrid-backup' );
532
  }
533
  }
@@ -540,9 +634,9 @@ class Boldgrid_Backup_Admin_Settings {
540
  *
541
  * @since 1.5.1
542
  */
543
- $original_scheduler = ! empty( $settings['scheduler'] ) ? $settings['scheduler'] : false;
544
  $schedulers_available = $this->core->scheduler->get_available();
545
- $scheduler_changed = ! empty( $_POST['scheduler'] ) && $original_scheduler !== $_POST['scheduler'];
546
  if ( $scheduler_changed && array_key_exists( $_POST['scheduler'], $schedulers_available ) ) {
547
  $settings['scheduler'] = $_POST['scheduler'];
548
  }
@@ -552,17 +646,11 @@ class Boldgrid_Backup_Admin_Settings {
552
  *
553
  * @since 1.5.1
554
  */
555
- $scheduler = ! empty( $settings['scheduler'] ) ? $settings['scheduler'] : null;
556
- if ( 'wp-cron' === $scheduler ) {
557
- $crons_added = $this->core->wp_cron->add_all_crons( $settings );
558
- } elseif ( 'cron' === $scheduler ) {
559
- $crons_added = $this->core->cron->add_all_crons( $settings );
560
- $settings['crontab_version'] = $this->core->cron->crontab_version;
561
- $settings['cron_secret'] = $this->core->cron->get_cron_secret();
562
- }
563
- // Take action if we tried and failed to add crons.
564
- if ( isset( $crons_added ) && ! $crons_added ) {
565
- $update_error = true;
566
  $update_errors[] = esc_html__( 'An error occurred when modifying cron jobs. Please try again.', 'boldgrid-backup' );
567
  }
568
 
@@ -600,23 +688,47 @@ class Boldgrid_Backup_Admin_Settings {
600
  *
601
  * @since 1.5.3
602
  */
603
- $settings['exclude_tables'] = $this->core->db_omit->get_from_post();
604
  $settings['exclude_tables_type'] = $this->core->db_omit->get_post_type();
605
 
606
  /*
607
  * Save folder exclusion settings.
608
  *
609
- * @since 1.5.4
610
  */
611
  $settings['folder_exclusion_include'] = $this->core->folder_exclusion->from_post( 'include' );
612
  $settings['folder_exclusion_exclude'] = $this->core->folder_exclusion->from_post( 'exclude' );
613
- $settings['folder_exclusion_type'] = $this->core->folder_exclusion->from_post( 'type' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
614
 
615
  // If no errors, then save the settings.
616
  if ( ! $update_error ) {
617
- $settings['updated'] = time();
618
  update_site_option( 'boldgrid_backup_settings', $settings );
619
- $this->update_boldgrid_settings( $boldgrid_settings );
620
  }
621
  }
622
 
@@ -644,7 +756,7 @@ class Boldgrid_Backup_Admin_Settings {
644
  *
645
  * @since 1.5.3
646
  */
647
- do_action( 'boldgrid_backup_settings_updated' );
648
  }
649
 
650
  // Return success.
@@ -665,16 +777,19 @@ class Boldgrid_Backup_Admin_Settings {
665
  *
666
  * @since 1.0
667
  *
668
- * @return null
 
669
  */
670
  public function page_backup_settings() {
 
 
 
 
671
  add_thickbox();
672
  wp_enqueue_style( 'boldgrid-backup-admin-new-thickbox-style' );
673
-
674
  wp_enqueue_style( 'bglib-ui-css' );
675
  wp_enqueue_script( 'bglib-ui-js' );
676
  wp_enqueue_script( 'bglib-sticky' );
677
-
678
  wp_enqueue_script( 'bglib-license' );
679
 
680
  if ( ! $this->is_saving_settings ) {
@@ -686,8 +801,9 @@ class Boldgrid_Backup_Admin_Settings {
686
  do_action(
687
  'boldgrid_backup_notice',
688
  sprintf(
689
- esc_html__(
690
- 'Functionality test has failed. You can go to %1$sFunctionality Test%1$s to view a report.',
 
691
  'boldgrid-backup'
692
  ),
693
  '<a href="' . admin_url( 'admin.php?page=boldgrid-backup-test' ) . '">',
@@ -697,53 +813,95 @@ class Boldgrid_Backup_Admin_Settings {
697
  );
698
  }
699
 
700
- // Display warning on resource usage and backups.
701
- do_action(
702
- 'boldgrid_backup_notice',
703
- esc_html__(
 
 
 
 
704
  'Warning: Making backups uses resources. When the system is backing up, it will slow down your site for visitors. Furthermore, when the database itself is being copied, your site must “pause” temporarily to preserve data integrity. For most sites, the pause is typically a few seconds and is not noticed by visitors. Large sites take longer though. Please keep the number of backups you have stored and how often you make those backups to a minimum.',
705
  'boldgrid-backup'
706
- ),
707
- 'notice notice-warning is-dismissible'
708
- );
 
709
 
710
  // Get BoldGrid reseller settings.
711
  $boldgrid_reseller = get_option( 'boldgrid_reseller' );
712
 
713
- // If not part of a reseller, then show the unofficial host notice.
714
- if ( empty( $boldgrid_reseller ) ) {
715
- do_action(
716
- 'boldgrid_backup_notice',
717
- esc_html__(
718
- 'Please note that your web hosting provider may have a policy against these types of backups. Please verify with your provider or choose a BoldGrid Official Host.',
719
- 'boldgrid-backup'
720
- ),
721
- 'notice notice-warning is-dismissible'
722
- );
 
 
 
723
  }
724
 
725
  // Check for settings update.
726
  if ( $this->is_saving_settings ) {
727
- // Verify nonce.
728
- check_admin_referer( 'boldgrid-backup-settings', 'settings_auth' );
729
-
730
  $this->update_settings();
731
  }
732
 
733
  // Enqueue CSS for the settings page.
734
- wp_enqueue_style( 'boldgrid-backup-admin-settings',
 
735
  plugin_dir_url( __FILE__ ) . 'css/boldgrid-backup-admin-settings.css', array(),
736
  BOLDGRID_BACKUP_VERSION, 'all'
737
  );
738
 
739
  // Enqueue the JS for the settings page.
740
- wp_enqueue_script( 'boldgrid-backup-admin-settings',
 
741
  plugin_dir_url( __FILE__ ) . 'js/boldgrid-backup-admin-settings.js',
742
  array( 'jquery' ),
743
  BOLDGRID_BACKUP_VERSION,
744
  false
745
  );
746
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
747
  $this->core->folder_exclusion->enqueue_scripts();
748
  $this->core->db_omit->enqueue_scripts();
749
 
@@ -756,10 +914,12 @@ class Boldgrid_Backup_Admin_Settings {
756
 
757
  $available_compressors = $this->core->compressors->get_available();
758
 
 
 
 
 
759
  // Include the page template.
760
  include BOLDGRID_BACKUP_PATH . '/admin/partials/boldgrid-backup-admin-settings.php';
761
-
762
- return;
763
  }
764
 
765
  /**
@@ -767,40 +927,34 @@ class Boldgrid_Backup_Admin_Settings {
767
  *
768
  * @since 1.5.2
769
  *
770
- * @param array $settings
771
  * @return bool True on success.
772
  */
773
  public function save( $settings ) {
774
-
775
- // For consistency, untrailingslashit the backup dir.
776
- if ( isset( $settings['backup_directory'] ) ) {
777
- $settings['backup_directory'] = untrailingslashit( $settings['backup_directory'] );
778
- }
779
-
780
  return update_site_option( 'boldgrid_backup_settings', $settings );
781
  }
782
 
783
  /**
784
- * Update BoldGrid general settings.
785
  *
786
- * @since 1.3.11
787
  *
788
- * @param array $settings Array of BoldGrid settings.
789
- * @return bool
790
  */
791
- public function update_boldgrid_settings( array $settings ) {
792
- $boldgrid_settings = get_site_option( 'boldgrid_settings' );
793
 
794
- $boldgrid_settings['plugin_autoupdate'] = (
795
- ( isset( $settings['plugin_autoupdate'] ) && 1 === $settings['plugin_autoupdate'] ) ?
796
- 1 : 0
797
- );
798
 
799
- $boldgrid_settings['theme_autoupdate'] = (
800
- ( isset( $settings['theme_autoupdate'] ) && 1 === $settings['theme_autoupdate'] ) ?
801
- 1 : 0
802
- );
 
 
 
803
 
804
- return update_site_option( 'boldgrid_settings', $boldgrid_settings );
805
  }
806
  }
1
  <?php
2
  /**
3
+ * File: class-boldgrid-backup-admin-settings.php
4
  *
5
+ * @link https://www.boldgrid.com
6
  * @since 1.0
7
  *
8
+ * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
+ * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
  */
14
 
15
+ use \Boldgrid\Library\Library\Notice;
16
+
17
+ // phpcs:disable WordPress.VIP
18
+
19
  /**
20
+ * Class: Boldgrid_Backup_Admin_Settings
21
  *
22
  * @since 1.0
23
  */
34
  /**
35
  * Whether or not we're in the middle of saving settings from $_POST.
36
  *
37
+ * @since 1.6.0
38
  * @access public
39
  * @var bool
40
  */
51
  // Save the Boldgrid_Backup_Admin_Core object as a class property.
52
  $this->core = $core;
53
 
54
+ $this->is_saving_settings = isset( $_POST['save_time'] ); // phpcs:ignore WordPress.CSRF.NonceVerification.NoNonceVerification
55
  }
56
 
57
  /**
67
  public function get_dow_count() {
68
  $count = 0;
69
 
70
+ if ( ! isset( $_POST ) || ! is_array( $_POST ) ) { // phpcs:ignore WordPress.CSRF.NonceVerification.NoNonceVerification
71
  return 0;
72
  }
73
 
74
  // Loop through each $_POST value and check if the key begins with dow_.
75
+ foreach ( $_POST as $k => $v ) { // phpcs:ignore WordPress.CSRF.NonceVerification.NoNonceVerification
76
  if ( substr( $k, 0, 4 ) === 'dow_' ) {
77
  $count++;
78
  }
81
  return $count;
82
  }
83
 
84
+ /**
85
+ * Get a setting from the settings.
86
+ *
87
+ * @since 1.9.0
88
+ *
89
+ * @param string $key The setting name.
90
+ * @return mixed
91
+ */
92
+ public function get_setting( $key ) {
93
+ $settings = $this->get_settings();
94
+
95
+ return isset( $settings[ $key ] ) ? $settings[ $key ] : null;
96
+ }
97
+
98
  /**
99
  * Get settings using defaults.
100
  *
107
  */
108
  public function get_settings( $raw = false ) {
109
  // Get settings.
110
+ $settings = get_site_option( 'boldgrid_backup_settings', [] );
111
 
112
  if ( $raw ) {
113
  return $settings;
121
  if ( ! empty( $settings['schedule'] ) ) {
122
  // Update schedule format.
123
  // Days of the week.
124
+ $settings['schedule']['dow_sunday'] = (
125
  ! empty( $settings['schedule']['dow_sunday'] ) ? 1 : 0
126
  );
127
+ $settings['schedule']['dow_monday'] = (
128
  ! empty( $settings['schedule']['dow_monday'] ) ? 1 : 0
129
  );
130
+ $settings['schedule']['dow_tuesday'] = (
131
  ! empty( $settings['schedule']['dow_tuesday'] ) ? 1 : 0
132
  );
133
  $settings['schedule']['dow_wednesday'] = (
134
  ! empty( $settings['schedule']['dow_wednesday'] ) ? 1 : 0
135
  );
136
+ $settings['schedule']['dow_thursday'] = (
137
  ! empty( $settings['schedule']['dow_thursday'] ) ? 1 : 0
138
  );
139
+ $settings['schedule']['dow_friday'] = (
140
  ! empty( $settings['schedule']['dow_friday'] ) ? 1 : 0
141
  );
142
+ $settings['schedule']['dow_saturday'] = (
143
  ! empty( $settings['schedule']['dow_saturday'] ) ? 1 : 0
144
  );
145
 
158
  );
159
 
160
  // Notification settings.
161
+ $settings['notifications']['backup'] = (
162
  ! isset( $settings['notifications']['backup'] ) ||
163
  ! empty( $settings['notifications']['backup'] ) ? 1 : 0
164
  );
176
  $settings['auto_backup'] = (
177
  ! isset( $settings['auto_backup'] ) || ! empty( $settings['auto_backup'] ) ? 1 : 0
178
  );
179
+
180
  $settings['auto_rollback'] = (
181
  ! isset( $settings['auto_rollback'] ) || ! empty( $settings['auto_rollback'] ) ?
182
  1 : 0
183
  );
184
+
185
+ // Get retention count setting. Limit 1-99, default is from config.
186
+ $settings['retention_count'] = ( isset( $settings['retention_count'] ) &&
187
+ 99 >= $settings['retention_count'] ) ?
188
+ $settings['retention_count'] : $this->core->config->get_default_retention();
189
+
190
+ if ( $settings['retention_count'] > 99 ) {
191
+ $settings['retention_count'] = 99;
192
+ }
193
  } else {
194
  // Define defaults.
195
  // Days of the week.
196
+ $settings['schedule']['dow_sunday'] = 0;
197
+ $settings['schedule']['dow_monday'] = 0;
198
+ $settings['schedule']['dow_tuesday'] = 0;
199
  $settings['schedule']['dow_wednesday'] = 0;
200
+ $settings['schedule']['dow_thursday'] = 0;
201
+ $settings['schedule']['dow_friday'] = 0;
202
+ $settings['schedule']['dow_saturday'] = 0;
203
 
204
  // Time of day.
205
  $settings['schedule']['tod_h'] = mt_rand( 1, 5 );
207
  $settings['schedule']['tod_a'] = 'AM';
208
 
209
  // Other settings.
210
+ $settings['retention_count'] = $this->core->config->get_default_retention();
211
+ $settings['notification_email'] = $this->core->config->get_admin_email();
212
+ $settings['notifications']['backup'] = 1;
213
  $settings['notifications']['restore'] = 1;
214
+ $settings['auto_backup'] = 1;
215
+ $settings['auto_rollback'] = 1;
 
216
 
217
+ $settings['remote']['local']['enabled'] = true;
 
 
 
 
 
 
 
 
 
 
218
  }
219
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
220
  if ( empty( $settings['remote'] ) ) {
221
  $settings['remote'] = array();
222
  }
234
  $settings['folder_exclusion_include'] = $this->core->folder_exclusion->from_settings( 'include', $settings );
235
  $settings['folder_exclusion_exclude'] = $this->core->folder_exclusion->from_settings( 'exclude', $settings );
236
 
237
+ // Site Check settings.
238
+ $settings['site_check']['enabled'] = isset( $settings['site_check']['enabled'] ) ?
239
+ (bool) $settings['site_check']['enabled'] : true;
240
+
241
+ $settings['site_check']['logger'] = isset( $settings['site_check']['logger'] ) ?
242
+ (bool) $settings['site_check']['logger'] : true;
243
+
244
+ $settings['site_check']['auto_recovery'] = isset( $settings['site_check']['auto_recovery'] ) ?
245
+ (bool) $settings['site_check']['auto_recovery'] : false;
246
+
247
+ $settings['notifications']['site_check'] = isset( $settings['notifications']['site_check'] ) ?
248
+ (bool) $settings['notifications']['site_check'] : true;
249
+
250
+ // Site Check interval (in minutes); 5-59, defaults to 15.
251
+ $settings['site_check']['interval'] = ( isset( $settings['site_check']['interval'] ) &&
252
+ 4 < $settings['site_check']['interval'] && 60 > $settings['site_check']['interval'] ) ?
253
+ $settings['site_check']['interval'] : 15;
254
+
255
+ // Encryption.
256
+ $settings['encrypt_db'] = isset( $settings['encrypt_db'] ) ? (bool) $settings['encrypt_db'] : false;
257
+
258
  // Return the settings array.
259
  return $settings;
260
  }
261
 
262
+ /**
263
+ * Determine whether or not the user has full site protection.
264
+ *
265
+ * Generally, this means they have scheduled backups that upload backups to a remote server.
266
+ *
267
+ * @since 1.10.0
268
+ *
269
+ * @return bool
270
+ */
271
+ public function has_full_protection() {
272
+ return $this->has_scheduled_backups() && $this->has_remote_configured();
273
+ }
274
+
275
+ /**
276
+ * Determine whether or not the user has any remote storage options enabled.
277
+ *
278
+ * @since 1.10.0
279
+ *
280
+ * @return bool
281
+ */
282
+ public function has_remote_configured() {
283
+ $remotes = $this->get_setting( 'remote', array() );
284
+
285
+ $has_remote = false;
286
+
287
+ foreach ( $remotes as $id => $config ) {
288
+ if ( 'local' === $id ) {
289
+ continue;
290
+ }
291
+
292
+ if ( ! empty( $config['enabled'] ) ) {
293
+ $has_remote = true;
294
+ }
295
+ }
296
+
297
+ return $has_remote;
298
+ }
299
+
300
+ /**
301
+ * Whether or not the user has backups scheduled.
302
+ *
303
+ * This method is not exhaustive, and insteads returns true if the user has any days of the week
304
+ * selected.
305
+ *
306
+ * @since 1.10.0
307
+ *
308
+ * @return bool
309
+ */
310
+ public function has_scheduled_backups() {
311
+ $settings = $this->get_settings();
312
+
313
+ $schedule = empty( $settings['schedule'] ) ? [] : $settings['schedule'];
314
+
315
+ $days_scheduled = 0;
316
+
317
+ foreach ( $schedule as $key => $value ) {
318
+ if ( 'dow_' !== substr( $key, 0, 4 ) ) {
319
+ continue;
320
+ }
321
+
322
+ $days_scheduled += empty( $value ) ? 0 : 1;
323
+ }
324
+
325
+ return ! empty( $days_scheduled );
326
+ }
327
+
328
+ /**
329
+ * Get the url to the settings pages.
330
+ *
331
+ * @since 1.10.1
332
+ *
333
+ * @param string $section If passed, $section will be appended to the url so it loads that
334
+ * specific section first.
335
+ * @return string
336
+ */
337
+ public function get_settings_url( $section = '' ) {
338
+ $url = admin_url( 'admin.php?page=boldgrid-backup-settings' );
339
+
340
+ if ( ! empty( $section ) ) {
341
+ $url .= '&section=' . $section;
342
+ }
343
+
344
+ return $url;
345
+ }
346
+
347
+ /**
348
+ * Whether or not we are backing up all files, as defined in the settings.
349
+ *
350
+ * @since 1.9.0
351
+ *
352
+ * @return bool
353
+ */
354
+ public function is_all_files() {
355
+ $is_all = true;
356
+
357
+ $folder_exclusion_exclude = $this->get_setting( 'folder_exclusion_exclude' );
358
+ $folder_exclusion_include = $this->get_setting( 'folder_exclusion_include' );
359
+
360
+ if ( $this->core->folder_exclusion->default_include !== $folder_exclusion_include ) {
361
+ $is_all = false;
362
+ }
363
+
364
+ if ( $this->core->folder_exclusion->default_exclude !== $folder_exclusion_exclude ) {
365
+ $is_all = false;
366
+ }
367
+
368
+ /**
369
+ * Filter whether or not the backup is considered backing up all files.
370
+ *
371
+ * For example, an advanced user may have custom include / exclude settings, and wants this
372
+ * to be considered a backup of all their files.
373
+ *
374
+ * @since 1.9.0
375
+ *
376
+ * @param bool $is_all The current value of $is_all.
377
+ */
378
+ apply_filters( 'boldgrid_backup_settings_is_all_files', $is_all );
379
+
380
+ return $is_all;
381
+ }
382
+
383
+ /**
384
+ * Whether or not we are backing up all tables, as defined in the settings.
385
+ *
386
+ * @since 1.9.0
387
+ *
388
+ * @return bool
389
+ */
390
+ public function is_all_tables() {
391
+ $exclude_tables = $this->get_setting( 'exclude_tables' );
392
+
393
+ return empty( $exclude_tables );
394
+ }
395
+
396
  /**
397
  * Move backups from one directory to another.
398
  *
399
  * @since 1.3.2
400
  *
401
+ * @param string $old_dir Source directory.
402
+ * @param string $new_dir Destination directory.
403
+ * @return bool TRUE on success / no backups needed to be moved.
404
  */
405
  private function move_backups( $old_dir, $new_dir ) {
406
  $fail_count = 0;
414
 
415
  // Loop through each archive and move it.
416
  foreach ( $archives as $archive ) {
417
+ $source = $archive['filepath'];
418
  $destination = $new_dir . $archive['filename'];
419
 
420
+ $success = @$this->core->wp_filesystem->move( $source, $destination ); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged
421
 
422
  if ( ! $success ) {
423
  $fail_count++;
441
  private function update_settings() {
442
  $update_errors = array();
443
 
444
+ // Check security nonce and referer.
445
+ if ( ! check_admin_referer( 'boldgrid-backup-settings', 'settings_auth' ) ) {
446
+ wp_send_json_error(
447
+ array(
448
+ 'error' => __( 'Security violation! Please try again.', 'boldgrid-backup' ),
449
+ )
450
+ );
 
451
  }
452
 
453
  // Check for settings update.
493
  if ( ! empty( $_POST[ $index ] ) ) {
494
  // Validate by type.
495
  switch ( $type ) {
496
+ case 'day':
497
  // Convert to integer.
498
  $_POST[ $index ] = (int) $_POST[ $index ];
499
 
503
  }
504
 
505
  break;
506
+ case 'h':
507
  if ( $_POST[ $index ] < 1 || $_POST[ $index ] > 12 ) {
508
  // Error in input.
509
  $update_error = true;
514
  $_POST[ $index ] = (int) $_POST[ $index ];
515
 
516
  break;
517
+ case 'm':
518
  if ( $_POST[ $index ] < 0 || $_POST[ $index ] > 59 ) {
519
  // Error in input.
520
  $update_error = true;
528
  $_POST[ $index ] = str_pad( $_POST[ $index ], 2, '0', STR_PAD_LEFT );
529
 
530
  break;
531
+ case 'a':
532
  if ( 'AM' !== $_POST[ $index ] && 'PM' !== $_POST[ $index ] ) {
533
  // Error in input; unknown type.
534
  $update_error = true;
536
  }
537
 
538
  break;
539
+ default:
540
  // Error in input; unknown type.
541
  $update_error = true;
542
  break 2;
556
  }
557
 
558
  // Validate input for other settings.
559
+ $settings['notifications']['backup'] = isset( $_POST['notify_backup'] ) &&
560
+ '1' === $_POST['notify_backup'] ? 1 : 0;
 
561
 
562
+ $settings['notifications']['restore'] = isset( $_POST['notify_restore'] ) &&
563
+ '1' === $_POST['notify_restore'] ? 1 : 0;
 
 
 
 
 
 
 
 
 
564
 
565
+ $settings['notifications']['site_check'] = isset( $_POST['notify_site_check'] ) &&
566
+ '1' === $_POST['notify_site_check'];
 
567
 
568
+ $settings['auto_backup'] = ! isset( $_POST['auto_backup'] ) ||
569
+ '1' === $_POST['auto_backup'] ? 1 : 0;
 
 
 
570
 
571
+ $settings['auto_rollback'] = ! isset( $_POST['auto_rollback'] ) ||
572
+ '1' === $_POST['auto_rollback'] ? 1 : 0;
 
 
573
 
574
+ $settings['site_check']['enabled'] = isset( $_POST['site_check'] ) &&
575
+ '1' === $_POST['site_check'];
 
 
576
 
577
+ $settings['site_check']['interval'] = isset( $_POST['site_check_interval'] ) &&
578
+ 4 < $_POST['site_check_interval'] && 60 > $_POST['site_check_interval'] ?
579
+ (int) $_POST['site_check_interval'] : 15;
580
 
581
+ $settings['site_check']['logger'] = isset( $_POST['site_check_logger'] ) &&
582
+ '1' === $_POST['site_check_logger'];
 
583
 
584
+ $settings['site_check']['auto_recovery'] = isset( $_POST['auto_recovery'] ) &&
585
+ '1' === $_POST['auto_recovery'];
 
 
 
586
 
587
+ // Update notification email address, if changed.
588
+ if ( isset( $settings['notification_email'] ) &&
589
+ sanitize_email( $_POST['notification_email'] ) !== $settings['notification_email'] ) {
590
+ $settings['notification_email'] = sanitize_email( $_POST['notification_email'] );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
591
  }
592
 
593
+ // Database encryption.
594
+ $settings['encrypt_db'] = isset( $_POST['encrypt_db'] ) && '1' === $_POST['encrypt_db'];
 
 
 
 
 
 
 
595
 
596
  /*
597
  * Save compressor settings.
600
  */
601
  if ( ! empty( $_POST['compressor'] ) ) {
602
  $available_compressors = $this->core->compressors->get_available();
603
+ $selected_compressor = $_POST['compressor'];
604
  if ( in_array( $selected_compressor, $available_compressors, true ) ) {
605
  $settings['compressor'] = $selected_compressor;
606
  } else {
607
+ $update_error = true;
608
  $update_errors[] = __( 'The compressor you seleted is unavailable. Please select another.', 'boldgrid-backup' );
609
  }
610
  }
612
  /*
613
  * Save extractor settings.
614
  *
615
+ * At this time, the extractor cannot be selected within the settings.
616
+ *
617
  * @since 1.5.1
618
  */
619
  if ( ! empty( $_POST['extractor'] ) ) {
621
  if ( in_array( $selected_extractor, $available_compressors, true ) ) {
622
  $settings['extractor'] = $selected_extractor;
623
  } else {
624
+ $update_error = true;
625
  $update_errors[] = __( 'The extractor you seleted is unavailable. Please select another.', 'boldgrid-backup' );
626
  }
627
  }
634
  *
635
  * @since 1.5.1
636
  */
637
+ $original_scheduler = ! empty( $settings['scheduler'] ) ? $settings['scheduler'] : false;
638
  $schedulers_available = $this->core->scheduler->get_available();
639
+ $scheduler_changed = ! empty( $_POST['scheduler'] ) && $original_scheduler !== $_POST['scheduler'];
640
  if ( $scheduler_changed && array_key_exists( $_POST['scheduler'], $schedulers_available ) ) {
641
  $settings['scheduler'] = $_POST['scheduler'];
642
  }
646
  *
647
  * @since 1.5.1
648
  */
649
+ $settings = $this->update_cron( $settings );
650
+
651
+ // Add a notice if we tried and failed to add crons.
652
+ if ( ! $settings['crons_added'] ) {
653
+ $update_error = true;
 
 
 
 
 
 
654
  $update_errors[] = esc_html__( 'An error occurred when modifying cron jobs. Please try again.', 'boldgrid-backup' );
655
  }
656
 
688
  *
689
  * @since 1.5.3
690
  */
691
+ $settings['exclude_tables'] = $this->core->db_omit->get_from_post();
692
  $settings['exclude_tables_type'] = $this->core->db_omit->get_post_type();
693
 
694
  /*
695
  * Save folder exclusion settings.
696
  *
697
+ * @since 1.6.0
698
  */
699
  $settings['folder_exclusion_include'] = $this->core->folder_exclusion->from_post( 'include' );
700
  $settings['folder_exclusion_exclude'] = $this->core->folder_exclusion->from_post( 'exclude' );
701
+ $settings['folder_exclusion_type'] = $this->core->folder_exclusion->from_post( 'type' );
702
+
703
+ // Read BoldGrid settings form POST request, sanitize, and merge settings with saved.
704
+ $boldgrid_settings = array_merge(
705
+ get_option( 'boldgrid_settings' ),
706
+ \Boldgrid\Library\Library\Page\Connect::sanitizeSettings(
707
+ array(
708
+ 'autoupdate' => ! empty( $_POST['autoupdate'] ) ?
709
+ (array) $_POST['autoupdate'] : array(),
710
+ 'release_channel' => ! empty( $_POST['plugin_release_channel'] ) ?
711
+ sanitize_key( $_POST['plugin_release_channel'] ) : 'stable',
712
+ 'theme_release_channel' => ! empty( $_POST['theme_release_channel'] ) ?
713
+ sanitize_key( $_POST['theme_release_channel'] ) : 'stable',
714
+ )
715
+ )
716
+ );
717
+
718
+ // Cleanup old settings.
719
+ unset(
720
+ $settings['plugin_autoupdate'],
721
+ $settings['theme_autoupdate'],
722
+ $boldgrid_settings['plugin_autoupdate'],
723
+ $boldgrid_settings['theme_autoupdate']
724
+ );
725
+
726
+ $settings['updated'] = time();
727
 
728
  // If no errors, then save the settings.
729
  if ( ! $update_error ) {
 
730
  update_site_option( 'boldgrid_backup_settings', $settings );
731
+ update_option( 'boldgrid_settings', $boldgrid_settings );
732
  }
733
  }
734
 
756
  *
757
  * @since 1.5.3
758
  */
759
+ do_action( 'boldgrid_backup_settings_updated', $settings );
760
  }
761
 
762
  // Return success.
777
  *
778
  * @since 1.0
779
  *
780
+ * @see Boldgrid_Backup_Admin_Config::get_is_premium
781
+ * @see Boldgrid_Backup_Admin_Config::is_premium_active
782
  */
783
  public function page_backup_settings() {
784
+ $is_premium = $this->core->config->get_is_premium();
785
+ $is_premium_installed = $this->core->config->is_premium_installed;
786
+ $is_premium_active = $this->core->config->is_premium_active;
787
+
788
  add_thickbox();
789
  wp_enqueue_style( 'boldgrid-backup-admin-new-thickbox-style' );
 
790
  wp_enqueue_style( 'bglib-ui-css' );
791
  wp_enqueue_script( 'bglib-ui-js' );
792
  wp_enqueue_script( 'bglib-sticky' );
 
793
  wp_enqueue_script( 'bglib-license' );
794
 
795
  if ( ! $this->is_saving_settings ) {
801
  do_action(
802
  'boldgrid_backup_notice',
803
  sprintf(
804
+ // translators: 1: HTML anchor link open tag, 2: HTML anchor closing tag.
805
+ __(
806
+ 'Functionality test has failed. You can go to %1$sFunctionality Test%2$s to view a report.',
807
  'boldgrid-backup'
808
  ),
809
  '<a href="' . admin_url( 'admin.php?page=boldgrid-backup-test' ) . '">',
813
  );
814
  }
815
 
816
+ /*
817
+ * Display warning on resource usage and backups.
818
+ *
819
+ * As of 1.11.6, this notice is dismissable (and won't return).
820
+ */
821
+ $notice_id = 'bgbkup_uses_resources';
822
+ if ( ! Notice::isDismissed( $notice_id ) ) {
823
+ $message = '<p>' . esc_html__(
824
  'Warning: Making backups uses resources. When the system is backing up, it will slow down your site for visitors. Furthermore, when the database itself is being copied, your site must “pause” temporarily to preserve data integrity. For most sites, the pause is typically a few seconds and is not noticed by visitors. Large sites take longer though. Please keep the number of backups you have stored and how often you make those backups to a minimum.',
825
  'boldgrid-backup'
826
+ ) . '</p>';
827
+
828
+ Notice::show( $message, $notice_id );
829
+ }
830
 
831
  // Get BoldGrid reseller settings.
832
  $boldgrid_reseller = get_option( 'boldgrid_reseller' );
833
 
834
+ /*
835
+ * If not part of a reseller, then show the unofficial host notice.
836
+ *
837
+ * As of 1.11.6, this notice is dismissable (and won't return).
838
+ */
839
+ $notice_id = 'bgbkup_host_policy';
840
+ if ( ! Notice::isDismissed( $notice_id ) && empty( $boldgrid_reseller ) ) {
841
+ $message = '<p>' . esc_html__(
842
+ 'Please note that your web hosting provider may have a policy against these types of backups. Please verify with your provider or choose a BoldGrid Official Host.',
843
+ 'boldgrid-backup'
844
+ ) . '</p>';
845
+
846
+ Notice::show( $message, $notice_id );
847
  }
848
 
849
  // Check for settings update.
850
  if ( $this->is_saving_settings ) {
851
+ // The nonce is verified in the update_settings method.
 
 
852
  $this->update_settings();
853
  }
854
 
855
  // Enqueue CSS for the settings page.
856
+ wp_enqueue_style(
857
+ 'boldgrid-backup-admin-settings',
858
  plugin_dir_url( __FILE__ ) . 'css/boldgrid-backup-admin-settings.css', array(),
859
  BOLDGRID_BACKUP_VERSION, 'all'
860
  );
861
 
862
  // Enqueue the JS for the settings page.
863
+ wp_enqueue_script(
864
+ 'boldgrid-backup-admin-settings',
865
  plugin_dir_url( __FILE__ ) . 'js/boldgrid-backup-admin-settings.js',
866
  array( 'jquery' ),
867
  BOLDGRID_BACKUP_VERSION,
868
  false
869
  );
870
 
871
+ wp_enqueue_script(
872
+ 'boldgrid-backup-admin-settings-autoupdate',
873
+ plugin_dir_url( __FILE__ ) . 'js/boldgrid-backup-admin-settings-autoupdate.js',
874
+ array( 'jquery' ),
875
+ BOLDGRID_BACKUP_VERSION,
876
+ false
877
+ );
878
+
879
+ // Enqueue JS for the toggles on the auto-updates section.
880
+ wp_enqueue_script(
881
+ 'boldgrid-library-connect',
882
+ \Boldgrid\Library\Library\Configs::get( 'libraryUrl' ) . 'src/assets/js/connect.js',
883
+ array( 'jquery' ),
884
+ BOLDGRID_BACKUP_VERSION,
885
+ false
886
+ );
887
+
888
+ // Enqueue jquery-toggles JS.
889
+ wp_enqueue_script(
890
+ 'jquery-toggles',
891
+ \Boldgrid\Library\Library\Configs::get( 'libraryUrl' ) . 'build/toggles.min.js',
892
+ array( 'jquery' ),
893
+ BOLDGRID_BACKUP_VERSION,
894
+ true
895
+ );
896
+
897
+ // Enqueue jquery-toggles CSS.
898
+ wp_enqueue_style(
899
+ 'jquery-toggles-full',
900
+ \Boldgrid\Library\Library\Configs::get( 'libraryUrl' ) . 'build/toggles-full.css',
901
+ array(),
902
+ BOLDGRID_BACKUP_VERSION
903
+ );
904
+
905
  $this->core->folder_exclusion->enqueue_scripts();
906
  $this->core->db_omit->enqueue_scripts();
907
 
914
 
915
  $available_compressors = $this->core->compressors->get_available();
916
 
917
+ if ( ! $is_premium || ! $is_premium_installed || ! $is_premium_active ) {
918
+ $settings['encrypt_db'] = false;
919
+ }
920
+
921
  // Include the page template.
922
  include BOLDGRID_BACKUP_PATH . '/admin/partials/boldgrid-backup-admin-settings.php';
 
 
923
  }
924
 
925
  /**
927
  *
928
  * @since 1.5.2
929
  *
930
+ * @param array $settings Settings.
931
  * @return bool True on success.
932
  */
933
  public function save( $settings ) {
 
 
 
 
 
 
934
  return update_site_option( 'boldgrid_backup_settings', $settings );
935
  }
936
 
937
  /**
938
+ * Update CRON jobs.
939
  *
940
+ * @since 1.8.0
941
  *
942
+ * @param array $settings Settings.
943
+ * @return array
944
  */
945
+ public function update_cron( array $settings ) {
946
+ $settings['crons_added'] = false;
947
 
948
+ $scheduler = ! empty( $settings['scheduler'] ) ? $settings['scheduler'] : null;
 
 
 
949
 
950
+ if ( 'wp-cron' === $scheduler ) {
951
+ $settings['crons_added'] = $this->core->wp_cron->add_all_crons( $settings );
952
+ } elseif ( 'cron' === $scheduler ) {
953
+ $settings['crons_added'] = $this->core->cron->add_all_crons( $settings );
954
+ $settings['crontab_version'] = $this->core->cron->crontab_version;
955
+ $settings['cron_secret'] = $this->core->cron->get_cron_secret();
956
+ }
957
 
958
+ return $settings;
959
  }
960
  }
admin/class-boldgrid-backup-admin-support.php ADDED
@@ -0,0 +1,249 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File: class-boldgrid-backup-admin-support.php
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.7.0
7
+ *
8
+ * @package Boldgrid_Backup
9
+ * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
+ * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
+ */
14
+
15
+ /**
16
+ * Class: Boldgrid_Backup_Admin_Support
17
+ *
18
+ * @since 1.7.0
19
+ */
20
+ class Boldgrid_Backup_Admin_Support {
21
+ /**
22
+ * Minumum PHP supported version.
23
+ *
24
+ * @since 1.7.1
25
+ *
26
+ * @var string
27
+ */
28
+ const PHP_MIN_VER = '5.4.0';
29
+
30
+ /**
31
+ * The core class object.
32
+ *
33
+ * @since 1.10.1
34
+ * @access private
35
+ * @var Boldgrid_Backup_Admin_Core
36
+ */
37
+ private $core;
38
+
39
+ /**
40
+ * Constructor.
41
+ *
42
+ * @since 1.10.1
43
+ *
44
+ * @param Boldgrid_Backup_Admin_Core $core Core class object.
45
+ */
46
+ public function __construct( $core = null ) {
47
+ $this->core = $core;
48
+ }
49
+
50
+ /**
51
+ * Add an admin notice.
52
+ *
53
+ * This method use to be "deactivate". Users only have 1 chance to see the message we're showing
54
+ * if we deactivate the plugin. If we instead just show an admin message, the user has more than
55
+ * once chance to see the notice and take action to resolve the issue.
56
+ *
57
+ * @since 1.7.0
58
+ *
59
+ * @param string $error Error message.
60
+ */
61
+ public function add_admin_notice( $error ) {
62
+ add_action(
63
+ 'admin_notices', function () use ( $error ) {
64
+ $allowed_html = [
65
+ 'p' => [],
66
+ 'strong' => [],
67
+ 'br' => [],
68
+ 'em' => [],
69
+ 'pre' => [],
70
+ 'a' => [
71
+ 'href' => [],
72
+ 'target' => [],
73
+ ],
74
+ ];
75
+
76
+ $error = '<p>' . sprintf(
77
+ // translators: 1: HTML opening strong tags, 2: HTML closing strong tag, 3: Plugin title.
78
+ __( '%1$s%3$s%2$s is unable to load due to the following error:', 'boldgrid-backup' ),
79
+ '<strong>',
80
+ '</strong>',
81
+ BOLDGRID_BACKUP_TITLE
82
+ ) . '<br /><br />' . $error . '</p>';
83
+
84
+ // Inform the user how to get help.
85
+ $error .= '<p>' . sprintf(
86
+ // translators: 1 Plugin title, 2 opening anchor tag linking to plugin page, 3 url to plugin page, 4 closing anchor tag.
87
+ __( 'Please deactivate / reactivate Total Upkeep as this often resolves issues. If you are installing %1$s from .zip, ensure you downloaded it from %2$s%3$s%4$s. For additional help, please post a question in the %5$sWordPress Support Forums.%4$s', 'boldgrid-backup' ),
88
+ BOLDGRID_BACKUP_TITLE,
89
+ '<a href="https://wordpress.org/plugins/boldgrid-backup/" target="_blank">',
90
+ 'https://wordpress.org/plugins/boldgrid-backup/',
91
+ '</a>',
92
+ '<a href="https://wordpress.org/support/plugin/boldgrid-backup/#new-topic-0" target="_blank">'
93
+ ) . '</p>';
94
+
95
+ // Echo our admin notice. Hide the "plugin activated" notice.
96
+ echo '
97
+ <div class="notice notice-error is-dismissible">' . wp_kses( $error, $allowed_html ) . '</div>
98
+ <style type="text/css">
99
+ .updated.notice { display: none; }
100
+ </style>
101
+ ';
102
+ }
103
+ );
104
+ }
105
+
106
+ /**
107
+ * Determine whether or not composer has been setup.
108
+ *
109
+ * @since 1.7.0
110
+ *
111
+ * @return bool
112
+ */
113
+ public function has_composer_installed() {
114
+ $exists_composer = file_exists( BOLDGRID_BACKUP_PATH . '/composer.json' );
115
+ $exists_autoload = file_exists( BOLDGRID_BACKUP_PATH . '/vendor/autoload.php' );
116
+
117
+ return ! $exists_composer || $exists_autoload;
118
+ }
119
+
120
+ /**
121
+ * Verify compatible PHP version.
122
+ *
123
+ * @since 1.7.1
124
+ *
125
+ * @return bool
126
+ */
127
+ public function has_compatible_php() {
128
+ return version_compare( PHP_VERSION, self::PHP_MIN_VER, '>=' );
129
+ }
130
+
131
+ /**
132
+ * Verify appropriate library is available.
133
+ *
134
+ * This is a very basic test. It could be more exhaustive. However, a missing library is rare and
135
+ * exhaustive tests are not needed.
136
+ *
137
+ * @since 1.13.5
138
+ *
139
+ * @return bool
140
+ */
141
+ public function has_library() {
142
+ // This can be updated to the newest library classes to check for a more recent version.
143
+ return class_exists( 'Boldgrid\Library\Library\Usage\Notice' );
144
+ }
145
+
146
+ /**
147
+ * Whether or not this version of the Backup Plugin is compatible with the premium extension.
148
+ *
149
+ * @since 1.11.3
150
+ *
151
+ * @return bool
152
+ */
153
+ public function is_premium_compatible() {
154
+ return ! defined( 'BOLDGRID_BACKUP_MIN_VERSION_FOR_PREMIUM' ) ||
155
+ version_compare( BOLDGRID_BACKUP_VERSION, BOLDGRID_BACKUP_MIN_VERSION_FOR_PREMIUM, '>=' );
156
+ }
157
+
158
+ /**
159
+ * Do a basic test and ensure we have access to the library.
160
+ *
161
+ * In theory, we should never have an issue with the library loading. This method should never
162
+ * be needed, and any issues with the library should be troubleshooted and resolved. However,
163
+ * we cannot have a library issue cause a fatal error, hence this check.
164
+ *
165
+ * @since 1.13.5
166
+ *
167
+ * @return bool
168
+ */
169
+ public function run_library_tests() {
170
+ // Total Upkeep's library is only registered after activation, hence the is_active() check below.
171
+ if ( Boldgrid_Backup_Admin_Utility::is_active() && ! $this->has_library() ) {
172
+ $boldgrid_settings = get_option( 'boldgrid_settings', array() );
173
+
174
+ $this->add_admin_notice( sprintf(
175
+ // translators: 1 A list of library versions that are registered. It will be within a <pre> tag.
176
+ __(
177
+ 'One or more library files are missing. Registered libraries: %1$s',
178
+ 'boldgrid-backup'
179
+ ),
180
+ ! empty( $boldgrid_settings['library'] ) ? '<pre>' . print_r( $boldgrid_settings['library'], 1 ) . '</pre>' : __( 'None', 'boldgrid-backup' ) // phpcs:ignore
181
+ ));
182
+
183
+ return false;
184
+ }
185
+
186
+ return true;
187
+ }
188
+
189
+ /**
190
+ * Run tests.
191
+ *
192
+ * These tests are triggered by the main class-boldgrid-backup.php file. If these tests fail, the
193
+ * rest of the plugin will not load.
194
+ *
195
+ * @since 1.7.1
196
+ *
197
+ * @see has_compatible_php()
198
+ * @see Boldgrid_Backup_Admin_Support::has_composer_installed()
199
+ * @see Boldgrid_Backup_Admin_Support::deactivate()
200
+ *
201
+ * @return bool
202
+ */
203
+ public function run_tests() {
204
+ // Utility method required in this method.
205
+ if ( ! class_exists( 'Boldgrid_Backup_Admin_Utility' ) ) {
206
+ require_once BOLDGRID_BACKUP_PATH . '/admin/class-boldgrid-backup-admin-utility.php';
207
+ }
208
+
209
+ if ( ! $this->has_compatible_php() ) {
210
+ $this->add_admin_notice(
211
+ sprintf(
212
+ // Translators: 1: Current PHP version, 2: Minimum supported PHP version.
213
+ __(
214
+ 'Your PHP version (%1$s) is not supported. Please upgrade PHP to %2$s or higher, or contact your host for further assistance.',
215
+ 'boldgrid-backup'
216
+ ),
217
+ PHP_VERSION,
218
+ self::PHP_MIN_VER
219
+ )
220
+ );
221
+
222
+ return false;
223
+ }
224
+
225
+ if ( ! $this->has_composer_installed() ) {
226
+ $this->add_admin_notice(
227
+ __(
228
+ 'The vendor folder is missing. Please run "composer install", or contact your host for further assistance.',
229
+ 'boldgrid-backup'
230
+ )
231
+ );
232
+
233
+ return false;
234
+ }
235
+
236
+ return true;
237
+ }
238
+
239
+ /**
240
+ * Render the support page.
241
+ *
242
+ * @since 1.10.1
243
+ */
244
+ public function page() {
245
+ wp_enqueue_style( 'bglib-ui-css' );
246
+
247
+ include BOLDGRID_BACKUP_PATH . '/admin/partials/boldgrid-backup-admin-support.php';
248
+ }
249
+ }
admin/class-boldgrid-backup-admin-test.php CHANGED
@@ -1,31 +1,31 @@
1
  <?php
2
  /**
3
- * The admin-specific test functionality of the plugin
4
  *
5
- * @link http://www.boldgrid.com
6
  * @since 1.0
7
  *
8
- * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
- * @copyright BoldGrid.com
11
- * @version $Id$
12
- * @author BoldGrid.com <wpb@boldgrid.com>
13
  */
14
 
 
 
15
  /**
16
- * BoldGrid Backup admin test class.
17
  *
18
  * @since 1.0
19
  */
20
  class Boldgrid_Backup_Admin_Test {
21
-
22
  /**
23
  * Base test filename.
24
  *
25
  * When we create test files, this is the prefix for all of them.
26
  *
27
  * @since 1.5.1
28
- * @access public
29
  * @var string
30
  */
31
  public $test_prefix = 'boldgrid-backup-test-file-';
@@ -93,15 +93,6 @@ class Boldgrid_Backup_Admin_Test {
93
  */
94
  private $is_php_safemode = null;
95
 
96
- /**
97
- * Functionality tests completed?
98
- *
99
- * @since 1.0
100
- * @access private
101
- * @var bool
102
- */
103
- private $functionality_tested = false;
104
-
105
  /**
106
  * Is functional?
107
  *
@@ -117,7 +108,6 @@ class Boldgrid_Backup_Admin_Test {
117
  * Default value is 300 seconds (5 minutes).
118
  *
119
  * @since 1.3.1
120
- * @access public
121
  * @var int
122
  */
123
  public $transient_time = 300;
@@ -134,12 +124,44 @@ class Boldgrid_Backup_Admin_Test {
134
  $this->core = $core;
135
  }
136
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
137
  /**
138
  * Wrapper for wp_filesystem exists.
139
  *
140
  * @since 1.5.1
141
  *
142
- * @param string $path
143
  * @return bool
144
  */
145
  public function exists( $path ) {
@@ -163,22 +185,26 @@ class Boldgrid_Backup_Admin_Test {
163
  *
164
  * @since 1.5.1
165
  *
166
- * @param string $dir
167
  * @return array
168
  */
169
  public function extensive_dir_test( $dir ) {
170
- $dir = Boldgrid_Backup_Admin_Utility::trailingslashit( $dir );
171
  $random_filename = $dir . $this->test_prefix . mt_rand();
172
- $txt_filename = $random_filename . '.txt';
173
- $info_filename = $random_filename . '.rtf';
174
- $str = __( 'This is a test file from BoldGrid Backup. You can delete this file.', 'boldgrid-backup' );
 
 
 
 
175
 
176
  $data['exists'] = $this->core->wp_filesystem->exists( $dir );
177
- $data['read'] = $this->core->wp_filesystem->is_readable( $dir );
178
- $data['write'] = $this->core->wp_filesystem->is_writable( $dir );
179
 
180
  // Can we get a directory listing?
181
- $dirlist = $this->core->wp_filesystem->dirlist( $dir );
182
  $data['dirlist'] = is_array( $dirlist );
183
 
184
  // Determine if we have permission to rename a file.
@@ -205,8 +231,8 @@ class Boldgrid_Backup_Admin_Test {
205
  *
206
  * @since 1.5.2
207
  *
208
- * @param string $folder_name
209
- * @param string $starting_dir
210
  * @return bool True if folder name found.
211
  */
212
  public function find_folder( $folder_name, $starting_dir = ABSPATH ) {
@@ -244,7 +270,7 @@ class Boldgrid_Backup_Admin_Test {
244
  *
245
  * @since 1.5.1
246
  *
247
- * @param string $dir
248
  * @return bool
249
  */
250
  public function delete_test_files( $dir ) {
@@ -260,7 +286,7 @@ class Boldgrid_Backup_Admin_Test {
260
  $filename = $file['name'];
261
 
262
  if ( 0 === strpos( $filename, $this->test_prefix ) ) {
263
- $this->core->wp_filesystem->delete( $dir . $filename );
264
  }
265
  }
266
 
@@ -292,7 +318,7 @@ class Boldgrid_Backup_Admin_Test {
292
  *
293
  * @since 1.5.1
294
  *
295
- * @param $dir string
296
  * @return bool
297
  */
298
  public function is_writable( $dir ) {
@@ -346,9 +372,14 @@ class Boldgrid_Backup_Admin_Test {
346
  return true;
347
  }
348
 
349
- $folders_found = __( 'The following node_modules folder was found in your account:', 'boldgrid-backup' );
350
  $possible_issues = __( 'Due to possible issues node_modules folders can cause when calculating disk space, your WordPress directory size was not calculated.', 'boldgrid-backup' );
351
- $ignore_warning = __( 'To ignore this warning and try again, please <a href="%1$s">click here</a>', 'boldgrid-backup' );
 
 
 
 
 
352
 
353
  $warning = sprintf(
354
  '<strong>%1$s</strong><br />
@@ -385,14 +416,14 @@ class Boldgrid_Backup_Admin_Test {
385
  return $this->is_crontab_available;
386
  }
387
 
388
- $test_entry = '# BoldGrid Backup Test Entry ' . time() . ' (You can delete this line).';
389
 
390
  /*
391
  * To determine if crontab is available, we will BOTH write and remove
392
  * a test entry from the crontab.
393
  */
394
- $entry_added = $this->core->cron->update_cron( $test_entry );
395
- $entry_deleted = $this->core->cron->entry_delete( $test_entry );
396
  $this->is_crontab_available = $entry_added && $entry_deleted;
397
 
398
  return $this->is_crontab_available;
@@ -450,6 +481,19 @@ class Boldgrid_Backup_Admin_Test {
450
  return $this->is_php_safemode;
451
  }
452
 
 
 
 
 
 
 
 
 
 
 
 
 
 
453
  /**
454
  * Determine if this is a plesk environment.
455
  *
@@ -467,69 +511,54 @@ class Boldgrid_Backup_Admin_Test {
467
  return false;
468
  }
469
 
 
 
 
 
 
 
 
 
 
 
 
 
 
470
  /**
471
  * Perform functionality tests.
472
  *
473
  * @since 1.0
474
  *
475
- * @global WP_Filesystem $wp_filesystem The WordPress Filesystem API global object.
476
- *
477
  * @return bool
478
  */
479
  public function run_functionality_tests() {
480
- // If functionality tests were already performed, then just return status.
481
- if ( $this->functionality_tested && null !== $this->is_functional ) {
482
  return $this->is_functional;
483
  }
484
 
485
- // Connect to the WordPress Filesystem API.
486
- global $wp_filesystem;
487
 
488
- // If not writable, then mark as not functional.
489
- if ( ! $this->get_is_abspath_writable() ) {
490
  $this->is_functional = false;
491
- }
492
-
493
- // Configure the backup directory path, or mark as not functional.
494
- if ( ! $this->core->backup_dir->get() ) {
495
  $this->is_functional = false;
496
- }
497
-
498
- // Get available compressors.
499
- $available_compressors = $this->core->config->get_available_compressors();
500
-
501
- // Test for available compressors, and add them to the array, or mark as not functional.
502
- if ( empty( $available_compressors ) ) {
503
  $this->is_functional = false;
504
- }
505
-
506
- if ( 'php_zip' === $this->core->compressors->get() ) {
507
- $php_zip = new Boldgrid_Backup_Admin_Compressor_Php_Zip( $this->core );
508
- if ( ! $php_zip->test( false ) ) {
509
- $this->is_functional = false;
510
- }
511
- }
512
-
513
- if ( 'pcl_zip' === $this->core->compressors->get() ) {
514
- $pcl_zip = new Boldgrid_Backup_Admin_Compressor_Pcl_Zip( $this->core );
515
- if ( ! $pcl_zip->test( false ) ) {
516
- $this->is_functional = false;
517
- }
518
- }
519
-
520
- // Test for PHP safe mode.
521
- if ( $this->is_php_safemode() ) {
522
  $this->is_functional = false;
523
- }
524
-
525
- // Save result, if not previously saved.
526
- if ( null === $this->is_functional ) {
 
 
 
 
 
527
  $this->is_functional = true;
528
  }
529
 
530
- // Mark as completed.
531
- $this->functionality_tested = true;
532
-
533
  return $this->is_functional;
534
  }
535
 
@@ -563,8 +592,8 @@ class Boldgrid_Backup_Admin_Test {
563
 
564
  // Get filesystem disk space information.
565
  $disk_total_space = disk_total_space( $home_dir );
566
- $disk_free_space = disk_free_space( $home_dir );
567
- $disk_used_space = $disk_total_space - $disk_free_space;
568
 
569
  // Initialize $wp_root_size.
570
  $wp_root_size = false;
@@ -595,12 +624,14 @@ class Boldgrid_Backup_Admin_Test {
595
  */
596
  private function get_wp_size() {
597
  // Save time, use transients.
598
- if ( false !== ( $transient = get_transient( 'boldgrid_backup_wp_size' ) ) ) {
 
 
599
  return $transient;
600
  }
601
 
602
  // Avoid timeout caused when node_modules exist. Return 0 bytes.
603
- if ( empty( $_GET['skip_node_modules'] ) ) {
604
  $node_modules_found = $this->node_modules_warning();
605
  if ( true === $node_modules_found ) {
606
  return 0;
@@ -624,6 +655,65 @@ class Boldgrid_Backup_Admin_Test {
624
  return $size;
625
  }
626
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
627
  /**
628
  * Get database size.
629
  *
@@ -635,7 +725,9 @@ class Boldgrid_Backup_Admin_Test {
635
  */
636
  public function get_database_size() {
637
  // Save some time, get transient.
638
- if ( false !== ( $transient = get_transient( 'boldgrid_backup_db_size' ) ) ) {
 
 
639
  return $transient;
640
  }
641
 
@@ -643,9 +735,11 @@ class Boldgrid_Backup_Admin_Test {
643
  global $wpdb;
644
 
645
  // Build query.
646
- $query = $wpdb->prepare(
647
- 'SELECT SUM(`data_length` + `index_length`) FROM `information_schema`.`TABLES` WHERE `TABLE_SCHEMA`=%s AND `TABLE_NAME` LIKE %s GROUP BY `TABLE_SCHEMA`;',
648
- DB_NAME, $wpdb->get_blog_prefix( is_multisite() ) . '%'
 
 
649
  );
650
 
651
  // Check query.
@@ -654,7 +748,7 @@ class Boldgrid_Backup_Admin_Test {
654
  }
655
 
656
  // Get the result.
657
- $result = $wpdb->get_row( $query, ARRAY_N );
658
 
659
  // If there was an error or nothing returned, then fail.
660
  if ( empty( $result ) ) {
@@ -722,8 +816,66 @@ class Boldgrid_Backup_Admin_Test {
722
  * @return bool
723
  */
724
  public function is_iis() {
725
- return $this->is_windows() &&
726
  ! empty( $_SERVER['SERVER_SOFTWARE'] ) &&
727
  false !== strpos( $_SERVER['SERVER_SOFTWARE'], 'IIS' );
728
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
729
  }
1
  <?php
2
  /**
3
+ * File: class-boldgrid-backup-admin-test.php
4
  *
5
+ * @link https://www.boldgrid.com
6
  * @since 1.0
7
  *
8
+ * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
+ * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
  */
14
 
15
+ // phpcs:disable WordPress.VIP
16
+
17
  /**
18
+ * Class: Boldgrid_Backup_Admin_Test
19
  *
20
  * @since 1.0
21
  */
22
  class Boldgrid_Backup_Admin_Test {
 
23
  /**
24
  * Base test filename.
25
  *
26
  * When we create test files, this is the prefix for all of them.
27
  *
28
  * @since 1.5.1
 
29
  * @var string
30
  */
31
  public $test_prefix = 'boldgrid-backup-test-file-';
93
  */
94
  private $is_php_safemode = null;
95
 
 
 
 
 
 
 
 
 
 
96
  /**
97
  * Is functional?
98
  *
108
  * Default value is 300 seconds (5 minutes).
109
  *
110
  * @since 1.3.1
 
111
  * @var int
112
  */
113
  public $transient_time = 300;
124
  $this->core = $core;
125
  }
126
 
127
+ /**
128
+ * Find out if we can write a file with exec, and then modify it with wp_filesystem.
129
+ *
130
+ * @since 1.6.5
131
+ *
132
+ * @param string $dir The directory to test.
133
+ * @return bool
134
+ */
135
+ public function can_exec_write( $dir ) {
136
+ if ( empty( $dir ) ) {
137
+ return false;
138
+ }
139
+
140
+ $file = trailingslashit( $dir ) . 'safe-to-delete.txt';
141
+ $txt = 'This file is safe to delete.';
142
+
143
+ // Write the file with an exec method.
144
+ $command = sprintf( 'echo "%1$s" > %2$s', $txt, $file );
145
+ $this->core->execute_command( $command, $success );
146
+ if ( ! $success ) {
147
+ return false;
148
+ }
149
+
150
+ // Read the file with wp_filesystem.
151
+ if ( trim( $this->core->wp_filesystem->get_contents( $file ) ) !== $txt ) {
152
+ return false;
153
+ }
154
+
155
+ // Delete the file with wp_filesystem.
156
+ return $this->core->wp_filesystem->delete( $file );
157
+ }
158
+
159
  /**
160
  * Wrapper for wp_filesystem exists.
161
  *
162
  * @since 1.5.1
163
  *
164
+ * @param string $path File or directory path.
165
  * @return bool
166
  */
167
  public function exists( $path ) {
185
  *
186
  * @since 1.5.1
187
  *
188
+ * @param string $dir Dircetory path.
189
  * @return array
190
  */
191
  public function extensive_dir_test( $dir ) {
192
+ $dir = Boldgrid_Backup_Admin_Utility::trailingslashit( $dir );
193
  $random_filename = $dir . $this->test_prefix . mt_rand();
194
+ $txt_filename = $random_filename . '.txt';
195
+ $info_filename = $random_filename . '.rtf';
196
+ $str = sprintf(
197
+ // translators: 1: Plugin title.
198
+ __( 'This is a test file from %1$s. You can delete this file.', 'boldgrid-backup' ),
199
+ BOLDGRID_BACKUP_TITLE
200
+ );
201
 
202
  $data['exists'] = $this->core->wp_filesystem->exists( $dir );
203
+ $data['read'] = $this->core->wp_filesystem->is_readable( $dir );
204
+ $data['write'] = $this->core->wp_filesystem->is_writable( $dir );
205
 
206
  // Can we get a directory listing?
207
+ $dirlist = $this->core->wp_filesystem->dirlist( $dir );
208
  $data['dirlist'] = is_array( $dirlist );
209
 
210
  // Determine if we have permission to rename a file.
231
  *
232
  * @since 1.5.2
233
  *
234
+ * @param string $folder_name Directory folder name.
235
+ * @param string $starting_dir Start director path.
236
  * @return bool True if folder name found.
237
  */
238
  public function find_folder( $folder_name, $starting_dir = ABSPATH ) {
270
  *
271
  * @since 1.5.1
272
  *
273
+ * @param string $dir Directory path.
274
  * @return bool
275
  */
276
  public function delete_test_files( $dir ) {
286
  $filename = $file['name'];
287
 
288
  if ( 0 === strpos( $filename, $this->test_prefix ) ) {
289
+ $this->core->wp_filesystem->delete( $dir . $filename, true );
290
  }
291
  }
292
 
318
  *
319
  * @since 1.5.1
320
  *
321
+ * @param string $dir Directory path.
322
  * @return bool
323
  */
324
  public function is_writable( $dir ) {
372
  return true;
373
  }
374
 
375
+ $folders_found = __( 'The following node_modules folder was found in your account:', 'boldgrid-backup' );
376
  $possible_issues = __( 'Due to possible issues node_modules folders can cause when calculating disk space, your WordPress directory size was not calculated.', 'boldgrid-backup' );
377
+
378
+ // translators: 1: Link.
379
+ $ignore_warning = __(
380
+ 'To ignore this warning and try again, please <a href="%1$s">click here</a>',
381
+ 'boldgrid-backup'
382
+ );
383
 
384
  $warning = sprintf(
385
  '<strong>%1$s</strong><br />
416
  return $this->is_crontab_available;
417
  }
418
 
419
+ $test_entry = '# ' . BOLDGRID_BACKUP_TITLE . ' Test Entry ' . time() . ' (You can delete this line).';
420
 
421
  /*
422
  * To determine if crontab is available, we will BOTH write and remove
423
  * a test entry from the crontab.
424
  */
425
+ $entry_added = $this->core->cron->update_cron( $test_entry );
426
+ $entry_deleted = $this->core->cron->entry_delete( $test_entry );
427
  $this->is_crontab_available = $entry_added && $entry_deleted;
428
 
429
  return $this->is_crontab_available;
481
  return $this->is_php_safemode;
482
  }
483
 
484
+ /**
485
+ * Determine whether or not php_zip is suppored.
486
+ *
487
+ * @since 1.7.0
488
+ *
489
+ * @return bool
490
+ */
491
+ public function is_php_zip_supported() {
492
+ $php_zip = new Boldgrid_Backup_Admin_Compressor_Php_Zip( $this->core );
493
+
494
+ return $php_zip->test( false );
495
+ }
496
+
497
  /**
498
  * Determine if this is a plesk environment.
499
  *
511
  return false;
512
  }
513
 
514
+ /**
515
+ * Determine whether or not system_zip is suppored.
516
+ *
517
+ * @since 1.13.0
518
+ *
519
+ * @return bool
520
+ */
521
+ public function is_system_zip_supported() {
522
+ $system_zip_test = new Boldgrid_Backup_Admin_Compressor_System_Zip_Test( $this->core );
523
+
524
+ return $system_zip_test->run();
525
+ }
526
+
527
  /**
528
  * Perform functionality tests.
529
  *
530
  * @since 1.0
531
  *
 
 
532
  * @return bool
533
  */
534
  public function run_functionality_tests() {
535
+ if ( null !== $this->is_functional ) {
 
536
  return $this->is_functional;
537
  }
538
 
539
+ $available_compressors = $this->core->config->get_available_compressors();
540
+ $compressor = $this->core->compressors->get();
541
 
542
+ if ( ! self::is_filesystem_supported() ) {
 
543
  $this->is_functional = false;
544
+ } elseif ( ! $this->get_is_abspath_writable() ) {
 
 
 
545
  $this->is_functional = false;
546
+ } elseif ( ! $this->core->backup_dir->get() ) {
 
 
 
 
 
 
547
  $this->is_functional = false;
548
+ } elseif ( empty( $available_compressors ) ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
549
  $this->is_functional = false;
550
+ } elseif ( 'php_zip' === $compressor && ! $this->is_php_zip_supported() ) {
551
+ $this->is_functional = false;
552
+ } elseif ( 'pcl_zip' === $compressor && ! $this->is_pcl_zip_supported() ) {
553
+ $this->is_functional = false;
554
+ } elseif ( 'system_zip' === $compressor && ! $this->is_system_zip_supported() ) {
555
+ $this->is_functional = false;
556
+ } elseif ( $this->is_php_safemode() ) {
557
+ $this->is_functional = false;
558
+ } else {
559
  $this->is_functional = true;
560
  }
561
 
 
 
 
562
  return $this->is_functional;
563
  }
564
 
592
 
593
  // Get filesystem disk space information.
594
  $disk_total_space = disk_total_space( $home_dir );
595
+ $disk_free_space = disk_free_space( $home_dir );
596
+ $disk_used_space = $disk_total_space - $disk_free_space;
597
 
598
  // Initialize $wp_root_size.
599
  $wp_root_size = false;
624
  */
625
  private function get_wp_size() {
626
  // Save time, use transients.
627
+ $transient = get_transient( 'boldgrid_backup_wp_size' );
628
+
629
+ if ( false !== $transient ) {
630
  return $transient;
631
  }
632
 
633
  // Avoid timeout caused when node_modules exist. Return 0 bytes.
634
+ if ( empty( $_GET['skip_node_modules'] ) ) { // phpcs:ignore WordPress.CSRF.NonceVerification.NoNonceVerification
635
  $node_modules_found = $this->node_modules_warning();
636
  if ( true === $node_modules_found ) {
637
  return 0;
655
  return $size;
656
  }
657
 
658
+ /**
659
+ * Check for support when php is ran from the CLI.
660
+ *
661
+ * If running a PHP script from CLI, it's possible that a different php.ini file will be used than
662
+ * if a server (nginx or apache) runs it.
663
+ *
664
+ * @since 1.6.2
665
+ *
666
+ * @return array
667
+ */
668
+ public function get_cli_support() {
669
+ $default = array(
670
+ 'has_curl_ssl' => false,
671
+ 'has_url_fopen' => false,
672
+ );
673
+
674
+ // Set a file path for the cli-support script output.
675
+ $filepath = wp_normalize_path( $this->core->backup_dir->get() . '/cli-support.txt' );
676
+
677
+ // Configure an array of commands to run.
678
+ $cmds = array(
679
+ 'php -qf ' . trailingslashit( BOLDGRID_BACKUP_PATH ) . 'cron/cli-support.php',
680
+ );
681
+
682
+ if ( ! $this->is_windows() && $this->core->execute_command( 'env' ) ) {
683
+ // Some environments may run PHP in CGI mode; try to force CLI, by preferencing paths.
684
+ $cmds[] = 'env PATH=/usr/local/bin:/usr/bin:/bin ' . $cmds[0];
685
+
686
+ if ( $this->is_ea4_cli() ) {
687
+ // If is a cPanel EA4 server with php-cli, then try using env first.
688
+ sort( $cmds );
689
+ }
690
+ }
691
+
692
+ // Find a command that gives us an array.
693
+ foreach ( $cmds as $cmd ) {
694
+ $this->core->execute_command( $cmd, $null, $null, $filepath );
695
+
696
+ // Our command may have resulted in unexpected output. Look for a json string.
697
+ preg_match( '/{.*}/', $this->core->wp_filesystem->get_contents( $filepath ), $matches );
698
+
699
+ $result = is_array( $matches ) && isset( $matches[0] ) ? json_decode( $matches[0], true ) : null;
700
+
701
+ $this->core->wp_filesystem->delete( $filepath );
702
+
703
+ if ( ! is_array( $result ) ) {
704
+ continue;
705
+ }
706
+
707
+ break;
708
+ }
709
+
710
+ $result = is_array( $result ) ? wp_parse_args( $result, $default ) : $default;
711
+
712
+ $result['can_remote_get'] = $result['has_curl_ssl'] || $result['has_url_fopen'];
713
+
714
+ return $result;
715
+ }
716
+
717
  /**
718
  * Get database size.
719
  *
725
  */
726
  public function get_database_size() {
727
  // Save some time, get transient.
728
+ $transient = get_transient( 'boldgrid_backup_db_size' );
729
+
730
+ if ( false !== $transient ) {
731
  return $transient;
732
  }
733
 
735
  global $wpdb;
736
 
737
  // Build query.
738
+ $query = sprintf(
739
+ 'SELECT SUM(`data_length` + `index_length`) FROM `information_schema`.`TABLES` WHERE `TABLE_SCHEMA`=' .
740
+ "'%s'" . ' AND `TABLE_NAME` LIKE ' . "'%s'" . ' GROUP BY `TABLE_SCHEMA`;',
741
+ DB_NAME,
742
+ $wpdb->get_blog_prefix( is_multisite() ) . '%'
743
  );
744
 
745
  // Check query.
748
  }
749
 
750
  // Get the result.
751
+ $result = $wpdb->get_row( $query, ARRAY_N ); // phpcs:ignore WordPress.WP.PreparedSQL.NotPrepared
752
 
753
  // If there was an error or nothing returned, then fail.
754
  if ( empty( $result ) ) {
816
  * @return bool
817
  */
818
  public function is_iis() {
819
+ return $this->is_windows() &&
820
  ! empty( $_SERVER['SERVER_SOFTWARE'] ) &&
821
  false !== strpos( $_SERVER['SERVER_SOFTWARE'], 'IIS' );
822
  }
823
+
824
+ /**
825
+ * Determine whether pcl_zip is supported.
826
+ *
827
+ * @since 1.7.0
828
+ *
829
+ * @return bool
830
+ */
831
+ public function is_pcl_zip_supported() {
832
+ $pcl_zip = new Boldgrid_Backup_Admin_Compressor_Pcl_Zip( $this->core );
833
+
834
+ return $pcl_zip->test( false );
835
+ }
836
+
837
+ /**
838
+ * Determine if this server has cPanel EasyApache 4 with php-cli installed.
839
+ *
840
+ * @since 1.6.3
841
+ *
842
+ * @link https://developer.wordpress.org/reference/classes/wp_filesystem_direct/
843
+ *
844
+ * @return bool
845
+ */
846
+ public function is_ea4_cli() {
847
+ $is_ea4 = $this->core->wp_filesystem->exists( '/etc/cpanel/ea4/is_ea4' ) ||
848
+ $this->core->wp_filesystem->is_dir( '/etc/cpanel/ea4' );
849
+
850
+ $has_php_cli = $this->core->wp_filesystem->exists( '/usr/local/bin/php' );
851
+
852
+ return $is_ea4 || $has_php_cli;
853
+ }
854
+
855
+ /**
856
+ * Determine whether or not the current filesystem is supported.
857
+ *
858
+ * @since 1.7.0
859
+ *
860
+ * @global object $wp_filesystem
861
+ *
862
+ * @return boolean
863
+ */
864
+ public static function is_filesystem_supported() {
865
+ global $wp_filesystem;
866
+
867
+ $supported = true;
868
+
869
+ // Ensure that the WP Filesystem API is loaded.
870
+ if ( empty( $wp_filesystem ) ) {
871
+ require_once ABSPATH . '/wp-admin/includes/file.php';
872
+ WP_Filesystem();
873
+ }
874
+
875
+ if ( 'direct' !== get_filesystem_method() ) {
876
+ $supported = false;
877
+ }
878
+
879
+ return $supported;
880
+ }
881
  }
admin/class-boldgrid-backup-admin-time.php CHANGED
@@ -1,24 +1,23 @@
1
  <?php
2
  /**
3
- * Time class.
4
  *
5
- * @link http://www.boldgrid.com
6
  * @since 1.6.0
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
- * @copyright BoldGrid.com
11
  * @version $Id$
12
- * @author BoldGrid.com <wpb@boldgrid.com>
13
  */
14
 
15
  /**
16
- * BoldGrid Backup Admin Time Class.
17
  *
18
  * @since 1.6.0
19
  */
20
  class Boldgrid_Backup_Admin_Time {
21
-
22
  /**
23
  * The core class object.
24
  *
@@ -35,7 +34,7 @@ class Boldgrid_Backup_Admin_Time {
35
  * @access public
36
  * @var int
37
  */
38
- public $utc_time;
39
 
40
  /**
41
  * Local time (local to a user).
@@ -75,6 +74,19 @@ class Boldgrid_Backup_Admin_Time {
75
  $this->core = $core;
76
  }
77
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
  /**
79
  * Get a server's UTC offset.
80
  *
@@ -98,7 +110,6 @@ class Boldgrid_Backup_Admin_Time {
98
  * @return mixed DateTimeZone object on success, false on failure.
99
  */
100
  public function get_server_timezone() {
101
-
102
  /*
103
  * Determine how we are going to get the server's timezone.
104
  *
@@ -123,8 +134,8 @@ class Boldgrid_Backup_Admin_Time {
123
  * ------------- --------------
124
  * DateTimeZone Object DateTimeZone Object
125
  * ( (
126
- * ) [timezone_type] => 2
127
- * [timezone] => EDT
128
  * )
129
  */
130
  $timezone = new DateTimeZone( 'EDT' );
@@ -153,12 +164,11 @@ class Boldgrid_Backup_Admin_Time {
153
  *
154
  * @since 1.6.0
155
  *
156
- * @param array $settings
157
- * @param array $tz_info
158
  * @return DateTime
159
  */
160
  public function get_settings_date( $settings = array(), $tz_info = array() ) {
161
-
162
  // Abort right away if bad data sent in.
163
  if ( ! is_array( $settings ) || ! is_array( $tz_info ) ) {
164
  return false;
@@ -167,7 +177,7 @@ class Boldgrid_Backup_Admin_Time {
167
  $settings = empty( $settings ) ? $this->core->settings->get_settings() : $settings;
168
 
169
  $tz_info = empty( $tz_info ) ? $this->get_timezone_info() : $tz_info;
170
- $is_utc = ! empty( $tz_info['abbr'] ) && 'UTC' === substr( $tz_info['abbr'], 0, 3 );
171
 
172
  $time_string = $settings['schedule']['tod_h'] . ':' . $settings['schedule']['tod_m'] . ' ' . $settings['schedule']['tod_a'];
173
 
@@ -234,7 +244,7 @@ class Boldgrid_Backup_Admin_Time {
234
  *
235
  * @since 1.6.0
236
  *
237
- * @param string $format
238
  * @return string
239
  */
240
  public function get_span( $format = 'M j, Y h:i a' ) {
@@ -298,7 +308,7 @@ class Boldgrid_Backup_Admin_Time {
298
  * @return array
299
  */
300
  public function get_timezone_info() {
301
- $tz_string = get_option( 'timezone_string' );
302
  $timezone_info = array();
303
 
304
  if ( $tz_string ) {
@@ -309,9 +319,9 @@ class Boldgrid_Backup_Admin_Time {
309
  }
310
 
311
  if ( $tz ) {
312
- $now = new DateTime( 'now', $tz );
313
- $formatted_gmt_offset = sprintf( 'UTC%s', $this->format_gmt_offset( $tz->getOffset( $now ) / 3600 ) );
314
- $tz_name = str_replace( '_', ' ', $tz->getName() );
315
  $timezone_info['abbr'] = $now->format( 'T' );
316
 
317
  // This set of code is not in core.
@@ -330,9 +340,11 @@ class Boldgrid_Backup_Admin_Time {
330
  $timezone_info['gmt_offset'] = $gmt_offset;
331
  }
332
 
333
- // Not sure why WordPress is doing this. If it is -4.5, show me -4.5 and not -4.
334
- // $formatted_gmt_offset = $this->format_gmt_offset( intval( $gmt_offset ) );
335
- $formatted_gmt_offset = $gmt_offset;
 
 
336
  $timezone_info['abbr'] = sprintf( 'UTC%s', $formatted_gmt_offset );
337
 
338
  /* translators: %s: UTC offset */
@@ -341,11 +353,11 @@ class Boldgrid_Backup_Admin_Time {
341
 
342
  // This set of code is not in core.
343
  $timezone_info['markup_timezone'] = sprintf( '<span title="%1$s">%2$s</span>', esc_attr( $timezone_info['description'] ), $timezone_info['abbr'] );
344
- $timezone_info['markup_change'] = sprintf(
345
  '<a href="%1$s" title="%3$s">%2$s</a>',
346
  admin_url( 'options-general.php' ),
347
  __( 'Change timezone', 'boldgrid-backup' ),
348
- esc_attr( __( 'WordPress timezone settings can be adjusted within Settings &raquo; General', 'boldgrid-backup' ) )
349
  );
350
 
351
  return $timezone_info;
@@ -357,7 +369,7 @@ class Boldgrid_Backup_Admin_Time {
357
  * @since 1.6.0
358
  *
359
  * @param int $time In seconds.
360
- * @param string $type The type of type ( utc, local, -5)
361
  */
362
  public function init( $time, $type = 'utc' ) {
363
  if ( empty( $time ) ) {
@@ -365,7 +377,7 @@ class Boldgrid_Backup_Admin_Time {
365
  return;
366
  }
367
 
368
- $gmt_offset = get_option( 'gmt_offset' );
369
  $valid_gmt_offset = ! empty( $gmt_offset ) || is_numeric( $gmt_offset );
370
 
371
  $this->local_timezone = 'UTC';
@@ -392,7 +404,7 @@ class Boldgrid_Backup_Admin_Time {
392
 
393
  // Once we have the UTC time (above), we can calculate the user's local time.
394
  if ( $valid_gmt_offset ) {
395
- $this->local_time = $this->utc_time + ( $gmt_offset * HOUR_IN_SECONDS );
396
  $this->local_timezone .= ' ' . $gmt_offset;
397
  } else {
398
  $this->local_time = $this->utc_time;
@@ -405,8 +417,8 @@ class Boldgrid_Backup_Admin_Time {
405
  * @since 1.6.0
406
  */
407
  public function reset() {
408
- $this->local_time = null;
409
  $this->local_timezone = null;
410
- $this->utc_time = null;
411
  }
412
  }
1
  <?php
2
  /**
3
+ * File :class-boldgrid-backup-admin-time.php
4
  *
5
+ * @link https://www.boldgrid.com
6
  * @since 1.6.0
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
  * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
  */
14
 
15
  /**
16
+ * Class: Boldgrid_Backup_Admin_Time
17
  *
18
  * @since 1.6.0
19
  */
20
  class Boldgrid_Backup_Admin_Time {
 
21
  /**
22
  * The core class object.
23
  *
34
  * @access public
35
  * @var int
36
  */
37
+ public $utc_time;
38
 
39
  /**
40
  * Local time (local to a user).
74
  $this->core = $core;
75
  }
76
 
77
+ /**
78
+ * Get the server's current date.
79
+ *
80
+ * @since 1.6.5
81
+ *
82
+ * @return string
83
+ */
84
+ public function get_server_date() {
85
+ $date = $this->core->execute_command( 'date' );
86
+
87
+ return ! $date ? __( 'Unknown', 'boldgrid-backup' ) : $date;
88
+ }
89
+
90
  /**
91
  * Get a server's UTC offset.
92
  *
110
  * @return mixed DateTimeZone object on success, false on failure.
111
  */
112
  public function get_server_timezone() {
 
113
  /*
114
  * Determine how we are going to get the server's timezone.
115
  *
134
  * ------------- --------------
135
  * DateTimeZone Object DateTimeZone Object
136
  * ( (
137
+ * ) [timezone_type] => 2
138
+ * [timezone] => EDT
139
  * )
140
  */
141
  $timezone = new DateTimeZone( 'EDT' );
164
  *
165
  * @since 1.6.0
166
  *
167
+ * @param array $settings Settings.
168
+ * @param array $tz_info Timezone information.
169
  * @return DateTime
170
  */
171
  public function get_settings_date( $settings = array(), $tz_info = array() ) {
 
172
  // Abort right away if bad data sent in.
173
  if ( ! is_array( $settings ) || ! is_array( $tz_info ) ) {
174
  return false;
177
  $settings = empty( $settings ) ? $this->core->settings->get_settings() : $settings;
178
 
179
  $tz_info = empty( $tz_info ) ? $this->get_timezone_info() : $tz_info;
180
+ $is_utc = ! empty( $tz_info['abbr'] ) && 'UTC' === substr( $tz_info['abbr'], 0, 3 );
181
 
182
  $time_string = $settings['schedule']['tod_h'] . ':' . $settings['schedule']['tod_m'] . ' ' . $settings['schedule']['tod_a'];
183
 
244
  *
245
  * @since 1.6.0
246
  *
247
+ * @param string $format Date format.
248
  * @return string
249
  */
250
  public function get_span( $format = 'M j, Y h:i a' ) {
308
  * @return array
309
  */
310
  public function get_timezone_info() {
311
+ $tz_string = get_option( 'timezone_string' );
312
  $timezone_info = array();
313
 
314
  if ( $tz_string ) {
319
  }
320
 
321
  if ( $tz ) {
322
+ $now = new DateTime( 'now', $tz );
323
+ $formatted_gmt_offset = sprintf( 'UTC%s', $this->format_gmt_offset( $tz->getOffset( $now ) / 3600 ) );
324
+ $tz_name = str_replace( '_', ' ', $tz->getName() );
325
  $timezone_info['abbr'] = $now->format( 'T' );
326
 
327
  // This set of code is not in core.
340
  $timezone_info['gmt_offset'] = $gmt_offset;
341
  }
342
 
343
+ /*
344
+ * Not sure why WordPress is doing this. If it is -4.5, show me -4.5 and not -4.
345
+ * $formatted_gmt_offset = $this->format_gmt_offset( intval( $gmt_offset ) );.
346
+ */
347
+ $formatted_gmt_offset = $gmt_offset;
348
  $timezone_info['abbr'] = sprintf( 'UTC%s', $formatted_gmt_offset );
349
 
350
  /* translators: %s: UTC offset */
353
 
354
  // This set of code is not in core.
355
  $timezone_info['markup_timezone'] = sprintf( '<span title="%1$s">%2$s</span>', esc_attr( $timezone_info['description'] ), $timezone_info['abbr'] );
356
+ $timezone_info['markup_change'] = sprintf(
357
  '<a href="%1$s" title="%3$s">%2$s</a>',
358
  admin_url( 'options-general.php' ),
359
  __( 'Change timezone', 'boldgrid-backup' ),
360
+ esc_html( __( 'WordPress timezone settings can be adjusted within Settings &raquo; General', 'boldgrid-backup' ) )
361
  );
362
 
363
  return $timezone_info;
369
  * @since 1.6.0
370
  *
371
  * @param int $time In seconds.
372
+ * @param string $type The type of type (utc, local, -5).
373
  */
374
  public function init( $time, $type = 'utc' ) {
375
  if ( empty( $time ) ) {
377
  return;
378
  }
379
 
380
+ $gmt_offset = get_option( 'gmt_offset' );
381
  $valid_gmt_offset = ! empty( $gmt_offset ) || is_numeric( $gmt_offset );
382
 
383
  $this->local_timezone = 'UTC';
404
 
405
  // Once we have the UTC time (above), we can calculate the user's local time.
406
  if ( $valid_gmt_offset ) {
407
+ $this->local_time = $this->utc_time + ( $gmt_offset * HOUR_IN_SECONDS );
408
  $this->local_timezone .= ' ' . $gmt_offset;
409
  } else {
410
  $this->local_time = $this->utc_time;
417
  * @since 1.6.0
418
  */
419
  public function reset() {
420
+ $this->local_time = null;
421
  $this->local_timezone = null;
422
+ $this->utc_time = null;
423
  }
424
  }
admin/class-boldgrid-backup-admin-tools.php CHANGED
@@ -1,28 +1,27 @@
1
  <?php
2
  /**
3
- * Tools class.
4
  *
5
- * @link http://www.boldgrid.com
6
- * @since 1.5.4
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
- * @copyright BoldGrid.com
11
  * @version $Id$
12
- * @author BoldGrid.com <wpb@boldgrid.com>
13
  */
14
 
15
  /**
16
- * BoldGrid Backup Admin Tools Class.
17
  *
18
- * @since 1.5.4
19
  */
20
  class Boldgrid_Backup_Admin_Tools {
21
-
22
  /**
23
  * The core class object.
24
  *
25
- * @since 1.5.4
26
  * @access private
27
  * @var Boldgrid_Backup_Admin_Core
28
  */
@@ -31,7 +30,7 @@ class Boldgrid_Backup_Admin_Tools {
31
  /**
32
  * Constructor.
33
  *
34
- * @since 1.5.4
35
  *
36
  * @param Boldgrid_Backup_Admin_Core $core Core class object.
37
  */
@@ -40,15 +39,28 @@ class Boldgrid_Backup_Admin_Tools {
40
  }
41
 
42
  /**
43
- * Render the tools page.
44
  *
45
- * @since 1.5.4
46
  */
47
- public function page() {
 
 
 
 
 
48
  wp_enqueue_style( 'bglib-ui-css' );
49
  wp_enqueue_script( 'bglib-ui-js' );
50
  wp_enqueue_script( 'bglib-sticky' );
51
 
 
 
 
 
 
 
 
 
 
 
52
  include BOLDGRID_BACKUP_PATH . '/admin/partials/boldgrid-backup-admin-tools.php';
53
  }
54
  }
1
  <?php
2
  /**
3
+ * File: class-boldgrid-backup-admin-tools.php
4
  *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.6.0
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
  * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
  */
14
 
15
  /**
16
+ * Class: Boldgrid_Backup_Admin_Tools
17
  *
18
+ * @since 1.6.0
19
  */
20
  class Boldgrid_Backup_Admin_Tools {
 
21
  /**
22
  * The core class object.
23
  *
24
+ * @since 1.6.0
25
  * @access private
26
  * @var Boldgrid_Backup_Admin_Core
27
  */
30
  /**
31
  * Constructor.
32
  *
33
+ * @since 1.6.0
34
  *
35
  * @param Boldgrid_Backup_Admin_Core $core Core class object.
36
  */
39
  }
40
 
41
  /**
 
42
  *
 
43
  */
44
+ public function admin_enqueue_scripts( $hook ) {
45
+ if ( 'total-upkeep_page_boldgrid-backup-tools' !== $hook ) {
46
+ return;
47
+ }
48
+
49
+ // Load classes for the UI class. As of @since 1.12.5, moved from self::page to here.
50
  wp_enqueue_style( 'bglib-ui-css' );
51
  wp_enqueue_script( 'bglib-ui-js' );
52
  wp_enqueue_script( 'bglib-sticky' );
53
 
54
+ // Add thickbox functionality. Initially added to support viewing log files.
55
+ add_thickbox();
56
+ }
57
+
58
+ /**
59
+ * Render the tools page.
60
+ *
61
+ * @since 1.6.0
62
+ */
63
+ public function page() {
64
  include BOLDGRID_BACKUP_PATH . '/admin/partials/boldgrid-backup-admin-tools.php';
65
  }
66
  }
admin/class-boldgrid-backup-admin-transfers.php ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File: class-boldgrid-backup-admin-transfers.php
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.11.0
7
+ *
8
+ * @package Boldgrid_Backup
9
+ * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
+ * @author BoldGrid <support@boldgrid.com>
12
+ */
13
+
14
+ /**
15
+ * Class: Boldgrid_Backup_Admin_Transfers
16
+ *
17
+ * @since 1.11.0
18
+ */
19
+ class Boldgrid_Backup_Admin_Transfers {
20
+ /**
21
+ * The core class object.
22
+ *
23
+ * @since 1.11.0
24
+ * @access private
25
+ * @var Boldgrid_Backup_Admin_Core
26
+ */
27
+ private $core;
28
+
29
+ /**
30
+ * Constructor.
31
+ *
32
+ * @since 1.11.0
33
+ *
34
+ * @param Boldgrid_Backup_Admin_Core $core Core class object.
35
+ */
36
+ public function __construct( Boldgrid_Backup_Admin_Core $core ) {
37
+ $this->core = $core;
38
+ }
39
+
40
+ /**
41
+ * Render the transfers page.
42
+ *
43
+ * @since 1.11.0
44
+ */
45
+ public function page() {
46
+ wp_enqueue_style( 'bglib-ui-css' );
47
+ wp_enqueue_script( 'bglib-ui-js' );
48
+ wp_enqueue_script( 'bglib-sticky' );
49
+
50
+ wp_enqueue_style(
51
+ 'boldgrid-backup-admin-transfers',
52
+ plugin_dir_url( __FILE__ ) . 'css/boldgrid-backup-admin-home.css',
53
+ [],
54
+ BOLDGRID_BACKUP_VERSION
55
+ );
56
+
57
+ include BOLDGRID_BACKUP_PATH . '/admin/partials/boldgrid-backup-admin-transfers.php';
58
+ }
59
+ }
admin/class-boldgrid-backup-admin-upload.php CHANGED
@@ -1,19 +1,21 @@
1
  <?php
2
  /**
3
- * The admin-specific core functionality of the plugin
4
  *
5
- * @link http://www.boldgrid.com
6
  * @since 1.2.2
7
  *
8
- * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
- * @copyright BoldGrid.com
11
- * @version $Id$
12
- * @author BoldGrid.com <wpb@boldgrid.com>
13
  */
14
 
 
 
15
  /**
16
- * BoldGrid Backup admin upload class.
17
  *
18
  * @since 1.2.2
19
  */
@@ -187,7 +189,7 @@ class Boldgrid_Backup_Admin_Upload {
187
  // Currently only "zip"; others to be added in the future.
188
  // @todo Write a method to get the allowed file extensions, based on available compressors.
189
  $allowed_file_ext = array(
190
- 'zip'
191
  );
192
 
193
  if ( ! in_array( $validate['ext'], $allowed_file_ext, true ) ) {
@@ -195,6 +197,7 @@ class Boldgrid_Backup_Admin_Upload {
195
  do_action(
196
  'boldgrid_backup_notice',
197
  sprintf(
 
198
  esc_html__(
199
  'Upload file extension type %s is not allowed.',
200
  'boldgrid-backup'
@@ -218,43 +221,44 @@ class Boldgrid_Backup_Admin_Upload {
218
  * @see Boldgrid_Backup_Admin_Config::get_backup_identifier()
219
  * @see Boldgrid_Backup_Admin_Backup_Dir::get()
220
  *
221
- * @return string The file save path.
 
222
  */
223
- public function get_save_path() {
224
- // Get the upload file basename.
225
- $file_basename = basename( $_FILES['file']['name'] );
226
-
227
- // Get backup identifier.
228
  $backup_identifier = $this->core->get_backup_identifier();
229
 
230
- // Get the backup directory.
231
- $backup_directory = $this->core->backup_dir->get();
232
 
233
  // Create an array of strings to remove from the filename.
234
  $remove_strings = array(
235
  'boldgrid-backup-',
236
  $backup_identifier,
237
  'uploaded-',
 
 
238
  );
239
 
240
  // Remove references from filename.
241
  foreach ( $remove_strings as $remove_string ) {
242
- $file_basename = str_replace( $remove_string, '', $file_basename );
 
 
 
 
 
243
  }
244
 
245
  // Reformat the filename.
246
- $file_basename = 'boldgrid-backup-' . $backup_identifier . '-uploaded-' . $file_basename;
247
 
248
  // Remove extra dashes.
249
- $file_basename = preg_replace( '#-+#', '-', $file_basename );
250
-
251
- // Create the file save path.
252
- $file_save_path = $backup_directory . DIRECTORY_SEPARATOR . $file_basename;
253
 
254
- // Update the base filename.
255
- $_FILES['file']['name'] = $file_basename;
256
 
257
- return $file_save_path;
 
258
  }
259
 
260
  /**
@@ -278,7 +282,8 @@ class Boldgrid_Backup_Admin_Upload {
278
  );
279
 
280
  // Add a filter to specify a custom upload directory (the backup directory).
281
- add_filter( 'upload_dir',
 
282
  array(
283
  $this->core->config,
284
  'custom_upload_dir',
@@ -288,7 +293,8 @@ class Boldgrid_Backup_Admin_Upload {
288
  $movefile = wp_handle_upload( $_FILES['file'], $upload_overrides );
289
 
290
  // Remove the temporary filter for a custom upload directory.
291
- remove_filter( 'upload_dir',
 
292
  array(
293
  $this->core->config,
294
  'custom_upload_dir',
@@ -328,7 +334,10 @@ class Boldgrid_Backup_Admin_Upload {
328
  }
329
 
330
  // Create the file save path, and update the destination base filename..
331
- $file_save_path = $this->get_save_path();
 
 
 
332
 
333
  // Handle the upload.
334
  $movefile = $this->handle_upload();
@@ -354,6 +363,7 @@ class Boldgrid_Backup_Admin_Upload {
354
  do_action(
355
  'boldgrid_backup_notice',
356
  sprintf(
 
357
  esc_html__( 'Upload has failed; %s.', 'boldgrid-backup' ),
358
  $movefile['error']
359
  ),
@@ -363,4 +373,140 @@ class Boldgrid_Backup_Admin_Upload {
363
  return false;
364
  }
365
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
366
  }
1
  <?php
2
  /**
3
+ * File: class-boldgrid-backup-admin-upload.php
4
  *
5
+ * @link https://www.boldgrid.com
6
  * @since 1.2.2
7
  *
8
+ * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
+ * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
  */
14
 
15
+ // phpcs:disable WordPress.VIP
16
+
17
  /**
18
+ * Class: Boldgrid_Backup_Admin_Upload
19
  *
20
  * @since 1.2.2
21
  */
189
  // Currently only "zip"; others to be added in the future.
190
  // @todo Write a method to get the allowed file extensions, based on available compressors.
191
  $allowed_file_ext = array(
192
+ 'zip',
193
  );
194
 
195
  if ( ! in_array( $validate['ext'], $allowed_file_ext, true ) ) {
197
  do_action(
198
  'boldgrid_backup_notice',
199
  sprintf(
200
+ // translators: 1: File extension.
201
  esc_html__(
202
  'Upload file extension type %s is not allowed.',
203
  'boldgrid-backup'
221
  * @see Boldgrid_Backup_Admin_Config::get_backup_identifier()
222
  * @see Boldgrid_Backup_Admin_Backup_Dir::get()
223
  *
224
+ * @param string $filename Filename.
225
+ * @return string
226
  */
227
+ public function get_save_path( $filename ) {
 
 
 
 
228
  $backup_identifier = $this->core->get_backup_identifier();
229
 
230
+ // Ensure that the input filename is a basename and remove any query string.
231
+ $filename = preg_replace( '/\?.*$/', '', basename( $filename ) );
232
 
233
  // Create an array of strings to remove from the filename.
234
  $remove_strings = array(
235
  'boldgrid-backup-',
236
  $backup_identifier,
237
  'uploaded-',
238
+ 'admin-ajax.php',
239
+ '.zip',
240
  );
241
 
242
  // Remove references from filename.
243
  foreach ( $remove_strings as $remove_string ) {
244
+ $filename = str_replace( $remove_string, '', $filename );
245
+ }
246
+
247
+ // If the filename is now empty, then make is a unix timestamp.
248
+ if ( empty( $filename ) ) {
249
+ $filename = current_time( 'timestamp', true );
250
  }
251
 
252
  // Reformat the filename.
253
+ $filename = 'boldgrid-backup-' . $backup_identifier . '-uploaded-' . $filename . '.zip';
254
 
255
  // Remove extra dashes.
256
+ $filename = preg_replace( '#-+#', '-', $filename );
 
 
 
257
 
258
+ $backup_directory = $this->core->backup_dir->get();
 
259
 
260
+ // Return the full file path.
261
+ return $backup_directory . DIRECTORY_SEPARATOR . $filename;
262
  }
263
 
264
  /**
282
  );
283
 
284
  // Add a filter to specify a custom upload directory (the backup directory).
285
+ add_filter(
286
+ 'upload_dir',
287
  array(
288
  $this->core->config,
289
  'custom_upload_dir',
293
  $movefile = wp_handle_upload( $_FILES['file'], $upload_overrides );
294
 
295
  // Remove the temporary filter for a custom upload directory.
296
+ remove_filter(
297
+ 'upload_dir',
298
  array(
299
  $this->core->config,
300
  'custom_upload_dir',
334
  }
335
 
336
  // Create the file save path, and update the destination base filename..
337
+ $file_save_path = $this->get_save_path( $_FILES['file']['name'] );
338
+
339
+ // Update the filename.
340
+ $_FILES['file']['name'] = basename( $file_save_path );
341
 
342
  // Handle the upload.
343
  $movefile = $this->handle_upload();
363
  do_action(
364
  'boldgrid_backup_notice',
365
  sprintf(
366
+ // translators: 1: Error message.
367
  esc_html__( 'Upload has failed; %s.', 'boldgrid-backup' ),
368
  $movefile['error']
369
  ),
373
  return false;
374
  }
375
  }
376
+
377
+ /**
378
+ * Callback function for importing a backup archive file via URL address.
379
+ *
380
+ * Used on the backup archives page.
381
+ *
382
+ * @since 1.7.0
383
+ *
384
+ * @see Boldgrid_Backup_Admin_Backup_Dir::get()
385
+ * @see Boldgrid_Backup_Admin_Backup_Dir::get_path_to()
386
+ * @see Boldgrid_Backup_Admin_Archive_Log::path_from_zip()
387
+ * @see Boldgrid_Backup_Admin_Archive_Log::restore_by_zip()
388
+ * @see Boldgrid_Backup_Admin_Remote::post_download()
389
+ *
390
+ * @uses $_POST['url'] URL address.
391
+ */
392
+ public function ajax_url_import() {
393
+ $logger = new Boldgrid_Backup_Admin_Log( $this->core );
394
+ $logger->init( 'transfer-archive.log' );
395
+ $logger->add_separator();
396
+ $logger->add( 'Beginning ajax_url_import...' );
397
+
398
+ // Check user permissions.
399
+ if ( ! current_user_can( 'update_plugins' ) ) {
400
+ wp_send_json_error(
401
+ array(
402
+ 'error' => __( 'User access violation!', 'boldgrid-backup' ),
403
+ )
404
+ );
405
+ }
406
+
407
+ // Check security nonce and referer.
408
+ if ( ! check_admin_referer( 'upload_archive_file' ) ) {
409
+ wp_send_json_error(
410
+ array(
411
+ 'error' => __( 'Security violation! Please try again.', 'boldgrid-backup' ),
412
+ )
413
+ );
414
+ }
415
+
416
+ $url = ! empty( $_POST['url'] ) ? esc_url_raw( $_POST['url'] ) : null;
417
+ $url_regex = '/' . $this->core->configs['url_regex'] . '/i';
418
+
419
+ if ( ! preg_match( $url_regex, $url ) ) {
420
+ wp_send_json_error(
421
+ array(
422
+ 'error' => __( 'Invalid URL address.', 'boldgrid-backup' ),
423
+ )
424
+ );
425
+ }
426
+
427
+ $backup_directory = $this->core->backup_dir->get();
428
+
429
+ if ( ! $this->core->backup_dir->is_valid( $backup_directory ) &&
430
+ ! empty( $this->core->backup_dir->errors ) ) {
431
+ wp_send_json_error(
432
+ array(
433
+ 'error' => implode( '<br />', $this->core->backup_dir->errors ),
434
+ )
435
+ );
436
+ }
437
+
438
+ $filepath = $this->get_save_path( basename( $url ) );
439
+
440
+ $allowed_content_types = array(
441
+ 'application/octet-stream',
442
+ 'binary/octet-stream',
443
+ 'application/zip',
444
+ );
445
+
446
+ $response = wp_remote_get(
447
+ $url, array(
448
+ 'filename' => $filepath,
449
+ 'headers' => 'Accept: ' . implode( ', ', $allowed_content_types ),
450
+ 'sslverify' => false,
451
+ 'stream' => true,
452
+ 'timeout' => MINUTE_IN_SECONDS * 20,
453
+ )
454
+ );
455
+
456
+ if ( is_array( $response ) && ! is_wp_error( $response ) &&
457
+ in_array( $response['headers']['content-type'], $allowed_content_types, true ) ) {
458
+ $logger->add( 'Archive downloaded successfully.' );
459
+ $logger->add( 'Headers: ' . ( empty( $response['headers'] ) ? 'Empty' : print_r( $response['headers'], 1 ) ) ); // phpcs:ignore
460
+
461
+ // Determine the archive log file path.
462
+ $log_filepath = $filepath;
463
+
464
+ if ( ! empty( $response['headers']['content-disposition'] ) ) {
465
+ $log_filepath = trim(
466
+ str_replace(
467
+ 'attachment; filename=', '', $response['headers']['content-disposition']
468
+ ), '"'
469
+ );
470
+
471
+ $log_filepath = $this->core->backup_dir->get_path_to( $log_filepath );
472
+ }
473
+
474
+ $log_filepath = $this->core->archive_log->path_from_zip( $log_filepath );
475
+ $filename = basename( $filepath );
476
+
477
+ // Restore the log file from the archive.
478
+ $restored = $this->core->archive_log->restore_by_zip( $filepath, basename( $log_filepath ) );
479
+ $logger->add( 'Log restored from zip: ' . ( $restored ? 'Success' : 'Fail' ) );
480
+
481
+ // Update the archive file modification time, based on the log file contents.
482
+ $this->core->remote->post_download( $filepath );
483
+
484
+ // Get the archive details.
485
+ $archive = $this->core->archive->get_by_name( $filename );
486
+
487
+ wp_send_json_success(
488
+ [
489
+ 'filepath' => $filepath,
490
+ 'detailsUrl' => admin_url(
491
+ 'admin.php?page=boldgrid-backup-archive-details&filename=' .
492
+ basename( $filepath )
493
+ ),
494
+ 'archiveFilename' => $filename,
495
+ 'archiveKey' => $archive['key'],
496
+ ]
497
+ );
498
+ } else {
499
+ $logger->add( 'Failed to download archive. $response = ' . print_r( $response, 1 ) ); // phpcs:ignore
500
+ $this->core->wp_filesystem->delete( $filepath );
501
+ }
502
+
503
+ wp_send_json_error(
504
+ [
505
+ 'error' => __(
506
+ 'Could not retrieve the remote file. It may not be a ZIP file, or the link is no longer valid.',
507
+ 'boldgrid-backup'
508
+ ),
509
+ ]
510
+ );
511
+ }
512
  }
admin/class-boldgrid-backup-admin-usage.php ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File: class-boldgrid-backup-admin-usage.php
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.12.3
7
+ *
8
+ * @package Boldgrid_Backup
9
+ * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
+ * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
+ */
14
+
15
+ /**
16
+ * Class: Boldgrid_Backup_Admin_Usage
17
+ *
18
+ * @since 1.12.3
19
+ */
20
+ class Boldgrid_Backup_Admin_Usage {
21
+ /**
22
+ * Screen prefixes.
23
+ *
24
+ * @since 1.12.3
25
+ * @access private
26
+ * @var array
27
+ */
28
+ private $prefixes = [
29
+ // The Total Upkeep dashboard.
30
+ 'toplevel_page_boldgrid-backup',
31
+ // Archive details page.
32
+ 'admin_page_boldgrid-backup',
33
+ // All other Total Upkeep pages.
34
+ 'total-upkeep_page',
35
+ ];
36
+
37
+ /**
38
+ * Admin init.
39
+ *
40
+ * @since 1.12.3
41
+ */
42
+ public function admin_init() {
43
+ /*
44
+ * Prompt the user to track usage.
45
+ *
46
+ * The Notice class will determine whether or not the notice should be displayed.
47
+ *
48
+ * The Notice class is instantiated, which adds appropriate hooks to load javascript, ajax
49
+ * listeners, etc.
50
+ */
51
+ $notice = new \Boldgrid\Library\Library\Usage\Notice();
52
+
53
+ /*
54
+ * Track usage.
55
+ *
56
+ * The usage class will determine whether or not usage should be collected.
57
+ *
58
+ * The Usage class is instantiated, which adds appropriate hooks to load javascript, ajax
59
+ * listeners, etc.
60
+ */
61
+ $usage = new \Boldgrid\Library\Library\Usage();
62
+ }
63
+
64
+ /**
65
+ * Determine whether or not to show the notice to the user to accept usage tracking.
66
+ *
67
+ * @since 1.12.3
68
+ *
69
+ * @return bool
70
+ */
71
+ public function maybe_show_notice( $show ) {
72
+ if ( $this->has_screen_prefix() && ! get_option( 'boldgrid_backup_latest_backup' ) ) {
73
+ /*
74
+ * Only show the notice if the user already has created a backup. If they haven't, they'll see
75
+ * admin notices telling them how to create their first backup, and we don't want this notice
76
+ * to derail the user from that task.
77
+ */
78
+ $show = false;
79
+ }
80
+
81
+ return $show;
82
+ }
83
+
84
+ /**
85
+ * Filter the notice that is given to users.
86
+ *
87
+ * @since 1.12.3S
88
+ *
89
+ * @param array $params
90
+ * @return array
91
+ */
92
+ public function filter_notice( $params ) {
93
+ if ( $this->has_screen_prefix() ) {
94
+ $params['message'] = '<p>' .
95
+ esc_html__(
96
+ 'Thank you for using Total Upkeep by BoldGrid! Would you be ok with helping us improve our products by sending anonymous usage data? Information collected will not be personal and is not used to identify or contact you.',
97
+ 'boldgrid-backup'
98
+ ) . '</p>';
99
+ }
100
+
101
+ return $params;
102
+ }
103
+
104
+ /**
105
+ * Filter prefixes.
106
+ *
107
+ * Tell the Usage class to listen to pages that begin with boldgrid-backup.
108
+ *
109
+ * @since 1.12.3
110
+ *
111
+ * @param array $prefixes An array of page prefixes.
112
+ * @return array
113
+ */
114
+ public function filter_prefixes( $prefixes ) {
115
+ $prefixes = array_merge( $prefixes, $this->prefixes );
116
+
117
+ return $prefixes;
118
+ }
119
+
120
+ /**
121
+ * Whether or not the current admin page begins with boldgrid-backup.
122
+ *
123
+ * @since 1.12.3
124
+ *
125
+ * @return bool
126
+ */
127
+ public function has_screen_prefix() {
128
+ return \Boldgrid\Library\Library\Usage\Helper::hasScreenPrefix( $this->prefixes );
129
+ }
130
+ }
admin/class-boldgrid-backup-admin-utility.php CHANGED
@@ -1,19 +1,21 @@
1
  <?php
2
  /**
3
- * The admin-specific utility methods for the plugin
4
  *
5
- * @link http://www.boldgrid.com
6
  * @since 1.0
7
  *
8
- * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
- * @copyright BoldGrid.com
11
- * @version $Id$
12
- * @author BoldGrid.com <wpb@boldgrid.com>
13
  */
14
 
 
 
15
  /**
16
- * BoldGrid Backup admin utility class.
17
  *
18
  * @since 1.0
19
  */
@@ -25,7 +27,7 @@ class Boldgrid_Backup_Admin_Utility {
25
  *
26
  * @static
27
  *
28
- * @param int $bytes Number of bytes.
29
  * @param int $decimals Number of decimal places.
30
  * @return string
31
  */
@@ -100,7 +102,7 @@ class Boldgrid_Backup_Admin_Utility {
100
  * Can be used in this manner:
101
  * set_error_handler( array( 'Boldgrid_Backup_Admin_Utility', 'handle_error' ) );
102
  * try{
103
- * // Try something
104
  * } catch( Exception $e ) {
105
  $e->getMessage();
106
  * }
@@ -108,13 +110,15 @@ class Boldgrid_Backup_Admin_Utility {
108
  *
109
  * @since 1.6.0
110
  *
111
- * @param int $errno Error number. (can be a PHP Error level constant)
 
 
112
  * @param string $errstr Error description.
113
  * @param string $errfile File in which the error occurs.
114
  * @param int $errline Line number where the error is situated.
 
115
  */
116
  public static function handle_error( $errno, $errstr, $errfile = false, $errline = false ) {
117
-
118
  // A set of errors to ignore.
119
  $skips = array(
120
 
@@ -167,34 +171,34 @@ class Boldgrid_Backup_Admin_Utility {
167
  */
168
  public static function translate_zip_error( $error_code = null ) {
169
  switch ( $error_code ) {
170
- case ZipArchive::ER_EXISTS :
171
  $message = esc_html__( 'File already exists', 'boldgrid-backup' );
172
  break;
173
- case ZipArchive::ER_INCONS :
174
  $message = esc_html__( 'Zip archive inconsistent', 'boldgrid-backup' );
175
  break;
176
- case ZipArchive::ER_INVAL :
177
  $message = esc_html__( 'Invalid argument', 'boldgrid-backup' );
178
  break;
179
- case ZipArchive::ER_MEMORY :
180
  $message = esc_html__( 'Malloc failure', 'boldgrid-backup' );
181
  break;
182
- case ZipArchive::ER_NOENT :
183
  $message = esc_html__( 'No such file', 'boldgrid-backup' );
184
  break;
185
- case ZipArchive::ER_NOZIP :
186
  $message = esc_html__( 'Not a zip archive', 'boldgrid-backup' );
187
  break;
188
- case ZipArchive::ER_OPEN :
189
  $message = esc_html__( 'Cannot open file', 'boldgrid-backup' );
190
  break;
191
- case ZipArchive::ER_READ :
192
  $message = esc_html__( 'Read error', 'boldgrid-backup' );
193
  break;
194
- case ZipArchive::ER_SEEK :
195
  $message = esc_html__( 'Seek error', 'boldgrid-backup' );
196
  break;
197
- default :
198
  $message = esc_html__( 'No error code was passed', 'boldgrid-backup' );
199
  break;
200
  }
@@ -305,21 +309,11 @@ class Boldgrid_Backup_Admin_Utility {
305
  if ( $wp_filesystem->is_dir( $filepath ) ) {
306
  // Is a directory.
307
  if ( ! $wp_filesystem->chmod( $filepath, 0755 ) ) {
308
- // Error chmod 755 a directory.
309
- error_log(
310
- __METHOD__ . ': Error using chmod 0755 on directory "' . $filepath . '".'
311
- );
312
-
313
  return false;
314
  }
315
  } else {
316
  // Is a file.
317
  if ( ! $wp_filesystem->chmod( $filepath, 0644 ) ) {
318
- // Error chmod 644 a file.
319
- error_log(
320
- __METHOD__ . ': Error using chmod 0644 on file "' . $filepath . '".'
321
- );
322
-
323
  return false;
324
  }
325
  }
@@ -360,7 +354,7 @@ class Boldgrid_Backup_Admin_Utility {
360
  if ( $current_max < $max_execution_time ) {
361
  set_time_limit( $max_execution_time );
362
 
363
- if ( false === ini_set( 'max_execution_time', $max_execution_time ) ) {
364
  return false;
365
  }
366
  }
@@ -377,7 +371,7 @@ class Boldgrid_Backup_Admin_Utility {
377
  *
378
  * @since 1.5.3
379
  *
380
- * @param string $plugin boldgrid-backup/boldgrid-backup.php
381
  * @return array
382
  */
383
  public function get_plugin_data( $plugin ) {
@@ -447,7 +441,7 @@ class Boldgrid_Backup_Admin_Utility {
447
  // If the current memory limit is less than specified, then try to increase it.
448
  // PHP default is "128M".
449
  if ( $current_limit_int < $memory_limit_int ) {
450
- if ( false === ini_set( 'memory_limit', $memory_limit_int ) ) {
451
  return false;
452
  }
453
  }
@@ -502,6 +496,42 @@ class Boldgrid_Backup_Admin_Utility {
502
  return true;
503
  }
504
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
505
  /**
506
  * Check if a file is a ZIP archive file.
507
  *
@@ -521,7 +551,7 @@ class Boldgrid_Backup_Admin_Utility {
521
  }
522
 
523
  // Create a ZipArchive object.
524
- $zip = new ZipArchive;
525
 
526
  // Check the ZIP file for consistency.
527
  $status = $zip->open( $file, ZipArchive::CHECKCONS );
@@ -545,9 +575,9 @@ class Boldgrid_Backup_Admin_Utility {
545
  *
546
  * @link http://php.net/manual/en/class.ziparchive.php
547
  *
548
- * @param string $zip_file Path to a ZIP file.
549
  * @param string $locate_file A filename or path to be located.
550
- * @param bool $is_path Is the input file a path.
551
  * @return bool
552
  */
553
  public static function zip_file_exists( $zip_file, $locate_file, $is_path = false ) {
@@ -557,7 +587,7 @@ class Boldgrid_Backup_Admin_Utility {
557
  }
558
 
559
  // Create a ZipArchive object.
560
- $zip = new ZipArchive;
561
 
562
  // Check the ZIP file for consistency.
563
  $status = $zip->open( $zip_file, ZipArchive::CHECKCONS );
@@ -588,8 +618,11 @@ class Boldgrid_Backup_Admin_Utility {
588
  *
589
  * @global WP_Filesystem $wp_filesystem The WordPress Filesystem API global object.
590
  *
 
 
591
  * @param string $file Path to a directory or file.
592
- * @param int $mode (Optional) The permissions as octal number, usually 0644 for files, 0755 for dirs.
 
593
  * @return bool
594
  */
595
  public static function chmod( $file, $mode = false ) {
@@ -711,6 +744,9 @@ class Boldgrid_Backup_Admin_Utility {
711
  $old_siteurl = untrailingslashit( $old_siteurl );
712
  $new_siteurl = untrailingslashit( $new_siteurl );
713
 
 
 
 
714
  // Update the WP otion "siteurl".
715
  update_option( 'siteurl', $new_siteurl );
716
 
@@ -720,6 +756,8 @@ class Boldgrid_Backup_Admin_Utility {
720
  // Get the database prefix (blog id 1 or 0 gets the base prefix).
721
  $db_prefix = $wpdb->get_blog_prefix( 1 );
722
 
 
 
723
  // Replace the URL in wp_posts.
724
  $wpdb->query(
725
  $wpdb->prepare(
@@ -755,6 +793,8 @@ class Boldgrid_Backup_Admin_Utility {
755
  ARRAY_N
756
  );
757
 
 
 
758
  // If there are no matches options, then return.
759
  if ( ! $matched_options ) {
760
  return true;
@@ -765,14 +805,14 @@ class Boldgrid_Backup_Admin_Utility {
765
  $option_value = get_option( $option_name[0] );
766
 
767
  // Replace siteurl.
768
- $option_value = Boldgrid_Backup_Admin_Utility::str_replace_recursive(
769
  $old_siteurl,
770
  $new_siteurl,
771
  $option_value
772
  );
773
 
774
  // Replace siteurl escaped with slashes.
775
- $option_value = Boldgrid_Backup_Admin_Utility::str_replace_recursive(
776
  addslashes( $old_siteurl ),
777
  addslashes( $new_siteurl ),
778
  $option_value
@@ -791,7 +831,7 @@ class Boldgrid_Backup_Admin_Utility {
791
  *
792
  * @static
793
  *
794
- * @param string $search Search string.
795
  * @param string $replace Replace string.
796
  * @param mixed $subject Input subject (array|object|string).
797
  * @return mixed The input subject with recursive string replacements.
@@ -802,7 +842,7 @@ class Boldgrid_Backup_Admin_Utility {
802
  } elseif ( is_array( $subject ) ) {
803
  foreach ( $subject as $index => $element ) {
804
  // Recurse.
805
- $subject[ $index ] = Boldgrid_Backup_Admin_Utility::str_replace_recursive(
806
  $search,
807
  $replace,
808
  $element
@@ -811,7 +851,7 @@ class Boldgrid_Backup_Admin_Utility {
811
  } elseif ( is_object( $subject ) ) {
812
  foreach ( $subject as $index => $element ) {
813
  // Recurse.
814
- $subject->$index = Boldgrid_Backup_Admin_Utility::str_replace_recursive(
815
  $search,
816
  $replace,
817
  $element
@@ -827,7 +867,7 @@ class Boldgrid_Backup_Admin_Utility {
827
  *
828
  * @since 1.5.3
829
  *
830
- * @param int $time
831
  * @return int
832
  */
833
  public function time( $time ) {
@@ -848,7 +888,9 @@ class Boldgrid_Backup_Admin_Utility {
848
  *
849
  * @since 1.5.1
850
  *
851
- * @param string
 
 
852
  * @return string
853
  */
854
  public static function trailingslashit( $string ) {
1
  <?php
2
  /**
3
+ * File: class-boldgrid-backup-admin-utility.php
4
  *
5
+ * @link https://www.boldgrid.com
6
  * @since 1.0
7
  *
8
+ * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
+ * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
  */
14
 
15
+ // phpcs:disable WordPress.VIP
16
+
17
  /**
18
+ * Class: Boldgrid_Backup_Admin_Utility
19
  *
20
  * @since 1.0
21
  */
27
  *
28
  * @static
29
  *
30
+ * @param int $bytes Number of bytes.
31
  * @param int $decimals Number of decimal places.
32
  * @return string
33
  */
102
  * Can be used in this manner:
103
  * set_error_handler( array( 'Boldgrid_Backup_Admin_Utility', 'handle_error' ) );
104
  * try{
105
+ * // Try something
106
  * } catch( Exception $e ) {
107
  $e->getMessage();
108
  * }
110
  *
111
  * @since 1.6.0
112
  *
113
+ * @static
114
+ *
115
+ * @param int $errno Error number. (can be a PHP Error level constant).
116
  * @param string $errstr Error description.
117
  * @param string $errfile File in which the error occurs.
118
  * @param int $errline Line number where the error is situated.
119
+ * @throws ErrorException Error exception object.
120
  */
121
  public static function handle_error( $errno, $errstr, $errfile = false, $errline = false ) {
 
122
  // A set of errors to ignore.
123
  $skips = array(
124
 
171
  */
172
  public static function translate_zip_error( $error_code = null ) {
173
  switch ( $error_code ) {
174
+ case ZipArchive::ER_EXISTS:
175
  $message = esc_html__( 'File already exists', 'boldgrid-backup' );
176
  break;
177
+ case ZipArchive::ER_INCONS:
178
  $message = esc_html__( 'Zip archive inconsistent', 'boldgrid-backup' );
179
  break;
180
+ case ZipArchive::ER_INVAL:
181
  $message = esc_html__( 'Invalid argument', 'boldgrid-backup' );
182
  break;
183
+ case ZipArchive::ER_MEMORY:
184
  $message = esc_html__( 'Malloc failure', 'boldgrid-backup' );
185
  break;
186
+ case ZipArchive::ER_NOENT:
187
  $message = esc_html__( 'No such file', 'boldgrid-backup' );
188
  break;
189
+ case ZipArchive::ER_NOZIP:
190
  $message = esc_html__( 'Not a zip archive', 'boldgrid-backup' );
191
  break;
192
+ case ZipArchive::ER_OPEN:
193
  $message = esc_html__( 'Cannot open file', 'boldgrid-backup' );
194
  break;
195
+ case ZipArchive::ER_READ:
196
  $message = esc_html__( 'Read error', 'boldgrid-backup' );
197
  break;
198
+ case ZipArchive::ER_SEEK:
199
  $message = esc_html__( 'Seek error', 'boldgrid-backup' );
200
  break;
201
+ default:
202
  $message = esc_html__( 'No error code was passed', 'boldgrid-backup' );
203
  break;
204
  }
309
  if ( $wp_filesystem->is_dir( $filepath ) ) {
310
  // Is a directory.
311
  if ( ! $wp_filesystem->chmod( $filepath, 0755 ) ) {
 
 
 
 
 
312
  return false;
313
  }
314
  } else {
315
  // Is a file.
316
  if ( ! $wp_filesystem->chmod( $filepath, 0644 ) ) {
 
 
 
 
 
317
  return false;
318
  }
319
  }
354
  if ( $current_max < $max_execution_time ) {
355
  set_time_limit( $max_execution_time );
356
 
357
+ if ( false === ini_set( 'max_execution_time', $max_execution_time ) ) { // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.runtime_configuration_ini_set
358
  return false;
359
  }
360
  }
371
  *
372
  * @since 1.5.3
373
  *
374
+ * @param string $plugin Plugin slug ("boldgrid-backup/boldgrid-backup.php").
375
  * @return array
376
  */
377
  public function get_plugin_data( $plugin ) {
441
  // If the current memory limit is less than specified, then try to increase it.
442
  // PHP default is "128M".
443
  if ( $current_limit_int < $memory_limit_int ) {
444
+ if ( false === ini_set( 'memory_limit', $memory_limit_int ) ) { // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.runtime_configuration_ini_set
445
  return false;
446
  }
447
  }
496
  return true;
497
  }
498
 
499
+ /**
500
+ * Determine whether or not Total Upkeep is active.
501
+ *
502
+ * The fact that Total Upkeep is calling this method shows that it is installed and activated.
503
+ * However, it we are not listed in the "active_plugins" option, then we are in the middle of
504
+ * activation.
505
+ *
506
+ * Because the library may not be available until activation, this method can help us determine
507
+ * whether or not we should instantiate library classes at a certain time.
508
+ *
509
+ * @since 1.13.5
510
+ *
511
+ * @return bool
512
+ */
513
+ public static function is_active() {
514
+ $active_plugins = get_option( 'active_plugins', array() );
515
+
516
+ return in_array( 'boldgrid-backup/boldgrid-backup.php', $active_plugins, true );
517
+ }
518
+
519
+ /**
520
+ * Determine whether or not the given $page is the current.
521
+ *
522
+ * @since 1.7.0
523
+ *
524
+ * @global string $pagenow
525
+ *
526
+ * @param string $page The page to check for in $_GET.
527
+ * @return boolean
528
+ */
529
+ public static function is_admin_page( $page ) {
530
+ global $pagenow;
531
+
532
+ return 'admin.php' === $pagenow && ! empty( $_GET['page'] ) && $page === $_GET['page']; // phpcs:ignore WordPress.CSRF.NonceVerification
533
+ }
534
+
535
  /**
536
  * Check if a file is a ZIP archive file.
537
  *
551
  }
552
 
553
  // Create a ZipArchive object.
554
+ $zip = new ZipArchive();
555
 
556
  // Check the ZIP file for consistency.
557
  $status = $zip->open( $file, ZipArchive::CHECKCONS );
575
  *
576
  * @link http://php.net/manual/en/class.ziparchive.php
577
  *
578
+ * @param string $zip_file Path to a ZIP file.
579
  * @param string $locate_file A filename or path to be located.
580
+ * @param bool $is_path Is the input file a path.
581
  * @return bool
582
  */
583
  public static function zip_file_exists( $zip_file, $locate_file, $is_path = false ) {
587
  }
588
 
589
  // Create a ZipArchive object.
590
+ $zip = new ZipArchive();
591
 
592
  // Check the ZIP file for consistency.
593
  $status = $zip->open( $zip_file, ZipArchive::CHECKCONS );
618
  *
619
  * @global WP_Filesystem $wp_filesystem The WordPress Filesystem API global object.
620
  *
621
+ * @static
622
+ *
623
  * @param string $file Path to a directory or file.
624
+ * @param int $mode (Optional) The permissions as octal number, usually 0644 for files,
625
+ * 0755 for dirs.
626
  * @return bool
627
  */
628
  public static function chmod( $file, $mode = false ) {
744
  $old_siteurl = untrailingslashit( $old_siteurl );
745
  $new_siteurl = untrailingslashit( $new_siteurl );
746
 
747
+ // There may be a filter, so remove it.
748
+ remove_all_filters( 'pre_update_option_siteurl' );
749
+
750
  // Update the WP otion "siteurl".
751
  update_option( 'siteurl', $new_siteurl );
752
 
756
  // Get the database prefix (blog id 1 or 0 gets the base prefix).
757
  $db_prefix = $wpdb->get_blog_prefix( 1 );
758
 
759
+ // phpcs:disable WordPress.DB.PreparedSQLPlaceholders
760
+
761
  // Replace the URL in wp_posts.
762
  $wpdb->query(
763
  $wpdb->prepare(
793
  ARRAY_N
794
  );
795
 
796
+ // phpcs:enable WordPress.DB.PreparedSQLPlaceholders
797
+
798
  // If there are no matches options, then return.
799
  if ( ! $matched_options ) {
800
  return true;
805
  $option_value = get_option( $option_name[0] );
806
 
807
  // Replace siteurl.
808
+ $option_value = self::str_replace_recursive(
809
  $old_siteurl,
810
  $new_siteurl,
811
  $option_value
812
  );
813
 
814
  // Replace siteurl escaped with slashes.
815
+ $option_value = self::str_replace_recursive(
816
  addslashes( $old_siteurl ),
817
  addslashes( $new_siteurl ),
818
  $option_value
831
  *
832
  * @static
833
  *
834
+ * @param string $search Search string.
835
  * @param string $replace Replace string.
836
  * @param mixed $subject Input subject (array|object|string).
837
  * @return mixed The input subject with recursive string replacements.
842
  } elseif ( is_array( $subject ) ) {
843
  foreach ( $subject as $index => $element ) {
844
  // Recurse.
845
+ $subject[ $index ] = self::str_replace_recursive(
846
  $search,
847
  $replace,
848
  $element
851
  } elseif ( is_object( $subject ) ) {
852
  foreach ( $subject as $index => $element ) {
853
  // Recurse.
854
+ $subject->$index = self::str_replace_recursive(
855
  $search,
856
  $replace,
857
  $element
867
  *
868
  * @since 1.5.3
869
  *
870
+ * @param int $time Time in UNIX seconds.
871
  * @return int
872
  */
873
  public function time( $time ) {
888
  *
889
  * @since 1.5.1
890
  *
891
+ * @static
892
+ *
893
+ * @param string $string A string.
894
  * @return string
895
  */
896
  public static function trailingslashit( $string ) {
admin/class-boldgrid-backup-admin-wp-cron.php CHANGED
@@ -1,29 +1,28 @@
1
  <?php
2
  /**
3
- * WP Cron.
4
  *
5
  * @link http://www.boldgrid.com
6
  * @since 1.5.1
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
- * @copyright BoldGrid.com
11
  * @version $Id$
12
- * @author BoldGrid.com <wpb@boldgrid.com>
13
  */
14
 
15
  /**
16
- * WP Cron.
17
  *
18
  * @since 1.5.1
19
  */
20
  class Boldgrid_Backup_Admin_WP_Cron {
21
-
22
  /**
23
- * $days of the weeky.
24
  *
25
  * @since 1.5.1
26
- * @access publc
27
  */
28
  public $days = array(
29
  'sunday',
@@ -48,12 +47,11 @@ class Boldgrid_Backup_Admin_WP_Cron {
48
  * Hooks.
49
  *
50
  * @since 1.5.1
51
- * @access public
52
  * @var array
53
  */
54
  public $hooks = array(
55
- 'backup' => 'boldgrid_backup_wp_cron_backup',
56
- 'restore' => 'boldgrid_backup_wp_cron_restore',
57
  'run_jobs' => 'boldgrid_backup_wp_cron_run_jobs',
58
  );
59
 
@@ -61,7 +59,6 @@ class Boldgrid_Backup_Admin_WP_Cron {
61
  * Schedules.
62
  *
63
  * @since 1.5.1
64
- * @access public
65
  * @var array
66
  */
67
  public $schedules = array();
@@ -79,20 +76,21 @@ class Boldgrid_Backup_Admin_WP_Cron {
79
  $this->schedules = array(
80
  'every-5-minutes' => array(
81
  'interval' => 5 * MINUTE_IN_SECONDS,
82
- 'display' => __( 'Every 5 minutes', 'boldgrid-backup' ),
83
  ),
84
- 'weekly' => array(
85
  'interval' => 7 * DAY_IN_SECONDS,
86
- 'display' => __( 'Weekly', 'boldgrid-backup' ),
87
  ),
 
88
  /*
89
  * It does not appear that crons can be added for a one time event.
90
  * Add a "never" schedule. Let someone in 1,000 years have the fun
91
  * of their site being restored out of nowhere wha ha ha!
92
  */
93
- 'never' => array(
94
  'interval' => 1000 * YEAR_IN_SECONDS,
95
- 'display' => __( 'Never', 'boldgrid-backup' ),
96
  ),
97
  );
98
  }
@@ -109,17 +107,17 @@ class Boldgrid_Backup_Admin_WP_Cron {
109
  *
110
  * @since 1.6.0
111
  *
112
- * @param array $settings
113
  * @return bool
114
  */
115
  public function add_all_crons( $settings = array() ) {
116
  $scheduler = ! empty( $settings['scheduler'] ) ? $settings['scheduler'] : null;
117
- $schedule = ! empty( $settings['schedule'] ) ? $settings['schedule'] : null;
118
 
119
  if ( 'wp-cron' === $scheduler && $this->core->scheduler->is_available( $scheduler ) && ! empty( $schedule ) ) {
120
  $this->core->scheduler->clear_all_schedules();
121
 
122
- $scheduled = $this->schedule( $settings, $this->hooks['backup'] );
123
  $jobs_scheduled = $this->schedule_jobs();
124
 
125
  return $scheduled && $jobs_scheduled;
@@ -135,9 +133,9 @@ class Boldgrid_Backup_Admin_WP_Cron {
135
  $pending_rollback = get_site_option( 'boldgrid_backup_pending_rollback' );
136
 
137
  // Get the archive to restore.
138
- $archives = $this->core->get_archive_list();
139
- $archive_key = 0;
140
- $archive = $archives[ $archive_key ];
141
  $archive_filename = $archive['filename'];
142
 
143
  // Remove existing restore cron jobs.
@@ -153,8 +151,6 @@ class Boldgrid_Backup_Admin_WP_Cron {
153
  $pending_rollback['deadline'] = $auto_restore_time;
154
  update_site_option( 'boldgrid_backup_pending_rollback', $pending_rollback );
155
  }
156
-
157
- return;
158
  }
159
 
160
  /**
@@ -162,7 +158,7 @@ class Boldgrid_Backup_Admin_WP_Cron {
162
  *
163
  * @since 1.5.1
164
  *
165
- * @param array An array of hooks to clear.
166
  */
167
  public function clear_schedules( $hooks = array() ) {
168
  if ( empty( $hooks ) ) {
@@ -179,7 +175,7 @@ class Boldgrid_Backup_Admin_WP_Cron {
179
  *
180
  * @since 1.5.1
181
  *
182
- * @param array $schedules
183
  * @return array
184
  */
185
  public function cron_schedules( $schedules ) {
@@ -201,10 +197,10 @@ class Boldgrid_Backup_Admin_WP_Cron {
201
  * should return 1 minute from now. If you pass in Monday 1:09pm, that time
202
  * has already passed, so return next Monday at 1:09pm.
203
  *
204
- * @param $d string Day of the week.
205
- * @param $h int Hour.
206
- * @param $m int Minute.
207
- * @param $p string Period (am/pm).
208
  * @return A timestamp on success.
209
  */
210
  public function get_next_time( $d, $h, $m, $p ) {
@@ -239,7 +235,7 @@ class Boldgrid_Backup_Admin_WP_Cron {
239
 
240
  $action_key = key( $cron[ $action ] );
241
 
242
- $ours[] = sprintf( '%1$s (%2$s %3$s %4$s)', $action, $cron[ $action ][ $action_key ]['schedule'], __( 'starting','boldgrid-backup' ), date( 'Y.m.d h:i:s a e', $time ) );
243
  }
244
 
245
  return $ours;
@@ -272,12 +268,11 @@ class Boldgrid_Backup_Admin_WP_Cron {
272
  *
273
  * @since 1.5.1
274
  *
275
- * @param array $settings
276
- * @param string $hook
277
  * @return bool
278
  */
279
  public function schedule( $settings, $hook ) {
280
-
281
  /*
282
  * WP Cron works off of UTC. Get our "local" time from our $settings and
283
  * convert it to UTC.
@@ -289,7 +284,7 @@ class Boldgrid_Backup_Admin_WP_Cron {
289
  * # Then it will get the settings from options, which is still 4am (as
290
  * it hasn't been saved yet).
291
  */
292
- $date = $this->core->time->get_settings_date( $settings );
293
  $new_timezone = new DateTimeZone( 'UTC' );
294
  $date->setTimezone( $new_timezone );
295
 
@@ -330,9 +325,8 @@ class Boldgrid_Backup_Admin_WP_Cron {
330
  * This hook will run every 5 minutes and run one job at a time, such as
331
  * upload to a remote storage provider.
332
  *
333
- * This method is usually ran after saving the BoldGrid Backup settings. If
334
- * after save wp-cron is our scheduler, then we need to make sure we have
335
- * the "run_jobs" wp-cron scheduled.
336
  *
337
  * @since 1.5.2
338
  *
@@ -343,7 +337,7 @@ class Boldgrid_Backup_Admin_WP_Cron {
343
 
344
  if ( ! wp_next_scheduled( $this->hooks['run_jobs'] ) ) {
345
  $scheduled = wp_schedule_event( time(), 'every-5-minutes', $this->hooks['run_jobs'] );
346
- $success = false !== $scheduled;
347
  }
348
 
349
  return $success;
1
  <?php
2
  /**
3
+ * FIle: class-boldgrid-backup-admin-wp-cron.php
4
  *
5
  * @link http://www.boldgrid.com
6
  * @since 1.5.1
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
  * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
  */
14
 
15
  /**
16
+ * Class: Boldgrid_Backup_Admin_WP_Cron
17
  *
18
  * @since 1.5.1
19
  */
20
  class Boldgrid_Backup_Admin_WP_Cron {
 
21
  /**
22
+ * Days of the week.
23
  *
24
  * @since 1.5.1
25
+ * @var array
26
  */
27
  public $days = array(
28
  'sunday',
47
  * Hooks.
48
  *
49
  * @since 1.5.1
 
50
  * @var array
51
  */
52
  public $hooks = array(
53
+ 'backup' => 'boldgrid_backup_wp_cron_backup',
54
+ 'restore' => 'boldgrid_backup_wp_cron_restore',
55
  'run_jobs' => 'boldgrid_backup_wp_cron_run_jobs',
56
  );
57
 
59
  * Schedules.
60
  *
61
  * @since 1.5.1
 
62
  * @var array
63
  */
64
  public $schedules = array();
76
  $this->schedules = array(
77
  'every-5-minutes' => array(
78
  'interval' => 5 * MINUTE_IN_SECONDS,
79
+ 'display' => __( 'Every 5 minutes', 'boldgrid-backup' ),
80
  ),
81
+ 'weekly' => array(
82
  'interval' => 7 * DAY_IN_SECONDS,
83
+ 'display' => __( 'Weekly', 'boldgrid-backup' ),
84
  ),
85
+
86
  /*
87
  * It does not appear that crons can be added for a one time event.
88
  * Add a "never" schedule. Let someone in 1,000 years have the fun
89
  * of their site being restored out of nowhere wha ha ha!
90
  */
91
+ 'never' => array(
92
  'interval' => 1000 * YEAR_IN_SECONDS,
93
+ 'display' => __( 'Never', 'boldgrid-backup' ),
94
  ),
95
  );
96
  }
107
  *
108
  * @since 1.6.0
109
  *
110
+ * @param array $settings Settings.
111
  * @return bool
112
  */
113
  public function add_all_crons( $settings = array() ) {
114
  $scheduler = ! empty( $settings['scheduler'] ) ? $settings['scheduler'] : null;
115
+ $schedule = ! empty( $settings['schedule'] ) ? $settings['schedule'] : null;
116
 
117
  if ( 'wp-cron' === $scheduler && $this->core->scheduler->is_available( $scheduler ) && ! empty( $schedule ) ) {
118
  $this->core->scheduler->clear_all_schedules();
119
 
120
+ $scheduled = $this->schedule( $settings, $this->hooks['backup'] );
121
  $jobs_scheduled = $this->schedule_jobs();
122
 
123
  return $scheduled && $jobs_scheduled;
133
  $pending_rollback = get_site_option( 'boldgrid_backup_pending_rollback' );
134
 
135
  // Get the archive to restore.
136
+ $archives = $this->core->get_archive_list();
137
+ $archive_key = 0;
138
+ $archive = $archives[ $archive_key ];
139
  $archive_filename = $archive['filename'];
140
 
141
  // Remove existing restore cron jobs.
151
  $pending_rollback['deadline'] = $auto_restore_time;
152
  update_site_option( 'boldgrid_backup_pending_rollback', $pending_rollback );
153
  }
 
 
154
  }
155
 
156
  /**
158
  *
159
  * @since 1.5.1
160
  *
161
+ * @param array $hooks An array of hooks to clear.
162
  */
163
  public function clear_schedules( $hooks = array() ) {
164
  if ( empty( $hooks ) ) {
175
  *
176
  * @since 1.5.1
177
  *
178
+ * @param array $schedules An array of events.
179
  * @return array
180
  */
181
  public function cron_schedules( $schedules ) {
197
  * should return 1 minute from now. If you pass in Monday 1:09pm, that time
198
  * has already passed, so return next Monday at 1:09pm.
199
  *
200
+ * @param string $d Day of the week.
201
+ * @param int $h Hour.
202
+ * @param int $m Minute.
203
+ * @param string $p Period (am/pm).
204
  * @return A timestamp on success.
205
  */
206
  public function get_next_time( $d, $h, $m, $p ) {
235
 
236
  $action_key = key( $cron[ $action ] );
237
 
238
+ $ours[] = sprintf( '%1$s (%2$s %3$s %4$s)', $action, $cron[ $action ][ $action_key ]['schedule'], __( 'starting', 'boldgrid-backup' ), date( 'Y.m.d h:i:s a e', $time ) );
239
  }
240
 
241
  return $ours;
268
  *
269
  * @since 1.5.1
270
  *
271
+ * @param array $settings Settings.
272
+ * @param string $hook Hook name.
273
  * @return bool
274
  */
275
  public function schedule( $settings, $hook ) {
 
276
  /*
277
  * WP Cron works off of UTC. Get our "local" time from our $settings and
278
  * convert it to UTC.
284
  * # Then it will get the settings from options, which is still 4am (as
285
  * it hasn't been saved yet).
286
  */
287
+ $date = $this->core->time->get_settings_date( $settings );
288
  $new_timezone = new DateTimeZone( 'UTC' );
289
  $date->setTimezone( $new_timezone );
290
 
325
  * This hook will run every 5 minutes and run one job at a time, such as
326
  * upload to a remote storage provider.
327
  *
328
+ * This method is usually ran after saving the settings. If after save wp-cron is our scheduler,
329
+ * then we need tomake sure we have the "run_jobs" wp-cron scheduled.
 
330
  *
331
  * @since 1.5.2
332
  *
337
 
338
  if ( ! wp_next_scheduled( $this->hooks['run_jobs'] ) ) {
339
  $scheduled = wp_schedule_event( time(), 'every-5-minutes', $this->hooks['run_jobs'] );
340
+ $success = false !== $scheduled;
341
  }
342
 
343
  return $success;
admin/class-boldgrid-backup-admin-wpcli.php ADDED
@@ -0,0 +1,247 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File: class-boldgrid-backup-admin-wpcli.php
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.8.0
7
+ *
8
+ * @package Boldgrid_Backup
9
+ * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
+ * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
+ */
14
+
15
+ // phpcs:disable WordPress.XSS.EscapeOutput.OutputNotEscaped
16
+
17
+ if ( ! defined( 'ABSPATH' ) ) {
18
+ die();
19
+ }
20
+
21
+ if ( ! defined( 'WP_CLI' ) ) {
22
+ return;
23
+ }
24
+
25
+ WP_CLI::add_command( 'bgbkup', 'Boldgrid_Backup_Admin_Wpcli' );
26
+
27
+ /**
28
+ * Support WP-CLI actions.
29
+ *
30
+ * ## EXAMPLES
31
+ *
32
+ * # Show the configured backup schedule
33
+ * $ wp bgbkup schedule show
34
+ * Backup schedule: Sunday, Wednesday at 3:11 AM (WordPress timezone: America/New_York / UTC -5)
35
+ * Success: Schedule listed.
36
+ *
37
+ * # Clear the backup schedule
38
+ * $ wp bgbkup schedule clear
39
+ * Success: Schedule cleared.
40
+ *
41
+ * # Set the backup schedule
42
+ * $ wp bgbkup schedule set --days=0,3 --time=0311
43
+ * Success: Schedule set.
44
+ *
45
+ * @since 1.8.0
46
+ */
47
+ class Boldgrid_Backup_Admin_Wpcli {
48
+ /**
49
+ * Boldgrid_Backup_Admin_Core object.
50
+ *
51
+ * @since 1.8.0
52
+ *
53
+ * @var Boldgrid_Backup_Admin_Core
54
+ * @staticvar
55
+ */
56
+ public static $core;
57
+
58
+ /**
59
+ * Print the backup schedule.
60
+ *
61
+ * ## OPTIONS
62
+ *
63
+ * clear: Clear the backup schedule.
64
+ * list: Print the backup schedule. (default command)
65
+ * set: Set the backup schedule. Day numbers (0-6: Sunday-Saturday, comma-delimited) and time of day (uses the timezone set in WordPress). PHP strtotime() is used when setting the time value.
66
+ * show: Alias for `list`.
67
+ *
68
+ * ## EXAMPLES
69
+ *
70
+ * # Show the configured backup schedule
71
+ * $ wp bgbkup schedule show
72
+ * Backup schedule: Sunday, Wednesday at 3:11 AM (WordPress timezone: America/New_York / UTC -5)
73
+ * Success: Schedule listed.
74
+ *
75
+ * # Clear the backup schedule
76
+ * $ wp bgbkup schedule clear
77
+ * Success: Schedule cleared.
78
+ *
79
+ * # Set the backup schedule
80
+ * $ wp bgbkup schedule set --days=0,3 --time=0311
81
+ * Success: Schedule set.
82
+ *
83
+ * @param array $args Array of arguments.
84
+ * @param array $assoc_args Associative array of arguments.
85
+ */
86
+ public function schedule( array $args = [], array $assoc_args = [] ) {
87
+ $cmd = isset( $args[0] ) ? $args[0] : null;
88
+
89
+ switch ( $cmd ) {
90
+ case 'clear':
91
+ $this->schedule_clear();
92
+ WP_CLI::success( __( 'Schedule cleared.', 'boldgrid-backup' ) );
93
+ break;
94
+ case 'show':
95
+ $this->schedule_list();
96
+ WP_CLI::success( __( 'Schedule listed.', 'boldgrid-backup' ) );
97
+ break;
98
+ case 'list':
99
+ $this->schedule_list();
100
+ WP_CLI::success( __( 'Schedule listed.', 'boldgrid-backup' ) );
101
+ break;
102
+ case 'set':
103
+ if ( $this->schedule_set( $assoc_args ) ) {
104
+ WP_CLI::success( __( 'Schedule set.', 'boldgrid-backup' ) );
105
+ } else {
106
+ WP_CLI::error( __( 'Could not set schedule. Check syntax.', 'boldgrid-backup' ) );
107
+ }
108
+ break;
109
+ case null:
110
+ WP_CLI::runcommand( 'help bgbkup schedule' );
111
+ break;
112
+ default:
113
+ // Translators: 1: WP-CLI command.
114
+ WP_CLI::error( sprintf( __( '"%s" is not a valid command.', 'boldgrid-backup' ), $cmd ) );
115
+ break;
116
+ }
117
+ }
118
+
119
+ /**
120
+ * Clear the backup schedule.
121
+ *
122
+ * @since 1.8.0
123
+ * @access protected
124
+ *
125
+ * @subcommand clear
126
+ */
127
+ protected function schedule_clear() {
128
+ $settings = self::$core->settings->get_settings();
129
+
130
+ $settings['schedule'] = null;
131
+
132
+ self::$core->scheduler->clear_all_schedules();
133
+ self::$core->settings->save( $settings );
134
+ }
135
+
136
+ /**
137
+ * Print the backup schedule.
138
+ *
139
+ * @since 1.8.0
140
+ * @access protected
141
+ *
142
+ * @subcommand list
143
+ * @subcommand show
144
+ */
145
+ protected function schedule_list() {
146
+ $backup_days = [];
147
+ $settings = self::$core->settings->get_settings();
148
+
149
+ if ( $settings['schedule']['dow_sunday'] ) {
150
+ $backup_days[] = __( 'Sunday', 'boldgrid-backup' );
151
+ }
152
+ if ( $settings['schedule']['dow_monday'] ) {
153
+ $backup_days[] = __( 'Monday', 'boldgrid-backup' );
154
+ }
155
+ if ( $settings['schedule']['dow_tuesday'] ) {
156
+ $backup_days[] = __( 'Tuesday', 'boldgrid-backup' );
157
+ }
158
+ if ( $settings['schedule']['dow_wednesday'] ) {
159
+ $backup_days[] = __( 'Wednesday', 'boldgrid-backup' );
160
+ }
161
+ if ( $settings['schedule']['dow_thursday'] ) {
162
+ $backup_days[] = __( 'Thursday', 'boldgrid-backup' );
163
+ }
164
+ if ( $settings['schedule']['dow_friday'] ) {
165
+ $backup_days[] = __( 'Friday', 'boldgrid-backup' );
166
+ }
167
+ if ( $settings['schedule']['dow_saturday'] ) {
168
+ $backup_days[] = __( 'Saturday', 'boldgrid-backup' );
169
+ }
170
+
171
+ $backup_days = implode( ', ', $backup_days );
172
+ $backup_days = $backup_days ? $backup_days : 'None';
173
+
174
+ echo 'Backup schedule: ' . $backup_days;
175
+
176
+ if ( 'None' !== $backup_days ) {
177
+ $has_tod = isset(
178
+ $settings['schedule']['tod_h'],
179
+ $settings['schedule']['tod_m'],
180
+ $settings['schedule']['tod_a']
181
+ );
182
+
183
+ if ( $has_tod ) {
184
+ echo __( ' at ', 'boldgrid-backup' ) . $settings['schedule']['tod_h'] . ':' .
185
+ $settings['schedule']['tod_m'] . ' ' . $settings['schedule']['tod_a'] .
186
+ __( ' (WordPress timezone: ', 'boldgrid-backup' ) .
187
+ get_option( 'timezone_string' ) . ' / UTC ' . get_option( 'gmt_offset' ) . ')';
188
+ } else {
189
+ esc_html_e( ' at unknown time', 'boldgrid-backup' );
190
+ }
191
+ }
192
+
193
+ echo PHP_EOL;
194
+ }
195
+
196
+ /**
197
+ * Set the backup schedule.
198
+ *
199
+ * @since 1.8.0
200
+ * @access protected
201
+ *
202
+ * @subsommand set
203
+ *
204
+ * @param array $assoc_args Associative array of arguments.
205
+ * @return bool
206
+ */
207
+ protected function schedule_set( array $assoc_args ) {
208
+ if ( ! isset( $assoc_args['days'], $assoc_args['time'] ) ) {
209
+ return false;
210
+ }
211
+
212
+ $days = explode( ',', $assoc_args['days'] );
213
+ $time = strtotime( $assoc_args['time'] );
214
+
215
+ if ( ! $time ) {
216
+ return false;
217
+ }
218
+
219
+ // Ensure that all of the day numbers are valid.
220
+ foreach ( $days as $day ) {
221
+ if ( ! preg_match( '/^[0-6]$/', $day ) ) {
222
+ return false;
223
+ }
224
+ }
225
+
226
+ $settings = self::$core->settings->get_settings();
227
+
228
+ $settings['schedule'] = [
229
+ 'dow_sunday' => in_array( '0', $days, true ) ? 1 : 0,
230
+ 'dow_monday' => in_array( '1', $days, true ) ? 1 : 0,
231
+ 'dow_tuesday' => in_array( '2', $days, true ) ? 1 : 0,
232
+ 'dow_wednesday' => in_array( '3', $days, true ) ? 1 : 0,
233
+ 'dow_thursday' => in_array( '4', $days, true ) ? 1 : 0,
234
+ 'dow_friday' => in_array( '5', $days, true ) ? 1 : 0,
235
+ 'dow_saturday' => in_array( '6', $days, true ) ? 1 : 0,
236
+ 'tod_h' => (int) date( 'g', $time ),
237
+ 'tod_m' => date( 'i', $time ),
238
+ 'tod_a' => date( 'A', $time ),
239
+ ];
240
+
241
+ $settings = self::$core->settings->update_cron( $settings );
242
+
243
+ self::$core->settings->save( $settings );
244
+
245
+ return $settings['crons_added'];
246
+ }
247
+ }
admin/class-boldgrid-backup-admin-xhprof.php CHANGED
@@ -1,19 +1,21 @@
1
  <?php
2
  /**
3
- * The admin-specific PHP profiling methods for the plugin
4
  *
5
- * @link http://www.boldgrid.com
6
  * @since 1.2
7
  *
8
- * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
- * @copyright BoldGrid.com
11
- * @version $Id$
12
- * @author BoldGrid.com <wpb@boldgrid.com>
13
  */
14
 
 
 
15
  /**
16
- * BoldGrid Backup admin xhprof class.
17
  *
18
  * @since 1.2
19
  */
@@ -42,7 +44,8 @@ class Boldgrid_Backup_Admin_Xhprof {
42
  // If XHprof was enabled, then register a shutdown action to disable XHProf and
43
  // save the run report data to file.
44
  if ( $this->xhprof_active ) {
45
- add_action( 'shutdown',
 
46
  array(
47
  $this,
48
  'xhprof_disable',
@@ -60,7 +63,7 @@ class Boldgrid_Backup_Admin_Xhprof {
60
  */
61
  private function xhprof_enable() {
62
  // If the action is "heartbeat", then abort.
63
- if ( ! empty( $_POST['action'] ) && 'heartbeat' === $_POST['action'] ) {
64
  return false;
65
  }
66
 
@@ -105,7 +108,7 @@ class Boldgrid_Backup_Admin_Xhprof {
105
  }
106
 
107
  // Configure the utils path.
108
- $xhprof_utils_path = '/usr/share/pear/xhprof_lib/utils';
109
 
110
  // If the utility libraries exists, then load them.
111
  if ( file_exists( $xhprof_utils_path . '/xhprof_lib.php' ) &&
@@ -115,16 +118,17 @@ class Boldgrid_Backup_Admin_Xhprof {
115
 
116
  // Save the run data to file.
117
  $xhprof_runs = new XHProfRuns_Default();
118
- $run_id = $xhprof_runs->save_run( $xhprof_data, 'xhprof_boldgrid_backup' );
119
 
120
  // Write the report URL to the error log.
121
  error_log(
122
- __METHOD__ . ': https://' . $_SERVER['HTTP_HOST'] .
123
- '/xhprof/index.php?run=' . $run_id . '&source=xhprof_boldgrid_backup'
 
 
 
124
  );
125
  }
126
  }
127
-
128
- return;
129
  }
130
  }
1
  <?php
2
  /**
3
+ * File: class-boldgrid-backup-admin-xhprof.php
4
  *
5
+ * @link https://www.boldgrid.com
6
  * @since 1.2
7
  *
8
+ * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
+ * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
  */
14
 
15
+ // phpcs:disable WordPress.VIP, WordPress.PHP.DevelopmentFunctions
16
+
17
  /**
18
+ * Class: Boldgrid_Backup_Admin_Xhprof
19
  *
20
  * @since 1.2
21
  */
44
  // If XHprof was enabled, then register a shutdown action to disable XHProf and
45
  // save the run report data to file.
46
  if ( $this->xhprof_active ) {
47
+ add_action(
48
+ 'shutdown',
49
  array(
50
  $this,
51
  'xhprof_disable',
63
  */
64
  private function xhprof_enable() {
65
  // If the action is "heartbeat", then abort.
66
+ if ( ! empty( $_POST['action'] ) && 'heartbeat' === $_POST['action'] ) { // phpcs:ignore WordPress.CSRF.NonceVerification.NoNonceVerification
67
  return false;
68
  }
69
 
108
  }
109
 
110
  // Configure the utils path.
111
+ $xhprof_utils_path = BOLDGRID_BACKUP_PATH . '/vendor/lox/xhprof/xhprof_lib/utils';
112
 
113
  // If the utility libraries exists, then load them.
114
  if ( file_exists( $xhprof_utils_path . '/xhprof_lib.php' ) &&
118
 
119
  // Save the run data to file.
120
  $xhprof_runs = new XHProfRuns_Default();
121
+ $run_id = $xhprof_runs->save_run( $xhprof_data, 'xhprof_boldgrid_backup' );
122
 
123
  // Write the report URL to the error log.
124
  error_log(
125
+ __METHOD__ . ': ' . plugins_url(
126
+ plugin_basename( BOLDGRID_BACKUP_PATH ) .
127
+ '/vendor/lox/xhprof/xhprof_html/index.php?run=' . $run_id .
128
+ '&source=xhprof_boldgrid_backup'
129
+ )
130
  );
131
  }
132
  }
 
 
133
  }
134
  }
admin/class-boldgrid-backup-admin.php CHANGED
@@ -1,23 +1,26 @@
1
  <?php
2
  /**
3
- * The admin-specific functionality of the plugin
4
  *
5
- * @link http://www.boldgrid.com
6
  * @since 1.0
7
  *
8
- * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
 
 
 
10
  */
11
 
 
 
12
  /**
13
- * The admin-specific functionality of the plugin.
14
  *
15
  * Defines the plugin name, version, and two examples hooks for how to
16
  * enqueue the admin-specific stylesheet and JavaScript.
17
  *
18
- * @package Boldgrid_Backup
19
- * @subpackage Boldgrid_Backup/admin
20
- * @author BoldGrid.com <wpb@boldgrid.com>
21
  */
22
  class Boldgrid_Backup_Admin {
23
  /**
@@ -69,7 +72,7 @@ class Boldgrid_Backup_Admin {
69
  */
70
  public function __construct( $plugin_name, $version ) {
71
  $this->plugin_name = $plugin_name;
72
- $this->version = $version;
73
 
74
  // Connect to the WordPress Filesystem API.
75
  global $wp_filesystem;
@@ -89,6 +92,8 @@ class Boldgrid_Backup_Admin {
89
  * @since 1.0
90
  */
91
  public function enqueue_styles() {
 
 
92
  /*
93
  * An instance of this class should be passed to the run() function
94
  * defined in Boldgrid_Backup_Loader as all of the hooks are defined
@@ -98,23 +103,27 @@ class Boldgrid_Backup_Admin {
98
  * between the defined hooks and the functions defined in this
99
  * class.
100
  */
101
- wp_enqueue_style( $this->plugin_name,
102
- plugin_dir_url( __FILE__ ) . 'css/boldgrid-backup-admin.css', array(), $this->version );
 
 
103
 
104
  // Enqueue JS.
105
- wp_register_script( 'boldgrid-backup-admin',
 
106
  plugin_dir_url( __FILE__ ) . 'js/boldgrid-backup-admin.js',
107
  array( 'jquery' ),
108
  BOLDGRID_BACKUP_VERSION,
109
  false
110
  );
111
 
112
- $spinner = '<span class="spinner inline"></span> ';
113
- $dots = ' ...';
114
  $translation = array(
115
- 'is_premium' => ( true === $this->config->get_is_premium() ? 'true' : 'false' ),
116
- 'lang' => $this->config->lang,
117
  'spinner_loading' => $spinner . __( 'Loading', 'boldgrid-backup' ) . $dots,
 
118
  'get_premium_url' => Boldgrid_Backup_Admin_Go_Pro::$url,
119
  );
120
 
@@ -122,13 +131,43 @@ class Boldgrid_Backup_Admin {
122
 
123
  wp_enqueue_script( 'boldgrid-backup-admin' );
124
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
125
  // Used by admin.js to highlight / bounce elements.
126
  wp_enqueue_script( 'jquery-effects-core' );
127
  wp_enqueue_script( 'jquery-effects-bounce' );
128
 
129
  // Enqueue CSS for the home page.
130
- if ( isset( $_REQUEST['page'] ) && 'boldgrid-backup' === $_REQUEST['page'] ) {
131
- wp_enqueue_style( 'boldgrid-backup-admin-home',
 
132
  plugin_dir_url( __FILE__ ) . 'css/boldgrid-backup-admin-home.css', array(),
133
  BOLDGRID_BACKUP_VERSION
134
  );
@@ -155,7 +194,7 @@ class Boldgrid_Backup_Admin {
155
 
156
  // Set the config file paths.
157
  $global_config_path = $config_dir . '/config.plugin.php';
158
- $local_config_path = $config_dir . '/config.local.php';
159
 
160
  // Initialize $global_configs array.
161
  $global_configs = array();
1
  <?php
2
  /**
3
+ * File: class-boldgrid-backup-admin.php
4
  *
5
+ * @link https://www.boldgrid.com
6
  * @since 1.0
7
  *
8
+ * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin
10
+ * @copyright BoldGrid
11
+ * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
  */
14
 
15
+ // phpcs:disable WordPress.VIP
16
+
17
  /**
18
+ * Class: Boldgrid_Backup_Admin
19
  *
20
  * Defines the plugin name, version, and two examples hooks for how to
21
  * enqueue the admin-specific stylesheet and JavaScript.
22
  *
23
+ * @since 1.0
 
 
24
  */
25
  class Boldgrid_Backup_Admin {
26
  /**
72
  */
73
  public function __construct( $plugin_name, $version ) {
74
  $this->plugin_name = $plugin_name;
75
+ $this->version = $version;
76
 
77
  // Connect to the WordPress Filesystem API.
78
  global $wp_filesystem;
92
  * @since 1.0
93
  */
94
  public function enqueue_styles() {
95
+ $core = apply_filters( 'boldgrid_backup_get_core', null );
96
+
97
  /*
98
  * An instance of this class should be passed to the run() function
99
  * defined in Boldgrid_Backup_Loader as all of the hooks are defined
103
  * between the defined hooks and the functions defined in this
104
  * class.
105
  */
106
+ wp_enqueue_style(
107
+ $this->plugin_name,
108
+ plugin_dir_url( __FILE__ ) . 'css/boldgrid-backup-admin.css', array(), $this->version
109
+ );
110
 
111
  // Enqueue JS.
112
+ wp_register_script(
113
+ 'boldgrid-backup-admin',
114
  plugin_dir_url( __FILE__ ) . 'js/boldgrid-backup-admin.js',
115
  array( 'jquery' ),
116
  BOLDGRID_BACKUP_VERSION,
117
  false
118
  );
119
 
120
+ $spinner = '<span class="spinner inline"></span> ';
121
+ $dots = ' ...';
122
  $translation = array(
123
+ 'is_premium' => ( true === $this->config->get_is_premium() ? 'true' : 'false' ),
124
+ 'lang' => $this->config->lang,
125
  'spinner_loading' => $spinner . __( 'Loading', 'boldgrid-backup' ) . $dots,
126
+ 'spinner' => $spinner,
127
  'get_premium_url' => Boldgrid_Backup_Admin_Go_Pro::$url,
128
  );
129
 
131
 
132
  wp_enqueue_script( 'boldgrid-backup-admin' );
133
 
134
+ // Enqueue "In Progress" script.
135
+ $handle = 'boldgrid-backup-admin-in-progress';
136
+ wp_register_script(
137
+ $handle,
138
+ plugin_dir_url( __FILE__ ) . 'js/' . $handle . '.js',
139
+ array( 'jquery' ),
140
+ BOLDGRID_BACKUP_VERSION,
141
+ false
142
+ );
143
+ $translation = array(
144
+ 'archive_file_size' => __( 'Archive file size: ', 'boldgrid-backup' ),
145
+ 'size_before_compression' => __( 'File size before compression: ', 'boldgrid-backup' ),
146
+ 'adding_tables' => __( 'Adding tables.', 'boldgrid-backup' ),
147
+ 'completing_database' => __( 'Completing database backup...', 'boldgrid-backup' ),
148
+ 'update_protection_activated' => $core->elements['update_protection_activated'],
149
+ 'backup_created' => $core->lang['backup_created'],
150
+ 'backup_error' => '<span class="dashicons dashicons-no red"></span>' . esc_html__( 'Unfortunately there was an error creating your backup. Update protection is not available.', 'boldgrid-backup' ),
151
+ 'error' => esc_html__( 'Error:', 'boldgrid-backup' ),
152
+ 'get_support' => $core->lang['get_support'],
153
+ );
154
+ wp_localize_script( $handle, 'BoldGridBackupAdminInProgress', $translation );
155
+ wp_enqueue_script( $handle );
156
+
157
+ // The "In Progress" script relies on the heartbeat.
158
+ wp_enqueue_script( 'heartbeat' );
159
+
160
+ // The "In Progress" script needs this progressbar script.
161
+ wp_enqueue_script( 'jquery-ui-progressbar' );
162
+
163
  // Used by admin.js to highlight / bounce elements.
164
  wp_enqueue_script( 'jquery-effects-core' );
165
  wp_enqueue_script( 'jquery-effects-bounce' );
166
 
167
  // Enqueue CSS for the home page.
168
+ if ( isset( $_REQUEST['page'] ) && 'boldgrid-backup' === $_REQUEST['page'] ) { // phpcs:ignore WordPress.CSRF.NonceVerification.NoNonceVerification
169
+ wp_enqueue_style(
170
+ 'boldgrid-backup-admin-home',
171
  plugin_dir_url( __FILE__ ) . 'css/boldgrid-backup-admin-home.css', array(),
172
  BOLDGRID_BACKUP_VERSION
173
  );
194
 
195
  // Set the config file paths.
196
  $global_config_path = $config_dir . '/config.plugin.php';
197
+ $local_config_path = $config_dir . '/config.local.php';
198
 
199
  // Initialize $global_configs array.
200
  $global_configs = array();
admin/class-cron.php ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Cron class.
4
+ *
5
+ * This is a controller class, working with classes within the admin/cron folder.
6
+ *
7
+ * @link https://www.boldgrid.com
8
+ * @since 1.11.0
9
+ *
10
+ * @package Boldgrid\Backup
11
+ * @subpackage Boldgrid\Backup\Cron
12
+ * @copyright BoldGrid
13
+ * @author BoldGrid <support@boldgrid.com>
14
+ */
15
+
16
+ namespace Boldgrid\Backup\Admin;
17
+
18
+ /**
19
+ * Class: Cron
20
+ *
21
+ * @since 1.11.0
22
+ */
23
+ class Cron {
24
+ /**
25
+ * Get our cron configs.
26
+ *
27
+ * @since 1.11.0
28
+ *
29
+ * @return array
30
+ */
31
+ public function get_configs() {
32
+ return require BOLDGRID_BACKUP_PATH . '/includes/config/config.cron.php';
33
+ }
34
+
35
+ /**
36
+ * Get our cron engine (either "cron" or "wp-cron").
37
+ *
38
+ * @since 1.11.0
39
+ *
40
+ * @return string
41
+ */
42
+ public function get_engine() {
43
+ $core = apply_filters( 'boldgrid_backup_get_core', null );
44
+
45
+ return $core->scheduler->get();
46
+ }
47
+
48
+ /**
49
+ * Get a cron entry.
50
+ *
51
+ * @since 1.11.0
52
+ *
53
+ * @param string $name The cron entry to get.
54
+ * @return mixed
55
+ */
56
+ public function get_entry( $name ) {
57
+ $configs = $this->get_configs();
58
+
59
+ $engine = $this->get_engine();
60
+ if ( empty( $engine ) ) {
61
+ return false;
62
+ }
63
+
64
+ // Get an instance of our entry class.
65
+ $entry = $this->get_entry_class();
66
+ if ( empty( $entry ) ) {
67
+ return false;
68
+ }
69
+
70
+ // Init our entry.
71
+ switch ( $name ) {
72
+ case 'backup':
73
+ $entry->init_via_search( $configs['entries'][ $name ]['search'][ $engine ] );
74
+ break;
75
+ default:
76
+ break;
77
+ }
78
+
79
+ return $entry;
80
+ }
81
+
82
+ /**
83
+ * Get our entry class object.
84
+ *
85
+ * Determine our cron engine and return the appropriate entry class object.
86
+ *
87
+ * @since 1.11.0
88
+ *
89
+ * @return mixed
90
+ */
91
+ public function get_entry_class() {
92
+ $entry_class = false;
93
+
94
+ $engine = $this->get_engine();
95
+
96
+ // Get our entry.
97
+ switch ( $engine ) {
98
+ case 'cron':
99
+ $entry_class = new \Boldgrid\Backup\Admin\Cron\Entry\Crontab();
100
+ break;
101
+ case 'wp-cron':
102
+ $entry_class = new \Boldgrid\Backup\Admin\Cron\Entry\Wpcron();
103
+ break;
104
+ default:
105
+ break;
106
+ }
107
+
108
+ return $entry_class;
109
+ }
110
+ }
admin/compressor/{pcl_zip.php → class-boldgrid-backup-admin-compressor-pcl-zip.php} RENAMED
@@ -1,28 +1,29 @@
1
  <?php
2
  /**
 
 
3
  * Pcl Zip Compressor.
4
  *
5
- * @link http://www.boldgrid.com
6
  * @since 1.5.1
7
  *
8
  * @package Boldgrid_Backup
9
- * @subpackage Boldgrid_Backup/admin
10
- * @copyright BoldGrid.com
11
  * @version $Id$
12
- * @author BoldGrid.com <wpb@boldgrid.com>
13
  */
14
 
15
  /**
16
- * BoldGrid Backup Admin Compressor Pclzip Class.
17
  *
18
  * @since 1.5.1
19
  */
20
  class Boldgrid_Backup_Admin_Compressor_Pcl_Zip extends Boldgrid_Backup_Admin_Compressor {
21
-
22
  /**
23
  * An array of errors.
24
  *
25
- * @since 1.5.4
26
  * @access public
27
  * @var array
28
  */
@@ -46,16 +47,25 @@ class Boldgrid_Backup_Admin_Compressor_Pcl_Zip extends Boldgrid_Backup_Admin_Com
46
  */
47
  public $test_errors = array();
48
 
 
 
 
 
 
 
 
 
 
49
  /**
50
  * Constructor.
51
  *
52
  * @since 1.5.1
53
  *
54
- * @param Boldgrid_Backup_Admin_Core $core
55
  */
56
  public function __construct( $core ) {
57
  if ( ! class_exists( 'PclZip' ) ) {
58
- require_once( ABSPATH . '/wp-admin/includes/class-pclzip.php' );
59
  }
60
 
61
  parent::__construct( $core );
@@ -75,30 +85,29 @@ class Boldgrid_Backup_Admin_Compressor_Pcl_Zip extends Boldgrid_Backup_Admin_Com
75
  * # wp-content/plugins/
76
  * # wp-content/plugins/boldgrid/
77
  *
78
- * @since 1.5.4
79
  *
80
- * @param array $list
81
- * @param array $contents
82
- * @param array $filenames
83
- * @param string $in_dir
84
  * @return array An updated $contents.
85
  */
86
  public function browse_add_dirs( $list, $contents, $filenames, $in_dir ) {
87
  foreach ( $list as $key => $file ) {
88
 
89
  // These variables are very similar, both exist for readability.
90
- $top_dir = null;
91
  $next_dir = null;
92
 
93
  if ( '.' === $in_dir ) {
94
  $top_dir = explode( '/', $file['filename'] );
95
  $top_dir = $top_dir[0];
96
 
97
- if ( empty( $top_dir ) || in_array( $top_dir, $filenames ) ) {
98
  continue;
99
  }
100
  } else {
101
-
102
  /*
103
  * Determine if file is in directory.
104
  *
@@ -122,17 +131,17 @@ class Boldgrid_Backup_Admin_Compressor_Pcl_Zip extends Boldgrid_Backup_Admin_Com
122
  $next_dir = explode( '/', $next_dir );
123
  $next_dir = $in_dir . '/' . $next_dir[0];
124
 
125
- if ( $next_dir === $file['filename'] || in_array( $next_dir, $filenames ) ) {
126
  continue;
127
  }
128
  }
129
 
130
- $dir = ! empty( $top_dir ) ? $top_dir : $next_dir;
131
- $sudo_file = array(
132
  'filename' => $dir,
133
- 'folder' => true,
134
  );
135
- $contents[] = $sudo_file;
136
  $filenames[] = $dir;
137
  }
138
 
@@ -144,7 +153,9 @@ class Boldgrid_Backup_Admin_Compressor_Pcl_Zip extends Boldgrid_Backup_Admin_Com
144
  *
145
  * @since 1.5.1
146
  *
147
- * @param array $filelist See Boldgrid_Backup_Admin_Filelist::get_total_size
 
 
148
  * @param array $info {
149
  * An array of data about the backup archive we are generating.
150
  *
@@ -157,8 +168,6 @@ class Boldgrid_Backup_Admin_Compressor_Pcl_Zip extends Boldgrid_Backup_Admin_Com
157
  * }
158
  */
159
  public function archive_files( $filelist, &$info ) {
160
- $info['filepath'] = $this->core->generate_archive_path( 'zip' );
161
-
162
  if ( $info['dryrun'] ) {
163
  return true;
164
  }
@@ -172,6 +181,10 @@ class Boldgrid_Backup_Admin_Compressor_Pcl_Zip extends Boldgrid_Backup_Admin_Com
172
  );
173
  }
174
 
 
 
 
 
175
  /*
176
  * Create our $new_filelist.
177
  *
@@ -179,18 +192,25 @@ class Boldgrid_Backup_Admin_Compressor_Pcl_Zip extends Boldgrid_Backup_Admin_Com
179
  * is an array of arrays, so we need to convert to simply an array of
180
  * strings (filenames to archive).
181
  */
182
- $new_filelist = array();
183
- foreach ( $filelist as $key => $file ) {
184
-
185
  // Don't add the database dump at this time, it will be added later.
186
  if ( ! empty( $this->core->db_dump_filepath ) && $file[0] === $this->core->db_dump_filepath ) {
187
  continue;
188
  }
189
 
 
 
190
  $new_filelist[] = $file[0];
191
  }
192
 
193
- $status = $archive->add( $new_filelist,
 
 
 
 
 
194
  PCLZIP_OPT_REMOVE_PATH, ABSPATH
195
  );
196
 
@@ -220,11 +240,13 @@ class Boldgrid_Backup_Admin_Compressor_Pcl_Zip extends Boldgrid_Backup_Admin_Com
220
  $status = $archive->add( $this->core->db_dump_filepath, PCLZIP_OPT_REMOVE_ALL_PATH );
221
  if ( 0 === $status ) {
222
  return array(
223
- 'error' => sprintf( 'Cannot add database dump to ZIP archive file: %1$s', $archive->errorInfo() ),
224
  );
225
  }
226
  }
227
 
 
 
228
  $this->wp_filesystem->chdir( $cwd );
229
 
230
  return true;
@@ -233,8 +255,8 @@ class Boldgrid_Backup_Admin_Compressor_Pcl_Zip extends Boldgrid_Backup_Admin_Com
233
  /**
234
  * Get the contents of a zip file.
235
  *
236
- * @param string $filepath
237
- * @param string $in_dir
238
  * @return array
239
  */
240
  public function browse( $filepath, $in_dir = '.' ) {
@@ -270,7 +292,6 @@ class Boldgrid_Backup_Admin_Compressor_Pcl_Zip extends Boldgrid_Backup_Admin_Com
270
  * https://pastebin.com/bjQZYcAt
271
  */
272
  foreach ( $list as $key => $file ) {
273
-
274
  /*
275
  * Calculate the parent directory this file / folder belongs to.
276
  *
@@ -285,7 +306,7 @@ class Boldgrid_Backup_Admin_Compressor_Pcl_Zip extends Boldgrid_Backup_Admin_Com
285
  continue;
286
  }
287
 
288
- $contents[] = $file;
289
  $filenames[] = rtrim( $file['filename'], '/' );
290
  }
291
 
@@ -299,8 +320,8 @@ class Boldgrid_Backup_Admin_Compressor_Pcl_Zip extends Boldgrid_Backup_Admin_Com
299
  *
300
  * @since 1.5.3
301
  *
302
- * @param string $filepath /home/user/boldgrid_backup/archive.zip
303
- * @param string $file wp-content/index.php
304
  * @return bool
305
  */
306
  public function extract_one( $filepath, $file ) {
@@ -333,10 +354,10 @@ class Boldgrid_Backup_Admin_Compressor_Pcl_Zip extends Boldgrid_Backup_Admin_Com
333
  *
334
  * @since 1.5.3
335
  *
336
- * @param string $filepath /home/user/boldgrid_backup/archive.zip
337
- * @param string $file wp-content/index.php
338
  * @return mixed False on failure, array on success {
339
- * Accessed via $file_contentws[0].
340
  *
341
  * @type string $filename wp-content/index.php
342
  * @type string $stored_filename wp-content/index.php
@@ -428,7 +449,7 @@ class Boldgrid_Backup_Admin_Compressor_Pcl_Zip extends Boldgrid_Backup_Admin_Com
428
  continue;
429
  }
430
 
431
- // If it's not in this format, skip it - Format: *.########-######.sql
432
  if ( 1 !== preg_match( '/\.[\d]+-[\d]+\.sql$/', $filename ) ) {
433
  continue;
434
  }
@@ -444,14 +465,14 @@ class Boldgrid_Backup_Admin_Compressor_Pcl_Zip extends Boldgrid_Backup_Admin_Com
444
  *
445
  * @since 1.5.2
446
  *
447
- * @param string $error_info
448
  * @return mixed False when no messages should be displayed, String when
449
  * returning a message to the user.
450
  */
451
  public function parse_error_info( $error_info ) {
452
- $parts = explode( '\'', $error_info );
453
  $force_php_zip = false;
454
- $messages = array();
455
 
456
  // Does not exist [code -4].
457
  if ( ! empty( $parts[2] ) && false !== strpos( $parts[2], 'code -4' ) ) {
@@ -460,6 +481,7 @@ class Boldgrid_Backup_Admin_Compressor_Pcl_Zip extends Boldgrid_Backup_Admin_Com
460
  // Check for broken symlink.
461
  if ( is_link( $path ) && ! $this->core->wp_filesystem->exists( $path ) ) {
462
  $force_php_zip = true;
 
463
  $messages[] = sprintf( __( 'PclZip encountered the following broken symlink and is unable to create a backup:<br />%1$s', 'boldgrid-backup' ), $parts[1] );
464
  }
465
  }
@@ -484,7 +506,7 @@ class Boldgrid_Backup_Admin_Compressor_Pcl_Zip extends Boldgrid_Backup_Admin_Com
484
  *
485
  * @since 1.5
486
  *
487
- * @param bool $display_errors
488
  * @return bool
489
  */
490
  public function test( $display_errors = true ) {
@@ -495,20 +517,36 @@ class Boldgrid_Backup_Admin_Compressor_Pcl_Zip extends Boldgrid_Backup_Admin_Com
495
  $backup_dir = $this->core->backup_dir->get();
496
 
497
  // Strings to help with creating test files.
498
- $test_file_contents = $str = __( 'This is a test file from BoldGrid Backup. You can delete this file.', 'boldgrid-backup' );
499
- $safe_to_delete = __( 'safe-to-delete', 'boldgrid-backup' );
500
- $test_zip_file = $this->core->test->test_prefix . '-zip';
501
- $test_filename = sprintf( '%1$s%5$s%2$s-%3$s-%4$s', $backup_dir, $test_zip_file, mt_rand(), $safe_to_delete, DIRECTORY_SEPARATOR );
502
- $zip_filepath = $test_filename . '.zip';
 
 
 
 
 
 
 
 
 
 
 
 
503
  $random_filename = $test_filename . '.txt';
504
 
505
- $cannot_touch_file = __( 'PclZip test failed. We were unable to create the following test file:<br />
 
 
506
  %1$s.<br />
507
  Please ensure your backup directory has read, write, and modify permissions.',
508
  'boldgrid-backup'
509
  );
510
 
511
- $cannot_put_contents = __( 'PclZip test failed. We were able to create the following test file, but we were unable to modify it. were unable to modify it:<br />
 
 
512
  %1$s<br />
513
  Please ensure your backup directory has read, write, and modify permissions.',
514
  'boldgrid-backup'
@@ -517,14 +555,14 @@ class Boldgrid_Backup_Admin_Compressor_Pcl_Zip extends Boldgrid_Backup_Admin_Com
517
  $touched = $this->core->wp_filesystem->touch( $random_filename );
518
  if ( ! $touched ) {
519
  $this->test_errors[] = sprintf( $cannot_touch_file, $random_filename );
520
- self::$test_result = false;
521
  return false;
522
  }
523
 
524
  $contents_put = $this->core->wp_filesystem->put_contents( $random_filename, $test_file_contents );
525
  if ( ! $contents_put ) {
526
  $this->test_errors[] = sprintf( $cannot_put_contents, $random_filename );
527
- self::$test_result = false;
528
  return false;
529
  }
530
 
@@ -541,6 +579,7 @@ class Boldgrid_Backup_Admin_Compressor_Pcl_Zip extends Boldgrid_Backup_Admin_Com
541
  $this->core->test->delete_test_files( $backup_dir );
542
 
543
  self::$test_result = true;
 
544
  return true;
545
  }
546
  }
1
  <?php
2
  /**
3
+ * File: class-boldgrid-backup-admin-compressor-pcl-zip.php
4
+ *
5
  * Pcl Zip Compressor.
6
  *
7
+ * @link https://www.boldgrid.com
8
  * @since 1.5.1
9
  *
10
  * @package Boldgrid_Backup
11
+ * @subpackage Boldgrid_Backup/admin/compressor
12
+ * @copyright BoldGrid
13
  * @version $Id$
14
+ * @author BoldGrid <support@boldgrid.com>
15
  */
16
 
17
  /**
18
+ * Class: Boldgrid_Backup_Admin_Compressor_Pcl_Zip
19
  *
20
  * @since 1.5.1
21
  */
22
  class Boldgrid_Backup_Admin_Compressor_Pcl_Zip extends Boldgrid_Backup_Admin_Compressor {
 
23
  /**
24
  * An array of errors.
25
  *
26
+ * @since 1.6.0
27
  * @access public
28
  * @var array
29
  */
47
  */
48
  public $test_errors = array();
49
 
50
+ /**
51
+ * Key.
52
+ *
53
+ * @since 1.13.0
54
+ * @access proteced
55
+ * @var string
56
+ */
57
+ protected $key = 'pcl_zip';
58
+
59
  /**
60
  * Constructor.
61
  *
62
  * @since 1.5.1
63
  *
64
+ * @param Boldgrid_Backup_Admin_Core $core Boldgrid_Backup_Admin_Core object.
65
  */
66
  public function __construct( $core ) {
67
  if ( ! class_exists( 'PclZip' ) ) {
68
+ require_once ABSPATH . '/wp-admin/includes/class-pclzip.php';
69
  }
70
 
71
  parent::__construct( $core );
85
  * # wp-content/plugins/
86
  * # wp-content/plugins/boldgrid/
87
  *
88
+ * @since 1.6.0
89
  *
90
+ * @param array $list A list of files.
91
+ * @param array $contents Contents; not used here.
92
+ * @param array $filenames Filenames.
93
+ * @param string $in_dir Current directory.
94
  * @return array An updated $contents.
95
  */
96
  public function browse_add_dirs( $list, $contents, $filenames, $in_dir ) {
97
  foreach ( $list as $key => $file ) {
98
 
99
  // These variables are very similar, both exist for readability.
100
+ $top_dir = null;
101
  $next_dir = null;
102
 
103
  if ( '.' === $in_dir ) {
104
  $top_dir = explode( '/', $file['filename'] );
105
  $top_dir = $top_dir[0];
106
 
107
+ if ( empty( $top_dir ) || in_array( $top_dir, $filenames, true ) ) {
108
  continue;
109
  }
110
  } else {
 
111
  /*
112
  * Determine if file is in directory.
113
  *
131
  $next_dir = explode( '/', $next_dir );
132
  $next_dir = $in_dir . '/' . $next_dir[0];
133
 
134
+ if ( $next_dir === $file['filename'] || in_array( $next_dir, $filenames, true ) ) {
135
  continue;
136
  }
137
  }
138
 
139
+ $dir = ! empty( $top_dir ) ? $top_dir : $next_dir;
140
+ $sudo_file = array(
141
  'filename' => $dir,
142
+ 'folder' => true,
143
  );
144
+ $contents[] = $sudo_file;
145
  $filenames[] = $dir;
146
  }
147
 
153
  *
154
  * @since 1.5.1
155
  *
156
+ * @see Boldgrid_Backup_Admin_Filelist::get_total_size()
157
+ *
158
+ * @param array $filelist File list.
159
  * @param array $info {
160
  * An array of data about the backup archive we are generating.
161
  *
168
  * }
169
  */
170
  public function archive_files( $filelist, &$info ) {
 
 
171
  if ( $info['dryrun'] ) {
172
  return true;
173
  }
181
  );
182
  }
183
 
184
+ // Prevent this process from ending; allow the archive to be completed.
185
+ ignore_user_abort( true );
186
+ set_time_limit( 0 );
187
+
188
  /*
189
  * Create our $new_filelist.
190
  *
192
  * is an array of arrays, so we need to convert to simply an array of
193
  * strings (filenames to archive).
194
  */
195
+ $total_size_archived = 0;
196
+ $new_filelist = [];
197
+ foreach ( $filelist as $file ) {
198
  // Don't add the database dump at this time, it will be added later.
199
  if ( ! empty( $this->core->db_dump_filepath ) && $file[0] === $this->core->db_dump_filepath ) {
200
  continue;
201
  }
202
 
203
+ $total_size_archived += empty( $file[2] ) ? 0 : $file[2];
204
+
205
  $new_filelist[] = $file[0];
206
  }
207
 
208
+ Boldgrid_Backup_Admin_In_Progress_Data::set_arg( 'step', 3 );
209
+ Boldgrid_Backup_Admin_In_Progress_Data::set_arg( 'total_size_archived', $total_size_archived );
210
+ Boldgrid_Backup_Admin_In_Progress_Data::set_arg( 'total_size_archived_size_format', size_format( $total_size_archived, 2 ) );
211
+
212
+ $status = $archive->add(
213
+ $new_filelist,
214
  PCLZIP_OPT_REMOVE_PATH, ABSPATH
215
  );
216
 
240
  $status = $archive->add( $this->core->db_dump_filepath, PCLZIP_OPT_REMOVE_ALL_PATH );
241
  if ( 0 === $status ) {
242
  return array(
243
+ 'error' => sprintf( 'Cannot add database dump to ZIP archive file: %1$s', $archive->errorInfo() ),
244
  );
245
  }
246
  }
247
 
248
+ Boldgrid_Backup_Admin_In_Progress_Data::delete_arg( 'step' );
249
+
250
  $this->wp_filesystem->chdir( $cwd );
251
 
252
  return true;
255
  /**
256
  * Get the contents of a zip file.
257
  *
258
+ * @param string $filepath File path.
259
+ * @param string $in_dir Current directory.
260
  * @return array
261
  */
262
  public function browse( $filepath, $in_dir = '.' ) {
292
  * https://pastebin.com/bjQZYcAt
293
  */
294
  foreach ( $list as $key => $file ) {
 
295
  /*
296
  * Calculate the parent directory this file / folder belongs to.
297
  *
306
  continue;
307
  }
308
 
309
+ $contents[] = $file;
310
  $filenames[] = rtrim( $file['filename'], '/' );
311
  }
312
 
320
  *
321
  * @since 1.5.3
322
  *
323
+ * @param string $filepath Archive path, such as "/home/user/boldgrid_backup/archive.zip".
324
+ * @param string $file A file path in the archive file, such as "wp-content/index.php".
325
  * @return bool
326
  */
327
  public function extract_one( $filepath, $file ) {
354
  *
355
  * @since 1.5.3
356
  *
357
+ * @param string $filepath Archive path, such as "/home/user/boldgrid_backup/archive.zip".
358
+ * @param string $file A file path in the archive file, such as "wp-content/index.php".
359
  * @return mixed False on failure, array on success {
360
+ * Accessed via $file_contents[0].
361
  *
362
  * @type string $filename wp-content/index.php
363
  * @type string $stored_filename wp-content/index.php
449
  continue;
450
  }
451
 
452
+ // If it's not in this format, skip it - Format: "*.########-######.sql".
453
  if ( 1 !== preg_match( '/\.[\d]+-[\d]+\.sql$/', $filename ) ) {
454
  continue;
455
  }
465
  *
466
  * @since 1.5.2
467
  *
468
+ * @param string $error_info Error message.
469
  * @return mixed False when no messages should be displayed, String when
470
  * returning a message to the user.
471
  */
472
  public function parse_error_info( $error_info ) {
473
+ $parts = explode( '\'', $error_info );
474
  $force_php_zip = false;
475
+ $messages = array();
476
 
477
  // Does not exist [code -4].
478
  if ( ! empty( $parts[2] ) && false !== strpos( $parts[2], 'code -4' ) ) {
481
  // Check for broken symlink.
482
  if ( is_link( $path ) && ! $this->core->wp_filesystem->exists( $path ) ) {
483
  $force_php_zip = true;
484
+ // translators: 1: File path.
485
  $messages[] = sprintf( __( 'PclZip encountered the following broken symlink and is unable to create a backup:<br />%1$s', 'boldgrid-backup' ), $parts[1] );
486
  }
487
  }
506
  *
507
  * @since 1.5
508
  *
509
+ * @param bool $display_errors Display errors; default is TRUE.
510
  * @return bool
511
  */
512
  public function test( $display_errors = true ) {
517
  $backup_dir = $this->core->backup_dir->get();
518
 
519
  // Strings to help with creating test files.
520
+ $test_file_contents = sprintf(
521
+ // translators: 1: Plugin title.
522
+ __( 'This is a test file from %1$s. You can delete this file.', 'boldgrid-backup' ),
523
+ BOLDGRID_BACKUP_TITLE
524
+ );
525
+
526
+ $safe_to_delete = __( 'safe-to-delete', 'boldgrid-backup' );
527
+ $test_zip_file = $this->core->test->test_prefix . '-zip';
528
+ $test_filename = sprintf(
529
+ '%1$s%5$s%2$s-%3$s-%4$s',
530
+ $backup_dir,
531
+ $test_zip_file,
532
+ mt_rand(),
533
+ $safe_to_delete,
534
+ DIRECTORY_SEPARATOR
535
+ );
536
+ $zip_filepath = $test_filename . '.zip';
537
  $random_filename = $test_filename . '.txt';
538
 
539
+ // translators: 1: File path.
540
+ $cannot_touch_file = __(
541
+ 'PclZip test failed. We were unable to create the following test file:<br />
542
  %1$s.<br />
543
  Please ensure your backup directory has read, write, and modify permissions.',
544
  'boldgrid-backup'
545
  );
546
 
547
+ // translators: 1: File path.
548
+ $cannot_put_contents = __(
549
+ 'PclZip test failed. We were able to create the following test file, but we were unable to modify it. were unable to modify it:<br />
550
  %1$s<br />
551
  Please ensure your backup directory has read, write, and modify permissions.',
552
  'boldgrid-backup'
555
  $touched = $this->core->wp_filesystem->touch( $random_filename );
556
  if ( ! $touched ) {
557
  $this->test_errors[] = sprintf( $cannot_touch_file, $random_filename );
558
+ self::$test_result = false;
559
  return false;
560
  }
561
 
562
  $contents_put = $this->core->wp_filesystem->put_contents( $random_filename, $test_file_contents );
563
  if ( ! $contents_put ) {
564
  $this->test_errors[] = sprintf( $cannot_put_contents, $random_filename );
565
+ self::$test_result = false;
566
  return false;
567
  }
568
 
579
  $this->core->test->delete_test_files( $backup_dir );
580
 
581
  self::$test_result = true;
582
+
583
  return true;
584
  }
585
  }
admin/compressor/class-boldgrid-backup-admin-compressor-php-zip.php ADDED
@@ -0,0 +1,352 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File: class-boldgrid-backup-admin-compressor-php-zip.php
4
+ *
5
+ * PHP Zip Compressor.
6
+ *
7
+ * @link https://www.boldgrid.com
8
+ * @since 1.5.1
9
+ *
10
+ * @package Boldgrid_Backup
11
+ * @subpackage Boldgrid_Backup/admin/compressor
12
+ * @copyright BoldGrid
13
+ * @version $Id$
14
+ * @author BoldGrid <support@boldgrid.com>
15
+ */
16
+
17
+ /**
18
+ * Class: Boldgrid_Backup_Admin_Compressor_Php_Zip
19
+ *
20
+ * @since 1.5.1
21
+ */
22
+ class Boldgrid_Backup_Admin_Compressor_Php_Zip extends Boldgrid_Backup_Admin_Compressor {
23
+ /**
24
+ * An array of directories we've added to the zip.
25
+ *
26
+ * @since 1.6.0
27
+ * @access public
28
+ * @var array
29
+ */
30
+ public $dirs = array();
31
+
32
+ /**
33
+ * The status of our test result.
34
+ *
35
+ * @since 1.5.1
36
+ * @access public
37
+ * @var mixed|bool|null
38
+ */
39
+ public static $test_result = null;
40
+
41
+ /**
42
+ * An array of any errors received while testing.
43
+ *
44
+ * @since 1.5.1
45
+ * @access public
46
+ * @var array
47
+ */
48
+ public $test_errors = array();
49
+
50
+ /**
51
+ * An instance of ZipArchive.
52
+ *
53
+ * @since 1.5.1
54
+ * @var ZipArchive
55
+ */
56
+ public $zip;
57
+
58
+ /**
59
+ * Key.
60
+ *
61
+ * @since 1.13.0
62
+ * @access protected
63
+ * @var string
64
+ */
65
+ protected $key = 'php_zip';
66
+
67
+ /**
68
+ * Add a file's directories to the zip.
69
+ *
70
+ * When you add a file, the parent directories are not always explicitly
71
+ * created. For example, if you add wp-content/themes/pavilion/index.php the
72
+ * wp-content directory (and so forth) is not explicity added to the zip.
73
+ *
74
+ * @since 1.6.0
75
+ *
76
+ * @param string $file A file path.
77
+ */
78
+ public function add_dir( $file ) {
79
+ $add_directory = '';
80
+ $dirs = explode( DIRECTORY_SEPARATOR, dirname( $file ) );
81
+
82
+ foreach ( $dirs as $key => $dir ) {
83
+ if ( 0 === $key ) {
84
+ $add_directory = $dir;
85
+ } else {
86
+ $add_directory .= '/' . $dir;
87
+ }
88
+
89
+ if ( ! in_array( $add_directory, $this->dirs, true ) ) {
90
+ $this->zip->addEmptyDir( $add_directory );
91
+ $this->dirs[] = $add_directory;
92
+ }
93
+ }
94
+ }
95
+
96
+ /**
97
+ * Archive files.
98
+ *
99
+ * @since 1.5.1
100
+ *
101
+ * @see Boldgrid_Backup_Admin_Filelist::get_total_size()
102
+ *
103
+ * @param array $filelist {
104
+ * File details.
105
+ *
106
+ * @type string 0 Path. Example: ""/home/user/public_html/readme.html".
107
+ * @type string 1 basename. Example: "readme.html".
108
+ * @type int 2 File size (in bytes). Example: "7413".
109
+ * @type string 3 File type. Examples: "d", "f".
110
+ * }
111
+ * @param array $info {
112
+ * Data about the backup archive we are generating.
113
+ *
114
+ * @type string mode backup
115
+ * @type bool dryrun
116
+ * @type string compressor php_zip
117
+ * @type int filesize 0
118
+ * @type bool save 1
119
+ * @type int total_size 0
120
+ * }
121
+ */
122
+ public function archive_files( $filelist, &$info ) {
123
+ // Init vars used for our "in progress" bar.
124
+ $number_files_archived = 0;
125
+ $total_size_archived = 0;
126
+ $number_files_todo = count( $filelist );
127
+ $last_x_files = array();
128
+
129
+ if ( $info['dryrun'] ) {
130
+ return true;
131
+ }
132
+
133
+ // Prevent this process from ending; allow the archive to be completed.
134
+ ignore_user_abort( true );
135
+ set_time_limit( 0 );
136
+
137
+ $this->zip = new ZipArchive();
138
+
139
+ $status = $this->zip->open( $info['filepath'], ZipArchive::CREATE );
140
+
141
+ if ( ! $status ) {
142
+ return array(
143
+ 'error' => 'Cannot open ZIP archive file "' . $info['filepath'] . '".',
144
+ 'error_code' => $status,
145
+ 'error_message' => Boldgrid_Backup_Admin_Utility::translate_zip_error( $status ),
146
+ );
147
+ }
148
+
149
+ $has_setexternalattributesname = method_exists( $this->zip, 'setExternalAttributesName' );
150
+
151
+ foreach ( $filelist as $fileinfo ) {
152
+ $is_dir = ! empty( $fileinfo[3] ) && 'd' === $fileinfo[3];
153
+
154
+ switch ( $is_dir ) {
155
+ case true:
156
+ $this->zip->addEmptyDir( $fileinfo[1] );
157
+ break;
158
+ case false:
159
+ if ( ! is_readable( $fileinfo[0] ) ) {
160
+ $info['backup_errors'][] = sprintf(
161
+ // translators: 1 The path to a file that was unable to be added to the backup.
162
+ __( 'Permission defined. Unable to add the following file to your backup: %1$s', 'boldgrid-backup' ),
163
+ $fileinfo[0]
164
+ );
165
+ continue 2;
166
+ } else {
167
+ $this->zip->addFile( $fileinfo[0], $fileinfo[1] );
168
+ $this->add_dir( $fileinfo[1] );
169
+ }
170
+ break;
171
+ }
172
+
173
+ /*
174
+ * ZipArchive::setExternalAttributesName() is avaiable in PHP >= 5.6.
175
+ * If available, use the method to set the permissions for items in the ZIP archive.
176
+ * By default, items in a ZIP file are extracted with loose (777/666) modes, which can
177
+ * cause issues on Linux systems using suEXEX/suPHP or other mechanisms requiring
178
+ * tighter (755/644; world non-writable permissions) modes on directories and files.
179
+ */
180
+ if ( $has_setexternalattributesname ) {
181
+ $this->zip->setExternalAttributesName(
182
+ $is_dir ? $fileinfo[1] . '/' : $fileinfo[1],
183
+ ZipArchive::OPSYS_UNIX,
184
+ fileperms( $fileinfo[0] ) << 16
185
+ );
186
+ }
187
+
188
+ $number_files_archived++;
189
+ $total_size_archived += empty( $fileinfo[2] ) ? 0 : $fileinfo[2];
190
+
191
+ /*
192
+ * If applicable, add this file to the list of files archived that we show the user.
193
+ *
194
+ * To give the user a more broad sense of the files being added, our list only contains
195
+ * every 20th file.
196
+ *
197
+ * Our list is only 5 long because we make hook into the heartbeat every 5 seconds to grab
198
+ * the last 5 files, and we display each file for 1 second.
199
+ */
200
+ if ( 0 === $number_files_archived % 20 ) {
201
+ $last_x_files[] = $fileinfo[1];
202
+ if ( count( $last_x_files ) > 5 ) {
203
+ array_shift( $last_x_files );
204
+ }
205
+ }
206
+
207
+ /*
208
+ * Update our "in progress" data.
209
+ *
210
+ * To prevent excessive calls to update options, we only update our in progress data every
211
+ * 100 files.
212
+ */
213
+ $all_files_archived = $number_files_archived >= $number_files_todo;
214
+ if ( 0 === $number_files_archived % 100 || $all_files_archived ) {
215
+ Boldgrid_Backup_Admin_In_Progress_Data::set_arg( 'total_files_done', $number_files_archived );
216
+ Boldgrid_Backup_Admin_In_Progress_Data::set_arg( 'last_files', $last_x_files );
217
+ Boldgrid_Backup_Admin_In_Progress_Data::set_arg( 'total_size_archived', $total_size_archived );
218
+ Boldgrid_Backup_Admin_In_Progress_Data::set_arg( 'total_size_archived_size_format', size_format( $total_size_archived, 2 ) );
219
+ Boldgrid_Backup_Admin_In_Progress_Data::set_arg( 'step', 2 );
220
+ }
221
+ }
222
+
223
+ $this->core->logger->add(
224
+ sprintf(
225
+ 'Total files / size archived: %1$s / %2$s (%3$s)',
226
+ $number_files_archived,
227
+ $total_size_archived,
228
+ size_format( $total_size_archived, 2 )
229
+ )
230
+ );
231
+
232
+ /*
233
+ * We're done archiving all files.
234
+ *
235
+ * Empty out the "last files archived" data, and set an appropriate status.
236
+ */
237
+ Boldgrid_Backup_Admin_In_Progress_Data::delete_arg( 'last_files' );
238
+ Boldgrid_Backup_Admin_In_Progress_Data::set_arg( 'step', 3 );
239
+
240
+ /*
241
+ * Verify files before write/close. Delete any invalid file indicies in the ZIP index.
242
+ *
243
+ * In some scenarios, a file will be added above, but then deleted before the zip->close()
244
+ * call below. For example, while a backup is in progress, users may be editing pages and
245
+ * on save, cache files may get deleted. If the cache file was added to the zip above, and then
246
+ * deleted before the zip->close() below, we're going to have a problem.
247
+ *
248
+ * There is one file path outside of ABSPATH; the database dump file.
249
+ * The full path of each file is determined by checking if it is the dump file or not.
250
+ *
251
+ * @todo The user is not notified if a file is removed below.
252
+ */
253
+ for ( $i = 0; $i < $this->zip->numFiles; $i++ ) {
254
+ $filename = $this->zip->getNameIndex( $i );
255
+ $filepath = false !== strpos( $this->core->db_dump_filepath, $filename ) ?
256
+ $this->core->db_dump_filepath : ABSPATH . $filename;
257
+
258
+ if ( ! $this->core->wp_filesystem->is_readable( $filepath ) ) {
259
+ $this->zip->deleteIndex( $i );
260
+ }
261
+ }
262
+
263
+ $this->core->logger->add( 'Starting to close the zip file.' );
264
+ $this->core->logger->add_memory();
265
+
266
+ $close = $this->zip->close();
267
+
268
+ $this->core->logger->add( 'Finished closing the zip file.' );
269
+ $this->core->logger->add_memory();
270
+
271
+ Boldgrid_Backup_Admin_In_Progress_Data::delete_arg( 'step' );
272
+
273
+ if ( ! $close ) {
274
+ return array(
275
+ 'error' => 'Cannot close ZIP archive file "' . $info['filepath'] . '".',
276
+ );
277
+ }
278
+
279
+ return true;
280
+ }
281
+
282
+ /**
283
+ * Determine if ZipArchive is available.
284
+ *
285
+ * @since 1.5.2
286
+ */
287
+ public static function is_extension_available() {
288
+ return extension_loaded( 'zip' ) && class_exists( 'ZipArchive' );
289
+ }
290
+
291
+ /**
292
+ * Test the functionality of php_zip.
293
+ *
294
+ * @since 1.5
295
+ *
296
+ * @return bool
297
+ */
298
+ public function test() {
299
+ if ( null !== self::$test_result ) {
300
+ return self::$test_result;
301
+ }
302
+
303
+ $backup_dir = $this->core->backup_dir->get();
304
+
305
+ $test_file_contents = sprintf(
306
+ // translators: 1: Plugin title.
307
+ __( 'This is a test file from %1$s. You can delete this file.', 'boldgrid-backup' ),
308
+ BOLDGRID_BACKUP_TITLE
309
+ );
310
+
311
+ // translators: 1: A filename.
312
+ $cannot_open_zip = __( 'Unable to create zip file: %1$s', 'boldgrid-backup' );
313
+
314
+ // translators: 1: Backup directory path.
315
+ $cannot_close_zip = __( 'When testing ZipArchive functionality, we are able to create a zip file and add files to it, but we were unable to close the zip file.<br /><strong>Please be sure the following backup directory has modify permissions</strong>:<br />%1$s', 'boldgrid-backup' );
316
+ $safe_to_delete = __( 'safe-to-delete', 'boldgrid-backup' );
317
+ $test_zip_file = $this->core->test->test_prefix . '-zip';
318
+ $test_filename = sprintf( '%1$s%5$s%2$s-%3$s-%4$s', $backup_dir, $test_zip_file, mt_rand(), $safe_to_delete, DIRECTORY_SEPARATOR );
319
+ $zip_filepath = $test_filename . '.zip';
320
+ $random_filename = $test_filename . '.txt';
321
+
322
+ $zip = new ZipArchive();
323
+ $status = $zip->open( $zip_filepath, ZipArchive::CREATE );
324
+
325
+ if ( ! $status ) {
326
+ $this->test_errors[] = sprintf( $cannot_open_zip, $zip_filepath );
327
+ self::$test_result = false;
328
+
329
+ return false;
330
+ }
331
+
332
+ $this->core->wp_filesystem->touch( $random_filename );
333
+ $this->core->wp_filesystem->put_contents( $random_filename, $test_file_contents );
334
+
335
+ $zip->addFile( $random_filename, 'test.txt' );
336
+
337
+ $zip_closed = @$zip->close(); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged
338
+
339
+ $this->core->test->delete_test_files( $backup_dir );
340
+
341
+ if ( ! $zip_closed ) {
342
+ $this->test_errors[] = sprintf( $cannot_close_zip, $backup_dir );
343
+ self::$test_result = false;
344
+
345
+ return false;
346
+ }
347
+
348
+ self::$test_result = true;
349
+
350
+ return true;
351
+ }
352
+ }
admin/compressor/class-boldgrid-backup-admin-compressor-system-zip-temp-folder.php ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File: class-boldgrid-backup-admin-compressor-system-zip-temp-folder.php
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.13.0
7
+ *
8
+ * @package Boldgrid_Backup
9
+ * @subpackage Boldgrid_Backup/admin/compressor
10
+ * @copyright BoldGrid
11
+ * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
+ */
14
+
15
+ /**
16
+ * Class: Boldgrid_Backup_Admin_Compressor_System_Zip_Temp_Folder
17
+ *
18
+ * @since 1.13.0
19
+ */
20
+ class Boldgrid_Backup_Admin_Compressor_System_Zip_Temp_Folder {
21
+ /**
22
+ * An instance of core.
23
+ *
24
+ * @since 1.13.0
25
+ * @access private
26
+ * @var Boldgrid_Backup_Admin_Core
27
+ */
28
+ private $core;
29
+
30
+ /**
31
+ * The name of the temporary folder where the compression will take place.
32
+ *
33
+ * @since 1.13.0
34
+ * @access private
35
+ * @var string
36
+ */
37
+ private static $name = 'system-zip-temp';
38
+
39
+ /**
40
+ * Constructor.
41
+ *
42
+ * @since 1.13.0
43
+ */
44
+ public function __construct() {
45
+ $this->core = apply_filters( 'boldgrid_backup_get_core', null );
46
+ }
47
+
48
+ /**
49
+ * Create the temp folder.
50
+ *
51
+ * @since 1.13.0
52
+ *
53
+ * @return bool True on success.
54
+ */
55
+ public function create() {
56
+ return $this->core->wp_filesystem->mkdir( self::get_path() );
57
+ }
58
+
59
+ /**
60
+ * Delete the temp folder.
61
+ *
62
+ * @since 1.13.0
63
+ *
64
+ * @return bool True on success.
65
+ */
66
+ public function delete() {
67
+ return $this->core->wp_filesystem->rmdir( self::get_path() );
68
+ }
69
+
70
+ /**
71
+ * Get the path to our temp folder.
72
+ *
73
+ * @since 1.13.0
74
+ *
75
+ * @return string
76
+ */
77
+ public static function get_path() {
78
+ $core = apply_filters( 'boldgrid_backup_get_core', null );
79
+
80
+ return $core->backup_dir->get_path_to( self::$name );
81
+ }
82
+ }
admin/compressor/class-boldgrid-backup-admin-compressor-system-zip-test.php ADDED
@@ -0,0 +1,303 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File: class-boldgrid-backup-admin-compressor-system-zip-test.php
4
+ *
5
+ * System Zip Compressor Tester.
6
+ *
7
+ * @link https://www.boldgrid.com
8
+ * @since 1.13.0
9
+ *
10
+ * @package Boldgrid_Backup
11
+ * @subpackage Boldgrid_Backup/admin/compressor
12
+ * @copyright BoldGrid
13
+ * @version $Id$
14
+ * @author BoldGrid <support@boldgrid.com>
15
+ */
16
+
17
+ /**
18
+ * Class: Boldgrid_Backup_Admin_Compressor_System_Zip_Test
19
+ *
20
+ * @since 1.13.0
21
+ */
22
+ class Boldgrid_Backup_Admin_Compressor_System_Zip_Test {
23
+ /**
24
+ * An instance of core.
25
+ *
26
+ * @since 1.13.0
27
+ * @access private
28
+ * @var Boldgrid_Backup_Admin_Core
29
+ */
30
+ private $core;
31
+
32
+ /**
33
+ * An error message.
34
+ *
35
+ * @since 1.13.0
36
+ * @access private
37
+ * @var string
38
+ */
39
+ private $error;
40
+
41
+ /**
42
+ * An array of files that will make up the self::filelist_filepath file.
43
+ *
44
+ * @since 1.13.0
45
+ * @access private
46
+ * @var array
47
+ */
48
+ private $filelist = [];
49
+
50
+ /**
51
+ * A filepath to the file containing a list of files we will zip.
52
+ *
53
+ * @since 1.13.0
54
+ * @access private
55
+ * @var array
56
+ */
57
+ private $filelist_filepath;
58
+
59
+ /**
60
+ * An array of files and folders that we will create.
61
+ *
62
+ * @since 1.13.0
63
+ * @access private
64
+ * @var array
65
+ */
66
+ private $items;
67
+
68
+ /**
69
+ * A path to a directory we will be creating, filling with files, and zipping.
70
+ *
71
+ * @since 1.13.0
72
+ * @access private
73
+ * @var string
74
+ */
75
+ private $test_dir;
76
+
77
+ /**
78
+ * A filepath to the zip we will be creating.
79
+ *
80
+ * @since 1.13.0
81
+ * @access private
82
+ * @var string
83
+ */
84
+ private $zip_filepath;
85
+
86
+ /**
87
+ * Constructor.
88
+ *
89
+ * @since 1.13.0
90
+ *
91
+ * @param Boldgrid_Backup_Admin_Core $core
92
+ */
93
+ public function __construct( Boldgrid_Backup_Admin_Core $core ) {
94
+ $this->core = $core;
95
+
96
+ $this->items = [
97
+ [
98
+ 'type' => 'f',
99
+ 'name' => 'file.txt',
100
+ ],
101
+ [
102
+ 'type' => 'd',
103
+ 'name' => 'folder-empty',
104
+ ],
105
+ [
106
+ 'type' => 'd',
107
+ 'name' => 'folder-1',
108
+ ],
109
+ [
110
+ 'type' => 'f',
111
+ 'name' => 'folder-1/file-1.txt',
112
+ ],
113
+ [
114
+ 'type' => 'd',
115
+ 'name' => 'folder-1/folder-1a',
116
+ ],
117
+ [
118
+ 'type' => 'd',
119
+ 'name' => 'folder-1/folder-1a/folder-1a.txt',
120
+ ],
121
+ ];
122
+
123
+ $this->zip_filepath = $this->core->backup_dir->get_path_to( $this->core->test->test_prefix . 'system-zip-test.zip' );
124
+ $this->filelist_filepath = $this->core->backup_dir->get_path_to( $this->core->test->test_prefix . 'system-zip-filelist.txt' );
125
+ $this->test_dir = $this->core->backup_dir->get_path_to( $this->core->test->test_prefix . 'system-zip-test' );
126
+ }
127
+
128
+ /**
129
+ * Get our error message.
130
+ *
131
+ * @since 1.13.0
132
+ *
133
+ * @return string
134
+ */
135
+ public function get_error() {
136
+ return $this->error;
137
+ }
138
+
139
+ /**
140
+ * Create and setup our test directory.
141
+ *
142
+ * We will be zipping up this directory.
143
+ *
144
+ * @since 1.13.0
145
+ *
146
+ * @return bool True on success.
147
+ */
148
+ private function test_dir_create() {
149
+ // Create our test directory.
150
+ if ( ! $this->core->wp_filesystem->mkdir( $this->test_dir ) ) {
151
+ $this->error = sprintf(
152
+ // translators: 1 The name of a folder that could not be created.
153
+ esc_html__( 'Unable to create test directory: %1$s', 'boldgrid-backup' ),
154
+ $this->test_dir
155
+ );
156
+
157
+ return false;
158
+ }
159
+
160
+ // Create all the files. Abort if one could not be.
161
+ foreach ( $this->items as $item ) {
162
+ $created = false;
163
+
164
+ switch ( $item['type'] ) {
165
+ case 'd':
166
+ $created = $this->core->wp_filesystem->mkdir( $this->test_dir . DIRECTORY_SEPARATOR . $item['name'] );
167
+ break;
168
+ case 'f':
169
+ $created = $this->core->wp_filesystem->touch( $this->test_dir . DIRECTORY_SEPARATOR . $item['name'] );
170
+ break;
171
+ }
172
+
173
+ // Add this item to our filelist (a .txt file containing a list of files to backup).
174
+ $this->filelist[] = $item['name'];
175
+
176
+ // Above if we could not create a file.
177
+ if ( ! $created ) {
178
+ $this->error = sprintf(
179
+ // translators: 1 The name of a file that could not be created.
180
+ esc_html__( 'Unable to create test file: %1$s', 'boldgrid-backup' ),
181
+ $item['name']
182
+ );
183
+
184
+ return false;
185
+ }
186
+ }
187
+
188
+ // Save the filelist.
189
+ if ( ! $this->core->wp_filesystem->put_contents( $this->filelist_filepath, implode( PHP_EOL, $this->filelist ) ) ) {
190
+ $this->error = esc_html__( 'Unable to create filelist.txt', 'boldgrid-backup' );
191
+
192
+ return false;
193
+ }
194
+
195
+ return true;
196
+ }
197
+
198
+ /**
199
+ * Restore our test directory from zip and make sure everything was restored.
200
+ *
201
+ * @since 1.13.0
202
+ *
203
+ * @return bool True on success.
204
+ */
205
+ private function test_dir_restore() {
206
+ // Delete the folder we zipped and make sure it's gone.
207
+ if ( ! $this->core->wp_filesystem->delete( $this->test_dir, true ) ) {
208
+ $this->error = esc_html__( 'Unable to delete test directory.', 'boldgrid-backup' );
209
+ return false;
210
+ }
211
+
212
+ // Create our test directory again.
213
+ if ( ! $this->core->wp_filesystem->mkdir( $this->test_dir ) ) {
214
+ $this->error = esc_html__( 'Unable to recreate test directory.', 'boldgrid-backup' );
215
+ return false;
216
+ }
217
+
218
+ // Move our zip file to our test directory.
219
+ if ( ! $this->core->wp_filesystem->move( $this->zip_filepath, $this->test_dir . DIRECTORY_SEPARATOR . basename( $this->zip_filepath ) ) ) {
220
+ $this->error = esc_html__( 'Unable to move zip to test directory.', 'boldgrid-backup' );
221
+ return false;
222
+ }
223
+
224
+ // Unzip.
225
+ $this->core->execute_command( 'cd ' . $this->test_dir . '; unzip ' . basename( $this->zip_filepath ) );
226
+ foreach ( $this->items as $item ) {
227
+ $path = $this->test_dir . DIRECTORY_SEPARATOR . $item['name'];
228
+
229
+ if ( ! $this->core->wp_filesystem->exists( $path ) ) {
230
+ $this->error = esc_html__( 'Unable to restore all files and folders.', 'boldgrid-backup' );
231
+ return false;
232
+ }
233
+ }
234
+
235
+ return true;
236
+ }
237
+
238
+ /**
239
+ * Zip up our test directory.
240
+ *
241
+ * @since 1.13.0
242
+ *
243
+ * @return bool True on success.
244
+ */
245
+ private function test_dir_zip() {
246
+ // Zip everything up and make sure it worked.
247
+ $this->core->execute_command( 'cd ' . $this->test_dir . '; zip ' . $this->zip_filepath . ' -@ < ' . $this->filelist_filepath );
248
+ if ( ! $this->core->wp_filesystem->exists( $this->zip_filepath ) ) {
249
+ $this->error = esc_html__( 'Unable to create zip file.', 'boldgrid-backup' );
250
+ return false;
251
+ }
252
+
253
+ return true;
254
+ }
255
+
256
+ /**
257
+ * Determine if system_zip is working as expected.
258
+ *
259
+ * On average, this takes 0.019 seconds to complete.
260
+ *
261
+ * @since 1.13.0
262
+ *
263
+ * @param bool $force Whether to run this test or get results from transient.
264
+ * @return bool True on success.
265
+ */
266
+ public function run( $force = false ) {
267
+ // Force a fresh test if we're on the preflight check page.
268
+ $force = Boldgrid_Backup_Admin_Utility::is_admin_page( 'boldgrid-backup-test' ) ? true : $force;
269
+
270
+ $pass = 1;
271
+
272
+ $transient_key = 'boldgrid_backup_system_zip_test';
273
+ $transient_value = get_transient( $transient_key );
274
+
275
+ if ( ! $force && false !== $transient_value ) {
276
+ return $transient_value;
277
+ }
278
+
279
+ // Before and after running the test, delete test files created.
280
+ $this->core->test->delete_test_files( $this->core->backup_dir->get() );
281
+
282
+ // This is the beef of the test, where we actually test things.
283
+ if ( ! $this->core->execute_command( '/usr/bin/zip -v ' ) ) {
284
+ $this->error = __( '/usr/bin/zip is not available.', 'boldgrid-backup' );
285
+ $pass = 0;
286
+ } elseif ( ! $this->test_dir_create() ) {
287
+ // Create our test directory.
288
+ $pass = 0;
289
+ } elseif ( ! $this->test_dir_zip() ) {
290
+ // Zip up our test directory.
291
+ $pass = 0;
292
+ } elseif ( ! $this->test_dir_restore() ) {
293
+ // Restore our test directory.
294
+ $pass = 0;
295
+ }
296
+
297
+ $this->core->test->delete_test_files( $this->core->backup_dir->get() );
298
+
299
+ set_transient( $transient_key, $pass, 24 * HOUR_IN_SECONDS );
300
+
301
+ return ! empty( $pass );
302
+ }
303
+ }
admin/compressor/class-boldgrid-backup-admin-compressor-system-zip.php ADDED
@@ -0,0 +1,227 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File: class-boldgrid-backup-admin-compressor-system-zip.php
4
+ *
5
+ * System Zip Compressor.
6
+ *
7
+ * @link https://www.boldgrid.com
8
+ * @since 1.13.0
9
+ *
10
+ * @package Boldgrid_Backup
11
+ * @subpackage Boldgrid_Backup/admin/compressor
12
+ * @copyright BoldGrid
13
+ * @version $Id$
14
+ * @author BoldGrid <support@boldgrid.com>
15
+ */
16
+
17
+ /**
18
+ * Class: Boldgrid_Backup_Admin_Compressor_System_Zip
19
+ *
20
+ * @since 1.13.0
21
+ */
22
+ class Boldgrid_Backup_Admin_Compressor_System_Zip extends Boldgrid_Backup_Admin_Compressor {
23
+ /**
24
+ * An array of files that should be archived.
25
+ *
26
+ * @since 1.13.0
27
+ * @access private
28
+ * @var array {
29
+ * An array of files.
30
+ *
31
+ * @type string 0 Path. Example: ""/home/user/public_html/readme.html".
32
+ * @type string 1 basename. Example: "readme.html".
33
+ * @type int 2 File size (in bytes). Example: "7413".
34
+ * @type string 3 File type. Examples: "d", "f".
35
+ * }
36
+ */
37
+ private $filelist = [];
38
+
39
+ /**
40
+ * The filepath to our text file holding list of files to archive.
41
+ *
42
+ * @since 1.13.0
43
+ * @access private
44
+ * @var string
45
+ */
46
+ private $filelist_path;
47
+
48
+ /**
49
+ * The filepath to the zip file.
50
+ *
51
+ * @since 1.13.0
52
+ * @access PRIVATE
53
+ * @var string
54
+ */
55
+ private $filepath;
56
+
57
+ /**
58
+ * The temporary folder used when saving a zip file.
59
+ *
60
+ * @since 1.13.0
61
+ * @access private
62
+ * @var Boldgrid_Backup_Admin_Compressor_System_Zip_Temp_Folder
63
+ */
64
+ private $temp_folder;
65
+
66
+ /**
67
+ * Key.
68
+ *
69
+ * @since 1.13.0
70
+ * @access protected
71
+ * @var string
72
+ */
73
+ protected $key = 'system_zip';
74
+
75
+ /**
76
+ * Constructor.
77
+ *
78
+ * @since 1.13.0
79
+ */
80
+ public function __construct() {
81
+ $core = apply_filters( 'boldgrid_backup_get_core', null );
82
+ parent::__construct( $core );
83
+
84
+ $this->temp_folder = new Boldgrid_Backup_Admin_Compressor_System_Zip_Temp_Folder();
85
+ }
86
+
87
+ /**
88
+ * Archive files.
89
+ *
90
+ * @since 1.5.1
91
+ *
92
+ * @see Boldgrid_Backup_Admin_Filelist::get_total_size()
93
+ *
94
+ * @param array $filelist {
95
+ * File details.
96
+ *
97
+ * @type string 0 Path. Example: ""/home/user/public_html/readme.html".
98
+ * @type string 1 basename. Example: "readme.html".
99
+ * @type int 2 File size (in bytes). Example: "7413".
100
+ * @type string 3 File type. Examples: "d", "f".
101
+ * }
102
+ * @param array $info {
103
+ * Data about the backup archive we are generating.
104
+ *
105
+ * @type string mode backup
106
+ * @type bool dryrun
107
+ * @type string compressor php_zip
108
+ * @type int filesize 0
109
+ * @type bool save 1
110
+ * @type int total_size 0
111
+ * }
112
+ */
113
+ public function archive_files( $filelist, &$info ) {
114
+ if ( $info['dryrun'] ) {
115
+ return true;
116
+ }
117
+
118
+ // Prevent this process from ending; allow the archive to be completed.
119
+ ignore_user_abort( true );
120
+ set_time_limit( 0 );
121
+
122
+ $this->filelist = $filelist;
123
+
124
+ $this->filepath = $info['filepath'];
125
+
126
+ $this->filelist_create();
127
+
128
+ Boldgrid_Backup_Admin_In_Progress_Data::set_arg( 'step', 3 );
129
+
130
+ $this->zip();
131
+
132
+ $this->zip_sql();
133
+
134
+ Boldgrid_Backup_Admin_In_Progress_Data::delete_arg( 'step' );
135
+
136
+ // Actions to take when we're all done / cleanup.
137
+ $this->core->wp_filesystem->delete( $this->filelist_path );
138
+
139
+ return true;
140
+ }
141
+
142
+ /**
143
+ * Create the file containing a list of files to backup.
144
+ *
145
+ * @since 1.13.0
146
+ */
147
+ private function filelist_create() {
148
+ $this->core->logger->add( 'Starting to create list of files to include in zip.' );
149
+ $this->core->logger->add_memory();
150
+
151
+ Boldgrid_Backup_Admin_In_Progress_Data::set_arg( 'step', 2 );
152
+
153
+ $this->filelist_path = $this->core->backup_dir->get_path_to( 'system_zip_filelist-' . time() . '.txt' );
154
+
155
+ $total_size_archived = 0;
156
+
157
+ // Create the file list.
158
+ $filelist_array = [];
159
+ foreach ( $this->filelist as $file ) {
160
+ $filelist_array[] = str_replace( ABSPATH, '', $file[0] );
161
+
162
+ $total_size_archived += empty( $file[2] ) ? 0 : $file[2];
163
+ }
164
+
165
+ // Add some values for "In progress".
166
+ Boldgrid_Backup_Admin_In_Progress_Data::set_arg( 'total_files_done', count( $this->filelist ) );
167
+ Boldgrid_Backup_Admin_In_Progress_Data::set_arg( 'total_size_archived', $total_size_archived );
168
+ Boldgrid_Backup_Admin_In_Progress_Data::set_arg( 'total_size_archived_size_format', size_format( $total_size_archived, 2 ) );
169
+
170
+ /*
171
+ * Remove our db_dump_filepath from the list.
172
+ *
173
+ * If we add it now, the zip file will include /home/user/boldgrid_backup/db.sql
174
+ *
175
+ * We'll add the sql separately in self::zip_sql().
176
+ */
177
+ if ( ( $key = array_search( $this->core->db_dump_filepath, $filelist_array ) ) !== false ) { // phpcs:ignore
178
+ unset( $filelist_array[ $key ] );
179
+ }
180
+
181
+ $this->core->wp_filesystem->put_contents(
182
+ $this->filelist_path,
183
+ implode( PHP_EOL, $filelist_array )
184
+ );
185
+
186
+ $this->core->logger->add( 'Finished creating list of files to include in zip.' );
187
+ $this->core->logger->add_memory();
188
+ }
189
+
190
+ /**
191
+ * Run the command to actually zip the files.
192
+ *
193
+ * @since 1.13.0
194
+ */
195
+ private function zip() {
196
+ $this->core->logger->add( 'Starting to close the zip file.' );
197
+ $this->core->logger->add_memory();
198
+
199
+ $this->temp_folder->create();
200
+
201
+ $this->core->execute_command( 'cd ' . ABSPATH . '; zip -b ' . $this->temp_folder->get_path() . ' ' . $this->filepath . ' -@ < ' . $this->filelist_path );
202
+
203
+ $this->temp_folder->delete();
204
+
205
+ $this->core->logger->add( 'Finished closing the zip file.' );
206
+ $this->core->logger->add_memory();
207
+ }
208
+
209
+ /**
210
+ * Add the .sql file individually.
211
+ *
212
+ * @since 1.13.0
213
+ *
214
+ * @see self::filelist_create
215
+ */
216
+ private function zip_sql() {
217
+ $this->core->logger->add( 'Starting to add db dump to the zip file.' );
218
+ $this->core->logger->add_memory();
219
+
220
+ $dir = pathinfo( $this->core->db_dump_filepath, PATHINFO_DIRNAME );
221
+
222
+ $this->core->execute_command( 'cd ' . $dir . '; zip ' . $this->filepath . ' ' . basename( $this->core->db_dump_filepath ) . ';' );
223
+
224
+ $this->core->logger->add( 'Finished adding db dump to the zip file.' );
225
+ $this->core->logger->add_memory();
226
+ }
227
+ }
admin/compressor/php_zip.php DELETED
@@ -1,212 +0,0 @@
1
- <?php
2
- /**
3
- * PHP Zip Compressor.
4
- *
5
- * @link http://www.boldgrid.com
6
- * @since 1.5.1
7
- *
8
- * @package Boldgrid_Backup
9
- * @subpackage Boldgrid_Backup/admin
10
- * @copyright BoldGrid.com
11
- * @version $Id$
12
- * @author BoldGrid.com <wpb@boldgrid.com>
13
- */
14
-
15
- /**
16
- * BoldGrid Backup Admin Compressor PHP Zip Class.
17
- *
18
- * @since 1.5.1
19
- */
20
- class Boldgrid_Backup_Admin_Compressor_Php_Zip extends Boldgrid_Backup_Admin_Compressor {
21
-
22
- /**
23
- * An array of directories we've added to the zip.
24
- *
25
- * @since 1.5.4
26
- * @access public
27
- * @var array
28
- */
29
- public $dirs = array();
30
-
31
- /**
32
- * The status of our test result.
33
- *
34
- * @since 1.5.1
35
- * @access public
36
- * @var mixed|bool|null
37
- */
38
- public static $test_result = null;
39
-
40
- /**
41
- * An array of any errors received while testing.
42
- *
43
- * @since 1.5.1
44
- * @access public
45
- * @var array
46
- */
47
- public $test_errors = array();
48
-
49
- /**
50
- * An instance of ZipArchive.
51
- *
52
- * @since 1.5.1
53
- * @var ZipArchive
54
- */
55
- public $zip;
56
-
57
- /**
58
- * Constructor.
59
- *
60
- * @since 1.5.1
61
- *
62
- * @param Boldgrid_Backup_Admin_Core $core
63
- */
64
- public function __construct( $core ) {
65
- parent::__construct( $core );
66
- }
67
-
68
- /**
69
- * Add a file's directories to the zip.
70
- *
71
- * When you add a file, the parent directories are not always explicitly
72
- * created. For example, if you add wp-content/themes/pavilion/index.php the
73
- * wp-content directory (and so forth) is not explicity added to the zip.
74
- *
75
- * @since 1.5.4
76
- *
77
- * @param string $file
78
- */
79
- public function add_dir( $file ) {
80
- $add_directory = '';
81
- $dirs = explode( DIRECTORY_SEPARATOR, dirname( $file ) );
82
-
83
- foreach ( $dirs as $key => $dir ) {
84
- if ( 0 === $key ) {
85
- $add_directory = $dir;
86
- } else {
87
- $add_directory .= '/' . $dir;
88
- }
89
-
90
- if ( ! in_array( $add_directory, $this->dirs, true ) ) {
91
- $this->zip->addEmptyDir( $add_directory );
92
- $this->dirs[] = $add_directory;
93
- }
94
- }
95
- }
96
-
97
- /**
98
- * Archive files.
99
- *
100
- * @since 1.5.1
101
- *
102
- * @param array $filelist See Boldgrid_Backup_Admin_Filelist::get_total_size
103
- * @param array $info {
104
- * An array of data about the backup archive we are generating.
105
- *
106
- * @type string mode backup
107
- * @type bool dryrun
108
- * @type string compressor php_zip
109
- * @type ing filesize 0
110
- * @type bool save 1
111
- * @type int total_size 0
112
- * }
113
- */
114
- public function archive_files( $filelist, &$info ) {
115
- $info['filepath'] = $this->core->generate_archive_path( 'zip' );
116
-
117
- if ( $info['dryrun'] ) {
118
- return true;
119
- }
120
-
121
- $this->zip = new ZipArchive();
122
-
123
- $status = $this->zip->open( $info['filepath'], ZipArchive::CREATE );
124
-
125
- if ( ! $status ) {
126
- return array(
127
- 'error' => 'Cannot open ZIP archive file "' . $info['filepath'] . '".',
128
- 'error_code' => $status,
129
- 'error_message' => Boldgrid_Backup_Admin_Utility::translate_zip_error( $status ),
130
- );
131
- }
132
-
133
- foreach ( $filelist as $fileinfo ) {
134
- $is_dir = ! empty( $fileinfo[3] ) && 'd' === $fileinfo[3];
135
-
136
- if ( $is_dir ) {
137
- $this->zip->addEmptyDir( $fileinfo[1] );
138
- } else {
139
- $this->zip->addFile( $fileinfo[0], $fileinfo[1] );
140
- $this->add_dir( $fileinfo[1] );
141
- }
142
- }
143
-
144
- if ( ! $this->zip->close() ) {
145
- return array(
146
- 'error' => 'Cannot close ZIP archive file "' . $info['filepath'] . '".',
147
- );
148
- }
149
-
150
- return true;
151
- }
152
-
153
- /**
154
- * Determine if ZipArchive is available.
155
- *
156
- * @since 1.5.2
157
- */
158
- public static function is_available() {
159
- return extension_loaded( 'zip' ) && class_exists( 'ZipArchive' );
160
- }
161
-
162
- /**
163
- * Test the functionality of php_zip.
164
- *
165
- * @since 1.5
166
- *
167
- * @return bool
168
- */
169
- public function test() {
170
- if ( null !== self::$test_result ) {
171
- return self::$test_result;
172
- }
173
-
174
- $backup_dir = $this->core->backup_dir->get();
175
-
176
- $test_file_contents = $str = __( 'This is a test file from BoldGrid Backup. You can delete this file.', 'boldgrid-backup' );
177
- $cannot_open_zip = __( 'Unable to create zip file: %1$s', 'boldgrid-backup' );
178
- $cannot_close_zip = __( 'When testing ZipArchive functionality, we are able to create a zip file and add files to it, but we were unable to close the zip file.<br /><strong>Please be sure the following backup directory has modify permissions</strong>:<br />%1$s', 'boldgrid-backup' );
179
- $safe_to_delete = __( 'safe-to-delete', 'boldgrid-backup' );
180
- $test_zip_file = $test_zip_file = $this->core->test->test_prefix . '-zip';
181
- $test_filename = sprintf( '%1$s%5$s%2$s-%3$s-%4$s', $backup_dir, $test_zip_file, mt_rand(), $safe_to_delete, DIRECTORY_SEPARATOR );
182
-
183
- $zip_filepath = $test_filename . '.zip';
184
- $random_filename = $test_filename . '.txt';
185
-
186
- $zip = new ZipArchive();
187
- $status = $zip->open( $zip_filepath, ZipArchive::CREATE );
188
- if ( ! $status ) {
189
- $this->test_errors[] = sprintf( $cannot_open_zip, $zip_filepath );
190
- self::$test_result = false;
191
- return false;
192
- }
193
-
194
- $this->core->wp_filesystem->touch( $random_filename );
195
- $this->core->wp_filesystem->put_contents( $random_filename, $test_file_contents );
196
-
197
- $zip->addFile( $random_filename, 'test.txt' );
198
-
199
- $zip_closed = @$zip->close();
200
-
201
- $this->core->test->delete_test_files( $backup_dir );
202
-
203
- if ( ! $zip_closed ) {
204
- $this->test_errors[] = sprintf( $cannot_close_zip, $backup_dir );
205
- self::$test_result = false;
206
- return false;
207
- }
208
-
209
- self::$test_result = true;
210
- return true;
211
- }
212
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/cron/class-crontab.php ADDED
@@ -0,0 +1,142 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Crontab class.
4
+ *
5
+ * This is an object class, representing crontab.
6
+ *
7
+ * @link https://www.boldgrid.com
8
+ * @since 1.11.0
9
+ *
10
+ * @package Boldgrid\Backup
11
+ * @subpackage Boldgrid\Backup\Cron
12
+ * @copyright BoldGrid
13
+ * @author BoldGrid <support@boldgrid.com>
14
+ */
15
+
16
+ namespace Boldgrid\Backup\Admin\Cron;
17
+
18
+ /**
19
+ * Class: Crontab
20
+ *
21
+ * @since 1.11.0
22
+ */
23
+ class Crontab {
24
+ /**
25
+ * Boldgrid_Backup_Admin_Core object.
26
+ *
27
+ * @since 1.11.1
28
+ * @access private
29
+ *
30
+ * @var Boldgrid_Backup_Admin_Core
31
+ */
32
+ private $core;
33
+
34
+ /**
35
+ * Constructor.
36
+ *
37
+ * @since 1.11.1
38
+ */
39
+ public function __construct() {
40
+ $this->core = apply_filters( 'boldgrid_backup_get_core', null );
41
+ }
42
+
43
+ /**
44
+ * Search for cron entries.
45
+ *
46
+ * This method is similar to the Boldgrid_Backup_Admin_Cron::entry_search() method, except it
47
+ * accepts an array of patterns to search for, rather than just one.
48
+ *
49
+ * @since 1.11.0
50
+ *
51
+ * @param array $patterns An array of patterns to search for. All patterns must be found in
52
+ * order to return a cron entry as a match.
53
+ * @return array An array of crons.
54
+ */
55
+ public function find_crons( array $patterns = [] ) {
56
+ $all_crons = $this->core->cron->get_all( false );
57
+
58
+ $matched_crons = [];
59
+
60
+ foreach ( $all_crons as $cron ) {
61
+ $all_patterns_found = true;
62
+
63
+ foreach ( $patterns as $pattern ) {
64
+ if ( false === strpos( $cron, $pattern ) ) {
65
+ $all_patterns_found = false;
66
+ }
67
+ }
68
+
69
+ if ( $all_patterns_found ) {
70
+ $matched_crons[] = $cron;
71
+ }
72
+ }
73
+
74
+ return $matched_crons;
75
+ }
76
+
77
+ /**
78
+ * Retrieve the system crontab entries.
79
+ *
80
+ * @since 1.11.1
81
+ *
82
+ * @return string|false
83
+ */
84
+ public function read_crontab() {
85
+ if ( ! $this->core->test->is_crontab_available() ) {
86
+ return false;
87
+ }
88
+
89
+ $command = 'crontab -l';
90
+ $crontab = $this->core->execute_command( $command, $success );
91
+
92
+ return $success ? $crontab : false;
93
+ }
94
+
95
+ /**
96
+ * Write to the system crontab.
97
+ *
98
+ * The crontab contents will be replaced with the string passed to this method.
99
+ *
100
+ * @since 1.11.1
101
+ *
102
+ * @param string $crontab The crontab contents to be written.
103
+ * @return bool
104
+ */
105
+ public function write_crontab( $crontab ) {
106
+ $backup_directory = $this->core->backup_dir->get();
107
+
108
+ if ( ! $this->core->wp_filesystem->is_writable( $backup_directory ) ) {
109
+ return false;
110
+ }
111
+
112
+ // Strip extra line breaks.
113
+ $crontab = str_replace( "\n\n", "\n", $crontab );
114
+
115
+ // Trim the crontab.
116
+ $crontab = trim( $crontab );
117
+
118
+ // Add a line break at the end of the file.
119
+ $crontab .= "\n";
120
+
121
+ // Save the temp crontab to file.
122
+ $temp_crontab_path = $backup_directory . '/crontab.' . microtime( true ) . '.tmp';
123
+
124
+ // Save a temporary file for crontab.
125
+ $this->core->wp_filesystem->put_contents( $temp_crontab_path, $crontab, 0600 );
126
+
127
+ // Check if the defaults file was written.
128
+ if ( ! $this->core->wp_filesystem->exists( $temp_crontab_path ) ) {
129
+ return false;
130
+ }
131
+
132
+ // Write crontab.
133
+ $command = 'crontab ' . $temp_crontab_path;
134
+
135
+ $this->core->execute_command( $command, $success );
136
+
137
+ // Remove temp crontab file.
138
+ $this->core->wp_filesystem->delete( $temp_crontab_path, false, 'f' );
139
+
140
+ return (bool) $success;
141
+ }
142
+ }
admin/cron/entry/class-base.php ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Entry class.
4
+ *
5
+ * This is our base class for an entry.
6
+ *
7
+ * @link https://www.boldgrid.com
8
+ * @since 1.11.0
9
+ *
10
+ * @package Boldgrid\Backup
11
+ * @subpackage Boldgrid\Backup\Cron
12
+ * @copyright BoldGrid
13
+ * @author BoldGrid <support@boldgrid.com>
14
+ */
15
+
16
+ namespace Boldgrid\Backup\Admin\Cron\Entry;
17
+
18
+ use Boldgrid\Backup\Admin\Cron\Entry\Entry;
19
+
20
+ /**
21
+ * Class: Entry
22
+ *
23
+ * @since 1.11.0
24
+ */
25
+ class Base implements Entry {
26
+ /**
27
+ * Get our cron entry's next runtime.
28
+ *
29
+ * @since 1.11.0
30
+ *
31
+ * @return bool
32
+ */
33
+ public function get_next_runtime() {
34
+ return false;
35
+ }
36
+
37
+ /**
38
+ * Initialize our cron entry.
39
+ *
40
+ * @since 1.11.0
41
+ *
42
+ * @return bool
43
+ */
44
+ public function init_via_search( array $patterns = [] ) {
45
+ return false;
46
+ }
47
+
48
+ /**
49
+ * Get whether or not our cron entry exists in the cron engine.
50
+ *
51
+ * @since 1.11.0
52
+ *
53
+ * @return boolean
54
+ */
55
+ public function is_set() {
56
+ return false;
57
+ }
58
+ }
admin/cron/entry/class-crontab.php ADDED
@@ -0,0 +1,161 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Crontab Entry class.
4
+ *
5
+ * This class represents a single entry in the crontab.
6
+ *
7
+ * @link https://www.boldgrid.com
8
+ * @since 1.11.0
9
+ *
10
+ * @package Boldgrid\Backup
11
+ * @subpackage Boldgrid\Backup\Cron
12
+ * @copyright BoldGrid
13
+ * @author BoldGrid <support@boldgrid.com>
14
+ */
15
+
16
+ namespace Boldgrid\Backup\Admin\Cron\Entry;
17
+
18
+ use Boldgrid\Backup\Admin\Cron\Entry\Entry;
19
+ use Boldgrid\Backup\Admin\Cron\Entry\Base;
20
+
21
+ /**
22
+ * Class: Crontab Entry.
23
+ *
24
+ * @since 1.11.0
25
+ */
26
+ class Crontab extends Base implements Entry {
27
+ /**
28
+ * Our cron entry's command.
29
+ *
30
+ * Given the following entry:
31
+ * "* * * * * COMMAND"
32
+ *
33
+ * This property is the "COMMAND" part.
34
+ *
35
+ * @since 1.11.0
36
+ * @access private
37
+ * @var string
38
+ */
39
+ private $command;
40
+
41
+ /**
42
+ * Whether or not this cron exists in the crontab.
43
+ *
44
+ * @since 1.11.0
45
+ * @access private
46
+ * @var bool
47
+ */
48
+ private $is_set;
49
+
50
+ /**
51
+ * The cron's entire command.
52
+ *
53
+ * Given the following entry:
54
+ * "* * * * * COMMAND"
55
+ *
56
+ * The raw command is the entire string, "* * * * * COMMAND".
57
+ *
58
+ * @since 1.11.0
59
+ * @access private
60
+ * @var string
61
+ */
62
+ private $raw_command;
63
+
64
+ /**
65
+ * The time defined for the cron.
66
+ *
67
+ * Given the following entry:
68
+ * "* * * * * COMMAND"
69
+ *
70
+ * The time is the "* * * * *" part.
71
+ *
72
+ * @since 1.11.0
73
+ * @access private
74
+ * @var string
75
+ */
76
+ private $time;
77
+
78
+ /**
79
+ * An instance of Boldgrid\Backup\Admin\Cron\Crontab.
80
+ *
81
+ * @since 1.11.0
82
+ * @access private
83
+ * @var Boldgrid\Backup\Admin\Cron\Crontab
84
+ */
85
+ private $engine;
86
+
87
+ /**
88
+ *
89
+ */
90
+ public function __construct() {
91
+ $this->engine = new \Boldgrid\Backup\Admin\Cron\Crontab();
92
+ }
93
+
94
+ /**
95
+ * Get our cron's next runtime.
96
+ *
97
+ * @since 1.11.0
98
+ *
99
+ * @return string The unix timestamp (UTC) of when this cron will run next.
100
+ */
101
+ public function get_next_runtime() {
102
+ $core = apply_filters( 'boldgrid_backup_get_core', null );
103
+
104
+ require_once BOLDGRID_BACKUP_PATH . '/vendor/chland/tdcron/class.tdcron.php';
105
+ require_once BOLDGRID_BACKUP_PATH . '/vendor/chland/tdcron/class.tdcron.entry.php';
106
+
107
+ /*
108
+ * Get our next runtime.
109
+ *
110
+ * Cron jobs are configured to run on the server's timezone, not UTC. Therefore, our next
111
+ * runtime will be server time.
112
+ */
113
+ $next_runtime = \tdCron::getNextOccurrence( $this->time );
114
+
115
+ /*
116
+ * Initialize our time class with our $next_runtime, and specify the time is in the server's
117
+ * timezone (local).
118
+ */
119
+ $core->time->init( $next_runtime, 'local' );
120
+
121
+ return $core->time->utc_time;
122
+ }
123
+
124
+ /**
125
+ * Init this cron entry.
126
+ *
127
+ * @since 1.11.0
128
+ *
129
+ * @return mixed
130
+ */
131
+ public function init_via_search( array $patterns = [] ) {
132
+ $this->is_set = false;
133
+
134
+ $matched_crons = $this->engine->find_crons( $patterns );
135
+
136
+ if ( 1 === count( $matched_crons ) ) {
137
+ $this->raw_command = $matched_crons[0];
138
+
139
+ $exploded_command = explode( ' ', trim( $this->raw_command ) );
140
+
141
+ $time = array_slice( $exploded_command, 0, 5 );
142
+ $this->time = implode( ' ', $time );
143
+
144
+ $command = array_splice( $exploded_command, 5 );
145
+ $this->command = implode( ' ', $command );
146
+
147
+ $this->is_set = true;
148
+ }
149
+ }
150
+
151
+ /**
152
+ * Whether or not this cron entry exists in the crontab.
153
+ *
154
+ * @since 1.11.0
155
+ *
156
+ * @return bool
157
+ */
158
+ public function is_set() {
159
+ return $this->is_set;
160
+ }
161
+ }
admin/cron/entry/class-entry.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Entry class.
4
+ *
5
+ * This is our entry interface.
6
+ *
7
+ * @link https://www.boldgrid.com
8
+ * @since 1.11.0
9
+ *
10
+ * @package Boldgrid\Backup
11
+ * @subpackage Boldgrid\Backup\Cron
12
+ * @copyright BoldGrid
13
+ * @author BoldGrid <support@boldgrid.com>
14
+ */
15
+
16
+ namespace Boldgrid\Backup\Admin\Cron\Entry;
17
+
18
+ /**
19
+ * Class: Entry
20
+ *
21
+ * @since 1.11.0
22
+ */
23
+ interface Entry {
24
+ public function get_next_runtime();
25
+
26
+ public function init_via_search( array $patterns = [] );
27
+
28
+ public function is_set();
29
+ }
admin/cron/entry/class-wpcron.php ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * WPCron Entry class.
4
+ *
5
+ * This class represents a single entry within WPCron.
6
+ *
7
+ * @link https://www.boldgrid.com
8
+ * @since 1.11.0
9
+ *
10
+ * @package Boldgrid\Backup
11
+ * @subpackage Boldgrid\Backup\Cron
12
+ * @copyright BoldGrid
13
+ * @author BoldGrid <support@boldgrid.com>
14
+ */
15
+
16
+ namespace Boldgrid\Backup\Admin\Cron\Entry;
17
+
18
+ use Boldgrid\Backup\Admin\Cron\Entry\Entry;
19
+ use Boldgrid\Backup\Admin\Cron\Entry\Base;
20
+
21
+ /**
22
+ * Class: Entry
23
+ *
24
+ * @since 1.11.0
25
+ */
26
+ class Wpcron extends Base implements Entry {
27
+ /**
28
+ * The hook this wpcron uses.
29
+ *
30
+ * @since 1.11.0
31
+ * @access private
32
+ * @var string
33
+ */
34
+ private $hook;
35
+
36
+ /**
37
+ * Whether or not this wpcron is set / configured within the wpcron system.
38
+ *
39
+ * @since 1.11.0
40
+ * @access private
41
+ * @var bool
42
+ */
43
+ private $is_set;
44
+
45
+ /**
46
+ * Get the next runtime of this wpcron.
47
+ *
48
+ * @since 1.11.0
49
+ *
50
+ * @return string Timestamp, the time the scheduled event will next occur (unix timestamp).
51
+ * False, if the event isn't scheduled.
52
+ */
53
+ public function get_next_runtime() {
54
+ return wp_next_scheduled( $this->hook );
55
+ }
56
+
57
+ /**
58
+ * Initialize this wpcron entry.
59
+ *
60
+ * @since 1.11.0
61
+ *
62
+ * @param string $hook
63
+ */
64
+ public function init_via_search( array $patterns = [] ) {
65
+ $this->is_set = false;
66
+
67
+ $this->hook = $patterns[0];
68
+
69
+ $schedule = wp_get_schedule( $this->hook );
70
+
71
+ if ( ! empty( $schedule ) ) {
72
+ $this->is_set = true;
73
+ }
74
+ }
75
+
76
+ /**
77
+ * Get whether or not this wpcron entry exists.
78
+ *
79
+ * @since 1.11.0
80
+ *
81
+ * @return bool
82
+ */
83
+ public function is_set() {
84
+ return $this->is_set;
85
+ }
86
+ }
admin/css/boldgrid-backup-admin-dashboard.css ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Style for specific cards.
3
+ */
4
+
5
+ #bgbkup_backups .bglib-card-icon {
6
+ border-top-color: #0073aa;
7
+ }
8
+
9
+ #bgbkup_backups .bglib-card-icon .dashicons {
10
+ color: #0073aa;
11
+ }
12
+
13
+ #bgbkup_updates .bglib-card-icon {
14
+ border-top-color: #aa0073;
15
+ }
16
+
17
+ #bgbkup_updates .bglib-card-icon .dashicons {
18
+ color: #aa0073;
19
+ }
20
+
21
+ #bgbkup_get_premium .bglib-card-icon {
22
+ border-top-color: #f95b26;
23
+ }
24
+
25
+ #bgbkup_get_premium .bglib-card-icon .dashicons {
26
+ color: #f95b26;
27
+ }
admin/css/boldgrid-backup-admin-folder-exclude.css CHANGED
@@ -94,7 +94,6 @@
94
  left: 0px;
95
  right: 0px;
96
  padding: 0px 10px;
97
- text-align: right;
98
  }
99
  .plugin-card-bottom #you_may_leave {
100
  float: left;
94
  left: 0px;
95
  right: 0px;
96
  padding: 0px 10px;
 
97
  }
98
  .plugin-card-bottom #you_may_leave {
99
  float: left;
admin/css/boldgrid-backup-admin-hide-all.css CHANGED
@@ -4,21 +4,28 @@
4
  * This set of styles hides everything on the page except for what the plugin
5
  * displays. This helps make the page look better in an iframe / modal.
6
  */
 
 
 
7
  #adminmenumain,
 
8
  #wpadminbar,
9
  #wpfooter {
10
  display: none;
11
  }
 
12
  #wpwrap {
13
  position: absolute;
14
  top: 0px;
15
  left: 0px;
16
  }
 
17
  #wpwrap #wpcontent {
18
  margin: 0px; !important;
19
  padding-left: 10px; !important;
20
  padding-right: 10px; !important;
21
  }
 
22
  #wpbody-content {
23
  padding-bottom: 0px;
24
- }
4
  * This set of styles hides everything on the page except for what the plugin
5
  * displays. This helps make the page look better in an iframe / modal.
6
  */
7
+
8
+ .boldgrid-backup-in-progress,
9
+ .update-nag,
10
  #adminmenumain,
11
+ [id$="-tgmpa"],
12
  #wpadminbar,
13
  #wpfooter {
14
  display: none;
15
  }
16
+
17
  #wpwrap {
18
  position: absolute;
19
  top: 0px;
20
  left: 0px;
21
  }
22
+
23
  #wpwrap #wpcontent {
24
  margin: 0px; !important;
25
  padding-left: 10px; !important;
26
  padding-right: 10px; !important;
27
  }
28
+
29
  #wpbody-content {
30
  padding-bottom: 0px;
31
+ }
admin/css/boldgrid-backup-admin-home.css CHANGED
@@ -13,4 +13,8 @@
13
  /* Disable floating of mine count so help section displays nicely. */
14
  .subsubsub {
15
  float: none;
16
- }
 
 
 
 
13
  /* Disable floating of mine count so help section displays nicely. */
14
  .subsubsub {
15
  float: none;
16
+ }
17
+
18
+ .page-title-actions {
19
+ display: inline-block;
20
+ }
admin/css/boldgrid-backup-admin-premium.css ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Style for specific premium feature cards.
3
+ */
4
+
5
+ #bgbkup_amazon_s3 .bglib-card-icon {
6
+ border-top-color: #feb424;
7
+ }
8
+
9
+ #bgbkup_database_encryption .bglib-card-icon {
10
+ border-top-color: #aaa;
11
+ }
12
+
13
+ #bgbkup_dream_objects .bglib-card-icon {
14
+ border-top-color: #3e95be;
15
+ }
16
+
17
+ #bgbkup_backups .bglib-card-icon {
18
+ border-top-color: #0073aa;
19
+ }
20
+
21
+ #bgbkup_google_drive .bglib-card-icon {
22
+ border-top-color: #1ba160;
23
+ }
24
+
25
+ #bgbkup_amazon .bglib-card-icon {
26
+ border-top-color: #feb424;
27
+ }
28
+
29
+ #bgbkup_dream_objects .bglib-card-icon {
30
+ border-top-color: #3e95be;
31
+ }
32
+
33
+ #bgbkup_history .bglib-card-icon {
34
+ color: #f04207;
35
+ border-top-color: #f04207;
36
+ }
37
+
38
+ #bgbkup_historical_versions .bglib-card-icon {
39
+ color: #9ebaa0;
40
+ border-top-color: #9ebaa0;
41
+ }
42
+
43
+ #bgbkup_plugin_editor_tools .bglib-card-icon {
44
+ color: #5d824b;
45
+ border-top-color: #5d824b;
46
+ }
47
+
48
+ #bgbkup_backups .bglib-card-icon .dashicons {
49
+ color: #0073aa;
50
+ }
51
+
52
+ #bgbkup_updates .bglib-card-icon {
53
+ border-top-color: #aa0073;
54
+ }
55
+
56
+ #bgbkup_updates .bglib-card-icon .dashicons {
57
+ color: #aa0073;
58
+ }
59
+
60
+ #bgbkup_one_click_restoration .bglib-card-icon {
61
+ color: #c604c6;
62
+ border-top-color: #c604c6;
63
+ }
64
+
65
+ #bgbkup_get_premium .bglib-card-icon {
66
+ border-top-color: #f95b26;
67
+ }
68
+
69
+ #bgbkup_get_premium .bglib-card-icon .dashicons {
70
+ color: #f95b26;
71
+ }
72
+
73
+ /**
74
+ * Misc.
75
+ */
76
+
77
+ /* The get premium button in the top notice. */
78
+ .bglib-card {
79
+ display: flex;
80
+ flex-direction: column;
81
+ }
82
+
83
+ .bglib-card-icon {
84
+ height: 60px;
85
+ }
86
+
87
+ .bg-box-bottom.premium .button-success {
88
+ float: none;
89
+ }
90
+
91
+ .bglib-card-footer {
92
+ flex-grow: 10;
93
+ }
94
+
95
+ .bglib-card-links {
96
+ flex-grow: 1;
97
+ }
98
+
99
+ .bglib-card-links a {
100
+ margin: 1em;
101
+ }
102
+
103
+ .bg-box-title {
104
+ font-size: 1.25em;
105
+ font-weight: 600;
106
+ }
107
+
108
+ .bglib-card-title {
109
+ height: 2em;
110
+ }
admin/css/boldgrid-backup-admin-settings.css CHANGED
@@ -6,4 +6,12 @@
6
  .form-table tr td p {
7
  padding: 5px 0px;
8
  margin: 0px;
9
- }
 
 
 
 
 
 
 
 
6
  .form-table tr td p {
7
  padding: 5px 0px;
8
  margin: 0px;
9
+ }
10
+
11
+ .bgb-unbold {
12
+ font-weight: normal;
13
+ }
14
+
15
+ #auto-recovery-tr {
16
+ display: none;
17
+ }
admin/css/boldgrid-backup-admin-test.css CHANGED
@@ -8,6 +8,7 @@
8
 
9
  .functionality-test-section table tr td {
10
  padding: 5px 10px;
 
11
  }
12
 
13
  .functionality-test-section table tr td h2 {
8
 
9
  .functionality-test-section table tr td {
10
  padding: 5px 10px;
11
+ vertical-align: top;
12
  }
13
 
14
  .functionality-test-section table tr td h2 {
admin/css/boldgrid-backup-admin.css CHANGED
@@ -34,6 +34,11 @@ th .help[data-id] {
34
  display: inline-block;
35
  }
36
 
 
 
 
 
 
37
  /* Prevent clicks on disabled links. */
38
  a[disabled] {
39
  pointer-events: none;
@@ -43,7 +48,7 @@ a[disabled] {
43
  cursor: wait !important;
44
  }
45
 
46
- .dashicons-warning.red {
47
  color: #dc3232;
48
  }
49
 
@@ -109,14 +114,14 @@ hr.separator-small {
109
  }
110
 
111
  /* Get Premium link in the left nav. */
112
- .toplevel_page_boldgrid-backup-settings .get-premium,
113
- .toplevel_page_boldgrid-backup-settings .dashicons-dashboard {
114
  color: #ffb900;
115
  }
116
 
117
  /* Needed style for bouncing help icon in mine count. */
118
  .subsubsub .ui-effects-wrapper {
119
- display: inline-block;
120
  }
121
 
122
  /* WordPress by default has both the h2 and h3 tags set to the same font size. */
@@ -126,4 +131,220 @@ h3 {
126
 
127
  input:invalid {
128
  border: 1px solid red;
129
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  display: inline-block;
35
  }
36
 
37
+ /* While thickbox is loading, show something rather than nothing. */
38
+ #TB_iframeContent {
39
+ background: #f1f1f1;
40
+ }
41
+
42
  /* Prevent clicks on disabled links. */
43
  a[disabled] {
44
  pointer-events: none;
48
  cursor: wait !important;
49
  }
50
 
51
+ .dashicons.red {
52
  color: #dc3232;
53
  }
54
 
114
  }
115
 
116
  /* Get Premium link in the left nav. */
117
+ #adminmenu [class*=boldgrid-backup] .get-premium,
118
+ #adminmenu [class*=boldgrid-backup] .dashicons-dashboard {
119
  color: #ffb900;
120
  }
121
 
122
  /* Needed style for bouncing help icon in mine count. */
123
  .subsubsub .ui-effects-wrapper {
124
+ display: inline-block;
125
  }
126
 
127
  /* WordPress by default has both the h2 and h3 tags set to the same font size. */
131
 
132
  input:invalid {
133
  border: 1px solid red;
134
+ }
135
+
136
+ #download-link-copy, #url-import-notice {
137
+ display: none;
138
+ }
139
+
140
+ #download-copy-button .dashicons {
141
+ font-size: 16px;
142
+ }
143
+
144
+ /**
145
+ * Progress bar.
146
+ *
147
+ * When a backup is in progress, we show the user a progress bar.
148
+ */
149
+
150
+ #boldgrid-backup-in-progress-bar:before {
151
+ transition: background-color 2s ease;
152
+ background-color: transparent;
153
+ }
154
+
155
+ .heartbeat-lost-focus #boldgrid-backup-in-progress-bar:before {
156
+ content:"";
157
+ display: block;
158
+ height: 100%;
159
+ position: absolute;
160
+ top: 0;
161
+ left: 0;
162
+ width: 100%;
163
+ background-color: rgba( 255, 255, 255, .9 );
164
+ }
165
+
166
+ .heartbeat-lost-focus #boldgrid-backup-in-progress-bar #last_file_archived,
167
+ .heartbeat-lost-focus #boldgrid-backup-in-progress-bar .progress-label {
168
+ color: #ddd;
169
+ }
170
+
171
+ #boldgrid-backup-in-progress-bar {
172
+ position: relative;
173
+ background: #f7f7f7;
174
+ border: 1px solid #ccc;
175
+ clear:both;
176
+ overflow: visible;
177
+ height: 2em;
178
+ margin: 0px;
179
+ margin-bottom: 20px;
180
+ }
181
+
182
+ /* The actual progress bar that goes from 0% to 100%. */
183
+ #boldgrid-backup-in-progress-bar .ui-progressbar-value {
184
+ background-color: #0085ba;
185
+ -webkit-transition: width 1s ease-out;
186
+ -moz-transition: width 1s ease-out;
187
+ -o-transition: width 1s ease-out;
188
+ transition: width 1s ease-out;
189
+ }
190
+
191
+ #boldgrid-backup-in-progress-bar #last_file_archived {
192
+ font-size: 10px;
193
+ position: absolute;
194
+ bottom: -20px;
195
+ left: 0px;
196
+ white-space: nowrap;
197
+ }
198
+
199
+ #boldgrid-backup-in-progress-bar .spinner {
200
+ vertical-align: middle;
201
+ margin-top: -2px;
202
+ }
203
+
204
+ .ui-progressbar .ui-progressbar-value {
205
+ height: 100%;
206
+ }
207
+
208
+ .progress-label {
209
+ position: absolute;
210
+ top: 4px;
211
+ font-weight: bold;
212
+ text-shadow: 1px 1px 0 #fff;
213
+ left:0;
214
+ right:0;
215
+ font-weight: 600;
216
+ color: #0073aa;
217
+ text-align: center;
218
+ }
219
+
220
+ .progress-label.over-50 {
221
+ color: #fff;
222
+ text-shadow: none;
223
+ }
224
+
225
+ #boldgrid_backup_in_progress_steps .step {
226
+ float: left;
227
+ width: 33%;
228
+ text-align:center;
229
+ color: #ddd;
230
+ }
231
+
232
+ #boldgrid_backup_in_progress_steps .step:first-of-type {
233
+ text-align: left;
234
+ }
235
+
236
+ #boldgrid_backup_in_progress_steps .step:last-of-type {
237
+ text-align: right;
238
+ }
239
+
240
+ #boldgrid_backup_in_progress_steps .step.active {
241
+ color: #444;
242
+ font-weight: bold;
243
+ }
244
+
245
+ /*
246
+ * Backup Archive Details: title and description.
247
+ *
248
+ * This section contains styles for the title and description input fields.
249
+ */
250
+ #titlediv #titlewrap #title {
251
+ margin-bottom: 15px;
252
+ }
253
+
254
+ [name="backup_description"] {
255
+ width: 100%;
256
+ height: 100px;
257
+ margin: 0px;
258
+ }
259
+
260
+ /*
261
+ * Remote Storage providers.
262
+ *
263
+ * More specifically, logos for remote storage providers.
264
+ */
265
+ .bgbkup-gdrive-logo {
266
+ background-image: url('../image/remote/google-drive-logo.png');
267
+ background-repeat: no-repeat;
268
+ background-size: 100% 100%;
269
+ width: calc(292px / 2.3);
270
+ height: calc(50px / 2.3);
271
+ display: inline-block;
272
+ }
273
+
274
+ .bgbkup-gdrive-logo-smaller {
275
+ width: calc(292px / 2.8);
276
+ height: calc(50px / 2.8);
277
+ }
278
+
279
+ .amazon-s3-logo {
280
+ background-image: url('../image/remote/amazon-s3-logo.png');
281
+ background-repeat: no-repeat;
282
+ background-size: 100% 100%;
283
+ width: calc(195px / 2.3);
284
+ height: calc(50px / 2.3);
285
+ display: inline-block;
286
+ }
287
+
288
+ .amazon-s3-logo-smaller {
289
+ width: calc(195px / 2.8);
290
+ height: calc(50px / 2.8);
291
+ }
292
+
293
+ p > .bgbkup-remote-logo {
294
+ vertical-align: bottom;
295
+ }
296
+
297
+ /**
298
+ * Support tab.
299
+ */
300
+ .bgbkup-support-page {
301
+ display: flex;
302
+ margin-top: 1em;
303
+ }
304
+
305
+ .bgbkup-support-page ul {
306
+ line-height: 1.4;
307
+ margin: 0;
308
+ }
309
+
310
+ /* @todo For reusability, these styles handling the bg-box display can be moved to library/src/assets/css/ui.css */
311
+ .bgbkup-support-page .bg-box {
312
+ margin: 1em;
313
+ width: 50%;
314
+ }
315
+
316
+ .bgbkup-premium-support .bgbkup-upgrade-message {
317
+ text-align: center;
318
+ }
319
+
320
+ .bgbkup-premium-support .bgbkup-upgrade-message p:first-of-type {
321
+ margin-top: 0;
322
+ }
323
+
324
+ .bgbkup-db-lock {
325
+ background-image: url('../image/db-lock-64.png');
326
+ background-position-y: 7px;
327
+ background-repeat: no-repeat;
328
+ background-size: 20px 20px;
329
+ display: block;
330
+ margin-left: 10px;
331
+ padding-left: 23px;
332
+ }
333
+
334
+ /**
335
+ * Misc.
336
+ */
337
+
338
+ /* Allow the standard Thickbox to be shown full screen. */
339
+ #TB_window.bg-full-screen {
340
+ margin: 0 !important;
341
+ top: 30px;
342
+ left: 30px;
343
+ width: calc( 100% - 60px ) !important;
344
+ height: calc( 100% - 60px );
345
+ }
346
+
347
+ #TB_window.bg-full-screen #TB_ajaxContent {
348
+ width: calc( 100% - 40px ) !important;
349
+ height: calc( 100% - 60px ) !important;
350
+ }
admin/image/db-lock-64.png ADDED
Binary file
admin/image/remote/amazon-s3-logo.png ADDED
Binary file
admin/image/remote/dreamhost-logo.png ADDED
Binary file
admin/image/remote/google-drive-logo.png ADDED
Binary file
admin/image/remote/google-drive.png ADDED
Binary file
admin/index.php CHANGED
@@ -1,2 +1,8 @@
1
  <?php
 
 
 
 
 
 
2
  // Silence is golden.
1
  <?php
2
+ /**
3
+ * File: index.php
4
+ *
5
+ * @package Boldgrid_Backup
6
+ */
7
+
8
  // Silence is golden.
admin/js/boldgrid-backup-admin-archive-actions.js CHANGED
@@ -1,9 +1,9 @@
1
  /**
2
- * BoldGrid Backup Admin Archive Actions.
3
  *
4
  * @summary JavaScript to handle archive actions.
5
  *
6
- * @since 1.5.4
7
  */
8
 
9
  /* global ajaxurl,BoldGridBackupAdminArchiveActions,jQuery */
@@ -12,8 +12,7 @@ var BOLDGRID = BOLDGRID || {};
12
  BOLDGRID.BACKUP = BOLDGRID.BACKUP || {};
13
 
14
  BOLDGRID.BACKUP.ACTIONS = function( $ ) {
15
- var $body,
16
- $wpbbody,
17
  self = this,
18
  lang = BoldGridBackupAdminArchiveActions;
19
 
@@ -23,7 +22,7 @@ BOLDGRID.BACKUP.ACTIONS = function( $ ) {
23
  * This function was originally in admin-home.js as of 1.0, but moved here
24
  * as of 1.5.4.
25
  *
26
- * @since 1.5.4
27
  */
28
  self.onClickDelete = function( e ) {
29
  var confirmResponse,
@@ -50,7 +49,7 @@ BOLDGRID.BACKUP.ACTIONS = function( $ ) {
50
  * This function was originally in admin-home.js as of 1.0, but moved here
51
  * as of 1.5.4.
52
  *
53
- * @since 1.5.4
54
  */
55
  self.downloadArchive = function( e ) {
56
  var downloadKey,
@@ -109,23 +108,28 @@ BOLDGRID.BACKUP.ACTIONS = function( $ ) {
109
  * This function was originally in admin-home.js as of 1.0, but moved here
110
  * as of 1.5.4.
111
  *
112
- * @since 1.5.4
113
  */
114
  self.restoreArchiveConfirm = function() {
115
- var confirmResponse,
116
- restoreConfirmText,
117
- $this = $( this ),
118
- filename = $this.attr( 'data-archive-filename' ),
119
  data = {
120
  action: 'boldgrid_backup_restore_archive',
121
- restore_now: $this.attr( 'data-restore-now' ),
122
- archive_key: $this.attr( 'data-archive-key' ),
123
  archive_filename: filename,
124
- archive_auth: $this.attr( 'data-nonce' )
125
  },
126
- $spinner = $this.next( '.spinner' );
 
 
 
 
 
 
127
 
128
- restoreConfirmText = lang.restoreConfirmText.replace( '%s', filename );
129
  confirmResponse = confirm( restoreConfirmText );
130
 
131
  if ( true === confirmResponse ) {
@@ -151,13 +155,109 @@ BOLDGRID.BACKUP.ACTIONS = function( $ ) {
151
  return false;
152
  };
153
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
154
  $( function() {
155
- $body = $( 'body' );
156
- $wpbody = $body.find( '#wpbody' );
157
 
158
- $body.on( 'click', '.action-download', self.downloadArchive );
159
- $body.on( 'click', '.restore-now', self.restoreArchiveConfirm );
160
- $body.on( 'click', '#delete-action a', self.onClickDelete );
 
 
161
  } );
162
  };
163
 
1
  /**
2
+ * Archive Actions
3
  *
4
  * @summary JavaScript to handle archive actions.
5
  *
6
+ * @since 1.6.0
7
  */
8
 
9
  /* global ajaxurl,BoldGridBackupAdminArchiveActions,jQuery */
12
  BOLDGRID.BACKUP = BOLDGRID.BACKUP || {};
13
 
14
  BOLDGRID.BACKUP.ACTIONS = function( $ ) {
15
+ var $wpbody,
 
16
  self = this,
17
  lang = BoldGridBackupAdminArchiveActions;
18
 
22
  * This function was originally in admin-home.js as of 1.0, but moved here
23
  * as of 1.5.4.
24
  *
25
+ * @since 1.6.0
26
  */
27
  self.onClickDelete = function( e ) {
28
  var confirmResponse,
49
  * This function was originally in admin-home.js as of 1.0, but moved here
50
  * as of 1.5.4.
51
  *
52
+ * @since 1.6.0
53
  */
54
  self.downloadArchive = function( e ) {
55
  var downloadKey,
108
  * This function was originally in admin-home.js as of 1.0, but moved here
109
  * as of 1.5.4.
110
  *
111
+ * @since 1.6.0
112
  */
113
  self.restoreArchiveConfirm = function() {
114
+ var $this = $( this ),
115
+ confirmResponse,
116
+ filename = $this.data( 'archive-filename' ),
117
+ restoreConfirmText = lang.restoreConfirmText.replace( '%s', filename ),
118
  data = {
119
  action: 'boldgrid_backup_restore_archive',
120
+ restore_now: $this.data( 'restore-now' ),
121
+ archive_key: $this.data( 'archive-key' ),
122
  archive_filename: filename,
123
+ archive_auth: $this.data( 'nonce' )
124
  },
125
+ $spinner = $this.next( '.spinner' ),
126
+ encryptDb = $wpbody.find( '#bgb-details-encrypt_db' ).data( 'value' ),
127
+ tokenMatch = $wpbody.find( '#bgbp-token-match' ).data( 'value' );
128
+
129
+ if ( 'Y' === encryptDb && 'Y' !== tokenMatch ) {
130
+ restoreConfirmText = restoreConfirmText + '\n\n' + lang.tokenMismatchText;
131
+ }
132
 
 
133
  confirmResponse = confirm( restoreConfirmText );
134
 
135
  if ( true === confirmResponse ) {
155
  return false;
156
  };
157
 
158
+ /**
159
+ * @summary Get a download link for a selected backup archive file.
160
+ *
161
+ * @since 1.7.0
162
+ */
163
+ self.getDownloadLink = function( e ) {
164
+ var $this = $( this ),
165
+ data = {
166
+ action: 'boldgrid_backup_generate_download_link',
167
+ archive_filename: $this.attr( 'data-filename' ),
168
+ archive_auth: $this.attr( 'data-nonce' )
169
+ },
170
+ $spinner = $this.next(),
171
+ $downloadLink = $( '#download-link-copy' );
172
+
173
+ e.preventDefault();
174
+
175
+ $this.attr( 'disabled', 'disabled' );
176
+
177
+ $spinner.addClass( 'inline' );
178
+
179
+ $.post( ajaxurl, data, function( response ) {
180
+ var $copyLink;
181
+
182
+ if ( response.data !== undefined && response.data.download_url !== undefined ) {
183
+ $downloadLink
184
+ .removeClass( 'notice-error' )
185
+ .addClass( 'notice-info' )
186
+ .html( response.data.download_url + ' ' );
187
+
188
+ $copyLink = $(
189
+ '<button class="button" id="download-copy-button"' +
190
+ ' data-clipboard-text="' +
191
+ response.data.download_url +
192
+ '"> ' +
193
+ lang.copyText +
194
+ ' <span class="dashicons dashicons-admin-links"></span></button>'
195
+ );
196
+ $downloadLink.append( $copyLink );
197
+
198
+ $downloadLink.wrapInner( '<p></p>' );
199
+
200
+ $downloadLink.append(
201
+ '<p>' +
202
+ lang.expiresText +
203
+ ' ' +
204
+ response.data.expires_when +
205
+ '</p><p>' +
206
+ lang.linkDisclaimerText +
207
+ '</p>'
208
+ );
209
+
210
+ new ClipboardJS( $copyLink[0] );
211
+ } else if ( response.data !== undefined && response.data.error !== undefined ) {
212
+ $downloadLink
213
+ .removeClass( 'notice-info' )
214
+ .addClass( 'notice-error' )
215
+ .html( response.data.error );
216
+ } else {
217
+ $downloadLink
218
+ .removeClass( 'notice-info' )
219
+ .addClass( 'notice-error' )
220
+ .html( lang.linkErrorText );
221
+ }
222
+ } )
223
+ .error( function() {
224
+ $downloadLink.html( lang.unknownErrorText );
225
+ } )
226
+ .always( function() {
227
+ $downloadLink.show();
228
+ $spinner.removeClass( 'inline' );
229
+ $this.removeAttr( 'disabled' );
230
+ } );
231
+ };
232
+
233
+ /**
234
+ * @summary Update the download link copy button after clicking, and then reset after 3 seconds.
235
+ *
236
+ * @since 1.7.0
237
+ */
238
+ self.updateCopyText = function( e ) {
239
+ var $this = $( this ),
240
+ oldHtml = $this.html();
241
+
242
+ e.preventDefault();
243
+
244
+ $this.attr( 'disabled', 'disabled' );
245
+ $this.html( lang.copiedText );
246
+
247
+ setTimeout( function() {
248
+ $this.html( oldHtml );
249
+ $this.removeAttr( 'disabled' );
250
+ }, 3000 );
251
+ };
252
+
253
  $( function() {
254
+ $wpbody = $( 'body #wpbody' );
 
255
 
256
+ $wpbody.on( 'click', '.action-download', self.downloadArchive );
257
+ $wpbody.on( 'click', '.restore-now', self.restoreArchiveConfirm );
258
+ $wpbody.on( 'click', '#delete-action a', self.onClickDelete );
259
+ $wpbody.on( 'click', '#download-link-button', self.getDownloadLink );
260
+ $wpbody.on( 'click', '#download-copy-button', self.updateCopyText );
261
  } );
262
  };
263
 
admin/js/boldgrid-backup-admin-archive-details.js CHANGED
@@ -1,12 +1,12 @@
1
  /**
2
- * Summary
3
  *
4
  * @summary JS for all admin backup pages.
5
  *
6
  * @since 1.3.3
7
  */
8
 
9
- /* global ajaxurl,BoldGridBackupAdmin,jQuery */
10
 
11
  var BoldGrid = BoldGrid || {};
12
 
@@ -46,8 +46,7 @@ BoldGrid.ArchiveDetails = function( $ ) {
46
  $a.parent().html( message );
47
  };
48
 
49
- $a
50
- .attr( 'disabled', 'disabled' )
51
  .text( lang.uploading + '...' )
52
  .after( ' <span class="spinner inline"></span>' );
53
 
@@ -71,7 +70,7 @@ BoldGrid.ArchiveDetails = function( $ ) {
71
  /**
72
  * @summary Action to take when a user clicks download.
73
  *
74
- * @since 1.5.4
75
  */
76
  self.onClickDownload = function() {
77
  var $button = $( this ),
@@ -100,7 +99,7 @@ BoldGrid.ArchiveDetails = function( $ ) {
100
  *
101
  * This method downloads the first remote archive it finds.
102
  *
103
- * @since 1.5.4
104
  */
105
  self.onClickDownloadFirst = function() {
106
  var $downloadToServer = $body.find( '.download-to-server' ),
@@ -122,7 +121,7 @@ BoldGrid.ArchiveDetails = function( $ ) {
122
  *
123
  * These are the "Files & Folders" and "Database" tabs.
124
  *
125
- * @since 1.5.4
126
  */
127
  self.onClickTab = function() {
128
  var $dbElements = $( '[data-view-type="db"]' ),
@@ -149,12 +148,83 @@ BoldGrid.ArchiveDetails = function( $ ) {
149
  }
150
  };
151
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
152
  /**
153
  * Init.
154
  */
155
  $( function() {
156
  $body.on( 'click', '.remote-storage a.upload', self.onClickUpload );
157
  $body.on( 'click', '.remote-storage .download-to-server', self.onClickDownload );
 
158
  $editorTabs.on( 'click', self.onClickTab );
159
  $downloadFirst.on( 'click', self.onClickDownloadFirst );
160
  } );
1
  /**
2
+ * Archive Details
3
  *
4
  * @summary JS for all admin backup pages.
5
  *
6
  * @since 1.3.3
7
  */
8
 
9
+ /* global ajaxurl,BoldGridBackupAdmin,jQuery,boldgrid_backup_archive_details */
10
 
11
  var BoldGrid = BoldGrid || {};
12
 
46
  $a.parent().html( message );
47
  };
48
 
49
+ $a.attr( 'disabled', 'disabled' )
 
50
  .text( lang.uploading + '...' )
51
  .after( ' <span class="spinner inline"></span>' );
52
 
70
  /**
71
  * @summary Action to take when a user clicks download.
72
  *
73
+ * @since 1.6.0
74
  */
75
  self.onClickDownload = function() {
76
  var $button = $( this ),
99
  *
100
  * This method downloads the first remote archive it finds.
101
  *
102
+ * @since 1.6.0
103
  */
104
  self.onClickDownloadFirst = function() {
105
  var $downloadToServer = $body.find( '.download-to-server' ),
121
  *
122
  * These are the "Files & Folders" and "Database" tabs.
123
  *
124
+ * @since 1.6.0
125
  */
126
  self.onClickTab = function() {
127
  var $dbElements = $( '[data-view-type="db"]' ),
148
  }
149
  };
150
 
151
+ /**
152
+ * @summary Action to take when the user clicks "Update".
153
+ *
154
+ * What are they updating? Not really the backup itself, but things like the title and
155
+ * description of the backup.
156
+ *
157
+ * @since 1.7.0
158
+ */
159
+ self.onClickUpdate = function() {
160
+ var request,
161
+ data = {
162
+ action: 'boldgrid_backup_update_archive_details',
163
+ filename: $( '#filename' ).val(),
164
+ security: $( '#_wpnonce' ).val(),
165
+ attributes: {
166
+ title: $( 'input#title' ).val(),
167
+ description: $( 'textarea#backup-description' ).val(),
168
+ protect: $( 'select#backup-protect' ).val(),
169
+ encrypt_db: $( 'select#encrypt-db' ).val()
170
+ }
171
+ },
172
+ onFail,
173
+ onSuccess,
174
+ $actions = $( '#major-publishing-actions' ),
175
+ $button = $( this ),
176
+ $spinner = $button.siblings( '.spinner' );
177
+
178
+ onSuccess = function( response ) {
179
+ if ( false === response.success ) {
180
+ onFail( response.data );
181
+ } else {
182
+
183
+ // Animate things.
184
+ $spinner.removeClass( 'inline' );
185
+ $button.text( adminLang.updated );
186
+ setTimeout( function() {
187
+ $button.text( adminLang.update ).prop( 'disabled', false );
188
+ }, 1000 );
189
+ }
190
+ };
191
+
192
+ onFail = function( msg ) {
193
+
194
+ // Configure our error message.
195
+ if ( msg === undefined ) {
196
+ msg = adminLang.unknown_error;
197
+ } else if ( 'object' === typeof msg && msg.statusText ) {
198
+ msg = msg.statusText;
199
+ }
200
+ msg = adminLang.failed_to_update + msg;
201
+
202
+ // Animate things.
203
+ $spinner.removeClass( 'inline' );
204
+ $button.text( adminLang.update ).prop( 'disabled', false );
205
+
206
+ // Add an error message and make it dissmissible.
207
+ $actions.prepend( '<div class="notice notice-error is-dismissible"><p>' + msg + '</p></div>' );
208
+ $( 'body' ).trigger( 'make_notices_dismissible' );
209
+ };
210
+
211
+ // Animate things.
212
+ $spinner.addClass( 'inline' );
213
+ $button.text( adminLang.updating ).prop( 'disabled', true );
214
+ $actions.find( '.notice' ).slideUp();
215
+
216
+ request = $.post( ajaxurl, data )
217
+ .done( onSuccess )
218
+ .fail( onFail );
219
+ };
220
+
221
  /**
222
  * Init.
223
  */
224
  $( function() {
225
  $body.on( 'click', '.remote-storage a.upload', self.onClickUpload );
226
  $body.on( 'click', '.remote-storage .download-to-server', self.onClickDownload );
227
+ $body.on( 'click', '#publishing-action button', self.onClickUpdate );
228
  $editorTabs.on( 'click', self.onClickTab );
229
  $downloadFirst.on( 'click', self.onClickDownloadFirst );
230
  } );
admin/js/boldgrid-backup-admin-backup-now.js CHANGED
@@ -1,5 +1,5 @@
1
  /**
2
- * BoldGrid Backup Admin Backup Now.
3
  *
4
  * JavaScript for handling "backup" buttons. This code was initially contained
5
  * within the home.js, but separated out as of 1.6.0 for reusability.
@@ -9,7 +9,7 @@
9
  * @param $ The jQuery object.
10
  */
11
 
12
- /* global ajaxurl,jQuery,localizeScriptData */
13
 
14
  var BOLDGRID = BOLDGRID || {};
15
  BOLDGRID.BACKUP = BOLDGRID.BACKUP || {};
@@ -18,14 +18,11 @@ BOLDGRID.BACKUP.BackupNow = function( $ ) {
18
  'use strict';
19
 
20
  var self = this,
21
- lang = localizeScriptData,
22
  $backupNowType = $( '[name="folder_exclusion_type"]' ),
23
  $tablesType = $( '[name="table_inclusion_type"]' );
24
 
25
  $( function() {
26
  $( 'body' ).on( 'click', '#backup-site-now', self.backupNow );
27
-
28
- $( 'body' ).on( 'boldgrid_backup_complete', self.updateProtectionEnabled );
29
  } );
30
 
31
  /**
@@ -38,14 +35,10 @@ BOLDGRID.BACKUP.BackupNow = function( $ ) {
38
  // Declare variables.
39
  var $this,
40
  $backupSiteSection,
41
- $backupSiteResults,
42
  backupNonce,
43
  wpHttpReferer,
44
  isUpdating,
45
- errorCallback,
46
- successCallback,
47
  data,
48
- markup,
49
  $folderExclude = $( '[name="folder_exclusion_exclude"]' ),
50
  $folderInclude = $( '[name="folder_exclusion_include"]' ),
51
  $tableInclude = $( '[name="include_tables[]"]' ),
@@ -74,9 +67,6 @@ BOLDGRID.BACKUP.BackupNow = function( $ ) {
74
  // Create a context selector for the Backup Site Now section.
75
  $backupSiteSection = $( '#backup-site-now-section' );
76
 
77
- // Create a context selector for the Backup Site Now results.
78
- $backupSiteResults = $( '#backup-site-now-results' );
79
-
80
  $( '#TB_ajaxContent' )
81
  .find( 'input' )
82
  .attr( 'disabled', true )
@@ -97,61 +87,6 @@ BOLDGRID.BACKUP.BackupNow = function( $ ) {
97
 
98
  $backupSiteSection.find( '.spinner' ).addClass( 'inline' );
99
 
100
- /**
101
- * @summary backupNow error callback.
102
- *
103
- * @since 1.0
104
- *
105
- * @param object jqXHR
106
- * @param string textStatus
107
- * @param string errorThrown
108
- */
109
- errorCallback = function( jqXHR, textStatus, errorThrown ) {
110
- var data,
111
- errorText = lang.errorText;
112
-
113
- /*
114
- * As of 1.5.2, we are hooking into the shutdown and checking for
115
- * errors. If a fatal error is found, we will return that, rather
116
- * than the generic errorText defined above.
117
- */
118
- if ( jqXHR.responseText !== undefined && '{' === jqXHR.responseText.charAt( 0 ) ) {
119
- data = JSON.parse( jqXHR.responseText );
120
-
121
- if ( data !== undefined && data.data !== undefined && data.data.errorText !== undefined ) {
122
- errorText = data.data.errorText;
123
- }
124
- }
125
-
126
- // Show error message.
127
- markup = '<div class="notice notice-error"><p>' + errorText + '</p></div>';
128
-
129
- $backupSiteResults.html( markup );
130
- };
131
-
132
- /**
133
- * @summary backupNow success callback.
134
- *
135
- * @since 1.5.3
136
- */
137
- successCallback = function( response ) {
138
- var data = JSON.parse( response ),
139
- success = data.success !== undefined && true === data.success,
140
- callback =
141
- success && data.data !== undefined && data.data.callback !== undefined ?
142
- data.data.callback :
143
- null;
144
-
145
- switch ( callback ) {
146
- case 'updateProtectionEnabled':
147
- self.updateProtectionEnabled();
148
- break;
149
- case 'reload':
150
- location.reload();
151
- break;
152
- }
153
- };
154
-
155
  // Generate the data array.
156
  data = {
157
  action: 'boldgrid_backup_now',
@@ -159,7 +94,9 @@ BOLDGRID.BACKUP.BackupNow = function( $ ) {
159
  _wp_http_referer: wpHttpReferer,
160
  is_updating: isUpdating,
161
  backup_now: '1',
162
- folder_exclusion_type: type
 
 
163
  };
164
 
165
  /*
@@ -190,47 +127,45 @@ BOLDGRID.BACKUP.BackupNow = function( $ ) {
190
  BOLDGRID.BACKUP.UpdateSelectors.disable();
191
  }
192
 
193
- // Make the call.
 
 
 
 
 
194
  $.ajax( {
195
  url: ajaxurl,
196
  data: data,
197
- type: 'post',
198
- dataType: 'text',
199
- success: successCallback,
200
- error: errorCallback,
201
- complete: function() {
202
-
203
- // Hide the spinner.
204
- $backupSiteSection.find( '.spinner' ).removeClass( 'is-active' );
205
-
206
- if ( undefined !== BOLDGRID.BACKUP.UpdateSelectors ) {
207
- BOLDGRID.BACKUP.UpdateSelectors.enable();
208
- }
209
- }
210
  } );
211
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
212
  // Prevent default browser action.
213
  e.preventDefault();
214
  };
215
-
216
- /**
217
- * @summary Show notice after backup and upgrade protection now enabled.
218
- *
219
- * This updates the current notice rather than generates a new one.
220
- *
221
- * @since 1.5.3
222
- */
223
- self.updateProtectionEnabled = function() {
224
- var $notice = $( '#backup-site-now-results' ).closest( '.notice' ),
225
- $status = $notice.find( '#protection_enabled' ),
226
- $backupNow = $( '#backup-site-now-section' );
227
-
228
- $notice.removeClass( 'notice-warning' ).addClass( 'notice-success' );
229
-
230
- $status.html( lang.updateProtectionActivated );
231
-
232
- $backupNow.html( '<p>' + lang.backupCreated + '</p>' );
233
- };
234
  };
235
 
236
  BOLDGRID.BACKUP.BackupNow( jQuery );
1
  /**
2
+ * Backup Now
3
  *
4
  * JavaScript for handling "backup" buttons. This code was initially contained
5
  * within the home.js, but separated out as of 1.6.0 for reusability.
9
  * @param $ The jQuery object.
10
  */
11
 
12
+ /* global ajaxurl,jQuery,localizeScriptData,pagenow */
13
 
14
  var BOLDGRID = BOLDGRID || {};
15
  BOLDGRID.BACKUP = BOLDGRID.BACKUP || {};
18
  'use strict';
19
 
20
  var self = this,
 
21
  $backupNowType = $( '[name="folder_exclusion_type"]' ),
22
  $tablesType = $( '[name="table_inclusion_type"]' );
23
 
24
  $( function() {
25
  $( 'body' ).on( 'click', '#backup-site-now', self.backupNow );
 
 
26
  } );
27
 
28
  /**
35
  // Declare variables.
36
  var $this,
37
  $backupSiteSection,
 
38
  backupNonce,
39
  wpHttpReferer,
40
  isUpdating,
 
 
41
  data,
 
42
  $folderExclude = $( '[name="folder_exclusion_exclude"]' ),
43
  $folderInclude = $( '[name="folder_exclusion_include"]' ),
44
  $tableInclude = $( '[name="include_tables[]"]' ),
67
  // Create a context selector for the Backup Site Now section.
68
  $backupSiteSection = $( '#backup-site-now-section' );
69
 
 
 
 
70
  $( '#TB_ajaxContent' )
71
  .find( 'input' )
72
  .attr( 'disabled', true )
87
 
88
  $backupSiteSection.find( '.spinner' ).addClass( 'inline' );
89
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
  // Generate the data array.
91
  data = {
92
  action: 'boldgrid_backup_now',
94
  _wp_http_referer: wpHttpReferer,
95
  is_updating: isUpdating,
96
  backup_now: '1',
97
+ folder_exclusion_type: type,
98
+ backup_title: $( '[name="backup_title"]' ).val(),
99
+ backup_description: $( '[name="backup_description"]' ).val()
100
  };
101
 
102
  /*
127
  BOLDGRID.BACKUP.UpdateSelectors.disable();
128
  }
129
 
130
+ /*
131
+ * Make the ajax call to "Backup Site Now".
132
+ *
133
+ * No success, error, or complete callback is passed to the ajax call. Successes will be
134
+ * handled by "in progress".
135
+ */
136
  $.ajax( {
137
  url: ajaxurl,
138
  data: data,
139
+ type: 'post'
 
 
 
 
 
 
 
 
 
 
 
 
140
  } );
141
 
142
+ /*
143
+ * Take action now that the ajax call to create a backup has been triggered.
144
+ *
145
+ * If we're on the Backup Archive's page page, wait 6 seconds and reload the page. Within the
146
+ * "Backup Site Now" modal, the user will be given a notice that their backup has started, and
147
+ * that the page will refresh and display a progress bar.
148
+ *
149
+ * Else, trigger 'boldgrid_backup_initiated'. The only listener is in-progress.js. When a
150
+ * backup has been initiated, it starts the WordPress Heartbeat and shows the in progress container.
151
+ *
152
+ * @todo Below, we wait 6 seconds because we are assuming that in that time the ajax call will
153
+ * trigger the backup and the flag for "a backup in progress" will be set. If the flag is not
154
+ * set by the time the page refreshes, the in progress notice will not show. The page should
155
+ * not refresh until we know a backup is in progress so that we know the in progress bar will
156
+ * show when the page refreshes.
157
+ */
158
+ if ( 'total-upkeep_page_boldgrid-backup' === pagenow ) {
159
+ setTimeout( function() {
160
+ location.reload();
161
+ }, 6000 );
162
+ } else {
163
+ $( 'body' ).trigger( 'boldgrid_backup_initiated' );
164
+ }
165
+
166
  // Prevent default browser action.
167
  e.preventDefault();
168
  };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169
  };
170
 
171
  BOLDGRID.BACKUP.BackupNow( jQuery );
admin/js/boldgrid-backup-admin-customizer.js CHANGED
@@ -1,8 +1,7 @@
1
  /**
2
- * BoldGrid Backup Admin Customizer.
3
  *
4
- * Javascript for the Custoimzer. Used for backup protection before updating
5
- * themes.
6
  *
7
  * @since 1.6.0
8
  */
1
  /**
2
+ * Admin Customizer
3
  *
4
+ * Javascript for the Custoimzer. Used for backup protection before updating themes.
 
5
  *
6
  * @since 1.6.0
7
  */
admin/js/boldgrid-backup-admin-folder-exclude.js CHANGED
@@ -1,9 +1,9 @@
1
  /**
2
- * BoldGrid Backup Folder Exclude.
3
  *
4
- * @summary JavaScript for handling Folder Exclude settings..
5
  *
6
- * @since 1.5.4
7
  *
8
  * @param $ The jQuery object.
9
  */
@@ -72,7 +72,7 @@ BoldGrid.FolderExclude = function( $ ) {
72
  /**
73
  * @summary Handle the click of the pagination button.s
74
  *
75
- * @since 1.5.4
76
  */
77
  self.onClickPagination = function() {
78
  var $a = $( this ),
@@ -96,7 +96,7 @@ BoldGrid.FolderExclude = function( $ ) {
96
  /**
97
  * @summary Handle the click of the preview button.
98
  *
99
- * @since 1.5.4
100
  */
101
  self.onClickPreview = function() {
102
  var data = {
@@ -140,7 +140,7 @@ BoldGrid.FolderExclude = function( $ ) {
140
  /**
141
  * @summary Handle the click of one of the samples.
142
  *
143
- * @since 1.5.4
144
  */
145
  self.onClickSample = function() {
146
  var $button = $( this ),
@@ -159,7 +159,7 @@ BoldGrid.FolderExclude = function( $ ) {
159
  /**
160
  * @summary Action to take when backup type has been changed.
161
  *
162
- * @since 1.5.4
163
  */
164
  self.onChangeType = function() {
165
  self.toggleConfig();
@@ -176,7 +176,7 @@ BoldGrid.FolderExclude = function( $ ) {
176
  * .current-page input, then we do nothing. Otherwise, we prevent default
177
  * action and do the pagination.
178
  *
179
- * @since 1.5.4
180
  */
181
  self.onKeyDown = function( e ) {
182
  var isCurrentPage = $( e.target ).hasClass( 'current-page' );
@@ -193,7 +193,7 @@ BoldGrid.FolderExclude = function( $ ) {
193
  /**
194
  * @summary Handle pagination.
195
  *
196
- * @since 1.5.4
197
  */
198
  self.onSubmitPagination = function() {
199
  var page = parseInt( $excludeFoldersPreview.find( '.current-page' ).val() ),
@@ -214,7 +214,7 @@ BoldGrid.FolderExclude = function( $ ) {
214
  * has typed into the filter box though, filteredList will be genereated
215
  * based on the filtered values.
216
  *
217
- * @since 1.5.4
218
  *
219
  * @todo Possibly move this toward a template system. For now, it works.
220
  *
@@ -281,7 +281,7 @@ BoldGrid.FolderExclude = function( $ ) {
281
  *
282
  * @todo Possibly move this toward a template system. For now, it works.
283
  *
284
- * @since 1.5.4
285
  *
286
  * @param int page
287
  * @param int perPage
@@ -350,7 +350,7 @@ BoldGrid.FolderExclude = function( $ ) {
350
  /**
351
  * @summary Toggle display of everything after the "full" or "custom" options.
352
  *
353
- * @since 1.5.4
354
  */
355
  self.toggleConfig = function() {
356
  var type = $type.filter( ':checked' ).val(),
1
  /**
2
+ * Folder Exclude
3
  *
4
+ * @summary JavaScript for handling Folder Exclude settings.
5
  *
6
+ * @since 1.6.0
7
  *
8
  * @param $ The jQuery object.
9
  */
72
  /**
73
  * @summary Handle the click of the pagination button.s
74
  *
75
+ * @since 1.6.0
76
  */
77
  self.onClickPagination = function() {
78
  var $a = $( this ),
96
  /**
97
  * @summary Handle the click of the preview button.
98
  *
99
+ * @since 1.6.0
100
  */
101
  self.onClickPreview = function() {
102
  var data = {
140
  /**
141
  * @summary Handle the click of one of the samples.
142
  *
143
+ * @since 1.6.0
144
  */
145
  self.onClickSample = function() {
146
  var $button = $( this ),
159
  /**
160
  * @summary Action to take when backup type has been changed.
161
  *
162
+ * @since 1.6.0
163
  */
164
  self.onChangeType = function() {
165
  self.toggleConfig();
176
  * .current-page input, then we do nothing. Otherwise, we prevent default
177
  * action and do the pagination.
178
  *
179
+ * @since 1.6.0
180
  */
181
  self.onKeyDown = function( e ) {
182
  var isCurrentPage = $( e.target ).hasClass( 'current-page' );
193
  /**
194
  * @summary Handle pagination.
195
  *
196
+ * @since 1.6.0
197
  */
198
  self.onSubmitPagination = function() {
199
  var page = parseInt( $excludeFoldersPreview.find( '.current-page' ).val() ),
214
  * has typed into the filter box though, filteredList will be genereated
215
  * based on the filtered values.
216
  *
217
+ * @since 1.6.0
218
  *
219
  * @todo Possibly move this toward a template system. For now, it works.
220
  *
281
  *
282
  * @todo Possibly move this toward a template system. For now, it works.
283
  *
284
+ * @since 1.6.0
285
  *
286
  * @param int page
287
  * @param int perPage
350
  /**
351
  * @summary Toggle display of everything after the "full" or "custom" options.
352
  *
353
+ * @since 1.6.0
354
  */
355
  self.toggleConfig = function() {
356
  var type = $type.filter( ':checked' ).val(),
admin/js/boldgrid-backup-admin-ftp-settings.js CHANGED
@@ -1,9 +1,9 @@
1
  /**
2
- * BoldGrid Backup FTP Settings
3
  *
4
  * @summary JavaScript for handling FTP Settings page.
5
  *
6
- * @since 1.5.4
7
  *
8
  * @param $ The jQuery object.
9
  */
@@ -17,13 +17,13 @@ BoldGrid.FtpSettings = function( $ ) {
17
 
18
  var self = this,
19
  lang = BoldGridBackupAdminFtpSettings,
20
- $action = $( '[name="action"]' ),
21
- $port = $( '[name="port"]' ),
22
- $type = $( '[name="type"]' ),
23
- $form = $port.closest( 'form' ),
24
- $saveButton = $form.find( '.button-primary' ),
25
- $deleteButton = $form.find( '.button-secondary' ),
26
- $spinner = $form.find( '.spinner' );
27
 
28
  /**
29
  * @summary Take action when the delete button is clicked.
@@ -38,7 +38,7 @@ BoldGrid.FtpSettings = function( $ ) {
38
  /**
39
  * @summary Action to take when form has been submitted.
40
  *
41
- * @since 1.5.4
42
  */
43
  self.onSubmit = function() {
44
  $saveButton.attr( 'disabled', true );
@@ -51,7 +51,7 @@ BoldGrid.FtpSettings = function( $ ) {
51
  /**
52
  * @summary Action to take when type has been changed.
53
  *
54
- * @since 1.5.4
55
  */
56
  self.onTypeChange = function() {
57
  var suggestedPort = lang.default_port[$type.val()];
@@ -60,6 +60,14 @@ BoldGrid.FtpSettings = function( $ ) {
60
  };
61
 
62
  $( function() {
 
 
 
 
 
 
 
 
63
  $type.on( 'change', self.onTypeChange );
64
  $form.on( 'submit', self.onSubmit );
65
  $deleteButton.on( 'click', self.onClickDelete );
1
  /**
2
+ * FTP Settings
3
  *
4
  * @summary JavaScript for handling FTP Settings page.
5
  *
6
+ * @since 1.6.0
7
  *
8
  * @param $ The jQuery object.
9
  */
17
 
18
  var self = this,
19
  lang = BoldGridBackupAdminFtpSettings,
20
+ $action,
21
+ $port,
22
+ $type,
23
+ $form,
24
+ $saveButton,
25
+ $deleteButton,
26
+ $spinner;
27
 
28
  /**
29
  * @summary Take action when the delete button is clicked.
38
  /**
39
  * @summary Action to take when form has been submitted.
40
  *
41
+ * @since 1.6.0
42
  */
43
  self.onSubmit = function() {
44
  $saveButton.attr( 'disabled', true );
51
  /**
52
  * @summary Action to take when type has been changed.
53
  *
54
+ * @since 1.6.0
55
  */
56
  self.onTypeChange = function() {
57
  var suggestedPort = lang.default_port[$type.val()];
60
  };
61
 
62
  $( function() {
63
+ ( $action = $( '[name="action"]' ) ),
64
+ ( $port = $( '[name="port"]' ) ),
65
+ ( $type = $( '[name="type"]' ) ),
66
+ ( $form = $port.closest( 'form' ) ),
67
+ ( $saveButton = $form.find( '.button-primary' ) ),
68
+ ( $deleteButton = $form.find( '.button-secondary' ) ),
69
+ ( $spinner = $form.find( '.spinner' ) );
70
+
71
  $type.on( 'change', self.onTypeChange );
72
  $form.on( 'submit', self.onSubmit );
73
  $deleteButton.on( 'click', self.onClickDelete );
admin/js/boldgrid-backup-admin-home.js CHANGED
@@ -1,7 +1,7 @@
1
  /**
2
- * BoldGrid Backup admin home page.
3
  *
4
- * @summary JavaScript for the BoldGrid Backup admin home page.
5
  *
6
  * @since 1.0
7
  *
@@ -18,12 +18,14 @@ BOLDGRID.BACKUP.HOME = function( $ ) {
18
 
19
  // General Variables.
20
  var self = this,
 
21
  $fileInput = $( 'input:file' ),
22
  $mineCount = $( '.mine' ),
23
  $mineCountHelp = $( '.subsubsub' ).find( '.dashicons' );
24
 
25
  // Onload event listener.
26
  $( function() {
 
27
 
28
  // On click action for the Upload button.
29
  $( '#upload-archive-form' )
@@ -50,6 +52,17 @@ BOLDGRID.BACKUP.HOME = function( $ ) {
50
  $mineCount.on( 'click', self.onClickCount ).on( 'mouseover', function() {
51
  $mineCountHelp.bgbuDrawAttention();
52
  } );
 
 
 
 
 
 
 
 
 
 
 
53
  } );
54
 
55
  /**
@@ -126,7 +139,7 @@ BOLDGRID.BACKUP.HOME = function( $ ) {
126
  /**
127
  * @summary Action to take when a user clicks on a mine count.
128
  *
129
- * @since 1.5.4
130
  */
131
  self.onClickCount = function() {
132
  var $anchor = $( this ),
@@ -191,6 +204,105 @@ BOLDGRID.BACKUP.HOME = function( $ ) {
191
  .next( '.help' )
192
  .toggle();
193
  };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
194
  };
195
 
196
  BOLDGRID.BACKUP.HOME( jQuery );
1
  /**
2
+ * Plugin home page
3
  *
4
+ * @summary JavaScript for the plugin home page.
5
  *
6
  * @since 1.0
7
  *
18
 
19
  // General Variables.
20
  var self = this,
21
+ lang = BoldGridBackupAdminHome,
22
  $fileInput = $( 'input:file' ),
23
  $mineCount = $( '.mine' ),
24
  $mineCountHelp = $( '.subsubsub' ).find( '.dashicons' );
25
 
26
  // Onload event listener.
27
  $( function() {
28
+ var $urlImportSection = $( '#url-import-section' );
29
 
30
  // On click action for the Upload button.
31
  $( '#upload-archive-form' )
52
  $mineCount.on( 'click', self.onClickCount ).on( 'mouseover', function() {
53
  $mineCountHelp.bgbuDrawAttention();
54
  } );
55
+
56
+ $urlImportSection
57
+ .find( 'input' )
58
+ .first()
59
+ .keypress( function( e ) {
60
+ if ( 13 === e.which ) {
61
+ self.urlUpload( e );
62
+ }
63
+ } );
64
+
65
+ $urlImportSection.find( '.button' ).on( 'click', self.urlUpload );
66
  } );
67
 
68
  /**
139
  /**
140
  * @summary Action to take when a user clicks on a mine count.
141
  *
142
+ * @since 1.6.0
143
  */
144
  self.onClickCount = function() {
145
  var $anchor = $( this ),
204
  .next( '.help' )
205
  .toggle();
206
  };
207
+
208
+ /**
209
+ * Upload a file from a URL address.
210
+ *
211
+ * @since 1.7.0
212
+ */
213
+ self.urlUpload = function( e ) {
214
+ var jqxhr,
215
+ $this = $( this ),
216
+ $spinner = $this.next(),
217
+ $notice = $( '#url-import-notice' ),
218
+ wpnonce = $( '#_wpnonce' ).val(),
219
+ urlRegex = new RegExp( lang.urlRegex, 'i' ),
220
+ data = {
221
+ action: 'boldgrid_backup_url_upload',
222
+ _wpnonce: wpnonce,
223
+ _wp_http_referer: $( 'input[name="_wp_http_referer"]' ).val(),
224
+ url: $( 'input[name="url"]' ).val()
225
+ };
226
+
227
+ e.preventDefault();
228
+
229
+ if ( ! urlRegex.test( data.url ) ) {
230
+ $notice
231
+ .removeClass( 'notice-success' )
232
+ .addClass( 'notice-error' )
233
+ .html( lang.invalidUrl )
234
+ .wrapInner( '<p></p>' )
235
+ .show();
236
+
237
+ return;
238
+ }
239
+
240
+ $notice
241
+ .removeClass( 'notice-error' )
242
+ .addClass( 'notice-success' )
243
+ .empty()
244
+ .hide();
245
+
246
+ $this.attr( 'disabled', 'disabled' );
247
+
248
+ $spinner.addClass( 'inline' );
249
+
250
+ jqxhr = $.post( ajaxurl, data, function( response ) {
251
+ if ( response.data !== undefined && response.data.filepath !== undefined ) {
252
+ $notice
253
+ .removeClass( 'notice-error' )
254
+ .addClass( 'notice-success' )
255
+ .html(
256
+ lang.savedTo +
257
+ response.data.filepath +
258
+ ' <a class="button" href="' +
259
+ response.data.detailsUrl +
260
+ '">' +
261
+ lang.viewDetails +
262
+ '</a>' +
263
+
264
+ // Add a "Restore" button.
265
+ ' <a class="button restore-now" href="#"' +
266
+ ' data-restore-now=1' +
267
+ '" data-archive-filename="' +
268
+ response.data.archiveFilename +
269
+ '" data-archive-key="' +
270
+ response.data.archiveKey +
271
+ '" data-nonce="' +
272
+ $( '[name="_wpnonce_restore"]' ).val() +
273
+ '">' +
274
+ lang.restore +
275
+ '</a><span class="spinner"></span>'
276
+ );
277
+ } else if ( response.data !== undefined && response.data.error !== undefined ) {
278
+ $notice
279
+ .removeClass( 'notice-success' )
280
+ .addClass( 'notice-error' )
281
+ .html( response.data.error );
282
+
283
+ $this.removeAttr( 'disabled' );
284
+ } else {
285
+ $notice
286
+ .removeClass( 'notice-success' )
287
+ .addClass( 'notice-error' )
288
+ .html( lang.unknownError );
289
+
290
+ $this.removeAttr( 'disabled' );
291
+ }
292
+ } )
293
+ .error( function() {
294
+ $notice
295
+ .removeClass( 'notice-success' )
296
+ .addClass( 'notice-error' )
297
+ .html( lang.ajaxError + jqxhr.status + ' (' + jqxhr.statusText + ')' );
298
+
299
+ $this.removeAttr( 'disabled' );
300
+ } )
301
+ .always( function() {
302
+ $notice.wrapInner( '<p></p>' ).show();
303
+ $spinner.removeClass( 'inline' );
304
+ } );
305
+ };
306
  };
307
 
308
  BOLDGRID.BACKUP.HOME( jQuery );
admin/js/boldgrid-backup-admin-in-progress.js ADDED
@@ -0,0 +1,616 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Backup In Progress Bar
3
+ *
4
+ * @summary This file handles the "In progress" bar for when a backup is in progress.
5
+ *
6
+ * @since 1.7.0
7
+ */
8
+
9
+ /* global jQuery,wp */
10
+
11
+ var BOLDGRID = BOLDGRID || {};
12
+
13
+ BOLDGRID.BACKUP = BOLDGRID.BACKUP || {};
14
+
15
+ ( function( $ ) {
16
+ 'use strict';
17
+
18
+ var self;
19
+
20
+ /**
21
+ * Suggest starter content.
22
+ *
23
+ * @since 1.7.0
24
+ */
25
+ BOLDGRID.BACKUP.InProgress = {
26
+
27
+ /**
28
+ * Whether or not there's an "In progress" notice on the page.
29
+ *
30
+ * @since 1.11.2
31
+ *
32
+ * @type bool
33
+ */
34
+ hasProgressNotice: false,
35
+
36
+ /**
37
+ * Whether or not there's an "Update Protection" notice on the page.
38
+ *
39
+ * @since 1.11.2
40
+ *
41
+ * @type bool
42
+ */
43
+ hasProtectionNotice: false,
44
+
45
+ /**
46
+ * Label.
47
+ *
48
+ * @since 1.7.0
49
+ *
50
+ * @type string
51
+ */
52
+ $label: null,
53
+
54
+ /**
55
+ * In progress notice.
56
+ *
57
+ * @since 1.7.0
58
+ *
59
+ * @type string
60
+ */
61
+ $inProgressNotice: null,
62
+
63
+ /**
64
+ * i18n.
65
+ *
66
+ * @since 1.7.0
67
+ *
68
+ * @type object
69
+ */
70
+ i18n: window.BoldGridBackupAdminInProgress || {},
71
+
72
+ /**
73
+ * The Update Protection notice.
74
+ *
75
+ * @since 1.11.2
76
+ *
77
+ * @type string
78
+ */
79
+ $protectionNotice: null,
80
+
81
+ /**
82
+ * Init.
83
+ *
84
+ * @since 1.7.0
85
+ */
86
+ init: function() {
87
+ self._onReady();
88
+ },
89
+
90
+ /**
91
+ * On ready.
92
+ *
93
+ * @since 1.7.0
94
+ */
95
+ _onReady: function() {
96
+ $( function() {
97
+ if ( 'undefined' !== typeof wp.heartbeat ) {
98
+
99
+ /*
100
+ * Check for a backup in progress.
101
+ *
102
+ * If there is, we need to begin listenting to the heartbeat to find out when it
103
+ * completes (so we can adjust the message).
104
+ */
105
+ setTimeout( self.onInProgress, 1000 );
106
+
107
+ /*
108
+ * Event "boldgrid_backup_progress_notice_added" currently only triggered within the
109
+ * customizer. When a user clicks on themes, we may dynamically show them a notice that
110
+ * a backup is in progress.
111
+ */
112
+ $( document ).on( 'boldgrid_backup_progress_notice_added', 'body', self.onInProgress );
113
+
114
+ /*
115
+ * Take action when a backup is started.
116
+ *
117
+ * The only script triggering this event is backup-now.js.
118
+ */
119
+ $( document ).on( 'boldgrid_backup_initiated', 'body', self.onBackupInitiated );
120
+
121
+ $( document ).on( 'boldgrid_backup_complete', 'body', self.onComplete );
122
+
123
+ // Configure our "Update Protection" values.
124
+ self.$protectionNotice = $( '.boldgrid-backup-protect-now' );
125
+ self.hasProtectionNotice = 1 === self.$protectionNotice.length;
126
+ } else {
127
+
128
+ // Something's gone wrong.
129
+ console.log( 'Error: Progress bar needs heartbeat enqueued.' );
130
+ }
131
+ } );
132
+ },
133
+
134
+ /**
135
+ * Determine whether or not a step is active.
136
+ *
137
+ * @since 1.7.0
138
+ *
139
+ * @param string step The id of the container.
140
+ * @return bool
141
+ */
142
+ isStepActive: function( step ) {
143
+ return $( '#boldgrid_backup_in_progress_steps' )
144
+ .find( '[data-step="' + step + '"]' )
145
+ .hasClass( 'active' );
146
+ },
147
+
148
+ /**
149
+ * Action to take when a backup is initiated.
150
+ *
151
+ * We configure the heartbeat and the progress bar.
152
+ *
153
+ * @since 1.7.0
154
+ */
155
+ onBackupInitiated: function() {
156
+ self.heartbeatStart();
157
+
158
+ // Show and initialize our progress bar.
159
+ $( '#boldgrid_backup_in_progress_container' ).show();
160
+ self.$label = $( '.progress-label' );
161
+ self.setPercentage( 0 );
162
+ },
163
+
164
+ /**
165
+ * Action to take when a backup is completed.
166
+ *
167
+ * This function is called within this file's onHeartbeatTick listener.
168
+ *
169
+ * @since 1.7.0
170
+ *
171
+ * @param object data The data object received from the WordPress Heartbeat.
172
+ */
173
+ onComplete: function( data ) {
174
+ var success;
175
+
176
+ // If we don't have any error messages, backup was a success.
177
+ success = '' === data.boldgrid_backup_error;
178
+
179
+ // Bail out of the heartbeat.
180
+ $( document ).off( 'heartbeat-tick', self.onHeartbeatTick );
181
+ $( document ).off( 'heartbeat-send', self.heartbeatModify );
182
+
183
+ /*
184
+ * Enable buttons again.
185
+ *
186
+ * We disabled certain buttons during the backup, like "Update now" and "Backup site now".
187
+ * Enable those buttons now.
188
+ */
189
+ if ( undefined !== BOLDGRID.BACKUP.UpdateSelectors ) {
190
+ BOLDGRID.BACKUP.UpdateSelectors.enable();
191
+ } else {
192
+ console.log( 'Error: BOLDGRID.BACKUP.UpdateSelectors class not available.' );
193
+ }
194
+
195
+ $( 'body' ).trigger( 'make_notices_dismissible' );
196
+
197
+ /*
198
+ * Hide "in progress" notices.
199
+ *
200
+ * There's no longer a backup in progress, so hide the progress bar.
201
+ *
202
+ * The notice is either:
203
+ * 1: Inside of its own .notice container, represented by self.$inProgressNotice. This
204
+ * is the admin notice added on page load when a backup is in progress.
205
+ * 2: Inside the "Update protection" notice, represented by #boldgrid_backup_in_progress_container.
206
+ * This is hidden on page load, and shown dynamically when a backup is initiated.
207
+ */
208
+ self.$inProgressNotice.slideUp();
209
+ $( '#boldgrid_backup_in_progress_container' ).slideUp();
210
+
211
+ success ? self.onSuccess( data ) : self.onError( data );
212
+ },
213
+
214
+ /**
215
+ * Steps to take when an error has occurred.
216
+ *
217
+ * @since 1.11.2
218
+ *
219
+ * @param object Heartbeat data.
220
+ */
221
+ onError: function( data ) {
222
+ var $notice;
223
+
224
+ if ( self.hasProtectionNotice ) {
225
+ self.$protectionNotice
226
+
227
+ // Change the notice from a warning to an error.
228
+ .removeClass( 'notice-warning' )
229
+ .addClass( 'notice-error' )
230
+
231
+ // Clean up the existing markup of the notice.
232
+ .find( '#protection_enabled' )
233
+ .nextAll()
234
+ .remove()
235
+ .end()
236
+ .remove()
237
+ .end()
238
+
239
+ // Break the news and tell the user an error occurred.
240
+ .append( '<p>' + self.i18n.backup_error + '</p>' )
241
+ .append(
242
+ '<div class="notice"><p><strong>' +
243
+ self.i18n.error +
244
+ '</strong><br /><em>' +
245
+ data.in_progress_data.error +
246
+ '</em></p></div>'
247
+ )
248
+ .append( '<p>' + self.i18n.get_support + '</p>' );
249
+ } else {
250
+ $notice = $( data.boldgrid_backup_error );
251
+ $notice
252
+
253
+ // Hide the notice before inserting it so that we can display it using slide down.
254
+ .css( 'display', 'none' )
255
+ .insertBefore( self.$inProgressNotice )
256
+ .slideDown();
257
+ }
258
+ },
259
+
260
+ /**
261
+ * Steps to take when our backup was successful.
262
+ *
263
+ * @since 1.11.2
264
+ *
265
+ * @param object Heartbeat data.
266
+ */
267
+ onSuccess: function( data ) {
268
+ var $notice;
269
+
270
+ if ( self.hasProgressNotice ) {
271
+
272
+ /*
273
+ * Display our notice.
274
+ *
275
+ * The backup is complete, and we either have a success notice or an error notice. Figure
276
+ * out which it is, and then display it.
277
+ *
278
+ * The markup for the actual notice is given to us via the heartbeat call.
279
+ */
280
+ $notice = $( data.boldgrid_backup_complete );
281
+ $notice
282
+
283
+ // Hide the notice before inserting it so that we can display it using slide down.
284
+ .css( 'display', 'none' )
285
+ .insertBefore( self.$inProgressNotice )
286
+ .slideDown();
287
+ }
288
+
289
+ /*
290
+ * Show a notice that upgrade protection is now enabled. This updates the current notice
291
+ * rather than generate a new one.
292
+ *
293
+ * This logic was originally introduced in 1.5.3 within backup-now.js. As of 1.11.2 it
294
+ * has been moved here so that backup-now.js can focus soley on triggering the ajax call
295
+ * to generate the backup and nothing else.
296
+ */
297
+ $( '#backup-site-now-results' )
298
+ .closest( '.notice' )
299
+
300
+ // Change it from warning to success.
301
+ .removeClass( 'notice-warning' )
302
+ .addClass( 'notice-success' )
303
+
304
+ // Find the protection enabled and change the html.
305
+ .find( '#protection_enabled' )
306
+ .html( self.i18n.update_protection_activated );
307
+
308
+ /*
309
+ * When a backup is completed, replace the "Backup Site Now" button with a "Backup Created
310
+ * Successfully" message.
311
+ *
312
+ * The .backup-site-now-section is the container for the "Backup Site Now" <form>.
313
+ *
314
+ * We're targeting the "visible" section so that the non-visible section, the one in the
315
+ * modal, does not get overwritten.
316
+ */
317
+ $( '#backup-site-now-section:visible' ).html( '<p>' + self.i18n.backup_created + '</p>' );
318
+ },
319
+
320
+ /**
321
+ * Steps to take when the heartbeat ticket is received.
322
+ *
323
+ * @since 1.7.0
324
+ */
325
+ onHeartbeatTick: function( e, data ) {
326
+
327
+ /*
328
+ * This class deals with backups in progress. If our in progress class didn't give us
329
+ * any information, abort.
330
+ */
331
+ if ( undefined === data.boldgrid_backup_in_progress ) {
332
+ return;
333
+ }
334
+
335
+ /*
336
+ * Ensure the fast heartbeat.
337
+ *
338
+ * At this point in the script, we've already set the heartbeat to fast. The problem
339
+ * is that this elevated heartbeat only lasts for at most 2.5 minutes. If you've got
340
+ * a really big site, once that heartbeat goes back to 60, it's going to look like
341
+ * this froze.
342
+ */
343
+ if ( 5 !== wp.heartbeat.interval ) {
344
+ wp.heartbeat.interval( 'fast' );
345
+ }
346
+
347
+ if ( data.in_progress_data.percentage ) {
348
+ self.setPercentage( data.in_progress_data.percentage );
349
+ }
350
+
351
+ // Update our progress bar.
352
+ if ( 1 === data.in_progress_data.step ) {
353
+ self.onStepDatabase( data.in_progress_data );
354
+ } else if ( 2 === data.in_progress_data.step ) {
355
+ self.onStepAddingFiles( data.in_progress_data );
356
+ } else if ( 3 === data.in_progress_data.step && data.in_progress_data.tmp ) {
357
+ self.onStepSaving( data.in_progress_data );
358
+ } else {
359
+ self.setStepActive();
360
+ self.setLabel( data.in_progress_data.status );
361
+ self.setSubText();
362
+ }
363
+
364
+ /*
365
+ * Steps to take when we no longer have a backup in progress.
366
+ *
367
+ * @todo This logic to determine when a backup has been completed needs to be improved.
368
+ */
369
+ if ( null === data.boldgrid_backup_in_progress ) {
370
+ self.onComplete( data );
371
+ }
372
+ },
373
+
374
+ /**
375
+ * Action to take if we have a backup in progress.
376
+ *
377
+ * This function is ran when the page is ready. It checks to see if we're showing a "Backup
378
+ * In Progress" notice. If we are, then we need to hook into the heartbeat and find out when
379
+ * that backup has been completed.
380
+ *
381
+ * @since 1.7.0
382
+ */
383
+ onInProgress: function() {
384
+ self.$inProgressNotice = $( '.boldgrid-backup-in-progress' );
385
+
386
+ self.hasProgressNotice = 1 === self.$inProgressNotice.length;
387
+
388
+ if ( self.hasProgressNotice ) {
389
+ self.onBackupInitiated();
390
+ }
391
+ },
392
+
393
+ /**
394
+ * Steps to take with the progress bar when we're adding files to the archive.
395
+ *
396
+ * @since 1.7.0
397
+ *
398
+ * @param object In progress data received from ajax call.
399
+ */
400
+ onStepAddingFiles: function( data ) {
401
+ var percentage = Math.floor( ( data.total_files_done / data.total_files_todo ) * 100 );
402
+
403
+ self.setStepActive( 2 );
404
+
405
+ self.setPercentage( percentage );
406
+
407
+ self.setLabel( percentage + '%' );
408
+
409
+ /*
410
+ * Different styles are needed as the progress bar reaches 50% and begins to overlap
411
+ * the status text.
412
+ */
413
+ if ( 50 <= percentage ) {
414
+ self.$label.addClass( 'over-50' );
415
+ }
416
+
417
+ if ( 100 === percentage && data.status ) {
418
+ self.setSubText();
419
+ }
420
+
421
+ /*
422
+ * If we have "last files" data within our "in progress data", loop through and use a
423
+ * setTimeout to display each one.
424
+ */
425
+ if ( data.last_files ) {
426
+ for ( var i = 0; i < data.last_files.length; i++ ) {
427
+ setTimeout( self.setSubText, i * 1000 + 1, data.last_files[i] );
428
+ }
429
+ }
430
+ },
431
+
432
+ /**
433
+ * Steps to take with the progress bar when we're backing up the database.
434
+ *
435
+ * @since 1.7.0
436
+ *
437
+ * @param object In progress data received from ajax call.
438
+ */
439
+ onStepDatabase: function( data ) {
440
+ var stepIsActive = self.isStepActive( 1 ),
441
+ timeout;
442
+
443
+ self.setStepActive( 1 );
444
+
445
+ /*
446
+ * Show tables being backed up.
447
+ *
448
+ * We only run this step once, the first time we know that database tables are being
449
+ * backed up.
450
+ */
451
+ if ( ! stepIsActive ) {
452
+ self.setSubText( self.i18n.adding_tables );
453
+
454
+ for ( var i = 0; i < data.tables.length; i++ ) {
455
+ timeout = ( ( i + 1 ) * 5000 ) / data.tables.length;
456
+ setTimeout( self.setLabel, timeout, data.tables[i] );
457
+ }
458
+
459
+ /*
460
+ * We really don't know how long the database backup will take. In the above loop,
461
+ * we show all the tables that are being backed up within a 5 second period. After
462
+ * that time, we just finish it up with a "Completing database backup" message,
463
+ * which for more users shouldn't show for too long.
464
+ */
465
+ setTimeout( function() {
466
+ self.setLabel( self.i18n.completing_database );
467
+ self.setSubText();
468
+ }, timeout + 2000 );
469
+ }
470
+ },
471
+
472
+ /**
473
+ * Steps to take with the progress bar when we're saving the archive.
474
+ *
475
+ * @since 1.7.0
476
+ *
477
+ * @param object In progress data received from ajax call.
478
+ */
479
+ onStepSaving: function( data ) {
480
+ var percentage = Math.floor( ( data.tmp.size / data.total_size_archived ) * 100 );
481
+
482
+ self.setStepActive( 3 );
483
+
484
+ self.setPercentage( percentage );
485
+
486
+ self.setLabel( ' ' + self.i18n.archive_file_size + data.tmp.size_format );
487
+
488
+ self.setSubText( self.i18n.size_before_compression + data.total_size_archived_size_format );
489
+ },
490
+
491
+ /**
492
+ * Set the text of the progress bar label.
493
+ *
494
+ * For example, if we're at 50% and the progress bar actually says "50%", it's the label
495
+ * that we're seeing.
496
+ *
497
+ * @since 1.7.0
498
+ */
499
+ setLabel: function( string ) {
500
+ self.$label.text( string );
501
+ },
502
+
503
+ /**
504
+ * Set the percentage of the progress bar.
505
+ *
506
+ * @since 1.7.0
507
+ *
508
+ * @param int percentage The percentage complete, 0 - 100.
509
+ */
510
+ setPercentage: function( percentage ) {
511
+ $( '#boldgrid-backup-in-progress-bar' )
512
+ .show()
513
+ .progressbar( {
514
+ value: percentage
515
+ } );
516
+
517
+ if ( 50 <= percentage ) {
518
+ self.$label.addClass( 'over-50' );
519
+ } else {
520
+ self.$label.removeClass( 'over-50' );
521
+ }
522
+ },
523
+
524
+ /**
525
+ * Set a step as being active.
526
+ *
527
+ * @since 2.0.0
528
+ *
529
+ * @param string step The id of the container.
530
+ */
531
+ setStepActive: function( step ) {
532
+ var $container = $( '#boldgrid_backup_in_progress_steps' ),
533
+ $steps = $container.find( '[data-step]' );
534
+
535
+ if ( step && self.isStepActive( step ) ) {
536
+ return;
537
+ }
538
+
539
+ $steps.removeClass( 'active' );
540
+
541
+ if ( step ) {
542
+ $container.find( '[data-step="' + step + '"]' ).addClass( 'active' );
543
+ }
544
+ },
545
+
546
+ /**
547
+ * Set our sub text.
548
+ *
549
+ * For example, if we're adding files and we want to show each file that is being added
550
+ * (in smaller text below the progress bar), that is sub text.
551
+ *
552
+ * @since 2.0.0
553
+ *
554
+ * @param string text
555
+ */
556
+ setSubText: function( text ) {
557
+ var $lastFileArchived = $( '#last_file_archived' );
558
+
559
+ if ( text ) {
560
+ $lastFileArchived.text( text );
561
+ } else {
562
+ $lastFileArchived.empty();
563
+ }
564
+ },
565
+
566
+ /**
567
+ * Modify the heartbeat and tell it we want "boldgrid_backup_in_progress" details.
568
+ *
569
+ * @since 1.7.0
570
+ */
571
+ heartbeatModify: function( e, data ) {
572
+ data.boldgrid_backup_in_progress = true;
573
+ $( 'body' ).removeClass( 'heartbeat-lost-focus' );
574
+ },
575
+
576
+ /**
577
+ * Start "In progress" Heartbeat.
578
+ *
579
+ * @since 1.7.0
580
+ */
581
+ heartbeatStart: function() {
582
+
583
+ // Increase the heartbeat so we can get an update sooner.
584
+ wp.heartbeat.interval( 'fast' );
585
+
586
+ // Modify the heartbeat and ask for an update on our in progress backup.
587
+ $( document ).on( 'heartbeat-send', self.heartbeatModify );
588
+
589
+ // Now that we've modified the heartbeat, we need to listen for its tick.
590
+ $( document ).on( 'heartbeat-tick', self.onHeartbeatTick );
591
+
592
+ /*
593
+ * When your window loses focus, the heartbeat may slow down and you may not get updates
594
+ * as quickly. If you have two windows open and you're not actively looking at the
595
+ * backup in progress, you'll think it froze because of the slower heartbeat.
596
+ *
597
+ * This method adds a class to the body to indicate that the heartbeat has lost focus.
598
+ * The class will lighten the progress bar, to show that it's not currently active.
599
+ */
600
+ window.setInterval( function() {
601
+ var $body = $( 'body' ),
602
+ body_class = 'heartbeat-lost-focus';
603
+
604
+ if ( wp.heartbeat.hasFocus() ) {
605
+ $body.removeClass( body_class );
606
+ } else {
607
+ $body.addClass( body_class );
608
+ }
609
+ }, 5000 );
610
+ }
611
+ };
612
+
613
+ self = BOLDGRID.BACKUP.InProgress;
614
+ } )( jQuery );
615
+
616
+ BOLDGRID.BACKUP.InProgress.init();
admin/js/boldgrid-backup-admin-logs.js ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Backup Logs.
3
+ *
4
+ * @summary This file handles the displaying of log files.
5
+ *
6
+ * @since 1.12.5
7
+ */
8
+
9
+ /* global jQuery */
10
+
11
+ var BOLDGRID = BOLDGRID || {};
12
+
13
+ BOLDGRID.BACKUP = BOLDGRID.BACKUP || {};
14
+
15
+ ( function( $ ) {
16
+ 'use strict';
17
+
18
+ var self;
19
+
20
+ /**
21
+ * Logs.
22
+ *
23
+ * @since 1.12.5
24
+ */
25
+ BOLDGRID.BACKUP.Logs = {
26
+
27
+ /**
28
+ * i18n.
29
+ *
30
+ * @since 1.7.0
31
+ *
32
+ * @type object
33
+ */
34
+ i18n: window.BoldGridBackupAdminLogs || {},
35
+
36
+ /**
37
+ * Init.
38
+ *
39
+ * @since 1.12.5
40
+ */
41
+ init: function() {
42
+ self._onReady();
43
+ },
44
+
45
+ /**
46
+ * Steps to take when a log file is clicked on.
47
+ *
48
+ * @since 1.12.5
49
+ */
50
+ onClickLog: function() {
51
+ var data = {
52
+ action: 'boldgrid_backup_view_log',
53
+ filename: $( this ).attr( 'data-filename' ),
54
+ nonce: $( '#bgbup_log_nonce' ).val()
55
+ };
56
+
57
+ /*
58
+ * Show a loading message in the thickbox modal.
59
+ *
60
+ * Thickbox has a few events, but "on open" is not one of them. The timeout is required
61
+ * to allow some time for the modal to open before we take action. In testing, a 1ms timeout
62
+ * worked. To be on the safe side, we're using 10ms.
63
+ */
64
+ setTimeout( function() {
65
+ $( '#TB_window' ).addClass( 'bg-full-screen' );
66
+
67
+ $( '#TB_ajaxContent' ).html(
68
+ '<p id="bgbu_thickbox_loading">' +
69
+ self.i18n.loading +
70
+ ' <span class="spinner inline"></span></p>'
71
+ );
72
+ }, 10 );
73
+
74
+ $.post( ajaxurl, data, function( response ) {
75
+ $( '#TB_ajaxContent' ).html( response.data );
76
+ } ).error( function() {
77
+ $( '#TB_ajaxConent' ).html(
78
+ '<div class="notice notice-error"><p>' + unknownError + '<p></div>'
79
+ );
80
+ } );
81
+ },
82
+
83
+ /**
84
+ * On ready.
85
+ *
86
+ * @since 1.7.0
87
+ */
88
+ _onReady: function() {
89
+ $( function() {
90
+ $( '#section_logs a[data-filename]' ).on( 'click', self.onClickLog );
91
+ } );
92
+ }
93
+ };
94
+
95
+ self = BOLDGRID.BACKUP.Logs;
96
+ } )( jQuery );
97
+
98
+ BOLDGRID.BACKUP.Logs.init();
admin/js/boldgrid-backup-admin-rollback.js CHANGED
@@ -1,7 +1,7 @@
1
  /**
2
- * BoldGrid Backup admin rollback notice.
3
  *
4
- * @summary JavaScript for the BoldGrid Backup admin rollback notice.
5
  *
6
  * @since 1.0
7
  */
@@ -15,9 +15,9 @@ var BOLDGRID = BOLDGRID || {};
15
  BOLDGRID.BACKUP = BOLDGRID.BACKUP || {};
16
 
17
  /**
18
- * BoldGrid Backup admin rollback.
19
  *
20
- * @summary JavaScript for the BoldGrid Backup admin rollback notice.
21
  *
22
  * @since 1.0
23
  *
1
  /**
2
+ * Rollback notice
3
  *
4
+ * @summary JavaScript for the rollback notice.
5
  *
6
  * @since 1.0
7
  */
15
  BOLDGRID.BACKUP = BOLDGRID.BACKUP || {};
16
 
17
  /**
18
+ * Rollback notice.
19
  *
20
+ * @summary JavaScript for the rollback notice.
21
  *
22
  * @since 1.0
23
  *
admin/js/boldgrid-backup-admin-settings-autoupdate.js ADDED
@@ -0,0 +1,201 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Auto update settings
3
+ *
4
+ * @summary JavaScript for the auto update settings.
5
+ */
6
+
7
+ /* global ajaxurl,jQuery */
8
+
9
+ var BOLDGRID = BOLDGRID || {};
10
+ BOLDGRID.SETTINGS = BOLDGRID.SETTINGS || {};
11
+
12
+ ( function( $ ) {
13
+ BOLDGRID.SETTINGS.AutoUpdate = {
14
+
15
+ /**
16
+ * Constructor.
17
+ *
18
+ * @since 1.7.0
19
+ */
20
+ init: function() {
21
+ $( self._onLoad );
22
+ },
23
+
24
+ /**
25
+ * On DOM load.
26
+ *
27
+ * @since 1.7.0
28
+ */
29
+ _onLoad: function() {
30
+ var $bgBox = $( '.bg-box' );
31
+
32
+ // Initialize jquery-toggles.
33
+ $bgBox.find( '.toggle' ).toggles( {
34
+ text: {
35
+ on: '',
36
+ off: ''
37
+ },
38
+ height: 15,
39
+ width: 40
40
+ } );
41
+
42
+ self._setMasterToggles();
43
+
44
+ $bgBox.find( '.toggle-group' ).on( 'click swipe contextmenu', self._toggleGroup );
45
+
46
+ $bgBox
47
+ .find( '.toggle' )
48
+ .not( '.toggle-group' )
49
+ .on( 'click swipe contextmenu', self._setMasterToggles );
50
+
51
+ $bgBox.find( '.dashicons-editor-help' ).on( 'click', self._toggleHelp );
52
+
53
+ $bgBox.find( '.bglib-collapsible-control' ).on( 'click', function() {
54
+ $( this ).toggleClass( 'bglib-collapsible-open' );
55
+ } );
56
+ },
57
+
58
+ /**
59
+ * Set inputs for toggles.
60
+ *
61
+ * @since 1.7.0
62
+ */
63
+ _setInputs: function() {
64
+ var $bgBox = $( '.bg-box' ),
65
+ $wpcoreToggles = $bgBox.find( '.wpcore-toggle' ),
66
+ $pluginToggles = $bgBox.find( '.plugin-toggle' ),
67
+ $themeToggles = $bgBox.find( '.theme-toggle' ),
68
+ $pluginsDefault = $bgBox.find( '#toggle-default-plugins' ),
69
+ $themesDefault = $bgBox.find( '#toggle-default-themes' );
70
+
71
+ // If the updates section is not in use, then just return.
72
+ if ( ! $pluginsDefault.data( 'toggles' ) ) {
73
+ return;
74
+ }
75
+
76
+ $wpcoreToggles.each( function() {
77
+ var $this = $( this );
78
+
79
+ $this
80
+ .next( 'input' )
81
+ .attr( 'name', 'autoupdate[wpcore][' + $this.data( 'wpcore' ) + ']' )
82
+ .val( $this.data( 'toggles' ).active ? 1 : 0 );
83
+ } );
84
+
85
+ $pluginToggles.each( function() {
86
+ var $this = $( this );
87
+
88
+ $this
89
+ .parent()
90
+ .next( 'input' )
91
+ .attr( 'name', 'autoupdate[plugins][' + $this.data( 'plugin' ) + ']' )
92
+ .val( $this.data( 'toggles' ).active ? 1 : 0 );
93
+ } );
94
+
95
+ $themeToggles.each( function() {
96
+ var $this = $( this );
97
+
98
+ $this
99
+ .parent()
100
+ .next( 'input' )
101
+ .attr( 'name', 'autoupdate[themes][' + $this.data( 'stylesheet' ) + ']' )
102
+ .val( $this.data( 'toggles' ).active ? 1 : 0 );
103
+ } );
104
+
105
+ $pluginsDefault
106
+ .parent()
107
+ .next( 'input' )
108
+ .val( $pluginsDefault.data( 'toggles' ).active ? 1 : 0 );
109
+
110
+ $themesDefault
111
+ .parent()
112
+ .next( 'input' )
113
+ .val( $themesDefault.data( 'toggles' ).active ? 1 : 0 );
114
+ },
115
+
116
+ /**
117
+ * Set master toggles.
118
+ *
119
+ * @since 1.7.0
120
+ */
121
+ _setMasterToggles: function() {
122
+ var $masters = $( '.bg-box' ).find( '.toggle-group' );
123
+
124
+ $masters.each( function() {
125
+ var $master = $( this ),
126
+ state = true;
127
+
128
+ $master
129
+ .closest( '.div-table-body' )
130
+ .find( '.toggle' )
131
+ .not( '.toggle-group,#toggle-default-plugins,#toggle-default-themes' )
132
+ .each( function() {
133
+ if ( ! state || ! $( this ).data( 'toggles' ).active ) {
134
+ state = false;
135
+ }
136
+ } );
137
+
138
+ $master.toggles( state );
139
+ } );
140
+
141
+ self._setInputs();
142
+ },
143
+
144
+ /**
145
+ * Toggle an entire group on/off.
146
+ *
147
+ * @since 1.7.0
148
+ */
149
+ _toggleGroup: function() {
150
+ var $this = $( this ),
151
+ $toggles = $this
152
+ .parent()
153
+ .parent()
154
+ .parent()
155
+ .find( '.toggle' )
156
+ .not( '#toggle-default-plugins,#toggle-default-themes' );
157
+
158
+ $toggles.toggles( $this.data( 'toggles' ).active );
159
+
160
+ self._setInputs();
161
+ },
162
+
163
+ /**
164
+ * Replace the notice with a clone when removed by dismissal.
165
+ *
166
+ * @since 1.7.0
167
+ */
168
+ _replaceNotice: function( $notice ) {
169
+ var $noticeClone = $notice.clone(),
170
+ $noticeNext = $notice.next();
171
+
172
+ $notice.one( 'click.wp-dismiss-notice', '.notice-dismiss', function() {
173
+ $noticeNext.before( $noticeClone );
174
+ $notice = $noticeClone;
175
+ $notice.hide();
176
+ } );
177
+ },
178
+
179
+ /**
180
+ * Handle form submission.
181
+ *
182
+ * @since 1.7.0
183
+ */
184
+ _toggleHelp: function( e ) {
185
+ var id = $( this ).attr( 'data-id' );
186
+
187
+ e.preventDefault();
188
+
189
+ if ( id === undefined ) {
190
+ return false;
191
+ }
192
+
193
+ $( '.help[data-id="' + id + '"]' ).slideToggle();
194
+
195
+ return false;
196
+ }
197
+ };
198
+
199
+ var self = BOLDGRID.SETTINGS.AutoUpdate;
200
+ BOLDGRID.SETTINGS.AutoUpdate.init();
201
+ } )( jQuery );
admin/js/boldgrid-backup-admin-settings.js CHANGED
@@ -1,5 +1,5 @@
1
  /**
2
- * BoldGrid Backup settings.
3
  *
4
  * @summary JavaScript for the settings page.
5
  *
@@ -23,7 +23,8 @@ BoldGrid.Settings = function( $ ) {
23
  $backupDir,
24
  $body = $( 'body' ),
25
  tb_unload_count,
26
- $moveBackups;
 
27
 
28
  /**
29
  * Directory to store backups.
@@ -259,27 +260,26 @@ BoldGrid.Settings = function( $ ) {
259
  };
260
 
261
  /**
262
- * Handle click of the undismissBoldgridNotice link for the key prompt.
263
  *
264
- * @since 1.5.4
265
  */
266
- self.undismissBoldgridNotice = function() {
267
- var data, nonce, wpHttpReferer;
268
-
269
- // Get the wpnonce and referer values.
270
- nonce = $( '#set_key_auth' ).val();
271
- wpHttpReferer = $( '[name="_wp_http_referer"]' ).val();
272
-
273
- data = {
274
- action: 'undismissBoldgridNotice',
275
- notice: 'bg-key-prompt',
276
- set_key_auth: nonce,
277
- _wp_http_referer: wpHttpReferer
278
- };
279
 
280
- $.post( ajaxurl, data, function() {
281
- location.reload();
282
- } );
 
 
 
283
  };
284
 
285
  // Onload event listener.
@@ -303,8 +303,9 @@ BoldGrid.Settings = function( $ ) {
303
 
304
  $body.on( 'click', '#license_check_again', self.onClickCheckAgain );
305
 
306
- /** Reverse dismiss action for the Conect Key prompt **/
307
- $( '.undismissBoldgridNotice' ).on( 'click', self.undismissBoldgridNotice );
 
308
  } );
309
  };
310
 
1
  /**
2
+ * Settings page
3
  *
4
  * @summary JavaScript for the settings page.
5
  *
23
  $backupDir,
24
  $body = $( 'body' ),
25
  tb_unload_count,
26
+ $moveBackups,
27
+ $siteCheck;
28
 
29
  /**
30
  * Directory to store backups.
260
  };
261
 
262
  /**
263
+ * @summary Toggle site check options.
264
  *
265
+ * @since 1.10.0
266
  */
267
+ self.toggleSiteCheck = function() {
268
+ if ( '1' === $siteCheck.filter( ':checked' ).val() ) {
269
+
270
+ // Site Check is enabled.
271
+ $( '#site-check-interval' ).removeAttr( 'disabled' );
272
+ $( 'input[name="site_check_logger"]' ).removeAttr( 'disabled' );
273
+ $( 'input[name="auto_recovery"]' ).removeAttr( 'disabled' );
274
+ $( '#notification-site-check' ).removeAttr( 'disabled' );
275
+ } else {
 
 
 
 
276
 
277
+ // Site Check is disabled.
278
+ $( '#site-check-interval' ).attr( 'disabled', true );
279
+ $( 'input[name="site_check_logger"]' ).attr( 'disabled', true );
280
+ $( 'input[name="auto_recovery"]' ).attr( 'disabled', true );
281
+ $( '#notification-site-check' ).attr( 'disabled', true );
282
+ }
283
  };
284
 
285
  // Onload event listener.
303
 
304
  $body.on( 'click', '#license_check_again', self.onClickCheckAgain );
305
 
306
+ $siteCheck = $( 'input[name="site_check"]' );
307
+ self.toggleSiteCheck();
308
+ $body.on( 'click', $siteCheck, self.toggleSiteCheck );
309
  } );
310
  };
311
 
admin/js/boldgrid-backup-admin-table-include.js CHANGED
@@ -1,9 +1,9 @@
1
  /**
2
- * BoldGrid Backup Table Include.
3
  *
4
- * @summary JavaScript for handling Table include settings.
5
  *
6
- * @since 1.5.4
7
  *
8
  * @param $ The jQuery object.
9
  */
@@ -32,7 +32,7 @@ BoldGrid.TableInclude = function( $ ) {
32
  /**
33
  * @summary Action to take when the type (full / custom) has been changed.
34
  *
35
- * @since 1.5.4
36
  */
37
  self.onChangeType = function() {
38
  self.toggleConfig();
@@ -41,7 +41,7 @@ BoldGrid.TableInclude = function( $ ) {
41
  /**
42
  * @summary Toogle all database tables so they are all backed up.
43
  *
44
- * @since 1.5.4
45
  */
46
  self.toggleAll = function() {
47
  $includeTables.bgbuDrawAttention();
@@ -54,7 +54,7 @@ BoldGrid.TableInclude = function( $ ) {
54
  /**
55
  * @summary Toggle the area that allows you to choose which tables to backup.
56
  *
57
- * @since 1.5.4
58
  */
59
  self.toggleConfig = function() {
60
  var type = $type.filter( ':checked' ).val();
@@ -69,7 +69,7 @@ BoldGrid.TableInclude = function( $ ) {
69
  /**
70
  * @summary Deselect all tables.
71
  *
72
- * @since 1.5.4
73
  */
74
  self.toggleNone = function() {
75
  $includeTables.bgbuDrawAttention();
@@ -82,7 +82,7 @@ BoldGrid.TableInclude = function( $ ) {
82
  /**
83
  * @summary Toogle the status that tells the user if they're backing up all tables.
84
  *
85
- * @since 1.5.4
86
  */
87
  self.toggleStatus = function() {
88
  var allIncluded = $includeTables.length === $includeTables.filter( ':checked' ).length;
1
  /**
2
+ * Table include
3
  *
4
+ * @summary JavaScript for handling table include settings.
5
  *
6
+ * @since 1.6.0
7
  *
8
  * @param $ The jQuery object.
9
  */
32
  /**
33
  * @summary Action to take when the type (full / custom) has been changed.
34
  *
35
+ * @since 1.6.0
36
  */
37
  self.onChangeType = function() {
38
  self.toggleConfig();
41
  /**
42
  * @summary Toogle all database tables so they are all backed up.
43
  *
44
+ * @since 1.6.0
45
  */
46
  self.toggleAll = function() {
47
  $includeTables.bgbuDrawAttention();
54
  /**
55
  * @summary Toggle the area that allows you to choose which tables to backup.
56
  *
57
+ * @since 1.6.0
58
  */
59
  self.toggleConfig = function() {
60
  var type = $type.filter( ':checked' ).val();
69
  /**
70
  * @summary Deselect all tables.
71
  *
72
+ * @since 1.6.0
73
  */
74
  self.toggleNone = function() {
75
  $includeTables.bgbuDrawAttention();
82
  /**
83
  * @summary Toogle the status that tells the user if they're backing up all tables.
84
  *
85
+ * @since 1.6.0
86
  */
87
  self.toggleStatus = function() {
88
  var allIncluded = $includeTables.length === $includeTables.filter( ':checked' ).length;
admin/js/boldgrid-backup-admin-update-selectors.js CHANGED
@@ -1,5 +1,5 @@
1
  /**
2
- * BoldGrid Backup Admin Update Selectors.
3
  *
4
  * JavaScript for handling WordPress' native "update" buttons and links. Primary
5
  * function is to disable "update" buttons when we're in the middle of making a
@@ -49,8 +49,11 @@ BOLDGRID.BACKUP = BOLDGRID.BACKUP || {};
49
  // Customizer > Installed themes > click a theme > "update now" link.
50
  '#update-theme',
51
 
52
- // BoldGrid Backup - Update Protection > "Backup Site Now" button.
53
- '#backup-site-now'
 
 
 
54
  ],
55
 
56
  /**
1
  /**
2
+ * Update Selectors
3
  *
4
  * JavaScript for handling WordPress' native "update" buttons and links. Primary
5
  * function is to disable "update" buttons when we're in the middle of making a
49
  // Customizer > Installed themes > click a theme > "update now" link.
50
  '#update-theme',
51
 
52
+ // Update Protection > "Backup Site Now" button.
53
+ '.notice #backup-site-now',
54
+
55
+ // Backup Archive > "Backup Site Now" button.
56
+ '.page-title-actions .page-title-action'
57
  ],
58
 
59
  /**
admin/js/boldgrid-backup-admin-zip-browser.js CHANGED
@@ -1,5 +1,5 @@
1
  /**
2
- * Browser.
3
  *
4
  * @summary JS for all admin backup pages.
5
  *
@@ -92,7 +92,7 @@ BoldGrid.ZipBrowser = function( $ ) {
92
  /**
93
  * @summary Handle the click of the "load archive browser" button.
94
  *
95
- * @since 1.5.4
96
  */
97
  self.onClickLoadBrowser = function() {
98
  $( this ).attr( 'disabled', 'disabled' );
@@ -103,7 +103,7 @@ BoldGrid.ZipBrowser = function( $ ) {
103
  /**
104
  * @summary Handle the click of the "restore this database" button.
105
  *
106
- * @since 1.5.4
107
  */
108
  self.onClickRestoreDb = function() {
109
  var $a = $( this ),
@@ -140,7 +140,7 @@ BoldGrid.ZipBrowser = function( $ ) {
140
  /**
141
  * @summary Handle the postbox-like toggle on thead th's that hide a table.
142
  *
143
- * @since 1.5.4
144
  */
145
  self.onClickToggle = function() {
146
  var $toggle = $( this ),
@@ -158,7 +158,7 @@ BoldGrid.ZipBrowser = function( $ ) {
158
  /**
159
  * @summary Handle the click of the "View details" button for a database.
160
  *
161
- * @since 1.5.4
162
  */
163
  self.onClickViewDb = function() {
164
  var $a = $( this ),
1
  /**
2
+ * Browser
3
  *
4
  * @summary JS for all admin backup pages.
5
  *
92
  /**
93
  * @summary Handle the click of the "load archive browser" button.
94
  *
95
+ * @since 1.6.0
96
  */
97
  self.onClickLoadBrowser = function() {
98
  $( this ).attr( 'disabled', 'disabled' );
103
  /**
104
  * @summary Handle the click of the "restore this database" button.
105
  *
106
+ * @since 1.6.0
107
  */
108
  self.onClickRestoreDb = function() {
109
  var $a = $( this ),
140
  /**
141
  * @summary Handle the postbox-like toggle on thead th's that hide a table.
142
  *
143
+ * @since 1.6.0
144
  */
145
  self.onClickToggle = function() {
146
  var $toggle = $( this ),
158
  /**
159
  * @summary Handle the click of the "View details" button for a database.
160
  *
161
+ * @since 1.6.0
162
  */
163
  self.onClickViewDb = function() {
164
  var $a = $( this ),
admin/js/boldgrid-backup-admin.js CHANGED
@@ -1,5 +1,5 @@
1
  /**
2
- * This file contains javascript to load on all admin pages of the BoldGrid Backup plugin.
3
  *
4
  * @summary JS for all admin backup pages.
5
  *
@@ -52,18 +52,18 @@ BoldGrid.Backup = function( $ ) {
52
  /**
53
  * @summary Handle the clicking of a show / hide toggle.
54
  *
55
- * In the example below, the show / hide link has a data-toggle-target attr
56
  * that helps to identify the element to toggle.
57
- * # <a href="" data-toggle-target="#more_info">Show</a>
58
  * # <div id="more_info" class="hidden">
59
  *
60
- * @since 1.5.4
61
  */
62
  self.onClickToggle = function() {
63
  var $e = $( this ),
64
  show = 'Show',
65
  hide = 'Hide',
66
- target = $e.attr( 'data-toggle-target' ),
67
  $target = $( target ),
68
  isVisible = $target.is( ':visible' );
69
 
@@ -78,62 +78,6 @@ BoldGrid.Backup = function( $ ) {
78
  return false;
79
  };
80
 
81
- /**
82
- * @summary Action to take if we have a backup in progress.
83
- *
84
- * If we do have a backup in progress, we'll hook into the heartbeat and find
85
- * out when that backup has been completed.
86
- *
87
- * @since 1.6.0
88
- */
89
- self.onInProgress = function() {
90
- var complete = false,
91
- $inProgressNotice = $( '.boldgrid-backup-in-progress' );
92
-
93
- // If we're not actually showing an "in progress" notice, abort.
94
- if ( 1 !== $inProgressNotice.length ) {
95
- return;
96
- }
97
-
98
- // Increase the heartbeat so we can get an update sooner.
99
- wp.heartbeat.interval( 'fast' );
100
-
101
- /*
102
- * When the heartbeat is sent, include that we're looking for an update
103
- * on the in progress backup.
104
- */
105
- $( document ).on( 'heartbeat-send', function( e, data ) {
106
- if ( ! complete ) {
107
- data['boldgrid_backup_in_progress'] = true;
108
- }
109
- } );
110
-
111
- // When the heartbeat is received, check to see if the backup has completed.
112
- $( document ).on( 'heartbeat-tick', function( e, data ) {
113
- var $notice;
114
-
115
- if ( undefined === data.boldgrid_backup_in_progress ) {
116
- return;
117
- }
118
-
119
- if ( ! data.boldgrid_backup_in_progress ) {
120
- $notice = $( data.boldgrid_backup_complete );
121
- $notice
122
- .css( 'display', 'none' )
123
- .insertBefore( $inProgressNotice )
124
- .slideDown();
125
-
126
- $inProgressNotice.slideUp();
127
-
128
- wp.heartbeat.interval( 'standard' );
129
- complete = true;
130
-
131
- $( 'body' ).trigger( 'make_notices_dismissible' );
132
- $( 'body' ).trigger( 'boldgrid_backup_complete' );
133
- }
134
- } );
135
- };
136
-
137
  /**
138
  * @summary Make an admin notice dismissible.
139
  *
@@ -173,14 +117,7 @@ BoldGrid.Backup = function( $ ) {
173
  self.hideBackupNotice();
174
  self.updatePremiumLink();
175
 
176
- /*
177
- * If and when a backup is in progress, we need to begin waiting to hear
178
- * for that backup to complete.
179
- */
180
- self.onInProgress();
181
- $( 'body' ).on( 'boldgrid_backup_progress_notice_added', self.onInProgress );
182
-
183
- $( 'body' ).on( 'click', '[data-toggle-target]', self.onClickToggle );
184
  $( 'body' ).on( 'make_notices_dismissible', self.makeNoticesDismissible );
185
 
186
  /*
@@ -214,7 +151,7 @@ BoldGrid.Backup( jQuery );
214
  /**
215
  * @summary Draw attention to an element.
216
  *
217
- * @since 1.5.4
218
  */
219
  jQuery.fn.bgbuDrawAttention = function() {
220
  var currentColor,
@@ -262,7 +199,7 @@ jQuery.fn.bgbuDrawAttention = function() {
262
  * For example, if we click "restore" on a page, we want to disable all other
263
  * actions within the wpwrap (IE can't restore and delete at the same time).
264
  *
265
- * @since 1.5.4
266
  */
267
  jQuery.fn.bgbuDisableActions = function() {
268
  this.find( 'a, [type="submit"]' ).attr( 'disabled', 'disabled' );
1
  /**
2
+ * This file contains javascript to load on all admin pages of the plugin
3
  *
4
  * @summary JS for all admin backup pages.
5
  *
52
  /**
53
  * @summary Handle the clicking of a show / hide toggle.
54
  *
55
+ * In the example below, the show / hide link has a data-bgbkup-toggle-target attr
56
  * that helps to identify the element to toggle.
57
+ * # <a href="" data-bgbkup-toggle-target="#more_info">Show</a>
58
  * # <div id="more_info" class="hidden">
59
  *
60
+ * @since 1.6.0
61
  */
62
  self.onClickToggle = function() {
63
  var $e = $( this ),
64
  show = 'Show',
65
  hide = 'Hide',
66
+ target = $e.attr( 'data-bgbkup-toggle-target' ),
67
  $target = $( target ),
68
  isVisible = $target.is( ':visible' );
69
 
78
  return false;
79
  };
80
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  /**
82
  * @summary Make an admin notice dismissible.
83
  *
117
  self.hideBackupNotice();
118
  self.updatePremiumLink();
119
 
120
+ $( 'body' ).on( 'click', '[data-bgbkup-toggle-target]', self.onClickToggle );
 
 
 
 
 
 
 
121
  $( 'body' ).on( 'make_notices_dismissible', self.makeNoticesDismissible );
122
 
123
  /*
151
  /**
152
  * @summary Draw attention to an element.
153
  *
154
+ * @since 1.6.0
155
  */
156
  jQuery.fn.bgbuDrawAttention = function() {
157
  var currentColor,
199
  * For example, if we click "restore" on a page, we want to disable all other
200
  * actions within the wpwrap (IE can't restore and delete at the same time).
201
  *
202
+ * @since 1.6.0
203
  */
204
  jQuery.fn.bgbuDisableActions = function() {
205
  this.find( 'a, [type="submit"]' ).attr( 'disabled', 'disabled' );
admin/partials/archive-details/browser-entry.php CHANGED
@@ -1,15 +1,20 @@
1
  <?php
2
  /**
 
 
3
  * Create the <tr> for each file in the archilve.
4
  *
5
- * @link http://www.boldgrid.com
6
  * @since 1.5.3
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin/partials/archive-details
 
 
 
10
  */
11
 
12
- defined( 'WPINC' ) ? : die;
13
 
14
  $class = $file['folder'] ? 'folder' : 'file';
15
 
@@ -45,5 +50,3 @@ return sprintf(
45
  $size,
46
  $this->core->time->get_span()
47
  );
48
-
49
-
1
  <?php
2
  /**
3
+ * File: browser-entry.php
4
+ *
5
  * Create the <tr> for each file in the archilve.
6
  *
7
+ * @link https://www.boldgrid.com
8
  * @since 1.5.3
9
  *
10
  * @package Boldgrid_Backup
11
  * @subpackage Boldgrid_Backup/admin/partials/archive-details
12
+ * @copyright BoldGrid
13
+ * @version $Id$
14
+ * @author BoldGrid <support@boldgrid.com>
15
  */
16
 
17
+ defined( 'WPINC' ) || die;
18
 
19
  $class = $file['folder'] ? 'folder' : 'file';
20
 
50
  $size,
51
  $this->core->time->get_span()
52
  );
 
 
admin/partials/archive-details/browser.php CHANGED
@@ -1,15 +1,20 @@
1
  <?php
2
  /**
 
 
3
  * Display the Archive Browser section on the Archive Details page.
4
  *
5
- * @link http://www.boldgrid.com
6
  * @since 1.5.3
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin/partials/archive-details
 
 
 
10
  */
11
 
12
- defined( 'WPINC' ) ? : die;
13
 
14
  $browser = '
15
  <div id="zip_browser" class="hidden" data-view-type="file">
@@ -23,9 +28,6 @@ $browser = '
23
  </tbody>
24
  </table>
25
  </div>
26
- </div>'
27
- ;
28
 
29
  return $browser;
30
-
31
-
1
  <?php
2
  /**
3
+ * File: browser.php
4
+ *
5
  * Display the Archive Browser section on the Archive Details page.
6
  *
7
+ * @link https://www.boldgrid.com
8
  * @since 1.5.3
9
  *
10
  * @package Boldgrid_Backup
11
  * @subpackage Boldgrid_Backup/admin/partials/archive-details
12
+ * @copyright BoldGrid
13
+ * @version $Id$
14
+ * @author BoldGrid <support@boldgrid.com>
15
  */
16
 
17
+ defined( 'WPINC' ) || die;
18
 
19
  $browser = '
20
  <div id="zip_browser" class="hidden" data-view-type="file">
28
  </tbody>
29
  </table>
30
  </div>
31
+ </div>';
 
32
 
33
  return $browser;
 
 
admin/partials/archive-details/db.php CHANGED
@@ -1,50 +1,64 @@
1
  <?php
2
  /**
 
 
3
  * Display the Database section on the Archive Details page.
4
  *
5
- * @link http://www.boldgrid.com
6
- * @since 1.5.4
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin/partials/archive-details
 
 
10
  */
11
 
12
- defined( 'WPINC' ) ? : die;
13
 
14
- $db = array(
15
  'browser' => '',
16
  'buttons' => '',
17
- );
18
 
19
  if ( empty( $dump_file ) ) {
20
- $db['browser'] = sprintf( '
 
21
  <div class="hidden" data-view-type="db">
22
  <p>%1$s</p>
23
  </div>',
24
  __( 'This archive does not contain a database backup.', 'boldgrid-backup' )
25
  );
 
26
  return $db;
27
  }
28
 
29
- $contains = __( 'This archive contains the following database backup: <strong>%1$s</strong>', 'boldgrid-backup' );
 
 
 
 
 
30
  $basename = basename( $dump_file );
31
 
32
- $db = array(
33
- 'browser' => sprintf( '
 
34
  <div class="hidden" data-view-type="db">
35
  <input type="hidden" id="dump_filename" value="%1$s" />
36
  <div id="db_details" data-rendered="false"></div>
37
  </div>',
38
  $basename
39
  ),
40
- 'buttons' => sprintf(
 
 
 
 
41
  '<a class="restore-db button button-primary" data-file="%2$s" data-view-type="db" style="display:none;">%1$s</a>%3$s',
42
  __( 'Restore this database', 'boldgrid-backup' ),
43
  esc_attr( $basename ),
44
  $this->core->lang['spinner']
45
- ),
46
- );
47
 
48
  return $db;
49
-
50
-
1
  <?php
2
  /**
3
+ * File: db.php
4
+ *
5
  * Display the Database section on the Archive Details page.
6
  *
7
+ * @link https://www.boldgrid.com
8
+ * @since 1.6.0
9
  *
10
  * @package Boldgrid_Backup
11
  * @subpackage Boldgrid_Backup/admin/partials/archive-details
12
+ * @copyright BoldGrid
13
+ * @author BoldGrid <support@boldgrid.com>
14
  */
15
 
16
+ defined( 'WPINC' ) || die;
17
 
18
+ $db = [
19
  'browser' => '',
20
  'buttons' => '',
21
+ ];
22
 
23
  if ( empty( $dump_file ) ) {
24
+ $db['browser'] = sprintf(
25
+ '
26
  <div class="hidden" data-view-type="db">
27
  <p>%1$s</p>
28
  </div>',
29
  __( 'This archive does not contain a database backup.', 'boldgrid-backup' )
30
  );
31
+
32
  return $db;
33
  }
34
 
35
+ // translators: 1: Backup archive filename.
36
+ $contains = esc_html__(
37
+ 'This archive contains the following database backup: <strong>%1$s</strong>',
38
+ 'boldgrid-backup'
39
+ );
40
+
41
  $basename = basename( $dump_file );
42
 
43
+ $db = [
44
+ 'browser' => sprintf(
45
+ '
46
  <div class="hidden" data-view-type="db">
47
  <input type="hidden" id="dump_filename" value="%1$s" />
48
  <div id="db_details" data-rendered="false"></div>
49
  </div>',
50
  $basename
51
  ),
52
+ 'buttons' => null,
53
+ ];
54
+
55
+ if ( empty( $archive['encrypt_db'] ) || ( $is_premium && $is_premium_active ) ) {
56
+ $db['buttons'] = sprintf(
57
  '<a class="restore-db button button-primary" data-file="%2$s" data-view-type="db" style="display:none;">%1$s</a>%3$s',
58
  __( 'Restore this database', 'boldgrid-backup' ),
59
  esc_attr( $basename ),
60
  $this->core->lang['spinner']
61
+ );
62
+ }
63
 
64
  return $db;
 
 
admin/partials/archive-details/details.php CHANGED
@@ -1,56 +1,62 @@
1
  <?php
2
  /**
 
 
3
  * Render the details of a particular backup.
4
  *
5
- * @since 1.5.4
 
6
  *
7
  * @package Boldgrid_Backup
8
- * @subpackage Boldgrid_Backup/admin/partials
 
 
 
9
  *
10
  * @param bool $archive_found Whether or not the archive was found.
11
  */
12
 
13
- defined( 'WPINC' ) ? : die;
14
 
15
  $details = '';
16
 
17
- $attribute = '<p><strong>%1$s</strong>: %2$s</p>';
18
 
19
  $datas = array(
20
  array(
21
- 'key' => 'trigger',
22
  'title' => __( 'Backup triggered by', 'boldgrid-backup' ),
23
  ),
24
  array(
25
- 'key' => 'compressor',
26
  'title' => __( 'Compressor', 'boldgrid-backup' ),
27
  ),
28
  array(
29
- 'key' => 'duration',
30
- 'title' => __( 'Total duration', 'boldgrid-backup' ),
31
  'suffix' => ' ' . __( 'seconds', 'boldgrid-backup' ),
32
  ),
33
  array(
34
- 'key' => 'db_duration',
35
- 'title' => __( 'Time to backup database', 'boldgrid-backup' ),
36
  'suffix' => ' ' . __( 'seconds', 'boldgrid-backup' ),
37
  ),
38
  array(
39
- 'key' => 'mail_success',
40
- 'title' => __( 'Email sent after backup', 'boldgrid-backup' ),
41
  'presentation' => 'bool',
42
  ),
43
  array(
44
- 'key' => 'folder_include',
45
  'title' => __( 'Files included', 'boldgrid-backup' ),
46
  ),
47
  array(
48
- 'key' => 'folder_exclude',
49
  'title' => __( 'Files excluded', 'boldgrid-backup' ),
50
  ),
51
  array(
52
- 'key' => 'table_exclude',
53
- 'title' => __( 'Database tables excluded', 'boldgrid-backup' ),
54
  'presentation' => 'comma_implode',
55
  ),
56
  );
@@ -64,17 +70,22 @@ foreach ( $datas as $data ) {
64
  $details .= sprintf( '<h2>%1$s:</h2>', $data['heading'] );
65
  }
66
 
67
- $value = $archive[ $data['key'] ];
 
 
68
  if ( ! empty( $data['presentation'] ) ) {
69
  switch ( $data['presentation'] ) {
70
  case 'bytes_to_human':
71
- $value = Boldgrid_Backup_Admin_Utility::bytes_to_human( $archive[ $data['key'] ] );
 
72
  break;
73
  case 'bool':
74
- $value = $archive[ $data['key'] ] ? __( 'yes', 'boldgrid-backup' ) : __( 'no', 'boldgrid-backup' );
 
75
  break;
76
  case 'comma_implode':
77
- $value = empty( $value ) ? __( 'n/a', 'boldgrid-backup' ) : implode( ', ', $value );
 
78
  break;
79
  }
80
  }
@@ -87,9 +98,12 @@ foreach ( $datas as $data ) {
87
  $value .= sprintf( '<input type="hidden" id="%1$s" value="%2$s" />', $data['key'], $archive[ $data['key'] ] );
88
  }
89
 
90
- $details .= sprintf( $attribute, $data['title'], $value );
91
  }
92
 
93
- return $details;
94
-
95
-
 
 
 
1
  <?php
2
  /**
3
+ * File: details.php
4
+ *
5
  * Render the details of a particular backup.
6
  *
7
+ * @link https://www.boldgrid.com
8
+ * @since 1.6.0
9
  *
10
  * @package Boldgrid_Backup
11
+ * @subpackage Boldgrid_Backup/admin/partials/archive-details
12
+ * @copyright BoldGrid
13
+ * @version $Id$
14
+ * @author BoldGrid <support@boldgrid.com>
15
  *
16
  * @param bool $archive_found Whether or not the archive was found.
17
  */
18
 
19
+ defined( 'WPINC' ) || die;
20
 
21
  $details = '';
22
 
23
+ $attribute = '<p><strong>%1$s</strong>: <span id="bgb-details-%3$s" data-value="%4$s">%2$s</span></p>';
24
 
25
  $datas = array(
26
  array(
27
+ 'key' => 'trigger',
28
  'title' => __( 'Backup triggered by', 'boldgrid-backup' ),
29
  ),
30
  array(
31
+ 'key' => 'compressor',
32
  'title' => __( 'Compressor', 'boldgrid-backup' ),
33
  ),
34
  array(
35
+ 'key' => 'duration',
36
+ 'title' => __( 'Total duration', 'boldgrid-backup' ),
37
  'suffix' => ' ' . __( 'seconds', 'boldgrid-backup' ),
38
  ),
39
  array(
40
+ 'key' => 'db_duration',
41
+ 'title' => __( 'Time to backup database', 'boldgrid-backup' ),
42
  'suffix' => ' ' . __( 'seconds', 'boldgrid-backup' ),
43
  ),
44
  array(
45
+ 'key' => 'mail_success',
46
+ 'title' => __( 'Email sent after backup', 'boldgrid-backup' ),
47
  'presentation' => 'bool',
48
  ),
49
  array(
50
+ 'key' => 'folder_include',
51
  'title' => __( 'Files included', 'boldgrid-backup' ),
52
  ),
53
  array(
54
+ 'key' => 'folder_exclude',
55
  'title' => __( 'Files excluded', 'boldgrid-backup' ),
56
  ),
57
  array(
58
+ 'key' => 'table_exclude',
59
+ 'title' => __( 'Database tables excluded', 'boldgrid-backup' ),
60
  'presentation' => 'comma_implode',
61
  ),
62
  );
70
  $details .= sprintf( '<h2>%1$s:</h2>', $data['heading'] );
71
  }
72
 
73
+ $value = $archive[ $data['key'] ];
74
+ $value_data = '';
75
+
76
  if ( ! empty( $data['presentation'] ) ) {
77
  switch ( $data['presentation'] ) {
78
  case 'bytes_to_human':
79
+ $value = Boldgrid_Backup_Admin_Utility::bytes_to_human( $archive[ $data['key'] ] );
80
+ $value_data = $archive[ $data['key'] ];
81
  break;
82
  case 'bool':
83
+ $value = $archive[ $data['key'] ] ? __( 'yes', 'boldgrid-backup' ) : __( 'no', 'boldgrid-backup' );
84
+ $value_data = $archive[ $data['key'] ] ? 'Y' : 'N';
85
  break;
86
  case 'comma_implode':
87
+ $value = empty( $value ) ? __( 'n/a', 'boldgrid-backup' ) : implode( ', ', $value );
88
+ $value_data = $value;
89
  break;
90
  }
91
  }
98
  $value .= sprintf( '<input type="hidden" id="%1$s" value="%2$s" />', $data['key'], $archive[ $data['key'] ] );
99
  }
100
 
101
+ $details .= sprintf( $attribute, $data['title'], $value, $data['key'], $value_data );
102
  }
103
 
104
+ /**
105
+ * Filter the archive details.
106
+ *
107
+ * @since 1.12.0
108
+ */
109
+ return apply_filters( 'boldgrid_backup_filter_archive_details', $details, $archive );
admin/partials/archive-details/not-found.php CHANGED
@@ -1,16 +1,20 @@
1
  <?php
2
  /**
 
 
3
  * Display for instances in which backup is not local and not remote.
4
  *
5
- * @link http://www.boldgrid.com
6
  * @since 1.6.0
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin/partials/archive-details
 
 
 
10
  */
11
 
12
- defined( 'WPINC' ) ? : die;
13
-
14
- return '<p>' . $this->core->lang['icon_warning'] . __( 'Backup file not found!', 'boldgrid-backup' ) . '</p>';
15
-
16
 
 
 
1
  <?php
2
  /**
3
+ * File: not-found.php
4
+ *
5
  * Display for instances in which backup is not local and not remote.
6
  *
7
+ * @link https://www.boldgrid.com
8
  * @since 1.6.0
9
  *
10
  * @package Boldgrid_Backup
11
  * @subpackage Boldgrid_Backup/admin/partials/archive-details
12
+ * @copyright BoldGrid
13
+ * @version $Id$
14
+ * @author BoldGrid <support@boldgrid.com>
15
  */
16
 
17
+ defined( 'WPINC' ) || die;
 
 
 
18
 
19
+ return '<p>' . $this->core->lang['icon_warning'] .
20
+ __( 'Backup file not found!', 'boldgrid-backup' ) . '</p>';
admin/partials/archive-details/only-remote.php CHANGED
@@ -1,17 +1,23 @@
1
  <?php
2
  /**
 
 
3
  * Display for instances in which backup is not local, but exists remotely.
4
  *
5
- * @link http://www.boldgrid.com
6
- * @since 1.5.4
7
  *
8
  * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin/partials/archive-details
 
 
 
10
  */
11
 
12
- defined( 'WPINC' ) ? : die;
13
 
14
- return sprintf( '
 
15
  <p>
16
  %1$s <span class="dashicons dashicons-editor-help" data-id="help-web-server"></span>
17
  </p>
@@ -23,10 +29,20 @@ return sprintf( '
23
  __( 'This backup file is not on your <strong>web server</strong>, but it is saved to one or more of your <strong>remote storage providers</strong>. If you would like to restore this backup or review the contents of this backup, you will first need to download it to your web server.', 'boldgrid-backup' ),
24
  '<a class="button button-primary" id="download_first">Download to web server</a>',
25
  $this->core->lang['spinner'],
26
- sprintf(
27
- __( 'After your backup has been downloaded to the web server, this page will refresh and you will see more options available. To learn more about your web server vs. remote storage providers, <a href="%1$s">click here</a>.', 'boldgrid-backup' ),
28
- 'admin.php?page=boldgrid-backup-tools&section=section_locations'
 
 
 
 
 
 
 
 
 
 
 
 
29
  )
30
  );
31
-
32
-
1
  <?php
2
  /**
3
+ * File: only-remote.php
4
+ *
5
  * Display for instances in which backup is not local, but exists remotely.
6
  *
7
+ * @link https://www.boldgrid.com
8
+ * @since 1.6.0
9
  *
10
  * @package Boldgrid_Backup
11
  * @subpackage Boldgrid_Backup/admin/partials/archive-details
12
+ * @copyright BoldGrid
13
+ * @version $Id$
14
+ * @author BoldGrid <support@boldgrid.com>
15
  */
16
 
17
+ defined( 'WPINC' ) || die;
18
 
19
+ return sprintf(
20
+ '
21
  <p>
22
  %1$s <span class="dashicons dashicons-editor-help" data-id="help-web-server"></span>
23
  </p>
29
  __( 'This backup file is not on your <strong>web server</strong>, but it is saved to one or more of your <strong>remote storage providers</strong>. If you would like to restore this backup or review the contents of this backup, you will first need to download it to your web server.', 'boldgrid-backup' ),
30
  '<a class="button button-primary" id="download_first">Download to web server</a>',
31
  $this->core->lang['spinner'],
32
+ wp_kses(
33
+ sprintf(
34
+ // translators: 1 An opening anchor tag to the tools page, 2 its closing tag.
35
+ __(
36
+ 'After your backup has been downloaded to the web server, this page will refresh and you will see more options available. To learn more about your web server vs. remote storage providers, %1$sclick here%2$s.',
37
+ 'boldgrid-backup'
38
+ ),
39
+ '<a href="' . admin_url( 'admin.php?page=boldgrid-backup-tools&section=section_locations' ) . '">',
40
+ '</a>'
41
+ ),
42
+ [
43
+ 'a' => [
44
+ 'href' => [],
45
+ ],
46
+ ]
47
  )
48
  );
 
 
admin/partials/archive-details/remote-storage.php CHANGED
@@ -1,14 +1,25 @@
1
  <?php
2
  /**
 
 
3
  * Render remote provider's table on archive details page.
 
 
 
 
 
 
4
  *
5
- * This file is included by admin/partials/boldgrid-backup-admin-archive-details.php
6
- * whis is included by admin/class-boldgrid-backup-admin-archive-details.php
 
 
 
7
  *
8
  * @param bool $archive_found Whether or not the archive was found.
9
  */
10
 
11
- defined( 'WPINC' ) ? : die;
12
 
13
  $data['postbox'] = '';
14
 
@@ -24,6 +35,17 @@ if ( empty( $this->remote_storage_li ) ) {
24
  return $data;
25
  }
26
 
 
 
 
 
 
 
 
 
 
 
 
27
  $count = 0;
28
  foreach ( $this->remote_storage_li as $provider ) {
29
  $count++;
@@ -31,7 +53,8 @@ foreach ( $this->remote_storage_li as $provider ) {
31
  // Generate a link to "download to server" from remote provider.
32
  $download = '';
33
  if ( ! $archive_found && $provider['uploaded'] ) {
34
- $download = sprintf( '
 
35
  <a class="button download-to-server" data-provider-id="%3$s">%1$s</a>
36
  %2$s
37
  ',
@@ -49,23 +72,23 @@ foreach ( $this->remote_storage_li as $provider ) {
49
  __( 'Upload', 'boldgrid-backup' ),
50
  $provider['id']
51
  );
52
- } elseif ( isset( $provider['is_setup'] ) and false === $provider['is_setup'] ) {
53
- $upload = sprintf( __( 'Please go to your <a target="_parent" href="%1$s">%2$s</a> to configure %3$s.', 'boldgrid-backup' ), 'admin.php?page=boldgrid-backup-settings', __( 'settings page', 'boldgrid-backup' ), $provider['title'] );
 
 
 
 
 
 
 
 
 
54
  } else {
55
  $upload = '';
56
  }
57
 
58
- $data['postbox'] .= sprintf( '
59
- %5$s
60
- <div data-remote-provider="%3$s">
61
- <span style="float:left;" %6$s><strong>%1$s</strong></span>
62
- <span style="float:right;max-width:50%%;">%2$s</span>
63
-
64
- <div style="clear:both;"></div>
65
-
66
- <p>%4$s</p>
67
- </div>
68
- ',
69
  /* 1 */ esc_html( $provider['title'] ),
70
  /* 2 */ $upload,
71
  /* 3 */ $provider['id'],
@@ -75,6 +98,47 @@ foreach ( $this->remote_storage_li as $provider ) {
75
  );
76
  }
77
 
78
- return $data;
 
 
 
 
 
 
 
 
 
 
 
79
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80
 
 
1
  <?php
2
  /**
3
+ * File: remote-storage.php
4
+ *
5
  * Render remote provider's table on archive details page.
6
+ * This file is included by:
7
+ * admin/partials/boldgrid-backup-admin-archive-details.php
8
+ * admin/class-boldgrid-backup-admin-archive-details.php
9
+ *
10
+ * @link https://www.boldgrid.com
11
+ * @since 1.5.2
12
  *
13
+ * @package Boldgrid_Backup
14
+ * @subpackage Boldgrid_Backup/admin/partials/archive-details
15
+ * @copyright BoldGrid
16
+ * @version $Id$
17
+ * @author BoldGrid <support@boldgrid.com>
18
  *
19
  * @param bool $archive_found Whether or not the archive was found.
20
  */
21
 
22
+ defined( 'WPINC' ) || die;
23
 
24
  $data['postbox'] = '';
25
 
35
  return $data;
36
  }
37
 
38
+ // This is the template used to render each remote storage provider.
39
+ $entry_template = '%5$s
40
+ <div data-remote-provider="%3$s">
41
+ <span style="float:left; width:calc(50%% - 10px);" %6$s><strong>%1$s</strong></span>
42
+ <span style="float:right; width:50%%;">%2$s</span>
43
+
44
+ <div style="clear:both;"></div>
45
+
46
+ <p>%4$s</p>
47
+ </div>';
48
+
49
  $count = 0;
50
  foreach ( $this->remote_storage_li as $provider ) {
51
  $count++;
53
  // Generate a link to "download to server" from remote provider.
54
  $download = '';
55
  if ( ! $archive_found && $provider['uploaded'] ) {
56
+ $download = sprintf(
57
+ '
58
  <a class="button download-to-server" data-provider-id="%3$s">%1$s</a>
59
  %2$s
60
  ',
72
  __( 'Upload', 'boldgrid-backup' ),
73
  $provider['id']
74
  );
75
+ } elseif ( isset( $provider['is_setup'] ) && false === $provider['is_setup'] ) {
76
+ $upload = sprintf(
77
+ // translators: 1: HTML anchor open tag, 2: HTML anchor close tag, 3: Provider title.
78
+ esc_html__(
79
+ 'Please go to your %1$ssettings page%2$s to configure %3$s.',
80
+ 'boldgrid-backup'
81
+ ),
82
+ '<a target="_parent" href="admin.php?page=boldgrid-backup-settings&section=section_storage">',
83
+ '</a>',
84
+ $provider['title']
85
+ );
86
  } else {
87
  $upload = '';
88
  }
89
 
90
+ $data['postbox'] .= sprintf(
91
+ $entry_template,
 
 
 
 
 
 
 
 
 
92
  /* 1 */ esc_html( $provider['title'] ),
93
  /* 2 */ $upload,
94
  /* 3 */ $provider['id'],
98
  );
99
  }
100
 
101
+ /*
102
+ * If the user is not on pro, show the remote storage providers available in pro.
103
+ *
104
+ * This is done by looping through the "premium_remote" settings in the configs.
105
+ */
106
+ if ( ! $this->core->config->get_is_premium() ) {
107
+ foreach ( $this->core->configs['premium_remote'] as $provider ) {
108
+ // Some providers will have a logo ($provider_span) shown instead of a title.
109
+ $provider_span = '';
110
+ if ( ! empty( $provider['logo_class'] ) ) {
111
+ $provider_span = '<span class="' . esc_attr( $provider['logo_class'] ) . ' ' . esc_attr( $provider['logo_class'] ) . '-smaller" title="' . esc_attr( $provider['title'] ) . '"></span>';
112
+ }
113
 
114
+ $data['postbox'] .= sprintf(
115
+ $entry_template,
116
+ /* 1 */ empty( $provider_span ) ? esc_html( $provider['title'] ) : $provider_span,
117
+ /* 2 */ wp_kses(
118
+ sprintf(
119
+ // translators: 1: HTML opening anchor tag linking to the plugin, 2: HTML closing anchor tag, 3: Name of a remote storage provider, 4: Premium plugin title.
120
+ __( 'Please upgrade to %1$s%4$s%2$s to enable %3$s.', 'boldgrid-backup' ),
121
+ '<a href="' . esc_url( $this->core->go_pro->get_premium_url( 'bgbkup-details-' . $provider['key'] ) ) . '">',
122
+ '</a>',
123
+ $provider['title'],
124
+ BOLDGRID_BACKUP_TITLE . ' Premium'
125
+ ),
126
+ [
127
+ 'span' => [
128
+ 'class' => [],
129
+ 'title' => [],
130
+ ],
131
+ 'a' => [
132
+ 'href' => [],
133
+ ],
134
+ ]
135
+ ),
136
+ /* 3 */ '',
137
+ /* 4 */ '',
138
+ /* 5 */ '<hr class="separator-small" />',
139
+ /* 6 */ ''
140
+ );
141
+ }
142
+ }
143
 
144
+ return $data;
admin/partials/archives/add-new.php CHANGED
@@ -1,40 +1,50 @@
1
  <?php
2
  /**
3
- * This file contains the markup necessary to upload a new backup archive.
4
  *
 
5
  * It follows the same structure as the "Upload Plugin" section of plugins.
6
  *
 
7
  * @since 1.5.1
8
  *
9
  * @package Boldgrid_Backup
10
  * @subpackage Boldgrid_Backup/admin/partials/archives
 
 
 
11
  */
12
 
13
- defined( 'WPINC' ) ? : die;
14
 
15
  $max_file_size = Boldgrid_Backup_Admin_Utility::get_upload_limit();
16
 
17
- $size_limit = esc_html__( 'File size limit', 'boldgrid-backup' ) . ': ' .
18
  Boldgrid_Backup_Admin_Utility::bytes_to_human(
19
  Boldgrid_Backup_Admin_Utility::get_upload_limit()
20
  );
21
 
22
- $size_info = esc_html__(
23
- 'To change the limit, you may be able to modify your server\'s php.ini or .htaccess file. Please ask your web hosting provider if you need assistance.',
24
  'boldgrid-backup'
25
  );
26
 
27
- $upload_info = esc_html__(
28
- 'You can upload a backup file that was created with BoldGrid Backup.
 
 
29
  If you choose to restore an uploaded file from a different web location (URL), then we will try to ensure that references to URL address are updated.
30
  There may be times when some items may need to be updated manually.',
31
- 'boldgrid-backup'
 
 
32
  );
33
 
34
  $backup_id_notice = sprintf(
35
- esc_html__(
36
- 'Your BoldGrid Backup id is %3$s. This backup id is used to determine if a backup archive file is associated with this WordPress installation.
37
- Manually uploaded archive files must have filenames starting with "%2$s", contain the BoldGrid Backup id "%3$s", and end with "%4$s", to be recognized.%1$s%1$s
 
38
  For example: %5$s%1$s%1$s
39
  Manually uploaded archive files should be uploaded to: %6$s',
40
  'boldgrid-backup'
@@ -44,7 +54,8 @@ $backup_id_notice = sprintf(
44
  $backup_identifier,
45
  '.zip',
46
  'boldgrid-backup-' . $backup_identifier . '-my_backup_file.zip',
47
- $settings['backup_directory']
 
48
  );
49
 
50
  ?>
@@ -57,12 +68,30 @@ $backup_id_notice = sprintf(
57
  </p>
58
 
59
  <p class="help wp-upload-form" data-id="upload-backup">
60
- <?php printf( '%1$s<br />%2$s<br /><br />%3$s', $size_limit, $size_info, $upload_info ); ?>
 
 
 
 
 
 
 
61
  </p>
62
 
 
 
 
 
 
 
 
 
 
 
63
  <div id="upload-archive-section" class="wp-upload-form">
 
64
  <form id="upload-archive-form" method="POST" enctype="multipart/form-data">
65
- <input type="hidden" name="MAX_FILE_SIZE" value="<?php echo $max_file_size; ?>" />
66
  <input type="hidden" name="uploading" value="1" />
67
  <?php wp_nonce_field( 'upload_archive_file' ); ?>
68
  <input name="file" type="file" />
@@ -71,21 +100,21 @@ $backup_id_notice = sprintf(
71
  </form>
72
 
73
  <p id="file_too_large" class="hidden">
74
- <span class="dashicons dashicons-warning yellow"></span> <?php echo __( 'The file you selected is too large.', 'boldgrid-bacup' ); ?>
75
  </p>
76
 
77
  <p id="bad_extension" class="hidden">
78
- <span class="dashicons dashicons-warning yellow"></span> <?php echo __( 'Invalid file format. Please choose a .zip file.', 'boldgrid-bacup' ); ?>
79
  </p>
80
  </div>
81
 
82
  <p class="install-help">
83
- <?php esc_html_e( 'Have a large site or want to FTP?', 'boldgrid-backup' ); ?>
84
  <span class="dashicons dashicons-editor-help" data-id="backup-id"></span>
85
  </p>
86
 
87
  <div class="help wp-upload-form" data-id="backup-id">
88
- <?php echo $backup_id_notice; ?>
89
  </div>
90
 
91
  </div>
1
  <?php
2
  /**
3
+ * File: add-new.php
4
  *
5
+ * This file contains the markup necessary to upload a new backup archive.
6
  * It follows the same structure as the "Upload Plugin" section of plugins.
7
  *
8
+ * @link https://www.boldgrid.com
9
  * @since 1.5.1
10
  *
11
  * @package Boldgrid_Backup
12
  * @subpackage Boldgrid_Backup/admin/partials/archives
13
+ * @copyright BoldGrid
14
+ * @version $Id$
15
+ * @author BoldGrid <support@boldgrid.com>
16
  */
17
 
18
+ defined( 'WPINC' ) || die;
19
 
20
  $max_file_size = Boldgrid_Backup_Admin_Utility::get_upload_limit();
21
 
22
+ $size_limit = __( 'File upload size limit', 'boldgrid-backup' ) . ': ' .
23
  Boldgrid_Backup_Admin_Utility::bytes_to_human(
24
  Boldgrid_Backup_Admin_Utility::get_upload_limit()
25
  );
26
 
27
+ $size_info = __(
28
+ 'Files uploaded from your computer are limited to a maximum size. To change the limit, you may be able to modify your server\'s php.ini or .htaccess file. Please ask your web hosting provider if you need assistance. Uploads from URL addresses do not have a size limit.',
29
  'boldgrid-backup'
30
  );
31
 
32
+ $upload_info = sprintf(
33
+ // translators: 1: Plugin title.
34
+ __(
35
+ 'You can upload a backup file that was created with %1$s.
36
  If you choose to restore an uploaded file from a different web location (URL), then we will try to ensure that references to URL address are updated.
37
  There may be times when some items may need to be updated manually.',
38
+ 'boldgrid-backup'
39
+ ),
40
+ BOLDGRID_BACKUP_TITLE
41
  );
42
 
43
  $backup_id_notice = sprintf(
44
+ // translators: 1: HTML tag, 2: Filename part, 3: Backup identifier, 4: File extension, 5: Archive filename, 6: Backup directory path, 7: Plugin title.
45
+ __(
46
+ 'Your %7$s id is %3$s. This backup id is used to determine if a backup archive file is associated with this WordPress installation.
47
+ Manually uploaded archive files must have filenames starting with "%2$s", contain the %7$s id "%3$s", and end with "%4$s", to be recognized.%1$s%1$s
48
  For example: %5$s%1$s%1$s
49
  Manually uploaded archive files should be uploaded to: %6$s',
50
  'boldgrid-backup'
54
  $backup_identifier,
55
  '.zip',
56
  'boldgrid-backup-' . $backup_identifier . '-my_backup_file.zip',
57
+ $settings['backup_directory'],
58
+ BOLDGRID_BACKUP_TITLE
59
  );
60
 
61
  ?>
68
  </p>
69
 
70
  <p class="help wp-upload-form" data-id="upload-backup">
71
+ <?php
72
+ printf(
73
+ '%1$s<br />%2$s<br /><br />%3$s',
74
+ esc_html( $size_limit ),
75
+ esc_html( $size_info ),
76
+ esc_html( $upload_info )
77
+ );
78
+ ?>
79
  </p>
80
 
81
+ <div id="url-import-section" class="wp-upload-form">
82
+ <p><?php esc_html_e( 'Import from a download link:', 'boldgrid-backup' ); ?></p>
83
+ <input type="text" name="url"
84
+ placeholder="<?php esc_attr_e( 'Download URL address', 'boldgrid-backup' ); ?>" size="30" />
85
+ <?php wp_nonce_field( 'boldgrid_backup_restore_archive', '_wpnonce_restore' ); ?>
86
+ <input class="button" type="submit" value="<?php esc_attr_e( 'Upload', 'boldgrid-backup' ); ?>" />
87
+ <span class='spinner'></span>
88
+ <div id="url-import-notice" class="notice notice-success inline"></div>
89
+ </div>
90
+
91
  <div id="upload-archive-section" class="wp-upload-form">
92
+ <p><?php esc_html_e( 'From a file on your computer:', 'boldgrid-backup' ); ?></p>
93
  <form id="upload-archive-form" method="POST" enctype="multipart/form-data">
94
+ <input type="hidden" name="MAX_FILE_SIZE" value="<?php echo esc_attr( $max_file_size ); ?>" />
95
  <input type="hidden" name="uploading" value="1" />
96
  <?php wp_nonce_field( 'upload_archive_file' ); ?>
97
  <input name="file" type="file" />
100
  </form>
101
 
102
  <p id="file_too_large" class="hidden">
103
+ <span class="dashicons dashicons-warning yellow"></span> <?php esc_html_e( 'The file you selected is too large.', 'boldgrid-bacup' ); ?>
104
  </p>
105
 
106
  <p id="bad_extension" class="hidden">
107
+ <span class="dashicons dashicons-warning yellow"></span> <?php esc_html_e( 'Invalid file format. Please choose a .zip file.', 'boldgrid-bacup' ); ?>
108
  </p>
109
  </div>
110
 
111
  <p class="install-help">
112
+ <?php esc_html_e( 'Have a large file to upload or want to use FTP?', 'boldgrid-backup' ); ?>
113
  <span class="dashicons dashicons-editor-help" data-id="backup-id"></span>
114
  </p>
115
 
116
  <div class="help wp-upload-form" data-id="backup-id">
117
+ <?php echo $backup_id_notice; // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped ?>
118
  </div>
119
 
120
  </div>
admin/partials/archives/note-pre-backup.php CHANGED
@@ -1,34 +1,47 @@
1
  <?php
2
  /**
 
 
3
  * Display a note for the user next to the "Backup Site Now" button.
4
  *
 
5
  * @since 1.3
6
  *
7
  * @package Boldgrid_Backup
8
  * @subpackage Boldgrid_Backup/admin/partials/archives
 
 
 
9
  */
10
 
11
- defined( 'WPINC' ) ? : die;
12
  ?>
13
 
14
  <p id='note-pre-backup'>
15
  <?php
 
16
  /*
17
  * Print this text:
18
  *
19
  * Note: Backups use resources and <a>must pause your site</a> momentarily. Use sparingly.
20
  */
21
- $link = sprintf(
22
  wp_kses(
23
- __( '<strong>Note</strong>: Backups use resources and <a href="%s" target="_blank">must pause your site</a> momentarily. Use sparingly. ', 'boldgrid-backup' ),
 
 
 
 
24
  array(
25
- 'a' => array( 'href' => array(), 'target' => array() ),
 
 
 
26
  'strong' => array(),
27
- )
28
  ),
29
  esc_url( $this->configs['urls']['resource_usage'] )
30
  );
31
- echo $link;
32
 
33
  /*
34
  * Print this text:
@@ -38,18 +51,21 @@ defined( 'WPINC' ) ? : die;
38
  * make room for your new backup. We recommend you download a backup to your local computer.
39
  */
40
  if ( count( $archives ) >= $settings['retention_count'] ) {
41
- $link = sprintf(
42
  wp_kses(
43
- __( 'You currently have %1$s backups stored on your server, and your <a href="%3$s">backup settings</a> are only configured to store %2$s. Backing up your site now will delete your oldest backup to make room for your new backup. We recommend you download a backup to your local computer.', 'boldgrid-backup' ),
 
 
 
 
44
  array(
45
  'a' => array( 'href' => array() ),
46
  )
47
  ),
48
  count( $archives ),
49
- $settings['retention_count'],
50
- get_admin_url( null, 'admin.php?page=boldgrid-backup-settings' )
51
  );
52
- echo $link;
53
  }
54
- ?>
55
  </p>
1
  <?php
2
  /**
3
+ * File: note-pre-backup.php
4
+ *
5
  * Display a note for the user next to the "Backup Site Now" button.
6
  *
7
+ * @link https://www.boldgrid.com
8
  * @since 1.3
9
  *
10
  * @package Boldgrid_Backup
11
  * @subpackage Boldgrid_Backup/admin/partials/archives
12
+ * @copyright BoldGrid
13
+ * @version $Id$
14
+ * @author BoldGrid <support@boldgrid.com>
15
  */
16
 
17
+ defined( 'WPINC' ) || die;
18
  ?>
19
 
20
  <p id='note-pre-backup'>
21
  <?php
22
+
23
  /*
24
  * Print this text:
25
  *
26
  * Note: Backups use resources and <a>must pause your site</a> momentarily. Use sparingly.
27
  */
28
+ printf(
29
  wp_kses(
30
+ // translators: 1: URL address.
31
+ __(
32
+ '<strong>Note</strong>: Backups use resources and <a href="%s" target="_blank">must pause your site</a> momentarily. Use sparingly. ',
33
+ 'boldgrid-backup'
34
+ ),
35
  array(
36
+ 'a' => array(
37
+ 'href' => array(),
38
+ 'target' => array(),
39
+ ),
40
  'strong' => array(),
41
+ )
42
  ),
43
  esc_url( $this->configs['urls']['resource_usage'] )
44
  );
 
45
 
46
  /*
47
  * Print this text:
51
  * make room for your new backup. We recommend you download a backup to your local computer.
52
  */
53
  if ( count( $archives ) >= $settings['retention_count'] ) {
54
+ printf(
55
  wp_kses(
56
+ // translators: 1: Archive count, 2: Retention limit, 3: URL address.
57
+ __(
58
+ 'You currently have %1$s backups stored on your server, and your <a href="%3$s">backup settings</a> are only configured to store %2$s. Backing up your site now will delete your oldest backup to make room for your new backup. We recommend you download a backup to your local computer.',
59
+ 'boldgrid-backup'
60
+ ),
61
  array(
62
  'a' => array( 'href' => array() ),
63
  )
64
  ),
65
  count( $archives ),
66
+ esc_html( $settings['retention_count'] ),
67
+ esc_url( get_admin_url( null, 'admin.php?page=boldgrid-backup-settings' ) )
68
  );
 
69
  }
70
+ ?>
71
  </p>
admin/partials/backup-now-modal/title.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Title and Description.
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.7.0
7
+ *
8
+ * @package Boldgrid_Backup
9
+ * @subpackage Boldgrid_Backup/admin/partials/settings
10
+ * @copyright BoldGrid
11
+ * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
+ */
14
+
15
+ defined( 'WPINC' ) || die;
16
+
17
+ return '
18
+ <div class="bg-box">
19
+ <div class="bg-box-top">
20
+ ' . esc_html__( 'Title & Description', 'boldgrid-backup' ) . '
21
+ </div>
22
+ <div class="bg-box-bottom">
23
+ <p>' . esc_html__( 'To help remember the details of this backup, you may enter a title and description.', 'boldgrid-backup' ) . '</p>
24
+ <input type="text" name="backup_title" style="width:100%" placeholder="' . esc_html__( 'Backup Title', 'boldgrid-backup' ) . '" /><br /><br />
25
+ <textarea name="backup_description" style="width:100%;height:75px;" placeholder="' . esc_html( 'Backup Description', 'boldgrid-backup' ) . '" /></textarea>
26
+ </div>
27
+ </div>
28
+ ';
admin/partials/boldgrid-backup-admin-archive-details.php CHANGED
@@ -1,18 +1,24 @@
1
  <?php
2
  /**
 
 
3
  * This file contains renders the details page of a backup archive.
4
  *
 
5
  * @since 1.5.1
6
  *
7
  * @package Boldgrid_Backup
8
  * @subpackage Boldgrid_Backup/admin/partials
 
 
 
9
  *
10
  * @param bool $archive_found Whether or not the archive was found.
11
  * @param array $archive An array of details about the archive, similar to
12
  * the $info created during archiving.
13
  */
14
 
15
- defined( 'WPINC' ) ? : die;
16
 
17
  wp_enqueue_style( 'editor-buttons' );
18
 
@@ -20,28 +26,42 @@ wp_nonce_field( 'boldgrid_backup_remote_storage_upload' );
20
 
21
  $separator = '<hr class="separator">';
22
 
23
- $details = include BOLDGRID_BACKUP_PATH . '/admin/partials/archive-details/details.php';
 
 
 
 
 
 
 
 
 
 
 
24
  $remote_storage = include BOLDGRID_BACKUP_PATH . '/admin/partials/archive-details/remote-storage.php';
25
- $browser = include BOLDGRID_BACKUP_PATH . '/admin/partials/archive-details/browser.php';
26
- $db = include BOLDGRID_BACKUP_PATH . '/admin/partials/archive-details/db.php';
27
 
28
  // Special situations where the backup file is not local and/or remote.
29
  $only_remote = include BOLDGRID_BACKUP_PATH . '/admin/partials/archive-details/only-remote.php';
30
- $not_found = include BOLDGRID_BACKUP_PATH . '/admin/partials/archive-details/not-found.php';
31
 
32
- $delete_link = $this->core->archive_actions->get_delete_link( $archive['filename'] );
33
  $download_button = $this->core->archive_actions->get_download_button( $archive['filename'] );
34
- $restore_button = $this->core->archive_actions->get_restore_button( $archive['filename'] );
 
35
 
36
  if ( ! $archive_found ) {
37
- $file_size = '';
38
- $backup_date = '';
39
- $more_info = '';
40
  $major_actions = '';
 
 
41
  } else {
42
  $file_size = sprintf(
43
  '<div class="misc-pub-section">%1$s: <strong>%2$s</strong></div>',
44
- __( 'File size', 'boldgrid-backup' ),
45
  Boldgrid_Backup_Admin_Utility::bytes_to_human( $archive['filesize'] )
46
  );
47
 
@@ -49,13 +69,14 @@ if ( ! $archive_found ) {
49
  $this->core->time->init( $archive['lastmodunix'], 'utc' );
50
  $backup_date = sprintf(
51
  '<div class="misc-pub-section">%1$s: <strong>%2$s</strong></div>',
52
- __( 'Backup date', 'boldgrid-backup' ),
53
  $this->core->time->get_span()
54
  );
55
 
56
- $more_info = empty( $details ) ? '' : sprintf( '
 
57
  <div class="misc-pub-section">
58
- More info <a href="" data-toggle-target="#more_info">Show</a>
59
  <div id="more_info" class="hidden">
60
  <hr />
61
  %1$s
@@ -64,74 +85,209 @@ if ( ! $archive_found ) {
64
  $details
65
  );
66
 
67
- $major_actions = sprintf( '
 
68
  <div id="major-publishing-actions">
69
- <div id="delete-action">
70
  %1$s
71
  </div>
72
-
 
 
 
73
  <div style="clear:both;"></div>
74
  </div>',
75
- $delete_link
 
76
  );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  }
78
 
79
- $main_meta_box = sprintf( '
 
80
  <div id="submitdiv" class="postbox">
81
  <h2 class="hndle ui-sortable-handle"><span>%1$s</span></h2>
82
  <div class="inside submitbox">
83
-
 
84
  <div class="misc-pub-section">%2$s: <strong>%3$s</strong></div>
85
-
86
  %4$s
87
-
88
  %5$s
89
-
90
  %6$s
91
-
92
  %7$s
93
-
94
  </div>
95
  </div>',
96
- /* 1 */ __( 'Backup Archive', 'boldgrid-backup' ),
97
- /* 2 */ __( 'File name', 'boldgrid-backup' ),
98
  /* 3 */ $archive['filename'],
99
  /* 4 */ $file_size,
100
  /* 5 */ $backup_date,
101
  /* 6 */ $more_info,
102
- /* 7 */ $major_actions
 
 
103
  );
104
 
105
- $remote_meta_box = sprintf( '
 
 
106
  <div class="postbox remote-storage">
107
  <h2 class="hndle ui-sortable-handle">
108
  <span>%1$s</span>
109
  <span class="dashicons dashicons-editor-help" data-id="remote-storage-help"></span>
110
  </h2>
111
-
112
  <div class="inside">
113
-
114
  <p class="help" data-id="remote-storage-help">%4$s</p>
115
-
116
  %2$s
117
  </div>
118
-
119
  %3$s
120
  </div>',
121
- /* 1 */ __( 'Remote Storage', 'boldgrid-backup' ),
122
  /* 2 */ $remote_storage['postbox'],
123
- /* 3 */ $this->core->config->is_premium_done ? '' : sprintf( '
 
124
  <div class="inside premium wp-clearfix">
125
  %1$s
126
  %2$s
127
  </div>',
128
- /* 1 */ $this->core->go_pro->get_premium_button(),
129
- /* 2 */ __( 'Upgrade to <strong>BoldGrid Backup Premium</strong> for more Storage Locations!', 'boldgrid-backup' )
 
 
 
 
 
 
130
  ),
131
- /* 4 */ __( 'Secure your backups by keeping copies of them on <a href="admin.php?page=boldgrid-backup-tools&section=section_locations">remote storage</a>.', 'boldgrid-backup' )
132
  );
133
 
134
- $editor_tools = sprintf( '
 
135
  <div style="padding-top:0px;" id="wp-content-editor-tools" class="wp-editor-tools hide-if-no-js">
136
  <div id="wp-content-media-buttons" class="wp-media-buttons">
137
  %1$s
@@ -143,69 +299,94 @@ $editor_tools = sprintf( '
143
  </div>
144
  ',
145
  /* 1 */ $db['buttons'],
146
- /* 2 */ __( 'Files & Folders', 'boldgrid-backup' ),
147
- /* 3 */ __( 'Database', 'boldgrid-backup' )
148
  );
149
 
150
- $intro = $this->core->config->is_premium_done ? '' : sprintf( '
 
 
151
  <div class="bg-box-bottom premium" style="margin-bottom:15px;">
152
  <strong>%1$s</strong>
153
-
154
  <p>
155
  %2$s
156
  %3$s
157
  </p>
158
  </div>',
159
- /* 1 */ __( 'One click file restorations', 'boldgrid-backup' ),
160
- /* 2 */ $this->core->go_pro->get_premium_button(),
161
- /* 3 */ __( 'Please note that most functionality for the Archive Browser, such as one click file restorations, is contained within the Premium version. For help with restoring a single file without this one click feature, please <a href="https://www.boldgrid.com/support" target="_blank">click here</a>.', 'boldgrid-backup' )
 
 
 
 
 
 
 
162
  );
163
 
164
  $main_content = '
165
  <div id="postdivrich" class="postarea wp-editor-expand">
166
-
167
  <div id="wp-content-wrap" class="wp-core-ui wp-editor-wrap tmce-active has-dfw">
168
-
169
  <h2 style="font-size:initial; padding:0px;">
170
- ' . __( 'Download & Restore', 'boldgrid-backup' ) . '
171
  <span class="dashicons dashicons-editor-help" data-id="download_and_restore"></span>
172
  </h2>
173
-
174
  <p class="help" data-id="download_and_restore">
175
- <strong>' . __( 'Download to Local Machine', 'boldgrid-backup' ) . '</strong><br />
176
- ' . __( 'Backup archives generally should be stored in more locations than just your <strong>web server</strong>. Be sure to keep copies on your <strong>local machine</strong> and / or a <strong>remote storage</strong> provider. Learn more about these different locations <a href="admin.php?page=boldgrid-backup-tools&section=section_locations">here</a>.', 'boldgrid-backup' ) . '<br /><br />
177
- <strong>' . __( 'Restore', 'boldgrid-backup' ) . '</strong><br />
178
- ' . __( 'Restore this backup. This will restore all the files and the database in this backup. Use the <strong>Backup Browser</strong> below to look at the backup archive and see what will be restored.', 'boldgrid-backup' ) . '
 
 
179
  </p>
180
-
181
  <p>
182
- ' . $download_button . ' ' . $restore_button . '
183
  </p>
184
-
185
  <hr class="separator" />
186
-
187
- <h2 style="font-size:initial; padding:0px;">' . __( 'Backup Browser', 'boldgrid-backup' ) . '</h2>
188
-
189
  <p>
190
- ' . __( 'Use the File & Folders and Database tools below to browse the contents of this backup file.', 'boldgrid-backup' ) . '
191
  </p>
192
-
193
  ' . $intro . $editor_tools . $browser . $db['browser'] . '
194
  </div>
195
  </div>
196
  ';
197
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
198
  if ( ! $this->core->archive->is_stored_locally() ) {
199
 
200
  if ( $this->core->archive->is_stored_remotely() ) {
201
  $main_content = $only_remote;
202
  } else {
203
- $main_content = $not_found;
204
  $remote_meta_box = '';
205
  }
206
  }
207
 
208
- $page = sprintf( '
 
209
  <input type="hidden" id="filename" value="%1$s" />
210
  <div class="wrap">
211
  <h1 class="wp-heading-inline">%2$s</h1>
@@ -228,13 +409,11 @@ $page = sprintf( '
228
  </div>
229
  ',
230
  /* 1 */ $archive['filename'],
231
- /* 2 */ __( 'Backup Archive Details', 'boldgrid-backup' ),
232
- /* 3 */ include BOLDGRID_BACKUP_PATH . '/admin/partials/boldgrid-backup-admin-nav.php',
233
  /* 4 */ $main_content,
234
  /* 5 */ $main_meta_box,
235
  /* 6 */ $remote_meta_box
236
  );
237
 
238
- echo $page;
239
-
240
-
1
  <?php
2
  /**
3
+ * File: boldgrid-backup-admin-archive-details.php
4
+ *
5
  * This file contains renders the details page of a backup archive.
6
  *
7
+ * @link https://www.boldgrid.com
8
  * @since 1.5.1
9
  *
10
  * @package Boldgrid_Backup
11
  * @subpackage Boldgrid_Backup/admin/partials
12
+ * @copyright BoldGrid
13
+ * @version $Id$
14
+ * @author BoldGrid <support@boldgrid.com>
15
  *
16
  * @param bool $archive_found Whether or not the archive was found.
17
  * @param array $archive An array of details about the archive, similar to
18
  * the $info created during archiving.
19
  */
20
 
21
+ defined( 'WPINC' ) || die;
22
 
23
  wp_enqueue_style( 'editor-buttons' );
24
 
26
 
27
  $separator = '<hr class="separator">';
28
 
29
+ $allowed_html = array(
30
+ 'a' => array(
31
+ 'href' => array(),
32
+ ),
33
+ );
34
+
35
+ $is_premium = $this->core->config->get_is_premium();
36
+ $is_premium_installed = $this->core->config->is_premium_installed;
37
+ $is_premium_active = $this->core->config->is_premium_active;
38
+ $is_premium_all = $is_premium && $is_premium_active;
39
+
40
+ $details = include BOLDGRID_BACKUP_PATH . '/admin/partials/archive-details/details.php';
41
  $remote_storage = include BOLDGRID_BACKUP_PATH . '/admin/partials/archive-details/remote-storage.php';
42
+ $browser = include BOLDGRID_BACKUP_PATH . '/admin/partials/archive-details/browser.php';
43
+ $db = include BOLDGRID_BACKUP_PATH . '/admin/partials/archive-details/db.php';
44
 
45
  // Special situations where the backup file is not local and/or remote.
46
  $only_remote = include BOLDGRID_BACKUP_PATH . '/admin/partials/archive-details/only-remote.php';
47
+ $not_found = include BOLDGRID_BACKUP_PATH . '/admin/partials/archive-details/not-found.php';
48
 
49
+ $delete_link = $this->core->archive_actions->get_delete_link( $archive['filename'] );
50
  $download_button = $this->core->archive_actions->get_download_button( $archive['filename'] );
51
+ $restore_button = $this->core->archive_actions->get_restore_button( $archive['filename'] );
52
+ $download_link = $this->core->archive_actions->get_download_link_button( $archive['filename'] );
53
 
54
  if ( ! $archive_found ) {
55
+ $file_size = '';
56
+ $backup_date = '';
57
+ $more_info = '';
58
  $major_actions = '';
59
+ $protect = '';
60
+ $encrypt_db = '';
61
  } else {
62
  $file_size = sprintf(
63
  '<div class="misc-pub-section">%1$s: <strong>%2$s</strong></div>',
64
+ esc_html__( 'File size', 'boldgrid-backup' ),
65
  Boldgrid_Backup_Admin_Utility::bytes_to_human( $archive['filesize'] )
66
  );
67
 
69
  $this->core->time->init( $archive['lastmodunix'], 'utc' );
70
  $backup_date = sprintf(
71
  '<div class="misc-pub-section">%1$s: <strong>%2$s</strong></div>',
72
+ esc_html__( 'Backup date', 'boldgrid-backup' ),
73
  $this->core->time->get_span()
74
  );
75
 
76
+ $more_info = empty( $details ) ? '' : sprintf(
77
+ '
78
  <div class="misc-pub-section">
79
+ More info <a href="" data-bgbkup-toggle-target="#more_info">Show</a>
80
  <div id="more_info" class="hidden">
81
  <hr />
82
  %1$s
85
  $details
86
  );
87
 
88
+ $major_actions = sprintf(
89
+ '
90
  <div id="major-publishing-actions">
91
+ <div id="delete-action-link">
92
  %1$s
93
  </div>
94
+ <div id="publishing-action">
95
+ <span class="spinner"></span>
96
+ <button class="button button-primary button-large">%2$s</button>
97
+ </div>
98
  <div style="clear:both;"></div>
99
  </div>',
100
+ $delete_link,
101
+ esc_html__( 'Update', 'boldgrid-backup' )
102
  );
103
+
104
+ $is_protected = (bool) $this->core->archive->get_attribute( 'protect' );
105
+ $protect = '
106
+ <div class="misc-pub-section bglib-misc-pub-section dashicons-lock">
107
+ ' . esc_html__( 'Ignore retention', 'boldgrid-backup' ) . ': <span class="value-displayed"></span>
108
+ <a class="edit" href="#" style="display: inline;">
109
+ <span aria-hidden="true">' . esc_html__( 'Edit', 'boldgrid-backup' ) . '</span>
110
+ </a>
111
+ <div class="options" style="display: none;">
112
+ <p>
113
+ <em>
114
+ ' .
115
+ wp_kses(
116
+ sprintf(
117
+ // translators: 1: HTML anchor open tags, 2: HTML close tag, 3: HTML anchor open tags, 4: HTML close tag.
118
+ __( 'Protect this backup from being deleted due to %1$sretention settings%2$s. Applies only to backups stored on your %3$sWeb Server%4$s.', 'boldgrid-backup' ),
119
+ '<a href="' . esc_url( admin_url( 'admin.php?page=boldgrid-backup-settings&section=section_storage' ) ) . '">',
120
+ '</a>',
121
+ '<a href="' . esc_url( admin_url( 'admin.php?page=boldgrid-backup-tools&section=section_locations' ) ) . '">',
122
+ '</a>'
123
+ ), $allowed_html
124
+ ) . '
125
+ </em>
126
+ </p>
127
+ <select name="backup_protect" id="backup-protect">
128
+ <option value="0" ' . selected( $is_protected, false, false ) . '>' . esc_html__( 'No', 'boldgrid-backup' ) . '</option>
129
+ <option value="1" ' . selected( $is_protected, true, false ) . '>' . esc_html__( 'Yes', 'boldgrid-backup' ) . '</option>
130
+ </select>
131
+ <p>
132
+ <a href="" class="button">' . esc_html__( 'OK', 'boldgrid-backup' ) . '</a>
133
+ <a href="" class="button-cancel">' . esc_html__( 'Cancel', 'boldgrid-backup' ) . '</a>
134
+ </p>
135
+ </div>
136
+ </div>
137
+ ';
138
+
139
+ // Determine premium message.
140
+ if ( ! $is_premium_all ) {
141
+ switch ( true ) {
142
+ case ! $is_premium:
143
+ $premium_url = $this->core->go_pro->get_premium_url( 'bgbkup-archive-encrypt' );
144
+ $premium_message = sprintf(
145
+ '<div class="premium">%1$s</div>
146
+ <div><p>%2$s</p></div>',
147
+ esc_html__(
148
+ 'Upgrade to Premium to protect your sensitive data!',
149
+ 'boldgrid-backup'
150
+ ),
151
+ '<form action="' . $premium_url . '" target="_blank"><button class="button button-success" type="submit">' .
152
+ esc_html__( 'Get Premium', 'boldgrid-backup' ) . '</button></form>'
153
+ );
154
+ break;
155
+ case ! $is_premium_installed:
156
+ $premium_url = $this->core->go_pro->get_premium_url(
157
+ 'bgbkup-archive-encrypt',
158
+ 'https://www.boldgrid.com/central/plugins'
159
+ );
160
+ $premium_message = sprintf(
161
+ '<div class="premium">%1$s</div>
162
+ <div><p>%2$s</p></div>',
163
+ esc_html__(
164
+ 'Secure your sesitive data with the Premium plugin!',
165
+ 'boldgrid-backup'
166
+ ),
167
+ '<form action="' . $premium_url . '" target="_blank"><button class="button button-success" type="submit">' .
168
+ esc_html__( 'Unlock Feature', 'boldgrid-backup' ) . '</button></form>'
169
+ );
170
+ break;
171
+ case ! $is_premium_active:
172
+ $premium_url = $this->core->go_pro->get_premium_url( 'bgbkup-archive-encrypt' );
173
+ $premium_message = '<div class="premium">' . sprintf(
174
+ // translators: 1: HTML anchor link open tag, 2: HTML anchor closing tag, 3: Premium plugin title.
175
+ __( '%3$s is not active. Please go to the %1$sPlugins%2$s page to activate it.', 'boldgrid-backup' ),
176
+ '<a href="' .
177
+ esc_url( admin_url( 'plugins.php?s=Boldgrid%20Backup%20Premium&plugin_status=inactive' ) ) .
178
+ '">',
179
+ '</a>',
180
+ BOLDGRID_BACKUP_TITLE . ' Premium'
181
+ ) . '</div>';
182
+ break;
183
+ default:
184
+ $premium_message = '';
185
+ break;
186
+ }
187
+ } else {
188
+ $premium_message = '';
189
+ }
190
+
191
+ $is_db_encrypted = (bool) $this->core->archive->get_attribute( 'encrypt_db' );
192
+ $encrypt_db = '
193
+ <div class="misc-pub-section bglib-misc-pub-section bgbkup-db-lock">
194
+ ' . esc_html__( 'Encrypt database', 'boldgrid-backup' ) . ': <span class="value-displayed"></span>
195
+ <a class="edit" href="#" style="display: inline;">
196
+ <span aria-hidden="true">' . esc_html__( 'Edit', 'boldgrid-backup' ) . '</span>
197
+ </a>
198
+ <div class="options" style="display: none;">
199
+ <p>
200
+ <em>
201
+ ' .
202
+ wp_kses(
203
+ sprintf(
204
+ // translators: 1: HTML anchor open tags, 2: HTML close tag, 3: HTML anchor open tags, 4: HTML close tag.
205
+ __( 'Database encryption protects sensitive data stored in backup archives. The encryption settings are configured on the %1$sBackup Security%2$s settings page.', 'boldgrid-backup' ),
206
+ '<a href="' .
207
+ esc_url( admin_url( 'admin.php?page=boldgrid-backup-settings&section=section_security' ) ) .
208
+ '">',
209
+ '</a>'
210
+ ), $allowed_html
211
+ ) . '
212
+ </em>
213
+ </p>
214
+ <select name="encrypt_db" id="encrypt-db">
215
+ <option value="0" ' . selected( $is_db_encrypted, false, false ) . ' ' .
216
+ disabled( $is_premium_all, false, false ) . '>' . esc_html__( 'No', 'boldgrid-backup' ) . '</option>
217
+ <option value="1" ' . selected( $is_db_encrypted, true, false ) . ' ' .
218
+ disabled( $is_premium_all, false, false ) . '>' . esc_html__( 'Yes', 'boldgrid-backup' ) . '</option>
219
+ </select>
220
+ <p>' . $premium_message . '</p>
221
+ <p>
222
+ <a href="" class="button">' . esc_html__( 'OK', 'boldgrid-backup' ) . '</a>
223
+ <a href="" class="button-cancel">' . esc_html__( 'Cancel', 'boldgrid-backup' ) . '</a>
224
+ </p>
225
+ </div>
226
+ </div>
227
+ ';
228
  }
229
 
230
+ $main_meta_box = sprintf(
231
+ '
232
  <div id="submitdiv" class="postbox">
233
  <h2 class="hndle ui-sortable-handle"><span>%1$s</span></h2>
234
  <div class="inside submitbox">
235
+ %8$s
236
+ %9$s
237
  <div class="misc-pub-section">%2$s: <strong>%3$s</strong></div>
 
238
  %4$s
 
239
  %5$s
 
240
  %6$s
 
241
  %7$s
 
242
  </div>
243
  </div>',
244
+ /* 1 */ esc_html__( 'Backup Archive', 'boldgrid-backup' ),
245
+ /* 2 */ esc_html__( 'File name', 'boldgrid-backup' ),
246
  /* 3 */ $archive['filename'],
247
  /* 4 */ $file_size,
248
  /* 5 */ $backup_date,
249
  /* 6 */ $more_info,
250
+ /* 7 */ $major_actions,
251
+ /* 8 */ $encrypt_db,
252
+ /* 9 */ $protect
253
  );
254
 
255
+ $premium_url = $this->core->go_pro->get_premium_url( 'bgbkup-archive-storage' );
256
+ $remote_meta_box = sprintf(
257
+ '
258
  <div class="postbox remote-storage">
259
  <h2 class="hndle ui-sortable-handle">
260
  <span>%1$s</span>
261
  <span class="dashicons dashicons-editor-help" data-id="remote-storage-help"></span>
262
  </h2>
 
263
  <div class="inside">
 
264
  <p class="help" data-id="remote-storage-help">%4$s</p>
 
265
  %2$s
266
  </div>
 
267
  %3$s
268
  </div>',
269
+ /* 1 */ esc_html__( 'Remote Storage', 'boldgrid-backup' ),
270
  /* 2 */ $remote_storage['postbox'],
271
+ /* 3 */ $this->core->config->is_premium_done ? '' : sprintf(
272
+ '
273
  <div class="inside premium wp-clearfix">
274
  %1$s
275
  %2$s
276
  </div>',
277
+ /* 1 */ $this->core->go_pro->get_premium_button( $premium_url ),
278
+ /* 2 */ sprintf(
279
+ // translators: 1: HTML strong open tag, 2: HTML strong close tag, 3: Plugin title.
280
+ esc_html__( 'Upgrade to %1$s%3$s%2$s for more Storage Locations!', 'boldgrid-backup' ),
281
+ '<strong>',
282
+ '</strong>',
283
+ BOLDGRID_BACKUP_TITLE . ' Premium'
284
+ )
285
  ),
286
+ /* 4 */ esc_html__( 'Secure your backups by keeping copies of them on <a href="admin.php?page=boldgrid-backup-tools&section=section_locations">remote storage</a>.', 'boldgrid-backup' )
287
  );
288
 
289
+ $editor_tools = sprintf(
290
+ '
291
  <div style="padding-top:0px;" id="wp-content-editor-tools" class="wp-editor-tools hide-if-no-js">
292
  <div id="wp-content-media-buttons" class="wp-media-buttons">
293
  %1$s
299
  </div>
300
  ',
301
  /* 1 */ $db['buttons'],
302
+ /* 2 */ esc_html__( 'Files & Folders', 'boldgrid-backup' ),
303
+ /* 3 */ esc_html__( 'Database', 'boldgrid-backup' )
304
  );
305
 
306
+ $premium_url = $this->core->go_pro->get_premium_url( 'bgbkup-archive-browser' );
307
+ $intro = $this->core->config->is_premium_done ? '' : sprintf(
308
+ '
309
  <div class="bg-box-bottom premium" style="margin-bottom:15px;">
310
  <strong>%1$s</strong>
 
311
  <p>
312
  %2$s
313
  %3$s
314
  </p>
315
  </div>',
316
+ /* 1 */ esc_html__( 'Restore Individual Files With One Click', 'boldgrid-backup' ),
317
+ /* 2 */ $this->core->go_pro->get_premium_button( $premium_url, esc_html__( 'Unlock Feature', 'boldgrid-backup' ) ),
318
+ /* 3 */ sprintf(
319
+ // translators: 1: Plugin title.
320
+ esc_html__(
321
+ 'Changed a file and now your site isn’t working properly? With %1$s, you can browse through past backup archives and restore individual files with a single click.',
322
+ 'boldgrid-backup'
323
+ ),
324
+ BOLDGRID_BACKUP_TITLE . ' Premium'
325
+ )
326
  );
327
 
328
  $main_content = '
329
  <div id="postdivrich" class="postarea wp-editor-expand">
 
330
  <div id="wp-content-wrap" class="wp-core-ui wp-editor-wrap tmce-active has-dfw">
 
331
  <h2 style="font-size:initial; padding:0px;">
332
+ ' . esc_html__( 'Download & Restore', 'boldgrid-backup' ) . '
333
  <span class="dashicons dashicons-editor-help" data-id="download_and_restore"></span>
334
  </h2>
 
335
  <p class="help" data-id="download_and_restore">
336
+ <strong>' . esc_html__( 'Download to Local Machine', 'boldgrid-backup' ) . '</strong><br />
337
+ ' . esc_html__( 'Backup archives generally should be stored in more locations than just your <strong>web server</strong>. Be sure to keep copies on your <strong>local machine</strong> and / or a <strong>remote storage</strong> provider. Learn more about these different locations <a href="admin.php?page=boldgrid-backup-tools&section=section_locations">here</a>.', 'boldgrid-backup' ) . '<br /><br />
338
+ <strong>' . esc_html__( 'Restore', 'boldgrid-backup' ) . '</strong><br />
339
+ ' . esc_html__( 'Restore this backup. This will restore all the files and the database in this backup. Use the <strong>Backup Browser</strong> below to look at the backup archive and see what will be restored.', 'boldgrid-backup' ) . '<br /><br />
340
+ <strong>' . esc_html__( 'Download Link', 'boldgrid-backup' ) . '</strong><br />
341
+ ' . esc_html__( 'A public link that is used to download a backup archive file. You can use it to migrate your website to another WordPress installation. Please keep download links private, as the download files contains sensitive data.', 'boldgrid-backup' ) . '
342
  </p>
 
343
  <p>
344
+ ' . $download_button . ' ' . $restore_button . ' ' . $download_link . '
345
  </p>
346
+ <div id="download-link-copy" class="notice notice-info inline"></div>
347
  <hr class="separator" />
348
+ <h2 style="font-size:initial; padding:0px;">' . esc_html__( 'Backup Browser', 'boldgrid-backup' ) . '</h2>
 
 
349
  <p>
350
+ ' . esc_html__( 'Use the File & Folders and Database tools below to browse the contents of this backup file.', 'boldgrid-backup' ) . '
351
  </p>
 
352
  ' . $intro . $editor_tools . $browser . $db['browser'] . '
353
  </div>
354
  </div>
355
  ';
356
 
357
+
358
+ /*
359
+ * Allow the user to enter a title and description for this backup.
360
+ *
361
+ * Prepend this to the main content area.
362
+ */
363
+ if ( $archive_found ) {
364
+ $main_content = '
365
+ <div id="titlediv">
366
+ <div id="titlewrap">
367
+ <input type="text" name="backup_title" size="30" value="' . esc_attr( $title ) .
368
+ '" id="title" spellcheck="true" autocomplete="off" placeholder="' .
369
+ esc_attr__( 'Unnamed Backup', 'boldgrid-backup' ) . '">
370
+ </div>
371
+ </div>
372
+ <textarea name="backup_description" id="backup-description" placeholder="' .
373
+ esc_attr__( 'Backup description.', 'boldgrid-backup' ) . '">' . esc_html( $description ) . '</textarea>
374
+ <hr class="separator">
375
+ ' . $main_content;
376
+ }
377
+
378
  if ( ! $this->core->archive->is_stored_locally() ) {
379
 
380
  if ( $this->core->archive->is_stored_remotely() ) {
381
  $main_content = $only_remote;
382
  } else {
383
+ $main_content = $not_found;
384
  $remote_meta_box = '';
385
  }
386
  }
387
 
388
+ $page = sprintf(
389
+ '
390
  <input type="hidden" id="filename" value="%1$s" />
391
  <div class="wrap">
392
  <h1 class="wp-heading-inline">%2$s</h1>
409
  </div>
410
  ',
411
  /* 1 */ $archive['filename'],
412
+ /* 2 */ esc_html__( 'Backup Archive Details', 'boldgrid-backup' ),
413
+ /* 3 */ require BOLDGRID_BACKUP_PATH . '/admin/partials/boldgrid-backup-admin-nav.php',
414
  /* 4 */ $main_content,
415
  /* 5 */ $main_meta_box,
416
  /* 6 */ $remote_meta_box
417
  );
418
 
419
+ echo $page; // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
 
 
admin/partials/boldgrid-backup-admin-backup-button.php CHANGED
@@ -1,40 +1,72 @@
1
  <?php
2
  /**
 
 
3
  * Display a "Backup Site Now" button.
4
  *
 
5
  * @since 1.3
6
  *
7
  * @package Boldgrid_Backup
8
- * @subpackage Boldgrid_Backup/admin/partials/archives
 
 
 
9
  */
10
 
11
- defined( 'WPINC' ) ? : die;
 
 
12
 
13
- $core = isset( $this->core ) ? $this->core : $this;
14
 
15
- // Are we loading the "protect now" form via ajax?
16
- $update_protection_ajax = ! empty( $_POST['action'] ) && 'boldgrid_backup_get_protect_notice' === $_POST['action'] && ! empty( $_POST['update_protection'] );
 
 
17
 
18
- return sprintf(
19
- '<div id="backup-site-now-section">
20
- <form action="#" id="backup-site-now-form" method="POST">
21
- %1$s
22
- <p id="you_may_leave" class="hidden">
23
- %4$s
24
- </p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  <p>
26
- <a id="backup-site-now" class="button button-primary" %3$s >
27
- %2$s
28
- </a>
29
  <span class="spinner"></span>
30
- </p>
 
 
 
31
  </form>
32
  </div>
33
- <div id="backup-site-now-results"></div>',
34
- wp_nonce_field( 'boldgrid_backup_now', 'backup_auth', true, false ),
35
- esc_html( 'Backup Site Now', 'boldgrid-backup' ),
36
- $update_protection_ajax || $core->auto_rollback->on_update_page ? 'data-updating="true"' : '',
37
- /* 4 */ __( 'You may leave this page, doing so will not stop your backup.', 'boldgrid-backup' )
38
- );
39
-
40
 
 
1
  <?php
2
  /**
3
+ * File: boldgrid-backup-admin-backup-button.php
4
+ *
5
  * Display a "Backup Site Now" button.
6
  *
7
+ * @link https://www.boldgrid.com
8
  * @since 1.3
9
  *
10
  * @package Boldgrid_Backup
11
+ * @subpackage Boldgrid_Backup/admin/partials
12
+ * @copyright BoldGrid
13
+ * @version $Id$
14
+ * @author BoldGrid <support@boldgrid.com>
15
  */
16
 
17
+ // phpcs:disable WordPress.VIP, WordPress.CSRF.NonceVerification.NoNonceVerification
18
+
19
+ defined( 'WPINC' ) || die;
20
 
21
+ $page = empty( $_GET['page'] ) ? '' : $_GET['page'];
22
 
23
+ $backup_button = '
24
+ <div id="backup-site-now-section">
25
+ <form action="#" id="backup-site-now-form" method="POST">' .
26
+ wp_nonce_field( 'boldgrid_backup_now', 'backup_auth', true, false );
27
 
28
+ /*
29
+ * Create the "beef" of the backup button.
30
+ *
31
+ * The backup button is displayed in two ways:
32
+ * 1. Within the "Backup Site Now" modal
33
+ * 2. In an admin notice for Update protection.
34
+ *
35
+ * If the page is 'boldgrid-backup', then you're in the modal. The buttons will generally be the same,
36
+ * but the formatting will be slightly different, hence the conditional below.
37
+ */
38
+ if ( 'boldgrid-backup' === $page ) {
39
+ // The first div in the grid is needed so the grid fills out properly.
40
+ $backup_button .= '
41
+ <div style="display:grid; grid-gap:2em; grid-template-columns: 5fr 2fr;">
42
+ <div>
43
+ <p id="you_may_leave" class="hidden">' .
44
+ esc_html__( 'Your backup is starting. This page will refresh and display the progress of the backup.', 'boldgrid-backup' ) .
45
+ '</p>
46
+ </div>
47
+ <p style="text-align:right;">
48
+ <a id="backup-site-now" class="button button-primary">' .
49
+ esc_html__( 'Backup Site Now', 'boldgrid-backup' ) .
50
+ '</a>
51
+ <span class="spinner"></span>
52
+ </p>
53
+ </div>';
54
+ } else {
55
+ $backup_button .= '
56
+ <p id="you_may_leave" class="hidden">' .
57
+ __( 'You may leave this page, doing so will not stop your backup.', 'boldgrid-backup' ) .
58
+ '</p>
59
  <p>
60
+ <a id="backup-site-now" class="button button-primary" data-updating="true" >' .
61
+ esc_html__( 'Backup Site Now', 'boldgrid-backup' ) .
62
+ '</a>
63
  <span class="spinner"></span>
64
+ </p>';
65
+ }
66
+
67
+ $backup_button .= '
68
  </form>
69
  </div>
70
+ <div id="backup-site-now-results"></div>';
 
 
 
 
 
 
71
 
72
+ return $backup_button;
admin/partials/boldgrid-backup-admin-backup-modal.php CHANGED
@@ -1,19 +1,28 @@
1
  <?php
2
  /**
 
 
3
  * Display a "Backup Site Now" button and modal.
4
  *
5
- * @since 1.5.4
 
6
  *
7
  * @package Boldgrid_Backup
8
  * @subpackage Boldgrid_Backup/admin/partials
 
 
 
9
  */
10
 
11
- defined( 'WPINC' ) ? : die;
12
 
13
- return sprintf('
 
14
  <div id="backup_now_content" style="display:none;">
15
  <h2>%1$s</h2>
16
 
 
 
17
  <p>%2$s</p>
18
 
19
  %3$s
@@ -28,9 +37,8 @@ return sprintf('
28
  </div>',
29
  /* 1 */ __( 'Backup Site Now', 'boldgrid-backup' ),
30
  /* 2 */ __( 'The <strong>Files and Folders</strong> and <strong>Database</strong> settings below customize which parts of your site to backup.', 'boldgrid-backup' ),
31
- /* 3 */ include BOLDGRID_BACKUP_PATH . '/admin/partials/settings/folders.php',
32
- /* 4 */ include BOLDGRID_BACKUP_PATH . '/admin/partials/settings/db.php',
33
- /* 5 */ include BOLDGRID_BACKUP_PATH . '/admin/partials/boldgrid-backup-admin-backup-button.php'
 
34
  );
35
-
36
-
1
  <?php
2
  /**
3
+ * File: boldgrid-backup-admin-backup-modal.php
4
+ *
5
  * Display a "Backup Site Now" button and modal.
6
  *
7
+ * @link https://www.boldgrid.com
8
+ * @since 1.6.0
9
  *
10
  * @package Boldgrid_Backup
11
  * @subpackage Boldgrid_Backup/admin/partials
12
+ * @copyright BoldGrid
13
+ * @version $Id$
14
+ * @author BoldGrid <support@boldgrid.com>
15
  */
16
 
17
+ defined( 'WPINC' ) || die;
18
 
19
+ return sprintf(
20
+ '
21
  <div id="backup_now_content" style="display:none;">
22
  <h2>%1$s</h2>
23
 
24
+ %6$s
25
+
26
  <p>%2$s</p>
27
 
28
  %3$s
37
  </div>',
38
  /* 1 */ __( 'Backup Site Now', 'boldgrid-backup' ),
39
  /* 2 */ __( 'The <strong>Files and Folders</strong> and <strong>Database</strong> settings below customize which parts of your site to backup.', 'boldgrid-backup' ),
40
+ /* 3 */ require BOLDGRID_BACKUP_PATH . '/admin/partials/settings/folders.php',
41
+ /* 4 */ require BOLDGRID_BACKUP_PATH . '/admin/partials/settings/db.php',
42
+ /* 5 */ require BOLDGRID_BACKUP_PATH . '/admin/partials/boldgrid-backup-admin-backup-button.php',
43
+ /* 6 */ require BOLDGRID_BACKUP_PATH . '/admin/partials/backup-now-modal/title.php'
44
  );
 
 
admin/partials/boldgrid-backup-admin-backup.php CHANGED
@@ -1,27 +1,32 @@
1
  <?php
2
  /**
3
- * Provide a admin area view for the plugin
4
  *
5
  * This file is used to markup the admin-facing aspects of the plugin.
6
  *
7
- * @link http://www.boldgrid.com
8
  * @since 1.0
9
  *
10
- * @package Boldgrid_Backup
11
  * @subpackage Boldgrid_Backup/admin/partials
 
 
 
 
 
12
  */
13
 
14
- defined( 'WPINC' ) ? : die;
15
 
16
- $is_restore = ! empty( $_POST['restore_now'] ) && '1' === $_POST['restore_now'];
17
- $is_success = ! empty( $archive_info ) && empty( $archive_info['error'] );
18
  $redirect_url = admin_url( 'admin.php?page=boldgrid-backup' );
19
 
20
  /*
21
  * Avoid backwards compatibility issues when restoring.
22
  *
23
- * For example, let's say you're running "BoldGrid Backup 1.5" and you're
24
- * trying to restore a "BoldGrid Backup 1.6" archive. The restoration request
25
  * is being handled by 1.5, who's $core is a bit different than the 1.6 $core.
26
  * Elements in this file are calling upon $core, but we don't know if $core
27
  * exists or what characteristics it has.
@@ -33,7 +38,6 @@ $redirect_url = admin_url( 'admin.php?page=boldgrid-backup' );
33
  * @since 1.6.0
34
  */
35
  if ( $is_restore && $is_success ) {
36
-
37
  /*
38
  * After restoration, redirect user to the backups page.
39
  *
@@ -51,14 +55,18 @@ if ( $is_restore && $is_success ) {
51
  * to see it. We'll take care of the refresh for the user.
52
  */
53
  if ( ! wp_doing_ajax() ) {
54
- printf( '<script type="text/javascript">window.location.href = "%1$s";</script>', $redirect_url );
 
 
55
  return;
56
  }
57
  }
58
 
 
 
59
  $core = isset( $this->core ) ? $this->core : $this;
60
 
61
- $core->archive->init( $archive_info['filepath'] );
62
 
63
  /**
64
  * If data exists in the $archive_info array, then print results, else show an error message.
@@ -75,22 +83,24 @@ $core->archive->init( $archive_info['filepath'] );
75
  */
76
 
77
  // Create a link to the settings page.
78
- $url = admin_url( 'admin.php?page=boldgrid-backup-settings' );
79
  $settings_page_link = sprintf(
80
  wp_kses(
81
- __( 'See <a href="%s">Settings for BoldGrid Backup</a> for details.', 'boldgrid-backup' ),
82
- array( 'a' => array( 'href' => array() ) )
 
83
  ),
84
- esc_url( $url )
 
85
  );
86
 
87
  if ( ! empty( $archive_info ) ) {
88
 
89
  if ( ! empty( $archive_info['dryrun'] ) ) {
90
- $message = array(
91
- 'class' => 'notice notice-info is-dismissible',
92
  'message' => sprintf( '<p>%1$s</p>', esc_html__( 'This was a dry run test', 'boldgrid-backup' ) ),
93
- );
94
  }
95
 
96
  /*
@@ -107,53 +117,62 @@ if ( ! empty( $archive_info ) ) {
107
  * may want to further organize this entire file.
108
  */
109
  if ( $is_success ) {
110
- $message = array(
111
- 'class' => 'notice notice-success is-dismissible boldgrid-backup-complete',
112
- 'message' => sprintf( '
 
113
  <h2 class="header-notice">%1$s - %2$s</h2>
114
  <p>%3$s <a href="%4$s">%5$s</a></p>
115
  ',
116
- /* 1 */ __( 'BoldGrid Backup', 'boldgrid-backup' ),
117
- /* 2 */ __( 'Backup complete', 'boldgrid-backup' ),
118
  /* 3 */ esc_html__( 'A backup archive file has been created successfully!', 'boldgrid-backup' ),
119
  /* 4 */ $core->archive->view_details_url,
120
- /* 5 */ __( 'View details', 'boldgrid-backup' )
121
  ),
122
- );
123
  } else {
124
- $message = array(
125
- 'class' => 'notice notice-error is-dismissible',
126
  'message' => esc_html( $archive_info['error'] ),
127
- 'header' => sprintf(
128
  '%1$s - %2$s',
129
- __( 'BoldGrid Backup', 'boldgrid-backup' ),
130
- empty( $_POST['restore_now'] ) ? __( 'Error creating archive', 'boldgrid-backup' ) : __( 'Error restoring archive', 'boldgrid-backup' )
 
 
131
  ),
132
- );
133
  }
134
  } else {
135
- $message = array(
136
- 'class' => 'notice notice-error is-dismissible',
137
- 'message' => sprintf('
 
138
  <p>%1$s</p>
139
  %2$s
140
  %3$s
141
  %4$s %5$s',
142
- /* 1 */ $is_restore ? esc_html__( 'There was an error restoring the selected backup archive file', 'boldgrid-backup' ) : esc_html__( 'There was an error creating a backup archive file', 'boldgrid-backup' ),
143
- /* 2 */ empty( $archive_info['filepath'] ) ? '' : '<p>' . sprintf( esc_html__( 'File Path: %s', 'boldgrid-backup' ), $archive_info['filepath'] ) . '</p>',
144
- /* 3 */ empty( $archive_info['error'] ) ? '' : '<p>' . $archive_info['error'] . '</p>',
145
- /* 4 */ ! isset( $archive_info['error_message'] ) ? '' : '<p>' . sprintf( __( 'Error Details: %s', 'boldgrid-backup' ), $archive_info['error_message'] ),
146
- /* 5 */ isset( $archive_info['error_message'] ) && isset( $archive_info['error_code'] ) ? ' (' . $archive_info['error_code'] . ')' : ''
 
 
 
 
 
147
  ),
148
- );
149
  }
150
 
151
  if ( ! isset( $message ) ) {
152
- $message = array(
153
- 'class' => 'notice notice-error is-dismissible',
154
- 'message' => __( 'Unknown error.', 'boldgrid-backup' ),
155
- 'header' => __( 'BoldGrid Backup', 'boldgrid-backup' ),
156
- );
157
  }
158
 
159
  $message['header'] = isset( $message['header'] ) ? $message['header'] : null;
1
  <?php
2
  /**
3
+ * File: boldgrid-backup-admin-backup.php
4
  *
5
  * This file is used to markup the admin-facing aspects of the plugin.
6
  *
7
+ * @link https://www.boldgrid.com
8
  * @since 1.0
9
  *
10
+ * @package Boldgrid_Backup
11
  * @subpackage Boldgrid_Backup/admin/partials
12
+ * @copyright BoldGrid
13
+ * @version $Id$
14
+ * @author BoldGrid <support@boldgrid.com>
15
+ *
16
+ * phpcs:disable WordPress.VIP
17
  */
18
 
19
+ defined( 'WPINC' ) || die;
20
 
21
+ $is_restore = ! empty( $_POST['restore_now'] ) && '1' === $_POST['restore_now']; // phpcs:ignore WordPress.CSRF.NonceVerification.NoNonceVerification
22
+ $is_success = ! empty( $archive_info ) && empty( $archive_info['error'] );
23
  $redirect_url = admin_url( 'admin.php?page=boldgrid-backup' );
24
 
25
  /*
26
  * Avoid backwards compatibility issues when restoring.
27
  *
28
+ * For example, let's say you're running version 1.5 and you're
29
+ * trying to restore a version 1.6 archive. The restoration request
30
  * is being handled by 1.5, who's $core is a bit different than the 1.6 $core.
31
  * Elements in this file are calling upon $core, but we don't know if $core
32
  * exists or what characteristics it has.
38
  * @since 1.6.0
39
  */
40
  if ( $is_restore && $is_success ) {
 
41
  /*
42
  * After restoration, redirect user to the backups page.
43
  *
55
  * to see it. We'll take care of the refresh for the user.
56
  */
57
  if ( ! wp_doing_ajax() ) {
58
+ ?>
59
+ <script type="text/javascript">window.location.href = "<?php echo esc_url( $redirect_url ); ?>";</script>
60
+ <?php
61
  return;
62
  }
63
  }
64
 
65
+ $archive_filepath = ! empty( $archive_info['filepath'] ) ? $archive_info['filepath'] : null;
66
+
67
  $core = isset( $this->core ) ? $this->core : $this;
68
 
69
+ $core->archive->init( $archive_filepath );
70
 
71
  /**
72
  * If data exists in the $archive_info array, then print results, else show an error message.
83
  */
84
 
85
  // Create a link to the settings page.
86
+ $url = admin_url( 'admin.php?page=boldgrid-backup-settings' );
87
  $settings_page_link = sprintf(
88
  wp_kses(
89
+ // translators: 1: URL address, 2: Plugin title.
90
+ __( 'See <a href="%1$s">Settings for %2$s</a> for details.', 'boldgrid-backup' ),
91
+ [ 'a' => [ 'href' => [] ] ]
92
  ),
93
+ esc_url( $url ),
94
+ BOLDGRID_BACKUP_TITLE
95
  );
96
 
97
  if ( ! empty( $archive_info ) ) {
98
 
99
  if ( ! empty( $archive_info['dryrun'] ) ) {
100
+ $message = [
101
+ 'class' => 'notice notice-info is-dismissible',
102
  'message' => sprintf( '<p>%1$s</p>', esc_html__( 'This was a dry run test', 'boldgrid-backup' ) ),
103
+ ];
104
  }
105
 
106
  /*
117
  * may want to further organize this entire file.
118
  */
119
  if ( $is_success ) {
120
+ $message = [
121
+ 'class' => 'notice notice-success is-dismissible boldgrid-backup-complete',
122
+ 'message' => sprintf(
123
+ '
124
  <h2 class="header-notice">%1$s - %2$s</h2>
125
  <p>%3$s <a href="%4$s">%5$s</a></p>
126
  ',
127
+ /* 1 */ BOLDGRID_BACKUP_TITLE,
128
+ /* 2 */ esc_html__( 'Backup complete', 'boldgrid-backup' ),
129
  /* 3 */ esc_html__( 'A backup archive file has been created successfully!', 'boldgrid-backup' ),
130
  /* 4 */ $core->archive->view_details_url,
131
+ /* 5 */ esc_html__( 'View details', 'boldgrid-backup' )
132
  ),
133
+ ];
134
  } else {
135
+ $message = [
136
+ 'class' => 'notice notice-error is-dismissible',
137
  'message' => esc_html( $archive_info['error'] ),
138
+ 'header' => sprintf(
139
  '%1$s - %2$s',
140
+ BOLDGRID_BACKUP_TITLE,
141
+ empty( $_POST['restore_now'] ) ? // phpcs:ignore WordPress.CSRF.NonceVerification.NoNonceVerification
142
+ esc_html__( 'Error creating archive', 'boldgrid-backup' ) :
143
+ esc_html__( 'Error restoring archive', 'boldgrid-backup' )
144
  ),
145
+ ];
146
  }
147
  } else {
148
+ $message = [
149
+ 'class' => 'notice notice-error is-dismissible',
150
+ 'message' => sprintf(
151
+ '
152
  <p>%1$s</p>
153
  %2$s
154
  %3$s
155
  %4$s %5$s',
156
+ $is_restore ?
157
+ esc_html__( 'There was an error restoring the selected backup archive file', 'boldgrid-backup' ) :
158
+ esc_html__( 'There was an error creating a backup archive file', 'boldgrid-backup' ),
159
+ // translators: 1: File path.
160
+ empty( $archive_info['filepath'] ) ? '' : '<p>' . sprintf( esc_html__( 'File Path: %1$s', 'boldgrid-backup' ), $archive_info['filepath'] ) . '</p>',
161
+ empty( $archive_info['error'] ) ? '' : '<p>' . $archive_info['error'] . '</p>',
162
+ // translators: 1: Error message.
163
+ ! isset( $archive_info['error_message'] ) ? '' : '<p>' . sprintf( esc_html__( 'Error Details: %1$s', 'boldgrid-backup' ), $archive_info['error_message'] ),
164
+ isset( $archive_info['error_message'] ) && isset( $archive_info['error_code'] ) ?
165
+ ' (' . $archive_info['error_code'] . ')' : ''
166
  ),
167
+ ];
168
  }
169
 
170
  if ( ! isset( $message ) ) {
171
+ $message = [
172
+ 'class' => 'notice notice-error is-dismissible',
173
+ 'message' => esc_html__( 'Unknown error.', 'boldgrid-backup' ),
174
+ 'header' => BOLDGRID_BACKUP_TITLE,
175
+ ];
176
  }
177
 
178
  $message['header'] = isset( $message['header'] ) ? $message['header'] : null;
admin/partials/boldgrid-backup-admin-dashboard.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File: boldgrid-backup-admin-dashboard.php
4
+ *
5
+ * This file is used to markup dashboard page.
6
+ *
7
+ * @link https://www.boldgrid.com
8
+ * @since 1.11.0
9
+ *
10
+ * @package Boldgrid_Backup
11
+ * @subpackage Boldgrid_Backup/admin/partials
12
+ * @copyright BoldGrid
13
+ * @version $Id$
14
+ * @author BoldGrid <support@boldgrid.com>
15
+ */
16
+
17
+ defined( 'WPINC' ) || die;
18
+
19
+ $nav = include BOLDGRID_BACKUP_PATH . '/admin/partials/boldgrid-backup-admin-nav.php';
20
+
21
+ $dashboard = new \Boldgrid\Library\Library\Ui\Dashboard();
22
+
23
+ $dashboard->cards = $this->get_cards();
24
+ ?>
25
+
26
+ <div class='wrap'>
27
+ <h1><?php echo esc_html( BOLDGRID_BACKUP_TITLE . ' ' . __( 'Dashboard', 'boldgrid-backup' ) ); ?></h1>
28
+
29
+ <?php
30
+ echo $nav; // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
31
+
32
+ $dashboard->printCards();
33
+ ?>
34
+ </div>
admin/partials/boldgrid-backup-admin-home.php CHANGED
@@ -1,17 +1,20 @@
1
  <?php
2
  /**
3
- * Provide a admin area view for the plugin
4
  *
5
  * This file is used to markup the admin-facing aspects of the plugin.
6
  *
7
- * @link http://www.boldgrid.com
8
  * @since 1.0
9
  *
10
- * @package Boldgrid_Backup
11
  * @subpackage Boldgrid_Backup/admin/partials
 
 
 
12
  */
13
 
14
- defined( 'WPINC' ) ? : die;
15
 
16
  /*
17
  * Variables passed by scope.
@@ -34,41 +37,53 @@ defined( 'WPINC' ) ? : die;
34
  $nav = include BOLDGRID_BACKUP_PATH . '/admin/partials/boldgrid-backup-admin-nav.php';
35
 
36
  // Premium advertisement on the bottom of the archives page.
37
- $ad = $this->config->is_premium_done ? '' : sprintf( '
 
 
38
  <div class="bg-box-bottom premium wp-clearfix">
39
  %1$s
40
- %2$s
41
  </div>',
42
- $this->go_pro->get_premium_button(),
43
  $this->lang['want_to']
44
  );
45
 
46
  // Backup now modal.
47
  $in_modal = true;
48
- $modal = include BOLDGRID_BACKUP_PATH . '/admin/partials/boldgrid-backup-admin-backup-modal.php';
49
  $in_modal = false;
50
 
51
  ?>
52
  <div class='wrap'>
53
 
54
- <h1 class="wp-heading-inline"><?php esc_html_e( 'Backup Archives', 'boldgrid-backup' ); ?></h1>
55
 
56
- <a href="#TB_inline?width=800&amp;height=600&amp;inlineId=backup_now_content" class="thickbox page-title-action page-title-action-primary"><?php echo __( 'Backup Site Now', 'boldgrid-backup' ); ?></a>
57
 
58
- <a class="page-title-action add-new"><?php echo __( 'Upload Backup', 'boldgrid-backup' ); ?></a>
 
 
 
 
59
 
60
  <?php
61
- echo $nav;
62
 
63
- include BOLDGRID_BACKUP_PATH . '/admin/partials/archives/add-new.php';
64
 
65
- echo $table;
66
 
67
- echo $modal;
68
 
69
- include BOLDGRID_BACKUP_PATH . '/admin/partials/archives/note-pre-backup.php';
 
 
 
70
 
71
- echo $ad;
 
 
 
72
  ?>
73
 
74
  </div>
1
  <?php
2
  /**
3
+ * File: boldgrid-backup-admin-home.php
4
  *
5
  * This file is used to markup the admin-facing aspects of the plugin.
6
  *
7
+ * @link https://www.boldgrid.com
8
  * @since 1.0
9
  *
10
+ * @package Boldgrid_Backup
11
  * @subpackage Boldgrid_Backup/admin/partials
12
+ * @copyright BoldGrid
13
+ * @version $Id$
14
+ * @author BoldGrid <support@boldgrid.com>
15
  */
16
 
17
+ defined( 'WPINC' ) || die;
18
 
19
  /*
20
  * Variables passed by scope.
37
  $nav = include BOLDGRID_BACKUP_PATH . '/admin/partials/boldgrid-backup-admin-nav.php';
38
 
39
  // Premium advertisement on the bottom of the archives page.
40
+ $premium_url = $this->go_pro->get_premium_url( 'bgbkup-archives-bottom' );
41
+ $ad = $this->config->is_premium_done ? '' : sprintf(
42
+ '
43
  <div class="bg-box-bottom premium wp-clearfix">
44
  %1$s
45
+ <p style="margin:0;">%2$s</p>
46
  </div>',
47
+ $this->go_pro->get_premium_button( $premium_url, esc_html__( 'Unlock Feature', 'boldgrid-backup' ) ),
48
  $this->lang['want_to']
49
  );
50
 
51
  // Backup now modal.
52
  $in_modal = true;
53
+ $modal = include BOLDGRID_BACKUP_PATH . '/admin/partials/boldgrid-backup-admin-backup-modal.php';
54
  $in_modal = false;
55
 
56
  ?>
57
  <div class='wrap'>
58
 
59
+ <h1 class="wp-heading-inline"><?php echo esc_html( BOLDGRID_BACKUP_TITLE . ' ' . __( 'Backup Archives', 'boldgrid-backup' ) ); ?></h1>
60
 
61
+ <div class="page-title-actions">
62
 
63
+ <a href="#TB_inline?width=800&amp;height=600&amp;inlineId=backup_now_content" class="thickbox page-title-action page-title-action-primary"><?php esc_html_e( 'Backup Site Now', 'boldgrid-backup' ); ?></a>
64
+
65
+ <a class="page-title-action add-new"><?php esc_html_e( 'Upload Backup', 'boldgrid-backup' ); ?></a>
66
+
67
+ </div>
68
 
69
  <?php
70
+ echo $nav; // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
71
 
72
+ require BOLDGRID_BACKUP_PATH . '/admin/partials/archives/add-new.php';
73
 
74
+ echo $table; // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
75
 
76
+ echo $modal; // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
77
 
78
+ /*
79
+ * @todo Revisit the usefulness of this notice in this location. Commented out @since 1.10.1
80
+ * require BOLDGRID_BACKUP_PATH . '/admin/partials/archives/note-pre-backup.php';
81
+ */
82
 
83
+ // Bombard the user with an ad before they've even made their first backup. I mean, don't.
84
+ if ( ! empty( $this->archives_all->all ) ) {
85
+ echo $ad; // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
86
+ }
87
  ?>
88
 
89
  </div>
admin/partials/boldgrid-backup-admin-mail-restore.php CHANGED
@@ -1,14 +1,20 @@
1
  <?php
2
  /**
 
 
3
  * Mail template for restoration notifications.
4
  *
 
5
  * @since 1.2.2
6
  *
7
- * @package Boldgrid_Backup
8
  * @subpackage Boldgrid_Backup/admin/partials
 
 
 
9
  */
10
 
11
- defined( 'WPINC' ) ? : die;
12
 
13
  /**
14
  * This template uses inherited variables.
@@ -19,16 +25,14 @@ defined( 'WPINC' ) ? : die;
19
  * @param bool $restore_ok Success of the restoration.
20
  * @param string $info['filepath'] The file path restored.
21
  */
22
- // Create a site identifier.
23
  $site_id = Boldgrid_Backup_Admin_Utility::create_site_id();
24
 
25
- // Create subject.
26
  $subject = sprintf(
 
27
  esc_html__( 'Restoration completed for %s', 'boldgrid-backup' ),
28
  $site_id
29
  );
30
 
31
- // Create message.
32
  $body = esc_html__( 'Hello', 'boldgrid-backup' ) . ",\n\n";
33
 
34
  if ( $dryrun ) {
@@ -45,6 +49,7 @@ if ( $restore_ok ) {
45
  }
46
 
47
  $body .= sprintf(
 
48
  __( ' for %s', 'boldgrid-backup' ),
49
  $site_id
50
  ) . ".\n\n";
@@ -52,11 +57,13 @@ $body .= sprintf(
52
  $body .= esc_html__( 'Restoration details', 'boldgrid-backup' ) . ":\n";
53
 
54
  $body .= sprintf(
 
55
  esc_html__( 'Archive file path: %s', 'boldgrid-backup' ),
56
  $info['filepath']
57
  ) . "\n";
58
 
59
  $body .= sprintf(
 
60
  esc_html__( 'Archive file size: %s', 'boldgrid-backup' ),
61
  Boldgrid_Backup_Admin_Utility::bytes_to_human( $info['filesize'] )
62
  ) . "\n";
@@ -68,11 +75,19 @@ if ( defined( 'DOING_CRON' ) ) {
68
  ) . ".\n\n";
69
  }
70
 
71
- $body .= esc_html__(
72
- 'You can manage notifications in your WordPress admin panel, under BoldGrid Backup Settings',
73
- 'boldgrid-backup'
 
 
 
 
74
  ) . ".\n\n";
75
 
76
  $body .= esc_html__( 'Best regards', 'boldgrid-backup' ) . ",\n\n";
77
 
78
- $body .= esc_html__( 'The BoldGrid Backup plugin', 'boldgrid-backup' ) . "\n\n";
 
 
 
 
1
  <?php
2
  /**
3
+ * File: boldgrid-backup-admin-mail-restore.php
4
+ *
5
  * Mail template for restoration notifications.
6
  *
7
+ * @link https://www.boldgrid.com
8
  * @since 1.2.2
9
  *
10
+ * @package Boldgrid_Backup
11
  * @subpackage Boldgrid_Backup/admin/partials
12
+ * @copyright BoldGrid
13
+ * @version $Id$
14
+ * @author BoldGrid <support@boldgrid.com>
15
  */
16
 
17
+ defined( 'WPINC' ) || die;
18
 
19
  /**
20
  * This template uses inherited variables.
25
  * @param bool $restore_ok Success of the restoration.
26
  * @param string $info['filepath'] The file path restored.
27
  */
 
28
  $site_id = Boldgrid_Backup_Admin_Utility::create_site_id();
29
 
 
30
  $subject = sprintf(
31
+ // translators: 1: Site identifier.
32
  esc_html__( 'Restoration completed for %s', 'boldgrid-backup' ),
33
  $site_id
34
  );
35
 
 
36
  $body = esc_html__( 'Hello', 'boldgrid-backup' ) . ",\n\n";
37
 
38
  if ( $dryrun ) {
49
  }
50
 
51
  $body .= sprintf(
52
+ // translators: 1: Site identifier.
53
  __( ' for %s', 'boldgrid-backup' ),
54
  $site_id
55
  ) . ".\n\n";
57
  $body .= esc_html__( 'Restoration details', 'boldgrid-backup' ) . ":\n";
58
 
59
  $body .= sprintf(
60
+ // translators: 1: Archive file path.
61
  esc_html__( 'Archive file path: %s', 'boldgrid-backup' ),
62
  $info['filepath']
63
  ) . "\n";
64
 
65
  $body .= sprintf(
66
+ // translators: 1: Archive file size.
67
  esc_html__( 'Archive file size: %s', 'boldgrid-backup' ),
68
  Boldgrid_Backup_Admin_Utility::bytes_to_human( $info['filesize'] )
69
  ) . "\n";
75
  ) . ".\n\n";
76
  }
77
 
78
+ $body .= sprintf(
79
+ // translators: 1: Plugin title.
80
+ esc_html__(
81
+ 'You can manage notifications in your WordPress admin panel, under %1$s Settings',
82
+ 'boldgrid-backup'
83
+ ),
84
+ BOLDGRID_BACKUP_TITLE
85
  ) . ".\n\n";
86
 
87
  $body .= esc_html__( 'Best regards', 'boldgrid-backup' ) . ",\n\n";
88
 
89
+ $body .= sprintf(
90
+ // translators: 1: Plugin title.
91
+ esc_html__( 'The %1$s plugin', 'boldgrid-backup' ),
92
+ BOLDGRID_BACKUP_TITLE
93
+ ) . "\n\n";
admin/partials/boldgrid-backup-admin-nav.php CHANGED
@@ -1,39 +1,72 @@
1
  <?php
2
  /**
3
- * This file contains the navbar for all BoldGrid Backup pages.
4
  *
 
 
 
5
  * @since 1.5.1
6
  *
7
  * @package Boldgrid_Backup
8
  * @subpackage Boldgrid_Backup/admin/partials
 
 
 
9
  */
10
 
11
- defined( 'WPINC' ) ? : die;
 
 
 
 
12
 
13
  $active = 'nav-tab-active';
14
 
15
- $navs = array(
16
- array(
 
 
 
 
 
 
17
  'title' => __( 'Backups', 'boldgrid-backup' ),
18
- 'href' => 'admin.php?page=boldgrid-backup',
19
  'class' => ! empty( $_GET['page'] ) && 'boldgrid-backup' === $_GET['page'] ? $active : '',
20
- ),
21
- array(
 
 
 
 
 
 
 
 
 
 
22
  'title' => __( 'Settings', 'boldgrid-backup' ),
23
- 'href' => 'admin.php?page=boldgrid-backup-settings',
24
  'class' => ! empty( $_GET['page'] ) && 'boldgrid-backup-settings' === $_GET['page'] ? $active : '',
25
- ),
26
- array(
27
  'title' => __( 'Preflight Check', 'boldgrid-backup' ),
28
- 'href' => 'admin.php?page=boldgrid-backup-test',
29
  'class' => ! empty( $_GET['page'] ) && 'boldgrid-backup-test' === $_GET['page'] ? $active : '',
30
- ),
31
- array(
32
- 'title' => __( 'Tools', 'boldgrid-backup' ),
33
- 'href' => 'admin.php?page=boldgrid-backup-tools',
34
- 'class' => ! empty( $_GET['page'] ) && 'boldgrid-backup-tools' === $_GET['page'] ? $active : '',
35
- ),
36
- );
 
 
 
 
 
 
 
37
 
38
  /**
39
  * Allow the update of our nav menu items.
@@ -47,14 +80,19 @@ $navs = apply_filters( 'boldgrid_backup_navs', $navs );
47
  $markup = '<h2 class="nav-tab-wrapper">';
48
  foreach ( $navs as $nav ) {
49
  $markup .= sprintf(
50
- '<a class="nav-tab %1$s" href="%2$s">%3$s</a>',
51
- $nav['class'],
52
- $nav['href'],
53
- $nav['title']
54
  );
 
 
 
 
 
 
 
55
  }
56
  $markup .= '</h2>';
57
 
58
  return $markup;
59
-
60
-
1
  <?php
2
  /**
3
+ * File: boldgrid-backup-admin-nav.php
4
  *
5
+ * This file contains the navbar for all plugin pages.
6
+ *
7
+ * @link https://www.boldgrid.com
8
  * @since 1.5.1
9
  *
10
  * @package Boldgrid_Backup
11
  * @subpackage Boldgrid_Backup/admin/partials
12
+ * @copyright BoldGrid
13
+ * @version $Id$
14
+ * @author BoldGrid <support@boldgrid.com>
15
  */
16
 
17
+ // phpcs:disable WordPress.VIP
18
+
19
+ defined( 'WPINC' ) || die;
20
+
21
+ $core = apply_filters( 'boldgrid_backup_get_core', null );
22
 
23
  $active = 'nav-tab-active';
24
 
25
+ // phpcs:disable WordPress.CSRF.NonceVerification.NoNonceVerification
26
+ $navs = [
27
+ [
28
+ 'title' => __( 'Dashboard', 'boldgrid-backup' ),
29
+ 'href' => 'admin.php?page=boldgrid-backup-dashboard',
30
+ 'class' => ! empty( $_GET['page'] ) && 'boldgrid-backup-dashboard' === $_GET['page'] ? $active : '',
31
+ ],
32
+ [
33
  'title' => __( 'Backups', 'boldgrid-backup' ),
34
+ 'href' => 'admin.php?page=boldgrid-backup',
35
  'class' => ! empty( $_GET['page'] ) && 'boldgrid-backup' === $_GET['page'] ? $active : '',
36
+ ],
37
+ [
38
+ 'title' => __( 'Transfers', 'boldgrid-backup' ),
39
+ 'href' => 'admin.php?page=boldgrid-backup-transfers',
40
+ 'class' => ! empty( $_GET['page'] ) && 'boldgrid-backup-transfers' === $_GET['page'] ? $active : '',
41
+ ],
42
+ [
43
+ 'title' => __( 'Tools', 'boldgrid-backup' ),
44
+ 'href' => 'admin.php?page=boldgrid-backup-tools',
45
+ 'class' => ! empty( $_GET['page'] ) && 'boldgrid-backup-tools' === $_GET['page'] ? $active : '',
46
+ ],
47
+ [
48
  'title' => __( 'Settings', 'boldgrid-backup' ),
49
+ 'href' => 'admin.php?page=boldgrid-backup-settings',
50
  'class' => ! empty( $_GET['page'] ) && 'boldgrid-backup-settings' === $_GET['page'] ? $active : '',
51
+ ],
52
+ [
53
  'title' => __( 'Preflight Check', 'boldgrid-backup' ),
54
+ 'href' => 'admin.php?page=boldgrid-backup-test',
55
  'class' => ! empty( $_GET['page'] ) && 'boldgrid-backup-test' === $_GET['page'] ? $active : '',
56
+ ],
57
+ [
58
+ 'title' => __( 'Support', 'boldgrid-backup' ),
59
+ 'href' => 'admin.php?page=boldgrid-backup-support',
60
+ 'class' => ! empty( $_GET['page'] ) && 'boldgrid-backup-support' === $_GET['page'] ? $active : '',
61
+ ],
62
+ [
63
+ 'title' => __( 'Premium Features', 'boldgrid-backup' ),
64
+ 'href' => 'admin.php?page=boldgrid-backup-premium-features',
65
+ 'class' => ! empty( $_GET['page'] ) && 'boldgrid-backup-premium-features' === $_GET['page'] ? $active : '',
66
+ 'count' => $core->plugin->getPageBySlug( 'boldgrid-backup-premium-features' )->getUnreadMarkup(),
67
+ ],
68
+ ];
69
+ // phpcs:enable WordPress.CSRF.NonceVerification.NoNonceVerification
70
 
71
  /**
72
  * Allow the update of our nav menu items.
80
  $markup = '<h2 class="nav-tab-wrapper">';
81
  foreach ( $navs as $nav ) {
82
  $markup .= sprintf(
83
+ '<a class="nav-tab %1$s" href="%2$s">%3$s',
84
+ esc_attr( $nav['class'] ),
85
+ esc_url( $nav['href'] ),
86
+ esc_html( $nav['title'] )
87
  );
88
+ if ( isset( $nav['count'] ) ) {
89
+ $markup .= sprintf(
90
+ ' %1$s',
91
+ $nav['count'] // This value is escaped already by Library\Plugin\Page::getUnreadMarkup
92
+ );
93
+ }
94
+ $markup .= '</a>';
95
  }
96
  $markup .= '</h2>';
97
 
98
  return $markup;
 
 
admin/partials/boldgrid-backup-admin-premium.php ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File: boldgrid-backup-admin-premium.php
4
+ *
5
+ * This file is used to markup premium cards page.
6
+ *
7
+ * @link https://www.boldgrid.com
8
+ * @since 1.13.0
9
+ *
10
+ * @package Boldgrid_Backup
11
+ * @subpackage Boldgrid_Backup/admin/partials
12
+ * @copyright BoldGrid
13
+ * @version $Id$
14
+ * @author BoldGrid <support@boldgrid.com>
15
+ */
16
+
17
+ defined( 'WPINC' ) || die;
18
+
19
+ $nav = include BOLDGRID_BACKUP_PATH . '/admin/partials/boldgrid-backup-admin-nav.php';
20
+
21
+ $dashboard = new \Boldgrid\Library\Library\Ui\Dashboard();
22
+
23
+ $dashboard->cards = $this->get_cards();
24
+
25
+ $dashboard->classes = 'bglib-smaller';
26
+
27
+ $premium_box = $this->core->config->is_premium_done ? '' : sprintf(
28
+ '
29
+ <div class="bg-box-bottom premium" style="margin:15px 0;">
30
+ <p style="margin-top:0;">
31
+ <span class="bg-box-title">%1$s</span>
32
+ %2$s
33
+ </p>
34
+ <p style="margin-bottom:0;">
35
+ %3$s
36
+ </p>
37
+ </div>',
38
+ /* 1 */ esc_html__( 'Total Upkeep Premium', 'boldgrid-backup' ),
39
+ /* 2 */ $this->core->go_pro->get_premium_button( $this->core->go_pro->get_premium_url( 'bgbkup-premium-features' ) ),
40
+ /* 3 */ esc_html__( 'Give your website data the protection it deserves with Total Upkeep Premium.
41
+ Enjoy automated remote backups to Google Drive and Amazon S3, individual file restoration,
42
+ the ability to restore from historical versions, premium support and more.', 'boldgrid-backup' )
43
+ );
44
+
45
+ ?>
46
+
47
+ <div class='wrap'>
48
+ <h1><?php echo esc_html( BOLDGRID_BACKUP_TITLE . ' ' . __( 'Dashboard', 'boldgrid-backup' ) ); ?></h1>
49
+
50
+ <?php
51
+ echo $nav; // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
52
+
53
+ echo $premium_box; // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
54
+
55
+ $dashboard->printCards();
56
+ ?>
57
+ </div>
admin/partials/boldgrid-backup-admin-settings.php CHANGED
@@ -1,71 +1,88 @@
1
  <?php
2
  /**
3
- * Provide a admin area view for the plugin
4
  *
5
  * This file is used to markup the admin-facing aspects of the plugin.
6
  *
7
- * @link http://www.boldgrid.com
8
  * @since 1.0
9
  *
10
- * @package Boldgrid_Backup
11
  * @subpackage Boldgrid_Backup/admin/partials
 
 
 
12
  */
13
 
14
- defined( 'WPINC' ) ? : die;
15
 
16
- $nav = include BOLDGRID_BACKUP_PATH . '/admin/partials/boldgrid-backup-admin-nav.php';
17
- $scheduler = include BOLDGRID_BACKUP_PATH . '/admin/partials/settings/scheduler.php';
 
 
18
  $folders_include = include BOLDGRID_BACKUP_PATH . '/admin/partials/settings/folders.php';
19
- $db = include BOLDGRID_BACKUP_PATH . '/admin/partials/settings/db.php';
20
- $retention = include BOLDGRID_BACKUP_PATH . '/admin/partials/settings/retention.php';
21
- $auto_updates = include BOLDGRID_BACKUP_PATH . '/admin/partials/settings/auto-updates.php';
22
- $notifications = include BOLDGRID_BACKUP_PATH . '/admin/partials/settings/notifications.php';
23
- $backup_directory = include BOLDGRID_BACKUP_PATH . '/admin/partials/settings/backup-directory.php';
24
- $connect_key = include BOLDGRID_BACKUP_PATH . '/admin/partials/settings/connect-key.php';
 
 
 
 
25
 
26
- $days_of_week = '';
27
- $time_of_day = '';
28
- $storage = '';
29
  if ( $this->core->scheduler->is_available( 'cron' ) || $this->core->scheduler->is_available( 'wp-cron' ) ) {
30
  $days_of_week = include BOLDGRID_BACKUP_PATH . '/admin/partials/settings/days-of-week.php';
31
- $time_of_day = include BOLDGRID_BACKUP_PATH . '/admin/partials/settings/time-of-day.php';
32
- $storage = include BOLDGRID_BACKUP_PATH . '/admin/partials/settings/storage.php';
33
  }
34
 
35
- $sections = array(
36
- 'sections' => array(
37
- array(
38
- 'id' => 'section_schedule',
39
- 'title' => __( 'Backup Schedule', 'boldgrid-backup' ),
40
- 'content' => $scheduler . $days_of_week . $time_of_day . $storage . $folders_include . $db,
41
- ),
42
- array(
43
- 'id' => 'connect_key',
44
- 'title' => __( 'BoldGrid Connect Key', 'boldgrid-bacup' ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  'content' => $connect_key,
46
- ),
47
- array(
48
- 'id' => 'section_retention',
49
- 'title' => __( 'Retention', 'boldgrid-backup' ),
50
- 'content' => $retention,
51
- ),
52
- array(
53
- 'id' => 'section_updates',
54
- 'title' => __( 'Auto Updates & Rollback', 'boldgrid-backup' ),
55
- 'content' => $auto_updates,
56
- ),
57
- array(
58
- 'id' => 'section_notifications',
59
- 'title' => __( 'Notifications', 'boldgrid-backup' ),
60
  'content' => $notifications,
61
- ),
62
- array(
63
- 'id' => 'section_directory',
64
- 'title' => __( 'Backup Directory', 'boldgrid-backup' ),
65
- 'content' => $backup_directory,
66
- ),
67
- ),
68
- 'post_col_right' => sprintf( '
69
  <div id="boldgrid-settings-submit-div">
70
  <p>
71
  <input id="boldgrid-settings-submit" class="button button-primary" type="submit" name="submit" value="%1$s" />
@@ -73,12 +90,12 @@ $sections = array(
73
  </div>',
74
  __( 'Save Changes', 'boldgrid-backup' )
75
  ),
76
- );
77
 
78
  /**
79
  * Allow other plugins to modify the sections of the settings page.
80
  *
81
- * @since 1.5.4
82
  *
83
  * @param array $sections
84
  */
@@ -87,9 +104,11 @@ $sections = apply_filters( 'boldgrid_backup_settings_sections', $sections );
87
  /**
88
  * Render the $sections into displayable markup.
89
  *
90
- * @since 1.5.4
91
  *
92
  * @param array $sections
 
 
93
  */
94
  $col_container = apply_filters( 'Boldgrid\Library\Ui\render_col_container', $sections );
95
  if ( is_array( $col_container ) ) {
@@ -98,11 +117,12 @@ if ( is_array( $col_container ) ) {
98
 
99
  // Check if settings are available, show an error notice if not.
100
  if ( empty( $settings ) ) {
101
- add_action( 'admin_footer',
102
- array(
 
103
  $this,
104
  'notice_settings_retrieval',
105
- )
106
  );
107
  }
108
 
@@ -110,37 +130,46 @@ wp_nonce_field( 'boldgrid_backup_settings' );
110
 
111
  ?>
112
  <div class='wrap'>
113
- <h1><?php esc_html_e( 'BoldGrid Backup and Restore Settings', 'boldgrid-backup' ); ?></h1>
114
 
115
  <?php
116
- echo $nav;
117
 
118
  /*
119
  * Print this text:
120
  *
121
- * The BoldGrid Backup and Restore system allows you to upgrade your themes and plugins without
122
  * being afraid it will do something you cannot easily undo. We perform a Preflight Check to see
123
  * if the needed support is available on your web hosting account.
124
  */
125
- $url = admin_url( 'admin.php?page=boldgrid-backup-test' );
126
- $link = sprintf(
 
 
127
  wp_kses(
128
- __( 'The BoldGrid Backup and Restore system allows you to upgrade your themes and plugins without being afraid it will do something you cannot easily undo. We perform a <a href="%s">Preflight Check</a> to see if the needed support is available on your web hosting account.', 'boldgrid-backup' ),
129
- array( 'a' => array( 'href' => array() ) )
 
 
 
 
130
  ),
131
- esc_url( $url )
 
132
  );
133
- echo '<p>' . $link . '</p>';
 
134
  ?>
 
135
 
136
  <hr />
137
 
138
- <form id='schedule-form' method='post'>
139
  <?php
140
- echo $col_container;
141
  wp_nonce_field( 'boldgrid-backup-settings', 'settings_auth' );
142
- printf( '<input type="hidden" name="save_time" value="%1$s" />', time() );
143
  ?>
 
144
  </form>
145
 
146
  </div>
1
  <?php
2
  /**
3
+ * File: boldgrid-backup-admin-settings.php
4
  *
5
  * This file is used to markup the admin-facing aspects of the plugin.
6
  *
7
+ * @link https://www.boldgrid.com
8
  * @since 1.0
9
  *
10
+ * @package Boldgrid_Backup
11
  * @subpackage Boldgrid_Backup/admin/partials
12
+ * @copyright BoldGrid
13
+ * @version $Id$
14
+ * @author BoldGrid <support@boldgrid.com>
15
  */
16
 
17
+ defined( 'WPINC' ) || die;
18
 
19
+ $library_dir = \Boldgrid\Library\Library\Configs::get( 'libraryDir' );
20
+ $nav = include BOLDGRID_BACKUP_PATH . '/admin/partials/boldgrid-backup-admin-nav.php';
21
+ $scheduler = include BOLDGRID_BACKUP_PATH . '/admin/partials/settings/scheduler.php';
22
+ $compressor = include BOLDGRID_BACKUP_PATH . '/admin/partials/settings/compressor.php';
23
  $folders_include = include BOLDGRID_BACKUP_PATH . '/admin/partials/settings/folders.php';
24
+ $db = include BOLDGRID_BACKUP_PATH . '/admin/partials/settings/db.php';
25
+ $auto_backup = include BOLDGRID_BACKUP_PATH . '/admin/partials/settings/auto-backup.php';
26
+ $auto_updates = include $library_dir . 'src/Library/Views/Connect/AutoUpdates.php';
27
+ $notifications = include BOLDGRID_BACKUP_PATH . '/admin/partials/settings/notifications.php';
28
+ $connect_key = include BOLDGRID_BACKUP_PATH . '/admin/partials/settings/connect-key.php';
29
+ $site_check = include BOLDGRID_BACKUP_PATH . '/admin/partials/settings/site-check.php';
30
+ $backup_security = include BOLDGRID_BACKUP_PATH . '/admin/partials/settings/backup-security.php';
31
+ $days_of_week = '';
32
+ $time_of_day = '';
33
+ $storage = '';
34
 
 
 
 
35
  if ( $this->core->scheduler->is_available( 'cron' ) || $this->core->scheduler->is_available( 'wp-cron' ) ) {
36
  $days_of_week = include BOLDGRID_BACKUP_PATH . '/admin/partials/settings/days-of-week.php';
37
+ $time_of_day = include BOLDGRID_BACKUP_PATH . '/admin/partials/settings/time-of-day.php';
38
+ $storage = include BOLDGRID_BACKUP_PATH . '/admin/partials/settings/storage.php';
39
  }
40
 
41
+ $sections = [
42
+ 'sections' => [
43
+ [
44
+ 'id' => 'section_schedule',
45
+ 'title' => __( 'Backup Schedule', 'boldgrid-backup' ),
46
+ 'content' => $days_of_week . $time_of_day . $scheduler,
47
+ ],
48
+ [
49
+ 'id' => 'section_storage',
50
+ 'title' => __( 'Backup Storage', 'boldgrid-backup' ),
51
+ 'content' => $storage . $folders_include . $db,
52
+ ],
53
+ [
54
+ 'id' => 'section_security',
55
+ 'title' => __( 'Backup Security', 'boldgrid-backup' ),
56
+ 'content' => $backup_security,
57
+ ],
58
+ [
59
+ 'id' => 'section_process',
60
+ 'title' => __( 'Backup Process', 'boldgrid-backup' ),
61
+ 'content' => $compressor,
62
+ ],
63
+ [
64
+ 'id' => 'connect_key',
65
+ 'title' => __( 'BoldGrid Connect Key', 'boldgrid-backup' ),
66
  'content' => $connect_key,
67
+ ],
68
+ [
69
+ 'id' => 'section_auto_updates',
70
+ 'title' => __( 'Auto Updates', 'boldgrid-backup' ),
71
+ 'content' => $auto_backup . $auto_updates,
72
+ ],
73
+ [
74
+ 'id' => 'section_site_check',
75
+ 'title' => __( 'Site Check', 'boldgrid-backup' ),
76
+ 'content' => $site_check,
77
+ ],
78
+ [
79
+ 'id' => 'section_notifications',
80
+ 'title' => __( 'Notifications', 'boldgrid-backup' ),
81
  'content' => $notifications,
82
+ ],
83
+ ],
84
+ 'post_col_right' => sprintf(
85
+ '
 
 
 
 
86
  <div id="boldgrid-settings-submit-div">
87
  <p>
88
  <input id="boldgrid-settings-submit" class="button button-primary" type="submit" name="submit" value="%1$s" />
90
  </div>',
91
  __( 'Save Changes', 'boldgrid-backup' )
92
  ),
93
+ ];
94
 
95
  /**
96
  * Allow other plugins to modify the sections of the settings page.
97
  *
98
+ * @since 1.6.0
99
  *
100
  * @param array $sections
101
  */
104
  /**
105
  * Render the $sections into displayable markup.
106
  *
107
+ * @since 1.6.0
108
  *
109
  * @param array $sections
110
+ *
111
+ * phpcs:disable WordPress.NamingConventions.ValidHookName
112
  */
113
  $col_container = apply_filters( 'Boldgrid\Library\Ui\render_col_container', $sections );
114
  if ( is_array( $col_container ) ) {
117
 
118
  // Check if settings are available, show an error notice if not.
119
  if ( empty( $settings ) ) {
120
+ add_action(
121
+ 'admin_footer',
122
+ [
123
  $this,
124
  'notice_settings_retrieval',
125
+ ]
126
  );
127
  }
128
 
130
 
131
  ?>
132
  <div class='wrap'>
133
+ <h1><?php echo esc_html( BOLDGRID_BACKUP_TITLE . ' ' . __( 'Backup and Restore Settings', 'boldgrid-backup' ) ); ?></h1>
134
 
135
  <?php
136
+ echo $nav; // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
137
 
138
  /*
139
  * Print this text:
140
  *
141
+ * The BOLDGRID_BACKUP_TITLE and Restore system allows you to upgrade your themes and plugins without
142
  * being afraid it will do something you cannot easily undo. We perform a Preflight Check to see
143
  * if the needed support is available on your web hosting account.
144
  */
145
+ ?>
146
+ <p>
147
+ <?php
148
+ printf(
149
  wp_kses(
150
+ // translators: 1: Plugin title, 2:URL address.
151
+ __(
152
+ 'The %1$s Backup and Restore system allows you to upgrade your themes and plugins without being afraid it will do something you cannot easily undo. We perform a <a href="%2$s">Preflight Check</a> to see if the needed support is available on your web hosting account.',
153
+ 'boldgrid-backup'
154
+ ),
155
+ [ 'a' => [ 'href' => [] ] ]
156
  ),
157
+ esc_html( BOLDGRID_BACKUP_TITLE ),
158
+ esc_url( admin_url( 'admin.php?page=boldgrid-backup-test' ) )
159
  );
160
+
161
+ $show_section = ! empty( $_REQUEST['section'] ) ? sanitize_key( $_REQUEST['section'] ) : ''; // phpcs:ignore WordPress
162
  ?>
163
+ </p>
164
 
165
  <hr />
166
 
167
+ <form id='bgb-settings-form' method='post'>
168
  <?php
169
+ echo $col_container; // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
170
  wp_nonce_field( 'boldgrid-backup-settings', 'settings_auth' );
 
171
  ?>
172
+ <input type="hidden" name="save_time" value="<?php echo esc_attr( time() ); ?>" />
173
  </form>
174
 
175
  </div>
admin/partials/boldgrid-backup-admin-support.php ADDED
@@ -0,0 +1,164 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File: boldgrid-backup-admin-support.php
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.10.1
7
+ *
8
+ * @package Boldgrid_Backup
9
+ * @subpackage Boldgrid_Backup/admin/partials
10
+ * @copyright BoldGrid
11
+ * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
+ *
14
+ * phpcs:disable WordPress.NamingConventions.ValidHookName
15
+ */
16
+
17
+ defined( 'WPINC' ) || die;
18
+
19
+ $allowed_tags = [
20
+ 'a' => [
21
+ 'href' => [],
22
+ 'target' => [],
23
+ ],
24
+ ];
25
+
26
+ $nav = include BOLDGRID_BACKUP_PATH . '/admin/partials/boldgrid-backup-admin-nav.php';
27
+ $reseller = get_option( 'boldgrid_reseller' );
28
+
29
+ if ( ! empty( $reseller ) ) {
30
+ // Is under a reseller.
31
+ $premium_markup = '<ul><li>' . sprintf(
32
+ wp_kses(
33
+ /* translators: 1: Anchored URL address for reseller support, 2: Reseller title/name, 3: HTML anchor close tag. */
34
+ __(
35
+ 'You can receive premium support from your official reseller %1$s%2$s%3$s',
36
+ 'boldgrid-backup'
37
+ ),
38
+ $allowed_tags
39
+ ),
40
+ '<a href="' . esc_url( $reseller['reseller_support_url'] ) . '" target="_blank">',
41
+ $reseller['reseller_title'],
42
+ '</a>'
43
+ ) . '</li>';
44
+
45
+ if ( ! empty( $reseller['reseller_phone'] ) ) {
46
+ $premium_markup .= '<li>' . sprintf(
47
+ wp_kses(
48
+ /* translators: 1: Reseller telephone number */
49
+ __(
50
+ 'Telephone: %1$s',
51
+ 'boldgrid-backup'
52
+ ),
53
+ $allowed_tags
54
+ ),
55
+ $reseller['reseller_phone']
56
+ ) . '</li>';
57
+ }
58
+
59
+ if ( ! empty( $reseller['reseller_email'] ) ) {
60
+ $premium_markup .= '<li>' . sprintf(
61
+ wp_kses(
62
+ /* translators: Reseller email address. */
63
+ __(
64
+ 'Email: %1$s',
65
+ 'boldgrid-backup'
66
+ ),
67
+ $allowed_tags
68
+ ),
69
+ '<a href="mailto:' . esc_attr( $reseller['reseller_email'] ) . '">' . esc_attr( $reseller['reseller_email'] ) . '</a>'
70
+ ) . '</li>';
71
+ }
72
+
73
+ $premium_markup .= '</ul>';
74
+ } elseif ( $this->core->config->is_premium_done ) {
75
+ // Is BoldGrid Premium.
76
+ $premium_markup = '<ul><li>' . sprintf(
77
+ wp_kses(
78
+ /* translators: 1: HTML anchor for the URL address for BoldGrid Central, 2: HTML anchor close tag.. */
79
+ __(
80
+ 'You can receive premium support using %1$sBoldGrid Central%2$s',
81
+ 'boldgrid-backup'
82
+ ),
83
+ $allowed_tags
84
+ ),
85
+ '<a href="https://www.boldgrid.com/central/" target="_blank">',
86
+ '</a>'
87
+ ) . '</li>';
88
+ } else {
89
+ $premium_button = $this->core->go_pro->get_premium_button(
90
+ $this->core->go_pro->get_premium_url( 'bgbkup-support' )
91
+ );
92
+ $premium_markup = '<div class="bgbkup-upgrade-message"><p>' .
93
+ esc_html__( 'Upgrade to receive premium support from BoldGrid', 'boldgrid-backup' ) .
94
+ '</p><p>' . $premium_button . '</p></div>';
95
+ }
96
+
97
+ ?>
98
+
99
+ <div class='wrap'>
100
+ <h1><?php esc_html( BOLDGRID_BACKUP_TITLE . ' ' . __( 'Support', 'boldgrid-backup' ) ); ?></h1>
101
+
102
+ <?php
103
+ echo $nav; // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
104
+ ?>
105
+ <div class="bgbkup-support-page">
106
+ <?php
107
+ printf(
108
+ '<div class="bgbkup-free-support bg-box">
109
+ <div class="bg-box-top">
110
+ %1$s
111
+ </div>
112
+ <div class="bg-box-bottom">
113
+ <ul>
114
+ <li>%2$s</li>
115
+ <li>%3$s</li>
116
+ <li>%4$s</li>
117
+ </ul>
118
+ </div>
119
+ </div>',
120
+ esc_html__( 'Free Support', 'boldgrid-backup' ),
121
+ sprintf(
122
+ wp_kses(
123
+ /* translators: URL address for the WordPress.org boldgrid-backup plugin support forum. */
124
+ __( 'Ask on <a href="%1$s" target="_blank">WordPress.org</a>', 'boldgrid-backup' ),
125
+ $allowed_tags
126
+ ),
127
+ 'https://wordpress.org/support/plugin/boldgrid-backup/'
128
+ ),
129
+ sprintf(
130
+ wp_kses(
131
+ /* translators: URL address for the WordPress.org boldgrid-backup plugin support forum. */
132
+ __( 'Browse our <a href="%1$s" target="_blank">Support Guides</a>', 'boldgrid-backup' ),
133
+ $allowed_tags
134
+ ),
135
+ 'https://www.boldgrid.com/support/boldgrid-backup/'
136
+ ),
137
+ sprintf(
138
+ wp_kses(
139
+ /* translators: URL address for the WordPress.org boldgrid-backup plugin support forum. */
140
+ __( 'Join <a href="%1$s" target="_blank">Team Orange User Group</a> on Facebook', 'boldgrid-backup' ),
141
+ $allowed_tags
142
+ ),
143
+ 'https://www.facebook.com/groups/BGTeamOrange'
144
+ )
145
+ );
146
+
147
+ printf(
148
+ '<div class="bgbkup-premium-support bg-box">
149
+ <div class="bg-box-top">
150
+ %1$s
151
+ </div>
152
+ <div class="bg-box-bottom">
153
+ %2$s
154
+ </div>
155
+ </div>',
156
+ esc_html__( 'Premium Support', 'boldgrid-backup' ),
157
+ $premium_markup // phpcs:ignore WordPress.XSS.EscapeOutput
158
+ );
159
+ ?>
160
+ </div>
161
+ <?php
162
+ echo '<hr />';
163
+ ?>
164
+ </div>
admin/partials/boldgrid-backup-admin-test.php CHANGED
@@ -1,26 +1,33 @@
1
  <?php
2
  /**
3
- * Provide a admin area view for the plugin functionality test report
4
  *
5
- * @link http://www.boldgrid.com
 
 
6
  * @since 1.0
7
  *
8
- * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin/partials
 
 
 
10
  */
11
 
12
- defined( 'WPINC' ) ? : die;
 
 
13
 
14
  // Setup our lang.
15
  $lang = array(
16
- 'yes' => __( 'Yes', 'boldgrid-backup' ),
17
- 'no' => __( 'No', 'boldgrid-backup' ),
18
- 'untested' => __( 'untested', 'boldgrid-backup' ),
19
- 'PASS' => __( 'PASS', 'boldgrid-backup' ),
20
- 'FAIL' => __( 'FAIL', 'boldgrid-backup' ),
21
- 'not_set' => __( 'not set', 'boldgrid-backup' ),
22
  'before_test_compress' => __( 'Before any compressors are tested, please be sure your backup directory is created and has proper permissions set.', 'boldgrid-backup' ),
23
- 'ensure_dir_perms' => __( 'Please be sure that your backup directory exists. If it does, also ensure it has read, write, and modify permissions.', 'boldgrid-backup' ),
24
  );
25
 
26
  $lang['dir_of_dir'] = $lang['ensure_dir_perms'];
@@ -28,18 +35,51 @@ if ( $this->test->is_windows() ) {
28
  $lang['dir_of_dir'] = __( 'Please review directory permissions. If you are on a Windows server, your user may need to be able to read BOTH the backup directory and its parent directory.', 'boldgrid-backup' );
29
  }
30
 
31
- $error_span = '<span class="error">%1$s</span><br />%2$s';
32
  $warning_span = '<span class="warning">%1$s</span><br />%2$s';
33
  $success_span = '<span class="success">%1$s</span>';
34
 
35
  $allowed_tags = array(
36
- 'span' => array(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  'class' => array(
38
- 'error'
39
  ),
 
40
  ),
41
- 'br' => array(),
42
- 'pre' => array(),
43
  );
44
 
45
  $backup_dir_perms = $this->test->extensive_dir_test( $backup_directory );
@@ -48,6 +88,8 @@ $php_zip = new Boldgrid_Backup_Admin_Compressor_Php_Zip( $this );
48
 
49
  $pcl_zip = new Boldgrid_Backup_Admin_Compressor_Pcl_Zip( $this );
50
 
 
 
51
  $valid_backup_dir = $backup_dir_perms['exists'] && $backup_dir_perms['read'] && $backup_dir_perms['write'] && $backup_dir_perms['rename'] && $backup_dir_perms['delete'] && $backup_dir_perms['dirlist'];
52
 
53
  $timezone = $this->time->get_server_timezone();
@@ -57,8 +99,8 @@ $timezone = false === $timezone ? 'UTC' . $this->time->get_server_offset() : $ti
57
  $tests = array(
58
  array(
59
  'id' => 'pass',
60
- 'k' => __( 'Functionality test status:', 'boldgrid-backup' ),
61
- 'v' => ( $this->test->run_functionality_tests() ? sprintf( $success_span, $lang['PASS'] ) : sprintf( $error_span, $lang['FAIL'], '' ) ),
62
  ),
63
  array(
64
  'heading' => __( 'General tests', 'boldgrid-backup' ),
@@ -89,7 +131,15 @@ $tests = array(
89
  ),
90
  array(
91
  'k' => __( 'PHP in safe mode?', 'boldgrid-backup' ),
92
- 'v' => ( $this->test->is_php_safemode() ? sprintf( $error_span, $lang['no'] ) : $lang['yes'] ),
 
 
 
 
 
 
 
 
93
  ),
94
  array(
95
  'k' => __( 'WordPress version:', 'boldgrid-backup' ),
@@ -99,6 +149,10 @@ $tests = array(
99
  'k' => __( 'Server time zone:', 'boldgrid-backup' ),
100
  'v' => $timezone,
101
  ),
 
 
 
 
102
  );
103
 
104
  $tests[] = array(
@@ -219,9 +273,12 @@ $tests[] = array(
219
  'v' => ( $this->config->is_compressor_available( 'system_tar' ) ? 'Yes' : 'No' ),
220
  );
221
 
222
- $tests[] = array(
 
223
  'k' => __( 'System ZIP available?', 'boldgrid-backup' ),
224
- 'v' => ( $this->config->is_compressor_available( 'system_zip' ) ? 'Yes' : 'No' ),
 
 
225
  );
226
 
227
  $tests[] = array(
@@ -235,7 +292,22 @@ $tests[] = array(
235
 
236
  $tests[] = array(
237
  'k' => __( 'PHP allow_url_fopen enabled?', 'boldgrid-backup' ),
238
- 'v' => ( ini_get( 'allow_url_fopen' ) ? $lang['yes'] : sprintf( $error_span, $lang['no'], '' ) ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
239
  );
240
 
241
  $tests[] = array(
@@ -243,6 +315,11 @@ $tests[] = array(
243
  'v' => '<pre>' . implode( '<br /><br />', $our_crons ) . '</pre>',
244
  );
245
 
 
 
 
 
 
246
  $tests[] = array(
247
  'k' => __( 'WP Cron enabled?', 'boldgrid-backup' ),
248
  'v' => ( $this->test->wp_cron_enabled() ? 'Yes' : 'No' ),
@@ -260,7 +337,7 @@ if ( $is_functional ) {
260
  );
261
 
262
  $tests[] = array(
263
- 'k' => __( 'Directory used to calculate disk space:', __( 'boldgrid-backup' ) ),
264
  'v' => $this->home_dir->get_for_disk(),
265
  );
266
 
@@ -326,13 +403,14 @@ if ( $is_functional ) {
326
  if ( $is_functional ) {
327
  $fail_tips = '';
328
  } else {
329
- $fail_tips = sprintf('
 
330
  <p>
331
  %1$s<br />
332
  <a href="%3$s" target="_blank" />%2$s</a>
333
  </p>',
334
- esc_html__( 'BoldGrid Backup is not compatible with your hosting account. For further help please see:', 'boldgrid-backup' ),
335
- esc_html__( 'Making your web hosting account compatible with BoldGrid Backup', 'boldgrid-backup' ),
336
  esc_url( $this->configs['urls']['compatibility'] )
337
  );
338
  }
@@ -343,17 +421,20 @@ foreach ( $tests as $test ) {
343
  if ( ! empty( $test['heading'] ) ) {
344
  $table .= sprintf( '<tr class="heading"><td colspan="2"><h2>%1$s</h2></td></tr>', esc_html( $test['heading'] ) );
345
  } elseif ( isset( $test['id'] ) && 'pass' === $test['id'] ) {
346
- $table .= sprintf('<tr><td>%1$s</td><td><strong>%2$s</strong></td></tr>',
 
347
  esc_html( $test['k'] ),
348
  wp_kses( $test['v'], $allowed_tags )
349
  );
350
  } elseif ( isset( $test['k'] ) ) {
351
- $table .= sprintf('<tr><td>%1$s</td><td><em>%2$s</em></td></tr>',
352
- esc_html( $test['k'] ),
 
353
  wp_kses( $test['v'], $allowed_tags )
354
  );
355
  } else {
356
- $table .= sprintf('<tr><td colspan="2">%1$s</td></tr>',
 
357
  esc_html( $test['v'] )
358
  );
359
  }
@@ -364,14 +445,15 @@ $table .= '</table>';
364
  <div class="functionality-test-section wrap">
365
 
366
  <?php
367
- printf( '<h1>%1$s</h1>', __( 'BoldGrid Backup Preflight Check', 'boldgrid-backup' ) );
368
 
369
  $nav = include BOLDGRID_BACKUP_PATH . '/admin/partials/boldgrid-backup-admin-nav.php';
370
- echo $nav;
 
 
371
 
372
- echo $fail_tips;
373
 
374
- echo $table;
375
  ?>
376
 
377
  </div>
1
  <?php
2
  /**
3
+ * File: boldgrid-backup-admin-test.php
4
  *
5
+ * Provide a admin area view for the plugin functionality test report.
6
+ *
7
+ * @link https://www.boldgrid.com
8
  * @since 1.0
9
  *
10
+ * @package Boldgrid_Backup
11
  * @subpackage Boldgrid_Backup/admin/partials
12
+ * @copyright BoldGrid
13
+ * @version $Id$
14
+ * @author BoldGrid <support@boldgrid.com>
15
  */
16
 
17
+ // phpcs:disable WordPress.VIP
18
+
19
+ defined( 'WPINC' ) || die;
20
 
21
  // Setup our lang.
22
  $lang = array(
23
+ 'yes' => __( 'Yes', 'boldgrid-backup' ),
24
+ 'no' => __( 'No', 'boldgrid-backup' ),
25
+ 'untested' => __( 'untested', 'boldgrid-backup' ),
26
+ 'PASS' => __( 'PASS', 'boldgrid-backup' ),
27
+ 'FAIL' => __( 'FAIL', 'boldgrid-backup' ),
28
+ 'not_set' => __( 'not set', 'boldgrid-backup' ),
29
  'before_test_compress' => __( 'Before any compressors are tested, please be sure your backup directory is created and has proper permissions set.', 'boldgrid-backup' ),
30
+ 'ensure_dir_perms' => __( 'Please be sure that your backup directory exists. If it does, also ensure it has read, write, and modify permissions.', 'boldgrid-backup' ),
31
  );
32
 
33
  $lang['dir_of_dir'] = $lang['ensure_dir_perms'];
35
  $lang['dir_of_dir'] = __( 'Please review directory permissions. If you are on a Windows server, your user may need to be able to read BOTH the backup directory and its parent directory.', 'boldgrid-backup' );
36
  }
37
 
38
+ $error_span = '<span class="error">%1$s</span><br />%2$s';
39
  $warning_span = '<span class="warning">%1$s</span><br />%2$s';
40
  $success_span = '<span class="success">%1$s</span>';
41
 
42
  $allowed_tags = array(
43
+ 'span' => array(
44
+ 'class' => array(
45
+ 'error',
46
+ 'dashicons',
47
+ 'dashicons-editor-help',
48
+ 'spinner',
49
+ 'inline',
50
+ ),
51
+ 'data-id' => array(
52
+ 'cron-time-zone',
53
+ ),
54
+ ),
55
+ 'br' => array(),
56
+ 'p' => array(
57
+ 'class' => array(
58
+ 'help',
59
+ ),
60
+ 'data-id' => array(
61
+ 'cron-time-zone',
62
+ ),
63
+ ),
64
+ 'pre' => array(),
65
+ 'form' => array(
66
+ 'method' => array(),
67
+ 'action' => array(
68
+ 'admin.php?page=boldgrid-backup-test',
69
+ ),
70
+ ),
71
+ 'input' => array(
72
+ 'type' => array(),
73
+ 'name' => array(
74
+ 'cron_timezone_test',
75
+ ),
76
+ 'value' => array(),
77
  'class' => array(
78
+ 'button',
79
  ),
80
+ 'style' => array(),
81
  ),
82
+ 'strong' => array(),
 
83
  );
84
 
85
  $backup_dir_perms = $this->test->extensive_dir_test( $backup_directory );
88
 
89
  $pcl_zip = new Boldgrid_Backup_Admin_Compressor_Pcl_Zip( $this );
90
 
91
+ $filesystem_method = get_filesystem_method();
92
+
93
  $valid_backup_dir = $backup_dir_perms['exists'] && $backup_dir_perms['read'] && $backup_dir_perms['write'] && $backup_dir_perms['rename'] && $backup_dir_perms['delete'] && $backup_dir_perms['dirlist'];
94
 
95
  $timezone = $this->time->get_server_timezone();
99
  $tests = array(
100
  array(
101
  'id' => 'pass',
102
+ 'k' => __( 'Functionality test status:', 'boldgrid-backup' ),
103
+ 'v' => ( $this->test->run_functionality_tests() ? sprintf( $success_span, $lang['PASS'] ) : sprintf( $error_span, $lang['FAIL'], '' ) ),
104
  ),
105
  array(
106
  'heading' => __( 'General tests', 'boldgrid-backup' ),
131
  ),
132
  array(
133
  'k' => __( 'PHP in safe mode?', 'boldgrid-backup' ),
134
+ 'v' => $this->test->is_php_safemode() ? sprintf( $error_span, $lang['yes'], '' ) : $lang['no'],
135
+ ),
136
+ array(
137
+ 'k' => __( 'Filesystem Method', 'boldgrid-backup' ),
138
+ 'v' => $this->test->is_filesystem_supported() ?
139
+ $filesystem_method : sprintf(
140
+ $error_span,
141
+ $filesystem_method, __( 'Only "direct" filesystem supported.', 'boldgrid-backup' )
142
+ ),
143
  ),
144
  array(
145
  'k' => __( 'WordPress version:', 'boldgrid-backup' ),
149
  'k' => __( 'Server time zone:', 'boldgrid-backup' ),
150
  'v' => $timezone,
151
  ),
152
+ array(
153
+ 'k' => __( 'Server date:', 'boldgrid-backup' ),
154
+ 'v' => $this->time->get_server_date(),
155
+ ),
156
  );
157
 
158
  $tests[] = array(
273
  'v' => ( $this->config->is_compressor_available( 'system_tar' ) ? 'Yes' : 'No' ),
274
  );
275
 
276
+ $system_zip_test = new Boldgrid_Backup_Admin_Compressor_System_Zip_Test( $this );
277
+ $tests[] = array(
278
  'k' => __( 'System ZIP available?', 'boldgrid-backup' ),
279
+ 'v' => $system_zip_test->run() ?
280
+ 'Yes' :
281
+ sprintf( $warning_span, $lang['no'], $system_zip_test->get_error() ),
282
  );
283
 
284
  $tests[] = array(
292
 
293
  $tests[] = array(
294
  'k' => __( 'PHP allow_url_fopen enabled?', 'boldgrid-backup' ),
295
+ 'v' => true === $cli_support['has_url_fopen'] ? $lang['yes'] : sprintf( $warning_span, $lang['no'], '' ),
296
+ );
297
+
298
+ $tests[] = array(
299
+ 'k' => __( 'Curl SSL enabled?', 'boldgrid-backup' ),
300
+ 'v' => true === $cli_support['has_curl_ssl'] ? $lang['yes'] : sprintf( $warning_span, $lang['no'], '' ),
301
+ );
302
+
303
+ $tests[] = array(
304
+ 'k' => __( 'Can fetch a remote url via CLI?', 'boldgrid-backup' ),
305
+ 'v' => true === $cli_support['can_remote_get'] ? $lang['yes'] : sprintf( $error_span, $lang['no'], '' ),
306
+ );
307
+
308
+ $tests[] = array(
309
+ 'k' => __( 'Cron time zone matches server time zone? <span class="dashicons dashicons-editor-help" data-id="cron-time-zone"></span>', 'boldgrid-backup' ),
310
+ 'v' => $this->cron_test->get_preflight_markup(),
311
  );
312
 
313
  $tests[] = array(
315
  'v' => '<pre>' . implode( '<br /><br />', $our_crons ) . '</pre>',
316
  );
317
 
318
+ $tests[] = array(
319
+ 'k' => __( 'Method used to read cron:', 'boldgrid-backup' ),
320
+ 'v' => $this->backup_dir->can_exec_write() ? __( 'Crontab output to file.', 'boldgrid-backup' ) : __( 'Crontab read via exec function.', 'boldgrid-backup' ),
321
+ );
322
+
323
  $tests[] = array(
324
  'k' => __( 'WP Cron enabled?', 'boldgrid-backup' ),
325
  'v' => ( $this->test->wp_cron_enabled() ? 'Yes' : 'No' ),
337
  );
338
 
339
  $tests[] = array(
340
+ 'k' => __( 'Directory used to calculate disk space:', 'boldgrid-backup' ),
341
  'v' => $this->home_dir->get_for_disk(),
342
  );
343
 
403
  if ( $is_functional ) {
404
  $fail_tips = '';
405
  } else {
406
+ $fail_tips = sprintf(
407
+ '
408
  <p>
409
  %1$s<br />
410
  <a href="%3$s" target="_blank" />%2$s</a>
411
  </p>',
412
+ esc_html( BOLDGRID_BACKUP_TITLE . ' ' . __( 'is not compatible with your hosting account. For further help please see:', 'boldgrid-backup' ) ),
413
+ esc_html( __( 'Making your web hosting account compatible with', 'boldgrid-backup' ) . ' ' . BOLDGRID_BACKUP_TITLE ),
414
  esc_url( $this->configs['urls']['compatibility'] )
415
  );
416
  }
421
  if ( ! empty( $test['heading'] ) ) {
422
  $table .= sprintf( '<tr class="heading"><td colspan="2"><h2>%1$s</h2></td></tr>', esc_html( $test['heading'] ) );
423
  } elseif ( isset( $test['id'] ) && 'pass' === $test['id'] ) {
424
+ $table .= sprintf(
425
+ '<tr><td>%1$s</td><td><strong>%2$s</strong></td></tr>',
426
  esc_html( $test['k'] ),
427
  wp_kses( $test['v'], $allowed_tags )
428
  );
429
  } elseif ( isset( $test['k'] ) ) {
430
+ $table .= sprintf(
431
+ '<tr><td>%1$s</td><td><em>%2$s</em></td></tr>',
432
+ wp_kses( $test['k'], $allowed_tags ),
433
  wp_kses( $test['v'], $allowed_tags )
434
  );
435
  } else {
436
+ $table .= sprintf(
437
+ '<tr><td colspan="2">%1$s</td></tr>',
438
  esc_html( $test['v'] )
439
  );
440
  }
445
  <div class="functionality-test-section wrap">
446
 
447
  <?php
448
+ printf( '<h1>%1$s</h1>', esc_html( BOLDGRID_BACKUP_TITLE . ' ' . __( 'Preflight Check', 'boldgrid-backup' ) ) );
449
 
450
  $nav = include BOLDGRID_BACKUP_PATH . '/admin/partials/boldgrid-backup-admin-nav.php';
451
+ echo $nav; // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
452
+
453
+ echo $fail_tips; // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
454
 
455
+ echo $table; // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
456
 
 
457
  ?>
458
 
459
  </div>
admin/partials/boldgrid-backup-admin-tools.php CHANGED
@@ -1,32 +1,45 @@
1
  <?php
2
  /**
3
- * Tools.
4
  *
5
- * @link http://www.boldgrid.com
6
- * @since 1.5.4
7
  *
8
- * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin/partials
 
 
 
10
  */
11
 
12
- defined( 'WPINC' ) ? : die;
13
 
14
  $nav = include BOLDGRID_BACKUP_PATH . '/admin/partials/boldgrid-backup-admin-nav.php';
15
 
16
  $sections = array(
17
  'sections' => array(
18
  array(
19
- 'id' => 'section_locations',
20
- 'title' => __( 'Local & Remote', 'boldgrid-backup' ),
21
  'content' => include BOLDGRID_BACKUP_PATH . '/admin/partials/tools/local-remote.php',
22
  ),
 
 
 
 
 
 
 
 
 
 
23
  ),
24
  );
25
 
26
  /**
27
  * Allow other plugins to modify the sections of the tools page.
28
  *
29
- * @since 1.5.4
30
  *
31
  * @param array $sections
32
  */
@@ -35,19 +48,20 @@ $sections = apply_filters( 'boldgrid_backup_tools_sections', $sections );
35
  /**
36
  * Render the $sections into displayable markup.
37
  *
38
- * @since 1.5.4
39
  *
40
  * @param array $sections
 
 
41
  */
42
  $col_container = apply_filters( 'Boldgrid\Library\Ui\render_col_container', $sections );
43
 
44
  ?>
45
 
46
  <div class='wrap'>
47
- <h1><?php esc_html_e( 'BoldGrid Backup and Restore Settings', 'boldgrid-backup' ); ?></h1>
48
 
49
  <?php
50
- echo $nav;
51
- echo $col_container;
52
  ?>
53
  </div>
1
  <?php
2
  /**
3
+ * File: boldgrid-backup-admin-tools.php
4
  *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.6.0
7
  *
8
+ * @package Boldgrid_Backup
9
  * @subpackage Boldgrid_Backup/admin/partials
10
+ * @copyright BoldGrid
11
+ * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
  */
14
 
15
+ defined( 'WPINC' ) || die;
16
 
17
  $nav = include BOLDGRID_BACKUP_PATH . '/admin/partials/boldgrid-backup-admin-nav.php';
18
 
19
  $sections = array(
20
  'sections' => array(
21
  array(
22
+ 'id' => 'section_locations',
23
+ 'title' => __( 'Local & Remote', 'boldgrid-backup' ),
24
  'content' => include BOLDGRID_BACKUP_PATH . '/admin/partials/tools/local-remote.php',
25
  ),
26
+ array(
27
+ 'id' => 'section_cron_log',
28
+ 'title' => __( 'Cron Log', 'boldgrid-backup' ),
29
+ 'content' => $this->core->cron_log->get_markup(),
30
+ ),
31
+ array(
32
+ 'id' => 'section_logs',
33
+ 'title' => __( 'Logs', 'boldgrid-backup' ),
34
+ 'content' => include BOLDGRID_BACKUP_PATH . '/admin/partials/tools/view-logs.php',
35
+ ),
36
  ),
37
  );
38
 
39
  /**
40
  * Allow other plugins to modify the sections of the tools page.
41
  *
42
+ * @since 1.6.0
43
  *
44
  * @param array $sections
45
  */
48
  /**
49
  * Render the $sections into displayable markup.
50
  *
51
+ * @since 1.6.0
52
  *
53
  * @param array $sections
54
+ *
55
+ * phpcs:disable WordPress.NamingConventions.ValidHookName
56
  */
57
  $col_container = apply_filters( 'Boldgrid\Library\Ui\render_col_container', $sections );
58
 
59
  ?>
60
 
61
  <div class='wrap'>
62
+ <h1><?php echo esc_html( BOLDGRID_BACKUP_TITLE . ' ' . __( 'Tools', 'boldgrid-backup' ) ); ?></h1>
63
 
64
  <?php
65
+ echo $nav . $col_container; // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
 
66
  ?>
67
  </div>
admin/partials/boldgrid-backup-admin-transfers.php ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File: boldgrid-backup-admin-transfers.php
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.11.0
7
+ *
8
+ * @package Boldgrid_Backup
9
+ * @subpackage Boldgrid_Backup/admin/partials
10
+ * @copyright BoldGrid
11
+ * @author BoldGrid <support@boldgrid.com>
12
+ */
13
+
14
+ defined( 'WPINC' ) || die;
15
+
16
+ $is_premium = $this->core->config->get_is_premium();
17
+ $is_premium_installed = $this->core->config->is_premium_installed;
18
+ $is_premium_active = $this->core->config->is_premium_active;
19
+
20
+ $nav = include BOLDGRID_BACKUP_PATH . '/admin/partials/boldgrid-backup-admin-nav.php';
21
+ $overview = include BOLDGRID_BACKUP_PATH . '/admin/partials/transfers/overview.php';
22
+ $source = include BOLDGRID_BACKUP_PATH . '/admin/partials/transfers/source.php';
23
+ $destination = include BOLDGRID_BACKUP_PATH . '/admin/partials/transfers/destination.php';
24
+
25
+ $this->core->archive_actions->enqueue_scripts();
26
+ $this->core->auto_rollback->enqueue_home_scripts();
27
+
28
+ $sections = [
29
+ 'sections' => [
30
+ [
31
+ 'id' => 'section_transfers',
32
+ 'title' => __( 'Overview', 'boldgrid-backup' ),
33
+ 'content' => $overview,
34
+ ],
35
+ [
36
+ 'id' => 'section_source',
37
+ 'title' => __( 'Source', 'boldgrid-backup' ),
38
+ 'content' => $source,
39
+ ],
40
+ [
41
+ 'id' => 'section_destination',
42
+ 'title' => __( 'Destination', 'boldgrid-backup' ),
43
+ 'content' => $destination,
44
+ ],
45
+ ],
46
+ ];
47
+
48
+ /**
49
+ * Allow other plugins to modify the sections of the transfers page.
50
+ *
51
+ * @since 1.6.0
52
+ *
53
+ * @param array $sections Sections.
54
+ */
55
+ $sections = apply_filters( 'boldgrid_backup_transfers_sections', $sections );
56
+
57
+ /**
58
+ * Render the $sections into displayable markup.
59
+ *
60
+ * @since 1.6.0
61
+ *
62
+ * @param array $sections Sections.
63
+ *
64
+ * phpcs:disable WordPress.NamingConventions.ValidHookName
65
+ */
66
+ $col_container = apply_filters( 'Boldgrid\Library\Ui\render_col_container', $sections );
67
+ ?>
68
+
69
+ <div class='wrap'>
70
+ <h1><?php echo esc_html( BOLDGRID_BACKUP_TITLE . ' ' . __( 'Transfers', 'boldgrid-backup' ) ); ?></h1>
71
+ <div class="bgbkup-transfers-page">
72
+ <?php echo $nav . $col_container; // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped ?>
73
+ </div>
74
+ </div>
admin/partials/remote/ftp.php CHANGED
@@ -1,88 +1,119 @@
1
  <?php
2
  /**
3
- * BoldGrid Backup - FTP Settings page.
4
  *
5
- * The file handles the rendering of the settings page.
 
 
 
 
 
 
 
 
 
 
 
 
6
  */
7
 
8
- $selected = 'selected="selected"';
9
- $ftp_selected = 'ftp' === $data['type'] ? $selected : '';
10
- $sftp_selected = 'sftp' === $data['type'] ? $selected : '';
 
11
 
 
 
 
 
12
  ?>
13
-
14
  <form method="post">
15
-
16
- <h1><?php echo __( 'BoldGrid Backup - FTP Settings', 'boldgrid-backup' )?></h1>
17
-
18
  <hr />
19
-
20
  <table class="widefat fixed striped">
21
  <tr>
22
  <td>
23
  <?php
24
- printf( '
 
25
  <label for="host">%1$s</label>
26
  <input type="text" name="host" value="%2$s" minlength="5" title="%3$s" required />
27
  ',
28
- __( 'FTP Host', 'boldgrid-backup' ),
29
- $data['host'],
30
- __( 'FTP host should be in the format of: example.com', 'boldgrid-backup' )
31
  );
32
- ?>
 
 
 
 
33
  </td>
34
- <td></td>
35
  </tr>
36
  <tr>
37
  <td>
38
- <?php echo __( 'FTP / SFTP', 'boldgrid-backup' ); ?><br />
39
  <select name="type">
40
- <option value='ftp' <?php echo esc_attr( $ftp_selected ); ?> >FTP</option>
41
- <option value='sftp' <?php echo esc_attr( $sftp_selected ); ?> >SFTP</option>
 
42
  </select>
43
  </td>
44
  <td>
45
- <?php echo __( 'FTP Port', 'boldgrid-backup' ); ?><br />
46
- <input type="number" name="port" value="<?php echo $data['port']; ?>" min="1" required />
 
 
 
 
47
  </td>
48
  </tr>
49
  <tr>
50
  <td>
51
- <?php echo __( 'FTP Username', 'boldgrid-backup' ); ?><br />
52
- <input type="text" name="user" value="<?php echo $data['user']; ?>" required />
53
  </td>
54
  <td>
55
- <?php echo __( 'FTP Password', 'boldgrid-backup' ); ?><br />
56
- <input type="password" name="pass" value="<?php echo $data['pass']; ?>" required />
 
 
 
 
 
 
 
57
  </td>
58
  </tr>
59
  <tr>
60
  <td>
61
- <?php echo __( 'Retention (Number of backup archives to retain)', 'boldgrid-backup' ) ?><br />
62
- <input type="number" name="retention_count" value="<?php echo $data['retention_count']; ?>" min="1" required/>
63
  </td>
64
  <td></td>
65
  </tr>
66
  <tr>
67
  <td>
68
- <?php echo __( 'Nickname (If you would like to refer to this account as something other than FTP)', 'boldgrid-backup' ) ?><br />
69
  <input type="text" name="nickname" value="<?php echo esc_attr( $data['nickname'] ); ?>" />
70
  </td>
71
  <td></td>
72
  </tr>
73
  </table>
74
-
75
  <p>
76
  <?php
77
- echo $this->core->lang['icon_warning'] . __( 'With automated FTP your credentials must be stored here in your WordPress. They will be encrypted in the database and this protects them significantly, but they could be decrypted in the unlikely event of a compromise. We recommended you use a separate FTP user and password specifically for backups.', 'boldgrid-backup' );
 
 
 
 
78
  ?>
79
  </p>
80
-
81
  <p>
82
  <input type="hidden" name="action" value="save" />
83
- <input class="button button-primary" type="submit" value="<?php echo __( 'Save changes', 'boldgrid-backup' ); ?>" />
84
- <button class="button button-secondary"><?php echo __( 'Delete settings', 'boldgrid-backup' ); ?></button>
85
  <span class="spinner inline middle hidden"></span>
86
  </p>
87
-
88
  </form>
1
  <?php
2
  /**
3
+ * File: ftp.php
4
  *
5
+ * This file handles the rendering of the remote FTP/SFTP options on the settings page.
6
+ *
7
+ * The $data array on this page used to fill in the form fields is generated in
8
+ * Boldgrid_Backup_Admin_Ftp_Page->settings().
9
+ *
10
+ * @link https://www.boldgrid.com
11
+ * @since 1.6.0
12
+ *
13
+ * @package Boldgrid_Backup
14
+ * @subpackage Boldgrid_Backup/admin/partials/remote
15
+ * @copyright BoldGrid
16
+ * @version $Id$
17
+ * @author BoldGrid <support@boldgrid.com>
18
  */
19
 
20
+ $selected = 'selected="selected"';
21
+ $ftp_selected = 'ftp' === $data['type'] ? $selected : '';
22
+ $ftpes_selected = 'ftpes' === $data['type'] ? $selected : '';
23
+ $sftp_selected = 'sftp' === $data['type'] ? $selected : '';
24
 
25
+ // FTP mode options.
26
+ $active_selected = 'active' === $data['ftp_mode'] ? $selected : '';
27
+ $passive_selected = 'passive' === $data['ftp_mode'] ? $selected : '';
28
+ $auto_selected = empty( $active_selected ) && empty( $passive_selected ) ? $selected : '';
29
  ?>
 
30
  <form method="post">
31
+ <?php wp_nonce_field( 'bgb-settings-ftp', 'ftp_auth' ); ?>
32
+ <h1><?php echo esc_html( BOLDGRID_BACKUP_TITLE . ' - ' . __( 'FTP Settings', 'boldgrid-backup' ) ); ?></h1>
 
33
  <hr />
 
34
  <table class="widefat fixed striped">
35
  <tr>
36
  <td>
37
  <?php
38
+ printf(
39
+ '
40
  <label for="host">%1$s</label>
41
  <input type="text" name="host" value="%2$s" minlength="5" title="%3$s" required />
42
  ',
43
+ esc_html__( 'FTP Host', 'boldgrid-backup' ),
44
+ esc_attr( $data['host'] ),
45
+ esc_attr__( 'FTP host should be in the format of: example.com', 'boldgrid-backup' )
46
  );
47
+ ?>
48
+ </td>
49
+ <td>
50
+ <?php esc_html_e( 'FTP Port', 'boldgrid-backup' ); ?><br />
51
+ <input type="number" name="port" value="<?php echo esc_attr( $data['port'] ); ?>" min="1" required />
52
  </td>
 
53
  </tr>
54
  <tr>
55
  <td>
56
+ <?php esc_html_e( 'FTP Type', 'boldgrid-backup' ); ?><br />
57
  <select name="type">
58
+ <option value='ftp' <?php echo esc_attr( $ftp_selected ); ?>>FTP</option>
59
+ <option value='ftpes' <?php echo esc_attr( $ftpes_selected ); ?>>FTPES</option>
60
+ <option value='sftp' <?php echo esc_attr( $sftp_selected ); ?>>SFTP</option>
61
  </select>
62
  </td>
63
  <td>
64
+ <?php esc_html_e( 'FTP Mode', 'boldgrid-backup' ); ?><br />
65
+ <select name="ftp_mode">
66
+ <option value='auto' <?php echo esc_attr( $auto_selected ); ?>><?php esc_html_e( 'Auto', 'boldgrid-backup' ); ?></option>
67
+ <option value='active' <?php echo esc_attr( $active_selected ); ?>><?php esc_html_e( 'Active', 'boldgrid-backup' ); ?></option>
68
+ <option value='passive' <?php echo esc_attr( $passive_selected ); ?>><?php esc_html_e( 'Passive', 'boldgrid-backup' ); ?></option>
69
+ </select>
70
  </td>
71
  </tr>
72
  <tr>
73
  <td>
74
+ <?php esc_html_e( 'FTP Username', 'boldgrid-backup' ); ?><br />
75
+ <input type="text" name="user" value="<?php echo esc_attr( $data['user'] ); ?>" required />
76
  </td>
77
  <td>
78
+ <?php esc_html_e( 'FTP Password', 'boldgrid-backup' ); ?><br />
79
+ <input type="password" name="pass" value="<?php echo esc_attr( $data['pass'] ); ?>" required />
80
+ </td>
81
+ </tr>
82
+ <tr>
83
+ <td colspan="2">
84
+ <?php esc_html_e( 'Folder name', 'boldgrid-backup' ); ?><br />
85
+ <?php esc_html_e( 'A folder in your FTP/SFTP server to store your backups, will be created if it doesn\'t exist. Please only use letters, numbers, dashes, and underscores.', 'boldgrid-backup' ); ?><br />
86
+ <input type="text" name="folder_name" value="<?php echo esc_attr( $data['folder_name'] ); ?>" min="1" required pattern="[A-Za-z0-9-_]+">
87
  </td>
88
  </tr>
89
  <tr>
90
  <td>
91
+ <?php esc_html_e( 'Retention (Number of backup archives to retain)', 'boldgrid-backup' ); ?><br />
92
+ <input type="number" name="retention_count" value="<?php echo esc_attr( $data['retention_count'] ); ?>" min="1" required/>
93
  </td>
94
  <td></td>
95
  </tr>
96
  <tr>
97
  <td>
98
+ <?php esc_html_e( 'Nickname (If you would like to refer to this account as something other than FTP)', 'boldgrid-backup' ); ?><br />
99
  <input type="text" name="nickname" value="<?php echo esc_attr( $data['nickname'] ); ?>" />
100
  </td>
101
  <td></td>
102
  </tr>
103
  </table>
 
104
  <p>
105
  <?php
106
+ echo $this->core->lang['icon_warning']; // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
107
+ esc_html_e(
108
+ 'With automated FTP your credentials must be stored here in your WordPress. They will be encrypted in the database and this protects them significantly, but they could be decrypted in the unlikely event of a compromise. We recommended you use a separate FTP user and password specifically for backups.',
109
+ 'boldgrid-backup'
110
+ );
111
  ?>
112
  </p>
 
113
  <p>
114
  <input type="hidden" name="action" value="save" />
115
+ <input class="button button-primary" type="submit" value="<?php esc_attr_e( 'Save changes', 'boldgrid-backup' ); ?>" />
116
+ <button class="button button-secondary"><?php esc_html_e( 'Delete settings', 'boldgrid-backup' ); ?></button>
117
  <span class="spinner inline middle hidden"></span>
118
  </p>
 
119
  </form>
admin/partials/remote/local.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File: local.php
4
+ *
5
+ * The file handles the rendering of the local web server options on the settings page.
6
+ *
7
+ * @link https://www.boldgrid.com
8
+ * @since 1.7.0
9
+ *
10
+ * @package Boldgrid_Backup
11
+ * @subpackage Boldgrid_Backup/admin/partials/remote
12
+ * @copyright BoldGrid
13
+ * @version $Id$
14
+ * @author BoldGrid <support@boldgrid.com>
15
+ *
16
+ * phpcs:disable WordPress.XSS.EscapeOutput
17
+ */
18
+
19
+ ?>
20
+
21
+ <form method="post">
22
+ <?php
23
+ wp_nonce_field( 'bgb-settings-webserver', 'webserver_auth' );
24
+
25
+ echo require BOLDGRID_BACKUP_PATH . '/admin/partials/settings/backup-directory.php';
26
+ echo require BOLDGRID_BACKUP_PATH . '/admin/partials/settings/retention.php';
27
+ ?>
28
+ <p>
29
+ <input type="hidden" name="action" value="save" />
30
+ <input class="button button-primary" type="submit" value="<?php esc_attr_e( 'Save changes', 'boldgrid-backup' ); ?>" />
31
+ <span class="spinner inline middle hidden"></span>
32
+ </p>
33
+ </form>
admin/partials/settings/auto-backup.php ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File: auto-backup.php
4
+ *
5
+ * Show "Auto Rollback" on settings page.
6
+ *
7
+ * @since 1.7.0
8
+ * @package Boldgrid_Backup
9
+ * @subpackage Boldgrid_Backup/admin/partials/settings
10
+ * @copyright BoldGrid
11
+ * @version $Id$
12
+ * @link https://www.boldgrid.com
13
+ * @author BoldGrid <support@boldgrid.com>
14
+ */
15
+
16
+ defined( 'WPINC' ) || die;
17
+
18
+ ob_start();
19
+ ?>
20
+ <div class="bg-box">
21
+ <div class="bg-box-top">
22
+ <?php esc_html_e( 'Automation', 'boldgrid-backup' ); ?>
23
+ <span class='dashicons dashicons-editor-help' data-id='automation'></span>
24
+ </div>
25
+ <div class="bg-box-bottom">
26
+ <p class='help' data-id='automation'>
27
+ <?php
28
+ printf(
29
+ // translators: 1: HTML anchor open tag, 2: HTML anchor close tag.
30
+ esc_html__(
31
+ 'Auto Backup Before Update: Automatically perform a backup before WordPress updates. When this feature is enabled, a full backup will be made during the %1$spre_auto_update action%2$s.',
32
+ 'boldgrid-backup'
33
+ ),
34
+ '<a target="_blank" href="https://developer.wordpress.org/reference/hooks/pre_auto_update/">',
35
+ '</a>'
36
+ );
37
+ ?>
38
+ </p>
39
+ <p class='help' data-id='automation'>
40
+ <?php
41
+ esc_html_e(
42
+ 'Auto Rollback: If something goes wrong while performing WordPress updates, automatically restore the site using a backup made before updating WordPress. This feature does not apply to auto updates.',
43
+ 'boldgrid-backup'
44
+ );
45
+ ?>
46
+ </p>
47
+ <table class="form-table">
48
+ <tr>
49
+ <th>
50
+ <?php esc_html_e( 'Auto Backup Before Update', 'boldgrid-backup' ); ?>
51
+ </th>
52
+ <td>
53
+ <input id='auto-backup-enabled' type='radio' name='auto_backup' value='1'
54
+ <?php
55
+ if ( ! isset( $settings['auto_backup'] ) ||
56
+ 1 === $settings['auto_backup'] ) {
57
+ echo ' checked';
58
+ }
59
+ ?>
60
+ /> <?php esc_html_e( 'Enabled (Recommended)', 'boldgrid-backup' ); ?> &nbsp; <input
61
+ id='auto-backup-disabled' type='radio' name='auto_backup' value='0'
62
+ <?php
63
+ if ( isset( $settings['auto_backup'] ) && 0 === $settings['auto_backup'] ) {
64
+ echo ' checked';
65
+ }
66
+ ?>
67
+ /> <?php esc_html_e( 'Disabled', 'boldgrid-backup' ); ?>
68
+ </td>
69
+ </tr>
70
+ <tr>
71
+ <th><?php esc_html_e( 'Auto Rollback', 'boldgrid-backup' ); ?></th>
72
+ <td>
73
+ <input id='auto-rollback-enabled' type='radio' name='auto_rollback' value='1'
74
+ <?php
75
+ if ( ! isset( $settings['auto_rollback'] ) ||
76
+ 1 === $settings['auto_rollback'] ) {
77
+ echo ' checked';
78
+ }
79
+ ?>
80
+ /> <?php esc_html_e( 'Enabled', 'boldgrid-backup' ); ?> &nbsp; <input
81
+ id='auto-rollback-disabled' type='radio' name='auto_rollback'
82
+ value='0'
83
+ <?php
84
+ if ( isset( $settings['auto_rollback'] ) && 0 === $settings['auto_rollback'] ) {
85
+ echo ' checked';
86
+ }
87
+ ?>
88
+ /> <?php esc_html_e( 'Disabled', 'boldgrid-backup' ); ?>
89
+ </td>
90
+ </tr>
91
+ </table>
92
+ </div>
93
+ </div>
94
+ <?php
95
+ $output = ob_get_contents();
96
+ ob_end_clean();
97
+
98
+ return $output;
admin/partials/settings/auto-updates.php DELETED
@@ -1,155 +0,0 @@
1
- <?php
2
- /**
3
- * Show "Auto Updates" on settings page.
4
- *
5
- * @since 1.5.4
6
- */
7
-
8
- defined( 'WPINC' ) ? : die;
9
-
10
- ob_start();
11
- ?>
12
-
13
- <div class="bg-box">
14
- <div class="bg-box-top">
15
- <?php echo __( 'Auto Updates and Rollback', 'boldgrid-inspirations' ); ?>
16
- </div>
17
- <div class="bg-box-bottom">
18
-
19
- <table class="form-table">
20
- <tr>
21
- <th>
22
- <?php esc_html_e( 'Plugin Auto-Updates', 'boldgrid-backup' ); ?>
23
- <span class="dashicons dashicons-editor-help" data-id="plugin-autoupdate"></span>
24
-
25
- <p class="help" data-id="plugin-autoupdate">
26
- <?php
27
- printf(
28
- __( 'Automatically perform all plugin updates when available. Enabling this feature adds the <a target="_blank" href="%1$s">auto_update_plugin filter</a>, which enables automatic plugin updates when an update is available.', 'boldgrid-backup' ),
29
- 'https://codex.wordpress.org/Configuring_Automatic_Background_Updates#Plugin_.26_Theme_Updates_via_Filter'
30
- );
31
- ?>
32
- </p>
33
- </th>
34
- <td>
35
- <input id="plugin-autoupdate-enabled" type="radio" name="plugin_autoupdate" value="1"
36
- <?php
37
- if ( isset( $settings['plugin_autoupdate'] ) &&
38
- 1 === $settings['plugin_autoupdate'] ) {
39
- ?> checked<?php
40
- }
41
- ?> /> <?php esc_html_e( 'Enabled', 'boldgrid-backup' ); ?> &nbsp; <input
42
- id="plugin-autoupdate-disabled" type="radio" name="plugin_autoupdate" value="0"
43
- <?php
44
- if ( ! isset( $settings['plugin_autoupdate'] ) ||
45
- ! $settings['plugin_autoupdate'] ) {
46
- ?> checked<?php
47
- }
48
- ?> /> <?php esc_html_e( 'Disabled', 'boldgrid-backup' ); ?>
49
- </td>
50
- </tr>
51
-
52
- <tr>
53
- <th>
54
- <?php esc_html_e( 'Theme Auto-Updates', 'boldgrid-backup' ); ?>
55
- <span class="dashicons dashicons-editor-help" data-id="theme-autoupdate"></span>
56
-
57
- <p class="help" data-id="theme-autoupdate">
58
- <?php
59
- printf(
60
- __( 'Automatically perform all theme updates when available. Enabling this feature adds the <a target="_blank" href="%1$s">auto_update_theme filter</a>, which enables automatic theme updates when an update is available.', 'boldgrid-backup' ),
61
- 'https://codex.wordpress.org/Configuring_Automatic_Background_Updates#Plugin_.26_Theme_Updates_via_Filter'
62
- );
63
- ?>
64
- <p>
65
- </th>
66
- <td>
67
- <input id="theme-autoupdate-enabled" type="radio" name="theme_autoupdate" value="1"
68
- <?php
69
- if ( isset( $settings['theme_autoupdate'] ) &&
70
- 1 === $settings['theme_autoupdate'] ) {
71
- ?> checked<?php
72
- }
73
- ?> /> <?php esc_html_e( 'Enabled', 'boldgrid-backup' ); ?> &nbsp; <input
74
- id="theme-autoupdate-disabled" type="radio" name="theme_autoupdate" value="0"
75
- <?php
76
- if ( ! isset( $settings['theme_autoupdate'] ) ||
77
- ! $settings['theme_autoupdate'] ) {
78
- ?> checked<?php
79
- }
80
- ?> /> <?php esc_html_e( 'Disabled', 'boldgrid-backup' ); ?>
81
- </td>
82
- </tr>
83
-
84
- <tr>
85
- <th>
86
- <?php echo __( 'Auto Backup<br />Before Updates', 'boldgrid-backup' ); ?>
87
- <span class='dashicons dashicons-editor-help' data-id='auto-backup'></span>
88
-
89
- <p class='help' data-id='auto-backup'>
90
- <?php
91
- printf(
92
- __( 'Automatically perform a backup before WordPress updates. When this feature is enabled, a full backup will be made during the <a target="_blank" href="%1$s">pre_auto_update action</a>. ', 'boldgrid-backup' ),
93
- 'https://developer.wordpress.org/reference/hooks/pre_auto_update/'
94
- );
95
- ?>
96
- <p>
97
- </th>
98
- <td>
99
- <input id='auto-backup-enabled' type='radio' name='auto_backup'
100
- value='1'
101
- <?php
102
- if ( ! isset( $settings['auto_backup'] ) ||
103
- 1 === $settings['auto_backup'] ) {
104
- echo ' checked';
105
- }
106
- ?> /> <?php esc_html_e( 'Enabled', 'boldgrid-backup' ); ?> &nbsp; <input
107
- id='auto-backup-disabled' type='radio' name='auto_backup' value='0'
108
- <?php
109
- if ( isset( $settings['auto_backup'] ) && 0 === $settings['auto_backup'] ) {
110
- echo ' checked';
111
- }
112
- ?> /> <?php esc_html_e( 'Disabled', 'boldgrid-backup' ); ?>
113
- </td>
114
- </tr>
115
-
116
- <tr>
117
- <th>
118
- <?php esc_html_e( 'Auto Rollback', 'boldgrid-backup' ); ?><span class='dashicons dashicons-editor-help' data-id='auto-rollback'></span>
119
-
120
- <p class='help' data-id='auto-rollback'>
121
- <?php
122
- esc_html_e(
123
- 'If something goes wrong while performing WordPress updates, automatically restore the site using a backup made before updating WordPress. This feature does not apply to auto updates.',
124
- 'boldgrid-backup'
125
- );
126
- ?>
127
- </p>
128
- </th>
129
- <td>
130
- <input id='auto-rollback-enabled' type='radio' name='auto_rollback'
131
- value='1'
132
- <?php
133
- if ( ! isset( $settings['auto_rollback'] ) ||
134
- 1 === $settings['auto_rollback'] ) {
135
- echo ' checked';
136
- }
137
- ?> /> <?php esc_html_e( 'Enabled', 'boldgrid-backup' ); ?> &nbsp; <input
138
- id='auto-rollback-disabled' type='radio' name='auto_rollback'
139
- value='0'
140
- <?php
141
- if ( isset( $settings['auto_rollback'] ) && 0 === $settings['auto_rollback'] ) {
142
- echo ' checked';
143
- }
144
- ?> /> <?php esc_html_e( 'Disabled', 'boldgrid-backup' ); ?>
145
- </td>
146
- </tr>
147
- </table>
148
- </div>
149
- </div>
150
-
151
- <?php
152
- $output = ob_get_contents();
153
- ob_end_clean();
154
- return $output;
155
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/partials/settings/backup-directory.php CHANGED
@@ -1,11 +1,20 @@
1
  <?php
2
  /**
 
 
3
  * Show "Backup Directory" on settings page.
4
  *
 
5
  * @since 1.3.1
 
 
 
 
 
 
6
  */
7
 
8
- defined( 'WPINC' ) ? : die;
9
 
10
  ob_start();
11
  ?>
@@ -16,7 +25,6 @@ ob_start();
16
  <span class='dashicons dashicons-editor-help' data-id='backup-dir'></span>
17
  </div>
18
  <div class="bg-box-bottom">
19
-
20
  <p class="help" data-id="backup-dir">
21
  <?php
22
  /*
@@ -26,21 +34,30 @@ ob_start();
26
  * this, it is not recommended that you change it again. You can find more help with setting
27
  * your backup directory <a>here</a>.
28
  */
29
- $link = sprintf(
30
- wp_kses(
31
- __( 'For security purposes, please do not set this to a publicly available directory. Once you set this, it is not recommended that you change it again. You can find more help with setting your backup directory <a href="%s" target="_blank">here</a>.', 'boldgrid-backup' ),
32
- array( 'a' => array( 'href' => array(), 'target' => array() ) )
 
33
  ),
34
- esc_url( $this->core->configs['urls']['setting_directory'] )
 
 
 
 
 
35
  );
36
- echo $link;
37
  ?>
38
  </p>
39
-
40
  <table class='backup-directory form-table'>
41
  <tr>
42
- <th><?php esc_html_e( 'Directory to store backup archives', 'boldgrid-backup' ); ?>:</th>
43
- <td><input id='backup-directory-path' type='text' size='40' name='backup_directory' value='<?php echo $settings['backup_directory']; ?>'></td>
 
 
 
 
 
44
  </tr>
45
  <tr id="move-backups" class="hidden">
46
  <th><?php esc_html_e( 'If you change this directory, current backups will not show in the list. Would you like us to move the backups to the new directory?', 'boldgrid-backup' ); ?></th>
@@ -54,4 +71,3 @@ ob_start();
54
  $output = ob_get_contents();
55
  ob_end_clean();
56
  return $output;
57
- ?>
1
  <?php
2
  /**
3
+ * File: backup-directory.php
4
+ *
5
  * Show "Backup Directory" on settings page.
6
  *
7
+ * @link https://www.boldgrid.com
8
  * @since 1.3.1
9
+ *
10
+ * @package Boldgrid_Backup
11
+ * @subpackage Boldgrid_Backup/admin/partials/settings
12
+ * @copyright BoldGrid
13
+ * @version $Id$
14
+ * @author BoldGrid <support@boldgrid.com>
15
  */
16
 
17
+ defined( 'WPINC' ) || die;
18
 
19
  ob_start();
20
  ?>
25
  <span class='dashicons dashicons-editor-help' data-id='backup-dir'></span>
26
  </div>
27
  <div class="bg-box-bottom">
 
28
  <p class="help" data-id="backup-dir">
29
  <?php
30
  /*
34
  * this, it is not recommended that you change it again. You can find more help with setting
35
  * your backup directory <a>here</a>.
36
  */
37
+ printf(
38
+ // translators: 1: URL address link.
39
+ esc_html__(
40
+ 'For security purposes, please do not set this to a publicly available directory. Once you set this, it is not recommended that you change it again. You can find more help with setting your backup directory %1$s.',
41
+ 'boldgrid-backup'
42
  ),
43
+ sprintf(
44
+ '<a target="_blank" href="' .
45
+ esc_url( $this->core->configs['urls']['setting_directory'] ) .
46
+ '">%1$s</a>',
47
+ esc_html__( 'here', 'boldgrid-backup' )
48
+ )
49
  );
 
50
  ?>
51
  </p>
 
52
  <table class='backup-directory form-table'>
53
  <tr>
54
+ <th><label for="backup_directory">
55
+ <?php esc_html_e( 'Directory to store backup archives', 'boldgrid-backup' ); ?>:
56
+ </label></th>
57
+ <td>
58
+ <input id='backup-directory-path' type='text' size='40' name='backup_directory'
59
+ value='<?php echo esc_attr( $settings['backup_directory'] ); ?>'>
60
+ </td>
61
  </tr>
62
  <tr id="move-backups" class="hidden">
63
  <th><?php esc_html_e( 'If you change this directory, current backups will not show in the list. Would you like us to move the backups to the new directory?', 'boldgrid-backup' ); ?></th>
71
  $output = ob_get_contents();
72
  ob_end_clean();
73
  return $output;
 
admin/partials/settings/backup-security.php ADDED
@@ -0,0 +1,124 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File: backup-security.php
4
+ *
5
+ * Show "Backup Security" on settings page.
6
+ *
7
+ * @since 1.12.0
8
+ * @package Boldgrid_Backup
9
+ * @subpackage Boldgrid_Backup/admin/partials/settings
10
+ * @copyright BoldGrid
11
+ * @link https://www.boldgrid.com
12
+ * @author BoldGrid <support@boldgrid.com>
13
+ */
14
+
15
+ defined( 'WPINC' ) || die;
16
+ ob_start();
17
+ ?>
18
+ <div class="bg-box">
19
+ <div class="bg-box-top">
20
+ <?php esc_html_e( 'Backup Security', 'boldgrid-backup' ); ?>
21
+ <span class='dashicons dashicons-editor-help' data-id='backup_security'></span>
22
+ </div>
23
+ <div class="bg-box-bottom">
24
+ <p class="help" data-id="backup_security">
25
+ <?php
26
+ printf(
27
+ // translators: 1: HTML break tag, 2: HTML strong open tag, 3: HTML strong closing tag.
28
+ esc_html__(
29
+ 'Manage security features to help protect backup archives.%1$s%1$s%2$sEncrypt Database%3$s%1$s This premium feature will encrypt the database dump file in backup archives in order to protect sensitive information.',
30
+ 'boldgrid-backup'
31
+ ),
32
+ '<br />',
33
+ '<strong>',
34
+ '</strong>'
35
+ );
36
+ ?>
37
+ </p>
38
+ <table class="form-table">
39
+ <tr>
40
+ <th><?php esc_html_e( 'Encrypt Database', 'boldgrid-backup' ); ?></th>
41
+ <td>
42
+ <input id="encrypt-db-enabled" type="radio" name="encrypt_db" value="1"
43
+ <?php
44
+ if ( $settings['encrypt_db'] ) {
45
+ echo ' checked'; // Default.
46
+ }
47
+
48
+ if ( ! $is_premium || ! $is_premium_installed || ! $is_premium_active ) {
49
+ echo ' disabled="disabled"';
50
+ }
51
+ ?>
52
+ /> <label for="encrypt-db-enabled"><?php esc_html_e( 'Enabled', 'boldgrid-backup' ); ?></label>
53
+ &nbsp; <input id="encrypt-db-disabled" type="radio" name="encrypt_db" value="0"
54
+ <?php
55
+ if ( ! $settings['encrypt_db'] ) {
56
+ echo ' checked';
57
+ }
58
+
59
+ if ( ! $is_premium || ! $is_premium_installed || ! $is_premium_active ) {
60
+ echo ' disabled="disabled"';
61
+ }
62
+ ?>
63
+ /> <label for="encrypt-db-disabled"><?php esc_html_e( 'Disabled', 'boldgrid-backup' ); ?></label>
64
+ </td>
65
+ </tr>
66
+ <?php
67
+ if ( ! $is_premium ) {
68
+ ?>
69
+ <tr><td colspan="2">
70
+ <div class="bg-box-bottom premium wp-clearfix">
71
+ <?php
72
+ $get_premium_url = 'https://www.boldgrid.com/update-backup?source=bgbkup-settings-security';
73
+ printf(
74
+ // translators: 1: Get premium button/link, 2: Premium plugin title.
75
+ esc_html__( '%1$sA %2$s license is required for encryption features.', 'boldgrid-backup' ),
76
+ $this->core->go_pro->get_premium_button( $get_premium_url, __( 'Get Premium', 'boldgrid-backup' ) ), // phpcs:ignore
77
+ esc_html( BOLDGRID_BACKUP_TITLE . ' Premium' )
78
+ );
79
+ ?>
80
+ </div>
81
+ </td></tr>
82
+ <?php
83
+ } elseif ( ! $is_premium_installed ) {
84
+ ?>
85
+ <tr><td colspan="2">
86
+ <div class="bg-box-bottom premium wp-clearfix">
87
+ <?php
88
+ $get_plugins_url = 'https://www.boldgrid.com/central/plugins?source=bgbkup-settings-security';
89
+ printf(
90
+ // translators: 1: Unlock Feature button/link, 2: Premium plugin title.
91
+ esc_html__( '%1$sThe %2$s plugin is required for encryption features.', 'boldgrid-backup' ),
92
+ $this->core->go_pro->get_premium_button( $get_plugins_url, __( 'Unlock Feature', 'boldgrid-backup' ) ), // phpcs:ignore
93
+ esc_html( BOLDGRID_BACKUP_TITLE . ' Premium' )
94
+ );
95
+ ?>
96
+ </div>
97
+ </td></tr>
98
+ <?php
99
+ } elseif ( ! $is_premium_active ) {
100
+ ?>
101
+ <tr><td colspan="2">
102
+ <?php
103
+ printf(
104
+ // translators: 1: HTML anchor link open tag, 2: HTML anchor closing tag, 3: Premium plugin title.
105
+ esc_html__( 'The %3$s plugin is not active. Encryption features are not available. Please go to the %1$sPlugins%2$s page to activate it.', 'boldgrid-backup' ),
106
+ '<a href="' .
107
+ esc_url( admin_url( 'plugins.php?s=Boldgrid%20Backup%20Premium&plugin_status=inactive' ) ) .
108
+ '">',
109
+ '</a>',
110
+ esc_html( BOLDGRID_BACKUP_TITLE . ' Premium' )
111
+ );
112
+ ?>
113
+ </td></tr>
114
+ <?php
115
+ }
116
+ ?>
117
+ </table>
118
+ </div>
119
+ </div>
120
+ <?php
121
+ $output = ob_get_contents();
122
+ ob_end_clean();
123
+
124
+ return $output;
admin/partials/settings/compressor.php CHANGED
@@ -1,64 +1,79 @@
1
  <?php
2
  /**
3
- * Compressor on settings page.
4
  *
 
5
  * This page is only shown for testers who have appropriate hooks in place.
6
  *
 
7
  * @since 1.5.1
8
  *
9
  * @package Boldgrid_Backup
10
  * @subpackage Boldgrid_Backup/admin/partials/settings
 
 
 
11
  */
12
 
13
- defined( 'WPINC' ) ? : die;
14
 
15
- ob_start();
16
 
17
- $selected = 'selected="selected"';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
 
19
- $available_compressors = array( 'php_zip', 'pcl_zip' );
 
 
 
20
 
21
- // Settings for compressor.
22
- $pcl_zip_selected = empty( $settings['compressor'] ) || 'pcl_zip' === $settings['compressor'] ? $selected : '';
23
- $php_zip_selected = ! empty( $settings['compressor'] ) && 'php_zip' === $settings['compressor'] ? $selected : '';
24
- $php_zip_option = ! in_array( 'php_zip', $available_compressors ) ? '' : sprintf( '<option value="php_zip" %1$s>ZipArchive</option>', $php_zip_selected );
25
 
26
- // Settings for extractor.
27
- $extractor_pcl_zip_selected = ! empty( $settings['extractor'] ) && 'pcl_zip' === $settings['extractor'] ? $selected : '';
28
- $extractor_php_zip_selected = empty( $settings['extractor'] ) || 'php_zip' === $settings['extractor'] ? $selected : '';
29
- $extractor_php_zip_option = ! in_array( 'php_zip', $available_compressors ) ? '' : sprintf( '<option value="php_zip" %1$s>ZipArchive</option>', $extractor_php_zip_selected );
 
 
 
 
30
 
 
31
  ?>
32
  <div class="bg-box">
33
  <div class="bg-box-top">
34
- <?php esc_html_e( 'Compressor & Extractor', 'boldgrid-backup' ); ?>
 
35
  <span class='dashicons dashicons-editor-help' data-id='compressor'></span>
36
  </div>
37
  <div class="bg-box-bottom">
38
 
39
  <p class="help" data-id="compressor">
40
  <?php
41
- echo __( 'These are advanced settings. You do not need to configure this setting.', 'boldgrid-backup' );
42
  ?>
43
  </p>
44
 
45
  <table class="form-table">
46
  <tr>
47
- <th><?php echo __( 'Compressor', 'boldgrid-backup' );?>:</th>
48
  <td>
49
- <select name="compressor">
50
- <option value='pcl_zip' <?php echo $pcl_zip_selected; ?> >PclZip</option>
51
- <?php echo $php_zip_option; ?>
52
- </select>
53
- </td>
54
- </tr>
55
- <tr>
56
- <th><?php echo __( 'Extractor', 'boldgrid-backup' ) ?>:</th>
57
- <td>
58
- <select name="extractor">
59
- <option value='pcl_zip' <?php echo $extractor_pcl_zip_selected; ?> >PclZip</option>
60
- <?php echo $extractor_php_zip_option; ?>
61
- </select>
62
  </td>
63
  </tr>
64
  </table>
@@ -69,4 +84,3 @@ $extractor_php_zip_option = ! in_array( 'php_zip', $available_compressors ) ? ''
69
  $output = ob_get_contents();
70
  ob_end_clean();
71
  return $output;
72
- ?>
1
  <?php
2
  /**
3
+ * File: compressor.php
4
  *
5
+ * Compressor on settings page.
6
  * This page is only shown for testers who have appropriate hooks in place.
7
  *
8
+ * @link https://www.boldgrid.com
9
  * @since 1.5.1
10
  *
11
  * @package Boldgrid_Backup
12
  * @subpackage Boldgrid_Backup/admin/partials/settings
13
+ * @copyright BoldGrid
14
+ * @version $Id$
15
+ * @author BoldGrid <support@boldgrid.com>
16
  */
17
 
18
+ defined( 'WPINC' ) || die;
19
 
20
+ $core = apply_filters( 'boldgrid_backup_get_core', null );
21
 
22
+ // An array of compressors we will let the user choose from.
23
+ $compressors = [
24
+ [
25
+ 'id' => 'pcl_zip',
26
+ 'name' => 'PclZip',
27
+ ],
28
+ [
29
+ 'id' => 'php_zip',
30
+ 'name' => 'ZipArchive',
31
+ ],
32
+ [
33
+ 'id' => 'system_zip',
34
+ 'name' => 'System zip',
35
+ ],
36
+ ];
37
 
38
+ // Create the Compressor options.
39
+ $select_compressor = '<select name="compressor">';
40
+ foreach ( $compressors as $compressor ) {
41
+ $object = $core->compressors->get_object( $compressor['id'] );
42
 
43
+ if ( ! $object->is_available() ) {
44
+ continue;
45
+ }
 
46
 
47
+ $select_compressor .= sprintf(
48
+ '<option value="%1$s" %2$s>%3$s</option>',
49
+ esc_attr( $compressor['id'] ),
50
+ $object->maybe_selected_compressor() ? 'selected="selected"' : '',
51
+ esc_html( $compressor['name'] )
52
+ );
53
+ }
54
+ $select_compressor .= '</select>';
55
 
56
+ ob_start();
57
  ?>
58
  <div class="bg-box">
59
  <div class="bg-box-top">
60
+ <?php esc_html_e( 'Compressor', 'boldgrid-backup' ); ?>
61
+ <span class="bgb-unbold">(<?php esc_html_e( 'Advanced', 'boldgrid-bacup' ); ?>)</span>
62
  <span class='dashicons dashicons-editor-help' data-id='compressor'></span>
63
  </div>
64
  <div class="bg-box-bottom">
65
 
66
  <p class="help" data-id="compressor">
67
  <?php
68
+ esc_html_e( 'These are advanced settings. You do not need to configure this setting.', 'boldgrid-backup' );
69
  ?>
70
  </p>
71
 
72
  <table class="form-table">
73
  <tr>
74
+ <th><?php esc_html_e( 'Compressor', 'boldgrid-backup' ); ?>:</th>
75
  <td>
76
+ <?php echo $select_compressor; // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped ?>
 
 
 
 
 
 
 
 
 
 
 
 
77
  </td>
78
  </tr>
79
  </table>
84
  $output = ob_get_contents();
85
  ob_end_clean();
86
  return $output;
 
admin/partials/settings/connect-key.php CHANGED
@@ -2,58 +2,19 @@
2
  /**
3
  * File: connect-key.php
4
  *
5
- * Show Connect Key status.
6
  *
7
- * @since 1.5.4
 
 
 
 
 
 
 
8
  */
9
 
10
- defined( 'WPINC' ) ? : die;
11
-
12
- $is_dismissed = apply_filters( 'Boldgrid\Library\Notice\KeyPrompt\getIsDismissed', false );
13
- $is_displayed = apply_filters( 'Boldgrid\Library\Notice\KeyPrompt\getIsDisplayed', false );
14
-
15
- $has_key_entered = ! empty( $this->core->configs['api_key'] );
16
-
17
- // Check again button to refresh license status.
18
- $refresh_key = ! $has_key_entered || $this->core->config->get_is_premium() ? '' : '<p>' .
19
- __( 'If you recently upgraded your BoldGrid Connect Key to Premium, click <strong>Check again</strong> to refresh the status of your license.', 'boldgrid-backup' ) .
20
- '<br />' .
21
- sprintf( '<a class="button" id="license_check_again">%1$s</a>', __( 'Check again', 'boldgrid-backup' ) ) .
22
- ' <strong>' . __( 'License type', 'boldgrid-backup' ) . '</strong>: <span id="license_string">' . $this->core->config->get_license_string() . '</span>' .
23
- ' <span class="spinner inline" style="display:none;vertical-align:text-bottom;"></span>' .
24
- '</p>' .
25
- '<p id="license_reload_page" class="hidden">' .
26
- $this->core->lang['icon_warning'] .
27
- __( 'Please reload this page for your new license status to take affect.', 'boldgrid-bakcup' ) .
28
- '</p>';
29
-
30
- ob_start();
31
- if ( $has_key_entered ) {
32
- printf(
33
- __( 'You have entered a <strong>%1$s</strong> BoldGrid Connect Key.', 'boldgrid-backup' ),
34
- $this->core->config->get_is_premium() ? __( 'Premium', 'boldgrid-backup' ) : __( 'Free', 'boldgrid-backup' )
35
- );
36
- } elseif ( $is_dismissed ) {
37
- _e(
38
- 'You have dismissed the prompt to enter a BoldGrid Connect Key. Click <a class="undismissBoldgridNotice" href="#">here</a> to restore the prompt.',
39
- 'boldgrid-backup'
40
- );
41
-
42
- wp_nonce_field( 'boldgrid_set_key', 'set_key_auth' );
43
- } else {
44
- _e( 'Please enter your BoldGrid Connect Key in the form at the top of this page.', 'boldgrid-backup' );
45
- }
46
- $output = ob_get_contents();
47
- ob_end_clean();
48
-
49
- // Add a "Get Premium" section under the Connect Key.
50
- $bottom_box_premium = '';
51
- if ( ! $this->core->config->get_is_premium() && ! $is_displayed ) {
52
- $bottom_box_premium = '<div class="bg-box-bottom premium">' .
53
- $this->core->go_pro->get_premium_button() .
54
- $this->core->lang['want_to'] .
55
- '</div>';
56
- }
57
 
58
  return '
59
  <div class="bg-box">
@@ -61,8 +22,12 @@ return '
61
  ' . __( 'BoldGrid Connect Key', 'boldgrid-backup' ) . '
62
  </div>
63
  <div class="bg-box-bottom">
64
- ' . $output . $refresh_key . '
 
 
 
 
 
65
  </div>
66
- ' . $bottom_box_premium . '
67
- </div>';
68
-
2
  /**
3
  * File: connect-key.php
4
  *
5
+ * Show link to Settings >> BoldGrid Connect.
6
  *
7
+ * @link https://www.boldgrid.com
8
+ * @since 1.6.0
9
+ *
10
+ * @package Boldgrid_Backup
11
+ * @subpackage Boldgrid_Backup/admin/partials/settings
12
+ * @copyright BoldGrid
13
+ * @version $Id$
14
+ * @author BoldGrid <support@boldgrid.com>
15
  */
16
 
17
+ defined( 'WPINC' ) || die;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
 
19
  return '
20
  <div class="bg-box">
22
  ' . __( 'BoldGrid Connect Key', 'boldgrid-backup' ) . '
23
  </div>
24
  <div class="bg-box-bottom">
25
+ ' .
26
+ sprintf(
27
+ '%1$s <a href="' . admin_url( 'options-general.php?page=boldgrid-connect.php' ) . '">%2$s</a>.',
28
+ __( 'Connect Key management has been moved to', 'boldgrid-backup' ),
29
+ __( 'Settings >> BoldGrid Connect', 'boldgrid-backup' )
30
+ ) . '
31
  </div>
32
+ </div>
33
+ ';
 
admin/partials/settings/days-of-week.php CHANGED
@@ -1,11 +1,20 @@
1
  <?php
2
  /**
 
 
3
  * Days of the week.
4
  *
5
- * @since 1.5.4
 
 
 
 
 
 
 
6
  */
7
 
8
- defined( 'WPINC' ) ? : die;
9
 
10
  ob_start();
11
  ?>
@@ -15,33 +24,83 @@ ob_start();
15
  <?php esc_html_e( 'Days of the Week', 'boldgrid-backup' ); ?>
16
  </div>
17
  <div class="bg-box-bottom">
18
- <input id='dow-sunday' type='checkbox' name='dow_sunday' value='1' <?php if ( ! empty( $settings['schedule']['dow_sunday'] ) ) { echo ' checked'; } ?> /><?php esc_html_e( 'Sunday', 'boldgrid-backup' ); ?><br />
19
- <input id='dow-monday' type='checkbox' name='dow_monday' value='1' <?php if ( ! empty( $settings['schedule']['dow_monday'] ) ) { echo ' checked'; } ?> /><?php esc_html_e( 'Monday', 'boldgrid-backup' ); ?><br />
20
- <input id='dow-tuesday' type='checkbox' name='dow_tuesday' value='1' <?php if ( ! empty( $settings['schedule']['dow_tuesday'] ) ) { echo ' checked'; } ?> /><?php esc_html_e( 'Tuesday', 'boldgrid-backup' ); ?><br />
21
- <input id='dow-wednesday' type='checkbox' name='dow_wednesday' value='1' <?php if ( ! empty( $settings['schedule']['dow_wednesday'] ) ) { echo ' checked'; } ?> /><?php esc_html_e( 'Wednesday', 'boldgrid-backup' ); ?><br />
22
- <input id='dow-thursday' type='checkbox' name='dow_thursday' value='1' <?php if ( ! empty( $settings['schedule']['dow_thursday'] ) ) { echo ' checked'; } ?> /><?php esc_html_e( 'Thursday', 'boldgrid-backup' ); ?><br />
23
- <input id='dow-friday' type='checkbox' name='dow_friday' value='1' <?php if ( ! empty( $settings['schedule']['dow_friday'] ) ) { echo ' checked'; } ?> /><?php esc_html_e( 'Friday', 'boldgrid-backup' ); ?><br />
24
- <input id='dow-saturday' type='checkbox' name='dow_saturday' value='1' <?php if ( ! empty( $settings['schedule']['dow_saturday'] ) ) { echo ' checked'; } ?> /><?php esc_html_e( 'Saturday', 'boldgrid-backup' ); ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
 
26
  <br /><br />
27
 
28
  <div class='hidden' id='no-backup-days'>
29
- <p><span class="dashicons dashicons-warning yellow"></span> <?php
 
30
  esc_html_e( 'Backup will not occur if no days are selected.', 'boldgrid-backup' );
31
- ?></p>
 
32
  </div>
33
 
34
  <?php
35
  $url = $this->core->configs['urls']['resource_usage'];
36
- $link = sprintf(
 
 
 
37
  wp_kses(
38
- __( 'Backups use resources and <a href="%s" target="_blank">must pause your site</a> momentarily. Use sparingly.', 'boldgrid-backup' ),
39
- array( 'a' => array( 'href' => array(), 'target' => array() ) )
 
 
 
 
 
 
 
 
 
40
  ),
41
  esc_url( $url )
42
  );
43
- printf( '<div id="use-sparingly" class="hidden"><p><span class="dashicons dashicons-warning yellow"></span> %s</p></div>', $link );
44
- ?>
 
45
  </div>
46
  </div>
47
 
@@ -49,4 +108,3 @@ ob_start();
49
  $output = ob_get_contents();
50
  ob_end_clean();
51
  return $output;
52
- ?>
1
  <?php
2
  /**
3
+ * File: days-of-week.php
4
+ *
5
  * Days of the week.
6
  *
7
+ * @link https://www.boldgrid.com
8
+ * @since 1.6.0
9
+ *
10
+ * @package Boldgrid_Backup
11
+ * @subpackage Boldgrid_Backup/admin/partials/settings
12
+ * @copyright BoldGrid
13
+ * @version $Id$
14
+ * @author BoldGrid <support@boldgrid.com>
15
  */
16
 
17
+ defined( 'WPINC' ) || die;
18
 
19
  ob_start();
20
  ?>
24
  <?php esc_html_e( 'Days of the Week', 'boldgrid-backup' ); ?>
25
  </div>
26
  <div class="bg-box-bottom">
27
+ <input id='dow-sunday' type='checkbox' name='dow_sunday' value='1'
28
+ <?php
29
+ if ( ! empty( $settings['schedule']['dow_sunday'] ) ) {
30
+ echo ' checked'; }
31
+ ?>
32
+ /><?php esc_html_e( 'Sunday', 'boldgrid-backup' ); ?><br />
33
+ <input id='dow-monday' type='checkbox' name='dow_monday' value='1'
34
+ <?php
35
+ if ( ! empty( $settings['schedule']['dow_monday'] ) ) {
36
+ echo ' checked'; }
37
+ ?>
38
+ /><?php esc_html_e( 'Monday', 'boldgrid-backup' ); ?><br />
39
+ <input id='dow-tuesday' type='checkbox' name='dow_tuesday' value='1'
40
+ <?php
41
+ if ( ! empty( $settings['schedule']['dow_tuesday'] ) ) {
42
+ echo ' checked'; }
43
+ ?>
44
+ /><?php esc_html_e( 'Tuesday', 'boldgrid-backup' ); ?><br />
45
+ <input id='dow-wednesday' type='checkbox' name='dow_wednesday' value='1'
46
+ <?php
47
+ if ( ! empty( $settings['schedule']['dow_wednesday'] ) ) {
48
+ echo ' checked'; }
49
+ ?>
50
+ /><?php esc_html_e( 'Wednesday', 'boldgrid-backup' ); ?><br />
51
+ <input id='dow-thursday' type='checkbox' name='dow_thursday' value='1'
52
+ <?php
53
+ if ( ! empty( $settings['schedule']['dow_thursday'] ) ) {
54
+ echo ' checked'; }
55
+ ?>
56
+ /><?php esc_html_e( 'Thursday', 'boldgrid-backup' ); ?><br />
57
+ <input id='dow-friday' type='checkbox' name='dow_friday' value='1'
58
+ <?php
59
+ if ( ! empty( $settings['schedule']['dow_friday'] ) ) {
60
+ echo ' checked'; }
61
+ ?>
62
+ /><?php esc_html_e( 'Friday', 'boldgrid-backup' ); ?><br />
63
+ <input id='dow-saturday' type='checkbox' name='dow_saturday' value='1'
64
+ <?php
65
+ if ( ! empty( $settings['schedule']['dow_saturday'] ) ) {
66
+ echo ' checked'; }
67
+ ?>
68
+ /><?php esc_html_e( 'Saturday', 'boldgrid-backup' ); ?>
69
 
70
  <br /><br />
71
 
72
  <div class='hidden' id='no-backup-days'>
73
+ <p><span class="dashicons dashicons-warning yellow"></span>
74
+ <?php
75
  esc_html_e( 'Backup will not occur if no days are selected.', 'boldgrid-backup' );
76
+ ?>
77
+ </p>
78
  </div>
79
 
80
  <?php
81
  $url = $this->core->configs['urls']['resource_usage'];
82
+
83
+ echo '<div id="use-sparingly" class="hidden"><p><span class="dashicons dashicons-warning yellow"></span> ';
84
+
85
+ printf(
86
  wp_kses(
87
+ // translators: 1: HTML markup.
88
+ __(
89
+ 'Backups use resources and <a href="%s" target="_blank">must pause your site</a> momentarily. Use sparingly.',
90
+ 'boldgrid-backup'
91
+ ),
92
+ array(
93
+ 'a' => array(
94
+ 'href' => array(),
95
+ 'target' => array(),
96
+ ),
97
+ )
98
  ),
99
  esc_url( $url )
100
  );
101
+
102
+ echo '</p></div>';
103
+ ?>
104
  </div>
105
  </div>
106
 
108
  $output = ob_get_contents();
109
  ob_end_clean();
110
  return $output;
 
admin/partials/settings/db.php CHANGED
@@ -2,10 +2,17 @@
2
  /**
3
  * Database settings.
4
  *
 
5
  * @since 1.5.3
 
 
 
 
 
 
6
  */
7
 
8
- defined( 'WPINC' ) ? : die;
9
 
10
  // $core will vary based on how this file is included.
11
  $core = isset( $this->core ) ? $this->core : $this;
@@ -17,12 +24,13 @@ $tables = $core->db_omit->format_prefixed_tables();
17
 
18
  // Determine if the "Backup all tables" option should be checked.
19
  $all_included = empty( $settings['exclude_tables'] );
20
- $type = $core->db_omit->get_settings_type();
21
  $full_checked = 'full' === $type || $all_included;
22
 
23
  $checked = 'checked="checked"';
24
 
25
- $types = sprintf( '
 
26
  <input type="radio" name="table_inclusion_type" value="full" %3$s>%1$s<br>
27
  <input type="radio" name="table_inclusion_type" value="custom" %4$s>%2$s
28
  ',
@@ -32,7 +40,8 @@ $types = sprintf( '
32
  /* 4 */ $in_modal || $full_checked ? '' : $checked
33
  );
34
 
35
- $buttons = sprintf( '
 
36
  <button id="include_all_tables" class="button button-primary">%1$s</button>
37
  <button id="exclude_all_tables" class="button button">%2$s</button>
38
  ',
@@ -40,7 +49,8 @@ $buttons = sprintf( '
40
  /* 2 */ esc_html__( 'Exclude all', 'boldgrid-backup' )
41
  );
42
 
43
- $status = sprintf( '
 
44
  <p class="yes-default">
45
  %1$s
46
  </p>
@@ -53,7 +63,8 @@ $status = sprintf( '
53
  /* 3 */ sprintf( '<a href="#" class="include-all">%1$s</a>', __( 'Backup all tables', 'boldgrid-backup' ) )
54
  );
55
 
56
- return sprintf( '
 
57
  <div class="bg-box" id="table_inclusion">
58
  <div class="bg-box-top">
59
  %1$s
@@ -79,5 +90,3 @@ return sprintf( '
79
  /* 4 */ $buttons,
80
  /* 5 */ $tables
81
  );
82
-
83
-
2
  /**
3
  * Database settings.
4
  *
5
+ * @link https://www.boldgrid.com
6
  * @since 1.5.3
7
+ *
8
+ * @package Boldgrid_Backup
9
+ * @subpackage Boldgrid_Backup/admin/partials/settings
10
+ * @copyright BoldGrid
11
+ * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
  */
14
 
15
+ defined( 'WPINC' ) || die;
16
 
17
  // $core will vary based on how this file is included.
18
  $core = isset( $this->core ) ? $this->core : $this;
24
 
25
  // Determine if the "Backup all tables" option should be checked.
26
  $all_included = empty( $settings['exclude_tables'] );
27
+ $type = $core->db_omit->get_settings_type();
28
  $full_checked = 'full' === $type || $all_included;
29
 
30
  $checked = 'checked="checked"';
31
 
32
+ $types = sprintf(
33
+ '
34
  <input type="radio" name="table_inclusion_type" value="full" %3$s>%1$s<br>
35
  <input type="radio" name="table_inclusion_type" value="custom" %4$s>%2$s
36
  ',
40
  /* 4 */ $in_modal || $full_checked ? '' : $checked
41
  );
42
 
43
+ $buttons = sprintf(
44
+ '
45
  <button id="include_all_tables" class="button button-primary">%1$s</button>
46
  <button id="exclude_all_tables" class="button button">%2$s</button>
47
  ',
49
  /* 2 */ esc_html__( 'Exclude all', 'boldgrid-backup' )
50
  );
51
 
52
+ $status = sprintf(
53
+ '
54
  <p class="yes-default">
55
  %1$s
56
  </p>
63
  /* 3 */ sprintf( '<a href="#" class="include-all">%1$s</a>', __( 'Backup all tables', 'boldgrid-backup' ) )
64
  );
65
 
66
+ return sprintf(
67
+ '
68
  <div class="bg-box" id="table_inclusion">
69
  <div class="bg-box-top">
70
  %1$s
90
  /* 4 */ $buttons,
91
  /* 5 */ $tables
92
  );
 
 
admin/partials/settings/folders.php CHANGED
@@ -4,18 +4,25 @@
4
  *
5
  * Which files and folders should be included / excluded?
6
  *
7
- * @since 1.5.4
 
 
 
 
 
 
 
8
  */
9
 
10
- defined( 'WPINC' ) ? : die;
11
 
12
  $nonce = wp_create_nonce( 'folder_exclusion_preview' );
13
 
14
  $tags = array(
15
  'strong' => array(),
16
- 'a' => array(
17
  'href' => array(),
18
- 'id' => array(),
19
  ),
20
  );
21
 
@@ -30,8 +37,9 @@ $using_defaults = $core->folder_exclusion->is_using_defaults();
30
 
31
  $markup = '<table class="form-table bulk-action-notice" id="folder_exclusion"><tbody>';
32
 
33
- // TR for the header and intro
34
- $tr_header = sprintf( '
 
35
  <p>
36
  <input type="radio" name="folder_exclusion_type" value="full" %3$s>%1$s<br>
37
  <input type="radio" name="folder_exclusion_type" value="custom" %4$s>%2$s
@@ -42,9 +50,9 @@ $tr_header = sprintf( '
42
  /* 4 */ ! $in_modal && ! $using_defaults ? $checked : ''
43
  );
44
 
45
- // This markup for the legend.
46
- // TR for the help text.
47
- $table_legend = sprintf( '
48
  <table class="folder_exclude_help wp-list-table widefat fixed striped pages">
49
  <tr>
50
  <th>*</th>
@@ -86,8 +94,9 @@ $table_legend = sprintf( '
86
  /* 8 */ wp_kses( __( 'For example, <strong>wp-admin,wp-includes</strong> will backup both the wp-admin folder and the wp-includes folder.', 'boldgrid-backup' ), $tags )
87
  );
88
 
89
- // Examples
90
- $table_examples = sprintf( '
 
91
  <table class="folder_exclude_help wp-list-table widefat fixed striped pages">
92
  <tr>
93
  <th><a href="#" class="folder_exclude_sample" data-include="%1$s" data-exclude="%2$s">%3$s</a></th>
@@ -119,7 +128,8 @@ $table_examples = sprintf( '
119
  /* 10 */ wp_kses( __( 'Backup everything except WordPress core files.', 'boldgrid-backup' ), $tags )
120
  );
121
 
122
- $status = sprintf( '
 
123
  <p class="yes-default">
124
  %1$s
125
  </p>
@@ -138,7 +148,8 @@ $status = sprintf( '
138
  );
139
 
140
  // TR for the help text.
141
- $tr_help = sprintf( '
 
142
  <div id="folder_misc_info">
143
  <p>
144
  <span class="dashicons dashicons-editor-help" data-id="folder_exclude_inputs" style="float:left;margin-right:4px;"></span>
@@ -170,8 +181,9 @@ $tr_help = sprintf( '
170
  /* 7 */ $status
171
  );
172
 
173
- // TR for the include
174
- $tr_include = sprintf( '
 
175
  <tr class="%3$s">
176
  <th style="padding-top:0px;">
177
  %1$s
@@ -187,7 +199,8 @@ $tr_include = sprintf( '
187
  );
188
 
189
  // TR for the exclude.
190
- $tr_exclude = sprintf( '
 
191
  <tr class="%3$s">
192
  <th>
193
  %1$s
@@ -202,8 +215,9 @@ $tr_exclude = sprintf( '
202
  /* A1 */ $using_defaults ? 'hidden' : ''
203
  );
204
 
205
- // TR for the preview
206
- $tr_preview = sprintf( '
 
207
  <tr class="%1$s">
208
  <th></th>
209
  <td>
@@ -232,7 +246,8 @@ $tr_preview = sprintf( '
232
  /* 4 */ esc_attr( __( 'Filter below results', 'boldgrid-backup' ) )
233
  );
234
 
235
- $markup = sprintf( '
 
236
  <div class="bg-box" id="folder_exclusion">
237
  <div class="bg-box-top">
238
  %1$s
@@ -258,5 +273,3 @@ $markup = sprintf( '
258
  );
259
 
260
  return $markup;
261
-
262
-
4
  *
5
  * Which files and folders should be included / excluded?
6
  *
7
+ * @link https://www.boldgrid.com
8
+ * @since 1.6.0
9
+ *
10
+ * @package Boldgrid_Backup
11
+ * @subpackage Boldgrid_Backup/admin/partials/settings
12
+ * @copyright BoldGrid
13
+ * @version $Id$
14
+ * @author BoldGrid <support@boldgrid.com>
15
  */
16
 
17
+ defined( 'WPINC' ) || die;
18
 
19
  $nonce = wp_create_nonce( 'folder_exclusion_preview' );
20
 
21
  $tags = array(
22
  'strong' => array(),
23
+ 'a' => array(
24
  'href' => array(),
25
+ 'id' => array(),
26
  ),
27
  );
28
 
37
 
38
  $markup = '<table class="form-table bulk-action-notice" id="folder_exclusion"><tbody>';
39
 
40
+ // TR for the header and intro.
41
+ $tr_header = sprintf(
42
+ '
43
  <p>
44
  <input type="radio" name="folder_exclusion_type" value="full" %3$s>%1$s<br>
45
  <input type="radio" name="folder_exclusion_type" value="custom" %4$s>%2$s
50
  /* 4 */ ! $in_modal && ! $using_defaults ? $checked : ''
51
  );
52
 
53
+ // This markup for the legend. TR for the help text.
54
+ $table_legend = sprintf(
55
+ '
56
  <table class="folder_exclude_help wp-list-table widefat fixed striped pages">
57
  <tr>
58
  <th>*</th>
94
  /* 8 */ wp_kses( __( 'For example, <strong>wp-admin,wp-includes</strong> will backup both the wp-admin folder and the wp-includes folder.', 'boldgrid-backup' ), $tags )
95
  );
96
 
97
+ // Examples.
98
+ $table_examples = sprintf(
99
+ '
100
  <table class="folder_exclude_help wp-list-table widefat fixed striped pages">
101
  <tr>
102
  <th><a href="#" class="folder_exclude_sample" data-include="%1$s" data-exclude="%2$s">%3$s</a></th>
128
  /* 10 */ wp_kses( __( 'Backup everything except WordPress core files.', 'boldgrid-backup' ), $tags )
129
  );
130
 
131
+ $status = sprintf(
132
+ '
133
  <p class="yes-default">
134
  %1$s
135
  </p>
148
  );
149
 
150
  // TR for the help text.
151
+ $tr_help = sprintf(
152
+ '
153
  <div id="folder_misc_info">
154
  <p>
155
  <span class="dashicons dashicons-editor-help" data-id="folder_exclude_inputs" style="float:left;margin-right:4px;"></span>
181
  /* 7 */ $status
182
  );
183
 
184
+ // TR for the include.
185
+ $tr_include = sprintf(
186
+ '
187
  <tr class="%3$s">
188
  <th style="padding-top:0px;">
189
  %1$s
199
  );
200
 
201
  // TR for the exclude.
202
+ $tr_exclude = sprintf(
203
+ '
204
  <tr class="%3$s">
205
  <th>
206
  %1$s
215
  /* A1 */ $using_defaults ? 'hidden' : ''
216
  );
217
 
218
+ // TR for the preview.
219
+ $tr_preview = sprintf(
220
+ '
221
  <tr class="%1$s">
222
  <th></th>
223
  <td>
246
  /* 4 */ esc_attr( __( 'Filter below results', 'boldgrid-backup' ) )
247
  );
248
 
249
+ $markup = sprintf(
250
+ '
251
  <div class="bg-box" id="folder_exclusion">
252
  <div class="bg-box-top">
253
  %1$s
273
  );
274
 
275
  return $markup;
 
 
admin/partials/settings/notifications.php CHANGED
@@ -1,11 +1,20 @@
1
  <?php
2
  /**
 
 
3
  * Show "Notifications" on settings page.
4
  *
 
5
  * @since 1.5.1
 
 
 
 
 
 
6
  */
7
 
8
- defined( 'WPINC' ) ? : die;
9
 
10
  ob_start();
11
  ?>
@@ -19,7 +28,7 @@ ob_start();
19
  <tr>
20
  <th><?php esc_html_e( 'Notification email address', 'boldgrid-backup' ); ?></th>
21
  <td>
22
- <input id='notification-email' type='text' size='40' name='notification_email' value='<?php echo $settings['notification_email']; ?>'></td>
23
  </tr>
24
  <tr>
25
  <th><?php esc_html_e( 'Send an email when a backup completes', 'boldgrid-backup' ); ?></th>
@@ -28,9 +37,10 @@ ob_start();
28
  <?php
29
  if ( ! isset( $settings['notifications']['backup'] ) ||
30
  0 !== $settings['notifications']['backup'] ) {
31
- echo ' checked';
32
  }
33
- ?> />
 
34
  </td>
35
  </tr>
36
  <tr>
@@ -40,9 +50,22 @@ ob_start();
40
  <?php
41
  if ( ! isset( $settings['notifications']['restore'] ) ||
42
  0 !== $settings['notifications']['restore'] ) {
43
- echo ' checked';
44
  }
45
- ?> />
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  </td>
47
  </tr>
48
  </table>
@@ -53,4 +76,3 @@ ob_start();
53
  $output = ob_get_contents();
54
  ob_end_clean();
55
  return $output;
56
- ?>
1
  <?php
2
  /**
3
+ * File: notifications.php
4
+ *
5
  * Show "Notifications" on settings page.
6
  *
7
+ * @link https://www.boldgrid.com
8
  * @since 1.5.1
9
+ *
10
+ * @package Boldgrid_Backup
11
+ * @subpackage Boldgrid_Backup/admin/partials/settings
12
+ * @copyright BoldGrid
13
+ * @version $Id$
14
+ * @author BoldGrid <support@boldgrid.com>
15
  */
16
 
17
+ defined( 'WPINC' ) || die;
18
 
19
  ob_start();
20
  ?>
28
  <tr>
29
  <th><?php esc_html_e( 'Notification email address', 'boldgrid-backup' ); ?></th>
30
  <td>
31
+ <input id='notification-email' type='text' size='40' name='notification_email' value='<?php echo esc_attr( $settings['notification_email'] ); ?>'></td>
32
  </tr>
33
  <tr>
34
  <th><?php esc_html_e( 'Send an email when a backup completes', 'boldgrid-backup' ); ?></th>
37
  <?php
38
  if ( ! isset( $settings['notifications']['backup'] ) ||
39
  0 !== $settings['notifications']['backup'] ) {
40
+ echo ' checked'; // Default.
41
  }
42
+ ?>
43
+ />
44
  </td>
45
  </tr>
46
  <tr>
50
  <?php
51
  if ( ! isset( $settings['notifications']['restore'] ) ||
52
  0 !== $settings['notifications']['restore'] ) {
53
+ echo ' checked'; // Default.
54
  }
55
+ ?>
56
+ />
57
+ </td>
58
+ </tr>
59
+ <tr>
60
+ <th><?php esc_html_e( 'Send an email when there is a failed site check', 'boldgrid-backup' ); ?></th>
61
+ <td>
62
+ <input id='notification-site-check' type='checkbox' name='notify_site_check' value='1'
63
+ <?php
64
+ if ( $settings['notifications']['site_check'] ) {
65
+ echo ' checked'; // Default.
66
+ }
67
+ ?>
68
+ />
69
  </td>
70
  </tr>
71
  </table>
76
  $output = ob_get_contents();
77
  ob_end_clean();
78
  return $output;
 
admin/partials/settings/premium-message.php CHANGED
@@ -1,57 +1,84 @@
1
  <?php
2
  /**
 
 
3
  * Show free / premium message.
4
  *
5
  * @summary Show an intro atop the settings page regarding free / premium version of the plugin.
6
  *
 
7
  * @since 1.3.1
 
 
 
 
 
 
8
  */
9
 
10
- defined( 'WPINC' ) ? : die;
 
 
 
 
11
 
12
- if( $this->core->config->get_is_premium() ) {
13
- ?><p><?php
14
  /*
15
  * Print this message:
16
  *
17
- * You are running the Premium version of the BoldGrid Backup Plugin. Please visit our
18
- * <a>BoldGrid Backup User Guide</a> for more information.
19
  */
20
  printf(
21
  wp_kses(
22
- __( 'You are running the Premium version of the BoldGrid Backup Plugin. Please visit our <a href="%s" target="_blank">BoldGrid Backup User Guide</a> for more information.', 'boldgrid-backup' ),
23
- array( 'a' => array( 'href' => array(), 'target' => array() ) )
 
 
 
 
 
 
 
 
 
24
  ),
25
- esc_url( $this->core->configs['urls']['user_guide'] )
 
26
  );
27
- ?></p><?php
 
 
28
  } else {
29
  /*
30
  * Print this message:
31
  *
32
- * The BoldGrid Backup plugin comes in two versions, the Free and Premium. The Premium
33
  * version is part of the BoldGrid Premium Suite. To learn about the capabilities of the
34
- * BoldGrid Backup Plugin, check out our <a>BoldGrid Backup User Guide</a>.
35
  *
36
  * Key differences are size of backups supported, scheduling capabilities, and number of
37
  * archives supported. To upgrade now, go <a>here</a>.
38
  */
39
  printf(
40
  wp_kses(
41
- __(
 
42
  '
43
- <p>The BoldGrid Backup plugin comes in two versions, the Free and Premium. The Premium version is part of the BoldGrid Premium Suite. To learn about the capabilities of the BoldGrid Backup Plugin, check out our <a href="%1$s" target="_blank">BoldGrid Backup User Guide</a>.</p>
44
  <p>Key differences are size of backups supported, scheduling capabilities, and number of archives supported. To upgrade now, go <a href="%2$s" target="_blank">here</a>.</p>
45
  ',
46
  'boldgrid-backup'
47
  ),
48
- array(
49
- 'a' => array( 'href' => array(), 'target' => array() ),
50
- 'p' => array(),
51
- )
 
 
 
52
  ),
53
  esc_url( $this->core->configs['urls']['user_guide'] ),
54
- esc_url( $this->core->configs['urls']['upgrade'] )
 
55
  );
56
  }
57
- ?>
1
  <?php
2
  /**
3
+ * File: premium-message.php
4
+ *
5
  * Show free / premium message.
6
  *
7
  * @summary Show an intro atop the settings page regarding free / premium version of the plugin.
8
  *
9
+ * @link https://www.boldgrid.com
10
  * @since 1.3.1
11
+ *
12
+ * @package Boldgrid_Backup
13
+ * @subpackage Boldgrid_Backup/admin/partials/settings
14
+ * @copyright BoldGrid
15
+ * @version $Id$
16
+ * @author BoldGrid <support@boldgrid.com>
17
  */
18
 
19
+ defined( 'WPINC' ) || die;
20
+
21
+ if ( $this->core->config->get_is_premium() ) {
22
+ ?><p>
23
+ <?php
24
 
 
 
25
  /*
26
  * Print this message:
27
  *
28
+ * You are running the Premium version of the BOLDGRID_BACKUP_TITLE Plugin. Please visit our
29
+ * <a>BOLDGRID_BACKUP_TITLE User Guide</a> for more information.
30
  */
31
  printf(
32
  wp_kses(
33
+ // translators: 1: URL address, 2: Plugin title.
34
+ esc_html__(
35
+ 'You are running the Premium version of the %2$s plugin. Please visit our <a href="%1$s" target="_blank">%2$s User Guide</a> for more information.',
36
+ 'boldgrid-backup'
37
+ ),
38
+ [
39
+ 'a' => [
40
+ 'href' => [],
41
+ 'target' => [],
42
+ ],
43
+ ]
44
  ),
45
+ esc_url( $this->core->configs['urls']['user_guide'] ),
46
+ esc_html( BOLDGRID_BACKUP_TITLE )
47
  );
48
+ ?>
49
+ </p>
50
+ <?php
51
  } else {
52
  /*
53
  * Print this message:
54
  *
55
+ * The BOLDGRID_BACKUP_TITLE plugin comes in two versions, the Free and Premium. The Premium
56
  * version is part of the BoldGrid Premium Suite. To learn about the capabilities of the
57
+ * BOLDGRID_BACKUP_TITLE Plugin, check out our <a>BOLDGRID_BACKUP_TITLE User Guide</a>.
58
  *
59
  * Key differences are size of backups supported, scheduling capabilities, and number of
60
  * archives supported. To upgrade now, go <a>here</a>.
61
  */
62
  printf(
63
  wp_kses(
64
+ // translators: 1: URL address for user guide, 2: URL address for upgrade, 3: Plugin title.
65
+ esc_html__(
66
  '
67
+ <p>The %3$s plugin comes in two versions, the Free and Premium. The Premium version is part of the BoldGrid Premium Suite. To learn about the capabilities of the %3$s plugin, check out our <a href="%1$s" target="_blank">%3$s User Guide</a>.</p>
68
  <p>Key differences are size of backups supported, scheduling capabilities, and number of archives supported. To upgrade now, go <a href="%2$s" target="_blank">here</a>.</p>
69
  ',
70
  'boldgrid-backup'
71
  ),
72
+ [
73
+ 'a' => [
74
+ 'href' => [],
75
+ 'target' => [],
76
+ ],
77
+ 'p' => [],
78
+ ]
79
  ),
80
  esc_url( $this->core->configs['urls']['user_guide'] ),
81
+ esc_url( $this->core->configs['urls']['upgrade'] ),
82
+ esc_html( BOLDGRID_BACKUP_TITLE )
83
  );
84
  }
 
admin/partials/settings/retention.php CHANGED
@@ -1,17 +1,30 @@
1
  <?php
2
  /**
3
- * Retention settings.
4
  *
5
- * @summary Show the retention settings section of the BoldGrid Backup settings page.
6
  *
 
7
  * @since 1.3.1
 
 
 
 
 
 
8
  */
9
 
10
- defined( 'WPINC' ) ? : die;
11
 
12
- ob_start();
 
 
 
 
 
 
13
 
14
- $is_retention_set = ( isset( $settings['retention_count'] ) );
15
  ?>
16
 
17
  <div class="bg-box">
@@ -19,40 +32,20 @@ $is_retention_set = ( isset( $settings['retention_count'] ) );
19
  <?php esc_html_e( 'Retention', 'boldgrid-backup' ); ?>
20
  </div>
21
  <div class="bg-box-bottom">
22
- <?php esc_html_e( 'Number of backup archives to retain', 'boldgrid-backup' ); ?>
23
-
24
- <select id='retention-count' name='retention_count'>
25
- <?php
26
- // Loop through each <option> and print it.
27
- for ( $x = 1; $x <= 10; $x ++ ) {
28
- // Is retention set and $x = that set retention?
29
- $x_is_retention = ( $is_retention_set && $x === $settings['retention_count'] );
30
-
31
- // Is retention not set and $x = the default retention?
32
- $x_is_default = ( ! $is_retention_set && $this->core->config->get_default_retention() === $x );
33
-
34
- // Should this option be 'selected'?
35
- $selected = ( ( $x_is_retention || $x_is_default ) ? ' selected' : '' );
36
-
37
- // Should we flag this option as "Requires Upgrade"?
38
- if ( ! $this->core->config->get_is_premium() && ( $this->core->config->get_default_retention() + 1 ) === $x ) {
39
- $requires_upgrade = esc_html__( '- Requires Upgrade', 'boldgrid-backup' );
40
- } else {
41
- $requires_upgrade = '';
42
- }
43
-
44
- printf( '<option value="%1$d" %2$s>%1$d</option>',
45
- $x,
46
- $selected
47
- );
48
- }
49
- ?>
50
- </select>
51
  </div>
52
  </div>
53
 
54
  <?php
55
  $output = ob_get_contents();
56
  ob_end_clean();
 
57
  return $output;
58
- ?>
1
  <?php
2
  /**
3
+ * File: retention.php
4
  *
5
+ * Show the retention settings section of the settings page.
6
  *
7
+ * @link https://www.boldgrid.com
8
  * @since 1.3.1
9
+ *
10
+ * @package Boldgrid_Backup
11
+ * @subpackage Boldgrid_Backup/admin/partials/settings
12
+ * @copyright BoldGrid
13
+ * @version $Id$
14
+ * @author BoldGrid <support@boldgrid.com>
15
  */
16
 
17
+ defined( 'WPINC' ) || die;
18
 
19
+ // Get retention count setting. Limit 1-99, default is from config.
20
+ $retention_count = isset( $settings['retention_count'] ) && 99 >= $settings['retention_count'] ?
21
+ $settings['retention_count'] : $this->core->config->get_default_retention();
22
+
23
+ if ( $retention_count > 99 ) {
24
+ $retention_count = 99;
25
+ }
26
 
27
+ ob_start();
28
  ?>
29
 
30
  <div class="bg-box">
32
  <?php esc_html_e( 'Retention', 'boldgrid-backup' ); ?>
33
  </div>
34
  <div class="bg-box-bottom">
35
+ <table class='form-table'>
36
+ <tr>
37
+ <th><label for="retention_count">
38
+ <?php esc_html_e( 'Number of backup archives to retain', 'boldgrid-backup' ); ?> (1 - 99):
39
+ </label></th>
40
+ <td><input type="number" id='retention-count' name='retention_count' min="1" max="99"
41
+ value="<?php echo esc_attr( $retention_count ); ?>" required /></td>
42
+ </tr>
43
+ </table>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
  </div>
45
  </div>
46
 
47
  <?php
48
  $output = ob_get_contents();
49
  ob_end_clean();
50
+
51
  return $output;
 
admin/partials/settings/scheduler.php CHANGED
@@ -1,17 +1,25 @@
1
  <?php
2
  /**
 
 
3
  * Show "Scheduler" on settings page.
4
  *
 
5
  * @since 1.5.1
 
 
 
 
 
 
6
  */
7
 
8
- defined( 'WPINC' ) ? : die;
9
 
10
  $schedulers_available = $this->core->scheduler->get_available();
11
-
12
- $schedulers_count = count( $schedulers_available );
13
-
14
- $scheduler = ! empty( $settings['scheduler'] ) ? $settings['scheduler'] : false;
15
 
16
  // No need to show the user any options if there is only 1 scheduler available.
17
  if ( 1 === $schedulers_count ) {
@@ -23,8 +31,10 @@ $wp_cron_warning = sprintf(
23
  __( 'When using WP Cron, we cannot guarantee that backups will be created at the times you specify. Cron is the recommended scheduler.', 'boldgrid-backup' )
24
  );
25
 
26
- $scheduler_options = '';
27
  foreach ( $schedulers_available as $key => $scheduler_data ) {
 
 
 
28
  $scheduler_options .= sprintf(
29
  '<option value="%1$s" %3$s>%2$s</option>',
30
  $key,
@@ -35,10 +45,11 @@ foreach ( $schedulers_available as $key => $scheduler_data ) {
35
 
36
  $scheduler_select = sprintf( '<select name="scheduler" id="scheduler">%1$s</select>', $scheduler_options );
37
 
38
- return sprintf( '
 
39
  <div class="bg-box">
40
  <div class="bg-box-top">
41
- %1$s
42
  </div>
43
  <div class="bg-box-bottom">
44
  %2$s
@@ -47,7 +58,6 @@ return sprintf( '
47
  </div>',
48
  __( 'Scheduler', 'boldgrid-backup' ),
49
  $scheduler_select,
50
- $wp_cron_warning
 
51
  );
52
-
53
-
1
  <?php
2
  /**
3
+ * File: scheduler.php
4
+ *
5
  * Show "Scheduler" on settings page.
6
  *
7
+ * @link https://www.boldgrid.com
8
  * @since 1.5.1
9
+ *
10
+ * @package Boldgrid_Backup
11
+ * @subpackage Boldgrid_Backup/admin/partials/settings
12
+ * @copyright BoldGrid
13
+ * @version $Id$
14
+ * @author BoldGrid <support@boldgrid.com>
15
  */
16
 
17
+ defined( 'WPINC' ) || die;
18
 
19
  $schedulers_available = $this->core->scheduler->get_available();
20
+ $schedulers_count = count( $schedulers_available );
21
+ $scheduler = ! empty( $settings['scheduler'] ) ? $settings['scheduler'] : false;
22
+ $scheduler_options = '';
 
23
 
24
  // No need to show the user any options if there is only 1 scheduler available.
25
  if ( 1 === $schedulers_count ) {
31
  __( 'When using WP Cron, we cannot guarantee that backups will be created at the times you specify. Cron is the recommended scheduler.', 'boldgrid-backup' )
32
  );
33
 
 
34
  foreach ( $schedulers_available as $key => $scheduler_data ) {
35
+ $scheduler_data['title'] = $scheduler_data['title'] . ( 'cron' === $key ?
36
+ ' (' . esc_html__( 'Recommended', 'boldgrid-backup' ) . ')' : '' );
37
+
38
  $scheduler_options .= sprintf(
39
  '<option value="%1$s" %3$s>%2$s</option>',
40
  $key,
45
 
46
  $scheduler_select = sprintf( '<select name="scheduler" id="scheduler">%1$s</select>', $scheduler_options );
47
 
48
+ return sprintf(
49
+ '
50
  <div class="bg-box">
51
  <div class="bg-box-top">
52
+ %1$s <span class="bgb-unbold">(%4$s)</span>
53
  </div>
54
  <div class="bg-box-bottom">
55
  %2$s
58
  </div>',
59
  __( 'Scheduler', 'boldgrid-backup' ),
60
  $scheduler_select,
61
+ $wp_cron_warning,
62
+ __( 'Advanced', 'boldgrid-backup' )
63
  );
 
 
admin/partials/settings/site-check.php ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File: site-check.php
4
+ *
5
+ * Show "Site Check" on settings page.
6
+ *
7
+ * @since 1.10.0
8
+ * @package Boldgrid_Backup
9
+ * @subpackage Boldgrid_Backup/admin/partials/settings
10
+ * @copyright BoldGrid
11
+ * @link https://www.boldgrid.com
12
+ * @author BoldGrid <support@boldgrid.com>
13
+ */
14
+
15
+ defined( 'WPINC' ) || die;
16
+ ob_start();
17
+ ?>
18
+ <div class="bg-box">
19
+ <div class="bg-box-top">
20
+ <?php esc_html_e( 'Site Check', 'boldgrid-backup' ); ?>
21
+ <span class='dashicons dashicons-editor-help' data-id='site_check'></span>
22
+ </div>
23
+ <div class="bg-box-bottom">
24
+ <p class="help" data-id="site_check">
25
+ <?php
26
+ printf(
27
+ wp_kses(
28
+ /* translators: 1: Log file path, 2: Wiki page URL address. */
29
+ __(
30
+ 'Site Check is a feature that can be enabled to periodically check your site for errors. If an error is found, it can be logged and an email alert can be sent to you. If logging is enabled, then activity is logged to a file "%1$s". More information on Site Check and the commands used can be found in the <a target="_blank" href="%2$s">wiki</a>.',
31
+ 'boldgrid-backup'
32
+ ),
33
+ [
34
+ 'a' => [
35
+ 'target' => [],
36
+ 'href' => [],
37
+ ],
38
+ ]
39
+ ),
40
+ esc_url( BOLDGRID_BACKUP_PATH . '/cli/bgbkup-cli.log' ),
41
+ esc_url( 'https://github.com/BoldGrid/boldgrid-backup/wiki/CLI-Commands' )
42
+ );
43
+ ?>
44
+ </p>
45
+ <table class="form-table">
46
+ <tr>
47
+ <th><?php esc_html_e( 'Site Checker', 'boldgrid-backup' ); ?></th>
48
+ <td>
49
+ <input id="site-check-enabled" type="radio" name="site_check" value="1"
50
+ <?php
51
+ if ( $settings['site_check']['enabled'] ) {
52
+ echo ' checked'; // Default.
53
+ }
54
+ ?>
55
+ /> <label for="site-check-enabled"><?php esc_html_e( 'Enabled', 'boldgrid-backup' ); ?></label>
56
+ &nbsp; <input id="site-check-disabled" type="radio" name="site_check" value="0"
57
+ <?php
58
+ if ( ! $settings['site_check']['enabled'] ) {
59
+ echo ' checked';
60
+ }
61
+ ?>
62
+ /> <label for="site-check-disabled"><?php esc_html_e( 'Disabled', 'boldgrid-backup' ); ?></label>
63
+ </td>
64
+ </tr>
65
+ <tr>
66
+ <th><?php esc_html_e( 'Check Interval (in minutes)', 'boldgrid-backup' ); ?></th>
67
+ <td>
68
+ <input id="site-check-interval" name="site_check_interval" type="number"
69
+ min="5" max="59" value="<?php echo esc_attr( $settings['site_check']['interval'] ); ?>" />
70
+ </td>
71
+ </tr>
72
+ <tr>
73
+ <th><?php esc_html_e( 'Logger', 'boldgrid-backup' ); ?></th>
74
+ <td>
75
+ <input id="site-check-logger-enabled" type="radio" name="site_check_logger" value="1"
76
+ <?php
77
+ if ( $settings['site_check']['logger'] ) {
78
+ echo ' checked'; // Default.
79
+ }
80
+ ?>
81
+ /> <label for="site-check-logger-enabled"><?php esc_html_e( 'Enabled', 'boldgrid-backup' ); ?></label>
82
+ &nbsp; <input id="site-check-logger-disabled" type="radio" name="site_check_logger" value="0"
83
+ <?php
84
+ if ( ! $settings['site_check']['logger'] ) {
85
+ echo ' checked';
86
+ }
87
+ ?>
88
+ /> <label for="site-check-logger-disabled"><?php esc_html_e( 'Disabled', 'boldgrid-backup' ); ?></label>
89
+ </td>
90
+ </tr>
91
+ <tr id="auto-recovery-tr">
92
+ <th><?php esc_html_e( 'Auto Recovery', 'boldgrid-backup' ); ?></th>
93
+ <td>
94
+ <input id="auto-recovery-enabled" type="radio" name="auto_recovery" value="1"
95
+ <?php
96
+ if ( $settings['site_check']['auto_recovery'] ) {
97
+ echo ' checked';
98
+ }
99
+ ?>
100
+ /> <label for="auto-recovery-enabled"><?php esc_html_e( 'Enabled', 'boldgrid-backup' ); ?></label>
101
+ &nbsp; <input id="auto-recovery-disabled" type="radio" name="auto_recovery" value="0"
102
+ <?php
103
+ if ( ! $settings['site_check']['auto_recovery'] ) {
104
+ echo ' checked'; // Default.
105
+ }
106
+ ?>
107
+ /> <label for="auto-recovery-enabled"><?php esc_html_e( 'Disabled', 'boldgrid-backup' ); ?></label>
108
+ </td>
109
+ </tr>
110
+ </table>
111
+ </div>
112
+ </div>
113
+ <?php
114
+ $output = ob_get_contents();
115
+ ob_end_clean();
116
+
117
+ return $output;
admin/partials/settings/storage-location.php CHANGED
@@ -1,13 +1,19 @@
1
  <?php
2
-
3
  /**
4
- * Display a single provider on the settings page.
5
  *
6
- * This page returns the html markup needed for the <tr> #storage_locations
7
- * table.
8
  *
 
9
  * @since 1.5.2
10
  *
 
 
 
 
 
 
11
  * @param array $location {
12
  * A remote storage location / provider.
13
  *
@@ -22,14 +28,21 @@
22
  * @return string
23
  */
24
 
25
- defined( 'WPINC' ) ? : die;
26
 
27
  $configure = '';
28
 
 
 
 
 
 
 
 
29
  $configure_link = '<a href="%1$s&TB_iframe=true&width=600&height=550" class="thickbox">%2$s</a>';
30
 
31
  if ( $location['is_setup'] && ! empty( $location['configure'] ) ) {
32
- $configure = sprintf( '&#10003; %1$s', __( 'Configured', 'boldgrid-backup' ) );
33
  $configure .= ' (' . sprintf( $configure_link, $location['configure'], __( 'update', 'boldgrid-backup' ) ) . ')';
34
  } elseif ( ! empty( $location['configure'] ) ) {
35
  $configure .= sprintf( $configure_link, $location['configure'], __( 'Configure', 'boldgrid-backup' ) );
@@ -39,13 +52,15 @@ $disabled = $location['is_setup'] ? '' : 'disabled';
39
 
40
  $checked = isset( $location['enabled'] ) && true === $location['enabled'] ? 'checked' : '';
41
 
42
- return sprintf( '
 
43
  <tr data-key="%4$s">
44
- <td>
45
  <input type="checkbox" name="storage_location[%4$s]" value="1" %3$s %5$s> <strong>%1$s</strong>
46
  </td>
47
  <td class="configure">
48
  %2$s
 
49
  </td>
50
  </tr>
51
  ',
@@ -53,7 +68,6 @@ return sprintf( '
53
  $configure,
54
  $disabled,
55
  $location['key'],
56
- $checked
 
57
  );
58
-
59
-
1
  <?php
 
2
  /**
3
+ * File: storage-location.php
4
  *
5
+ * Display a single provider on the settings page.
6
+ * This page returns the html markup needed for the <tr> #storage_locations table.
7
  *
8
+ * @link https://www.boldgrid.com
9
  * @since 1.5.2
10
  *
11
+ * @package Boldgrid_Backup
12
+ * @subpackage Boldgrid_Backup/admin/partials/settings
13
+ * @copyright BoldGrid
14
+ * @version $Id$
15
+ * @author BoldGrid <support@boldgrid.com>
16
+ *
17
  * @param array $location {
18
  * A remote storage location / provider.
19
  *
28
  * @return string
29
  */
30
 
31
+ defined( 'WPINC' ) || die;
32
 
33
  $configure = '';
34
 
35
+ // Some storage locations need to be authorized, such as Google Drive.
36
+ if ( ! empty( $location['authorized'] ) ) {
37
+ $configure = sprintf( '&#10003; %1$s | ', __( 'Authorized', 'boldgrid-backup' ) );
38
+ } elseif ( ! empty( $location['authorize'] ) ) {
39
+ $configure .= '<a href="' . esc_url( $location['authorize'] ) . '">' . __( 'Authorize', 'boldgrid-backup' ) . '</a> | ';
40
+ }
41
+
42
  $configure_link = '<a href="%1$s&TB_iframe=true&width=600&height=550" class="thickbox">%2$s</a>';
43
 
44
  if ( $location['is_setup'] && ! empty( $location['configure'] ) ) {
45
+ $configure .= sprintf( '&#10003; %1$s', __( 'Configured', 'boldgrid-backup' ) );
46
  $configure .= ' (' . sprintf( $configure_link, $location['configure'], __( 'update', 'boldgrid-backup' ) ) . ')';
47
  } elseif ( ! empty( $location['configure'] ) ) {
48
  $configure .= sprintf( $configure_link, $location['configure'], __( 'Configure', 'boldgrid-backup' ) );
52
 
53
  $checked = isset( $location['enabled'] ) && true === $location['enabled'] ? 'checked' : '';
54
 
55
+ return sprintf(
56
+ '
57
  <tr data-key="%4$s">
58
+ <td style="vertical-align:top; min-width:120px;">
59
  <input type="checkbox" name="storage_location[%4$s]" value="1" %3$s %5$s> <strong>%1$s</strong>
60
  </td>
61
  <td class="configure">
62
  %2$s
63
+ %6$s
64
  </td>
65
  </tr>
66
  ',
68
  $configure,
69
  $disabled,
70
  $location['key'],
71
+ $checked,
72
+ ( empty( $location['error'] ) ? '' : '<div class="notice notice-error inline" style="margin-bottom:0;">' . esc_html( $location['error'] ) . '</div>' )
73
  );
 
 
admin/partials/settings/storage.php CHANGED
@@ -1,25 +1,25 @@
1
  <?php
2
  /**
3
- * Display "Backup Storage" options.
4
  *
5
- * This file is included on the BoldGrid Backup Settings page and helps render
6
- * the "Backup Storage" section.
7
  *
 
8
  * @since 1.5.2
 
 
 
 
 
 
9
  */
10
 
11
- defined( 'WPINC' ) ? : die;
12
 
13
  ob_start();
14
 
15
- $storage_locations = array(
16
- array(
17
- 'title' => __( 'Web Server', 'boldgrid-backup' ),
18
- 'key' => 'local',
19
- 'is_setup' => true,
20
- 'enabled' => ! empty( $settings['remote']['local']['enabled'] ) && true === $settings['remote']['local']['enabled'],
21
- ),
22
- );
23
 
24
  /**
25
  * Allow other storage providers to register themselves.
@@ -38,17 +38,38 @@ $storage_locations = array(
38
  */
39
  $storage_locations = apply_filters( 'boldgrid_backup_register_storage_location', $storage_locations );
40
 
41
- $premium_box = $this->core->config->is_premium_done ? '' : sprintf( '
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  <div class="bg-box-bottom premium">
43
- <input type="checkbox" disabled="true" /> <strong>%1$s</strong>
44
 
45
  <p>
46
  %2$s
47
  %3$s
48
  </p>
49
  </div>',
50
- /* 1 */ __( 'Amazon S3', 'boldgrid-backup' ),
51
- /* 2 */ $this->core->go_pro->get_premium_button(),
52
  /* 3 */ __( 'Upgrade to premium for more Storage Locations!', 'boldgrid-backup' )
53
  );
54
 
@@ -56,19 +77,31 @@ $premium_box = $this->core->config->is_premium_done ? '' : sprintf( '
56
 
57
  <div class='bg-box'>
58
  <div class='bg-box-top'>
59
- <?php echo __( 'Backup Storage', 'boldgrid-backup' ); ?>
60
  <?php echo '<span class="dashicons dashicons-editor-help" data-id="remote_storage"></span>'; ?>
61
  </div>
62
  <div class='bg-box-bottom'>
63
  <p class="help" data-id="remote_storage">
64
- <?php echo __( 'The following is a list of storage locations available to store your backup archives on. It is recommended to store your backups on at least 2 different storage locations. You can find more information <a href="admin.php?page=boldgrid-backup-tools&section=section_locations">here</a>.', 'boldgrid-backup' ); ?>
 
 
 
 
 
 
 
 
 
 
 
 
65
  </p>
66
 
67
  <table id="storage_locations">
68
  <?php
69
  foreach ( $storage_locations as $location ) {
70
  $tr = include BOLDGRID_BACKUP_PATH . '/admin/partials/settings/storage-location.php';
71
- echo $tr;
72
  }
73
  ?>
74
  </table>
@@ -76,14 +109,13 @@ $premium_box = $this->core->config->is_premium_done ? '' : sprintf( '
76
  <br />
77
  <p class="hidden" id="no_storage">
78
  <span class="dashicons dashicons-warning yellow"></span>
79
- <?php echo __( 'Backup will not occur if no storage locations are selected.', 'boldgrid-backup' ); ?>
80
  </p>
81
  </div>
82
- <?php echo $premium_box; ?>
83
  </div>
84
 
85
  <?php
86
  $output = ob_get_contents();
87
  ob_end_clean();
88
  return $output;
89
- ?>
1
  <?php
2
  /**
3
+ * File: storage.php
4
  *
5
+ * This file is included on the settings page and helps render the "Backup Storage" section.
 
6
  *
7
+ * @link https://www.boldgrid.com
8
  * @since 1.5.2
9
+ *
10
+ * @package Boldgrid_Backup
11
+ * @subpackage Boldgrid_Backup/admin/partials/settings
12
+ * @copyright BoldGrid
13
+ * @version $Id$
14
+ * @author BoldGrid <support@boldgrid.com>
15
  */
16
 
17
+ defined( 'WPINC' ) || die;
18
 
19
  ob_start();
20
 
21
+ // Add the web server storage details.
22
+ $storage_locations = [ $this->core->local->get_webserver_details() ];
 
 
 
 
 
 
23
 
24
  /**
25
  * Allow other storage providers to register themselves.
38
  */
39
  $storage_locations = apply_filters( 'boldgrid_backup_register_storage_location', $storage_locations );
40
 
41
+ /*
42
+ * Create markup containing a list of premium storage providers. These will only be shown to the user
43
+ * if they are on the free version.
44
+ */
45
+ $premium_inputs = '';
46
+ if ( ! $this->core->config->is_premium_done ) {
47
+ foreach ( $this->core->configs['premium_remote'] as $provider ) {
48
+ $premium_inputs .= '<p><input type="checkbox" disabled="true" /> ';
49
+
50
+ if ( ! empty( $provider['logo_class'] ) ) {
51
+ $premium_inputs .= '<span style="vertical-align:top;" title="' . esc_attr( $provider['title'] ) . '" class="' . esc_attr( $provider['logo_class'] ) . '"></span>';
52
+ } else {
53
+ $premium_inputs .= '<strong>' . esc_html( $provider['title'] ) . '</strong>';
54
+ }
55
+
56
+ $premium_inputs .= '</p>';
57
+ }
58
+ }
59
+
60
+ $premium_url = $this->core->go_pro->get_premium_url( 'bgbkup-settings-storage' );
61
+ $premium_box = $this->core->config->is_premium_done ? '' : sprintf(
62
+ '
63
  <div class="bg-box-bottom premium">
64
+ %1$s
65
 
66
  <p>
67
  %2$s
68
  %3$s
69
  </p>
70
  </div>',
71
+ /* 1 */ $premium_inputs,
72
+ /* 2 */ $this->core->go_pro->get_premium_button( $premium_url ),
73
  /* 3 */ __( 'Upgrade to premium for more Storage Locations!', 'boldgrid-backup' )
74
  );
75
 
77
 
78
  <div class='bg-box'>
79
  <div class='bg-box-top'>
80
+ <?php esc_html_e( 'Backup Storage', 'boldgrid-backup' ); ?>
81
  <?php echo '<span class="dashicons dashicons-editor-help" data-id="remote_storage"></span>'; ?>
82
  </div>
83
  <div class='bg-box-bottom'>
84
  <p class="help" data-id="remote_storage">
85
+ <?php
86
+ printf(
87
+ wp_kses(
88
+ // translators: 1: URL address.
89
+ __(
90
+ 'The following is a list of storage locations available to store your backup archives on. It is recommended to store your backups on at least 2 different storage locations. You can find more information <a href="%1$s">here</a>.',
91
+ 'boldgrid-backup'
92
+ ),
93
+ [ 'a' => [ 'href' => [] ] ]
94
+ ),
95
+ esc_url( admin_url( 'admin.php?page=boldgrid-backup-tools&section=section_locations' ) )
96
+ );
97
+ ?>
98
  </p>
99
 
100
  <table id="storage_locations">
101
  <?php
102
  foreach ( $storage_locations as $location ) {
103
  $tr = include BOLDGRID_BACKUP_PATH . '/admin/partials/settings/storage-location.php';
104
+ echo $tr; // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
105
  }
106
  ?>
107
  </table>
109
  <br />
110
  <p class="hidden" id="no_storage">
111
  <span class="dashicons dashicons-warning yellow"></span>
112
+ <?php esc_html_e( 'Backup will not occur if no storage locations are selected.', 'boldgrid-backup' ); ?>
113
  </p>
114
  </div>
115
+ <?php echo $premium_box; // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped ?>
116
  </div>
117
 
118
  <?php
119
  $output = ob_get_contents();
120
  ob_end_clean();
121
  return $output;
 
admin/partials/settings/time-of-day.php CHANGED
@@ -1,11 +1,18 @@
1
  <?php
2
  /**
3
- * Time of day.
4
  *
5
- * @since 1.5.4
 
 
 
 
 
 
 
6
  */
7
 
8
- defined( 'WPINC' ) ? : die;
9
 
10
  $tz_info = $this->core->time->get_timezone_info();
11
 
@@ -20,14 +27,15 @@ ob_start();
20
  <select id='tod-h' name='tod_h'>
21
  <?php
22
  for ( $x = 1; $x <= 12; $x ++ ) {
23
- ?>
24
- <option value='<?php echo $x;?>'
25
- <?php
26
- if ( ! empty( $settings['schedule']['tod_h'] ) && $x === $settings['schedule']['tod_h'] ) {
27
- echo ' selected';
28
- }
29
- ?>><?php echo $x;?></option>
30
- <?php
 
31
  }
32
  ?>
33
  </select>
@@ -37,14 +45,15 @@ ob_start();
37
  for ( $x = 0; $x <= 59; $x ++ ) {
38
  // Convert $x to a padded string.
39
  $x = str_pad( $x, 2, '0', STR_PAD_LEFT );
40
- ?>
41
- <option value='<?php echo $x;?>'
42
- <?php
43
- if ( ! empty( $settings['schedule']['tod_m'] ) && $x == $settings['schedule']['tod_m'] ) {
44
- echo ' selected';
45
- }
46
- ?>><?php echo $x;?></option>
47
- <?php
 
48
  }
49
  ?>
50
  </select>
@@ -55,20 +64,24 @@ ob_start();
55
  if ( ! isset( $settings['schedule']['tod_a'] ) || 'PM' !== $settings['schedule']['tod_a'] ) {
56
  echo ' selected';
57
  }
58
- ?>>AM</option>
 
59
  <option value='PM'
60
  <?php
61
  if ( isset( $settings['schedule']['tod_a'] ) && 'PM' === $settings['schedule']['tod_a'] ) {
62
  echo ' selected';
63
  }
64
- ?>>PM</option>
 
65
  </select>
66
 
67
  <div style="vertical-align:middle;display:inline-block;">
68
- <?php echo $tz_info['markup_timezone'] . ' <em>' . $tz_info['markup_change'] . '</em>' ?>
 
 
69
  </div>
70
 
71
- <p class="wp-cron-notice hidden"><em>WP Cron runs on GMT time, which is currently <?php echo date( 'l g:i a e' )?>.</em></p>
72
  </div>
73
  </div>
74
 
@@ -76,4 +89,3 @@ ob_start();
76
  $output = ob_get_contents();
77
  ob_end_clean();
78
  return $output;
79
- ?>
1
  <?php
2
  /**
3
+ * File: time-of-day.php
4
  *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.6.0
7
+ *
8
+ * @package Boldgrid_Backup
9
+ * @subpackage Boldgrid_Backup/admin/partials/settings
10
+ * @copyright BoldGrid
11
+ * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
  */
14
 
15
+ defined( 'WPINC' ) || die;
16
 
17
  $tz_info = $this->core->time->get_timezone_info();
18
 
27
  <select id='tod-h' name='tod_h'>
28
  <?php
29
  for ( $x = 1; $x <= 12; $x ++ ) {
30
+ ?>
31
+ <option value='<?php echo esc_attr( $x ); ?>'
32
+ <?php
33
+ if ( ! empty( $settings['schedule']['tod_h'] ) && $x == $settings['schedule']['tod_h'] ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
34
+ echo ' selected';
35
+ }
36
+ ?>
37
+ ><?php echo esc_html( $x ); ?></option>
38
+ <?php
39
  }
40
  ?>
41
  </select>
45
  for ( $x = 0; $x <= 59; $x ++ ) {
46
  // Convert $x to a padded string.
47
  $x = str_pad( $x, 2, '0', STR_PAD_LEFT );
48
+ ?>
49
+ <option value='<?php echo esc_attr( $x ); ?>'
50
+ <?php
51
+ if ( ! empty( $settings['schedule']['tod_m'] ) && $x === $settings['schedule']['tod_m'] ) {
52
+ echo ' selected';
53
+ }
54
+ ?>
55
+ ><?php echo esc_html( $x ); ?></option>
56
+ <?php
57
  }
58
  ?>
59
  </select>
64
  if ( ! isset( $settings['schedule']['tod_a'] ) || 'PM' !== $settings['schedule']['tod_a'] ) {
65
  echo ' selected';
66
  }
67
+ ?>
68
+ >AM</option>
69
  <option value='PM'
70
  <?php
71
  if ( isset( $settings['schedule']['tod_a'] ) && 'PM' === $settings['schedule']['tod_a'] ) {
72
  echo ' selected';
73
  }
74
+ ?>
75
+ >PM</option>
76
  </select>
77
 
78
  <div style="vertical-align:middle;display:inline-block;">
79
+ <?php
80
+ echo $tz_info['markup_timezone'] . ' <em>' . $tz_info['markup_change'] . '</em>'; // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
81
+ ?>
82
  </div>
83
 
84
+ <p class="wp-cron-notice hidden"><em>WP Cron runs on GMT time, which is currently <?php echo esc_html( date( 'l g:i a e' ) ); ?>.</em></p>
85
  </div>
86
  </div>
87
 
89
  $output = ob_get_contents();
90
  ob_end_clean();
91
  return $output;
 
admin/partials/tools/local-remote.php CHANGED
@@ -1,52 +1,71 @@
1
  <?php
2
  /**
 
 
3
  * Show "Auto Updates" on settings page.
4
  *
5
- * @since 1.5.4
 
 
 
 
 
 
6
  */
7
 
8
- defined( 'WPINC' ) ? : die;
9
 
10
- // https://github.com/cbschuld/Browser.php
11
- include_once BOLDGRID_BACKUP_PATH . '/vendor/cbschuld/browser.php/lib/Browser.php';
12
- $browser = new Browser();
13
 
14
  ob_start();
15
 
16
- $local_info = array(
17
- array(
 
 
 
 
 
 
18
  'title' => __( 'Browser', 'boldgrid-backup' ),
19
- 'value' => $browser->getBrowser() . ' ' . $browser->getVersion(),
20
- ),
21
- array(
 
 
22
  'title' => __( 'Operating System', 'boldgrid-backup' ),
23
- 'value' => $browser->getPlatform(),
24
- ),
25
- );
26
 
27
  $local_info_markup = '';
 
28
  foreach ( $local_info as $info ) {
29
  if ( empty( $info['value'] ) ) {
30
  continue;
31
  }
32
 
33
- $local_info_markup .= sprintf( '<li><strong>%1$s</strong>: %2$s</li>', $info['title'], $info['value'] );
 
 
 
 
34
  }
35
 
36
- $server_info = array(
37
- array(
38
  'title' => __( 'Server Name', 'boldgrid-backup' ),
39
- 'key' => 'SERVER_NAME',
40
- ),
41
- array(
42
  'title' => __( 'Server IP Address', 'boldgrid-backup' ),
43
- 'key' => 'SERVER_ADDR',
44
- ),
45
- array(
46
- 'title' => __( 'Server Type / OS', 'boldgrid-backup' ),
47
- 'key' => 'SERVER_SOFTWARE',
48
- ),
49
- );
50
 
51
  $server_info_markup = '';
52
  foreach ( $server_info as $info ) {
@@ -54,77 +73,160 @@ foreach ( $server_info as $info ) {
54
  continue;
55
  }
56
 
57
- $server_info_markup .= sprintf( '<li><strong>%1$s</strong>: %2$s</li>', $info['title'], $_SERVER[ $info['key'] ] );
 
 
 
 
58
  }
59
 
60
- printf( '
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  <h2>%1$s</h2>
62
  <p>%2$s</p>
63
  <p>%3$s</p>
64
  <hr />',
65
- __( 'Where should I store my backups?', 'boldgrid-backup' ),
66
- __( 'Throughout the BoldGrid Backup plugin, you will see references to <strong>Local Machine</strong>, <strong>Web Server</strong>, and <strong>Remote Storage</strong>. These are all locations you can save your backup archives to.', 'boldgrid-backup' ),
67
- __( 'Continue reading below to find out more about each. It is recommended to store backup archives in at least 2 different storage locations.', 'boldgrid-backup' )
 
 
 
 
 
 
 
 
 
 
 
 
68
  );
69
 
 
70
 
71
-
72
- printf( '<h3>%1$s</h3>', __( 'Local Machine', 'boldgrid-backup' ) );
73
-
74
  printf(
75
- '<p>%1$s</p>',
76
- __( 'Your <strong>Local Machine</strong> is the device you are using right now to access the internet. It could be a desktop, laptop, tablet, or even a smart phone.', 'boldgrid-backup' )
 
 
 
 
 
77
  );
 
78
 
79
  if ( ! empty( $local_info_markup ) ) {
80
- printf( '
 
81
  <p>%1$s</p>
82
  %2$s',
83
- __( 'We are able to see the following information about your <strong>Local Machine</strong>:', 'boldgrid-backup' ),
84
- $local_info_markup
 
 
 
 
 
 
 
 
85
  );
86
  }
87
 
88
  echo '<hr />';
89
-
90
- printf( '<h3>%1$s</h3>', __( 'Web Server', 'boldgrid-backup' ) );
91
-
92
  printf(
93
- '<p>%1$s</p>',
94
- __( 'The <strong>Web Server</strong> is the server where your WordPress website lives. You usually pay your web hosting provider monthly or yearly for hosting.', 'boldgrid-backup' )
 
 
 
 
 
95
  );
 
96
 
97
  if ( ! empty( $server_info_markup ) ) {
98
- printf( '
 
99
  <p>%1$s</p>
100
  %2$s',
101
- __( 'We are able to see the following information about your <strong>Web Server</strong>:', 'boldgrid-backup' ),
102
- $server_info_markup
 
 
 
 
 
 
 
 
103
  );
104
  }
105
 
106
  echo '<hr />';
107
 
108
- printf( '<h3>%1$s</h3>', __( 'Remote Storage', 'boldgrid-backup' ) );
109
 
 
110
  printf(
111
- '<p>%1$s</p>',
112
- __( '<strong>Remote Storage</strong> providers are servers other than your <em>Local Machine</em> and <em>Web Server</em> where you can store files. For example, <em>FTP</em>, <em>SFTP</em>, and <em>Amazon S3</em> are all considered Remote Storage Providers.', 'boldgrid-backup' )
 
 
 
 
 
 
 
 
 
113
  );
 
114
 
115
  if ( ! $this->core->config->is_premium_done ) {
116
- printf( '
 
 
117
  <div class="bg-box-bottom premium wp-clearfix">
118
  %1$s
119
  %2$s
120
  </div>',
121
- $this->core->go_pro->get_premium_button(),
122
- __( 'Upgrade to <strong>BoldGrid Backup Premium</strong> to gain access to more <em>Remote Storage Providers</em>.', 'boldgrid-backup' )
 
 
 
 
 
 
 
 
 
123
  );
124
  }
125
 
126
-
127
  $output = ob_get_contents();
128
  ob_end_clean();
129
- return $output;
130
 
 
1
  <?php
2
  /**
3
+ * File: local-remote.php
4
+ *
5
  * Show "Auto Updates" on settings page.
6
  *
7
+ * @link https://www.boldgrid.com
8
+ * @since 1.6.0
9
+ *
10
+ * @package Boldgrid_Backup
11
+ * @subpackage Boldgrid_Backup/admin/partials/tools
12
+ * @copyright BoldGrid
13
+ * @author BoldGrid <support@boldgrid.com>
14
  */
15
 
16
+ // phpcs:disable WordPress.VIP
17
 
18
+ defined( 'WPINC' ) || die;
 
 
19
 
20
  ob_start();
21
 
22
+ preg_match(
23
+ '/\(([^\)]+)\).+?(MSIE|(?!Gecko.+)Firefox|(?!AppleWebKit.+Chrome.+)Safari|(?!AppleWebKit.+)Chrome|AppleWebKit(?!.+Chrome|.+Safari)|Gecko(?!.+Firefox))(?: |\/)([\d\.apre]+)/',
24
+ $_SERVER['HTTP_USER_AGENT'],
25
+ $browser_info
26
+ );
27
+
28
+ $local_info = [
29
+ [
30
  'title' => __( 'Browser', 'boldgrid-backup' ),
31
+ 'value' => ( ! empty( $browser_info[2] ) ? $browser_info[2] : __( 'Unknown browser', 'boldgrid-backup' ) ) .
32
+ ' ' .
33
+ ( ! empty( $browser_info[3] ) ? $browser_info[3] : __( 'Unknown version', 'boldgrid-backup' ) ),
34
+ ],
35
+ [
36
  'title' => __( 'Operating System', 'boldgrid-backup' ),
37
+ 'value' => ! empty( $browser_info[1] ) ? $browser_info[1] : __( 'Unknown', 'boldgrid-backup' ),
38
+ ],
39
+ ];
40
 
41
  $local_info_markup = '';
42
+
43
  foreach ( $local_info as $info ) {
44
  if ( empty( $info['value'] ) ) {
45
  continue;
46
  }
47
 
48
+ $local_info_markup .= sprintf(
49
+ '<li><strong>%1$s</strong>: %2$s</li>',
50
+ esc_html( $info['title'] ),
51
+ esc_html( $info['value'] )
52
+ );
53
  }
54
 
55
+ $server_info = [
56
+ [
57
  'title' => __( 'Server Name', 'boldgrid-backup' ),
58
+ 'key' => 'SERVER_NAME',
59
+ ],
60
+ [
61
  'title' => __( 'Server IP Address', 'boldgrid-backup' ),
62
+ 'key' => 'SERVER_ADDR',
63
+ ],
64
+ [
65
+ 'title' => __( 'Server Type', 'boldgrid-backup' ),
66
+ 'key' => 'SERVER_SOFTWARE',
67
+ ],
68
+ ];
69
 
70
  $server_info_markup = '';
71
  foreach ( $server_info as $info ) {
73
  continue;
74
  }
75
 
76
+ $server_info_markup .= sprintf(
77
+ '<li><strong>%1$s</strong>: %2$s</li>',
78
+ $info['title'],
79
+ $_SERVER[ $info['key'] ]
80
+ );
81
  }
82
 
83
+ if ( function_exists( 'php_uname' ) ) {
84
+ $server_architecture = sprintf(
85
+ '%1$s %2$s %3$s',
86
+ php_uname( 's' ),
87
+ php_uname( 'r' ),
88
+ php_uname( 'm' )
89
+ );
90
+ } else {
91
+ $server_architecture = __( 'Unknown', 'boldgrid-backup' );
92
+ }
93
+
94
+ $server_info_markup .= sprintf(
95
+ '<li><strong>%1$s</strong>: %2$s</li>',
96
+ __( 'Server OS', 'boldgrid-backup' ),
97
+ $server_architecture
98
+ );
99
+
100
+ printf(
101
+ '
102
  <h2>%1$s</h2>
103
  <p>%2$s</p>
104
  <p>%3$s</p>
105
  <hr />',
106
+ esc_html__( 'Where should I store my backups?', 'boldgrid-backup' ),
107
+ sprintf(
108
+ // translators: 1: HTML strong open tag. 2: HTML strong close tag, 3: Plugin title.
109
+ esc_html__(
110
+ 'Throughout the %3$s plugin, you will see references to %1$sLocal Machine%2$s, %1$sWeb Server%2$s, and %1$sRemote Storage%2$s. These are all locations you can save your backup archives to.',
111
+ 'boldgrid-backup'
112
+ ),
113
+ '<strong>',
114
+ '</strong>',
115
+ esc_html( BOLDGRID_BACKUP_TITLE )
116
+ ),
117
+ esc_html__(
118
+ 'Continue reading below to find out more about each. It is recommended to store backup archives in at least 2 different storage locations.',
119
+ 'boldgrid-backup'
120
+ )
121
  );
122
 
123
+ printf( '<h3>%1$s</h3>', esc_html__( 'Local Machine', 'boldgrid-backup' ) );
124
 
125
+ echo '<p>';
 
 
126
  printf(
127
+ // translators: 1: HTML strong open tag. 2: HTML strong close tag.
128
+ esc_html__(
129
+ 'Your %1$sLocal Machine%2$s is the device you are using right now to access the internet. It could be a desktop, laptop, tablet, or even a smart phone.',
130
+ 'boldgrid-backup'
131
+ ),
132
+ '<strong>',
133
+ '</strong>'
134
  );
135
+ echo '</p>';
136
 
137
  if ( ! empty( $local_info_markup ) ) {
138
+ printf(
139
+ '
140
  <p>%1$s</p>
141
  %2$s',
142
+ sprintf(
143
+ // translators: 1: HTML strong open tag. 2: HTML strong close tag.
144
+ esc_html__(
145
+ 'We are able to see the following information about your %1$sLocal Machine%2$s:',
146
+ 'boldgrid-backup'
147
+ ),
148
+ '<strong>',
149
+ '</strong>'
150
+ ),
151
+ $local_info_markup // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
152
  );
153
  }
154
 
155
  echo '<hr />';
156
+ printf( '<h3>%1$s</h3>', esc_html__( 'Web Server', 'boldgrid-backup' ) );
157
+ echo '<p>';
 
158
  printf(
159
+ // translators: 1: HTML strong open tag. 2: HTML strong close tag.
160
+ esc_html__(
161
+ 'The %1$sWeb Server%2$s is the server where your WordPress website lives. You usually pay your web hosting provider monthly or yearly for hosting.',
162
+ 'boldgrid-backup'
163
+ ),
164
+ '<strong>',
165
+ '</strong>'
166
  );
167
+ echo '</p>';
168
 
169
  if ( ! empty( $server_info_markup ) ) {
170
+ printf(
171
+ '
172
  <p>%1$s</p>
173
  %2$s',
174
+ sprintf(
175
+ // translators: 1: HTML strong open tag. 2: HTML strong close tag.
176
+ esc_html__(
177
+ 'We are able to see the following information about your %1$sWeb Server%2$s:',
178
+ 'boldgrid-backup'
179
+ ),
180
+ '<strong>',
181
+ '</strong>'
182
+ ),
183
+ $server_info_markup // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
184
  );
185
  }
186
 
187
  echo '<hr />';
188
 
189
+ printf( '<h3>%1$s</h3>', esc_html__( 'Remote Storage', 'boldgrid-backup' ) );
190
 
191
+ echo '<p>';
192
  printf(
193
+ // translators: 1: HTML strong open tag, 2: HTML strong close tag, 3: HTML em open tag, 4: HTML em close tag.
194
+ esc_html__(
195
+ '%1$sRemote Storage%2$s providers are servers other than your %3$sLocal Machine%4$s and %3$sWeb Server%4$s where you can store files. For example, %3$sFTP%4$s, %5$s, and %6$s are all considered Remote Storage Providers.',
196
+ 'boldgrid-backup'
197
+ ),
198
+ /* 1 */ '<strong>',
199
+ /* 2 */ '</strong>',
200
+ /* 3 */ '<em>',
201
+ /* 4 */ '</em>',
202
+ /* 5 */ '<span class="bgbkup-remote-logo bgbkup-gdrive-logo" title="' . esc_attr( __( 'Google Drive', 'boldgrid-backup' ) ) . '"></span>',
203
+ /* 6 */ '<span class="bgbkup-remote-logo amazon-s3-logo" title="' . esc_attr( __( 'Amazon S3', 'boldgrid-backup' ) ) . '"></span>'
204
  );
205
+ echo '</p>';
206
 
207
  if ( ! $this->core->config->is_premium_done ) {
208
+ $premium_url = $this->core->go_pro->get_premium_url( 'bgbkup-tools-faq-storage' );
209
+ printf(
210
+ '
211
  <div class="bg-box-bottom premium wp-clearfix">
212
  %1$s
213
  %2$s
214
  </div>',
215
+ $this->core->go_pro->get_premium_button( $premium_url, esc_html__( 'Unlock Feature', 'boldgrid-backup' ) ), // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
216
+ esc_html(
217
+ sprintf(
218
+ // translators: 1: Plugin title.
219
+ __(
220
+ 'Changed a file and now your site isn’t working properly? With %1$s, you can browse through past backup archives and restore individual files with a single click.',
221
+ 'boldgrid-backup'
222
+ ),
223
+ BOLDGRID_BACKUP_TITLE . ' Premium'
224
+ )
225
+ )
226
  );
227
  }
228
 
 
229
  $output = ob_get_contents();
230
  ob_end_clean();
 
231
 
232
+ return $output;
admin/partials/tools/view-logs.php ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File: logs.php
4
+ *
5
+ * Show "Auto Updates" on settings page.
6
+ *
7
+ * @link https://www.boldgrid.com
8
+ * @since 1.6.0
9
+ *
10
+ * @package Boldgrid_Backup
11
+ * @subpackage Boldgrid_Backup/admin/partials/tools
12
+ * @copyright BoldGrid
13
+ * @author BoldGrid <support@boldgrid.com>
14
+ */
15
+
16
+ // phpcs:disable WordPress.VIP
17
+
18
+ defined( 'WPINC' ) || die;
19
+
20
+ // Get a listing of all our logs and order them asc.
21
+ $logs_dir = $this->core->backup_dir->get_logs_dir();
22
+ $list = $this->core->wp_filesystem->dirlist( $logs_dir );
23
+ uasort( $list, function( $a, $b ) {
24
+ return $a['lastmodunix'] > $b['lastmodunix'];
25
+ });
26
+
27
+ ob_start();
28
+
29
+ echo '<h2>' . esc_html__( 'Logs', 'boldgrid-backup' ) . '</h2>';
30
+
31
+ if ( empty( $list ) ) {
32
+ echo '<div><em>' . esc_html__( 'No log files exist.', 'boldgrid-backup' ) . '</em></div>';
33
+ } else {
34
+ echo '
35
+ <table class="wp-list-table widefat fixed striped pages">
36
+ <thead>
37
+ <tr>
38
+ <th>' . esc_html__( 'Filename', 'boldgrid-backup' ) . '</th>
39
+ <th>' . esc_html__( 'Size', 'boldgrid-backup' ) . '</th>
40
+ <th>' . esc_html__( 'Timestamp', 'boldgrid-backup' ) . '</th>
41
+ </tr>
42
+ </thead>
43
+ <tbody>';
44
+
45
+ foreach ( $list as $item ) {
46
+ $this->core->time->init( $item['lastmodunix'] );
47
+
48
+ echo '
49
+ <tr>
50
+ <td>
51
+ <a
52
+ title="' . esc_attr( $item['name'] ) . '"
53
+ class="thickbox"
54
+ data-filename="' . esc_attr( $item['name'] ) . '"
55
+ href="#TB_inline&inlineId=bgbkup_show_log">' .
56
+ esc_html( $item['name'] ) .
57
+ '</a>
58
+ </td>
59
+ <td>' . esc_html( size_format( $item['size'] ) ) . '</td>
60
+ <td>' .
61
+ wp_kses(
62
+ $this->core->time->get_span(),
63
+ [
64
+ 'span' => [
65
+ 'title' => [],
66
+ ],
67
+ ]
68
+ ) . '</td>
69
+ </tr>';
70
+ }
71
+
72
+ echo '
73
+ </tbody>
74
+ </table>';
75
+ }
76
+
77
+ wp_nonce_field( 'boldgrid_backup_view_log', 'bgbup_log_nonce' );
78
+
79
+ echo '<div id="bgbkup_show_log" style="display:none;"></div>';
80
+
81
+ $output = ob_get_contents();
82
+ ob_end_clean();
83
+
84
+ return $output;
admin/partials/transfers/destination.php ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File: destination.php
4
+ *
5
+ * Show "Destnation" on transfers page.
6
+ *
7
+ * @link https://www.boldgrid.com
8
+ * @since 1.11.0
9
+ *
10
+ * @package Boldgrid_Backup
11
+ * @subpackage Boldgrid_Backup/admin/partials/transfers
12
+ * @copyright BoldGrid
13
+ * @author BoldGrid <support@boldgrid.com>
14
+ */
15
+
16
+ defined( 'WPINC' ) || die;
17
+
18
+ switch ( true ) {
19
+ case $is_premium && $is_premium_active:
20
+ // Has a premium license and the premium plugin activated.
21
+ $encrypt_message = sprintf(
22
+ // translators: 1: HTML anchor link open tag, 2: HTML anchor closing tag.
23
+ __( 'Note: If you are going to import and restore a backup containing encrypted files, then don\'t forget to copy your encryption token to your source site. You can save your encryption token on the %1$sBackup Security%2$s settings page.', 'boldgrid-backup' ),
24
+ '<a href="' .
25
+ esc_url( admin_url( 'admin.php?page=boldgrid-backup-settings&section=section_security' ) ) .
26
+ '">',
27
+ '</a>'
28
+ );
29
+ break;
30
+
31
+ case ! $is_premium:
32
+ // Does not have a premium license.
33
+ $get_premium_url = $this->core->go_pro->get_premium_url( 'bgbkup-transfer-destination' );
34
+ $encrypt_message = sprintf(
35
+ // translators: 1: Get premium button/link, 2: Premium plugin title.
36
+ __( 'If you are going to import and restore a backup containing encrypted files, then a %2$s license is required for decryption. %1$s', 'boldgrid-backup' ),
37
+ $this->core->go_pro->get_premium_button( $get_premium_url, __( 'Get Premium', 'boldgrid-backup' ) ), // phpcs:ignore
38
+ BOLDGRID_BACKUP_TITLE . ' Premium'
39
+ );
40
+ break;
41
+
42
+ case ! $is_premium_installed:
43
+ // Has a premium license, but no premium plugin is installed.
44
+ $get_plugins_url = $this->core->go_pro->get_premium_url( 'bgbkup-transfer-destination' );
45
+ $encrypt_message = sprintf(
46
+ // translators: 1: Unlock Feature button/link, 2: Premium plugin title.
47
+ esc_html__( 'The %2$s plugin is required for encryption. %1$s', 'boldgrid-backup' ),
48
+ $this->core->go_pro->get_premium_button( $get_plugins_url, __( 'Unlock Feature', 'boldgrid-backup' ) ), // phpcs:ignore
49
+ BOLDGRID_BACKUP_TITLE . ' Premium'
50
+ );
51
+ break;
52
+
53
+ case $is_premium_installed && ! $is_premium_active:
54
+ // Has a premium license and the premium plugin installed, but not activated.
55
+ $encrypt_message = sprintf(
56
+ // translators: 1: HTML anchor link open tag, 2: HTML anchor closing tag, 3: Premium plugin title.
57
+ __( '%3$s is not active and required for encryption features. Please go to the %1$sPlugins%2$s page to activate it.', 'boldgrid-backup' ),
58
+ '<a href="' .
59
+ esc_url( admin_url( 'plugins.php?s=Boldgrid%20Backup%20Premium&plugin_status=inactive' ) ) .
60
+ '">',
61
+ '</a>',
62
+ BOLDGRID_BACKUP_TITLE . ' Premium'
63
+ );
64
+ break;
65
+
66
+ default:
67
+ $encrypt_message = '';
68
+ break;
69
+ }
70
+
71
+ return sprintf(
72
+ '<div class="bgbkup-transfers-destination">
73
+ <h2>%1$s</h2>
74
+ <p>%2$s</p>
75
+ <p>%3$s</p>
76
+ <p>%9$s</p>
77
+ <div id="url-import-section" class="wp-upload-form">
78
+ %4$s <input type="text" name="url" placeholder="%5$s" size="30" />
79
+ <input class="button" type="submit" value="%6$s" />
80
+ <span class="spinner"></span>
81
+ <div id="url-import-notice" class="notice notice-success inline"></div>
82
+ %7$s
83
+ %8$s
84
+ </div>
85
+ </div>',
86
+ esc_html__( 'Use this section if you want to select this WordPress installation as the destination.', 'boldgrid_backup' ),
87
+ esc_html(
88
+ sprintf(
89
+ // translators: 1: Plugin title.
90
+ __(
91
+ 'Retrieve a download link from %1$s on another WordPress installation, paste the link in form below, and click "Upload". Once the download completes, you can either inspect the backup files and database or click "Restore".',
92
+ 'boldgrid_backup'
93
+ ),
94
+ BOLDGRID_BACKUP_TITLE
95
+ )
96
+ ),
97
+ esc_html__( 'Note: Performing a restoration in this installation will replace files and the database contents.', 'boldgrid_backup' ),
98
+ esc_html__( 'Import from a download link:', 'boldgrid-backup' ),
99
+ esc_attr__( 'Download URL address', 'boldgrid-backup' ),
100
+ esc_attr__( 'Upload', 'boldgrid-backup' ),
101
+ wp_nonce_field( 'upload_archive_file' ), // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
102
+ wp_nonce_field( 'boldgrid_backup_restore_archive', '_wpnonce_restore' ), // phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped
103
+ $encrypt_message
104
+ );
admin/partials/transfers/overview.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File: overview.php
4
+ *
5
+ * Show "Overview" on transfers page.
6
+ *
7
+ * @link https://www.boldgrid.com
8
+ * @since 1.11.0
9
+ *
10
+ * @package Boldgrid_Backup
11
+ * @subpackage Boldgrid_Backup/admin/partials/transfers
12
+ * @copyright BoldGrid
13
+ * @author BoldGrid <support@boldgrid.com>
14
+ */
15
+
16
+ defined( 'WPINC' ) || die;
17
+
18
+ return sprintf(
19
+ '<div class="bgbkup-transfers-overview">
20
+ <h2>%1$s</h2>
21
+ <p>%2$s</p>
22
+ <p>%3$s</p>
23
+ </div>',
24
+ esc_html__( 'Easily transfer websites!', 'boldgrid_backup' ),
25
+ esc_html( BOLDGRID_BACKUP_TITLE . ' ' . __( 'provides an easy way to transfer a website from one installation to another.', 'boldgrid_backup' ) ),
26
+ esc_html__( 'Use the section selection on the left to choose if this WordPress installation is either the source or destination.', 'boldgrid_backup' )
27
+ );
admin/partials/transfers/source.php ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File: source.php
4
+ *
5
+ * Show "Source" on transfers page.
6
+ *
7
+ * @link https://www.boldgrid.com
8
+ * @since 1.11.0
9
+ *
10
+ * @package Boldgrid_Backup
11
+ * @subpackage Boldgrid_Backup/admin/partials/transfers
12
+ * @copyright BoldGrid
13
+ * @author BoldGrid <support@boldgrid.com>
14
+ */
15
+
16
+ defined( 'WPINC' ) || die;
17
+
18
+ $archive_list = $this->core->archives->get_table(
19
+ [
20
+ 'show_link_button' => true,
21
+ 'transfers_mode' => true,
22
+ ]
23
+ );
24
+
25
+ $contains_encrypted = false !== strpos( $archive_list, 'bgbkup-db-encrypted' );
26
+
27
+ switch ( true ) {
28
+ case ! $contains_encrypted:
29
+ // Has no encrypted files.
30
+ $encrypt_message = '';
31
+ break;
32
+
33
+ case $contains_encrypted && $is_premium && $is_premium_active:
34
+ // Has encrypted files, a premium license, and the premium plugin activated.
35
+ $encrypt_message = sprintf(
36
+ // translators: 1: HTML anchor link open tag, 2: HTML anchor closing tag.
37
+ __( 'Note: If you are going to migrate and restore a backup containing encrypted files, then don\'t forget to copy your encryption token to your destination site. You can retrieve your encryption token on the %1$sBackup Security%2$s settings page. ', 'boldgrid-backup' ),
38
+ '<a href="' .
39
+ esc_url( admin_url( 'admin.php?page=boldgrid-backup-settings&section=section_security' ) ) .
40
+ '">',
41
+ '</a>'
42
+ );
43
+ break;
44
+
45
+ case $contains_encrypted && ! $is_premium:
46
+ // Has encrypted files but no premium license.
47
+ $get_premium_url = 'https://www.boldgrid.com/update-backup?source=bgbkup-settings-transfer-source';
48
+ $encrypt_message = sprintf(
49
+ // translators: 1: Get premium button/link, 2: Premium plugin title.
50
+ __( 'If you are going to migrate and restore a backup containing encrypted files, then a %2$s license is required for decryption. %1$s', 'boldgrid-backup' ),
51
+ $this->core->go_pro->get_premium_button( $get_premium_url, __( 'Get Premium', 'boldgrid-backup' ) ), // phpcs:ignore
52
+ BOLDGRID_BACKUP_TITLE . ' Premium'
53
+ );
54
+ break;
55
+
56
+ case $contains_encrypted && ! $is_premium_installed:
57
+ // Has encrypted files and a premium license, but no premium plugin installed.
58
+ $get_plugins_url = 'https://www.boldgrid.com/central/plugins?source=bgbkup-settings-transfer-source';
59
+ $encrypt_message = sprintf(
60
+ // translators: 1: Unlock Feature button/link, 2: Premium plugin title.
61
+ esc_html__( 'The %2$s plugin is required for encryption. %1$s', 'boldgrid-backup' ),
62
+ $this->core->go_pro->get_premium_button( $get_plugins_url, __( 'Unlock Feature', 'boldgrid-backup' ) ), // phpcs:ignore
63
+ BOLDGRID_BACKUP_TITLE . ' Premium'
64
+ );
65
+ break;
66
+
67
+ case $contains_encrypted && $is_premium_installed && ! $is_premium_active:
68
+ // Has encrypted files, a premium license, premium plugin installed, but not activated.
69
+ $encrypt_message = sprintf(
70
+ // translators: 1: HTML anchor link open tag, 2: HTML anchor closing tag, 3: Premium plugin title.
71
+ __( '%3$s is not active and required for encryption features. Please go to the %1$sPlugins%2$s page to activate it.', 'boldgrid-backup' ),
72
+ '<a href="' .
73
+ esc_url( admin_url( 'plugins.php?s=Boldgrid%20Backup%20Premium&plugin_status=inactive' ) ) .
74
+ '">',
75
+ '</a>',
76
+ BOLDGRID_BACKUP_TITLE . ' Premium'
77
+ );
78
+ break;
79
+
80
+ default:
81
+ $encrypt_message = '';
82
+ break;
83
+ }
84
+
85
+ return sprintf(
86
+ '<div class="bgbkup-transfers-source">
87
+ <h2>%1$s</h2>
88
+ <p>%2$s</p>
89
+ <p>%3$s</p>
90
+ <p>%4$s</p>
91
+ %5$s
92
+ </div>',
93
+ esc_html__( 'Use this section if you want to select this WordPress installation as the source.', 'boldgrid_backup' ),
94
+ esc_html__(
95
+ 'Choose a full backup in the list, click the "Get Download Link" button, and then click the "Copy Link" button. The download link is valid for a limited time and can be used to import the backed-up website into another WordPress installation using',
96
+ 'boldgrid_backup'
97
+ ) . ' ' . BOLDGRID_BACKUP_TITLE . '.',
98
+ esc_html__( 'Note: Backup archives only existing in remote storage must first be downloaded to this web server in order to get a download link. Click the "View Details" for an archive and use the details page to download from remote storage.', 'boldgrid_backup' ),
99
+ $encrypt_message,
100
+ $archive_list
101
+ );
admin/remote/{ftp-hooks.php → class-boldgrid-backup-admin-ftp-hooks.php} RENAMED
@@ -1,32 +1,37 @@
1
  <?php
2
  /**
3
- * FTP Hooks class.
4
  *
5
- * @link http://www.boldgrid.com
6
- * @since 1.5.4
7
  *
8
  * @package Boldgrid_Backup
9
- * @subpackage Boldgrid_Backup/admin
10
- * @copyright BoldGrid.com
11
  * @version $Id$
12
- * @author BoldGrid.com <wpb@boldgrid.com>
 
 
 
 
 
 
13
  */
14
 
15
  /**
16
- * FTP Hooks class.
17
  *
18
  * The only purpose this class is to be used for is to separate methods that are
19
  * used for registering a new remove provider. All of these methods are called
20
  * via hooks.
21
  *
22
- * @since 1.5.4
23
  */
24
  class Boldgrid_Backup_Admin_Ftp_Hooks {
25
-
26
  /**
27
  * The core class object.
28
  *
29
- * @since 1.5.4
30
  * @access private
31
  * @var Boldgrid_Backup_Admin_Core
32
  */
@@ -35,7 +40,7 @@ class Boldgrid_Backup_Admin_Ftp_Hooks {
35
  /**
36
  * Constructor.
37
  *
38
- * @since 1.5.4
39
  *
40
  * @param Boldgrid_Backup_Admin_Core $core Core class object.
41
  */
@@ -46,7 +51,7 @@ class Boldgrid_Backup_Admin_Ftp_Hooks {
46
  /**
47
  * Add menu items.
48
  *
49
- * @since 1.5.4
50
  */
51
  public function add_menu_items() {
52
  $capability = 'administrator';
@@ -67,24 +72,24 @@ class Boldgrid_Backup_Admin_Ftp_Hooks {
67
  /**
68
  * Hook into the filter to add all ftp backups to the full list of backups.
69
  *
70
- * @since 1.5.4
71
  */
72
  public function filter_get_all() {
73
- $contents = $this->core->ftp->get_contents( true, $this->core->ftp->remote_dir );
74
  $contents = $this->core->ftp->format_raw_contents( $contents );
75
 
76
  foreach ( $contents as $item ) {
77
  $filename = $item['filename'];
78
 
79
  $backup = array(
80
- 'filename' => $filename,
81
  'last_modified' => $item['time'],
82
- 'size' => $item['size'],
83
- 'locations' => array(
84
  array(
85
- 'title' => $this->core->ftp->nickname,
86
  'on_remote_server' => true,
87
- 'title_attr' => $this->core->ftp->title_attr,
88
  ),
89
  ),
90
  );
@@ -96,7 +101,7 @@ class Boldgrid_Backup_Admin_Ftp_Hooks {
96
  /**
97
  * Determine if FTP is setup.
98
  *
99
- * @since 1.5.4
100
  */
101
  public function is_setup_ajax() {
102
  if ( ! current_user_can( 'update_plugins' ) ) {
@@ -110,7 +115,7 @@ class Boldgrid_Backup_Admin_Ftp_Hooks {
110
  $settings = $this->core->settings->get_settings();
111
 
112
  $location = $this->core->ftp->get_details();
113
- $tr = include BOLDGRID_BACKUP_PATH . '/admin/partials/settings/storage-location.php';
114
 
115
  if ( $this->core->ftp->is_setup() ) {
116
  wp_send_json_success( $tr );
@@ -122,12 +127,11 @@ class Boldgrid_Backup_Admin_Ftp_Hooks {
122
  /**
123
  * Actions to take after a backup file has been generated.
124
  *
125
- * @since 1.5.4
126
  *
127
- * @param array $info
128
  */
129
  public function post_archive_files( $info ) {
130
-
131
  /*
132
  * We only want to add this to the jobs queue if we're in the middle of
133
  * an automatic backup. If the user simply clicked on "Backup site now",
@@ -143,9 +147,10 @@ class Boldgrid_Backup_Admin_Ftp_Hooks {
143
  }
144
 
145
  $args = array(
146
- 'filepath' => $info['filepath'],
147
- 'action' => 'boldgrid_backup_' . $this->core->ftp->key . '_upload_post_archive',
148
- 'action_data' => $info['filepath'],
 
149
  'action_title' => sprintf( __( 'Upload backup file to %1$s', 'boldgrid-backup' ), $this->core->ftp->title ),
150
  );
151
 
@@ -155,10 +160,12 @@ class Boldgrid_Backup_Admin_Ftp_Hooks {
155
  /**
156
  * Register FTP as a storage location.
157
  *
158
- * @since 1.5.4
 
 
159
  */
160
  public function register_storage_location( $storage_locations ) {
161
- $storage_locations[] = $this->core->ftp->get_details();
162
 
163
  return $storage_locations;
164
  }
@@ -166,24 +173,36 @@ class Boldgrid_Backup_Admin_Ftp_Hooks {
166
  /**
167
  * Register FTP on the archive details page.
168
  *
169
- * @since 1.5.4
170
  *
171
- * @param string $filepath
172
  */
173
  public function single_archive_remote_option( $filepath ) {
174
  $allow_upload = $this->core->ftp->is_setup();
175
- $uploaded = $this->core->ftp->is_uploaded( $filepath );
176
 
177
  $this->core->archive_details->remote_storage_li[] = array(
178
- 'id' => $this->core->ftp->key,
179
- 'title' => $this->core->ftp->nickname,
180
- 'title_attr' => $this->core->ftp->title_attr,
181
- 'uploaded' => $uploaded,
182
  'allow_upload' => $allow_upload,
183
- 'is_setup' => $this->core->ftp->is_setup(),
184
  );
185
  }
186
 
 
 
 
 
 
 
 
 
 
 
 
 
187
  /**
188
  * Upload a file (triggered by jobs queue).
189
  *
@@ -191,7 +210,7 @@ class Boldgrid_Backup_Admin_Ftp_Hooks {
191
  *
192
  * @since 1.0.0
193
  *
194
- * @param string $filepath
195
  */
196
  public function upload_post_archiving( $filepath ) {
197
  $success = $this->core->ftp->upload( $filepath );
@@ -202,11 +221,17 @@ class Boldgrid_Backup_Admin_Ftp_Hooks {
202
  /**
203
  * Handle the ajax request to download an FTP backup locally.
204
  *
205
- * @since 1.5.4
206
  */
207
  public function wp_ajax_download() {
208
  $error = __( 'Unable to download backup from FTP', 'bolgrid-bakcup' );
209
 
 
 
 
 
 
 
210
  // Validation, user role.
211
  if ( ! current_user_can( 'update_plugins' ) ) {
212
  $this->core->notice->add_user_notice(
@@ -241,11 +266,17 @@ class Boldgrid_Backup_Admin_Ftp_Hooks {
241
 
242
  if ( $result ) {
243
  $this->core->notice->add_user_notice(
244
- sprintf(
245
- __( '<h2>%2$s</h2><p>Backup file <strong>%1$s</strong> successfully downloaded from FTP.</p>', 'boldgrid-backup' ),
246
- /* 1 */ $filename,
247
- /* 2 */ __( 'BoldGrid Backup Premium - FTP Download', 'boldgrid-backup' )
 
 
 
 
 
248
  ),
 
249
  'notice notice-success'
250
  );
251
  wp_send_json_success();
@@ -255,7 +286,7 @@ class Boldgrid_Backup_Admin_Ftp_Hooks {
255
  /**
256
  * Upload a file (triggered by ajax).
257
  *
258
- * @since 1.5.4
259
  */
260
  public function wp_ajax_upload() {
261
  if ( ! current_user_can( 'update_plugins' ) ) {
1
  <?php
2
  /**
3
+ * File: class-boldgrid-backup-admin-ftp-hooks.php
4
  *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.6.0
7
  *
8
  * @package Boldgrid_Backup
9
+ * @subpackage Boldgrid_Backup/admin/remote
10
+ * @copyright BoldGrid
11
  * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
+ */
14
+
15
+ /*
16
+ * AJAX callback functions in this class have their nonce verified by validate_nonce() in the Boldgrid_Backup_Admin_Archive_Details class.
17
+ *
18
+ * phpcs:disable WordPress.VIP, WordPress.CSRF.NonceVerification.NoNonceVerification, WordPress.Security.NonceVerification.NoNonceVerification
19
  */
20
 
21
  /**
22
+ * Class: Boldgrid_Backup_Admin_Ftp_Hooks
23
  *
24
  * The only purpose this class is to be used for is to separate methods that are
25
  * used for registering a new remove provider. All of these methods are called
26
  * via hooks.
27
  *
28
+ * @since 1.6.0
29
  */
30
  class Boldgrid_Backup_Admin_Ftp_Hooks {
 
31
  /**
32
  * The core class object.
33
  *
34
+ * @since 1.6.0
35
  * @access private
36
  * @var Boldgrid_Backup_Admin_Core
37
  */
40
  /**
41
  * Constructor.
42
  *
43
+ * @since 1.6.0
44
  *
45
  * @param Boldgrid_Backup_Admin_Core $core Core class object.
46
  */
51
  /**
52
  * Add menu items.
53
  *
54
+ * @since 1.6.0
55
  */
56
  public function add_menu_items() {
57
  $capability = 'administrator';
72
  /**
73
  * Hook into the filter to add all ftp backups to the full list of backups.
74
  *
75
+ * @since 1.6.0
76
  */
77
  public function filter_get_all() {
78
+ $contents = $this->core->ftp->get_contents( true, $this->core->ftp->get_folder_name() );
79
  $contents = $this->core->ftp->format_raw_contents( $contents );
80
 
81
  foreach ( $contents as $item ) {
82
  $filename = $item['filename'];
83
 
84
  $backup = array(
85
+ 'filename' => $filename,
86
  'last_modified' => $item['time'],
87
+ 'size' => $item['size'],
88
+ 'locations' => array(
89
  array(
90
+ 'title' => $this->core->ftp->nickname,
91
  'on_remote_server' => true,
92
+ 'title_attr' => $this->core->ftp->title_attr,
93
  ),
94
  ),
95
  );
101
  /**
102
  * Determine if FTP is setup.
103
  *
104
+ * @since 1.6.0
105
  */
106
  public function is_setup_ajax() {
107
  if ( ! current_user_can( 'update_plugins' ) ) {
115
  $settings = $this->core->settings->get_settings();
116
 
117
  $location = $this->core->ftp->get_details();
118
+ $tr = include BOLDGRID_BACKUP_PATH . '/admin/partials/settings/storage-location.php';
119
 
120
  if ( $this->core->ftp->is_setup() ) {
121
  wp_send_json_success( $tr );
127
  /**
128
  * Actions to take after a backup file has been generated.
129
  *
130
+ * @since 1.6.0
131
  *
132
+ * @param array $info Archive information.
133
  */
134
  public function post_archive_files( $info ) {
 
135
  /*
136
  * We only want to add this to the jobs queue if we're in the middle of
137
  * an automatic backup. If the user simply clicked on "Backup site now",
147
  }
148
 
149
  $args = array(
150
+ 'filepath' => $info['filepath'],
151
+ 'action' => 'boldgrid_backup_' . $this->core->ftp->key . '_upload_post_archive',
152
+ 'action_data' => $info['filepath'],
153
+ // translators: 1: FTP account title/name.
154
  'action_title' => sprintf( __( 'Upload backup file to %1$s', 'boldgrid-backup' ), $this->core->ftp->title ),
155
  );
156
 
160
  /**
161
  * Register FTP as a storage location.
162
  *
163
+ * @since 1.6.0
164
+ *
165
+ * @param array $storage_locations Storage locations.
166
  */
167
  public function register_storage_location( $storage_locations ) {
168
+ $storage_locations[] = $this->core->ftp->get_details( true );
169
 
170
  return $storage_locations;
171
  }
173
  /**
174
  * Register FTP on the archive details page.
175
  *
176
+ * @since 1.6.0
177
  *
178
+ * @param string $filepath File path.
179
  */
180
  public function single_archive_remote_option( $filepath ) {
181
  $allow_upload = $this->core->ftp->is_setup();
182
+ $uploaded = $this->core->ftp->is_uploaded( $filepath );
183
 
184
  $this->core->archive_details->remote_storage_li[] = array(
185
+ 'id' => $this->core->ftp->key,
186
+ 'title' => $this->core->ftp->nickname,
187
+ 'title_attr' => $this->core->ftp->title_attr,
188
+ 'uploaded' => $uploaded,
189
  'allow_upload' => $allow_upload,
190
+ 'is_setup' => $this->core->ftp->is_setup(),
191
  );
192
  }
193
 
194
+ /**
195
+ * Hook into WordPress' shutdown action and close any open FTP connections.
196
+ *
197
+ * Closing the connections now, rather than when we're done with a specific ftp action, will
198
+ * eliminate numerous ftp connections being opened on a single admin page.
199
+ *
200
+ * @since 1.7.2
201
+ */
202
+ public function shutdown() {
203
+ $this->core->ftp->disconnect();
204
+ }
205
+
206
  /**
207
  * Upload a file (triggered by jobs queue).
208
  *
210
  *
211
  * @since 1.0.0
212
  *
213
+ * @param string $filepath File path.
214
  */
215
  public function upload_post_archiving( $filepath ) {
216
  $success = $this->core->ftp->upload( $filepath );
221
  /**
222
  * Handle the ajax request to download an FTP backup locally.
223
  *
224
+ * @since 1.6.0
225
  */
226
  public function wp_ajax_download() {
227
  $error = __( 'Unable to download backup from FTP', 'bolgrid-bakcup' );
228
 
229
+ $allowed_html = array(
230
+ 'h2' => array(),
231
+ 'p' => array(),
232
+ 'strong' => array(),
233
+ );
234
+
235
  // Validation, user role.
236
  if ( ! current_user_can( 'update_plugins' ) ) {
237
  $this->core->notice->add_user_notice(
266
 
267
  if ( $result ) {
268
  $this->core->notice->add_user_notice(
269
+ wp_kses(
270
+ sprintf(
271
+ // translators: 1: Plugin title,2: Filename.
272
+ __(
273
+ '<h2>%1$s - FTP Download</h2><p>Backup file <strong>%2$s</strong> successfully downloaded from FTP.</p>',
274
+ 'boldgrid-backup'
275
+ ),
276
+ $filename
277
+ ), $allowed_html
278
  ),
279
+ BOLDGRID_BACKUP_TITLE . ' Premium',
280
  'notice notice-success'
281
  );
282
  wp_send_json_success();
286
  /**
287
  * Upload a file (triggered by ajax).
288
  *
289
+ * @since 1.6.0
290
  */
291
  public function wp_ajax_upload() {
292
  if ( ! current_user_can( 'update_plugins' ) ) {
admin/remote/class-boldgrid-backup-admin-ftp-page.php ADDED
@@ -0,0 +1,237 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File: class-boldgrid-backup-admin-ftp-page.php
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.6.0
7
+ *
8
+ * @package Boldgrid_Backup
9
+ * @subpackage Boldgrid_Backup/admin/remote
10
+ * @copyright BoldGrid
11
+ * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
+ */
14
+
15
+ // phpcs:disable WordPress.VIP
16
+
17
+ /**
18
+ * Class: Boldgrid_Backup_Admin_Ftp_Page
19
+ *
20
+ * @since 1.6.0
21
+ */
22
+ class Boldgrid_Backup_Admin_Ftp_Page {
23
+ /**
24
+ * The core class object.
25
+ *
26
+ * @since 1.6.0
27
+ * @access private
28
+ * @var Boldgrid_Backup_Admin_Core
29
+ */
30
+ private $core;
31
+
32
+ /**
33
+ * Constructor.
34
+ *
35
+ * @since 1.6.0
36
+ *
37
+ * @param Boldgrid_Backup_Admin_Core $core Core class object.
38
+ */
39
+ public function __construct( $core ) {
40
+ $this->core = $core;
41
+ }
42
+
43
+ /**
44
+ * Enqueue scripts.
45
+ *
46
+ * @since 1.6.0
47
+ */
48
+ public function enqueue_scripts() {
49
+ if ( $this->core->utility->is_admin_page( 'boldgrid-backup-ftp' ) ) {
50
+ $handle = 'boldgrid-backup-admin-ftp-settings';
51
+ wp_register_script(
52
+ $handle,
53
+ plugin_dir_url( dirname( __FILE__ ) ) . 'js/' . $handle . '.js',
54
+ array( 'jquery' ),
55
+ BOLDGRID_BACKUP_VERSION,
56
+ false
57
+ );
58
+ $translation = array(
59
+ 'default_port' => $this->core->ftp->default_port,
60
+ );
61
+ wp_localize_script( $handle, 'BoldGridBackupAdminFtpSettings', $translation );
62
+ wp_enqueue_script( $handle );
63
+
64
+ wp_enqueue_style(
65
+ $handle,
66
+ plugin_dir_url( dirname( __FILE__ ) ) . 'css/' . $handle . '.css',
67
+ array(),
68
+ BOLDGRID_BACKUP_VERSION
69
+ );
70
+
71
+ wp_enqueue_style( 'boldgrid-backup-admin-hide-all' );
72
+ }
73
+ }
74
+
75
+ /**
76
+ * Generate the submenu page for our FTP Settings page.
77
+ *
78
+ * @since 1.6.0
79
+ */
80
+ public function settings() {
81
+ if ( ! current_user_can( 'update_plugins' ) ) {
82
+ return false;
83
+ }
84
+
85
+ // Used with wp_kses call below.
86
+ $allowed_html = array(
87
+ 'div' => array(
88
+ 'class' => array(),
89
+ ),
90
+ 'span' => array(
91
+ 'class' => array(),
92
+ ),
93
+ );
94
+
95
+ /*
96
+ * Blank data, used when deleting settings.
97
+ *
98
+ * If we are deleting our settings, this data will be used to repopulate the form.
99
+ */
100
+ $type = $this->core->ftp->default_type;
101
+ $blank_data = array(
102
+ 'type' => $type,
103
+ 'ftp_mode' => $this->core->ftp->default_ftp_mode,
104
+ 'host' => null,
105
+ 'port' => $this->core->ftp->default_port[ $type ],
106
+ 'user' => null,
107
+ 'pass' => null,
108
+ 'folder_name' => $this->core->ftp->default_folder_name,
109
+ 'retention_count' => $this->core->ftp->retention_count,
110
+ 'nickname' => '',
111
+ );
112
+
113
+ // Post data, used by default or when updating settings.
114
+ $post_data = $this->core->ftp->get_from_post();
115
+
116
+ $action = ! empty( $_POST['action'] ) ? sanitize_key( $_POST['action'] ) : null; // phpcs:ignore WordPress.CSRF.NonceVerification.NoNonceVerification, WordPress.Security.NonceVerification.NoNonceVerification
117
+
118
+ switch ( $action ) {
119
+ case 'save':
120
+ echo wp_kses( $this->core->elements['long_checking_creds'], $allowed_html );
121
+ if ( ob_get_level() > 0 ) {
122
+ ob_flush();
123
+ }
124
+ flush();
125
+
126
+ $this->settings_save();
127
+ $data = $post_data;
128
+ break;
129
+ case 'delete':
130
+ $this->settings_delete();
131
+ $data = $blank_data;
132
+ break;
133
+ default:
134
+ $data = $post_data;
135
+ }
136
+
137
+ include BOLDGRID_BACKUP_PATH . '/admin/partials/remote/ftp.php';
138
+ }
139
+
140
+ /**
141
+ * Process the user's request to update their FTP settings.
142
+ *
143
+ * @since 1.6.0
144
+ */
145
+ public function settings_delete() {
146
+ $ftp = $this->core->ftp;
147
+
148
+ if ( ! current_user_can( 'update_plugins' ) ) {
149
+ return false;
150
+ }
151
+
152
+ $settings = $this->core->settings->get_settings();
153
+ if ( ! isset( $settings['remote'][ $ftp->key ] ) || ! is_array( $settings['remote'][ $ftp->key ] ) ) {
154
+ $settings['remote'][ $ftp->key ] = array();
155
+ }
156
+
157
+ $settings['remote'][ $ftp->key ] = array();
158
+ update_site_option( 'boldgrid_backup_settings', $settings );
159
+
160
+ $ftp->reset();
161
+ $ftp->disconnect();
162
+
163
+ do_action( 'boldgrid_backup_notice', __( 'Settings deleted.', 'boldgrid-backup' ), 'notice updated is-dismissible' );
164
+ }
165
+
166
+ /**
167
+ * Process the user's request to update their FTP settings.
168
+ *
169
+ * @since 1.6.0
170
+ *
171
+ * @return bool
172
+ */
173
+ public function settings_save() {
174
+ $success = true;
175
+
176
+ if ( ! check_ajax_referer( 'bgb-settings-ftp', 'ftp_auth' ) ) {
177
+ do_action(
178
+ 'boldgrid_backup_notice',
179
+ __( 'Unauthorized request.', 'boldgrid-backup' ),
180
+ 'notice error is-dismissible'
181
+ );
182
+
183
+ return false;
184
+ }
185
+
186
+ // Readability.
187
+ $ftp = $this->core->ftp;
188
+
189
+ if ( ! current_user_can( 'update_plugins' ) ) {
190
+ return false;
191
+ }
192
+
193
+ if ( empty( $_POST ) ) {
194
+ return false;
195
+ }
196
+
197
+ $settings = $this->core->settings->get_settings();
198
+ if ( ! isset( $settings['remote'][ $ftp->key ] ) || ! is_array( $settings['remote'][ $ftp->key ] ) ) {
199
+ $settings['remote'][ $ftp->key ] = array();
200
+ }
201
+
202
+ // This method has default values for each setting and also handles sanitization.
203
+ $data = $ftp->get_from_post();
204
+
205
+ $valid_credentials = $ftp->is_valid_credentials(
206
+ $data['host'],
207
+ $data['user'],
208
+ $data['pass'],
209
+ $data['port'],
210
+ $data['type'],
211
+ $data['ftp_mode']
212
+ );
213
+
214
+ if ( $valid_credentials ) {
215
+ $settings['remote'][ $ftp->key ]['host'] = $data['host'];
216
+ $settings['remote'][ $ftp->key ]['user'] = $data['user'];
217
+ $settings['remote'][ $ftp->key ]['pass'] = $data['pass'];
218
+ $settings['remote'][ $ftp->key ]['port'] = $data['port'];
219
+ $settings['remote'][ $ftp->key ]['type'] = $data['type'];
220
+ $settings['remote'][ $ftp->key ]['ftp_mode'] = $data['ftp_mode'];
221
+ }
222
+
223
+ $settings['remote'][ $ftp->key ]['retention_count'] = $data['retention_count'];
224
+ $settings['remote'][ $ftp->key ]['nickname'] = $data['nickname'];
225
+ $settings['remote'][ $ftp->key ]['folder_name'] = $data['folder_name'];
226
+
227
+ if ( ! empty( $ftp->errors ) ) {
228
+ do_action( 'boldgrid_backup_notice', implode( '<br /><br />', $ftp->errors ) );
229
+ $success = false;
230
+ } else {
231
+ update_site_option( 'boldgrid_backup_settings', $settings );
232
+ do_action( 'boldgrid_backup_notice', __( 'Settings saved.', 'boldgrid-backup' ), 'notice updated is-dismissible' );
233
+ }
234
+
235
+ return $success;
236
+ }
237
+ }
admin/remote/class-boldgrid-backup-admin-ftp.php ADDED
@@ -0,0 +1,1172 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File: class-boldgrid-backup-admin-ftp.php
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.6.0
7
+ *
8
+ * @package Boldgrid_Backup
9
+ * @subpackage Boldgrid_Backup/admin/remote
10
+ * @copyright BoldGrid
11
+ * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
+ */
14
+
15
+ // phpcs:disable WordPress.VIP
16
+
17
+ /**
18
+ * Class: Boldgrid_Backup_Admin_Ftp
19
+ *
20
+ * @since 1.6.0
21
+ */
22
+ class Boldgrid_Backup_Admin_Ftp {
23
+ /**
24
+ * Default folder name.
25
+ *
26
+ * Set using Boldgrid_Backup_Admin_Ftp->set_default_folder_name(), within the constructor.
27
+ *
28
+ * @since 1.9.1
29
+ * @var string
30
+ */
31
+ public $default_folder_name;
32
+
33
+ /**
34
+ * Default port numbers.
35
+ *
36
+ * @since 1.6.0
37
+ * @var array
38
+ */
39
+ public $default_port = [
40
+ 'ftp' => 21,
41
+ 'ftpes' => 21,
42
+ 'sftp' => 22,
43
+ ];
44
+
45
+ /**
46
+ * Default type.
47
+ *
48
+ * @since 1.6.0
49
+ * @var string
50
+ */
51
+ public $default_type = 'sftp';
52
+
53
+ /**
54
+ * Default FTP mode.
55
+ *
56
+ * @since 1.10.5
57
+ * @var string
58
+ */
59
+ public $default_ftp_mode = 'auto';
60
+
61
+ /**
62
+ * Errors.
63
+ *
64
+ * @since 1.6.0
65
+ * @var array
66
+ */
67
+ public $errors = [];
68
+
69
+ /**
70
+ * The folder on the remote FTP server where backups are stored.
71
+ *
72
+ * Handled by Boldgrid_Backup_Admin_Ftp->get_folder_name().
73
+ *
74
+ * @since 1.9.1
75
+ * @var string
76
+ */
77
+ public $folder_name;
78
+
79
+ /**
80
+ * Hooks class.
81
+ *
82
+ * @since 1.6.0
83
+ * @var Boldgrid_Backup_Admin_Ftp_Hooks
84
+ */
85
+ public $hooks;
86
+
87
+ /**
88
+ * Whether or not we have logged in.
89
+ *
90
+ * @since 1.6.0
91
+ * @var bool
92
+ */
93
+ public $logged_in = false;
94
+
95
+ /**
96
+ * Nickname.
97
+ *
98
+ * So the user can refer to their ftp account as something other than ftp.
99
+ *
100
+ * @since 1.6.0
101
+ * @var string
102
+ */
103
+ public $nickname;
104
+
105
+ /**
106
+ * Our key / label for ftp.
107
+ *
108
+ * @since 1.6.0
109
+ * @var string
110
+ */
111
+ public $key = 'ftp';
112
+
113
+ /**
114
+ * Retention count.
115
+ *
116
+ * @since 1.6.0
117
+ * @var int $retention_count
118
+ */
119
+ public $retention_count = 5;
120
+
121
+ /**
122
+ * Settings class.
123
+ *
124
+ * @since 1.7.2
125
+ * @var Boldgrid_Backup_Admin_Remote_Settings
126
+ */
127
+ public $settings;
128
+
129
+ /**
130
+ * Default timeout.
131
+ *
132
+ * @since 1.6.0
133
+ * @var int
134
+ */
135
+ public $timeout = 10;
136
+
137
+ /**
138
+ * Our title / label for ftp.
139
+ *
140
+ * @since 1.6.0
141
+ * @var string
142
+ */
143
+ public $title = 'FTP / SFTP';
144
+
145
+ /**
146
+ * Title attribute.
147
+ *
148
+ * If you are using a nickname, hovering over the nickname should show this
149
+ * more clear title.
150
+ *
151
+ * @since 1.6.0
152
+ * @var string
153
+ */
154
+ public $title_attr;
155
+
156
+ /**
157
+ * Our FTP type, ftp or sftp.
158
+ *
159
+ * @since 1.6.0
160
+ * @var string
161
+ */
162
+ public $type = null;
163
+
164
+ /**
165
+ * Valid types.
166
+ *
167
+ * @since 1.6.0
168
+ * @var array
169
+ */
170
+ public $valid_types = [
171
+ 'ftp',
172
+ 'ftpes',
173
+ 'sftp',
174
+ ];
175
+
176
+ /**
177
+ * FTP mode.
178
+ *
179
+ * Valid values: auto, active, passive.
180
+ *
181
+ * @since 1.10.5
182
+ * @var string
183
+ */
184
+ public $ftp_mode;
185
+
186
+ /**
187
+ * An FTP connection.
188
+ *
189
+ * @since 1.6.0
190
+ * @access private
191
+ * @var Resource
192
+ */
193
+ private $connection = null;
194
+
195
+ /**
196
+ * The core class object.
197
+ *
198
+ * @since 1.6.0
199
+ * @access private
200
+ * @var Boldgrid_Backup_Admin_Core
201
+ */
202
+ private $core;
203
+
204
+ /**
205
+ * FTP host.
206
+ *
207
+ * @since 1.6.0
208
+ * @access private
209
+ * @var string
210
+ */
211
+ private $host = null;
212
+
213
+ /**
214
+ * FTP password.
215
+ *
216
+ * @since 1.6.0
217
+ * @access private
218
+ * @var string
219
+ */
220
+ private $pass = null;
221
+
222
+ /**
223
+ * FTP username.
224
+ *
225
+ * @since 1.6.0
226
+ * @access private
227
+ * @var string
228
+ */
229
+ private $user = null;
230
+
231
+ /**
232
+ * Whether or not we have logged in.
233
+ *
234
+ * @since 1.9.3
235
+ * @access private
236
+ * @var bool
237
+ */
238
+ private $reconnected = false;
239
+
240
+ /**
241
+ * Constructor.
242
+ *
243
+ * @since 1.6.0
244
+ *
245
+ * @param Boldgrid_Backup_Admin_Core $core Core class object.
246
+ */
247
+ public function __construct( $core ) {
248
+ include_once BOLDGRID_BACKUP_PATH . '/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php';
249
+
250
+ $this->core = $core;
251
+ $this->hooks = new Boldgrid_Backup_Admin_Ftp_Hooks( $core );
252
+ $this->page = new Boldgrid_Backup_Admin_Ftp_Page( $core );
253
+ $this->settings = new Boldgrid_Backup_Admin_Remote_Settings( $this->key );
254
+
255
+ $this->set_default_folder_name();
256
+ }
257
+
258
+ /**
259
+ * Connect to our ftp server.
260
+ *
261
+ * @since 1.6.0
262
+ */
263
+ public function connect() {
264
+ if ( ! empty( $this->connection ) ) {
265
+ return;
266
+ }
267
+
268
+ $this->init();
269
+
270
+ if ( empty( $this->user ) || empty( $this->pass ) || empty( $this->host ) || empty( $this->type ) || empty( $this->port ) ) {
271
+ return;
272
+ }
273
+
274
+ switch ( $this->type ) {
275
+ case 'ftp':
276
+ $this->connection = ftp_connect( $this->host, $this->port, $this->timeout );
277
+ break;
278
+ case 'ftpes':
279
+ $this->connection = ftp_ssl_connect( $this->host, $this->port, $this->timeout );
280
+ break;
281
+ case 'sftp':
282
+ $this->connection = new phpseclib\Net\SFTP( $this->host, $this->port );
283
+ break;
284
+ default:
285
+ break;
286
+ }
287
+ }
288
+
289
+ /**
290
+ * Create backup directory on remote host.
291
+ *
292
+ * @since 1.6.0
293
+ *
294
+ * @return bool False when we were unable to create directory.
295
+ */
296
+ public function create_backup_dir() {
297
+ $this->connect();
298
+ $this->log_in();
299
+ if ( ! $this->logged_in ) {
300
+ return false;
301
+ }
302
+
303
+ $contents = $this->get_contents();
304
+ if ( ! $contents || ! is_array( $contents ) ) {
305
+ $this->errors[] = __( 'Unable to get a directory listing from FTP server.', 'boldgrid-backup' );
306
+ return false;
307
+ } elseif ( in_array( $this->get_folder_name(), $contents, true ) ) {
308
+ return true;
309
+ }
310
+
311
+ switch ( $this->type ) {
312
+ case 'ftp':
313
+ case 'ftpes':
314
+ $created = ftp_mkdir( $this->connection, $this->get_folder_name() );
315
+ break;
316
+ case 'sftp':
317
+ $created = $this->connection->mkdir( $this->get_folder_name() );
318
+ break;
319
+ default:
320
+ break;
321
+ }
322
+
323
+ if ( ! $created ) {
324
+ $this->errors[] = sprintf(
325
+ // translators: 1: Remote directory path.
326
+ __(
327
+ 'Unable to create the following directory on FTP server: %1$s',
328
+ 'boldgrid-backup'
329
+ ),
330
+ $this->get_folder_name()
331
+ );
332
+ }
333
+
334
+ return $created;
335
+ }
336
+
337
+ /**
338
+ * Disconnect from FTP server.
339
+ *
340
+ * @since 1.6.0
341
+ */
342
+ public function disconnect() {
343
+ if ( ( 'ftp' === $this->type || 'ftpes' === $this->type ) && is_resource( $this->connection ) ) {
344
+ ftp_close( $this->connection );
345
+ $this->connection = null;
346
+ $this->logged_in = false;
347
+ }
348
+ }
349
+
350
+ /**
351
+ * Download a backup via FTP.
352
+ *
353
+ * @since 1.6.0
354
+ *
355
+ * @param string $filename Filename.
356
+ * @return bool
357
+ */
358
+ public function download( $filename ) {
359
+ $this->connect();
360
+
361
+ $local_filepath = $this->core->backup_dir->get_path_to( $filename );
362
+ $server_filepath = $this->get_folder_name() . '/' . $filename;
363
+ $success = false;
364
+
365
+ $this->log_in();
366
+
367
+ switch ( $this->type ) {
368
+ case 'ftp':
369
+ case 'ftpes':
370
+ $success = ftp_get( $this->connection, $local_filepath, $server_filepath, FTP_BINARY );
371
+ break;
372
+ case 'sftp':
373
+ $success = $this->connection->get( $server_filepath, $local_filepath );
374
+ break;
375
+ default:
376
+ break;
377
+ }
378
+
379
+ if ( $success ) {
380
+ $this->core->remote->post_download( $local_filepath );
381
+ }
382
+
383
+ return $success;
384
+ }
385
+
386
+ /**
387
+ * Enforce retention.
388
+ *
389
+ * @since 1.6.0
390
+ */
391
+ public function enforce_retention() {
392
+ if ( empty( $this->retention_count ) ) {
393
+ return;
394
+ }
395
+
396
+ $contents = $this->get_contents( true, $this->get_folder_name() );
397
+ $backups = $this->format_raw_contents( $contents );
398
+
399
+ $count_to_delete = count( $backups ) - $this->retention_count;
400
+
401
+ if ( empty( $backups ) || $count_to_delete <= 0 ) {
402
+ return false;
403
+ }
404
+
405
+ usort(
406
+ $backups, function( $a, $b ) {
407
+ return $a['time'] < $b['time'] ? -1 : 1;
408
+ }
409
+ );
410
+
411
+ for ( $x = 0; $x < $count_to_delete; $x++ ) {
412
+ $filename = $backups[ $x ]['filename'];
413
+ $path = $this->get_folder_name() . '/' . $filename;
414
+
415
+ switch ( $this->type ) {
416
+ case 'ftp':
417
+ case 'ftpes':
418
+ ftp_delete( $this->connection, $path );
419
+ break;
420
+ case 'sftp':
421
+ $this->connection->delete( $path, false );
422
+ break;
423
+ default:
424
+ break;
425
+ }
426
+
427
+ /**
428
+ * Remote file deleted due to remote retention settings.
429
+ *
430
+ * @since 1.6.0
431
+ */
432
+ do_action(
433
+ 'boldgrid_backup_remote_retention_deleted',
434
+ $this->title,
435
+ $filename
436
+ );
437
+ }
438
+ }
439
+
440
+ /**
441
+ * Get our ftp folder name.
442
+ *
443
+ * @since 1.9.1
444
+ *
445
+ * @return string
446
+ */
447
+ public function get_folder_name() {
448
+ if ( ! empty( $this->folder_name ) ) {
449
+ return $this->folder_name;
450
+ }
451
+
452
+ $settings = $this->core->settings->get_settings();
453
+ $has_settings = isset( $settings['remote'][ $this->key ] );
454
+ $has_folder_set = ! empty( $settings['remote'][ $this->key ]['folder_name'] );
455
+
456
+ /*
457
+ * In version 1, no folder name was configurable by the user and it defaulted to
458
+ * "boldgrid-backup" ($this->remote_dir, which was removed in 1.9.1). In version 2, the user
459
+ * can set a custom folder name.
460
+ *
461
+ * This is for backwards compatibility.
462
+ */
463
+ $version = $has_settings && ! $has_folder_set ? 1 : 2;
464
+
465
+ switch ( $version ) {
466
+ case 1:
467
+ $this->folder_name = 'boldgrid_backup';
468
+ break;
469
+ case 2:
470
+ $this->folder_name = $has_folder_set ? $settings['remote'][ $this->key ]['folder_name'] : $this->default_folder_name;
471
+ break;
472
+ default:
473
+ break;
474
+ }
475
+
476
+ return $this->folder_name;
477
+ }
478
+
479
+ /**
480
+ * Get our settings from $_POST.
481
+ *
482
+ * For example, if we are saving our FTP settings, get all the data the user set from $_POST.
483
+ *
484
+ * @since 1.6.0
485
+ *
486
+ * @return array
487
+ */
488
+ public function get_from_post() {
489
+ $settings = $this->core->settings->get_settings();
490
+
491
+ $values = [
492
+ [
493
+ 'key' => 'host',
494
+ 'default' => null,
495
+ /*
496
+ * Sanitize ftp hostname. Initially sanitize_file_name was used, but it converted
497
+ * sub.domain.org to sub.domain_.org (because "org" was not a valid mime type).
498
+ */
499
+ 'callback' => 'sanitize_text_field',
500
+ ],
501
+ [
502
+ 'key' => 'user',
503
+ 'default' => null,
504
+ 'callback' => 'sanitize_text_field',
505
+ ],
506
+ [
507
+ 'key' => 'pass',
508
+ 'default' => null,
509
+ ],
510
+ [
511
+ 'key' => 'folder_name',
512
+ 'default' => $this->get_folder_name(),
513
+ 'callback' => 'sanitize_file_name',
514
+ ],
515
+ [
516
+ 'key' => 'type',
517
+ 'default' => $this->default_type,
518
+ 'callback' => 'sanitize_key',
519
+ ],
520
+ [
521
+ 'key' => 'ftp_mode',
522
+ 'default' => $this->default_ftp_mode,
523
+ 'callback' => 'sanitize_key',
524
+ ],
525
+ [
526
+ 'key' => 'port',
527
+ 'default' => $this->default_port[ $this->default_type ],
528
+ 'callback' => 'intval',
529
+ ],
530
+ [
531
+ 'key' => 'retention_count',
532
+ 'default' => $this->retention_count,
533
+ 'callback' => 'intval',
534
+ ],
535
+ [
536
+ 'key' => 'nickname',
537
+ 'default' => '',
538
+ 'callback' => 'stripslashes',
539
+ ],
540
+ ];
541
+
542
+ // phpcs:disable WordPress.CSRF.NonceVerification.NoNonceVerification, WordPress.Security.NonceVerification.NoNonceVerification
543
+
544
+ foreach ( $values as $value ) {
545
+ $key = $value['key'];
546
+ $callback = ! empty( $value['callback'] ) ? $value['callback'] : null;
547
+
548
+ if ( ! empty( $_POST[ $key ] ) ) {
549
+ $data[ $key ] = $_POST[ $key ];
550
+ } elseif ( ! empty( $settings['remote'][ $this->key ][ $key ] ) ) {
551
+ $data[ $key ] = $settings['remote'][ $this->key ][ $key ];
552
+ } else {
553
+ $data[ $key ] = $value['default'];
554
+ }
555
+
556
+ // If there is a callback function for sanitizing the value, then run it.
557
+ if ( $callback ) {
558
+ $data[ $key ] = $callback( $data[ $key ] );
559
+ }
560
+ }
561
+
562
+ // phpcs:enable WordPress.CSRF.NonceVerification.NoNonceVerification, WordPress.Security.NonceVerification.NoNonceVerification
563
+
564
+ return $data;
565
+ }
566
+
567
+ /**
568
+ * Format raw contents.
569
+ *
570
+ * This method takes in raw contents and returns an array of backups, with
571
+ * keys defining timestamp and filename.
572
+ *
573
+ * The array of backups returned DO NOT include:
574
+ * # . or .. (typical when getting a directory listing).
575
+ * # Files / backups that do not belong to this site.
576
+ * See $this->core->archive->is_site_archive().
577
+ *
578
+ * @since 1.6.0
579
+ *
580
+ * @param array $contents Raw contents received from this->get_contents.
581
+ * @return array {
582
+ * An array of backups.
583
+ *
584
+ * @type int $time Timestamp file was uploaded to ftp server.
585
+ * @type string $filename
586
+ * }
587
+ */
588
+ public function format_raw_contents( $contents ) {
589
+ $skips = [
590
+ '.',
591
+ '..',
592
+ ];
593
+ $backups = [];
594
+
595
+ if ( ! is_array( $contents ) ) {
596
+ return $backups;
597
+ }
598
+
599
+ foreach ( $contents as $item ) {
600
+
601
+ if ( 'sftp' === $this->type ) {
602
+ $filename = $item['filename'];
603
+ if ( in_array( $filename, $skips, true ) ) {
604
+ continue;
605
+ }
606
+
607
+ $backups[] = [
608
+ 'time' => $item['mtime'],
609
+ 'filename' => $filename,
610
+ 'size' => $item['size'],
611
+ ];
612
+ } else {
613
+ // Before exploding by space, replace multiple spaces with one space.
614
+ $item = preg_replace( '!\s+!', ' ', $item );
615
+
616
+ $exploded_item = explode( ' ', $item );
617
+ $count = count( $exploded_item );
618
+
619
+ $filename = $exploded_item[ $count - 1 ];
620
+ if ( in_array( $filename, $skips, true ) ) {
621
+ continue;
622
+ }
623
+
624
+ /*
625
+ * Determine the format of our raw contents.
626
+ *
627
+ * There are for sure more than 2 formats (see notes at https://pastebin.com/eL5XpeYP),
628
+ * but for now we're currently testing for:
629
+ * # Windows 10-24-2018 11:12AM 302501 boldgrid-backup-localhost_wordpress-90d7727c-20181024-175039.zip
630
+ * # Linux -rw-r--r-- 1 boldgrid4s boldgrid4s 997834 Oct 24 10:36 boldgrid-backup-domain.com-b2cf0453-20181024-143320.zip
631
+ *
632
+ * Flag as a windows ftp server if first item is a date in xx-xx-xxxx format.
633
+ */
634
+ $is_windows = 1 === preg_match( '/(\d{2})-(\d{2})-(\d{4})/', $exploded_item[0] );
635
+
636
+ if ( $is_windows ) {
637
+ $time = strtotime( $exploded_item[0] . ' ' . $exploded_item[1] );
638
+ $size = $exploded_item[2];
639
+ } else {
640
+ // Get the timestamp.
641
+ $month = $exploded_item[ $count - 4 ];
642
+ $day = $exploded_item[ $count - 3 ];
643
+ $time = $exploded_item[ $count - 2 ];
644
+ $time = strtotime( $month . ' ' . $day . ' ' . $time );
645
+
646
+ $size = $exploded_item[ $count - 5 ];
647
+ }
648
+
649
+ $backups[] = [
650
+ 'time' => $time,
651
+ 'filename' => $filename,
652
+ 'size' => $size,
653
+ ];
654
+ }
655
+ }
656
+
657
+ foreach ( $backups as $key => $backup ) {
658
+ if ( ! $this->core->archive->is_site_archive( $backup['filename'] ) ) {
659
+ unset( $backups[ $key ] );
660
+ }
661
+ }
662
+ $backups = array_values( $backups );
663
+
664
+ return $backups;
665
+ }
666
+
667
+ /**
668
+ * Get the remote contents / listing.
669
+ *
670
+ * This method allows for both ftp / sftp AND rawlist / nlist functions. The return data can
671
+ * vary based on server. Example return data available here: https://pastebin.com/eL5XpeYP
672
+ *
673
+ * @since 1.6.0
674
+ *
675
+ * @param bool $raw Whether to get the raw contents (ftp_rawlist) or not
676
+ * (ftp_nlist).
677
+ * @param string $dir The directory to get listing of.
678
+ * @return mixed
679
+ */
680
+ public function get_contents( $raw = false, $dir = '.' ) {
681
+ $this->connect();
682
+ $this->log_in();
683
+ if ( ! $this->logged_in ) {
684
+ $this->errors[] = __( 'Unable to log in to FTP server.', 'boldgrid-backup' );
685
+ return [];
686
+ }
687
+
688
+ switch ( $this->type ) {
689
+ case 'ftp':
690
+ case 'ftpes':
691
+ if ( $raw ) {
692
+ $contents = ftp_rawlist( $this->connection, $dir );
693
+ } else {
694
+ $contents = ftp_nlist( $this->connection, $dir );
695
+ }
696
+ break;
697
+ case 'sftp':
698
+ if ( $raw ) {
699
+ $contents = $this->connection->rawlist( $dir );
700
+ } else {
701
+ $contents = $this->connection->nlist( $dir );
702
+ }
703
+ break;
704
+ default:
705
+ break;
706
+ }
707
+
708
+ /*
709
+ * Some ftp servers respond with slightly different formats. In some scenarious on a Windows
710
+ * FTP server, the folders will be prepended with a "./" (See comment in this method's
711
+ * docblock). Before returning the data, remove "./" from the beginning of all items.
712
+ */
713
+ $fix_windows = function( $item ) {
714
+ if ( './' === substr( $item, 0, 2 ) ) {
715
+ $item = substr( $item, 2 );
716
+ }
717
+ return $item;
718
+ };
719
+
720
+ if ( ( 'ftp' === $this->type || 'ftpes' === $this->type ) && is_array( $contents ) ) {
721
+ $contents = array_map( $fix_windows, $contents );
722
+ }
723
+
724
+ return $contents;
725
+ }
726
+
727
+ /**
728
+ * Get settings.
729
+ *
730
+ * @since 1.6.0
731
+ *
732
+ * @param bool $try_cache Whether or not to use last_login to validate the ftp account. Please
733
+ * see param definition in $this->is_setup().
734
+ */
735
+ public function get_details( $try_cache = false ) {
736
+ $is_setup = $this->is_setup( $try_cache );
737
+
738
+ $settings = $this->core->settings->get_settings();
739
+
740
+ return [
741
+ 'title' => $this->title,
742
+ 'key' => $this->key,
743
+ 'configure' => 'admin.php?page=boldgrid-backup-ftp',
744
+ 'is_setup' => $is_setup,
745
+ 'enabled' => ! empty( $settings['remote'][ $this->key ]['enabled'] ) && $settings['remote'][ $this->key ]['enabled'] && $is_setup,
746
+ ];
747
+ }
748
+
749
+ /**
750
+ * Init properties.
751
+ *
752
+ * @since 1.6.0
753
+ */
754
+ public function init() {
755
+ if ( ! empty( $this->user ) || ! empty( $this->pass ) || ! empty( $this->host ) ) {
756
+ return;
757
+ }
758
+
759
+ $settings = $this->core->settings->get_settings();
760
+
761
+ $labels = [
762
+ 'user',
763
+ 'pass',
764
+ 'host',
765
+ 'port',
766
+ 'type',
767
+ 'ftp_mode',
768
+ 'retention_count',
769
+ 'nickname',
770
+ ];
771
+
772
+ $configs = [
773
+ [
774
+ 'property' => 'user',
775
+ 'default' => null,
776
+ ],
777
+ [
778
+ 'property' => 'pass',
779
+ 'default' => null,
780
+ ],
781
+ [
782
+ 'property' => 'host',
783
+ 'default' => null,
784
+ ],
785
+ [
786
+ 'property' => 'port',
787
+ 'default' => $this->default_port,
788
+ ],
789
+ [
790
+ 'property' => 'type',
791
+ 'default' => $this->default_type,
792
+ ],
793
+ [
794
+ 'property' => 'ftp_mode',
795
+ 'default' => $this->default_ftp_mode,
796
+ ],
797
+ [
798
+ 'property' => 'retention_count',
799
+ 'default' => $this->retention_count,
800
+ ],
801
+ [
802
+ 'property' => 'nickname',
803
+ 'default' => $this->title,
804
+ ],
805
+ ];
806
+
807
+ foreach ( $configs as $config ) {
808
+ $property = $config['property'];
809
+
810
+ if ( ! empty( $settings['remote'][ $this->key ][ $property ] ) ) {
811
+ $this->$property = $settings['remote'][ $this->key ][ $property ];
812
+ } else {
813
+ $this->$property = $config['default'];
814
+ }
815
+ }
816
+
817
+ if ( ! empty( $this->host ) ) {
818
+ $this->title_attr = strtoupper( $this->type ) . ': ' . $this->host;
819
+ }
820
+ }
821
+
822
+ /**
823
+ * Determine whether or not FTP is setup.
824
+ *
825
+ * @since 1.6.0
826
+ *
827
+ * @param bool $try_cache Whether or not to use the last_login value to determine if we are
828
+ * setup. For example, if $try_cache and we logged in an hour ago, no
829
+ * need to try to connect and log in again, we logged in an hour ago so
830
+ * assume all is still good.
831
+ * @return bool
832
+ */
833
+ public function is_setup( $try_cache = false ) {
834
+
835
+ // If successfully logged in within last 24 hours, return true.
836
+ if ( $try_cache && $this->settings->is_last_login_valid() ) {
837
+ return true;
838
+ }
839
+
840
+ $this->connect();
841
+ $this->log_in();
842
+
843
+ $logged_in = $this->logged_in;
844
+
845
+ return $logged_in;
846
+ }
847
+
848
+ /**
849
+ * Determine if a set of FTP credentials are valid.
850
+ *
851
+ * @since 1.6.0
852
+ *
853
+ * @param string $host Hostname.
854
+ * @param string $user Username.
855
+ * @param string $pass Password.
856
+ * @param int $port Port number.
857
+ * @param string $type Type.
858
+ * @param string $ftp_mode FTP mode: active, passive.
859
+ * @return bool
860
+ */
861
+ public function is_valid_credentials( $host, $user, $pass, $port, $type, $ftp_mode ) {
862
+ $connection = false;
863
+ $logged_in = false;
864
+ $port = intval( $port );
865
+
866
+ // Avoid a really long timeout.
867
+ if ( 21 === $port && 'sftp' === $type ) {
868
+ $this->errors[] = sprintf(
869
+ // translators: 1: Hostname, 2: Port number.
870
+ __(
871
+ 'Unable to connect to %1$s over port %2$u.',
872
+ 'boldgrid-backup'
873
+ ),
874
+ $host,
875
+ $port
876
+ );
877
+ return false;
878
+ }
879
+
880
+ switch ( $type ) {
881
+ case 'ftp':
882
+ $connection = @ftp_connect( $host, $port, $this->timeout ); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged
883
+ break;
884
+ case 'ftpes':
885
+ $connection = @ftp_ssl_connect( $host, $port, $this->timeout ); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged
886
+ break;
887
+ case 'sftp':
888
+ $connection = @new phpseclib\Net\SFTP( $host, $port, $this->timeout ); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged
889
+ break;
890
+ default:
891
+ break;
892
+ }
893
+ if ( ! $connection ) {
894
+ $this->errors[] = sprintf(
895
+ // translators: 1: Hostname, 2: Port number.
896
+ __(
897
+ 'Unable to connect to %1$s over port %2$u.',
898
+ 'boldgrid-backup'
899
+ ),
900
+ $host,
901
+ $port
902
+ );
903
+ return false;
904
+ }
905
+
906
+ /*
907
+ * Try to login.
908
+ *
909
+ * When:
910
+ * # Connecting over bad ports (like port FTP over port 22)
911
+ * # Using invalid login credentials
912
+ * Notices are thrown instead of catachable errors. This makes it difficult
913
+ * to know if a connection failed because of of a bad port number or because
914
+ * of bad credentials.
915
+ *
916
+ * If we have any trouble connecting, we'll use a custom error handler
917
+ * and throw an Exception.
918
+ */
919
+ $error_caught = false;
920
+ $ftp_listing_success = true;
921
+
922
+ set_error_handler( // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_set_error_handler
923
+ [
924
+ 'Boldgrid_Backup_Admin_Utility',
925
+ 'handle_error',
926
+ ]
927
+ );
928
+
929
+ try {
930
+ switch ( $type ) {
931
+ case 'ftp':
932
+ case 'ftpes':
933
+ $logged_in = ftp_login( $connection, $user, $pass );
934
+ if ( 'auto' !== $ftp_mode ) {
935
+ if ( 'passive' === $ftp_mode ) {
936
+ ftp_pasv( $connection, true );
937
+ }
938
+ $ftp_listing_success = is_array( ftp_nlist( $connection, '.' ) );
939
+ }
940
+ ftp_close( $connection );
941
+ break;
942
+ case 'sftp':
943
+ $logged_in = $connection->login( $user, $pass );
944
+ break;
945
+ default:
946
+ break;
947
+ }
948
+ } catch ( Exception $e ) {
949
+ $this->errors[] = $e->getMessage();
950
+ $error_caught = true;
951
+ }
952
+ restore_error_handler();
953
+
954
+ if ( ! $error_caught && ! $logged_in ) {
955
+ $this->errors[] = __( 'Invalid username / password.', 'boldgrid-backup' );
956
+ }
957
+
958
+ if ( ! $ftp_listing_success ) {
959
+ $this->errors[] = __( 'Could not retrieve FTP directory listing.', 'boldgrid-backup' );
960
+ $logged_in = false;
961
+ }
962
+
963
+ return false !== $logged_in;
964
+ }
965
+
966
+ /**
967
+ * Log into the FTP server.
968
+ *
969
+ * @since 1.6.0
970
+ *
971
+ * @return bool
972
+ */
973
+ public function log_in() {
974
+ if ( $this->logged_in ) {
975
+ return;
976
+ }
977
+
978
+ // If we tried to connect but don't have a connection, abort.
979
+ $this->connect();
980
+ if ( empty( $this->connection ) ) {
981
+ return false;
982
+ }
983
+
984
+ switch ( $this->type ) {
985
+ case 'ftp':
986
+ case 'ftpes':
987
+ $this->logged_in = @ftp_login( $this->connection, $this->user, $this->pass ); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged
988
+ break;
989
+ case 'sftp':
990
+ $this->logged_in = $this->connection->login( $this->user, $this->pass );
991
+ break;
992
+ default:
993
+ break;
994
+ }
995
+
996
+ if ( $this->logged_in && ! $this->reconnected ) {
997
+ $this->maybe_passive();
998
+
999
+ $this->settings->set_last_login();
1000
+ }
1001
+ }
1002
+
1003
+ /**
1004
+ * Turn on passive mode, only if needed.
1005
+ *
1006
+ * Turning on passive mode can only be done after a successful login. This method assumes you've
1007
+ * already logged in.
1008
+ *
1009
+ * @since 1.7.0
1010
+ */
1011
+ public function maybe_passive() {
1012
+ if ( 'active' !== $this->ftp_mode && ( 'ftp' === $this->type || 'ftpes' === $this->type ) ) {
1013
+ $this->ftp_mode = 'auto' === $this->ftp_mode && is_array( $this->get_contents() ) ?
1014
+ 'active' : 'passive';
1015
+
1016
+ // If the ftp_mode has changed, then save it.
1017
+ $settings = $this->core->settings->get_settings();
1018
+ $saved_ftp_mode = ! empty( $settings['remote'][ $this->key ]['ftp_mode'] ) ?
1019
+ $settings['remote'][ $this->key ]['ftp_mode'] : null;
1020
+ if ( $saved_ftp_mode !== $this->ftp_mode ) {
1021
+ $settings['remote'][ $this->key ]['ftp_mode'] = $this->ftp_mode;
1022
+ update_site_option( 'boldgrid_backup_settings', $settings );
1023
+ }
1024
+
1025
+ if ( 'passive' === $this->ftp_mode ) {
1026
+ $this->reconnected = true;
1027
+ $this->disconnect();
1028
+ $this->connect();
1029
+ $this->log_in();
1030
+ ftp_pasv( $this->connection, true );
1031
+ }
1032
+ }
1033
+ }
1034
+
1035
+ /**
1036
+ * Reset class properties.
1037
+ *
1038
+ * If the user wants to delete all FTP settings, after we clear the data from
1039
+ * the options, run this method to clear the properties.
1040
+ *
1041
+ * @since 1.6.0
1042
+ */
1043
+ public function reset() {
1044
+ $this->host = null;
1045
+ $this->user = null;
1046
+ $this->set_pass( null );
1047
+ $this->port = $this->default_port['ftp'];
1048
+ $this->retention_count = null;
1049
+ $this->type = $this->default_type;
1050
+ $this->ftp_mode = $this->default_ftp_mode;
1051
+ }
1052
+
1053
+ /**
1054
+ * Set our default_folder_name.
1055
+ *
1056
+ * @since 1.9.1
1057
+ */
1058
+ public function set_default_folder_name() {
1059
+ $site_url = get_site_url();
1060
+ $site_url = str_replace( 'https://', '', $site_url );
1061
+ $site_url = str_replace( 'http://', '', $site_url );
1062
+ $site_url = str_replace( '/', '-', $site_url );
1063
+ $site_url = str_replace( '.', '-', $site_url );
1064
+
1065
+ $this->default_folder_name = sanitize_file_name( 'boldgrid-backup-' . $site_url );
1066
+ }
1067
+
1068
+ /**
1069
+ * Set our ftp password.
1070
+ *
1071
+ * @since 1.6.0
1072
+ *
1073
+ * @param string $pass Password.
1074
+ */
1075
+ public function set_pass( $pass ) {
1076
+ $this->pass = $pass;
1077
+ }
1078
+
1079
+ /**
1080
+ * Determine if a backup archive is uploaded to the remote server.
1081
+ *
1082
+ * @since 1.6.0
1083
+ *
1084
+ * @param string $filepath File path.
1085
+ */
1086
+ public function is_uploaded( $filepath ) {
1087
+ $contents = $this->get_contents( false, $this->get_folder_name() );
1088
+
1089
+ return ! is_array( $contents ) ? false : in_array( basename( $filepath ), $contents, true );
1090
+ }
1091
+
1092
+ /**
1093
+ * Upload a file.
1094
+ *
1095
+ * @since 1.6.0
1096
+ *
1097
+ * @param string $filepath File path.
1098
+ * @return bool
1099
+ */
1100
+ public function upload( $filepath ) {
1101
+ // Make sure our backup file exists.
1102
+ if ( ! $this->core->wp_filesystem->exists( $filepath ) ) {
1103
+ $this->last_error = sprintf(
1104
+ // translators: 1 The filepath to a backup file.
1105
+ __( 'Archive does not exist: $1$s', 'boldgrid-backup' ),
1106
+ $filepath
1107
+ );
1108
+ return false;
1109
+ }
1110
+
1111
+ $remote_file = $this->get_folder_name() . '/' . basename( $filepath );
1112
+
1113
+ $timestamp = filemtime( $filepath );
1114
+
1115
+ $this->connect();
1116
+ $this->log_in();
1117
+ if ( ! $this->logged_in ) {
1118
+ $this->errors[] = __( 'Unable to log in to ftp server.', 'boldgrid-backup' );
1119
+ return false;
1120
+ }
1121
+
1122
+ $has_remote_dir = $this->create_backup_dir();
1123
+ if ( ! $has_remote_dir ) {
1124
+ return false;
1125
+ }
1126
+
1127
+ switch ( $this->type ) {
1128
+ case 'ftp':
1129
+ case 'ftpes':
1130
+ $uploaded = ftp_put( $this->connection, $remote_file, $filepath, FTP_BINARY );
1131
+
1132
+ /*
1133
+ * Ensure the timestamp is unchanged.
1134
+ *
1135
+ * Not 100% accurate however. In testing, when setting a remote file's timestamp to
1136
+ * 11am UTC, that remote server convereted the UTC time to local time.
1137
+ */
1138
+ $cmd = 'MFMT ' . date( 'YmdHis', $timestamp ) . ' ' . $remote_file;
1139
+ ftp_raw( $this->connection, $cmd );
1140
+ break;
1141
+ case 'sftp':
1142
+ $uploaded = $this->connection->put( $remote_file, $filepath, 1 );
1143
+
1144
+ // Adjust timestamp.
1145
+ $this->connection->touch( $remote_file, $timestamp );
1146
+ break;
1147
+ default:
1148
+ break;
1149
+ }
1150
+
1151
+ if ( ! $uploaded ) {
1152
+ $last_error = error_get_last();
1153
+
1154
+ $this->errors[] = __( 'Unable to upload file.', 'boldgrid-backup' );
1155
+
1156
+ /*
1157
+ * The last error message may be important on a failed uploaded,
1158
+ * such as ftp_put(): Quota exceeded. Make sure the user sees the
1159
+ * last error.
1160
+ */
1161
+ if ( ! empty( $last_error['message'] ) && ! empty( $last_error['file'] ) && __FILE__ === $last_error['file'] ) {
1162
+ $this->errors[] = $last_error['message'];
1163
+ }
1164
+
1165
+ return false;
1166
+ }
1167
+
1168
+ $this->enforce_retention();
1169
+
1170
+ return true;
1171
+ }
1172
+ }
admin/remote/class-boldgrid-backup-admin-remote-settings.php ADDED
@@ -0,0 +1,235 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File: class-boldgrid-backup-admin-remote-settings.php
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.7.2
7
+ *
8
+ * @package Boldgrid_Backup
9
+ * @subpackage Boldgrid_Backup/admin/remote
10
+ * @copyright BoldGrid
11
+ * @version $Id$
12
+ * @author BoldGrid <support@boldgrid.com>
13
+ */
14
+
15
+ /**
16
+ * Class: Boldgrid_Backup_Admin_Remote_Settings
17
+ *
18
+ * The purpose of this class is to handle remote settings stored in the database. This class was
19
+ * introduced as of 1.7.2, however prior code working with settings has not been refactored to use
20
+ * this class.
21
+ *
22
+ * The remote settings are stored in the boldgrid_backup_settings option, such as:
23
+ * boldgrid_backup_settings['remote']['ftp']['host']
24
+ *
25
+ * @since 1.7.2
26
+ */
27
+ class Boldgrid_Backup_Admin_Remote_Settings {
28
+ /**
29
+ * Our remote_id.
30
+ *
31
+ * For example, the 'ftp' in boldgrid_backup_settings['remote']['ftp'].
32
+ *
33
+ * @since 1.7.2
34
+ * @access private
35
+ * @var string
36
+ */
37
+ private $remote_id;
38
+
39
+ /**
40
+ * The settings key that stores the last successful login.
41
+ *
42
+ * For example, the last_login in boldgrid_backup_settings['remote']['ftp']['last_login'].
43
+ *
44
+ * @since 1.7.2
45
+ * @access private
46
+ * @var string
47
+ */
48
+ private $last_login_key = 'last_login';
49
+
50
+ /**
51
+ * The WordPress option that stores settings.
52
+ *
53
+ * @since 1.7.2
54
+ * @access private
55
+ * @var string
56
+ */
57
+ private $option_name = 'boldgrid_backup_settings';
58
+
59
+ /**
60
+ * The key within our settings option that contains all remote settings.
61
+ *
62
+ * For example, the 'remote' in boldgrid_backup_settings['remote']['ftp'].
63
+ *
64
+ * @since 1.7.2
65
+ * @access private
66
+ * @var string
67
+ */
68
+ private $remote_key = 'remote';
69
+
70
+ /**
71
+ * Constructor.
72
+ *
73
+ * @since 1.7.2
74
+ *
75
+ * @param string $remote_id The remote id, such as 'ftp' or 'amazon_s3'.
76
+ */
77
+ public function __construct( $remote_id ) {
78
+ $this->remote_id = $remote_id;
79
+ }
80
+
81
+ /**
82
+ * Delete all settings for this provider.
83
+ *
84
+ * @since 1.11.3
85
+ */
86
+ public function delete_settings() {
87
+ $this->save_settings( [] );
88
+ }
89
+
90
+ /**
91
+ * Get the time we last logged in successfully.
92
+ *
93
+ * @since 1.7.2
94
+ *
95
+ * @return int
96
+ */
97
+ public function get_last_login() {
98
+ return $this->get_setting( $this->last_login_key, 0 );
99
+ }
100
+
101
+ /**
102
+ * Get our boldgrid_backup_settings option.
103
+ *
104
+ * @since 1.7.2
105
+ *
106
+ * @return array
107
+ */
108
+ public function get_option() {
109
+ return get_option( $this->option_name, array() );
110
+ }
111
+
112
+ /**
113
+ * Get one setting.
114
+ *
115
+ * @since 1.7.2
116
+ *
117
+ * @param string $key The key of the setting.
118
+ * @param mixed $default The default value if one does not exist.
119
+ * @return mixed
120
+ */
121
+ public function get_setting( $key, $default = false ) {
122
+ $settings = $this->get_settings();
123
+
124
+ return isset( $settings[ $key ] ) ? $settings[ $key ] : $default;
125
+ }
126
+
127
+ /**
128
+ * Get our remote_id's settings.
129
+ *
130
+ * For example, if our remote_id is 'ftp', return all of our ftp settings.
131
+ *
132
+ * @since 1.7.2
133
+ *
134
+ * @return array
135
+ */
136
+ public function get_settings() {
137
+ $option = $this->get_option();
138
+
139
+ $settings = ! empty( $option[ $this->remote_key ][ $this->remote_id ] ) ? $option[ $this->remote_key ][ $this->remote_id ] : array();
140
+
141
+ return $settings;
142
+ }
143
+
144
+ /**
145
+ * Deterine whether or not this provider has a set of settings.
146
+ *
147
+ * For example, if working with an s3 client, we'll want to know if it has a key, host, etc.
148
+ *
149
+ * @since 1.11.3
150
+ *
151
+ * @param array $keys An array of keys to check for.
152
+ * @return bool
153
+ */
154
+ public function has_setting_keys( array $keys ) {
155
+ $has_setting_keys = true;
156
+
157
+ $settings = $this->get_settings();
158
+
159
+ foreach ( $keys as $key ) {
160
+ if ( empty( $settings[ $key ] ) ) {
161
+ $has_setting_keys = false;
162
+ }
163
+ }
164
+
165
+ return $has_setting_keys;
166
+ }
167
+
168
+ /**
169
+ * Whether or not this remove provider has settings saved.
170
+ *
171
+ * @since 1.11.3
172
+ *
173
+ * @return bool
174
+ */
175
+ public function has_settings() {
176
+ $settings = $this->get_settings();
177
+
178
+ return is_array( $settings ) && ! empty( $settings );
179
+ }
180
+
181
+ /**
182
+ * Determine whether or not our last login is within the last_login_lifetime range.
183
+ *
184
+ * Please see comments for last_login_lifetime within the plugin's config file.
185
+ *
186
+ * @since 1.7.2
187
+ *
188
+ * @return bool
189
+ */
190
+ public function is_last_login_valid() {
191
+ $core = apply_filters( 'boldgrid_backup_get_core', null );
192
+
193
+ return $this->get_last_login() + $core->configs['last_login_lifetime'] >= time();
194
+ }
195
+
196
+ /**
197
+ * Set and save a setting.
198
+ *
199
+ * @since 1.7.2
200
+ *
201
+ * @param string $key Key/index.
202
+ * @param mixed $value Value.
203
+ */
204
+ public function save_setting( $key, $value ) {
205
+ $settings = $this->get_settings();
206
+
207
+ $settings[ $key ] = $value;
208
+
209
+ $this->save_settings( $settings );
210
+ }
211
+
212
+ /**
213
+ * Save our remote_id's settings.
214
+ *
215
+ * @since 1.7.2
216
+ *
217
+ * @param array $settings An array containing our remote_id's settings.
218
+ */
219
+ public function save_settings( $settings ) {
220
+ $option = $this->get_option();
221
+
222
+ $option[ $this->remote_key ][ $this->remote_id ] = $settings;
223
+
224
+ update_option( $this->option_name, $option );
225
+ }
226
+
227
+ /**
228
+ * Set the time that we last logged in successfully.
229
+ *
230
+ * @since 1.7.2
231
+ */
232
+ public function set_last_login() {
233
+ $this->save_setting( $this->last_login_key, time() );
234
+ }
235
+ }
admin/remote/ftp-page.php DELETED
@@ -1,190 +0,0 @@
1
- <?php
2
- /**
3
- * FTP Page class.
4
- *
5
- * @link http://www.boldgrid.com
6
- * @since 1.5.4
7
- *
8
- * @package Boldgrid_Backup
9
- * @subpackage Boldgrid_Backup/admin
10
- * @copyright BoldGrid.com
11
- * @version $Id$
12
- * @author BoldGrid.com <wpb@boldgrid.com>
13
- */
14
-
15
- /**
16
- * FTP Page class.
17
- *
18
- * @since 1.5.4
19
- */
20
- class Boldgrid_Backup_Admin_Ftp_Page {
21
-
22
- /**
23
- * The core class object.
24
- *
25
- * @since 1.5.4
26
- * @access private
27
- * @var Boldgrid_Backup_Admin_Core
28
- */
29
- private $core;
30
-
31
- /**
32
- * Constructor.
33
- *
34
- * @since 1.5.4
35
- *
36
- * @param Boldgrid_Backup_Admin_Core $core Core class object.
37
- */
38
- public function __construct( $core ) {
39
- $this->core = $core;
40
- }
41
-
42
- /**
43
- * Enqueue scripts.
44
- *
45
- * @since 1.5.4
46
- */
47
- public function enqueue_scripts() {
48
- $handle = 'boldgrid-backup-admin-ftp-settings';
49
- wp_register_script( $handle,
50
- plugin_dir_url( dirname( __FILE__ ) ) . 'js/' . $handle . '.js',
51
- array( 'jquery' ),
52
- BOLDGRID_BACKUP_VERSION,
53
- false
54
- );
55
- $translation = array(
56
- 'default_port' => $this->core->ftp->default_port,
57
- );
58
- wp_localize_script( $handle, 'BoldGridBackupAdminFtpSettings', $translation );
59
- wp_enqueue_script( $handle );
60
-
61
- wp_enqueue_style(
62
- $handle,
63
- plugin_dir_url( dirname( __FILE__ ) ) . 'css/' . $handle . '.css',
64
- array(),
65
- BOLDGRID_BACKUP_VERSION
66
- );
67
- }
68
-
69
- /**
70
- * Generate the submenu page for our FTP Settings page.
71
- *
72
- * @since 1.5.4
73
- */
74
- public function settings() {
75
- if ( ! current_user_can( 'update_plugins' ) ) {
76
- return false;
77
- }
78
-
79
- $this->enqueue_scripts();
80
- wp_enqueue_style( 'boldgrid-backup-admin-hide-all' );
81
-
82
- // Blank data, used when deleting settings.
83
- $type = $this->core->ftp->default_type;
84
- $blank_data = array(
85
- 'type' => $type,
86
- 'host' => null,
87
- 'port' => $this->core->ftp->default_port[ $type ],
88
- 'user' => null,
89
- 'pass' => null,
90
- 'retention_count' => $this->core->ftp->retention_count,
91
- 'nickname' => '',
92
- );
93
-
94
- // Post data, used by default or when updating settings.
95
- $post_data = $this->core->ftp->get_from_post();
96
-
97
- $action = ! empty( $_POST['action'] ) ? sanitize_key( $_POST['action'] ) : null;
98
-
99
- switch ( $action ) {
100
- case 'save':
101
- echo $this->core->elements['long_checking_creds'];
102
- ob_flush();
103
- flush();
104
-
105
- $this->settings_save();
106
- $data = $post_data;
107
- break;
108
- case 'delete':
109
- $this->settings_delete();
110
- $data = $blank_data;
111
- break;
112
- default:
113
- $data = $post_data;
114
- }
115
-
116
- include BOLDGRID_BACKUP_PATH . '/admin/partials/remote/ftp.php';
117
- }
118
-
119
- /**
120
- * Process the user's request to update their FTP settings.
121
- *
122
- * @since 1.5.4
123
- */
124
- public function settings_delete() {
125
- $ftp = $this->core->ftp;
126
-
127
- if ( ! current_user_can( 'update_plugins' ) ) {
128
- return false;
129
- }
130
-
131
- $settings = $this->core->settings->get_settings();
132
- if ( ! isset( $settings['remote'][ $ftp->key ] ) || ! is_array( $settings['remote'][ $ftp->key ] ) ) {
133
- $settings['remote'][ $ftp->key ] = array();
134
- }
135
-
136
- $settings['remote'][ $ftp->key ] = array();
137
- update_site_option( 'boldgrid_backup_settings', $settings );
138
-
139
- $ftp->reset();
140
- $ftp->disconnect();
141
-
142
- do_action( 'boldgrid_backup_notice', __( 'Settings deleted.', 'boldgrid-backup' ), 'notice updated is-dismissible' );
143
- }
144
-
145
- /**
146
- * Process the user's request to update their FTP settings.
147
- *
148
- * @since 1.5.4
149
- */
150
- public function settings_save() {
151
-
152
- // Readability.
153
- $ftp = $this->core->ftp;
154
-
155
- if ( ! current_user_can( 'update_plugins' ) ) {
156
- return false;
157
- }
158
-
159
- if ( empty( $_POST ) ) {
160
- return false;
161
- }
162
-
163
- $settings = $this->core->settings->get_settings();
164
- if ( ! isset( $settings['remote'][ $ftp->key ] ) || ! is_array( $settings['remote'][ $ftp->key ] ) ) {
165
- $settings['remote'][ $ftp->key ] = array();
166
- }
167
-
168
- $data = $ftp->get_from_post();
169
-
170
- $valid_credentials = $ftp->is_valid_credentials( $data['host'], $data['user'], $data['pass'], $data['port'], $data['type'] );
171
-
172
- if ( $valid_credentials ) {
173
- $settings['remote'][ $ftp->key ]['host'] = $data['host'];
174
- $settings['remote'][ $ftp->key ]['user'] = $data['user'];
175
- $settings['remote'][ $ftp->key ]['pass'] = $data['pass'];
176
- $settings['remote'][ $ftp->key ]['port'] = $data['port'];
177
- $settings['remote'][ $ftp->key ]['type'] = $data['type'];
178
- }
179
-
180
- $settings['remote'][ $ftp->key ]['retention_count'] = $data['retention_count'];
181
- $settings['remote'][ $ftp->key ]['nickname'] = $data['nickname'];
182
-
183
- if ( ! empty( $ftp->errors ) ) {
184
- do_action( 'boldgrid_backup_notice', implode( '<br /><br />', $ftp->errors ) );
185
- } else {
186
- update_site_option( 'boldgrid_backup_settings', $settings );
187
- do_action( 'boldgrid_backup_notice', __( 'Settings saved.', 'boldgrid-backup' ), 'notice updated is-dismissible' );
188
- }
189
- }
190
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/remote/ftp.php DELETED
@@ -1,858 +0,0 @@
1
- <?php
2
- /**
3
- * FTP class.
4
- *
5
- * @link http://www.boldgrid.com
6
- * @since 1.5.4
7
- *
8
- * @package Boldgrid_Backup
9
- * @subpackage Boldgrid_Backup/admin
10
- * @copyright BoldGrid.com
11
- * @version $Id$
12
- * @author BoldGrid.com <wpb@boldgrid.com>
13
- */
14
-
15
- /**
16
- * FTP class.
17
- *
18
- * @since 1.5.4
19
- */
20
- class Boldgrid_Backup_Admin_Ftp {
21
-
22
- /**
23
- * An FTP connection.
24
- *
25
- * @since 1.5.4
26
- * @access private
27
- * @var Resource
28
- */
29
- private $connection = null;
30
-
31
- /**
32
- * The core class object.
33
- *
34
- * @since 1.5.4
35
- * @access private
36
- * @var Boldgrid_Backup_Admin_Core
37
- */
38
- private $core;
39
-
40
- /**
41
- * Default port numbers.
42
- *
43
- * @since 1.5.4
44
- * @access public
45
- * @var array
46
- */
47
- public $default_port = array(
48
- 'ftp' => 21,
49
- 'sftp' => 22,
50
- );
51
-
52
- /**
53
- * Default type.
54
- *
55
- * @since 1.5.4
56
- * @access public
57
- * @var string
58
- */
59
- public $default_type = 'sftp';
60
-
61
- /**
62
- * Errors.
63
- *
64
- * @since 1.5.4
65
- * @access public
66
- * @var array
67
- */
68
- public $errors = array();
69
-
70
- /**
71
- * Hooks class.
72
- *
73
- * @since 1.5.4
74
- * @access public
75
- * @var Boldgrid_Backup_Admin_Ftp_Hooks
76
- */
77
- public $hooks;
78
-
79
- /**
80
- * FTP host.
81
- *
82
- * @since 1.5.4
83
- * @access private
84
- * @var string
85
- */
86
- private $host = null;
87
-
88
- /**
89
- * Whether or not we have logged in.
90
- *
91
- * @since 1.5.4
92
- * @access public
93
- * @var bool
94
- */
95
- public $logged_in = false;
96
-
97
- /**
98
- * Nickname.
99
- *
100
- * So the user can refer to their ftp account as something other than ftp.
101
- *
102
- * @since 1.6.0
103
- * @access public
104
- * @var string
105
- */
106
- public $nickname;
107
-
108
- /**
109
- * Our key / label for ftp.
110
- *
111
- * @since 1.5.4
112
- * @access public
113
- * @var string
114
- */
115
- public $key = 'ftp';
116
-
117
- /**
118
- * FTP password.
119
- *
120
- * @since 1.5.4
121
- * @access private
122
- * @var string
123
- */
124
- private $pass = null;
125
-
126
- /**
127
- * FTP remote directory.
128
- *
129
- * @since 1.5.4
130
- * @access public
131
- * @var string
132
- */
133
- public $remote_dir = 'boldgrid_backup';
134
-
135
- /**
136
- * Retention count.
137
- *
138
- * @since 1.5.4
139
- * @access public
140
- * @var int $retention_count
141
- */
142
- public $retention_count = 5;
143
-
144
- /**
145
- * Default timeout.
146
- *
147
- * @since 1.5.4
148
- * @access public
149
- * @var int
150
- */
151
- public $timeout = 10;
152
-
153
- /**
154
- * Our title / label for ftp.
155
- *
156
- * @since 1.5.4
157
- * @access public
158
- * @var string
159
- */
160
- public $title = 'FTP / SFTP';
161
-
162
- /**
163
- * Title attribute.
164
- *
165
- * If you are using a nickname, hovering over the nickname should show this
166
- * more clear title.
167
- *
168
- * @since 1.6.0
169
- * @access public
170
- * @var string
171
- */
172
- public $title_attr;
173
-
174
- /**
175
- * Our FTP type, ftp or sftp.
176
- *
177
- * @since 1.5.4
178
- * @access public
179
- * @var string
180
- */
181
- public $type = null;
182
-
183
- /**
184
- * FTP username.
185
- *
186
- * @since 1.5.4
187
- * @access private
188
- * @var string
189
- */
190
- private $user = null;
191
-
192
- /**
193
- * Valid types.
194
- *
195
- * @since 1.5.4
196
- * @access public
197
- * @var array
198
- */
199
- public $valid_types = array( 'ftp', 'sftp' );
200
-
201
- /**
202
- * Constructor.
203
- *
204
- * @since 1.5.4
205
- *
206
- * @param Boldgrid_Backup_Admin_Core $core Core class object.
207
- */
208
- public function __construct( $core ) {
209
- include_once BOLDGRID_BACKUP_PATH . '/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php';
210
-
211
- $this->core = $core;
212
- $this->hooks = new Boldgrid_Backup_Admin_Ftp_Hooks( $core );
213
- $this->page = new Boldgrid_Backup_Admin_Ftp_Page( $core );
214
- }
215
-
216
- /**
217
- * Connect to our ftp server.
218
- *
219
- * @since 1.5.4
220
- */
221
- public function connect() {
222
- if ( ! empty( $this->connection ) ) {
223
- return;
224
- }
225
-
226
- $this->init();
227
-
228
- if ( empty( $this->user ) || empty( $this->pass ) || empty( $this->host ) || empty( $this->type ) || empty( $this->port ) ) {
229
- return;
230
- }
231
-
232
- switch ( $this->type ) {
233
- case 'ftp':
234
- $this->connection = ftp_connect( $this->host, $this->port, $this->timeout );
235
- break;
236
- case 'sftp':
237
- $this->connection = new phpseclib\Net\SFTP( $this->host, $this->port );
238
- break;
239
- }
240
- }
241
-
242
- /**
243
- * Create backup directory on remote host.
244
- *
245
- * @since 1.5.4
246
- *
247
- * @return bool False when we were unable to create directory.
248
- */
249
- public function create_backup_dir() {
250
- $this->connect();
251
- $this->log_in();
252
- if ( ! $this->logged_in ) {
253
- return false;
254
- }
255
-
256
- $contents = $this->get_contents();
257
- if ( ! $contents || ! is_array( $contents ) ) {
258
- $this->errors[] = __( 'Unable to get a directory listing from FTP server.', 'boldgrid-backup' );
259
- return false;
260
- } elseif ( in_array( $this->remote_dir, $contents, true ) ) {
261
- return true;
262
- }
263
-
264
- switch ( $this->type ) {
265
- case 'ftp':
266
- $created = ftp_mkdir( $this->connection, $this->remote_dir );
267
- break;
268
- case 'sftp':
269
- $created = $this->connection->mkdir( $this->remote_dir );
270
- break;
271
- }
272
-
273
- if ( ! $created ) {
274
- $this->errors[] = sprintf( __( 'Unable to create the following directory on FTP server: %1$s', 'boldgrid-backup' ), $this->remote_dir );
275
- }
276
-
277
- return $created;
278
- }
279
-
280
- /**
281
- * Disconnect from FTP server.
282
- *
283
- * @since 1.5.4
284
- */
285
- public function disconnect() {
286
- if ( 'ftp' === $this->type && is_resource( $this->connection ) ) {
287
- ftp_close( $this->connection );
288
- $this->connection = null;
289
- $this->logged_in = false;
290
- }
291
- }
292
-
293
- /**
294
- * Download a backup via FTP.
295
- *
296
- * @since 1.5.4
297
- *
298
- * @param string $filename
299
- * @return bool
300
- */
301
- public function download( $filename ) {
302
- $this->connect();
303
-
304
- $local_filepath = $this->core->backup_dir->get_path_to( $filename );
305
- $server_filepath = $this->remote_dir . '/' . $filename;
306
- $success = false;
307
-
308
- $this->log_in();
309
-
310
- switch ( $this->type ) {
311
- case 'ftp':
312
- $success = ftp_get( $this->connection, $local_filepath, $server_filepath, FTP_BINARY );
313
- break;
314
- case 'sftp':
315
- $success = $this->connection->get( $server_filepath, $local_filepath );
316
- break;
317
- }
318
-
319
- if ( $success ) {
320
- $this->core->remote->post_download( $local_filepath );
321
- }
322
-
323
- return $success;
324
- }
325
-
326
- /**
327
- * Enforce retention.
328
- *
329
- * @since 1.5.4
330
- */
331
- public function enforce_retention() {
332
- if ( empty( $this->retention_count ) ) {
333
- return;
334
- }
335
-
336
- $contents = $this->get_contents( true, $this->remote_dir );
337
- $backups = $this->format_raw_contents( $contents );
338
-
339
- $count_to_delete = count( $backups ) - $this->retention_count;
340
-
341
- if ( empty( $backups ) || $count_to_delete <= 0 ) {
342
- return false;
343
- }
344
-
345
- usort( $backups, function( $a, $b ) {
346
- return $a['time'] < $b['time'] ? -1 : 1;
347
- });
348
-
349
- for ( $x = 0; $x < $count_to_delete; $x++ ) {
350
- $filename = $backups[ $x ]['filename'];
351
- $path = $this->remote_dir . '/' . $filename;
352
-
353
- switch ( $this->type ) {
354
- case 'ftp':
355
- ftp_delete( $this->connection, $path );
356
- break;
357
- case 'sftp':
358
- $this->connection->delete( $path, false );
359
- break;
360
- }
361
-
362
- /**
363
- * Remote file deleted due to remote retention settings.
364
- *
365
- * @since 1.5.4
366
- */
367
- do_action(
368
- 'boldgrid_backup_remote_retention_deleted',
369
- $this->title,
370
- $filename
371
- );
372
- }
373
- }
374
-
375
- /**
376
- * Get our settings from $_POST.
377
- *
378
- * @since 1.5.4
379
- *
380
- * @return array
381
- */
382
- public function get_from_post() {
383
- $settings = $this->core->settings->get_settings();
384
-
385
- $values = array(
386
- array(
387
- 'key' => 'host',
388
- 'default' => null,
389
- 'callback' => 'sanitize_file_name',
390
- ),
391
- array(
392
- 'key' => 'user',
393
- 'default' => null,
394
- 'callback' => 'sanitize_text_field',
395
- ),
396
- array(
397
- 'key' => 'pass',
398
- 'default' => null,
399
- ),
400
- array(
401
- 'key' => 'type',
402
- 'default' => $this->default_type,
403
- 'callback' => 'sanitize_key',
404
- ),
405
- array(
406
- 'key' => 'port',
407
- 'default' => $this->default_port[ $this->default_type ],
408
- 'callback' => 'intval',
409
- ),
410
- array(
411
- 'key' => 'retention_count',
412
- 'default' => $this->retention_count,
413
- 'callback' => 'intval',
414
- ),
415
- array(
416
- 'key' => 'nickname',
417
- 'default' => '',
418
- 'callback' => 'stripslashes',
419
- ),
420
- );
421
-
422
- foreach ( $values as $value ) {
423
- $key = $value['key'];
424
- $callback = ! empty( $value['callback'] ) ? $value['callback'] : null;
425
-
426
- if ( ! empty( $_POST[ $key ] ) ) {
427
- $data[ $key ] = $_POST[ $key ];
428
- } elseif ( ! empty( $settings['remote'][ $this->key ][ $key ] ) ) {
429
- $data[ $key ] = $settings['remote'][ $this->key ][ $key ];
430
- } else {
431
- $data[ $key ] = $value['default'];
432
- }
433
-
434
- // If there is a callback function for sanitizing the value, then run it.
435
- if ( $callback ) {
436
- $data[ $key ] = $callback( $data[ $key ] );
437
- }
438
- }
439
-
440
- return $data;
441
- }
442
-
443
- /**
444
- * Format raw contents.
445
- *
446
- * This method takes in raw contents and returns an array of backups, with
447
- * keys defining timestamp and filename.
448
- *
449
- * The array of backups returned DO NOT include:
450
- * # . or .. (typical when getting a directory listing).
451
- * # Files / backups that do not belong to this site.
452
- * See $this->core->archive->is_site_archive().
453
- *
454
- * @since 1.5.4
455
- *
456
- * @param array $conents Raw contents received from this->get_contents.
457
- * @return array {
458
- * An array of backups.
459
- *
460
- * @type int $time Timestamp file was uploaded to ftp server.
461
- * @type string $filename
462
- * }
463
- */
464
- public function format_raw_contents( $contents ) {
465
- $skips = array( '.', '..' );
466
- $backups = array();
467
-
468
- if ( ! is_array( $contents ) ) {
469
- return $backups;
470
- }
471
-
472
- foreach ( $contents as $item ) {
473
-
474
- if ( 'sftp' === $this->type ) {
475
- $filename = $item['filename'];
476
- if ( in_array( $filename, $skips, true ) ) {
477
- continue;
478
- }
479
-
480
- $backups[] = array(
481
- 'time' => $item['mtime'],
482
- 'filename' => $filename,
483
- 'size' => $item['size'],
484
- );
485
- } else {
486
- // Before exploding by space, replace multiple spaces with one space.
487
- $item = preg_replace( '!\s+!', ' ', $item );
488
-
489
- $exploded_item = explode( ' ', $item );
490
- $count = count( $exploded_item );
491
-
492
- $filename = $exploded_item[ $count - 1 ];
493
- if ( in_array( $filename, $skips, true ) ) {
494
- continue;
495
- }
496
-
497
- // Get the timestamp.
498
- $month = $exploded_item[ $count - 4 ];
499
- $day = $exploded_item[ $count - 3 ];
500
- $time = $exploded_item[ $count - 2 ];
501
- $time = strtotime( $month . ' ' . $day . ' ' . $time );
502
-
503
- $backups[] = array(
504
- 'time' => $time,
505
- 'filename' => $filename,
506
- 'size' => $exploded_item[ $count - 5 ],
507
- );
508
- }
509
- }
510
-
511
- foreach ( $backups as $key => $backup ) {
512
- if ( ! $this->core->archive->is_site_archive( $backup['filename'] ) ) {
513
- unset( $backups[ $key ] );
514
- }
515
- }
516
- $backups = array_values( $backups );
517
-
518
- return $backups;
519
- }
520
-
521
- /**
522
- * Get the remote contents / listing.
523
- *
524
- * @since 1.5.4
525
- *
526
- * @param bool $raw Whether to get the raw contents (ftp_rawlist) or not
527
- * (ftp_nlist).
528
- * @param string $dir The directory to get listing of.
529
- * @return mixed
530
- */
531
- public function get_contents( $raw = false, $dir = '.' ) {
532
- $this->connect();
533
- $this->log_in();
534
- if ( ! $this->logged_in ) {
535
- $this->errors[] = __( 'Unable to log in to FTP server.', 'boldgrid-backup' );
536
- return array();
537
- }
538
-
539
- switch ( $this->type ) {
540
- case 'ftp':
541
- if ( $raw ) {
542
- return ftp_rawlist( $this->connection, $dir );
543
- } else {
544
- return ftp_nlist( $this->connection , $dir );
545
- }
546
- break;
547
- case 'sftp':
548
- if ( $raw ) {
549
- return $this->connection->rawlist( $dir );
550
- } else {
551
- return $this->connection->nlist( $dir );
552
- }
553
- break;
554
- }
555
- }
556
-
557
- /**
558
- * Get settings.
559
- *
560
- * @since 1.5.4
561
- */
562
- public function get_details() {
563
- $is_setup = $this->is_setup();
564
-
565
- $settings = $this->core->settings->get_settings();
566
-
567
- return array(
568
- 'title' => $this->title,
569
- 'key' => $this->key,
570
- 'configure' => 'admin.php?page=boldgrid-backup-ftp',
571
- 'is_setup' => $is_setup,
572
- 'enabled' => ! empty( $settings['remote'][ $this->key ]['enabled'] ) && $settings['remote'][ $this->key ]['enabled'] && $is_setup,
573
- );
574
- }
575
-
576
- /**
577
- * Init properties.
578
- *
579
- * @since 1.5.4
580
- */
581
- public function init() {
582
- if ( ! empty( $this->user ) || ! empty( $this->pass ) || ! empty( $this->host ) ) {
583
- return;
584
- }
585
-
586
- $settings = $this->core->settings->get_settings();
587
-
588
- $labels = array( 'user', 'pass', 'host', 'port', 'type', 'retention_count', 'nickname' );
589
-
590
- $configs = array(
591
- array(
592
- 'property' => 'user',
593
- 'default' => null,
594
- ),
595
- array(
596
- 'property' => 'pass',
597
- 'default' => null,
598
- ),
599
- array(
600
- 'property' => 'host',
601
- 'default' => null,
602
- ),
603
- array(
604
- 'property' => 'port',
605
- 'default' => $this->default_port,
606
- ),
607
- array(
608
- 'property' => 'type',
609
- 'default' => $this->default_type,
610
- ),
611
- array(
612
- 'property' => 'retention_count',
613
- 'default' => $this->retention_count,
614
- ),
615
- array(
616
- 'property' => 'nickname',
617
- 'default' => $this->title,
618
- ),
619
- );
620
-
621
- foreach ( $configs as $config ) {
622
- $property = $config['property'];
623
-
624
- if ( ! empty( $settings['remote'][ $this->key ][ $property ] ) ) {
625
- $this->$property = $settings['remote'][ $this->key ][ $property ];
626
- } else {
627
- $this->$property = $config['default'];
628
- }
629
- }
630
-
631
- if ( ! empty( $this->host ) ) {
632
- $this->title_attr = strtoupper( $this->type ) . ': ' . $this->host;
633
- }
634
- }
635
-
636
- /**
637
- * Determine whether or not FTP is setup.
638
- *
639
- * @since 1.5.4
640
- *
641
- * @return bool
642
- */
643
- public function is_setup() {
644
- $this->connect();
645
- $this->log_in();
646
-
647
- $logged_in = $this->logged_in;
648
-
649
- $this->disconnect();
650
-
651
- return $logged_in;
652
- }
653
-
654
- /**
655
- * Determine if a set of FTP credentials are valid.
656
- *
657
- * @since 1.5.4
658
- *
659
- * @param string $host
660
- * @param string $user
661
- * @param string $pass
662
- * @param int $port
663
- * @param string $type
664
- * @return bool
665
- */
666
- public function is_valid_credentials( $host, $user, $pass, $port, $type ) {
667
- $connection = false;
668
- $logged_in = false;
669
- $port = intval( $port );
670
-
671
- // Avoid a really long timeout.
672
- if ( 21 === $port && 'sftp' === $type ) {
673
- $this->errors[] = sprintf( __( 'Unable to connect to %1$s over port %2$u.', 'boldgrid-backup' ), $host, $port );
674
- return false;
675
- }
676
-
677
- switch ( $type ) {
678
- case 'ftp':
679
- $connection = @ftp_connect( $host, $port, $this->timeout );
680
- break;
681
- case 'sftp':
682
- $connection = @new phpseclib\Net\SFTP( $host, $port, $this->timeout );
683
- break;
684
- }
685
- if ( ! $connection ) {
686
- $this->errors[] = sprintf( __( 'Unable to connect to %1$s over port %2$u.', 'boldgrid-backup' ), $host, $port );
687
- return false;
688
- }
689
-
690
- /*
691
- * Try to login.
692
- *
693
- * When:
694
- * # Connecting over bad ports (like port FTP over port 22)
695
- * # Using invalid login credentials
696
- * Notices are thrown instead of catachable errors. This makes it difficult
697
- * to know if a connection failed because of of a bad port number or because
698
- * of bad credentials.
699
- *
700
- * If we have any trouble connecting, we'll use a custom error handler
701
- * and throw an Exception.
702
- */
703
- $error_caught = false;
704
- set_error_handler( array( 'Boldgrid_Backup_Admin_Utility', 'handle_error' ) );
705
- try {
706
- switch ( $type ) {
707
- case 'ftp':
708
- $logged_in = ftp_login( $connection, $user, $pass );
709
- ftp_close( $connection );
710
- break;
711
- case 'sftp':
712
- $logged_in = $connection->login( $user, $pass );
713
- break;
714
- }
715
- } catch ( Exception $e ) {
716
- $this->errors[] = $e->getMessage();
717
- $error_caught = true;
718
- }
719
- restore_error_handler();
720
-
721
- if ( ! $error_caught && ! $logged_in ) {
722
- $this->errors[] = __( 'Invalid username / password.', 'boldgrid-backup' );
723
- }
724
-
725
- return false !== $logged_in;
726
- }
727
-
728
- /**
729
- * Log into the FTP server.
730
- *
731
- * @since 1.5.4
732
- *
733
- * @return bool
734
- */
735
- public function log_in() {
736
- if ( $this->logged_in ) {
737
- return;
738
- }
739
-
740
- // If we tried to connect but don't have a connection, abort.
741
- $this->connect();
742
- if ( empty( $this->connection ) ) {
743
- return false;
744
- }
745
-
746
- switch ( $this->type ) {
747
- case 'ftp':
748
- $this->logged_in = @ftp_login( $this->connection, $this->user, $this->pass );
749
- break;
750
- case 'sftp':
751
- $this->logged_in = $this->connection->login( $this->user, $this->pass );
752
- break;
753
- }
754
-
755
- // If we tried to login and it failed, disconnect.
756
- if ( ! $this->logged_in ) {
757
- $this->disconnect();
758
- }
759
- }
760
-
761
- /**
762
- * Reset class properties.
763
- *
764
- * If the user wants to delete all FTP settings, after we clear the data from
765
- * the options, run this method to clear the properties.
766
- *
767
- * @since 1.5.4
768
- */
769
- public function reset() {
770
- $this->host = null;
771
- $this->user = null;
772
- $this->set_pass( null );
773
- $this->port = $this->default_port['ftp'];
774
- $this->retention_count = null;
775
- $this->type = $this->default_type;
776
- }
777
-
778
- /**
779
- * Set our ftp password.
780
- *
781
- * @since 1.5.4
782
- *
783
- * @param string $pass
784
- */
785
- public function set_pass( $pass ) {
786
- $this->pass = $pass;
787
- }
788
-
789
- /**
790
- * Determine if a backup archive is uploaded to the remote server.
791
- *
792
- * @since 1.5.4
793
- *
794
- * @param string $filepath
795
- */
796
- public function is_uploaded( $filepath ) {
797
- $contents = $this->get_contents( false, $this->remote_dir );
798
-
799
- return ! is_array( $contents ) ? false : in_array( basename( $filepath ), $contents, true );
800
- }
801
-
802
- /**
803
- * Upload a file.
804
- *
805
- * @since 1.5.4
806
- *
807
- * @param string $filepath
808
- * @return bool
809
- */
810
- public function upload( $filepath ) {
811
- $remote_file = $this->remote_dir . '/' . basename( $filepath );
812
-
813
- $this->connect();
814
- $this->log_in();
815
- if ( ! $this->logged_in ) {
816
- $this->errors[] = __( 'Unable to log in to ftp server.', 'boldgrid-backup' );
817
- return false;
818
- }
819
-
820
- $has_remote_dir = $this->create_backup_dir();
821
- if ( ! $has_remote_dir ) {
822
- return false;
823
- }
824
-
825
- switch ( $this->type ) {
826
- case 'ftp':
827
- $uploaded = ftp_put( $this->connection, $remote_file, $filepath, FTP_BINARY );
828
- break;
829
- case 'sftp':
830
- $uploaded = $this->connection->put( $remote_file, $filepath, 1 );
831
- break;
832
- }
833
-
834
- if ( ! $uploaded ) {
835
- $last_error = error_get_last();
836
-
837
- $this->disconnect();
838
- $this->errors[] = __( 'Unable to upload file.', 'boldgrid-backup' );
839
-
840
- /*
841
- * The last error message may be important on a failed uploaded,
842
- * such as ftp_put(): Quota exceeded. Make sure the user sees the
843
- * last error.
844
- */
845
- if ( ! empty( $last_error['message'] ) && ! empty( $last_error['file'] ) && $last_error['file'] === __FILE__ ) {
846
- $this->errors[] = $last_error['message'];
847
- }
848
-
849
- return false;
850
- }
851
-
852
- $this->enforce_retention();
853
-
854
- $this->disconnect();
855
-
856
- return true;
857
- }
858
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/remote/sftp.php DELETED
@@ -1,553 +0,0 @@
1
- <?php
2
- /**
3
- * SFTP class.
4
- *
5
- * @link http://www.boldgrid.com
6
- * @since 1.5.4
7
- *
8
- * @package Boldgrid_Backup
9
- * @subpackage Boldgrid_Backup/admin
10
- * @copyright BoldGrid.com
11
- * @version $Id$
12
- * @author BoldGrid.com <wpb@boldgrid.com>
13
- */
14
-
15
- /**
16
- * SFTP class.
17
- *
18
- * @since 1.5.4
19
- */
20
- class Boldgrid_Backup_Admin_Sftp {
21
-
22
- /**
23
- * An SFTP connection.
24
- *
25
- * @since 1.5.4
26
- * @access private
27
- * @var Resource
28
- */
29
- private $connection = null;
30
-
31
- /**
32
- * The core class object.
33
- *
34
- * @since 1.5.4
35
- * @access private
36
- * @var Boldgrid_Backup_Admin_Core
37
- */
38
- private $core;
39
-
40
- /**
41
- * Hooks class.
42
- *
43
- * @since 1.5.4
44
- * @access public
45
- * @var Boldgrid_Backup_Admin_Sftp_Hooks
46
- */
47
- public $hooks;
48
-
49
- /**
50
- * SFTP host.
51
- *
52
- * @since 1.5.4
53
- * @access private
54
- * @var string
55
- */
56
- private $host = null;
57
-
58
- /**
59
- * Whether or not we have logged in.
60
- *
61
- * @since 1.5.4
62
- * @access public
63
- * @var bool
64
- */
65
- public $logged_in = false;
66
-
67
- /**
68
- * Our key / label for sftp.
69
- *
70
- * @since 1.5.4
71
- * @access public
72
- * @var string
73
- */
74
- public $key = 'sftp';
75
-
76
- /**
77
- * SFTP password.
78
- *
79
- * @since 1.5.4
80
- * @access private
81
- * @var string
82
- */
83
- private $pass = null;
84
-
85
- /**
86
- * SFTP port.
87
- *
88
- * @since 1.5.4
89
- * @access public
90
- * @var int
91
- */
92
- public $port = 22;
93
-
94
- /**
95
- * SFTP remote directory.
96
- *
97
- * @since 1.5.4
98
- * @access public
99
- * @var string
100
- */
101
- public $remote_dir = 'boldgrid_backup';
102
-
103
- /**
104
- * Retention count.
105
- *
106
- * @since 1.5.4
107
- * @access public
108
- * @var int $retention_count
109
- */
110
- public $retention_count = 5;
111
-
112
- /**
113
- * Our title / label for sftp.
114
- *
115
- * @since 1.5.4
116
- * @access public
117
- * @var string
118
- */
119
- public $title = 'SFTP';
120
-
121
- /**
122
- * SFTP username.
123
- *
124
- * @since 1.5.4
125
- * @access private
126
- * @var string
127
- */
128
- private $user = null;
129
-
130
- /**
131
- * Constructor.
132
- *
133
- * @since 1.5.4
134
- *
135
- * @param Boldgrid_Backup_Admin_Core $core Core class object.
136
- */
137
- public function __construct( $core ) {
138
- include_once BOLDGRID_BACKUP_PATH . '/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php';
139
-
140
- $this->core = $core;
141
- // $this->hooks = new Boldgrid_Backup_Admin_Sftp_Hooks( $core );
142
- }
143
-
144
- /**
145
- * Connect to our sftp server.
146
- *
147
- * @since 1.5.4
148
- */
149
- public function connect() {
150
- if ( ! empty( $this->connection ) ) {
151
- return;
152
- }
153
-
154
- $this->init();
155
-
156
- if ( empty( $this->user ) || empty( $this->pass ) || empty( $this->host ) ) {
157
- return;
158
- }
159
-
160
- $this->connection = new phpseclib\Net\SFTP( $this->host, $this->port );
161
- }
162
-
163
- /**
164
- * Create backup directory on remote host.
165
- *
166
- * @since 1.5.4
167
- *
168
- * @return bool False when we were unable to create directory.
169
- */
170
- public function create_backup_dir() {
171
- $this->connect();
172
- $this->log_in();
173
- if ( ! $this->logged_in ) {
174
- return false;
175
- }
176
-
177
- $contents = $this->get_contents();
178
- if ( in_array( $this->remote_dir, $contents, true ) ) {
179
- return true;
180
- }
181
-
182
- return $this->connection->mkdir( $this->remote_dir );
183
- }
184
-
185
- /**
186
- * Disconnect from SFTP server.
187
- *
188
- * @since 1.5.4
189
- */
190
- public function disconnect() {
191
- if ( $this->connection ) {
192
- // sftp_close( $this->connection );
193
- // $this->connection = null;
194
- // $this->logged_in = false;
195
- }
196
- }
197
-
198
- /**
199
- * Enforce retention.
200
- *
201
- * @since 1.5.4
202
- */
203
- public function enforce_retention() {
204
- if ( empty( $this->retention_count ) ) {
205
- return;
206
- }
207
-
208
- $backups = array();
209
- $contents = $this->get_contents( true, $this->remote_dir );
210
-
211
- // The contents usually include . and .., so remove 2 from list.
212
- $count_to_delete = count( $contents ) - $this->retention_count - 2;
213
-
214
- if ( ! is_array( $contents ) || $count_to_delete <= 0 ) {
215
- return false;
216
- }
217
-
218
- $backups = $this->format_raw_contents( $contents );
219
-
220
- usort( $backups, function( $a, $b ) {
221
- return $a['time'] < $b['time'] ? -1 : 1;
222
- });
223
-
224
- for ( $x = 0; $x < $count_to_delete; $x++ ) {
225
- $filename = $backups[ $x ]['filename'];
226
- $this->connection->delete( $this->remote_dir . '/' . $filename );
227
-
228
- /**
229
- * Remote file deleted due to remote retention settings.
230
- *
231
- * @since 1.5.4
232
- */
233
- do_action(
234
- 'boldgrid_backup_remote_retention_deleted',
235
- $this->title,
236
- $filename
237
- );
238
- }
239
- }
240
-
241
- /**
242
- * Format raw contents.
243
- *
244
- * This method takes in raw contents and returns an array of backups, with
245
- * keys defining timestamp and filename.
246
- *
247
- * @since 1.5.4
248
- *
249
- * @param array $conents Raw contents received from this->get_contents.
250
- * @return array {
251
- * An array of backups.
252
- *
253
- * @type int $time Timestamp file was uploaded to sftp server.
254
- * @type string $filename
255
- * }
256
- */
257
- public function format_raw_contents( $contents ) {
258
- $skips = array( '.', '..' );
259
- $backups = array();
260
-
261
- if ( ! is_array( $contents ) ) {
262
- return array();
263
- }
264
-
265
- foreach ( $contents as $item ) {
266
- $exploded_item = explode( ' ', $item );
267
-
268
- $count = count( $exploded_item );
269
-
270
- $filename = $exploded_item[ $count - 1 ];
271
-
272
- if ( in_array( $filename, $skips, true ) ) {
273
- continue;
274
- }
275
-
276
- // Get the timestamp.
277
- $month = $exploded_item[ $count - 4 ];
278
- $day = $exploded_item[ $count - 3 ];
279
- $time = $exploded_item[ $count - 2 ];
280
- $time = strtotime( $month . ' ' . $day . ' ' . $time );
281
-
282
- $backups[] = array(
283
- 'time' => $time,
284
- 'filename' => $filename,
285
- );
286
- }
287
-
288
- return $backups;
289
- }
290
-
291
- /**
292
- * Get the remote contents / listing.
293
- *
294
- * @since 1.5.4
295
- *
296
- * @param bool $raw Whether to get the raw contents (sftp_rawlist) or not
297
- * (sftp_nlist).
298
- * @param string $dir The directory to get listing of.
299
- * @return mixed
300
- */
301
- public function get_contents( $raw = false, $dir = '.' ) {
302
- $this->connect();
303
- $this->log_in();
304
- if ( ! $this->logged_in ) {
305
- return array();
306
- }
307
-
308
- if ( $raw ) {
309
- return $this->connection->rawlist( $dir );
310
- } else {
311
- return $this->connection->nlist( $dir );
312
- }
313
- }
314
-
315
- /**
316
- * Get settings.
317
- *
318
- * @since 1.5.4
319
- */
320
- public function get_details() {
321
- $settings = $this->core->settings->get_settings();
322
-
323
- return array(
324
- 'title' => $this->title,
325
- 'key' => $this->key,
326
- 'configure' => 'admin.php?page=boldgrid-backup-sftp',
327
- 'is_setup' => $this->is_setup(),
328
- 'enabled' => ! empty( $settings['remote'][ $this->key ]['enabled'] ) && $settings['remote'][ $this->key ]['enabled'] && $this->is_setup(),
329
- );
330
- }
331
-
332
- /**
333
- * Init properties.
334
- *
335
- * @since 1.5.4
336
- */
337
- public function init() {
338
- if ( ! empty( $this->user ) || ! empty( $this->pass ) || ! empty( $this->host ) ) {
339
- return;
340
- }
341
-
342
- $settings = $this->core->settings->get_settings();
343
-
344
- $labels = array( 'user', 'pass', 'host', 'port', 'retention_count' );
345
-
346
- foreach ( $labels as $label ) {
347
- $this->$label = ! empty( $settings['remote'][ $this->key ][ $label ] ) ? $settings['remote'][ $this->key ][ $label ] : null;
348
- }
349
- }
350
-
351
- /**
352
- * Determine whether or not SFTP is setup.
353
- *
354
- * @since 1.5.4
355
- *
356
- * @return bool
357
- */
358
- public function is_setup() {
359
- $this->connect();
360
- $this->log_in();
361
-
362
- return $this->logged_in;
363
- }
364
-
365
- /**
366
- * Determine if a set of SFTP credentials are valid.
367
- *
368
- * @since 1.5.4
369
- *
370
- * @param string $host
371
- * @param string $user
372
- * @param string $pass
373
- * @param int $port
374
- * @return bool
375
- */
376
- public function is_valid_credentials( $host, $user, $pass, $port ) {
377
- $connection = new phpseclib\Net\SFTP( $host, $port );
378
- if ( ! $connection ) {
379
- return false;
380
- }
381
-
382
- $logged_in = @$connection->login( $user, $pass );
383
- if ( ! $logged_in ) {
384
- // sftp_close( $connection );
385
- $this->errors[] = __( 'Unable to connect and log in.', 'boldgrid-backup' );
386
- return false;
387
- }
388
-
389
- // sftp_close( $connection );
390
- return true;
391
- }
392
-
393
- /**
394
- * Log into the SFTP server.
395
- *
396
- * @since 1.5.4
397
- *
398
- * @return bool
399
- */
400
- public function log_in() {
401
- if ( $this->logged_in ) {
402
- return;
403
- }
404
-
405
- $this->connect();
406
- if ( empty( $this->connection ) ) {
407
- return false;
408
- }
409
-
410
- $this->logged_in = $this->connection->login( $this->user, $this->pass );
411
- if ( ! $this->logged_in ) {
412
- $this->disconnect();
413
- }
414
- }
415
-
416
- /**
417
- *
418
- */
419
- public function is_uploaded( $filepath ) {
420
- $contents = $this->get_contents( false, $this->remote_dir );
421
-
422
- return ! is_array( $contents ) ? false : in_array( basename( $filepath ), $contents, true );
423
- }
424
-
425
- /**
426
- * Generate the submenu page for our SFTP Settings page.
427
- *
428
- * @since 1.5.4
429
- */
430
- public function submenu_page() {
431
- wp_enqueue_style( 'boldgrid-backup-admin-hide-all' );
432
-
433
- $this->submenu_page_save();
434
-
435
- $settings = $this->core->settings->get_settings();
436
-
437
- $host = ! empty( $settings['remote'][ $this->key ]['host'] ) ? $settings['remote'][ $this->key ]['host'] : null;
438
- $user = ! empty( $settings['remote'][ $this->key ]['user'] ) ? $settings['remote'][ $this->key ]['user'] : null;
439
- $pass = ! empty( $settings['remote'][ $this->key ]['pass'] ) ? $settings['remote'][ $this->key ]['pass'] : null;
440
- $port = ! empty( $settings['remote'][ $this->key ]['port'] ) ? $settings['remote'][ $this->key ]['port'] : $this->port;
441
- $retention_count = ! empty( $settings['remote'][ $this->key ]['retention_count'] ) ? $settings['remote'][ $this->key ]['retention_count'] : $this->retention_count;
442
-
443
- include BOLDGRID_BACKUP_PATH . '/admin/partials/remote/sftp.php';
444
- }
445
-
446
- /**
447
- * Process the user's request to update their SFTP settings.
448
- *
449
- * @since 1.5.4
450
- */
451
- public function submenu_page_save() {
452
- if ( ! current_user_can( 'update_plugins' ) ) {
453
- return false;
454
- }
455
-
456
- if ( empty( $_POST ) ) {
457
- return false;
458
- }
459
-
460
- $settings = $this->core->settings->get_settings();
461
- if ( ! isset( $settings['remote'][ $this->key ] ) || ! is_array( $settings['remote'][ $this->key ] ) ) {
462
- $settings['remote'][ $this->key ] = array();
463
- }
464
-
465
- /*
466
- * If the user has requested to delete all their settings, do that now
467
- * and return.
468
- */
469
- if ( __( 'Delete settings', 'boldgrid-backup' ) === $_POST['submit'] ) {
470
- $settings['remote'][ $this->key ] = array();
471
- update_site_option( 'boldgrid_backup_settings', $settings );
472
-
473
- $this->host = null;
474
- $this->user = null;
475
- $this->pass = null;
476
- $this->retention_count = null;
477
- $this->disconnect();
478
-
479
- do_action( 'boldgrid_backup_notice', __( 'Settings saved.', 'boldgrid-backup' ), 'notice updated is-dismissible' );
480
- return;
481
- }
482
-
483
- $errors = array();
484
-
485
- // Get and validate our credentials.
486
- $host = ! empty( $_POST['host'] ) ? sanitize_file_name( $_POST['host'] ) : null;
487
- $user = ! empty( $_POST['user'] ) ? sanitize_text_field( $_POST['user'] ) : null;
488
- $pass = ! empty( $_POST['pass'] ) ? $_POST['pass'] : null;
489
- $port = ! empty( $_POST['port'] ) ? (int) $_POST['port'] : $this->port;
490
-
491
- $valid_credentials = $this->is_valid_credentials( $host, $user, $pass, $port );
492
-
493
- if ( $valid_credentials ) {
494
- $settings['remote'][ $this->key ]['host'] = $host;
495
- $settings['remote'][ $this->key ]['user'] = $user;
496
- $settings['remote'][ $this->key ]['pass'] = $pass;
497
- $settings['remote'][ $this->key ]['port'] = $port;
498
- } elseif ( empty( $this->errors ) ) {
499
- $this->errors[] = __( 'Unknown error.', 'boldgrid-backup' );
500
- }
501
-
502
- $retention_count = ! empty( $_POST['retention_count'] ) &&
503
- is_numeric( $_POST['retention_count'] ) ?
504
- (int) $_POST['retention_count'] : $this->retention_count;
505
-
506
- $settings['remote'][ $this->key ]['retention_count'] = $retention_count;
507
-
508
- if ( ! empty( $this->errors ) ) {
509
- do_action( 'boldgrid_backup_notice', implode( '<br /><br />', $this->errors ) );
510
- } else {
511
- update_site_option( 'boldgrid_backup_settings', $settings );
512
- do_action( 'boldgrid_backup_notice', __( 'Settings saved.', 'boldgrid-backup' ), 'notice updated is-dismissible' );
513
- }
514
- }
515
-
516
- /**
517
- * Upload a file.
518
- *
519
- * @since 1.5.4
520
- *
521
- * @param string $filepath
522
- * @return bool
523
- */
524
- public function upload( $filepath ) {
525
- $remote_file = $this->remote_dir . '/' . basename( $filepath );
526
-
527
- $this->connect();
528
- $this->log_in();
529
- if ( ! $this->logged_in ) {
530
- $this->errors[] = __( 'Unable to log in to sftp server.', 'boldgrid-backup' );
531
- return false;
532
- }
533
-
534
- $has_remote_dir = $this->create_backup_dir();
535
- if ( ! $has_remote_dir ) {
536
- $this->errors[] = sprint_f( __( 'Unable to create the following directory on SFTP server: %1$s', 'boldgrid-backup' ), $this->remote_dir );
537
- return false;
538
- }
539
-
540
- $uploaded = $this->connection->put( $remote_file, $filepath, NET_SFTP_LOCAL_FILE );
541
- if ( ! $uploaded ) {
542
- $this->disconnect();
543
- $this->errors[] = __( 'Unable to upload file.', 'boldgrid-backup' );
544
- return false;
545
- }
546
-
547
- $this->enforce_retention();
548
-
549
- $this->disconnect();
550
-
551
- return true;
552
- }
553
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/storage/class-boldgrid-backup-admin-storage-local.php ADDED
@@ -0,0 +1,310 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File: class-boldgrid-backup-admin-storage-local.php
4
+ *
5
+ * Local storage.
6
+ *
7
+ * @link https://www.boldgrid.com
8
+ * @since 1.5.2
9
+ *
10
+ * @package Boldgrid_Backup
11
+ * @subpackage Boldgrid_Backup/admin/storage
12
+ * @copyright BoldGrid
13
+ * @version $Id$
14
+ * @author BoldGrid <support@boldgrid.com>
15
+ */
16
+
17
+ /**
18
+ * Class: Boldgrid_Backup_Admin_Storage_Local
19
+ *
20
+ * @since 1.5.2
21
+ */
22
+ class Boldgrid_Backup_Admin_Storage_Local {
23
+ /**
24
+ * The core class object.
25
+ *
26
+ * @since 1.5.2
27
+ * @access private
28
+ * @var Boldgrid_Backup_Admin_Core
29
+ */
30
+ private $core;
31
+
32
+ /**
33
+ * Constructor.
34
+ *
35
+ * @since 1.5.2
36
+ *
37
+ * @param Boldgrid_Backup_Admin_Core $core Boldgrid_Backup_Admin_Core object.
38
+ */
39
+ public function __construct( $core ) {
40
+ $this->core = $core;
41
+ }
42
+
43
+ /**
44
+ * Delete a local backup file.
45
+ *
46
+ * This method is registered to the "boldgrid_backup_delete_local" action.
47
+ * If the user does not wish to keep local copies of backups, after all
48
+ * remote backup providers have been run, this method will run and delete
49
+ * it locally.
50
+ *
51
+ * @since 1.5.2
52
+ *
53
+ * @param string $filepath Full path to backup file.
54
+ */
55
+ public function delete_local( $filepath ) {
56
+ return $this->core->wp_filesystem->delete( $filepath );
57
+ }
58
+
59
+ /**
60
+ * Action to take after a backup file has been created.
61
+ *
62
+ * If the user has not chosen to keep local copies, this method adds the
63
+ * "delete local copy" to the jobs queue.
64
+ *
65
+ * @since 1.5.2
66
+ *
67
+ * @see self::delete_local()
68
+ *
69
+ * @param array $info Archive information.
70
+ */
71
+ public function post_archive_files( $info ) {
72
+ /*
73
+ * Do not "delete local copy" in the following scenarios:
74
+ *
75
+ * We only want to add this to the jobs queue if we're in the middle of
76
+ * an automatic backup. If the user simply clicked on "Backup site now",
77
+ * we don't want to automatically delete the backup, there's a button
78
+ * for that.
79
+ *
80
+ * If we're doing a backup immediately before WordPress does an auto
81
+ * update, we want to make sure this backup is not deleted.
82
+ */
83
+ if ( ! $this->core->doing_cron || $this->core->pre_auto_update ) {
84
+ return;
85
+ }
86
+
87
+ if ( $this->core->remote->is_enabled( 'local' ) ) {
88
+ return;
89
+ }
90
+
91
+ $args = array(
92
+ 'filepath' => $info['filepath'],
93
+ 'action' => 'boldgrid_backup_delete_local',
94
+ 'action_data' => $info['filepath'],
95
+ 'action_title' => __( 'Delete backup from Web Server', 'boldgrid-backup' ),
96
+ );
97
+
98
+ $this->core->jobs->add( $args );
99
+ }
100
+
101
+ /**
102
+ * Add submenu pages.
103
+ *
104
+ * @since 1.7.0
105
+ */
106
+ public function add_submenus() {
107
+ add_submenu_page(
108
+ null,
109
+ __( 'Web Server', 'boldgrid-backup' ),
110
+ __( 'Web Server', 'boldgrid-backup' ),
111
+ 'administrator',
112
+ 'boldgrid-backup-web-server',
113
+ array(
114
+ $this,
115
+ 'webserver_subpage',
116
+ )
117
+ );
118
+ }
119
+
120
+ /**
121
+ * Generate the submenu page for the Web Server settings page.
122
+ *
123
+ * @since 1.7.0
124
+ */
125
+ public function webserver_subpage() {
126
+ wp_enqueue_style( 'boldgrid-backup-admin-hide-all' );
127
+ wp_enqueue_style( 'bglib-ui-css' );
128
+ wp_enqueue_script( 'bglib-ui-js' );
129
+ wp_enqueue_script( 'bglib-sticky' );
130
+
131
+ wp_enqueue_script(
132
+ 'boldgrid-backup-admin-settings',
133
+ plugin_dir_url( dirname( __FILE__ ) ) . 'js/boldgrid-backup-admin-settings.js',
134
+ array( 'jquery' ),
135
+ BOLDGRID_BACKUP_VERSION,
136
+ false
137
+ );
138
+
139
+ $this->webserver_subpage_save();
140
+
141
+ $settings = $this->core->settings->get_settings();
142
+
143
+ include BOLDGRID_BACKUP_PATH . '/admin/partials/remote/local.php';
144
+ }
145
+
146
+ /**
147
+ * Process the user's request to update their Amazon S3 settings.
148
+ *
149
+ * @since 1.7.0
150
+ *
151
+ * @see Boldgrid_Backup_Admin_Test::run_functionality_tests()
152
+ * @see Boldgrid_Backup_Admin_Settings::get_settings()
153
+ * @see Boldgrid_Backup_Admin_Backup_Dir::create()
154
+ * @see Boldgrid_Backup_Admin_Backup_Dir::is_valid()
155
+ *
156
+ * @uses $_POST[] Settings.
157
+ *
158
+ * @return bool
159
+ */
160
+ public function webserver_subpage_save() {
161
+ if ( empty( $_POST ) || ! current_user_can( 'update_plugins' ) ) {
162
+ return false;
163
+ }
164
+
165
+ if ( ! check_ajax_referer( 'bgb-settings-webserver', 'webserver_auth' ) ) {
166
+ do_action(
167
+ 'boldgrid_backup_notice',
168
+ __( 'Unauthorized request.', 'boldgrid-backup' ),
169
+ 'notice error is-dismissible'
170
+ );
171
+
172
+ return false;
173
+ }
174
+
175
+ if ( ! $this->core->test->run_functionality_tests() ) {
176
+ $this->core->settings->errors[] = sprintf(
177
+ // translators: 1: HTML anchor link open tag, 2: HTML anchor closing tag.
178
+ __(
179
+ 'Functionality test has failed. You can go to %1$sFunctionality Test%2$s to view a report.',
180
+ 'boldgrid-backup'
181
+ ),
182
+ '<a href="' . admin_url( 'admin.php?page=boldgrid-backup-test' ) . '">',
183
+ '</a>'
184
+ );
185
+ } else {
186
+ $settings = $this->core->settings->get_settings();
187
+
188
+ $original_backup_directory = $settings['backup_directory'];
189
+
190
+ // For consistency, untrailingslashit the input backup dir, or use the default.
191
+ $settings['backup_directory'] = ! empty( $_POST['backup_directory'] ) ?
192
+ untrailingslashit(
193
+ str_replace( '\\\\', '\\', trim( $_POST['backup_directory'] ) )
194
+ ) : $this->core->backup_dir->get();
195
+
196
+ $this->core->backup_dir->create( $settings['backup_directory'] );
197
+
198
+ if ( ! $this->core->backup_dir->is_valid( $settings['backup_directory'] ) ) {
199
+ $this->core->settings->errors[] = __( 'Invalid backup directory', 'boldgrid-backup' );
200
+ } elseif ( $original_backup_directory !== $settings['backup_directory'] &&
201
+ isset( $_POST['move-backups'] ) && 'on' === $_POST['move-backups'] ) {
202
+ // Move backups to the new directory, if changed and opted.
203
+ $backups_moved = $this->core->settings->move_backups(
204
+ $original_backup_directory,
205
+ $settings['backup_directory']
206
+ );
207
+
208
+ if ( ! $backups_moved ) {
209
+ $this->core->settings->errors[] = sprintf(
210
+ // translators: 1: Original backup directory, 2: New backup directory.
211
+ __(
212
+ 'Unable to move backups from %1$s to %2$s',
213
+ 'boldgrid-backup'
214
+ ),
215
+ $original_backup_directory,
216
+ $settings['backup_directory']
217
+ );
218
+ }
219
+ }
220
+
221
+ $settings['retention_count'] = (
222
+ ! empty( $_POST['retention_count'] ) ?
223
+ (int) $_POST['retention_count'] : $this->core->config->get_default_retention()
224
+ );
225
+ }
226
+
227
+ $success = empty( $this->core->settings->errors );
228
+
229
+ if ( ! $success ) {
230
+ do_action( 'boldgrid_backup_notice', implode( '<br /><br />', $this->core->settings->errors ) );
231
+ } else {
232
+ update_site_option( 'boldgrid_backup_settings', $settings );
233
+
234
+ do_action(
235
+ 'boldgrid_backup_notice',
236
+ __( 'Settings saved.', 'boldgrid-backup' ),
237
+ 'notice updated is-dismissible'
238
+ );
239
+ }
240
+
241
+ return $success;
242
+ }
243
+
244
+ /**
245
+ * Are the web server settings configured?
246
+ *
247
+ * @since 1.7.0
248
+ *
249
+ * @see Boldgrid_Backup_Admin_Settings::get_settings
250
+ * @see Boldgrid_Backup_Admin_Backup_Dir::is_valid
251
+ *
252
+ * @return bool
253
+ */
254
+ public function is_webserver_setup() {
255
+ $settings = $this->core->settings->get_settings();
256
+ $has_valid_dir = $this->core->backup_dir->is_valid( $settings['backup_directory'] );
257
+ $has_valid_retention = is_int( $settings['retention_count'] ) &&
258
+ 0 < $settings['retention_count'];
259
+
260
+ return $has_valid_dir && $has_valid_retention;
261
+ }
262
+
263
+ /**
264
+ * Determine if local web server storage is setup/configured.
265
+ *
266
+ * @since 1.7.0
267
+ *
268
+ * @see self::is_webserver_setup()
269
+ * @see self::get_webserver_details()
270
+ */
271
+ public function is_setup_ajax() {
272
+ if ( ! current_user_can( 'update_plugins' ) ) {
273
+ wp_send_json_error( __( 'Permission denied.', 'boldgrid-backup' ) );
274
+ }
275
+
276
+ if ( ! check_ajax_referer( 'boldgrid_backup_settings', 'security', false ) ) {
277
+ wp_send_json_error( __( 'Invalid nonce.', 'boldgrid-backup' ) );
278
+ }
279
+
280
+ $location = $this->get_webserver_details();
281
+
282
+ $tr = include BOLDGRID_BACKUP_PATH . '/admin/partials/settings/storage-location.php';
283
+
284
+ if ( $this->is_webserver_setup() ) {
285
+ wp_send_json_success( $tr );
286
+ } else {
287
+ wp_send_json_error( $tr );
288
+ }
289
+ }
290
+
291
+ /**
292
+ * Get the web server storage details.
293
+ *
294
+ * @since 1.7.0
295
+ *
296
+ * @return array
297
+ */
298
+ public function get_webserver_details() {
299
+ $settings = $this->core->settings->get_settings();
300
+
301
+ return array(
302
+ 'title' => __( 'Web Server', 'boldgrid-backup' ),
303
+ 'key' => 'local',
304
+ 'configure' => 'admin.php?page=boldgrid-backup-web-server',
305
+ 'is_setup' => $this->is_webserver_setup(),
306
+ 'enabled' => ! empty( $settings['remote']['local']['enabled'] ) &&
307
+ true === $settings['remote']['local']['enabled'],
308
+ );
309
+ }
310
+ }
admin/storage/local.php DELETED
@@ -1,100 +0,0 @@
1
- <?php
2
- /**
3
- * Local storage.
4
- *
5
- * @link http://www.boldgrid.com
6
- * @since 1.5.2
7
- *
8
- * @package Boldgrid_Backup
9
- * @subpackage Boldgrid_Backup/admin
10
- * @copyright BoldGrid.com
11
- * @version $Id$
12
- * @author BoldGrid.com <wpb@boldgrid.com>
13
- */
14
-
15
- /**
16
- * Local storage.
17
- *
18
- * @since 1.5.2
19
- */
20
- class Boldgrid_Backup_Admin_Storage_Local {
21
-
22
- /**
23
- * The core class object.
24
- *
25
- * @since 1.5.2
26
- * @access private
27
- * @var Boldgrid_Backup_Admin_Core
28
- */
29
- private $core;
30
-
31
- /**
32
- * Constructor.
33
- *
34
- * @since 1.5.2
35
- *
36
- * @param Boldgrid_Backup_Admin_Core $core
37
- */
38
- public function __construct( $core ) {
39
- $this->core = $core;
40
- }
41
-
42
- /**
43
- * Delete a local backup file.
44
- *
45
- * This method is registered to the "boldgrid_backup_delete_local" action.
46
- * If the user does not wish to keep local copies of backups, after all
47
- * remote backup providers have been run, this method will run and delete
48
- * it locally.
49
- *
50
- * @since 1.5.2
51
- *
52
- * @param string $filepath Full path to backup file.
53
- */
54
- public function delete_local( $filepath ) {
55
- return $this->core->wp_filesystem->delete( $filepath );
56
- }
57
-
58
- /**
59
- * Action to take after a backup file has been created.
60
- *
61
- * If the user has not chosen to keep local copies, this method adds the
62
- * "delete local copy" to the jobs queue.
63
- *
64
- * @since 1.5.2
65
- *
66
- * @see self::delete_local()
67
- *
68
- * @param array $info
69
- */
70
- public function post_archive_files( $info ) {
71
-
72
- /*
73
- * Do not "delete local copy" in the following scenarios:
74
- *
75
- * We only want to add this to the jobs queue if we're in the middle of
76
- * an automatic backup. If the user simply clicked on "Backup site now",
77
- * we don't want to automatically delete the backup, there's a button
78
- * for that.
79
- *
80
- * If we're doing a backup immediately before WordPress does an auto
81
- * update, we want to make sure this backup is not deleted.
82
- */
83
- if ( ! $this->core->doing_cron || $this->core->pre_auto_update ) {
84
- return;
85
- }
86
-
87
- if ( $this->core->remote->is_enabled( 'local' ) ) {
88
- return;
89
- }
90
-
91
- $args = array(
92
- 'filepath' => $info['filepath'],
93
- 'action' => 'boldgrid_backup_delete_local',
94
- 'action_data' => $info['filepath'],
95
- 'action_title' => __( 'Delete backup from Web Server', 'boldgrid-backup' ),
96
- );
97
-
98
- $this->core->jobs->add( $args );
99
- }
100
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
boldgrid-backup-cron.php CHANGED
@@ -1,19 +1,29 @@
1
  <?php
2
  /**
3
- * BoldGrid Backup cron control script
4
  *
5
- * @link http://www.boldgrid.com
 
 
6
  * @since 1.0
7
  *
8
- * @package Boldgrid_Backup
9
- * @copyright BoldGrid.com
10
- * @version $Id$
11
- * @author BoldGrid.com <wpb@boldgrid.com>
12
  */
13
 
 
 
 
 
 
 
14
  // Abort if not being ran from the command line.
15
- if ( ! isset( $_SERVER['argv'], $_SERVER['argc'] ) || ! $_SERVER['argc'] ) {
16
- die( 'Error: No parameters were passed. A "siteurl", "mode", and "id" are required.' . PHP_EOL );
 
 
17
  }
18
 
19
  // Initialize $input and $error.
@@ -41,6 +51,7 @@ foreach ( $required_arguments as $required_argument ) {
41
  }
42
 
43
  if ( $error ) {
 
44
  die( $error );
45
  }
46
 
@@ -51,22 +62,40 @@ $valid_modes = array(
51
  );
52
 
53
  if ( ! in_array( $input['mode'], $valid_modes, true ) ) {
54
- die( 'Error: Invalid mode "' . $input['mode'] . '".' . PHP_EOL );
 
 
55
  }
56
 
57
  // Make an ajax call to run jobs, and report status.
58
- $url = $input['siteurl'] . '/wp-admin/admin-ajax.php?action=boldgrid_backup_run_' . $input['mode'] .
59
- '&id=' . $input['id'] . '&secret=' . $input['secret'] . '&doing_wp_cron=' . time();
 
 
 
 
 
 
 
 
 
 
 
 
60
 
61
- // Sanitize the url.
62
- $url = filter_var( $url, FILTER_SANITIZE_URL );
63
 
64
- $result = file_get_contents( $url );
 
 
 
65
 
66
  if ( false !== $result ) {
67
  $message = $result;
68
  } else {
69
- $message = 'Error: Could not reach URL address "' . $url . '".';
 
 
70
  }
71
 
72
  die( $message );
1
  <?php
2
  /**
3
+ * File: boldgrid-backup-cron.php
4
  *
5
+ * Total Upkeep cron control script.
6
+ *
7
+ * @link https://www.boldgrid.com
8
  * @since 1.0
9
  *
10
+ * @package Boldgrid_Backup
11
+ * @copyright BoldGrid
12
+ * @version $Id$
13
+ * @author BoldGrid <support@boldgrid.com>
14
  */
15
 
16
+ // phpcs:disable WordPress.VIP,WordPress.XSS.EscapeOutput.OutputNotEscaped
17
+
18
+ require dirname( __FILE__ ) . '/admin/class-boldgrid-backup-admin-cron-log.php';
19
+ require dirname( __FILE__ ) . '/cron/class-boldgrid-backup-cron-helper.php';
20
+ $cron_helper = new Boldgrid_Backup_Cron_Helper();
21
+
22
  // Abort if not being ran from the command line.
23
+ if ( ! $cron_helper->is_cli() ) {
24
+ $error = 'Error: No parameters were passed. A "siteurl", "mode", and "id" are required.';
25
+ Boldgrid_Backup_Admin_Cron_Log::add_log( $error );
26
+ die( $error . PHP_EOL );
27
  }
28
 
29
  // Initialize $input and $error.
51
  }
52
 
53
  if ( $error ) {
54
+ Boldgrid_Backup_Admin_Cron_Log::add_log( $error );
55
  die( $error );
56
  }
57
 
62
  );
63
 
64
  if ( ! in_array( $input['mode'], $valid_modes, true ) ) {
65
+ $error = 'Error: Invalid mode "' . $input['mode'] . '".';
66
+ Boldgrid_Backup_Admin_Cron_Log::add_log( $error );
67
+ die( $error );
68
  }
69
 
70
  // Make an ajax call to run jobs, and report status.
71
+ $query_string = array(
72
+ 'action' => 'boldgrid_backup_run_' . $input['mode'],
73
+ 'id' => $input['id'],
74
+ 'secret' => $input['secret'],
75
+ 'doing_wp_cron' => time(),
76
+ );
77
+
78
+ if ( ! empty( $input['archive_filename'] ) ) {
79
+ $query_string['archive_filename'] = $input['archive_filename'];
80
+ }
81
+
82
+ if ( isset( $input['archive_key'] ) && is_numeric( $input['archive_key'] ) ) {
83
+ $query_string['archive_key'] = (int) $input['archive_key'];
84
+ }
85
 
86
+ $url = $input['siteurl'] . '/wp-admin/admin-ajax.php?' . http_build_query( $query_string );
 
87
 
88
+ // The helper class method will sanitize the url.
89
+ require dirname( __FILE__ ) . '/cron/class-boldgrid-backup-url-helper.php';
90
+ $url_helper = new Boldgrid_Backup_Url_Helper();
91
+ $result = $url_helper->call_url( $url );
92
 
93
  if ( false !== $result ) {
94
  $message = $result;
95
  } else {
96
+ $error = 'Error: Could not reach admin-ajax.php address';
97
+ Boldgrid_Backup_Admin_Cron_Log::add_log( $error );
98
+ $message = $error . ': "' . $url . '".';
99
  }
100
 
101
  die( $message );
boldgrid-backup.php CHANGED
@@ -1,21 +1,22 @@
1
  <?php
2
  /**
3
- * The plugin bootstrap file
4
  *
 
5
  * This file is read by WordPress to generate the plugin information in the plugin
6
  * admin area. This file also includes all of the dependencies used by the plugin,
7
  * registers the activation and deactivation functions, and defines a function
8
  * that starts the plugin.
9
  *
10
- * @link http://www.boldgrid.com
11
- * @since 1.0.1
12
  * @package Boldgrid_Backup
13
  *
14
  * @wordpress-plugin
15
- * Plugin Name: BoldGrid Backup
16
  * Plugin URI: https://www.boldgrid.com/boldgrid-backup/
17
- * Description: BoldGrid Backup provides WordPress backup and restoration with update protection.
18
- * Version: 1.6.1-rc.1
19
  * Author: BoldGrid
20
  * Author URI: https://www.boldgrid.com/
21
  * License: GPL-2.0+
@@ -39,6 +40,16 @@ if ( ! defined( 'BOLDGRID_BACKUP_PATH' ) ) {
39
  define( 'BOLDGRID_BACKUP_PATH', dirname( __FILE__ ) );
40
  }
41
 
 
 
 
 
 
 
 
 
 
 
42
  /**
43
  * The code that runs during plugin activation.
44
  * This action is documented in includes/class-boldgrid-backup-activator.php
@@ -72,7 +83,7 @@ function run_boldgrid_backup() {
72
  }
73
 
74
  /**
75
- * Load BoldGrid Backup.
76
  *
77
  * Before loading, ensure system meets minimium requirements:
78
  * # vendor folder exists. This is not a system requirement, but we want to make
@@ -80,46 +91,41 @@ function run_boldgrid_backup() {
80
  *
81
  * @since 1.6.0
82
  *
 
 
83
  * @return bool
84
  */
85
  function load_boldgrid_backup() {
 
 
 
86
 
87
- // Ensure we have our vendor/autoload.php file.
88
- $exists_composer = file_exists( BOLDGRID_BACKUP_PATH . '/composer.json' );
89
- $exists_autoload = file_exists( BOLDGRID_BACKUP_PATH . '/vendor/autoload.php' );
90
- if ( $exists_composer && ! $exists_autoload ) {
91
- add_action( 'admin_init', function() {
92
- deactivate_plugins( 'boldgrid-backup/boldgrid-backup.php', true );
93
-
94
- add_action( 'admin_notices', function() {
95
- ?>
96
- <div class="notice notice-error is-dismissible">
97
- <p><?php _e( '<strong>BoldGrid Backup</strong> has been deactivated because the vendor folder is missing. Please run <strong>composer install</strong>, or contact your host for further assistance.', 'boldgrid-backup' ); ?></p>
98
- </div>
99
- <?php
100
- });
101
- });
102
-
103
  return false;
104
  }
105
 
106
- register_activation_hook( __FILE__, 'activate_boldgrid_backup' );
107
- register_deactivation_hook( __FILE__, 'deactivate_boldgrid_backup' );
108
-
109
  // Include the autoloader to set plugin options and create instance.
110
  $loader = require plugin_dir_path( __FILE__ ) . 'vendor/autoload.php';
111
 
112
  // Load Library.
113
  $load = new Boldgrid\Library\Util\Load(
114
  array(
115
- 'type' => 'plugin',
116
- 'file' => plugin_basename( __FILE__ ),
117
- 'loader' => $loader,
118
- 'keyValidate' => true,
119
- 'licenseActivate', false,
120
  )
121
  );
122
 
 
 
 
 
 
 
 
 
123
  return true;
124
  }
125
 
@@ -135,12 +141,9 @@ function load_boldgrid_backup() {
135
  * Run the plugin only if on a wp-admin page or when DOING_CRON.
136
  */
137
  if ( is_admin() || ( defined( 'DOING_CRON' ) && DOING_CRON ) || defined( 'WP_CLI' ) && WP_CLI ) {
138
-
139
  // If we could not load boldgrid_backup (missing system requirements), abort.
140
- if ( ! load_boldgrid_backup() ) {
141
- return;
 
142
  }
143
-
144
- require_once BOLDGRID_BACKUP_PATH . '/includes/class-boldgrid-backup.php';
145
- run_boldgrid_backup();
146
  }
1
  <?php
2
  /**
3
+ * File: boldgrid-backup.php
4
  *
5
+ * The plugin bootstrap file.
6
  * This file is read by WordPress to generate the plugin information in the plugin
7
  * admin area. This file also includes all of the dependencies used by the plugin,
8
  * registers the activation and deactivation functions, and defines a function
9
  * that starts the plugin.
10
  *
11
+ * @link https://www.boldgrid.com
12
+ * @since 1.0.0
13
  * @package Boldgrid_Backup
14
  *
15
  * @wordpress-plugin
16
+ * Plugin Name: Total Upkeep
17
  * Plugin URI: https://www.boldgrid.com/boldgrid-backup/
18
+ * Description: Automated backups, remote backup to Amazon S3 and Google Drive, stop website crashes before they happen and more. Total Upkeep is the backup solution you need.
19
+ * Version: 1.13.7
20
  * Author: BoldGrid
21
  * Author URI: https://www.boldgrid.com/
22
  * License: GPL-2.0+
40
  define( 'BOLDGRID_BACKUP_PATH', dirname( __FILE__ ) );
41
  }
42
 
43
+ // Define boldgrid-backup key.
44
+ if ( ! defined( 'BOLDGRID_BACKUP_KEY' ) ) {
45
+ define( 'BOLDGRID_BACKUP_KEY', 'boldgrid-backup' );
46
+ }
47
+
48
+ // Define The plugin title.
49
+ if ( ! defined( 'BOLDGRID_BACKUP_TITLE' ) ) {
50
+ define( 'BOLDGRID_BACKUP_TITLE', 'Total Upkeep' );
51
+ }
52
+
53
  /**
54
  * The code that runs during plugin activation.
55
  * This action is documented in includes/class-boldgrid-backup-activator.php
83
  }
84
 
85
  /**
86
+ * Load Total Upkeep.
87
  *
88
  * Before loading, ensure system meets minimium requirements:
89
  * # vendor folder exists. This is not a system requirement, but we want to make
91
  *
92
  * @since 1.6.0
93
  *
94
+ * @see Boldgrid_Backup_Admin_Support::run_tests()
95
+ *
96
  * @return bool
97
  */
98
  function load_boldgrid_backup() {
99
+ require_once BOLDGRID_BACKUP_PATH . '/admin/class-boldgrid-backup-admin-support.php';
100
+ $support = new Boldgrid_Backup_Admin_Support();
101
+ $tests_passed = $support->run_tests();
102
 
103
+ if ( ! $tests_passed ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
  return false;
105
  }
106
 
 
 
 
107
  // Include the autoloader to set plugin options and create instance.
108
  $loader = require plugin_dir_path( __FILE__ ) . 'vendor/autoload.php';
109
 
110
  // Load Library.
111
  $load = new Boldgrid\Library\Util\Load(
112
  array(
113
+ 'type' => 'plugin',
114
+ 'file' => plugin_basename( __FILE__ ),
115
+ 'loader' => $loader,
116
+ 'keyValidate' => true,
117
+ 'licenseActivate' => false,
118
  )
119
  );
120
 
121
+ // Make sure we have necessary library files.
122
+ if ( ! $support->run_library_tests() ) {
123
+ return false;
124
+ }
125
+
126
+ register_activation_hook( __FILE__, 'activate_boldgrid_backup' );
127
+ register_deactivation_hook( __FILE__, 'deactivate_boldgrid_backup' );
128
+
129
  return true;
130
  }
131
 
141
  * Run the plugin only if on a wp-admin page or when DOING_CRON.
142
  */
143
  if ( is_admin() || ( defined( 'DOING_CRON' ) && DOING_CRON ) || defined( 'WP_CLI' ) && WP_CLI ) {
 
144
  // If we could not load boldgrid_backup (missing system requirements), abort.
145
+ if ( load_boldgrid_backup() ) {
146
+ require_once BOLDGRID_BACKUP_PATH . '/includes/class-boldgrid-backup.php';
147
+ run_boldgrid_backup();
148
  }
 
 
 
149
  }
cli/bgbkup-cli.php ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File: bgbkup-cli.php
4
+ *
5
+ * Performs site integrity checks and manual and emergency restoration.
6
+ *
7
+ * @link https://www.boldgrid.com
8
+ * @link https://github.com/BoldGrid/boldgrid-backup/wiki/Restorations-outside-of-WordPress
9
+ * @since 1.9.0
10
+ *
11
+ * @package Boldgrid_Backup
12
+ * @subpackage Boldgrid_Backup\Cli
13
+ * @copyright BoldGrid
14
+ * @author BoldGrid <support@boldgrid.com>
15
+ *
16
+ * @see \Boldgrid\Backup\Cli\Info::has_errors()
17
+ * @see \Boldgrid\Backup\Cli\Info::print_errors()
18
+ * @see \Boldgrid\Backup\Cli\Site_Check::should_restore()
19
+ * @see \Boldgrid\Backup\Cli\Site_Restore::run()
20
+ * @see \Boldgrid\Backup\Cli\Log::write()
21
+ *
22
+ * phpcs:disable WordPress.VIP,WordPress.XSS.EscapeOutput
23
+ */
24
+
25
+ namespace Boldgrid\Backup\Cli;
26
+
27
+ $php_min_version = '5.4';
28
+
29
+ if ( version_compare( PHP_VERSION, $php_min_version, '<' ) ) {
30
+ echo 'Error: Incompatible PHP version "' . PHP_VERSION . '". This utility requires "' .
31
+ $php_min_version . '" or higher.' . PHP_EOL;
32
+ exit( 1 );
33
+ }
34
+
35
+ require __DIR__ . '/class-info.php';
36
+ require __DIR__ . '/class-site-check.php';
37
+ require __DIR__ . '/class-log.php';
38
+ require __DIR__ . '/class-email.php';
39
+
40
+ if ( Info::has_errors() ) {
41
+ Info::print_errors();
42
+ exit( 1 );
43
+ }
44
+
45
+ if ( Site_Check::should_restore() ) {
46
+ require __DIR__ . '/class-site-restore.php';
47
+ ( new Site_Restore() )->run();
48
+ } else {
49
+ $message = 'Info: No action taken.';
50
+ echo $message . PHP_EOL;
51
+ Log::write( $message, LOG_INFO );
52
+ }
cli/class-email.php ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File: class-email.php
4
+ *
5
+ * Email functions
6
+ *
7
+ * @link https://www.boldgrid.com
8
+ * @since 1.10.0
9
+ *
10
+ * @package Boldgrid\Backup
11
+ * @subpackage Boldgrid\Backup\Cli
12
+ * @copyright BoldGrid
13
+ * @author BoldGrid <support@boldgrid.com>
14
+ *
15
+ * phpcs:disable WordPress.VIP,WordPress.WP.AlternativeFunctions
16
+ */
17
+
18
+ namespace Boldgrid\Backup\Cli;
19
+
20
+ /**
21
+ * Class: Email
22
+ *
23
+ * @since 1.10.0
24
+ */
25
+ class Email {
26
+ /**
27
+ * Recipient email addresss.
28
+ *
29
+ * @since 1.10.0
30
+ * @access private
31
+ *
32
+ * @var string
33
+ */
34
+ private $recipient;
35
+
36
+ /**
37
+ * Constructor.
38
+ *
39
+ * @since 1.10.0
40
+ *
41
+ * @link https://www.php.net/manual/en/function.mail.php
42
+ * @link http://www.faqs.org/rfcs/rfc2822
43
+ *
44
+ * @param string $recipient Recipient email address (with or without name).
45
+ */
46
+ public function __construct( $recipient ) {
47
+ $this->recipient = trim( $recipient );
48
+ }
49
+
50
+ /**
51
+ * Send a notification email.
52
+ *
53
+ * @since 1.10.0
54
+ *
55
+ * @param string $subject Message subject.
56
+ * @param string $message Message body.
57
+ * @return bool
58
+ */
59
+ public function send( $subject, $message ) {
60
+ $headers = 'From: ' . $this->recipient . "\r\nX-Mailer: PHP/" . phpversion() . "\r\n";
61
+
62
+ $message = "Hello,\r\n\r\n" . trim( $message ) . "\r\n\r\n" .
63
+ "Best regards,\r\n\r\nThe Total Upkeep plugin\r\n";
64
+
65
+ return mail( $this->recipient, $subject, $message, $headers );
66
+ }
67
+ }
cli/class-info.php ADDED
@@ -0,0 +1,897 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File: class-info.php
4
+ *
5
+ * Get information needed for CLI processes.
6
+ *
7
+ * @link https://www.boldgrid.com
8
+ * @since 1.9.0
9
+ *
10
+ * @package Boldgrid\Backup
11
+ * @subpackage Boldgrid\Backup\Cli
12
+ * @copyright BoldGrid
13
+ * @author BoldGrid <support@boldgrid.com>
14
+ *
15
+ * phpcs:disable WordPress.VIP,WordPress.WP.AlternativeFunctions,WordPress.XSS.EscapeOutput
16
+ */
17
+
18
+ namespace Boldgrid\Backup\Cli;
19
+
20
+ /**
21
+ * Class: Info.
22
+ *
23
+ * @since 1.9.0
24
+ */
25
+ class Info {
26
+ /**
27
+ * Archive and environment information.
28
+ *
29
+ * @since 1.9.0
30
+ * @access private
31
+ *
32
+ * @var array
33
+ * @staticvar
34
+ */
35
+ private static $info = [];
36
+
37
+ /**
38
+ * Backup result information JSON file path.
39
+ *
40
+ * @since 1.8.0
41
+ * @access private
42
+ * @staticvar
43
+ *
44
+ * @var string
45
+ */
46
+ private static $results_file_path;
47
+
48
+ /**
49
+ * Get the results file path.
50
+ *
51
+ * @since 1.9.0
52
+ * @static
53
+ *
54
+ * @return string
55
+ */
56
+ public static function get_results_filepath() {
57
+ if ( null === self::$results_file_path ) {
58
+ self::$results_file_path = dirname( __DIR__ ) . '/cron/restore-info.json';
59
+ }
60
+
61
+ return self::$results_file_path;
62
+ }
63
+
64
+ /**
65
+ * Get information.
66
+ *
67
+ * @since 1.9.0
68
+ * @static
69
+ *
70
+ * @see self::get_results_filepath()
71
+ * @see self::is_cli()
72
+ * @see self::get_mode()
73
+ * @see self::get_notify_flag()
74
+ * @see self::get_email_arg()
75
+ * @see self::get_zip_arg()
76
+ * @see self::have_execution_functions()
77
+ * @see self::get_restore_info()
78
+ * @see self::choose_method()
79
+ * @see \Boldgrid\Backup\Cli\Log::write()
80
+ *
81
+ * @return array
82
+ */
83
+ public static function get_info() {
84
+ if ( empty( self::$info['checked'] ) ) {
85
+ self::get_results_filepath();
86
+ self::is_cli();
87
+ self::get_mode();
88
+ self::get_log_flag();
89
+ self::get_log_level();
90
+ self::get_notify_flag();
91
+ self::get_email_arg();
92
+ self::get_zip_arg();
93
+ self::have_execution_functions();
94
+ self::get_restore_info();
95
+ self::choose_method(); // Requires data from self::get_restore_info().
96
+ Log::write( 'Gathered information.', LOG_DEBUG );
97
+ }
98
+
99
+ return self::$info;
100
+ }
101
+
102
+ /**
103
+ * Check for errors.
104
+ *
105
+ * @since 1.9.0
106
+ * @static
107
+ *
108
+ * @see self::get_info()
109
+ *
110
+ * @return bool
111
+ */
112
+ public static function has_errors() {
113
+ self::get_info();
114
+
115
+ return ! empty( self::$info['errors'] );
116
+ }
117
+
118
+ /**
119
+ * Print errors (to STDERR / FD2) and log (if enabled).
120
+ *
121
+ * @since 1.9.0
122
+ * @static
123
+ *
124
+ * @see self::has_errors()
125
+ */
126
+ public static function print_errors() {
127
+ if ( self::has_errors() ) {
128
+ if ( ! defined( 'STDERR' ) ) {
129
+ define( 'STDERR', fopen( 'php://stderr', 'w' ) );
130
+ }
131
+
132
+ fwrite( STDERR, implode( PHP_EOL, self::$info['errors'] ) . PHP_EOL );
133
+ }
134
+ }
135
+
136
+ /**
137
+ * Is this process running from the command line.
138
+ *
139
+ * @since 1.9.0
140
+ * @static
141
+ *
142
+ * @see \Boldgrid_Backup_Cron_Helper::is_cli()
143
+ * @see \Boldgrid\Backup\Cli\Log::write()
144
+ *
145
+ * @return bool
146
+ */
147
+ public static function is_cli() {
148
+ require_once dirname( __DIR__ ) . '/cron/class-boldgrid-backup-cron-helper.php';
149
+
150
+ if ( ! \Boldgrid_Backup_Cron_Helper::is_cli() ) {
151
+ self::$info['errors']['cli'] = 'Error: This process must run from the CLI.';
152
+ Log::write( self::$info['errors']['cli'], LOG_ERR );
153
+ return false;
154
+ } else {
155
+ return true;
156
+ }
157
+ }
158
+
159
+ /**
160
+ * Get the operational mode.
161
+ *
162
+ * A specific mode is required.
163
+ * "help" will print usage and exit. This is the default option.
164
+ * "check" will check issues and restore if needed.
165
+ * "restore" will force a restoration.
166
+ *
167
+ * @since 1.9.0
168
+ * @static
169
+ *
170
+ * @see self::has_arg_flag()
171
+ * @see \Boldgrid\Backup\Cli\Log::write()
172
+ *
173
+ * @return string|false
174
+ */
175
+ public static function get_mode() {
176
+ if ( ! isset( self::$info['operation'] ) ) {
177
+ switch ( true ) {
178
+ case self::has_arg_flag( 'help' ):
179
+ self::$info['operation'] = 'help';
180
+ break;
181
+ case self::has_arg_flag( 'restore' ):
182
+ self::$info['operation'] = 'restore';
183
+ break;
184
+ case self::has_arg_flag( 'check' ):
185
+ self::$info['operation'] = 'check';
186
+ break;
187
+ default:
188
+ self::$info['operation'] = false;
189
+ break;
190
+ }
191
+
192
+ $usage = 'Usage: php bgbkup-cli.php <check|restore> [log] [notify] [email=<email_address>] [method=<ajax|cli|pclzip|ziparchive>] [zip=<path/to/backup.zip>] [log_level=<(LOG_EMERG|LOG_ALERT|LOG_CRIT|LOG_ERR|LOG_WARNING|LOG_NOTICE|LOG_INFO|LOG_DEBUG)|(0-7)>]';
193
+
194
+ if ( 'help' === self::$info['operation'] ) {
195
+ self::$info['errors']['help'] = $usage;
196
+ } elseif ( ! self::$info['operation'] ) {
197
+ self::$info['errors']['mode'] =
198
+ 'Error: An operational mode (check/restore) is required.';
199
+ self::$info['errors']['help'] = $usage;
200
+ } else {
201
+ Log::write( 'Operational mode set to "' . self::$info['operation'] . '".', LOG_INFO );
202
+ }
203
+ }
204
+
205
+ return self::$info['operation'];
206
+ }
207
+
208
+ /**
209
+ * Are there available execution functions.
210
+ *
211
+ * @since 1.9.0
212
+ * @static
213
+ *
214
+ * @see \Boldgrid_Backup_Admin_Cli::get_execution_functions()
215
+ * @see \Boldgrid\Backup\Cli\Log::write()
216
+ *
217
+ * @return bool
218
+ */
219
+ public static function have_execution_functions() {
220
+ require_once dirname( __DIR__ ) . '/admin/class-boldgrid-backup-admin-cli.php';
221
+
222
+ $exec_functions = \Boldgrid_Backup_Admin_Cli::get_execution_functions();
223
+
224
+ if ( empty( $exec_functions ) ) {
225
+ self::$info['errors']['no_exec'] = 'Error: No available PHP executable functions.';
226
+ Log::write( self::$info['errors']['no_exec'], LOG_ERR );
227
+ return false;
228
+ } else {
229
+ return true;
230
+ }
231
+ }
232
+
233
+ /**
234
+ * Get CLI arguments, save the array in $info['cli_args'], and return the array of CLI args.
235
+ *
236
+ * @since 1.9.0
237
+ * @static
238
+ *
239
+ * @return array;
240
+ */
241
+ public static function get_cli_args() {
242
+ if ( empty( self::$info['cli_args'] ) ) {
243
+ if ( ! empty( $_SERVER['argv'] ) ) {
244
+ parse_str(
245
+ implode( '&', array_slice( $_SERVER['argv'], 1 ) ),
246
+ self::$info['cli_args']
247
+ );
248
+ } else {
249
+ self::$info['cli_args'] = [];
250
+ }
251
+ }
252
+
253
+ return self::$info['cli_args'];
254
+ }
255
+
256
+ /**
257
+ * Do CLI arguments include specified flag.
258
+ *
259
+ * @since 1.9.0
260
+ * @static
261
+ *
262
+ * @see self::get_cli_args()
263
+ *
264
+ * @param string $flag Flag argument.
265
+ * @return bool
266
+ */
267
+ public static function has_arg_flag( $flag ) {
268
+ return isset( self::get_cli_args()[ $flag ] );
269
+ }
270
+
271
+ /**
272
+ * Get the value of a spcified CLI arguments.
273
+ *
274
+ * @since 1.9.0
275
+ * @static
276
+ *
277
+ * @see self::get_cli_args()
278
+ *
279
+ * @param string $name Argument name.
280
+ * @return string|null
281
+ */
282
+ public static function get_arg_value( $name ) {
283
+ $args = self::get_cli_args();
284
+ $value = isset( $args[ $name ] ) ? urldecode( $args[ $name ] ) : null;
285
+
286
+ return $value;
287
+ }
288
+
289
+ /**
290
+ * Get the log flag spcified in CLI arguments.
291
+ *
292
+ * This method triggers reading the CLI arguments and appends to the self:$info array.
293
+ *
294
+ * @since 1.10.0
295
+ * @static
296
+ *
297
+ * @see self::has_arg_flag()
298
+ *
299
+ * @return bool
300
+ */
301
+ public static function get_log_flag() {
302
+ if ( ! isset( self::$info['log'] ) ) {
303
+ self::$info['log'] = self::has_arg_flag( 'log' );
304
+ }
305
+
306
+ return self::$info['log'];
307
+ }
308
+
309
+ /**
310
+ * Get the log level argument spcified in CLI arguments.
311
+ *
312
+ * This method triggers reading the CLI arguments and appends to the self:$info array.
313
+ *
314
+ * @since 1.10.0
315
+ * @static
316
+ *
317
+ * @see self::get_arg_value()
318
+ *
319
+ * @return int
320
+ */
321
+ public static function get_log_level() {
322
+ $allowed = [
323
+ 'LOG_EMERG', // 0.
324
+ 'LOG_ALERT', // 1.
325
+ 'LOG_CRIT', // 2.
326
+ 'LOG_ERR', // 3.
327
+ 'LOG_WARNING', // 4.
328
+ 'LOG_NOTICE', // 5 -- Our default.
329
+ 'LOG_INFO', // 6.
330
+ 'LOG_DEBUG', // 7.
331
+ ];
332
+
333
+ if ( ! isset( self::$info['log_level'] ) ) {
334
+ self::$info['log_level'] = self::get_arg_value( 'log_level' );
335
+
336
+ // Validate the log level.
337
+ if ( in_array( self::$info['log_level'], $allowed, true ) ) {
338
+ // Convert string to the constant integer value.
339
+ self::$info['log_level'] = constant( self::$info['log_level'] );
340
+ } elseif ( ! is_numeric( self::$info['log_level'] ) ||
341
+ self::$info['log_level'] < LOG_EMERG || self::$info['log_level'] > LOG_DEBUG ) {
342
+ // Invalid or no input value; set to the default.
343
+ self::$info['log_level'] = LOG_NOTICE;
344
+ }
345
+ }
346
+
347
+ return (int) self::$info['log_level'];
348
+ }
349
+
350
+ /**
351
+ * Get the notification flag spcified in CLI arguments.
352
+ *
353
+ * This method triggers reading the CLI arguments and appends to the self:$info array.
354
+ *
355
+ * @since 1.10.0
356
+ * @static
357
+ *
358
+ * @see self::has_arg_flag()
359
+ *
360
+ * @return bool
361
+ */
362
+ public static function get_notify_flag() {
363
+ if ( ! isset( self::$info['notify'] ) ) {
364
+ self::$info['notify'] = self::has_arg_flag( 'notify' );
365
+ }
366
+
367
+ return self::$info['notify'];
368
+ }
369
+
370
+ /**
371
+ * Get the notification email address spcified in CLI arguments.
372
+ *
373
+ * This method triggers reading the CLI arguments and appends to the self:$info array.
374
+ *
375
+ * @since 1.10.0
376
+ * @static
377
+ *
378
+ * @see self::get_arg_value()
379
+ *
380
+ * @return string|false
381
+ */
382
+ public static function get_email_arg() {
383
+ if ( ! isset( self::$info['email'] ) ) {
384
+ self::$info['email'] = self::get_arg_value( 'email' );
385
+ }
386
+
387
+ return self::$info['email'];
388
+ }
389
+
390
+ /**
391
+ * Get the ZIP path spcified in CLI arguments.
392
+ *
393
+ * ZIP archive value specified is formatted into a canonicalized absolute pathname.
394
+ * This method triggers reading the CLI arguments and appends to the self:$info array.
395
+ *
396
+ * @since 1.9.0
397
+ * @static
398
+ *
399
+ * @see self::get_arg_value()
400
+ * @see self::has_arg_flag()
401
+ *
402
+ * @return string|false
403
+ */
404
+ public static function get_zip_arg() {
405
+ if ( ! isset( self::$info['zip'] ) ) {
406
+ $zip_arg = self::get_arg_value( 'zip' );
407
+ $zip_path = realpath( $zip_arg );
408
+
409
+ if ( self::has_arg_flag( 'zip' ) && empty( $zip_arg ) ) {
410
+ self::$info['errors']['zip_path_empty'] = 'Error: Empty ZIP archive path specified.';
411
+ } elseif ( $zip_arg && ! file_exists( $zip_path ) ) {
412
+ self::$info['errors']['zip_path_bad'] = 'Error: Specified ZIP archive path "' .
413
+ ( $zip_path ? $zip_path : $zip_arg ) . '" does not exist.';
414
+ }
415
+
416
+ self::$info['zip'] = ( $zip_arg && $zip_path && file_exists( $zip_path ) ) ?
417
+ $zip_path : false;
418
+ }
419
+
420
+ return self::$info['zip'];
421
+ }
422
+
423
+ /**
424
+ * Determine the restoration method.
425
+ *
426
+ * This method either validates and uses the specified method, or determines one to use.
427
+ * Valid values are: "ajax", "ziparchive", "pclzip", "cli".
428
+ * This method triggers reading the CLI arguments and appends to the self:$info array.
429
+ *
430
+ * @since 1.9.0
431
+ * @static
432
+ *
433
+ * @see self::get_arg_value()
434
+ * @see Site_Check::is_siteurl_reachable()
435
+ * @see \Boldgrid_Backup_Admin_Cli::call_command()
436
+ * @see \Boldgrid\Backup\Cli\Log::write()
437
+ *
438
+ * @return string|false
439
+ */
440
+ public static function choose_method() {
441
+ if ( ! isset( self::$info['method'] ) ) {
442
+ self::$info['method'] = false;
443
+ $method_arg = self::get_arg_value( 'method' );
444
+ $unavail_msg = 'Error: The method "' . $method_arg . '" is not available.';
445
+
446
+ switch ( $method_arg ) {
447
+ case 'ajax':
448
+ if ( ! ( Site_Check::is_siteurl_reachable() && ! empty( self::$info['restore_cmd'] ) ) ) {
449
+ self::$info['errors']['method_unavailable'] = $unavail_msg;
450
+ break;
451
+ }
452
+ self::$info['method'] = $method_arg;
453
+ break;
454
+ case 'cli':
455
+ if ( ! ( \Boldgrid_Backup_Admin_Cli::call_command( 'unzip', $success, $return_var ) || $success || 0 === $return_var ) ) {
456
+ self::$info['errors']['method_unavailable'] = $unavail_msg;
457
+ break;
458
+ }
459
+ self::$info['method'] = $method_arg;
460
+ break;
461
+ case 'pclzip':
462
+ if ( empty( self::$info['ABSPATH'] ) || ! file_exists( self::$info['ABSPATH'] . 'wp-admin/includes/class-pclzip.php' ) ) {
463
+ self::$info['errors']['method_unavailable'] = $unavail_msg;
464
+ break;
465
+ }
466
+ self::$info['method'] = $method_arg;
467
+ break;
468
+ case 'ziparchive':
469
+ if ( ! class_exists( 'ZipArchive' ) ) {
470
+ self::$info['errors']['method_unavailable'] = $unavail_msg;
471
+ break;
472
+ }
473
+ self::$info['method'] = $method_arg;
474
+ break;
475
+ case '':
476
+ // Determine method.
477
+ switch ( true ) {
478
+ case class_exists( 'ZipArchive' ):
479
+ self::$info['method'] = 'ziparchive';
480
+ break;
481
+ case file_exists( $info['ABSPATH'] . 'wp-admin/includes/class-pclzip.php' ):
482
+ self::$info['method'] = 'pclzip';
483
+ break;
484
+ case \Boldgrid_Backup_Admin_Cli::call_command( 'unzip', $success, $return_var ) || $success || 0 === $return_var:
485
+ self::$info['method'] = 'cli';
486
+ break;
487
+ default:
488
+ self::$info['method'] = 'ajax';
489
+ break;
490
+ }
491
+ break;
492
+ default:
493
+ self::$info['errors']['method_invalid'] =
494
+ 'Error: The specified restoration method is invalid; must be one of the following: ajax, cli, pclzip, ziparchive.';
495
+ break;
496
+ }
497
+ }
498
+
499
+ Log::write( 'Chosen restoration method: "' . self::$info['method'] . '".', LOG_INFO );
500
+
501
+ return self::$info['method'];
502
+ }
503
+
504
+ /**
505
+ * Get environment info, save the array in $info['env'], and return the array.
506
+ *
507
+ * @since 1.9.0
508
+ * @static
509
+ *
510
+ * @see Boldgrid_Backup_Url_Helper::call_url()
511
+ *
512
+ * @return array;
513
+ */
514
+ public static function get_env_info() {
515
+ if ( empty( self::$info['env'] ) ) {
516
+ require_once dirname( __DIR__ ) . '/cron/class-boldgrid-backup-url-helper.php';
517
+ $url_helper = new \Boldgrid_Backup_Url_Helper();
518
+
519
+ self::$info['env'] = json_decode(
520
+ $url_helper->call_url(
521
+ self::$info['siteurl'] . '/wp-content/plugins/boldgrid-backup/cli/env-info.php'
522
+ ),
523
+ true
524
+ );
525
+ }
526
+
527
+ return self::$info['env'];
528
+ }
529
+
530
+ /**
531
+ * Read a JSON file, and return the contents in an array.
532
+ *
533
+ * @since 1.9.0
534
+ * @static
535
+ *
536
+ * @param string $file_path JSON file path.
537
+ * @return array
538
+ */
539
+ public static function read_json_file( $file_path ) {
540
+ $result = file_exists( $file_path ) ?
541
+ json_decode( file_get_contents( $file_path ), true ) : false;
542
+
543
+ return $result ? $result : [];
544
+ }
545
+
546
+ /**
547
+ * Extarct a file from a backup archive ZIP file.
548
+ *
549
+ * @since 1.9.0
550
+ * @static
551
+ *
552
+ * @see \Boldgrid\Backup\Cli\Log::write()
553
+ *
554
+ * @param string $extract_dir Extraction directory.
555
+ * @param string $file File to be extracted.
556
+ * @return bool
557
+ */
558
+ public static function extract_file( $extract_dir, $file ) {
559
+ $success = false;
560
+
561
+ Log::write( 'Extracting "' . $file . '" into "' . $extract_dir . '".', LOG_DEBUG );
562
+
563
+ switch ( true ) {
564
+ case class_exists( 'ZipArchive' ):
565
+ $zip = new \ZipArchive();
566
+ if ( true === $zip->open( self::$info['filepath'] ) ) {
567
+ $success = $zip->extractTo( $extract_dir, $file );
568
+ $zip->close();
569
+ } else {
570
+ $message = 'Error: Could not open the specified ZIP file path "' .
571
+ self::$info['filepath'] . '".';
572
+ self::$info['errors'][] = $message;
573
+ Log::write( $message, LOG_ERR );
574
+ }
575
+ break;
576
+ // @todo: Add PCLZip and unzip (CLI).
577
+ default:
578
+ $message = 'Error: Could not extract files; ZipArchive unavailable.';
579
+ self::$info['errors'][] = $message;
580
+ Log::write( $message, LOG_ERR );
581
+ }
582
+
583
+ if ( ! $success || ! file_exists( $extract_dir . '/' . $file ) ) {
584
+ $success = false;
585
+ $message = 'Error: The file "' . $file .
586
+ '" does not exist in the specified ZIP file path "' . self::$info['filepath'] .
587
+ '".';
588
+ self::$info['errors'][] = $message;
589
+ Log::write( $message, LOG_ERR );
590
+ }
591
+
592
+ return $success;
593
+ }
594
+
595
+ /**
596
+ * Read an archive log JSON file from inside of a backup archive ZIP file, and return the
597
+ * contents in an array.
598
+ *
599
+ * @since 1.9.0
600
+ * @static
601
+ *
602
+ * @see \Boldgrid\Backup\Cli\Log::write()
603
+ * @see self::extract_file()
604
+ * @see self::read_json_file()
605
+ *
606
+ * @return array
607
+ */
608
+ public static function read_zip_log() {
609
+ if ( ! preg_match( '/\.zip$/', self::$info['filepath'] ) ) {
610
+ self::$info['errors']['zip_path_invalid'] =
611
+ 'Error: Invalid ZIP file path specified; must end with ".zip".';
612
+ Log::write( self::$info['errors']['zip_path_invalid'], LOG_ERR );
613
+ return [];
614
+ }
615
+
616
+ $log_info = [];
617
+ $extract_dir = dirname( self::$info['filepath'] );
618
+ $archive_log_file = basename( preg_replace( '/\.zip$/', '.log', self::$info['filepath'] ) );
619
+ $extract_filepath = $extract_dir . '/' . $archive_log_file;
620
+
621
+ if ( ! file_exists( $extract_filepath ) ) {
622
+ // Extract the log file.
623
+ $success = self::extract_file( $extract_dir, $archive_log_file );
624
+
625
+ if ( $success && file_exists( $extract_filepath ) ) {
626
+ $log_info = self::read_json_file( $extract_filepath );
627
+ unlink( $extract_filepath );
628
+ }
629
+ } else {
630
+ // Log file already existed, so just read it.
631
+ $log_info = self::read_json_file( $extract_filepath );
632
+ }
633
+
634
+ return $log_info;
635
+ }
636
+
637
+ /**
638
+ * Set an item in the info array.
639
+ *
640
+ * @since 1.9.0
641
+ * @static
642
+ *
643
+ * @param string $key Index/key name.
644
+ * @param mixed $value Value.
645
+ */
646
+ public static function set_info_item( $key, $value ) {
647
+ if ( isset( $key, $value ) && is_string( $key ) ) {
648
+ self::$info[ $key ] = $value;
649
+ }
650
+ }
651
+
652
+ /**
653
+ * Retrieve validated restoration information.
654
+ *
655
+ * If validation fails, then errors are saved in the $info['errors'] class property.
656
+ *
657
+ * @since 1.9.0
658
+ * @access private
659
+ * @static
660
+ *
661
+ * @see \Boldgrid\Backup\Cli\Log::write()
662
+ * @see self::get_zip_info()
663
+ * @see self::get_latest_info()
664
+ * @see self::read_json_file()
665
+ * @see self::read_zip_log()
666
+ *
667
+ * @return bool
668
+ */
669
+ private static function get_restore_info() {
670
+ self::$info['checked'] = time();
671
+
672
+ // Initialize restore attempts counter, which is a default until merge with $results.
673
+ self::$info['restore_attempts'] = 0;
674
+
675
+ // Check for PHP safe mode.
676
+ if ( ini_get( 'safe_mode' ) ) {
677
+ $message = 'Error: Cannot continue in PHP safe mode.';
678
+ self::$info['errors'][] = $message;
679
+ Log::write( $message, LOG_ERR );
680
+ return false;
681
+ }
682
+
683
+ if ( self::has_arg_flag( 'zip' ) ) {
684
+ // Use the specified ZIP archive file path from the CLI arguments.
685
+ if ( ! self::get_zip_info() ) {
686
+ // Error already added by self::get_zip_info().
687
+ return false;
688
+ }
689
+ } else {
690
+ // Use the latest backup archive created by the plugin. Get the backup results file.
691
+ if ( ! self::get_latest_info() ) {
692
+ // Error already added by self::get_latest_info().
693
+ return false;
694
+ }
695
+ }
696
+
697
+ if ( empty( self::$info['ABSPATH'] ) ) {
698
+ $message = 'Error: Unknown ABSPATH.';
699
+ self::$info['errors'][] = $message;
700
+ Log::write( $message, LOG_ERR );
701
+ return false;
702
+ }
703
+
704
+ if ( ! is_dir( self::$info['ABSPATH'] ) ) {
705
+ $message = 'Error: ABSPATH directory "' . self::$info['ABSPATH'] .
706
+ '" does not exist or is not a directory.';
707
+ self::$info['errors'][] = $message;
708
+ Log::write( $message, LOG_ERR );
709
+ }
710
+
711
+ if ( ! is_writable( self::$info['ABSPATH'] ) ) {
712
+ $message = 'Error: ABSPATH directory "' . self::$info['ABSPATH'] .
713
+ '" is not writable.';
714
+ self::$info['errors'][] = $message;
715
+ Log::write( $message, LOG_ERR );
716
+ }
717
+
718
+ if ( empty( self::$info['siteurl'] ) ) {
719
+ $message = 'Error: Unknown siteurl.';
720
+ self::$info['errors'][] = $message;
721
+ Log::write( $message, LOG_ERR );
722
+ }
723
+
724
+ if ( empty( self::$info['db_filename'] ) ) {
725
+ $message = 'Error: Unknown database dump filename.';
726
+ self::$info['errors'][] = $message;
727
+ Log::write( $message, LOG_ERR );
728
+ } else {
729
+ self::$info['db_filepath'] = self::$info['ABSPATH'] . self::$info['db_filename'];
730
+ }
731
+
732
+ self::get_env_info();
733
+
734
+ return true;
735
+ }
736
+
737
+ /**
738
+ * Retrieve validated restoration information from the specified ZIP file path.
739
+ *
740
+ * If validation fails, then errors are saved in the $info['errors'] class property.
741
+ *
742
+ * @since 1.9.0
743
+ * @access private
744
+ * @static
745
+ *
746
+ * @see self::get_zip_arg()
747
+ * @see self::read_json_file()
748
+ * @see self::read_zip_log()
749
+ *
750
+ * @return bool
751
+ */
752
+ private static function get_zip_info() {
753
+ $zip_filepath = self::get_zip_arg();
754
+
755
+ if ( empty( $zip_filepath ) ) {
756
+ // Error already added by self::get_zip_arg().
757
+ return false;
758
+ }
759
+
760
+ self::$info['filepath'] = $zip_filepath;
761
+ self::$info['archive_key'] = 0;
762
+ self::$info['restore_cmd'] = null;
763
+
764
+ // Attempt to read information from the last backup's result file.
765
+ $results = self::read_json_file( self::$results_file_path );
766
+ self::$info['cron_secret'] = isset( $results['cron_secret'] ) ? $results['cron_secret'] : null;
767
+ self::$info['site_title'] = isset( $results['site_title'] ) ? $results['site_title'] : null;
768
+
769
+ // Retrieve information from the log file in the ZIP archive.
770
+ $log_info = self::read_zip_log();
771
+
772
+ if ( empty( $log_info ) ) {
773
+ // Error already added by self::read_zip_log().
774
+ return false;
775
+ }
776
+
777
+ self::$info = array_merge( self::$info, $log_info );
778
+
779
+ if ( self::$info['siteurl'] && self::$info['backup_id'] && self::$info['cron_secret'] ) {
780
+ // Build the restore command.
781
+ self::$info['restore_cmd'] = 'php -d register_argc_argv=1 -qf "' . dirname( __DIR__ ) .
782
+ '/boldgrid-backup-cron.php" ' .
783
+ http_build_query(
784
+ [
785
+ 'mode' => 'restore',
786
+ 'siteurl' => self::$info['siteurl'],
787
+ 'id' => self::$info['backup_id'],
788
+ 'secret' => self::$info['cron_secret'],
789
+ 'archive_key' => self::$info['archive_key'],
790
+ 'archive_filename' => basename( self::$info['filepath'] ),
791
+ ],
792
+ '',
793
+ ' '
794
+ );
795
+ }
796
+
797
+ self::$info['timestamp'] = time();
798
+
799
+ return true;
800
+ }
801
+
802
+ /**
803
+ * Retrieve validated restoration information from the latest backup archive.
804
+ *
805
+ * If validation fails, then errors are saved in the $info['errors'] class property.
806
+ *
807
+ * @since 1.9.0
808
+ * @access private
809
+ * @static
810
+ *
811
+ * @see self::has_arg_flag()
812
+ * @see \Boldgrid\Backup\Cli\Log::write()
813
+ * @see self::read_json_file()
814
+ * @see self::read_zip_log()
815
+ *
816
+ * @return bool
817
+ */
818
+ private static function get_latest_info() {
819
+ // If mode is not check or restore, then the restore info is not needed.
820
+ if ( ! self::has_arg_flag( 'check' ) && ! self::has_arg_flag( 'restore' ) ) {
821
+ return false;
822
+ }
823
+
824
+ // We require the results info file from the last full backup.
825
+ if ( ! file_exists( self::$results_file_path ) ) {
826
+ $message = 'Error: Missing backup results file ("' .
827
+ self::$results_file_path . '").';
828
+ self::$info['errors'][] = $message;
829
+ Log::write( $message, LOG_ERR );
830
+ return false;
831
+ }
832
+
833
+ $results = self::read_json_file( self::$results_file_path );
834
+
835
+ // Validate results file content.
836
+ if ( empty( $results ) ) {
837
+ $message = 'Error: No backup results found.';
838
+ self::$info['errors'][] = $message;
839
+ Log::write( $message, LOG_ERR );
840
+ return false;
841
+ }
842
+
843
+ if ( empty( $results['filepath'] ) ) {
844
+ $message = 'Error: Unknown backup archive file path.';
845
+ self::$info['errors'][] = $message;
846
+ Log::write( $message, LOG_ERR );
847
+ return false;
848
+ }
849
+
850
+ // Check if archive exists.
851
+ if ( ! file_exists( $results['filepath'] ) ) {
852
+ $message = 'Error: Backup archive file "' .
853
+ $results['filepath'] . '" does not exist.';
854
+ self::$info['errors'][] = $message;
855
+ Log::write( $message, LOG_ERR );
856
+ return false;
857
+ }
858
+
859
+ // Get the archive log file and merge info.
860
+ $archive_log_filepath = preg_replace( '/\.zip$/', '.log', $results['filepath'] );
861
+
862
+ if ( ! file_exists( $archive_log_filepath ) ) {
863
+ $message = 'Error: Backup archive log file "' . $archive_log_filepath .
864
+ '" does not exist.';
865
+ self::$info['errors'][] = $message;
866
+ Log::write( $message, LOG_ERR );
867
+ return false;
868
+ }
869
+
870
+ $log_info = self::read_json_file( $archive_log_filepath );
871
+
872
+ // Validate results file content.
873
+ if ( empty( $log_info ) ) {
874
+ $message = 'Error: No backup information found in the log file "' .
875
+ $archive_log_filepath . '".';
876
+ self::$info['errors'][] = $message;
877
+ Log::write( $message, LOG_ERR );
878
+ return false;
879
+ }
880
+
881
+ // Merge info and results arrays.
882
+ self::$info = array_merge( self::$info, $log_info, $results );
883
+
884
+ if ( empty( self::$info['cron_secret'] ) ) {
885
+ $message = 'Error: Unknown cron_secret.';
886
+ self::$info['errors'][] = $message;
887
+ Log::write( $message, LOG_ERR );
888
+ }
889
+
890
+ // Ensure that there is a site title.
891
+ if ( empty( self::$info['site_title'] ) ) {
892
+ self::$info['site_title'] = 'WordPress';
893
+ }
894
+
895
+ return true;
896
+ }
897
+ }
cli/class-log.php ADDED
@@ -0,0 +1,122 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File: class-log.php
4
+ *
5
+ * Log functions
6
+ *
7
+ * @link https://www.boldgrid.com
8
+ * @since 1.10.0
9
+ *
10
+ * @package Boldgrid\Backup
11
+ * @subpackage Boldgrid\Backup\Cli
12
+ * @copyright BoldGrid
13
+ * @author BoldGrid <support@boldgrid.com>
14
+ *
15
+ * phpcs:disable WordPress.VIP,WordPress.WP.AlternativeFunctions
16
+ */
17
+
18
+ namespace Boldgrid\Backup\Cli;
19
+
20
+ /**
21
+ * Class: Log
22
+ *
23
+ * @since 1.10.0
24
+ */
25
+ class Log {
26
+ /**
27
+ * Log level label map.
28
+ *
29
+ * Uses log level constants in PHP core:
30
+ * LOG_EMERG 0 System is unusable.
31
+ * LOG_ALERT 1 Action must be taken immediately.
32
+ * LOG_CRIT 2 Critical conditions.
33
+ * LOG_ERR 3 Error conditions.
34
+ * LOG_WARNING 4 Warning conditions.
35
+ * LOG_NOTICE 5 Normal, but significant, condition.
36
+ * LOG_INFO 6 Informational message.
37
+ * LOG_DEBUG 7 Debug-level message.
38
+ *
39
+ * @since 1.10.0
40
+ * @access private
41
+ *
42
+ * @var array
43
+ * @staticvar
44
+ */
45
+ private static $log_levels = [
46
+ LOG_EMERG => 'EMERG',
47
+ LOG_ALERT => 'ALERT',
48
+ LOG_CRIT => 'CRIT',
49
+ LOG_ERR => 'ERR',
50
+ LOG_WARNING => 'WARNING',
51
+ LOG_NOTICE => 'NOTICE',
52
+ LOG_INFO => 'INFO',
53
+ LOG_DEBUG => 'DEBUG',
54
+ ];
55
+
56
+ /**
57
+ * Log file path.
58
+ *
59
+ * @since 1.10.0
60
+ * @access private
61
+ *
62
+ * @var string
63
+ * @staticvar
64
+ */
65
+ private static $log_filename = '/bgbkup-cli.log';
66
+
67
+ /**
68
+ * Log timestamp format.
69
+ *
70
+ * @since 1.10.0
71
+ * @access private
72
+ *
73
+ * @var string
74
+ * @staticvar
75
+ */
76
+ private static $date_format = 'Y-m-d H:i:s';
77
+
78
+ /**
79
+ * Write a message to the log file.
80
+ *
81
+ * @since 1.10.0
82
+ * @static
83
+ *
84
+ * @param int $log_level Log level.
85
+ * @return string
86
+ */
87
+ public static function get_level_label( $log_level ) {
88
+ return self::$log_levels[ $log_level ];
89
+ }
90
+
91
+ /**
92
+ * Write a message to the log file.
93
+ *
94
+ * @since 1.10.0
95
+ * @static
96
+ *
97
+ * @see \Boldgrid\Backup\Cli\Info::get_log_flag()
98
+ * @see \Boldgrid\Backup\Cli\Info::get_log_level()
99
+ * @see self::get_level_label()
100
+ *
101
+ * @param string $message Message.
102
+ * @param int $log_level Log level. Default: LOG_NOTICE.
103
+ * @return bool
104
+ */
105
+ public static function write( $message, $log_level = LOG_NOTICE ) {
106
+ $success = true;
107
+
108
+ // If fopen is not enabled, then we cannot write; abort.
109
+ if ( ! ini_get( 'allow_url_fopen' ) ) {
110
+ return false;
111
+ }
112
+
113
+ // If logging is enabled and the message log level is included, then write to the log file.
114
+ if ( Info::get_log_flag() && Info::get_log_level() >= $log_level ) {
115
+ $message = date( self::$date_format ) . ' [' . self::get_level_label( $log_level ) . '] ' .
116
+ $message . PHP_EOL;
117
+ $success = false !== file_put_contents( __DIR__ . self::$log_filename, $message, FILE_APPEND );
118
+ }
119
+
120
+ return $success;
121
+ }
122
+ }
cli/class-site-check.php ADDED
@@ -0,0 +1,251 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File: class-site-check.php
4
+ *
5
+ * Check the integrity of the website.
6
+ *
7
+ * @link https://www.boldgrid.com
8
+ * @since 1.9.0
9
+ *
10
+ * @package Boldgrid\Backup
11
+ * @subpackage Boldgrid\Backup\Cli
12
+ * @copyright BoldGrid
13
+ * @author BoldGrid <support@boldgrid.com>
14
+ *
15
+ * phpcs:disable WordPress.WP.AlternativeFunctions,WordPress.XSS.EscapeOutput
16
+ */
17
+
18
+ namespace Boldgrid\Backup\Cli;
19
+
20
+ /**
21
+ * Class: Site_Check.
22
+ *
23
+ * @since 1.9.0
24
+ */
25
+ class Site_Check {
26
+ /**
27
+ * Maximum restoration attempts.
28
+ *
29
+ * @since 1.9.0
30
+ * @access private
31
+ * @static
32
+ *
33
+ * @var int
34
+ */
35
+ private static $max_restore_attempts = 2;
36
+
37
+ /**
38
+ * Test resukt output from the wp-test script.
39
+ *
40
+ * @since 1.10.0
41
+ * @access private
42
+ * @static
43
+ *
44
+ * @var string
45
+ */
46
+ private static $wp_test_result;
47
+
48
+ /**
49
+ * Run the site check process, to determine if the site needs to be restored from backup.
50
+ *
51
+ * Decide if a restoration should be completed.
52
+ *
53
+ * @since 1.9.0
54
+ * @static
55
+ *
56
+ * @see \Boldgrid\Backup\Cli\Info::has_errors()
57
+ * @see self::does_wp_load()
58
+ * @see \Boldgrid\Backup\Cli\Info::has_arg_flag()
59
+ * @see \Boldgrid\Backup\Cli\Info::get_notify_flag()
60
+ * @see \Boldgrid\Backup\Cli\Info::get_email_arg()
61
+ * @see \Boldgrid\Backup\Cli\Info::get_info()
62
+ *
63
+ * @return bool
64
+ */
65
+ public static function should_restore() {
66
+ $should_restore = false;
67
+
68
+ // Abort if there are errors retrieving information.
69
+ if ( Info::has_errors() ) {
70
+ return false;
71
+ }
72
+
73
+ // If the "auto_recovery" argument is passed and set to "1", then set-up for auto-restore.
74
+ $auto_restore = false !== Info::has_arg_flag( 'auto_recovery' ) &&
75
+ '1' === Info::get_cli_args()['auto_recovery'];
76
+ $mode = Info::get_mode();
77
+ $restore_attempts = Info::get_info()['restore_attempts'];
78
+ $attempts_exceeded = $restore_attempts >= self::$max_restore_attempts;
79
+
80
+ // If "check" flag was passed and there have not been too many restoration attempts.
81
+ if ( 'check' === $mode && ! $attempts_exceeded ) {
82
+ $result = self::check();
83
+
84
+ if ( ! $result && $auto_restore ) {
85
+ $should_restore = true;
86
+ }
87
+
88
+ // If a check has failed, then send an email notification, if enabled.
89
+ $should_notify = ! $result && Info::get_notify_flag() && Info::get_email_arg();
90
+
91
+ if ( $should_notify ) {
92
+ self::send_notification();
93
+ }
94
+ }
95
+
96
+ // If the "auto_recovery" argument is not passed or set to "0", then do not restore.
97
+ if ( false === Info::has_arg_flag( 'auto_recovery' ) ||
98
+ '0' === Info::get_cli_args()['auto_recovery'] ) {
99
+ $should_restore = false;
100
+ }
101
+
102
+ // If "Restore" flag was possed, it is a forced restoration.
103
+ if ( 'restore' === $mode ) {
104
+ $should_restore = true;
105
+ }
106
+
107
+ return $should_restore;
108
+ }
109
+
110
+ /**
111
+ * Is the site reachable.
112
+ *
113
+ * @since 1.9.0
114
+ * @static
115
+ *
116
+ * @see \Boldgrid\Backup\Cli\Info::get_info()
117
+ * @see \Boldgrid_Backup_Url_Helper::call_url()
118
+ *
119
+ * @return bool;
120
+ */
121
+ public static function is_siteurl_reachable() {
122
+ $result = false;
123
+
124
+ require_once dirname( __DIR__ ) . '/cron/class-boldgrid-backup-url-helper.php';
125
+
126
+ if ( ! empty( Info::get_info()['siteurl'] ) ) {
127
+ $response = ( new \Boldgrid_Backup_Url_Helper() )->call_url(
128
+ Info::get_info()['siteurl'],
129
+ $status,
130
+ $errorno,
131
+ $error
132
+ );
133
+
134
+ if ( 200 === $status ) {
135
+ $result = true;
136
+ }
137
+ }
138
+
139
+ return $result;
140
+ }
141
+
142
+ /**
143
+ * Does WordPress load via PHP.
144
+ *
145
+ * @since 1.9.0
146
+ * @static
147
+ *
148
+ * @see \Boldgrid_Backup_Admin_Cli::call_command()
149
+ *
150
+ * @return bool
151
+ */
152
+ public static function does_wp_load() {
153
+ self::$wp_test_result = \Boldgrid_Backup_Admin_Cli::call_command(
154
+ 'cd ' . __DIR__ . '; php -qf wp-test.php',
155
+ $success
156
+ );
157
+
158
+ return $success;
159
+ }
160
+
161
+ /**
162
+ * Check if a port is open.
163
+ *
164
+ * @since 1.10.0
165
+ * @static
166
+ *
167
+ * @link https://www.php.net/manual/en/function.fsockopen.php
168
+ *
169
+ * @param int $port Port number (1-65535).
170
+ * @param string $host Optional hostname; defaults to "localhost".
171
+ * @param int $timeout Connect timeout, in seconds; defaults to 5.
172
+ * @param int $errno If provided, holds the system level error number that occurred in the system-level connect() call.
173
+ * @param string $errstr The error message as a string.
174
+ * @return bool
175
+ */
176
+ public static function check_port( $port, $host = 'localhost', $timeout = 5, &$errno, &$errstr ) {
177
+ // Check for valid port reange.
178
+ if ( 0 > $port || 65535 < $port ) {
179
+ return false;
180
+ }
181
+
182
+ $res = @fsockopen( $host, $port, $errno, $errstr, $timeout ); // phpcs:ignore Generic.PHP.NoSilencedErrors
183
+
184
+ if ( is_resource( $res ) ) {
185
+ fclose( $res );
186
+ return true;
187
+ }
188
+
189
+ return false;
190
+ }
191
+
192
+ /**
193
+ * Perform a site check.
194
+ *
195
+ * @since 1.10.0
196
+ * @static
197
+ *
198
+ * @see self::does_wp_load()
199
+ * @see \Boldgrid\Backup\Cli\Log::write()
200
+ *
201
+ * @todo More checks and login coming soon.
202
+ *
203
+ * @param bool $print Print status information. Defaults to TRUE.
204
+ * @return bool
205
+ */
206
+ public static function check( $print = true ) {
207
+ $status = self::does_wp_load();
208
+ $output = json_decode( self::$wp_test_result, true );
209
+ $message = 'Site Check: ' . ( $status ? 'Ok' : 'Failed' ) .
210
+ ( ! $status && is_array( $output ) ? ': ' . self::$wp_test_result : '' );
211
+ Log::write( $message, ( $status ? LOG_INFO : LOG_ERR ) );
212
+
213
+ if ( $print ) {
214
+ echo $message . PHP_EOL;
215
+ }
216
+
217
+ return $status;
218
+ }
219
+
220
+ /**
221
+ * Send a notification email message.
222
+ *
223
+ * @since 1.10.0
224
+ * @static
225
+ *
226
+ * @see \Boldgrid\Backup\Cli\Info::get_email_arg()
227
+ * @see \Boldgrid\Backup\Cli\Info::get_info()
228
+ * @see \Boldgrid\Backup\Cli\Log::write()
229
+ * @see \Boldgrid\Backup\Cli\Email::send()
230
+ *
231
+ * @return bool
232
+ */
233
+ public static function send_notification() {
234
+ $recipient = Info::get_info()['site_title'] . ' <' . Info::get_email_arg() . '>';
235
+ $subject = 'Failed Site Check for ' . Info::get_info()['siteurl'];
236
+ $message = "A Site Check has failed. You should check your site and can perform a manual restoration.\r\n\r\nFor help, please visit: https://www.boldgrid.com/support/boldgrid-backup/what-to-do-when-boldgrid-backup-site-check-fails/\r\n\r\nYou can manage notifications in your WordPress admin panel, under Total Upkeep Settings at:\r\n" .
237
+ Info::get_info()['siteurl'] .
238
+ "/wp-admin/admin.php?page=boldgrid-backup-settings\r\n";
239
+ Log::write( 'Sending email notification for failed site check to "' . $recipient . '".', LOG_INFO );
240
+
241
+ $result = json_decode( self::$wp_test_result, true );
242
+
243
+ if ( ! empty( $result['error']['message'] ) ) {
244
+ $message .= "\r\nError message:\r\n" . $result['error']['message'] . ' in ' . $result['error']['file'] . ' on line ' .
245
+ $result['error']['line'] . "\r\n";
246
+ }
247
+
248
+ echo 'Info: Sending notification email to "' . $recipient . '".' . PHP_EOL;
249
+ return ( new Email( $recipient ) )->send( $subject, $message );
250
+ }
251
+ }
cli/class-site-restore.php ADDED
@@ -0,0 +1,366 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File: class-site-restore.php
4
+ *
5
+ * Used when there is a severe issue with the site which requires immediate restoration from the
6
+ * latest backup archive. A restoration can be forced using the "restore" flag.
7
+ *
8
+ * @link https://www.boldgrid.com
9
+ * @since 1.9.0
10
+ *
11
+ * @package Boldgrid\Backup
12
+ * @subpackage Boldgrid\Backup\Cli
13
+ * @copyright BoldGrid
14
+ * @author BoldGrid <support@boldgrid.com>
15
+ *
16
+ * phpcs:disable WordPress.VIP,WordPress.XSS.EscapeOutput,WordPress.WP.AlternativeFunctions
17
+ */
18
+
19
+ namespace Boldgrid\Backup\Cli;
20
+
21
+ /**
22
+ * Class: Site_Restore.
23
+ *
24
+ * @since 1.9.0
25
+ */
26
+ class Site_Restore {
27
+ /**
28
+ * Run the restoration process.
29
+ *
30
+ * @since 1.9.0
31
+ *
32
+ * @see \Boldgrid\Backup\Cli\Log::write()
33
+ * @see \Boldgrid\Backup\Cli\Info::get_info()
34
+ * @see self::restore()
35
+ */
36
+ public function run() {
37
+ $message = 'Starting restoration process...';
38
+ Log::write( $message, LOG_INFO );
39
+ echo $message . PHP_EOL;
40
+
41
+ $message = 'Attempting to restore "' . Info::get_info()['siteurl'] .
42
+ '" from backup archive file "' . Info::get_info()['filepath'] . '"...';
43
+ echo $message . PHP_EOL;
44
+ Log::write( $message, LOG_INFO );
45
+
46
+ $success = $this->restore();
47
+
48
+ $message = ( $success ? 'Success.' : 'Error: Could not perform restoration.' );
49
+ Log::write( $message, ( $success ? LOG_INFO : LOG_ERR ) );
50
+ echo $message . PHP_EOL;
51
+ }
52
+
53
+ /**
54
+ * Ensure that archive file destinations are writable.
55
+ *
56
+ * @since 1.9.0
57
+ * @access private
58
+ *
59
+ * @see ZipArchive()
60
+ * @see \Boldgrid\Backup\Cli\Info::get_info()
61
+ * @see \Boldgrid\Backup\Cli\Log::write()
62
+ */
63
+ private function set_writable_permissions() {
64
+ if ( class_exists( 'ZipArchive' ) ) {
65
+ Log::write( 'Setting file permissions.', LOG_DEBUG );
66
+ $zip = new \ZipArchive();
67
+
68
+ if ( $zip->open( Info::get_info()['filepath'] ) ) {
69
+ for ( $i = 0; $i < $zip->numFiles; $i++ ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName
70
+ $data = $zip->statIndex( $i );
71
+
72
+ if ( ! empty( $data['name'] ) ) {
73
+ chmod( Info::get_info()['ABSPATH'] . $data['name'], 0644 );
74
+ }
75
+ }
76
+ }
77
+ }
78
+ }
79
+
80
+ /**
81
+ * Set the PHP timeout limit to at least 15 minutes.
82
+ *
83
+ * Various places within this class use to set the timeout limit to 300 seconds. This timeout
84
+ * limit has been increased to 900 seconds and moved into its own method.
85
+ *
86
+ * @since 1.9.0
87
+ * @access private
88
+ *
89
+ * @param int $time_limit Limit in seconds.
90
+ */
91
+ private function set_time_limit( $time_limit = 900 ) {
92
+ $max_execution_time = ini_get( 'max_execution_time' );
93
+ set_time_limit( $max_execution_time > $time_limit ? $max_execution_time : $time_limit );
94
+ }
95
+
96
+ /**
97
+ * Get database config from wp-config.php file.
98
+ *
99
+ * @since 1.9.0
100
+ * @access private
101
+ *
102
+ * @see \Boldgrid\Backup\Cli\Info::get_info()
103
+ *
104
+ * @return bool
105
+ */
106
+ private function get_db_config() {
107
+ $wpconfig = file_get_contents( Info::get_info()['ABSPATH'] . 'wp-config.php' );
108
+
109
+ if ( $wpconfig ) {
110
+ preg_match_all( '/define\(.+DB_(NAME|USER|PASSWORD|HOST).+\);/', $wpconfig, $matches1 );
111
+ foreach ( $matches1[0] as $match1 ) {
112
+ preg_match_all( '/\'(.+?)\'/', $match1, $matches2 );
113
+ if ( ! empty( $matches2[1] ) ) {
114
+ define( $matches2[1][0], $matches2[1][1] );
115
+ }
116
+ }
117
+ }
118
+
119
+ return defined( 'DB_NAME' ) && defined( 'DB_USER' ) && defined( 'DB_PASSWORD' ) && defined( 'DB_HOST' );
120
+ }
121
+
122
+ /**
123
+ * Perform restoration.
124
+ *
125
+ * @since 1.9.0
126
+ * @access private
127
+ *
128
+ * @see \Boldgrid\Backup\Cli\Info::get_info()
129
+ * @see \Boldgrid\Backup\Cli\Info::choose_method()
130
+ * @see \Boldgrid_Backup_Admin_Cli::call_command()
131
+ * @see self::set_time_limit()
132
+ * @see self::restore_files()
133
+ * @see self::restore_database()
134
+ * @see self::increment_restore_attempts()
135
+ * @see \Boldgrid\Backup\Cli\Log::write()
136
+ * @see self::cancel_rollback()
137
+ *
138
+ * @return bool;
139
+ */
140
+ private function restore() {
141
+ $restore_cmd = ! empty( Info::get_info()['restore_cmd'] ) ?
142
+ Info::get_info()['restore_cmd'] : null;
143
+
144
+ if ( 'ajax' === Info::choose_method() ) {
145
+ // Call the normal restore command.
146
+ $message = 'Using Ajax URL address restoration process...';
147
+ echo $message . PHP_EOL;
148
+ Log::write( $message, LOG_INFO );
149
+ \Boldgrid_Backup_Admin_Cli::call_command( $restore_cmd, $success, $return_var );
150
+ } else {
151
+ // Start the standalone restoration process.
152
+ $message = 'Using standalone restoration process...';
153
+ echo $message . PHP_EOL;
154
+ Log::write( $message, LOG_INFO );
155
+ ignore_user_abort( true );
156
+ $this->set_time_limit();
157
+ $success = $this->restore_files() && $this->restore_database();
158
+
159
+ $this->cancel_rollback();
160
+ }
161
+
162
+ $this->increment_restore_attempts();
163
+
164
+ return $success;
165
+ }
166
+
167
+ /**
168
+ * Perform restoration of files.
169
+ *
170
+ * @since 1.9.0
171
+ * @access private
172
+ *
173
+ * @see \Boldgrid\Backup\Cli\Info::get_info()
174
+ * @see \Boldgrid_Backup_Admin_Cli::call_command()
175
+ * @see \ZipArchive::open()
176
+ * @see \ZipArchive::extractTo()
177
+ * @see \PclZip::extract()
178
+ * @see \Boldgrid\Backup\Cli\Log::write()
179
+ *
180
+ * @return bool
181
+ */
182
+ private function restore_files() {
183
+ $success = false;
184
+ $info = Info::get_info();
185
+ $method = Info::choose_method();
186
+
187
+ switch ( true ) {
188
+ case ( ! $method || 'ziparchive' === $method ) && class_exists( 'ZipArchive' ):
189
+ $message = 'Attempting file restoration using PHP ZipArchive...';
190
+ echo $message . PHP_EOL;
191
+ Log::write( $message, LOG_INFO );
192
+ $archive = new \ZipArchive();
193
+ if ( true === $archive->open( $info['filepath'] ) ) {
194
+ $success = $archive->extractTo( $info['ABSPATH'] );
195
+ $archive->close();
196
+ }
197
+ break;
198
+
199
+ case ( ! $method || 'pclzip' === $method ) && file_exists( $info['ABSPATH'] . 'wp-admin/includes/class-pclzip.php' ):
200
+ $message = 'Attempting file restoration using PHP PCLZip...';
201
+ echo $message . PHP_EOL;
202
+ Log::write( $message, LOG_INFO );
203
+ require $info['ABSPATH'] . 'wp-admin/includes/class-pclzip.php';
204
+ $archive = new \PclZip( $info['filepath'] );
205
+ $result = $archive->extract(
206
+ PCLZIP_OPT_PATH,
207
+ $info['ABSPATH'],
208
+ PCLZIP_OPT_REPLACE_NEWER
209
+ );
210
+ $success = is_array( $result ) && ! empty( $result );
211
+ if ( ! $success ) {
212
+ echo 'Error: ' . $archive->errorInfo( true ) . PHP_EOL;
213
+ }
214
+ break;
215
+
216
+ case ( ! $method || 'cli' === $method ) && ( \Boldgrid_Backup_Admin_Cli::call_command( 'unzip', $success, $return_var ) || $success || 0 === $return_var ):
217
+ $message = 'Attempting file restoration using unzip (CLI)...';
218
+ echo $message . PHP_EOL;
219
+ Log::write( $message, LOG_INFO );
220
+ $cmd = 'cd ' . $info['ABSPATH'] . ';unzip -oqq ' . $info['filepath'];
221
+ \Boldgrid_Backup_Admin_Cli::call_command(
222
+ $cmd,
223
+ $success,
224
+ $return_var
225
+ );
226
+
227
+ echo 'Checking/fixing permissions...' . PHP_EOL;
228
+ // Assuming Linux.
229
+ $cmd = 'for i in $(unzip -Z1 ' . $info['filepath'] .
230
+ ' | sed -e "/^\.\/$/d" -e "s~/$~~"); do test -d "$i" && chmod 755 "$i";test -f "$i" && chmod 644 "$i"; done';
231
+ \Boldgrid_Backup_Admin_Cli::call_command(
232
+ $cmd,
233
+ $success2,
234
+ $return_var2
235
+ );
236
+
237
+ break;
238
+
239
+ default:
240
+ $message = 'Error: Could not extract files; ZipArchive, PCLZip, and unzip (CLI) unavailable.';
241
+ echo $message . PHP_EOL;
242
+ Log::write( $message, LOG_ERR );
243
+ break;
244
+ }
245
+
246
+ $message = ( $success ? 'Success.' : 'Failed.' );
247
+ Log::write( $message, ( $success ? LOG_INFO : LOG_ERR ) );
248
+ echo $message . PHP_EOL;
249
+
250
+ return $success;
251
+ }
252
+
253
+ /**
254
+ * Perform restoration of database.
255
+ *
256
+ * @since 1.9.0
257
+ * @access private
258
+ *
259
+ * @see \Boldgrid\Backup\Cli\Info::get_info()
260
+ * @see self::get_db_config()
261
+ * @see \Boldgrid_Backup_Admin_Db_Import::import()
262
+ * @see \Boldgrid_Backup_Admin_Cli::call_command()
263
+ * @see \Boldgrid\Backup\Cli\Log::write()
264
+ *
265
+ * @return bool;
266
+ */
267
+ private function restore_database() {
268
+ $info = Info::get_info();
269
+
270
+ if ( ! file_exists( $info['db_filepath'] ) ) {
271
+ $message = 'Error: Database dump file "' . $info['db_filepath'] . '" does not exist.';
272
+ echo $message . PHP_EOL;
273
+ Log::write( $message, LOG_ERR );
274
+ $success = false;
275
+ } else {
276
+ $success = $this->get_db_config();
277
+ }
278
+
279
+ switch ( true ) {
280
+ case ! $success:
281
+ $message = 'Error: Could not get database credentials from "' . $info['ABSPATH'] .
282
+ 'wp-config.php".';
283
+ echo $message . PHP_EOL;
284
+ Log::write( $message, LOG_ERR );
285
+ break;
286
+
287
+ case class_exists( 'PDO' ):
288
+ $message = 'Attempting to restore database using PHP PDO...';
289
+ echo $message . PHP_EOL;
290
+ Log::write( $message, LOG_INFO );
291
+ require dirname( __DIR__ ) . '/admin/class-boldgrid-backup-admin-db-import.php';
292
+ $importer = new \Boldgrid_Backup_Admin_Db_Import();
293
+ $success = $importer->import( $info['ABSPATH'] . $info['db_filename'] );
294
+
295
+ if ( ! $success ) {
296
+ $message = 'Error: Could not import database (using PDO).';
297
+ echo $message . PHP_EOL;
298
+ Log::write( $message, LOG_ERR );
299
+ }
300
+ break;
301
+
302
+ case \Boldgrid_Backup_Admin_Cli::call_command( 'mysql -V', $success, $return_var ) || $success || 0 === $return_var:
303
+ $message = 'Attempting to restore database using mysql client (CLI)...';
304
+ echo $message . PHP_EOL;
305
+ Log::write( $message, LOG_INFO );
306
+ $cmd = 'mysql -h ' . DB_HOST . ' -p' . DB_PASSWORD . ' -u ' . DB_USER . ' ' .
307
+ DB_NAME . ' < "' . $info['db_filepath'] . '"';
308
+ \Boldgrid_Backup_Admin_Cli::call_command( $cmd, $success, $return_var );
309
+
310
+ if ( ! $success ) {
311
+ $message = 'Error: Could not import database (using mysql client).';
312
+ echo $message . PHP_EOL;
313
+ Log::write( $message, LOG_ERR );
314
+ }
315
+ break;
316
+
317
+ default:
318
+ $message = 'Error: Could not import database; PDO and mysql client (CLI) unavailable.';
319
+ echo $message . PHP_EOL;
320
+ Log::write( $message, LOG_ERR );
321
+ $success = false;
322
+ break;
323
+ }
324
+
325
+ return $success;
326
+ }
327
+
328
+ /**
329
+ * Increment restore attemps counter and update results file.
330
+ *
331
+ * @since 1.9.0
332
+ * @access private
333
+ *
334
+ * @see \Boldgrid\Backup\Cli\Info::get_results_filepath()
335
+ * @see \Boldgrid\Backup\Cli\Info::set_info_item()
336
+ */
337
+ private function increment_restore_attempts() {
338
+ $results_filepath = Info::get_results_filepath();
339
+
340
+ if ( file_exists( $results_filepath ) && is_readable( $results_filepath ) ) {
341
+ $results = json_decode( file_get_contents( $results_filepath ), true );
342
+
343
+ $results['restore_attempts'] = isset( $results['restore_attempts'] ) ?
344
+ ++$results['restore_attempts'] : 1;
345
+
346
+ file_put_contents( $results_filepath, json_encode( $results ) );
347
+
348
+ Info::set_info_item( 'restore_attempts', $results['restore_attempts'] );
349
+ }
350
+ }
351
+
352
+ /**
353
+ * Cancel any rollback scheduled.
354
+ *
355
+ * @since 1.10.7
356
+ * @access private
357
+ *
358
+ * @see \Boldgrid\Backup\Cli\Info::get_arg_value()
359
+ */
360
+ private function cancel_rollback() {
361
+ require_once dirname( dirname( __FILE__ ) ) . '/cron/class-boldgrid-backup-url-helper.php';
362
+ $url = Info::get_info()['siteurl'] . '/wp-admin/admin-ajax.php?action=boldgrid_cli_cancel_rollback&backup_id=' .
363
+ Info::get_arg_value( 'backup_id' );
364
+ $success = ( new \Boldgrid_Backup_Url_Helper() )->call_url( $url, $status, $errorno, $error );
365
+ }
366
+ }
cli/env-info.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File: env-info.php
4
+ *
5
+ * @link https://www.boldgrid.com
6
+ * @since 1.8.0
7
+ *
8
+ * @package Boldgrid_Backup
9
+ * @subpackage Boldgrid_Backup/Cli
10
+ * @copyright BoldGrid
11
+ * @author BoldGrid <support@boldgrid.com>
12
+ *
13
+ * phpcs:disable WordPress.WP.AlternativeFunctions
14
+ */
15
+
16
+ echo json_encode( array(
17
+ 'gateway_interface' => getenv( 'GATEWAY_INTERFACE' ),
18
+ 'http_host' => getenv( 'HTTP_HOST' ),
19
+ 'php_sapi_name' => php_sapi_name(),
20
+ 'php_uname' => php_uname(),
21
+ 'php_version' => phpversion(),
22
+ 'server_addr' => getenv( 'SERVER_ADDR' ) ? getenv( 'SERVER_ADDR' ) : getenv( 'LOCAL_ADDR' ),
23
+ 'server_name' => getenv( 'SERVER_NAME' ),
24
+ 'server_protocol' => getenv( 'SERVER_PROTOCOL' ),
25
+ 'server_software' => getenv( 'SERVER_SOFTWARE' ),
26
+ 'uid' => getmyuid(),
27
+ 'username' => get_current_user(),
28
+ ) );
cli/wp-test.php ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * File: wp-test.php
4
+ *
5
+ * Tests if WordPress loads.
6
+ *
7
+ * @link https://www.boldgrid.com
8
+ * @link https://github.com/BoldGrid/boldgrid-backup/wiki/Restorations-outside-of-WordPress
9
+ * @since 1.10.0
10
+ *
11
+ * @package Boldgrid_Backup
12
+ * @subpackage Boldgrid_Backup\Cli
13
+ * @copyright BoldGrid
14
+ * @author BoldGrid <support@boldgrid.com>
15
+ *
16
+ * phpcs:disable WordPress.WP.AlternativeFunctions,WordPress.PHP.DevelopmentFunctions
17
+ */
18
+
19
+ use Boldgrid\Backup\Cli\Info;
20
+
21
+ // Track if there was an exception. This is not the greatest idea, but works for now.
22
+ $had_exception = false;
23
+
24
+ /**
25
+ * Clean (erase) the output buffer and turn off output buffering for all levels.
26
+ *
27
+ * @since 1.10.0
28
+ */
29
+ function ob_clean_all() {
30
+ while ( ob_get_level() > 0 ) {
31
+ ob_end_clean();
32
+ }
33
+ }
34
+
35
+ /**
36
+ * Handle fatal errors on PHP shutdown.
37
+ *
38
+ * @since 1.10.0
39
+ *
40
+ * @link https://www.php.net/manual/en/errorfunc.constants.php
41
+ */
42
+ function handle_shutdown() {
43
+ global $had_exception;
44
+
45
+ $error = error_get_last();
46
+ $error_nums = [
47
+ 1, // E_ERROR.
48
+ 4, // E_PARSE.
49
+ 64, // E_COMPILE_ERROR.
50
+ 256, // E_USER_ERROR.
51
+ ];
52
+
53
+ if ( ! empty( $error['type'] ) && in_array( $error['type'], $error_nums, true ) ) {
54
+ ob_clean_all();
55
+ echo json_encode( [
56
+ 'success' => false,
57
+ 'error' => $error,
58
+ ] );
59
+ exit( 255 );
60
+ } elseif ( ! $had_exception && null === $error ) {
61
+ // Success.
62
+ ob_clean_all();
63
+ echo json_encode( [ 'success' => true ] );
64
+ exit( 0 );
65
+ }
66
+ }
67
+
68
+ register_shutdown_function( 'handle_shutdown' );
69
+
70
+ require __DIR__ . '/class-info.php';
71
+
72
+ $get_results_filepath = Info::get_results_filepath();
73
+ $info = Info::read_json_file( $get_results_filepath );
74
+
75
+ if ( empty( $info['ABSPATH'] ) ) {
76
+ echo json_encode( [
77
+ 'type' => 256,
78
+ 'message' => 'Error: Could not retrieve ABSPATH from "' . $get_results_filepath . '".',
79
+ 'file' => __FILE__,
80
+ 'line' => __LINE__,
81
+ ] );
82
+ exit( 1 );
83
+ }
84
+
85
+ // Start output buffering.
86
+ ob_start();
87
+
88
+ // Change to the WordPress ABSPATH (root/installation) directory.
89
+ chdir( $info['ABSPATH'] );
90
+
91
+ // Disable WP Cron for the tests.
92
+ defined( 'DISABLE_WP_CRON' ) || define( 'DISABLE_WP_CRON', true );
93
+
94
+ // Test loading WordPress front-end.
95
+ try {
96
+ require 'wp-load.php';
97
+ } catch ( Exception $e ) {
98
+ $had_exception = true;
99
+ ob_clean_all();
100
+ echo json_encode( [
101
+ 'success' => false,
102
+ 'message' => 'Could not load the WordPress site front-end. Exception message: "' .
103
+ $e->getMessage() . '" (File: "' . $e->getFile() . '" Line: "' . $e->getLine() . '")',
104
+ 'debug_backtrace' => debug_backtrace( 0 ),
105
+ ] );
106
+ exit( 1 );
107
+ }
108
+
109
+ // Test loading WordPress admin back-end.
110
+ $test_uri = 'wp-admin/admin-ajax.php';
111
+ $url_parts = parse_url( $info['siteurl'] );
112
+ $_SERVER['HTTP_HOST'] = $url_parts['host'];
113
+ $_SERVER['SERVER_PROTOCOL'] = $url_parts['scheme'];
114
+ $_SERVER['PHP_SELF'] = ( ! empty( $url_parts['path'] ) ? $url_parts['path'] : '' ) . '/' . $test_uri;
115
+ $_SERVER['REQUEST_METHOD'] = 'GET';
116
+ $_SERVER['SERVER_NAME'] = '';
117
+ $_SERVER['SERVER_PORT'] = 'https' === $url_parts['scheme'] ? '443' : '80';
118
+
119
+ try {
120
+ require $test_uri;
121
+ } catch ( Exception $e ) {
122
+ $had_exception = true;
123
+ ob_clean_all();
124
+ echo json_encode( [
125
+ 'success' => false,
126
+ 'message' => 'Could not load the WordPress admin back-end. Exception message: "' .
127
+ $e->getMessage() . '" (File: "' . $e->getFile() . '" Line: "' . $e->getLine() . '")',
128
+ 'debug_backtrace' => debug_backtrace( 0 ),
129
+ ] );
130
+ exit( 1 );
131
+ }
coverage.xml ADDED
@@ -0,0 +1,94369 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <coverage generated="1591729540">
3
+ <project timestamp="1591729540">
4
+ <package name="Boldgrid\Backup\Admin\Card">
5
+ <file name="/home/travis/build/BoldGrid/boldgrid-backup/admin/card/class-amazon-s3.php">
6
+ <class name="Amazon_S3" namespace="Boldgrid\Backup\Admin\Card" fullPackage="Amazon">
7
+ <metrics complexity="1" methods="1" coveredmethods="1" conditionals="0" coveredconditionals="0" statements="14" coveredstatements="14" elements="15" coveredelements="15"/>
8
+ </class>
9
+ <line num="29" type="method" name="init" visibility="public" complexity="1" crap="1" count="1"/>
10
+ <line num="30" type="stmt" count="1"/>
11
+ <line num="32" type="stmt" count="1"/>
12
+ <line num="34" type="stmt" count="1"/>
13
+ <line num="36" type="stmt" count="1"/>
14
+ <line num="37" type="stmt" count="1"/>
15
+ <line num="38" type="stmt" count="1"/>
16
+ <line num="39" type="stmt" count="1"/>
17
+ <line num="41" type="stmt" count="1"/>
18
+ <line num="43" type="stmt" count="1"/>
19
+ <line num="44" type="stmt" count="1"/>
20
+ <line num="45" type="stmt" count="1"/>
21
+ <line num="46" type="stmt" count="1"/>
22
+ <line num="48" type="stmt" count="1"/>
23
+ <line num="49" type="stmt" count="1"/>
24
+ <metrics loc="50" ncloc="27" classes="1" methods="1" coveredmethods="1" conditionals="0" coveredconditionals="0" statements="14" coveredstatements="14" elements="15" coveredelements="15"/>
25
+ </file>
26
+ <file name="/home/travis/build/BoldGrid/boldgrid-backup/admin/card/class-backups.php">
27
+ <class name="Backups" namespace="Boldgrid\Backup\Admin\Card">
28
+ <metrics complexity="2" methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="12" coveredstatements="0" elements="13" coveredelements="0"/>
29
+ </class>
30
+ <line num="29" type="method" name="init" visibility="public" complexity="2" crap="6" count="0"/>
31
+ <line num="30" type="stmt" count="0"/>
32
+ <line num="32" type="stmt" count="0"/>
33
+ <line num="34" type="stmt" count="0"/>
34
+ <line num="36" type="stmt" count="0"/>
35
+ <line num="38" type="stmt" count="0"/>
36
+ <line num="39" type="stmt" count="0"/>
37
+ <line num="40" type="stmt" count="0"/>
38
+ <line num="41" type="stmt" count="0"/>
39
+ <line num="42" type="stmt" count="0"/>
40
+ <line num="43" type="stmt" count="0"/>
41
+ <line num="44" type="stmt" count="0"/>
42
+ <line num="45" type="stmt" count="0"/>
43
+ <metrics loc="46" ncloc="21" classes="1" methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="12" coveredstatements="0" elements="13" coveredelements="0"/>
44
+ </file>
45
+ <file name="/home/travis/build/BoldGrid/boldgrid-backup/admin/card/class-database-encryption.php">
46
+ <class name="Database_Encryption" namespace="Boldgrid\Backup\Admin\Card" fullPackage="Database">
47
+ <metrics complexity="1" methods="1" coveredmethods="1" conditionals="0" coveredconditionals="0" statements="14" coveredstatements="14" elements="15" coveredelements="15"/>
48
+ </class>
49
+ <line num="29" type="method" name="init" visibility="public" complexity="1" crap="1" count="1"/>
50
+ <line num="30" type="stmt" count="1"/>
51
+ <line num="32" type="stmt" count="1"/>
52
+ <line num="34" type="stmt" count="1"/>
53
+ <line num="36" type="stmt" count="1"/>
54
+ <line num="37" type="stmt" count="1"/>
55
+ <line num="38" type="stmt" count="1"/>
56
+ <line num="39" type="stmt" count="1"/>
57
+ <line num="41" type="stmt" count="1"/>
58
+ <line num="43" type="stmt" count="1"/>
59
+ <line num="44" type="stmt" count="1"/>
60
+ <line num="45" type="stmt" count="1"/>
61
+ <line num="46" type="stmt" count="1"/>
62
+ <line num="48" type="stmt" count="1"/>
63
+ <line num="49" type="stmt" count="1"/>
64
+ <metrics loc="50" ncloc="27" classes="1" methods="1" coveredmethods="1" conditionals="0" coveredconditionals="0" statements="14" coveredstatements="14" elements="15" coveredelements="15"/>
65
+ </file>
66
+ <file name="/home/travis/build/BoldGrid/boldgrid-backup/admin/card/class-dream-objects.php">
67
+ <class name="Dream_Objects" namespace="Boldgrid\Backup\Admin\Card" fullPackage="Dream">
68
+ <metrics complexity="1" methods="1" coveredmethods="1" conditionals="0" coveredconditionals="0" statements="14" coveredstatements="14" elements="15" coveredelements="15"/>
69
+ </class>
70
+ <line num="30" type="method" name="init" visibility="public" complexity="1" crap="1" count="1"/>
71
+ <line num="31" type="stmt" count="1"/>
72
+ <line num="33" type="stmt" count="1"/>
73
+ <line num="35" type="stmt" count="1"/>
74
+ <line num="37" type="stmt" count="1"/>
75
+ <line num="38" type="stmt" count="1"/>
76
+ <line num="39" type="stmt" count="1"/>
77
+ <line num="40" type="stmt" count="1"/>
78
+ <line num="42" type="stmt" count="1"/>
79
+ <line num="44" type="stmt" count="1"/>
80
+ <line num="45" type="stmt" count="1"/>
81
+ <line num="46" type="stmt" count="1"/>
82
+ <line num="47" type="stmt" count="1"/>
83
+ <line num="49" type="stmt" count="1"/>
84
+ <line num="50" type="stmt" count="1"/>
85
+ <metrics loc="51" ncloc="27" classes="1" methods="1" coveredmethods="1" conditionals="0" coveredconditionals="0" statements="14" coveredstatements="14" elements="15" coveredelements="15"/>
86
+ </file>
87
+ <file name="/home/travis/build/BoldGrid/boldgrid-backup/admin/card/class-find-modified-files.php">
88
+ <class name="Find_Modified_Files" namespace="Boldgrid\Backup\Admin\Card" fullPackage="Find.Modified">
89
+ <metrics complexity="1" methods="1" coveredmethods="1" conditionals="0" coveredconditionals="0" statements="9" coveredstatements="9" elements="10" coveredelements="10"/>
90
+ </class>
91
+ <line num="27" type="method" name="init" visibility="public" complexity="1" crap="1" count="1"/>
92
+ <line num="28" type="stmt" count="1"/>
93
+ <line num="30" type="stmt" count="1"/>
94
+ <line num="32" type="stmt" count="1"/>
95
+ <line num="34" type="stmt" count="1"/>
96
+ <line num="36" type="stmt" count="1"/>
97
+ <line num="37" type="stmt" count="1"/>
98
+ <line num="38" type="stmt" count="1"/>
99
+ <line num="39" type="stmt" count="1"/>
100
+ <line num="40" type="stmt" count="1"/>
101
+ <metrics loc="41" ncloc="20" classes="1" methods="1" coveredmethods="1" conditionals="0" coveredconditionals="0" statements="9" coveredstatements="9" elements="10" coveredelements="10"/>
102
+ </file>
103
+ <file name="/home/travis/build/BoldGrid/boldgrid-backup/admin/card/class-google-drive.php">
104
+ <class name="Google_Drive" namespace="Boldgrid\Backup\Admin\Card" fullPackage="Google">
105
+ <metrics complexity="1" methods="1" coveredmethods="1" conditionals="0" coveredconditionals="0" statements="14" coveredstatements="14" elements="15" coveredelements="15"/>
106
+ </class>
107
+ <line num="30" type="method" name="init" visibility="public" complexity="1" crap="1" count="1"/>
108
+ <line num="31" type="stmt" count="1"/>
109
+ <line num="33" type="stmt" count="1"/>
110
+ <line num="35" type="stmt" count="1"/>
111
+ <line num="37" type="stmt" count="1"/>
112
+ <line num="39" type="stmt" count="1"/>
113
+ <line num="40" type="stmt" count="1"/>
114
+ <line num="41" type="stmt" count="1"/>
115
+ <line num="42" type="stmt" count="1"/>
116
+ <line num="44" type="stmt" count="1"/>
117
+ <line num="46" type="stmt" count="1"/>
118
+ <line num="47" type="stmt" count="1"/>
119
+ <line num="48" type="stmt" count="1"/>
120
+ <line num="49" type="stmt" count="1"/>
121
+ <line num="50" type="stmt" count="1"/>
122
+ <metrics loc="51" ncloc="27" classes="1" methods="1" coveredmethods="1" conditionals="0" coveredconditionals="0" statements="14" coveredstatements="14" elements="15" coveredelements="15"/>
123
+ </file>
124
+ <file name="/home/travis/build/BoldGrid/boldgrid-backup/admin/card/class-historical-versions.php">
125
+ <class name="Historical_Versions" namespace="Boldgrid\Backup\Admin\Card" fullPackage="Historical">
126
+ <metrics complexity="1" methods="1" coveredmethods="1" conditionals="0" coveredconditionals="0" statements="14" coveredstatements="14" elements="15" coveredelements="15"/>
127
+ </class>
128
+ <line num="30" type="method" name="init" visibility="public" complexity="1" crap="1" count="1"/>
129
+ <line num="31" type="stmt" count="1"/>
130
+ <line num="33" type="stmt" count="1"/>
131
+ <line num="35" type="stmt" count="1"/>
132
+ <line num="37" type="stmt" count="1"/>
133
+ <line num="39" type="stmt" count="1"/>
134
+ <line num="40" type="stmt" count="1"/>
135
+ <line num="41" type="stmt" count="1"/>
136
+ <line num="42" type="stmt" count="1"/>
137
+ <line num="44" type="stmt" count="1"/>
138
+ <line num="46" type="stmt" count="1"/>
139
+ <line num="47" type="stmt" count="1"/>
140
+ <line num="48" type="stmt" count="1"/>
141
+ <line num="49" type="stmt" count="1"/>
142
+ <line num="50" type="stmt" count="1"/>
143
+ <metrics loc="51" ncloc="27" classes="1" methods="1" coveredmethods="1" conditionals="0" coveredconditionals="0" statements="14" coveredstatements="14" elements="15" coveredelements="15"/>
144
+ </file>
145
+ <file name="/home/travis/build/BoldGrid/boldgrid-backup/admin/card/class-history.php">
146
+ <class name="History" namespace="Boldgrid\Backup\Admin\Card">
147
+ <metrics complexity="1" methods="1" coveredmethods="1" conditionals="0" coveredconditionals="0" statements="14" coveredstatements="14" elements="15" coveredelements="15"/>
148
+ </class>
149
+ <line num="30" type="method" name="init" visibility="public" complexity="1" crap="1" count="1"/>
150
+ <line num="31" type="stmt" count="1"/>
151
+ <line num="33" type="stmt" count="1"/>
152
+ <line num="35" type="stmt" count="1"/>
153
+ <line num="37" type="stmt" count="1"/>
154
+ <line num="39" type="stmt" count="1"/>
155
+ <line num="40" type="stmt" count="1"/>
156
+ <line num="41" type="stmt" count="1"/>
157
+ <line num="42" type="stmt" count="1"/>
158
+ <line num="44" type="stmt" count="1"/>
159
+ <line num="46" type="stmt" count="1"/>
160
+ <line num="47" type="stmt" count="1"/>
161
+ <line num="48" type="stmt" count="1"/>
162
+ <line num="49" type="stmt" count="1"/>
163
+ <line num="50" type="stmt" count="1"/>
164
+ <metrics loc="51" ncloc="27" classes="1" methods="1" coveredmethods="1" conditionals="0" coveredconditionals="0" statements="14" coveredstatements="14" elements="15" coveredelements="15"/>
165
+ </file>
166
+ <file name="/home/travis/build/BoldGrid/boldgrid-backup/admin/card/class-one-click-restoration.php">
167
+ <class name="One_Click_Restoration" namespace="Boldgrid\Backup\Admin\Card" fullPackage="One.Click">
168
+ <metrics complexity="1" methods="1" coveredmethods="1" conditionals="0" coveredconditionals="0" statements="14" coveredstatements="14" elements="15" coveredelements="15"/>
169
+ </class>
170
+ <line num="30" type="method" name="init" visibility="public" complexity="1" crap="1" count="1"/>
171
+ <line num="31" type="stmt" count="1"/>
172
+ <line num="33" type="stmt" count="1"/>
173
+ <line num="35" type="stmt" count="1"/>
174
+ <line num="37" type="stmt" count="1"/>
175
+ <line num="39" type="stmt" count="1"/>
176
+ <line num="40" type="stmt" count="1"/>
177
+ <line num="41" type="stmt" count="1"/>
178
+ <line num="42" type="stmt" count="1"/>
179
+ <line num="44" type="stmt" count="1"/>
180
+ <line num="46" type="stmt" count="1"/>
181
+ <line num="47" type="stmt" count="1"/>
182
+ <line num="48" type="stmt" count="1"/>
183
+ <line num="49" type="stmt" count="1"/>
184
+ <line num="50" type="stmt" count="1"/>
185
+ <metrics loc="51" ncloc="27" classes="1" methods="1" coveredmethods="1" conditionals="0" coveredconditionals="0" statements="14" coveredstatements="14" elements="15" coveredelements="15"/>
186
+ </file>
187
+ <file name="/home/travis/build/BoldGrid/boldgrid-backup/admin/card/class-plugin-editor-tools.php">
188
+ <class name="Plugin_Editor_Tools" namespace="Boldgrid\Backup\Admin\Card" fullPackage="Plugin.Editor">
189
+ <metrics complexity="1" methods="1" coveredmethods="1" conditionals="0" coveredconditionals="0" statements="14" coveredstatements="14" elements="15" coveredelements="15"/>
190
+ </class>
191
+ <line num="30" type="method" name="init" visibility="public" complexity="1" crap="1" count="1"/>
192
+ <line num="31" type="stmt" count="1"/>
193
+ <line num="33" type="stmt" count="1"/>
194
+ <line num="35" type="stmt" count="1"/>
195
+ <line num="37" type="stmt" count="1"/>
196
+ <line num="39" type="stmt" count="1"/>
197
+ <line num="40" type="stmt" count="1"/>
198
+ <line num="41" type="stmt" count="1"/>
199
+ <line num="42" type="stmt" count="1"/>
200
+ <line num="44" type="stmt" count="1"/>
201
+ <line num="46" type="stmt" count="1"/>
202
+ <line num="47" type="stmt" count="1"/>
203
+ <line num="48" type="stmt" count="1"/>
204
+ <line num="49" type="stmt" count="1"/>
205
+ <line num="50" type="stmt" count="1"/>
206
+ <metrics loc="51" ncloc="27" classes="1" methods="1" coveredmethods="1" conditionals="0" coveredconditionals="0" statements="14" coveredstatements="14" elements="15" coveredelements="15"/>
207
+ </file>
208
+ <file name="/home/travis/build/BoldGrid/boldgrid-backup/admin/card/class-premium.php">
209
+ <class name="Premium" namespace="Boldgrid\Backup\Admin\Card">
210
+ <metrics complexity="3" methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="29" coveredstatements="0" elements="30" coveredelements="0"/>
211
+ </class>
212
+ <line num="29" type="method" name="init" visibility="public" complexity="3" crap="12" count="0"/>
213
+ <line num="30" type="stmt" count="0"/>
214
+ <line num="32" type="stmt" count="0"/>
215
+ <line num="34" type="stmt" count="0"/>
216
+ <line num="36" type="stmt" count="0"/>
217
+ <line num="38" type="stmt" count="0"/>
218
+ <line num="40" type="stmt" count="0"/>
219
+ <line num="41" type="stmt" count="0"/>
220
+ <line num="43" type="stmt" count="0"/>
221
+ <line num="45" type="stmt" count="0"/>
222
+ <line num="46" type="stmt" count="0"/>
223
+ <line num="47" type="stmt" count="0"/>
224
+ <line num="48" type="stmt" count="0"/>
225
+ <line num="49" type="stmt" count="0"/>
226
+ <line num="50" type="stmt" count="0"/>
227
+ <line num="51" type="stmt" count="0"/>
228
+ <line num="53" type="stmt" count="0"/>
229
+ <line num="55" type="stmt" count="0"/>
230
+ <line num="56" type="stmt" count="0"/>
231
+ <line num="57" type="stmt" count="0"/>
232
+ <line num="58" type="stmt" count="0"/>
233
+ <line num="59" type="stmt" count="0"/>
234
+ <line num="60" type="stmt" count="0"/>
235
+ <line num="61" type="stmt" count="0"/>
236
+ <line num="63" type="stmt" count="0"/>
237
+ <line num="65" type="stmt" count="0"/>
238
+ <line num="66" type="stmt" count="0"/>
239
+ <line num="67" type="stmt" count="0"/>
240
+ <line num="68" type="stmt" count="0"/>
241
+ <line num="69" type="stmt" count="0"/>
242
+ <metrics loc="70" ncloc="39" classes="1" methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="29" coveredstatements="0" elements="30" coveredelements="0"/>
243
+ </file>
244
+ <file name="/home/travis/build/BoldGrid/boldgrid-backup/admin/card/class-updates.php">
245
+ <class name="Updates" namespace="Boldgrid\Backup\Admin\Card">
246
+ <metrics complexity="1" methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="10" coveredstatements="0" elements="11" coveredelements="0"/>
247
+ </class>
248
+ <line num="29" type="method" name="init" visibility="public" complexity="1" crap="2" count="0"/>
249
+ <line num="30" type="stmt" count="0"/>
250
+ <line num="32" type="stmt" count="0"/>
251
+ <line num="34" type="stmt" count="0"/>
252
+ <line num="36" type="stmt" count="0"/>
253
+ <line num="38" type="stmt" count="0"/>
254
+ <line num="39" type="stmt" count="0"/>
255
+ <line num="40" type="stmt" count="0"/>
256
+ <line num="41" type="stmt" count="0"/>
257
+ <line num="42" type="stmt" count="0"/>
258
+ <line num="43" type="stmt" count="0"/>
259
+ <metrics loc="44" ncloc="19" classes="1" methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="10" coveredstatements="0" elements="11" coveredelements="0"/>
260
+ </file>
261
+ </package>
262
+ <package name="Boldgrid\Backup\Admin\Card\Feature">
263
+ <file name="/home/travis/build/BoldGrid/boldgrid-backup/admin/card/feature/class-auto-rollback.php">
264
+ <class name="Auto_Rollback" namespace="Boldgrid\Backup\Admin\Card\Feature" fullPackage="Auto">
265
+ <metrics complexity="2" methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="18" coveredstatements="0" elements="19" coveredelements="0"/>
266
+ </class>
267
+ <line num="29" type="method" name="init" visibility="public" complexity="2" crap="6" count="0"/>
268
+ <line num="30" type="stmt" count="0"/>
269
+ <line num="32" type="stmt" count="0"/>
270
+ <line num="34" type="stmt" count="0"/>
271
+ <line num="36" type="stmt" count="0"/>
272
+ <line num="37" type="stmt" count="0"/>
273
+ <line num="38" type="stmt" count="0"/>
274
+ <line num="39" type="stmt" count="0"/>
275
+ <line num="40" type="stmt" count="0"/>
276
+ <line num="41" type="stmt" count="0"/>
277
+ <line num="42" type="stmt" count="0"/>
278
+ <line num="44" type="stmt" count="0"/>
279
+ <line num="45" type="stmt" count="0"/>
280
+ <line num="46" type="stmt" count="0"/>
281
+ <line num="47" type="stmt" count="0"/>
282
+ <line num="48" type="stmt" count="0"/>
283
+ <line num="49" type="stmt" count="0"/>
284
+ <line num="50" type="stmt" count="0"/>
285
+ <line num="51" type="stmt" count="0"/>
286
+ <metrics loc="52" ncloc="27" classes="1" methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="18" coveredstatements="0" elements="19" coveredelements="0"/>
287
+ </file>
288
+ <file name="/home/travis/build/BoldGrid/boldgrid-backup/admin/card/feature/class-auto-update-backup.php">
289
+ <class name="Auto_Update_Backup" namespace="Boldgrid\Backup\Admin\Card\Feature" fullPackage="Auto.Update">
290
+ <metrics complexity="2" methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="19" coveredstatements="0" elements="20" coveredelements="0"/>
291
+ </class>
292
+ <line num="30" type="method" name="init" visibility="public" complexity="2" crap="6" count="0"/>
293
+ <line num="31" type="stmt" count="0"/>
294
+ <line num="33" type="stmt" count="0"/>
295
+ <line num="35" type="stmt" count="0"/>
296
+ <line num="38" type="stmt" count="0"/>
297
+ <line num="39" type="stmt" count="0"/>
298
+ <line num="41" type="stmt" count="0"/>
299
+ <line num="42" type="stmt" count="0"/>
300
+ <line num="43" type="stmt" count="0"/>
301
+ <line num="44" type="stmt" count="0"/>
302
+ <line num="45" type="stmt" count="0"/>
303
+ <line num="46" type="stmt" count="0"/>
304
+ <line num="48" type="stmt" count="0"/>
305
+ <line num="49" type="stmt" count="0"/>
306
+ <line num="50" type="stmt" count="0"/>
307
+ <line num="51" type="stmt" count="0"/>
308
+ <line num="52" type="stmt" count="0"/>
309
+ <line num="53" type="stmt" count="0"/>
310
+ <line num="54" type="stmt" count="0"/>
311
+ <line num="55" type="stmt" count="0"/>
312
+ <metrics loc="56" ncloc="28" classes="1" methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="19" coveredstatements="0" elements="20" coveredelements="0"/>
313
+ </file>
314
+ <file name="/home/travis/build/BoldGrid/boldgrid-backup/admin/card/feature/class-central.php">
315
+ <class name="Central" namespace="Boldgrid\Backup\Admin\Card\Feature">
316
+ <metrics complexity="1" methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="6" coveredstatements="0" elements="7" coveredelements="0"/>
317
+ </class>
318
+ <line num="29" type="method" name="init" visibility="public" complexity="1" crap="2" count="0"/>
319
+ <line num="30" type="stmt" count="0"/>
320
+ <line num="32" type="stmt" count="0"/>
321
+ <line num="34" type="stmt" count="0"/>
322
+ <line num="36" type="stmt" count="0"/>
323
+ <line num="38" type="stmt" count="0"/>
324
+ <line num="39" type="stmt" count="0"/>
325
+ <metrics loc="40" ncloc="15" classes="1" methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="6" coveredstatements="0" elements="7" coveredelements="0"/>
326
+ </file>
327
+ <file name="/home/travis/build/BoldGrid/boldgrid-backup/admin/card/feature/class-cloud-wordpress.php">
328
+ <class name="Cloud_Wordpress" namespace="Boldgrid\Backup\Admin\Card\Feature" fullPackage="Cloud">
329
+ <metrics complexity="1" methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="4" coveredstatements="0" elements="5" coveredelements="0"/>
330
+ </class>
331
+ <line num="27" type="method" name="init" visibility="public" complexity="1" crap="2" count="0"/>
332
+ <line num="28" type="stmt" count="0"/>
333
+ <line num="30" type="stmt" count="0"/>
334
+ <line num="32" type="stmt" count="0"/>
335
+ <line num="33" type="stmt" count="0"/>
336
+ <metrics loc="34" ncloc="11" classes="1" methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="4" coveredstatements="0" elements="5" coveredelements="0"/>
337
+ </file>
338
+ <file name="/home/travis/build/BoldGrid/boldgrid-backup/admin/card/feature/class-database-encryption.php">
339
+ <class name="Database_Encryption" namespace="Boldgrid\Backup\Admin\Card\Feature" fullPackage="Database">
340
+ <metrics complexity="1" methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="13" coveredstatements="0" elements="14" coveredelements="0"/>
341
+ </class>
342
+ <line num="27" type="method" name="init" visibility="public" complexity="1" crap="2" count="0"/>
343
+ <line num="28" type="stmt" count="0"/>
344
+ <line num="30" type="stmt" count="0"/>
345
+ <line num="32" type="stmt" count="0"/>
346
+ <line num="34" type="stmt" count="0"/>
347
+ <line num="35" type="stmt" count="0"/>
348
+ <line num="36" type="stmt" count="0"/>
349
+ <line num="38" type="stmt" count="0"/>
350
+ <line num="39" type="stmt" count="0"/>
351
+ <line num="40" type="stmt" count="0"/>
352
+ <line num="41" type="stmt" count="0"/>
353
+ <line num="42" type="stmt" count="0"/>
354
+ <line num="43" type="stmt" count="0"/>
355
+ <line num="44" type="stmt" count="0"/>
356
+ <metrics loc="45" ncloc="22" classes="1" methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="13" coveredstatements="0" elements="14" coveredelements="0"/>
357
+ </file>
358
+ <file name="/home/travis/build/BoldGrid/boldgrid-backup/admin/card/feature/class-more-backup.php">
359
+ <class name="More_Backup" namespace="Boldgrid\Backup\Admin\Card\Feature" fullPackage="More">
360
+ <metrics complexity="1" methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="20" coveredstatements="0" elements="21" coveredelements="0"/>
361
+ </class>
362
+ <line num="27" type="method" name="init" visibility="public" complexity="1" crap="2" count="0"/>
363
+ <line num="28" type="stmt" count="0"/>
364
+ <line num="30" type="stmt" count="0"/>
365
+ <line num="32" type="stmt" count="0"/>
366
+ <line num="33" type="stmt" count="0"/>
367
+ <line num="34" type="stmt" count="0"/>
368
+ <line num="36" type="stmt" count="0"/>
369
+ <line num="37" type="stmt" count="0"/>
370
+ <line num="39" type="stmt" count="0"/>
371
+ <line num="40" type="stmt" count="0"/>
372
+ <line num="41" type="stmt" count="0"/>
373
+ <line num="42" type="stmt" count="0"/>
374
+ <line num="43" type="stmt" count="0"/>
375
+ <line num="44" type="stmt" count="0"/>
376
+ <line num="45" type="stmt" count="0"/>
377
+ <line num="46" type="stmt" count="0"/>
378
+ <line num="47" type="stmt" count="0"/>
379
+ <line num="48" type="stmt" count="0"/>
380
+ <line num="49" type="stmt" count="0"/>
381
+ <line num="50" type="stmt" count="0"/>
382
+ <line num="51" type="stmt" count="0"/>
383
+ <metrics loc="52" ncloc="27" classes="1" methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="20" coveredstatements="0" elements="21" coveredelements="0"/>
384
+ </file>
385
+ <file name="/home/travis/build/BoldGrid/boldgrid-backup/admin/card/feature/class-more-boldgrid.php">
386
+ <class name="More_Boldgrid" namespace="Boldgrid\Backup\Admin\Card\Feature" fullPackage="More">
387
+ <metrics complexity="1" methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="4" coveredstatements="0" elements="5" coveredelements="0"/>
388
+ </class>
389
+ <line num="27" type="method" name="init" visibility="public" complexity="1" crap="2" count="0"/>
390
+ <line num="28" type="stmt" count="0"/>
391
+ <line num="30" type="stmt" count="0"/>
392
+ <line num="32" type="stmt" count="0"/>
393
+ <line num="33" type="stmt" count="0"/>
394
+ <metrics loc="34" ncloc="13" classes="1" methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="4" coveredstatements="0" elements="5" coveredelements="0"/>
395
+ </file>
396
+ <file name="/home/travis/build/BoldGrid/boldgrid-backup/admin/card/feature/class-more-central.php">
397
+ <class name="More_Central" namespace="Boldgrid\Backup\Admin\Card\Feature" fullPackage="More">
398
+ <metrics complexity="1" methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="7" coveredstatements="0" elements="8" coveredelements="0"/>
399
+ </class>
400
+ <line num="27" type="method" name="init" visibility="public" complexity="1" crap="2" count="0"/>
401
+ <line num="28" type="stmt" count="0"/>
402
+ <line num="30" type="stmt" count="0"/>
403
+ <line num="32" type="stmt" count="0"/>
404
+ <line num="34" type="stmt" count="0"/>
405
+ <line num="36" type="stmt" count="0"/>
406
+ <line num="38" type="stmt" count="0"/>
407
+ <line num="39" type="stmt" count="0"/>
408
+ <metrics loc="40" ncloc="19" classes="1" methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="7" coveredstatements="0" elements="8" coveredelements="0"/>
409
+ </file>
410
+ <file name="/home/travis/build/BoldGrid/boldgrid-backup/admin/card/feature/class-remote-storage.php">
411
+ <class name="Remote_Storage" namespace="Boldgrid\Backup\Admin\Card\Feature" fullPackage="Remote">
412
+ <metrics complexity="2" methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="32" coveredstatements="0" elements="33" coveredelements="0"/>
413
+ </class>
414
+ <line num="27" type="method" name="init" visibility="public" complexity="2" crap="6" count="0"/>
415
+ <line num="28" type="stmt" count="0"/>
416
+ <line num="30" type="stmt" count="0"/>
417
+ <line num="32" type="stmt" count="0"/>
418
+ <line num="34" type="stmt" count="0"/>
419
+ <line num="35" type="stmt" count="0"/>
420
+ <line num="37" type="stmt" count="0"/>
421
+ <line num="38" type="stmt" count="0"/>
422
+ <line num="39" type="stmt" count="0"/>
423
+ <line num="41" type="stmt" count="0"/>
424
+ <line num="42" type="stmt" count="0"/>
425
+ <line num="43" type="stmt" count="0"/>
426
+ <line num="44" type="stmt" count="0"/>
427
+ <line num="45" type="stmt" count="0"/>
428
+ <line num="46" type="stmt" count="0"/>
429
+ <line num="47" type="stmt" count="0"/>
430
+ <line num="48" type="stmt" count="0"/>
431
+ <line num="49" type="stmt" count="0"/>
432
+ <line num="50" type="stmt" count="0"/>
433
+ <line num="51" type="stmt" count="0"/>
434
+ <line num="52" type="stmt" count="0"/>
435
+ <line num="53" type="stmt" count="0"/>
436
+ <line num="54" type="stmt" count="0"/>
437
+ <line num="55" type="stmt" count="0"/>
438
+ <line num="56" type="stmt" count="0"/>
439
+ <line num="58" type="stmt" count="0"/>
440
+ <line num="59" type="stmt" count="0"/>
441
+ <line num="60" type="stmt" count="0"/>
442
+ <line num="61" type="stmt" count="0"/>
443
+ <line num="62" type="stmt" count="0"/>
444
+ <line num="63" type="stmt" count="0"/>
445
+ <line num="64" type="stmt" count="0"/>
446
+ <line num="65" type="stmt" count="0"/>
447
+ <metrics loc="66" ncloc="41" classes="1" methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="32" coveredstatements="0" elements="33" coveredelements="0"/>
448
+ </file>
449
+ <file name="/home/travis/build/BoldGrid/boldgrid-backup/admin/card/feature/class-scheduled-backups.php">
450
+ <class name="Scheduled_Backups" namespace="Boldgrid\Backup\Admin\Card\Feature" fullPackage="Scheduled">
451
+ <metrics complexity="3" methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="37" coveredstatements="0" elements="38" coveredelements="0"/>
452
+ </class>
453
+ <line num="29" type="method" name="init" visibility="public" complexity="3" crap="12" count="0"/>
454
+ <line num="30" type="stmt" count="0"/>
455
+ <line num="32" type="stmt" count="0"/>
456
+ <line num="34" type="stmt" count="0"/>
457
+ <line num="36" type="stmt" count="0"/>
458
+ <line num="37" type="stmt" count="0"/>
459
+ <line num="51" type="stmt" count="0"/>
460
+ <line num="52" type="stmt" count="0"/>
461
+ <line num="54" type="stmt" count="0"/>
462
+ <line num="55" type="stmt" count="0"/>
463
+ <line num="57" type="stmt" count="0"/>
464
+ <line num="58" type="stmt" count="0"/>
465
+ <line num="59" type="stmt" count="0"/>
466
+ <line num="60" type="stmt" count="0"/>
467
+ <line num="61" type="stmt" count="0"/>
468
+ <line num="62" type="stmt" count="0"/>
469
+ <line num="63" type="stmt" count="0"/>
470
+ <line num="64" type="stmt" count="0"/>
471
+ <line num="65" type="stmt" count="0"/>
472
+ <line num="66" type="stmt" count="0"/>
473
+ <line num="67" type="stmt" count="0"/>
474
+ <line num="68" type="stmt" count="0"/>
475
+ <line num="69" type="stmt" count="0"/>
476
+ <line num="70" type="stmt" count="0"/>
477
+ <line num="71" type="stmt" count="0"/>
478
+ <line num="72" type="stmt" count="0"/>
479
+ <line num="74" type="stmt" count="0"/>
480
+ <line num="75" type="stmt" count="0"/>
481
+ <line num="76" type="stmt" count="0"/>
482
+ <line num="77" type="stmt" count="0"/>
483
+ <line num="78" type="stmt" count="0"/>
484
+ <line num="79" type="stmt" count="0"/>
485
+ <line num="80" type="stmt" count="0"/>
486
+ <line num="81" type="stmt" count="0"/>
487
+ <line num="82" type="stmt" count="0"/>
488
+ <line num="83" type="stmt" count="0"/>
489
+ <line num="84" type="stmt" count="0"/>
490
+ <line num="85" type="stmt" count="0"/>
491
+ <metrics loc="86" ncloc="47" classes="1" methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="37" coveredstatements="0" elements="38" coveredelements="0"/>
492
+ </file>
493
+ <file name="/home/travis/build/BoldGrid/boldgrid-backup/admin/card/feature/class-sign-up.php">
494
+ <class name="Sign_Up" namespace="Boldgrid\Backup\Admin\Card\Feature" fullPackage="Sign">
495
+ <metrics complexity="1" methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="5" coveredstatements="0" elements="6" coveredelements="0"/>
496
+ </class>
497
+ <line num="27" type="method" name="init" visibility="public" complexity="1" crap="2" count="0"/>
498
+ <line num="28" type="stmt" count="0"/>
499
+ <line num="30" type="stmt" count="0"/>
500
+ <line num="32" type="stmt" count="0"/>
501
+ <line num="34" type="stmt" count="0"/>
502
+ <line num="35" type="stmt" count="0"/>
503
+ <metrics loc="36" ncloc="15" classes="1" methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="5" coveredstatements="0" elements="6" coveredelements="0"/>
504
+ </file>
505
+ <file name="/home/travis/build/BoldGrid/boldgrid-backup/admin/card/feature/class-speed-coach.php">
506
+ <class name="Speed_Coach" namespace="Boldgrid\Backup\Admin\Card\Feature" fullPackage="Speed">
507
+ <metrics complexity="1" methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="4" coveredstatements="0" elements="5" coveredelements="0"/>
508
+ </class>
509
+ <line num="27" type="method" name="init" visibility="public" complexity="1" crap="2" count="0"/>
510
+ <line num="28" type="stmt" count="0"/>
511
+ <line num="30" type="stmt" count="0"/>
512
+ <line num="32" type="stmt" count="0"/>
513
+ <line num="33" type="stmt" count="0"/>
514
+ <metrics loc="34" ncloc="13" classes="1" methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="4" coveredstatements="0" elements="5" coveredelements="0"/>
515
+ </file>
516
+ <file name="/home/travis/build/BoldGrid/boldgrid-backup/admin/card/feature/class-versions.php">
517
+ <class name="Versions" namespace="Boldgrid\Backup\Admin\Card\Feature">
518
+ <metrics complexity="4" methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="30" coveredstatements="0" elements="31" coveredelements="0"/>
519
+ </class>
520
+ <line num="25" type="method" name="init" visibility="public" complexity="4" crap="20" count="0"/>
521
+ <line num="26" type="stmt" count="0"/>
522
+ <line num="28" type="stmt" count="0"/>
523
+ <line num="30" type="stmt" count="0"/>
524
+ <line num="32" type="stmt" count="0"/>
525
+ <line num="34" type="stmt" count="0"/>
526
+ <line num="35" type="stmt" count="0"/>
527
+ <line num="36" type="stmt" count="0"/>
528
+ <line num="38" type="stmt" count="0"/>
529
+ <line num="39" type="stmt" count="0"/>
530
+ <line num="40" type="stmt" count="0"/>
531
+ <line num="41" type="stmt" count="0"/>
532
+ <line num="42" type="stmt" count="0"/>
533
+ <line num="44" type="stmt" count="0"/>
534
+ <line num="45" type="stmt" count="0"/>
535
+ <line num="46" type="stmt" count="0"/>
536
+ <line num="48" type="stmt" count="0"/>
537
+ <line num="49" type="stmt" count="0"/>
538
+ <line num="50" type="stmt" count="0"/>
539
+ <line num="51" type="stmt" count="0"/>
540
+ <line num="52" type="stmt" count="0"/>
541
+ <line num="53" type="stmt" count="0"/>
542
+ <line num="54" type="stmt" count="0"/>
543
+ <line num="55" type="stmt" count="0"/>
544
+ <line num="56" type="stmt" count="0"/>
545
+ <line num="57" type="stmt" count="0"/>
546
+ <line num="58" type="stmt" count="0"/>
547
+ <line num="59" type="stmt" count="0"/>
548
+ <line num="60" type="stmt" count="0"/>
549
+ <line num="61" type="stmt" count="0"/>
550
+ <line num="62" type="stmt" count="0"/>
551
+ <metrics loc="63" ncloc="40" classes="1" methods="1" coveredmethods="0" conditionals="0" coveredconditionals="0" statements="30" coveredstatements="0" elements="31" coveredelements="0"/>
552
+ </file>
553
+ </package>
554
+ <file name="/home/travis/build/BoldGrid/boldgrid-backup/admin/class-boldgrid-backup-admin-archive-actions.php">
555
+ <class name="Boldgrid_Backup_Admin_Archive_Actions" namespace="global" fullPackage="Boldgrid.Backup.Admin.Archive">
556
+ <metrics complexity="15" methods="7" coveredmethods="1" conditionals="0" coveredconditionals="0" statements="107" coveredstatements="2" elements="114" coveredelements="3"/>
557
+ </class>
558
+ <line num="38" type="method" name="__construct" visibility="public" complexity="1" crap="1" count="20"/>
559
+ <line num="39" type="stmt" count="20"/>
560
+ <line num="40" type="stmt" count="20"/>
561
+ <line num="47" type="method" name="enqueue_scripts" visibility="public" complexity="1" crap="2" count="0"/>
562
+ <line num="48" type="stmt" count="0"/>
563
+ <line num="49" type="stmt" count="0"/>
564
+ <line num="50" type="stmt" count="0"/>
565
+ <line num="51" type="stmt" count="0"/>
566
+ <line num="53" type="stmt" count="0"/>
567
+ <line num="56" type="stmt" count="0"/>
568
+ <line num="57" type="stmt" count="0"/>
569
+ <line num="59" type="stmt" count="0"/>
570
+ <line num="61" type="stmt" count="0"/>
571
+ <line num="62" type="stmt" count="0"/>
572
+ <line num="63" type="stmt" count="0"/>
573
+ <line num="64" type="stmt" count="0"/>
574
+ <line num="65" type="stmt" count="0"/>
575
+ <line num="66" type="stmt" count="0"/>
576
+ <line num="67" type="stmt" count="0"/>
577
+ <line num="69" type="stmt" count="0"/>
578
+ <line num="70" type="stmt" count="0"/>
579
+ <line num="71" type="stmt" count="0"/>
580
+ <line num="73" type="stmt" count="0"/>
581
+ <line num="75" type="stmt" count="0"/>
582
+ <line num="77" type="stmt" count="0"/>
583
+ <line num="78" type="stmt" count="0"/>
584
+ <line num="79" type="stmt" count="0"/>
585
+ <line num="80" type="stmt" count="0"/>
586
+ <line num="81" type="stmt" count="0"/>
587
+ <line num="83" type="stmt" count="0"/>
588
+ <line num="86" type="stmt" count="0"/>
589
+ <line num="87" type="stmt" count="0"/>
590
+ <line num="88" type="stmt" count="0"/>
591
+ <line num="89" type="stmt" count="0"/>
592
+ <line num="90" type="stmt" count="0"/>
593
+ <line num="91" type="stmt" count="0"/>
594
+ <line num="92" type="stmt" count="0"/>
595
+ <line num="93" type="stmt" count="0"/>
596
+ <line num="94" type="stmt" count="0"/>
597
+ <line num="95" type="stmt" count="0"/>
598
+ <line num="96" type="stmt" count="0"/>
599
+ <line num="97" type="stmt" count="0"/>
600
+ <line num="99" type="stmt" count="0"/>
601
+ <line num="100" type="stmt" count="0"/>
602
+ <line num="102" type="stmt" count="0"/>
603
+ <line num="103" type="stmt" count="0"/>
604
+ <line num="113" type="method" name="get_delete_link" visibility="public" complexity="2" crap="6" count="0"/>
605
+ <line num="114" type="stmt" count="0"/>
606
+ <line num="116" type="stmt" count="0"/>
607
+ <line num="117" type="stmt" count="0"/>
608
+ <line num="118" type="stmt" count="0"/>
609
+ <line num="119" type="stmt" count="0"/>
610
+ <line num="128" type="stmt" count="0"/>
611
+ <line num="129" type="stmt" count="0"/>
612
+ <line num="130" type="stmt" count="0"/>
613
+ <line num="131" type="stmt" count="0"/>
614
+ <line num="132" type="stmt" count="0"/>
615
+ <line num="133" type="stmt" count="0"/>
616
+ <line num="134" type="stmt" count="0"/>
617
+ <line num="137" type="stmt" count="0"/>
618
+ <line num="148" type="method" name="get_download_button" visibility="public" complexity="2" crap="6" count="0"/>
619
+ <line num="149" type="stmt" count="0"/>
620
+ <line num="151" type="stmt" count="0"/>
621
+