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 / Database / DatabaseBackup.php

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

228 lines 8.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace WPSynchro\Database;
4
5 use WPSynchro\Database\DatabaseHelperFunctions;
6 use WPSynchro\Logger\LoggerFactory;
7 use WPSynchro\Logger\LoggerInterface;
8 use WPSynchro\Migration\MigrationController;
9 use WPSynchro\Transport\Destination;
10 use WPSynchro\Transport\RemoteTransport;
11 use WPSynchro\Utilities\SyncTimerList;
12
13 /**
14 * Class for handling database backup
15 */
16 class DatabaseBackup
17 {
18 // Data objects
19 public $job = null;
20 public $migration = null;
21 public $databasesync = null;
22 // Dependencies
23 public $logger = null;
24 public $timer = null;
25
26 /**
27 * Constructor
28 */
29 public function __construct()
30 {
31 $this->databasesync = new DatabaseSync();
32 $this->logger = MigrationController::getInstance()->getLogger();
33 $this->timer = SyncTimerList::getInstance();
34 }
35
36 /**
37 * Backup database on target
38 */
39 public function backupDatabase(&$migration, &$job)
40 {
41 $this->migration = &$migration;
42 $this->job = &$job;
43
44 $this->logger->log("INFO", "Starting database backup loop with remaining time: " . $this->timer->getRemainingSyncTime());
45
46 // Make sure we have a list of tables to do
47 if ($this->job->db_backup_tables == null) {
48 $this->job->db_backup_tables = $this->createListOfTablesToBackup();
49 }
50
51 if (count($this->job->db_backup_tables) == 0) {
52 // update progress
53 $this->updateProgress();
54 return;
55 }
56
57 // Create destination, we always want to backup the target
58 $destination = new Destination(Destination::TARGET);
59
60 // Do a work chunk on remote end
61 $lastrun_time = 2; // init for 3 seconds
62 foreach ($this->job->db_backup_tables as &$table) {
63 if ($table->is_completed) {
64 continue;
65 }
66
67 while (!$table->is_completed) {
68 // Check if we should abort
69 if (!$this->timer->shouldContinueWithLastrunTime($lastrun_time)) {
70 $this->logger->log("INFO", "Ending database backup loop due to time constraint with remaining time: " . $this->timer->getRemainingSyncTime());
71 return;
72 }
73
74 $lastrun_timer = $this->timer->startTimer("databasebackup", "while", "lastrun");
75
76 // Set temp name on table to the same as table, as we are not renaming anything
77 $table->temp_name = $table->name;
78
79 // Send table to be dumped on remote
80 $url = $destination->getFullURL() . "?action=wpsynchro_backupdatabase";
81 $body = new \stdClass();
82 $body->table = $table;
83 $body->filename = "database_backup_" . $this->job->id . ".sql";
84 $body->memory_limit = intval($this->job->to_memory_limit * 0.7);
85 $body->time_limit = intval($this->timer->getRemainingSyncTime() / 2);
86
87 $this->logger->log('DEBUG', 'Getting data from remote DB with data: ' . json_encode($body));
88
89 // Get remote transfer object
90 $remotetransport = new RemoteTransport();
91 $remotetransport->setDestination($destination);
92 $remotetransport->setJob($job);
93 $remotetransport->init();
94 $remotetransport->setUrl($url);
95 $remotetransport->setDataObject($body);
96 $databasebackup_result = $remotetransport->remotePOST();
97
98 if ($databasebackup_result->isSuccess()) {
99 $result_body = $databasebackup_result->getBody();
100 $this->logger->log('DEBUG', 'Got response with content: ' . json_encode($result_body));
101 $result_table = $result_body->table;
102
103 // Copy data
104 $table->completed_rows = $result_table->completed_rows;
105 $table->last_primary_key = $result_table->last_primary_key;
106
107 // Check for completion
108 if (!$result_body->has_more_rows_in_table) {
109 $table->completed_rows = $table->rows;
110 $table->is_completed = true;
111 }
112 } else {
113 $this->job->errors[] = __("Database backup Service responded with error, which means we can not continue the migration.", "wpsynchro");
114 }
115
116 // update progress
117 $this->updateProgress();
118
119 // Timings
120 $remainingtime = $this->timer->getRemainingSyncTime();
121 $lastrun_time = $this->timer->endTimer($lastrun_timer);
122 $this->logger->log("DEBUG", sprintf("Backup table %s with rows %d / %d with remainingtime %s and lastrun %s", $table->name, $table->completed_rows, $table->rows, $remainingtime, $lastrun_time));
123
124 // Check if we should abort
125 if (!$this->timer->shouldContinueWithLastrunTime($lastrun_time)) {
126 $this->logger->log("INFO", "Ending database backup loop due to time constraint with remaining time: " . $this->timer->getRemainingSyncTime());
127 return;
128 }
129 }
130 }
131
132 $this->logger->log("INFO", "Ending database backup loop with remaining time: " . $this->timer->getRemainingSyncTime());
133 }
134
135 /**
136 * Create list of tables to backup
137 */
138 public function createListOfTablesToBackup()
139 {
140
141 $tables_to_backup = [];
142
143 // Generate list of tables on target, that is not temp tables, aka possible list to backup
144 $target_tables = [];
145 foreach ($this->job->to_dbmasterdata as $table) {
146 if (strpos($table->name, DatabaseSync::TMP_TABLE_PREFIX) === 0) {
147 continue;
148 }
149
150 $table->is_completed = false;
151 $target_tables[] = $table;
152 }
153
154 // Go through the database tables from the source and create a lookup
155 $source_lookup = [];
156 foreach ($this->job->from_dbmasterdata as $table) {
157 $changed_prefix = DatabaseHelperFunctions::handleTablePrefixChange($table->name, $this->job->from_wpdb_prefix, $this->job->to_wpdb_prefix);
158 $source_lookup[$changed_prefix] = true;
159 }
160
161
162
163 if ($this->migration->include_all_database_tables) {
164 $tables_to_backup = $target_tables;
165 } else {
166 // Generate the list of tables from source that will be moved
167 $onlyinclude = $this->migration->only_include_database_table_names;
168 $includes_with_prefix_changed = [];
169 foreach ($onlyinclude as $tableinc) {
170 $includes_with_prefix_changed[] = DatabaseHelperFunctions::handleTablePrefixChange($tableinc, $this->job->from_wpdb_prefix, $this->job->to_wpdb_prefix);
171 }
172
173 // Check which target tables should be included
174 foreach ($target_tables as $table) {
175 if (in_array($table->name, $includes_with_prefix_changed)) {
176 $tables_to_backup[] = $table;
177 }
178 }
179 }
180
181 return $tables_to_backup;
182 }
183
184 /**
185 * Create list of tables to backup
186 */
187 public function updateProgress()
188 {
189 $totalrows = 0;
190 $completed_rows = 0;
191 $completion_percent = 0;
192 foreach ($this->job->db_backup_tables as $table) {
193 $totalrows += $table->rows;
194 $completed_rows += $table->completed_rows;
195 }
196
197 if ($totalrows == 0) {
198 $this->job->database_backup_progress = 100;
199 $this->job->database_backup_completed = true;
200 $this->job->database_backup_progress_description = "";
201 $this->job->save();
202 return;
203 }
204
205 if ($completed_rows > 0) {
206 $completion_percent = intval(($completed_rows / $totalrows) * 100);
207 if ($completion_percent > 100) {
208 $completion_percent = 100;
209 }
210 }
211
212 $completed_rows = number_format_i18n($completed_rows, 0);
213 $totalrows = number_format_i18n($totalrows, 0);
214
215 if ($completion_percent == 100) {
216 $this->job->database_backup_completed = true;
217 }
218 $this->job->database_backup_progress = $completion_percent;
219
220 if ($completion_percent < 100) {
221 $this->job->database_backup_progress_description = sprintf(__("Row %s / %s", "wpsynchro"), $completed_rows, $totalrows);
222 } else {
223 $this->job->database_backup_progress_description = "";
224 }
225 $this->job->save();
226 }
227 }
228