PluginProbe ʕ •ᴥ•ʔ
WP STAGING – WordPress Backup, Restore, Migration & Clone / 4.7.0
WP STAGING – WordPress Backup, Restore, Migration & Clone v4.7.0
4.9.3 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 / PreserveDataSecondStep.php
wp-staging / Backend / Modules / Jobs Last commit date
Cleaners 4 months ago Exceptions 5 years ago Cancel.php 7 months ago CancelUpdate.php 7 months ago Cloning.php 4 months ago CloningProcess.php 1 year ago Data.php 7 months ago Database.php 4 months ago Delete.php 5 months ago Directories.php 5 months ago Files.php 6 months ago Finish.php 5 months ago Job.php 5 months ago JobExecutable.php 7 months ago Logs.php 3 years ago PreserveDataFirstStep.php 5 months ago PreserveDataSecondStep.php 5 months ago ProcessLock.php 1 year ago Scan.php 5 months ago SearchReplace.php 6 months ago TotalStepsAreNumberOfTables.php 5 years ago Updating.php 5 months ago
PreserveDataSecondStep.php
290 lines
1 <?php
2
3 namespace WPStaging\Backend\Modules\Jobs;
4
5 use WPStaging\Core\WPStaging;
6 use WPStaging\Framework\Adapter\SourceDatabase;
7 use WPStaging\Staging\CloneOptions;
8 use WPStaging\Staging\Sites;
9 use WPStaging\Staging\FirstRun;
10 use WPStaging\Backend\Modules\Jobs\Job as MainJob;
11
12 use function WPStaging\functions\debug_log;
13
14 /**
15 * Copy wpstg_tmp_data back to wpstg_staging_sites after cloning with class::PreserveDataSecondStep
16 * @package WPStaging\Backend\Modules\Jobs
17 */
18 class PreserveDataSecondStep 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 object */
30 private $preservedData;
31
32 protected function calculateTotalSteps()
33 {
34 $this->options->totalSteps = 1;
35 }
36
37 /** @return object */
38 public function start()
39 {
40 $this->run();
41 $this->saveOptions();
42
43 return (object)$this->response;
44 }
45
46 /** @return false */
47 protected function execute()
48 {
49 $db = new SourceDatabase($this->options);
50
51 $this->stagingDb = $db->getDatabase();
52 $this->productionDb = WPStaging::getInstance()->get("wpdb");
53 $this->stagingPrefix = $this->options->prefix;
54
55 if ($db->isExternalDatabase()) {
56 $this->stagingPrefix = $this->options->databasePrefix;
57 }
58
59 $this->copyToStaging();
60 $this->prepareResponse(true, true);
61
62 return false;
63 }
64
65 /** @return true */
66 public function copyToStaging()
67 {
68 // Early bail if table doesn't exist
69 if (!$this->tableExists($this->stagingPrefix . "options")) {
70 return true;
71 }
72
73 // Get wpstg_tmp_data from production database
74 $result = $this->productionDb->get_var(
75 $this->productionDb->prepare(
76 "SELECT `option_value` FROM " . $this->productionDb->prefix . "options WHERE `option_name` = %s",
77 "wpstg_tmp_data"
78 )
79 );
80
81 // Nothing to do
82 if (!$result) {
83 return true;
84 }
85
86 // Make sure this is compatible with Free Version
87 // @see \WPStaging\Backup\BackupScheduler::OPTION_BACKUP_SCHEDULES
88 $backupSchedulesOption = 'wpstg_backup_schedules';
89
90 // Delete wpstg_tmp_data from the production site
91 $deleteTmpData = $this->productionDb->query(
92 $this->productionDb->prepare("DELETE FROM " . $this->productionDb->prefix . "options WHERE `option_name` = %s", "wpstg_tmp_data")
93 );
94
95 if ($deleteTmpData === false) {
96 $this->log("Preserve Data Second Step: Failed to delete wpstg_tmp_data from the production site");
97 }
98
99 $this->preservedData = maybe_unserialize($result);
100
101 // Preserve wpstg_staging_sites in staging database
102 $this->preserveStagingOption(Sites::STAGING_SITES_OPTION, $this->preservedData->stagingSites, 'existing clones');
103 // Preserve wpstg_settings in staging database (preserved during update only, not during reset)
104 if ($this->options->mainJob === MainJob::UPDATE && isset($this->preservedData->settings)) {
105 $this->preserveStagingOption("wpstg_settings", $this->preservedData->settings, 'settings');
106 }
107
108 // Preserve wpstg_login_link_settings in staging database
109 $this->preserveStagingOption("wpstg_login_link_settings", $this->preservedData->loginLinkSettings, 'login settings');
110
111 // Preserve wpstg_clone_options in staging database
112 $this->updateCloneOptions();
113 $this->preserveStagingOption(CloneOptions::WPSTG_CLONE_SETTINGS_KEY, $this->preservedData->cloneOptions, 'clone options');
114
115 // Preserve backup schedules
116 $this->preserveStagingOption($backupSchedulesOption, $this->preservedData->backupSchedules, 'backup schedules');
117
118 if ($this->propertyExists('googleDrive')) {
119 $this->preserveStagingOption('wpstg_googledrive', $this->preservedData->googleDrive, 'Google Drive settings');
120 } else {
121 $this->deleteStagingSiteOption('wpstg_googledrive');
122 }
123
124 if ($this->propertyExists('amazonS3')) {
125 $this->preserveStagingOption('wpstg_amazons3', $this->preservedData->amazonS3, 'Amazon S3 settings');
126 } else {
127 $this->deleteStagingSiteOption('wpstg_amazons3');
128 }
129
130 if ($this->propertyExists('sftp')) {
131 $this->preserveStagingOption('wpstg_sftp', $this->preservedData->sftp, 'sFTP/FTP settings');
132 } else {
133 $this->deleteStagingSiteOption('wpstg_sftp');
134 }
135
136 if ($this->propertyExists('digitalOceanSpaces')) {
137 $this->preserveStagingOption('wpstg_digitalocean-spaces', $this->preservedData->digitalOceanSpaces, 'Digital Ocean Spaces settings');
138 } else {
139 $this->deleteStagingSiteOption('wpstg_digitalocean-spaces');
140 }
141
142 if ($this->propertyExists('wasabiS3')) {
143 $this->preserveStagingOption('wpstg_wasabi', $this->preservedData->wasabiS3, 'Wasabi S3 settings');
144 } else {
145 $this->deleteStagingSiteOption('wpstg_wasabi');
146 }
147
148 if ($this->propertyExists('genericS3')) {
149 $this->preserveStagingOption('wpstg_generic-s3', $this->preservedData->genericS3, 'S3 Compat settings');
150 } else {
151 $this->deleteStagingSiteOption('wpstg_generic-s3');
152 }
153
154 if ($this->propertyExists('dropbox')) {
155 $this->preserveStagingOption('wpstg_dropbox', $this->preservedData->dropbox, 'Dropbox settings');
156 } else {
157 $this->deleteStagingSiteOption('wpstg_dropbox');
158 }
159
160 if ($this->propertyExists('oneDrive')) {
161 $this->preserveStagingOption('wpstg_one-drive', $this->preservedData->oneDrive, 'Microsoft OneDrive settings');
162 } else {
163 $this->deleteStagingSiteOption('wpstg_one-drive');
164 }
165
166 if ($this->propertyExists('pCloud')) {
167 $this->preserveStagingOption('wpstg_pcloud', $this->preservedData->pCloud, 'pCloud settings');
168 } else {
169 $this->deleteStagingSiteOption('wpstg_pcloud');
170 }
171
172 return true;
173 }
174
175 /**
176 * @param string $optionName
177 * @param string $optionValue
178 * @param bool $autoload
179 */
180 protected function preserveStagingOption($optionName, $optionValue, $logEntity, $autoload = false)
181 {
182 $isDeleted = $this->deleteStagingSiteOption($optionName);
183
184 if ($isDeleted === false) {
185 $this->log("Preserve Data Second Step: Failed to delete " . $optionName . " from the staging site");
186 }
187
188 $isInserted = $this->insertOptionIntoStagingSite($optionName, $optionValue, $autoload);
189
190 if ($isInserted === false) {
191 $this->log("Preserve Data Second Step: Failed to insert preserved " . $logEntity . " into " . $optionName . " of the staging site");
192 }
193 }
194
195 /**
196 * @param string $optionName
197 *
198 * @return bool|int Number of rows affected. Boolean false on error
199 */
200 protected function deleteStagingSiteOption($optionName)
201 {
202 return $this->stagingDb->query(
203 $this->stagingDb->prepare("DELETE FROM " . $this->stagingPrefix . "options WHERE `option_name` = %s", $optionName)
204 );
205 }
206
207 /**
208 * @param string $optionName
209 * @param string $optionValue
210 * @param bool $autoload
211 *
212 * @return bool|int Number of rows affected. Boolean false on error
213 */
214 protected function insertOptionIntoStagingSite($optionName, $optionValue, $autoload = false)
215 {
216 $autoload = $autoload ? 'yes' : 'no';
217
218 return $this->stagingDb->query(
219 $this->stagingDb->prepare(
220 "INSERT INTO `" . $this->stagingPrefix . "options` ( `option_id`, `option_name`, `option_value`, `autoload` ) VALUES ( NULL , %s, %s, %s )",
221 $optionName,
222 $optionValue,
223 $autoload
224 )
225 );
226 }
227
228 /**
229 * @param string $property
230 *
231 * @return bool
232 */
233 protected function propertyExists($property)
234 {
235 if (!is_object($this->preservedData) && !is_string($property)) {
236 return false;
237 }
238
239 if (!property_exists($this->preservedData, $property)) {
240 return false;
241 }
242
243 return !empty($this->preservedData->{$property});
244 }
245
246 /**
247 * Check if table exists
248 * @param string $table
249 * @return bool
250 */
251 private function tableExists($table)
252 {
253 return !($table != $this->stagingDb->get_var("SHOW TABLES LIKE '{$table}'"));
254 }
255
256 /**
257 * Update wpstg_clone_options before restoring it.
258 *
259 * @return void
260 */
261 private function updateCloneOptions()
262 {
263 if ($this->getOptions()->mainJob !== MainJob::UPDATE) {
264 return;
265 }
266
267 $cloneOptions = $this->preservedData->cloneOptions;
268
269 $data = maybe_unserialize($cloneOptions);
270 if (empty($cloneOptions)) {
271 $data = new \stdClass();
272 }
273
274 // Should not happen, but if it happens just return earlier without changing anything.
275 if (!is_object($data)) {
276 debug_log('Fail to update clone options before restore.');
277 return;
278 }
279
280 // clean up old option wpstg_woo_scheduler_disabled if exists
281 if (property_exists($data, 'wpstg_woo_scheduler_disabled')) {
282 unset($data->wpstg_woo_scheduler_disabled);
283 }
284
285 $schedulerKey = FirstRun::WOO_SCHEDULER_ENABLED_KEY;
286 $data->{$schedulerKey} = empty($this->getOptions()->isWooSchedulerEnabled) ? false : true;
287 $this->preservedData->cloneOptions = maybe_serialize($data);
288 }
289 }
290