PluginProbe ʕ •ᴥ•ʔ
WP STAGING – WordPress Backup, Restore, Migration & Clone / 4.9.0
WP STAGING – WordPress Backup, Restore, Migration & Clone v4.9.0
4.9.1 4.9.0 4.8.1 trunk 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.10.0 3.2.0 3.3.1 3.3.2 3.3.3 3.4.1 3.4.3 3.5.0 3.6.0 3.7.1 3.8.0 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.8.6 3.8.7 3.9.0 3.9.1 3.9.2 3.9.3 3.9.4 4.0.0 4.1.0 4.1.1 4.1.2 4.1.3 4.1.4 4.2.0 4.2.1 4.3.0 4.3.1 4.3.2 4.4.0 4.5.0 4.6.0 4.7.0 4.7.1 4.7.2 4.7.3 4.8.0
wp-staging / Backend / Upgrade / Upgrade.php
wp-staging / Backend / Upgrade Last commit date
Upgrade.php 1 month ago
Upgrade.php
390 lines
1 <?php
2
3 /**
4 * Upgrade Class
5 * This must be loaded on every page init to ensure all settings are
6 * adjusted correctly and to run any upgrade process if necessary.
7 */
8
9 namespace WPStaging\Backend\Upgrade;
10
11 use WPStaging\Core\Utils\IISWebConfig;
12 use WPStaging\Core\Utils\Htaccess;
13 use WPStaging\Core\WPStaging;
14 use WPStaging\Framework\BackgroundProcessing\Queue;
15 use WPStaging\Notifications\Notifications;
16 use WPStaging\Staging\Sites;
17 use WPStaging\Backup\BackupScheduler;
18 use WPStaging\Backup\Storage\Providers;
19 use WPStaging\Framework\Upgrade\UpgradeFlags;
20
21 // No Direct Access
22 if (!defined("WPINC")) {
23 die;
24 }
25
26 class Upgrade
27 {
28 /**
29 * @var string
30 */
31 const OPTION_UPGRADE_DATE = 'wpstg_free_upgrade_date';
32
33 /**
34 * @var string
35 */
36 const OPTION_INSTALL_DATE = 'wpstg_free_install_date';
37
38 /**
39 * Previous Version number
40 * @var string
41 */
42 private $previousVersion;
43
44 /**
45 * Global settings
46 * @var object
47 */
48 private $settings;
49
50 /**
51 * db object
52 * @var object
53 */
54 private $db;
55
56 /**
57 * @var Sites
58 */
59 private $stagingSitesHelper;
60
61 /**
62 * @var UpgradeFlags
63 */
64 private $upgradeFlags;
65
66 public function __construct()
67 {
68 // Previous version
69 $this->previousVersion = preg_replace('/[^0-9.].*/', '', get_option('wpstg_version'));
70
71 $this->settings = (object) get_option("wpstg_settings", []);
72
73 // db
74 $this->db = WPStaging::getInstance()->get("wpdb");
75
76 /** @var Sites */
77 $this->stagingSitesHelper = WPStaging::make(Sites::class);
78 $this->upgradeFlags = WPStaging::make(UpgradeFlags::class);
79 }
80
81 /**
82 * @return void
83 */
84 public function doUpgrade()
85 {
86 $this->upgrade2_0_3();
87 $this->upgrade2_1_2();
88 $this->upgrade2_2_0();
89 $this->upgrade2_4_4();
90 $this->upgrade2_5_9();
91 $this->upgrade2_8_7();
92 $this->upgrade3_0_7();
93 $this->upgrade3_8_1();
94 $this->migrateRemoteStorageOptionNames();
95
96 $this->setVersion();
97 }
98
99 /**
100 * Enable backup notification by default
101 * @return void
102 */
103 private function upgrade3_8_1() // phpcs:ignore
104 {
105 // Early bail: Previous version is greater than 3.8.1
106 if (version_compare($this->previousVersion, '3.8.1', '>')) {
107 return;
108 }
109
110 if (!class_exists('WPStaging\Backup\BackupScheduler')) {
111 return;
112 }
113
114 $optionBackupScheduleReportEmail = get_option(Notifications::OPTION_BACKUP_SCHEDULE_REPORT_EMAIL);
115 if (empty($optionBackupScheduleReportEmail) || !filter_var($optionBackupScheduleReportEmail, FILTER_VALIDATE_EMAIL)) {
116 $wpstgSettings = (array)get_option('wpstg_settings');
117
118 if (!empty($wpstgSettings['schedulesReportEmail'])) {
119 $optionBackupScheduleReportEmail = $wpstgSettings['schedulesReportEmail'];
120 } else {
121 $userObject = wp_get_current_user();
122 if (is_object($userObject) && !empty($userObject->user_email)) {
123 $optionBackupScheduleReportEmail = $userObject->user_email;
124 }
125 }
126
127 update_option(Notifications::OPTION_BACKUP_SCHEDULE_REPORT_EMAIL, $optionBackupScheduleReportEmail);
128 }
129
130 // boolean false: Default value if the option does not exist/created yet
131 if (get_option(BackupScheduler::OPTION_BACKUP_SCHEDULE_ERROR_REPORT) === false && !empty($optionBackupScheduleReportEmail)) {
132 update_option(BackupScheduler::OPTION_BACKUP_SCHEDULE_ERROR_REPORT, 'true');
133 }
134 }
135
136 /**
137 * Rename remote storage options from legacy lowercase to new hyphenated format
138 * (e.g. wpstg_googledrive -> wpstg_google-drive).
139 *
140 * Guarded by a persistent feature flag instead of version_compare so the
141 * migration runs exactly once, independent of how wpstg_version is set.
142 *
143 * @return void
144 */
145 private function migrateRemoteStorageOptionNames()
146 {
147 if ($this->upgradeFlags->has('remote_storage_option_names_migrated')) {
148 return;
149 }
150
151 (new Providers())->migrateRemoteStorageOptions();
152 $this->upgradeFlags->mark('remote_storage_option_names_migrated');
153 }
154
155 /**
156 * Add response field to queue table if not exist
157 * @return void
158 */
159 private function upgrade3_0_7() // phpcs:ignore
160 {
161 // Early bail: Previous version is greater than 3.0.6
162 if (version_compare($this->previousVersion, '3.0.6', '>')) {
163 return;
164 }
165
166 $queueUtil = WPStaging::make(Queue::class);
167 $queueUtil->maybeAddResponseColumnToTable();
168 }
169
170 /**
171 * Move existing staging sites to new option defined in Sites::STAGING_SITES_OPTION
172 * @return void
173 */
174 private function upgrade2_8_7() // phpcs:ignore
175 {
176 $this->stagingSitesHelper->addMissingCloneNameUpgradeStructure();
177 $this->stagingSitesHelper->upgradeStagingSitesOption();
178 }
179
180 /**
181 * Fix array keys of staging sites
182 * @return void
183 */
184 private function upgrade2_5_9() // phpcs:ignore
185 {
186 // Previous version lower than 2.5.9
187 if (version_compare($this->previousVersion, '2.5.9', '<')) {
188 // Current options
189 $sites = $this->stagingSitesHelper->tryGettingStagingSites();
190
191 $new = [];
192
193 // Fix keys. Replace white spaces with dash character
194 foreach ($sites as $oldKey => $site) {
195 $key = preg_replace("#\W+#", '-', strtolower($oldKey));
196 $new[$key] = $sites[$oldKey];
197 }
198
199 if (!empty($new)) {
200 $this->stagingSitesHelper->updateStagingSites($new);
201 }
202 }
203 }
204
205 /**
206 * @return void
207 */
208 private function upgrade2_4_4() // phpcs:ignore
209 {
210 // Previous version lower than 2.4.4
211 if (version_compare($this->previousVersion, '2.4.4', '<')) {
212 // Add htaccess to wp staging uploads folder
213 $htaccess = new Htaccess();
214 $htaccess->create(trailingslashit(WPStaging::getContentDir()) . '.htaccess');
215 $htaccess->create(trailingslashit(WPStaging::getContentDir()) . 'logs/.htaccess');
216
217 // Add litespeed htaccess to wp root folder
218 if (extension_loaded('litespeed')) {
219 $htaccess->createLitespeed(ABSPATH . '.htaccess');
220 }
221
222 // create web.config file for IIS in wp staging uploads folder
223 $webconfig = new IISWebConfig();
224 $webconfig->create(trailingslashit(WPStaging::getContentDir()) . 'web.config');
225 $webconfig->create(trailingslashit(WPStaging::getContentDir()) . 'logs/web.config');
226 }
227 }
228
229 /**
230 * Upgrade method 2.2.0
231 * @return void
232 */
233 public function upgrade2_2_0() // phpcs:ignore
234 {
235 // Previous version lower than 2.2.0
236 if (version_compare($this->previousVersion, '2.2.0', '<')) {
237 $this->upgradeElements();
238 }
239 }
240
241 /**
242 * Add missing elements
243 * @return void
244 */
245 private function upgradeElements()
246 {
247 // Current options
248 $sites = $this->stagingSitesHelper->tryGettingStagingSites();
249
250 if ($sites === false || count($sites) === 0) {
251 return;
252 }
253
254 // Check if key prefix is missing and add it
255 foreach ($sites as $key => $value) {
256 if (empty($sites[$key]['directoryName'])) {
257 continue;
258 }
259
260 !empty($sites[$key]['prefix']) ?
261 $sites[$key]['prefix'] = $value['prefix'] :
262 $sites[$key]['prefix'] = $this->getStagingPrefix($sites[$key]['directoryName']);
263 }
264
265 if (count($sites) > 0) {
266 $this->stagingSitesHelper->updateStagingSites($sites);
267 }
268 }
269
270 /**
271 * Check and return prefix of the staging site
272 * @param string $directory
273 * @return string
274 */
275 private function getStagingPrefix($directory)
276 {
277 // Try to get staging prefix from wp-config.php of staging site
278 $path = ABSPATH . $directory . "/wp-config.php";
279
280 if (($content = @file_get_contents($path)) === false) {
281 $prefix = "";
282 } else {
283 // Get prefix from wp-config.php
284 preg_match("/table_prefix\s*=\s*'(\w*)';/", $content, $matches);
285
286 if (!empty($matches[1])) {
287 $prefix = $matches[1];
288 } else {
289 $prefix = "";
290 }
291 }
292
293 // return result: Check if staging prefix is the same as the live prefix
294 if ($this->db->prefix != $prefix) {
295 return $prefix;
296 } else {
297 return "";
298 }
299 }
300
301 /**
302 * Upgrade method 2.0.3
303 * @return void
304 */
305 public function upgrade2_0_3() // phpcs:ignore
306 {
307 // Previous version lower than 2.0.2
308 if (version_compare($this->previousVersion, '2.0.2', '<')) {
309 $this->initialInstall();
310 $this->upgradeNotices();
311 }
312 }
313
314 /**
315 * Upgrade method 2.1.2
316 * Sanitize the clone key value.
317 * @return void
318 */
319 private function upgrade2_1_2() // phpcs:ignore
320 {
321 if ($this->previousVersion === false || version_compare($this->previousVersion, '2.1.2', '<')) {
322 // Current options
323 $clones = $this->stagingSitesHelper->tryGettingStagingSites();
324
325 foreach ($clones as $key => $value) {
326 unset($clones[$key]);
327 $clones[preg_replace("#\W+#", '-', strtolower($key))] = $value;
328 }
329
330 if (!empty($clones)) {
331 $this->stagingSitesHelper->updateStagingSites($clones);
332 }
333 }
334 }
335
336 /**
337 * Upgrade routine for new install
338 * @return void
339 */
340 private function initialInstall()
341 {
342 // Write some default vars
343 add_option('wpstg_installDate', date('Y-m-d h:i:s')); // Common install date for free or pro version - deprecated. Remove 2023
344 add_option(self::OPTION_INSTALL_DATE, date('Y-m-d h:i:s'));
345 $this->settings->optimizer = "1";
346 update_option('wpstg_settings', $this->settings);
347 }
348
349 /**
350 * Write new version number into db
351 * @return bool
352 */
353 private function setVersion()
354 {
355 // Check if version number in DB is lower than version number in current plugin
356 if (version_compare($this->previousVersion, WPStaging::getVersion(), '<')) {
357 // Update Version number
358 update_option('wpstg_version', preg_replace('/[^0-9.].*/', '', WPStaging::getVersion()));
359 // Update "upgraded from" version number
360 update_option('wpstg_version_upgraded_from', preg_replace('/[^0-9.].*/', '', $this->previousVersion));
361 // Update the time version upgraded at
362 update_option(self::OPTION_UPGRADE_DATE, date('Y-m-d H:i'));
363
364 return true;
365 }
366
367 return false;
368 }
369
370 /**
371 * Upgrade Notices db options from wpstg 1.3 -> 2.0.1
372 * Fix some logical db options
373 * @return void
374 */
375 private function upgradeNotices()
376 {
377 $poll = get_option("wpstg_start_poll", false);
378 $beta = get_option("wpstg_hide_beta", false);
379 $rating = get_option("wpstg_RatingDiv", false);
380
381 if ($beta && $beta === "yes") {
382 update_option('wpstg_beta', 'no');
383 }
384
385 if ($rating && $rating === 'yes') {
386 update_option('wpstg_rating', 'no');
387 }
388 }
389 }
390