PluginProbe ʕ •ᴥ•ʔ
WP STAGING – WordPress Backup, Restore, Migration & Clone / 4.9.2
WP STAGING – WordPress Backup, Restore, Migration & Clone v4.9.2
4.9.2 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 / Modules / Jobs / PreserveDataFirstStep.php
wp-staging / Backend / Modules / Jobs Last commit date
Cleaners 3 months ago Exceptions 5 years ago Cancel.php 7 months ago CancelUpdate.php 7 months ago Cloning.php 2 weeks ago CloningProcess.php 1 year ago Data.php 7 months ago Database.php 3 months ago Delete.php 4 months ago Directories.php 4 months ago Files.php 1 week ago Finish.php 2 months ago Job.php 2 weeks ago JobExecutable.php 7 months ago Logs.php 3 years ago PreserveDataFirstStep.php 1 month ago PreserveDataSecondStep.php 1 month ago ProcessLock.php 1 year ago Scan.php 4 months ago SearchReplace.php 5 months ago TotalStepsAreNumberOfTables.php 5 years ago Updating.php 2 weeks ago
PreserveDataFirstStep.php
234 lines
1 <?php
2
3 namespace WPStaging\Backend\Modules\Jobs;
4
5 use WPStaging\Backup\Storage\Providers;
6 use WPStaging\Core\WPStaging;
7 use WPStaging\Framework\Adapter\SourceDatabase;
8 use WPStaging\Staging\CloneOptions;
9 use WPStaging\Staging\Sites;
10 use WPStaging\Backend\Modules\Jobs\Job as MainJob;
11
12 /**
13 * Preserve staging sites in wpstg_staging_sites in staging database while updating a site
14 * While cloning, copy an existing entry from staging site to wpstg_tmp_data and after cloning restore that data.
15 * Mainly used while an existing staging site is updated, not initially cloned
16 * @package WPStaging\Backend\Modules\Jobs
17 */
18 class PreserveDataFirstStep extends JobExecutable
19 {
20 /** @var \wpdb */
21 private $stagingDb;
22
23 /** @var \wpdb */
24 private $productionDb;
25
26 /** @var string */
27 private $stagingPrefix;
28
29 /** @var string */
30 private $backupSchedulesOption;
31
32 protected function calculateTotalSteps()
33 {
34 $this->options->totalSteps = 1;
35
36 if (class_exists('\WPStaging\Backup\BackupScheduler')) {
37 $this->backupSchedulesOption = \WPStaging\Backup\BackupScheduler::OPTION_BACKUP_SCHEDULES;
38 } else {
39 // Fallback if pro namespace is not available
40 // @see \WPStaging\Backup\BackupScheduler::OPTION_BACKUP_SCHEDULES
41 $this->backupSchedulesOption = 'wpstg_backup_schedules';
42 }
43 }
44
45 /** @return object */
46 public function start()
47 {
48 $db = new SourceDatabase($this->options);
49
50 $this->stagingDb = $db->getDatabase();
51 $this->productionDb = WPStaging::getInstance()->get("wpdb");
52 $this->stagingPrefix = $this->options->prefix;
53
54 if ($db->isExternalDatabase()) {
55 $this->stagingPrefix = $this->options->databasePrefix;
56 }
57
58 $this->run();
59 $this->saveOptions();
60
61 return (object)$this->response;
62 }
63
64 /** @return false */
65 protected function execute()
66 {
67 $this->copyToTmp();
68 $this->prepareResponse(true, true);
69
70 return false;
71 }
72
73 /** @return true */
74 public function copyToTmp()
75 {
76 // Delete wpstg_tmp_data and reset it
77 $delete = $this->productionDb->query(
78 $this->productionDb->prepare("DELETE FROM " . $this->productionDb->prefix . "options WHERE `option_name` = %s", "wpstg_tmp_data")
79 );
80
81 if (!$this->tableExists($this->stagingPrefix . "options")) {
82 return true;
83 }
84
85 // Get wpstg_staging_sites from staging database
86 $stagingSites = $this->getStagingSiteOption(Sites::STAGING_SITES_OPTION);
87
88 // Get wpstg_settings from staging database (preserved during update only, not during reset)
89 if ($this->options->mainJob === MainJob::UPDATE) {
90 $settings = $this->getStagingSiteOption("wpstg_settings");
91 }
92
93 $loginLinkSettings = $this->getStagingSiteOption("wpstg_login_link_settings");
94
95 // Get wpstg_clone_options from staging database
96 $cloneOptions = $this->getStagingSiteOption(CloneOptions::WPSTG_CLONE_SETTINGS_KEY);
97
98 // Automated backup schedules
99 $backupSchedules = $this->getStagingSiteOption($this->backupSchedulesOption);
100
101 // All remote storages for backup
102 $remoteStorages = $this->preserveRemoteStorages();
103
104 // Nothing to do
105 if (!$stagingSites && !$settings && !$cloneOptions && !$backupSchedules && !$loginLinkSettings && empty($remoteStorages)) {
106 return true;
107 }
108
109 $options = [
110 'stagingSites' => $stagingSites,
111 'cloneOptions' => $cloneOptions,
112 'backupSchedules' => $backupSchedules,
113 'loginLinkSettings' => $loginLinkSettings,
114 ];
115
116 // Only include settings if it is update operation
117 if ($this->options->mainJob === MainJob::UPDATE) {
118 $options['settings'] = $settings;
119 }
120
121 $options = array_merge($options, $remoteStorages);
122 $tmpData = serialize((object) $options);
123
124 // Insert staging site preserved data into wpstg_tmp_data in production database
125 $insert = $this->productionDb->query(
126 $this->productionDb->prepare(
127 "INSERT INTO `" . $this->productionDb->prefix . "options` ( `option_id`, `option_name`, `option_value`, `autoload` ) VALUES ( NULL , %s, %s, %s )",
128 "wpstg_tmp_data",
129 $tmpData,
130 "no"
131 )
132 );
133
134 if ($delete === false) {
135 $this->log("Preserve Data: Failed to delete wpstg_tmp_data");
136 }
137
138 if ($stagingSites === false) {
139 $this->log("Preserve Data: Failed to get wpstg_staging_sites");
140 }
141
142 if ($settings === false) {
143 $this->log("Preserve Data: Failed to get wpstg_settings");
144 }
145
146 if ($cloneOptions === false) {
147 $this->log("Preserve Data: Failed to get wpstg_clone_options");
148 }
149
150 if ($loginLinkSettings === false) {
151 $this->log("Preserve Data: Failed to get wpstg_login_link_settings");
152 }
153
154 if ($backupSchedules === false) {
155 $this->log("Preserve Data: Failed to get " . $this->backupSchedulesOption);
156 }
157
158 if ($insert === false) {
159 $this->log("Preserve Data: Failed to insert wpstg_staging_sites to wpstg_tmp_data");
160 }
161
162 return true;
163 }
164
165 /** @return array */
166 protected function preserveRemoteStorages()
167 {
168 $storages = [];
169
170 foreach (Providers::STORAGE_LABELS as $identifier => $label) {
171 $value = $this->getStagingSiteStorageOption($identifier);
172 if ($value === false) {
173 $this->log("Preserve Data: Failed to get {$label} Settings");
174 } else {
175 $storages[$identifier] = $value;
176 }
177 }
178
179 return $storages;
180 }
181
182 /**
183 * Get a storage option from the staging database, checking both the new hyphenated
184 * and legacy option names for backward compatibility with older staging sites.
185 *
186 * @param string $identifier The storage identifier (e.g. 'google-drive')
187 * @return string|null|false The option value, null if not found, false on error
188 */
189 protected function getStagingSiteStorageOption($identifier)
190 {
191 $value = $this->getStagingSiteOption('wpstg_' . $identifier);
192
193 // Fall back to legacy names only when the new-format option is absent (null), not empty —
194 // empty means the user cleared credentials intentionally.
195 if ($value !== null) {
196 return $value;
197 }
198
199 if (isset(Providers::LEGACY_OPTION_MAP[$identifier])) {
200 $legacyValue = $this->getStagingSiteOption(Providers::LEGACY_OPTION_MAP[$identifier]);
201 if ($legacyValue !== null) {
202 return $legacyValue;
203 }
204 }
205
206 return $value;
207 }
208
209 /**
210 * @param string $optionName
211 *
212 * @return string|null
213 */
214 protected function getStagingSiteOption($optionName)
215 {
216 return $this->stagingDb->get_var(
217 $this->stagingDb->prepare(
218 "SELECT `option_value` FROM " . $this->stagingPrefix . "options WHERE `option_name` = %s",
219 $optionName
220 )
221 );
222 }
223
224 /**
225 * Check if table exists
226 * @param string $table
227 * @return bool
228 */
229 private function tableExists($table)
230 {
231 return !($table != $this->stagingDb->get_var("SHOW TABLES LIKE '{$table}'"));
232 }
233 }
234