PluginProbe
WP Synchro – The Ultimate WordPress Migration Tool / trunk
WP Synchro – The Ultimate WordPress Migration Tool vtrunk
1.16.1 1.16.0 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.1.0 1.10.0 1.11.0 1.11.1 1.11.2 1.11.3 1.11.4 1.11.5 1.12.0 1.13.0 1.14.0 1.15.0 1.2.0 1.3.0 1.3.1 1.3.2 All 45 releases
wpsynchro / src / Migration / MigrationController.php

MigrationController.php in WP Synchro – The Ultimate WordPress Migration Tool trunk, at src/Migration/MigrationController.php

331 lines 10.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace WPSynchro\Migration;
4
5 use WPSynchro\Utilities\SingletonTrait;
6 use WPSynchro\Database\DatabaseBackup;
7 use WPSynchro\Database\DatabaseSync;
8 use WPSynchro\Files\FilesSync;
9 use WPSynchro\Finalize\FinalizeSync;
10 use WPSynchro\Initiate\InitiateSync;
11 use WPSynchro\Logger\FileLogger;
12 use WPSynchro\Logger\SyncMetadataLog;
13 use WPSynchro\Masterdata\MasterdataSync;
14 use WPSynchro\Utilities\Actions;
15 use WPSynchro\Utilities\CommonFunctions;
16 use WPSynchro\Utilities\SyncTimerList;
17
18 /**
19 * Class for controlling the migration flow (main controller)
20 * Called from API service, for both the worker thread and the status thread
21 */
22 class MigrationController
23 {
24 use SingletonTrait;
25
26 // General data
27 public string $migration_id = '';
28 public string $job_id = '';
29 // Objects
30 public ?Job $job = null;
31 public ?Migration $migration = null;
32 // Timer
33 public ?SyncTimerList $timer = null;
34 // Helpers
35 public ?CommonFunctions $common = null;
36 // Errors and warnings
37 public array $errors = [];
38 public array $warnings = [];
39 // Logger
40 public ?FileLogger $logger = null;
41
42 /**
43 * Setup the data needed for migration, needed for both worker and status thread
44 */
45 public function setup(string $migration_id, string $job_id)
46 {
47 // Get sync timer
48 $this->timer = SyncTimerList::getInstance();
49 $this->timer->init();
50
51 // Set migration and job id
52 $this->migration_id = $migration_id;
53 $this->job_id = $job_id;
54
55 // Common
56 $this->common = new CommonFunctions();
57
58 // Init logging
59 $this->logger = new FileLogger($this->common->getLogFilename($this->job_id));
60
61 // Get job data
62 $this->job = new Job();
63 $this->job->load($this->migration_id, $this->job_id);
64
65 // Get migration
66 $migrationFactory = MigrationFactory::getInstance();
67 $this->migration = $migrationFactory->retrieveMigration($this->migration_id);
68
69 // Load actions
70 $actions = new Actions();
71 $actions->loadActions();
72 }
73
74 /**
75 * Run migration
76 */
77 public function runMigration()
78 {
79 $result = $this->getResult();
80
81 if ($this->job == null) {
82 return null;
83 }
84
85 // Handle job locking
86 $this->common->updateLastRunning();
87
88 if (isset($this->job->run_lock) && $this->job->run_lock === true) {
89 // Ohhh noes, already running
90 $errormsg = __('Job is already running or error has happened - Check PHP error logs', 'wpsynchro');
91 $result->errors[] = $errormsg;
92 $this->logger->log("CRITICAL", $errormsg);
93 return $result;
94 }
95
96 // If we are completed, just return
97 if ($this->job->is_completed) {
98 return $result;
99 }
100
101 // Set lock in job
102 $this->job->run_lock = true;
103 $this->job->run_lock_timer = time();
104 $this->job->run_lock_problem_time = time() + ceil($this->common->getPHPMaxExecutionTime() * 1.5); // Status thread will check if this time has passed (aka the migration thread has stopped
105 $this->job->save();
106
107 // Reset full time frame request
108 $this->job->request_full_timeframe = false;
109
110 // Start jobs
111 $lastrun_time = 0;
112 while ($this->timer->shouldContinueWithLastrunTime($lastrun_time)) {
113 $timer_start_identifier = $this->timer->startTimer("migrate-controller", "while", "lastrun");
114 $allotted_time_for_subjob = $this->timer->getRemainingSyncTime();
115
116 $this->logger->log("INFO", "Starting migration loop - With allotted time: " . $allotted_time_for_subjob . " seconds");
117
118 // If run requires full time frame
119 if ($this->job->request_full_timeframe) {
120 break;
121 }
122
123 // Handle the steps
124 if (!$this->job->initiation_completed) {
125 // Initiation
126 $this->handleInitiationStep();
127 break;
128 } elseif (!$this->job->masterdata_completed) {
129 // Metadata
130 $this->handleStepMasterdata();
131 break;
132 } elseif (!$this->job->database_backup_completed) {
133 // Database backup
134 if ($this->migration->sync_database && $this->migration->db_make_backup) {
135 $this->handleStepDatabaseBackup();
136 } else {
137 $this->job->database_backup_progress = 100;
138 $this->job->database_backup_completed = true;
139 }
140 break;
141 } elseif (!$this->job->database_completed) {
142 // Database
143 if ($this->migration->sync_database) {
144 $this->handleStepDatabase();
145 } else {
146 $this->job->database_progress = 100;
147 $this->job->database_completed = true;
148 }
149 break;
150 } elseif (!$this->job->files_all_completed) {
151 // Files sync
152 if ($this->migration->sync_files) {
153 $this->handleStepFiles();
154 } else {
155 $this->job->files_progress = 100;
156 $this->job->files_all_completed = true;
157 }
158 break;
159 } elseif (!$this->job->finalize_completed) {
160 // Finalize
161 $this->handleStepFinalize();
162 break;
163 } else {
164 break;
165 }
166
167 $lastrun_time = $this->timer->getElapsedTimeToNow($timer_start_identifier);
168 }
169
170 // Add errors and warnings to job
171 $this->job->errors = array_merge($this->job->errors, $this->errors);
172 $this->job->warnings = array_merge($this->job->warnings, $this->warnings);
173
174 // Set post run data
175 $this->updateCompletedState();
176 $this->job->run_lock = false;
177
178 // Get result to return
179 $result = $this->getResult();
180
181 // save job status before returning
182 $this->job->save();
183
184 if (count($this->job->errors) > 0) {
185 // Do error action
186 do_action("wpsynchro_migration_failure", $this->migration_id, $this->job_id, $this->job->errors, $this->job->warnings);
187
188 // Set this migration to failed
189 $metadatalog = new SyncMetadataLog();
190 $metadatalog->setMigrationToFailed($this->job_id, $this->migration_id);
191 }
192
193 // If we are completed
194 if ($this->job->is_completed) {
195 // Do migration completed action
196 do_action("wpsynchro_migration_completed", $this->migration_id, $this->job_id);
197 }
198
199 // Stop all timers and debug log them
200 $this->timer->endSync();
201 $this->logger->log("INFO", "Ending migration loop - with remaining time: " . $this->timer->getRemainingSyncTime());
202
203 return $result;
204 }
205
206 /**
207 * Try to resume a migration that had errors
208 */
209 public function attemptMigrationResume()
210 {
211 // Clean up first
212 $this->job->errors = [];
213 $this->job->warnings = [];
214 $this->job->run_lock = false;
215 $this->job->save();
216
217 $this->logger->log("INFO", "User restarted the migration");
218 }
219
220 /**
221 * Get migration result
222 */
223 public function getResult()
224 {
225 $result = new \stdClass();
226 $result->is_completed = $this->job->is_completed;
227 $result->transfertoken = $this->job->local_transfer_token;
228 $result->errors = $this->job->errors;
229 $result->warnings = $this->job->warnings;
230 $result->migration_complete_messages = $this->job->finalize_success_messages_frontend;
231 return $result;
232 }
233
234 /**
235 * Handle initiation step
236 */
237 private function handleInitiationStep()
238 {
239 $initiate = new InitiateSync();
240 $initiate->initiatemigration($this->migration, $this->job);
241 }
242
243 /**
244 * Handle masterdata step
245 */
246 private function handleStepMasterdata()
247 {
248 $masterdata = new MasterdataSync();
249 $masterdata->runMasterdataStep($this->migration, $this->job);
250 }
251
252 /**
253 * Handle database backup step
254 */
255 private function handleStepDatabaseBackup()
256 {
257 $databasebackup = new DatabaseBackup();
258 $databasebackup->backupDatabase($this->migration, $this->job);
259 }
260
261 /**
262 * Handle database step
263 */
264 private function handleStepDatabase()
265 {
266 $database_sync = new DatabaseSync();
267 $database_sync->runDatabaseSync($this->migration, $this->job);
268 }
269
270 /**
271 * Handle files step
272 */
273 private function handleStepFiles()
274 {
275 $filessync = new FilesSync();
276 if ($filessync != null) {
277 $filessync->runFilesSync($this->migration, $this->job);
278 }
279 }
280
281 /**
282 * Handle finalize step
283 */
284 private function handleStepFinalize()
285 {
286 $finalizesync = new FinalizeSync();
287 $finalizesync->runFinalize($this->migration, $this->job);
288 }
289
290 /**
291 * Updated completed status
292 */
293 private function updateCompletedState()
294 {
295 if ($this->job->masterdata_completed) {
296 $this->job->masterdata_progress = 100;
297 }
298 if ($this->job->database_backup_completed) {
299 $this->job->database_backup_progress = 100;
300 }
301 if ($this->job->database_completed) {
302 $this->job->database_progress = 100;
303 }
304 if ($this->job->files_all_completed) {
305 $this->job->files_progress = 100;
306 }
307 if ($this->job->finalize_completed) {
308 $this->job->finalize_progress = 100;
309 }
310 if ($this->job->masterdata_completed && $this->job->database_backup_completed && $this->job->database_completed && $this->job->files_all_completed && $this->job->finalize_completed) {
311 $this->job->is_completed = true;
312
313 // Stop migration and mark as completed in metadatalog
314 $metadatalog = new SyncMetadataLog();
315 $metadatalog->stopMigration($this->job_id, $this->migration_id);
316 }
317 }
318
319 /**
320 * Get the logger used for this migration
321 */
322 public function getLogger(): ?FileLogger
323 {
324 if (is_null($this->logger)) {
325 $common = new CommonFunctions();
326 $this->logger = new FileLogger($common->getLogFilename($this->job_id));
327 }
328 return $this->logger;
329 }
330 }
331